This commit is contained in:
maliakal_d 2020-05-20 10:14:57 +02:00
parent 6d71d6cf9f
commit fa768e584e
11 changed files with 421 additions and 13 deletions

View File

@ -6955,7 +6955,7 @@ int get_receiver_parameters(int file_des) {
// exptime
#ifdef MYTHEN3D
i64 = getExpTime(0);
i64 = 0;
#else
i64 = getExpTime();
#endif
@ -7099,6 +7099,76 @@ int get_receiver_parameters(int file_des) {
if (n < 0)
return printSocketReadError();
// exptime1
#ifdef MYTHEN3D
i64 = getExpTime(0);
#else
i64 = 0;
#endif
n += sendData(file_des, &i64, sizeof(i64), INT64);
if (n < 0)
return printSocketReadError();
// exptime2
#ifdef MYTHEN3D
i64 = getExpTime(1);
#else
i64 = 0;
#endif
n += sendData(file_des, &i64, sizeof(i64), INT64);
if (n < 0)
return printSocketReadError();
// exptime3
#ifdef MYTHEN3D
i64 = getExpTime(2);
#else
i64 = 0;
#endif
n += sendData(file_des, &i64, sizeof(i64), INT64);
if (n < 0)
return printSocketReadError();
// gatedelay1
#ifdef MYTHEN3D
i64 = getGateDelay(0);
#else
i64 = 0;
#endif
n += sendData(file_des, &i64, sizeof(i64), INT64);
if (n < 0)
return printSocketReadError();
// gatedelay2
#ifdef MYTHEN3D
i64 = getGateDelay(1);
#else
i64 = 0;
#endif
n += sendData(file_des, &i64, sizeof(i64), INT64);
if (n < 0)
return printSocketReadError();
// gatedelay3
#ifdef MYTHEN3D
i64 = getGateDelay(2);
#else
i64 = 0;
#endif
n += sendData(file_des, &i64, sizeof(i64), INT64);
if (n < 0)
return printSocketReadError();
// gates
#ifdef MYTHEN3D
i32 = getNumGates();
#else
i32 = 0;
#endif
n += sendData(file_des, &i32, sizeof(i32), INT32);
if (n < 0)
return printSocketReadError();
LOG(logINFO, ("Sent %d bytes for receiver parameters\n", n));
return OK;

View File

@ -1032,6 +1032,10 @@ int Module::getNumberOfGates() { return sendToDetector<int>(F_GET_NUM_GATES); }
void Module::setNumberOfGates(int value) {
LOG(logDEBUG1) << "Setting number of gates to " << value;
sendToDetector(F_SET_NUM_GATES, value, nullptr);
if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending number of gates to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_GATES, value, nullptr);
}
}
int64_t Module::getExptime(int gateIndex) {
@ -1049,7 +1053,7 @@ void Module::setExptime(int gateIndex, int64_t value) {
sendToDetector(F_SET_EXPTIME, args, nullptr);
if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr);
sendToReceiver(F_RECEIVER_SET_EXPTIME, args, nullptr);
}
if (prevVal != value) {
updateRateCorrection();
@ -1071,6 +1075,10 @@ void Module::setGateDelay(int gateIndex, int64_t value) {
<< "ns (gateindex: " << gateIndex << ")";
int64_t args[]{static_cast<int64_t>(gateIndex), value};
sendToDetector(F_SET_GATE_DELAY, args, nullptr);
if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending gate delay to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_GATE_DELAY, args, nullptr);
}
}
std::array<int64_t, 3> Module::getGateDelayForAllGates() {
@ -1473,7 +1481,14 @@ void Module::setReceiverHostname(const std::string &receiverIP) {
<< "roi.xmin:" << retval.roi.xmin << std::endl
<< "roi.xmax:" << retval.roi.xmax << std::endl
<< "countermask:" << retval.countermask << std::endl
<< "burstType:" << retval.burstType << std::endl;
<< "burstType:" << retval.burstType << std::endl
<< "exptime1:" << retval.expTime1Ns << std::endl
<< "exptime2:" << retval.expTime2Ns << std::endl
<< "exptime3:" << retval.expTime3Ns << std::endl
<< "gateDelay1:" << retval.gateDelay1Ns << std::endl
<< "gateDelay2:" << retval.gateDelay2Ns << std::endl
<< "gateDelay3:" << retval.gateDelay3Ns << std::endl
<< "gates:" << retval.gates << std::endl;
sls::MacAddr retvals[2];
sendToReceiver(F_SETUP_RECEIVER, retval, retvals);

View File

@ -191,6 +191,13 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
"Dbit Offset : %d\n"
"Dbit Bitset : %lld\n"
"Roi (xmin, xmax) : %d %d\n"
"Exptime1 (ns) : %lld\n"
"Exptime2 (ns) : %lld\n"
"Exptime3 (ns) : %lld\n"
"GateDelay1 (ns) : %lld\n"
"GateDelay2 (ns) : %lld\n"
"GateDelay3 (ns) : %lld\n"
"Gates : %d\n"
"Timestamp : %s\n\n"
"#Frame Header\n"
@ -224,7 +231,13 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
masterFileAttributes.dbitoffset,
(long long int)masterFileAttributes.dbitlist,
masterFileAttributes.roiXmin, masterFileAttributes.roiXmax,
ctime(&t));
(long long int)masterFileAttributes.exptime1Ns,
(long long int)masterFileAttributes.exptime2Ns,
(long long int)masterFileAttributes.exptime3Ns,
(long long int)masterFileAttributes.gateDelay1Ns,
(long long int)masterFileAttributes.gateDelay2Ns,
(long long int)masterFileAttributes.gateDelay3Ns,
masterFileAttributes.gates, ctime(&t));
if (strlen(message) > maxMasterFileSize) {
throw sls::RuntimeError("Master File Size " +
std::to_string(strlen(message)) +

View File

@ -197,7 +197,9 @@ int ClientInterface::functionTable(){
flist[F_SET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::set_additional_json_parameter;
flist[F_GET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::get_additional_json_parameter;
flist[F_GET_RECEIVER_PROGRESS] = &ClientInterface::get_progress;
flist[F_SET_RECEIVER_NUM_GATES] = &ClientInterface::set_num_gates;
flist[F_SET_RECEIVER_GATE_DELAY] = &ClientInterface::set_gate_delay;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
getFunctionNameFromEnum((enum detFuncs)i) << ") located at " << flist[i];
@ -368,7 +370,14 @@ int ClientInterface::setup_receiver(Interface &socket) {
<< "roi.xmin:" << arg.roi.xmin << std::endl
<< "roi.xmax:" << arg.roi.xmax << std::endl
<< "countermask:" << arg.countermask << std::endl
<< "burstType:" << arg.burstType << std::endl;
<< "burstType:" << arg.burstType << std::endl
<< "exptime1:" << arg.expTime1Ns << std::endl
<< "exptime2:" << arg.expTime2Ns << std::endl
<< "exptime3:" << arg.expTime3Ns << std::endl
<< "gateDelay1:" << arg.gateDelay1Ns << std::endl
<< "gateDelay2:" << arg.gateDelay2Ns << std::endl
<< "gateDelay3:" << arg.gateDelay3Ns << std::endl
<< "gates:" << arg.gates << std::endl;
// if object exists, verify unlocked and idle, else only verify lock
// (connecting first time)
@ -438,7 +447,9 @@ int ClientInterface::setup_receiver(Interface &socket) {
" due to fifo structure memory allocation.");
}
}
impl()->setAcquisitionTime(arg.expTimeNs);
if (myDetectorType != MYTHEN3) {
impl()->setAcquisitionTime(arg.expTimeNs);
}
impl()->setAcquisitionPeriod(arg.periodNs);
if (myDetectorType == EIGER) {
impl()->setSubExpTime(arg.subExpTimeNs);
@ -502,6 +513,13 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == MYTHEN3) {
int ncounters = __builtin_popcount(arg.countermask);
impl()->setNumberofCounters(ncounters);
impl()->setAcquisitionTime1(arg.expTime1Ns);
impl()->setAcquisitionTime2(arg.expTime2Ns);
impl()->setAcquisitionTime3(arg.expTime3Ns);
impl()->setGateDelay1(arg.gateDelay1Ns);
impl()->setGateDelay2(arg.gateDelay2Ns);
impl()->setGateDelay3(arg.gateDelay3Ns);
impl()->setNumberOfGates(arg.gates);
}
if (myDetectorType == GOTTHARD) {
impl()->setBurstMode(arg.burstType);
@ -679,9 +697,44 @@ int ClientInterface::set_num_digital_samples(Interface &socket) {
}
int ClientInterface::set_exptime(Interface &socket) {
auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting exptime to " << value << "ns";
impl()->setAcquisitionTime(value);
int64_t args[2]{-1, -1};
socket.Receive(args);
int gateIndex = static_cast<int>(args[0]);
int64_t value = args[1];
LOG(logDEBUG1) << "Setting exptime to " << value
<< "ns (gateIndex: " << gateIndex << ")";
switch (gateIndex) {
case -1:
if (myDetectorType == MYTHEN3) {
impl()->setAcquisitionTime1(value);
impl()->setAcquisitionTime2(value);
impl()->setAcquisitionTime3(value);
} else {
impl()->setAcquisitionTime(value);
}
break;
case 0:
if (myDetectorType != MYTHEN3) {
functionNotImplemented();
}
impl()->setAcquisitionTime1(value);
break;
case 1:
if (myDetectorType != MYTHEN3) {
functionNotImplemented();
}
impl()->setAcquisitionTime2(value);
break;
case 2:
if (myDetectorType != MYTHEN3) {
functionNotImplemented();
}
impl()->setAcquisitionTime3(value);
break;
default:
throw RuntimeError("Unknown gate index for exptime " +
std::to_string(gateIndex));
}
return socket.Send(OK);
}
@ -1651,4 +1704,46 @@ int ClientInterface::get_progress(Interface &socket) {
int retval = impl()->getProgress();
LOG(logDEBUG1) << "progress retval: " << retval;
return socket.sendResult(retval);
}
int ClientInterface::set_num_gates(Interface &socket) {
auto value = socket.Receive<int>();
LOG(logDEBUG1) << "Setting num gates to " << value;
if (myDetectorType != MYTHEN3) {
functionNotImplemented();
}
impl()->setNumberOfGates(value);
return socket.Send(OK);
}
int ClientInterface::set_gate_delay(Interface &socket) {
int64_t args[2]{-1, -1};
socket.Receive(args);
int gateIndex = static_cast<int>(args[0]);
int64_t value = args[1];
LOG(logDEBUG1) << "Setting gate delay to " << value
<< "ns (gateIndex: " << gateIndex << ")";
if (myDetectorType != MYTHEN3) {
functionNotImplemented();
}
switch (gateIndex) {
case -1:
impl()->setGateDelay1(value);
impl()->setGateDelay2(value);
impl()->setGateDelay3(value);
break;
case 0:
impl()->setGateDelay1(value);
break;
case 1:
impl()->setGateDelay2(value);
break;
case 2:
impl()->setGateDelay3(value);
break;
default:
throw RuntimeError("Unknown gate index for gate delay " +
std::to_string(gateIndex));
}
return socket.Send(OK);
}

View File

@ -2,8 +2,8 @@
#include "Implementation.h"
#include "ServerSocket.h"
#include "receiver_defs.h"
#include "sls_detector_funcs.h"
#include "sls_detector_defs.h"
#include "sls_detector_funcs.h"
class ServerInterface;
#include <atomic>
@ -153,6 +153,8 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_additional_json_parameter(sls::ServerInterface &socket);
int get_additional_json_parameter(sls::ServerInterface &socket);
int get_progress(sls::ServerInterface &socket);
int set_num_gates(sls::ServerInterface &socket);
int set_gate_delay(sls::ServerInterface &socket);
Implementation *impl() {
if (receiver != nullptr) {

View File

@ -725,6 +725,98 @@ void HDF5File::CreateMasterDataFile(masterAttributes &masterFileAttributes) {
PredType::NATIVE_INT);
}
// Exptime1
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"exposure time1", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptime1Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Exptime2
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"exposure time2", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptime2Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Exptime3
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"exposure time3", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptime3Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// GateDelay1
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"gate delay1", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.gateDelay1Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// GateDelay2
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"gate delay2", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.gateDelay2Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// GateDelay3
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"gate delay3", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.gateDelay3Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Dbit Offset
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group5.createDataSet("gates", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.gates), PredType::NATIVE_INT);
}
// Timestamp
{
time_t t = time(0);

View File

@ -100,10 +100,17 @@ void Implementation::InitializeMembers() {
numberOfTriggers = 1;
numberOfBursts = 1;
numberOfAdditionalStorageCells = 0;
numberOfGates = 0;
timingMode = AUTO_TIMING;
burstMode = BURST_OFF;
acquisitionPeriod = SAMPLE_TIME_IN_NS;
acquisitionTime = 0;
acquisitionTime1 = 0;
acquisitionTime2 = 0;
acquisitionTime3 = 0;
gateDelay1 = 0;
gateDelay2 = 0;
gateDelay3 = 0;
subExpTime = 0;
subPeriod = 0;
numberOfAnalogSamples = 0;
@ -889,6 +896,13 @@ void Implementation::SetupWriter() {
for (auto &i : ctbDbitList) {
attr.dbitlist |= (1 << i);
}
attr.exptime1Ns = acquisitionTime1;
attr.exptime2Ns = acquisitionTime2;
attr.exptime3Ns = acquisitionTime3;
attr.gateDelay1Ns = gateDelay1;
attr.gateDelay2Ns = gateDelay2;
attr.gateDelay3Ns = gateDelay3;
attr.gates = numberOfGates;
try {
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
@ -1343,6 +1357,12 @@ void Implementation::setNumberOfAdditionalStorageCells(const int i) {
updateTotalNumberOfFrames();
}
void Implementation::setNumberOfGates(const int i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
numberOfGates = i;
LOG(logINFO) << "Number of Gates: " << numberOfGates;
}
slsDetectorDefs::timingMode Implementation::getTimingMode() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return timingMode;
@ -1385,6 +1405,15 @@ uint64_t Implementation::getAcquisitionTime() const {
return acquisitionTime;
}
void Implementation::updateAcquisitionTime() {
if (acquisitionTime1 == acquisitionTime2 &&
acquisitionTime2 == acquisitionTime3) {
acquisitionTime = acquisitionTime1;
} else {
acquisitionTime = -1;
}
}
void Implementation::setAcquisitionTime(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
@ -1393,6 +1422,54 @@ void Implementation::setAcquisitionTime(const uint64_t i) {
<< "s";
}
void Implementation::setAcquisitionTime1(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
acquisitionTime1 = i;
LOG(logINFO) << "Acquisition Time1: " << (double)acquisitionTime1 / (1E9)
<< "s";
updateAcquisitionTime();
}
void Implementation::setAcquisitionTime2(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
acquisitionTime2 = i;
LOG(logINFO) << "Acquisition Time2: " << (double)acquisitionTime2 / (1E9)
<< "s";
updateAcquisitionTime();
}
void Implementation::setAcquisitionTime3(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
acquisitionTime3 = i;
LOG(logINFO) << "Acquisition Time3: " << (double)acquisitionTime3 / (1E9)
<< "s";
updateAcquisitionTime();
}
void Implementation::setGateDelay1(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
gateDelay1 = i;
LOG(logINFO) << "Gate Delay1: " << (double)gateDelay1 / (1E9) << "s";
}
void Implementation::setGateDelay2(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
gateDelay2 = i;
LOG(logINFO) << "Gate Delay2: " << (double)gateDelay2 / (1E9) << "s";
}
void Implementation::setGateDelay3(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
gateDelay3 = i;
LOG(logINFO) << "Gate Delay3: " << (double)gateDelay3 / (1E9) << "s";
}
uint64_t Implementation::getSubExpTime() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return subExpTime;

View File

@ -140,15 +140,34 @@ class Implementation : private virtual slsDetectorDefs {
uint64_t getNumberOfTriggers() const;
void setNumberOfTriggers(const uint64_t i);
uint64_t getNumberOfBursts() const;
/** [Gottthard2] */
void setNumberOfBursts(const uint64_t i);
int getNumberOfAdditionalStorageCells() const;
/** [Jungfrau] */
void setNumberOfAdditionalStorageCells(const int i);
/** [Mythen3] */
void setNumberOfGates(const int i);
timingMode getTimingMode() const;
void setTimingMode(const timingMode i);
burstMode getBurstMode() const;
/** [Gottthard2] */
void setBurstMode(const burstMode i);
uint64_t getAcquisitionTime() const;
void setAcquisitionTime(const uint64_t i);
/** [Mythen3] */
void updateAcquisitionTime();
/** [Mythen3] */
void setAcquisitionTime1(const uint64_t i);
/** [Mythen3] */
void setAcquisitionTime2(const uint64_t i);
/** [Mythen3] */
void setAcquisitionTime3(const uint64_t i);
/** [Mythen3] */
void setGateDelay1(const uint64_t i);
/** [Mythen3] */
void setGateDelay2(const uint64_t i);
/** [Mythen3] */
void setGateDelay3(const uint64_t i);
uint64_t getAcquisitionPeriod() const;
void setAcquisitionPeriod(const uint64_t i);
uint64_t getSubExpTime() const;
@ -286,10 +305,17 @@ class Implementation : private virtual slsDetectorDefs {
uint64_t numberOfTriggers;
uint64_t numberOfBursts;
int numberOfAdditionalStorageCells;
int numberOfGates;
timingMode timingMode;
burstMode burstMode;
uint64_t acquisitionPeriod;
uint64_t acquisitionTime;
uint64_t acquisitionTime1;
uint64_t acquisitionTime2;
uint64_t acquisitionTime3;
uint64_t gateDelay1;
uint64_t gateDelay2;
uint64_t gateDelay3;
uint64_t subExpTime;
uint64_t subPeriod;
uint64_t numberOfAnalogSamples;

View File

@ -40,8 +40,8 @@
#define MAX_CHUNKED_IMAGES (1)
// versions
#define HDF5_WRITER_VERSION (5.0) // 1 decimal places
#define BINARY_WRITER_VERSION (5.0) // 1 decimal places
#define HDF5_WRITER_VERSION (6.0) // 1 decimal places
#define BINARY_WRITER_VERSION (6.0) // 1 decimal places
// parameters to calculate fifo depth
#define SAMPLE_TIME_IN_NS (100000000) // 100ms
@ -79,4 +79,11 @@ struct masterAttributes {
uint64_t dbitlist;
uint32_t roiXmin;
uint32_t roiXmax;
uint64_t exptime1Ns;
uint64_t exptime2Ns;
uint64_t exptime3Ns;
uint64_t gateDelay1Ns;
uint64_t gateDelay2Ns;
uint64_t gateDelay3Ns;
uint32_t gates;
};

View File

@ -477,6 +477,13 @@ typedef struct {
ROI roi;
uint32_t countermask{0};
burstMode burstType{BURST_OFF};
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));
#endif

View File

@ -298,6 +298,8 @@ enum detFuncs {
F_GET_ADDITIONAL_JSON_PARAMETER,
F_GET_RECEIVER_PROGRESS,
F_SETUP_RECEIVER,
F_SET_RECEIVER_NUM_GATES,
F_SET_RECEIVER_GATE_DELAY,
NUM_REC_FUNCTIONS
};
@ -598,6 +600,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER";
case F_GET_RECEIVER_PROGRESS: return "F_GET_RECEIVER_PROGRESS";
case F_SETUP_RECEIVER: return "F_SETUP_RECEIVER";
case F_SET_RECEIVER_NUM_GATES: return "F_SET_RECEIVER_NUM_GATES" ;
case F_SET_RECEIVER_GATE_DELAY: return "F_SET_RECEIVER_GATE_DELAY" ;
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function";