#ifndef MULTITHREADED_ANALOG_DETECTOR_H #define MULTITHREADED_ANALOG_DETECTOR_H #define MAXTHREADS 1000 #include #include #include #include #include #include //#include //#include //#include #include #include #include #include "analogDetector.h" #include "circularFifo.h" #include #include #include //#include using namespace std; class threadedAnalogDetector { public: threadedAnalogDetector(analogDetector *d, int fs=10000) { char *mm;//*mem, det=d; fifoFree=new CircularFifo(fs); fifoData=new CircularFifo(fs); // mem==NULL; /* mem=(char*)calloc(fs, det->getDataSize()); */ /* if (mem) */ /* memset(mem,0, fs*det->getDataSize()); */ int i; for (i=0; igetDataSize(); // cout << i << endl; mm=(char*)calloc(1, det->getDataSize()); if (mm) { //memset(mm,0, det->getDataSize()); fifoFree->push(mm); } else break; } if (i=0) { det->setFrameMode((frameMode)fm); fMode=fm; } return fMode; }; virtual double setThreshold(double th) {return det->setThreshold(th);}; virtual void setROI(int xmin, int xmax, int ymin, int ymax) {det->setROI(xmin,xmax,ymin,ymax);}; virtual int setDetectorMode(int dm) { if (dm>=0) { det->setDetectorMode((detectorMode)dm); dMode=dm; } return dMode; }; virtual void newDataSet(){det->newDataSet();}; //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, int &nsy) {return det->getImageSize(nnx, nny, ns, nsy);}; virtual int getDetectorSize(int &nnx, int &nny) {return det->getDetectorSize(nnx, nny);}; virtual ~threadedAnalogDetector() {StopThread(); 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; cout << "Detector number " << det->getId() << endl; cout << "common mode is " << det->getCommonModeSubtraction()<< endl; cout << "ghos summation is " << det->getGhostSummation()<< endl; return (pthread_create(&_thread, NULL, processData, this) == 0); } virtual void StopThread() { stop=1; (void) pthread_join(_thread, NULL); } virtual bool pushData(char* &ptr) { return fifoData->push(ptr); } virtual bool popFree(char* &ptr) { return fifoFree->pop(ptr); } virtual int isBusy() {if (fifoData->isEmpty() && busy==0) return 0; return 1;} //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) {return det->writeImage(imgname);}; virtual void clearImage(){det->clearImage();}; 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();}; virtual double setNSigma(double n) {return det->setNSigma(n);}; virtual void setEnergyRange(double emi, double ema) {det->setEnergyRange(emi,ema);}; virtual void prepareInterpolation(int &ok){ slsInterpolation *interp=det->getInterpolation(); if (interp) interp->prepareInterpolation(ok); } virtual int *getFlatField(){ slsInterpolation *interp=(det)->getInterpolation(); if (interp) return interp->getFlatField(); else return NULL; } virtual int *setFlatField(int *ff, int nb, double emin, double emax){ slsInterpolation *interp=(det)->getInterpolation(); if (interp) return interp->setFlatField(ff, nb, emin, emax); else return NULL; } void *writeFlatField(const char * imgname) { slsInterpolation *interp=(det)->getInterpolation(); //cout << "interp " << interp << endl; if (interp) { cout << imgname << endl; return interp->writeFlatField(imgname); } return NULL; } void *readFlatField(const char * imgname, int nb=-1, double emin=1, double emax=0){ slsInterpolation *interp=(det)->getInterpolation(); if (interp) return interp->readFlatField(imgname, nb, emin, emax); return NULL; } virtual int *getFlatField(int &nb, double emi, double ema){ slsInterpolation *interp=(det)->getInterpolation(); int *ff=NULL; if (interp) { ff=interp->getFlatField(nb,emi,ema); } return ff; } virtual slsInterpolation *getInterpolation() { return (det)->getInterpolation(); } virtual void resetFlatField() { slsInterpolation *interp=(det)->getInterpolation(); if (interp) interp->resetFlatField();//((interpolatingDetector*)det)->resetFlatField(); } virtual int setNSubPixels(int ns, int nsy) { slsInterpolation *interp=(det)->getInterpolation(); if (interp) interp->setNSubPixels(ns, nsy); return 1;}; virtual slsInterpolation *setInterpolation(slsInterpolation *f){ return (det)->setInterpolation(f); }; protected: analogDetector *det; int fMode; int dMode; int *dataSize; pthread_t _thread; 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); //busy=0; } } return NULL; } }; class multiThreadedAnalogDetector { public: multiThreadedAnalogDetector(analogDetector *d, int n, int fs=1000) : stop(0), 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; isetFrameMode(fm); for (int i=1; isetFrameMode(fm);} return ret;}; virtual double setThreshold(int fm) { double ret=dets[0]->setThreshold(fm); for (int i=1; isetThreshold(fm); return ret;}; virtual int setDetectorMode(int dm) { int ret=dets[0]->setDetectorMode(dm);; for (int i=1; isetDetectorMode(dm); return ret;}; virtual void setROI(int xmin, int xmax, int ymin, int ymax) { for (int i=0; isetROI(xmin, xmax,ymin,ymax);}; virtual void newDataSet(){for (int i=0; inewDataSet();}; virtual int *getImage(int &nnx, int &nny, int &ns, int &nsy) { int *img; // int nnx, nny, ns; // int nnx, nny, ns; int nn=dets[0]->getImageSize(nnx, nny,ns, nsy); if (image) { delete [] image; image=NULL; } image=new int[nn]; //int nn=dets[0]->getImageSize(nnx, nny, ns); //for (i=0; igetImage(); for (int i=0; i0) image[i]=img[i]; // else // image[i]=0; else //if (img[i]>0) image[i]+=img[i]; //if (img[i]) cout << "det " << ii << " pix " << i << " val " << img[i] << " " << image[i] << endl; } } return image; } virtual void clearImage() { for (int ii=0; iiclearImage(); } } virtual void *writeImage(const char * imgname, double t=1) { /* #ifdef SAVE_ALL */ /* for (int ii=0; iiwriteImage(tit); */ /* } */ /* #endif */ int nnx, nny, ns, nsy; getImage(nnx, nny, ns,nsy); //int nnx, nny, ns; int nn=dets[0]->getImageSize(nnx, nny, ns, nsy); float *gm=new float[nn]; if (gm) { for (int ix=0; ix0 && ix/nnx<350) cout << ix/nnx << " " << ix%nnx << " " << image[ix]<< " " << gm[ix] << endl; } //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(); } virtual int isBusy() { int ret=0, ret1; for (int i=0; iisBusy(); ret|=ret1; // if (ret1) cout << "thread " << i <<" still busy " << endl; } return ret; } virtual bool pushData(char* &ptr) { return dets[ithread]->pushData(ptr); } virtual bool popFree(char* &ptr) { // cout << ithread << endl; return dets[ithread]->popFree(ptr); } virtual int nextThread() { ithread++; if (ithread==nThreads) ithread=0; return ithread; } virtual double *getPedestal(){ int nx, ny; dets[0]->getDetectorSize(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); // cout << i << endl; p0=dets[i]->getPedestal(p0); if (p0) { if (i==0) { for (int ib=0; ibgetDetectorSize(nx,ny); // if (ped) delete [] ped; double *rms=new double[nx*ny]; double *p0=new double[nx*ny]; for (int i=0; igetInterpolation(nb,emi,ema); // cout << i << endl; p0=dets[i]->getPedestalRMS(p0); if (p0) { if (i==0) { for (int ib=0; ib0) */ /* rms[ib]=sqrt(ped[ib]); */ /* else */ /* rms[ib]=0; */ /* } */ return rms; }; virtual double *setPedestal(double *h=NULL){ //int nb=0; int nx, ny; dets[0]->getDetectorSize(nx,ny); if (h==NULL) h=ped; for (int i=0; isetPedestal(h); } return NULL; }; virtual 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); double *rms=getPedestalRMS(); 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>(uint)nx) nx=nnx; if (nny>(uint)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 */ virtual FILE *getFilePointer(){return dets[0]->getFilePointer();}; protected: bool stop; const int nThreads; threadedAnalogDetector *dets[MAXTHREADS]; analogDetector *dd[MAXTHREADS]; int ithread; int *image; int *ff; double *ped; pthread_mutex_t fmutex; }; #endif