diff --git a/python/slsdet/jsonproxy.py b/python/slsdet/jsonproxy.py new file mode 100644 index 000000000..a85adf630 --- /dev/null +++ b/python/slsdet/jsonproxy.py @@ -0,0 +1,30 @@ +from .utils import element_if_equal + +class JsonProxy: + """ + Proxy class to allow for intuitive setting and getting of rx_jsonpara + This class is returned by Detectr.rx_jsonpara + """ + def __init__(self, det): + self.det = det + + def __getitem__(self, key): + return element_if_equal(self.det.getAdditionalJsonParameter(key)) + + def __setitem__(self, key, value): + self.det.setAdditionalJsonParameter(key, str(value)) + + def __repr__(self): + r = element_if_equal(self.det.getAdditionalJsonHeader()) + if isinstance(r, list): + rstr = '' + for i, list_item in enumerate(r): + list_item = dict(list_item) + rstr += ''.join([f'{i}:{key}: {value}\n' for key, value in list_item.items()]) + + return rstr.strip('\n') + else: + r = dict(r) + return '\n'.join([f'{key}: {value}' for key, value in r.items()]) + + diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 0b3f5c8e7..adc94c79c 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -6941,6 +6941,16 @@ int get_receiver_parameters(int file_des) { if (n < 0) return printSocketReadError(); + // additional storage cells +#ifdef JUNGFRAUD + i32 = getNumAdditionalStorageCells(); +#else + i32 = 0; +#endif + n += sendData(file_des, &i32, sizeof(i32), INT32); + if (n < 0) + return printSocketReadError(); + // analog samples #if defined(CHIPTESTBOARDD) || defined(MOENCHD) i32 = getNumAnalogSamples(); @@ -7018,6 +7028,26 @@ int get_receiver_parameters(int file_des) { if (n < 0) return printSocketReadError(); + // readnlines +#ifdef EIGERD + i32 = getReadNLines(); +#else + i32 = 0; +#endif + n += sendData(file_des, &i32, sizeof(i32), INT32); + if (n < 0) + return printSocketReadError(); + + // threshold ev +#ifdef EIGERD + i32 = getThresholdEnergy(); +#else + i32 = 0; +#endif + n += sendData(file_des, &i32, sizeof(i32), INT32); + if (n < 0) + return printSocketReadError(); + // dynamic range i32 = setDynamicRange(GET_FLAG); n += sendData(file_des, &i32, sizeof(i32), INT32); @@ -7178,6 +7208,26 @@ int get_receiver_parameters(int file_des) { if (n < 0) return printSocketReadError(); + // scan parameters + // scan enable, dac, start, stop, step + // scan dac settle time + int i32s[5] = {0, 0, 0, 0, 0}; + i64 = 0; + i32s[0] = scan; + if (scan) { + i32s[1] = scanGlobalIndex; + i32s[2] = scanSteps[0]; + i32s[3] = scanSteps[numScanSteps - 1]; + i32s[4] = scanSteps[1] - scanSteps[0]; + i64 = scanSettleTime_ns; + } + n += sendData(file_des, i32s, sizeof(i32s), INT32); + if (n < 0) + return printSocketReadError(); + n += sendData(file_des, &i64, sizeof(i64), INT64); + if (n < 0) + return printSocketReadError(); + LOG(logINFO, ("Sent %d bytes for receiver parameters\n", n)); return OK; diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 79e407812..2f0c344d2 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -474,6 +474,9 @@ defs::scanParameters Module::getScan() const { void Module::setScan(const defs::scanParameters t) { auto retval = sendToDetector(F_SET_SCAN, t); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_SCAN, t, nullptr); + } // if disabled, retval is 1, else its number of steps setNumberOfFrames(retval); } @@ -1083,6 +1086,9 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings, // check as there is client processing if (shm()->myDetectorType == EIGER) { setThresholdEnergyAndSettings(e_eV, isettings, trimbits); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_THRESHOLD, e_eV, nullptr); + } } // moench - send threshold energy to processor else if (shm()->myDetectorType == MOENCH) { diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index eababfbf2..09ee538bc 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -83,7 +83,8 @@ void ClientInterface::startTCPServer() { try { auto socket = server.accept(); try { - verifyLock(); + verifyLock(); // lock should be checked only for set (not get), + // Move it back? ret = decodeFunction(socket); } catch (const RuntimeError &e) { // We had an error needs to be sent to client @@ -202,6 +203,8 @@ int ClientInterface::functionTable(){ flist[F_GET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::get_streaming_start_fnum; flist[F_SET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::set_streaming_start_fnum; flist[F_SET_RECEIVER_RATE_CORRECT] = &ClientInterface::set_rate_correct; + flist[F_SET_RECEIVER_SCAN] = &ClientInterface::set_scan; + flist[F_RECEIVER_SET_THRESHOLD] = &ClientInterface::set_threshold; for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { LOG(logDEBUG1) << "function fnum: " << i << " (" << @@ -364,6 +367,9 @@ int ClientInterface::setup_receiver(Interface &socket) { if (myDetectorType == GOTTHARD2) { impl()->setNumberOfBursts(arg.bursts); } + if (myDetectorType == JUNGFRAU) { + impl()->setNumberOfAdditionalStorageCells(arg.additionalStorageCells); + } if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) { try { impl()->setNumberofAnalogSamples(arg.analogSamples); @@ -398,6 +404,8 @@ int ClientInterface::setup_receiver(Interface &socket) { std::to_string(arg.quad) + " due to fifo strucutre memory allocation"); } + impl()->setReadNLines(arg.numLinesReadout); + impl()->setThresholdEnergy(arg.thresholdEnergyeV); } if (myDetectorType == EIGER || myDetectorType == MYTHEN3) { try { @@ -459,6 +467,7 @@ int ClientInterface::setup_receiver(Interface &socket) { if (myDetectorType == GOTTHARD2) { impl()->setBurstMode(arg.burstType); } + impl()->setScan(arg.scanParams); return socket.sendResult(retvals); } @@ -1107,7 +1116,7 @@ int ClientInterface::set_additional_json_header(Interface &socket) { json[key] = value; } } - verifyIdle(socket); + // verifyIdle(socket); allowing it to be set on the fly LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json); impl()->setAdditionalJsonHeader(json); return socket.Send(OK); @@ -1523,7 +1532,7 @@ int ClientInterface::increment_file_index(Interface &socket) { int ClientInterface::set_additional_json_parameter(Interface &socket) { char args[2][SHORT_STR_LENGTH]{}; socket.Receive(args); - verifyIdle(socket); + // verifyIdle(socket); allowing it to be set on the fly LOG(logDEBUG1) << "Setting additional json parameter (" << args[0] << "): " << args[1]; impl()->setAdditionalJsonParameter(args[0], args[1]); @@ -1622,4 +1631,22 @@ int ClientInterface::set_rate_correct(Interface &socket) { LOG(logINFOBLUE) << "Setting rate corrections[" << index << ']'; impl()->setRateCorrections(t); return socket.Send(OK); +} + +int ClientInterface::set_scan(Interface &socket) { + auto arg = socket.Receive(); + LOG(logDEBUG) << "Scan Mode: " << sls::ToString(arg); + verifyIdle(socket); + impl()->setScan(arg); + return socket.Send(OK); +} + +int ClientInterface::set_threshold(Interface &socket) { + auto arg = socket.Receive(); + LOG(logDEBUG) << "Threshold: " << arg << " eV"; + if (myDetectorType != EIGER) + functionNotImplemented(); + verifyIdle(socket); + impl()->setThresholdEnergy(arg); + return socket.Send(OK); } \ No newline at end of file diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index bf066acb5..b4acc1239 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -157,6 +157,8 @@ class ClientInterface : private virtual slsDetectorDefs { int get_streaming_start_fnum(sls::ServerInterface &socket); int set_streaming_start_fnum(sls::ServerInterface &socket); int set_rate_correct(sls::ServerInterface &socket); + int set_scan(sls::ServerInterface &socket); + int set_threshold(sls::ServerInterface &socket); Implementation *impl() { if (receiver != nullptr) { diff --git a/slsReceiverSoftware/src/DataStreamer.cpp b/slsReceiverSoftware/src/DataStreamer.cpp index 9c55803a7..74d4e37a6 100644 --- a/slsReceiverSoftware/src/DataStreamer.cpp +++ b/slsReceiverSoftware/src/DataStreamer.cpp @@ -69,7 +69,9 @@ void DataStreamer::SetFlippedDataX(int fd) { flippedDataX = fd; } void DataStreamer::SetAdditionalJsonHeader( const std::map &json) { - additionJsonHeader = json; + std::lock_guard lock(additionalJsonMutex); + additionalJsonHeader = json; + isAdditionalJsonUpdated = true; } void DataStreamer::CreateZmqSockets(int *nunits, uint32_t port, @@ -232,7 +234,14 @@ int DataStreamer::SendHeader(sls_receiver_header *rheader, uint32_t size, zHeader.quad = *quadEnable; zHeader.completeImage = (header.packetNumber < generalData->packetsPerFrame ? false : true); - zHeader.addJsonHeader = additionJsonHeader; + + // update local copy only if it was updated (to prevent locking each time) + if (isAdditionalJsonUpdated) { + std::lock_guard lock(additionalJsonMutex); + localAdditionalJsonHeader = additionalJsonHeader; + isAdditionalJsonUpdated = false; + } + zHeader.addJsonHeader = localAdditionalJsonHeader; return zmqSocket->SendHeader(index, zHeader); } diff --git a/slsReceiverSoftware/src/DataStreamer.h b/slsReceiverSoftware/src/DataStreamer.h index bbfc5aba9..89f213b97 100644 --- a/slsReceiverSoftware/src/DataStreamer.h +++ b/slsReceiverSoftware/src/DataStreamer.h @@ -16,6 +16,7 @@ class DataStreamer; class ZmqSocket; #include +#include class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { @@ -166,7 +167,17 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { int flippedDataX; /** additional json header */ - std::map additionJsonHeader; + std::map additionalJsonHeader; + + /** Used by streamer thread to update local copy (reduce number of locks + * during streaming) */ + std::atomic isAdditionalJsonUpdated{false}; + + /** mutex to update json and to read and update local copy */ + mutable std::mutex additionalJsonMutex; + + /** local copy of additional json header (it can be update on the fly) */ + std::map localAdditionalJsonHeader; /** Aquisition Started flag */ bool startedFlag{nullptr}; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 27056c60f..0524cd125 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -483,6 +483,11 @@ std::vector Implementation::getNumMissingPackets() const { return mp; } +void Implementation::setScan(slsDetectorDefs::scanParameters s) { + scanParams = s; + LOG(logINFO) << "Scan parameters: " << sls::ToString(scanParams); +} + void Implementation::startReceiver() { LOG(logINFO) << "Starting Receiver"; stoppedFlag = false; @@ -719,27 +724,37 @@ void Implementation::SetupWriter() { "Unknown detector type to set up master file attributes"); } masterAttributes->detType = myDetectorType; + masterAttributes->timingMode = timingMode; masterAttributes->imageSize = generalData->imageSize; masterAttributes->nPixels = xy(generalData->nPixelsX, generalData->nPixelsY); masterAttributes->maxFramesPerFile = framesPerFile; + masterAttributes->frameDiscardMode = frameDiscardMode; + masterAttributes->framePadding = framePadding; + masterAttributes->scanParams = scanParams; masterAttributes->totalFrames = numberOfTotalFrames; masterAttributes->exptime = acquisitionTime; masterAttributes->period = acquisitionPeriod; + masterAttributes->burstMode = burstMode; + masterAttributes->numUDPInterfaces = numUDPInterfaces; masterAttributes->dynamicRange = dynamicRange; masterAttributes->tenGiga = tengigaEnable; + masterAttributes->thresholdEnergyeV = thresholdEnergyeV; masterAttributes->subExptime = subExpTime; masterAttributes->subPeriod = subPeriod; masterAttributes->quad = quadEnable; + masterAttributes->numLinesReadout = numLinesReadout; masterAttributes->ratecorr = rateCorrections; masterAttributes->adcmask = tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga; masterAttributes->analog = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; + masterAttributes->analogSamples = numberOfAnalogSamples; masterAttributes->digital = (readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; + masterAttributes->digitalSamples = numberOfDigitalSamples; masterAttributes->dbitoffset = ctbDbitOffset; masterAttributes->dbitlist = 0; for (auto &i : ctbDbitList) { @@ -754,6 +769,7 @@ void Implementation::SetupWriter() { masterAttributes->gateDelay2 = gateDelay2; masterAttributes->gateDelay3 = gateDelay3; masterAttributes->gates = numberOfGates; + masterAttributes->additionalJsonHeader = additionalJsonHeader; try { for (unsigned int i = 0; i < dataProcessor.size(); ++i) { @@ -1464,6 +1480,11 @@ void Implementation::setReadNLines(const int value) { LOG(logINFO) << "Number of Lines to readout: " << numLinesReadout; } +void Implementation::setThresholdEnergy(const int value) { + thresholdEnergyeV = value; + LOG(logINFO) << "Threshold Energy: " << thresholdEnergyeV << " eV"; +} + void Implementation::setRateCorrections(const std::vector &t) { rateCorrections = t; LOG(logINFO) << "Rate Corrections: " << sls::ToString(rateCorrections); diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index aa1949afe..a15d24695 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -81,6 +81,7 @@ class Implementation : private virtual slsDetectorDefs { uint64_t getAcquisitionIndex() const; double getProgress() const; std::vector getNumMissingPackets() const; + void setScan(slsDetectorDefs::scanParameters s); void startReceiver(); void setStoppedFlag(bool stopped); void stopReceiver(); @@ -214,6 +215,8 @@ class Implementation : private virtual slsDetectorDefs { int getReadNLines() const; /* [Eiger] */ void setReadNLines(const int value); + /** [Eiger] */ + void setThresholdEnergy(const int value); /* [Eiger] */ void setRateCorrections(const std::vector &t); readoutMode getReadoutMode() const; @@ -292,6 +295,7 @@ class Implementation : private virtual slsDetectorDefs { // acquisition std::atomic status{IDLE}; bool stoppedFlag{false}; + scanParameters scanParams{}; // network configuration (UDP) int numUDPInterfaces{1}; @@ -340,6 +344,7 @@ class Implementation : private virtual slsDetectorDefs { bool activated{true}; bool deactivatedPaddingEnable{true}; int numLinesReadout{MAX_EIGER_ROWS_PER_READOUT}; + int thresholdEnergyeV{-1}; std::vector rateCorrections; readoutMode readoutType{ANALOG_ONLY}; uint32_t adcEnableMaskOneGiga{BIT32_MASK}; diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index 0726c29ee..2718de1bc 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -15,8 +15,8 @@ using namespace H5; using ns = std::chrono::nanoseconds; // versions -#define HDF5_WRITER_VERSION (6.1) // 1 decimal places -#define BINARY_WRITER_VERSION (6.1) // 1 decimal places +#define HDF5_WRITER_VERSION (6.2) // 1 decimal places +#define BINARY_WRITER_VERSION (6.2) // 1 decimal places struct MasterAttributes { slsDetectorDefs::detectorType detType{slsDetectorDefs::GENERIC}; @@ -24,19 +24,28 @@ struct MasterAttributes { uint32_t imageSize{0}; slsDetectorDefs::xy nPixels{}; uint32_t maxFramesPerFile{0}; + slsDetectorDefs::frameDiscardPolicy frameDiscardMode{ + slsDetectorDefs::NO_DISCARD}; + int framePadding{1}; + slsDetectorDefs::scanParameters scanParams{}; uint64_t totalFrames{0}; ns exptime{0}; ns period{0}; + slsDetectorDefs::burstMode burstMode{slsDetectorDefs::BURST_INTERNAL}; + int numUDPInterfaces{0}; uint32_t dynamicRange{0}; uint32_t tenGiga{0}; - int threshold{0}; + int thresholdEnergyeV{0}; ns subExptime{0}; ns subPeriod{0}; uint32_t quad{0}; + uint32_t numLinesReadout; std::vector ratecorr; uint32_t adcmask{0}; uint32_t analog{0}; + uint32_t analogSamples{0}; uint32_t digital{0}; + uint32_t digitalSamples{0}; uint32_t dbitoffset{0}; uint64_t dbitlist{0}; slsDetectorDefs::ROI roi{}; @@ -48,6 +57,7 @@ struct MasterAttributes { ns gateDelay2{0}; ns gateDelay3{0}; uint32_t gates; + std::map additionalJsonHeader; MasterAttributes(){}; virtual ~MasterAttributes(){}; @@ -69,11 +79,25 @@ struct MasterAttributes { << "Image Size : " << imageSize << " bytes" << '\n' << "Pixels : " << sls::ToString(nPixels) << '\n' << "Max Frames Per File : " << maxFramesPerFile << '\n' + << "Frame Discard Policy : " + << sls::ToString(frameDiscardMode) << '\n' + << "Frame Padding : " << framePadding << '\n' + << "Scan Parameters : " << sls::ToString(scanParams) + << '\n' << "Total Frames : " << totalFrames << '\n'; return oss.str(); }; void WriteBinaryAttributes(FILE *fd, std::string message) { + // adding few common parameters to the end + if (!additionalJsonHeader.empty()) { + std::ostringstream oss; + oss << "Additional Json Header : " + << sls::ToString(additionalJsonHeader) << '\n'; + message += oss.str(); + } + + // adding sls_receiver header format message += std::string("\n#Frame Header\n" "Frame Number : 8 bytes\n" "SubFrame Number/ExpLength : 4 bytes\n" @@ -90,6 +114,7 @@ struct MasterAttributes { "Header Version : 1 byte\n" "Packets Caught Mask : 64 bytes\n"); + // writing to file if (fwrite((void *)message.c_str(), 1, message.length(), fd) != message.length()) { throw sls::RuntimeError( @@ -103,14 +128,14 @@ struct MasterAttributes { "by a child class"; }; - void WriteHDF5Attributes(H5File *fd, Group *group){ + void WriteHDF5Attributes(H5File *fd, Group *group) { // clang-format off // version { double version = BINARY_WRITER_VERSION; DataSpace dataspace = DataSpace(H5S_SCALAR); Attribute attribute = fd->createAttribute( - "version", PredType::NATIVE_DOUBLE, dataspace); + "Version", PredType::NATIVE_DOUBLE, dataspace); attribute.write(PredType::NATIVE_DOUBLE, &version); } // timestamp @@ -119,7 +144,7 @@ struct MasterAttributes { StrType strdatatype(PredType::C_S1, 256); DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = - group->createDataSet("timestamp", strdatatype, dataspace); + group->createDataSet("Timestamp", strdatatype, dataspace); dataset.write(std::string(ctime(&t)), strdatatype); } // detector type @@ -127,7 +152,7 @@ struct MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("detector type", strdatatype, dataspace); + group->createDataSet("Detector Type", strdatatype, dataspace); dataset.write(sls::ToString(detType), strdatatype); } // timing mode @@ -135,19 +160,19 @@ struct MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("timing mode", strdatatype, dataspace); + group->createDataSet("Timing Mode", strdatatype, dataspace); dataset.write(sls::ToString(timingMode), strdatatype); } // Image Size { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "image size", PredType::NATIVE_INT, dataspace); + "Image Size", PredType::NATIVE_INT, dataspace); dataset.write(&imageSize, PredType::NATIVE_INT); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); Attribute attribute = - dataset.createAttribute("unit", strdatatype, dataspaceAttr); + dataset.createAttribute("Unit", strdatatype, dataspaceAttr); attribute.write(strdatatype, std::string("bytes")); } //TODO: make this into an array? @@ -155,37 +180,69 @@ struct MasterAttributes { { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "number of pixels in x axis", PredType::NATIVE_INT, dataspace); + "Number of pixels in x axis", PredType::NATIVE_INT, dataspace); dataset.write(&nPixels.x, PredType::NATIVE_INT); } // y { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "number of pixels in y axis", PredType::NATIVE_INT, dataspace); + "Number of pixels in y axis", PredType::NATIVE_INT, dataspace); dataset.write(&nPixels.y, PredType::NATIVE_INT); } // Maximum frames per file { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "maximum frames per file", PredType::NATIVE_INT, dataspace); + "Maximum frames per file", PredType::NATIVE_INT, dataspace); dataset.write(&maxFramesPerFile, PredType::NATIVE_INT); } + // Frame Discard Policy + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Frame Discard Policy", strdatatype, dataspace); + dataset.write(sls::ToString(frameDiscardMode), strdatatype); + } + // Frame Padding + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet( + "Frame Padding", PredType::NATIVE_INT, dataspace); + dataset.write(&framePadding, PredType::NATIVE_INT); + } + // Scan Parameters + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Scan Parameters", strdatatype, dataspace); + dataset.write(sls::ToString(scanParams), strdatatype); + } // Total Frames { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "total frames", PredType::STD_U64LE, dataspace); + "Total Frames", PredType::STD_U64LE, dataspace); dataset.write(&totalFrames, PredType::STD_U64LE); } + // additional json header + if (!additionalJsonHeader.empty()) { + std::string json = sls::ToString(additionalJsonHeader); + StrType strdatatype(PredType::C_S1, json.length()); + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Additional JSON Header", strdatatype, dataspace); + dataset.write(sls::ToString(additionalJsonHeader), strdatatype); + } }; void WriteHDF5Exptime(H5File *fd, Group *group) { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("exposure time", strdatatype, dataspace); + group->createDataSet("Exposure Time", strdatatype, dataspace); dataset.write(sls::ToString(exptime), strdatatype); }; @@ -193,26 +250,26 @@ struct MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("acquisition period", strdatatype, dataspace); + group->createDataSet("Acquisition Period", strdatatype, dataspace); dataset.write(sls::ToString(period), strdatatype); }; void WriteHDF5DynamicRange(H5File *fd, Group *group) { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "dynamic range", PredType::NATIVE_INT, dataspace); + "Dynamic Range", PredType::NATIVE_INT, dataspace); dataset.write(&dynamicRange, PredType::NATIVE_INT); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); Attribute attribute = - dataset.createAttribute("unit", strdatatype, dataspaceAttr); + dataset.createAttribute("Unit", strdatatype, dataspaceAttr); attribute.write(strdatatype, std::string("bits")); }; void WriteHDF5TenGiga(H5File *fd, Group *group) { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "ten giga enable", PredType::NATIVE_INT, dataspace); + "Ten Giga Enable", PredType::NATIVE_INT, dataspace); dataset.write(&tenGiga, PredType::NATIVE_INT); }; #endif @@ -264,7 +321,8 @@ class JungfrauMasterAttributes : public MasterAttributes { std::ostringstream oss; oss << MasterAttributes::GetBinaryMasterAttributes() << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n'; + << "Period : " << sls::ToString(period) << '\n' + << "Number of UDP Interfaces : " << numUDPInterfaces << '\n'; std::string message = oss.str(); MasterAttributes::WriteBinaryAttributes(fd, message); }; @@ -274,6 +332,12 @@ class JungfrauMasterAttributes : public MasterAttributes { MasterAttributes::WriteHDF5Attributes(fd, group); MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet( + "Number of UDP Interfaces", PredType::NATIVE_INT, dataspace); + dataset.write(&numUDPInterfaces, PredType::NATIVE_INT); + } }; #endif }; @@ -294,6 +358,7 @@ class EigerMasterAttributes : public MasterAttributes { << "SubPeriod : " << sls::ToString(subPeriod) << '\n' << "Quad : " << quad << '\n' + << "Number of Lines read out : " << numLinesReadout << '\n' << "Rate Corrections : " << sls::ToString(ratecorr) << '\n'; std::string message = oss.str(); @@ -311,19 +376,19 @@ class EigerMasterAttributes : public MasterAttributes { { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "threshold", PredType::NATIVE_INT, dataspace); + "Threshold Energy", PredType::NATIVE_INT, dataspace); dataset.write(&threshold, PredType::NATIVE_INT); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); Attribute attribute = - dataset.createAttribute("unit", strdatatype, dataspaceAttr); + dataset.createAttribute("Unit", strdatatype, dataspaceAttr); attribute.write(strdatatype, std::string("eV")); } // SubExptime { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = group->createDataSet("sub exposure time", + DataSet dataset = group->createDataSet("Sub Exposure Time", strdatatype, dataspace); dataset.write(sls::ToString(subExptime), strdatatype); } @@ -332,21 +397,28 @@ class EigerMasterAttributes : public MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("sub period", strdatatype, dataspace); + group->createDataSet("Sub Period", strdatatype, dataspace); dataset.write(sls::ToString(subPeriod), strdatatype); } // Quad { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = - group->createDataSet("quad", PredType::NATIVE_INT, dataspace); + group->createDataSet("Quad", PredType::NATIVE_INT, dataspace); dataset.write(&quad, PredType::NATIVE_INT); } + // numLinesReadout + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet( + "Number of Lines read out", PredType::NATIVE_INT, dataspace); + dataset.write(&numLinesReadout, PredType::NATIVE_INT); + } // Rate corrections { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 1024); - DataSet dataset = group->createDataSet("rate corrections", + DataSet dataset = group->createDataSet("Rate Corrections", strdatatype, dataspace); dataset.write(sls::ToString(ratecorr), strdatatype); } @@ -393,7 +465,7 @@ class Mythen3MasterAttributes : public MasterAttributes { { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "counter mask", PredType::STD_U32LE, dataspace); + "Counter Mask", PredType::STD_U32LE, dataspace); dataset.write(&counterMask, PredType::STD_U32LE); } // Exptime1 @@ -401,7 +473,7 @@ class Mythen3MasterAttributes : public MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("exposure time1", strdatatype, dataspace); + group->createDataSet("Exposure Time1", strdatatype, dataspace); dataset.write(sls::ToString(exptime1), strdatatype); } // Exptime2 @@ -409,7 +481,7 @@ class Mythen3MasterAttributes : public MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("exposure time2", strdatatype, dataspace); + group->createDataSet("Exposure Time2", strdatatype, dataspace); dataset.write(sls::ToString(exptime2), strdatatype); } // Exptime3 @@ -417,7 +489,7 @@ class Mythen3MasterAttributes : public MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("exposure time3", strdatatype, dataspace); + group->createDataSet("Exposure Time3", strdatatype, dataspace); dataset.write(sls::ToString(exptime3), strdatatype); } // GateDelay1 @@ -425,7 +497,7 @@ class Mythen3MasterAttributes : public MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("gate delay1", strdatatype, dataspace); + group->createDataSet("Gate Delay1", strdatatype, dataspace); dataset.write(sls::ToString(gateDelay1), strdatatype); } // GateDelay2 @@ -433,7 +505,7 @@ class Mythen3MasterAttributes : public MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("gate delay2", strdatatype, dataspace); + group->createDataSet("Gate Delay2", strdatatype, dataspace); dataset.write(sls::ToString(gateDelay2), strdatatype); } // GateDelay3 @@ -441,14 +513,14 @@ class Mythen3MasterAttributes : public MasterAttributes { DataSpace dataspace = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("gate delay3", strdatatype, dataspace); + group->createDataSet("Gate Delay3", strdatatype, dataspace); dataset.write(sls::ToString(gateDelay3), strdatatype); } // Gates { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = - group->createDataSet("gates", PredType::STD_U32LE, dataspace); + group->createDataSet("Gates", PredType::STD_U32LE, dataspace); dataset.write(&gates, PredType::STD_U32LE); } }; @@ -463,7 +535,9 @@ class Gotthard2MasterAttributes : public MasterAttributes { std::ostringstream oss; oss << MasterAttributes::GetBinaryMasterAttributes() << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n'; + << "Period : " << sls::ToString(period) << '\n' + << "Burst Mode : " << sls::ToString(burstMode) + << '\n'; std::string message = oss.str(); MasterAttributes::WriteBinaryAttributes(fd, message); }; @@ -473,6 +547,14 @@ class Gotthard2MasterAttributes : public MasterAttributes { MasterAttributes::WriteHDF5Attributes(fd, group); MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); + // burst mode + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Burst Mode", strdatatype, dataspace); + dataset.write(sls::ToString(burstMode), strdatatype); + } }; #endif }; @@ -488,7 +570,8 @@ class MoenchMasterAttributes : public MasterAttributes { << "Period : " << sls::ToString(period) << '\n' << "Ten Giga : " << tenGiga << '\n' << "ADC Mask : " << sls::ToStringHex(adcmask) - << '\n'; + << '\n' + << "Analog Samples : " << analogSamples << '\n'; std::string message = oss.str(); MasterAttributes::WriteBinaryAttributes(fd, message); }; @@ -503,9 +586,16 @@ class MoenchMasterAttributes : public MasterAttributes { { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "adc mask", PredType::NATIVE_INT, dataspace); + "ADC Mask", PredType::NATIVE_INT, dataspace); dataset.write(&adcmask, PredType::NATIVE_INT); } + // Analog Samples + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet( + "Analog Samples", PredType::NATIVE_INT, dataspace); + dataset.write(&analogSamples, PredType::NATIVE_INT); + } }; #endif }; @@ -523,7 +613,9 @@ class CtbMasterAttributes : public MasterAttributes { << "ADC Mask : " << sls::ToStringHex(adcmask) << '\n' << "Analog Flag : " << analog << '\n' + << "Analog Samples : " << analogSamples << '\n' << "Digital Flag : " << digital << '\n' + << "Digital Samples : " << digitalSamples << '\n' << "Dbit Offset : " << dbitoffset << '\n' << "Dbit Bitset : " << dbitlist << '\n'; std::string message = oss.str(); @@ -540,35 +632,49 @@ class CtbMasterAttributes : public MasterAttributes { { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "adc mask", PredType::NATIVE_INT, dataspace); + "ADC mMsk", PredType::NATIVE_INT, dataspace); dataset.write(&adcmask, PredType::NATIVE_INT); } // Analog Flag { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "analog flag", PredType::NATIVE_INT, dataspace); + "Analog Flag", PredType::NATIVE_INT, dataspace); dataset.write(&analog, PredType::NATIVE_INT); } + // Analog Samples + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet( + "Analog Samples", PredType::NATIVE_INT, dataspace); + dataset.write(&analogSamples, PredType::NATIVE_INT); + } // Digital Flag { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "digital flag", PredType::NATIVE_INT, dataspace); + "Digital Flag", PredType::NATIVE_INT, dataspace); dataset.write(&digital, PredType::NATIVE_INT); } + // Digital Samples + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet( + "Digital Samples", PredType::NATIVE_INT, dataspace); + dataset.write(&digitalSamples, PredType::NATIVE_INT); + } // Dbit Offset { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "dbit offset", PredType::NATIVE_INT, dataspace); + "Dbit Offset", PredType::NATIVE_INT, dataspace); dataset.write(&dbitoffset, PredType::NATIVE_INT); } // Dbit List { DataSpace dataspace = DataSpace(H5S_SCALAR); DataSet dataset = group->createDataSet( - "dbit bitset list", PredType::STD_U64LE, dataspace); + "Dbit Bitset List", PredType::STD_U64LE, dataspace); dataset.write(&dbitlist, PredType::STD_U64LE); } }; diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 41b0ac2ce..2fa9919fa 100644 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -404,60 +404,6 @@ typedef struct { enum timingSourceType { TIMING_INTERNAL, TIMING_EXTERNAL }; #ifdef __cplusplus - /** - * structure to udpate receiver - */ - struct rxParameters { - detectorType detType{GENERIC}; - xy numberOfDetector; - int moduleId{0}; - char hostname[MAX_STR_LENGTH]; - int udpInterfaces{1}; - int udp_dstport{0}; - uint32_t udp_dstip{0U}; - uint64_t udp_dstmac{0LU}; - int udp_dstport2{0}; - uint32_t udp_dstip2{0U}; - uint64_t udp_dstmac2{0LU}; - int64_t frames{0}; - int64_t triggers{0}; - int64_t bursts{0}; - int analogSamples{0}; - int digitalSamples{0}; - int64_t expTimeNs{0}; - int64_t periodNs{0}; - int64_t subExpTimeNs{0}; - int64_t subDeadTimeNs{0}; - int activate{0}; - int quad{0}; - int dynamicRange{16}; - timingMode timMode{AUTO_TIMING}; - int tenGiga{0}; - readoutMode roMode{ANALOG_ONLY}; - uint32_t adcMask{0}; - uint32_t adc10gMask{0}; - ROI roi; - uint32_t countermask{0}; - burstMode burstType{BURST_INTERNAL}; - int64_t expTime1Ns{0}; - int64_t expTime2Ns{0}; - int64_t expTime3Ns{0}; - int64_t gateDelay1Ns{0}; - int64_t gateDelay2Ns{0}; - int64_t gateDelay3Ns{0}; - int gates{0}; - } __attribute__((packed)); - - /** pattern structure */ - struct patternParameters { - uint64_t word[MAX_PATTERN_LENGTH]{}; - uint64_t patioctrl{0}; - uint32_t patlimits[2]{}; - uint32_t patloop[6]{}; - uint32_t patnloop[3]{}; - uint32_t patwait[3]{}; - uint64_t patwaittime[3]{}; - } __attribute__((packed)); /** scan structure */ struct scanParameters { @@ -488,6 +434,66 @@ typedef struct { (dacSettleTime_ns == other.dacSettleTime_ns)); } } __attribute__((packed)); + + /** + * structure to udpate receiver + */ + struct rxParameters { + detectorType detType{GENERIC}; + xy numberOfDetector; + int moduleId{0}; + char hostname[MAX_STR_LENGTH]; + int udpInterfaces{1}; + int udp_dstport{0}; + uint32_t udp_dstip{0U}; + uint64_t udp_dstmac{0LU}; + int udp_dstport2{0}; + uint32_t udp_dstip2{0U}; + uint64_t udp_dstmac2{0LU}; + int64_t frames{0}; + int64_t triggers{0}; + int64_t bursts{0}; + int additionalStorageCells{0}; + int analogSamples{0}; + int digitalSamples{0}; + int64_t expTimeNs{0}; + int64_t periodNs{0}; + int64_t subExpTimeNs{0}; + int64_t subDeadTimeNs{0}; + int activate{0}; + int quad{0}; + int numLinesReadout{0}; + int thresholdEnergyeV{0}; + int dynamicRange{16}; + timingMode timMode{AUTO_TIMING}; + int tenGiga{0}; + readoutMode roMode{ANALOG_ONLY}; + uint32_t adcMask{0}; + uint32_t adc10gMask{0}; + ROI roi; + uint32_t countermask{0}; + burstMode burstType{BURST_INTERNAL}; + int64_t expTime1Ns{0}; + int64_t expTime2Ns{0}; + int64_t expTime3Ns{0}; + int64_t gateDelay1Ns{0}; + int64_t gateDelay2Ns{0}; + int64_t gateDelay3Ns{0}; + int gates{0}; + scanParameters scanParams{}; + } __attribute__((packed)); + + /** pattern structure */ + struct patternParameters { + uint64_t word[MAX_PATTERN_LENGTH]{}; + uint64_t patioctrl{0}; + uint32_t patlimits[2]{}; + uint32_t patloop[6]{}; + uint32_t patnloop[3]{}; + uint32_t patwait[3]{}; + uint64_t patwaittime[3]{}; + } __attribute__((packed)); + #endif #ifdef __cplusplus diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index fc78512f3..a0f1d293e 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -312,6 +312,8 @@ enum detFuncs { F_GET_RECEIVER_STREAMING_START_FNUM, F_SET_RECEIVER_STREAMING_START_FNUM, F_SET_RECEIVER_RATE_CORRECT, + F_SET_RECEIVER_SCAN, + F_RECEIVER_SET_THRESHOLD, NUM_REC_FUNCTIONS }; @@ -625,6 +627,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_RECEIVER_STREAMING_START_FNUM: return "F_GET_RECEIVER_STREAMING_START_FNUM"; case F_SET_RECEIVER_STREAMING_START_FNUM: return "F_SET_RECEIVER_STREAMING_START_FNUM"; case F_SET_RECEIVER_RATE_CORRECT: return "F_SET_RECEIVER_RATE_CORRECT"; + case F_SET_RECEIVER_SCAN: return "F_SET_RECEIVER_SCAN"; + case F_RECEIVER_SET_THRESHOLD: return "F_RECEIVER_SET_THRESHOLD"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; default: return "Unknown Function"; diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index e9935ab9f..a69097365 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -40,6 +40,7 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) { << "frames:" << r.frames << std::endl << "triggers:" << r.triggers << std::endl << "bursts:" << r.bursts << std::endl + << "additionalStorageCells:" << r.additionalStorageCells << std::endl << "analogSamples:" << r.analogSamples << std::endl << "digitalSamples:" << r.digitalSamples << std::endl << "expTime:" << ToString(std::chrono::nanoseconds(r.expTimeNs)) @@ -52,6 +53,8 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) { << std::endl << "activate:" << r.activate << std::endl << "quad:" << r.quad << std::endl + << "numLinesReadout:" << r.numLinesReadout << std::endl + << "thresholdEnergyeV:" << r.thresholdEnergyeV << std::endl << "dynamicRange:" << r.dynamicRange << std::endl << "timMode:" << r.timMode << std::endl << "tenGiga:" << r.tenGiga << std::endl @@ -75,6 +78,7 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) { << "gateDelay3:" << ToString(std::chrono::nanoseconds(r.gateDelay3Ns)) << std::endl << "gates:" << r.gates << std::endl + << "scanParams:" << sls::ToString(r.scanParams) << std::endl << ']'; return oss.str(); }