#ifndef MULTITHREADED_ANALOG_DETECTOR_H #define MULTITHREADED_ANALOG_DETECTOR_H #include #include #include #include #include #include //#include //#include //#include #include #include #include //#include "analogDetector.h" #include "singlePhotonDetector.h" //#include "interpolatingDetector.h" #include "circularFifo.h" #include "slsInterpolation.h" #include #include #include //#include using namespace std; class threadedAnalogDetector { public: threadedAnalogDetector(analogDetector *d, int fs=10000) { char *mem, *mm; det=d; fifoFree=new CircularFifo(fs); fifoData=new CircularFifo(fs); mem=(char*)malloc(fs*det->getDataSize()); // cout << "data size is " << det->getDataSize()*fs << endl; for (int i=0; igetDataSize(); fifoFree->push(mm); } busy=0; stop=1; fMode=eFrame; ff=NULL; } virtual int setFrameMode(int fm) {fMode=fm; if (fMode>=0) det->setFrameMode((frameMode)fMode);}; //fMode=fm; return fMode;} /* void prepareInterpolation(int &ok) { */ /* cout << "-" << endl; */ /* det->prepareInterpolation(ok); */ /* }; */ virtual int *getImage() { return det->getImage(); } virtual int getImageSize(int &nnx, int &nny, int &ns) {return det->getImageSize(nnx, nny, ns);}; virtual int getDetectorSize(int &nnx, int &nny) {return det->getDetectorSize(nnx, nny);}; ~threadedAnalogDetector() {StopThread(); free(mem); delete fifoFree; delete fifoData;} /** Returns true if the thread was successfully started, false if there was an error starting the thread */ virtual bool StartThread() { stop=0; return (pthread_create(&_thread, NULL, processData, this) == 0); } virtual void StopThread() { stop=1; (void) pthread_join(_thread, NULL); } virtual bool pushData(char* &ptr) { fifoData->push(ptr); } virtual bool popFree(char* &ptr) { fifoFree->pop(ptr); } virtual int isBusy() {return busy;} //protected: /** Implement this method in your subclass with the code you want your thread to run. */ //virtual void InternalThreadEntry() = 0; virtual void *writeImage(const char * imgname) {cout << "a" <writeImage(imgname);}; virtual void clearImage(){det->clearImage();}; virtual void prepareInterpolation(int &ok){ slsInterpolation *interp=(slsInterpolation*)det->getInterpolation(); if (interp) interp->prepareInterpolation(ok); } virtual int *getFlatField(){ slsInterpolation *interp=(slsInterpolation*)det->getInterpolation(); if (interp) return interp->getFlatField(); else return NULL; } virtual int *setFlatField(int *ff, int nb, double emin, double emax){ slsInterpolation *interp=(slsInterpolation*)det->getInterpolation(); if (interp) return interp->setFlatField(ff, nb, emin, emax); else return NULL; } virtual int *getFlatField(int &nb, double emi, double ema){ slsInterpolation *interp=(slsInterpolation*)det->getInterpolation(); int *ff; if (interp) { ff=interp->getFlatField(nb,emi,ema); // cout << "tdgff* ff has " << nb << " bins " << endl; return ff; } else return NULL; } virtual char *getInterpolation() { return det->getInterpolation(); } virtual void setPedestal(double *ped, double *rms=NULL, int m=-1){det->setPedestal(ped,rms,m);}; virtual void setPedestalRMS(double *rms){ det->setPedestalRMS(rms);}; virtual double *getPedestal(double *ped=NULL){return det->getPedestal(ped);}; virtual double *getPedestalRMS(double *rms=NULL){ return det->getPedestalRMS(rms);}; /** sets file pointer where to write the clusters to \param f file pointer \returns current file pointer */ FILE *setFilePointer(FILE *f){return det->setFilePointer(f); }; /** gets file pointer where to write the clusters to \returns current file pointer */ FILE *getFilePointer(){return det->getFilePointer();}; void setMutex(pthread_mutex_t *fmutex){det->setMutex(fmutex);}; private: analogDetector *det; int fMode; int *dataSize; pthread_t _thread; char *mem; CircularFifo *fifoFree; CircularFifo *fifoData; int stop; int busy; char *data; int *ff; static void * processData(void * ptr) { threadedAnalogDetector *This=((threadedAnalogDetector *)ptr); return This->processData(); } void * processData() { busy=1; while (!stop) { if (fifoData->isEmpty()) { busy=0; usleep(100); } else { busy=1; fifoData->pop(data); //blocking! det->processData(data); fifoFree->push(data); } } return NULL; } }; class multiThreadedAnalogDetector { public: multiThreadedAnalogDetector(analogDetector *d, int n, int fs=1000) : nThreads(n), ithread(0) { dd[0]=d; if (nThreads==1) dd[0]->setId(100); else dd[0]->setId(0); for (int i=1; iClone(); dd[i]->setId(i); } for (int i=0; igetImageSize(nnx, nny,ns); image=new int[nn]; ff=NULL; ped=NULL; } ~multiThreadedAnalogDetector() { StopThreads(); for (int i=0; isetFrameMode(fm); return ret;}; int *getImage(int &nnx, int &nny, int &ns) { int *img; // int nnx, nny, ns; int nn=dets[0]->getImageSize(nnx, nny, ns); //for (i=0; igetImageSize(nnx, nny, ns) << " " << nnx << " " << nny << " " << ns << endl; img=dets[ii]->getImage(); for (int i=0; iclearImage(); } } virtual void *writeImage(const char * imgname) { /* #ifdef SAVE_ALL */ /* for (int ii=0; iiwriteImage(tit); */ /* } */ /* #endif */ int nnx, nny, ns; getImage(nnx, nny, ns); //int nnx, nny, ns; int nn=dets[0]->getImageSize(nnx, nny, ns); float *gm=new float[nn]; if (gm) { for (int ix=0; ix0) cout << ix << " " << image[ix]<< endl; gm[ix]=image[ix]; } //cout << "image " << nnx << " " << nny << endl; WriteToTiff(gm,imgname ,nnx, nny); delete [] gm; } else cout << "Could not allocate float image " << endl; return NULL; } virtual void StartThreads() { for (int i=0; iStartThread(); } virtual void StopThreads() { for (int i=0; iStopThread(); } int isBusy() { int ret=0, ret1; for (int i=0; iisBusy(); ret|=ret1; // if (ret1) cout << "thread " << i <<" still busy " << endl; } return ret; } bool pushData(char* &ptr) { dets[ithread]->pushData(ptr); } bool popFree(char* &ptr) { dets[ithread]->popFree(ptr); } int nextThread() { ithread++; if (ithread==nThreads) ithread=0; return ithread; } virtual void prepareInterpolation(int &ok){ getFlatField(); //sum up all etas setFlatField(); //set etas to all detectors for (int i=0; iprepareInterpolation(ok); } } virtual int *getFlatField(){ int nb=0; double emi, ema; int *f0; slsInterpolation* inte=(slsInterpolation*)dets[0]->getInterpolation(); if (inte) { if (inte->getFlatField(nb,emi,ema)) { if (ff) delete [] ff; ff=new int[nb*nb]; for (int i=0; igetInterpolation(); f0=inte->getFlatField(); if (f0) { // cout << "ff " << i << endl; for (int ib=0; ib0) */ /* cout << i << " " << ib << " " << f0[ib] << " " << ff[ib] << endl; */ } } } return ff; } } return NULL; } virtual int *setFlatField(int *h=NULL, int nb=-1, double emin=1, double emax=0){ //int nb=0; double emi, ema; slsInterpolation* inte=(slsInterpolation*)dets[0]->getFlatField(nb,emi,ema); if (inte) { if (h==NULL) h=ff; for (int i=0; isetFlatField(h, nb, emin, emax); } } return NULL; }; void *writeFlatField(const char * imgname){ int nb=0; double emi, ema; slsInterpolation* inte=(slsInterpolation*)dets[0]->getFlatField(nb,emi,ema); if (inte) { if (getFlatField()) { // cout << "mtwff* ff has " << nb << " bins " << endl; float *gm=new float[nb*nb]; if (gm) { for (int ix=0; ixgetFlatField(nb,emin,emax); if (inte) { uint32 nnx; uint32 nny; float *gm=ReadFromTiff(imgname, nnx, nny); if (ff) delete [] ff; if (nnx>nb) nb=nnx; if (nny>nb) nb=nny; ff=new int[nb*nb]; for (int ix=0; ixgetDetectorSize(nx,ny); if (ped) delete [] ped; ped=new double[nx*ny]; double *p0=new double[nx*ny]; for (int i=0; igetInterpolation(nb,emi,ema); p0=dets[i]->getPedestal(p0); if (p0) { for (int ib=0; ibgetDetectorSize(nx,ny); if (h==NULL) h=ped; for (int i=0; isetPedestal(h); } return NULL; }; void *writePedestal(const char * imgname){ int nx, ny; dets[0]->getDetectorSize(nx,ny); getPedestal(); float *gm=new float[nx*ny]; if (gm) { for (int ix=0; ixgetDetectorSize(nx,ny); uint32 nnx; uint32 nny; float *gm=ReadFromTiff(imgname, nnx, nny); if (ped) delete [] ped; if (nnx>nx) nx=nnx; if (nny>ny) ny=nny; ped=new double[nx*ny]; for (int ix=0; ixsetFilePointer(f); //dets[i]->setMutex(&fmutex); } return dets[0]->getFilePointer(); }; /** gets file pointer where to write the clusters to \returns current file pointer */ FILE *getFilePointer(){return dets[0]->getFilePointer();}; private: bool stop; const int nThreads; threadedAnalogDetector *dets[20]; analogDetector *dd[20]; int ithread; int *image; int *ff; double *ped; pthread_mutex_t fmutex; }; #endif