6707 lines
180 KiB
C++

#include "slsDetector.h"
#include "multiSlsDetector.h"
#include "sls_detector_exceptions.h"
#include "SharedMemory.h"
#include "ClientInterface.h"
#include "gitInfoLib.h"
#include "versionAPI.h"
#include "slsDetectorCommand.h"
#include "utilities.h"
#include "MySocketTCP.h"
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <bitset>
#include <cstdlib>
#include <math.h>
#include <iomanip>
#include <sys/stat.h>
#define DEFAULT_HOSTNAME "localhost"
slsDetector::slsDetector(detectorType type, int multiId, int id, bool verify)
: detId(id),
sharedMemory(0),
thisDetector(0),
thisDetectorControl(0),
thisDetectorStop(0),
thisReceiver(0),
controlSocket(0),
stopSocket(0),
dataSocket(0),
detectorModules(0),
dacs(0),
adcs(0),
chipregs(0),
chanregs(0),
gain(0),
offset(0) {
/* called from put hostname command,
* so sls shared memory will be created */
// ensure shared memory was not created before
auto shm = SharedMemory(multiId, id);
if (shm.IsExisting()) {
FILE_LOG(logWARNING, ("Weird, this shared memory should have been "
"deleted before! %s. Freeing it again.\n", shm.GetName().c_str()));
freeSharedMemory(multiId, id);
}
initSharedMemory(true, type, multiId, verify);
initializeDetectorStructure(type);
initializeMembers();
initializeDetectorStructurePointers();
}
slsDetector::slsDetector(int multiId, int id, bool verify)
: detId(id),
sharedMemory(0),
thisDetector(0),
thisDetectorControl(0),
thisDetectorStop(0),
thisReceiver(0),
controlSocket(0),
stopSocket(0),
dataSocket(0),
detectorModules(0),
dacs(0),
adcs(0),
chipregs(0),
chanregs(0),
gain(0),
offset(0) {
/* called from multi constructor to populate structure,
* so sls shared memory will be opened, not created */
// getDetectorType Froom shm will check if it was already existing
detectorType type = getDetectorTypeFromShm(multiId, verify);
initSharedMemory(false, type, multiId, verify);
initializeMembers();
}
slsDetector::~slsDetector() {
if (sharedMemory) {
sharedMemory->UnmapSharedMemory(thisDetector);
delete sharedMemory;
}
if (thisDetectorControl)
delete thisDetectorControl;
if (thisDetectorStop)
delete thisDetectorStop;
if (thisReceiver)
delete thisReceiver;
if (controlSocket)
delete controlSocket;
if (stopSocket)
delete stopSocket;
if (dataSocket)
delete dataSocket;
/* detectorModules, dacs..ffoerrors are offsets from the
* shared memory and created within shared memory structure.
* Deleting shared memory will also delete memory pointed to
* by these pointers
*/
}
int slsDetector::checkVersionCompatibility(portType t) {
int fnum = F_CHECK_VERSION;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0};
int64_t arg = 0;
// detector
if (t == CONTROL_PORT) {
// get api version number for detector server
switch (thisDetector->myDetectorType) {
case EIGER: arg = APIEIGER; break;
case JUNGFRAU: arg = APIJUNGFRAU; break;
case GOTTHARD: arg = APIGOTTHARD; break;
default:
FILE_LOG(logERROR) << "Check version compatibility is not implemented for this detector";
setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY));
return FAIL;
}
FILE_LOG(logDEBUG5) << "Checking version compatibility with detector with "
"value " << std::hex << arg;
// control server
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &arg, sizeof(arg), NULL, 0, mess);
disconnectControl();
if (ret == FAIL)
thisDetector->detectorControlAPIVersion = 0;
// stop server
else {
thisDetector->detectorControlAPIVersion = arg;
ret = FAIL;
if (connectStop() == OK) {
ret = thisDetectorStop->Client_Send(fnum, &arg, sizeof(arg), NULL, 0, mess);
disconnectStop();
if (ret == FAIL)
thisDetector->detectorStopAPIVersion = 0;
else
thisDetector->detectorStopAPIVersion = arg;
}
}
}
}
// receiver
else {
fnum = F_RECEIVER_CHECK_VERSION;
arg = APIRECEIVER;
FILE_LOG(logDEBUG5) << "Checking version compatibility with receiver with "
"value " << std::hex << arg;
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), NULL, 0);
disconnectData();
if (ret == FAIL)
thisDetector->receiverAPIVersion = 0;
else
thisDetector->receiverAPIVersion = arg;
}
}
if (ret == FAIL) {
setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY));
if (strstr(mess,"Unrecognized Function") != NULL) {
FILE_LOG(logERROR) << "The " << ((t == CONTROL_PORT) ? "detector" : "receiver") <<
" server is too old to get API version. Please update detector server!";
}
}
return ret;
}
int64_t slsDetector::getId( idMode mode) {
int fnum = F_GET_ID;
int ret = FAIL;
int arg = (int)mode;
int64_t retval = -1;
FILE_LOG(logDEBUG5) << "Getting id type " << mode;
// client version
if (mode == THIS_SOFTWARE_VERSION) {
ret = OK;
retval = GITDATE;
}
// receiver version
else if (mode==RECEIVER_VERSION) {
fnum = F_GET_RECEIVER_ID;
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectData();
// handle ret
if (ret == FAIL)
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
else if (ret == FORCE_UPDATE)
ret = updateReceiver();
}
}
// detector versions
else {
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL)
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
else if (ret == FORCE_UPDATE)
updateDetector();
}
}
if (ret != FAIL) {
FILE_LOG(logDEBUG5) << "Id ("<< mode << "): 0x" << std::hex << retval << std::setbase(10);
}
return retval;
}
void slsDetector::freeSharedMemory(int multiId, int slsId) {
auto shm = SharedMemory(multiId, slsId);
shm.RemoveSharedMemory();
}
void slsDetector::freeSharedMemory() {
if (sharedMemory) {
sharedMemory->UnmapSharedMemory(thisDetector);
sharedMemory->RemoveSharedMemory();
delete sharedMemory;
sharedMemory = 0;
}
thisDetector = 0;
}
void slsDetector::setHostname(const char *name) {
setTCPSocket(std::string(name));
if (thisDetector->onlineFlag == ONLINE_FLAG)
updateDetector();
}
std::string slsDetector::getHostname() {
return std::string(thisDetector->hostname);
}
/*
* pre: sharedMemory=0, thisDetector = 0
* exceptions are caught in calling function, shm unmapped and deleted
*/
void slsDetector::initSharedMemory(bool created, detectorType type, int multiId,
bool verify) {
try {
// calculate shared memory size
int sz = calculateSharedMemorySize(type);
// shared memory object with name
sharedMemory = new SharedMemory(multiId, detId);
// create
if (created) {
thisDetector = (sharedSlsDetector*)sharedMemory->CreateSharedMemory(sz);
}
// open and verify version
else {
thisDetector = (sharedSlsDetector*)sharedMemory->OpenSharedMemory(sz);
if (verify && thisDetector->shmversion != SLS_SHMVERSION) {
FILE_LOG(logERROR, ("Single shared memory (%d-%d:)version mismatch "
"(expected 0x%x but got 0x%x)\n",
multiId, detId, SLS_SHMVERSION,
thisDetector->shmversion));
throw SharedMemoryException();
}
}
} catch(...) {
if (sharedMemory) {
// unmap
if (thisDetector) {
sharedMemory->UnmapSharedMemory(thisDetector);
thisDetector = 0;
}
// delete
delete sharedMemory;
sharedMemory = 0;
}
throw;
}
}
void slsDetector::setDetectorSpecificParameters(detectorType type, detParameterList& list) {
switch (type) {
case GOTTHARD:
list.nChanX = 128;
list.nChanY = 1;
list.nChipX = 10;
list.nChipY = 1;
list.nDacs = 8;
list.nAdcs = 5;
list.nGain = 0;
list.nOffset = 0;
list.dynamicRange = 16;
list.nGappixelsX = 0;
list.nGappixelsY = 0;
break;
case JUNGFRAU:
list.nChanX = 256;
list.nChanY = 256;
list.nChipX = 4;
list.nChipY = 2;
list.nDacs = 16;
list.nAdcs = 0;
list.nGain = 0;
list.nOffset = 0;
list.dynamicRange = 16;
list.nGappixelsX = 0;
list.nGappixelsY = 0;
break;
case JUNGFRAUCTB:
list.nChanX = 36;
list.nChanY = 1;
list.nChipX = 1;
list.nChipY = 1;
list.nDacs = 16;
list.nAdcs = 9;//???? When calculating size, only d+a=16 how come?FIXME
list.nGain = 0;
list.nOffset = 0;
list.dynamicRange =16;
list.nGappixelsX = 0;
list.nGappixelsY = 0;
break;
case EIGER:
list.nChanX = 256;
list.nChanY = 256;
list.nChipX = 4;
list.nChipY = 1;
list.nDacs = 16;
list.nAdcs = 0;
list.nGain = 0; // can be set back to 4 in case we require it again
list.nOffset = 0; // can be set back to 4 in case we require it again
list.dynamicRange = 16;
list.nGappixelsX = 6;
list.nGappixelsY = 1;
break;
default:
FILE_LOG(logERROR, ("Unknown detector type!\n"));
throw std::exception();
}
}
int slsDetector::calculateSharedMemorySize(detectorType type) {
// get the detector parameters based on type
detParameterList detlist;
setDetectorSpecificParameters(type, detlist);
int nch = detlist.nChanX * detlist.nChanY;
int nc = detlist.nChipX * detlist.nChipY;
int nd = detlist.nDacs + detlist.nAdcs;
int ng = detlist.nGain;
int no = detlist.nOffset;
/** The size of the shared memory is
* size of shared structure +
* ffcoefficents+fferrors+modules+dacs+adcs+chips+chans+gain+offset */
int sz = sizeof(sharedSlsDetector) +
2 * nch * nc * sizeof(double) +
sizeof(sls_detector_module) +
sizeof(int) * nc +
sizeof(int) * nd +
sizeof(int) * nch * nc +
sizeof(int) * ng +
sizeof(int) * no;
FILE_LOG(logDEBUG5) << "Size of shared memory is " << sz;
return sz;
}
void slsDetector::initializeDetectorStructure(detectorType type) {
thisDetector->shmversion = SLS_SHMVERSION;
thisDetector->onlineFlag = OFFLINE_FLAG;
thisDetector->stoppedFlag = 0;
strncpy(thisDetector->hostname, DEFAULT_HOSTNAME, MAX_STR_LENGTH-1);
thisDetector->hostname[MAX_STR_LENGTH-1] = 0;
thisDetector->myDetectorType = type;
thisDetector->offset[X] = 0;
thisDetector->offset[Y] = 0;
thisDetector->multiSize[X] = 0;
thisDetector->multiSize[Y] = 0;
thisDetector->controlPort = DEFAULT_PORTNO;
thisDetector->stopPort = DEFAULT_PORTNO + 1;
strncpy(thisDetector->settingsDir, getenv("HOME"), MAX_STR_LENGTH-1);
thisDetector->settingsDir[MAX_STR_LENGTH-1] = 0;
thisDetector->nTrimEn = 0;
for(int i = 0; i < MAX_TRIMEN; ++i)
thisDetector->trimEnergies[i] = 0;
thisDetector->threadedProcessing = 1;
thisDetector->nROI = 0;
memset(thisDetector->roiLimits, 0, MAX_ROIS * sizeof(ROI));
thisDetector->roFlags = NORMAL_READOUT;
strcpy(thisDetector->settingsFile, "none");
thisDetector->currentSettings = UNINITIALIZED;
thisDetector->currentThresholdEV = -1;
thisDetector->timerValue[FRAME_NUMBER] = 1;
thisDetector->timerValue[ACQUISITION_TIME] = 0;
thisDetector->timerValue[FRAME_PERIOD] = 0;
thisDetector->timerValue[DELAY_AFTER_TRIGGER] = 0;
thisDetector->timerValue[GATES_NUMBER] = 0;
thisDetector->timerValue[CYCLES_NUMBER] = 1;
thisDetector->timerValue[ACTUAL_TIME] = 0;
thisDetector->timerValue[MEASUREMENT_TIME] = 0;
thisDetector->timerValue[PROGRESS] = 0;
thisDetector->timerValue[MEASUREMENTS_NUMBER] = 1;
thisDetector->timerValue[FRAMES_FROM_START] = 0;
thisDetector->timerValue[FRAMES_FROM_START_PG] = 0;
thisDetector->timerValue[SAMPLES_JCTB] = 1;
thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME] = 0;
thisDetector->timerValue[STORAGE_CELL_NUMBER] = 0;
thisDetector->timerValue[SUBFRAME_DEADTIME] = 0;
strcpy(thisDetector->receiver_hostname, "none");
thisDetector->receiverTCPPort = DEFAULT_PORTNO+2;
thisDetector->receiverUDPPort = DEFAULT_UDP_PORTNO;
thisDetector->receiverUDPPort2 = DEFAULT_UDP_PORTNO + 1;
strcpy(thisDetector->receiverUDPIP, "none");
strcpy(thisDetector->receiverUDPMAC, "none");
strncpy(thisDetector->detectorMAC, DEFAULT_DET_MAC, MAX_STR_LENGTH-1);
thisDetector->detectorMAC[MAX_STR_LENGTH-1] = 0;
strncpy(thisDetector->detectorIP, DEFAULT_DET_IP, MAX_STR_LENGTH-1);
thisDetector->detectorIP[MAX_STR_LENGTH-1] = 0;
thisDetector->receiverOnlineFlag = OFFLINE_FLAG;
thisDetector->tenGigaEnable = 0;
thisDetector->flippedData[X] = 0;
thisDetector->flippedData[Y] = 0;
thisDetector->zmqport = DEFAULT_ZMQ_CL_PORTNO +
(detId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1));
thisDetector->receiver_zmqport = DEFAULT_ZMQ_RX_PORTNO +
(detId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1));
thisDetector->receiver_upstream = false;
thisDetector->receiver_read_freq = 0;
memset(thisDetector->zmqip, 0, MAX_STR_LENGTH);
memset(thisDetector->receiver_zmqip, 0, MAX_STR_LENGTH);
thisDetector->gappixels = 0;
memset(thisDetector->receiver_additionalJsonHeader, 0, MAX_STR_LENGTH);
thisDetector->detectorControlAPIVersion = 0;
thisDetector->detectorStopAPIVersion = 0;
thisDetector->receiverAPIVersion = 0;
thisDetector->receiver_frameDiscardMode = NO_DISCARD;
thisDetector->receiver_framePadding = 1;
thisDetector->activated = true;
thisDetector->receiver_deactivatedPaddingEnable = true;
thisDetector->receiver_silentMode = false;
strcpy(thisDetector->receiver_filePath, "/");
strcpy(thisDetector->receiver_fileName, "run");
thisDetector->receiver_fileIndex = 0;
thisDetector->receiver_fileFormatType = BINARY;
switch(thisDetector->myDetectorType) {
case GOTTHARD:
thisDetector->receiver_framesPerFile = MAX_FRAMES_PER_FILE;
break;
case EIGER:
thisDetector->receiver_framesPerFile = EIGER_MAX_FRAMES_PER_FILE;
break;
case JUNGFRAU:
thisDetector->receiver_framesPerFile = JFRAU_MAX_FRAMES_PER_FILE;
break;
case JUNGFRAUCTB:
thisDetector->receiver_framesPerFile = JFRAU_MAX_FRAMES_PER_FILE;
break;
default:
break;
}
thisDetector->receiver_fileWriteEnable = 1;
thisDetector->receiver_overWriteEnable = 1;
// get the detector parameters based on type
detParameterList detlist;
setDetectorSpecificParameters(type, detlist);
thisDetector->nChan[X] = detlist.nChanX;
thisDetector->nChan[Y] = detlist.nChanY;
thisDetector->nChip[X] = detlist.nChipX;
thisDetector->nChip[Y] = detlist.nChipY;
thisDetector->nDacs = detlist.nDacs;
thisDetector->nAdcs = detlist.nAdcs;
thisDetector->nGain = detlist.nGain;
thisDetector->nOffset = detlist.nOffset;
thisDetector->dynamicRange = detlist.dynamicRange;
thisDetector->nGappixels[X] = detlist.nGappixelsX;
thisDetector->nGappixels[Y] = detlist.nGappixelsY;
// derived parameters
thisDetector->nChans = thisDetector->nChan[X] * thisDetector->nChan[Y];
thisDetector->nChips = thisDetector->nChip[X] * thisDetector->nChip[Y];
// calculating databytes
thisDetector->dataBytes = thisDetector->nChips * thisDetector->nChans *
thisDetector->dynamicRange/8;
thisDetector->dataBytesInclGapPixels =
(thisDetector->nChip[X] * thisDetector->nChan[X] +
thisDetector->gappixels * thisDetector->nGappixels[X]) *
(thisDetector->nChip[Y] * thisDetector->nChan[Y] +
thisDetector->gappixels * thisDetector->nGappixels[Y]) *
thisDetector->dynamicRange/8;
// special for jctb
if (thisDetector->myDetectorType==JUNGFRAUCTB) {
getTotalNumberOfChannels();
}
/** calculates the memory offsets for
* flat field coefficients and errors,
* module structures, dacs, adcs, chips and channels */
thisDetector->modoff = sizeof(sharedSlsDetector);
thisDetector->dacoff = thisDetector->modoff +
sizeof(sls_detector_module);
thisDetector->adcoff = thisDetector->dacoff +
sizeof(int) * thisDetector->nDacs;
thisDetector->chipoff = thisDetector->adcoff +
sizeof(int) * thisDetector->nAdcs;
thisDetector->chanoff = thisDetector->chipoff +
sizeof(int) * thisDetector->nChips;
thisDetector->gainoff = thisDetector->chanoff +
sizeof(int) * thisDetector->nGain;
thisDetector->offsetoff = thisDetector->gainoff +
sizeof(int) * thisDetector->nOffset;
}
void slsDetector::initializeMembers() {
// slsdetector
// assign addresses
char *goff = (char*)thisDetector;
detectorModules = (sls_detector_module*)(goff + thisDetector->modoff);
dacs = (int*)(goff + thisDetector->dacoff);
adcs = (int*)(goff + thisDetector->adcoff);
chipregs = (int*)(goff + thisDetector->chipoff);
chanregs = (int*)(goff + thisDetector->chanoff);
gain = (int*)(goff + thisDetector->gainoff);
offset = (int*)(goff + thisDetector->offsetoff);
if (thisDetectorControl) {
delete thisDetectorControl;
thisDetectorControl = 0;
}
if (thisDetectorStop) {
delete thisDetectorStop;
thisDetectorStop = 0;
}
if (thisReceiver) {
delete thisReceiver;
thisReceiver = 0;
}
thisDetectorControl = new ClientInterface(controlSocket, detId, "Detector (Control server)");
thisDetectorStop = new ClientInterface(stopSocket, detId, "Detector (Stop server)");
thisReceiver = new ClientInterface(dataSocket, detId, "Receiver");
}
void slsDetector::initializeDetectorStructurePointers() {
sls_detector_module* thisMod;
// set thisMod to point to one of the detector structure modules
thisMod = detectorModules;
thisMod->serialnumber = 0;
thisMod->nchan = thisDetector->nChans*thisDetector->nChips;
thisMod->nchip = thisDetector->nChips;
thisMod->ndac = thisDetector->nDacs;
thisMod->nadc = thisDetector->nAdcs;
thisMod->reg = 0;
// dacs, adcs, chipregs and chanregs for thisMod is not allocated in
// detectorModules in shared memory as they are already allocated separately
// in shared memory (below)
thisMod->gain = -1.;
thisMod->offset = -1.;
// initializes the dacs values to 0
for (int i = 0; i < thisDetector->nDacs; ++i) {
*(dacs + i) = 0;
}
// initializes the adc values to 0
for (int i = 0; i < thisDetector->nAdcs; ++i) {
*(adcs + i) = 0;
}
// initializes the chip registers to 0
for (int i = 0; i < thisDetector->nChips; ++i) {
*(chipregs + i) = -1;
}
// initializes the channel registers to 0
for (int i = 0; i < thisDetector->nChans * thisDetector->nChips; ++i) {
*(chanregs + i) = -1;
}
// initializes the gain values to 0
for (int i = 0; i < thisDetector->nGain; ++i) {
*(gain + i) = 0;
}
// initializes the offset values to 0
for (int i = 0; i < thisDetector->nOffset; ++i) {
*(offset + i) = 0;
}
}
slsDetectorDefs::sls_detector_module* slsDetector::createModule() {
return createModule(thisDetector->myDetectorType);
}
slsDetectorDefs::sls_detector_module* slsDetector::createModule(detectorType type) {
// get the detector parameters based on type
detParameterList detlist;
int nch = 0, nc = 0, nd = 0, na = 0;
try {
setDetectorSpecificParameters(type, detlist);
nch = detlist.nChanX * detlist.nChanY;
nc = detlist.nChipX * detlist.nChipY;
nd = detlist.nDacs;
na = detlist.nAdcs;
} catch(...) {
return NULL;
}
int *dacs = new int[nd];
int *adcs = new int[na];
int *chipregs = new int[nc];
int *chanregs = new int[nch*nc];
sls_detector_module *myMod = (sls_detector_module*)malloc(sizeof(sls_detector_module));
myMod->ndac = nd;
myMod->nadc = na;
myMod->nchip = nc;
myMod->nchan = nch*nc;
myMod->dacs = dacs;
myMod->adcs = adcs;
myMod->chipregs = chipregs;
myMod->chanregs = chanregs;
return myMod;
}
void slsDetector::deleteModule(sls_detector_module *myMod) {
delete [] myMod->dacs;
delete [] myMod->adcs;
delete [] myMod->chipregs;
delete [] myMod->chanregs;
delete myMod;
}
int slsDetector::connectControl() {
if (controlSocket) {
if (controlSocket->Connect() >= 0)
return OK;
else {
FILE_LOG(logERROR) << "Cannot connect to detector";
setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR));
return FAIL;
}
}
return UNDEFINED;
}
void slsDetector::disconnectControl() {
if (controlSocket)
controlSocket->Disconnect();
}
int slsDetector::connectData() {
if (dataSocket) {
if (dataSocket->Connect() >= 0)
return OK;
else {
FILE_LOG(logERROR) << "Cannot connect to receiver";
setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER));
return FAIL;}
}
return UNDEFINED;
}
void slsDetector::disconnectData() {
if (dataSocket)
dataSocket->Disconnect();
}
int slsDetector::connectStop() {
if (stopSocket) {
if (stopSocket->Connect() >= 0)
return OK;
else {
FILE_LOG(logERROR) << "Cannot connect to stop server";
setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR));
return FAIL;
}
}
return UNDEFINED;
}
void slsDetector::disconnectStop() {
if (stopSocket)
stopSocket->Disconnect();
}
int slsDetector::sendModule(sls_detector_module *myMod) {
int ts = 0;
//send module structure
ts += controlSocket->SendDataOnly(&(myMod->serialnumber),sizeof(myMod->serialnumber));
ts += controlSocket->SendDataOnly(&(myMod->nchan),sizeof(myMod->nchan));
ts += controlSocket->SendDataOnly(&(myMod->nchip),sizeof(myMod->nchip));
ts += controlSocket->SendDataOnly(&(myMod->ndac),sizeof(myMod->ndac));
ts += controlSocket->SendDataOnly(&(myMod->nadc),sizeof(myMod->nadc));
ts += controlSocket->SendDataOnly(&(myMod->reg),sizeof(myMod->reg));
ts += controlSocket->SendDataOnly(&(myMod->gain),sizeof(myMod->gain));
ts += controlSocket->SendDataOnly(&(myMod->offset), sizeof(myMod->offset));
// actual data to the pointers
ts += controlSocket->SendDataOnly(myMod->dacs,sizeof(int)*(myMod->ndac));
ts += controlSocket->SendDataOnly(myMod->adcs,sizeof(int)*(myMod->nadc));
if (thisDetector->myDetectorType != JUNGFRAU) {
ts += controlSocket->SendDataOnly(myMod->chipregs,sizeof(int)*(myMod->nchip));
ts += controlSocket->SendDataOnly(myMod->chanregs,sizeof(int)*(myMod->nchan));
}
return ts;
}
int slsDetector::receiveModule(sls_detector_module* myMod) {
int *dacptr = myMod->dacs;
int *adcptr = myMod->adcs;
int *chipptr = myMod->chipregs;
int *chanptr = myMod->chanregs;
int ts = 0;
//send module structure
ts += controlSocket->ReceiveDataOnly(&(myMod->serialnumber),sizeof(myMod->serialnumber));
ts += controlSocket->ReceiveDataOnly(&(myMod->nchan),sizeof(myMod->nchan));
ts += controlSocket->ReceiveDataOnly(&(myMod->nchip),sizeof(myMod->nchip));
ts += controlSocket->ReceiveDataOnly(&(myMod->ndac),sizeof(myMod->ndac));
ts += controlSocket->ReceiveDataOnly(&(myMod->nadc),sizeof(myMod->nadc));
ts += controlSocket->ReceiveDataOnly(&(myMod->reg),sizeof(myMod->reg));
ts += controlSocket->ReceiveDataOnly(&(myMod->gain), sizeof(myMod->gain));
ts += controlSocket->ReceiveDataOnly(&(myMod->offset), sizeof(myMod->offset));
myMod->dacs = dacptr;
myMod->adcs = adcptr;
myMod->chipregs = chipptr;
myMod->chanregs = chanptr;
FILE_LOG(logDEBUG5) << "received module of size "<< ts << " register " << myMod->reg;
ts += controlSocket->ReceiveDataOnly(myMod->dacs,sizeof(int)*(myMod->ndac));
FILE_LOG(logDEBUG5) << "received dacs of size "<< ts;
ts += controlSocket->ReceiveDataOnly(myMod->adcs,sizeof(int)*(myMod->nadc));
FILE_LOG(logDEBUG5) << "received adc of size "<< ts;
if (thisDetector->myDetectorType != JUNGFRAU) {
ts += controlSocket->ReceiveDataOnly(myMod->chipregs,sizeof(int)*(myMod->nchip));
FILE_LOG(logDEBUG5) << "received chips of size "<< ts;
ts += controlSocket->ReceiveDataOnly(myMod->chanregs,sizeof(int)*(myMod->nchan));
FILE_LOG(logDEBUG5) << "nchans= " << thisDetector->nChans << " nchips= " << thisDetector->nChips
<< "mod - nchans= " << myMod->nchan << " nchips= " <<myMod->nchip;
<< "received chans of size "<< ts;
}
FILE_LOG(logDEBUG5) << "received module of size "<< ts << " register " << myMod->reg;
return ts;
}
slsDetectorDefs::detectorType slsDetector::getDetectorTypeFromShm(int multiId, bool verify) {
auto shm = SharedMemory(multiId, detId);
if (!shm.IsExisting()) {
FILE_LOG(logERROR, ("Shared memory %s does not exist.\n"
"Corrupted Multi Shared memory. Please free shared memory.\n",
shm.GetName().c_str()));
throw SharedMemoryException();
}
size_t sz = sizeof(sharedSlsDetector);
// open, map, verify version
auto sdet = (sharedSlsDetector*)shm.OpenSharedMemory(sz);
if (verify && sdet->shmversion != SLS_SHMVERSION) {
FILE_LOG(logERROR, ("Single shared memory (%d-%d:)version mismatch "
"(expected 0x%x but got 0x%x)\n",
multiId, detId, SLS_SHMVERSION, sdet->shmversion));
// unmap and throw
sharedMemory->UnmapSharedMemory(thisDetector);
throw SharedMemoryException();
}
// get type, unmap
auto type = sdet->myDetectorType;
shm.UnmapSharedMemory(sdet);
return type;
}
// static function
slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int cport) {
int fnum = F_GET_DETECTOR_TYPE;
int ret = FAIL;
detectorType retval = GENERIC;
MySocketTCP* mySocket = 0;
try {
mySocket = new MySocketTCP(name, cport);
} catch(...) {
FILE_LOG(logERROR) << "Cannot create socket to control server " << name
<< " over port " << cport;
return retval;
}
FILE_LOG(logDEBUG5) << "Getting detector type ";
if (mySocket->Connect() >= 0) {
mySocket->SendDataOnly(&fnum,sizeof(fnum));
mySocket->ReceiveDataOnly(&ret,sizeof(ret));
mySocket->ReceiveDataOnly(&retval,sizeof(retval));
mySocket->Disconnect();
} else {
FILE_LOG(logERROR) << "Cannot connect to server " << name << " over port " << cport;
}
if (ret != FAIL) {
FILE_LOG(logDEBUG5) << "Detector type is " << retval;
}
delete mySocket;
return retval;
}
int slsDetector::setDetectorType(detectorType const type) {
int fnum = F_GET_DETECTOR_TYPE;
int ret = FAIL;
detectorType retval = GENERIC;
FILE_LOG(logDEBUG5) << "Setting detector type to " << arg;
// if unspecified, then get from detector
if (type == GET_DETECTOR_TYPE) {
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
// ret is never fail with this function
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
thisDetector->myDetectorType = GENERIC;
} else {
thisDetector->myDetectorType = (detectorType)retval;
FILE_LOG(logDEBUG5) << "Detector Type: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
} else ret = OK;
// receiver
if ((thisDetector->receiverOnlineFlag == ONLINE_FLAG) && ret == OK) {
fnum = F_GET_RECEIVER_TYPE;
ret = FAIL;
int arg = (int)thisDetector->myDetectorType;
retval = GENERIC;
FILE_LOG(logINFO) << "Sending detector type to Receiver " << (int)thisDetector->myDetectorType;
if (connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
// handle ret
if (ret == FAIL) {
FILE_LOG(logERROR) << "Could not send detector type to receiver";
setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET));
} else {
FILE_LOG(logDEBUG5) << "Receiver Type: " << retval;
if (ret == FORCE_UPDATE)
ret = updateReceiver();
}
}
}
return retval;
}
int slsDetector::setDetectorType(std::string const stype) {
return setDetectorType(getDetectorType(stype));
}
slsDetectorDefs::detectorType slsDetector::getDetectorsType() {
return thisDetector->myDetectorType;
}
std::string slsDetector::sgetDetectorsType() {
return getDetectorType(getDetectorsType());
}
std::string slsDetector::getDetectorType() {
return sgetDetectorsType();
}
int slsDetector::getTotalNumberOfChannels() {
FILE_LOG(logDEBUG5) << "Get total number of channels";
if (thisDetector->myDetectorType == JUNGFRAUCTB) {
if (thisDetector->roFlags & DIGITAL_ONLY)
thisDetector->nChan[X] = 4;
else if (thisDetector->roFlags & ANALOG_AND_DIGITAL)
thisDetector->nChan[X] = 36;
else
thisDetector->nChan[X] = 32;
if (thisDetector->nChan[X] >= 32) {
if (thisDetector->nROI > 0) {
thisDetector->nChan[X] -= 32;
for (int iroi = 0; iroi < thisDetector->nROI; ++iroi)
thisDetector->nChan[X] +=
thisDetector->roiLimits[iroi].xmax -
thisDetector->roiLimits[iroi].xmin + 1;
}
}
thisDetector->nChans = thisDetector->nChan[X];
thisDetector->dataBytes = thisDetector->nChans * thisDetector->nChips * 2
* thisDetector->timerValue[SAMPLES_JCTB];
}
FILE_LOG(logDEBUG5) << "Total number of channels: " <<
thisDetector->nChans * thisDetector->nChips <<
<< ". Data bytes: " << thisDetector->dataBytes;
return thisDetector->nChans * thisDetector->nChips;
}
int slsDetector::getTotalNumberOfChannels(dimension d) {
getTotalNumberOfChannels();
return thisDetector->nChan[d] * thisDetector->nChip[d];
}
int slsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d) {
getTotalNumberOfChannels();
return (thisDetector->nChan[d] * thisDetector->nChip[d] + thisDetector->gappixels
* thisDetector->nGappixels[d]);
}
int slsDetector::getNChans() {
return thisDetector->nChans;
}
int slsDetector::getNChans(dimension d) {
return thisDetector->nChan[d];
}
int slsDetector::getNChips() {
return thisDetector->nChips;
}
int slsDetector::getNChips(dimension d) {
return thisDetector->nChip[d];
}
int slsDetector::getDetectorOffset(dimension d) {
return thisDetector->offset[d];
}
void slsDetector::setDetectorOffset(dimension d, int off) {
if (off >= 0)
thisDetector->offset[d] = off;
}
void slsDetector::updateMultiSize(int detx, int dety) {
thisDetector->multiSize[0] = detx;
thisDetector->multiSize[1] = dety;
}
int slsDetector::setOnline(int off) {
int old = thisDetector->onlineFlag;
// setting it online/offline
if (off != GET_ONLINE_FLAG) {
thisDetector->onlineFlag = off;
if (thisDetector->onlineFlag == ONLINE_FLAG) {
setTCPSocket();
// connecting first time
if (thisDetector->onlineFlag == ONLINE_FLAG && old == OFFLINE_FLAG) {
FILE_LOG(logINFO) << "Detector connecting for the first time - updating!";
updateDetector();
}
// error
else if (thisDetector->onlineFlag == OFFLINE_FLAG) {
FILE_LOG(logERROR) << "Cannot connect to detector";
setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR));
}
}
}
return thisDetector->onlineFlag;
}
std::string slsDetector::checkOnline() {
std::string retval;
if (!controlSocket) {
//this already sets the online/offline flag
setTCPSocket();
if (thisDetector->onlineFlag == OFFLINE_FLAG)
return std::string(thisDetector->hostname);
else
return std::string("");
}
//still cannot connect to socket, controlSocket=0
if (controlSocket) {
if (connectControl() == FAIL) {
controlSocket->SetTimeOut(5);
thisDetector->onlineFlag = OFFLINE_FLAG;
delete controlSocket;
controlSocket = 0;
retval = std::string(thisDetector->hostname);
FILE_LOG(logDEBUG5) << "offline!";
} else {
thisDetector->onlineFlag = ONLINE_FLAG;
controlSocket->SetTimeOut(100);
disconnectControl();
FILE_LOG(logDEBUG5) << "online!";
}
}
//still cannot connect to socket, stopSocket=0
if (stopSocket) {
if (connectStop() == FAIL) {
stopSocket->SetTimeOut(5);
thisDetector->onlineFlag = OFFLINE_FLAG;
delete stopSocket;
stopSocket = 0;
retval = std::string(thisDetector->hostname);
FILE_LOG(logDEBUG5) << "stop offline!";
} else {
thisDetector->onlineFlag = ONLINE_FLAG;
stopSocket->SetTimeOut(100);
disconnectStop();
FILE_LOG(logDEBUG5) << "stop online!";
}
}
return retval;
}
int slsDetector::setTCPSocket(std::string const name, int const control_port, int const stop_port) {
char thisName[MAX_STR_LENGTH] = {0};
int thisCP = 0, thisSP = 0;
int ret = OK;
// hostname
if (name.empty()) {
strcpy(thisName,thisDetector->hostname);
} else {
FILE_LOG(logDEBUG5) << "Setting hostname";
strcpy(thisName,name.c_str());
strcpy(thisDetector->hostname,thisName);
if (controlSocket) {
delete controlSocket;
controlSocket = 0;
}
if (stopSocket) {
delete stopSocket;
stopSocket = 0;
}
}
// control port
if (control_port > 0) {
FILE_LOG(logDEBUG5) << "Setting control port";
thisCP = control_port;
thisDetector->controlPort = thisCP;
if (controlSocket) {
delete controlSocket;
controlSocket = 0;
}
} else
thisCP = thisDetector->controlPort;
// stop port
if (stop_port > 0) {
FILE_LOG(logDEBUG5) << "Setting stop port";
thisSP = stop_port;
thisDetector->stopPort = thisSP;
if (stopSocket) {
delete stopSocket;
stopSocket = 0;
}
} else
thisSP = thisDetector->stopPort;
// create control socket
if (!controlSocket) {
try {
controlSocket = new MySocketTCP(thisName, thisCP);
FILE_LOG(logDEBUG5) << "Control socket connected " << thisName << " " << thisCP;
} catch(...) {
FILE_LOG(logERROR) << "Could not connect control socket " << thisName << " " << thisCP;
controlSocket = 0;
ret = FAIL;
}
}
// create stop socket
if (!stopSocket) {
try {
stopSocket = new MySocketTCP(thisName, thisSP);
FILE_LOG(logDEBUG5) << "Stop socket connected " << thisName << " " << thisSP;
} catch(...) {
FILE_LOG(logERROR) << "Could not connect Stop socket " << thisName << " " << thisSP;
stopSocket = 0;
ret = FAIL;
}
}
if (ret == FAIL) {
thisDetector->onlineFlag = OFFLINE_FLAG;
FILE_LOG(logDEBUG5) << "Detector offline";
}
// check online and version compatibility
else {
checkOnline();
thisDetectorControl->SetSocket(controlSocket);
thisDetectorStop->SetSocket(stopSocket);
// check for version compatibility
switch (thisDetector->myDetectorType) {
case EIGER:
case JUNGFRAU:
case GOTTHARD:
// check version compatibility only if it hasnt been checked yet (shm value)
if ((thisDetector->detectorControlAPIVersion == 0) ||
(thisDetector->detectorStopAPIVersion == 0)) {
if (checkVersionCompatibility(CONTROL_PORT) == FAIL)
thisDetector->onlineFlag=OFFLINE_FLAG;
}
break;
default:
break;
}
}
return ret;
}
int slsDetector::setPort(portType index, int num) {
int fnum = F_SET_PORT;
int ret = FAIL;
int retval = -1;
// set
if (num >= 0) {
switch(index) {
case CONTROL_PORT:
FILE_LOG(logDEBUG5) << "Setting control port " << " to " << num;
// same port
if (num == thisDetector->controlPort)
return thisDetector->controlPort;
// control socket not created
if (!controlSocket) {
FILE_LOG(logDEBUG5) << "Control socket not created. "
"Connecting to port: " << thisDetector->controlPort;
setTCPSocket();
}
// set port
if (controlSocket && thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &num, sizeof(num), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_CONTROL_PORT));
} else {
thisDetector->controlPort = retval;
FILE_LOG(logDEBUG5) << "Control port: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
break;
case STOP_PORT:
FILE_LOG(logDEBUG5) << "Setting stop port " << " to " << num;
// same port
if (num == thisDetector->stopPort)
return thisDetector->stopPort;
// stop socket not created
if (!stopSocket) {
FILE_LOG(logDEBUG5) << "Stop socket not created. "
"Connecting to port: " << thisDetector->stopPort;
setTCPSocket();
}
// set port
if (stopSocket && thisDetector->onlineFlag == ONLINE_FLAG && connectStop() == OK) {
ret = thisDetectorStop->Client_Send(fnum, &num, sizeof(num), &retval, sizeof(retval));
disconnectStop();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_STOP_PORT));
} else {
thisDetector->stopPort = retval;
FILE_LOG(logDEBUG5) << "Stop port: " << retval;
}
}
break;
case DATA_PORT:
FILE_LOG(logDEBUG5) << "Setting receiver port " << " to " << num;
// same port
if (num == thisDetector->receiverTCPPort)
return thisDetector->receiverTCPPort;
// control socket not created
if (!dataSocket) {
FILE_LOG(logDEBUG5) << "Stop socket not created. "
"Connecting to port: " << thisDetector->receiverTCPPort;;
setReceiverTCPSocket();
}
// set port
if (dataSocket && receiverOnlineFlag->onlineFlag == ONLINE_FLAG && connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, &num, sizeof(num), &retval, sizeof(retval));
disconnectData();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_DATA_PORT));
} else {
thisDetector->receiverTCPPort = retval;
FILE_LOG(logDEBUG5) << "Receiver port: " << retval;
if (ret == FORCE_UPDATE)
ret = updateReceiver();
}
}
break;
default:
FILE_LOG(logERROR) << "Unknown port index " << index;
return -1;
}
}
// get
switch(index) {
case CONTROL_PORT:
return thisDetector->controlPort;
case STOP_PORT:
return thisDetector->stopPort;
case DATA_PORT:
return thisDetector->receiverTCPPort;
default:
return -1;
}
}
int slsDetector::getControlPort() {
return thisDetector->controlPort;
}
int slsDetector::getStopPort() {
return thisDetector->stopPort;
}
int slsDetector::getReceiverPort() {
return thisDetector->receiverTCPPort;
}
int slsDetector::lockServer(int lock) {
int fnum = F_LOCK_SERVER;
int ret = FAIL;
int retval = -1;
FILE_LOG(logDEBUG5) << "Setting detector server lock to " << lock;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &lock, sizeof(lock), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Lock: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
std::string slsDetector::getLastClientIP() {
int fnum = F_LOCK_SERVER;
int ret = FAIL;
char retval[INET_ADDRSTRLEN] = {0};
FILE_LOG(logDEBUG5) << "Getting last client ip to detector server";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Last client IP to detector: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return std::string(retval);
}
int slsDetector::exitServer() {
int fnum = F_EXIT_SERVER;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Sending exit command to detector server";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectControl();
// no ret handling as ret never fail
FILE_LOG(logINFO) << "Shutting down the Detector server";
}
return ret;
}
int slsDetector::execCommand(std::string cmd) {
int fnum = F_EXEC_COMMAND;
int ret = FAIL;
char arg[MAX_STR_LENGTH] = {0};
char retval[MAX_STR_LENGTH] = {0};
strcpy(arg, cmd.c_str());
FILE_LOG(logDEBUG5) << "Sending command to detector " << arg;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum,
arg, sizeof(arg), retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logINFO) << "Detector " << detId << " returned:\n" << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int slsDetector::updateDetectorNoWait() {
int n = 0, i32 = 0;
int64_t i64 = 0;
char lastClientIP[INET_ADDRSTRLEN];
n += controlSocket->ReceiveDataOnly(lastClientIP, sizeof(lastClientIP));
FILE_LOG(logDEBUG5) << "Updating detector last modified by " << lastClientIP;
n += controlSocket->ReceiveDataOnly(&i32, sizeof(i32));
thisDetector->dynamicRange = i32;
n += controlSocket->ReceiveDataOnly(&i32, sizeof(i32));
thisDetector->dataBytes = i32;
n += controlSocket->ReceiveDataOnly(&i32, sizeof(i32));
thisDetector->currentSettings = (detectorSettings)i32;
if (thisDetector->myDetectorType == EIGER) {
n += controlSocket->ReceiveDataOnly(&i32, sizeof(i32));
thisDetector->currentThresholdEV = i32;
}
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[FRAME_NUMBER] = i64;
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[ACQUISITION_TIME] = i64;
if (thisDetector->myDetectorType == EIGER) {
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME] = i64;
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[SUBFRAME_DEADTIME] = i64;
}
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[FRAME_PERIOD] = i64;
if (thisDetector->myDetectorType != EIGER) {
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[DELAY_AFTER_TRIGGER] = i64;
}
if ((thisDetector->myDetectorType != JUNGFRAU) &&
(thisDetector->myDetectorType != EIGER)) {
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[GATES_NUMBER] = i64;
}
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
thisDetector->timerValue[CYCLES_NUMBER] = i64;
if (thisDetector->myDetectorType == JUNGFRAUCTB) {
n += controlSocket->ReceiveDataOnly(&i64, sizeof(i64));
if (i64 >= 0)
thisDetector->timerValue[SAMPLES_JCTB] = i64;
n += controlSocket->ReceiveDataOnly(&i32, sizeof(i32));
thisDetector->roFlags = (readOutFlags)i32;
getTotalNumberOfChannels();
}
if (!n)
FILE_LOG(logERROR) << "Could not update detector, received 0 bytes\n";
return OK;
}
int slsDetector::updateDetector() {
int fnum = F_UPDATE_CLIENT;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Sending update client to detector server";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
// no ret handling as ret never fail
updateDetectorNoWait();
disconnectControl();
}
return ret;
}
int slsDetector::writeConfigurationFile(std::string const fname, multiSlsDetector* m) {
int iline = 0;
std::ofstream outfile;
outfile.open(fname.c_str(),std::ios_base::out);
if (outfile.is_open()) {
iline = writeConfigurationFile(outfile, m);
outfile.close();
}
else {
FILE_LOG(logERROR) << "Error opening configuration file " << fname <<
" for writing";
setErrorMask((getErrorMask())|(CONFIG_FILE));
return FAIL;
}
FILE_LOG(logINFO) << iline << " lines written to configuration file";
return OK;
}
int slsDetector::writeConfigurationFile(std::ofstream &outfile, multiSlsDetector* m) {
const std::vector<std::string> names;
// common config
names.push_back("hostname");
names.push_back("port");
names.push_back("stopport");
names.push_back("settingsdir");
names.push_back("ffdir");
names.push_back("outdir");
names.push_back("lock");
// receiver config
names.push_back("detectormac");
names.push_back("detectorip");
names.push_back("zmqport");
names.push_back("rx_zmqport");
names.push_back("zmqip");
names.push_back("rx_zmqip");
names.push_back("rx_tcpport");
names.push_back("rx_udpport");
names.push_back("rx_udpport2");
names.push_back("rx_udpip");
names.push_back("rx_hostname");
names.push_back("r_readfreq");
// detector specific config
switch (thisDetector->myDetectorType) {
case GOTTHARD:
names.push_back("extsig:0");
names.push_back("vhighvoltage");
break;
case EIGER:
names.push_back("vhighvoltage");
names.push_back("trimen");
names.push_back("iodelay");
names.push_back("tengiga");
break;
case JUNGFRAU:
names.push_back("powerchip");
names.push_back("vhighvoltage");
break;
case JUNGFRAUCTB:
names.push_back("powerchip");
names.push_back("vhighvoltage");
break;
default:
FILE_LOG(logERROR) << "Unknown detector type " << thisDetector->myDetectorType;
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
return FAIL;
}
auto cmd = slsDetectorCommand(m);
for (int iline = 0; iline < nvar; ++iline) {
char* args[] = {(char*)names[iline].c_str()};
outfile << detId << ":";
outfile << names[iline] << " " << cmd.executeLine(1, args, GET_ACTION) << std::endl;
}
return OK;
}
std::string slsDetector::getSettingsFile() {
std::string s(thisDetector->settingsFile);
// return without suffix .sn[detid]
if (s.length() > 6) {
if (s.substr(s.length()-6,3) == std::string(".sn") && s.substr(s.length()-3)!=std::string("xxx"))
return s.substr(0,s.length()-6);
}
return std::string(thisDetector->settingsFile);
}
int slsDetector::writeSettingsFile(std::string fname, int iodelay, int tau) {
return writeSettingsFile(fname, detectorModules[0], iodelay, tau);
}
slsDetectorDefs::detectorSettings slsDetector::getSettings() {
return sendSettingsOnly(GET_SETTINGS);
}
slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings isettings) {
FILE_LOG(logDEBUG5) << "slsDetector setSettings " << isettings;
if (isettings == -1)
return getSettings();
// eiger: only set shm, setting threshold loads the module data
if (thisDetector->myDetectorType == EIGER) {
switch (isettings) {
case STANDARD:
case HIGHGAIN:
case LOWGAIN:
case VERYHIGHGAIN:
case VERYLOWGAIN:
thisDetector->currentSettings = isettings;
return thisDetector->currentSettings;
default:
FILE_LOG(logERROR) << "Unknown settings " << getDetectorSettings(isettings) <<
" for this detector!";
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
return GET_SETTINGS;
}
}
// others: send only the settings, detector server will update dac values already in server
return sendSettingsOnly(isettings);
}
slsDetectorDefs::detectorSettings slsDetector::sendSettingsOnly(detectorSettings isettings) {
int fnum = F_SET_SETTINGS;
int ret = FAIL;
int arg = (int)isettings;
int retval = -1;
FILE_LOG(logDEBUG5) << "Setting settings to " << arg;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
} else {
FILE_LOG(logDEBUG5) << "Settings: " << retval;
thisDetector->currentSettings = (detectorSettings)retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return thisDetector->currentSettings;
}
int slsDetector::getThresholdEnergy() {
int fnum = F_GET_THRESHOLD_ENERGY;
int ret = FAIL;
int retval = -1;
FILE_LOG(logDEBUG5) << "Getting threshold energy";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Threshold: " << retval;
thisDetector->currentThresholdEV = retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return thisDetector->currentThresholdEV;
}
int slsDetector::setThresholdEnergy(int e_eV, detectorSettings isettings, int tb) {
// check as there is client processing
if (thisDetector->myDetectorType == EIGER) {
setThresholdEnergyAndSettings(e_eV, isettings, tb);
return thisDetector->currentThresholdEV;
}
FILE_LOG(logERROR) << "Set threshold energy not implemented for this detector";
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
return -1;
}
int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb) {
// if settings provided, use that, else use the shared memory variable
detectorSettings is = ((isettings != GET_SETTINGS) ? isettings:
thisDetector->currentSettings);
std::string ssettings;
switch (is) {
case STANDARD:
ssettings="/standard";
thisDetector->currentSettings=STANDARD;
break;
case HIGHGAIN:
ssettings="/highgain";
thisDetector->currentSettings=HIGHGAIN;
break;
case LOWGAIN:
ssettings="/lowgain";
thisDetector->currentSettings=LOWGAIN;
break;
case VERYHIGHGAIN:
ssettings="/veryhighgain";
thisDetector->currentSettings=VERYHIGHGAIN;
break;
case VERYLOWGAIN:
ssettings="/verylowgain";
thisDetector->currentSettings=VERYLOWGAIN;
break;
default:
FILE_LOG(logERROR) << "Unknown settings " << getDetectorSettings(is) << " for this detector!";
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
return FAIL;
}
//verify e_eV exists in trimEneregies[]
if (!thisDetector->nTrimEn ||
(e_eV < thisDetector->trimEnergies[0]) ||
(e_eV > thisDetector->trimEnergies[thisDetector->nTrimEn-1]) ) {
FILE_LOG(logERROR) << "This energy " << e_eV << " not defined for this module!";
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
return FAIL;
}
//find if interpolation required
bool interpolate = true;
for (int i = 0; i < thisDetector->nTrimEn; ++i) {
if (thisDetector->trimEnergies[i] == e_eV) {
interpolate = false;
break;
}
}
//fill detector module structure
sls_detector_module *myMod = NULL;
int iodelay = -1; //not included in the module
int tau = -1; //not included in the module
//normal
if (!interpolate) {
//find their directory names
std::ostringstream ostfn;
ostfn << thisDetector->settingsDir << ssettings << "/" << e_eV << "eV"
<< "/noise.sn" << std::setfill('0') << std::setw(3) << std::dec << getId(DETECTOR_SERIAL_NUMBER) << std::setbase(10);
std::string settingsfname = ostfn.str();
FILE_LOG(logDEBUG5) << "Settings File is " << settingsfname;
//read the files
myMod=createModule();
if (NULL == readSettingsFile(settingsfname, iodelay, tau, myMod, tb)) {
if (myMod)deleteModule(myMod);
return FAIL;
}
}
//interpolate
else {
//find the trim values
int trim1 = -1, trim2 = -1;
for (int i = 0; i < thisDetector->nTrimEn; ++i) {
if (e_eV < thisDetector->trimEnergies[i]) {
trim2 = thisDetector->trimEnergies[i];
trim1 = thisDetector->trimEnergies[i-1];
break;
}
}
//find their directory names
std::ostringstream ostfn;
ostfn << thisDetector->settingsDir << ssettings << "/" << trim1 << "eV"
<< "/noise.sn" << std::setfill('0') << std::setw(3) << std::dec <<
getId(DETECTOR_SERIAL_NUMBER) << std::setbase(10);
std::string settingsfname1 = ostfn.str();
ostfn.str(""); ostfn.clear();
ostfn << thisDetector->settingsDir << ssettings << "/" << trim2 << "eV"
<< "/noise.sn" << std::setfill('0') << std::setw(3) << std::dec <<
getId(DETECTOR_SERIAL_NUMBER) << std::setbase(10);
std::string settingsfname2 = ostfn.str();
//read the files
FILE_LOG(logDEBUG5) << "Settings Files are " << settingsfname1 << " and " << settingsfname2;
sls_detector_module *myMod1=createModule();
sls_detector_module *myMod2=createModule();
int iodelay1 = -1; //not included in the module
int tau1 = -1; //not included in the module
int iodelay2 = -1; //not included in the module
int tau2 = -1; //not included in the module
if (NULL == readSettingsFile(settingsfname1,iodelay1, tau1, myMod1, tb)) {
setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN));
deleteModule(myMod1);
deleteModule(myMod2);
return FAIL;
}
if (NULL == readSettingsFile(settingsfname2, iodelay2, tau2, myMod2, tb)) {
setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN));
deleteModule(myMod1);
deleteModule(myMod2);
return FAIL;
}
if (iodelay1 != iodelay2) {
FILE_LOG(logERROR) << "Iodelays do not match between files";
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
deleteModule(myMod1);
deleteModule(myMod2);
return FAIL;
}
iodelay = iodelay1;
//interpolate module
myMod = interpolateTrim( myMod1, myMod2, e_eV, trim1, trim2, tb);
if (myMod == NULL) {
FILE_LOG(logERROR) << "Could not interpolate, different dac values in files";
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
deleteModule(myMod1);
deleteModule(myMod2);
return FAIL;
}
//interpolate tau
tau = linearInterpolation(e_eV, trim1, trim2, tau1, tau2);
//printf("new tau:%d\n",tau);
deleteModule(myMod1);
deleteModule(myMod2);
}
myMod->reg=thisDetector->currentSettings;
setModule(*myMod, iodelay, tau, e_eV, 0, 0, tb);
deleteModule(myMod);
if (getSettings() != is) {
FILE_LOG(logERROR) << "Could not set settings in detector";
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
return FAIL;
}
return OK;
}
std::string slsDetector::getSettingsDir() {
return std::string(thisDetector->settingsDir);
}
std::string slsDetector::setSettingsDir(std::string s) {
sprintf(thisDetector->settingsDir, s.c_str());
return thisDetector->settingsDir;
}
int slsDetector::loadSettingsFile(std::string fname) {
std::string fn = fname;
std::ostringstream ostfn;
ostfn << fname;
// find specific file if it has detid in file name (.snxxx)
if (thisDetector->myDetectorType == EIGER) {
if (fname.find(".sn")==std::string::npos && fname.find(".trim")==
std::string::npos && fname.find(".settings")==std::string::npos) {
ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec <<
getId(DETECTOR_SERIAL_NUMBER);
}
}
fn = ostfn.str();
// read settings file
sls_detector_module *myMod=NULL;
int iodelay = -1;
int tau = -1;
myMod = readSettingsFile(fn, iodelay, tau, myMod);
// set module
int ret = FAIL;
if (myMod != NULL) {
myMod->reg = -1;
ret = setModule(*myMod, iodelay, tau, -1, 0, 0);
deleteModule(myMod);
}
return ret;
}
int slsDetector::saveSettingsFile(std::string fname) {
std::string fn = fname;
std::ostringstream ostfn;
ostfn << fname;
// find specific file if it has detid in file name (.snxxx)
if (thisDetector->myDetectorType == EIGER) {
ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec <<
getId(DETECTOR_SERIAL_NUMBER);
}
fn=ostfn.str();
// get module
int ret = FAIL;
sls_detector_module *myMod = NULL;
if ((myMod = getModule())) {
int iodelay = -1;
int tau = -1;
if (thisDetector->myDetectorType == EIGER) {
iodelay = (int)setDAC((int)-1, IO_DELAY, 0);
tau = getRateCorrection();
}
ret = writeSettingsFile(fn, *myMod, iodelay, tau);
deleteModule(myMod);
}
return ret;
}
slsDetectorDefs::runStatus slsDetector::getRunStatus() {
int fnum = F_GET_RUN_STATUS;
int ret = FAIL;
runStatus retval = ERROR;
FILE_LOG(logDEBUG5) << "Getting status";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectStop() == OK) {
ret = thisDetectorStop->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectStop();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Detector status: " << runStatusType(retval);
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
int slsDetector::prepareAcquisition() {
int fnum = F_PREPARE_ACQUISITION;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Preparing Detector for Acquisition";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(PREPARE_ACQUISITION));
} else {
FILE_LOG(logDEBUG5) << "Prepare Acquisition successful";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int slsDetector::startAcquisition() {
int fnum = F_START_ACQUISITION;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Starting Acquisition";
thisDetector->stoppedFlag = 0;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Starting Acquisition successful";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int slsDetector::stopAcquisition() {
// get status before stopping acquisition
runStatus s = ERROR, r = ERROR;
if (thisDetector->receiver_upstream) {
s = getRunStatus();
r = getReceiverStatus();
}
int fnum = F_STOP_ACQUISITION;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Stopping Acquisition";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectStop() == OK) {
ret = thisDetectorStop->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectStop();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Stopping Acquisition successful";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
thisDetector->stoppedFlag = 1;
// if rxr streaming and acquisition finished, restream dummy stop packet
if ((thisDetector->receiver_upstream) && (s == IDLE) && (r == IDLE)) {
restreamStopFromReceiver();
}
return ret;
}
int slsDetector::sendSoftwareTrigger() {
int fnum = F_SOFTWARE_TRIGGER;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Sending software trigger";
thisDetector->stoppedFlag = 0;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Sending software trigger successful";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int slsDetector::startAndReadAll() {
int fnum = F_START_AND_READ_ALL;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Starting and reading all frames";
thisDetector->stoppedFlag = 0;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectControl();
// handle ret
if (ret == FAIL) {
thisDetector->stoppedFlag = 1;
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Detector successfully finished acquisition";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int slsDetector::startReadOut() {
int fnum = F_START_READOUT;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Starting readout";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Starting detector readout successful";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int slsDetector::readAll() {
int fnum = F_READ_ALL;
int ret = FAIL;
FILE_LOG(logDEBUG5) << "Reading all frames";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectControl();
// handle ret
if (ret == FAIL) {
thisDetector->stoppedFlag = 1;
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Detector successfully finished reading all frames";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int slsDetector::configureMAC() {
int fnum = F_CONFIGURE_MAC;
int ret = FAIL;
char args[9][50];
memset(args, 0, sizeof(args));
char retvals[3][50];
memset(retvals, 0, sizeof(retvals));
FILE_LOG(logDEBUG5) << "Configuring MAC";
// if rx_udpip is none
if (!(strcmp(thisDetector->receiverUDPIP,"none"))) {
//hostname is an ip address
if (strchr(thisDetector->receiver_hostname,'.') != NULL)
strcpy(thisDetector->receiverUDPIP, thisDetector->receiver_hostname);
//if hostname not ip, convert it to ip
else {
struct addrinfo *result;
if (!dataSocket->ConvertHostnameToInternetAddress(
thisDetector->receiver_hostname, &result)) {
// on success
memset(thisDetector->receiverUDPIP, 0, MAX_STR_LENGTH);
// on failure, back to none
if (dataSocket->ConvertInternetAddresstoIpString(result,
thisDetector->receiverUDPIP, MAX_STR_LENGTH)) {
strcpy(thisDetector->receiverUDPIP, "none");
}
}
}
}
// rx_udpip and rx_udpmac is none
if ((!strcmp(thisDetector->receiverUDPIP, "none")) ||
(!strcmp(thisDetector->receiverUDPMAC, "none"))) {
FILE_LOG(logERROR) << "Configure MAC Error. IP/MAC Addresses not set";
setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC));
return FAIL;
}
FILE_LOG(logDEBUG5) << "rx_hostname and rx_udpip is valid ";
// copy to args
strcpy(args[0],thisDetector->receiverUDPIP);
strcpy(args[1],thisDetector->receiverUDPMAC);
sprintf(args[2],"%x",thisDetector->receiverUDPPort);
strcpy(args[3],thisDetector->detectorMAC);
strcpy(args[4],thisDetector->detectorIP);
sprintf(args[5],"%x",thisDetector->receiverUDPPort2);
// 2d positions to detector to put into udp header
{
int pos[3] = {0, 0, 0};
int max = thisDetector->multiSize[1];
// row
pos[0] = (detId % max);
// col for horiz. udp ports
pos[1] = (detId / max) * ((thisDetector->myDetectorType == EIGER) ? 2 : 1);
// pos[2] (z is reserved)
FILE_LOG(logDEBUG5) << "Detector [" << detId << "] - ("
<< pos[0] << "," << pos[1] << ")";
sprintf(args[6], "%x", pos[0]);
sprintf(args[7], "%x", pos[1]);
sprintf(args[8], "%x", pos[2]);
}
{
//converting IPaddress to std::hex
std::stringstream ss(arg[0]);
char cword[50]="";
bzero(cword, 50);
std::string s;
while (getline(ss, s, '.')) {
sprintf(cword,"%s%02x",cword,atoi(s.c_str()));
}
bzero(arg[0], 50);
strcpy(arg[0],cword);
FILE_LOG(logDEBUG5) << "receiver udp ip:" << arg[0] << "-";
}
{
//converting MACaddress to std::hex
std::stringstream ss(arg[1]);
char cword[50]="";
bzero(cword, 50);
std::string s;
while (getline(ss, s, ':')) {
sprintf(cword,"%s%s",cword,s.c_str());
}
bzero(arg[1], 50);
strcpy(arg[1],cword);
FILE_LOG(logDEBUG5) << "receiver udp mac:" << arg[1] << "-";
}
FILE_LOG(logDEBUG5) << "receiver udp port:" << arg[2] << "-";
{
std::stringstream ss(arg[3]);
char cword[50]="";
bzero(cword, 50);
std::string s;
while (getline(ss, s, ':')) {
sprintf(cword,"%s%s",cword,s.c_str());
}
bzero(arg[3], 50);
strcpy(arg[3],cword);
FILE_LOG(logDEBUG5) << "detecotor udp mac:" << arg[3] << "-";
}
{
//converting IPaddress to std::hex
std::stringstream ss(arg[4]);
char cword[50]="";
bzero(cword, 50);
std::string s;
while (getline(ss, s, '.')) {
sprintf(cword,"%s%02x",cword,atoi(s.c_str()));
}
bzero(arg[4], 50);
strcpy(arg[4],cword);
FILE_LOG(logDEBUG5) << "detecotor udp ip:" << arg[4] << "-";
}
FILE_LOG(logDEBUG5) << "receiver udp port2:" << arg[5] << "-";
FILE_LOG(logDEBUG5) << "row:" << arg[6] << "-";
FILE_LOG(logDEBUG5) << "col:" << arg[7] << "-";
FILE_LOG(logDEBUG5) << "reserved:" << arg[8] << "-";
// send to server
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, args, sizeof(args), retvals, sizeof(retvals));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC));
} else {
// get detectormac, detector ip
uint64_t idetectormac = 0;
uint32_t idetectorip = 0;
sscanf(retval[1], "%lx", &idetectormac);
sscanf(retval[2], "%x", &idetectorip);
sprintf(retval[1],"%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned int)((idetectormac>>40)&0xFF),
(unsigned int)((idetectormac>>32)&0xFF),
(unsigned int)((idetectormac>>24)&0xFF),
(unsigned int)((idetectormac>>16)&0xFF),
(unsigned int)((idetectormac>>8)&0xFF),
(unsigned int)((idetectormac>>0)&0xFF));
sprintf(retval[2],"%d.%d.%d.%d",
(idetectorip>>24)&0xff,
(idetectorip>>16)&0xff,
(idetectorip>>8)&0xff,
(idetectorip)&0xff);
// update if different
if (strcasecmp(retval[1],thisDetector->detectorMAC)) {
memset(thisDetector->detectorMAC, 0, MAX_STR_LENGTH);
strcpy(thisDetector->detectorMAC, retval[1]);
FILE_LOG(logINFO, ("%d: Detector MAC updated to %s\n", detId,
thisDetector->detectorMAC));
}
if (strcasecmp(retval[2],thisDetector->detectorIP)) {
memset(thisDetector->detectorIP, 0, MAX_STR_LENGTH);
strcpy(thisDetector->detectorIP, retval[2]);
FILE_LOG(logINFO, ("%d: Detector IP updated to %s\n", detId,
thisDetector->detectorIP));
}
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return ret;
}
int64_t slsDetector::setTimer(timerIndex index, int64_t t) {
int fnum = F_SET_TIMER;
int ret = FAIL;
int64_t args[2] = {(int64_t)index, t};
int64_t retval = -1;
FILE_LOG(logDEBUG5) << "Setting " << getTimerType(index) << " to " << t " ns/value";
// meausurement is only shm level
if (index == MEASUREMENTS_NUMBER) {
if (t >= 0) {
thisDetector->timerValue[index] = t;
FILE_LOG(logDEBUG5) << getTimerType(index) << ": " << t;
}
return thisDetector->timerValue[index];
}
// send to detector
int64_t oldtimer = thisDetector->timerValue[index];
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, args, sizeof(args), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(DETECTOR_TIMER_VALUE_NOT_SET));
} else {
FILE_LOG(logDEBUG5) << getTimerType(index) << ": " << retval;
thisDetector->timerValue[index] = retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
// setting timers consequences (eiger (ratecorr) and jctb (databytes))
// (a get can also change timer value, hence check difference)
if (oldtimer != thisDetector->timerValue[index]) {
// jctb: change samples, change databytes
if (thisDetector->myDetectorType == JUNGFRAUCTB) {
if (index == SAMPLES_JCTB) {
setDynamicRange();
FILE_LOG(logINFO) << "Changing samples: data size = " << thisDetector->dataBytes;
}
}
// eiger: change exptime/subexptime, set rate correction to update table
else if (thisDetector->myDetectorType == EIGER) {
int dr = thisDetector->dynamicRange;
if ((dr == 32 && index == SUBFRAME_ACQUISITION_TIME) ||
(dr == 16 && index == ACQUISITION_TIME)) {
int r = getRateCorrection();
if (r)
setRateCorrection(r);
}
}
}
// send to reciever
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && ret == OK) {
switch (index) {
case FRAME_NUMBER:
case FRAME_PERIOD:
case CYCLES_NUMBER:
case ACQUISITION_TIME:
case SUBFRAME_ACQUISITION_TIME:
case SUBFRAME_DEADTIME:
case SAMPLES_JCTB:
case STORAGE_CELL_NUMBER:
// send
fnum = F_SET_RECEIVER_TIMER;
ret = FAIL;
args[1] = thisDetector->timerValue[index]; // to the value given by detector
retval = -1;
// rewrite args
if ((index == FRAME_NUMBER) || (index == CYCLES_NUMBER) || (index == STORAGE_CELL_NUMBER)) {
args[1] = thisDetector->timerValue[FRAME_NUMBER] *
((thisDetector->timerValue[CYCLES_NUMBER] > 0) ?
(thisDetector->timerValue[CYCLES_NUMBER]) : 1) *
((thisDetector->timerValue[STORAGE_CELL_NUMBER] > 0)
? (thisDetector->timerValue[STORAGE_CELL_NUMBER])+1 : 1);
}
FILE_LOG(logDEBUG5) << "Sending " <<
(((index == FRAME_NUMBER) ||
(index == CYCLES_NUMBER) ||
(index == STORAGE_CELL_NUMBER)) ?
"(#Frames) * (#cycles) * (#storage cells)" : getTimerType(index)) <<
<< " to receiver: " << args[1];
if (connectData() == OK) {
char mess[MAX_STR_LENGTH] = {0};
ret = thisReceiver->Client_Send(fnum, args, sizeof(args), &retval, sizeof(retval), mess);
disconnectData();
// handle ret
if (ret == FAIL) {
switch(index) {
case ACQUISITION_TIME:
setErrorMask((getErrorMask())|(RECEIVER_ACQ_TIME_NOT_SET));
break;
case FRAME_PERIOD:
setErrorMask((getErrorMask())|(RECEIVER_ACQ_PERIOD_NOT_SET));
break;
case SUBFRAME_ACQUISITION_TIME:
case SUBFRAME_DEADTIME:
case SAMPLES_JCTB:
setErrorMask((getErrorMask())|(RECEIVER_TIMER_NOT_SET));
break;
case FRAME_NUMBER:
case CYCLES_NUMBER:
case STORAGE_CELL_NUMBER:
setErrorMask((getErrorMask())|(RECEIVER_FRAME_NUM_NOT_SET));
break;
default:
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
break;
}
} else if (ret == FORCE_UPDATE)
ret = updateReceiver();
}
break;
default:
break;
}
}
return thisDetector->timerValue[index];
}
int64_t slsDetector::getTimeLeft(timerIndex index) {
int fnum = F_GET_TIME_LEFT;
int ret = FAIL;
int64_t retval = -1;
FILE_LOG(logDEBUG5) << "Getting " << getTimerType(index) << " left";
if (thisDetector->onlineFlag == ONLINE_FLAG && connectStop() == OK) {
ret = thisDetectorStop->Client_Send(fnum, &index, sizeof(index), &retval, sizeof(retval));
disconnectStop();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << getTimerType(index) << " left: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
int slsDetector::setSpeed(speedVariable sp, int value) {
int fnum = F_SET_SPEED;
int ret = FAIL;
int retval = -1;
FILE_LOG(logDEBUG5) << "Setting speed index " << sp << " to " << value;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &value, sizeof(value), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULD_NOT_SET_SPEED_PARAMETERS));
} else {
FILE_LOG(logDEBUG5) << "Speed index " << sp << ": " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
int slsDetector::setDynamicRange(int n) {
int fnum = F_SET_DYNAMIC_RANGE;
int ret = FAIL;
int retval = -1;
FILE_LOG(logDEBUG5) << "Setting dynamic range to " << n;
// send to detector
int olddr = thisDetector->dynamicRange;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &n, sizeof(n), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
// eiger: dr set correctly, consequent rate correction was a problem
if ((thisDetector->myDetectorType == EIGER &&
strstr(mess,"Rate Correction") != NULL)) {
// rate correction is switched off if not 32 bit mode
if (strstr(mess,"32") != NULL)
setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32or16BIT));
else
setErrorMask((getErrorMask())|(COULD_NOT_SET_RATE_CORRECTION));
ret = OK; // dr was set correctly to reach rate correction
}
else
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
}
// ret might be set to OK above
if (ret != FAIL) {
FILE_LOG(logDEBUG5) << "Dynamic Range: " << retval;
thisDetector->dynamicRange = retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
// setting dr consequences on databytes shm
// (a get can also change timer value, hence check difference)
if (olddr != thisDetector->dynamicRange) {
thisDetector->dataBytes = thisDetector->nChips * thisDetector->nChans * retval / 8;
thisDetector->dataBytesInclGapPixels =
(thisDetector->nChip[X] * thisDetector->nChan[X] +
thisDetector->gappixels * thisDetector->nGappixels[X]) *
(thisDetector->nChip[Y] * thisDetector->nChan[Y] +
thisDetector->gappixels * thisDetector->nGappixels[Y]) *
retval / 8;
if (thisDetector->myDetectorType == JUNGFRAUCTB)
getTotalNumberOfChannels();
FILE_LOG(logDEBUG5) << "Data bytes " << thisDetector->dataBytes;
FILE_LOG(logDEBUG5) << "Data bytes including gap pixels" << thisDetector->dataBytesInclGapPixels;
}
// send to receiver
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && ret == OK) {
fnum = F_SET_RECEIVER_DYNAMIC_RANGE;
ret = FAIL;
n = thisDetector->dynamicRange;
retval = -1;
FILE_LOG(logINFO) << "Sending dynamic range to receiver " << n;
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum2, &n, sizeof(n), &retval, sizeof(retval));
disconnectData();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(RECEIVER_DYNAMIC_RANGE));
} else {
FILE_LOG(logDEBUG5) << "Receiver Dynamic range: " << retval;
if (ret == FORCE_UPDATE)
ret = updateReceiver();
}
}
}
return thisDetector->dynamicRange;
}
int slsDetector::getDataBytes() {
return thisDetector->dataBytes;
}
int slsDetector::getDataBytesInclGapPixels() {
return thisDetector->dataBytesInclGapPixels;
}
int slsDetector::setDAC(int val, dacIndex index, int mV) {
if ((index == HV_NEW) && (thisDetector->myDetectorType == GOTTHARD))
index = HV_POT;
int fnum = F_SET_DAC;
int ret = FAIL;
int args[3] = {(int)index, mV, val};
int retvals[2] = {-1, -1};
FILE_LOG(logDEBUG5) << "Setting DAC " << index << " to " << val << (mV ? "mV" : "dac units");
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, args, sizeof(args), retvals, sizeof(retvals));
disconnectControl();
// handle ret
if (ret == FAIL)
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
else {
FILE_LOG(logDEBUG5) << "Dac index " << index << ": "
<< retval[0] << " dac units (" << retval[1] << "mV)";
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
if (mV)
return retval[1];
return retval[0];
}
int slsDetector::getADC(dacIndex index) {
int fnum = F_GET_ADC;
int ret = FAIL;
int arg = (int)index;
int retval = -1;
FILE_LOG(logDEBUG5) << "Getting ADC " << index;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL)
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
else
FILE_LOG(logDEBUG5) << "ADC (" << index << "): " << retval;
/*commented out to allow adc read during acquire
else if (ret == FORCE_UPDATE)
updateDetector();*/
}
return retval;
}
slsDetectorDefs::externalCommunicationMode slsDetector::setExternalCommunicationMode(
externalCommunicationMode pol) {
int fnum = F_SET_EXTERNAL_COMMUNICATION_MODE;
int ret = FAIL;
int arg = (int)pol;
externalCommunicationMode retval = GET_EXTERNAL_COMMUNICATION_MODE;
FILE_LOG(logDEBUG5) << "Setting communication to mode " << pol;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Timing Mode: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
slsDetectorDefs::externalSignalFlag slsDetector::setExternalSignalFlags(
externalSignalFlag pol, int signalindex) {
int fnum = F_SET_EXTERNAL_SIGNAL_FLAG;
int ret = FAIL;
int args[2] = {signalindex, pol};
externalCommunicationMode retval = GET_EXTERNAL_SIGNAL_FLAG;
FILE_LOG(logDEBUG5) << "Setting signal " << signalindex << " to flag " << pol;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, args, sizeof(args), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
} else {
FILE_LOG(logDEBUG5) << "Ext Signal (" << signalindex << "): " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
int slsDetector::setReadOutFlags(readOutFlags flag) {
int fnum = F_SET_READOUT_FLAGS;
int ret = FAIL;
int arg = (int)flag;
readOutFlags retval = GET_READOUT_FLAGS;
FILE_LOG(logDEBUG5) << "Setting readout flags to " << flag;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULD_NOT_SET_READOUT_FLAGS));
} else {
FILE_LOG(logDEBUG5) << "Readout flag: " << retval;
thisDetector->roFlags = (readOutFlags)retval;
if (thisDetector->myDetectorType == JUNGFRAUCTB) {
getTotalNumberOfChannels();
}
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return thisDetector->roFlags;
}
uint32_t slsDetector::writeRegister(uint32_t addr, uint32_t val) {
int fnum = F_WRITE_REGISTER;
int ret = FAIL;
uint32_t args[2] = {addr, val};
uint32_t retval = -1;
FILE_LOG(logDEBUG5) << "Writing to register 0x" << std::hex <<
addr << "data: 0x" << std::hex << val << std::dec;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, args, sizeof(args), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL)
setErrorMask((getErrorMask())|(REGISER_WRITE_READ));
else {
FILE_LOG(logDEBUG5) << "Register 0x" <<
std::hex << addr << ": 0x" << std::hex << retval << std::dec;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
uint32_t slsDetector::readRegister(uint32_t addr) {
int fnum = F_READ_REGISTER;
int ret = FAIL;
uint32_t arg = -1;
uint32_t retval = -1;
FILE_LOG(logDEBUG5) << "Reading register 0x" << std::hex << addr << std::dec;
if (thisDetector->onlineFlag == ONLINE_FLAG && connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL)
setErrorMask((getErrorMask())|(REGISER_WRITE_READ));
else {
FILE_LOG(logDEBUG5) << "Register 0x" <<
std::hex << addr << ": 0x" << std::hex << retval << std::dec;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return retval;
}
uint32_t slsDetector::setBit(uint32_t addr, int n) {
if (n < 0 || n > 31) {
FILE_LOG(logERROR) << "Bit number " << n << " out of Range";
setErrorMask((getErrorMask())|(REGISER_WRITE_READ));
return -1;
}
else {
uint32_t val = readRegister(addr);
if (getErrorMask() | REGISER_WRITE_READ)
return -1;
return writeRegister(addr, val | 1 << n);
}
}
uint32_t slsDetector::clearBit(uint32_t addr, int n) {
if (n < 0 || n > 31) {
FILE_LOG(logERROR) << "Bit number " << n << " out of Range";
setErrorMask((getErrorMask())|(REGISER_WRITE_READ));
return -1;
}
else {
uint32_t val = readRegister(addr);
if (getErrorMask() | REGISER_WRITE_READ)
return -1;
return writeRegister(addr, val & ~(1 << n));
}
}
std::string slsDetector::setNetworkParameter(networkParameter index, std::string value) {
switch (index) {
case DETECTOR_MAC:
return setDetectorMAC(value);
case DETECTOR_IP:
return setDetectorIP(value);
case RECEIVER_HOSTNAME:
return setReceiver(value);
case RECEIVER_UDP_IP:
return setReceiverUDPIP(value);
case RECEIVER_UDP_MAC:
return setReceiverUDPMAC(value);
case RECEIVER_UDP_PORT:
setReceiverUDPPort(stoi(value));
return getReceiverUDPPort();
case RECEIVER_UDP_PORT2:
if (thisDetector->myDetectorType == EIGER) {
setReceiverUDPPort2(stoi(value));
return getReceiverUDPPort2();
} else {
setReceiverUDPPort(stoi(value));
return getReceiverUDPPort();
}
case DETECTOR_TXN_DELAY_LEFT:
case DETECTOR_TXN_DELAY_RIGHT:
case DETECTOR_TXN_DELAY_FRAME:
case FLOW_CONTROL_10G:
return setDetectorNetworkParameter(index, stoi(value));
case CLIENT_STREAMING_PORT:
return setClientStreamingPort(value);
case RECEIVER_STREAMING_PORT:
return setReceiverStreamingPort(value);
case CLIENT_STREAMING_SRC_IP:
return setClientStreamingIP(value);
case RECEIVER_STREAMING_SRC_IP:
return setReceiverStreamingIP(value);
case ADDITIONAL_JSON_HEADER:
return setAdditionalJsonHeader(value);
case RECEIVER_UDP_SCKT_BUF_SIZE:
setReceiverUDPSocketBufferSize(stoi(value));
return getReceiverUDPSocketBufferSize();
default:
return (char*)("unknown network parameter");
}
}
std::string slsDetector::getNetworkParameter(networkParameter index) {
switch (index) {
case DETECTOR_MAC:
return getDetectorMAC();
case DETECTOR_IP:
return getDetectorIP();
case RECEIVER_HOSTNAME:
return getReceiver();
case RECEIVER_UDP_IP:
return getReceiverUDPIP();
case RECEIVER_UDP_MAC:
return getReceiverUDPMAC();
case RECEIVER_UDP_PORT:
return getReceiverUDPPort();
case RECEIVER_UDP_PORT2:
return getReceiverUDPPort2();
case DETECTOR_TXN_DELAY_LEFT:
case DETECTOR_TXN_DELAY_RIGHT:
case DETECTOR_TXN_DELAY_FRAME:
case FLOW_CONTROL_10G:
return setDetectorNetworkParameter(index, -1);
case CLIENT_STREAMING_PORT:
return getClientStreamingPort();
case RECEIVER_STREAMING_PORT:
return getReceiverStreamingPort();
case CLIENT_STREAMING_SRC_IP:
return getClientStreamingIP();
case RECEIVER_STREAMING_SRC_IP:
return getReceiverStreamingIP();
case ADDITIONAL_JSON_HEADER:
return getAdditionalJsonHeader();
case RECEIVER_UDP_SCKT_BUF_SIZE:
return getReceiverUDPSocketBufferSize();
case RECEIVER_REAL_UDP_SCKT_BUF_SIZE:
return getReceiverRealUDPSocketBufferSize();
default:
return std::string("unknown network parameter");
}
}
std::string slsDetector::getDetectorMAC() {
return std::string(thisDetector->detectorMAC);
}
std::string slsDetector::getDetectorIP() {
return std::string(thisDetector->detectorIP);
}
std::string slsDetector::getReceiver() {
return std::string(thisDetector->receiver_hostname);
}
std::string slsDetector::getReceiverUDPIP() {
return std::string(thisDetector->receiverUDPIP);
}
std::string slsDetector::getReceiverUDPMAC() {
return std::string(thisDetector->receiverUDPMAC);
}
std::string slsDetector::getReceiverUDPPort() {
return std::to_string(thisDetector->receiverUDPPort);
}
std::string slsDetector::getReceiverUDPPort2() {
return std::to_string(thisDetector->receiverUDPPort2);
}
std::string slsDetector::getClientStreamingPort() {
return std::to_string(thisDetector->zmqport);
}
std::string slsDetector::getReceiverStreamingPort() {
return std::to_string(thisDetector->receiver_zmqport);
}
std::string slsDetector::getClientStreamingIP() {
return std::string(thisDetector->zmqip);
}
std::string slsDetector::getReceiverStreamingIP() {
return std::string(thisDetector->receiver_zmqip);
}
std::string slsDetector::getAdditionalJsonHeader() {
return std::string(thisDetector->receiver_additionalJsonHeader);
}
std::string slsDetector::getReceiverUDPSocketBufferSize() {
return setReceiverUDPSocketBufferSize();
}
std::string slsDetector::getReceiverRealUDPSocketBufferSize() {
int fnum = F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE;
int ret = FAIL;
int retval = -1;
FILE_LOG(logDEBUG5) << "Getting real UDP Socket Buffer size to receiver";
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectData();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
} else {
FILE_LOG(logDEBUG5) << "Real Receiver UDP Socket Buffer size: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return std::string(retval);
}
std::string slsDetector::setDetectorMAC(std::string detectorMAC) {
// invalid format
if ((detectorMAC.length() != 17) ||
(detectorMAC[2] == ':') || (detectorMAC[5] == ':') || (detectorMAC[8] == ':') ||
(detectorMAC[11] == ':') ||(detectorMAC[14] == ':')) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
FILE_LOG(logERROR) << "server MAC Address should be in xx:xx:xx:xx:xx:xx format";
}
// valid format
else {
strcpy(thisDetector->detectorMAC, detectorMAC.c_str());
if (!strcmp(thisDetector->receiver_hostname, "none")) {
FILE_LOG(logDEBUG5) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL)
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
}
return std::string(thisDetector->detectorMAC);
}
std::string slsDetector::setDetectorIP(std::string detectorIP) {
struct sockaddr_in sa;
if (detectorIP.length() && detectorIP.length() < 16) {
int result = inet_pton(AF_INET, detectorIP.c_str(), &(sa.sin_addr));
// invalid format
if (result == 0) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
FILE_LOG(logERROR) << "Detector IP Address should be VALID and in "
"xxx.xxx.xxx.xxx format";
}
// valid format
else {
strcpy(thisDetector->detectorIP, detectorIP.c_str());
if (!strcmp(thisDetector->receiver_hostname, "none")) {
FILE_LOG(logDEBUG5) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
}
}
return std::string(thisDetector->detectorIP);
}
std::string slsDetector::setReceiver(std::string receiverIP) {
FILE_LOG(logDEBUG5) << "Setting up Receiver with " << receiverIP;
// recieverIP is none
if (receiverIP == "none") {
memset(thisDetector->receiver_hostname, 0, MAX_STR_LENGTH);
strcpy(thisDetector->receiver_hostname, "none");
thisDetector->receiverOnlineFlag = OFFLINE_FLAG;
return std::string(thisDetector->receiver_hostname);
}
// stop acquisition if running
if (getRunStatus()==RUNNING) {
FILE_LOG(logWARNING, ("Acquisition already running, Stopping it.\n"));
stopAcquisition();
}
// update detector before receiver
updateDetector();
// start updating
strcpy(thisDetector->receiver_hostname, receiverIP.c_str());
if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) {
FILE_LOG(logDEBUG5) <<
"detector type:" << (slsDetectorDefs::getDetectorType(thisDetector->myDetectorType)) <<
"\ndetector id:" << detId <<
"\ndetector hostname:" << thisDetector->hostname <<
"\nfile path:" << thisDetector->receiver_filePath <<
"\nfile name:" << thisDetector->receiver_fileName <<
"\nfile index:" << thisDetector->receiver_fileIndex <<
"\nfile format:" << thisDetector->receiver_fileFormatType <<
"\nr_framesperfile:" << thisDetector->receiver_framesPerFile <<
"\nr_discardpolicy:" << thisDetector->receiver_frameDiscardMode <<
"\nr_padding:" << thisDetector->receiver_framePadding <<
"\nwrite enable:" << thisDetector->receiver_fileWriteEnable <<
"\noverwrite enable:" << thisDetector->receiver_overWriteEnable <<
"\nframe index needed:" <<
((thisDetector->timerValue[FRAME_NUMBER] * thisDetector->timerValue[CYCLES_NUMBER]) > 1) <<
"\nframe period:" << (thisDetector->timerValue[FRAME_PERIOD]) <<
"\nframe number:" << (thisDetector->timerValue[FRAME_NUMBER]) <<
"\nsub exp time:" << (thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME]) <<
"\nsub dead time:" << (thisDetector->timerValue[SUBFRAME_DEADTIME]) <<
"\nsamples:" << (thisDetector->timerValue[SAMPLES_JCTB]) <<
"\ndynamic range:" << thisDetector->dynamicRange <<
"\nflippeddatax:" << (thisDetector->flippedData[X]) <<
"\nactivated: " << thisDetector->activated <<
"\nreceiver deactivated padding: " << thisDetector->receiver_deactivatedPaddingEnable <<
"\nsilent Mode:" << thisDetector->receiver_silentMode <<
"\n10GbE:" << thisDetector->tenGigaEnable <<
"\nGap pixels: " << thisDetector->gappixels <<
"\nr_readfreq:" << thisDetector->receiver_read_freq <<
"\nrx streaming port:" << thisDetector->receiver_zmqport <<
"\nrx streaming source ip:" << thisDetector->receiver_zmqip <<
"\nrx additional json header:" << thisDetector->receiver_additionalJsonHeader <<
"\nrx_datastream:" << enableDataStreamingFromReceiver(-1) << std::endl;
if (setDetectorType(thisDetector->myDetectorType) != GENERIC) {
sendMultiDetectorSize();
setDetectorId();
setDetectorHostname();
setUDPConnection();
setFilePath(thisDetector->receiver_filePath);
setFileName(thisDetector->receiver_fileName);
setFileIndex(thisDetector->receiver_fileIndex);
setFileFormat(thisDetector->receiver_fileFormatType);
setReceiverFramesPerFile(thisDetector->receiver_framesPerFile);
setReceiverFramesDiscardPolicy(thisDetector->receiver_frameDiscardMode);
setReceiverPartialFramesPadding(thisDetector->receiver_framePadding);
enableWriteToFile(thisDetector->receiver_fileWriteEnable);
overwriteFile(thisDetector->receiver_overWriteEnable);
setTimer(FRAME_PERIOD,thisDetector->timerValue[FRAME_PERIOD]);
setTimer(FRAME_NUMBER,thisDetector->timerValue[FRAME_NUMBER]);
setTimer(ACQUISITION_TIME,thisDetector->timerValue[ACQUISITION_TIME]);
if (thisDetector->myDetectorType == EIGER) {
setTimer(SUBFRAME_ACQUISITION_TIME,
thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME]);
setTimer(SUBFRAME_DEADTIME,thisDetector->timerValue[SUBFRAME_DEADTIME]);
}
if (thisDetector->myDetectorType == JUNGFRAUCTB)
setTimer(SAMPLES_JCTB,thisDetector->timerValue[SAMPLES_JCTB]);
setDynamicRange(thisDetector->dynamicRange);
if (thisDetector->myDetectorType == EIGER) {
setFlippedData(X,-1);
activate(-1);
setDeactivatedRxrPaddingMode(thisDetector->receiver_deactivatedPaddingEnable);
}
setReceiverSilentMode(thisDetector->receiver_silentMode);
if (thisDetector->myDetectorType == EIGER)
enableTenGigabitEthernet(thisDetector->tenGigaEnable);
enableGapPixels(thisDetector->gappixels);
// data streaming
setReceiverStreamingFrequency(thisDetector->receiver_read_freq);
setReceiverStreamingPort(getReceiverStreamingPort());
setReceiverStreamingIP(getReceiverStreamingIP());
setAdditionalJsonHeader(getAdditionalJsonHeader());
enableDataStreamingFromReceiver(enableDataStreamingFromReceiver(-1));
if (thisDetector->myDetectorType == GOTTHARD)
sendROI(-1, NULL);
}
}
return std::string(thisDetector->receiver_hostname);
}
std::string slsDetector::setReceiverUDPIP(std::string udpip) {
struct sockaddr_in sa;
if (udpip.length() && udpip.length() < 16) {
int result = inet_pton(AF_INET, udpip.c_str(), &(sa.sin_addr));
// invalid format
if (result == 0) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
FILE_LOG(logERROR) << "Receiver UDP IP Address should be VALID "
"and in xxx.xxx.xxx.xxx format" << std::endl;
}
// valid format
else {
strcpy(thisDetector->receiverUDPIP,udpip.c_str());
if (!strcmp(thisDetector->receiver_hostname, "none")) {
FILE_LOG(logDEBUG5) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
}
}
return std::string(thisDetector->receiverUDPIP);
}
std::string slsDetector::setReceiverUDPMAC(std::string udpmac) {
// invalid format
if ((udpmac.length() != 17) ||
(udpmac[2] == ':') || (udpmac[5] == ':') || (udpmac[8] == ':') ||
(udpmac[11] == ':') ||(udpmac[14] == ':')) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
FILE_LOG(logERROR) << "receiver udp MAC Address should be in xx:xx:xx:xx:xx:xx format";
}
// valid format
else {
strcpy(thisDetector->receiverUDPMAC, udpmac.c_str());
if (!strcmp(thisDetector->receiver_hostname, "none")) {
FILE_LOG(logDEBUG5) << "Receiver hostname not set yet";
}
// not doing setUDPConnection as rx_udpmac will get replaced,(must use configuremac)
strcpy(thisDetector->receiverUDPMAC,udpmac.c_str());
}
return std::string(thisDetector->receiverUDPMAC);
}
int slsDetector::setReceiverUDPPort(int udpport) {
thisDetector->receiverUDPPort = udpport;
if (!strcmp(thisDetector->receiver_hostname, "none")) {
FILE_LOG(logDEBUG5) << "Receiver hostname not set yet";
}
else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return thisDetector->receiverUDPPort;
}
int slsDetector::setReceiverUDPPort2(int udpport) {
thisDetector->receiverUDPPort2 = udpport;
if (!strcmp(thisDetector->receiver_hostname, "none")) {
FILE_LOG(logDEBUG5) << "Receiver hostname not set yet";
}
else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return thisDetector->receiverUDPPort2;
}
std::string slsDetector::setClientStreamingPort(std::string port) {
thisDetector->zmqport = stoi(port);
return getClientStreamingPort();
}
std::string slsDetector::setReceiverStreamingPort(std::string port) {
// copy now else it is lost if rx_hostname not set yet
thisDetector->receiver_zmqport = stoi(port);
int fnum = F_SET_RECEIVER_STREAMING_PORT;
int ret = FAIL;
int arg = thisDetector->receiver_zmqport;
int retval = -1;
FILE_LOG(logDEBUG5) << "Sending receiver streaming port to receiver " << arg;
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
} else {
FILE_LOG(logDEBUG5) << "Receiver streaming port: " << retval;
thisDetector->receiver_zmqport = retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return getReceiverStreamingPort();
}
std::string slsDetector::setClientStreamingIP(std::string sourceIP) {
struct addrinfo *result;
// on failure to convert to a valid ip
if (dataSocket->ConvertHostnameToInternetAddress(sourceIP.c_str(), &result)) {
FILE_LOG(logWARNING) << "Could not convert zmqip into a valid IP" << sourceIP;
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
return getClientStreamingIP();
}
// on success put IP as std::string into arg
memset(thisDetector->zmqip, 0, MAX_STR_LENGTH);
dataSocket->ConvertInternetAddresstoIpString(result, thisDetector->zmqip, MAX_STR_LENGTH);
return getClientStreamingIP();
}
std::string slsDetector::setReceiverStreamingIP(std::string sourceIP) {
int fnum = F_RECEIVER_STREAMING_SRC_IP;
int ret = FAIL;
char args[MAX_STR_LENGTH] = {0};
char retvals[MAX_STR_LENGTH] = {0};
FILE_LOG(logDEBUG5) << "Sending receiver streaming IP to receiver " << sourceIP;
// if empty, give rx_hostname
if (sourceIP.empty()) {
if (!strcmp(thisDetector->receiver_hostname, "none")) {
FILE_LOG(logWARNING) << "Receiver hostname not set yet. Cannot create rx_zmqip from none";
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
return getReceiverStreamingIP();
}
sourceIP.assign(thisDetector->receiver_hostname);
}
// verify the ip
{
struct addrinfo *result;
// on failure to convert to a valid ip
if (dataSocket->ConvertHostnameToInternetAddress(sourceIP.c_str(), &result)) {
FILE_LOG(logWARNING) << "Could not convert rx_zmqip into a valid IP" << sourceIP;
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
return getReceiverStreamingIP();
}
// on success put IP as std::string into arg
dataSocket->ConvertInternetAddresstoIpString(result, args, sizeof(args));
}
// set it anyway, else it is lost if rx_hostname is not set yet
memset(thisDetector->receiver_zmqip, 0, MAX_STR_LENGTH);
strcpy(thisDetector->receiver_zmqip, args);
// if zmqip is empty, update it
if (! strlen(thisDetector->zmqip))
strcpy(thisDetector->zmqip, args);
FILE_LOG(logDEBUG5) << "Sending receiver streaming IP to receiver " << args;
// send to receiver
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, args, sizeof(args), retvals, sizeof(retvals));
disconnectData();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
} else {
FILE_LOG(logDEBUG5) << "Receiver streaming port: " << retvals;
memset(thisDetector->receiver_zmqip, 0, MAX_STR_LENGTH);
strcpy(thisDetector->receiver_zmqip, retvals);
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return getReceiverStreamingIP();
}
std::string slsDetector::setAdditionalJsonHeader(std::string jsonheader) {
int fnum = F_ADDITIONAL_JSON_HEADER;
int ret = FAIL;
char args[MAX_STR_LENGTH] = {0};
char retvals[MAX_STR_LENGTH] = {0};
strcpy(args, jsonheader.c_str());
FILE_LOG(logDEBUG5) << "Sending additional json header " << args;
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, args, sizeof(args), retvals, sizeof(retvals));
disconnectData();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
} else {
FILE_LOG(logDEBUG5) << "Additional json header: " << retvals;
memset(thisDetector->receiver_additionalJsonHeader, 0, MAX_STR_LENGTH);
strcpy(thisDetector->receiver_additionalJsonHeader, retvals);
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return getAdditionalJsonHeader();
}
std::string slsDetector::setReceiverUDPSocketBufferSize(int udpsockbufsize) {
int fnum = F_RECEIVER_UDP_SOCK_BUF_SIZE;
int ret = FAIL;
int arg = udpsockbufsize;
int retval = -1;
FILE_LOG(logDEBUG5) << "Sending UDP Socket Buffer size to receiver " << arg;
if (thisDetector->receiverOnlineFlag == ONLINE_FLAG && connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
// handle ret
if (ret == FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER));
} else {
FILE_LOG(logDEBUG5) << "Receiver UDP Socket Buffer size: " << retval;
if (ret == FORCE_UPDATE)
ret = updateDetector();
}
}
return std::to_string(retval);
}
std::string slsDetector::setDetectorNetworkParameter(networkParameter index, int delay) {
int fnum = F_SET_NETWORK_PARAMETER;
int ret = FAIL;
int retval = -1;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
FILE_LOG(logINFO) << "Setting Transmission delay of mode "<< index << " to " << delay << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&index,sizeof(index));
controlSocket->SendDataOnly(&delay,sizeof(delay));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(DETECTOR_NETWORK_PARAMETER));
} else
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
#ifdef VERBOSE
FILE_LOG(logINFO) << "Speed set to "<< retval << std::endl;
#endif
std::ostringstream ss;
ss << retval;
std::string s = ss.str();
return s;
}
int slsDetector::setUDPConnection() {
int ret = FAIL;
int fnum = F_SETUP_RECEIVER_UDP;
char args[3][MAX_STR_LENGTH] = {0};
char retval[MAX_STR_LENGTH] = {0};
//called before set up
if (!strcmp(thisDetector->receiver_hostname,"none")) {
#ifdef VERBOSE
std::cout << "Warning: Receiver hostname not set yet." << std::endl;
#endif
return FAIL;
}
//if no udp ip given, use hostname
if (!strcmp(thisDetector->receiverUDPIP,"none")) {
//hostname is an ip address
if (strchr(thisDetector->receiver_hostname,'.')!=NULL)
strcpy(thisDetector->receiverUDPIP,thisDetector->receiver_hostname);
//if hostname not ip, convert it to ip
else {
struct addrinfo *result;
if (!dataSocket->ConvertHostnameToInternetAddress(
thisDetector->receiver_hostname, &result)) {
// on success
memset(thisDetector->receiverUDPIP, 0, MAX_STR_LENGTH);
// on failure, back to none
if (dataSocket->ConvertInternetAddresstoIpString(result,
thisDetector->receiverUDPIP, MAX_STR_LENGTH)) {
strcpy(thisDetector->receiverUDPIP, "none");
}
}
}
}
//copy arguments to args[][]
strcpy(args[0],thisDetector->receiverUDPIP);
sprintf(args[1],"%d",thisDetector->receiverUDPPort);
sprintf(args[2],"%d",thisDetector->receiverUDPPort2);
#ifdef VERBOSE
std::cout << "Receiver udp ip address: " << thisDetector->receiverUDPIP << std::endl;
std::cout << "Receiver udp port: " << thisDetector->receiverUDPPort << std::endl;
std::cout << "Receiver udp port2: " << thisDetector->receiverUDPPort2 << std::endl;
#endif
//set up receiver for UDP Connection and get receivermac address
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
std::cout << "Setting up UDP Connection for Receiver " << args[0] << "\t" << args[1] << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &args, sizeof(args), &retval, sizeof(retval));
disconnectData();
}
if (ret!=FAIL) {
strcpy(thisDetector->receiverUDPMAC,retval);
#ifdef VERBOSE
std::cout << "Receiver mac address: " << thisDetector->receiverUDPMAC << std::endl;
#endif
if (ret==FORCE_UPDATE)
updateReceiver();
//configure detector with udp details, -100 is so it doesnt overwrite
//the previous value
if (configureMAC()==FAIL) {
setReceiverOnline(OFFLINE_FLAG);
std::cout << "could not configure mac" << std::endl;
}
}
} else
ret=FAIL;
#ifdef VERBOSE
printReceiverConfiguration();
#endif
return ret;
}
int slsDetector::digitalTest( digitalTestMode mode, int ival) {
int fnum = F_DIGITAL_TEST;
int ret = FAIL;
int args[2] = {mode, ival};
int retval = -1;
FILE_LOG(logDEBUG5) << "Sending digital test of mode " << mode << ", ival " << ival;
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
ret = thisDetectorControl->Client_Send(fnum,
args, sizeof(args), &retval, sizeof(retval));
disconnectControl();
// handle ret
if (ret == FAIL)
setErrorMask((getErrorMask())|(OTHER_ERROR_CODE));
else if (ret == FORCE_UPDATE)
updateDetector();
}
}
if (ret != FAIL && mode == DIGITAL_BIT_TEST) {
FILE_LOG(logDEBUG5) << "Digital test bit: " << retval;
}
return retval;
}
int slsDetector::loadImageToDetector(imageType index,std::string const fname) {
int ret=FAIL;
short int arg[thisDetector->nChans*thisDetector->nChips];
#ifdef VERBOSE
std::cout<< std::endl<< "Loading ";
if (!index)
std::cout<<"Dark";
else
std::cout<<"Gain";
std::cout<<" image from file " << fname << std::endl;
#endif
if (readDataFile(fname,arg,getTotalNumberOfChannels())) {
ret = sendImageToDetector(index,arg);
return ret;
}
FILE_LOG(logERROR) << "Could not open file "<< fname << std::endl;
return ret;
}
int slsDetector::sendImageToDetector(imageType index,short int imageVals[]) {
int ret=FAIL;
int retval;
int fnum=F_LOAD_IMAGE;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<<"Sending image to detector " <<std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&index,sizeof(index));
controlSocket->SendDataOnly(imageVals,thisDetector->dataBytes);
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL)
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::writeCounterBlockFile(std::string const fname,int startACQ) {
#ifdef VERBOSE
std::cout<< std::endl<< "Reading Counter to \""<<fname;
if (startACQ==1)
std::cout<<"\" and Restarting Acquisition";
std::cout<<std::endl;
#endif
short int counterVals[thisDetector->nChans*thisDetector->nChips];
int ret=getCounterBlock(counterVals,startACQ);
if (ret==OK)
ret=writeDataFile(fname, getTotalNumberOfChannels(), counterVals);
return ret;
}
int slsDetector::getCounterBlock(short int arg[],int startACQ) {
int ret=FAIL;
int fnum=F_READ_COUNTER_BLOCK;
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&startACQ,sizeof(startACQ));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL)
controlSocket->ReceiveDataOnly(arg,thisDetector->dataBytes);
else {
char mess[MAX_STR_LENGTH]="";
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::resetCounterBlock(int startACQ) {
int ret=FAIL;
int fnum=F_RESET_COUNTER_BLOCK;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<< std::endl<< "Resetting Counter";
if (startACQ==1)
std::cout<<" and Restarting Acquisition";
std::cout<<std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&startACQ,sizeof(startACQ));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::setCounterBit(int i) {
int fnum=F_SET_COUNTER_BIT;
int ret = FAIL;
int retval=-1;
char mess[MAX_STR_LENGTH]="";
if (thisDetector->onlineFlag==ONLINE_FLAG) {
FILE_LOG(logINFO) <<
((i == -1) ? "Getting" : ((i == 0) ? "Reseting" : "Setting")) <<
" counter bit from detector" << std::endl;
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&i,sizeof(i));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(COULD_NOT_SET_COUNTER_BIT));
}
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::setROI(int n,ROI roiLimits[]) {
int ret = FAIL;
//sort ascending order
int temp;
for(int i=0;i<n;++i) {
// std::cout << "*** ROI "<< i << " xmin " << roiLimits[i].xmin << " xmax "
//<< roiLimits[i].xmax << std::endl;
for(int j=i+1;j<n;++j) {
if (roiLimits[j].xmin<roiLimits[i].xmin) {
temp=roiLimits[i].xmin;roiLimits[i].xmin=roiLimits[j].xmin;
roiLimits[j].xmin=temp;
temp=roiLimits[i].xmax;roiLimits[i].xmax=roiLimits[j].xmax;
roiLimits[j].xmax=temp;
temp=roiLimits[i].ymin;roiLimits[i].ymin=roiLimits[j].ymin;
roiLimits[j].ymin=temp;
temp=roiLimits[i].ymax;roiLimits[i].ymax=roiLimits[j].ymax;
roiLimits[j].ymax=temp;
}
}
// std::cout << "UUU ROI "<< i << " xmin " << roiLimits[i].xmin << " xmax "
//<< roiLimits[i].xmax << std::endl;
}
ret = sendROI(n,roiLimits);
if (thisDetector->myDetectorType==JUNGFRAUCTB) getTotalNumberOfChannels();
return ret;
}
slsDetectorDefs::ROI* slsDetector::getROI(int &n) {
sendROI(-1,NULL);
n=thisDetector->nROI;
if (thisDetector->myDetectorType==JUNGFRAUCTB) getTotalNumberOfChannels();
return thisDetector->roiLimits;
}
int slsDetector::getNRoi() {
return thisDetector->nROI;
}
int slsDetector::sendROI(int n,ROI roiLimits[]) {
int ret=FAIL;
int fnum=F_SET_ROI;
char mess[MAX_STR_LENGTH]="";
int arg = n;
int retvalsize=0;
ROI retval[MAX_ROIS];
int nrec=-1;
if (roiLimits==NULL)
roiLimits=thisDetector->roiLimits;
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&arg,sizeof(arg));
if (arg==-1) {;
#ifdef VERBOSE
std::cout << "Getting ROI from detector" << std::endl;
#endif
} else {
#ifdef VERBOSE
std::cout << "Sending ROI of size " << arg << " to detector" << std::endl;
#endif
for(int i = 0; i < n; ++i) {
controlSocket->SendDataOnly(&roiLimits[i].xmin, sizeof(int));
controlSocket->SendDataOnly(&roiLimits[i].xmax, sizeof(int));
controlSocket->SendDataOnly(&roiLimits[i].ymin, sizeof(int));
controlSocket->SendDataOnly(&roiLimits[i].ymax, sizeof(int));
}
//controlSocket->SendDataOnly(roiLimits,arg*sizeof(ROI));
}
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
controlSocket->ReceiveDataOnly(&retvalsize,sizeof(retvalsize));
nrec = 0;
for(int i = 0; i < retvalsize; ++i) {
nrec += controlSocket->ReceiveDataOnly(&retval[i].xmin, sizeof(int));
nrec += controlSocket->ReceiveDataOnly(&retval[i].xmax, sizeof(int));
nrec += controlSocket->ReceiveDataOnly(&retval[i].ymin, sizeof(int));
nrec += controlSocket->ReceiveDataOnly(&retval[i].ymax, sizeof(int));
}
//nrec = controlSocket->ReceiveDataOnly(retval,retvalsize*sizeof(ROI));
if (nrec!=(retvalsize*(int)sizeof(ROI))) {
ret=FAIL;
std::cout << " wrong size received: received " << nrec <<
"but expected " << retvalsize*sizeof(ROI) << std::endl;
}
} else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
//update client
if (ret==FAIL) {
setErrorMask((getErrorMask())|(COULDNOT_SET_ROI));
} else {
for(int i=0;i<retvalsize;++i)
thisDetector->roiLimits[i]=retval[i];
thisDetector->nROI = retvalsize;
}
#ifdef VERBOSE
for(int j=0;j<thisDetector->nROI;++j)
std::cout<<"ROI [" <<j<<"] ("<< roiLimits[j].xmin<<"\t"<<roiLimits[j].xmax<<"\t"
<<roiLimits[j].ymin<<"\t"<<roiLimits[j].ymax<<")"<<std::endl;
#endif
// old firmware requires configuremac after setting roi
if (thisDetector->myDetectorType == GOTTHARD) {
ret = configureMAC();
}
// update roi in receiver
if (ret == OK && thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
int fnum = F_RECEIVER_SET_ROI;
ret = FAIL;
#ifdef VERBOSE
std::cout << "Sending ROI to receiver " << thisDetector->nROI << std::endl;
#endif
if (connectData() == OK) {
dataSocket->SendDataOnly(&fnum,sizeof(fnum));
dataSocket->SendDataOnly(&thisDetector->nROI, sizeof(thisDetector->nROI));
for(int i = 0; i < thisDetector->nROI; ++i) {
dataSocket->SendDataOnly(&thisDetector->roiLimits[i].xmin, sizeof(int));
dataSocket->SendDataOnly(&thisDetector->roiLimits[i].xmax, sizeof(int));
dataSocket->SendDataOnly(&thisDetector->roiLimits[i].ymin, sizeof(int));
dataSocket->SendDataOnly(&thisDetector->roiLimits[i].ymax, sizeof(int));
}
dataSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret == FAIL) {
dataSocket->ReceiveDataOnly(mess,MAX_STR_LENGTH);
setErrorMask((getErrorMask())|(COULDNOT_SET_ROI));
FILE_LOG(logERROR, ("Receiver %d returned error: %s", detId, mess));
}
disconnectData();
}
}
return ret;
}
int slsDetector::writeAdcRegister(int addr, int val) {
int retval=-1;
int fnum=F_WRITE_ADC_REG;
int ret=FAIL;
char mess[MAX_STR_LENGTH]="";
uint32_t arg[2];
arg[0]=addr;
arg[1]=val;
#ifdef VERBOSE
std::cout<< std::endl;
FILE_LOG(logINFO) << "Writing to adc register "<< std::hex<<addr << " data " << std::hex<<val << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(arg,sizeof(arg));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL)
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
#ifdef VERBOSE
FILE_LOG(logINFO) << "ADC Register returned "<< retval << std::endl;
#endif
if (ret==FAIL) {
FILE_LOG(logERROR) << "Write ADC to register failed " << std::endl;
setErrorMask((getErrorMask())|(REGISER_WRITE_READ));
}
return retval;
}
int slsDetector::activate(int const enable) {
int fnum = F_ACTIVATE;
int fnum2 = F_RECEIVER_ACTIVATE;
int retval = -1;
int arg = enable;
char mess[MAX_STR_LENGTH]="";
int ret = FAIL;
if (thisDetector->myDetectorType != EIGER) {
FILE_LOG(logERROR) << "Not implemented for this detector" << std::endl;
setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE));
return -1;
}
FILE_LOG(logDEBUG5) <<
(!enable ? "Deactivating" : (enable == -1 ? "Getting activate" : "Activating")) <<
" Detector" << std::endl;
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&arg,sizeof(arg));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE));
} else {
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
thisDetector->activated = retval;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
#ifdef VERBOSE
if (retval==1)
std::cout << "Detector Activated" << std::endl;
else if (retval==0)
std::cout << "Detector Deactivated" << std::endl;
else
std::cout << "Detector Activation unknown:" << retval << std::endl;
#endif
if (ret!=FAIL) {
int arg = thisDetector->activated;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
std::cout << "Activating/Deactivating Receiver: " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum2, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL)
setErrorMask((getErrorMask())|(RECEIVER_ACTIVATE));
}
}
#ifdef VERBOSE
if (retval==1)
std::cout << "Receiver Activated" << std::endl;
else if (retval==0)
std::cout << "Receiver Deactivated" << std::endl;
else
std::cout << "Receiver Activation unknown:" << retval << std::endl;
#endif
return thisDetector->activated;
}
int slsDetector::setDeactivatedRxrPaddingMode(int padding) {
int fnum = F_RECEIVER_DEACTIVATED_PADDING_ENABLE;
int retval = -1;
int arg = padding;
int ret = OK;
if (thisDetector->myDetectorType != EIGER) {
FILE_LOG(logERROR) << "Not implemented for this detector" << std::endl;
setErrorMask((getErrorMask())|(RECEIVER_ACTIVATE));
return -1;
}
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
std::cout << "Deactivated Receiver Padding Enable: " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL)
setErrorMask((getErrorMask())|(RECEIVER_ACTIVATE));
else
thisDetector->receiver_deactivatedPaddingEnable = retval;
}
return thisDetector->receiver_deactivatedPaddingEnable;
}
int slsDetector::getFlippedData(dimension d) {
return thisDetector->flippedData[d];
}
int slsDetector::setFlippedData(dimension d, int value) {
int retval=-1;
int fnum=F_SET_FLIPPED_DATA_RECEIVER;
int ret=FAIL;
int args[2]={X,-1};
if (thisDetector->myDetectorType!= EIGER) {
std::cout << "Flipped Data is not implemented in this detector" << std::endl;
setErrorMask((getErrorMask())|(RECEIVER_FLIPPED_DATA_NOT_SET));
return -1;
}
#ifdef VERBOSE
std::cout << std::endl;
std::cout << "Setting/Getting flipped data across axis " << d <<" with value "
<< value << std::endl;
#endif
if (value > -1) {
thisDetector->flippedData[d] = value;
args[1] = value;
} else
args[1] = thisDetector->flippedData[d];
args[0] = d;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, args, sizeof(args), &retval, sizeof(retval));
disconnectData();
}
if ((args[1] != retval && args[1]>=0) || (ret==FAIL)) {
ret = FAIL;
setErrorMask((getErrorMask())|(RECEIVER_FLIPPED_DATA_NOT_SET));
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
return thisDetector->flippedData[d];
}
int slsDetector::setAllTrimbits(int val) {
int fnum=F_SET_ALL_TRIMBITS;
int retval = -1;
int ret=OK;
#ifdef VERBOSE
FILE_LOG(logINFO) << "Setting all trimbits to "<< val << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&val,sizeof(val));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
char mess[MAX_STR_LENGTH]="";
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(ALLTIMBITS_NOT_SET));
} else {
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
#ifdef VERBOSE
FILE_LOG(logINFO) << "All trimbits were set to "<< retval << std::endl;
#endif
return retval;
}
int slsDetector::enableGapPixels(int val) {
if (val > 0 && thisDetector->myDetectorType!= EIGER)
val = -1;
if (val >= 0) {
val=(val>0)?1:0;
// send to receiver
int ret=OK;
int retval=-1;
int fnum=F_ENABLE_GAPPIXELS_IN_RECEIVER;
int arg=val;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if ((arg != retval) || (ret==FAIL)) {
ret = FAIL;
setErrorMask((getErrorMask())|(RECEIVER_ENABLE_GAPPIXELS_NOT_SET));
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
// update client
if (ret == OK) {
thisDetector->gappixels = val;
thisDetector->dataBytesInclGapPixels = 0;
if (thisDetector->dynamicRange != 4) {
thisDetector->dataBytesInclGapPixels =
(thisDetector->nChip[X] *
thisDetector->nChan[X] + thisDetector->gappixels *
thisDetector->nGappixels[X]) *
(thisDetector->nChip[Y] *
thisDetector->nChan[Y] + thisDetector->gappixels *
thisDetector->nGappixels[Y]) *
thisDetector->dynamicRange/8;
// set data bytes for other detector ( for future use)
if (thisDetector->myDetectorType==JUNGFRAUCTB)
getTotalNumberOfChannels();
}
}
}
return thisDetector->gappixels;
}
int slsDetector::setTrimEn(int nen, int *en) {
if (en) {
for (int ien=0; ien<nen; ien++)
thisDetector->trimEnergies[ien]=en[ien];
thisDetector->nTrimEn=nen;
}
return (thisDetector->nTrimEn);
}
int slsDetector::getTrimEn(int *en) {
if (en) {
for (int ien=0; ien<thisDetector->nTrimEn; ien++)
en[ien]=thisDetector->trimEnergies[ien];
}
return (thisDetector->nTrimEn);
}
int slsDetector::pulsePixel(int n,int x,int y) {
int ret=FAIL;
int fnum=F_PULSE_PIXEL;
char mess[MAX_STR_LENGTH]="";
int arg[3];
arg[0] = n; arg[1] = x; arg[2] = y;
#ifdef VERBOSE
std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times at (" <<
x << "," << "y)" << std::endl << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(arg,sizeof(arg));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(COULD_NOT_PULSE));
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::pulsePixelNMove(int n,int x,int y) {
int ret=FAIL;
int fnum=F_PULSE_PIXEL_AND_MOVE;
char mess[MAX_STR_LENGTH]="";
int arg[3];
arg[0] = n; arg[1] = x; arg[2] = y;
#ifdef VERBOSE
std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times and move "
"by deltax:" << x << " deltay:" << y << std::endl << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(arg,sizeof(arg));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(COULD_NOT_PULSE));
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::pulseChip(int n) {
int ret=FAIL;
int fnum=F_PULSE_CHIP;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times" << std::endl << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&n,sizeof(n));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(COULD_NOT_PULSE));
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::setThresholdTemperature(int val) {
int retval = -1;
int fnum = F_THRESHOLD_TEMP;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = "";
int arg=val;
#ifdef VERBOSE
std::cout<< std::endl;
FILE_LOG(logINFO) << "Setting/Getting Threshold Temperature to "<< val << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectStop() == OK) {
stopSocket->SendDataOnly(&fnum,sizeof(fnum));
stopSocket->SendDataOnly(&arg,sizeof(arg));
stopSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
stopSocket->ReceiveDataOnly(&retval,sizeof(retval));
#ifdef VERBOSE
FILE_LOG(logINFO) << "Threshold Temperature returned "<< retval << std::endl;
#endif
} else {
stopSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL));
}
disconnectStop();
}
}
return retval;
}
int slsDetector::setTemperatureControl(int val) {
int retval = -1;
int fnum = F_TEMP_CONTROL;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = "";
int arg=val;
#ifdef VERBOSE
std::cout<< std::endl;
FILE_LOG(logINFO) << "Setting/Getting Threshold Temperature to "<< val << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectStop() == OK) {
stopSocket->SendDataOnly(&fnum,sizeof(fnum));
stopSocket->SendDataOnly(&arg,sizeof(arg));
stopSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
stopSocket->ReceiveDataOnly(&retval,sizeof(retval));
#ifdef VERBOSE
FILE_LOG(logINFO) << "Threshold Temperature returned "<< retval << std::endl;
#endif
} else {
stopSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL));
}
disconnectStop();
}
}
return retval;
}
int slsDetector::setTemperatureEvent(int val) {
int retval = -1;
int fnum = F_TEMP_EVENT;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = "";
int arg=val;
#ifdef VERBOSE
std::cout<< std::endl;
FILE_LOG(logINFO) << "Setting/Getting Threshold Temperature to "<< val << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectStop() == OK) {
stopSocket->SendDataOnly(&fnum,sizeof(fnum));
stopSocket->SendDataOnly(&arg,sizeof(arg));
stopSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
stopSocket->ReceiveDataOnly(&retval,sizeof(retval));
#ifdef VERBOSE
FILE_LOG(logINFO) << "Threshold Temperature returned "<< retval << std::endl;
#endif
} else {
stopSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL));
}
disconnectStop();
}
}
return retval;
}
int slsDetector::setStoragecellStart(int pos) {
int ret=FAIL;
int fnum=F_STORAGE_CELL_START;
char mess[MAX_STR_LENGTH] = {0};
int retval=-1;
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending storage cell start index " << pos << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&pos,sizeof(pos));
//check opening error
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(STORAGE_CELL_START));
} else
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::programFPGA(std::string fname) {
int ret=FAIL;
int fnum=F_PROGRAM_FPGA;
char mess[MAX_STR_LENGTH]="";
size_t filesize=0;
char* fpgasrc = NULL;
if (thisDetector->myDetectorType != JUNGFRAU &&
thisDetector->myDetectorType != JUNGFRAUCTB) {
std::cout << "Not implemented for this detector" << std::endl;
return FAIL;
}
//check if it exists
struct stat st;
if (stat(fname.c_str(),&st)) {
std::cout << "Programming file does not exist" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
// open src
FILE* src = fopen(fname.c_str(),"rb");
if (src == NULL) {
std::cout << "Could not open source file for programming: " << fname << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
// create temp destination file
char destfname[] = "/tmp/Jungfrau_MCB.XXXXXX";
int dst = mkstemp(destfname); // create temporary file and open it in r/w
if (dst == -1) {
std::cout << "Could not create destination file in /tmp for programming: "
<< destfname << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
// convert src to dst rawbin
#ifdef VERBOSE
std::cout << "Converting " << fname << " to " << destfname << std::endl;
#endif
int filepos,x,y,i;
// Remove header (0...11C)
for (filepos=0; filepos < 0x11C; ++filepos)
fgetc(src);
// Write 0x80 times 0xFF (0...7F)
{
char c = 0xFF;
for (filepos=0; filepos < 0x80; ++filepos)
write(dst, &c, 1);
}
// Swap bits and write to file
for (filepos=0x80; filepos < 0x1000000; ++filepos) {
x = fgetc(src);
if (x < 0) break;
y=0;
for (i=0; i < 8; ++i)
y=y| ( (( x & (1<<i) ) >> i) << (7-i) ); // This swaps the bits
write(dst, &y, 1);
}
if (filepos < 0x1000000) {
std::cout << "Could not convert programming file. EOF before end of flash"
<< std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
if (fclose(src)) {
std::cout << "Could not close source file" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
if (close(dst)) {
std::cout << "Could not close destination file" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
#ifdef VERBOSE
std::cout << "File has been converted to " << destfname << std::endl;
#endif
//loading dst file to memory
FILE* fp = fopen(destfname,"r");
if (fp == NULL) {
std::cout << "Could not open rawbin file" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
if (fseek(fp,0,SEEK_END)) {
std::cout << "Seek error in rawbin file" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
filesize = ftell(fp);
if (filesize <= 0) {
std::cout << "Could not get length of rawbin file" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
rewind(fp);
fpgasrc = (char*)malloc(filesize+1);
if (fpgasrc == NULL) {
std::cout << "Could not allocate size of program" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
return FAIL;
}
if (fread(fpgasrc, sizeof(char), filesize, fp) != filesize) {
std::cout << "Could not read rawbin file" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
if (fpgasrc != NULL)
free(fpgasrc);
return FAIL;
}
if (fclose(fp)) {
std::cout << "Could not close destination file after converting" << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
if (fpgasrc != NULL)
free(fpgasrc);
return FAIL;
}
unlink(destfname); // delete temporary file
#ifdef VERBOSE
std::cout << "Successfully loaded the rawbin file to program memory" << std::endl;
#endif
// send program from memory to detector
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending programming binary to detector " << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&filesize,sizeof(filesize));
//check opening error
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
filesize = 0;
}
//erasing flash
if (ret!=FAIL) {
FILE_LOG(logINFO) << "This can take awhile. Please be patient..." << std::endl;
printf("Erasing Flash:%d%%\r",0);
std::cout << std::flush;
//erasing takes 65 seconds, printing here (otherwise need threads
//in server-unnecessary)
int count = 66;
while(count>0) {
usleep(1 * 1000 * 1000);
--count;
printf("Erasing Flash:%d%%\r",(int) (((double)(65-count)/65)*100));
std::cout << std::flush;
}
std::cout<<std::endl;
printf("Writing to Flash:%d%%\r",0);
std::cout << std::flush;
}
//sending program in parts of 2mb each
size_t unitprogramsize = 0;
int currentPointer = 0;
size_t totalsize= filesize;
while(ret != FAIL && (filesize > 0)) {
unitprogramsize = MAX_FPGAPROGRAMSIZE; //2mb
if (unitprogramsize > filesize) //less than 2mb
unitprogramsize = filesize;
#ifdef VERBOSE
std::cout << "unitprogramsize:" << unitprogramsize << "\t filesize:"
<< filesize << std::endl;
#endif
controlSocket->SendDataOnly(fpgasrc+currentPointer,unitprogramsize);
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
filesize-=unitprogramsize;
currentPointer+=unitprogramsize;
//print progress
printf("Writing to Flash:%d%%\r",
(int) (((double)(totalsize-filesize)/totalsize)*100));
std::cout << std::flush;
} else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
}
}
std::cout<<std::endl;
//check ending error
if ((ret == FAIL) &&
(strstr(mess,"not implemented") == NULL) &&
(strstr(mess,"locked") == NULL) &&
(strstr(mess,"-update") == NULL)) {
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
}
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
//remapping stop server
if ((ret == FAIL) &&
(strstr(mess,"not implemented") == NULL) &&
(strstr(mess,"locked") == NULL) &&
(strstr(mess,"-update") == NULL)) {
fnum=F_RESET_FPGA;
int stopret;
if (connectStop() == OK) {
stopSocket->SendDataOnly(&fnum,sizeof(fnum));
stopSocket->ReceiveDataOnly(&stopret,sizeof(stopret));
if (stopret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
}
disconnectControl();
}
}
}
if (ret != FAIL) {
printf("You can now restart the detector servers in normal mode.\n");
}
//free resources
if (fpgasrc != NULL)
free(fpgasrc);
return ret;
}
int slsDetector::resetFPGA() {
int ret=FAIL;
int fnum=F_RESET_FPGA;
char mess[MAX_STR_LENGTH]="";
if (thisDetector->myDetectorType != JUNGFRAU) {
std::cout << "Not implemented for this detector" << std::endl;
return FAIL;
}
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending reset to FPGA " << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
// control server
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(RESET_ERROR));
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::powerChip(int ival) {
int ret=FAIL;
int fnum=F_POWER_CHIP;
char mess[MAX_STR_LENGTH]="";
int retval=-1;
if (thisDetector->myDetectorType != JUNGFRAU &&
thisDetector->myDetectorType != JUNGFRAUCTB ) {
std::cout << "Not implemented for this detector" << std::endl;
return FAIL;
}
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending power on/off/get to the chip " << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&ival,sizeof(ival));
//check opening error
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(POWER_CHIP));
} else
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::setAutoComparatorDisableMode(int ival) {
int ret=FAIL;
int fnum=F_AUTO_COMP_DISABLE;
char mess[MAX_STR_LENGTH]="";
int retval=-1;
if (thisDetector->myDetectorType != JUNGFRAU) {
std::cout << "Not implemented for this detector" << std::endl;
return FAIL;
}
#ifdef VERBOSE
FILE_LOG(logINFO) << "Enabling/disabling Auto comp disable mode " << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&ival,sizeof(ival));
//check opening error
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(AUTO_COMP_DISABLE));
} else
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::getChanRegs(double* retval,bool fromDetector) {
int n=getTotalNumberOfChannels();
if (fromDetector) {
getModule();
}
//the original array has 0 initialized
if (chanregs) {
for (int i=0; i<n; ++i)
retval[i] = (double) (chanregs[i] & TRIMBITMASK);
}
return n;
}
int slsDetector::setModule(sls_detector_module module, int iodelay, int tau,
int e_eV, int* gainval, int* offsetval, int tb) {
int fnum=F_SET_MODULE;
int retval=-1;
int ret=FAIL;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout << "slsDetector set module " << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
//to exclude trimbits
if (!tb) {
module.nchan=0;
module.nchip=0;
}
sendModule(&module);
//not included in module
if (gainval && (thisDetector->nGain))
controlSocket->SendDataOnly(gainval,sizeof(int)*thisDetector->nGain);
if (offsetval && (thisDetector->nOffset))
controlSocket->SendDataOnly(offsetval,sizeof(int)*thisDetector->nOffset);
if (thisDetector->myDetectorType == EIGER) {
controlSocket->SendDataOnly(&iodelay,sizeof(iodelay));
controlSocket->SendDataOnly(&tau,sizeof(tau));
controlSocket->SendDataOnly(&e_eV,sizeof(e_eV));
}
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL)
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
if (strstr(mess,"default tau")!=NULL)
setErrorMask((getErrorMask())|(RATE_CORRECTION_NO_TAU_PROVIDED));
}
disconnectControl();
if (ret==FORCE_UPDATE)
ret = updateDetector();
}
}
if (ret!=FAIL) {
if (detectorModules) {
if (tb) {
(detectorModules)->nchan=module.nchan;
(detectorModules)->nchip=module.nchip;
}
(detectorModules)->ndac=module.ndac;
(detectorModules)->nadc=module.nadc;
if (tb) {
thisDetector->nChips=module.nchip;
thisDetector->nChans=module.nchan/module.nchip;
}
thisDetector->nDacs=module.ndac;
thisDetector->nAdcs=module.nadc;
if (thisDetector->myDetectorType != JUNGFRAU) {
if (tb) {
for (int ichip=0; ichip<thisDetector->nChips; ++ichip) {
if (chipregs)
chipregs[ichip]=
module.chipregs[ichip];
if (chanregs) {
for (int i=0; i<thisDetector->nChans; ++i) {
chanregs[i+ichip*
thisDetector->nChans]=
module.chanregs[ichip*thisDetector->nChans+i];
}
}
}
}
if (adcs) {
for (int i=0; i<thisDetector->nAdcs; ++i)
adcs[i]=module.adcs[i];
}
}
if (dacs) {
for (int i=0; i<thisDetector->nDacs; ++i)
dacs[i]=module.dacs[i];
}
(detectorModules)->gain=module.gain;
(detectorModules)->offset=module.offset;
(detectorModules)->serialnumber=module.serialnumber;
(detectorModules)->reg=module.reg;
}
if ((thisDetector->nGain) && (gainval) && (gain)) {
for (int i=0; i<thisDetector->nGain; ++i)
gain[i]=gainval[i];
}
if ((thisDetector->nOffset) && (offsetval) && (offset)) {
for (int i=0; i<thisDetector->nOffset; ++i)
offset[i]=offsetval[i];
}
if (e_eV != -1)
thisDetector->currentThresholdEV = e_eV;
}
#ifdef VERBOSE
FILE_LOG(logINFO) << "Module register returned "<< retval << std::endl;
#endif
return ret;
}
slsDetectorDefs::sls_detector_module *slsDetector::getModule() {
#ifdef VERBOSE
std::cout << "slsDetector get module " << std::endl;
#endif
int fnum=F_GET_MODULE;
sls_detector_module *myMod=createModule();
int* gainval=0, *offsetval=0;
if (thisDetector->nGain)
gainval=new int[thisDetector->nGain];
if (thisDetector->nOffset)
offsetval=new int[thisDetector->nOffset];
int ret=FAIL;
char mess[MAX_STR_LENGTH]="";
// int n;
#ifdef VERBOSE
FILE_LOG(logINFO) << "getting module " << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
receiveModule(myMod);
//extra gain and offset - eiger
if (thisDetector->nGain)
controlSocket->ReceiveDataOnly(gainval,sizeof(int)*thisDetector->nGain);
if (thisDetector->nOffset)
controlSocket->ReceiveDataOnly(offsetval,sizeof(int)*thisDetector->nOffset);
} else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
if (ret!=FAIL) {
if (detectorModules) {
(detectorModules)->nchan=myMod->nchan;
(detectorModules)->nchip=myMod->nchip;
(detectorModules)->ndac=myMod->ndac;
(detectorModules)->nadc=myMod->nadc;
thisDetector->nChips=myMod->nchip;
thisDetector->nChans=myMod->nchan/myMod->nchip;
thisDetector->nDacs=myMod->ndac;
thisDetector->nAdcs=myMod->nadc;
if (thisDetector->myDetectorType != JUNGFRAU) {
for (int ichip=0; ichip<thisDetector->nChips; ++ichip) {
if (chipregs)
chipregs[ichip]=
myMod->chipregs[ichip];
if (chanregs) {
for (int i=0; i<thisDetector->nChans; ++i) {
chanregs[i+ichip*thisDetector->nChans]=
myMod->chanregs[ichip*thisDetector->nChans+i];
}
}
}
if (adcs) {
for (int i=0; i<thisDetector->nAdcs; ++i)
adcs[i]=myMod->adcs[i];
}
}
if (dacs) {
for (int i=0; i<thisDetector->nDacs; ++i) {
dacs[i]=myMod->dacs[i];
}
}
(detectorModules)->gain=myMod->gain;
(detectorModules)->offset=myMod->offset;
(detectorModules)->serialnumber=myMod->serialnumber;
(detectorModules)->reg=myMod->reg;
}
if ((thisDetector->nGain) && (gainval) && (gain)) {
for (int i=0; i<thisDetector->nGain; ++i)
gain[i+thisDetector->nGain]=gainval[i];
}
if ((thisDetector->nOffset) && (offsetval) && (offset)) {
for (int i=0; i<thisDetector->nOffset; ++i)
offset[i+thisDetector->nOffset]=offsetval[i];
}
} else {
deleteModule(myMod);
myMod=NULL;
}
if (gainval) delete[]gainval;
if (offsetval) delete[]offsetval;
return myMod;
}
int slsDetector::calibratePedestal(int frames) {
int ret=FAIL;
int retval=-1;
int fnum=F_CALIBRATE_PEDESTAL;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<<"Calibrating Pedestal " <<std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&frames,sizeof(frames));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL)
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::setRateCorrection(int t) {
if (getDetectorsType() == EIGER) {
int fnum=F_SET_RATE_CORRECT;
int ret=FAIL;
char mess[MAX_STR_LENGTH]="";
int64_t arg = t;
#ifdef VERBOSE
FILE_LOG(logINFO) << "Setting Rate Correction to " << arg << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&arg,sizeof(arg));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
if (strstr(mess,"default tau")!=NULL)
setErrorMask((getErrorMask())|(RATE_CORRECTION_NO_TAU_PROVIDED));
if (strstr(mess,"32")!=NULL)
setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32or16BIT));
else
setErrorMask((getErrorMask())|(COULD_NOT_SET_RATE_CORRECTION));
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret; //only success/fail
}
printf("unknown detector\n");
return -1;
}
int slsDetector::getRateCorrection() {
int fnum=F_GET_RATE_CORRECT;
int ret=FAIL;
char mess[MAX_STR_LENGTH]="";
int64_t retval = -1;
#ifdef VERBOSE
FILE_LOG(logINFO) << "Setting Rate Correction to " << arg << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL)
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::printReceiverConfiguration() {
std::cout << std::endl
<< "#Detector " << detId << ":" << std::endl;
std::cout << "Detector IP:\t\t" << getNetworkParameter(DETECTOR_IP) << std::endl;
std::cout << "Detector MAC:\t\t" << getNetworkParameter(DETECTOR_MAC) << std::endl;
std::cout << "Receiver Hostname:\t" << getNetworkParameter(RECEIVER_HOSTNAME) << std::endl;
std::cout << "Receiver UDP IP:\t" << getNetworkParameter(RECEIVER_UDP_IP) << std::endl;
std::cout << "Receiver UDP MAC:\t" << getNetworkParameter(RECEIVER_UDP_MAC) << std::endl;
std::cout << "Receiver UDP Port:\t" << getNetworkParameter(RECEIVER_UDP_PORT) << std::endl;
if (thisDetector->myDetectorType == EIGER)
std::cout << "Receiver UDP Port2:\t" << getNetworkParameter(RECEIVER_UDP_PORT2)
<< std::endl;
std::cout << std::endl;
return OK;
}
int slsDetector::setReceiverOnline(int off) {
if (off!=GET_ONLINE_FLAG) {
// no receiver
if (!strcmp(thisDetector->receiver_hostname,"none"))
thisDetector->receiverOnlineFlag = OFFLINE_FLAG;
else
thisDetector->receiverOnlineFlag = off;
// check receiver online
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
setReceiverTCPSocket();
// error in connecting
if (thisDetector->receiverOnlineFlag==OFFLINE_FLAG) {
std::cout << "cannot connect to receiver" << std::endl;
setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER));
}
}
}
return thisDetector->receiverOnlineFlag;
}
std::string slsDetector::checkReceiverOnline() {
std::string retval = "";
//if it doesnt exits, create data socket
if (!dataSocket) {
//this already sets the online/offline flag
setReceiverTCPSocket();
if (thisDetector->receiverOnlineFlag==OFFLINE_FLAG)
return std::string(thisDetector->receiver_hostname);
else
return std::string("");
}
//still cannot connect to socket, dataSocket=0
if (dataSocket) {
if (connectData() == FAIL) {
dataSocket->SetTimeOut(5);
thisDetector->receiverOnlineFlag=OFFLINE_FLAG;
delete dataSocket;
dataSocket=0;
#ifdef VERBOSE
FILE_LOG(logINFO) << "receiver offline!" << std::endl;
#endif
return std::string(thisDetector->receiver_hostname);
} else {
thisDetector->receiverOnlineFlag=ONLINE_FLAG;
dataSocket->SetTimeOut(100);
disconnectData();
#ifdef VERBOSE
FILE_LOG(logINFO) << "receiver online!" << std::endl;
#endif
return std::string("");
}
}
return retval;
}
int slsDetector::setReceiverTCPSocket(std::string const name, int const receiver_port) {
char thisName[MAX_STR_LENGTH];
int thisRP;
int retval=OK;
//if receiver ip given
if (strcmp(name.c_str(),"")!=0) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "setting receiver" << std::endl;
#endif
strcpy(thisName,name.c_str());
strcpy(thisDetector->receiver_hostname,thisName);
if (dataSocket) {
delete dataSocket;
dataSocket=0;
}
} else
strcpy(thisName,thisDetector->receiver_hostname);
//if receiverTCPPort given
if (receiver_port>0) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "setting data port" << std::endl;
#endif
thisRP=receiver_port;
thisDetector->receiverTCPPort=thisRP;
if (dataSocket) {
delete dataSocket;
dataSocket=0;
}
} else
thisRP=thisDetector->receiverTCPPort;
//create data socket
if (!dataSocket) {
try {
dataSocket = new MySocketTCP(thisName, thisRP);
#ifdef VERYVERBOSE
FILE_LOG(logINFO) << "Data socket connected " <<
thisName << " " << thisRP << std::endl;
#endif
} catch(...) {
#ifdef VERBOSE
FILE_LOG(logERROR) << "Could not connect Data socket " <<
thisName << " " << thisRP << std::endl;
#endif
dataSocket = 0;
retval = FAIL;
}
}
//check if it connects
if (retval!=FAIL) {
checkReceiverOnline();
thisReceiver->SetSocket(dataSocket);
// check for version compatibility
switch (thisDetector->myDetectorType) {
case EIGER:
case JUNGFRAU:
case GOTTHARD:
if (thisDetector->receiverAPIVersion == 0) {
if (checkVersionCompatibility(DATA_PORT) == FAIL)
thisDetector->receiverOnlineFlag=OFFLINE_FLAG;
}
break;
default:
break;
}
} else {
thisDetector->receiverOnlineFlag=OFFLINE_FLAG;
#ifdef VERBOSE
FILE_LOG(logINFO) << "offline!" << std::endl;
#endif
}
return retval;
}
int slsDetector::lockReceiver(int lock) {
int fnum=F_LOCK_RECEIVER;
int ret = FAIL;
int retval=-1;
int arg=lock;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Locking or Unlocking Receiver " << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
return retval;
}
std::string slsDetector::getReceiverLastClientIP() {
int fnum=F_GET_LAST_RECEIVER_CLIENT_IP;
int ret = FAIL;
char retval[INET_ADDRSTRLEN]="";
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Geting Last Client IP connected to Receiver " << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, retval, INET_ADDRSTRLEN);
disconnectData();
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
return std::string(retval);
}
int slsDetector::exitReceiver() {
int fnum = F_EXIT_RECEIVER;
int ret = FAIL;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
if (connectData() == OK) {
ret = thisReceiver->Client_Send(fnum, NULL, 0, NULL, 0);
disconnectData();
}
}
if (ret == OK) {
std::cout << std::endl << "Shutting down the receiver" << std::endl << std::endl;
}
return ret;
}
int slsDetector::execReceiverCommand(std::string cmd) {
int fnum = F_EXEC_RECEIVER_COMMAND;
int ret = FAIL;
char arg[MAX_STR_LENGTH] = {0};
char retval[MAX_STR_LENGTH] = {0};
strcpy(arg,cmd.c_str());
FILE_LOG(logDEBUG5) << "Sending command to receiver " << arg;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, arg, sizeof(arg), retval, sizeof(retval));
disconnectData();
}
if (ret != FAIL) {
FILE_LOG(logINFO) << "Receiver " << detId << " returned:\n" << retval;
}
}
return ret;
}
int slsDetector::updateReceiverNoWait() {
int n = 0,ind;
char path[MAX_STR_LENGTH];
char lastClientIP[INET_ADDRSTRLEN];
n += dataSocket->ReceiveDataOnly(lastClientIP,sizeof(lastClientIP));
#ifdef VERBOSE
FILE_LOG(logINFO) << "Updating receiver last modified by " << lastClientIP << std::endl;
#endif
// filepath
n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH);
strcpy(thisDetector->receiver_filePath, path);
// filename
n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH);
strcpy(thisDetector->receiver_fileName, path);
// index
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_fileIndex = ind;
//file format
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_fileFormatType = (fileFormat)ind;
// frames per file
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_framesPerFile = ind;
// frame discard policy
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_frameDiscardMode = (frameDiscardPolicy)ind;
// frame padding
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_framePadding = ind;
// file write enable
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_fileWriteEnable = ind;
// file overwrite enable
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_overWriteEnable = ind;
// gap pixels
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->gappixels = ind;
// receiver read frequency
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_read_freq = ind;
// receiver streaming port
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_zmqport = ind;
// streaming source ip
n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH);
strcpy(thisDetector->receiver_zmqip, path);
// additional json header
n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH);
strcpy(thisDetector->receiver_additionalJsonHeader, path);
// receiver streaming enable
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_upstream = ind;
// activate
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->activated = ind;
// deactivated padding enable
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_deactivatedPaddingEnable = ind;
// silent mode
n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind));
thisDetector->receiver_silentMode = ind;
if (!n) printf("n: %d\n", n);
return OK;
}
int slsDetector::updateReceiver() {
int fnum=F_UPDATE_RECEIVER_CLIENT;
int ret=OK;
char mess[MAX_STR_LENGTH]="";
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
if (connectData() == OK) {
dataSocket->SendDataOnly(&fnum,sizeof(fnum));
dataSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret == FAIL) {
dataSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
else
updateReceiverNoWait();
//if ret is force update, do not update now as client is updating
//receiver currently
disconnectData();
}
}
return ret;
}
void slsDetector::sendMultiDetectorSize() {
int fnum=F_SEND_RECEIVER_MULTIDETSIZE;
int ret = FAIL;
int retval = -1;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending multi detector size to Receiver (" <<
thisDetector->multiSize[0] << ","
<< thisDetector->multiSize[1] << ")" << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, thisDetector->multiSize, sizeof(thisDetector->multiSize), &retval, sizeof(retval));
disconnectData();
}
if ((ret==FAIL)) {
FILE_LOG(logERROR) << "Could not set position Id" << std::endl;
setErrorMask((getErrorMask())|(RECEIVER_MULTI_DET_SIZE_NOT_SET));
}
}
}
void slsDetector::setDetectorId() {
int fnum=F_SEND_RECEIVER_DETPOSID;
int ret = FAIL;
int retval = -1;
int arg = detId;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending detector pos id to Receiver " << detId << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if ((ret==FAIL) || (retval != arg)) {
FILE_LOG(logERROR) << "Could not set position Id" << std::endl;
setErrorMask((getErrorMask())|(RECEIVER_DET_POSID_NOT_SET));
}
}
}
void slsDetector::setDetectorHostname() {
int fnum=F_SEND_RECEIVER_DETHOSTNAME;
int ret = FAIL;
char retval[MAX_STR_LENGTH]="";
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending detector hostname to Receiver " <<
thisDetector->hostname << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, thisDetector->hostname, MAX_STR_LENGTH, retval, MAX_STR_LENGTH);
disconnectData();
}
if ((ret==FAIL) || (strcmp(retval,thisDetector->hostname)))
setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTNAME_NOT_SET));
}
}
std::string slsDetector::getFilePath() {
return thisDetector->receiver_filePath;
}
std::string slsDetector::setFilePath(std::string s) {
if (s.empty())
return getFilePath();
int fnum = F_SET_RECEIVER_FILE_PATH;
int ret = FAIL;
char arg[MAX_STR_LENGTH]="";
char retval[MAX_STR_LENGTH] = "";
strcpy(arg,s.c_str());
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending file path to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, arg, sizeof(arg), retval, sizeof(retval));
disconnectData();
}
if (ret!=FAIL) {
strcpy(thisDetector->receiver_filePath,retval);
}
else {
if (!s.empty()) {
FILE_LOG(logERROR) << "file path does not exist" << std::endl;
setErrorMask((getErrorMask())|(FILE_PATH_DOES_NOT_EXIST));
} else
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
return getFilePath();
}
std::string slsDetector::getFileName() {
return thisDetector->receiver_fileName;
}
std::string slsDetector::setFileName(std::string s) {
if (s.empty())
return getFileName();
int fnum=F_SET_RECEIVER_FILE_NAME;
int ret = FAIL;
char arg[MAX_STR_LENGTH]="";
char retval[MAX_STR_LENGTH]="";
strcpy(arg,s.c_str());
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending file name to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, arg, sizeof(arg), retval, sizeof(retval));
disconnectData();
}
if (ret == FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else
strcpy(thisDetector->receiver_fileName,retval);
if (ret==FORCE_UPDATE)
updateReceiver();
}
return getFileName();
}
int slsDetector::setReceiverFramesPerFile(int f) {
if (f < 0)
return thisDetector->receiver_framesPerFile;
int fnum = F_SET_RECEIVER_FRAMES_PER_FILE;
int ret = FAIL;
int retval = -1;
int arg = f;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending frames per file to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret == FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else
thisDetector->receiver_framesPerFile = retval;
if (ret==FORCE_UPDATE)
updateReceiver();
}
return thisDetector->receiver_framesPerFile;
}
slsDetectorDefs::frameDiscardPolicy slsDetector::setReceiverFramesDiscardPolicy(frameDiscardPolicy f) {
int fnum = F_RECEIVER_DISCARD_POLICY;
int ret = FAIL;
int retval = -1;
int arg = f;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending frames discard policy to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else if (ret!=FAIL && retval > -1) {
thisDetector->receiver_frameDiscardMode = (frameDiscardPolicy)retval;
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
return thisDetector->receiver_frameDiscardMode;
}
int slsDetector::setReceiverPartialFramesPadding(int f) {
int fnum = F_RECEIVER_PADDING_ENABLE;
int ret = FAIL;
int retval = -1;
int arg = f;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending partial frames enable to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else if (ret!=FAIL && retval > -1) {
thisDetector->receiver_framePadding = (bool)retval;
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
return thisDetector->receiver_framePadding;
}
slsDetectorDefs::fileFormat slsDetector::setFileFormat(fileFormat f) {
if (f == GET_FILE_FORMAT)
return getFileFormat();
int fnum=F_SET_RECEIVER_FILE_FORMAT;
int ret = FAIL;
int arg = f;
int retval = -1;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending file format to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret == FAIL)
setErrorMask((getErrorMask())|(RECEIVER_FILE_FORMAT));
else
thisDetector->receiver_fileFormatType = (fileFormat)retval;
if (ret==FORCE_UPDATE)
updateReceiver();
}
return getFileFormat();
}
slsDetectorDefs::fileFormat slsDetector::getFileFormat() {
return thisDetector->receiver_fileFormatType;
}
int slsDetector::getFileIndex() {
return thisDetector->receiver_fileIndex;
}
int slsDetector::setFileIndex(int i) {
if (i < 0)
return getFileIndex();
int fnum=F_SET_RECEIVER_FILE_INDEX;
int ret = FAIL;
int retval=-1;
int arg = i;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending file index to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret == FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else
thisDetector->receiver_fileIndex = retval;
if (ret==FORCE_UPDATE)
updateReceiver();
}
return getFileIndex();
}
int slsDetector::incrementFileIndex() {
if (thisDetector->receiver_fileWriteEnable)
return setFileIndex(thisDetector->receiver_fileIndex+1);
return thisDetector->receiver_fileIndex;
}
int slsDetector::startReceiver() {
int fnum=F_START_RECEIVER;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = "";
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Starting Receiver " << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, NULL, 0, mess);
disconnectData();
}
if (ret==FORCE_UPDATE)
ret=updateReceiver();
else if (ret == FAIL) {
if (strstr(mess,"UDP")!=NULL)
setErrorMask((getErrorMask())|(COULDNOT_CREATE_UDP_SOCKET));
else if (strstr(mess,"file")!=NULL)
setErrorMask((getErrorMask())|(COULDNOT_CREATE_FILE));
else
setErrorMask((getErrorMask())|(COULDNOT_START_RECEIVER));
}
}
return ret;
}
int slsDetector::stopReceiver() {
int fnum=F_STOP_RECEIVER;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = "";
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Stopping Receiver " << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, NULL, 0, mess);
disconnectData();
}
if (ret==FORCE_UPDATE)
ret=updateReceiver();
else if (ret == FAIL)
setErrorMask((getErrorMask())|(COULDNOT_STOP_RECEIVER));
}
return ret;
}
slsDetectorDefs::runStatus slsDetector::getReceiverStatus() {
int fnum=F_GET_RECEIVER_STATUS;
int ret = FAIL;
int retval=-1;
runStatus s = ERROR;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Getting Receiver Status" << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectData();
}
if (retval!=-1)
s=(runStatus)retval;
if (ret==FORCE_UPDATE)
updateReceiver();
}
return s;
}
int slsDetector::getFramesCaughtByReceiver() {
int fnum=F_GET_RECEIVER_FRAMES_CAUGHT;
int ret = FAIL;
int retval=-1;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Getting Frames Caught by Receiver " << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectData();
}
if (ret==FORCE_UPDATE)
ret=updateReceiver();
}
return retval;
}
int slsDetector::getFramesCaughtByAnyReceiver() {
return getFramesCaughtByReceiver();
}
int slsDetector::getReceiverCurrentFrameIndex() {
int fnum=F_GET_RECEIVER_FRAME_INDEX;
int ret = FAIL;
int retval=-1;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Getting Current Frame Index of Receiver " << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, &retval, sizeof(retval));
disconnectData();
}
if (ret==FORCE_UPDATE)
ret=updateReceiver();
}
return retval;
}
int slsDetector::resetFramesCaught() {
int fnum=F_RESET_RECEIVER_FRAMES_CAUGHT;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = "";
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Reset Frames Caught by Receiver" << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, NULL, 0, mess);
disconnectData();
}
if (ret==FORCE_UPDATE)
ret=updateReceiver();
}
return ret;
}
int slsDetector::enableWriteToFile(int enable) {
if (enable < 0)
return thisDetector->receiver_fileWriteEnable;
int fnum=F_ENABLE_RECEIVER_FILE_WRITE;
int ret = FAIL;
int retval=-1;
int arg = enable;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending enable file write to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret == FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else
thisDetector->receiver_fileWriteEnable = retval;
if (ret==FORCE_UPDATE)
updateReceiver();
}
return thisDetector->receiver_fileWriteEnable;
}
int slsDetector::overwriteFile(int enable) {
if (enable < 0)
return thisDetector->receiver_overWriteEnable;
int fnum=F_ENABLE_RECEIVER_OVERWRITE;
int ret = FAIL;
int retval=-1;
int arg = enable;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending enable file write to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret == FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else
thisDetector->receiver_overWriteEnable = retval;
if (ret==FORCE_UPDATE)
updateReceiver();
}
return thisDetector->receiver_overWriteEnable;
}
int slsDetector::setReceiverStreamingFrequency(int freq) {
if (freq >= 0) {
thisDetector->receiver_read_freq = freq;
int fnum=F_RECEIVER_STREAMING_FREQUENCY;
int ret = FAIL;
int retval=-1;
int arg = freq;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending read frequency to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if ((ret == FAIL) || (retval != freq)) {
FILE_LOG(logERROR) << "could not set receiver read frequency to " << freq
<<" Returned:" << retval << std::endl;
setErrorMask((getErrorMask())|(RECEIVER_STREAMING_FREQUENCY));
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
}
return thisDetector->receiver_read_freq;
}
int slsDetector::setReceiverStreamingTimer(int time_in_ms) {
int fnum=F_RECEIVER_STREAMING_TIMER;
int ret = FAIL;
int arg = time_in_ms;
int retval = -1;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "Sending read timer to receiver " << arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret==FORCE_UPDATE)
updateReceiver();
}
if ((time_in_ms > 0) && (retval != time_in_ms)) {
FILE_LOG(logERROR) << "could not set receiver read timer to " << time_in_ms
<<" Returned:" << retval << std::endl;
setErrorMask((getErrorMask())|(RECEIVER_STREAMING_TIMER));
}
return retval;
}
int slsDetector::enableDataStreamingToClient(int enable) {
FILE_LOG(logERROR, ("Must be called from the multi Detector level\n"));
return 0;
}
int slsDetector::enableDataStreamingFromReceiver(int enable) {
if (enable >= 0) {
int fnum=F_STREAM_DATA_FROM_RECEIVER;
int ret = FAIL;
int retval=-1;
int arg = enable;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "***************Sending Data Streaming in Receiver "
<< arg << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &arg, sizeof(arg), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL) {
retval = -1;
FILE_LOG(logERROR) << "could not set data streaming in receiver to " <<
enable <<" Returned:" << retval << std::endl;
setErrorMask((getErrorMask())|(DATA_STREAMING));
} else {
thisDetector->receiver_upstream = retval;
if (ret==FORCE_UPDATE)
updateReceiver();
}
}
}
return thisDetector->receiver_upstream;
}
int slsDetector::enableTenGigabitEthernet(int i) {
int ret=FAIL;
int retval = -1;
int fnum=F_ENABLE_TEN_GIGA,fnum2 = F_ENABLE_RECEIVER_TEN_GIGA;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<< std::endl<< "Enabling / Disabling 10Gbe" << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&i,sizeof(i));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(DETECTOR_TEN_GIGA));
}
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
if (ret!=FAIL) {
//must also configuremac
if ((i != -1)&&(retval == i))
if (configureMAC() != FAIL) {
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
ret = FAIL;
retval=-1;
#ifdef VERBOSE
FILE_LOG(logINFO) << "Enabling / Disabling 10Gbe in receiver: "
<< i << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum2, &i, sizeof(i), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL)
setErrorMask((getErrorMask())|(RECEIVER_TEN_GIGA));
}
}
}
if (ret != FAIL)
thisDetector->tenGigaEnable=retval;
return retval;
}
int slsDetector::setReceiverFifoDepth(int i) {
int fnum=F_SET_RECEIVER_FIFO_DEPTH;
int ret = FAIL;
int retval=-1;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
if (i ==-1)
FILE_LOG(logINFO) << "Getting Receiver Fifo Depth" << std::endl;
else
FILE_LOG(logINFO) << "Setting Receiver Fifo Depth to " << i << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &i, sizeof(i), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL)
setErrorMask((getErrorMask())|(COULD_NOT_SET_FIFO_DEPTH));
}
return retval;
}
int slsDetector::setReceiverSilentMode(int i) {
int fnum=F_SET_RECEIVER_SILENT_MODE;
int ret = FAIL;
int retval=-1;
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
if (i ==-1)
FILE_LOG(logINFO) << "Getting Receiver Silent Mode" << std::endl;
else
FILE_LOG(logINFO) << "Setting Receiver Silent Mode to " << i << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, &i, sizeof(i), &retval, sizeof(retval));
disconnectData();
}
if (ret==FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
else
thisDetector->receiver_silentMode = retval;
}
return thisDetector->receiver_silentMode;
}
int slsDetector::restreamStopFromReceiver() {
int fnum=F_RESTREAM_STOP_FROM_RECEIVER;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = "";
if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) {
#ifdef VERBOSE
FILE_LOG(logINFO) << "To Restream stop dummy from Receiver via zmq" << std::endl;
#endif
if (connectData() == OK) {
ret=thisReceiver->Client_Send(fnum, NULL, 0, NULL, 0, mess);
disconnectData();
}
if (ret==FORCE_UPDATE)
ret=updateReceiver();
else if (ret == FAIL) {
setErrorMask((getErrorMask())|(RESTREAM_STOP_FROM_RECEIVER));
FILE_LOG(logERROR) << " Could not restream stop dummy packet from receiver" << std::endl;
}
}
return ret;
}
int slsDetector::setCTBPattern(std::string fname) {
uint64_t word;
int addr=0;
FILE *fd=fopen(fname.c_str(),"r");
if (fd>0) {
while (fread(&word, sizeof(word), 1,fd)) {
setCTBWord(addr,word);
// std::cout << std::hex << addr << " " << word << std::dec << std::endl;
++addr;
}
fclose(fd);
} else
return -1;
return addr;
}
uint64_t slsDetector::setCTBWord(int addr,uint64_t word) {
//uint64_t ret;
int ret=FAIL;
uint64_t retval=-1;
int fnum=F_SET_CTB_PATTERN;
int mode=0; //sets word
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<<"Setting CTB word" <<std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&mode,sizeof(mode));
controlSocket->SendDataOnly(&addr,sizeof(addr));
controlSocket->SendDataOnly(&word,sizeof(word));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL)
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::setCTBPatLoops(int level,int &start, int &stop, int &n) {
int retval[3], args[4];
args[0]=level;
args[1]=start;
args[2]=stop;
args[3]=n;
int ret=FAIL;
int fnum=F_SET_CTB_PATTERN;
int mode=1; //sets loop
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<<"Setting CTB word" <<std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&mode,sizeof(mode));
controlSocket->SendDataOnly(&args,sizeof(args));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
start=retval[0];
stop=retval[1];
n=retval[2];
} else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::setCTBPatWaitAddr(int level, int addr) {
int retval=-1;
int ret=FAIL;
int fnum=F_SET_CTB_PATTERN;
int mode=2; //sets loop
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<<"Setting CTB word" <<std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&mode,sizeof(mode));
controlSocket->SendDataOnly(&level,sizeof(level));
controlSocket->SendDataOnly(&addr,sizeof(addr));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
} else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
int slsDetector::setCTBPatWaitTime(int level, uint64_t t) {
uint64_t retval=-1;
int ret=FAIL;
// uint64_t retval=-1;
int fnum=F_SET_CTB_PATTERN;
int mode=3; //sets loop
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<<"Setting CTB word" <<std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK) {
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&mode,sizeof(mode));
controlSocket->SendDataOnly(&level,sizeof(level));
controlSocket->SendDataOnly(&t,sizeof(t));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret!=FAIL) {
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
} else {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
FILE_LOG(logERROR) << "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}
slsDetectorDefs::sls_detector_module* slsDetector::interpolateTrim(
sls_detector_module* a, sls_detector_module* b,
const int energy, const int e1, const int e2, int tb) {
// only implemented for eiger currently (in terms of which dacs)
if (thisDetector->myDetectorType != EIGER) {
printf("Interpolation of Trim values not implemented for this detector!\n");
return NULL;
}
sls_detector_module* myMod = createModule(thisDetector->myDetectorType);
enum eiger_DacIndex{SVP,VTR,VRF,VRS,SVN,VTGSTV,VCMP_LL,VCMP_LR,CAL,
VCMP_RL,RXB_RB,RXB_LB,VCMP_RR,VCP,VCN,VIS};
//Copy other dacs
int dacs_to_copy[] = {SVP,VTR,SVN,VTGSTV,RXB_RB,RXB_LB,VCN,VIS};
int num_dacs_to_copy = sizeof(dacs_to_copy) / sizeof(dacs_to_copy[0]);
for (int i = 0; i < num_dacs_to_copy; ++i) {
if (a->dacs[dacs_to_copy[i]] != b->dacs[dacs_to_copy[i]]) {
deleteModule(myMod);
return NULL;
}
myMod->dacs[dacs_to_copy[i]] = a->dacs[dacs_to_copy[i]];
}
//Copy irrelevant dacs (without failing): CAL
if (a->dacs[CAL] != b->dacs[CAL]) {
printf("Warning: DAC CAL differs in both energies (%d, %d)! ",
a->dacs[CAL], b->dacs[CAL]);
printf("Taking first: %d\n", a->dacs[CAL]);
}
myMod->dacs[CAL] = a->dacs[CAL];
//Interpolate vrf, vcmp, vcp
int dacs_to_interpolate[] = {VRF,VCMP_LL,VCMP_LR,VCMP_RL,VCMP_RR,VCP, VRS};
int num_dacs_to_interpolate = sizeof(dacs_to_interpolate) / sizeof(dacs_to_interpolate[0]);
for (int i = 0; i < num_dacs_to_interpolate; ++i) {
myMod->dacs[dacs_to_interpolate[i]] = linearInterpolation(energy, e1, e2,
a->dacs[dacs_to_interpolate[i]], b->dacs[dacs_to_interpolate[i]]);
}
//Interpolate all trimbits
if (tb) {
for (int i = 0; i<myMod->nchan; i++)
myMod->chanregs[i] = linearInterpolation(energy, e1, e2, a->chanregs[i], b->chanregs[i]);
}
return myMod;
}
slsDetectorDefs::sls_detector_module* slsDetector::readSettingsFile(std::string fname,
int& iodelay, int& tau, sls_detector_module* myMod, int tb) {
int nflag=0;
if (myMod==NULL) {
myMod=createModule(thisDetector->myDetectorType);
nflag=1;
}
int id=0,i;
std::string names[100];
std::string myfname;
std::string str;
std::ifstream infile;
std::ostringstream oss;
int iline=0;
std::string sargname;
int ival;
int idac=0;
//ascii settings/trim file
switch (thisDetector->myDetectorType) {
case GOTTHARD:
names[id++]="Vref";
names[id++]="VcascN";
names[id++]="VcascP";
names[id++]="Vout";
names[id++]="Vcasc";
names[id++]="Vin";
names[id++]="Vref_comp";
names[id++]="Vib_test";
break;
case EIGER:
break;
case JUNGFRAU:
names[id++]="VDAC0";
names[id++]="VDAC1";
names[id++]="VDAC2";
names[id++]="VDAC3";
names[id++]="VDAC4";
names[id++]="VDAC5";
names[id++]="VDAC6";
names[id++]="VDAC7";
names[id++]="VDAC8";
names[id++]="VDAC9";
names[id++]="VDAC10";
names[id++]="VDAC11";
names[id++]="VDAC12";
names[id++]="VDAC13";
names[id++]="VDAC14";
names[id++]="VDAC15";
break;
default:
FILE_LOG(logERROR) << "Unknown detector type - unknown format for settings file" << std::endl;
return NULL;
}
#ifdef VERBOSE
std::cout<< "reading settings file" << std::endl;
#endif
myfname=fname;
#ifdef VERBOSE
FILE_LOG(logINFO) << "file name is "<< myfname << std::endl;
#endif
switch (thisDetector->myDetectorType) {
case EIGER:
infile.open(myfname.c_str(),std::ifstream::binary);
if (infile.is_open()) {
infile.read((char*) myMod->dacs,sizeof(int)*(myMod->ndac));
infile.read((char*)&iodelay,sizeof(iodelay));
infile.read((char*)&tau,sizeof(tau));
#ifdef VERBOSE
for(int i=0;i<myMod->ndac;i++)
FILE_LOG(logINFO) << "dac " << i << ":" << myMod->dacs[i] << std::endl;
FILE_LOG(logINFO) << "iodelay:" << iodelay << std::endl;
FILE_LOG(logINFO) << "tau:" << tau << std::endl;
#endif
if (tb) {
infile.read((char*) myMod->chanregs,sizeof(int)*(myMod->nchan));
if (infile.eof()) {
std::cout<<std::endl<<"Error, could not load trimbits end of file, "
<<myfname<<", reached."<<std::endl<<std::endl;
if (nflag)
deleteModule(myMod);
return NULL;
}
}
infile.close();
strcpy(thisDetector->settingsFile,fname.c_str());
printf("Settings file loaded: %s\n",thisDetector->settingsFile);
return myMod;
}
break;
case GOTTHARD:
case JUNGFRAU:
//---------------dacs---------------
infile.open(myfname.c_str(), std::ios_base::in);
if (infile.is_open()) {
while(infile.good()) {
getline(infile,str);
iline++;
#ifdef VERBOSE
std::cout<< str << std::endl;
#endif
std::istringstream ssstr(str);
ssstr >> sargname >> ival;
for (i=0;i<id;i++) {
if (!strcasecmp(sargname.c_str(),names[i].c_str())) {
myMod->dacs[i]=ival;
idac++;
#ifdef VERBOSE
std::cout<< sargname << " dac nr. " << idac << " is " << ival << std::endl;
#endif
break;
}
}
}
if (i < id) {
#ifdef VERBOSE
std::cout<< sargname << " dac nr. " << idac << " is " << ival << std::endl;
#endif
} else
FILE_LOG(logERROR) << "Unknown dac " << sargname << std::endl;
infile.close();
strcpy(thisDetector->settingsFile,fname.c_str());
printf("Settings file loaded: %s\n",thisDetector->settingsFile);
return myMod;
}
//----------------------------------
break;
default:
FILE_LOG(logERROR) << "Unknown detector type - don't know how to read file" << myfname << std::endl;
infile.close();
deleteModule(myMod);
return NULL;
}
printf("Error: Could not open settings file %s\n", myfname.c_str());
if (nflag)
deleteModule(myMod);
return NULL;
}
int slsDetector::writeSettingsFile(std::string fname, sls_detector_module mod,
int iodelay, int tau) {
std::ofstream outfile;
std::string names[100];
int id=0;
switch (thisDetector->myDetectorType) {
case GOTTHARD:
names[id++]="Vref";
names[id++]="VcascN";
names[id++]="VcascP";
names[id++]="Vout";
names[id++]="Vcasc";
names[id++]="Vin";
names[id++]="Vref_comp";
names[id++]="Vib_test";
break;
case EIGER:
break;
case JUNGFRAU:
names[id++]="VDAC0";
names[id++]="VDAC1";
names[id++]="VDAC2";
names[id++]="VDAC3";
names[id++]="VDAC4";
names[id++]="VDAC5";
names[id++]="VDAC6";
names[id++]="VDAC7";
names[id++]="VDAC8";
names[id++]="VDAC9";
names[id++]="VDAC10";
names[id++]="VDAC11";
names[id++]="VDAC12";
names[id++]="VDAC13";
names[id++]="VDAC14";
names[id++]="VDAC15";
break;
default:
FILE_LOG(logERROR) << "Unknown detector type - unknown format for settings file" << std::endl;
return FAIL;
}
int iv;
int idac;
switch (thisDetector->myDetectorType) {
case EIGER:
outfile.open(fname.c_str(), std::ofstream::binary);
if (outfile.is_open()) {
iv = 1150;
#ifdef VERBOSE
for(int i=0;i<mod.ndac;i++)
FILE_LOG(logINFO) << "dac " << i << ":" << mod.dacs[i] << std::endl;
FILE_LOG(logINFO) << "iodelay: " << iodelay << std::endl;
FILE_LOG(logINFO) << "tau: " << tau << std::endl;
#endif
outfile.write((char*)mod.dacs, sizeof(int)*(mod.ndac));
outfile.write(reinterpret_cast<char*>(&iodelay), sizeof(iodelay));
outfile.write(reinterpret_cast<char*>(&tau), sizeof(tau));
outfile.write((char*)mod.chanregs, sizeof(int)*(mod.nchan));
outfile.close();
return slsDetectorDefs::OK;
}
printf("Could not open Settings file %s\n", fname.c_str());
return slsDetectorDefs::FAIL;
default:
outfile.open(fname.c_str(), std::ios_base::out);
if (outfile.is_open()) {
for (idac=0; idac<mod.ndac; idac++) {
iv=(int)mod.dacs[idac];
outfile << names[idac] << " " << iv << std::endl;
}
outfile.close();
return OK;
}
FILE_LOG(logERROR) << "could not open SETTINGS file " << fname << std::endl;
return FAIL;
}
}