diff --git a/RELEASE.txt b/RELEASE.txt index 96a6a645d..d94a1897f 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -39,7 +39,7 @@ This document describes the differences between v7.x.x and v7.0.0 Eiger 7.0.0 - Jungfrau 7.0.0 + Jungfrau 7.0.2 Mythen3 7.0.0 Gotthard2 7.0.0 Gotthard 7.0.0 diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 803faee77..4c9920916 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -1441,6 +1441,10 @@ class Detector(CppDetectorApi): @udp_srcip.setter def udp_srcip(self, ip): + if ip == "auto": + if self.type == detectorType.GOTTHARD: + raise NotImplementedError('Auto for udp_srcip cannot be used for GotthardI') + ip = socket.gethostbyname(self.hostname[0]) ip = ut.make_ip(ip) ut.set_using_dict(self.setSourceUDPIP, ip) @@ -1467,6 +1471,8 @@ class Detector(CppDetectorApi): @udp_srcip2.setter def udp_srcip2(self, ip): + if ip == "auto": + ip = socket.gethostbyname(self.hostname) ip = ut.make_ip(ip) ut.set_using_dict(self.setSourceUDPIP2, ip) diff --git a/serverBin/ctbDetectorServerv7.0.0 b/serverBin/ctbDetectorServerv7.0.0 deleted file mode 120000 index bc7dc05d2..000000000 --- a/serverBin/ctbDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/eigerDetectorServerv7.0.0 b/serverBin/eigerDetectorServerv7.0.0 deleted file mode 120000 index 06272c8f6..000000000 --- a/serverBin/eigerDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/gotthard2DetectorServerv7.0.0 b/serverBin/gotthard2DetectorServerv7.0.0 deleted file mode 120000 index 6e601d619..000000000 --- a/serverBin/gotthard2DetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/gotthardDetectorServerv7.0.0 b/serverBin/gotthardDetectorServerv7.0.0 deleted file mode 120000 index d8d2d651e..000000000 --- a/serverBin/gotthardDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/jungfrauDetectorServerv7.0.0 b/serverBin/jungfrauDetectorServerv7.0.0 deleted file mode 120000 index c91c000b3..000000000 --- a/serverBin/jungfrauDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/moenchDetectorServerv7.0.0 b/serverBin/moenchDetectorServerv7.0.0 deleted file mode 120000 index ea12c878c..000000000 --- a/serverBin/moenchDetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv7.0.0 \ No newline at end of file diff --git a/serverBin/mythen3DetectorServerv7.0.0 b/serverBin/mythen3DetectorServerv7.0.0 deleted file mode 120000 index f5fe23393..000000000 --- a/serverBin/mythen3DetectorServerv7.0.0 +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv7.0.0 \ No newline at end of file diff --git a/slsDetectorCalibration/analogDetector.h b/slsDetectorCalibration/analogDetector.h index ce8affbdf..0bd28a73e 100644 --- a/slsDetectorCalibration/analogDetector.h +++ b/slsDetectorCalibration/analogDetector.h @@ -78,7 +78,7 @@ template class analogDetector { stat[i] = new pedestalSubtraction[nx]; /* pedMean[i]=new double[nx]; */ /* pedVariance[i]=new double[nx]; */ - for (ix = 0; ix < nx; ++ix) { + for (int ix = 0; ix < nx; ++ix) { stat[i][ix].SetNPedestals(nped); /* stat[i][ix].setPointers(&(pedMean[iy][ix]),&(pedVariance[iy][ix])); */ @@ -166,8 +166,8 @@ template class analogDetector { int nped = orig->SetNPedestals(); // cout << nped << " " << orig->getPedestal(ix,iy) << // orig->getPedestalRMS(ix,iy) << endl; - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { // stat[iy][ix].setPointers(&(pedMean[iy][ix]),&(pedVariance[iy][ix])); stat[iy][ix].SetNPedestals(nped); setPedestal(ix, iy, orig->getPedestal(ix, iy), @@ -298,8 +298,8 @@ template class analogDetector { if (gmap) delete[] gmap; gmap = new double[nnx * nny]; - for (iy = 0; iy < static_cast(nny); ++iy) { - for (ix = 0; ix < static_cast(nnx); ++ix) { + for (int iy = 0; iy < static_cast(nny); ++iy) { + for (int ix = 0; ix < static_cast(nnx); ++ix) { gmap[iy * nnx + ix] = gm[iy * nnx + ix]; // cout << gmap[iy*nnx+ix] << " " ; } @@ -319,8 +319,8 @@ template class analogDetector { void *ret; if (gmap) { gm = new float[nx * ny]; - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { gm[iy * nx + ix] = gmap[iy * nx + ix]; } } @@ -335,8 +335,8 @@ template class analogDetector { virtual void newDataSet() { iframe = -1; - for (iy = 0; iy < ny; ++iy) - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) + for (int ix = 0; ix < nx; ++ix) { stat[iy][ix].Clear(); image[iy * nx + ix] = 0; } @@ -445,8 +445,8 @@ template class analogDetector { // cout << "+"<< getId() << endl; if (cmSub) { // cout << "*" << endl; - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { // if (getNumpedestals(ix,iy)>0) // if (det->isGood(ix,iy)) { addToCommonMode(data, ix, iy); @@ -539,8 +539,8 @@ template class analogDetector { if (ped == NULL) { ped = new double[nx * ny]; } - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { ped[iy * nx + ix] = stat[iy][ix].getPedestal(); // cout << ped[iy*nx+ix] << " " ; } @@ -558,8 +558,8 @@ template class analogDetector { if (ped == NULL) { ped = new double[nx * ny]; } - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { ped[iy * nx + ix] = stat[iy][ix].getPedestalRMS(); } } @@ -592,8 +592,8 @@ template class analogDetector { */ virtual void setPedestal(double *ped, double *rms = NULL, int m = -1) { double rr = 0; - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { if (rms) rr = rms[iy * nx + ix]; stat[iy][ix].setPedestal(ped[iy * nx + ix], rr, m); @@ -619,8 +619,8 @@ template class analogDetector { \param rms pointer to array of pedestal rms */ virtual void setPedestalRMS(double *rms) { - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { stat[iy][ix].setPedestalRMS(rms[iy * nx + ix]); }; }; @@ -662,8 +662,8 @@ template class analogDetector { #endif gm = new float[nx * ny]; - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { gm[iy * nx + ix] = image[iy * nx + ix]; #ifdef ROOTSPECTRUM hmap->SetBinContent(ix + 1, iy + 1, image[iy * nx + ix]); @@ -710,8 +710,8 @@ template class analogDetector { new TH2F("hmap", "hmap", nx, -0.5, nx - 0.5, ny, -0.5, ny - 0.5); #endif - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { /* if (cmSub) */ /* gm[iy*nx+ix]=stat[iy][ix].getPedestal()-cmSub->getCommonMode(); */ @@ -758,8 +758,8 @@ template class analogDetector { nny = ny; if (gm) { - for (iy = 0; iy < nny; ++iy) { - for (ix = 0; ix < nnx; ++ix) { + for (int iy = 0; iy < nny; ++iy) { + for (int ix = 0; ix < nnx; ++ix) { stat[iy][ix].setPedestal(gm[iy * nx + ix], -1, -1); } } @@ -783,8 +783,8 @@ template class analogDetector { nny = ny; if (gm) { - for (iy = 0; iy < nny; ++iy) { - for (ix = 0; ix < nnx; ++ix) { + for (int iy = 0; iy < nny; ++iy) { + for (int ix = 0; ix < nnx; ++ix) { image[iy * nx + ix] = gm[iy * nx + ix]; } } @@ -808,8 +808,8 @@ template class analogDetector { float *gm = NULL; void *ret; gm = new float[nx * ny]; - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { gm[iy * nx + ix] = stat[iy][ix].getPedestalRMS(); } } @@ -832,8 +832,8 @@ template class analogDetector { if (nny > ny) nny = ny; if (gm) { - for (iy = 0; iy < nny; ++iy) { - for (ix = 0; ix < nnx; ++ix) { + for (uint32_t iy = 0; iy < nny; ++iy) { + for (uint32_t ix = 0; ix < nnx; ++ix) { stat[iy][ix].setPedestalRMS(gm[iy * nx + ix]); } } @@ -862,8 +862,8 @@ template class analogDetector { // cout << xmin << " " << xmax << endl; // cout << ymin << " " << ymax << endl; - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { if (det->isGood(ix, iy)) { // addToPedestal(data,ix,iy,1); addToPedestal(data, ix, iy, cm); @@ -997,14 +997,13 @@ template class analogDetector { virtual int *subtractPedestal(char *data, int *val = NULL, int cm = 0) { newFrame(data); - if (val == NULL) val = image; // new double[nx*ny]; // calcGhost(data); - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { if (det->isGood(ix, iy)) val[iy * nx + ix] += subtractPedestal(data, ix, iy, cm); } @@ -1152,8 +1151,6 @@ template class analogDetector { image is used \returns pointer to array containing the number of photons */ virtual int *getNPhotons(char *data, int *nph = NULL) { - - // double val; if (nph == NULL) nph = image; @@ -1169,8 +1166,8 @@ template class analogDetector { /* } */ // calcGhost(data); addToCommonMode(data); - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { switch (fMode) { case eRaw: // cout << "raw" << endl; @@ -1190,8 +1187,8 @@ template class analogDetector { */ virtual void clearImage() { - for (iy = 0; iy < ny; ++iy) { - for (ix = 0; ix < nx; ++ix) { + for (int iy = 0; iy < ny; ++iy) { + for (int ix = 0; ix < nx; ++ix) { image[iy * nx + ix] = 0; } } @@ -1219,10 +1216,9 @@ template class analogDetector { \returns actual number of samples */ int SetNPedestals(int i = -1) { - int ix = 0, iy = 0; if (i > 0) - for (iy = 0; iy < ny; ++iy) - for (ix = 0; ix < nx; ++ix) + for (int iy = 0; iy < ny; ++iy) + for (int ix = 0; ix < nx; ++ix) stat[iy][ix].SetNPedestals(i); return stat[0][0].SetNPedestals(); }; @@ -1264,8 +1260,8 @@ template class analogDetector { newFrame(data); // calcGhost(data); addToCommonMode(data); - for (iy = ymi; iy < yma; ++iy) - for (ix = xmi; ix < xma; ++ix) + for (int iy = ymi; iy < yma; ++iy) + for (int ix = xmi; ix < xma; ++ix) if (det->isGood(ix, iy)) { if (ix >= 0 && ix < nx && iy >= 0 && iy < ny) val += convertToPhotons(data, ix, iy); @@ -1379,7 +1375,6 @@ template class analogDetector { frameMode fMode; /**< current detector frame mode */ detectorMode dMode; /**< current detector frame mode */ FILE *myFile; /**< file pointer to write to */ - int ix, iy; #ifdef ROOTSPECTRUM TH2F *hs; #ifdef ROOTCLUST diff --git a/slsDetectorCalibration/dataStructures/jungfrauLGADStrixelsData_new.h b/slsDetectorCalibration/dataStructures/jungfrauLGADStrixelsData_new.h index 32c401f89..1ef8c11b9 100644 --- a/slsDetectorCalibration/dataStructures/jungfrauLGADStrixelsData_new.h +++ b/slsDetectorCalibration/dataStructures/jungfrauLGADStrixelsData_new.h @@ -406,9 +406,9 @@ class jungfrauLGADStrixelsData : public slsDetectorData { np = 0; //int pn; - // std::cout << dataSize << std::endl; - if (ff >= 0) - // fnum = ff; + //std::cout << dataSize << std::endl; + //if (ff >= 0) { + // fnum = ff; } if (filebin.is_open()) { if (filebin.read(data, dataSize)) { @@ -417,7 +417,10 @@ class jungfrauLGADStrixelsData : public slsDetectorData { np = getPacketNumber(data); return data; } - } + std::cout << "#"; + } else { + std::cout << "File not open" << std::endl; + } return NULL; }; diff --git a/slsDetectorCalibration/dataStructures/jungfrauModuleData.h b/slsDetectorCalibration/dataStructures/jungfrauModuleData.h index 4742d6fdd..98d084919 100644 --- a/slsDetectorCalibration/dataStructures/jungfrauModuleData.h +++ b/slsDetectorCalibration/dataStructures/jungfrauModuleData.h @@ -2,6 +2,7 @@ // Copyright (C) 2021 Contributors to the SLS Detector Package #ifndef JUNGFRAUMODULEDATA_H #define JUNGFRAUMODULEDATA_H +#include #include "slsDetectorData.h" //#define VERSION_V2 diff --git a/slsDetectorCalibration/interpolatingDetector.h b/slsDetectorCalibration/interpolatingDetector.h index 48d1508b2..81fdaf5c4 100644 --- a/slsDetectorCalibration/interpolatingDetector.h +++ b/slsDetectorCalibration/interpolatingDetector.h @@ -51,6 +51,7 @@ class interpolatingDetector : public singlePhotonDetector { // cout << "**"<< xmin << " " << xmax << " " << ymin << " " << ymax << // endl; fi = new pthread_mutex_t; + pthread_mutex_init(fi, NULL); }; interpolatingDetector(interpolatingDetector *orig) diff --git a/slsDetectorCalibration/jungfrauExecutables/CMakeLists.txt b/slsDetectorCalibration/jungfrauExecutables/CMakeLists.txt index 15e031b0b..08b32462a 100644 --- a/slsDetectorCalibration/jungfrauExecutables/CMakeLists.txt +++ b/slsDetectorCalibration/jungfrauExecutables/CMakeLists.txt @@ -14,7 +14,7 @@ target_compile_definitions(jungfrauRawDataProcess PRIVATE MODULE) list(APPEND JUNGFRAU_EXECUTABLES jungfrauRawDataProcess) # jungfrauRawDataProcessStrx -add_executable(jungfrauRawDataProcessStrx jungfrauRawDataProcess.cpp) +add_executable(jungfrauRawDataProcessStrx jungfrauRawDataProcess_filetxt.cpp) target_compile_definitions(jungfrauRawDataProcessStrx PRIVATE JFSTRX) list(APPEND JUNGFRAU_EXECUTABLES jungfrauRawDataProcessStrx) diff --git a/slsDetectorCalibration/jungfrauExecutables/Makefile.rawdataprocess b/slsDetectorCalibration/jungfrauExecutables/Makefile.rawdataprocess index bca4c0cbd..1dfdf0b57 100644 --- a/slsDetectorCalibration/jungfrauExecutables/Makefile.rawdataprocess +++ b/slsDetectorCalibration/jungfrauExecutables/Makefile.rawdataprocess @@ -3,9 +3,11 @@ #module add CBFlib/0.9.5 -INCDIR=-I. -I../ -I../interpolations -I../interpolations/etaVEL -I../dataStructures -I../../slsSupportLib/include/ -I../../slsReceiverSoftware/include/ -I../tiffio/include +INCDIR=-I. -I../ -I../interpolations -I../interpolations/etaVEL -I../dataStructures -I../../slsSupportLib/include/ -I../../slsReceiverSoftware/include/ -I../tiffio/include -I/afs/psi/project/sls_det_software/conda/envs/pyclang_fmt/include/ -LDFLAG= ../tiffio/src/tiffIO.cpp -L/usr/lib64/ -lpthread -lm -lstdc++ -pthread -lrt -ltiff -O3 -std=c++11 +LDFLAG= ../tiffio/src/tiffIO.cpp -L/afs/psi/project/sls_det_software/conda/envs/pyclang_fmt/lib/ -L/usr/lib64/ -lpthread -lm -lstdc++ -pthread -lrt -ltiff -O3 -std=c++11 -lfmt +#-L/afs/psi/project/sls_det_software/conda/envs/pyclang_fmt/lib/ +#THE ORDER OF LIBRARIES MATTERS! MAIN=jungfrauClusterFinder.cpp diff --git a/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess.cpp b/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess.cpp index c6ca0d5cb..8fd72c54b 100644 --- a/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess.cpp +++ b/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess.cpp @@ -41,12 +41,38 @@ #include #include + +std::string getRootString( const std::string& filepath ) { + size_t pos1 = filepath.find_last_of("/"); + size_t pos2 = filepath.find_last_of("."); + std::cout << "pos1 " << pos1 << " pos2 " << pos2 << " size " << filepath.length() << std::endl; + return filepath.substr( pos1+1, pos2-pos1-1 ); +} + +//Create file name string according to slsDetectorPackage format +// dir: directory +// fprefix: fileprefix (without extension) +// fsuffix: filesuffix (for output files, e.g. "ped") +// fext: file extension (e.g. "raw") +// mindex: module index ("d0" in standard) +// findex: file index for one acquisition ("f0") +// aindex: acquisition index (i.e. "run number") + +std::string createFileName( const std::string& dir, const std::string& fprefix="run", const std::string& fsuffix="", const std::string& fext="raw", int aindex=0, int mindex=0, int findex=0, int outfilecounter=-1 ) { + if (outfilecounter >= 0) + return fmt::format("{:s}/{:s}_d{:d}_f{:d}_{:d}_f{:05d}.{:s}", dir, fprefix, mindex, findex, aindex, outfilecounter, fext); + else if (fsuffix.length()!=0) + return fmt::format("{:s}/{:s}_{:s}.{:s}", dir, fprefix, fsuffix, fext); + else + return fmt::format("{:s}/{:s}_d{:d}_f{:d}_{:d}.{:s}", dir, fprefix, mindex, findex, aindex, fext); +} + int main(int argc, char *argv[]) { if (argc < 5) { std::cout << "Usage is " << argv[0] - << "indir outdir fname(with formatting, no extension) fextension " + << "indir outdir fprefix(excluding slsDetector standard suffixes and extension) fextension " "[runmin] [runmax] [pedfile (raw or tiff)] [threshold] " "[nframes] [xmin xmax ymin ymax] [gainmap]" << std::endl; @@ -75,11 +101,11 @@ int main(int argc, char *argv[]) { int ff, np; // cout << " data size is " << dsize; - ifstream filebin; - char *indir = argv[1]; - char *outdir = argv[2]; - char *fformat = argv[3]; - char *fext = argv[4]; + //ifstream filebin; + std::string indir(argv[1]); + std::string outdir(argv[2]); + std::string fprefix(argv[3]); + std::string fext(argv[4]); int runmin = 0; // cout << "argc is " << argc << endl; @@ -93,9 +119,9 @@ int main(int argc, char *argv[]) { runmax = atoi(argv[6]); } - char *pedfile = NULL; + std::string pedfilename{}; if (argc >= 8) { - pedfile = argv[7]; + pedfilename = argv[7]; } double thr = 0; double thr1 = 1; @@ -109,12 +135,7 @@ int main(int argc, char *argv[]) { if (argc >= 10) { nframes = atoi(argv[9]); } - - char ffname[10000]; - char fname[10000]; - char imgfname[10000]; - char cfname[10000]; - + // Define decoders... #if !defined JFSTRX && !defined JFSTRXOLD && !defined JFSTRXCHIP1 && \ !defined JFSTRXCHIP6 @@ -137,36 +158,38 @@ int main(int argc, char *argv[]) { uint16_t yymax = 0; #ifndef ALDO - using header = sls::defs::sls_receiver_header; - // check if there is a roi in the header - typedef struct { + { //THIS SCOPE IS IMPORTANT! (To ensure proper destruction of ifstream) + using header = sls::defs::sls_receiver_header; + // check if there is a roi in the header + typedef struct { uint16_t xmin; uint16_t xmax; uint16_t ymin; uint16_t ymax; - } receiverRoi_compact; - receiverRoi_compact croi; - sprintf(ffname, "%s/%s.%s", indir, fformat, fext); - sprintf(fname, (const char *)ffname, runmin); - std::cout << "Reading header of file " << fname << " to check for ROI " - << std::endl; - filebin.open((const char *)(fname), ios::in | ios::binary); - if (filebin.is_open()) { + } receiverRoi_compact; + receiverRoi_compact croi; + std::string fsuffix{}; + auto filename = createFileName( indir, fprefix, fsuffix, fext, runmin ); + std::cout << "Reading header of file " << filename << " to check for ROI " + << std::endl; + ifstream firstfile(filename, ios::in | ios::binary); + if (firstfile.is_open()) { header hbuffer; std::cout << "sizeof(header) = " << sizeof(header) << std::endl; - if (filebin.read((char *)&hbuffer, sizeof(header))) { - memcpy(&croi, &hbuffer.detHeader.detSpec1, 8); - std::cout << "Read ROI [" << croi.xmin << ", " << croi.xmax << ", " - << croi.ymin << ", " << croi.ymax << "]" << std::endl; - xxmin = croi.xmin; - xxmax = croi.xmax; - yymin = croi.ymin; - yymax = croi.ymax; + if (firstfile.read((char *)&hbuffer, sizeof(header))) { + memcpy(&croi, &hbuffer.detHeader.detSpec1, 8); + std::cout << "Read ROI [" << croi.xmin << ", " << croi.xmax << ", " + << croi.ymin << ", " << croi.ymax << "]" << std::endl; + xxmin = croi.xmin; + xxmax = croi.xmax; + yymin = croi.ymin; + yymax = croi.ymax; } else - std::cout << "reading error" << std::endl; - filebin.close(); - } else - std::cout << "Could not open " << fname << " for reading " << std::endl; + std::cout << "reading error" << std::endl; + firstfile.close(); + } else + std::cout << "Could not open " << filename << " for reading " << std::endl; + } //end of protective scope #endif jungfrauLGADStrixelsData *decoder = @@ -213,14 +236,13 @@ int main(int argc, char *argv[]) { std::time_t end_time; - FILE *of = NULL; std::cout << "input directory is " << indir << std::endl; std::cout << "output directory is " << outdir << std::endl; - std::cout << "input file is " << fformat << std::endl; + std::cout << "input file prefix is " << fprefix << std::endl; std::cout << "runmin is " << runmin << std::endl; std::cout << "runmax is " << runmax << std::endl; - if (pedfile) - std::cout << "pedestal file is " << pedfile << std::endl; + if (pedfilename.length()!=0) + std::cout << "pedestal file is " << pedfilename << std::endl; if (thr > 0) std::cout << "threshold is " << thr << std::endl; std::cout << "Nframes is " << nframes << std::endl; @@ -256,8 +278,6 @@ int main(int argc, char *argv[]) { char *buff; - // multiThreadedAnalogDetector *mt=new - // multiThreadedAnalogDetector(filter,nthreads,fifosize); multiThreadedCountingDetector *mt = new multiThreadedCountingDetector(filter, nthreads, fifosize); mt->setClusterSize(csize, csize); @@ -285,84 +305,75 @@ int main(int argc, char *argv[]) { int ifr = 0; - char froot[1000]; - double *ped = new double[nx * ny]; //, *ped1; + if (pedfilename.length()!=0) { - int pos, pos1; + std::string froot = getRootString(pedfilename); - if (pedfile) { + std::cout << "PEDESTAL " << std::endl; - if (string(pedfile).find(".dat") != std::string::npos) { - pos1 = string(pedfile).rfind("/"); - strcpy(froot, pedfile + pos1); - pos = string(froot).find(".dat"); - froot[pos] = '\0'; - } + if (pedfilename.find(".tif") == std::string::npos) { + std::string fname = pedfilename; + std::cout << fname << std::endl; + std::time(&end_time); + std::cout << "aaa " << std::ctime(&end_time) << std::endl; - std::cout << "PEDESTAL " << std::endl; - // sprintf(imgfname, "%s/pedestals.tiff", outdir); + mt->setFrameMode(ePedestal); - if (string(pedfile).find(".tif") == std::string::npos) { - sprintf(fname, "%s", pedfile); - std::cout << fname << std::endl; - std::time(&end_time); - std::cout << "aaa" << std::ctime(&end_time) << std::endl; + ifstream pedefile(fname, ios::in | ios::binary); + // //open file + if (pedefile.is_open()) { + std::cout << "bbbb " << std::ctime(&end_time) << std::endl; + + ff = -1; + while (decoder->readNextFrame(pedefile, ff, np, buff)) { + // if (np == 40) { + if ((ifr + 1) % 100 == 0) { + std::cout + << " ****" + << decoder->getValue(buff, 20, 20); // << std::endl; + } + mt->pushData(buff); + mt->nextThread(); + mt->popFree(buff); + ifr++; + if (ifr % 100 == 0) { + std::cout << " ****" << ifr << " " << ff << " " << np + << std::endl; + } // else + //std::cout << ifr << " " << ff << " " << np << std::endl; + if (ifr >= 1000) + break; + ff = -1; + } + pedefile.close(); + while (mt->isBusy()) { + ; + } - mt->setFrameMode(ePedestal); - // sprintf(fn,fformat,irun); - filebin.open((const char *)(fname), ios::in | ios::binary); - // //open file - if (filebin.is_open()) { - std::cout << "bbbb" << std::ctime(&end_time) << std::endl; + std::cout << "froot " << froot << std::endl; + auto imgfname = createFileName( outdir, froot, "ped", "tiff"); + mt->writePedestal(imgfname.c_str()); + imgfname = createFileName( outdir, froot, "rms", "tiff"); + mt->writePedestalRMS(imgfname.c_str()); - ff = -1; - while (decoder->readNextFrame(filebin, ff, np, buff)) { - // if (np == 40) { - if ((ifr + 1) % 100 == 0) { - std::cout - << " ****" - << decoder->getValue(buff, 20, 20); // << endl; - } - mt->pushData(buff); - mt->nextThread(); - mt->popFree(buff); - ifr++; - if (ifr % 100 == 0) { - std::cout << " ****" << ifr << " " << ff << " " << np - << std::endl; - } // else - // cout << ifr << " " << ff << " " << np << endl; - if (ifr >= 1000) - break; - ff = -1; - } - filebin.close(); - while (mt->isBusy()) { - ; - } - - sprintf(imgfname, "%s/%s_ped.tiff", outdir, froot); - mt->writePedestal(imgfname); - sprintf(imgfname, "%s/%s_rms.tiff", outdir, froot); - mt->writePedestalRMS(imgfname); - - } else - std::cout << "Could not open pedestal file " << fname - << " for reading " << std::endl; + } else + std::cout << "Could not open pedestal file " << fname + << " for reading " << std::endl; } else { - float *pp = ReadFromTiff(pedfile, nny, nnx); - if (pp && (int)nnx == nx && (int)nny == ny) { - for (int i = 0; i < nx * ny; i++) { - ped[i] = pp[i]; - } - delete[] pp; - mt->setPedestal(ped); - std::cout << "Pedestal set from tiff file " << pedfile - << std::endl; - } else { - std::cout << "Could not open pedestal tiff file " << pedfile - << " for reading " << std::endl; - } + std::vector ped(nx * ny); + float *pp = ReadFromTiff(pedfilename.c_str(), nny, nnx); + if (pp && (int)nnx == nx && (int)nny == ny) { + for (int i = 0; i < nx * ny; i++) { + ped[i] = pp[i]; + } + delete[] pp; + mt->setPedestal(ped.data()); + std::cout << "Pedestal set from tiff file " << pedfilename + << std::endl; + } else { + std::cout << "Could not open pedestal tiff file " << pedfilename + << " for reading " << std::endl; + } } std::time(&end_time); std::cout << std::ctime(&end_time) << std::endl; @@ -373,27 +384,26 @@ int main(int argc, char *argv[]) { mt->setFrameMode(eFrame); + FILE *of = NULL; + for (int irun = runmin; irun <= runmax; irun++) { std::cout << "DATA "; - // sprintf(fn,fformat,irun); - sprintf(ffname, "%s/%s.%s", indir, fformat, fext); - sprintf(fname, (const char *)ffname, irun); - sprintf(ffname, "%s/%s.tiff", outdir, fformat); - sprintf(imgfname, (const char *)ffname, irun); - sprintf(ffname, "%s/%s.clust", outdir, fformat); - sprintf(cfname, (const char *)ffname, irun); + std::string fsuffix{}; + auto fname = createFileName( indir, fprefix, fsuffix, fext, irun ); + auto imgfname = createFileName( outdir, fprefix, fsuffix, "tiff", irun ); + auto cfname = createFileName( outdir, fprefix, fsuffix, "clust", irun ); std::cout << fname << " "; std::cout << imgfname << std::endl; std::time(&end_time); std::cout << std::ctime(&end_time) << std::endl; - // cout << fname << " " << outfname << " " << imgfname << endl; - filebin.open((const char *)(fname), ios::in | ios::binary); + // std::cout << fname << " " << outfname << " " << imgfname << std::endl; + ifstream filebin(fname, ios::in | ios::binary); // //open file ifile = 0; if (filebin.is_open()) { if (thr <= 0 && cf != 0) { // cluster finder if (of == NULL) { - of = fopen(cfname, "w"); + of = fopen(cfname.c_str(), "w"); if (of) { mt->setFilePointer(of); std::cout << "file pointer set " << std::endl; @@ -414,7 +424,7 @@ int main(int argc, char *argv[]) { if ((ifr + 1) % 100 == 0) { std::cout << " ****" - << decoder->getValue(buff, 20, 20); // << endl; + << decoder->getValue(buff, 20, 20); // << std::endl; } mt->pushData(buff); // // //pop @@ -426,16 +436,14 @@ int main(int argc, char *argv[]) { std::cout << " " << ifr << " " << ff << std::endl; if (nframes > 0) { if (ifr % nframes == 0) { - sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat, - ifile); - sprintf(imgfname, (const char *)ffname, irun); - mt->writeImage(imgfname, thr1); + imgfname = createFileName( outdir, fprefix, fsuffix, "tiff", irun, 0, 0, ifile ); + mt->writeImage(imgfname.c_str(), thr1); mt->clearImage(); ifile++; } } // } else - // cout << ifr << " " << ff << " " << np << endl; + //std::cout << ifr << " " << ff << " " << np << std::endl; ff = -1; } std::cout << "--" << std::endl; @@ -444,16 +452,11 @@ int main(int argc, char *argv[]) { ; } if (nframes >= 0) { - if (nframes > 0) { - sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat, ifile); - sprintf(imgfname, (const char *)ffname, irun); - } else { - sprintf(ffname, "%s/%s.tiff", outdir, fformat); - sprintf(imgfname, (const char *)ffname, irun); - } + if (nframes > 0) + imgfname = createFileName( outdir, fprefix, fsuffix, "tiff", irun, 0, 0, ifile ); std::cout << "Writing tiff to " << imgfname << " " << thr1 << std::endl; - mt->writeImage(imgfname, thr1); + mt->writeImage(imgfname.c_str(), thr1); mt->clearImage(); if (of) { fclose(of); @@ -468,10 +471,9 @@ int main(int argc, char *argv[]) { << std::endl; } if (nframes < 0) { - sprintf(ffname, "%s/%s.tiff", outdir, fformat); - strcpy(imgfname, ffname); + auto imgfname = createFileName( outdir, fprefix, "sum", "tiff", -1, 0, 0, -1 ); std::cout << "Writing tiff to " << imgfname << " " << thr1 << std::endl; - mt->writeImage(imgfname, thr1); + mt->writeImage(imgfname.c_str(), thr1); } return 0; diff --git a/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess_argvunlimited.cpp b/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess_argvunlimited.cpp new file mode 100644 index 000000000..0d3e66d13 --- /dev/null +++ b/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess_argvunlimited.cpp @@ -0,0 +1,467 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package +// #include "sls/ansi.h" +#include +#undef CORR + +#define C_GHOST 0.0004 + +#define CM_ROWS 50 + +#define RAWDATA + +#if !defined JFSTRX && !defined JFSTRXOLD && !defined JFSTRXCHIP1 && \ + !defined JFSTRXCHIP6 +#ifndef MODULE +#include "jungfrauHighZSingleChipData.h" +#endif +#ifdef MODULE +#include "jungfrauModuleData.h" +#endif +#endif + +#ifdef JFSTRX +#include "jungfrauLGADStrixelsData_new.h" +#endif +#if defined JFSTRXCHIP1 || defined JFSTRXCHIP6 +#include "jungfrauLGADStrixelsDataSingleChip.h" +#endif +#ifdef JFSTRXOLD +#include "jungfrauStrixelsHalfModuleOldDesign.h" +#endif + +#include "multiThreadedCountingDetector.h" +#include "singlePhotonDetector.h" + +#include +#include +#include +#include + +#include +#include + +std::string getRootString( const std::string filepath ) { + size_t pos1; + if (filepath.find("/") == std::string::npos ) + pos1 = 0; + else + pos1 = filepath.find_last_of("/")+1; + size_t pos2 = filepath.find_last_of("."); + //std::cout << "pos1 " << pos1 << " pos2 " << pos2 << " size " << filepath.length() << std::endl; + return filepath.substr( pos1, pos2-pos1 ); +} + +//Create file name string +// dir: directory +// fprefix: fileprefix (without extension) +// fsuffix: filesuffix (for output files, e.g. "ped") +// fext: file extension (e.g. "raw") +std::string createFileName( const std::string dir, std::string fprefix="run", std::string fsuffix="", std::string fext="raw", int outfilecounter=-1 ) { + std::string filename{}; + if (outfilecounter >= 0) + filename = fmt::format("{:s}/{:s}_{:s}_f{:05d}.{:s}", dir, fprefix, fsuffix, outfilecounter, fext); + else if (fsuffix.length()!=0) + filename = fmt::format("{:s}/{:s}_{:s}.{:s}", dir, fprefix, fsuffix, fext); + else + filename = fmt::format("{:s}/{:s}.{:s}", dir, fprefix, fext); + return filename; +} + + +//NOTE THAT THE DATA FILES HAVE TO BE IN THE RIGHT ORDER SO THAT PEDESTAL TRACKING WORKS! +int main(int argc, char *argv[]) { + + if (argc < 10) { + std::cout + << "Usage is " << argv[0] + << "outdir [pedfile (raw or tiff)] [xmin xmax ymin ymax] " + "[threshold] [nframes] [full file path and names (with bash wildcards)] " + " NOTE THAT THE DATA FILES HAVE TO BE IN THE RIGHT ORDER SO THAT PEDESTAL TRACKING WORKS! " + << std::endl; + std::cout + << "threshold <0 means analog; threshold=0 means cluster finder; " + "threshold>0 means photon counting" + << std::endl; + std::cout + << "nframes <0 means sum everything; nframes=0 means one file per " + "run; nframes>0 means one file every nframes" + << std::endl; + return 1; + } + + int fifosize = 1000; + int nthreads = 10; + int csize = 3; // 3 + int nsigma = 5; + int nped = 10000; + + int cf = 0; + + double *gainmap = NULL; + // float *gm; + + int ff, np; + // cout << " data size is " << dsize; + + std::string outdir(argv[1]); + std::string pedfilename(argv[2]); + + int xmin = atoi(argv[3]); + int xmax = atoi(argv[4]); + int ymin = atoi(argv[5]); + int ymax = atoi(argv[6]); + + double thr = 0; + double thr1 = 1; + thr = atof(argv[7]); + + int nframes = 0; + nframes = atoi(argv[8]); + + // Define decoders... +#if !defined JFSTRX && !defined JFSTRXOLD && !defined JFSTRXCHIP1 && \ + !defined JFSTRXCHIP6 +#ifndef MODULE + jungfrauHighZSingleChipData *decoder = new jungfrauHighZSingleChipData(); + int nx = 256, ny = 256; +#endif +#ifdef MODULE + jungfrauModuleData *decoder = new jungfrauModuleData(); + int nx = 1024, ny = 512; +#endif +#endif + +#ifdef JFSTRX + cout << "Jungfrau strixel full module readout" << endl; + // ROI + uint16_t xxmin = 0; + uint16_t xxmax = 0; + uint16_t yymin = 0; + uint16_t yymax = 0; + +#ifndef ALDO + { //THIS SCOPE IS IMPORTANT! (To ensure proper destruction of ifstream) + using header = sls::defs::sls_receiver_header; + // check if there is a roi in the header + typedef struct { + uint16_t xmin; + uint16_t xmax; + uint16_t ymin; + uint16_t ymax; + } receiverRoi_compact; + receiverRoi_compact croi; + std::string filepath(argv[9]); //This is a problem if the input files have different ROIs! + std::cout << "Reading header of file " << filepath << " to check for ROI " + << std::endl; + ifstream firstfile(filepath, ios::in | ios::binary); + if (firstfile.is_open()) { + header hbuffer; + std::cout << "sizeof(header) = " << sizeof(header) << std::endl; + if (firstfile.read((char *)&hbuffer, sizeof(header))) { + memcpy(&croi, &hbuffer.detHeader.detSpec1, 8); + std::cout << "Read ROI [" << croi.xmin << ", " << croi.xmax << ", " + << croi.ymin << ", " << croi.ymax << "]" << std::endl; + xxmin = croi.xmin; + xxmax = croi.xmax; + yymin = croi.ymin; + yymax = croi.ymax; + } else + std::cout << "reading error" << std::endl; + firstfile.close(); + } else + std::cout << "Could not open " << filepath << " for reading " << std::endl; + } //end of protective scope +#endif + + jungfrauLGADStrixelsData *decoder = + new jungfrauLGADStrixelsData(xxmin, xxmax, yymin, yymax); + int nx = 1024 / 3, ny = 512 * 5; +#endif +#ifdef JFSTRXCHIP1 + std::cout << "Jungfrau strixel LGAD single chip 1" << std::endl; + jungfrauLGADStrixelsDataSingleChip *decoder = + new jungfrauLGADStrixelsDataSingleChip(1); + int nx = 256 / 3, ny = 256 * 5; +#endif +#ifdef JFSTRXCHIP6 + std::cout << "Jungfrau strixel LGAD single chip 6" << std::endl; + jungfrauLGADStrixelsDataSingleChip *decoder = + new jungfrauLGADStrixelsDataSingleChip(6); + int nx = 256 / 3, ny = 256 * 5; +#endif +#ifdef JFSTRXOLD + std::cout << "Jungfrau strixels old design" << std::endl; + jungfrauStrixelsHalfModuleOldDesign *decoder = + new jungfrauStrixelsHalfModuleOldDesign(); + int nx = 1024 * 3, ny = 512 / 3; +#endif + + decoder->getDetectorSize(nx, ny); + std::cout << "Detector size is " << nx << " " << ny << std::endl; + + + if ( xmin == xmax ) { + xmin = 0; + xmax = nx; + } + if ( ymin == ymax ) { + ymin = 0; + ymax = ny; + } + std::cout << xmin << " " << xmax << " " << ymin << " " << ymax << " " + << std::endl; + + /* + char *gainfname = NULL; + if (argc > 14) { + gainfname = argv[14]; + std::cout << "Gain map file name is: " << gainfname << std::endl; + } + */ + + std::time_t end_time; + + std::cout << "output directory is " << outdir << std::endl; + if (pedfilename.length()!=0) + std::cout << "pedestal file is " << pedfilename << std::endl; + if (thr > 0) + std::cout << "threshold is " << thr << std::endl; + std::cout << "Nframes is " << nframes << std::endl; + + uint32_t nnx, nny; + + singlePhotonDetector *filter = new singlePhotonDetector( + decoder, 3, nsigma, 1, NULL, nped, 200, -1, -1, gainmap, NULL); + + /* + if (gainfname) { + + if (filter->readGainMap(gainfname)) + std::cout << "using gain map " << gainfname << std::endl; + else + std::cout << "Could not open gain map " << gainfname << std::endl; + } else + */ + thr = 0.15 * thr; + filter->newDataSet(); + // int dsize = decoder->getDataSize(); + + if (thr > 0) { + std::cout << "threshold is " << thr << std::endl; + filter->setThreshold(thr); + cf = 0; + + } else + cf = 1; + + filter->setROI(xmin, xmax, ymin, ymax); + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + + char *buff; + + multiThreadedCountingDetector *mt = + new multiThreadedCountingDetector(filter, nthreads, fifosize); + mt->setClusterSize(csize, csize); + +#ifndef ANALOG + mt->setDetectorMode(ePhotonCounting); + std::cout << "Counting!" << std::endl; + if (thr > 0) { + cf = 0; + } +#endif +//{ +#ifdef ANALOG + mt->setDetectorMode(eAnalog); + std::cout << "Analog!" << std::endl; + cf = 0; + // thr1=thr; +#endif + // } + + mt->StartThreads(); + mt->popFree(buff); + + // cout << "mt " << endl; + + int ifr = 0; + + if (pedfilename.length()>1) { + + std::string froot = getRootString(pedfilename); + + std::cout << "PEDESTAL " << std::endl; + + if (pedfilename.find(".tif") == std::string::npos) { + std::string fname = pedfilename; + std::cout << fname << std::endl; + std::time(&end_time); + std::cout << "aaa " << std::ctime(&end_time) << std::endl; + + mt->setFrameMode(ePedestal); + + ifstream pedefile(fname, ios::in | ios::binary); + // //open file + if (pedefile.is_open()) { + std::cout << "bbbb " << std::ctime(&end_time) << std::endl; + + ff = -1; + while (decoder->readNextFrame(pedefile, ff, np, buff)) { + // if (np == 40) { + if ((ifr + 1) % 100 == 0) { + std::cout + << " ****" + << decoder->getValue(buff, 20, 20); // << std::endl; + } + mt->pushData(buff); + mt->nextThread(); + mt->popFree(buff); + ifr++; + if (ifr % 100 == 0) { + std::cout << " ****" << ifr << " " << ff << " " << np + << std::endl; + } // else + //std::cout << ifr << " " << ff << " " << np << std::endl; + if (ifr >= 1000) + break; + ff = -1; + } + pedefile.close(); + while (mt->isBusy()) { + ; + } + + std::cout << "froot " << froot << std::endl; + auto imgfname = createFileName( outdir, froot, "ped", "tiff"); + mt->writePedestal(imgfname.c_str()); + imgfname = createFileName( outdir, froot, "rms", "tiff"); + mt->writePedestalRMS(imgfname.c_str()); + + } else + std::cout << "Could not open pedestal file " << fname + << " for reading " << std::endl; + } else { + std::vector ped(nx * ny); + float *pp = ReadFromTiff(pedfilename.c_str(), nny, nnx); + if (pp && (int)nnx == nx && (int)nny == ny) { + for (int i = 0; i < nx * ny; i++) { + ped[i] = pp[i]; + } + delete[] pp; + mt->setPedestal(ped.data()); + std::cout << "Pedestal set from tiff file " << pedfilename + << std::endl; + } else { + std::cout << "Could not open pedestal tiff file " << pedfilename + << " for reading " << std::endl; + } + } + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + } + + ifr = 0; + int ifile = 0; + + mt->setFrameMode(eFrame); + + FILE *of = NULL; + + //NOTE THAT THE DATA FILES HAVE TO BE IN THE RIGHT ORDER SO THAT PEDESTAL TRACKING WORKS! + for (int iargc = 9; iargc != argc; ++iargc) { + std::cout << "DATA "; + std::string fname(argv[iargc]); + std::string fsuffix{}; + std::string fprefix = getRootString(fname); + std::string imgfname = createFileName( outdir, fprefix, fsuffix, "tiff" ); + std::string cfname = createFileName( outdir, fprefix, fsuffix, "clust" ); + std::cout << fname << " "; + std::cout << imgfname << std::endl; + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + + ifstream filebin(fname, ios::in | ios::binary); + // //open file + ifile = 0; + if (filebin.is_open()) { + if (thr <= 0 && cf != 0) { // cluster finder + if (of == NULL) { + of = fopen(cfname.c_str(), "w"); + if (of) { + mt->setFilePointer(of); + std::cout << "file pointer set " << std::endl; + } else { + std::cout << "Could not open " << cfname + << " for writing " << std::endl; + mt->setFilePointer(NULL); + return 1; + } + } + } + // //while read frame + ff = -1; + ifr = 0; + while (decoder->readNextFrame(filebin, ff, np, buff)) { + // if (np == 40) { + // //push + + if ((ifr + 1) % 100 == 0) { + std::cout << " ****" + << decoder->getValue(buff, 20, 20); // << std::endl; + } + mt->pushData(buff); + // // //pop + mt->nextThread(); + mt->popFree(buff); + + ifr++; + if (ifr % 100 == 0) + std::cout << " " << ifr << " " << ff << std::endl; + if (nframes > 0) { + if (ifr % nframes == 0) { + imgfname = createFileName( outdir, fprefix, fsuffix, "tiff", ifile ); + mt->writeImage(imgfname.c_str(), thr1); + mt->clearImage(); + ifile++; + } + } + // } else + //std::cout << ifr << " " << ff << " " << np << std::endl; + ff = -1; + } + std::cout << "--" << std::endl; + filebin.close(); + while (mt->isBusy()) { + ; + } + if (nframes >= 0) { + if (nframes > 0) + imgfname = createFileName( outdir, fprefix, fsuffix, "tiff", ifile ); + std::cout << "Writing tiff to " << imgfname << " " << thr1 + << std::endl; + mt->writeImage(imgfname.c_str(), thr1); + mt->clearImage(); + if (of) { + fclose(of); + of = NULL; + mt->setFilePointer(NULL); + } + } + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + } else + std::cout << "Could not open " << fname << " for reading " + << std::endl; + } + if (nframes < 0) { + std::string fname(argv[10]); + auto fprefix = getRootString(fname); //This might by a non-ideal name choice for that file + auto imgfname = createFileName( outdir, fprefix, "sum", "tiff" ); + std::cout << "Writing tiff to " << imgfname << " " << thr1 << std::endl; + mt->writeImage(imgfname.c_str(), thr1); + } + + return 0; +} diff --git a/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess_filetxt.cpp b/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess_filetxt.cpp new file mode 100644 index 000000000..4f6132cc0 --- /dev/null +++ b/slsDetectorCalibration/jungfrauExecutables/jungfrauRawDataProcess_filetxt.cpp @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package +// #include "sls/ansi.h" +#include +#undef CORR + +#define C_GHOST 0.0004 + +#define CM_ROWS 50 + +#define RAWDATA + +#if !defined JFSTRX && !defined JFSTRXOLD && !defined JFSTRXCHIP1 && \ + !defined JFSTRXCHIP6 +#ifndef MODULE +#include "jungfrauHighZSingleChipData.h" +#endif +#ifdef MODULE +#include "jungfrauModuleData.h" +#endif +#endif + +#ifdef JFSTRX +#include "jungfrauLGADStrixelsData_new.h" +#endif +#if defined JFSTRXCHIP1 || defined JFSTRXCHIP6 +#include "jungfrauLGADStrixelsDataSingleChip.h" +#endif +#ifdef JFSTRXOLD +#include "jungfrauStrixelsHalfModuleOldDesign.h" +#endif + +#include "multiThreadedCountingDetector.h" +#include "singlePhotonDetector.h" + +#include +#include +#include +#include + +#include +#include + + +std::string getRootString( const std::string& filepath ) { + size_t pos1; + if (filepath.find("/") == std::string::npos ) + pos1 = 0; + else + pos1 = filepath.find_last_of("/")+1; + size_t pos2 = filepath.find_last_of("."); + //std::cout << "pos1 " << pos1 << " pos2 " << pos2 << " size " << filepath.length() << std::endl; + return filepath.substr( pos1, pos2-pos1 ); +} + +//Create file name string +// dir: directory +// fprefix: fileprefix (without extension) +// fsuffix: filesuffix (for output files, e.g. "ped") +// fext: file extension (e.g. "raw") +std::string createFileName( const std::string& dir, const std::string& fprefix="run", const std::string& fsuffix="", const std::string& fext="raw", int outfilecounter=-1 ) { + if (outfilecounter >= 0) + return fmt::format("{:s}/{:s}_{:s}_f{:05d}.{:s}", dir, fprefix, fsuffix, outfilecounter, fext); + else if (fsuffix.length()!=0) + return fmt::format("{:s}/{:s}_{:s}.{:s}", dir, fprefix, fsuffix, fext); + else + return fmt::format("{:s}/{:s}.{:s}", dir, fprefix, fext); +} + + +//NOTE THAT THE DATA FILES HAVE TO BE IN THE RIGHT ORDER SO THAT PEDESTAL TRACKING WORKS! +int main(int argc, char *argv[]) { + + if (argc < 10) { + std::cout + << "Usage is " << argv[0] + << "filestxt outdir [pedfile (raw or tiff)] [xmin xmax ymin ymax] " + "[threshold] [nframes] " + "NOTE THAT THE DATA FILES HAVE TO BE IN THE RIGHT ORDER SO THAT PEDESTAL TRACKING WORKS! " + << std::endl; + std::cout + << "threshold <0 means analog; threshold=0 means cluster finder; " + "threshold>0 means photon counting" + << std::endl; + std::cout + << "nframes <0 means sum everything; nframes=0 means one file per " + "run; nframes>0 means one file every nframes" + << std::endl; + return 1; + } + + int fifosize = 1000; + int nthreads = 10; + int csize = 3; // 3 + int nsigma = 5; + int nped = 10000; + + int cf = 0; + + double *gainmap = NULL; + // float *gm; + + int ff, np; + // cout << " data size is " << dsize; + + const std::string txtfilename(argv[1]); + const std::string outdir(argv[2]); + const std::string pedfilename(argv[3]); + + int xmin = atoi(argv[4]); + int xmax = atoi(argv[5]); + int ymin = atoi(argv[6]); + int ymax = atoi(argv[7]); + + double thr = 0; + double thr1 = 1; + thr = atof(argv[8]); + + int nframes = 0; + nframes = atoi(argv[9]); + + //Get vector of filenames from input txt-file + std::vector filenames{}; + //filenames.reserve(512); + { //Safety scope for ifstream + ifstream inputs( txtfilename, std::ios::in ); + if (inputs.is_open()) { + std::cout << "Reading imput filenames from txt-file ..." << std::endl; + std::string line{}; + while (!inputs.eof()) { + std::getline(inputs, line); + filenames.emplace_back(line); + std::cout << line << " line.max_size() " << line.max_size() << " filenames.capacity() " << filenames.capacity() << '\n'; + } + inputs.close(); + std::cout << "---- Reached end of txt-file. ----" << std::endl; + } else + std::cout << "Could not open " << txtfilename << std::endl; + if (filenames.size()>0) { + std::cout << filenames.size() << " filenames found in " << txtfilename << std::endl; + std::cout << "The files will be processed in the same order as found in the txt-file." << std::endl; + } else { + std::cout << "No files found in txt-file!" << std::endl; + return 1; + } + } + + std::cout << "###############" << std::endl; + + // Define decoders... +#if !defined JFSTRX && !defined JFSTRXOLD && !defined JFSTRXCHIP1 && \ + !defined JFSTRXCHIP6 +#ifndef MODULE + jungfrauHighZSingleChipData *decoder = new jungfrauHighZSingleChipData(); + int nx = 256, ny = 256; +#endif +#ifdef MODULE + jungfrauModuleData *decoder = new jungfrauModuleData(); + int nx = 1024, ny = 512; +#endif +#endif + +#ifdef JFSTRX + cout << "Jungfrau strixel full module readout" << endl; + // ROI + uint16_t xxmin = 0; + uint16_t xxmax = 0; + uint16_t yymin = 0; + uint16_t yymax = 0; + +#ifndef ALDO + { //THIS SCOPE IS IMPORTANT! (To ensure proper destruction of ifstream) + using header = sls::defs::sls_receiver_header; + // check if there is a roi in the header + typedef struct { + uint16_t xmin; + uint16_t xmax; + uint16_t ymin; + uint16_t ymax; + } receiverRoi_compact; + receiverRoi_compact croi; + //std::string filepath(argv[9]); //This is a problem if the input files have different ROIs! + std::cout << "Reading header of file " << filenames[0] << " to check for ROI " + << std::endl; + ifstream firstfile(filenames[0], ios::in | ios::binary); + if (firstfile.is_open()) { + header hbuffer; + std::cout << "sizeof(header) = " << sizeof(header) << std::endl; + if (firstfile.read((char *)&hbuffer, sizeof(header))) { + memcpy(&croi, &hbuffer.detHeader.detSpec1, 8); + std::cout << "Read ROI [" << croi.xmin << ", " << croi.xmax << ", " + << croi.ymin << ", " << croi.ymax << "]" << std::endl; + xxmin = croi.xmin; + xxmax = croi.xmax; + yymin = croi.ymin; + yymax = croi.ymax; + } else + std::cout << "reading error" << std::endl; + firstfile.close(); + } else + std::cout << "Could not open " << filenames[0] << " for reading " << std::endl; + } //end of protective scope +#endif + + jungfrauLGADStrixelsData *decoder = + new jungfrauLGADStrixelsData(xxmin, xxmax, yymin, yymax); + int nx = 1024 / 3, ny = 512 * 5; +#endif +#ifdef JFSTRXCHIP1 + std::cout << "Jungfrau strixel LGAD single chip 1" << std::endl; + jungfrauLGADStrixelsDataSingleChip *decoder = + new jungfrauLGADStrixelsDataSingleChip(1); + int nx = 256 / 3, ny = 256 * 5; +#endif +#ifdef JFSTRXCHIP6 + std::cout << "Jungfrau strixel LGAD single chip 6" << std::endl; + jungfrauLGADStrixelsDataSingleChip *decoder = + new jungfrauLGADStrixelsDataSingleChip(6); + int nx = 256 / 3, ny = 256 * 5; +#endif +#ifdef JFSTRXOLD + std::cout << "Jungfrau strixels old design" << std::endl; + jungfrauStrixelsHalfModuleOldDesign *decoder = + new jungfrauStrixelsHalfModuleOldDesign(); + int nx = 1024 * 3, ny = 512 / 3; +#endif + + decoder->getDetectorSize(nx, ny); + std::cout << "Detector size is " << nx << " " << ny << std::endl; + + + if ( xmin == xmax ) { + xmin = 0; + xmax = nx; + } + if ( ymin == ymax ) { + ymin = 0; + ymax = ny; + } + std::cout << xmin << " " << xmax << " " << ymin << " " << ymax << " " + << std::endl; + + /* + char *gainfname = NULL; + if (argc > 14) { + gainfname = argv[14]; + std::cout << "Gain map file name is: " << gainfname << std::endl; + } + */ + + std::time_t end_time; + + std::cout << "output directory is " << outdir << std::endl; + if (pedfilename.length()!=0) + std::cout << "pedestal file is " << pedfilename << std::endl; + if (thr > 0) + std::cout << "threshold is " << thr << std::endl; + std::cout << "Nframes is " << nframes << std::endl; + + uint32_t nnx, nny; + + singlePhotonDetector *filter = new singlePhotonDetector( + decoder, 3, nsigma, 1, NULL, nped, 200, -1, -1, gainmap, NULL); + + /* + if (gainfname) { + + if (filter->readGainMap(gainfname)) + std::cout << "using gain map " << gainfname << std::endl; + else + std::cout << "Could not open gain map " << gainfname << std::endl; + } else + */ + thr = 0.15 * thr; + filter->newDataSet(); + // int dsize = decoder->getDataSize(); + + if (thr > 0) { + std::cout << "threshold is " << thr << std::endl; + filter->setThreshold(thr); + cf = 0; + + } else + cf = 1; + + filter->setROI(xmin, xmax, ymin, ymax); + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + + char *buff; + + multiThreadedCountingDetector *mt = + new multiThreadedCountingDetector(filter, nthreads, fifosize); + mt->setClusterSize(csize, csize); + +#ifndef ANALOG + mt->setDetectorMode(ePhotonCounting); + std::cout << "Counting!" << std::endl; + if (thr > 0) { + cf = 0; + } +#endif +//{ +#ifdef ANALOG + mt->setDetectorMode(eAnalog); + std::cout << "Analog!" << std::endl; + cf = 0; + // thr1=thr; +#endif + // } + + mt->StartThreads(); + mt->popFree(buff); + + // cout << "mt " << endl; + + int ifr = 0; + + if (pedfilename.length()>1) { + + std::string froot = getRootString(pedfilename); + + std::cout << "PEDESTAL " << std::endl; + + if (pedfilename.find(".tif") == std::string::npos) { + const std::string fname(pedfilename); + std::cout << fname << std::endl; + std::time(&end_time); + std::cout << "aaa " << std::ctime(&end_time) << std::endl; + + mt->setFrameMode(ePedestal); + + std::ifstream pedefile(fname, ios::in | ios::binary); + // //open file + if (pedefile.is_open()) { + std::cout << "bbbb " << std::ctime(&end_time) << std::endl; + + ff = -1; + while (decoder->readNextFrame(pedefile, ff, np, buff)) { + // if (np == 40) { + if ((ifr + 1) % 100 == 0) { + std::cout + << " ****" + << decoder->getValue(buff, 20, 20); // << std::endl; + } + mt->pushData(buff); + mt->nextThread(); + mt->popFree(buff); + ifr++; + if (ifr % 100 == 0) { + std::cout << " ****" << ifr << " " << ff << " " << np + << std::endl; + } // else + //std::cout << ifr << " " << ff << " " << np << std::endl; + if (ifr >= 1000) + break; + ff = -1; + } + pedefile.close(); + while (mt->isBusy()) { + ; + } + + std::cout << "froot " << froot << std::endl; + auto imgfname = createFileName( outdir, froot, "ped", "tiff"); + mt->writePedestal(imgfname.c_str()); + imgfname = createFileName( outdir, froot, "rms", "tiff"); + mt->writePedestalRMS(imgfname.c_str()); + + } else + std::cout << "Could not open pedestal file " << fname + << " for reading " << std::endl; + } else { + std::vector ped(nx * ny); + float *pp = ReadFromTiff(pedfilename.c_str(), nny, nnx); + if (pp && (int)nnx == nx && (int)nny == ny) { + for (int i = 0; i < nx * ny; i++) { + ped[i] = pp[i]; + } + delete[] pp; + mt->setPedestal(ped.data()); + std::cout << "Pedestal set from tiff file " << pedfilename + << std::endl; + } else { + std::cout << "Could not open pedestal tiff file " << pedfilename + << " for reading " << std::endl; + } + } + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + } + + ifr = 0; + int ioutfile = 0; + + mt->setFrameMode(eFrame); + + FILE *of = NULL; + std::ifstream filebin{}; + + //NOTE THAT THE DATA FILES HAVE TO BE IN THE RIGHT ORDER SO THAT PEDESTAL TRACKING WORKS! + for (unsigned int ifile = 0; ifile != filenames.size(); ++ifile) { + std::cout << "DATA "; + std::string fsuffix{}; + const std::string fprefix( getRootString(filenames[ifile]) ); + std::string imgfname( createFileName( outdir, fprefix, fsuffix, "tiff" ) ); + const std::string cfname( createFileName( outdir, fprefix, fsuffix, "clust" ) ); + std::cout << filenames[ifile] << " "; + std::cout << imgfname << std::endl; + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + + ifstream filebin(filenames[ifile], ios::in | ios::binary); + // //open file + ioutfile = 0; + if (filebin.is_open()) { + if (thr <= 0 && cf != 0) { // cluster finder + if (of == NULL) { + of = fopen(cfname.c_str(), "w"); + if (of) { + mt->setFilePointer(of); + std::cout << "file pointer set " << std::endl; + } else { + std::cout << "Could not open " << cfname + << " for writing " << std::endl; + mt->setFilePointer(NULL); + return 1; + } + } + } + // //while read frame + ff = -1; + ifr = 0; + while (decoder->readNextFrame(filebin, ff, np, buff)) { + // if (np == 40) { + // //push + + if ((ifr + 1) % 100 == 0) { + std::cout << " ****" + << decoder->getValue(buff, 20, 20); // << std::endl; + } + mt->pushData(buff); + // // //pop + mt->nextThread(); + mt->popFree(buff); + + ifr++; + if (ifr % 100 == 0) + std::cout << " " << ifr << " " << ff << std::endl; + if (nframes > 0) { + if (ifr % nframes == 0) { + imgfname = createFileName( outdir, fprefix, fsuffix, "tiff", ioutfile ); + mt->writeImage(imgfname.c_str(), thr1); + mt->clearImage(); + ++ioutfile; + } + } + // } else + //std::cout << ifr << " " << ff << " " << np << std::endl; + ff = -1; + } + std::cout << "aa --" << std::endl; + filebin.close(); + std::cout << "bb --" << std::endl; + while (mt->isBusy()) { + ; + } + std::cout << "cc --" << std::endl; + if (nframes >= 0) { + if (nframes > 0) + imgfname = createFileName( outdir, fprefix, fsuffix, "tiff", ioutfile ); + std::cout << "Writing tiff to " << imgfname << " " << thr1 + << std::endl; + mt->writeImage(imgfname.c_str(), thr1); + mt->clearImage(); + if (of) { + fclose(of); + of = NULL; + mt->setFilePointer(NULL); + } + } + std::time(&end_time); + std::cout << std::ctime(&end_time) << std::endl; + } else + std::cout << "Could not open " << filenames[ifile] << " for reading " + << std::endl; + } + if (nframes < 0) { + //std::string fname(argv[10]); + std::string fprefix( getRootString(filenames[0]) ); //This might by a non-ideal name choice for that file + std::string imgfname( createFileName( outdir, fprefix, "sum", "tiff" ) ); + std::cout << "Writing tiff to " << imgfname << " " << thr1 << std::endl; + mt->writeImage(imgfname.c_str(), thr1); + } + + return 0; +} diff --git a/slsDetectorCalibration/multiThreadedAnalogDetector.h b/slsDetectorCalibration/multiThreadedAnalogDetector.h index 8ae978003..eb9b0215c 100644 --- a/slsDetectorCalibration/multiThreadedAnalogDetector.h +++ b/slsDetectorCalibration/multiThreadedAnalogDetector.h @@ -130,6 +130,7 @@ class threadedAnalogDetector { // return 1;} virtual int isBusy() { + //std::cout << busy << " " << fifoData->isEmpty() << " " << fifoData->getDataValue() << " " << fifoData->getFreeValue() << std::endl; if (busy == 0) { usleep(100); if (busy == 0) { @@ -447,7 +448,7 @@ class multiThreadedAnalogDetector { for (int i = 0; i < nThreads; i++) { ret1 = dets[i]->isBusy(); ret |= ret1; - // if (ret1) cout << "thread " << i <<" still busy " << endl; + //if (ret1) cout << "thread " << i <<" still busy " << endl; } return ret; } diff --git a/slsDetectorCalibration/singlePhotonDetector.h b/slsDetectorCalibration/singlePhotonDetector.h index 202ad55b7..61df4bbcd 100644 --- a/slsDetectorCalibration/singlePhotonDetector.h +++ b/slsDetectorCalibration/singlePhotonDetector.h @@ -63,6 +63,7 @@ class singlePhotonDetector : public analogDetector { quad(UNDEFINED_QUADRANT), tot(0), quadTot(0) { fm = new pthread_mutex_t; + pthread_mutex_init(fm, NULL); eventMask = new eventType *[ny]; // val=new double*[ny]; @@ -233,8 +234,8 @@ class singlePhotonDetector : public analogDetector { //cout << "add to common mode?" << endl; addToCommonMode(data); } - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { if (det->isGood(ix, iy)) { val = subtractPedestal(data, ix, iy, cm); @@ -252,8 +253,8 @@ class singlePhotonDetector : public analogDetector { } } - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { if (det->isGood(ix, iy)) { eventMask[iy][ix] = PEDESTAL; @@ -404,8 +405,8 @@ class singlePhotonDetector : public analogDetector { double *val = new double[ny * nx]; - for (iy = ymin; iy < ymax; ++iy) { - for (ix = xmin; ix < xmax; ++ix) { + for (int iy = ymin; iy < ymax; ++iy) { + for (int ix = xmin; ix < xmax; ++ix) { if (det->isGood(ix, iy) == 0) continue; diff --git a/slsDetectorGui/src/qTabSettings.cpp b/slsDetectorGui/src/qTabSettings.cpp index e45abdbce..f2d1dacf3 100644 --- a/slsDetectorGui/src/qTabSettings.cpp +++ b/slsDetectorGui/src/qTabSettings.cpp @@ -130,7 +130,7 @@ void qTabSettings::SetupWidgetWindow() { } void qTabSettings::SetExportMode(bool exportMode) { - if (comboGainMode->isVisible()) { + if (comboGainMode->isEnabled()) { ShowFixG0(exportMode); } } diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 04a503ab9..56f49a5cd 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index ea5764e54..c0febc991 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 69c624742..9a0cfb408 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -1449,7 +1449,7 @@ void setTiming(enum timingMode arg) { } enum timingMode getTiming() { - if (bus_r(EXT_SIGNAL_REG) == EXT_SIGNAL_MSK) + if ((bus_r(EXT_SIGNAL_REG) & EXT_SIGNAL_MSK) >> EXT_SIGNAL_OFST) return TRIGGER_EXPOSURE; return AUTO_TIMING; } @@ -1736,40 +1736,40 @@ int setDetectorPosition(int pos[]) { detPos[2] = outerPos[X]; detPos[3] = outerPos[Y]; - // row + // row [Y] // outer uint32_t addr = COORD_ROW_REG; bus_w(addr, (bus_r(addr) & ~COORD_ROW_OUTER_MSK) | - ((outerPos[X] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK)); + ((outerPos[Y] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK)); if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) != - outerPos[X]) - ret = FAIL; - // inner - bus_w(addr, - (bus_r(addr) & ~COORD_ROW_INNER_MSK) | - ((innerPos[X] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK)); - if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) != - innerPos[X]) - ret = FAIL; - - // col - // outer - addr = COORD_COL_REG; - bus_w(addr, - (bus_r(addr) & ~COORD_COL_OUTER_MSK) | - ((outerPos[Y] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK)); - if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) != outerPos[Y]) ret = FAIL; // inner bus_w(addr, - (bus_r(addr) & ~COORD_COL_INNER_MSK) | - ((innerPos[Y] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK)); - if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) != + (bus_r(addr) & ~COORD_ROW_INNER_MSK) | + ((innerPos[Y] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK)); + if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) != innerPos[Y]) ret = FAIL; + // col [X] + // outer + addr = COORD_COL_REG; + bus_w(addr, + (bus_r(addr) & ~COORD_COL_OUTER_MSK) | + ((outerPos[X] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK)); + if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) != + outerPos[X]) + ret = FAIL; + // inner + bus_w(addr, + (bus_r(addr) & ~COORD_COL_INNER_MSK) | + ((innerPos[X] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK)); + if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) != + innerPos[X]) + ret = FAIL; + if (ret == OK) { if (getNumberofUDPInterfaces() == 1) { LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n", diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index b80fdb937..6b7eede39 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 50e38b3e0..cf55894d5 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -1345,7 +1345,7 @@ void setTiming(enum timingMode arg) { } enum timingMode getTiming() { - if (bus_r(EXT_SIGNAL_REG) == EXT_SIGNAL_MSK) + if ((bus_r(EXT_SIGNAL_REG) & EXT_SIGNAL_MSK) >> EXT_SIGNAL_OFST) return TRIGGER_EXPOSURE; return AUTO_TIMING; } @@ -1632,40 +1632,40 @@ int setDetectorPosition(int pos[]) { detPos[2] = outerPos[X]; detPos[3] = outerPos[Y]; - // row + // row [Y] // outer uint32_t addr = COORD_ROW_REG; bus_w(addr, (bus_r(addr) & ~COORD_ROW_OUTER_MSK) | - ((outerPos[X] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK)); + ((outerPos[Y] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK)); if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) != - outerPos[X]) - ret = FAIL; - // inner - bus_w(addr, - (bus_r(addr) & ~COORD_ROW_INNER_MSK) | - ((innerPos[X] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK)); - if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) != - innerPos[X]) - ret = FAIL; - - // col - // outer - addr = COORD_COL_REG; - bus_w(addr, - (bus_r(addr) & ~COORD_COL_OUTER_MSK) | - ((outerPos[Y] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK)); - if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) != outerPos[Y]) ret = FAIL; // inner bus_w(addr, - (bus_r(addr) & ~COORD_COL_INNER_MSK) | - ((innerPos[Y] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK)); - if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) != + (bus_r(addr) & ~COORD_ROW_INNER_MSK) | + ((innerPos[Y] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK)); + if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) != innerPos[Y]) ret = FAIL; + // col [X] + // outer + addr = COORD_COL_REG; + bus_w(addr, + (bus_r(addr) & ~COORD_COL_OUTER_MSK) | + ((outerPos[X] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK)); + if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) != + outerPos[X]) + ret = FAIL; + // inner + bus_w(addr, + (bus_r(addr) & ~COORD_COL_INNER_MSK) | + ((innerPos[X] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK)); + if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) != + innerPos[X]) + ret = FAIL; + if (ret == OK) { if (getNumberofUDPInterfaces() == 1) { LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n", diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 229911c1f..1c0d895ba 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -4203,19 +4203,28 @@ int set_adc_enable_mask(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - ret = setADCEnableMask(arg); - if (ret == FAIL) { - sprintf(mess, "Could not set 1Gb ADC Enable mask to 0x%x.\n", arg); + if (arg == 0u) { + ret = FAIL; + sprintf(mess, + "Not allowed to set adc mask of 0 due to data readout. \n"); LOG(logERROR, (mess)); } else { - uint32_t retval = getADCEnableMask(); - if (arg != retval) { - ret = FAIL; - sprintf(mess, + ret = setADCEnableMask(arg); + if (ret == FAIL) { + sprintf(mess, "Could not set 1Gb ADC Enable mask to 0x%x.\n", + arg); + LOG(logERROR, (mess)); + } else { + uint32_t retval = getADCEnableMask(); + if (arg != retval) { + ret = FAIL; + sprintf( + mess, "Could not set 1Gb ADC Enable mask. Set 0x%x, but read " "0x%x\n", arg, retval); - LOG(logERROR, (mess)); + LOG(logERROR, (mess)); + } } } } @@ -4254,15 +4263,22 @@ int set_adc_enable_mask_10g(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - setADCEnableMask_10G(arg); - uint32_t retval = getADCEnableMask_10G(); - if (arg != retval) { + if (arg == 0u) { ret = FAIL; sprintf(mess, - "Could not set 10Gb ADC Enable mask. Set 0x%x, but " - "read 0x%x\n", - arg, retval); + "Not allowed to set adc mask of 0 due to data readout \n"); LOG(logERROR, (mess)); + } else { + setADCEnableMask_10G(arg); + uint32_t retval = getADCEnableMask_10G(); + if (arg != retval) { + ret = FAIL; + sprintf(mess, + "Could not set 10Gb ADC Enable mask. Set 0x%x, but " + "read 0x%x\n", + arg, retval); + LOG(logERROR, (mess)); + } } } #endif diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index bcea6581e..5c9d4750c 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -857,7 +857,7 @@ void Detector::stopDetector(Positions pos) { throw RuntimeError( "Could not stop detector. Returned error status."); } - pimpl->Parallel(&Module::stopAcquisition, pos); + pimpl->stopDetector(pos); status = getDetectorStatus().squash(defs::runStatus::RUNNING); ++retries; @@ -916,7 +916,7 @@ void Detector::setNextFrameNumber(uint64_t value, Positions pos) { } void Detector::sendSoftwareTrigger(const bool block, Positions pos) { - pimpl->Parallel(&Module::sendSoftwareTrigger, pos, block); + pimpl->sendSoftwareTrigger(block, pos); } Result Detector::getScan(Positions pos) const { @@ -954,18 +954,23 @@ void Detector::setNumberofUDPInterfaces(int n, Positions pos) { } void Detector::setNumberofUDPInterfaces_(int n, Positions pos) { + if (!size()) { + throw RuntimeError("No modules added."); + } bool previouslyClientStreaming = pimpl->getDataStreamingToClient(); + int clientStartingPort = getClientZmqPort({0}).squash(0); bool useReceiver = getUseReceiverFlag().squash(false); bool previouslyReceiverStreaming = false; - int startingPort = 0; + int rxStartingPort = 0; if (useReceiver) { previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true); - startingPort = getRxZmqPort({0}).squash(0); + rxStartingPort = getRxZmqPort({0}).squash(0); } pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n); // ensure receiver zmq socket ports are multiplied by 2 (2 interfaces) - if (getUseReceiverFlag().squash(false) && size()) { - setRxZmqPort(startingPort, -1); + setClientZmqPort(clientStartingPort, -1); + if (getUseReceiverFlag().squash(false)) { + setRxZmqPort(rxStartingPort, -1); } // redo the zmq sockets if enabled if (previouslyClientStreaming) { diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 36d9b7a10..a2f155f22 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -755,7 +755,7 @@ void DetectorImpl::readFrameFromReceiver() { int nDetActualPixelsY = nDetPixelsY; if (gapPixels) { - int n = InsertGapPixels(multiframe.get(), multigappixels, + int n = insertGapPixels(multiframe.get(), multigappixels, quadEnable, dynamicRange, nDetActualPixelsX, nDetActualPixelsY); callbackImage = multigappixels; @@ -794,7 +794,7 @@ void DetectorImpl::readFrameFromReceiver() { delete[] multigappixels; } -int DetectorImpl::InsertGapPixels(char *image, char *&gpImage, bool quadEnable, +int DetectorImpl::insertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr, int &nPixelsx, int &nPixelsy) { LOG(logDEBUG) << "Insert Gap pixels:" @@ -1242,43 +1242,105 @@ int DetectorImpl::acquire() { return OK; } -void DetectorImpl::startAcquisition(bool blocking, std::vector positions) { - // handle Mythen3 synchronization - if (shm()->detType == defs::MYTHEN3 && size() > 1) { - std::vector master; - std::vector slaves; - if (positions.empty() || - (positions.size() == 1 && positions[0] == -1)) { - positions.resize(modules.size()); - std::iota(begin(positions), end(positions), 0); - } - // could be all slaves in positions - slaves.reserve(positions.size()); - auto is_master = Parallel(&Module::isMaster, positions); - for (size_t i : positions) { - if (is_master[i]) - master.push_back(i); - else - slaves.push_back(i); +bool DetectorImpl::handleSynchronization(Positions pos) { + bool handleSync = false; + // multi module m3 or multi module sync enabled jungfrau + if (size() > 1) { + switch (shm()->detType) { + case defs::MYTHEN3: + case defs::GOTTHARD2: + case defs::GOTTHARD: + handleSync = true; + break; + case defs::JUNGFRAU: + case defs::MOENCH: + if (Parallel(&Module::getSynchronizationFromStopServer, pos) + .tsquash("Inconsistent synchronization among modules")) { + handleSync = true; + } + break; + default: + break; } + } + return handleSync; +} +void DetectorImpl::getMasterSlaveList(std::vector positions, + std::vector &masters, + std::vector &slaves) { + // expand positions list + if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) { + positions.resize(modules.size()); + std::iota(begin(positions), end(positions), 0); + } + // could be all slaves in positions + slaves.reserve(positions.size()); + auto is_master = Parallel(&Module::isMaster, positions); + for (size_t i : positions) { + if (is_master[i]) + masters.push_back(i); + else + slaves.push_back(i); + } +} + +void DetectorImpl::startAcquisition(const bool blocking, Positions pos) { + + // slaves first + if (handleSynchronization(pos)) { + std::vector masters; + std::vector slaves; + getMasterSlaveList(pos, masters, slaves); if (!slaves.empty()) { Parallel(&Module::startAcquisition, slaves); } - if (!master.empty()) { - if (blocking) { - Parallel(&Module::startAndReadAll, master); - } else { - Parallel(&Module::startAcquisition, master); - } - } - } else { - if (blocking) { - Parallel(&Module::startAndReadAll, positions); - } else { - Parallel(&Module::startAcquisition, positions); + if (!masters.empty()) { + Parallel((blocking ? &Module::startAndReadAll + : &Module::startAcquisition), + pos); } } + // all in parallel + else { + Parallel( + (blocking ? &Module::startAndReadAll : &Module::startAcquisition), + pos); + } +} + +void DetectorImpl::sendSoftwareTrigger(const bool block, Positions pos) { + // slaves first + if (handleSynchronization(pos)) { + std::vector masters; + std::vector slaves; + getMasterSlaveList(pos, masters, slaves); + if (!slaves.empty()) + Parallel(&Module::sendSoftwareTrigger, slaves, false); + if (!masters.empty()) + Parallel(&Module::sendSoftwareTrigger, masters, block); + } + // all in parallel + else { + Parallel(&Module::sendSoftwareTrigger, pos, block); + } +} + +void DetectorImpl::stopDetector(Positions pos) { + // masters first + if (handleSynchronization(pos)) { + std::vector masters; + std::vector slaves; + getMasterSlaveList(pos, masters, slaves); + if (!masters.empty()) + Parallel(&Module::stopAcquisition, masters); + if (!slaves.empty()) + Parallel(&Module::stopAcquisition, slaves); + } + // all in parallel + else { + Parallel(&Module::stopAcquisition, pos); + } } void DetectorImpl::printProgress(double progress) { @@ -1383,7 +1445,8 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { default: throw RuntimeError( "Unknown detector type. Did the 'hostname' command execute " - "successfully? Or use update mode in the detector server side."); + "successfully? Or use update mode in the detector server " + "side."); } LOG(logINFO) << "This can take awhile. Please be patient."; @@ -1411,10 +1474,9 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { int dst = mkstemp(destfname); // create temporary file and open it in r/w if (dst == -1) { fclose(src); - throw RuntimeError( - std::string( - "Could not create destination file in /tmp for programming: ") + - destfname); + throw RuntimeError(std::string("Could not create destination file " + "in /tmp for programming: ") + + destfname); } // convert src to dst rawbin @@ -1466,8 +1528,8 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { } // validate pof: read less than footer offset if (isPof && dstFilePos < pofFooterOfst) { - throw RuntimeError( - "Could not convert programming file. EOF before end of flash"); + throw RuntimeError("Could not convert programming file. EOF " + "before end of flash"); } } if (fclose(src) != 0) { diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index 9dd8fcb80..53d2d9a63 100644 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -278,7 +278,13 @@ class DetectorImpl : public virtual slsDetectorDefs { int acquire(); /** also takes care of master and slave for multi module mythen */ - void startAcquisition(bool blocking, std::vector positions); + void startAcquisition(const bool blocking, Positions pos); + + /** also takes care of master and slave for multi module mythen */ + void sendSoftwareTrigger(const bool block, Positions pos); + + /** also takes care of master and slave for multi module mythen */ + void stopDetector(Positions pos); /** * Combines data from all readouts and gives it to the gui @@ -379,9 +385,14 @@ class DetectorImpl : public virtual slsDetectorDefs { * @param nPixelsy number of pixels in Y axis (updated) * @returns total data bytes for updated image */ - int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr, + int insertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr, int &nPixelsx, int &nPixelsy); + bool handleSynchronization(Positions pos); + void getMasterSlaveList(std::vector positions, + std::vector &masters, + std::vector &slaves); + void printProgress(double progress); void startProcessingThread(bool receiver); diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index cb47f4d7c..f7d437927 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -544,8 +544,15 @@ bool Module::getSynchronization() const { return sendToDetector(F_GET_SYNCHRONIZATION); } +bool Module::getSynchronizationFromStopServer() const { + return sendToDetectorStop(F_GET_SYNCHRONIZATION); +} + void Module::setSynchronization(const bool value) { sendToDetector(F_SET_SYNCHRONIZATION, static_cast(value), nullptr); + // to deal with virtual servers as well + // (get sync from stop server during blocking acquisition) + sendToDetectorStop(F_SET_SYNCHRONIZATION, static_cast(value), nullptr); } std::vector Module::getBadChannels() const { @@ -3215,7 +3222,7 @@ slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id, bool verify) { if (!shm.exists()) { throw SharedMemoryError("Shared memory " + shm.getName() + - "does not exist.\n Corrupted Multi Shared " + " does not exist.\n Corrupted Multi Shared " "memory. Please free shared memory."); } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 0d2d0fb92..40233c720 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -130,6 +130,7 @@ class Module : public virtual slsDetectorDefs { bool isMaster() const; void setMaster(const bool master); bool getSynchronization() const; + bool getSynchronizationFromStopServer() const; void setSynchronization(const bool value); std::vector getBadChannels() const; void setBadChannels(std::vector list); diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index 1f03f9e15..3107df290 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -1207,10 +1207,10 @@ TEST_CASE("dbitphase", "[.cmd]") { } { std::ostringstream oss1, oss2; - proxy.Call("dbitphase", {"20", "deg"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "dbitphase 20 deg\n"); + proxy.Call("dbitphase", {"23", "deg"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "dbitphase 23 deg\n"); proxy.Call("dbitphase", {"deg"}, -1, GET, oss2); - REQUIRE(oss2.str() == "dbitphase 20 deg\n"); + REQUIRE(oss2.str() == "dbitphase 23 deg\n"); } for (int i = 0; i != det.size(); ++i) { det.setDBITPhase(prev_val[i], {i}); diff --git a/slsReceiverSoftware/src/DataStreamer.cpp b/slsReceiverSoftware/src/DataStreamer.cpp index 8ade0941a..6eb833aea 100644 --- a/slsReceiverSoftware/src/DataStreamer.cpp +++ b/slsReceiverSoftware/src/DataStreamer.cpp @@ -56,6 +56,8 @@ void DataStreamer::SetAdditionalJsonHeader( isAdditionalJsonUpdated = true; } +void DataStreamer::SetReceiverROI(ROI roi) { receiverRoi = roi; } + void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) { StopRunning(); startedFlag = false; @@ -249,6 +251,7 @@ int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size, isAdditionalJsonUpdated = false; } zHeader.addJsonHeader = localAdditionalJsonHeader; + zHeader.rx_roi = receiverRoi.getIntArray(); return zmqSocket->SendHeader(index, zHeader); } diff --git a/slsReceiverSoftware/src/DataStreamer.h b/slsReceiverSoftware/src/DataStreamer.h index f05c4e466..6f3fbb7d3 100644 --- a/slsReceiverSoftware/src/DataStreamer.h +++ b/slsReceiverSoftware/src/DataStreamer.h @@ -38,6 +38,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { void SetNumberofTotalFrames(uint64_t value); void SetAdditionalJsonHeader(const std::map &json); + void SetReceiverROI(ROI roi); void ResetParametersforNewAcquisition(const std::string &fname); /** @@ -92,6 +93,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { uint64_t fileIndex{0}; bool flipRows{false}; std::map additionalJsonHeader; + ROI receiverRoi{}; /** Used by streamer thread to update local copy (reduce number of locks * during streaming) */ diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 1e1337cd2..3e3202295 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -216,6 +216,8 @@ void Implementation::SetupDataStreamer(int i) { dataStreamer[i]->SetNumberofPorts(numPorts); dataStreamer[i]->SetQuadEnable(quadEnable); dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames); + dataStreamer[i]->SetReceiverROI( + portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]); } slsDetectorDefs::xy Implementation::getDetectorSize() const { @@ -231,6 +233,11 @@ const slsDetectorDefs::xy Implementation::GetPortGeometry() const { return portGeometry; } +const slsDetectorDefs::ROI Implementation::GetMaxROIPerPort() const { + return slsDetectorDefs::ROI{0, (int)generalData->nPixelsX - 1, 0, + (int)generalData->nPixelsY - 1}; +} + void Implementation::setDetectorSize(const slsDetectorDefs::xy size) { xy portGeometry = GetPortGeometry(); @@ -458,6 +465,10 @@ void Implementation::setReceiverROI(const slsDetectorDefs::ROI arg) { listener[i]->SetNoRoi(portRois[i].noRoi()); for (size_t i = 0; i != dataProcessor.size(); ++i) dataProcessor[i]->SetReceiverROI(portRois[i]); + for (size_t i = 0; i != dataStreamer.size(); ++i) { + dataStreamer[i]->SetReceiverROI( + portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]); + } LOG(logINFO) << "receiver roi: " << ToString(receiverRoi); if (generalData->numUDPInterfaces == 2 && generalData->detType != slsDetectorDefs::GOTTHARD2) { diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 3dc3b3cda..dca7990f9 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -282,6 +282,7 @@ class Implementation : private virtual slsDetectorDefs { void SetupFifoStructure(); const xy GetPortGeometry() const; + const ROI GetMaxROIPerPort() const; void ResetParametersforNewAcquisition(); void CreateUDPSockets(); void SetupWriter(); diff --git a/slsSupportLib/include/sls/ZmqSocket.h b/slsSupportLib/include/sls/ZmqSocket.h index 3537f1f35..7baa6defd 100644 --- a/slsSupportLib/include/sls/ZmqSocket.h +++ b/slsSupportLib/include/sls/ZmqSocket.h @@ -12,6 +12,7 @@ #include "sls/container_utils.h" #include "sls/sls_detector_exceptions.h" +#include #include #include @@ -83,6 +84,8 @@ struct zmqHeader { bool completeImage{false}; /** additional json header */ std::map addJsonHeader; + /** (xmin, xmax, ymin, ymax) roi only in files written */ + std::array rx_roi{}; }; class ZmqSocket { diff --git a/slsSupportLib/include/sls/network_utils.h b/slsSupportLib/include/sls/network_utils.h index aeaed5aa9..e0e48c416 100644 --- a/slsSupportLib/include/sls/network_utils.h +++ b/slsSupportLib/include/sls/network_utils.h @@ -2,6 +2,7 @@ // Copyright (C) 2021 Contributors to the SLS Detector Package #pragma once #include +#include #include #include diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 5a1a5fee8..94b3a8533 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -2,12 +2,12 @@ // Copyright (C) 2021 Contributors to the SLS Detector Package /** API versions */ #define RELEASE "developer" -#define APICTB "developer 0x230224" #define APIGOTTHARD "developer 0x230224" #define APIGOTTHARD2 "developer 0x230224" -#define APIJUNGFRAU "developer 0x230224" #define APIMYTHEN3 "developer 0x230224" -#define APIMOENCH "developer 0x230224" #define APILIB "developer 0x230224" #define APIRECEIVER "developer 0x230224" #define APIEIGER "developer 0x230224" +#define APIJUNGFRAU "developer 0x230508" +#define APIMOENCH "developer 0x230508" +#define APICTB "developer 0x230522" diff --git a/slsSupportLib/src/ZmqSocket.cpp b/slsSupportLib/src/ZmqSocket.cpp index c4c024179..f0ed37fba 100644 --- a/slsSupportLib/src/ZmqSocket.cpp +++ b/slsSupportLib/src/ZmqSocket.cpp @@ -254,6 +254,8 @@ int ZmqSocket::SendHeader(int index, zmqHeader header) { } oss << " } "; } + oss << ", \"rx_roi\":[" << header.rx_roi[0] << ", " << header.rx_roi[1] + << ", " << header.rx_roi[2] << ", " << header.rx_roi[3] << "]"; oss << "}\n"; std::string message = oss.str(); int length = message.length(); @@ -375,6 +377,11 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff, } } + const Value &a = document["rx_roi"].GetArray(); + for (SizeType i = 0; i != a.Size(); ++i) { + zHeader.rx_roi[i] = a[i].GetInt(); + } + return 1; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b30a8aa26..f222cc599 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -58,3 +58,5 @@ set_target_properties(tests PROPERTIES include(CTest) include(Catch) catch_discover_tests(tests) + +configure_file(scripts/test_simulators.py ${CMAKE_BINARY_DIR}/bin/test_simulators.py COPYONLY) diff --git a/tests/scripts/test_simulators.py b/tests/scripts/test_simulators.py new file mode 100644 index 000000000..24ee6f4dd --- /dev/null +++ b/tests/scripts/test_simulators.py @@ -0,0 +1,200 @@ +# SPDX-License-Identifier: LGPL-3.0-or-other +# Copyright (C) 2021 Contributors to the SLS Detector Package +''' +This file is used to start up simulators, receivers and run all the tests on them and finally kill the simulators and receivers. +''' +import argparse +import os, sys, subprocess, time, colorama, signal, psutil + +from colorama import Fore +from slsdet import Detector, detectorType, detectorSettings +from slsdet.defines import DEFAULT_TCP_CNTRL_PORTNO, DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO +HALFMOD2_TCP_CNTRL_PORTNO=1955 +HALFMOD2_TCP_RX_PORTNO=1957 + +colorama.init(autoreset=True) + +class RuntimeException (Exception): + def __init__ (self, message): + super().__init__(Fore.RED + message) + +def Log(color, message): + print('\n' + color + message, flush=True) + +def checkIfProcessRunning(processName): + ''' + Check if there is any running process that contains the given name processName. + https://gist.github.com/Sanix-Darker/8cbed2ff6f8eb108ce2c8c51acd2aa5a + ''' + # Iterate over the all the running process + for proc in psutil.process_iter(): + try: + # Check if process name contains the given name string. + if processName.lower() in proc.name().lower(): + return True + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + pass + return False; + +def killProcess(name): + if checkIfProcessRunning(name): + Log(Fore.GREEN, 'killing ' + name) + p = subprocess.run(['killall', name]) + if p.returncode != 0: + raise RuntimeException('error in killall ' + name) + +def cleanup(name, d): + ''' + kill both servers, receivers and clean shared memory + ''' + Log(Fore.GREEN, 'Cleaning up...') + killProcess(name + 'DetectorServer_virtual') + killProcess('slsReceiver') + killProcess('slsMultiReceiver') + d.freeSharedMemory() + +def startProcessInBackground(name): + try: + # in background and dont print output + p = subprocess.Popen(name.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + Log(Fore.GREEN, 'Starting up ' + name + ' ...') + except: + Log(Fore.RED, 'Could not start ' + name) + raise + +def startServer(name): + startProcessInBackground(name + 'DetectorServer_virtual') + # second half + if name == 'eiger': + startProcessInBackground(name + 'DetectorServer_virtual -p' + str(HALFMOD2_TCP_CNTRL_PORTNO)) + tStartup = 6 + Log(Fore.WHITE, 'Takes ' + str(tStartup) + ' seconds... Please be patient') + time.sleep(tStartup) + +def startReceiver(name): + startProcessInBackground('slsReceiver') + # second half + if name == 'eiger': + startProcessInBackground('slsReceiver -t' + str(HALFMOD2_TCP_RX_PORTNO)) + time.sleep(2) + +def loadConfig(name, rx_hostname, settingsdir): + try: + d = Detector() + if name == 'eiger': + d.hostname = 'localhost:' + str(DEFAULT_TCP_CNTRL_PORTNO) + '+localhost:' + str(HALFMOD2_TCP_CNTRL_PORTNO) + #d.udp_dstport = {2: 50003} + # will set up for every module + d.udp_dstport = DEFAULT_UDP_DST_PORTNO + d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1 + d.rx_hostname = rx_hostname + ':' + str(DEFAULT_TCP_RX_PORTNO) + '+' + rx_hostname + ':' + str(HALFMOD2_TCP_RX_PORTNO) + d.udp_dstip = 'auto' + d.trimen = [4500, 5400, 6400] + d.settingspath = settingsdir + '/eiger/' + d.setThresholdEnergy(4500, detectorSettings.STANDARD) + else: + d.hostname = 'localhost' + d.rx_hostname = rx_hostname + d.udp_dstip = 'auto' + if d.type == detectorType.GOTTHARD: + d.udp_srcip = d.udp_dstip + else: + d.udp_srcip = 'auto' + if d.type == detectorType.JUNGFRAU or d.type == detectorType.MOENCH: + d.powerchip = 1 + except: + Log(Fore.RED, 'Could not load config for ' + name) + raise + +def startCmdTests(name, fp): + try: + p = subprocess.run(['tests', '--abort', '[.cmd]'], stdout=fp, stderr=fp) + if p.returncode != 0: + raise Exception + except: + Log(Fore.RED, 'Cmd tests failed for ' + name) + raise + +def startNormalTests(d, fp): + try: + Log(Fore.BLUE, '\nNormal tests') + p = subprocess.run(['tests', '--abort' ], stdout=fp, stderr=fp) + if p.returncode != 0: + raise Exception + d.freeSharedMemory() + except: + Log(Fore.RED, 'Normal tests failed') + raise + + +# parse cmd line for rx_hostname and settingspath using the argparse library +parser = argparse.ArgumentParser(description = 'automated tests with the virtual detector servers') +parser.add_argument('rx_hostname', help = 'hostname/ip of the current machine') +parser.add_argument('settingspath', help = 'Relative or absolut path to the settingspath') +parser.add_argument('-s', '--servers', help='Detector servers to run', nargs='*') +args = parser.parse_args() +if args.rx_hostname == 'localhost': + raise RuntimeException('Cannot use localhost for rx_hostname for the tests (fails for rx_arping for eg.)') + +if args.servers is None: + servers = [ + 'eiger', + 'jungfrau', + 'mythen3', + 'gotthard2', + 'gotthard', + 'ctb', + 'moench', + ] +else: + servers = args.servers + +Log(Fore.WHITE, 'rx_hostname: ' + args.rx_hostname + '\settingspath: \'' + args.settingspath + '\'') + + +# handle zombies (else killing slsReceivers will fail) +# dont care about child process success +signal.signal(signal.SIGCHLD, signal.SIG_IGN) + + +# redirect to file +original_stdout = sys.stdout +original_stderr = sys.stderr +fname = '/tmp/slsDetectorPackage_virtual_test.txt' +Log(Fore.BLUE, 'Tests -> ' + fname) +with open(fname, 'w') as fp: + sys.stdout = fp + sys.stderr = fp + + d = Detector() + # TODO: redirect Detector object print out also to file + startNormalTests(d, fp) + + for server in servers: + try: + # print to terminal for progress + sys.stdout = original_stdout + sys.stderr = original_stderr + Log(Fore.BLUE, server + ' tests') + sys.stdout = fp + sys.stderr = fp + + # cmd tests for det + Log(Fore.BLUE, 'Cmd Tests for ' + server) + cleanup(server, d) + startServer(server) + startReceiver(server) + loadConfig(server, args.rx_hostname, args.settingspath) + startCmdTests(server, fp) + cleanup(server, d) + except: + cleanup(server, d) + raise + + + Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers)) + +# redirect to terminal +sys.stdout = original_stdout +sys.stderr = original_stderr +Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers) + '\nYayyyy! :) ') \ No newline at end of file