#include "module.c" #include #include #include #include #include #include const char *CHANNEL_NAMES[] = {"EVENT_NUM", "EVENT_I", "EVENT_J", "EVENT_CHARGE", "EVENT_ETA_X", "EVENT_ETA_Y", "EVENT_I_INTERP", "EVENT_J_INTERP"}; // max number of events per frame #define MAX_NUM_EVENTS 600 #define EVENT_CHANNELS 7 double evt_p[EVENT_CHANNELS][MAX_NUM_EVENTS]; int func_ph_1d_double( double *frame, int i_dim, int j_dim, double *th_m); void setArrayToValue(double array[], int size, double value) { int i; for (i = 0; i < size; i++) { array[i] = value; } } //Initialization: Threshold & background initialized = 0; int threshold_num_elements=-1; double *threshold= NULL; double *background= NULL; const int MAX_LINE_LENGTH = 50000; int parseTextFile(const char * fileName, double *arr, int size_x, int size_y){ FILE *file = fopen(fileName, "rb"); if (file == NULL) { syslog(LOG_ERR, "Failed to open data file: %s" , fileName); return -1; } int ret = 1; char line[MAX_LINE_LENGTH]; int x = 0; int y = 0; while (fgets(line, sizeof(line), file) != NULL) { char* token = strtok(line, " "); while (token != NULL) { threshold[y * size_x + x] = atof(token); token = strtok(NULL, " "); x++; } y++; if (x != size_x){ syslog(LOG_ERR, "Invalid data file - wrong number of columns: %s" , fileName); ret = -2; break; } x = 0; } if (y != size_y){ syslog(LOG_ERR, "Invalid data file - wrong number of rows: %s" , fileName); ret = -3; } fclose(file); return ret; } double getParDouble(PyObject *pars, char *name, double defaultValue){ PyObject* threshold_obj = PyDict_GetItemString(pars, name); if (threshold_obj!=NULL){ if (PyFloat_Check(threshold_obj)) { return PyFloat_AsDouble(threshold_obj); } else if (PyLong_Check(threshold_obj)) { return PyLong_AsDouble(threshold_obj); } } return defaultValue; } int initialize(int size_x, int size_y, PyObject *pars){ openlog("single_photon", LOG_PID, LOG_USER); syslog(LOG_INFO, "Initialized single_photon."); int ret = 1; threshold = (double *)malloc(size_x*size_y*sizeof(double)); double threshold_val = getParDouble(pars, "threshold", 1.0); PyObject* threshold_file = PyDict_GetItemString(pars, "threshold_file"); if (threshold_file!=NULL){ const char * threshold_file_str = PyUnicode_AsUTF8(threshold_file); int ret = parseTextFile(threshold_file_str, threshold, size_x, size_y); if (ret<0){ setArrayToValue(threshold,size_x*size_y, threshold_val); } } else { setArrayToValue(threshold,size_x*size_y, threshold_val); } //background (all matrices are indexed in 1d) background = malloc(size_x*size_y*sizeof(double)); double background_val = getParDouble(pars, "background", 0.0); PyObject* background_file = PyDict_GetItemString(pars, "background_file"); if (background_file!=NULL){ const char * background_file_str = PyUnicode_AsUTF8(background_file); int ret = parseTextFile(background_file_str, background, size_x, size_y); if (ret<0){ setArrayToValue(background,size_x*size_y, background_val); } } else { setArrayToValue(background,size_x*size_y, background_val); } return ret; } //def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None): PyObject *process(PyObject *self, PyObject *args) { PyArrayObject *image; long pulse_id; PyObject /*double*/ *timestamp; long seconds, nanos; PyArrayObject *x_axis; PyArrayObject *y_axis; PyObject *pars; PyObject *bsdata; //if (!PyArg_ParseTuple(args, "OldOOO|O", &image, &pulse_id, ×tamp, &x_axis, &y_axis, &pars, &bsdata)) if ( !PyArg_ParseTuple(args, "OlOOOO|O", &image, &pulse_id, ×tamp, &x_axis, &y_axis, &pars, &bsdata) || !PyArg_ParseTuple(timestamp, "ll", &seconds, &nanos) ) return NULL; if (pulse_id < 0) { PyErr_SetString(moduleErr, "Invalid Pulse ID"); return NULL; } //Acessing image int element_size = image->descr->elsize; int dims = image->nd; int size_x = image->dimensions[1]; int size_y = image->dimensions[0]; unsigned short* img_data = (unsigned short*)image->data; //Initialization if (initialized==0){ initialized = initialize(size_x, size_y, pars); } int i,j,l; int i_dim=size_y; int j_dim=size_x; double *frameBKsub = malloc(i_dim*j_dim*sizeof(double)); for(i=0; i=MAX_NUM_EVENTS){ break; } for(j=0;j=MAX_NUM_EVENTS){ break; } // 2x2 version charge = frame[i*j_dim+j]+frame[(i+1)*j_dim+j] + frame[i*j_dim+(j+1)]+frame[(i+1)*j_dim+j+1]; //pixel by pixel threshold th = th_m[i*j_dim +j]; //check if charge above threshold if(charge>th) { eta_x = (frame[(i+1)*j_dim + j ]+frame[(i+1)*j_dim + (j+1)])/charge; eta_y = (frame[ i*j_dim + (j+1)]+frame[(i+1)*j_dim + (j+1)])/charge; i_interp = i + (C[0] + C[1]*eta_x+ C[2]*pow(eta_x,2) + C[3]*pow(eta_x,3) + C[4]*pow(eta_x,4)+ C[5]*pow(eta_x,5) + C[6]*pow(eta_x,6) + C[7]*pow(eta_x,7)); j_interp = j + (D[0] + D[1]*eta_y+ D[2]*pow(eta_y,2) + D[3]*pow(eta_y,3) + D[4]*pow(eta_y,4)+ D[5]*pow(eta_y,5) + D[6]*pow(eta_y,6) + D[7]*pow(eta_y,7)); // 1st case: first event if(evt_i==0){ evt_p[0][evt_i] = i; evt_p[1][evt_i] = j; evt_p[2][evt_i] = charge; evt_p[3][evt_i] = eta_x; evt_p[4][evt_i] = eta_y; evt_p[5][evt_i] = i_interp; // evt_p[6][evt_i] = j_interp; // evt_i++; } else { // 2nd case: not 1st event. we check if it is a neighbourg of the previos events and if charge is larger n=0; evt_m_i = evt_i; for(m=0; m