diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 37d8887d2..c85348339 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -1803,29 +1803,31 @@ int setVetoPhoton(int chipIndex, int gainIndex, int *values) { ("Setting veto photon [chip:%d, G%d]\n", chipIndex, gainIndex)); // add gain bits - { - int gainValue = 0; - switch (gainIndex) { - case 0: - gainValue = ASIC_G0_VAL; - break; - case 1: - gainValue = ASIC_G1_VAL; - break; - case 2: - gainValue = ASIC_G2_VAL; - break; - default: - LOG(logERROR, ("Unknown gain index %d\n", gainIndex)); - return FAIL; - } - LOG(logDEBUG2, ("Adding gain bits\n")); - for (int i = 0; i < NCHAN; ++i) { - values[i] |= gainValue; - LOG(logDEBUG2, ("Value %d: 0x%x\n", i, values[i])); - } + int gainValue = 0; + switch (gainIndex) { + case 0: + gainValue = ASIC_G0_VAL; + break; + case 1: + gainValue = ASIC_G1_VAL; + break; + case 2: + gainValue = ASIC_G2_VAL; + break; + default: + LOG(logERROR, ("Unknown gain index %d\n", gainIndex)); + return FAIL; + } + LOG(logDEBUG2, ("Adding gain bits\n")); + for (int i = 0; i < NCHAN; ++i) { + values[i] |= gainValue; + LOG(logDEBUG2, ("Value %d: 0x%x\n", i, values[i])); } + return configureASICVetoReference(chipIndex, values); +} + +int configureASICVetoReference(int chipIndex, int *values) { const int lenDataBitsPerchannel = ASIC_GAIN_MAX_BITS + ADU_MAX_BITS; // 14 const int lenBits = lenDataBitsPerchannel * NCHAN; // 1792 const int padding = 4; // due to address (4) to make it byte aligned @@ -1906,6 +1908,32 @@ int getVetoPhoton(int chipIndex, int *retvals) { return OK; } +int setVetoFile(int chipIndex, int *gainIndices, int *values) { + LOG(logINFO, ("Setting veto file [chip:%d]\n", chipIndex)); + + // correct gain bits and integrate into values + for (int i = 0; i < NCHAN; ++i) { + switch (gainIndices[i]) { + case 0: + gainIndices[i] = ASIC_G0_VAL; + break; + case 1: + gainIndices[i] = ASIC_G1_VAL; + break; + case 2: + gainIndices[i] = ASIC_G2_VAL; + break; + default: + LOG(logERROR, + ("Unknown gain index %d for channel %d\n", gainIndices[i], i)); + return FAIL; + } + values[i] |= gainIndices[i]; + LOG(logDEBUG2, ("Values[%d]: 0x%x\n", i, values[i])); + } + return configureASICVetoReference(chipIndex, values); +} + int configureSingleADCDriver(int chipIndex) { LOG(logINFO, ("Configuring ADC for %s chips [chipIndex:%d Burst Mode:%d]\n", chipIndex == -1 ? "All" : "Single", chipIndex, burstMode)); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 274ffa1ed..f86431a4b 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -504,7 +504,9 @@ int setInjectChannel(int offset, int increment); void getInjectedChannels(int *offset, int *increment); int setVetoReference(int gainIndex, int value); int setVetoPhoton(int chipIndex, int gainIndex, int *values); +int configureASICVetoReference(int chipIndex, int *values); int getVetoPhoton(int chipIndex, int *retvals); +int setVetoFile(int chipIndex, int *gainIndices, int *values); int configureSingleADCDriver(int chipIndex); int configureADC(); int setBurstModeinFPGA(enum burstMode value); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index a68d18d17..cc0f1ba52 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -233,3 +233,4 @@ int get_cds_gain(int); int set_cds_gain(int); int get_filter(int); int set_filter(int); +int set_veto_file(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 4e2b6dff3..81e8b95f5 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -350,6 +350,7 @@ void function_table() { flist[F_SET_CDS_GAIN] = &set_cds_gain; flist[F_GET_FILTER] = &get_filter; flist[F_SET_FILTER] = &set_filter; + flist[F_SET_VETO_FILE] = &set_veto_file; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -6319,6 +6320,7 @@ int set_veto_photon(int file_des) { if (receiveData(file_des, args, sizeof(args), INT32) < 0) return printSocketReadError(); int values[args[2]]; + memset(values, 0, sizeof(values)); if (receiveData(file_des, values, sizeof(values), INT32) < 0) return printSocketReadError(); LOG(logINFO, ("Setting Veto Photon: [chipIndex:%d, G%d, nch:%d]\n", args[0], @@ -6356,7 +6358,7 @@ int set_veto_photon(int file_des) { sprintf(mess, "Could not set veto photon. Invalid ADU value 0x%x " "for channel %d, must be 12 bit.\n", - i, values[i]); + values[i], i); LOG(logERROR, (mess)); break; } @@ -7746,3 +7748,75 @@ int set_filter(int file_des) { #endif return Server_SendResult(file_des, INT32, NULL, 0); } + +int set_veto_file(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + int chipIndex = args[0]; + int nch = args[1]; + int gainIndices[nch]; + memset(gainIndices, 0, sizeof(gainIndices)); + int values[nch]; + memset(values, 0, sizeof(values)); + if (receiveData(file_des, gainIndices, sizeof(gainIndices), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, values, sizeof(values), INT32) < 0) + return printSocketReadError(); + LOG(logINFO, + ("Setting Veto file: [chipIndex:%d, nch:%d]\n", chipIndex, nch)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + if (chipIndex < -1 || chipIndex >= NCHIP) { + ret = FAIL; + sprintf(mess, "Could not set veto file. Invalid chip index %d\n", + chipIndex); + LOG(logERROR, (mess)); + } else if (nch != NCHAN) { + ret = FAIL; + sprintf(mess, + "Could not set veto file. Invalid number of channels %d. " + "Expected %d\n", + nch, NCHAN); + LOG(logERROR, (mess)); + } else { + for (int i = 0; i < NCHAN; ++i) { + if (values[i] < 0 || values[i] > ADU_MAX_VAL) { + ret = FAIL; + sprintf(mess, + "Could not set veto file. Invalid ADU value 0x%x " + "for channel %d, must be 12 bit.\n", + values[i], i); + LOG(logERROR, (mess)); + break; + } + if (gainIndices[i] < 0 || gainIndices[i] > 2) { + ret = FAIL; + sprintf(mess, + "Could not set veto file. Invalid gain index %d " + "for channel %d\n", + gainIndices[i], i); + LOG(logERROR, (mess)); + break; + } + } + if (ret == OK) { + ret = setVetoFile(chipIndex, gainIndices, values); + if (ret == FAIL) { + sprintf(mess, "Could not set veto file for chip index %d\n", + chipIndex); + LOG(logERROR, (mess)); + } + } + } + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} \ No newline at end of file diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index ebc08e2b7..d9c38c950 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -983,6 +983,10 @@ class Detector { void setVetoReference(const int gainIndex, const int value, Positions pos = {}); + /** [Gotthard2] */ + void setVetoFile(const int chipIndex, const std::string &fname, + Positions pos = {}); + /** [Gotthard2] */ Result getBurstMode(Positions pos = {}); diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 99f811e5c..9f00b1966 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1669,6 +1669,29 @@ std::string CmdProxy::VetoReference(int action) { return os.str(); } +std::string CmdProxy::VetoFile(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[chip index 0-10, -1 for all] [file name] \n\t[Gotthard2] Set " + "veto reference for each 128 channels for specific chip. The " + "file should have 128 rows of gain index and 12 bit value in hex" + << '\n'; + } else if (action == defs::GET_ACTION) { + throw sls::RuntimeError( + "cannot get vetofile. Did you mean vetophoton?"); + } else if (action == defs::PUT_ACTION) { + if (args.size() != 2) { + WrongNumberOfParameters(2); + } + det->setVetoFile(StringTo(args[0]), args[1], {det_id}); + os << sls::ToString(args) << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + std::string CmdProxy::BurstMode(int action) { std::ostringstream os; os << cmd << ' '; diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 3acd49f40..fc09ae484 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -834,6 +834,7 @@ class CmdProxy { {"inj_ch", &CmdProxy::InjectChannel}, {"vetophoton", &CmdProxy::VetoPhoton}, {"vetoref", &CmdProxy::VetoReference}, + {"vetofile", &CmdProxy::VetoFile}, {"burstmode", &CmdProxy::BurstMode}, {"cdsgain", &CmdProxy::cdsgain}, {"filter", &CmdProxy::filter}, @@ -1015,6 +1016,7 @@ class CmdProxy { std::string InjectChannel(int action); std::string VetoPhoton(int action); std::string VetoReference(int action); + std::string VetoFile(int action); std::string BurstMode(int action); /* Mythen3 Specific */ std::string Counters(int action); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 9295cf87b..cc63db8d9 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1297,6 +1297,11 @@ void Detector::setVetoReference(const int gainIndex, const int value, pimpl->Parallel(&Module::setVetoReference, pos, gainIndex, value); } +void Detector::setVetoFile(const int chipIndex, const std::string &fname, + Positions pos) { + pimpl->Parallel(&Module::setVetoFile, pos, chipIndex, fname); +} + Result Detector::getBurstMode(Positions pos) { return pimpl->Parallel(&Module::getBurstMode, pos); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 4ae008d31..d62d47a8d 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1521,6 +1521,82 @@ void Module::setVetoReference(const int gainIndex, const int value) { sendToDetector(F_SET_VETO_REFERENCE, args, nullptr); } +void Module::setVetoFile(const int chipIndex, const std::string &fname) { + if (shm()->myDetectorType != GOTTHARD2) { + throw RuntimeError( + "Set Veto file is not implemented for this detector"); + } + if (chipIndex < -1 || chipIndex >= shm()->nChip.x) { + throw RuntimeError("Could not set veto file. Invalid chip index: " + + std::to_string(chipIndex)); + } + std::ifstream infile(fname.c_str()); + if (!infile.is_open()) { + throw RuntimeError("Could not set veto file for chip " + + std::to_string(chipIndex) + + ". Could not open file: " + fname); + } + + std::ifstream input_file(fname); + if (!input_file.is_open()) { + throw RuntimeError("Could not open veto file " + fname + + " for reading"); + } + + int ch = shm()->nChan.x; + int nRead = 0; + int gainIndices[ch]; + memset(gainIndices, 0, sizeof(gainIndices)); + int values[ch]; + memset(values, 0, sizeof(values)); + + for (std::string line; std::getline(input_file, line);) { + if (line.find('#') != std::string::npos) { + line.erase(line.find('#')); + } + LOG(logDEBUG1) << "line after removing comments:\n\t" << line; + if (line.length() > 1) { + // convert command and string to a vector + std::istringstream iss(line); + std::string val; + if (!(iss >> gainIndices[nRead] >> val)) { + throw RuntimeError("Could not set veto file. Invalid gain " + "or reference value for channel " + + std::to_string(nRead)); + } + try { + values[nRead] = StringTo(val); + } catch (...) { + throw RuntimeError("Could not set veto file. Invalid value " + + val + " for channel " + + std::to_string(nRead)); + } + ++nRead; + if (nRead >= ch) { + break; + } + } + } + + int fnum = F_SET_VETO_FILE; + int ret = FAIL; + int args[]{chipIndex, ch}; + LOG(logDEBUG) << "Sending veto file value to detector [chip:" << chipIndex + << "]: " << args; + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.Send(&fnum, sizeof(fnum)); + client.Send(args, sizeof(args)); + client.Send(gainIndices, sizeof(gainIndices)); + client.Send(values, sizeof(values)); + client.Receive(&ret, sizeof(ret)); + if (ret == FAIL) { + char mess[MAX_STR_LENGTH]{}; + client.Receive(mess, MAX_STR_LENGTH); + throw RuntimeError("Detector " + std::to_string(moduleId) + + " returned error: " + std::string(mess)); + } +} + slsDetectorDefs::burstMode Module::getBurstMode() { auto r = sendToDetector(F_GET_BURST_MODE); return static_cast(r); diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 684bc06f3..971bd40ff 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -373,6 +373,7 @@ class Module : public virtual slsDetectorDefs { void setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string &fname); void setVetoReference(const int gainIndex, const int value); + void setVetoFile(const int chipIndex, const std::string &fname); burstMode getBurstMode(); void setBurstMode(burstMode value); bool getCDSGain(); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp index 46fdd9551..af4baab6c 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp @@ -343,6 +343,20 @@ TEST_CASE("vetoref", "[.cmd][.new]") { } } +TEST_CASE("vetofile", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + + if (det_type == defs::GOTTHARD2) { + REQUIRE_THROWS(proxy.Call("vetofile", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vetofile", {"12", "/tmp/bla.txt"}, -1, + PUT)); // invalid chip index + } else { + REQUIRE_THROWS(proxy.Call("vetofile", {"-1"}, -1, GET)); + } +} + TEST_CASE("burstmode", "[.cmd][.new]") { Detector det; CmdProxy proxy(&det); diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index cf7195407..10f4e2a3e 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -207,6 +207,7 @@ enum detFuncs { F_SET_CDS_GAIN, F_GET_FILTER, F_SET_FILTER, + F_SET_VETO_FILE, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -512,6 +513,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_CDS_GAIN: return "F_SET_CDS_GAIN"; case F_GET_FILTER: return "F_GET_FILTER"; case F_SET_FILTER: return "F_SET_FILTER"; + case F_SET_VETO_FILE: return "F_SET_VETO_FILE"; + case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";