diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 67f3312ce..efc980320 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -666,6 +666,7 @@ void multiSlsDetector::freeSharedMemory() // multi detector if (sharedMemory) { + sharedMemory->Unmap(thisMultiDetector); sharedMemory->RemoveSharedMemory(); delete sharedMemory; } @@ -718,11 +719,13 @@ bool multiSlsDetector::initSharedMemory(bool verify) bool created = false; sharedMemory = new SharedMemory(detId, -1); if (SharedMemory::IsExisting(sharedMemory->GetName())) { - thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->OpenSharedMemory(sz, verify); + thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->OpenSharedMemory(sz); if (verify && thisMultiDetector->shmversion != MULTI_SHMVERSION) { - cprintf(RED, "Multi shared memory version mismatch " - "(expected 0x%x but got 0x%x)\n", + cprintf(RED, "Multi shared memory (%d) version mismatch " + "(expected 0x%x but got 0x%x)\n", detId, MULTI_SHMVERSION, thisMultiDetector->shmversion); + sharedMemory->UnmapSharedMemory(thisMultiDetector);/** is this unncessary? */ + delete sharedMemory;/** is this unncessary? */ throw SharedMemoryException(); } } else { @@ -930,7 +933,8 @@ std::string multiSlsDetector::exec(const char* cmd) void multiSlsDetector::setHostname(string s) -{ +{ /* to just add at the end of list, + command line should not clear shm upon command hostname */ size_t p1 = 0; string temp = string(s); size_t p2 = temp.find('+', p1); @@ -990,14 +994,14 @@ void multiSlsDetector::addSlsDetector (std::string s) int pos = detectors.size(); slsDetector* sdet = new slsDetector(type, detId, pos, false, this); detectors.push_back(sdet); - detectors[pos]->setTCPSocket(s.c_str()); - detectors[pos]->setOnline(ONLINE_FLAG); + thisMultiDetector->numberOfDetectors = detectors.size(); - ++thisMultiDetector->numberOfDetectors; + detectors[pos]->setHostname(s.c_str()); + if (detectors[pos]->setOnline() ==ONLINE_FLAG) + detectors[pos]->updateDetector(); thisMultiDetector->dataBytes += detectors[pos]->getDataBytes(); thisMultiDetector->dataBytesInclGapPixels += detectors[pos]->getDataBytesInclGapPixels(); - thisMultiDetector->numberOfChannels += detectors[pos]->getTotalNumberOfChannels(); thisMultiDetector->maxNumberOfChannels += detectors[pos]->getMaxNumberOfChannels(); @@ -1444,8 +1448,16 @@ int multiSlsDetector::exitServer() int multiSlsDetector::readConfigurationFile(string const fname) { - freeSharedMemory(); - clearAllErrorMask(); + { + clearAllErrorMask(); + freeSharedMemory(); + + bool created = initSharedMemory(verify); + initializeDetectorStructure(created, verify); + initializeMembers(); // also deletes zmq objects and destroys threadpool + updateUserdetails(); + } + multiSlsDetectorClient* cmd; string ans; @@ -4886,15 +4898,6 @@ int multiSlsDetector::resetFramesCaught() int multiSlsDetector::createReceivingDataSockets(const bool destroy) { - - //number of sockets - int numSockets = detectors.size(); - int numSocketsPerDetector = 1; - if (getDetectorsType() == EIGER) { - numSocketsPerDetector = 2; - } - numSockets *= numSocketsPerDetector; - if (destroy) { cprintf(MAGENTA, "Going to destroy data sockets\n"); //close socket @@ -4910,6 +4913,13 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) cprintf(MAGENTA, "Going to create data sockets\n"); + int numSockets = detectors.size(); + int numSocketsPerDetector = 1; + if (getDetectorsType() == EIGER) { + numSocketsPerDetector = 2; + } + numSockets *= numSocketsPerDetector; + for (int i = 0; i < numSockets; ++i) { uint32_t portnum = 0; sscanf(detectors[i / numSocketsPerDetector]->getClientStreamingPort().c_str(), "%d", &portnum); @@ -4938,19 +4948,17 @@ void multiSlsDetector::readFrameFromReceiver() int nX = thisMultiDetector->numberOfDetector[X]; // to copy data in multi module int nY = thisMultiDetector->numberOfDetector[Y]; // for eiger, to reverse the data - int numSockets = detectors.size(); bool gappixelsenable = false; bool eiger = false; if (getDetectorsType() == EIGER) { eiger = true; nX *= 2; - numSockets *= 2; gappixelsenable = detectors[0]->enableGapPixels(-1) >= 1 ? true : false; } - bool runningList[numSockets], connectList[numSockets]; + bool runningList[zmqSocket.size()], connectList[zmqSocket.size()]; int numRunning = 0; - for (int i = 0; i < numSockets; ++i) { + for (int i = 0; i < zmqSocket.size(); ++i) { if (!zmqSocket[i]->Connect()) { connectList[i] = true; runningList[i] = true; @@ -4991,7 +4999,7 @@ void multiSlsDetector::readFrameFromReceiver() memset(multiframe, 0xFF, multisize); //get each frame - for (int isocket = 0; isocket < numSockets; ++isocket) { + for (int isocket = 0; isocket < zmqSocket.size(); ++isocket) { //if running if (runningList[isocket]) { @@ -5011,7 +5019,7 @@ void multiSlsDetector::readFrameFromReceiver() if (image == NULL) { // allocate size = doc["size"].GetUint(); - multisize = size * numSockets; + multisize = size * zmqSocket.size(); image = new char[size]; multiframe = new char[multisize]; memset(multiframe, 0xFF, multisize); @@ -5132,7 +5140,7 @@ void multiSlsDetector::readFrameFromReceiver() running = false; else { //starting a new scan/measurement (got dummy data) - for (int i = 0; i < numSockets; ++i) + for (int i = 0; i < zmqSocket.size(); ++i) runningList[i] = connectList[i]; numRunning = numConnected; } @@ -5140,7 +5148,7 @@ void multiSlsDetector::readFrameFromReceiver() } // Disconnect resources - for (int i = 0; i < numSockets; ++i) + for (int i = 0; i < zmqSocket.size(); ++i) if (connectList[i]) zmqSocket[i]->Disconnect(); diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h index 4eaa5d4b1..4ac1ca527 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -13,6 +13,13 @@ ID: $Id$ #ifndef MULTI_SLS_DETECTOR_H #define MULTI_SLS_DETECTOR_H +/** + @libdoc The multiSlsDetector class is used to operate several slsDetectors in parallel. + * @short This is the base class for multi detector system functionalities + * @author Anna Bergamaschi + */ + + #include "slsDetectorUtils.h" class slsDetector; class SharedMemory; @@ -28,15 +35,13 @@ class ZmqSocket; #define SHORT_STRING_LENGTH 50 #define DATE_LENGTH 29 -/** - @libdoc The multiSlsDetector class is used to operate several slsDetectors in parallel. - * @short This is the base class for multi detector system functionalities - * @author Anna Bergamaschi - */ - class multiSlsDetector : public slsDetectorUtils { +private: + /** + * @short structure allocated in shared memory to store detector settings for IPC and cache + */ typedef struct sharedMultiSlsDetector { @@ -225,24 +230,17 @@ class multiSlsDetector : public slsDetectorUtils { public: - using slsDetectorUtils::flatFieldCorrect; using slsDetectorUtils::rateCorrect; using slsDetectorUtils::setBadChannelCorrection; using slsDetectorUtils::readAngularConversion; using slsDetectorUtils::writeAngularConversion; - /* - @short Structure allocated in shared memory to store detector settings and - be accessed in parallel by several applications - - */ - /** * Constructor * @param id multi detector id - * @param verify true to verify if shared memory size matches existing one + * @param verify true to verify if shared memory version matches existing one * @param update true to update last user pid, date etc */ multiSlsDetector(int id = 0, bool verify = true, bool update = true); @@ -458,20 +456,20 @@ public: void setErrorMaskFromAllDetectors(); /** - Set acquiring flag in shared memory - \param b acquiring flag + * Set acquiring flag in shared memory + * @param b acquiring flag */ void setAcquiringFlag(bool b=false); /** - Get acquiring flag from shared memory - \returns acquiring flag + * Get acquiring flag from shared memory + * @returns acquiring flag */ bool getAcquiringFlag(); /** * Check if acquiring flag is set, set error if set - * \returns FAIL if not ready, OK if ready + * @returns FAIL if not ready, OK if ready */ bool isAcquireReady(); @@ -578,7 +576,7 @@ public: /** * Returns the number of detectors in the multidetector structure * @returns number of detectors - */ + */ int getNumberOfDetectors(); /** @@ -724,9 +722,9 @@ public: * Checks if the multi detectors are online and sets the online flag * @param online if GET_ONLINE_FLAG, only returns shared memory online flag, * else sets the detector in online/offline state - * if OFFLINE_FLAG, (i.e. no communication to the detector - using only local structure - no data acquisition possible!); - * if ONLINE_FLAG, detector in online state (i.e. communication to the detector updating the local structure) - * @returns online/offline status + * if OFFLINE_FLAG, (i.e. no communication to the detector - using only local structure - no data acquisition possible!); + * if ONLINE_FLAG, detector in online state (i.e. communication to the detector updating the local structure) + * @returns online/offline status */ int setOnline(int const online=GET_ONLINE_FLAG); @@ -734,7 +732,7 @@ public: * Checks if each of the detectors are online/offline * @returns empty string if they are all online, * else returns concatenation of strings of all detectors that are offline - */ + */ std::string checkOnline(); /** @@ -1841,7 +1839,7 @@ private: void initializeDetectorStructure(bool created, bool verify = true); /** - * Initialize class members (and from slsDetectorUtils) + * Initialize class members (and from parent classes) */ void initializeMembers(); diff --git a/slsDetectorSoftware/sharedMemory/SharedMemory.cpp b/slsDetectorSoftware/sharedMemory/SharedMemory.cpp index e34fdc4c0..e5b4a10ac 100644 --- a/slsDetectorSoftware/sharedMemory/SharedMemory.cpp +++ b/slsDetectorSoftware/sharedMemory/SharedMemory.cpp @@ -64,7 +64,7 @@ void* SharedMemory::CreateSharedMemory(size_t sz){ return MapSharedMemory(sz); } -void* SharedMemory::OpenSharedMemory(size_t sz, bool verify){ +void* SharedMemory::OpenSharedMemory(size_t sz){ // open fd = shm_open(name.c_str(), O_RDWR, 0); if (fd < 0) { @@ -73,11 +73,6 @@ void* SharedMemory::OpenSharedMemory(size_t sz, bool verify){ throw SharedMemoryException(); } - // verification required and size does not match - if (verify) - VerifySizeMatch(sz); - - // map return MapSharedMemory(sz); } diff --git a/slsDetectorSoftware/sharedMemory/SharedMemory.h b/slsDetectorSoftware/sharedMemory/SharedMemory.h index 070b221f7..09e27527e 100644 --- a/slsDetectorSoftware/sharedMemory/SharedMemory.h +++ b/slsDetectorSoftware/sharedMemory/SharedMemory.h @@ -42,18 +42,15 @@ public: * Create Shared memory and call MapSharedMemory to map it to an address * throws a SharedMemoryException exception on failure to create, ftruncate or map * @param sz of shared memory - * @param addr double pointer to address to be mapped */ void* CreateSharedMemory(size_t sz); /** * Open existing Shared memory and call MapSharedMemory to map it to an address - * throws a SharedMemoryException exception on failure to open, incorrect size if verify true, or map + * throws a SharedMemoryException exception on failure to open or map * @param sz of shared memory - * @param addr double pointer to address to be mapped - * @param verify true to verify if the size matches existing one and return fail if does not match */ - void* OpenSharedMemory(size_t sz, bool verify = true); + void* OpenSharedMemory(size_t sz); /** * Unmap shared memory from an address @@ -85,16 +82,13 @@ private: /** * Map shared memory to an address * throws a SharedMemoryException exception on failure - * @param addr double pointer to address to be mapped * @param sz of shared memory */ - //template - // void MapSharedMemory(myType*& addr, size_t sz); void* MapSharedMemory(size_t sz); /** * Verify if existing shared memory size matches expected size - * @param sz expected size of shared memory, replaced with smaller size if size does not match + * @param expectedSize expected size of shared memory, replaced with smaller size if size does not match * @return 0 for success, 1 for fail */ int VerifySizeMatch(size_t expectedSize); diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 4d77bd56c..843aabbeb 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -1,7 +1,14 @@ #include "slsDetector.h" +#include "multiSlsDetector.h" +#include "SharedMemory.h" +#include "receiverInterface.h" +#include "gitInfoLib.h" +#include "versionAPI.h" #include "usersFunctions.h" #include "slsDetectorCommand.h" #include "postProcessingFuncs.h" + + #include #include #include @@ -9,382 +16,706 @@ #include #include #include -#include "gitInfoLib.h" -#include "versionAPI.h" using namespace std; -int slsDetector::initSharedMemory(detectorType type, int id) { - /** - the shared memory key is set to DEFAULT_SHM_KEY+id - */ - key_t mem_key=DEFAULT_SHM_KEY+id; - int shm_id; - int nch, nm, nc, nd, ng, no; - int sz; +slsDetector::slsDetector(detectorType type, int multiId, int id, bool verify, MultiDet* m) +: slsDetectorUtils(), + detId(id), + sharedMemory(0), + thisDetector(0), + multiDet(m), + thisReceiver(0), + controlSocket(0), + stopSocket(0), + dataSocket(0), + detectorModules(0), + dacs(0), + adcs(0), + chipregs(0), + chanregs(0), + gain(0), + offset(0), + ffcoefficients(0), + fferrors(0) +{ + /* called from put hostname command, + * so sls shared memory will be created */ + freeSharedMemory(multiId, id); + initSharedMemory(true, type, multiId, verify); + initializeDetectorStructure(true, type, verify); + initializeMembers(); +} - //shmId=-1; -#ifdef VERBOSE - cout << "init shm"<< endl; -#endif - switch(type) { - case MYTHEN: - nch=128; // complete mythen system - nm=24; - nc=10; - nd=6; // dacs+adcs - ng=0; - no=0; - break; - case PICASSO: - nch=128; // complete mythen system - nm=24; - nc=12; - nd=6; // dacs+adcs - ng=0; - no=0; - break; - case GOTTHARD: - nch=128; - nm=1; - nc=10; - nd=13; // dacs+adcs - ng=0; - no=0; - break; - case PROPIX: - nch=22*22; - nm=1; - nc=1; - nd=13; // dacs+adcs - break; - case EIGER: - nch=256*256; // one EIGER half module - nm=1; //modules/detector - nc=4; //chips - nd=16; //dacs+adcs - ng=4; - no=4; - break; - case MOENCH: - nch=160*160; - nm=1; //modules/detector - nc=1; //chips - nd=9; //dacs+adcs - ng=0; - no=0; - break; - case JUNGFRAU: - nch=256*256; - nm=1; //modules/detector - nc=8; //chips - nd=16; //dacs+adcs - ng=0; - no=0; - break; - case JUNGFRAUCTB: - nch=36; //36? is using digital value as well - nm=1; //modules/detector - nc=1; //chips - nd=16; //dacs+adcs - ng=0; - no=0; - break; - default: - nch=0; // dum! - nm=0; //modules/detector - nc=0; //chips - nd=0; //dacs+adcs - ng=0; - no=0; - break; - } - /** - The size of the shared memory is: - size of shared structure + ffcoefficents +fferrors + modules+ dacs+adcs+chips+chans+gain+offset - */ +slsDetector::slsDetector(int multiId, int id, bool verify, MultiDet* m) +: slsDetectorUtils(), + detId(id), + sharedMemory(0), + thisDetector(0), + multiDet(m), + thisReceiver(0), + controlSocket(0), + stopSocket(0), + dataSocket(0), + detectorModules(0), + dacs(0), + adcs(0), + chipregs(0), + chanregs(0), + gain(0), + offset(0), + ffcoefficients(0), + fferrors(0) +{ + /* called from multi constructor to populate structure, + * so sls shared memory will be opened, not created */ + // shared memory will be opened, hence false + detectorType type = GetDetectorTypeFromShm(multiId, verify); + initSharedMemory(false, type, multiId, verify); + initializeDetectorStructure(false, type, verify); + initializeMembers(); +} +slsDetector::~slsDetector() +{ + if (sharedMemory) { + sharedMemory->UnmapSharedMemory(thisMultiDetector); + delete sharedMemory; + } + if(thisReceiver) + delete thisReceiver; + if(controlSocket) + delete controlSocket; + if(stopSocket) + delete stopSocket; + if(dataSocket) + delete dataSocket; - sz=sizeof(sharedSlsDetector)+nm*(2*nch*nc*sizeof(double)+sizeof(sls_detector_module)+sizeof(int)*nc+sizeof(dacs_t)*nd+sizeof(int)*nch*nc+sizeof(int)*ng+sizeof(int)*no); -#ifdef VERBOSE - std::cout<<"Size of shared memory is "<< sz << "(type " << type << " - id " << mem_key << ")"<< std::endl; -#endif - shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory - - if (shm_id < 0) { - std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; - return shm_id; - } - - /** - thisDetector pointer is set to the memory address of the shared memory - */ - - thisDetector = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ - - if (thisDetector == (void*)-1) { - std::cout<<"*** shmat error (server) ***" << std::endl; - return shm_id; - } -#ifdef VERBOSE - cout <<"shm done"<nChans*thisDetector->nChips*thisDetector->nMods; + if (thisDetector->myDetectorType == JUNGFRAUCTB) + nn=thisDetector->dataBytes/2; + } else { + if (thisDetector->myDetectorType == JUNGFRAUCTB) { + nn=thisDetector->dataBytes/2; + dataout=new double[nn]; + } else { + dataout=new double[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + nn=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; + } + } - detectorType type=(detectorType)getDetectorType(id); + int ival = 0, ipos = 0, ichan=0, ibyte = 0; + char *ptr = (char*)datain; + char iptr = 0; + int nbits=thisDetector->dynamicRange; + int nch=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; - while (shmId<0) { - /**Initlializes shared memory \sa initSharedMemory - - if it fails the detector id is incremented until it succeeds - */ - shmId=initSharedMemory(type,id); - ++id; - } - --id; -#ifdef VERBOSE - std::cout<< "Detector id is " << id << std::endl; -#endif - detId=id; + if (thisDetector->timerValue[PROBES_NUMBER]==0) { + if (thisDetector->myDetectorType==JUNGFRAUCTB) { + for (ichan=0; ichandataBytes; ++ibyte) { + iptr=ptr[ibyte]; + for (ipos=0; ipos<8; ++ipos) { + ival=(iptr>>(ipos))&0x1; + dataout[ichan]=ival; + ++ichan; + } + } + break; + case 4: + for (ibyte=0; ibytedataBytes; ++ibyte) { + iptr=ptr[ibyte]; + for (ipos=0; ipos<2; ++ipos) { + ival=(iptr>>(ipos*4))&0xf; + dataout[ichan]=ival; + ++ichan; + } + } + break; + case 8: + for (ichan=0; ichandataBytes; ++ichan) { + ival=ptr[ichan]&0xff; + dataout[ichan]=ival; + } + break; + case 16: + for (ichan=0; ichanmyDetectorType == MYTHEN) mask=0xffffff; + for (ichan=0; ichangetNumberOfDetectors();++i){ + if(multiDet->getDetectorId(i) == getDetectorId()) + multiDet->setErrorMask(multiDet->getErrorMask()|(0<setAcquiringFlag(b); } -slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int cport) { +bool slsDetector::getAcquiringFlag() +{ + return multiDet->getAcquiringFlag(); +} - int retval=FAIL; - detectorType t=GENERIC; - int fnum=F_GET_DETECTOR_TYPE; - MySocketTCP *s= new MySocketTCP(name, cport); - char m[100]; -#ifdef VERBOSE - cout << "Getting detector type " << endl; -#endif - if (s->Connect()>=0) { - s->SendDataOnly(&fnum,sizeof(fnum)); - s->ReceiveDataOnly(&retval,sizeof(retval)); - if (retval!=FAIL) { - s->ReceiveDataOnly(&t,sizeof(t)); +bool slsDetector::isAcquireReady() +{ + return multiDet->isAcquireReady(); +} + + +int slsDetector::checkVersionCompatibility(portType t) +{ + int fnum = F_CHECK_VERSION; + if (t == DATA_PORT) + fnum = F_RECEIVER_CHECK_VERSION; + int ret = FAIL; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); + int64_t arg = 0; + + // detector + if (t == CONTROL_PORT) { + + switch (thisDetector->myDetectorType) { + case EIGER: arg = APIEIGER; break; + case JUNGFRAU: arg = APIJUNGFRAU; break; + case GOTTHARD: arg = APIGOTTHARD; break; + default: + std::cout<< "Check version compatibility is not implemented for this detector" << std::endl; + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + return FAIL; + } #ifdef VERBOSE - cout << "Detector type is "<< t << endl; + std::cout<< std::endl<< "Checking version compatibility with detector with value " << hex << arg << std::endl; #endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + // control port + 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)); + cprintf(RED, "Detector returned error: (Control Server) %s", mess); + if(strstr(mess,"Unrecognized Function")!=NULL) + std::cout << "The detector server is too old to get API version. Please update detector server!" << std::endl; + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + thisDetector->detectorControlAPIVersion = 0; + } else { + thisDetector->detectorControlAPIVersion = arg; + } + disconnectControl(); + } + if (ret!= FAIL) { + ret = FAIL; - } else { - s->ReceiveDataOnly(m,sizeof(m)); - std::cout<< "Detector returned error: " << m << std::endl; - } - s->Disconnect(); - } else { - cout << "Cannot connect to server " << name << " over port " << cport << endl; - } + // stop port + if (connectStop() == OK){ + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + cprintf(RED, "Detector returned error: (Stop Server) %s", mess); + if(strstr(mess,"Unrecognized Function")!=NULL) + std::cout << "The detector server is too old to get API version. Please update detector server!" << std::endl; + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + thisDetector->detectorStopAPIVersion = 0; + } else { + thisDetector->detectorStopAPIVersion = arg; + } + disconnectStop(); + } + } + } + } - -/* - //receiver - if((t != GENERIC) && (setReceiverOnline()==ONLINE_FLAG)) { - int k; - retval = FAIL; - if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ + // receiver + else { + arg = APIRECEIVER; #ifdef VERBOSE - std::cout << "Sending detector type to Receiver " << (int)thisDetector->myDetectorType << std::endl; + std::cout<< std::endl<< "Checking version compatibility with receiver with value " << hex << arg << std::endl; #endif - if (connectData() == OK) - retval=thisReceiver->sendInt(fnum2,k,(int)t); - disconnectData(); - if(retval==FAIL){ - cout << "ERROR: Could not send detector type to receiver" << endl; - setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); - } - } - } -*/ - delete s; - return t; + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + // data port + if (connectData() == OK){ + // ignoring retval + int64_t retval = -1; + ret=thisReceiver->sendInt(fnum,retval,arg); + if (ret==FAIL){ + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + if(strstr(mess,"Unrecognized Function")!=NULL) + std::cout << "The receiver software is too old to get API version. Please update receiver software!" << std::endl; + thisDetector->receiverAPIVersion = 0; + } else { + thisDetector->receiverAPIVersion = arg; + } + disconnectData(); + } + } + } + return ret; +} + + + + +int64_t slsDetector::getId( idMode mode, int imod) +{ + + int64_t retval=-1; + int fnum=F_GET_ID,fnum2 = F_GET_RECEIVER_ID; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< std::endl; + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Getting id of "<< imod << std::endl; + else + std::cout<< "Getting id type "<< mode << std::endl; +#endif + if (mode==THIS_SOFTWARE_VERSION) { + ret=OK; + retval=GITDATE; + } else if (mode==RECEIVER_VERSION) { + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + if (connectData() == OK){ + ret=thisReceiver->getInt(fnum2,retval); + disconnectData(); + } + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + } else { + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() != OK) + ret = FAIL; + else{ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + if (mode==MODULE_SERIAL_NUMBER) + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + } + if (ret==FAIL) { + std::cout<< "Get id failed " << std::endl; + return ret; + } else { +#ifdef VERBOSE + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Id of "<< imod <<" is " << hex <RemoveSharedMemory(); + delete shm; +} + +void slsDetector::freeSharedMemory() +{ + if (sharedMemory) { + sharedMemory->UnmapSharedMemory(thisDetector); + sharedMemory->RemoveSharedMemory(); + delete sharedMemory; + } + thisDetector = 0; +} + +string slsDetector::setHostname(const char *name) +{ + setTCPSocket(string(name)); + return getHostname(); +} + +string slsDetector::getHostname() +{ + return string(thisDetector->hostname); +} + + +detectorType slsDetector::getDetectorTypeFromShm(int multiId) +{ + SharedMemory* shm = new SharedMemory(multiId, detId); + std::string shmname = shm->GetName(); + + // shm not created before + if (!SharedMemory::IsExisting(shmname)) { + cprintf(RED,"Shared memory %s does not exist.\n" + "Corrupted Multi Shared memory. Please free shared memory.\n", + shmname.c_str()); + throw SharedMemoryException(); + } + + // map basic size of sls detector structure (no need of offsets, just version is required) + slsDetector* sdet = 0; + size_t sz = sizeof(sharedSlsDetector); + + // open, map, verify version, get type + sdet = (sharedSlsDetector*)shm->OpenSharedMemory(sz); + if (verify && thisDetector->shmversion != SLS_SHMVERSION) { + cprintf(RED, "Single shared memory (%d-%d:)version mismatch " + "(expected 0x%x but got 0x%x)\n", + multiId, detId, SLS_SHMVERSION, thisDetector->shmversion); + shm->UnmapSharedMemory(sdet); /** is this unncessary? */ + delete shm;/** is this unncessary? */ + throw SharedMemoryException(); + } + detectorType type = sdet->type; + + // unmap + shm->UnmapSharedMemory(sdet); + delete shm; + + return type; +} + + +slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int cport) +{ + int fnum=F_GET_DETECTOR_TYPE; + int retval = FAIL; + detectorType t=GENERIC; + MySocketTCP *s= new MySocketTCP(name, cport); + char m[MAX_STR_LENGTH]; +#ifdef VERBOSE + cout << "Getting detector type " << endl; +#endif + if (s->Connect() >= 0) { + s->SendDataOnly(&fnum,sizeof(fnum)); + s->ReceiveDataOnly(&retval,sizeof(retval)); + if (retval!=FAIL) { + s->ReceiveDataOnly(&t,sizeof(t)); +#ifdef VERBOSE + cout << "Detector type is "<< t << endl; +#endif + } else { + s->ReceiveDataOnly(m,sizeof(m)); + std::cout<< "Detector returned error: " << m << std::endl; + } + s->Disconnect(); + } else { + cout << "Cannot connect to server " << name << " over port " << cport << endl; + } + delete s; + return t; +} + + +void slsDetector::initSharedMemory(bool created, detectorType type, int multiId, bool verify) +{ + if (sharedMemory) + delete sharedMemory; + thisDetector = 0; + + // calculate shared memory size + int sz = calculateSharedMemorySize(type); + + // shared memory object with name + sharedMemory = new SharedMemory(multiId, detId); + // create + if (create) { + try { + thisSingleDet = (sharedSingleDet*)sharedMemory->CreateSharedMemory(sz); + } catch(...) { + sharedMemory->RemoveSharedMemory(); + thisSingleDet = 0; + throw; + } + } + // open and verify version + else { + thisSingleDet = (sharedSingleDet*)sharedMemory->OpenSharedMemory(sz, verify); + if (verify && thisDetector->shmversion != SLS_SHMVERSION) { + cprintf(RED, "Single shared memory (%d-%d:)version mismatch " + "(expected 0x%x but got 0x%x)\n", + multiId, detId, SLS_SHMVERSION, thisDetector->shmversion); + shm->UnmapSharedMemory(sdet); /** is this unncessary? */ + delete shm;/** is this unncessary? */ + throw SharedMemoryException(); + } + } +} + + +int slsDetector::calculateSharedMemorySize(detectorType type) +{ + int nch = 0, nm = 0, nc = 0, nd = 0, ng = 0, no = 0; + switch(type) { + case MYTHEN: + nch=128; // complete mythen system + nm=24; + nc=10; + nd=6; // dacs+adcs + ng=0; + no=0; + break; + case PICASSO: + nch=128; // complete mythen system + nm=24; + nc=12; + nd=6; // dacs+adcs + ng=0; + no=0; + break; + case GOTTHARD: + nch=128; + nm=1; + nc=10; + nd=13; // dacs+adcs + ng=0; + no=0; + break; + case PROPIX: + nch=22*22; + nm=1; + nc=1; + nd=13; // dacs+adcs + break; + case EIGER: + nch=256*256; // one EIGER half module + nm=1; //modules/detector + nc=4; //chips + nd=16; //dacs+adcs + ng=4; + no=4; + break; + case MOENCH: + nch=160*160; + nm=1; //modules/detector + nc=1; //chips + nd=9; //dacs+adcs + ng=0; + no=0; + break; + case JUNGFRAU: + nch=256*256; + nm=1; //modules/detector + nc=8; //chips + nd=16; //dacs+adcs + ng=0; + no=0; + break; + case JUNGFRAUCTB: + nch=36; //36? is using digital value as well + nm=1; //modules/detector + nc=1; //chips + nd=16; //dacs+adcs + ng=0; + no=0; + break; + default: + nch=0; // dum! + nm=0; //modules/detector + nc=0; //chips + nd=0; //dacs+adcs + ng=0; + no=0; + break; + } + + /** + The size of the shared memory is: + size of shared structure + ffcoefficents +fferrors + modules+ dacs+adcs+chips+chans+gain+offset + */ + int sz = sizeof(sharedSlsDetector) + + nm * ( + 2 * nch * nc * sizeof(double) + + sizeof(sls_detector_module) + + sizeof(int) * nc + + sizeof(dacs_t) * nd + + sizeof(int) * nch * nc + + sizeof(int) * ng + + sizeof(int) * no); +#ifdef VERBOSE + std::cout<<"Size of shared memory is " << sz << std::endl; +#endif + return sz; +} + + +void slsDetector::initializeDetectorStructure(bool created, detectorType type, bool verify) +{ + char *goff = (char*)thisDetector; + + // initialize detector structure to defaults + if (created) { + thisDetector->shmversion = SLS_SHMVERSION; + thisDetector->onlineFlag = OFFLINE_FLAG; + thisDetector->stoppedFlag = 0; + strncpy(thisDetector->hostname, DEFAULT_HOSTNAME, strlength(DEFAULT_HOSTNAME)); + thisDetector->controlPort = DEFAULT_PORTNO; + thisDetector->stopPort = DEFAULT_PORTNO + 1; + thisDetector->myDetectorType = type; + strcpy(thisDetector->settingsDir, getenv("HOME")); + strcpy(thisDetector->calDir, getenv("HOME")); +nTrimEn; +trimEnergies[100]; +progressIndex; +totalProgress; +filePath[MAX_STR_LENGTH]; +nMod[2]; +nMods; +nModMax[2]; +nModsMax; +nChans; +nChan[2]; +nChips; +nChip[2]; +nDacs; +nAdcs; +nGain; +nOffset; +dynamicRange; +dataBytes; +correctionMask; +threadedProcessing; +tDead; +flatFieldDir[MAX_STR_LENGTH]; +flatFieldFile[MAX_STR_LENGTH]; +nBadChans; +badChanFile[MAX_STR_LENGTH]; +badChansList[MAX_BADCHANS]; +nBadFF; +badFFList[MAX_BADCHANS]; +angConvFile[MAX_STR_LENGTH]; +angOff[MAXMODS]; +angDirection; +fineOffset; +globalOffset; +numberOfPositions; +detPositions[MAXPOS]; +binSize; +moveFlag; +nROI; +roiLimits[MAX_ROIS]; +roFlags; +settingsFile[MAX_STR_LENGTH]; +currentSettings; +currentThresholdEV; +timerValue[MAX_TIMERS]; +actionMask; +actionScript[MAX_ACTIONS]; +actionParameter[MAX_ACTIONS]; +scanMode[MAX_SCAN_LEVELS]; +scanScript[MAX_SCAN_LEVELS]; +scanParameter[MAX_SCAN_LEVELS]; +nScanSteps[MAX_SCAN_LEVELS]; +scanSteps[MAX_SCAN_LEVELS]; +scanPrecision[MAX_SCAN_LEVELS]; +ffoff; +fferroff; +modoff; +dacoff; +adcoff; +chipoff; +chanoff; +gainoff; +offsetoff; +receiver_hostname[MAX_STR_LENGTH]; +receiverTCPPort; +receiverUDPPort; +receiverUDPPort2; +receiverUDPIP[MAX_STR_LENGTH]; +receiverUDPMAC[MAX_STR_LENGTH]; +detectorMAC[MAX_STR_LENGTH]; +detectorIP[MAX_STR_LENGTH]; +receiverOnlineFlag; +tenGigaEnable; +flippedData[2]; +zmqport; +receiver_zmqport; +receiver_upstream; +receiver_read_freq; +zmqip[MAX_STR_LENGTH]; +receiver_zmqip[MAX_STR_LENGTH]; +gappixels; +nGappixels[2]; +dataBytesInclGapPixels; +receiver_additionalJsonHeader[MAX_STR_LENGTH]; +receiver_framesPerFile; +detectorControlAPIVersion; +detectorStopAPIVersion; +receiverAPIVersion; + + } } @@ -394,140 +725,31 @@ slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int -int slsDetector::exists(int id) { - - key_t mem_key=DEFAULT_SHM_KEY+id; - int shm_id; - int sz; - - sz=sizeof(sharedSlsDetector); - - -#ifdef VERBOSE - cout << "getDetectorType: generic shared memory of size " << sz << endl; -#endif - shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory - - if (shm_id < 0) { - std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; - return -1; - } - - /** - thisDetector pointer is set to the memory address of the shared memory - */ - - sharedSlsDetector* det = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ - - if (det == (void*)-1) { - std::cout<<"*** shmat error (server) ***" << std::endl; - return -1; - } - /** - shm_id returns -1 is shared memory initialization fails - */ - //shmId=shm_id; - - - - - if (det->alreadyExisting==0) { - // Detach Memory address - if (shmdt(det) == -1) { - perror("shmdt failed\n"); - return 0; - } -#ifdef VERBOSE - printf("Shared memory %d detached\n", shm_id); -#endif - // remove shared memory - if (shmctl(shm_id, IPC_RMID, 0) == -1) { - perror("shmctl(IPC_RMID) failed\n"); - return 0; - } -#ifdef VERBOSE - printf("Shared memory %d deleted\n", shm_id); -#endif - return 0; - } - - return 1; - - - -} -slsDetectorDefs::detectorType slsDetector::getDetectorType(int id) { - - detectorType t=GENERIC; - key_t mem_key=DEFAULT_SHM_KEY+id; - int shm_id; - int sz; - - sz=sizeof(sharedSlsDetector); -#ifdef VERBOSE - cout << "getDetectorType: generic shared memory of size " << sz << endl; -#endif - shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory - - if (shm_id < 0) { - std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; - return t; - } - - /** - thisDetector pointer is set to the memory address of the shared memory - */ - - sharedSlsDetector* det = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ - - if (det == (void*)-1) { - std::cout<<"*** shmat error (server) ***" << std::endl; - return t; - } - /** - shm_id returns -1 is shared memory initialization fails - */ - //shmId=shm_id; - - t=det->myDetectorType; - if (det->alreadyExisting==0) { - // Detach Memory address - if (shmdt(det) == -1) { - perror("shmdt failed\n"); - return t; - } -#ifdef VERBOSE - printf("Shared memory %d detached\n", shm_id); -#endif - // remove shared memory - if (shmctl(shm_id, IPC_RMID, 0) == -1) { - perror("shmctl(IPC_RMID) failed\n"); - return t; - } -#ifdef VERBOSE - printf("Shared memory %d deleted\n", shm_id); -#endif - } - -#ifdef VERBOSE - cout << "Detector type is " << t << endl; -#endif - - return t; -} + + + + + + + + + + + + int slsDetector::initializeDetectorSize(detectorType type) { @@ -916,10 +1138,10 @@ int slsDetector::initializeDetectorSize(detectorType type) { filePath=thisDetector->filePath; pthread_mutex_lock(&ms); - fileName=parentDet->fileName; - fileIndex=parentDet->fileIndex; - framesPerFile=parentDet->framesPerFile; - fileFormatType=parentDet->fileFormatType; + fileName=multiDet->fileName; + fileIndex=multiDet->fileIndex; + framesPerFile=multiDet->framesPerFile; + fileFormatType=multiDet->fileFormatType; if((thisDetector->myDetectorType==GOTTHARD)||(thisDetector->myDetectorType==PROPIX)){ fileIO::setFramesPerFile(MAX_FRAMES_PER_FILE); pthread_mutex_unlock(&ms); @@ -1939,7 +2161,7 @@ int slsDetector::setNumberOfModules(int n, dimension d){ if(n != GET_FLAG){ pthread_mutex_lock(&ms); - parentDet->updateOffsets(); + multiDet->updateOffsets(); pthread_mutex_unlock(&ms); } @@ -2240,86 +2462,7 @@ slsDetectorDefs::externalCommunicationMode slsDetector::setExternalCommunication }; -// Tests and identification -/* - Gets versions - enum idMode{ - MODULE_SERIAL_NUMBER, - MODULE_FIRMWARE_VERSION, - DETECTOR_SERIAL_NUMBER, - DETECTOR_FIRMWARE_VERSION, - DETECTOR_SOFTWARE_VERSION, - THIS_SOFTWARE_VERSION, - RECEIVER_VERSION - }{}; -*/ - - - - - -int64_t slsDetector::getId( idMode mode, int imod){ - - int64_t retval=-1; - int fnum=F_GET_ID,fnum2 = F_GET_RECEIVER_ID; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<< std::endl; - if (mode==MODULE_SERIAL_NUMBER) - std::cout<< "Getting id of "<< imod << std::endl; - else - std::cout<< "Getting id type "<< mode << std::endl; -#endif - if (mode==THIS_SOFTWARE_VERSION) { - ret=OK; - retval=GITDATE; - } else if (mode==RECEIVER_VERSION) { - if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { - if (connectData() == OK){ - ret=thisReceiver->getInt(fnum2,retval); - disconnectData(); - } - if(ret==FORCE_UPDATE) - ret=updateReceiver(); - } - } else { - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() != OK) - ret = FAIL; - else{ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&mode,sizeof(mode)); - if (mode==MODULE_SERIAL_NUMBER) - controlSocket->SendDataOnly(&imod,sizeof(imod)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - } - if (ret==FAIL) { - std::cout<< "Get id failed " << std::endl; - return ret; - } else { -#ifdef VERBOSE - if (mode==MODULE_SERIAL_NUMBER) - std::cout<< "Id of "<< imod <<" is " << hex <nChans*thisDetector->nChips*thisDetector->nMods; - // printf("not allocating fdata!\n"); - if (thisDetector->myDetectorType==JUNGFRAUCTB) nn=thisDetector->dataBytes/2; - } else { - if (thisDetector->myDetectorType==JUNGFRAUCTB) { - nn=thisDetector->dataBytes/2; - dataout=new double[nn]; - - // std::cout<< "nn is "<< nn << std::endl; - } else { - dataout=new double[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; - nn=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; - } - - // printf("allocating fdata!\n"); - } - // const int bytesize=8; - - int ival=0; - char *ptr=(char*)datain; - char iptr; - - int nbits=thisDetector->dynamicRange; - int nch=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; - int ipos=0, ichan=0, ibyte; - - if (thisDetector->timerValue[PROBES_NUMBER]==0) { - if (thisDetector->myDetectorType==JUNGFRAUCTB) { - - for (ichan=0; ichandataBytes; ++ibyte) { - iptr=ptr[ibyte];//&0x1; - for (ipos=0; ipos<8; ++ipos) { - // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; - ival=(iptr>>(ipos))&0x1; - dataout[ichan]=ival; - ++ichan; - } - } - break; - case 4: - for (ibyte=0; ibytedataBytes; ++ibyte) { - iptr=ptr[ibyte]; - for (ipos=0; ipos<2; ++ipos) { - // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; - ival=(iptr>>(ipos*4))&0xf; - dataout[ichan]=ival; - ++ichan; - } - } - break; - case 8: - for (ichan=0; ichandataBytes; ++ichan) { - ival=ptr[ichan]&0xff; - dataout[ichan]=ival; - } - break; - case 16: - for (ichan=0; ichanmyDetectorType == MYTHEN) mask=0xffffff; - for (ichan=0; ichanenableWriteToFileMask() << endl; - std::cout << "overwrite enable:" << parentDet->enableOverwriteMask() << endl; + std::cout << "write enable:" << multiDet->enableWriteToFileMask() << endl; + std::cout << "overwrite enable:" << multiDet->enableOverwriteMask() << endl; pthread_mutex_unlock(&ms); std::cout << "frame index needed:" << ((thisDetector->timerValue[FRAME_NUMBER]*thisDetector->timerValue[CYCLES_NUMBER])>1) << endl; std::cout << "frame period:" << thisDetector->timerValue[FRAME_PERIOD] << endl; @@ -6334,11 +6374,11 @@ string slsDetector::setReceiver(string receiverIP){ setFileFormat(fileIO::getFileFormat()); setReceiverFramesPerFile(thisDetector->receiver_framesPerFile); pthread_mutex_lock(&ms); - int imask = parentDet->enableWriteToFileMask(); + int imask = multiDet->enableWriteToFileMask(); pthread_mutex_unlock(&ms); enableWriteToFile(imask); pthread_mutex_lock(&ms); - imask = parentDet->enableOverwriteMask(); + imask = multiDet->enableOverwriteMask(); pthread_mutex_unlock(&ms); overwriteFile(imask); setTimer(FRAME_PERIOD,thisDetector->timerValue[FRAME_PERIOD]); @@ -6835,7 +6875,7 @@ int slsDetector::configureMAC(){ // only jungfrau and eiger, send x, y and z in detector udp header if (thisDetector->myDetectorType == JUNGFRAU || thisDetector->myDetectorType == EIGER) { sendpos = true; - int max = parentDet->getNumberOfDetectors(X); + int max = multiDet->getNumberOfDetectors(X); if(!posId) { pos[0] = 0; pos[1] = 0; @@ -8454,7 +8494,7 @@ string slsDetector::setFileName(string s) { /*if(!s.empty()){ pthread_mutex_lock(&ms); fileIO::setFileName(s); - s=parentDet->createReceiverFilePrefix(); + s=multiDet->createReceiverFilePrefix(); pthread_mutex_unlock(&ms); }*/ @@ -8473,7 +8513,7 @@ string slsDetector::setFileName(string s) { #endif /* pthread_mutex_lock(&ms); - fileIO::setFileName(parentDet->getNameFromReceiverFilePrefix(string(retval))); + fileIO::setFileName(multiDet->getNameFromReceiverFilePrefix(string(retval))); pthread_mutex_unlock(&ms); */ sretval = fileIO::getNameFromReceiverFilePrefix(string(retval)); @@ -8931,13 +8971,13 @@ int slsDetector::updateReceiverNoWait() { // file write enable n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); pthread_mutex_lock(&ms); - parentDet->enableWriteToFileMask(ind); + multiDet->enableWriteToFileMask(ind); pthread_mutex_unlock(&ms); // file overwrite enable n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); pthread_mutex_lock(&ms); - parentDet->enableOverwriteMask(ind); + multiDet->enableOverwriteMask(ind); pthread_mutex_unlock(&ms); // receiver read frequency @@ -9039,7 +9079,7 @@ int slsDetector::enableWriteToFile(int enable){ if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ if(enable>=0){ pthread_mutex_lock(&ms); - parentDet->enableWriteToFileMask(enable); + multiDet->enableWriteToFileMask(enable); pthread_mutex_unlock(&ms); } } @@ -9054,7 +9094,7 @@ int slsDetector::enableWriteToFile(int enable){ } if(ret!=FAIL){ pthread_mutex_lock(&ms); - parentDet->enableWriteToFileMask(retval); + multiDet->enableWriteToFileMask(retval); pthread_mutex_unlock(&ms); } if(ret==FORCE_UPDATE) @@ -9062,7 +9102,7 @@ int slsDetector::enableWriteToFile(int enable){ } pthread_mutex_lock(&ms); - retval = parentDet->enableWriteToFileMask(); + retval = multiDet->enableWriteToFileMask(); pthread_mutex_unlock(&ms); return retval; @@ -9081,7 +9121,7 @@ int slsDetector::overwriteFile(int enable){ if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ if(enable>=0){ pthread_mutex_lock(&ms); - parentDet->enableOverwriteMask(enable); + multiDet->enableOverwriteMask(enable); pthread_mutex_unlock(&ms); } } @@ -9096,7 +9136,7 @@ int slsDetector::overwriteFile(int enable){ } if(ret!=FAIL){ pthread_mutex_lock(&ms); - parentDet->enableOverwriteMask(retval); + multiDet->enableOverwriteMask(retval); pthread_mutex_unlock(&ms); } if(ret==FORCE_UPDATE) @@ -9104,7 +9144,7 @@ int slsDetector::overwriteFile(int enable){ } pthread_mutex_lock(&ms); - retval = parentDet->enableOverwriteMask(); + retval = multiDet->enableOverwriteMask(); pthread_mutex_unlock(&ms); return retval; @@ -9147,18 +9187,7 @@ int slsDetector::calibratePedestal(int frames){ -int64_t slsDetector::clearAllErrorMask(){ - clearErrorMask(); - pthread_mutex_lock(&ms); - for(int i=0;igetNumberOfDetectors();++i){ - if(parentDet->getDetectorId(i) == getDetectorId()) - parentDet->setErrorMask(parentDet->getErrorMask()|(0<getNumberOfDetectors(arg[0],arg[1]); + multiDet->getNumberOfDetectors(arg[0],arg[1]); pthread_mutex_unlock(&ms); if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ @@ -9795,18 +9824,6 @@ int slsDetector::pulseChip(int n) { -void slsDetector::setAcquiringFlag(bool b){ - parentDet->setAcquiringFlag(b); -} - -bool slsDetector::getAcquiringFlag(){ - return parentDet->getAcquiringFlag(); -} - - -bool slsDetector::isAcquireReady() { - return parentDet->isAcquireReady(); -} int slsDetector::restreamStopFromReceiver(){ @@ -9834,98 +9851,3 @@ int slsDetector::restreamStopFromReceiver(){ return ret; } - -int slsDetector::checkVersionCompatibility(portType t) { - int fnum = F_CHECK_VERSION; - if (t == DATA_PORT) - fnum = F_RECEIVER_CHECK_VERSION; - int ret = FAIL; - char mess[MAX_STR_LENGTH]; - memset(mess, 0, MAX_STR_LENGTH); - int64_t arg = 0; - - // detector - if (t == CONTROL_PORT) { - - switch (thisDetector->myDetectorType) { - case EIGER: arg = APIEIGER; break; - case JUNGFRAU: arg = APIJUNGFRAU; break; - case GOTTHARD: arg = APIGOTTHARD; break; - default: - std::cout<< "Check version compatibility is not implemented for this detector" << std::endl; - setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); - return FAIL; - } - -#ifdef VERBOSE - std::cout<< std::endl<< "Checking version compatibility with detector with value " << hex << arg << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - // control port - 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)); - cprintf(RED, "Detector returned error: (Control Server) %s", mess); - if(strstr(mess,"Unrecognized Function")!=NULL) - std::cout << "The detector server is too old to get API version. Please update detector server!" << std::endl; - setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); - thisDetector->detectorControlAPIVersion = 0; - } else { - thisDetector->detectorControlAPIVersion = arg; - } - disconnectControl(); - } - if (ret!= FAIL) { - ret = FAIL; - - // stop port - if (connectStop() == OK){ - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->SendDataOnly(&arg,sizeof(arg)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret == FAIL) { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - cprintf(RED, "Detector returned error: (Stop Server) %s", mess); - if(strstr(mess,"Unrecognized Function")!=NULL) - std::cout << "The detector server is too old to get API version. Please update detector server!" << std::endl; - setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); - thisDetector->detectorStopAPIVersion = 0; - } else { - thisDetector->detectorStopAPIVersion = arg; - } - disconnectStop(); - } - } - } - } - - // receiver - else { - arg = APIRECEIVER; -#ifdef VERBOSE - std::cout<< std::endl<< "Checking version compatibility with receiver with value " << hex << arg << std::endl; -#endif - if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { - // data port - if (connectData() == OK){ - // ignoring retval - int64_t retval = -1; - ret=thisReceiver->sendInt(fnum,retval,arg); - if (ret==FAIL){ - setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); - if(strstr(mess,"Unrecognized Function")!=NULL) - std::cout << "The receiver software is too old to get API version. Please update receiver software!" << std::endl; - thisDetector->receiverAPIVersion = 0; - } else { - thisDetector->receiverAPIVersion = arg; - } - disconnectData(); - } - } - } - - return ret; -} diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 2cb9df900..e9cdd0ca3 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -1,418 +1,602 @@ - - - #ifndef SLS_DETECTOR_H #define SLS_DETECTOR_H +/** + * + * @short complete detector functionalities for a single module detector. + * The slsDetector class takes care of the communication with the + * detector and all kind actions related with a single detector controller + * @author Anna Bergamaschi + */ -#include "multiSlsDetector.h" #include "slsDetectorUtils.h" #include "energyConversion.h" #include "angleConversionConstant.h" #include "MySocketTCP.h" - #include "angleConversionConstant.h" -#include "receiverInterface.h" +class multiSlsDetector; +class SharedMemory; +class receiverInterface; -/** - * - * @short the slsDetector class takes care of the communication with the detector and all kind actions related with a single detector controller - * @author Anna Bergamaschi - * @version 0.1alpha - */ - +#define SLS_SHMVERSION 0x180620 #define NMODMAXX 24 #define NMODMAXY 24 #define NCHIPSMAX 10 #define NCHANSMAX 65536 #define NDACSMAX 16 - -/** - @short complete detector functionalities for a single module detector -*/ class slsDetector : public slsDetectorUtils, public energyConversion { +private: + /** + * @short structure allocated in shared memory to store detector settings for IPC and cache + */ + typedef struct sharedSlsDetector { + /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/ - public: - - /* /\** online flags enum \sa setOnline*\/ */ - /* enum {GET_ONLINE_FLAG=-1, /\**< returns wether the detector is in online or offline state *\/ */ - /* OFFLINE_FLAG=0, /\**< detector in offline state (i.e. no communication to the detector - using only local structure - no data acquisition possible!) *\/ */ - /* ONLINE_FLAG =1/\**< detector in online state (i.e. communication to the detector updating the local structure) *\/ */ - /* }; */ + /** shared memory version */ + int shmversion; + /** END OF FIXED PATTERN -----------------------------------------------*/ - /** - @short Structure allocated in shared memory to store detector settings. - - Structure allocated in shared memory to store detector settings and be accessed in parallel by several applications on the same machine (take care of possible conflicts, particularly if things are run on different machines!) - - */ - typedef struct sharedSlsDetector { - /** already existing flag. If the detector does not yet exist (alreadyExisting=0) the sharedMemory will be created, otherwise it will simly be linked */ - int alreadyExisting; - - - - - /** last process id accessing the shared memory */ - - pid_t lastPID; - - - - - /** online flag - is set if the detector is connected, unset if socket connection is not possible */ - int onlineFlag; - - - /** stopped flag - is set if an acquisition error occurs or the detector is stopped manually. Is reset to 0 at the start of the acquisition */ - int stoppedFlag; - - /** is the hostname (or IP address) of the detector. needs to be set before startin the communication */ - char hostname[MAX_STR_LENGTH]; - - /** is the port used for control functions normally it should not be changed*/ - int controlPort; - /** is the port used to stop the acquisition normally it should not be changed*/ - int stopPort; - - /** detector type \ see :: detectorType*/ - detectorType myDetectorType; - - - /** path of the trimbits/settings files */ - char settingsDir[MAX_STR_LENGTH]; - /** path of the calibration files */ - char calDir[MAX_STR_LENGTH]; - /** number of energies at which the detector has been trimmed (unused) */ - int nTrimEn; - /** list of the energies at which the detector has been trimmed (unused) */ - int trimEnergies[100]; - - - /** indicator for the acquisition progress - set to 0 at the beginning of the acquisition and incremented every time that the data are written to file */ - int progressIndex; - /** total number of frames to be acquired */ - int totalProgress; - - /** path of the output files */ - char filePath[MAX_STR_LENGTH]; - - /* size of the detector */ - - /** number of installed modules of the detector (x and y directions) */ - int nMod[2]; - /** number of modules ( nMod[X]*nMod[Y]) \see nMod */ - int nMods; - /** maximum number of modules of the detector (x and y directions) */ - int nModMax[2]; - /** maximum number of modules (nModMax[X]*nModMax[Y]) \see nModMax */ - int nModsMax; - /** number of channels per chip */ - int nChans; - /** number of channels per chip in one direction */ - int nChan[2]; - /** number of chips per module*/ - int nChips; - /** number of chips per module in one direction */ - int nChip[2]; - /** number of dacs per module*/ - int nDacs; - /** number of adcs per module */ - int nAdcs; - /** number of extra gain values*/ - int nGain; - /** number of extra offset values */ - int nOffset; - /** dynamic range of the detector data */ - int dynamicRange; - /** size of the data that are transfered from the detector */ - int dataBytes; - - - - /** corrections to be applied to the data \see ::correctionFlags */ - int correctionMask; - /** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */ - int threadedProcessing; - /** dead time (in ns) for rate corrections */ - double tDead; - /** directory where the flat field files are stored */ - char flatFieldDir[MAX_STR_LENGTH]; - /** file used for flat field corrections */ - char flatFieldFile[MAX_STR_LENGTH]; - /** number of bad channels from bad channel list */ - int nBadChans; - /** file with the bad channels */ - char badChanFile[MAX_STR_LENGTH]; - /** list of bad channels */ - int badChansList[MAX_BADCHANS]; - /** number of bad channels from flat field i.e. channels which read 0 in the flat field file */ - int nBadFF; - /** list of bad channels from flat field i.e. channels which read 0 in the flat field file */ - int badFFList[MAX_BADCHANS]; - - /** file with the angular conversion factors */ - char angConvFile[MAX_STR_LENGTH]; - /** array of angular conversion constants for each module \see ::angleConversionConstant */ - angleConversionConstant angOff[MAXMODS]; - /** angular direction (1 if it corresponds to the encoder direction i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */ - int angDirection; - /** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */ - double fineOffset; - /** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */ - double globalOffset; - /** number of positions at which the detector should acquire */ - int numberOfPositions; - /** list of encoder positions at which the detector should acquire */ - double detPositions[MAXPOS]; - /** bin size for data merging */ - double binSize; - /** add encoder value flag (i.e. wether the detector is moving - 1 - or stationary - 0) */ - int moveFlag; - - - /* infos necessary for the readout to determine the size of the data */ - - /** number of rois defined */ - int nROI; - /** list of rois */ - ROI roiLimits[MAX_ROIS]; - - /** readout flags */ - readOutFlags roFlags; - - - /* detector setup - not needed */ - /** name root of the output files */ - char settingsFile[MAX_STR_LENGTH]; - /** detector settings (standard, fast, etc.) */ - detectorSettings currentSettings; - /** detector threshold (eV) */ - int currentThresholdEV; - /** timer values */ - int64_t timerValue[MAX_TIMERS]; - /** clock divider */ - //int clkDiv; - - - /** Scans and scripts */ - ////////////////////////// only in the multi detector class?!?!?!? additional shared memory class?!?!?!? - int actionMask; - - mystring actionScript[MAX_ACTIONS]; - - mystring actionParameter[MAX_ACTIONS]; - - - int scanMode[MAX_SCAN_LEVELS]; - mystring scanScript[MAX_SCAN_LEVELS]; - mystring scanParameter[MAX_SCAN_LEVELS]; - int nScanSteps[MAX_SCAN_LEVELS]; - mysteps scanSteps[MAX_SCAN_LEVELS]; - int scanPrecision[MAX_SCAN_LEVELS]; - - //////////////////////////////////////////////////////////////////////////////////////////////// - - - /*offsets*/ - /** memory offsets for the flat field coefficients */ - int ffoff; - /** memory offsets for the flat filed coefficient errors */ - int fferroff; - /** memory offsets for the module structures */ - int modoff; - /** memory offsets for the dac arrays */ - int dacoff; - /** memory offsets for the adc arrays */ - int adcoff; - /** memory offsets for the chip register arrays */ - int chipoff; - /** memory offsets for the channel register arrays -trimbits*/ - int chanoff; - /** memory offsets for the gain register arrays */ - int gainoff; - /** memory offsets for the offset register arrays -trimbits*/ - int offsetoff; - - - /* receiver*/ - /** ip address/hostname of the receiver for the client to connect to**/ - char receiver_hostname[MAX_STR_LENGTH]; - /** is the port used to communicate between client and the receiver*/ - int receiverTCPPort; - /** is the port used to communicate between detector and the receiver*/ - int receiverUDPPort; - /** is the port used to communicate between second half module of Eiger detector and the receiver*/ - int receiverUDPPort2; - /** ip address of the receiver for the detector to send packets to**/ - char receiverUDPIP[MAX_STR_LENGTH]; - /** mac address of receiver for the detector to send packets to **/ - char receiverUDPMAC[MAX_STR_LENGTH]; - /** mac address of the detector **/ - char detectorMAC[MAX_STR_LENGTH]; - /** ip address of the detector **/ - char detectorIP[MAX_STR_LENGTH]; - /** online flag - is set if the receiver is connected, unset if socket connection is not possible */ - int receiverOnlineFlag; - - /** 10 Gbe enable*/ - int tenGigaEnable; - - /** flipped data across x or y axis */ - int flippedData[2]; - /** tcp port from gui/different process to receiver (only data) */ - int zmqport; - /** tcp port from receiver to gui/different process (only data) */ - int receiver_zmqport; - /** data streaming (up stream) enable in receiver */ - bool receiver_upstream; - /* Receiver read frequency */ - int receiver_read_freq; - /** zmq tcp src ip address in client (only data) **/ - char zmqip[MAX_STR_LENGTH]; - /** zmq tcp src ip address in receiver (only data) **/ - char receiver_zmqip[MAX_STR_LENGTH]; - /** gap pixels enable */ - int gappixels; - /** gap pixels in each direction */ - int nGappixels[2]; - /** data bytes including gap pixels */ - int dataBytesInclGapPixels; - /** additional json header */ - char receiver_additionalJsonHeader[MAX_STR_LENGTH]; - /** frames per file in receiver */ - int receiver_framesPerFile; - - /** detector control server software API version */ - int64_t detectorControlAPIVersion; - /** detector stop server software API version */ - int64_t detectorStopAPIVersion; - /** receiver server software API version */ - int64_t receiverAPIVersion; - - - } sharedSlsDetector; - - - - - - - - using slsDetectorUtils::getDetectorType; - - using postProcessing::flatFieldCorrect; - using postProcessing::rateCorrect; - using postProcessing::setBadChannelCorrection; - - using angularConversion::readAngularConversion; - using angularConversion::writeAngularConversion; - - using slsDetectorUtils::getAngularConversion; - string getDetectorType(){return sgetDetectorsType();}; + /** online flag - is set if the detector is connected, unset if socket + * connection is not possible */ + int onlineFlag; + /** stopped flag - is set if an acquisition error occurs or the detector + * is stopped manually. Is reset to 0 at the start of the acquisition */ + int stoppedFlag; + /** is the hostname (or IP address) of the detector. needs to be set + * before starting the communication */ + char hostname[MAX_STR_LENGTH]; - /** (default) constructor - \param type is needed to define the size of the detector shared memory 9defaults to GENERIC i.e. the largest shared memory needed by any slsDetector is allocated - \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently - \param pos is the index of object in the parent multislsdet array - \param p is the parent multislsdet to access filename ,path etc + /** is the port used for control functions */ + int controlPort; - */ + /** is the port used to stop the acquisition */ + int stopPort; - slsDetector(int pos, detectorType type=GENERIC, int id=0, multiSlsDetector *p=NULL); + /** detector type \ see :: detectorType*/ + detectorType myDetectorType; - /** constructor - \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently - \param pos is the index of object in the parent multislsdet array - \param p is the parent multislsdet to access filename ,path etc - */ - slsDetector(int pos, int id, multiSlsDetector *p=NULL); + /** path of the trimbits/settings files */ + char settingsDir[MAX_STR_LENGTH]; + /** path of the calibration files */ + char calDir[MAX_STR_LENGTH]; - slsDetector(int pos, char *name, int id=0, int cport=DEFAULT_PORTNO, multiSlsDetector *p=NULL); - //slsDetector(string const fname); - // ~slsDetector(){while(dataQueue.size()>0){}}; - /** destructor */ - virtual ~slsDetector(); + /** number of energies at which the detector has been trimmed */ + int nTrimEn; - /** - * returns true. Used when reference is slsDetectorUtils and to determine if command can be implemented as slsDetector/multiSlsDetector object/ - */ - bool isMultiSlsDetectorClass(){return 0;}; + /** list of the energies at which the detector has been trimmed */ + int trimEnergies[100]; - int setOnline(int const online=GET_ONLINE_FLAG); - - string checkOnline(); + /** indicator for the acquisition progress - set to 0 at the beginning + * of the acquisition and incremented when each frame is processed */ + int progressIndex; - /** @short activates the detector (detector specific) - \param enable can be: -1 returns wether the detector is in active (1) or inactive (0) state - \returns 0 (inactive) or 1 (active) - */ - int activate(int const enable=GET_ONLINE_FLAG); + /** total number of frames to be acquired */ + int totalProgress; + /** path of the output files */ + char filePath[MAX_STR_LENGTH]; - /** returns if the detector already existed - \returns 1 if the detector structure has already be initlialized, 0 otherwise */ - int exists() {return thisDetector->alreadyExisting;}; - - /** returns 1 if the detetcor with id has already been allocated and initialized in shared memory - \param detector id - \returns 1 if the detector structure has already be initlialized, 0 otherwise */ - static int exists(int id); + /** number of installed modules of the detector (x and y directions) */ + int nMod[2]; - /** - configures mac for gotthard, moench readout - \returns OK or FAIL - */ - int configureMAC(); + /** number of modules ( nMod[X]*nMod[Y]) \see nMod */ + int nMods; - /** - Prints receiver configuration - \returns OK or FAIL - */ - int printReceiverConfiguration(); + /** maximum number of modules of the detector (x and y directions) */ + int nModMax[2]; - /** - Reads the configuration file fname - \param fname file name - \returns OK or FAIL - */ - int readConfigurationFile(string const fname); + /** maximum number of modules (nModMax[X]*nModMax[Y]) \see nModMax */ + int nModsMax; - - int readConfigurationFile(ifstream &infile); + /** number of channels per chip */ + int nChans; + /** number of channels per chip in one direction */ + int nChan[2]; - - /** + /** number of chips per module*/ + int nChips; - Writes the configuration file fname - \param fname file name - \returns OK or FAIL + /** number of chips per module in one direction */ + int nChip[2]; - */ - int writeConfigurationFile(string const fname); - int writeConfigurationFile(ofstream &outfile, int id=-1); + /** number of dacs per module*/ + int nDacs; + /** number of adcs per module */ + int nAdcs; + /** number of extra gain values*/ + int nGain; + /** number of extra offset values */ + int nOffset; + /** dynamic range of the detector data */ + int dynamicRange; + /** size of the data that are transfered from the detector */ + int dataBytes; + /** corrections to be applied to the data \see ::correctionFlags */ + int correctionMask; + /** threaded processing flag + * (i.e. if data are processed in a separate thread) */ + int threadedProcessing; - /** + /** dead time (in ns) for rate corrections */ + double tDead; + + /** directory where the flat field files are stored */ + char flatFieldDir[MAX_STR_LENGTH]; + + /** file used for flat field corrections */ + char flatFieldFile[MAX_STR_LENGTH]; + + /** number of bad channels from bad channel list */ + int nBadChans; + + /** file with the bad channels */ + char badChanFile[MAX_STR_LENGTH]; + + /** list of bad channels */ + int badChansList[MAX_BADCHANS]; + + /** number of bad channels from flat field + * i.e. channels which read 0 in the flat field file */ + int nBadFF; + + /** list of bad channels from flat field + * i.e. channels which read 0 in the flat field file */ + int badFFList[MAX_BADCHANS]; + + /** file with the angular conversion factors */ + char angConvFile[MAX_STR_LENGTH]; + + /** array of angular conversion constants for each module + * \see ::angleConversionConstant */ + angleConversionConstant angOff[MAXMODS]; + + /** angular direction (1 if it corresponds to the encoder direction + * i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */ + int angDirection; + + /** beamline fine offset (of the order of mdeg, + * might be adjusted for each measurements) */ + double fineOffset; + + /** beamline offset (might be a few degrees beacuse of encoder offset - + * normally it is kept fixed for a long period of time) */ + double globalOffset; + + /** number of positions at which the detector should acquire */ + int numberOfPositions; + + /** list of encoder positions at which the detector should acquire */ + double detPositions[MAXPOS]; + + /** bin size for data merging */ + double binSize; + + /** add encoder value flag (i.e. wether the detector is + * moving - 1 - or stationary - 0) */ + int moveFlag; + + /** number of rois defined */ + int nROI; + + /** list of rois */ + ROI roiLimits[MAX_ROIS]; + + /** readout flags */ + readOutFlags roFlags; + + /** name root of the output files */ + char settingsFile[MAX_STR_LENGTH]; + + /** detector settings (standard, fast, etc.) */ + detectorSettings currentSettings; + + /** detector threshold (eV) */ + int currentThresholdEV; + + /** timer values */ + int64_t timerValue[MAX_TIMERS]; + + /** action mask */ + int actionMask; + + /** action script */ + mystring actionScript[MAX_ACTIONS]; + + /** action parameter */ + mystring actionParameter[MAX_ACTIONS]; + + /** scan mode */ + int scanMode[MAX_SCAN_LEVELS]; + + /** scan script */ + mystring scanScript[MAX_SCAN_LEVELS]; + + /** scan parameter */ + mystring scanParameter[MAX_SCAN_LEVELS]; + + /** n scan steps */ + int nScanSteps[MAX_SCAN_LEVELS]; + + /** scan steps */ + mysteps scanSteps[MAX_SCAN_LEVELS]; + + /** scan precision */ + int scanPrecision[MAX_SCAN_LEVELS]; + + /** memory offsets for the flat field coefficients */ + int ffoff; + + /** memory offsets for the flat filed coefficient errors */ + int fferroff; + + /** memory offsets for the module structures */ + int modoff; + + /** memory offsets for the dac arrays */ + int dacoff; + + /** memory offsets for the adc arrays */ + int adcoff; + + /** memory offsets for the chip register arrays */ + int chipoff; + + /** memory offsets for the channel register arrays -trimbits*/ + int chanoff; + + /** memory offsets for the gain register arrays */ + int gainoff; + + /** memory offsets for the offset register arrays -trimbits*/ + int offsetoff; + + /** ip address/hostname of the receiver for client control via TCP */ + char receiver_hostname[MAX_STR_LENGTH]; + + /** is the TCP port used to communicate between client and the receiver */ + int receiverTCPPort; + + /** is the UDP port used to send data from detector to receiver */ + int receiverUDPPort; + + /** is the port used to communicate between second half module of + * Eiger detector and the receiver*/ + int receiverUDPPort2; + + /** ip address of the receiver for the detector to send packets to**/ + char receiverUDPIP[MAX_STR_LENGTH]; + + /** mac address of receiver for the detector to send packets to **/ + char receiverUDPMAC[MAX_STR_LENGTH]; + + /** mac address of the detector **/ + char detectorMAC[MAX_STR_LENGTH]; + + /** ip address of the detector **/ + char detectorIP[MAX_STR_LENGTH]; + + /** online flag - is set if the receiver is connected, + * unset if socket connection is not possible */ + int receiverOnlineFlag; + + /** 10 Gbe enable*/ + int tenGigaEnable; + + /** flipped data across x or y axis */ + int flippedData[2]; + + /** tcp port from gui/different process to receiver (only data) */ + int zmqport; + + /** tcp port from receiver to gui/different process (only data) */ + int receiver_zmqport; + + /** data streaming (up stream) enable in receiver */ + bool receiver_upstream; + + /* Receiver read frequency */ + int receiver_read_freq; + + /** zmq tcp src ip address in client (only data) **/ + char zmqip[MAX_STR_LENGTH]; + + /** zmq tcp src ip address in receiver (only data) **/ + char receiver_zmqip[MAX_STR_LENGTH]; + + /** gap pixels enable */ + int gappixels; + + /** gap pixels in each direction */ + int nGappixels[2]; + + /** data bytes including gap pixels */ + int dataBytesInclGapPixels; + + /** additional json header */ + char receiver_additionalJsonHeader[MAX_STR_LENGTH]; + + /** frames per file in receiver */ + int receiver_framesPerFile; + + /** detector control server software API version */ + int64_t detectorControlAPIVersion; + + /** detector stop server software API version */ + int64_t detectorStopAPIVersion; + + /** receiver server software API version */ + int64_t receiverAPIVersion; + + } sharedSlsDetector; + + + + + +public: + + using slsDetectorUtils::getDetectorType; + using postProcessing::flatFieldCorrect; + using postProcessing::rateCorrect; + using postProcessing::setBadChannelCorrection; + using angularConversion::readAngularConversion; + using angularConversion::writeAngularConversion; + using slsDetectorUtils::getAngularConversion; + + + /** + * Constructor called when creating new shared memory + * @param type detector type + * @param multiId multi detector shared memory id + * @param id sls detector id (position in detectors list) + * @param verify true to verify if shared memory version matches existing one + * @param m multiSlsDetector reference + */ + slsDetector(detectorType type, int multiId = 0, int id = 0, bool verify = true, MultiDet* m = NULL); + + /** + * Constructor called when opening existing shared memory + * @param multiId multi detector shared memory id + * @param id sls detector id (position in detectors list) + * @param verify true to verify if shared memory version matches existing one + * @param m multiSlsDetector reference + */ + slsDetector(int multiId = 0, int id = 0, bool verify = true, MultiDet* m = NULL); + + /** + * Destructor + */ + virtual ~slsDetector(); + + /** + * returns false. Used when reference is slsDetectorUtils and to determine + * if command can be implemented as slsDetector/multiSlsDetector object/ + */ + bool isMultiSlsDetectorClass(); + + /** + * Decode data from the detector converting them to an array of doubles, + * one for each channel (Mythen only) + * @param datain data from the detector + * @param nn size of datain array + * @param fdata double array of decoded data + * @returns pointer to a double array with a data per channel + */ + double* decodeData(int *datain, int &nn, double *fdata=NULL); + + /** + * Clears error mask and also the bit in parent det multi error mask + * @returns error mask + */ + int64_t clearAllErrorMask(); + + /** + * Set acquiring flag in shared memory + * @param b acquiring flag + */ + void setAcquiringFlag(bool b=false); + + /** + * Get acquiring flag from shared memory + * @returns acquiring flag + */ + bool getAcquiringFlag(); + + /** + * Check if acquiring flag is set, set error if set + * @returns FAIL if not ready, OK if ready + */ + bool isAcquireReady(); + + /** + * Check version compatibility with detector/receiver software + * (if hostname/rx_hostname has been set/ sockets created) + * @param p port type control port or receiver port + * @returns FAIL for incompatibility, OK for compatibility + */ + int checkVersionCompatibility(portType t); + + /** + * Get ID or version numbers + * @param mode version type + * @param imod module number in entire module list (gets decoded) (-1 for all) + * @returns Id or version number of that type + */ + int64_t getId(idMode mode, int imod=0); + + /** + * Free shared memory without creating objects + * If this is called, must take care to update + * multiSlsDetectors thisMultiDetector->numberofDetectors + * avoiding creating the constructor classes and mapping + * @param multiId multi detector Id + * @param slsId slsDetectorId or position of slsDetector in detectors list + */ + static void freeSharedMemory(int multiId, int slsId); + + /** + * Free shared memory and delete shared memory structure + * occupied by the sharedSlsDetector structure + * If this is called, must take care to update + * multiSlsDetectors thisMultiDetector->numberofDetectors + * and not use this object again (delete and start anew) + */ + void freeSharedMemory(); + + + + /** returns the detector hostname \sa sharedSlsDetector */ + string setHostname(const char *name); + + + /** returns the detector hostname \sa sharedSlsDetector */ + string getHostname(); + + + /** + returns the detector type from hostname and controlport + \param + \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) + */ + static detectorType getDetectorType(const char *name, int cport=DEFAULT_PORTNO); + + + + + /** + sets/gets detector type + normally the detector knows what type of detector it is + \param type is the detector type (defaults to GET_DETECTOR_TYPE) + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) + */ + int setDetectorType(detectorType type=GET_DETECTOR_TYPE); + + /** + sets/gets detector type + normally the detector knows what type of detector it is + \param type is the detector type ("Mythen", "Pilatus", "XFS", "Gotthard", Agipd", "Mönch") + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) + */ + int setDetectorType(string type); + + /** + gets detector type + normally the detector knows what type of detector it is + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH,-1 command failed) + */ + detectorType getDetectorsType(int pos=-1); + + detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorsType(pos);}; + + string sgetDetectorsType(int pos=-1){return getDetectorType(getDetectorsType(pos));}; + + string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(getDetectorsType(pos));}; + string ssetDetectorsType(string t, int pos=-1){return getDetectorType(getDetectorsType(pos));} + + string getDetectorType(){return sgetDetectorsType();}; + + + + + /** + returns the detector type from hostname and controlport + \param + \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) + */ + static detectorType getDetectorType(int id); + + + + + /** Returns the number of modules (without connecting to the detector) */ + int getNMods(){return thisDetector->nMods;}; // + + /** Returns the number of modules in direction d (without connecting to the detector) */ + int getNMod(dimension d){return thisDetector->nMod[d];}; // + + + /** Returns the number of modules (without connecting to the detector) */ + int getMaxMods(){return thisDetector->nModsMax;}; // + + /** Returns the max number of modules in direction d (without connecting to the detector) */ + int getNMaxMod(dimension d){return thisDetector->nModMax[d];}; // + + /** + get the maximum size of the detector + \param d dimension + \returns maximum number of modules that can be installed in direction d + */ + int getMaxNumberOfModules(dimension d=X); // + + + /** + set/get the size of the detector + \param n number of modules + \param d dimension + \returns current number of modules in direction d + */ + int setNumberOfModules(int n=GET_FLAG, dimension d=X); // if n=GET_FLAG returns the number of installed modules + + + int getChansPerMod(int imod=0){return thisDetector->nChans*thisDetector->nChips;}; + + int getChansPerMod( dimension d,int imod=0){return thisDetector->nChan[d]*thisDetector->nChip[d];}; + + + int getTotalNumberOfChannels(); + //{return thisDetector->nChans*thisDetector->nChips*thisDetector->nMods;}; + + int getTotalNumberOfChannels(dimension d); + //{return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nMod[d];}; + + int getTotalNumberOfChannelsInclGapPixels(dimension d); + + + int getMaxNumberOfChannels();//{return thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax;}; + + int getMaxNumberOfChannels(dimension d);//{return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nModMax[d];}; + + int getMaxNumberOfChannelsInclGapPixels(dimension d); + + + + /** Returns the number of channels per chip (without connecting to the detector) */ + int getNChans(){return thisDetector->nChans;}; // + + /** Returns the number of channels per chip (without connecting to the detector) in one direction */ + int getNChans(dimension d){return thisDetector->nChan[d];}; // + + /** Returns the number of chips per module (without connecting to the detector) */ + int getNChips(){return thisDetector->nChips;}; // + + /** Returns the number of chips per module (without connecting to the detector) */ + int getNChips(dimension d){return thisDetector->nChip[d];}; // + + int setOnline(int const online=GET_ONLINE_FLAG); + + string checkOnline(); + + /** configure the socket communication and initializes the socket instances \param name hostname - if "" the current hostname is used @@ -421,107 +605,635 @@ class slsDetector : public slsDetectorUtils, public energyConversion { \returns OK is connection succeded, FAIL otherwise \sa sharedSlsDetector - */ - int setTCPSocket(string const name="", int const control_port=-1, int const stop_port=-1); + */ + int setTCPSocket(string const name="", int const control_port=-1, int const stop_port=-1); - /** + + /** changes/gets the port number \param type port type \param num new port number (-1 gets) \returns actual port number - */ - int setPort(portType type, int num=-1); - - /** returns the detector control port \sa sharedSlsDetector */ - int getControlPort() {return thisDetector->controlPort;}; - /** returns the detector stop port \sa sharedSlsDetector */ - int getStopPort() {return thisDetector->stopPort;}; - /** returns the receiver port \sa sharedSlsDetector */ - int getReceiverPort() {return thisDetector->receiverTCPPort;}; - - /** Locks/Unlocks the connection to the server + */ + int setPort(portType type, int num=-1); + + /** returns the detector control port \sa sharedSlsDetector */ + int getControlPort() {return thisDetector->controlPort;}; + /** returns the detector stop port \sa sharedSlsDetector */ + int getStopPort() {return thisDetector->stopPort;}; + /** returns the receiver port \sa sharedSlsDetector */ + int getReceiverPort() {return thisDetector->receiverTCPPort;}; + + + + /** Locks/Unlocks the connection to the server /param lock sets (1), usets (0), gets (-1) the lock /returns lock status of the server - */ - int lockServer(int lock=-1); + */ + int lockServer(int lock=-1); - /** + /** Returns the IP of the last client connecting to the detector - */ - string getLastClientIP(); + */ + string getLastClientIP(); + /** + turns off server + */ + int exitServer(); - /** returns the detector hostname \sa sharedSlsDetector */ - string getHostname(int ipos=-1) {return string(thisDetector->hostname);}; - /** returns the detector hostname \sa sharedSlsDetector */ - string setHostname(const char *name, int ipos=-1) {setTCPSocket(string(name)); return string(thisDetector->hostname);}; - /** connect to the control port */ - int connectControl(); - /** disconnect from the control port */ - int disconnectControl(); + /** + executes a system command on the server + e.g. mount an nfs disk, reboot and returns answer etc. + \param cmd is the command to be executed + \param answer is the answer from the detector + \returns OK or FAIL depending on the command outcome + */ + int execCommand(string cmd, string answer); - /** connect to the receiver port */ - int connectData(); - /** disconnect from the receiver port */ - int disconnectData(); + /** + updates the shared memory receiving the data from the detector (without asking and closing the connection + /returns OK + */ + int updateDetectorNoWait(); - /** connect to the stop port */ - int connectStop(); - /** disconnect from the stop port */ - int disconnectStop(); + /** + updates the shared memory receiving the data from the detector + /returns OK - /** + */ + int updateDetector(); + + + /** connect to the control port */ + int connectControl(); + /** disconnect from the control port */ + int disconnectControl(); + + /** connect to the receiver port */ + int connectData(); + /** disconnect from the receiver port */ + int disconnectData(); + + /** connect to the stop port */ + int connectStop(); + /** disconnect from the stop port */ + int disconnectStop(); + + /** Allocates the memory for a sls_detector_module structure and initializes it + \returns myMod the pointer to the allocate dmemory location + + */ + sls_detector_module* createModule(){return createModule(thisDetector->myDetectorType);}; + + + /** Allocates the memory for a sls_detector_module structure and initializes it + \returns myMod the pointer to the allocate dmemory location + + */ + sls_detector_module* createModule(detectorType myDetectorType); + + /** frees the memory for a sls_detector_module structure + \param myMod the pointer to the memory to be freed + + */ + + void deleteModule(sls_detector_module *myMod); + + /** + Reads the configuration file fname + \param fname file name + \returns OK or FAIL + */ + int readConfigurationFile(string const fname); + + + int readConfigurationFile(ifstream &infile); + + + /** + + Writes the configuration file fname + \param fname file name + \returns OK or FAIL + + */ + int writeConfigurationFile(string const fname); + int writeConfigurationFile(ofstream &outfile, int id=-1); + + + /** + returns currently the loaded trimfile/settingsfile name + */ + string getSettingsFile(){\ + string s(thisDetector->settingsFile); \ + if (s.length()>6) {\ + if (s.substr(s.length()-6,3)==string(".sn") && s.substr(s.length()-3)!=string("xxx") ) \ + return s.substr(0,s.length()-6); \ + } \ + return string(thisDetector->settingsFile);\ + }; + + + /** + writes a trim/settings file for module number imod - the values will be read from the current detector structure + \param fname name of the file to be written + \param imod module number + \param iodelay io delay (detector specific) + \param tau tau (detector specific) + \returns OK or FAIL if the file could not be written + \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int) + */ + using energyConversion::writeSettingsFile; + int writeSettingsFile(string fname, int imod, int iodelay, int tau); + + + + /** + get detector settings + \param imod module number (-1 all) + \returns current settings detectorSettings sendSettingsOnly(detectorSettings isettings); + */ + detectorSettings getSettings(int imod=-1); + + /** + set detector settings + \param isettings settings + \param imod module number (-1 all) + \returns current settings + + in this function trimbits/settings and calibration files are searched in the settingsDir and calDir directories and the detector is initialized + */ + detectorSettings setSettings(detectorSettings isettings, int imod=-1); + + + + /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ + std::string getSettingsDir() {return std::string(thisDetector->settingsDir);}; + /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ + std::string setSettingsDir(string s) {sprintf(thisDetector->settingsDir, s.c_str()); return thisDetector->settingsDir;}; + + + + /** + returns the location of the calibration files + \sa sharedSlsDetector + */ + std::string getCalDir() {return thisDetector->calDir;}; + /** + sets the location of the calibration files + \sa sharedSlsDetector + */ + std::string setCalDir(string s) {sprintf(thisDetector->calDir, s.c_str()); return thisDetector->calDir;}; + + /** loads the modules settings/trimbits reading from a file + \param fname file name . If not specified, extension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int loadSettingsFile(string fname, int imod=-1); + + + /** saves the modules settings/trimbits writing to a file + \param fname file name . Axtension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int saveSettingsFile(string fname, int imod=-1); + + + /** loads the modules calibration data reading from a file + \param fname file name . If not specified, extension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int loadCalibrationFile(string fname, int imod=-1); + + + /** saves the modules calibration data writing to a file + \param fname file name . Axtension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int saveCalibrationFile(string fname, int imod=-1); + + + /** returns if the detector is Master, slave or nothing + \param flag can be GET_MASTER, NO_MASTER, IS_MASTER, IS_SLAVE + \returns master flag of the detector + */ + masterFlags setMaster(masterFlags flag); + + + /** + Sets/gets the synchronization mode of the various detectors + \param sync syncronization mode can be GET_SYNCHRONIZATION_MODE, NONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS + \returns current syncronization mode + */ + synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); + + /** calcualtes the total number of steps of the acquisition. + called when number of frames, number of cycles, number of positions and scan steps change + */ + int setTotalProgress(); + + /** returns the current progress in % */ + double getCurrentProgress(); + + runStatus getRunStatus(); + + /** + prepares detector for acquisition + \returns OK/FAIL + */ + int prepareAcquisition(); + + /** + prepares detector for acquisition + \returns OK/FAIL + */ + int cleanupAcquisition(); + + /** + start detector acquisition + \returns OK/FAIL + */ + int startAcquisition(); + + /** + stop detector acquisition + \returns OK/FAIL + */ + int stopAcquisition(); + + /** + start readout (without exposure or interrupting exposure) + \returns OK/FAIL + */ + int startReadOut(); + + /** + start detector acquisition and read all data putting them a data queue + \returns pointer to the front of the data queue + \sa startAndReadAllNoWait getDataFromDetector dataQueue + */ + int* startAndReadAll(); + + + /** + start detector acquisition and read out, but does not read data from socket leaving socket opened + \returns OK or FAIL + + */ + int startAndReadAllNoWait(); + + /** + Receives a data frame from the detector socket + \returns pointer to the data (or NULL if failed) + + */ + int* getDataFromDetector(int *retval=NULL); + + /** + asks and receives a data frame from the detector and puts it in the data queue + \returns pointer to the data or NULL. + \sa getDataFromDetector + */ + int* readFrame(); + + /** + asks and receives all data from the detector and puts them in a data queue + \returns pointer to the front of the queue or NULL. + \sa getDataFromDetector dataQueue + */ + int* readAll(); + + /** + asks and receives all data from the detector and leaves the socket opened + \returns OK or FAIL + */ + int readAllNoWait(); + + /** + configures mac for gotthard, moench readout + \returns OK or FAIL + */ + int configureMAC(); + + /** + get threshold energy + \param imod module number (-1 all) + \returns current threshold value for imod in ev (-1 failed) + */ + int getThresholdEnergy(int imod=-1); + + + /** + set threshold energy + \param e_eV threshold in eV + \param imod module number (-1 all) + \param isettings ev. change settings + \param tb 1 to include trimbits, 0 to exclude + \returns current threshold value for imod in ev (-1 failed) + */ + int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS, int tb=1); + + /** + set threshold energy + \param e_eV threshold in eV + \param isettings ev. change settings + \param tb 1 to include trimbits, 0 to exclude + \returns OK if successful, else FAIL + */ + int setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb=1); + + + /** + send detector settings only (set only for Jungfrau, Gotthard, Moench, get for all) + \param isettings settings + \param imod module number (-1 all) + \returns current settings + + in this function only the settings is sent to the detector, where it will initialize all the dacs already stored in the detector server. + */ + detectorSettings sendSettingsOnly(detectorSettings isettings, int imod=-1); + + + + /** + set/get timer value + \param index timer index + \param t time in ns or number of...(e.g. frames, gates, probes) + \returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t setTimer(timerIndex index, int64_t t=-1); + + /** + get current timer value + \param index timer index + \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t getTimeLeft(timerIndex index); + + /** sets/gets the value of important readout speed parameters + \param sp is the parameter to be set/get + \param value is the value to be set, if -1 get value + \returns current value for the specified parameter + \sa speedVariable + */ + int setSpeed(speedVariable sp, int value=-1); + + // Flags + /** + set/get dynamic range + \param n dynamic range (-1 get) + \returns current dynamic range + updates the size of the data expected from the detector + \sa sharedSlsDetector + */ + int setDynamicRange(int n=-1); + + /** + set/get dynamic range + \returns number of bytes sent by the detector + \sa sharedSlsDetector + */ + int getDataBytes(){return thisDetector->dataBytes;}; + + /** + * returns number of bytes sent by detector including gap pixels + * \sa sharedSlsDetector + */ + int getDataBytesInclGapPixels(){return thisDetector->dataBytesInclGapPixels;}; + + /** + set dacs value + \param val value (in V) + \param index DAC index + \param mV 0 in dac units or 1 in mV + \param imod module number (if -1 alla modules) + \returns current DAC value + */ + dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); + + /** + set dacs value + \param index ADC index + \param imod module number + \returns current ADC value (temperature for eiger and jungfrau in millidegrees) + */ + dacs_t getADC(dacIndex index, int imod=0); + /** + set/get the external communication mode + + obsolete \sa setExternalSignalFlags + \param pol value to be set \sa externalCommunicationMode + \returns current external communication mode + */ + externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); + + /** + set/get the use of an external signal + \param pol meaning of the signal \sa externalSignalFlag + \param signalIndex index of the signal + \returns current meaning of signal signalIndex + */ + externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); + + /** + set/get readout flags + \param flag readout flag to be set + \returns current flag + */ + int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); + + /** + write register + \param addr address + \val value + \returns current register value + + */ + uint32_t writeRegister(uint32_t addr, uint32_t val); + + /** + read register + \param addr address + \returns current register value + + */ + uint32_t readRegister(uint32_t addr); + + /** + sets a bit in a register + \param addr address + \param n nth bit ranging from 0 to 31 + \returns current register value + + DO NOT USE!!! ONLY EXPERT USER!!! + */ + uint32_t setBit(uint32_t addr, int n); + + + /** + clear a bit in a register + \param addr address + \param n nth bit ranging from 0 to 31 + \returns current register value + + DO NOT USE!!! ONLY EXPERT USER!!! + */ + uint32_t clearBit(uint32_t addr, int n); + + /** sets the network parameters must restart streaming in client/receiver if to do with zmq after calling this function \param i network parameter type \param s value to be set \returns parameter - */ - string setNetworkParameter(networkParameter index, string value); + */ + string setNetworkParameter(networkParameter index, string value); - /** + /** gets the network parameters \param i network parameter type can be RECEIVER_IP, RECEIVER_MAC, SERVER_MAC \returns parameter - */ - string getNetworkParameter(networkParameter index); + */ + string getNetworkParameter(networkParameter index); - /* I/O */ - - /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ - std::string getSettingsDir() {return std::string(thisDetector->settingsDir);}; - /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ - std::string setSettingsDir(string s) {sprintf(thisDetector->settingsDir, s.c_str()); return thisDetector->settingsDir;}; + /** + Digital test of the modules + \param mode test mode + \param imod module number for chip test or module firmware test + \returns OK or error mask + */ + int digitalTest(digitalTestMode mode, int imod=0); + /** + execute trimming + \param mode trim mode + \param par1 if noise, beam or fixed setting trimming it is count limit, if improve maximum number of iterations + \param par2 if noise or beam nsigma, if improve par2!=means vthreshold will be optimized, if fixed settings par2<0 trimwith median, par2>=0 trim with level + \param imod module number (-1 all) + \returns OK or FAIl (FAIL also if some channel are 0 or 63 + */ + int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); + /** + Loads dark image or gain image from a file and sends it to the detector + \param index is 0 for dark image and 1 for gain image + \param fname file name to load data from - /** - returns the location of the calibration files - \sa sharedSlsDetector - */ - std::string getCalDir() {return thisDetector->calDir;}; - /** - sets the location of the calibration files - \sa sharedSlsDetector - */ - std::string setCalDir(string s) {sprintf(thisDetector->calDir, s.c_str()); return thisDetector->calDir;}; + */ + int loadImageToDetector(imageType index,string const fname); + + /** + Called from loadImageToDetector to send the image to detector + \param index is 0 for dark image and 1 for gain image + \param arg image + + */ + int sendImageToDetector(imageType index,short int imageVals[]); + + /** + writes the counter memory block from the detector + \param startACQ is 1 to start acquisition after reading counter + \param fname file name to load data from + \returns OK or FAIL + */ + int writeCounterBlockFile(string const fname,int startACQ=0); - - /** returns the number of trim energies and their value \sa sharedSlsDetector - \param point to the array that will contain the trim energies (in ev) - \returns number of trim energies + /** + gets counter memory block in detector + \param startACQ is 1 to start acquisition after reading counter + \param arg counter memory block from detector + \returns OK or FAIL + */ + int getCounterBlock(short int arg[],int startACQ=0); - unused! + /** + Resets counter in detector + \param startACQ is 1 to start acquisition after resetting counter + \returns OK or FAIL + */ + int resetCounterBlock(int startACQ=0); - \sa sharedSlsDetector - */ - int getTrimEn(int *en=NULL) {if (en) {for (int ien=0; iennTrimEn; ien++) en[ien]=thisDetector->trimEnergies[ien];} return (thisDetector->nTrimEn);}; + /** set/get counter bit in detector + * @param i is -1 to get, 0 to reset and any other value to set the counter bit + /returns the counter bit in detector + */ + int setCounterBit(int i = -1); - /** sets the number of trim energies and their value \sa sharedSlsDetector + /** + set roi + \param n number of rois + \param roiLimits array of roi + \returns success or failure + */ + int setROI(int n=-1,ROI roiLimits[]=NULL); + + /** + get roi from each detector and convert it to the multi detector scale + \param n number of roi + \returns an array of multidetector's rois + */ + slsDetectorDefs::ROI* getROI(int &n); + + + /** Returns number of rois */ + int getNRoi(){return thisDetector->nROI;}; + + + int sendROI(int n=-1,ROI roiLimits[]=NULL); + + + /** + write register + \param addr address + \val value + \returns current register value + + */ + int writeAdcRegister(int addr, int val); + + + /** @short activates the detector (detector specific) + \param enable can be: -1 returns wether the detector is in active (1) or inactive (0) state + \returns 0 (inactive) or 1 (active) + */ + int activate(int const enable=GET_ONLINE_FLAG); + + + /** returns the enable if data will be flipped across x or y axis + * \param d axis across which data is flipped + * returns 1 or 0 + */ + int getFlippedData(dimension d=X){return thisDetector->flippedData[d];}; + + /** sets the enable which determines if data will be flipped across x or y axis + * \param d axis across which data is flipped + * \param value 0 or 1 to reset/set or -1 to get value + * \return enable flipped data across x or y axis + */ + int setFlippedData(dimension d=X, int value=-1); + /** sets all the trimbits to a particular value + \param val trimbit value + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int setAllTrimbits(int val, int imod=-1); + + /** + * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. 4 bit mode gap pixels only in gui call back + * @param val 1 sets, 0 unsets, -1 gets + * @return gap pixel enable or -1 for error + */ + int enableGapPixels(int val=-1); + /** sets the number of trim energies and their value \sa sharedSlsDetector \param nen number of energies \param en array of energies \returns number of trim energies @@ -529,530 +1241,121 @@ class slsDetector : public slsDetectorUtils, public energyConversion { unused! \sa sharedSlsDetector - */ - int setTrimEn(int nen, int *en=NULL) {if (en) {for (int ien=0; ientrimEnergies[ien]=en[ien]; thisDetector->nTrimEn=nen;} return (thisDetector->nTrimEn);}; - - - //virtual int writeSettingsFile(string fname, sls_detector_module mod); - - /** - writes a trim/settings file for module number imod - the values will be read from the current detector structure - \param fname name of the file to be written - \param imod module number - \param iodelay io delay (detector specific) - \param tau tau (detector specific) - \returns OK or FAIL if the file could not be written - \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int) - */ - using energyConversion::writeSettingsFile; - int writeSettingsFile(string fname, int imod, int iodelay, int tau); - - - /** - returns currently the loaded trimfile/settingsfile name - */ - string getSettingsFile(){\ - string s(thisDetector->settingsFile); \ - if (s.length()>6) {\ - if (s.substr(s.length()-6,3)==string(".sn") && s.substr(s.length()-3)!=string("xxx") ) \ - return s.substr(0,s.length()-6); \ - } \ - return string(thisDetector->settingsFile);\ - }; - - - /** programs FPGA with pof file - \param fname file name - \returns OK or FAIL - */ - int programFPGA(string fname); - - /** resets FPGA - \returns OK or FAIL - */ - int resetFPGA(); - - /** power on/off the chip - \param ival on is 1, off is 0, -1 to get - \returns OK or FAIL - */ - int powerChip(int ival= -1); - - /** automatic comparator disable for Jungfrau only - \param ival on is 1, off is 0, -1 to get - \returns OK or FAIL - */ - int setAutoComparatorDisableMode(int ival= -1); - - - /** loads the modules settings/trimbits reading from a file - \param fname file name . If not specified, extension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int loadSettingsFile(string fname, int imod=-1); - - - /** saves the modules settings/trimbits writing to a file - \param fname file name . Axtension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int saveSettingsFile(string fname, int imod=-1); - - /** sets all the trimbits to a particular value - \param val trimbit value - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int setAllTrimbits(int val, int imod=-1); - - - /** loads the modules calibration data reading from a file - \param fname file name . If not specified, extension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int loadCalibrationFile(string fname, int imod=-1); - - - /** saves the modules calibration data writing to a file - \param fname file name . Axtension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int saveCalibrationFile(string fname, int imod=-1); - - - /** - - reads an angular conversion file - \param fname file to be read - \sa angleConversionConstant mythenDetector::readAngularConversion - */ - int readAngularConversionFile(string fname=""); - - - /** - - reads an angular conversion file - \param fname file to be read - \sa angleConversionConstant mythenDetector::readAngularConversion - */ - int readAngularConversion(ifstream& ifs); - - - - /** - Pure virtual function - writes an angular conversion file - \param fname file to be written - \sa angleConversionConstant mythenDetector::writeAngularConversion - */ - int writeAngularConversion(string fname=""); - - - - /** - Pure virtual function - writes an angular conversion file - \param fname file to be written - \sa angleConversionConstant mythenDetector::writeAngularConversion - */ - int writeAngularConversion(ofstream &ofs); - - - - - - /** Returns the number of channels per chip (without connecting to the detector) */ - int getNChans(){return thisDetector->nChans;}; // - - /** Returns the number of channels per chip (without connecting to the detector) in one direction */ - int getNChans(dimension d){return thisDetector->nChan[d];}; // - - /** Returns the number of chips per module (without connecting to the detector) */ - int getNChips(){return thisDetector->nChips;}; // - - /** Returns the number of chips per module (without connecting to the detector) */ - int getNChips(dimension d){return thisDetector->nChip[d];}; // - - /** Returns the number of modules (without connecting to the detector) */ - int getNMods(){return thisDetector->nMods;}; // - - /** Returns the number of modules in direction d (without connecting to the detector) */ - int getNMod(dimension d){return thisDetector->nMod[d];}; // - - int getChansPerMod(int imod=0){return thisDetector->nChans*thisDetector->nChips;}; - - int getChansPerMod( dimension d,int imod=0){return thisDetector->nChan[d]*thisDetector->nChip[d];}; - - /** Returns the max number of modules in direction d (without connecting to the detector) */ - int getNMaxMod(dimension d){return thisDetector->nModMax[d];}; // - - /** Returns the number of modules (without connecting to the detector) */ - int getMaxMods(){return thisDetector->nModsMax;}; // - - - /** number of rois defined */ - int nROI; - /** list of rois */ - ROI roiLimits[MAX_ROIS]; - - /** readout flags */ - readOutFlags roFlags; - - - int getTotalNumberOfChannels(); - //{return thisDetector->nChans*thisDetector->nChips*thisDetector->nMods;}; - - int getTotalNumberOfChannels(dimension d); - //{return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nMod[d];}; - - int getTotalNumberOfChannelsInclGapPixels(dimension d); - - int getMaxNumberOfChannels();//{return thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax;}; - - int getMaxNumberOfChannels(dimension d);//{return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nModMax[d];}; - - int getMaxNumberOfChannelsInclGapPixels(dimension d); - - /** returns the enable if data will be flipped across x or y axis - * \param d axis across which data is flipped - * returns 1 or 0 - */ - int getFlippedData(dimension d=X){return thisDetector->flippedData[d];}; - - /** Returns number of rois */ - int getNRoi(){return thisDetector->nROI;}; - - - - /* Communication to server */ - - - /** - executes a system command on the server - e.g. mount an nfs disk, reboot and returns answer etc. - \param cmd is the command to be executed - \param answer is the answer from the detector - \returns OK or FAIL depending on the command outcome - */ - int execCommand(string cmd, string answer); - - /** - sets/gets detector type - normally the detector knows what type of detector it is - \param type is the detector type (defaults to GET_DETECTOR_TYPE) - \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) - */ - int setDetectorType(detectorType type=GET_DETECTOR_TYPE); - - /** - sets/gets detector type - normally the detector knows what type of detector it is - \param type is the detector type ("Mythen", "Pilatus", "XFS", "Gotthard", Agipd", "Mönch") - \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) - */ - int setDetectorType(string type); - - /** - gets detector type - normally the detector knows what type of detector it is - \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH,-1 command failed) - */ - detectorType getDetectorsType(int pos=-1); - - detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorsType(pos);}; - - string sgetDetectorsType(int pos=-1){return getDetectorType(getDetectorsType(pos));}; - - string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(getDetectorsType(pos));}; - string ssetDetectorsType(string t, int pos=-1){return getDetectorType(getDetectorsType(pos));} - - // Detector configuration functions - /** - set/get the size of the detector - \param n number of modules - \param d dimension - \returns current number of modules in direction d - */ - - // Detector configuration functions - /** - set/get the size of the detector - \param n number of modules - \param d dimension - \returns current number of modules in direction d - */ - int setNumberOfModules(int n=GET_FLAG, dimension d=X); // if n=GET_FLAG returns the number of installed modules - - - /** sets the enable which determines if data will be flipped across x or y axis - * \param d axis across which data is flipped - * \param value 0 or 1 to reset/set or -1 to get value - * \return enable flipped data across x or y axis - */ - int setFlippedData(dimension d=X, int value=-1); - - /** - * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. 4 bit mode gap pixels only in gui call back - * @param val 1 sets, 0 unsets, -1 gets - * @return gap pixel enable or -1 for error - */ - int enableGapPixels(int val=-1); - - - /* - returns the instrinsic size of the detector (maxmodx, maxmody, nchans, nchips, ndacs - enum numberOf { - MAXMODX, - MAXMODY, - CHANNELS, - CHIPS, - DACS - } - */ - - - /** - get the maximum size of the detector - \param d dimension - \returns maximum number of modules that can be installed in direction d - */ - int getMaxNumberOfModules(dimension d=X); // - - - /** - set/get the use of an external signal - \param pol meaning of the signal \sa externalSignalFlag - \param signalIndex index of the signal - \returns current meaning of signal signalIndex - */ - externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); - - - /** - set/get the external communication mode - - obsolete \sa setExternalSignalFlags - \param pol value to be set \sa externalCommunicationMode - \returns current external communication mode - */ - externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); - - - // Tests and identification - - /** - get detector ids/versions for module - \param mode which id/version has to be read - \param imod module number for module serial number - \returns id - */ - int64_t getId(idMode mode, int imod=0); - /** - Digital test of the modules - \param mode test mode - \param imod module number for chip test or module firmware test - \returns OK or error mask - */ - int digitalTest(digitalTestMode mode, int imod=0); - /** - analog test - \param modte test mode - \return pointer to acquired data - - not yet implemented - */ - - int* analogTest(analogTestMode mode); - - /** - enable analog output of channel ichan - - not yet implemented - */ - int enableAnalogOutput(int ichan); - - /** - enable analog output of channel ichan, chip ichip, module imod - - not yet implemented - */ - int enableAnalogOutput(int imod, int ichip, int ichan); - - /** - give a train of calibration pulses - \param vcal pulse amplitude - \param npulses number of pulses - - not yet implemented - - */ - int giveCalibrationPulse(double vcal, int npulses); - - // Expert Initialization functions - - - /** - write register - \param addr address - \val value - \returns current register value - - */ - uint32_t writeRegister(uint32_t addr, uint32_t val); - - - /** - write register - \param addr address - \val value - \returns current register value - - */ - int writeAdcRegister(int addr, int val); - - /** - read register - \param addr address - \returns current register value - - */ - uint32_t readRegister(uint32_t addr); - - /** - sets a bit in a register - \param addr address - \param n nth bit ranging from 0 to 31 - \returns current register value - - DO NOT USE!!! ONLY EXPERT USER!!! - */ - uint32_t setBit(uint32_t addr, int n); - - - /** - clear a bit in a register - \param addr address - \param n nth bit ranging from 0 to 31 - \returns current register value - - DO NOT USE!!! ONLY EXPERT USER!!! - */ - uint32_t clearBit(uint32_t addr, int n); - - /** - set dacs value - \param val value (in V) - \param index DAC index - \param mV 0 in dac units or 1 in mV - \param imod module number (if -1 alla modules) - \returns current DAC value - */ - dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); - - /** - set dacs value - \param index ADC index - \param imod module number - \returns current ADC value (temperature for eiger and jungfrau in millidegrees) - */ - dacs_t getADC(dacIndex index, int imod=0); - - /** + */ + int setTrimEn(int nen, int *en=NULL) {if (en) {for (int ien=0; ientrimEnergies[ien]=en[ien]; thisDetector->nTrimEn=nen;} return (thisDetector->nTrimEn);}; + + + /** returns the number of trim energies and their value \sa sharedSlsDetector + \param point to the array that will contain the trim energies (in ev) + \returns number of trim energies + + + unused! + + \sa sharedSlsDetector + */ + int getTrimEn(int *en=NULL) {if (en) {for (int ien=0; iennTrimEn; ien++) en[ien]=thisDetector->trimEnergies[ien];} return (thisDetector->nTrimEn);}; + + /** + Pulse Pixel + \param n is number of times to pulse + \param x is x coordinate + \param y is y coordinate + \returns OK or FAIL + */ + int pulsePixel(int n=0,int x=0,int y=0); + + /** + Pulse Pixel and move by a relative value + \param n is number of times to pulse + \param x is relative x value + \param y is relative y value + \returns OK or FAIL + */ + int pulsePixelNMove(int n=0,int x=0,int y=0); + + /** + Pulse Chip + \param n is number of times to pulse + \returns OK or FAIL + */ + int pulseChip(int n=0); + + /** set/gets threshold temperature (Jungfrau only) \param val value in millidegrees, -1 gets \param imod module number, -1 is all \returns threshold temperature in millidegrees - */ - int setThresholdTemperature(int val=-1, int imod=-1); - - /** + */ + int setThresholdTemperature(int val=-1, int imod=-1); + + /** enables/disables temperature control (Jungfrau only) \param val value, -1 gets \param imod module number, -1 is all \returns temperature control enable - */ - int setTemperatureControl(int val=-1, int imod=-1); + */ + int setTemperatureControl(int val=-1, int imod=-1); - /** + /** Resets/ gets over-temperature event (Jungfrau only) \param val value, -1 gets \param imod module number, -1 is all \returns over-temperature event - */ - int setTemperatureEvent(int val=-1, int imod=-1); + */ + int setTemperatureEvent(int val=-1, int imod=-1); - /** - configure channel - \param reg channel register - \param ichan channel number (-1 all) - \param ichip chip number (-1 all) - \param imod module number (-1 all) - \returns current register value - \sa ::sls_detector_channel - */ - int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); - - /** - configure channel - \param chan channel to be set - must contain correct channel, module and chip number - \returns current register value - */ - int setChannel(sls_detector_channel chan); - - /** - get channel - \param ichan channel number - \param ichip chip number - \param imod module number - \returns current channel structure for channel - */ - sls_detector_channel getChannel(int ichan, int ichip, int imod); - + /** + * set storage cell that stores first acquisition of the series (Jungfrau only) + * \param value storage cell index. Value can be 0 to 15. (-1 gets) + * \returns the storage cell that stores the first acquisition of the series + */ + int setStoragecellStart(int pos=-1); - /** - configure chip - \param reg chip register - \param ichip chip number (-1 all) - \param imod module number (-1 all) - \returns current register value - \sa ::sls_detector_chip - */ - int setChip(int reg, int ichip=-1, int imod=-1); - - /** - configure chip - \param chip chip to be set - must contain correct module and chip number and also channel registers - \returns current register value - \sa ::sls_detector_chip - */ - int setChip(sls_detector_chip chip); + /** programs FPGA with pof file + \param fname file name + \returns OK or FAIL + */ + int programFPGA(string fname); - /** - get chip - \param ichip chip number - \param imod module number - \returns current chip structure for channel + /** resets FPGA + \returns OK or FAIL + */ + int resetFPGA(); - \bug probably does not return corretly! - */ - sls_detector_chip getChip(int ichip, int imod); + /** power on/off the chip + \param ival on is 1, off is 0, -1 to get + \returns OK or FAIL + */ + int powerChip(int ival= -1); + + /** automatic comparator disable for Jungfrau only + \param ival on is 1, off is 0, -1 to get + \returns OK or FAIL + */ + int setAutoComparatorDisableMode(int ival= -1); - /** + /** + gets the trimbits from shared memory *chanRegs + \param retval is the array with the trimbits + \param fromDetector is true if the trimbits shared memory have to be uploaded from detector + \returns the total number of channels for the detector + \sa ::sls_detector_module + */ + int getChanRegs(double* retval,bool fromDetector); + + /** configure module \param imod module number (-1 all) \returns current register value \sa ::sls_detector_module - */ - int setModule(int reg, int imod=-1); - //virtual int setModule(int reg, int imod=-1); + */ + int setModule(int reg, int imod=-1); + //virtual int setModule(int reg, int imod=-1); - /** + /** configure chip \param module module to be set - must contain correct module number and also channel and chip registers \param iodelay iodelay (detector specific) @@ -1063,610 +1366,248 @@ class slsDetector : public slsDetectorUtils, public energyConversion { \param tb 1 to include trimbits, 0 to exclude (used for eiger) \returns current register value \sa ::sls_detector_module - */ - int setModule(sls_detector_module module, int iodelay, int tau, int e_eV, int* gainval=0, int* offsetval=0, int tb=1); - //virtual int setModule(sls_detector_module module); + */ + int setModule(sls_detector_module module, int iodelay, int tau, int e_eV, int* gainval=0, int* offsetval=0, int tb=1); + //virtual int setModule(sls_detector_module module); - /** + /** get module \param imod module number \returns pointer to module structure (which has bee created and must then be deleted) - */ - sls_detector_module *getModule(int imod); - //virtual sls_detector_module *getModule(int imod); - - // calibration functions - // int setCalibration(int imod, detectorSettings isettings, double gain, double offset); - //int getCalibration(int imod, detectorSettings isettings, double &gain, double &offset); - + */ + sls_detector_module *getModule(int imod); - /* - calibrated setup of the threshold - */ - /** - get threshold energy + /** + configure channel + \param reg channel register + \param ichan channel number (-1 all) + \param ichip chip number (-1 all) \param imod module number (-1 all) - \returns current threshold value for imod in ev (-1 failed) - */ - int getThresholdEnergy(int imod=-1); + \returns current register value + \sa ::sls_detector_channel + */ + int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); - /** - set threshold energy - \param e_eV threshold in eV - \param imod module number (-1 all) - \param isettings ev. change settings - \param tb 1 to include trimbits, 0 to exclude - \returns current threshold value for imod in ev (-1 failed) - */ - int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS, int tb=1); + /** + configure channel + \param chan channel to be set - must contain correct channel, module and chip number + \returns current register value + */ + int setChannel(sls_detector_channel chan); - /** - set threshold energy - \param e_eV threshold in eV - \param isettings ev. change settings - \param tb 1 to include trimbits, 0 to exclude - \returns OK if successful, else FAIL - */ - int setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb=1); - - /** - get detector settings - \param imod module number (-1 all) - \returns current settings detectorSettings sendSettingsOnly(detectorSettings isettings); - */ - detectorSettings getSettings(int imod=-1); + /** + get channel + \param ichan channel number + \param ichip chip number + \param imod module number + \returns current channel structure for channel + */ + sls_detector_channel getChannel(int ichan, int ichip, int imod); - /** - set detector settings - \param isettings settings - \param imod module number (-1 all) - \returns current settings + /** + configure chip + \param reg chip register + \param ichip chip number (-1 all) + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_chip + */ + int setChip(int reg, int ichip=-1, int imod=-1); - in this function trimbits/settings and calibration files are searched in the settingsDir and calDir directories and the detector is initialized - */ - detectorSettings setSettings(detectorSettings isettings, int imod=-1); + /** + configure chip + \param chip chip to be set - must contain correct module and chip number and also channel registers + \returns current register value + \sa ::sls_detector_chip + */ + int setChip(sls_detector_chip chip); + /** + get chip + \param ichip chip number + \param imod module number + \returns current chip structure for channel - /** - send detector settings only (set only for Jungfrau, Gotthard, Moench, get for all) - \param isettings settings - \param imod module number (-1 all) - \returns current settings + \bug probably does not return corretly! + */ + sls_detector_chip getChip(int ichip, int imod); - in this function only the settings is sent to the detector, where it will initialize all the dacs already stored in the detector server. - */ - detectorSettings sendSettingsOnly(detectorSettings isettings, int imod=-1); + int getMoveFlag(int imod){if (moveFlag) return *moveFlag; else return 1;}; + int fillModuleMask(int *mM); - //virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1); + /** Starts acquisition, calibrates pedestal and writes to fpga + /returns number of frames + */ + int calibratePedestal(int frames = 0); - /** - gets the trimbits from shared memory *chanRegs - \param retval is the array with the trimbits - \param fromDetector is true if the trimbits shared memory have to be uploaded from detector - \returns the total number of channels for the detector - \sa ::sls_detector_module - */ - int getChanRegs(double* retval,bool fromDetector); - - /** - - updates the shared memory receiving the data from the detector (without asking and closing the connection - /returns OK - - */ - - int updateDetectorNoWait(); - - /** - - updates the shared memory receiving the data from the detector - /returns OK - - */ - - - int updateDetector(); - - // Acquisition functions - - /** - prepares detector for acquisition - \returns OK/FAIL - */ - int prepareAcquisition(); - - /** - prepares detector for acquisition - \returns OK/FAIL - */ - int cleanupAcquisition(); - - /** - start detector acquisition - \returns OK/FAIL - */ - int startAcquisition(); - - /** - stop detector acquisition - \returns OK/FAIL - */ - int stopAcquisition(); - - /** - start readout (without exposure or interrupting exposure) - \returns OK/FAIL - */ - int startReadOut(); - - /** - get run status - \returns status mask - */ - //virtual runStatus getRunStatus()=0; - runStatus getRunStatus(); - - /** - start detector acquisition and read all data putting them a data queue - \returns pointer to the front of the data queue - \sa startAndReadAllNoWait getDataFromDetector dataQueue - */ - int* startAndReadAll(); - - /** - start detector acquisition and read out, but does not read data from socket leaving socket opened - \returns OK or FAIL - - */ - int startAndReadAllNoWait(); - - /* /\** */ - /* receives a data frame from the detector socket */ - /* \returns pointer to the data or NULL. If NULL disconnects the socket */ - /* \sa getDataFromDetector */ - /* *\/ */ - /* int* getDataFromDetectorNoWait(); */ - - /** - asks and receives a data frame from the detector and puts it in the data queue - \returns pointer to the data or NULL. - \sa getDataFromDetector - */ - int* readFrame(); - - /** - asks and receives all data from the detector and puts them in a data queue - \returns pointer to the front of the queue or NULL. - \sa getDataFromDetector dataQueue - */ - int* readAll(); - - /** - asks and receives all data from the detector and leaves the socket opened - \returns OK or FAIL - */ - int readAllNoWait(); - - - - - - /** - set/get timer value - \param index timer index - \param t time in ns or number of...(e.g. frames, gates, probes) - \returns timer set value in ns or number of...(e.g. frames, gates, probes) - */ - int64_t setTimer(timerIndex index, int64_t t=-1); - - /** - get current timer value - \param index timer index - \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) - */ - int64_t getTimeLeft(timerIndex index); - - /** - * set storage cell that stores first acquisition of the series (Jungfrau only) - * \param value storage cell index. Value can be 0 to 15. (-1 gets) - * \returns the storage cell that stores the first acquisition of the series - */ - int setStoragecellStart(int pos=-1); - - - /** sets/gets the value of important readout speed parameters - \param sp is the parameter to be set/get - \param value is the value to be set, if -1 get value - \returns current value for the specified parameter - \sa speedVariable - */ - int setSpeed(speedVariable sp, int value=-1); - - // Flags - /** - set/get dynamic range - \param n dynamic range (-1 get) - \returns current dynamic range - updates the size of the data expected from the detector - \sa sharedSlsDetector - */ - int setDynamicRange(int n=-1); - - /** - set/get dynamic range - \returns number of bytes sent by the detector - \sa sharedSlsDetector - */ - int getDataBytes(){return thisDetector->dataBytes;}; - - /** - * returns number of bytes sent by detector including gap pixels - * \sa sharedSlsDetector - */ - int getDataBytesInclGapPixels(){return thisDetector->dataBytesInclGapPixels;}; - - - /** - set roi - \param n number of rois - \param roiLimits array of roi - \returns success or failure - */ - int setROI(int n=-1,ROI roiLimits[]=NULL); - - /** - get roi from each detector and convert it to the multi detector scale - \param n number of roi - \returns an array of multidetector's rois - */ - slsDetectorDefs::ROI* getROI(int &n); - - - int sendROI(int n=-1,ROI roiLimits[]=NULL); - - /** - set/get readout flags - \param flag readout flag to be set - \returns current flag - */ - int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); - - /** - execute trimming - \param mode trim mode - \param par1 if noise, beam or fixed setting trimming it is count limit, if improve maximum number of iterations - \param par2 if noise or beam nsigma, if improve par2!=means vthreshold will be optimized, if fixed settings par2<0 trimwith median, par2>=0 trim with level - \param imod module number (-1 all) - \returns OK or FAIl (FAIL also if some channel are 0 or 63 - */ - int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); - - - //Corrections - - - /** - set flat field corrections - \param fname name of the flat field file (or "" if disable) - \returns 0 if disable (or file could not be read), >0 otherwise - */ - int setFlatFieldCorrection(string fname=""); - - /** - set flat field corrections - \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) - \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) - \returns 0 if ff correction disabled, >0 otherwise - */ - int setFlatFieldCorrection(double *corr, double *ecorr=NULL); - - - /** - get flat field corrections - \param corr if !=NULL will be filled with the correction coefficients - \param ecorr if !=NULL will be filled with the correction coefficients errors - \returns 0 if ff correction disabled, >0 otherwise - */ - int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL); - - - /** + /** set rate correction \param t dead time in ns - if 0 disable correction, if >0 set dead time to t, if <0 set deadtime to default dead time for current settings \returns 0 if rate correction disabled, >0 otherwise - */ - int setRateCorrection(double t=0); + */ + int setRateCorrection(double t=0); - - /** + + /** get rate correction \param t reference for dead time \returns 0 if rate correction disabled, >0 otherwise - */ - int getRateCorrection(double &t); + */ + int getRateCorrection(double &t); - - /** + + /** get rate correction tau \returns 0 if rate correction disabled, otherwise the tau used for the correction - */ - double getRateCorrectionTau(); - /** + */ + double getRateCorrectionTau(); + /** get rate correction \returns 0 if rate correction disabled, >0 otherwise - */ - int getRateCorrection(); - - /** - set bad channels correction - \param fname file with bad channel list ("" disable) - \returns 0 if bad channel disabled, >0 otherwise - */ - int setBadChannelCorrection(string fname=""); - - /** - set bad channels correction - \param nch number of bad channels - \param chs array of channels - \param ff 0 if normal bad channels, 1 if ff bad channels - \returns 0 if bad channel disabled, >0 otherwise - */ - int setBadChannelCorrection(int nch, int *chs, int ff=0); - - /** - get bad channels correction - \param bad pointer to array that if bad!=NULL will be filled with the bad channel list - \returns 0 if bad channel disabled or no bad channels, >0 otherwise - */ - int getBadChannelCorrection(int *bad=NULL); - - - /** - pure virtual function - get angular conversion - \param reference to diffractometer direction - \param angconv array that will be filled with the angular conversion constants - \returns 0 if angular conversion disabled, >0 otherwise - \sa mythenDetector::getAngularConversion - */ - int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; - - angleConversionConstant *getAngularConversionPointer(int imod=0) {return &thisDetector->angOff[imod];}; + */ + int getRateCorrection(); - - /** - decode data from the detector converting them to an array of doubles, one for each channle - \param datain data from the detector - \returns pointer to a double array with a data per channel - */ - double* decodeData(int *datain, int &nn, double *fdata=NULL); - - - - - - /** - flat field correct data - \param datain data array - \param errin error array on data (if NULL will default to sqrt(datain) - \param dataout array of corrected data - \param errout error on corrected data (if not NULL) - \returns 0 - */ - int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); - - - - - /** + /** rate correct data \param datain data array \param errin error array on data (if NULL will default to sqrt(datain) \param dataout array of corrected data \param errout error on corrected data (if not NULL) \returns 0 - */ - int rateCorrect(double* datain, double *errin, double* dataout, double *errout); - - - /* /\** */ - /* pure virtual function */ - /* sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); */ - /* \param mp already merged postions */ - /* \param mv already merged data */ - /* \param me already merged errors (squared sum) */ - /* \param mm multiplicity of merged arrays */ - /* \returns OK or FAIL */ - /* \sa mythenDetector::resetMerging */ - /* *\/ */ - - /* int resetMerging(double *mp, double *mv,double *me, int *mm); */ - - /* /\** */ - /* pure virtual function */ - /* merge dataset */ - /* \param p1 angular positions of dataset */ - /* \param v1 data */ - /* \param e1 errors */ - /* \param mp already merged postions */ - /* \param mv already merged data */ - /* \param me already merged errors (squared sum) */ - /* \param mm multiplicity of merged arrays */ - /* \sa mythenDetector::addToMerging */ - /* *\/ */ - /* int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm); */ - - /* /\** pure virtual function */ - /* calculates the "final" positions, data value and errors for the emrged data */ - /* \param mp already merged postions */ - /* \param mv already merged data */ - /* \param me already merged errors (squared sum) */ - /* \param mm multiplicity of merged arrays */ - /* \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) */ - /* \sa mythenDetector::finalizeMerging */ - /* *\/ */ - /* int finalizeMerging(double *mp, double *mv,double *me, int *mm); */ - - /** - turns off server - */ - int exitServer(); + */ + int rateCorrect(double* datain, double *errin, double* dataout, double *errout); - /** Allocates the memory for a sls_detector_module structure and initializes it - \returns myMod the pointer to the allocate dmemory location + /** + set flat field corrections + \param fname name of the flat field file (or "" if disable) + \returns 0 if disable (or file could not be read), >0 otherwise + */ + int setFlatFieldCorrection(string fname=""); - */ - sls_detector_module* createModule(){return createModule(thisDetector->myDetectorType);}; + /** + set flat field corrections + \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) + \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) + \returns 0 if ff correction disabled, >0 otherwise + */ + int setFlatFieldCorrection(double *corr, double *ecorr=NULL); - /** Allocates the memory for a sls_detector_module structure and initializes it - \returns myMod the pointer to the allocate dmemory location + /** + get flat field corrections + \param corr if !=NULL will be filled with the correction coefficients + \param ecorr if !=NULL will be filled with the correction coefficients errors + \returns 0 if ff correction disabled, >0 otherwise + */ + int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL); - */ - sls_detector_module* createModule(detectorType myDetectorType); - - /** frees the memory for a sls_detector_module structure - \param myMod the pointer to the memory to be freed - - */ - - void deleteModule(sls_detector_module *myMod); - - - /** calcualtes the total number of steps of the acquisition. - called when number of frames, number of cycles, number of positions and scan steps change - */ - int setTotalProgress(); - - /** returns the current progress in % */ - double getCurrentProgress(); - - - // double* convertAngles(double pos); + /** + flat field correct data + \param datain data array + \param errin error array on data (if NULL will default to sqrt(datain) + \param dataout array of corrected data + \param errout error on corrected data (if not NULL) + \returns 0 + */ + int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(string fname=""); + + /** + set bad channels correction + \param nch number of bad channels + \param chs array of channels + \param ff 0 if normal bad channels, 1 if ff bad channels + \returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(int nch, int *chs, int ff=0); + + /** + get bad channels correction + \param bad pointer to array that if bad!=NULL will be filled with the bad channel list + \returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + int getBadChannelCorrection(int *bad=NULL); + + /** + + reads an angular conversion file + \param fname file to be read + \sa angleConversionConstant mythenDetector::readAngularConversion + */ + int readAngularConversionFile(string fname=""); - /** - returns the detector type from hostname and controlport - \param - \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) - */ - static detectorType getDetectorType(const char *name, int cport=DEFAULT_PORTNO); - - /** - returns the detector type from hostname and controlport - \param - \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) - */ - static detectorType getDetectorType(int id); - + /** - /** - Returns detector id - \returns detector id - */ - - int getDetectorId(int i=-1) {return detId;}; - - /** - Receives a data frame from the detector socket - \returns pointer to the data (or NULL if failed) - - */ - int* getDataFromDetector(int *retval=NULL); - - //int* + reads an angular conversion file + \param fname file to be read + \sa angleConversionConstant mythenDetector::readAngularConversion + */ + int readAngularConversion(ifstream& ifs); - /** returns if the detector is Master, slave or nothing - \param flag can be GET_MASTER, NO_MASTER, IS_MASTER, IS_SLAVE - \returns master flag of the detector - */ - masterFlags setMaster(masterFlags flag); - /** - Loads dark image or gain image from a file and sends it to the detector - \param index is 0 for dark image and 1 for gain image - \param fname file name to load data from + /** + Pure virtual function + writes an angular conversion file + \param fname file to be written + \sa angleConversionConstant mythenDetector::writeAngularConversion + */ + int writeAngularConversion(string fname=""); - */ - int loadImageToDetector(imageType index,string const fname); - /** - Called from loadImageToDetector to send the image to detector - \param index is 0 for dark image and 1 for gain image - \param arg image - */ - int sendImageToDetector(imageType index,short int imageVals[]); + /** + Pure virtual function + writes an angular conversion file + \param fname file to be written + \sa angleConversionConstant mythenDetector::writeAngularConversion + */ + int writeAngularConversion(ofstream &ofs); - /** - Sets/gets the synchronization mode of the various detectors - \param sync syncronization mode can be GET_SYNCHRONIZATION_MODE, NONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS - \returns current syncronization mode - */ - synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); - - /** - writes the counter memory block from the detector - \param startACQ is 1 to start acquisition after reading counter - \param fname file name to load data from + + /** + pure virtual function + get angular conversion + \param reference to diffractometer direction + \param angconv array that will be filled with the angular conversion constants + \returns 0 if angular conversion disabled, >0 otherwise + \sa mythenDetector::getAngularConversion + */ + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; + + angleConversionConstant *getAngularConversionPointer(int imod=0) {return &thisDetector->angOff[imod];}; + + + /** + Prints receiver configuration \returns OK or FAIL - */ - int writeCounterBlockFile(string const fname,int startACQ=0); + */ + int printReceiverConfiguration(); - /** - gets counter memory block in detector - \param startACQ is 1 to start acquisition after reading counter - \param arg counter memory block from detector - \returns OK or FAIL - */ - int getCounterBlock(short int arg[],int startACQ=0); - - - /** - Resets counter in detector - \param startACQ is 1 to start acquisition after resetting counter - \returns OK or FAIL - */ - int resetCounterBlock(int startACQ=0); - - /** set/get counter bit in detector - * @param i is -1 to get, 0 to reset and any other value to set the counter bit - /returns the counter bit in detector - */ - int setCounterBit(int i = -1); - - - int getMoveFlag(int imod){if (moveFlag) return *moveFlag; else return 1;}; - - /** Frees the shared memory - should not be used*/ - int freeSharedMemory(); - - - - - - //receiver - - - /** + /** calls setReceiverTCPSocket if online and sets the flag - */ - int setReceiverOnline(int const online=GET_ONLINE_FLAG); + */ + int setReceiverOnline(int const online=GET_ONLINE_FLAG); - /** + /** Checks if the receiver is really online - */ - string checkReceiverOnline(); + */ + string checkReceiverOnline(); - /** + /** configure the socket communication and initializes the socket instances \param name receiver ip - if "" the current receiver hostname is used @@ -1674,518 +1615,482 @@ class slsDetector : public slsDetectorUtils, public energyConversion { \returns OK is connection succeded, FAIL otherwise \sa sharedSlsDetector - */ - int setReceiverTCPSocket(string const name="", int const receiver_port=-1); + */ + int setReceiverTCPSocket(string const name="", int const receiver_port=-1); - /** + + /** Locks/Unlocks the connection to the receiver + /param lock sets (1), usets (0), gets (-1) the lock + /returns lock status of the receiver + */ + int lockReceiver(int lock=-1); + + /** + Returns the IP of the last client connecting to the receiver + */ + string getReceiverLastClientIP(); + /** + Turns off the receiver server! + */ + int exitReceiver(); + /** + updates the shared memory receiving the data from the detector (without asking and closing the connection + /returns OK + */ + int updateReceiverNoWait(); + + /** + updates the shared memory receiving the data from the detector + /returns OK + */ + int updateReceiver(); + + /** + * Send the multi detector size to the detector + */ + void sendMultiDetectorSize(); + + /** send the detector pos id to the receiver + * for various file naming conventions for multi detectors in receiver + */ + void setDetectorId(); + + /** send the detector host name to the receiver + * for various handshaking required with the detector + */ + void setDetectorHostname(); + + + /** + \returns file dir + */ + string getFilePath(){return setFilePath();}; + + /** Sets up the file directory @param s fileDir file directory \returns file dir - */ - string setFilePath(string s=""); + */ + string setFilePath(string s=""); - /** + + /** + \returns file name + */ + string getFileName(){return setFileName();}; + /** Sets up the file name @param s file name \returns file name - */ - string setFileName(string s=""); + */ + string setFileName(string s=""); - /** + + /** Sets the max frames per file in receiver @param f max frames per file \returns max frames per file in receiver - */ - int setReceiverFramesPerFile(int f = -1); + */ + int setReceiverFramesPerFile(int f = -1); - /** + /** + \returns file name + */ + fileFormat getFileFormat(){return setFileFormat();}; + + /** Sets up the file format @param f file format \returns file format - */ - fileFormat setFileFormat(fileFormat f=GET_FILE_FORMAT); + */ + fileFormat setFileFormat(fileFormat f=GET_FILE_FORMAT); - /** + /** + \returns file index + */ + int getFileIndex(){return setFileIndex();}; + /** Sets up the file index @param i file index \returns file index - */ - int setFileIndex(int i=-1); - - /** - \returns file dir - */ - string getFilePath(){return setFilePath();}; - - /** - \returns file name - */ - string getFileName(){return setFileName();}; - - /** - \returns file name - */ - fileFormat getFileFormat(){return setFileFormat();}; - - /** - \returns file index - */ - int getFileIndex(){return setFileIndex();}; + */ + int setFileIndex(int i=-1); - /** Starts the listening mode of receiver + + + /** Starts the listening mode of receiver \returns OK or FAIL - */ - int startReceiver(); + */ + int startReceiver(); - /** Stops the listening mode of receiver + /** Stops the listening mode of receiver \returns OK or FAIL - */ - int stopReceiver(); + */ + int stopReceiver(); - /** Sets the receiver to start any readout remaining in the fifo and - * change status to transmitting. - * The status changes to run_finished when fifo is empty - */ - runStatus startReceiverReadout(); + /** Sets the receiver to start any readout remaining in the fifo and + * change status to transmitting. + * The status changes to run_finished when fifo is empty + */ + runStatus startReceiverReadout(); - /** gets the status of the listening mode of receiver + /** gets the status of the listening mode of receiver \returns status - */ - runStatus getReceiverStatus(); + */ + runStatus getReceiverStatus(); - /** gets the number of frames caught by receiver + /** gets the number of frames caught by receiver \returns number of frames caught by receiver - */ - int getFramesCaughtByReceiver(); + */ + int getFramesCaughtByReceiver(); - /** gets the number of frames caught by any one receiver (to avoid using threadpool) + /** gets the number of frames caught by any one receiver (to avoid using threadpool) \returns number of frames caught by any one receiver (master receiver if exists) - */ - int getFramesCaughtByAnyReceiver() {return getFramesCaughtByReceiver();}; + */ + int getFramesCaughtByAnyReceiver() {return getFramesCaughtByReceiver();}; - /** gets the current frame index of receiver + /** gets the current frame index of receiver \returns current frame index of receiver - */ - int getReceiverCurrentFrameIndex(); + */ + int getReceiverCurrentFrameIndex(); - /** - * resets framescaught - * @param index frames caught by receiver - */ - int resetFramesCaught(); + /** + * resets framescaught + * @param index frames caught by receiver + */ + int resetFramesCaught(); - /** Locks/Unlocks the connection to the receiver - /param lock sets (1), usets (0), gets (-1) the lock - /returns lock status of the receiver - */ - int lockReceiver(int lock=-1); - /** - Returns the IP of the last client connecting to the receiver - */ - string getReceiverLastClientIP(); - - /** - updates the shared memory receiving the data from the detector (without asking and closing the connection - /returns OK - */ - int updateReceiverNoWait(); - - /** - updates the shared memory receiving the data from the detector - /returns OK - */ - int updateReceiver(); - - /** - Turns off the receiver server! - */ - int exitReceiver(); - - /** + /** Sets/Gets receiver file write enable @param enable 1 or 0 to set/reset file write enable /returns file write enable - */ - int enableWriteToFile(int enable=-1); + */ + int enableWriteToFile(int enable=-1); - /** + /** Sets/Gets file overwrite enable @param enable 1 or 0 to set/reset file overwrite enable /returns file overwrite enable - */ - int overwriteFile(int enable=-1); + */ + int overwriteFile(int enable=-1); - - int fillModuleMask(int *mM); - - - /** Starts acquisition, calibrates pedestal and writes to fpga - /returns number of frames - */ - int calibratePedestal(int frames = 0); - - - /** Clears error mask and also the bit in parent det multi error mask - /returns error mask - */ - int64_t clearAllErrorMask(); - - - /** returns the detector MAC address\sa sharedSlsDetector */ - string getDetectorMAC() {return string(thisDetector->detectorMAC);}; - /** returns the detector IP address\sa sharedSlsDetector */ - string getDetectorIP() {return string(thisDetector->detectorIP);}; - /** returns the receiver IP address \sa sharedSlsDetector */ - string getReceiver() {return string(thisDetector->receiver_hostname);}; - /** returns the receiver UDP IP address \sa sharedSlsDetector */ - string getReceiverUDPIP() {return string(thisDetector->receiverUDPIP);}; - /** returns the receiver UDP MAC address \sa sharedSlsDetector */ - string getReceiverUDPMAC() {return string(thisDetector->receiverUDPMAC);}; - /** returns the receiver UDP IP address \sa sharedSlsDetector */ - string getReceiverUDPPort() {ostringstream ss; ss << thisDetector->receiverUDPPort; string s = ss.str(); return s;}; - /** returns the receiver UDP2 for Eiger IP address \sa sharedSlsDetector */ - string getReceiverUDPPort2() {ostringstream ss; ss << thisDetector->receiverUDPPort2; string s = ss.str(); return s;}; - /** returns the client zmq port \sa sharedSlsDetector */ - string getClientStreamingPort() {ostringstream ss; ss << thisDetector->zmqport; string s = ss.str(); return s;}; - /** returns the receiver zmq port \sa sharedSlsDetector */ - string getReceiverStreamingPort() {ostringstream ss; ss << thisDetector->receiver_zmqport; string s = ss.str(); return s;}; - /** gets the zmq source ip in client, returns "none" if default setting and no custom ip set*/ - string getClientStreamingIP(){return string(thisDetector->zmqip);}; - /** gets the zmq source ip in receiver, returns "none" if default setting and no custom ip set*/ - string getReceiverStreamingIP(){return string(thisDetector->receiver_zmqip);}; - /** gets the additional json header, returns "none" if default setting and no custom set*/ - string getAdditionalJsonHeader(){return string(thisDetector->receiver_additionalJsonHeader);}; - /** returns the receiver UDP socket buffer size */ - string getReceiverUDPSocketBufferSize() {return setReceiverUDPSocketBufferSize();}; - /** returns the real receiver UDP socket buffer size */ - string getReceiverRealUDPSocketBufferSize(); - - - /** validates the format of detector MAC address and sets it \sa sharedSlsDetector */ - string setDetectorMAC(string detectorMAC); - /** validates the format of detector IP address and sets it \sa sharedSlsDetector */ - string setDetectorIP(string detectorIP); - /** validates and sets the receiver IP address/hostname \sa sharedSlsDetector */ - string setReceiver(string receiver); - /** validates the format of receiver udp ip and sets it \sa sharedSlsDetector */ - string setReceiverUDPIP(string udpip); - /** validates the format of receiver udp mac and sets it \sa sharedSlsDetector */ - string setReceiverUDPMAC(string udpmac); - /** sets the receiver udp port \sa sharedSlsDetector */ - int setReceiverUDPPort(int udpport); - /** sets the receiver udp port2 for Eiger \sa sharedSlsDetector */ - int setReceiverUDPPort2(int udpport); - /** sets the zmq port in client (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ - string setClientStreamingPort(string port); - /** sets the zmq port in receiver (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ - string setReceiverStreamingPort(string port); - /** sets the zmq source ip in client */ - string setClientStreamingIP(string sourceIP); - /** sets the zmq source ip in receiver. if empty, uses rx_hostname*/ - string setReceiverStreamingIP(string sourceIP); - /** additional json header, returns "none" if default setting and no custom set */ - string setAdditionalJsonHeader(string jsonheader); - /** sets the receiver UDP socket buffer size */ - string setReceiverUDPSocketBufferSize(int udpsockbufsize=-1); - - /** sets the transmission delay for left or right port or for an entire frame*/ - string setDetectorNetworkParameter(networkParameter index, int delay); - - /** Sets the read receiver frequency + /** Sets the read receiver frequency if data required from receiver randomly readRxrFrequency=0, else every nth frame to be sent to gui @param freq is the receiver read frequency /returns read receiver frequency - */ - int setReadReceiverFrequency(int freq=-1); + */ + int setReadReceiverFrequency(int freq=-1); - /** Sets the read receiver timer + /** Sets the read receiver timer if data required from receiver randomly readRxrFrequency=0, then the timer between each data stream is set with time_in_ms @param time_in_ms timer between frames /returns read receiver timer - */ - int setReceiverReadTimer(int time_in_ms=500); + */ + int setReceiverReadTimer(int time_in_ms=500); - /** - * Enable data streaming to client - * @param enable 0 to disable, 1 to enable, -1 to get the value - * @returns data streaming to client enable - */ - int enableDataStreamingToClient(int enable=-1) { - cprintf(RED,"ERROR: Must be called from the multi Detector level\n"); - return 0; - } + /** + * Enable data streaming to client + * @param enable 0 to disable, 1 to enable, -1 to get the value + * @returns data streaming to client enable + */ + int enableDataStreamingToClient(int enable=-1) { + cprintf(RED,"ERROR: Must be called from the multi Detector level\n"); + return 0; + } - /** Enable or disable streaming data from receiver to client - * @param enable 0 to disable 1 to enable -1 to only get the value - * @returns data streaming from receiver enable - */ - int enableDataStreamingFromReceiver(int enable=-1); + /** Enable or disable streaming data from receiver to client + * @param enable 0 to disable 1 to enable -1 to only get the value + * @returns data streaming from receiver enable + */ + int enableDataStreamingFromReceiver(int enable=-1); - /** enable/disable or get data compression in receiver - * @param i is -1 to get, 0 to disable and 1 to enable + /** enable/disable or get data compression in receiver + * @param i is -1 to get, 0 to disable and 1 to enable /returns data compression in receiver - */ - int enableReceiverCompression(int i = -1); + */ + int enableReceiverCompression(int i = -1); - /** - * Send the multi detector size to the detector - */ - void sendMultiDetectorSize(); - - /** send the detector pos id to the receiver - * for various file naming conventions for multi detectors in receiver - */ - void setDetectorId(); - - /** send the detector host name to the receiver - * for various handshaking required with the detector - */ - void setDetectorHostname(); - - /** enable/disable or 10Gbe - * @param i is -1 to get, 0 to disable and 1 to enable + /** enable/disable or 10Gbe + * @param i is -1 to get, 0 to disable and 1 to enable /returns if 10Gbe is enabled - */ - int enableTenGigabitEthernet(int i = -1); + */ + int enableTenGigabitEthernet(int i = -1); - /** set/get receiver fifo depth - * @param i is -1 to get, any other value to set the fifo deph + /** set/get receiver fifo depth + * @param i is -1 to get, any other value to set the fifo deph /returns the receiver fifo depth - */ - int setReceiverFifoDepth(int i = -1); + */ + int setReceiverFifoDepth(int i = -1); - /** set/get receiver silent mode - * @param i is -1 to get, 0 unsets silent mode, 1 sets silent mode + /** set/get receiver silent mode + * @param i is -1 to get, 0 unsets silent mode, 1 sets silent mode /returns the receiver silent mode enable - */ - int setReceiverSilentMode(int i = -1); + */ + int setReceiverSilentMode(int i = -1); - /******** CTB funcs */ - - /** opens pattern file and sends pattern to CTB - @param fname pattern file to open - @returns OK/FAIL - */ - int setCTBPattern(string fname); - - - /** Writes a pattern word to the CTB - @param addr address of the word, -1 is I/O control register, -2 is clk control register - @param word 64bit word to be written, -1 gets - @returns actual value - */ - uint64_t setCTBWord(int addr,uint64_t word=-1); - - /** Sets the pattern or loop limits in the CTB - @param level -1 complete pattern, 0,1,2, loop level - @param start start address if >=0 - @param stop stop address if >=0 - @param n number of loops (if level >=0) - @returns OK/FAIL - */ - int setCTBPatLoops(int level,int &start, int &stop, int &n); - - - /** Sets the wait address in the CTB - @param level 0,1,2, wait level - @param addr wait address, -1 gets - @returns actual value - */ - int setCTBPatWaitAddr(int level, int addr=-1); - - /** Sets the wait time in the CTB - @param level 0,1,2, wait level - @param t wait time, -1 gets - @returns actual value - */ - int setCTBPatWaitTime(int level, uint64_t t=-1); - - /** - Pulse Pixel - \param n is number of times to pulse - \param x is x coordinate - \param y is y coordinate - \returns OK or FAIL - */ - int pulsePixel(int n=0,int x=0,int y=0); - - /** - Pulse Pixel and move by a relative value - \param n is number of times to pulse - \param x is relative x value - \param y is relative y value - \returns OK or FAIL - */ - int pulsePixelNMove(int n=0,int x=0,int y=0); - - /** - Pulse Chip - \param n is number of times to pulse - \returns OK or FAIL - */ - int pulseChip(int n=0); - - /** - Set acquiring flag in shared memory - \param b acquiring flag - */ - void setAcquiringFlag(bool b=false); - - /** - Get acquiring flag from shared memory - \returns acquiring flag - */ - bool getAcquiringFlag(); - - /** - * Check if acquiring flag is set, set error if set - * \returns FAIL if not ready, OK if ready - */ - bool isAcquireReady(); - - /** + /** If data streaming in receiver is enabled, restream the stop dummy packet from receiver Used usually for Moench, in case it is lost in network due to high data rate \returns OK if success else FAIL - */ - int restreamStopFromReceiver(); + */ + int restreamStopFromReceiver(); - /** - * Check version compatibility with detector/receiver software - * (if hostname/rx_hostname has been set/ sockets created) - * \param p port type control port or receiver port - * \returns FAIL for incompatibility, OK for compatibility - */ - int checkVersionCompatibility(portType t); + /** opens pattern file and sends pattern to CTB + @param fname pattern file to open + @returns OK/FAIL + */ + int setCTBPattern(string fname); - protected: - + /** Writes a pattern word to the CTB + @param addr address of the word, -1 is I/O control register, -2 is clk control register + @param word 64bit word to be written, -1 gets + @returns actual value + */ + uint64_t setCTBWord(int addr,uint64_t word=-1); - /** - address of the detector structure in shared memory - */ - sharedSlsDetector *thisDetector; - - - /** - detector ID - */ - int detId; - - /** - position ID - */ - int posId; + /** Sets the pattern or loop limits in the CTB + @param level -1 complete pattern, 0,1,2, loop level + @param start start address if >=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ + int setCTBPatLoops(int level,int &start, int &stop, int &n); - /** - * parent multi detector - * */ + /** Sets the wait address in the CTB + @param level 0,1,2, wait level + @param addr wait address, -1 gets + @returns actual value + */ + int setCTBPatWaitAddr(int level, int addr=-1); - multiSlsDetector *parentDet; + /** Sets the wait time in the CTB + @param level 0,1,2, wait level + @param t wait time, -1 gets + @returns actual value + */ + int setCTBPatWaitTime(int level, uint64_t t=-1); - /** - shared memeory ID - */ - int shmId; - - /** - socket for control commands - */ - MySocketTCP *controlSocket; - - /** - socket for emergency stop - */ - MySocketTCP *stopSocket; - - /** - socket for data acquisition - */ - MySocketTCP *dataSocket; - - - /** pointer to flat field coefficients */ - double *ffcoefficients; - /** pointer to flat field coefficient errors */ - double *fferrors; + /** returns the detector MAC address\sa sharedSlsDetector */ + string getDetectorMAC() {return string(thisDetector->detectorMAC);}; + /** returns the detector IP address\sa sharedSlsDetector */ + string getDetectorIP() {return string(thisDetector->detectorIP);}; + /** returns the receiver IP address \sa sharedSlsDetector */ + string getReceiver() {return string(thisDetector->receiver_hostname);}; + /** returns the receiver UDP IP address \sa sharedSlsDetector */ + string getReceiverUDPIP() {return string(thisDetector->receiverUDPIP);}; + /** returns the receiver UDP MAC address \sa sharedSlsDetector */ + string getReceiverUDPMAC() {return string(thisDetector->receiverUDPMAC);}; + /** returns the receiver UDP IP address \sa sharedSlsDetector */ + string getReceiverUDPPort() {ostringstream ss; ss << thisDetector->receiverUDPPort; string s = ss.str(); return s;}; + /** returns the receiver UDP2 for Eiger IP address \sa sharedSlsDetector */ + string getReceiverUDPPort2() {ostringstream ss; ss << thisDetector->receiverUDPPort2; string s = ss.str(); return s;}; + /** returns the client zmq port \sa sharedSlsDetector */ + string getClientStreamingPort() {ostringstream ss; ss << thisDetector->zmqport; string s = ss.str(); return s;}; + /** returns the receiver zmq port \sa sharedSlsDetector */ + string getReceiverStreamingPort() {ostringstream ss; ss << thisDetector->receiver_zmqport; string s = ss.str(); return s;}; + /** gets the zmq source ip in client, returns "none" if default setting and no custom ip set*/ + string getClientStreamingIP(){return string(thisDetector->zmqip);}; + /** gets the zmq source ip in receiver, returns "none" if default setting and no custom ip set*/ + string getReceiverStreamingIP(){return string(thisDetector->receiver_zmqip);}; + /** gets the additional json header, returns "none" if default setting and no custom set*/ + string getAdditionalJsonHeader(){return string(thisDetector->receiver_additionalJsonHeader);}; + /** returns the receiver UDP socket buffer size */ + string getReceiverUDPSocketBufferSize() {return setReceiverUDPSocketBufferSize();}; + /** returns the real receiver UDP socket buffer size */ + string getReceiverRealUDPSocketBufferSize(); - /** pointer to detector module structures */ - sls_detector_module *detectorModules; - /** pointer to dac valuse */ - dacs_t *dacs; - /** pointer to adc valuse */ - dacs_t *adcs; - /** pointer to chip registers */ - int *chipregs; - /** pointer to channal registers */ - int *chanregs; - /** pointer to gain values */ - int *gain; - /** pointer to offset values */ - int *offset; + /** validates the format of detector MAC address and sets it \sa sharedSlsDetector */ + string setDetectorMAC(string detectorMAC); + /** validates the format of detector IP address and sets it \sa sharedSlsDetector */ + string setDetectorIP(string detectorIP); + /** validates and sets the receiver IP address/hostname \sa sharedSlsDetector */ + string setReceiver(string receiver); + /** validates the format of receiver udp ip and sets it \sa sharedSlsDetector */ + string setReceiverUDPIP(string udpip); + /** validates the format of receiver udp mac and sets it \sa sharedSlsDetector */ + string setReceiverUDPMAC(string udpmac); + /** sets the receiver udp port \sa sharedSlsDetector */ + int setReceiverUDPPort(int udpport); + /** sets the receiver udp port2 for Eiger \sa sharedSlsDetector */ + int setReceiverUDPPort2(int udpport); + /** sets the zmq port in client (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ + string setClientStreamingPort(string port); + /** sets the zmq port in receiver (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ + string setReceiverStreamingPort(string port); + /** sets the zmq source ip in client */ + string setClientStreamingIP(string sourceIP); + /** sets the zmq source ip in receiver. if empty, uses rx_hostname*/ + string setReceiverStreamingIP(string sourceIP); + /** additional json header, returns "none" if default setting and no custom set */ + string setAdditionalJsonHeader(string jsonheader); + /** sets the receiver UDP socket buffer size */ + string setReceiverUDPSocketBufferSize(int udpsockbufsize=-1); - receiverInterface *thisReceiver; + /** sets the transmission delay for left or right port or for an entire frame*/ + string setDetectorNetworkParameter(networkParameter index, int delay); - /** Initializes the shared memory - \param type is needed to define the size of the shared memory - \param id is the detector id needed to define the shared memory id - \return shm_id shared memory id - */ - int initSharedMemory(detectorType type=GENERIC, int id=0); - /** - Initializes the thisDetector structure - \param type is needed to define the number of channels, chips, modules etc. - \sa sharedSlsDetector - */ - int initializeDetectorSize(detectorType type); - /** - Initializes the module structures in thisDetector if the detector did not exists before - */ - int initializeDetectorStructure(); - /** + /** + analog test + \param modte test mode + \return pointer to acquired data + + not yet implemented + */ + + int* analogTest(analogTestMode mode); + + /** + enable analog output of channel ichan + + not yet implemented + */ + int enableAnalogOutput(int ichan); + + /** + enable analog output of channel ichan, chip ichip, module imod + + not yet implemented + */ + int enableAnalogOutput(int imod, int ichip, int ichan); + + /** + give a train of calibration pulses + \param vcal pulse amplitude + \param npulses number of pulses + + not yet implemented + + */ + int giveCalibrationPulse(double vcal, int npulses); + + +private: + /** + * Get Detector Type from Shared Memory (opening shm without verifying size) + * @param multiId multi detector Id + * @param verify true to verify if shm size matches existing one + * @returns detector type + */ + detectorType getDetectorTypeFromShm(int multiId, bool verify = true); + /** + * Initialize shared memory + * @param created true if shared memory must be created, else false to open + * @param type type of detector + * @param multiId multi detector Id + * @param verify true to verify if shm size matches existing one + * @returns true if the shared memory was created now + */ + void initSharedMemory(bool created, detectorType type, int multiId, bool verify = true); + + /** + * Calculate shared memory size based on detector type + * @param type type of detector + */ + int calculateSharedMemorySize(detectorType type); + + /** + * Initialize detector structure + * @param created true if shared memory was just created now + * @param type type of detector + * @param verify true to verify if shm size matches existing one + */ + void initializeDetectorStructure(bool created, detectorType type, bool verify = true); + + /** + * Initialize class members (and from parent classes) + */ + void initializeMembers(); + + /** Gets MAC from receiver and sets up UDP Connection */ + int setUDPConnection(); + + + /** send a sls_detector_channel structure over socket - */ - int sendChannel(sls_detector_channel*); - /** + */ + int sendChannel(sls_detector_channel*); + /** send a sls_detector_chip structure over socket - */ - int sendChip(sls_detector_chip*); - /** + */ + int sendChip(sls_detector_chip*); + /** send a sls_detector_module structure over socket - */ - int sendModule(sls_detector_module*); - /** + */ + int sendModule(sls_detector_module*); + /** receive a sls_detector_channel structure over socket - */ - int receiveChannel(sls_detector_channel*); - /** + */ + int receiveChannel(sls_detector_channel*); + /** receive a sls_detector_chip structure over socket - */ - int receiveChip(sls_detector_chip*); - /** + */ + int receiveChip(sls_detector_chip*); + /** receive a sls_detector_module structure over socket - */ - int receiveModule(sls_detector_module*); - - /** Gets MAC from receiver and sets up UDP Connection */ - int setUDPConnection(); + */ + int receiveModule(sls_detector_module*); + + /** slsDetector Id or position in the detectors list */ + int detId; + + /** Shared Memory object */ + SharedMemory* sharedMemory; + + /** Shared memory structure */ + sharedSlsDetector *thisDetector; + + /** multiSlsDetector referece */ + multiSlsDetector *multiDet; + + receiverInterface *thisReceiver; + + /** socket for control commands */ + MySocketTCP *controlSocket; + + /** socket for emergency stop */ + MySocketTCP *stopSocket; + + /** socket for data acquisition */ + MySocketTCP *dataSocket; + + /** pointer to detector module structures in shared memory */ + sls_detector_module *detectorModules; + /** pointer to dac valuse in shared memory */ + dacs_t *dacs; + /** pointer to adc valuse in shared memory */ + dacs_t *adcs; + /** pointer to chip registers in shared memory */ + int *chipregs; + /** pointer to channal registers in shared memory */ + int *chanregs; + /** pointer to gain values in shared memory */ + int *gain; + /** pointer to offset values in shared memory */ + int *offset; + + /** pointer to flat field coefficients in shared memory */ + double *ffcoefficients; + /** pointer to flat field coefficient errors in shared memory */ + double *fferrors; + }; #endif