From 8d09f061da14afa9ca354c7642ab1ef97d80ef7a Mon Sep 17 00:00:00 2001 From: bergamaschi Date: Thu, 12 Dec 2013 16:05:24 +0000 Subject: [PATCH] some doxy comments added git-svn-id: file:///afs/psi.ch/project/sls_det_software/svn/slsDetectorCalibration@13 113b152e-814d-439b-b186-022a431db7b5 --- slsDetectorCalibration/MovingStat.h | 97 +++++--- .../commonModeSubtraction.h | 46 ++-- slsDetectorCalibration/moench02ModuleData.h | 60 +++-- slsDetectorCalibration/moenchCommonMode.h | 41 ++-- slsDetectorCalibration/pedestalSubtraction.h | 28 ++- slsDetectorCalibration/singlePhotonDetector.h | 135 ++++++++--- slsDetectorCalibration/single_photon_hit.h | 72 +++--- slsDetectorCalibration/slsDetectorData.h | 213 +++++++++--------- slsDetectorCalibration/slsReceiverData.h | 165 ++++++++++++++ 9 files changed, 599 insertions(+), 258 deletions(-) create mode 100644 slsDetectorCalibration/slsReceiverData.h diff --git a/slsDetectorCalibration/MovingStat.h b/slsDetectorCalibration/MovingStat.h index d856228dd..00d692cc0 100755 --- a/slsDetectorCalibration/MovingStat.h +++ b/slsDetectorCalibration/MovingStat.h @@ -6,43 +6,60 @@ class MovingStat { + + /** @short approximated moving average structure */ public: + + + /** constructor + \param nn number of samples parameter to be used + */ MovingStat(int nn=1000) : n(nn), m_n(0) {} + /** + clears the moving average number of samples parameter, mean and standard deviation + */ void Clear() { m_n = 0; - m_oldM=0; m_newM=0; - m_oldM2=0; m_newM2=0; } - void SetN(int i) {n=i;}; + + /** sets number of samples parameter + \param i number of samples parameter to be set + */ + + void SetN(int i) {if (i>=1) n=i;}; + + /** + gets number of samples parameter + \returns actual number of samples parameter + */ int GetN() {return n;}; + + /** calculates the moving average i.e. adds if number of elements is lower than number of samples parameter, pushes otherwise + \param x value to calculate the moving average + */ inline void Calc(double x) { if (m_n 0) ? m_newM/m_n : 0.0; } + + /** returns the squared mean, 0 if no elements are inside + \returns returns the squared average + */ double M2() const { return ( (m_n > 1) ? m_newM2/m_n : 0.0 ); } + /** returns the variance, 0 if no elements are inside + \returns returns the variance + */ inline double Variance() const { return ( (m_n > 1) ? (M2()-Mean()*Mean()) : 0.0 ); } + /** returns the standard deviation, 0 if no elements are inside + \returns returns the standard deviation + */ inline double StandardDeviation() const { return ( (Variance() > 0) ? sqrt( Variance() ) : -1 ); } private: - int n; - int m_n; - double m_oldM, m_newM, m_oldM2, m_newM2; + int n; /**< number of samples parameter */ + int m_n; /**< current number of elements */ + double m_newM; /**< accumulated average */ + double m_newM2; /**< accumulated squared average */ }; #endif diff --git a/slsDetectorCalibration/commonModeSubtraction.h b/slsDetectorCalibration/commonModeSubtraction.h index 89984ed81..4029e99b5 100644 --- a/slsDetectorCalibration/commonModeSubtraction.h +++ b/slsDetectorCalibration/commonModeSubtraction.h @@ -5,10 +5,22 @@ class commonModeSubtraction { + /** @short class to calculate the common mode of the pedestals based on an approximated moving average*/ + public: + + /** constructor + \param nn number of samples for the moving average to calculate the average common mode + \param iroi number of regions on which one can calculate the common mode separately. Defaults to 1 i.e. whole detector + + */ commonModeSubtraction(int nn=1000, int iroi=1) : cmStat(NULL), cmPed(NULL), nCm(NULL), nROI(iroi) {cmStat=new MovingStat[nROI]; for (int i=0; i0) cmStat[i].Calc(cmPed[i]/nCm[i]); @@ -23,25 +36,32 @@ class commonModeSubtraction { cmPed[i]=0; }}; - virtual void addToCommonMode(double val, int ix=0, int iy=0) { - (void)ix; (void)iy; - cmPed[0]+=val; - nCm[0]++;}; - - virtual double getCommonMode(int ix=0, int iy=0) { - (void)ix; (void)iy; - if (nCm[0]>0) return cmPed[0]/nCm[0]-cmStat[0].Mean(); - else return 0;}; + /** adds the pixel to the sum of pedestals -- virtual func + \param isc region of interest index + */ + virtual void addToCommonMode(double val, int isc=0) { + if (isc>=0 && isc=0 && isc0) return cmPed[0]/nCm[0]-cmStat[0].Mean(); + return 0;}; protected: - MovingStat *cmStat; //stores the common mode average per supercolumn */ - double *cmPed; // stores the common mode for this frame per supercolumn */ - double *nCm; // stores the number of pedestals to calculate the cm per supercolumn */ - const int nROI; + MovingStat *cmStat; /** -#include - -#include -using namespace std; +#include "slsReceiverData.h" -class moench02ModuleData : public slsDetectorData { +class moench02ModuleData : public slsReceiverData { public: /** - - Constructor (no error checking if datasize and offsets are compatible!) - \param npx number of pixels in the x direction - \param npy number of pixels in the y direction - \param ds size of the dataset - \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) - \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) - + Implements the slsReceiverData structure for the moench02 prototype read out by a module i.e. using the slsReceiver + (160x160 pixels, 40 packets 1286 large etc.) + \param c crosstalk parameter for the output buffer */ - moench02ModuleData(double c=0): slsDetectorData(160, 160, 40, 1286), xtalk(c) { + moench02ModuleData(double c=0): slsReceiverData(160, 160, 40, 1286), xtalk(c) { @@ -60,7 +45,7 @@ class moench02ModuleData : public slsDetectorData { ix=isc*40+ic; iy=ip*16+ir; - dMap[iy][ix]=1286*(isc*10+ip)+2*ir*40+2*ic; + dMap[iy][ix]=1286*(isc*10+ip)+2*ir*40+2*ic+4; // cout << ix << " " << iy << " " << dMap[ix][iy] << endl; } } @@ -85,9 +70,15 @@ class moench02ModuleData : public slsDetectorData { }; - // ~moench02ModuleData() {if (buff) delete [] buff; if (oldbuff) delete [] oldbuff; }; + + /** + gets the packets number (last packet is labelled with 0 and is replaced with 40) + \param buff pointer to the memory + \returns packet number + */ + int getPacketNumber(char *buff){ int np=(*(int*)buff)&0xff; if (np==0) @@ -95,6 +86,15 @@ class moench02ModuleData : public slsDetectorData { return np; }; + + /** + returns the pixel value as double correcting for the output buffer crosstalk + \param data pointer to the memory + \param ix coordinate in the x direction + \param iy coordinate in the y direction + \returns channel value as double + + */ double getValue(char *data, int ix, int iy=0) { if (xtalk==0 || ix%40==0) return (double)getValue(data, ix, iy); @@ -102,7 +102,19 @@ class moench02ModuleData : public slsDetectorData { return slsDetectorData::getValue(data, ix, iy)-xtalk*slsDetectorData::getValue(data, ix-1, iy); }; + + + /** sets the output buffer crosstalk correction parameter + \param c output buffer crosstalk correction parameter to be set + \returns current value for the output buffer crosstalk correction parameter + + */ double setXTalk(double c) {xtalk=c; return xtalk;} + + + /** gets the output buffer crosstalk parameter + \returns current value for the output buffer crosstalk correction parameter + */ double getXTalk() {return xtalk;} @@ -113,7 +125,7 @@ class moench02ModuleData : public slsDetectorData { private: - double xtalk; + double xtalk; /**=0 && isc<4) { - cmPed[isc]+=val; - nCm[isc]++; - } - - }; - virtual double getCommonMode(int ix=0, int iy=0) { - (void)iy; - int isc=ix/40; - if (isc>=0 && isc<4) { - if (nCm[isc]>0) return cmPed[isc]/nCm[isc]-cmStat[isc].Mean(); - } - return 0;}; + /** add value to common mode as a function of the pixel value, subdividing the region of interest in the 4 supercolumns of 40 columns each; + \param val value to add to the common mode + \param ix pixel coordinate in the x direction + \param iy pixel coordinate in the y direction + */ + virtual void addToCommonMode(double val, int ix=0, int iy=0) { + (void) iy; + commonModeSubtraction::addToCommonMode(val, ix/40); + }; + /**returns common mode value as a function of the pixel value, subdividing the region of interest in the 4 supercolumns of 40 columns each; + \param ix pixel coordinate in the x direction + \param iy pixel coordinate in the y direction + \returns common mode value + */ + virtual double getCommonMode(int ix=0, int iy=0) { + (void) iy; + return commonModeSubtraction::getCommonMode(ix/40); + }; }; diff --git a/slsDetectorCalibration/pedestalSubtraction.h b/slsDetectorCalibration/pedestalSubtraction.h index f80991ec0..29bc98628 100644 --- a/slsDetectorCalibration/pedestalSubtraction.h +++ b/slsDetectorCalibration/pedestalSubtraction.h @@ -4,21 +4,45 @@ #include "MovingStat.h" class pedestalSubtraction { - + /** @short class defining the pedestal subtraction based on an approximated moving average */ public: + /** constructor + \param nn number of samples to calculate the moving average (defaults to 1000) + */ pedestalSubtraction (int nn=1000) : stat(nn) {}; + + /** virtual destructorr + */ virtual ~pedestalSubtraction() {}; + /** clears the moving average */ virtual void Clear() {stat.Clear();} + + /** adds the element to the moving average + \param val value to be added + */ virtual void addToPedestal(double val){ stat.Calc(val);}; + + /** returns the average value of the pedestal + \returns mean of the moving average + */ virtual double getPedestal(){return stat.Mean();}; + + /** returns the standard deviation of the moving average + \returns standard deviation of the moving average + */ virtual double getPedestalRMS(){return stat.StandardDeviation();}; + + /**sets/gets the number of samples for the moving average + \param i number of elements for the moving average. If -1 (default) or negative, gets. + \returns actual number of samples for the moving average + */ virtual int SetNPedestals(int i=-1) {if (i>0) stat.SetN(i); return stat.GetN();}; private: - MovingStat stat; + MovingStat stat; /**< approximated moving average struct */ }; #endif diff --git a/slsDetectorCalibration/singlePhotonDetector.h b/slsDetectorCalibration/singlePhotonDetector.h index 886896971..78c6e1ea2 100644 --- a/slsDetectorCalibration/singlePhotonDetector.h +++ b/slsDetectorCalibration/singlePhotonDetector.h @@ -2,7 +2,6 @@ #define SINGLEPHOTONDETECTOR_H -#include #include "slsDetectorData.h" #include "single_photon_hit.h" @@ -37,6 +36,7 @@ using namespace std; template class singlePhotonDetector { + /** @short class to perform pedestal subtraction etc. and find single photon clusters for an analog detector */ public: @@ -44,11 +44,12 @@ class singlePhotonDetector { /** Constructor (no error checking if datasize and offsets are compatible!) - \param npx number of pixels in the x direction - \param npy number of pixels in the y direction - \param ds size of the dataset - \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) - \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) + \param s detector data structure to be used + \param csize cluster size (should be an odd number). Defaults to 3 + \param nsigma number of rms to discriminate from the noise. Defaults to 5 + \param cm common mode subtraction algorithm, if any. Defaults to NULL i.e. none + \param nped number of samples for pedestal averaging + \param nd number of dark frames to average as pedestals without photon discrimination at the beginning of the measurement */ @@ -63,7 +64,6 @@ class singlePhotonDetector { int nd=100) : det(d), nx(0), ny(0), stat(NULL), cmSub(cm), nDark(nd), eventMask(NULL),nSigma (nsigma), clusterSize(csize), clusterSizeY(csize), cluster(NULL), iframe(-1), dataSign(sign) { - det->getDetectorSize(nx,ny); @@ -80,39 +80,80 @@ class singlePhotonDetector { clusterSizeY=1; cluster=new single_photon_hit(clusterSize,clusterSizeY); + setClusterSize(csize); }; - + /** + destructor. Deletes the cluster structure and the pdestalSubtraction array + */ virtual ~singlePhotonDetector() {delete cluster; for (int i=0; iClear(); }; + + /** resets the eventMask to undefined and the commonModeSubtraction */ void newFrame(){iframe++; for (int iy=0; iynewFrame();}; + /** sets the commonModeSubtraction algorithm to be used + \param cm commonModeSubtraction algorithm to be used (NULL unsets) + \returns pointer to the actual common mode subtraction algorithm + */ commonModeSubtraction setCommonModeSubtraction(commonModeSubtraction *cm) {cmSub=cm; return cmSub;}; + + /** + sets the sign of the data + \param sign 1 means positive values for photons, -1 negative, 0 gets + \returns current sign for the data + */ int setDataSign(int sign=0) {if (sign==1 || sign==-1) dataSign=sign; return dataSign;}; + + /** + adds value to pedestal (and common mode) for the given pixel + \param val value to be added + \param ix pixel x coordinate + \param iy pixel y coordinate + */ virtual void addToPedestal(double val, int ix, int iy){ if (ix>=0 && ix=0 && iyisGood(ix, iy) ) cmSub->addToCommonMode(val, ix, iy);}}; - + /** + gets pedestal (and common mode) + \param ix pixel x coordinate + \param iy pixel y coordinate + \param cm 0 (default) without common mode subtraction, 1 with common mode subtraction (if defined) + */ virtual double getPedestal(int ix, int iy, int cm=0){if (ix>=0 && ix=0 && iy0) return stat[iy][ix].getPedestal()-cmSub->getCommonMode(); else return stat[iy][ix].getPedestal(); else return -1;}; - + /** + gets pedestal rms (i.e. noise) + \param ix pixel x coordinate + \param iy pixel y coordinate + */ double getPedestalRMS(int ix, int iy){if (ix>=0 && ix=0 && iy0) nSigma=n; return nSigma;} - + + /** sets/gets cluster size + \param n cluster size to be set, (0 or negative gets). If even is incremented by 1. + \returns actual cluster size + */ int setClusterSize(int n=-1){ if (n>0 && n!=clusterSize) { if (n%2==0) n+=1; clusterSize=n; - delete cluster; + if (cluster) + delete cluster; if (ny>1) clusterSizeY=clusterSize; - cluster=new single_photon_hit(clusterSize,clusterSizeY); } return clusterSize; @@ -120,6 +161,17 @@ class singlePhotonDetector { + + /** finds event type for pixel and fills cluster structure. The algorithm loops only if the evenMask for this pixel is still undefined. + if pixel or cluster around it are above threshold (nsigma*pedestalRMS) cluster is filled and pixel mask is PHOTON_MAX (if maximum in cluster) or NEIGHBOUR; If PHOTON_MAX, the elements of the cluster are also set as NEIGHBOURs in order to speed up the looping + if below threshold the pixel is either marked as PEDESTAL (and added to the pedestal calculator) or NEGATIVE_PEDESTAL is case it's lower than -threshold, otherwise the pedestal average would drift to negative values while it should be 0. + + /param data pointer to the data + /param ix pixel x coordinate + /param iy pixel y coordinate + /param cm enable(1)/disable(0) common mode subtraction (if defined). + /returns event type for the given pixel + */ eventType getEventType(char *data, int ix, int iy, int cm=0) { // eventType ret=PEDESTAL; @@ -194,13 +246,32 @@ class singlePhotonDetector { - + /** sets/gets number of samples for moving average pedestal calculation + \param i number of samples to be set (0 or negative gets) + \returns actual number of samples + */ int SetNPedestals(int i=-1) {int ix=0, iy=0; if (i>0) for (ix=0; ixget_data(ic,ir);}; - eventType getEventMask(int ic, int ir){return eventMask[ir][ic];}; + /** returns value for cluster element in relative coordinates + \param ic x coordinate (center is (0,0)) + \param ir y coordinate (center is (0,0)) + \returns cluster element + */ + double getClusterElement(int ic, int ir=0){return cluster->get_data(ic,ir);}; + + /** returns event mask for the given pixel + \param ic x coordinate (center is (0,0)) + \param ir y coordinate (center is (0,0)) + \returns event mask enum for the given pixel + */ + eventType getEventMask(int ic, int ir=0){return eventMask[ir][ic];}; -#ifdef MYROOT1 +#ifdef MYROOT1 + /** generates a tree and maps the branches + \param tname name for the tree + \param iframe pointer to the frame number + \returns returns pointer to the TTree + */ TTree *initEventTree(char *tname, int *iFrame=NULL) { TTree* tall=new TTree(tname,tname); @@ -223,22 +294,22 @@ class singlePhotonDetector { private: - slsDetectorData *det; - int nx, ny; + slsDetectorData *det; /**< slsDetectorData to be used */ + int nx; /**< Size of the detector in x direction */ + int ny; /**< Size of the detector in y direction */ - pedestalSubtraction **stat; - commonModeSubtraction *cmSub; - //MovingStat **stat; - int nDark; - eventType **eventMask; - double nSigma; - int clusterSize, clusterSizeY; - single_photon_hit *cluster; - int iframe; - int dataSign; - - /* int cx, cy; */ + pedestalSubtraction **stat; /**< pedestalSubtraction class */ + commonModeSubtraction *cmSub;/**< commonModeSubtraction class */ + int nDark; /**< number of frames to be used at the beginning of the dataset to calculate pedestal without applying photon discrimination */ + eventType **eventMask; /**< matrix of event type or each pixel */ + double nSigma; /**< number of sigma parameter for photon discrimination */ + int clusterSize; /**< cluster size in the x direction */ + int clusterSizeY; /**< cluster size in the y direction i.e. 1 for strips, clusterSize for pixels */ + single_photon_hit *cluster; /**< single photon hit data structure */ + int iframe; /**< frame number (not from file but incremented within the dataset every time newFrame is called */ + int dataSign; /**< sign of the data i.e. 1 if photon is positive, -1 if negative */ + }; diff --git a/slsDetectorCalibration/single_photon_hit.h b/slsDetectorCalibration/single_photon_hit.h index 278c9f691..dda4d7571 100644 --- a/slsDetectorCalibration/single_photon_hit.h +++ b/slsDetectorCalibration/single_photon_hit.h @@ -5,38 +5,56 @@ typedef double double32_t; typedef float float32_t; typedef int int32_t; -/* /\** */ -/* @short structure for a single photon hit */ -/* *\/ */ -/* typedef struct{ */ -/* double* data; /\**< data size *\/ */ -/* int x; /\**< x-coordinate of the center of hit *\/ */ -/* int y; /\**< x-coordinate of the center of hit *\/ */ -/* double rms; /\**< noise of central pixel *\/ */ -/* double ped; /\**< pedestal of the central pixel *\/ */ -/* int iframe; /\**< frame number *\/ */ -/* }single_photon_hit; */ - class single_photon_hit { - public: - single_photon_hit(int nx, int ny=1): dx(nx), dy(ny) {data=new double[dx*dy];}; - ~single_photon_hit(){delete [] data;}; - void write(FILE *myFile) {fwrite((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fwrite((void*)data, 1, dx*dy*sizeof(double), myFile);}; - void read(FILE *myFile) {fread((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fread((void*)data, 1, dx*dy*sizeof(double), myFile);}; - void set_data(double v, int ix, int iy=0){data[(iy+dy/2)*dx+ix+dx/2]=v;}; - double get_data(int ix, int iy=0){return data[(iy+dy/2)*dx+ix+dx/2];}; + /** @short Structure for a single photon hit */ + public: + /** constructor, instantiates the data array -- all class elements are public! + \param nx cluster size in x direction + \param ny cluster size in y direction (defaults to 1 for 1D detectors) + */ + single_photon_hit(int nx, int ny=1): dx(nx), dy(ny) {data=new double[dx*dy];}; + + ~single_photon_hit(){delete [] data;}; /**< destructor, deletes the data array */ + + /** binary write to file of all elements of the structure, except size of the cluster + \param myFile file descriptor + */ + void write(FILE *myFile) {fwrite((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fwrite((void*)data, 1, dx*dy*sizeof(double), myFile);}; - int x; /**< x-coordinate of the center of hit */ - int y; /**< x-coordinate of the center of hit */ - double rms; /**< noise of central pixel */ - double ped; /**< pedestal of the central pixel */ - int iframe; /**< frame number */ - double *data; /**< data size */ - const int dx; - const int dy; + /** + binary read from file of all elements of the structure, except size of the cluster. The structure is then filled with those args + \param myFile file descriptor + */ + void read(FILE *myFile) {fread((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fread((void*)data, 1, dx*dy*sizeof(double), myFile);}; + + /** + assign the value to the element of the cluster matrix, with relative coordinates where the center of the cluster is (0,0) + \param v value to be set + \param ix coordinate x within the cluster (center is (0,0)) + \param iy coordinate y within the cluster (center is (0,0)) + */ + void set_data(double v, int ix, int iy=0){data[(iy+dy/2)*dx+ix+dx/2]=v;}; + + + /** + gets the value to the element of the cluster matrix, with relative coordinates where the center of the cluster is (0,0) + \param ix coordinate x within the cluster (center is (0,0)) + \param iy coordinate y within the cluster (center is (0,0)) + \returns value of the cluster element + */ + double get_data(int ix, int iy=0){return data[(iy+dy/2)*dx+ix+dx/2];}; + + int x; /**< x-coordinate of the center of hit */ + int y; /**< x-coordinate of the center of hit */ + double rms; /**< noise of central pixel l -- at some point it can be removed*/ + double ped; /**< pedestal of the central pixel -- at some point it can be removed*/ + int iframe; /**< frame number */ + double *data; /**< pointer to data */ + const int dx; /**< size of data cluster in x */ + const int dy; /**< size of data cluster in y */ }; diff --git a/slsDetectorCalibration/slsDetectorData.h b/slsDetectorCalibration/slsDetectorData.h index 59bd872f0..c28e447aa 100644 --- a/slsDetectorCalibration/slsDetectorData.h +++ b/slsDetectorCalibration/slsDetectorData.h @@ -1,6 +1,7 @@ #ifndef SLSDETECTORDATA_H #define SLSDETECTORDATA_H +#include #include #include @@ -15,16 +16,19 @@ class slsDetectorData { /** - Constructor (no error checking if datasize and offsets are compatible!) - \param npx number of pixels in the x direction - \param npy number of pixels in the y direction - \param ds size of the dataset - \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) - \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) + General slsDetectors data structure. Works for data acquired using the slsDetectorReceiver. Can be generalized to other detectors (many virtual funcs). + + Constructor (no error checking if datasize and offsets are compatible!) + \param npx number of pixels in the x direction + \param npy number of pixels in the y direction (1 for strips) + \param dsize size of the data + \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) + \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) + \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. */ - slsDetectorData(int npx, int npy, int np, int psize, int **dMap=NULL, dataType **dMask=NULL, int **dROI=NULL): nx(npx), ny(npy), nPackets(np), packetSize(psize) { + slsDetectorData(int npx, int npy, int dsize, int **dMap=NULL, dataType **dMask=NULL, int **dROI=NULL): nx(npx), ny(npy), dataSize(dsize) { @@ -59,13 +63,20 @@ class slsDetectorData { delete [] dataROIMask; } + /** + defines the data map (as offset) - no error checking if datasize and offsets are compatible! + \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset). If NULL (default),the data are arranged as if read out row by row (dataMap[iy][ix]=(iy*nx+ix)*sizeof(dataType);) + + */ + + void setDataMap(int **dMap=NULL) { if (dMap==NULL) { for (int iy=0; iy=0 && ix=0 && iy=0 && ix=0 && iy=0 && ix=0 && iy=0 && dataMap[iy][ix]=0 && ix=0 && iy=0 && dataMap[iy][ix]>8;}; - virtual int getPacketNumber(char *buff) {return (*(int*)buff)&0xff;}; + Returns the frame number for the given dataset. Purely virtual func. + \param buff pointer to the dataset + \returns frame number + + */ - virtual char *findNextFrame(char *data, int &npackets, int dsize) { - char *retval=NULL, *p=data; - int dd=0; - int fn, fnum=-1, np=0, pnum=-1; - while (dd<=(dsize-packetSize)) { - pnum=getPacketNumber(p); - fn=getFrameNumber(p); - if (pnum<0 || pnum>=nPackets) { - cout << "Bad packet number " << pnum << " frame "<< fn << endl; - retval=NULL; - continue; - } - if (pnum==1) { - fnum=fn; - retval=p; - if (np>0) - cout << "*Incomplete frame number " << fnum << endl; - np=0; - } else if (fn!=fnum) { - if (fnum!=-1) { - cout << " **Incomplete frame number " << fnum << " pnum " << pnum << " " << getFrameNumber(p) << endl; - retval=NULL; - } - np=0; - } - p+=packetSize; - dd+=packetSize; - np++; - if (np==nPackets) - if (pnum==nPackets) - break; - else { - cout << "Too many packets for this frame! "<< fnum << " " << pnum << endl; - retval=NULL; - } - } - if (np<40) { - if (np>0) - cout << "Too few packets for this frame! "<< fnum << " " << pnum << endl; - } - - npackets=np; - - return retval; - }; + virtual int getFrameNumber(char *buff)=0; + + /** + + Returns the packet number for the given dataset. purely virtual func + \param buff pointer to the dataset + \returns packet number number + + */ + + virtual int getPacketNumber(char *buff)=0; - virtual char *readNextFrame(ifstream &filebin) { - + /** -/* if (oldbuff) */ -/* delete [] oldbuff; */ + Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). purely virtual func + \param data pointer to the memory to be analyzed + \param ndata reference to the amount of data found for the frame, in case the frame is incomplete at the end of the memory slot + \param dsize size of the memory slot to be analyzed + \returns pointer to the beginning of the last good frame (might be incomplete if ndata smaller than dataSize), or NULL if no frame is found -/* oldbuff=buff; */ - - // char *p=new char[1286]; - char *data=new char[packetSize*nPackets]; - char *retval=0; - int np=40; - - if (filebin.is_open()) { - while (filebin.read(data+np*packetSize,packetSize)) { - - if (np==nPackets) { - - retval=findNextFrame(data,np,packetSize*nPackets); - if (retval==data && np==nPackets) - return data; - else if (np>nPackets) { - cout << "too many packets!!!!!!!!!!" << endl; - delete [] data; - return NULL; - } else { - for (int ip=0; ipnPackets) { - cout << "*******too many packets!!!!!!!!!!" << endl; - delete [] data; - return NULL; - } else { - // memcpy(data+np*1286,p,1286); - np++; - } - - } - } - delete [] data; - return NULL; - }; + */ + virtual char *findNextFrame(char *data, int &ndata, int dsize)=0; + /** - private: + Loops over a file stream until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! + \param filebin input file stream (binary) + \returns pointer to the begin of the last good frame, NULL if no frame is found or last frame is incomplete + + */ + virtual char *readNextFrame(ifstream &filebin)=0; + + + protected: const int nx; /**< Number of pixels in the x direction */ const int ny; /**< Number of pixels in the y direction */ - const int nPackets; /** +class slsReceiverData : public slsDetectorData { + + + public: + + /** + + + slsReceiver data structure. Works for data acquired using the slsDetectorReceiver subdivided in different packets with headers and footers. + Inherits and implements slsDetectorData. + + Constructor (no error checking if datasize and offsets are compatible!) + \param npx number of pixels in the x direction + \param npy number of pixels in the y direction (1 for strips) + \param np number of packets + \param psize packets size + \param dMap array of size nx*ny storing the pointers to the data in the dataset (as offset) + \param dMask Array of size nx*ny storing the polarity of the data in the dataset (should be 0 if no inversion is required, 0xffffffff is inversion is required) + \param dROI Array of size nx*ny. The elements are 1s if the channel is good or in the ROI, 0 is bad or out of the ROI. NULL (default) means all 1s. + + */ + slsReceiverData(int npx, int npy, int np, int psize, int **dMap=NULL, dataType **dMask=NULL, int **dROI=NULL): slsDetectorData(npx, npy, np*psize, dMap, dMask, dROI), nPackets(np), packetSize(psize) {}; + + + + /** + + Returns the frame number for the given dataset. Virtual func: works for slsDetectorReceiver data (also for each packet), but can be overloaded. + \param buff pointer to the dataset + \returns frame number + + */ + + virtual int getFrameNumber(char *buff){return ((*(int*)buff)&(0xffffff00))>>8;}; + + /** + + Returns the packet number for the given dataset. Virtual func: works for slsDetectorReceiver packets, but can be overloaded. + \param buff pointer to the dataset + \returns packet number number + + */ + + virtual int getPacketNumber(char *buff) {return (*(int*)buff)&0xff;}; + + + + + /** + + Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! + \param data pointer to the memory to be analyzed + \param ndata + \param dsize size of the memory slot to be analyzed + \returns pointer to the first packet of the last good frame (might be incomplete if npackets lower than the number of packets), or NULL if no frame is found + + */ + + virtual char *findNextFrame(char *data, int &npackets, int dsize) { + char *retval=NULL, *p=data; + int dd=0; + int fn, fnum=-1, np=0, pnum=-1; + while (dd<=(dsize-packetSize)) { + pnum=getPacketNumber(p); + fn=getFrameNumber(p); + if (pnum<0 || pnum>=nPackets) { + cout << "Bad packet number " << pnum << " frame "<< fn << endl; + retval=NULL; + continue; + } + if (pnum==1) { + fnum=fn; + retval=p; + if (np>0) + cout << "*Incomplete frame number " << fnum << endl; + np=0; + } else if (fn!=fnum) { + if (fnum!=-1) { + cout << " **Incomplete frame number " << fnum << " pnum " << pnum << " " << getFrameNumber(p) << endl; + retval=NULL; + } + np=0; + } + p+=packetSize; + dd+=packetSize; + np++; + if (np==nPackets) + if (pnum==nPackets) + break; + else { + cout << "Too many packets for this frame! "<< fnum << " " << pnum << endl; + retval=NULL; + } + } + if (np<40) { + if (np>0) + cout << "Too few packets for this frame! "<< fnum << " " << pnum << endl; + } + + npackets=np*packetSize; + + return retval; + }; + + /** + + Loops over a file stream until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! + \param filebin input file stream (binary) + \returns pointer to the first packet of the last good frame, NULL if no frame is found or last frame is incomplete + + */ + + virtual char *readNextFrame(ifstream &filebin) { + char *data=new char[packetSize*nPackets]; + char *retval=0; + int np=0, nd; + + if (filebin.is_open()) { + while (filebin.read(data+np*packetSize,packetSize)) { + + if (np==(nPackets-1)) { + + retval=findNextFrame(data,nd,packetSize*nPackets); + np=nd/packetSize; + + if (retval==data && np==nPackets) + return data; + else if (np>nPackets) { + cout << "too many packets!!!!!!!!!!" << endl; + delete [] data; + return NULL; + } else { + for (int ip=0; ipnPackets) { + cout << "*******too many packets!!!!!!!!!!" << endl; + delete [] data; + return NULL; + } else { + np++; + } + } + } + delete [] data; + return NULL; + }; + + + + private: + const int nPackets; /**