// SPDX-License-Identifier: LGPL-3.0-or-other // Copyright (C) 2021 Contributors to the SLS Detector Package #ifndef SLSDETECTORDATA_H #define SLSDETECTORDATA_H #include #include template class slsDetectorData { protected: const int nx; /**< Number of pixels in the x direction */ const int ny; /**< Number of pixels in the y direction */ int dataSize; /**= 0 && ix < nx && iy >= 0 && iy < ny) dataROIMask[iy][ix] = i; return isGood(ix, iy); }; /** Define bad channel or roi mask for a single channel \param ix channel x coordinate \param iy channel y coordinate (1 for strips) \returns 1 if pixel is good, 0 if it's bad, -1 if pixel is out of range */ int isGood(int ix, int iy) { if (ix >= 0 && ix < nx && iy >= 0 && iy < ny) return dataROIMask[iy][ix]; else return -1; }; /** Returns detector size in x,y \param npx reference to number of channels in x \param npy reference to number of channels in y (will be 1 for strips) \returns total number of channels */ int getDetectorSize(int &npx, int &npy) { npx = nx; npy = ny; return nx * ny; }; /** Returns the size of the data frame */ int getDataSize() { return dataSize; }; /** changes the size of the data frame */ int setDataSize(int d) { dataSize = d; return dataSize; }; virtual void getPixel(int ip, int &x, int &y) { x = xmap[ip]; y = ymap[ip]; }; virtual dataType **getData(char *ptr, int dsize = -1) { int el = dsize / sizeof(dataType); // dataType **data; int ix, iy; // data=new dataType*[ny]; // for(int i = 0; i < ny; i++) { // data[i]=new dataType[nx]; // } isOrdered = 0; if (dsize <= 0 || dsize > dataSize) dsize = dataSize; for (int ip = 0; ip < (el); ip++) { getPixel(ip, ix, iy); if (ix >= 0 && ix < nx && iy >= 0 && iy < ny) { // data[iy][ix]=getChannel(ptr,ix,iy); orderedData[iy][ix] = *(ptr + ip); // getChannel(ptr,ix,iy); } } isOrdered = 1; return orderedData; } void newFrame() { isOrdered = 0; }; virtual double **getImage(char *ptr, int dsize = -1) { double **data; int ix, iy; data = new double *[ny]; for (int i = 0; i < ny; i++) { data[i] = new double[nx]; } int el = dsize / sizeof(dataType); if (dsize <= 0 || dsize > dataSize) dsize = dataSize; for (int ip = 0; ip < el; ip++) { getPixel(ip, ix, iy); if (ix >= 0 && ix < nx && iy >= 0 && iy < ny) { data[iy][ix] = getValue(ptr, ix, iy); } } return data; }; /** Returns the value of the selected channel for the given dataset. Virtual function, can be overloaded. \param data pointer to the dataset (including headers etc) \param ix pixel number in the x direction \param iy pixel number in the y direction \returns data for the selected channel, with inversion if required */ virtual dataType getChannel(char *data, int ix, int iy = 0) { dataType m = 0, d = 0; if (ix >= 0 && ix < nx && iy >= 0 && iy < ny && dataMap[iy][ix] >= 0 && dataMap[iy][ix] < dataSize) { // cout << ix << " " << iy << " " ; // cout << dataMap[ix][iy] << " " << (void*)data << " " << // dataSize<< endl; m = dataMask[iy][ix]; if (isOrdered == 0) d = *((dataType *)(data + getPointer(ix, iy))); else d = orderedData[iy][ix]; } return d ^ m; }; virtual int getGain(char *data, int ix, int iy = 0) { return 0; }; /** Returns the value of the selected channel for the given dataset. Virtual function, can be overloaded. \param data pointer to the dataset (including headers etc) \param ix pixel number in the x direction \param iy pixel number in the y direction \returns data for the selected channel, with inversion if required or -1 if its a missing packet */ virtual int getChannelwithMissingPackets(char *data, int ix, int iy) { return 0; }; /** Returns the value of the selected channel for the given dataset as double. \param data pointer to the dataset (including headers etc) \param ix pixel number in the x direction \param iy pixel number in the y direction \returns data for the selected channel, with inversion if required as double */ virtual double getValue(char *data, int ix, int iy = 0) { /* cout << " x "<< ix << " y"<< iy << " val " << getChannel(data, ix, * iy)<< endl;*/ return (double)getChannel(data, ix, iy); }; /** Returns the frame number for the given dataset. Purely virtual func. \param buff pointer to the dataset \returns frame number */ 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; */ /** 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 */ virtual char *findNextFrame(char *data, int &ndata, int dsize) = 0; /** 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(std::ifstream &filebin) = 0; }; #endif