diff --git a/examples/gotthard2_veto_photon.txt b/examples/gotthard2_veto_photon.txt new file mode 100644 index 000000000..b75b2002b --- /dev/null +++ b/examples/gotthard2_veto_photon.txt @@ -0,0 +1,132 @@ +#G1 Energy #G2 Energy +300 7000 + +#G0 pedestal G1 pedestal G2 pedestal G0 gain G1 gain G2 gain (for every channel) ADU +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 +100 100 100 10 1 0.1 diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index c4389e6ff..420371f3d 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index b743f10a7..720afaea6 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -43,6 +43,7 @@ int defaultDacValues[NDAC] = {0}; int defaultOnChipdacValues[ONCHIP_NDAC][NCHIP] = {0}; int injectedChannelsOffset = 0; int injectedChannelsIncrement = 0; +int vetoReference[NCHIP][NCHAN]; int detPos[2] = {0, 0}; int isInitCheckDone() { @@ -334,9 +335,13 @@ void setupDetector() { clkFrequency[SYSTEM_C1] = DEFAULT_SYSTEM_C1; clkFrequency[SYSTEM_C2] = DEFAULT_SYSTEM_C2; clkFrequency[SYSTEM_C3] = DEFAULT_SYSTEM_C3; - + detPos[0] = 0; + detPos[1] = 0; highvoltage = 0; + injectedChannelsOffset = 0; + injectedChannelsIncrement = 0; + { int i, j; for (i = 0; i < NUM_CLOCKS; ++i) { @@ -344,11 +349,19 @@ void setupDetector() { } for (i = 0; i < NDAC; ++i) { dacValues[i] = 0; + defaultDacValues[i] = 0; } for (i = 0; i < ONCHIP_NDAC; ++i) { - for (j = 0; j < NCHIP; ++j) - onChipdacValues[i][j] = -1; - } + for (j = 0; j < NCHIP; ++j) { + onChipdacValues[i][j] = -1; + defaultOnChipdacValues[i][j] = -1; + } + } + for (i = 0; i < NCHIP; ++i) { + for (j = 0; j < NCHAN; ++j) { + vetoReference[i][j] = 0; + } + } } @@ -1097,6 +1110,111 @@ void getInjectedChannels(int* offset, int* increment) { *increment = injectedChannelsIncrement; } +int setVetoPhoton(int chipIndex, int gainIndex, int* values) { + FILE_LOG(logINFO, ("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: + FILE_LOG(logERROR, ("Unknown gain index %d\n", gainIndex)); + return FAIL; + } + FILE_LOG(logDEBUG1, ("Adding gain bits\n")); + int i = 0; + for (i = 0; i < NCHAN; ++i) { + values[i] |= gainValue; + FILE_LOG(logDEBUG1, ("Value %d: 0x%x\n", i, values[i])); + } + } + // create command + const int lenAduBits = ASIC_GAIN_MAX_BITS + ADU_MAX_BITS; + const int lenBits = lenAduBits * NCHAN; + const int len = lenBits / 8; + char buffer[len]; + memset(buffer, 0, len); + int iBit = 4; // 4 due to padding + int ich = 0; + for (ich = 0; ich < NCHAN; ++ich) { + // copy 14 bits for each channel + int totalToCopy = lenAduBits; + while (totalToCopy > 0) { + int byteIndex = iBit / 8; + int bitIndex = iBit % 8; + // how much to copy in a byte + int toCopy = 8 - bitIndex; + if (toCopy > totalToCopy) { + toCopy = totalToCopy; + } + int copyMask = (1 << toCopy) - 1; + // value pushed out by whats left and masked + int val = (values[ich] >> (totalToCopy - toCopy)) & copyMask; + if (toCopy + bitIndex != 8) { + val = val << (8 - bitIndex - toCopy); + } + buffer[byteIndex] |= val; + // incrememnt indices + iBit += toCopy; + totalToCopy -= toCopy; + } + } + + // address at the end + buffer[16] |= (ASIC_VETO_REF_ADDR); + + if (ASIC_Driver_Set(chipIndex, sizeof(buffer), buffer) == FAIL) { + return FAIL; + } + + // all chips + if (chipIndex == -1) { + int ichip = 0; + int ichan = 0; + for (ichan = 0; ichan < NCHAN; ++ichan) { + for (ichip = 0; ichip < NCHIP; ++ichip) { + vetoReference[ichip][ichan] = values[ichan]; + } + } + } + + // specific chip + else { + int ichan = 0; + for (ichan = 0; ichan < NCHAN; ++ichan) { + vetoReference[chipIndex][chipIndex] = values[ichan];; + } + } + return OK; +} + +int getVetoPhoton(int chipIndex, int* retvals) { + if (chipIndex == -1) { + int i = 0, j = 0; + for (i = 0; i < NCHAN; ++i) { + int val = vetoReference[0][i]; + for (j = 1; j < NCHIP; ++j) { + if (vetoReference[j][i] != val) { + FILE_LOG(logERROR, ("Get vet photon fail for chipIndex:%d. Different values between [nchip:%d, nchan:%d, value:%d] and [nchip:0, nchan:%d, value:%d]\n", chipIndex, j, i, vetoReference[j][i], i, val)); + return FAIL; + } + } + } + chipIndex = 0; + } + memcpy((char*)retvals, ((char*)vetoReference) + NCHAN * chipIndex * sizeof(int), sizeof(int) * NCHAN); + return OK; +} + /* aquisition */ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index 256e9a226..7345019ac 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -19,6 +19,9 @@ #define CONFIG_FILE ("config.txt") #define DAC_MAX_MV (2048) #define ONCHIP_DAC_MAX_VAL (0x3FF) +#define ADU_MAX_VAL (0xFFF) +#define ADU_MAX_BITS (12) + /** Default Parameters */ #define DEFAULT_NUM_FRAMES (1) @@ -38,7 +41,6 @@ #define READOUT_PLL_VCO_FREQ_HZ (866666688) // Hz #define SYSTEM_PLL_VCO_FREQ_HZ (722222240) // Hz - /** Other Definitions */ #define BIT16_MASK (0xFFFF) @@ -81,7 +83,13 @@ enum PLLINDEX {READOUT_PLL, SYSTEM_PLL}; /** Chip Definitions */ #define ASIC_CURRENT_INJECT_ADDR (0x9) +#define ASIC_VETO_REF_ADDR (0xA) +#define ASIC_GAIN_MAX_BITS (2) +#define ASIC_GAIN_MSK (0x3) +#define ASIC_G0_VAL ((0x0 & ASIC_GAIN_MSK) << ADU_MAX_BITS) +#define ASIC_G1_VAL ((0x1 & ASIC_GAIN_MSK) << ADU_MAX_BITS) +#define ASIC_G2_VAL ((0x3 & ASIC_GAIN_MSK) << ADU_MAX_BITS) /* Struct Definitions */ typedef struct udp_header_struct { diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 7a8040e0e..13d10f8a1 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -450,6 +450,8 @@ int setClockDivider(enum CLKINDEX ind, int val); int getClockDivider(enum CLKINDEX ind); int setInjectChannel(int offset, int increment); void getInjectedChannels(int* offset, int* increment); +int setVetoPhoton(int chipIndex, int gainIndex, int* values); +int getVetoPhoton(int chipIndex, int* retvals); #endif diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index c7ec163fc..3b6a7e91e 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -196,4 +196,6 @@ int get_pipeline(int); int set_on_chip_dac(int); int get_on_chip_dac(int); int set_inject_channel(int); -int get_inject_channel(int); \ No newline at end of file +int get_inject_channel(int); +int set_veto_photon(int); +int get_veto_photon(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c b/slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c index 3f1368952..96d79dabf 100755 --- a/slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c +++ b/slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c @@ -83,8 +83,8 @@ int ALTERA_PLL_C10_GetMaxPhaseShiftStepsofVCO() { int ALTERA_PLL_C10_Reconfigure(int pllIndex) { FILE_LOG(logINFO, ("\tReconfiguring PLL %d\n", pllIndex)); - uint32_t waitreg = ALTERA_PLL_C10_Wait_Reg[pllIndex]; - uint32_t waitmsk = ALTERA_PLL_C10_Wait_Msk[pllIndex]; + //uint32_t waitreg = ALTERA_PLL_C10_Wait_Reg[pllIndex]; + //uint32_t waitmsk = ALTERA_PLL_C10_Wait_Msk[pllIndex]; // write anything to base address to start reconfiguring FILE_LOG(logDEBUG1, ("\tWriting 1 to base address 0x%x to start reconfiguring\n", ALTERA_PLL_C10_BaseAddress[pllIndex])); @@ -115,8 +115,8 @@ int ALTERA_PLL_C10_Reconfigure(int pllIndex) { void ALTERA_PLL_C10_ResetPLL (int pllIndex) { FILE_LOG(logINFO, ("Resetting PLL %d\n", pllIndex)); - uint32_t resetreg = ALTERA_PLL_C10_Reset_Reg[pllIndex]; - uint32_t resetmsk = ALTERA_PLL_C10_Reset_Msk[pllIndex]; + //uint32_t resetreg = ALTERA_PLL_C10_Reset_Reg[pllIndex]; + //uint32_t resetmsk = ALTERA_PLL_C10_Reset_Msk[pllIndex]; FILE_LOG(logERROR, ("Reset not implemented yet!\n")); /* TODO reset reg and reset mask to be done in firware, so wait instead (above) diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index dcde8320a..427bf67cd 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -298,6 +298,8 @@ const char* getFunctionName(enum detFuncs func) { case F_GET_ON_CHIP_DAC: return "F_GET_ON_CHIP_DAC"; case F_SET_INJECT_CHANNEL: return "F_SET_INJECT_CHANNEL"; case F_GET_INJECT_CHANNEL: return "F_GET_INJECT_CHANNEL"; + case F_SET_VETO_PHOTON: return "F_SET_VETO_PHOTON"; + case F_GET_VETO_PHOTON: return "F_GET_VETO_PHOTON"; default: return "Unknown Function"; } @@ -473,7 +475,9 @@ void function_table() { flist[F_GET_ON_CHIP_DAC] = &get_on_chip_dac; flist[F_SET_INJECT_CHANNEL] = &set_inject_channel; flist[F_GET_INJECT_CHANNEL] = &get_inject_channel; - + flist[F_SET_VETO_PHOTON] = &set_veto_photon; + flist[F_GET_VETO_PHOTON] = &get_veto_photon; + // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { FILE_LOG(logERROR, ("The last detector function enum has reached its limit\nGoodbye!\n")); @@ -6176,7 +6180,6 @@ int set_inject_channel(int file_des) { } else { ret = setInjectChannel(offset, increment); if (ret == FAIL) { - ret = FAIL; strcpy(mess, "Could not inject channel\n"); FILE_LOG(logERROR, (mess)); } @@ -6206,3 +6209,102 @@ int get_inject_channel(int file_des) { #endif return Server_SendResult(file_des, INT32, UPDATE, retvals, sizeof(retvals)); } + + +int set_veto_photon(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[3] = {-1, -1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + int values[args[2]]; + if (receiveData(file_des, values, sizeof(values), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logINFO, ("Setting Veto Photon: [chipIndex:%d, G%d, nch:%d]\n", args[0], args[1], args[2])); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + int chipIndex = args[0]; + int gainIndex = args[1]; + int numChannels = args[2]; + if (chipIndex < -1 || chipIndex >= NCHIP) { + ret = FAIL; + sprintf(mess, "Could not set veto photon. Invalid chip index %d\n", chipIndex); + FILE_LOG(logERROR, (mess)); + } else if (gainIndex < 0 || gainIndex > 2) { + ret = FAIL; + sprintf(mess, "Could not set veto photon. Invalid gain index %d\n", gainIndex); + FILE_LOG(logERROR, (mess)); + } else if (numChannels != NCHAN) { + ret = FAIL; + sprintf(mess, "Could not set veto photon. Invalid number of channels %d. Expected %d\n", numChannels, NCHAN); + FILE_LOG(logERROR, (mess)); + } else { + int i = 0; + for (i = 0; i < NCHAN; ++i) { + if (values[i] > ADU_MAX_VAL) { + ret = FAIL; + sprintf(mess, "Could not set veto photon. Invalid ADU value 0x%x for channel %d, must be 12 bit.\n", i, values[i]); + FILE_LOG(logERROR, (mess)); + break; + } + } + if (ret == OK) { + ret = setVetoPhoton(chipIndex, gainIndex, values); + if (ret == FAIL) { + sprintf(mess, "Could not set veto photon for chip index %d\n", chipIndex); + FILE_LOG(logERROR, (mess)); + } + } + } + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); +} + + +int get_veto_photon(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retvals[NCHAN]; + memset(retvals, 0, sizeof(retvals)); + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG1, ("Getting veto photon [chip Index:%d]\n", arg)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + int chipIndex = arg; + if (chipIndex < -1 || chipIndex >= NCHIP) { + ret = FAIL; + sprintf(mess, "Could not get veto photon. Invalid chip index %d\n", chipIndex); + FILE_LOG(logERROR, (mess)); + } else { + ret = getVetoPhoton(chipIndex, retvals); + if (ret == FAIL) { + strcpy(mess, "Could not get veto photon for chipIndex -1. Not the same for all chips.\n"); + FILE_LOG(logERROR, (mess)); + } else { + int i = 0; + for (i = 0; i < NCHAN; ++i) { + FILE_LOG(logDEBUG1, ("%d:0x%x\n", i, retvals[i])); + } + } + } +#endif + Server_SendResult(file_des, INT32, UPDATE, NULL, 0); + if (ret != FAIL) { + int nch = NCHAN; + sendData(file_des, &nch, sizeof(nch), INT32); + sendData(file_des, retvals, sizeof(retvals), INT32); + } + return ret; +} \ No newline at end of file diff --git a/slsDetectorSoftware/include/CmdProxy.h b/slsDetectorSoftware/include/CmdProxy.h index 9eaac65f1..599270807 100644 --- a/slsDetectorSoftware/include/CmdProxy.h +++ b/slsDetectorSoftware/include/CmdProxy.h @@ -777,6 +777,7 @@ class CmdProxy { /* Gotthard2 Specific */ {"inj_ch", &CmdProxy::InjectChannel}, + {"vetophoton", &CmdProxy::VetoPhoton}, /* CTB Specific */ {"samples", &CmdProxy::Samples}, @@ -925,7 +926,8 @@ class CmdProxy { std::string ROI(int action); std::string ClearROI(int action); /* Gotthard2 Specific */ - std::string InjectChannel(int action); + std::string InjectChannel(int action); + std::string VetoPhoton(int action); /* CTB Specific */ std::string Samples(int action); std::string Dbitphase(int action); diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index 6101b49ac..d0dc6dd09 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -881,10 +881,17 @@ class Detector { /** [Gotthard2] offset channel, increment channel */ Result> getInjectChannel(Positions pos = {}); + /** [Gotthard2] * @param offsetChannel starting channel to be injected * @param incrementChannel determines succeeding channels to be injected */ - void setInjectChannel(int offsetChannel, int incrementChannel, Positions pos = {}); + void setInjectChannel(const int offsetChannel, const int incrementChannel, Positions pos = {}); + + /** [Gotthard2] adu values for each channel */ + Result> getVetoPhoton(const int chipIndex, Positions pos = {}); + + /** [Gotthard2] energy in keV */ + void setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string& fname, Positions pos = {}); /************************************************** * * diff --git a/slsDetectorSoftware/include/slsDetector.h b/slsDetectorSoftware/include/slsDetector.h index a4c259f53..55862ae65 100755 --- a/slsDetectorSoftware/include/slsDetector.h +++ b/slsDetectorSoftware/include/slsDetector.h @@ -1109,8 +1109,13 @@ class slsDetector : public virtual slsDetectorDefs { /** [Gotthard2] * @param offsetChannel starting channel to be injected * @param incrementChannel determines succeeding channels to be injected */ - void setInjectChannel(int offsetChannel, int incrementChannel); + void setInjectChannel(const int offsetChannel, const int incrementChannel); + /** [Gotthard2] asic input */ + std::vector getVetoPhoton(const int chipIndex); + + /** [Gotthard2] energy in keV */ + void setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string& fname); /** * Set/get counter bit in detector (Gotthard) * @param i is -1 to get, 0 to reset and any other value to set the counter diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 747888ee0..f00e37d7e 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1035,7 +1035,7 @@ std::string CmdProxy::InjectChannel(int action) { if (args.size() != 2) { WrongNumberOfParameters(2); } - det->setInjectChannel(std::stoi(args[0]), std::stoi(args[1]),{det_id}); + det->setInjectChannel(std::stoi(args[0]), std::stoi(args[1]), {det_id}); os << sls::ToString(args) << '\n'; } else { throw sls::RuntimeError("Unknown action"); @@ -1043,6 +1043,28 @@ std::string CmdProxy::InjectChannel(int action) { return os.str(); } +std::string CmdProxy::VetoPhoton(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[n_chip] [#photons] [energy in keV] [reference file]\n\t[Gotthard2] Set veto reference for 128 channels for chip n_chip according to referenc file and #photons and energy in keV." << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + auto t = det->getVetoPhoton(std::stoi(args[0]), {det_id}); + os << args[0] << ' ' << OutStringHex(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + if (args.size() != 4) { + WrongNumberOfParameters(4); + } + det->setVetoPhoton(std::stoi(args[0]), std::stoi(args[1]), std::stoi(args[2]), args[3], {det_id}); + os << sls::ToString(args) << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} /* CTB Specific */ diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index cd7cacb94..038bc33a5 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1092,10 +1092,18 @@ Result> Detector::getInjectChannel(Positions pos) { return pimpl->Parallel(&slsDetector::getInjectChannel, pos); } -void Detector::setInjectChannel(int offsetChannel, int incrementChannel, Positions pos) { +void Detector::setInjectChannel(const int offsetChannel, const int incrementChannel, Positions pos) { pimpl->Parallel(&slsDetector::setInjectChannel, pos, offsetChannel, incrementChannel); } +Result> Detector::getVetoPhoton(const int chipIndex, Positions pos) { + return pimpl->Parallel(&slsDetector::getVetoPhoton, pos, chipIndex); +} + +void Detector::setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string& fname, Positions pos) { + pimpl->Parallel(&slsDetector::setVetoPhoton, pos, chipIndex, numPhotons, energy, fname); +} + // CTB Specific Result Detector::getNumberOfAnalogSamples(Positions pos) const { diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index dded9c63a..eb14dacff 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -2352,12 +2352,129 @@ std::array slsDetector::getInjectChannel() { return retvals; } -void slsDetector::setInjectChannel(int offsetChannel, int incrementChannel) { +void slsDetector::setInjectChannel(const int offsetChannel, const int incrementChannel) { int args[]{offsetChannel, incrementChannel}; FILE_LOG(logDEBUG1) << "Setting inject channels [offset: " << offsetChannel << ", increment: " << incrementChannel << ']'; sendToDetector(F_SET_INJECT_CHANNEL, args, nullptr); } +std::vector slsDetector::getVetoPhoton(const int chipIndex) { + int fnum = F_GET_VETO_PHOTON; + int ret = FAIL; + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.Send(&fnum, sizeof(fnum)); + client.Send(&chipIndex, sizeof(chipIndex)); + 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(detId) + + " returned error: " + std::string(mess)); + } else { + int nch = -1; + client.Receive(&nch, sizeof(nch)); + + int adus[nch]; + memset(adus, 0, sizeof(adus)); + client.Receive(adus, sizeof(adus)); + std::vector retvals(adus, adus + nch); + FILE_LOG(logDEBUG1) << "Getting veto photon [" << chipIndex << "]: " << nch << " channels\n"; + if (ret == FORCE_UPDATE) { + updateCachedDetectorVariables(); + } + return retvals; + } +} + +void slsDetector::setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string& fname) { + if (shm()->myDetectorType != GOTTHARD2) { + throw RuntimeError("Set Veto reference is not implemented for this detector"); + } + if (chipIndex < -1 || chipIndex >= shm()->nChip.x) { + throw RuntimeError("Could not set veto photon. Invalid chip index: " + std::to_string(chipIndex)); + } + if (numPhotons < 1) { + throw RuntimeError("Could not set veto photon. Invalid number of photons: " + std::to_string(numPhotons)); + } + if (energy < 1) { + throw RuntimeError("Could not set veto photon. Invalid energy: " + std::to_string(energy)); + } + std::ifstream infile(fname.c_str()); + if (!infile.is_open()) { + throw RuntimeError("Could not set veto photon. Could not open file: " + fname); + } + + int totalEnergy = numPhotons * energy; + int ch = shm()->nChan.x; + int gainIndex = 2; + int nRead = 0; + int value[ch]; + memset(value, 0, sizeof(value)); + bool firstLine = true; + + while (infile.good()) { + std::string line; + getline(infile, line); + if (line.find('#') != std::string::npos) { + line.erase(line.find('#')); + } + if (line.length() < 1) { + continue; + } + std::istringstream ss(line); + // first line: caluclate gain index from gain thresholds from file + if (firstLine) { + int g0 = -1, g1 = -1; + if (!(ss >> g0 >> g1)) { + throw RuntimeError("Could not set veto photon. Invalid gain thresholds"); + } + // set gain index and gain bit values + if (totalEnergy < g0) { + gainIndex = 0; + } else if (totalEnergy < g1) { + gainIndex = 1; + } + FILE_LOG(logINFO) << "Setting veto photon. Reading Gain " << gainIndex << " values"; + firstLine = false; + } + // read pedestal and gain values + else { + double p[3] = {-1, -1, -1}, g[3] = {-1, -1, -1}; + if (!(ss >> p[0] >> p[1] >> p[2] >> g[0] >> g[1] >> g[2])) { + throw RuntimeError("Could not set veto photon. Invalid pedestal or gain values for channel " + std::to_string(nRead)); + } + value[nRead] = p[gainIndex] + (g[gainIndex] * totalEnergy); //ADU value = pedestal + gain * total energy + ++nRead; + if (nRead >= ch) { + break; + } + } + } + if (nRead != ch) { + throw RuntimeError("Could not set veto photon. Insufficient pedestal pr gain values: " + std::to_string(nRead)); + } + + int fnum = F_SET_VETO_PHOTON; + int ret = FAIL; + int args[]{chipIndex, gainIndex, ch}; + FILE_LOG(logDEBUG) << "Sending veto photon value to detector [chip:" << chipIndex << ", G" << gainIndex << "]: " << args; + auto client = DetectorSocket(shm()->hostname, shm()->controlPort); + client.Send(&fnum, sizeof(fnum)); + client.Send(args, sizeof(args)); + client.Send(value, sizeof(value)); + 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(detId) + + " returned error: " + std::string(mess)); + } else { + if (ret == FORCE_UPDATE) { + updateCachedDetectorVariables(); + } + } +} + int slsDetector::setCounterBit(int cb) { int retval = -1; FILE_LOG(logDEBUG1) << "Sending counter bit " << cb; diff --git a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp index e41ba2a95..cf144fc85 100644 --- a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp +++ b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp @@ -9,6 +9,20 @@ auto GET = slsDetectorDefs::GET_ACTION; auto PUT = slsDetectorDefs::PUT_ACTION; +TEST_CASE("vetophoton", "[.cmd][.gotthard2]") { + if (test::type == slsDetectorDefs::GOTTHARD2) { + REQUIRE_THROWS(multiSlsDetectorClient("vetophoton 12 1 39950 examples/gotthard2_veto_photon.txt", PUT)); // invalid chip index + REQUIRE_THROWS(multiSlsDetectorClient("vetophoton -1 0 39950 examples/gotthard2_veto_photon.txt", PUT)); // invalid photon number + REQUIRE_NOTHROW(multiSlsDetectorClient("vetophoton -1 1 39950 examples/gotthard2_veto_photon.txt", PUT)); + REQUIRE_THROWS(multiSlsDetectorClient("vetophoton", GET)); + REQUIRE_NOTHROW(multiSlsDetectorClient("vetophoton -1", GET)); + } else { + REQUIRE_THROWS(multiSlsDetectorClient("vetophoton -1", GET)); + } +} + + + TEST_CASE("inj_ch", "[.cmd][.gotthard2]") { if (test::type == slsDetectorDefs::GOTTHARD2) { { diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index f92d64e85..bd159ac5f 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -179,6 +179,8 @@ enum detFuncs{ F_GET_ON_CHIP_DAC, F_SET_INJECT_CHANNEL, F_GET_INJECT_CHANNEL, + F_SET_VETO_PHOTON, + F_GET_VETO_PHOTON, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */ @@ -422,7 +424,8 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_ON_CHIP_DAC: return "F_GET_ON_CHIP_DAC"; case F_SET_INJECT_CHANNEL: return "F_SET_INJECT_CHANNEL"; case F_GET_INJECT_CHANNEL: return "F_GET_INJECT_CHANNEL"; - + case F_SET_VETO_PHOTON: return "F_SET_VETO_PHOTON"; + case F_GET_VETO_PHOTON: return "F_GET_VETO_PHOTON"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 378697e76..366b3cfe1 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -9,4 +9,4 @@ #define APIJUNGFRAU 0x191111 #define APIEIGER 0x191111 #define APIMYTHEN3 0x191111 -#define APIGOTTHARD2 0x191113 +#define APIGOTTHARD2 0x191114