From b294b3e8b1a19a81094833e04ce9a1094da829ea Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 12 Jun 2018 12:14:55 +0200 Subject: [PATCH] in progress with integratign new shm in multi --- slsDetectorSoftware/Makefile | 6 +- .../commonFiles/sls_detector_exceptions.h | 19 + .../multiSlsDetector/multiSlsDetector.cpp | 404 +++- .../multiSlsDetector/multiSlsDetector.h | 1703 +++++++++-------- .../sharedMemory/SharedMemory.cpp | 165 ++ .../sharedMemory/SharedMemory.h | 117 ++ .../slsDetector/slsDetector.cpp | 2 +- 7 files changed, 1471 insertions(+), 945 deletions(-) create mode 100644 slsDetectorSoftware/commonFiles/sls_detector_exceptions.h create mode 100644 slsDetectorSoftware/sharedMemory/SharedMemory.cpp create mode 100644 slsDetectorSoftware/sharedMemory/SharedMemory.h diff --git a/slsDetectorSoftware/Makefile b/slsDetectorSoftware/Makefile index 850edef3f..072422dbf 100644 --- a/slsDetectorSoftware/Makefile +++ b/slsDetectorSoftware/Makefile @@ -9,15 +9,15 @@ CFLAGS= -g -DC_ONLY -fPIC DFLAGS= -g -DDACS_INT -INCLUDES?= -IcommonFiles -IslsDetector -I../slsReceiverSoftware/MySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -I../slsReceiverSoftware/include -IthreadFiles -I$(ASM) +INCLUDES?= -IcommonFiles -IslsDetector -I../slsReceiverSoftware/MySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -I../slsReceiverSoftware/include -IthreadFiles -IsharedMemory-I$(ASM) #EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -Wl,-R/usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -lca -lCom LIBZMQDIR = ../slsReceiverSoftware/include LIBZMQ = -L$(LIBZMQDIR) -Wl,-rpath=$(LIBZMQDIR) -lzmq -SRC_CLNT=slsDetectorAnalysis/fileIO.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsDetector/slsDetectorUsers.cpp threadFiles/CondVar.cpp threadFiles/Mutex.cpp threadFiles/ThreadPool.cpp #../slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp -DEPSINCLUDES = $(LIBZMQDIR)/sls_receiver_defs.h $(LIBZMQDIR)/sls_receiver_funcs.h $(LIBZMQDIR)/ansi.h commonFiles/sls_detector_defs.h commonFiles/sls_detector_funcs.h commonFiles/error_defs.h slsDetector/slsDetectorBase.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h slsDetectorAnalysis/badChannelCorrections.h slsDetectorAnalysis/detectorData.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/fileIOStatic.h slsDetectorAnalysis/movingStat.h slsDetectorAnalysis/runningStat.h slsDetectorAnalysis/single_photon_hit.h threadFiles/Global.h threadFiles/Task.h usersFunctions/angleFunction.h +SRC_CLNT=slsDetectorAnalysis/fileIO.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsDetector/slsDetectorUsers.cpp threadFiles/CondVar.cpp threadFiles/Mutex.cpp threadFiles/ThreadPool.cpp sharedMemory/SharedMemory.cpp #../slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp +DEPSINCLUDES = $(LIBZMQDIR)/sls_receiver_defs.h $(LIBZMQDIR)/sls_receiver_funcs.h $(LIBZMQDIR)/ansi.h commonFiles/sls_detector_defs.h commonFiles/sls_detector_funcs.h commonFiles/error_defs.h slsDetector/slsDetectorBase.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h slsDetectorAnalysis/badChannelCorrections.h slsDetectorAnalysis/detectorData.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/fileIOStatic.h slsDetectorAnalysis/movingStat.h slsDetectorAnalysis/runningStat.h slsDetectorAnalysis/single_photon_hit.h threadFiles/Global.h threadFiles/Task.h usersFunctions/angleFunction.h sharedMemory/sharedMemory.h commonFiles/sls_detector_exceptions.h diff --git a/slsDetectorSoftware/commonFiles/sls_detector_exceptions.h b/slsDetectorSoftware/commonFiles/sls_detector_exceptions.h new file mode 100644 index 000000000..d45ae933c --- /dev/null +++ b/slsDetectorSoftware/commonFiles/sls_detector_exceptions.h @@ -0,0 +1,19 @@ +#pragma once +/************************************************ + * @file sls_detector_exceptions.h + * @short exceptions defined + ***********************************************/ +/** + *@short exceptions defined + */ + +#include +#include +using namespace std; + + +struct SharedMemoryException : public exception { +public: + SharedMemoryException() {} + string GetMessage() const { return "Shared Memory Failed";}; +};//shmException; diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 6436fe957..bc9b92f9c 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -9,84 +9,331 @@ ID: $Id$ ********************************************************************/ #include "multiSlsDetector.h" +#include "SharedMemory.h" +#include "slsDetector.h" +#include "sls_detector_exceptions.h" #include "ThreadPool.h" #include "ZmqSocket.h" #include "multiSlsDetectorClient.h" #include "multiSlsDetectorCommand.h" #include "postProcessingFuncs.h" -#include "slsDetector.h" #include "usersFunctions.h" +#include #include +#include +#include #include //json header in zmq stream -#include #include #include -#include -#include -// char ans[MAX_STR_LENGTH]; -int multiSlsDetector::freeSharedMemory() + +multiSlsDetector::multiSlsDetector(int id, bool verify, bool update) + : slsDetectorUtils(), + detId(id), + sharedMemory(0), + thisMultiDetector(0), + client_downstream(false), + threadpool(0) { - // Detach Memory address - for (int id = 0; id < thisMultiDetector->numberOfDetectors; ++id) { - if (detectors[id]) - detectors[id]->freeSharedMemory(); - } + bool created = initSharedMemory(verify, update); + initializeDetectorStructure(created, verify, update); - if (shmdt(thisMultiDetector) == -1) { - perror("shmdt failed\n"); - return FAIL; - } -#ifdef VERBOSE - printf("Shared memory %d detached\n", shmId); -#endif - // remove shared memory - if (shmctl(shmId, IPC_RMID, 0) == -1) { - perror("shmctl(IPC_RMID) failed\n"); - return FAIL; - } - printf("Shared memory %d deleted\n", shmId); - return OK; + getNMods(); + getMaxMods(); + if (createThreadPool() == FAIL) + exit(-1); } -int multiSlsDetector::initSharedMemory(int id = 0) -{ - key_t mem_key = DEFAULT_SHM_KEY + MAXDET + id; - int shm_id; - int sz; - sz = sizeof(sharedMultiSlsDetector); +multiSlsDetector::~multiSlsDetector(){ + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + delete(*it); + } + detectors.clear(); -#ifdef VERBOSE - std::cout << "multiSlsDetector: Size of shared memory is " << sz << " - id " << mem_key << std::endl; -#endif - shm_id = shmget(mem_key, sz, IPC_CREAT | 0666); // allocate shared memory + if (sharedMemory) { + sharedMemory->UnmapSharedMemory(thisMultiDetector); + delete sharedMemory; + } - if (shm_id < 0) { - std::cout << "*** shmget error (server) ***" << shm_id << std::endl; - return shm_id; + for (int i = 0; i < MAXDET; ++i) { + if (zmqSocket[i]) { + delete zmqSocket[i]; + } } - - /** - thisMultiDetector pointer is set to the memory address of the shared memory - */ - - thisMultiDetector = (sharedMultiSlsDetector*)shmat(shm_id, NULL, 0); /* attach */ - - if (thisMultiDetector == (void*)-1) { - std::cout << "*** shmat error (server) ***" << std::endl; - return shm_id; - } - /** - shm_id returns -1 is shared memory initialization fails - */ - - return shm_id; + destroyThreadPool(); } +slsDetector* multiSlsDetector::getSlsDetector(unsigned int pos) { + if (pos >= 0 && pos < detectors.size()) { + return detectors[pos]; + } + return 0; +} + + + +void multiSlsDetector::freeSharedMemory(int multiId) { + // get number of detectors + int numDetectors = 0; + SharedMemory* shm = new SharedMemory(multiId, -1); + std::string shmname = shm->GetName(); + + // shm not created before + if (SharedMemory::IsExisting(shmname)) { + sharedMultiDet* mdet = (sharedMultiSlsDetector*)shm->OpenSharedMemory( + sizeof(sharedMultiSlsDetector), false); + numDetectors = mdet->numberOfDetectors; + shm->UnmapSharedMemory(mdet); + shm->RemoveSharedMemory(); + } + delete shm; + + for (int i = 0; i < numDetectors; ++i) { + SharedMemory* shm = new SharedMemory(multiId, i); + shm->RemoveSharedMemory(); + delete shm; + } +} + + + +void multiSlsDetector::freeSharedMemory() { + + // single detector vector + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + (*it)->freeSharedMemory(); + delete (*it); + } + detectors.clear(); + + // multi detector + if (sharedMemory) { + sharedMemory->RemoveSharedMemory(); + delete sharedMemory; + } + thisMultiDetector = 0; +} + + +std::string multiSlsDetector::getUserDetails() { + std::ostringstream sstream; + + if (!detectors.size()) { + return std::string("none"); + } + + //hostname + sstream << "\nHostname: " << getHostname(); + //type + sstream<< "\nType: "; + + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) + sstream<< (*it)->sgetDetectorsType() << "+"; /*change funtion signature without argument*/ + //PID + sstream << "\nPID: " << thisMultiDetector->lastPID + //user + << "\nUser: " << thisMultiDetector->lastUser + << "\nDate: " << thisMultiDetector->lastDate << endl; + + string s = sstream.str(); + return s; +} + + +bool multiSlsDetector::initSharedMemory(bool verify, bool update) { + + // clear + if (sharedMemory) + delete sharedMemory; + thisMultiDetector = 0; + + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + delete(*it); + } + detectors.clear(); + + // create/open shm and map to structure + size_t sz = sizeof(sharedMultiSlsDetector); + + bool created = false; + sharedMemory = new SharedMemory(detId, -1); + if (SharedMemory::IsExisting(sharedMemory->GetName())) { + thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->OpenSharedMemory(sz, verify); + if (verify && thisMultiDetector->shmversion != MULTI_SHMVERSION) { + cprintf(RED, "Multi shared memory version mismatch " + "(expected 0x%x but got 0x%x)\n", + MULTI_SHMVERSION, thisMultiDetector->shmversion); + throw SharedMemoryException(); + } + } else { + try { + thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->CreateSharedMemory(sz); + created = true; + } catch(...) { + sharedMemory->RemoveSharedMemory(); + thisMultiDetector = 0; + throw; + } + } + + return created; +} + + +void multiSlsDetector::initializeDetectorStructure(bool created, bool verify, bool update) { + // set up new structure + if (created) { + thisMultiDetector->shmversion = MULTI_SHMVERSION; + thisMultiDetector->numberOfDetectors = 0; + thisMultiDetector->numberOfDetector[X] = 0; + thisMultiDetector->numberOfDetector[Y] = 0; + thisMultiDetector->onlineFlag = 1; + + stoppedFlag = 0; + masterPosition = -1; + syncMode; + dataBytes = 0; + dataBytesInclGapPixels = 0; + numberOfChannels = 0; + numberOfChannel[X] = 0; + numberOfChannel[Y] = 0; + numberOfChannelInclGapPixels[X] = 0; + numberOfChannelInclGapPixels[Y] = 0; + maxNumberOfChannels = 0; + maxNumberOfChannel[X] = 0; + maxNumberOfChannel[Y] = 0; + maxNumberOfChannelInclGapPixels[X] = 0; + maxNumberOfChannelInclGapPixels[Y] = 0; + maxNumberOfChannelsPerDetector[X] = 0; + maxNumberOfChannelsPerDetector[Y] = 0; + + int64_t timerValue[MAX_TIMERS]; + detectorSettings currentSettings; + currentThresholdEV; + progressIndex = 0; + totalProgress = 1; + fileIndex = 0; + strncpy(thisMultiDetector->fileName, "run", MAX_STR_LENGTH); + strncpy(thisMultiDetector->filePath, "/", MAX_STR_LENGTH); + + framesPerFile = 1; + fileFormat fileFormatType = ASCII; + correctionMask = (1 << WRITE_FILE) | (1 << OVERWRITE_FILE); + threadedProcessing; + tDead = 0; + strncpy(flatFieldDir, getenv("HOME"), MAX_STR_LENGTH); + strncpy(flatFieldFile, "none", MAX_STR_LENGTH); + strncpy(thisMultiDetector->badChanFile, "none", MAX_STR_LENGTH); + angConvFile[MAX_STR_LENGTH]; + angDirection; + fineOffset; + globalOffset; + binSize; + sampleDisplacement[2]; + numberOfPositions; + detPositions[MAXPOS]; + actionMask; + mystring actionScript[MAX_ACTIONS]; + mystring actionParameter[MAX_ACTIONS]; + scanMode[MAX_SCAN_LEVELS]; + mystring scanScript[MAX_SCAN_LEVELS]; + mystring scanParameter[MAX_SCAN_LEVELS]; + nScanSteps[MAX_SCAN_LEVELS]; + mysteps scanSteps[MAX_SCAN_LEVELS]; + scanPrecision[MAX_SCAN_LEVELS]; + acquiringFlag; + externalgui; + receiverOnlineFlag; + receiver_upstream; + } + + // get objects from single det shared memory (open) + for (int i = 0; i < thisMultiDetector->numberOfDetectors; i++) { + slsDetector* sdet = new slsDetector(detId, i, verify, this); + detectors.push_back(sdet); + } + + + //update user details + if (update) { + thisMultiDetector->lastPID = getpid(); + memset(thisMultiDetector->lastUser, 0, SHORT_STRING_LENGTH); + memset(thisMultiDetector->lastDate, 0, SHORT_STRING_LENGTH); + try { + strncpy(thisMultiDetector->lastUser, exec("whoami").c_str(), SHORT_STRING_LENGTH); + strncpy(thisMultiDetector->lastDate, exec("date").c_str(), DATE_LENGTH); + } catch(...) { + strncpy(thisMultiDetector->lastUser, exec("errorreading").c_str(), SHORT_STRING_LENGTH); + strncpy(thisMultiDetector->lastDate, exec("errorreading").c_str(), SHORT_STRING_LENGTH); + } + } +} + + +void multiSlsDetector::AddSingleDetector (std::string s) { + + cout << "Adding detector " << s << endl; + + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + if ((*it)->GetHostname() == s) { + cout << "Detector " << s << "already part of the multiDetector!" << endl + << "Remove it before adding it back in a new position!" << endl; + return; + } + } + + //check entire shared memory if it doesnt exist?? needed? + //could be that detectors not loaded completely cuz of crash in new slsdetector in initsharedmemory + + // get type by connecting + detectorType type = slsDetector::GetDetectorTypeFromDetector(s, DEFAULT_PORTNO); + if (type == GENERIC) { + cout << "Detector " << s << "does not exist in shared memory " + "and could not connect to it to determine the type!" << endl; + setErrorMask(getErrorMask() | MULTI_DETECTORS_NOT_ADDED); + appendNotAddedList(name); + return; + } + + + + int pos = detectors.size(); + slsDetector* sdet = new slsDetector(type, detId, pos, false, this); + detectors.push_back(sdet); + detectors[pos]->SetHostname(s); + detectors[pos]->SetOnline(1); + ++thisMultiDetector->numberOfDetectors; +} + + + +std::string multiSlsDetector::exec(const char* cmd) { + int bufsize = 1char buffer[bufsize]; + std::string result = ""; + FILE* pipe = popen(cmd, "r"); + if (!pipe) throw std::exception(); + try { + while (!feof(pipe)) { + if (fgets(buffer, bufsize, pipe) != NULL) + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + result.erase(result.find_last_not_of(" \t\n\r")+1); + return result; +} + + + + + multiSlsDetector::multiSlsDetector(int id) : slsDetectorUtils() , shmId(-1) @@ -103,57 +350,14 @@ multiSlsDetector::multiSlsDetector(int id) } if (thisMultiDetector->alreadyExisting == 0) { - thisMultiDetector->onlineFlag = ONLINE_FLAG; + thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG; - thisMultiDetector->numberOfDetectors = 0; - thisMultiDetector->numberOfDetector[X] = 0; - thisMultiDetector->numberOfDetector[Y] = 0; - for (int id = 0; id < MAXDET; ++id) { - thisMultiDetector->detectorIds[id] = -1; - thisMultiDetector->offsetX[id] = 0; - thisMultiDetector->offsetY[id] = 0; - } - thisMultiDetector->masterPosition = -1; - thisMultiDetector->dataBytes = 0; - thisMultiDetector->dataBytesInclGapPixels = 0; - thisMultiDetector->numberOfChannels = 0; - thisMultiDetector->numberOfChannel[X] = 0; - thisMultiDetector->numberOfChannel[Y] = 0; - thisMultiDetector->numberOfChannelInclGapPixels[X] = 0; - thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0; - thisMultiDetector->maxNumberOfChannels = 0; - thisMultiDetector->maxNumberOfChannel[X] = 0; - thisMultiDetector->maxNumberOfChannel[Y] = 0; - thisMultiDetector->maxNumberOfChannelInclGapPixels[X] = 0; - thisMultiDetector->maxNumberOfChannelInclGapPixels[Y] = 0; - thisMultiDetector->maxNumberOfChannelsPerDetector[X] = -1; - thisMultiDetector->maxNumberOfChannelsPerDetector[Y] = -1; - /** set trimDsdir, calDir and filePath to default to root directory*/ - strcpy(thisMultiDetector->filePath, "/"); - /** set fileName to default to run*/ - strcpy(thisMultiDetector->fileName, "run"); - /** set fileIndex to default to 0*/ - thisMultiDetector->fileIndex = 0; - /** set frames per file to default to 1*/ - thisMultiDetector->framesPerFile = 1; - /** set fileFormat to default to ascii*/ - thisMultiDetector->fileFormatType = ASCII; - /** set progress Index to default to 0*/ - thisMultiDetector->progressIndex = 0; - /** set total number of frames to be acquired to default to 1*/ - thisMultiDetector->totalProgress = 1; - /** set correction mask to 0*/ - thisMultiDetector->correctionMask = 1 << WRITE_FILE; - thisMultiDetector->correctionMask |= (1 << OVERWRITE_FILE); - /** set deat time*/ - thisMultiDetector->tDead = 0; - /** sets bad channel list file to none */ - strcpy(thisMultiDetector->badChanFile, "none"); + /** sets flat field correction directory */ strcpy(thisMultiDetector->flatFieldDir, getenv("HOME")); /** sets flat field correction file */ @@ -175,7 +379,7 @@ multiSlsDetector::multiSlsDetector(int id) strcpy(thisMultiDetector->angConvFile, "none"); /** set binsize*/ thisMultiDetector->binSize = 0.001; - thisMultiDetector->stoppedFlag = 0; + thisMultiDetector->threadedProcessing = 1; diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h index f6e531ea2..151ca28c3 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -6,7 +6,7 @@ Author: $Author$ URL: $URL$ ID: $Id$ -********************************************************************/ + ********************************************************************/ @@ -14,572 +14,570 @@ ID: $Id$ #define MULTI_SLS_DETECTOR_H #include "slsDetectorUtils.h" - class slsDetector; +class SharedMemory; class ThreadPool; class ZmqSocket; -//#include "sls_detector_defs.h" - - - - + +#include +#include +#define MULTI_SHMVERSION 0x180608 +#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 - * @version 0.1alpha - -*/ + */ class multiSlsDetector : public slsDetectorUtils { - //public virtual slsDetectorUtils { - - - typedef struct sharedMultiSlsDetector { - + typedef struct sharedMultiSlsDetector { - /** 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; - + /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/ - /** last process id accessing the shared memory */ - pid_t lastPID; + /** shared memory version */ + int shmversion; + /** 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; - - - /** Number of detectors operated at once */ - int numberOfDetectors; + /** last user name accessing the shared memory */ + char lastUser[SHORT_STRING_LENGTH]; - /** Number of detectors operated at once */ - int numberOfDetector[2]; + /** last time stamp when accessing the shared memory */ + char lastDate[SHORT_STRING_LENGTH]; - /** Ids of the detectors to be operated at once */ - int detectorIds[MAXDET]; + /** number of sls detectors in shared memory */ + int numberOfDetectors; + /** END OF FIXED PATTERN -----------------------------------------------*/ - /** Detectors offset in the X direction (in number of channels)*/ - int offsetX[MAXDET]; - /** Detectors offsets in the Y direction (in number of channels) */ - int offsetY[MAXDET]; - /** position of the master detector */ - int masterPosition; - - /** type of synchronization between detectors */ - synchronizationMode syncMode; - - /** size of the data that are transfered from all detectors */ - int dataBytes; - /** data bytes including gap pixels transferred from all detectors */ - int dataBytesInclGapPixels; - - /** total number of channels for all detectors */ - int numberOfChannels; - - /** total number of channels for all detectors in one dimension*/ - int numberOfChannel[2]; - /** total number of channels including gap pixels in one dimension */ - int numberOfChannelInclGapPixels[2]; + /** Number of detectors operated at once */ + int numberOfDetector[2]; - /** total number of channels for all detectors */ - int maxNumberOfChannels; - - /** max number of channels for all detectors in one dimension*/ - int maxNumberOfChannel[2]; + /** online flag - is set if the detector is connected, unset if socket connection is not possible */ + int onlineFlag; - /** max number of channels including gap pixels for all detectors in one dimension*/ - int maxNumberOfChannelInclGapPixels[2]; + /** 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; - /** max number of channels allowed for the complete set of detectors in one dimension */ - int maxNumberOfChannelsPerDetector[2]; + /** position of the master detector */ + int masterPosition; - /** timer values */ - int64_t timerValue[MAX_TIMERS]; // needed?!?!?!? + /** type of synchronization between detectors */ + synchronizationMode syncMode; - /** detector settings (standard, fast, etc.) */ - detectorSettings currentSettings; // needed?!?!?!? - /** detector threshold (eV) */ - int currentThresholdEV; // needed?!?!?!? + /** size of the data that are transfered from all detectors */ + int dataBytes; - - /** 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; - - /** current index of the output file */ - int fileIndex; - /** name root of the output files */ - char fileName[MAX_STR_LENGTH]; - /** path of the output files */ - char filePath[MAX_STR_LENGTH]; - /** max frames per file */ - int framesPerFile; - /** file format*/ - fileFormat fileFormatType; + /** data bytes including gap pixels transferred from all detectors */ + int dataBytesInclGapPixels; - /** 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; + /** total number of channels for all detectors */ + int numberOfChannels; + /** total number of channels for all detectors in one dimension*/ + int numberOfChannel[2]; + /** total number of channels including gap pixels in one dimension */ + int numberOfChannelInclGapPixels[2]; - /** directory where the flat field files are stored */ - char flatFieldDir[MAX_STR_LENGTH]; - /** file used for flat field corrections */ - char flatFieldFile[MAX_STR_LENGTH]; + /** total number of channels for all detectors */ + int maxNumberOfChannels; + /** max number of channels for all detectors in one dimension*/ + int maxNumberOfChannel[2]; - /** file with the bad channels */ - char badChanFile[MAX_STR_LENGTH]; + /** max number of channels including gap pixels for all detectors in one dimension*/ + int maxNumberOfChannelInclGapPixels[2]; + /** max number of channels allowed for the complete set of detectors in one dimension */ + int maxNumberOfChannelsPerDetector[2]; - /** angular conversion file */ - char angConvFile[MAX_STR_LENGTH]; + /** timer values */ + int64_t timerValue[MAX_TIMERS]; + /** detector settings (standard, fast, etc.) */ + detectorSettings currentSettings; + /** detector threshold (eV) */ + int currentThresholdEV; + /** 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; + /** current index of the output file */ + int fileIndex; + /** name root of the output files */ + char fileName[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; - /** bin size for data merging */ - double binSize; + /** path of the output files */ + char filePath[MAX_STR_LENGTH]; + /** max frames per file */ + int framesPerFile; + /** file format*/ + fileFormat fileFormatType; - //X and Y displacement - double sampleDisplacement[2]; + /** corrections to be applied to the data \see ::correctionFlags */ + int correctionMask; - /** number of positions at which the detector should acquire */ - int numberOfPositions; - /** list of encoder positions at which the detector should acquire */ - double detPositions[MAXPOS]; + /** 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]; + /** file with the bad channels */ + char badChanFile[MAX_STR_LENGTH]; + /** angular conversion file */ + char angConvFile[MAX_STR_LENGTH]; - /** Scans and scripts */ + /** 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; - int actionMask; - - //int actionMode[MAX_ACTIONS]; - mystring actionScript[MAX_ACTIONS]; - mystring actionParameter[MAX_ACTIONS]; - + /** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */ + double fineOffset; - 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]; - - /** flag for acquiring */ - bool acquiringFlag; + /** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */ + double globalOffset; - /** external gui */ - bool externalgui; + /** bin size for data merging */ + double binSize; - /** receiver online flag - is set if the receiver is connected, unset if socket connection is not possible */ - int receiverOnlineFlag; + //X and Y displacement + double sampleDisplacement[2]; - /** data streaming (up stream) enable in receiver */ - bool receiver_upstream; + /** number of positions at which the detector should acquire */ + int numberOfPositions; - } sharedMultiSlsDetector; + /** list of encoder positions at which the detector should acquire */ + double detPositions[MAXPOS]; + /** Scans and scripts */ + 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]; + /** flag for acquiring */ + bool acquiringFlag; + /** external gui */ + bool externalgui; + /** receiver online flag - is set if the receiver is connected, unset if socket connection is not possible */ + int receiverOnlineFlag; + /** data streaming (up stream) enable in receiver */ + bool receiver_upstream; + } sharedMultiSlsDetector; +public: + using slsDetectorUtils::flatFieldCorrect; + using slsDetectorUtils::rateCorrect; + using slsDetectorUtils::setBadChannelCorrection; + using slsDetectorUtils::readAngularConversion; + using slsDetectorUtils::writeAngularConversion; - - 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 (take care of possible conflicts!) - - */ + + */ - /** (default) 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 - - - */ - multiSlsDetector(int id=0); - //slsDetector(std::string const fname); - /** destructor */ - virtual ~multiSlsDetector(); - - /** - * returns true. Used when reference is slsDetectorUtils and to determine if command can be implemented as slsDetector/multiSlsDetector object/ - */ - bool isMultiSlsDetectorClass(){return 1;}; + /** + * Constructor + * @param id multi detector id + * @param verify true to verify if shared memory size matches existing one + * @param update true to update last user pid, date etc + */ + multiSlsDetector(int id = 0, bool verify = true, bool update = true); - /** - * Creates all the threads in the threadpool + /** + * Destructor + */ + virtual ~multiSlsDetector(); + + /** + * Get sls detector object from position in detectors array + * @param pos position in detectors array + * @returns pointer to sls detector object + */ + slsDetector* getSlsDetector(unsigned int pos); + + /** + * Free shared memory from the command line + * avoiding creating the constructor classes and mapping + * @param multiId multi detector Id + */ + static void freeSharedMemory(int multiId); + + /** + * Free shared memory and delete shared memory structure + * occupied by the sharedMultiSlsDetector structure + */ + void freeSharedMemory(); + + /** + * Get user details of shared memory + * @returns string with user details + */ + std::string getUserDetails(); + + + + + + + /** + * returns true. Used when reference is slsDetectorUtils and to determine if command can be implemented as slsDetector/multiSlsDetector object/ + */ + bool isMultiSlsDetectorClass(){return 1;}; + + /** + * Creates all the threads in the threadpool \returns OK or FAIL - */ - int createThreadPool(); + */ + int createThreadPool(); - /** destroys all the threads in the threadpool */ - void destroyThreadPool(); - - /** frees the shared memory occpied by the sharedMultiSlsDetector structure */ - int freeSharedMemory() ; - - /** allocates the shared memory occpied for the sharedMultiSlsDetector structure */ - int initSharedMemory(int) ; - - /** adds the detector with ID id in postion pos + /** destroys all the threads in the threadpool */ + void destroyThreadPool(); + + + /** adds the detector with ID id in postion pos \param id of the detector to be added (should already exist!) \param pos position where it should be added (normally at the end of the list (default to -1) \return the actual number of detectors or -1 if it failed*/ - int addSlsDetector(int id, int pos=-1); + int addSlsDetector(int id, int pos=-1); - /** adds the detector with ID id in postion pos + /** adds the detector with ID id in postion pos \param name of the detector to be added (should already exist in shared memory or at least be online) \param pos position where it should be added (normally at the end of the list (default to -1) \return the actual number of detectors or -1 if it failed*/ - int addSlsDetector(const char *name, int pos=-1); + int addSlsDetector(const char *name, int pos=-1); - int addSlsDetector(detectorType type, int pos=-1); + int addSlsDetector(detectorType type, int pos=-1); - /**removes the detector in position pos from the multidetector + /**removes the detector in position pos from the multidetector \param pos position of the detector to be removed from the multidetector system (defaults to -1 i.e. last detector) \returns the actual number of detectors - */ - int removeSlsDetector(int pos=-1); + */ + int removeSlsDetector(int pos=-1); - /**removes the detector in position pos from the multidetector + /**removes the detector in position pos from the multidetector \param name is the name of the detector \returns the actual number of detectors - */ - int removeSlsDetector(char *name); + */ + int removeSlsDetector(char *name); - std::string setHostname(const char*, int pos=-1); + std::string setHostname(const char*, int pos=-1); - std::string getHostname(int pos=-1); - using slsDetectorBase::getDetectorType; + std::string getHostname(int pos=-1); + using slsDetectorBase::getDetectorType; - std::string getDetectorType(){return sgetDetectorsType();}; + std::string getDetectorType(){return sgetDetectorsType();}; - detectorType getDetectorsType(int pos=-1); - detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){addSlsDetector(type, pos); return getDetectorsType(pos);}; + detectorType getDetectorsType(int pos=-1); + detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){addSlsDetector(type, pos); return getDetectorsType(pos);}; - std::string sgetDetectorsType(int pos=-1); - std::string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(setDetectorsType(type, pos));}; // - std::string ssetDetectorsType(std::string s, int pos=-1);//{return getDetectorType(setDetectorsType(getDetectorType(s),pos));}; // should decode detector type + std::string sgetDetectorsType(int pos=-1); + std::string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(setDetectorsType(type, pos));}; // + std::string ssetDetectorsType(std::string s, int pos=-1);//{return getDetectorType(setDetectorsType(getDetectorType(s),pos));}; // should decode detector type - /** adds a detector by id in position pos + /** adds a detector by id in position pos \param ival detector id to be added \param pos position to add it (-1 fails) \returns detector ID or -1 if detector in position i is empty - */ - int setDetectorId(int ival, int pos=-1); + */ + int setDetectorId(int ival, int pos=-1); - /** returns the id of the detector in position i + /** returns the id of the detector in position i \param i position of the detector \returns detector ID or -1 if detector in position i is empty*/ - int getDetectorId(int i); + int getDetectorId(int i); - /** returns the number of detectors in the multidetector structure + /** returns the number of detectors in the multidetector structure \returns number of detectors */ - int getNumberOfDetectors() {return thisMultiDetector->numberOfDetectors;}; + int getNumberOfDetectors() {return thisMultiDetector->numberOfDetectors;}; - /**returns number of detectors in dimension d - * \param d dimension d - * \returns number of detectors in dimension d - */ - int getNumberOfDetectors(dimension d) {return thisMultiDetector->numberOfDetector[d];}; + /**returns number of detectors in dimension d + * \param d dimension d + * \returns number of detectors in dimension d + */ + int getNumberOfDetectors(dimension d) {return thisMultiDetector->numberOfDetector[d];}; - /** returns the number of detectors in each direction + /** returns the number of detectors in each direction \param nx number of detectors in x direction \param ny number of detectors in y direction - */ - void getNumberOfDetectors(int& nx, int& ny){nx=thisMultiDetector->numberOfDetector[X];ny=thisMultiDetector->numberOfDetector[Y];}; + */ + void getNumberOfDetectors(int& nx, int& ny){nx=thisMultiDetector->numberOfDetector[X];ny=thisMultiDetector->numberOfDetector[Y];}; - int getMaxMods(); - int getNMods(); - int getMaxMod(dimension d); - int getNMod(dimension d); + int getMaxMods(); + int getNMods(); + int getMaxMod(dimension d); + int getNMod(dimension d); - int getChansPerMod(int imod=0); + int getChansPerMod(int imod=0); - angleConversionConstant *getAngularConversionPointer(int imod=0); - + angleConversionConstant *getAngularConversionPointer(int imod=0); - int getTotalNumberOfChannels(); - int getTotalNumberOfChannels(dimension d); + int getTotalNumberOfChannels(); - int getTotalNumberOfChannelsInclGapPixels(dimension d); + int getTotalNumberOfChannels(dimension d); - int getMaxNumberOfChannels(); + int getTotalNumberOfChannelsInclGapPixels(dimension d); - int getMaxNumberOfChannels(dimension d); + int getMaxNumberOfChannels(); - int getMaxNumberOfChannelsInclGapPixels(dimension d); + int getMaxNumberOfChannels(dimension d); - int getMaxNumberOfChannelsPerDetector(dimension d){return thisMultiDetector->maxNumberOfChannelsPerDetector[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); + int getMaxNumberOfChannelsPerDetector(dimension d){return thisMultiDetector->maxNumberOfChannelsPerDetector[d];}; - int setMaxNumberOfChannelsPerDetector(dimension d,int i){thisMultiDetector->maxNumberOfChannelsPerDetector[d]=i; return thisMultiDetector->maxNumberOfChannelsPerDetector[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); - double getScanStep(int index, int istep){return thisMultiDetector->scanSteps[index][istep];}; - /** returns the detector offset (in number of channels) + int setMaxNumberOfChannelsPerDetector(dimension d,int i){thisMultiDetector->maxNumberOfChannelsPerDetector[d]=i; return thisMultiDetector->maxNumberOfChannelsPerDetector[d];}; + + double getScanStep(int index, int istep){return thisMultiDetector->scanSteps[index][istep];}; + /** returns the detector offset (in number of channels) \param pos position of the detector \param ox reference to the offset in x \param oy reference to the offset in y \returns OK/FAIL if the detector does not exist - */ - int getDetectorOffset(int pos, int &ox, int &oy); + */ + int getDetectorOffset(int pos, int &ox, int &oy); - /** sets the detector offset (in number of channels) + /** sets the detector offset (in number of channels) \param pos position of the detector \param ox offset in x (-1 does not change) \param oy offset in y (-1 does not change) \returns OK/FAIL if the detector does not exist - */ - int setDetectorOffset(int pos, int ox=-1, int oy=-1); + */ + int setDetectorOffset(int pos, int ox=-1, int oy=-1); - - /** sets the detector in position i as master of the structure (e.g. it gates the other detectors and therefore must be started as last.
Assumes that signal 0 is gate in, signal 1 is trigger in, signal 2 is gate out + + /** sets the detector in position i as master of the structure (e.g. it gates the other detectors and therefore must be started as last.
Assumes that signal 0 is gate in, signal 1 is trigger in, signal 2 is gate out \param i position of master (-1 gets, -2 unset) \return master's position (-1 none) - */ - int setMaster(int i=-1); - - /** + */ + int setMaster(int i=-1); + + /** Sets/gets the synchronization mode of the various detectors \param sync syncronization mode \returns current syncronization mode - */ - /* enum synchronizationMode { */ - /* GET_SYNCHRONIZATION_MODE=-1, /\**< the multidetector will return its synchronization mode *\/ */ - /* NONE, /\**< all detectors are independent (no cabling) *\/ */ - /* MASTER_GATES, /\**< the master gates the other detectors *\/ */ - /* MASTER_TRIGGERS, /\**< the master triggers the other detectors *\/ */ - /* SLAVE_STARTS_WHEN_MASTER_STOPS /\**< the slave acquires when the master finishes, to avoid deadtime *\/ */ - /* }; */ + */ + /* enum synchronizationMode { */ + /* GET_SYNCHRONIZATION_MODE=-1, /\**< the multidetector will return its synchronization mode *\/ */ + /* NONE, /\**< all detectors are independent (no cabling) *\/ */ + /* MASTER_GATES, /\**< the master gates the other detectors *\/ */ + /* MASTER_TRIGGERS, /\**< the master triggers the other detectors *\/ */ + /* SLAVE_STARTS_WHEN_MASTER_STOPS /\**< the slave acquires when the master finishes, to avoid deadtime *\/ */ + /* }; */ - synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); + synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); - /** sets the onlineFlag + /** sets the onlineFlag \param off can be: GET_ONLINE_FLAG, returns wether the detector is in online or offline state; OFFLINE_FLAG, detector in offline state (i.e. no communication to the detector - using only local structure - no data acquisition possible!); 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); + */ + int setOnline(int const online=GET_ONLINE_FLAG); - /** checks if each of the detectors are online + /** checks if each of the detectors are online \returns online/offline status and -1 if any of the detector's online status is different from the other - */ - std::string checkOnline(); + */ + std::string checkOnline(); - /** @short activates the detector (detector specific) + /** @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); + */ + int activate(int const enable=GET_ONLINE_FLAG); - /** + /** \returns 1 if the detector structure has already be initlialized with the given id and belongs to this multiDetector instance, 0 otherwise */ - int exists(); + int exists(); - /** + /** Prints receiver configuration \returns OK or FAIL - */ - int printReceiverConfiguration(); + */ + int printReceiverConfiguration(); - /** + /** Purely virtual function Should be implemented in the specific detector class /sa mythenDetector::readConfigurationFile - */ + */ - int readConfigurationFile(std::string const fname); - /** + int readConfigurationFile(std::string const fname); + /** Purely virtual function Should be implemented in the specific detector class /sa mythenDetector::writeConfigurationFile - */ - int writeConfigurationFile(std::string const fname); + */ + int writeConfigurationFile(std::string const fname); - - /* I/O */ - + + /* I/O */ - /* Communication to server */ - // Expert Initialization functions - - /** + /* Communication to server */ + + // Expert Initialization functions + + /** get threshold energy \param imod module number (-1 all) \returns current threshold value for imod in ev (-1 failed) - */ - int getThresholdEnergy(int imod=-1); + */ + 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); - - /** + */ + int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS,int tb=1); + + /** get detector settings \param imod module number (-1 all) \returns current settings - */ - detectorSettings getSettings(int imod=-1); + */ + detectorSettings getSettings(int imod=-1); - /** + /** set detector settings \param isettings settings \param imod module number (-1 all) \returns current settings in this function trimbits and calibration files are searched in the trimDir and calDir directories and the detector is initialized - */ - detectorSettings setSettings(detectorSettings isettings, int imod=-1); + */ + detectorSettings setSettings(detectorSettings isettings, int imod=-1); - /** + /** Returns the trimbits from the detector's shared memmory \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 - */ - int getChanRegs(double* retval,bool fromDetector); + */ + int getChanRegs(double* retval,bool fromDetector); - - int64_t getId(idMode mode, int imod=0); - int digitalTest(digitalTestMode mode, int imod=0); - int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); - std::string getSettingsFile(); + + int64_t getId(idMode mode, int imod=0); + int digitalTest(digitalTestMode mode, int imod=0); + int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); + std::string getSettingsFile(); - int decodeNMod(int i, int &idet, int &imod); + int decodeNMod(int i, int &idet, int &imod); - /** programs FPGA with pof file + /** programs FPGA with pof file \param fname file name \returns OK or FAIL - */ - int programFPGA(std::string fname); + */ + int programFPGA(std::string fname); - /** resets FPGA + /** resets FPGA \returns OK or FAIL - */ - int resetFPGA(); + */ + int resetFPGA(); - /** power on/off the chip + /** 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); + */ + int powerChip(int ival= -1); - /** automatic comparator disable for Jungfrau only + /** 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); + */ + int setAutoComparatorDisableMode(int ival= -1); - /** loads the modules settings/trimbits reading from a file - file name extension is automatically generated! */ - int loadSettingsFile(std::string fname, int nmod=-1); + /** loads the modules settings/trimbits reading from a file - file name extension is automatically generated! */ + int loadSettingsFile(std::string fname, int nmod=-1); - /** gets the modules settings/trimbits and writes them to file - file name extension is automatically generated! */ - int saveSettingsFile(std::string fname, int nmod=-1); + /** gets the modules settings/trimbits and writes them to file - file name extension is automatically generated! */ + int saveSettingsFile(std::string fname, int nmod=-1); - /** sets all the trimbits to a particular value + /** 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); + */ + int setAllTrimbits(int val, int imod=-1); - /** loads the modules calibration data reading from a file - file name extension is automatically generated! */ - int loadCalibrationFile(std::string fname, int nmod=-1); + /** loads the modules calibration data reading from a file - file name extension is automatically generated! */ + int loadCalibrationFile(std::string fname, int nmod=-1); - /** gets the modules calibration data and writes them to file - file name extension is automatically generated! */ - int saveCalibrationFile(std::string fname, int nmod=-1); + /** gets the modules calibration data and writes them to file - file name extension is automatically generated! */ + int saveCalibrationFile(std::string fname, int nmod=-1); @@ -599,108 +597,108 @@ class multiSlsDetector : public slsDetectorUtils { - // Acquisition functions - /** + // Acquisition functions + /** prepares detector for acquisition \returns OK if all detectors are properly started, FAIL otherwise - */ - int prepareAcquisition(); + */ + int prepareAcquisition(); - /** + /** prepares detector for acquisition \returns OK if all detectors are properly started, FAIL otherwise - */ - int cleanupAcquisition(); + */ + int cleanupAcquisition(); - /** + /** start detector acquisition (master is started as last) \returns OK if all detectors are properly started, FAIL otherwise - */ - int startAcquisition(); + */ + int startAcquisition(); - /** + /** stop detector acquisition (master firtst) \returns OK/FAIL - */ - int stopAcquisition(); - - /** + */ + int stopAcquisition(); + + /** start readout (without exposure or interrupting exposure) (master first) \returns OK/FAIL - */ - int startReadOut(); + */ + 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(); - - /** + */ + int* startAndReadAll(); + + /** start detector acquisition and read out, but does not read data from socket - - */ - int startAndReadAllNoWait(); - /** + */ + 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(); - /** + */ + //int* getDataFromDetectorNoWait(); + /** receives a data frame from the detector socket \returns pointer to the data or NULL. If NULL disconnects the socket \sa getDataFromDetector - */ - int* getDataFromDetector(); + */ + int* getDataFromDetector(); - /** + /** 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(); + */ + 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(); + */ + int* readAll(); - - /** + + /** pops the data from the data queue \returns pointer to the popped data or NULL if the queue is empty. \sa dataQueue - */ - int* popDataQueue(); + */ + int* popDataQueue(); - /** + /** pops the data from thepostprocessed data queue \returns pointer to the popped data or NULL if the queue is empty. \sa finalDataQueue - */ - detectorData* popFinalDataQueue(); + */ + detectorData* popFinalDataQueue(); - /** + /** resets the raw data queue \sa dataQueue - */ - void resetDataQueue(); + */ + void resetDataQueue(); - /** + /** resets the postprocessed data queue \sa finalDataQueue - */ - void resetFinalDataQueue(); + */ + void resetFinalDataQueue(); @@ -708,111 +706,111 @@ class multiSlsDetector : public slsDetectorUtils { - int setSpeed(speedVariable sp, int value=-1); + int setSpeed(speedVariable sp, int value=-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); - /** + */ + int64_t setTimer(timerIndex index, int64_t t=-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 getTimeLeft(timerIndex index); + */ + 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); + /** + * 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); - /* /\** */ - /* 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); */ + /* /\** */ + /* 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); */ - // Flags - /** + // Flags + /** set/get dynamic range and updates the number of dataBytes \param n dynamic range (-1 get) \param pos detector position (-1 all detectors) \returns current dynamic range updates the size of the data expected from the detector \sa sharedSlsDetector - */ - int setDynamicRange(int n, int pos); + */ + int setDynamicRange(int n, int pos); - int getDataBytes(); + int getDataBytes(); - /** + /** decodes which detector and the corresponding channel numbers for it \param offsetX channel number or total channel offset in x direction \param offsetY channel number or total channel offset in y direction \param channelX channel number from detector offset in x direction \param channelY channel number from detector offset in x direction \returns detector id or -1 if channel number out of range - */ - int decodeNChannel(int offsetX, int offsetY, int &channelX, int &channelY); + */ + int decodeNChannel(int offsetX, int offsetY, int &channelX, int &channelY); -/** + /** verifies that min is less than max \param n number of rois \param r array of rois - */ - void verifyMinMaxROI(int n, ROI r[]); + */ + void verifyMinMaxROI(int n, ROI r[]); - /** + /** set roi \param n number of rois \param roiLimits array of roi \returns success or failure - */ - int setROI(int n=-1,ROI roiLimits[]=NULL); + */ + 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 rois \returns an array of multidetector's rois - */ - ROI* getROI(int &n); + */ + ROI* getROI(int &n); - //Corrections + //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(std::string fname=""); + */ + int setFlatFieldCorrection(std::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); + */ + 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); + */ + int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL); @@ -821,86 +819,86 @@ class multiSlsDetector : public slsDetectorUtils { - /** + /** 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(); - - /** + */ + int getRateCorrection(); + + /** set bad channels correction \param fname file with bad channel list ("" disable) \returns 0 if bad channel disabled, >0 otherwise - */ - int setBadChannelCorrection(std::string fname=""); - + */ + int setBadChannelCorrection(std::string fname=""); - int setBadChannelCorrection(int nch, int *chs, int ff); + + int setBadChannelCorrection(int nch, int *chs, int ff); - /** + /** 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); + */ + 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 - */ - /////////////////////////////////////////////////// virtual int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL); - - + */ + /////////////////////////////////////////////////// virtual int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL); - int readAngularConversionFile(std::string fname); - int writeAngularConversion(std::string fname); - // double* convertAngles(double pos); + int readAngularConversionFile(std::string fname); + + int writeAngularConversion(std::string fname); + + // double* convertAngles(double pos); - /** + /** 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); + */ + double* decodeData(int *datain, int &nn, double *fdata=NULL); - - - - /** + + + + /** flat field correct data \param datain data \param errin error on data (if<=0 will default to sqrt(datain) @@ -909,22 +907,22 @@ class multiSlsDetector : public slsDetectorUtils { \param ffcoefficient flat field correction coefficient \param fferr erro on ffcoefficient \returns 0 - */ - // int flatFieldCorrect(double datain, double errin, double &dataout, double &errout, double ffcoefficient, double fferr); - - /** + */ + // int flatFieldCorrect(double datain, double errin, double &dataout, double &errout, double ffcoefficient, double fferr); + + /** 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); - + */ + int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); - - /** + + + /** rate correct data \param datain data \param errin error on data (if<=0 will default to sqrt(datain) @@ -933,87 +931,87 @@ class multiSlsDetector : public slsDetectorUtils { \param tau dead time 9in ns) \param t acquisition time (in ns) \returns 0 - */ - // int rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t); - - /** + */ + // int rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t); + + /** 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); + */ + int rateCorrect(double* datain, double *errin, double* dataout, double *errout); - /** + /** turns off server - */ - int exitServer(); + */ + int exitServer(); - /** pure /////////////////////////////////////////////////// virtual function + /** pure /////////////////////////////////////////////////// virtual function function for processing data /param delflag if 1 the data are processed, written to file and then deleted. If 0 they are added to the finalDataQueue \sa mythenDetector::processData - */ - /////////////////////////////////////////////////// virtual void* processData(int delflag=1); // thread function + */ + /////////////////////////////////////////////////// virtual void* processData(int delflag=1); // thread function - - /////////////////////////////////////////////////// virtual void acquire(int delflag=1); - /** calcualtes the total number of steps of the acquisition. + /////////////////////////////////////////////////// virtual void acquire(int delflag=1); + + /** 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(); ////////////// from slsDetectorUtils! + */ + /////////////////////////////////////// int setTotalProgress(); ////////////// from slsDetectorUtils! - /** returns the current progress in % */ - ////////////////////////////////double getCurrentProgress();////////////// from slsDetectorUtils! - + /** returns the current progress in % */ + ////////////////////////////////double getCurrentProgress();////////////// from slsDetectorUtils! - /** + + /** 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); + */ + dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); - /** + /** set dacs value \param val value (in V) \param index DAC index \param imod module number (if -1 alla modules) \returns current DAC value (temperature for eiger and jungfrau in millidegrees) - */ - dacs_t getADC(dacIndex index, int imod=-1); + */ + dacs_t getADC(dacIndex index, int imod=-1); - /** + /** 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) @@ -1021,598 +1019,624 @@ class multiSlsDetector : public slsDetectorUtils { \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); - /** + */ + int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); + /** 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) ; - - + */ + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; - /** + + + /** get run status \returns status mask - */ - //virtual runStatus getRunStatus()=0; - runStatus getRunStatus(); + */ + //virtual runStatus getRunStatus()=0; + runStatus getRunStatus(); -void setErrorMaskFromAllDetectors(); + void setErrorMaskFromAllDetectors(); - std::string concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos); + std::string concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos); -template - bool allElemetsEqual(const std::vector&); + template + bool allElemetsEqual(const std::vector&); - template - T callDetectorMember(T (slsDetector::*somefunc)()); + template + T callDetectorMember(T (slsDetector::*somefunc)()); - std::string callDetectorMember(std::string(slsDetector::*somefunc)()); + std::string callDetectorMember(std::string(slsDetector::*somefunc)()); - template - T callDetectorMember(T (slsDetector::*somefunc)(V), V value); + template + T callDetectorMember(T (slsDetector::*somefunc)(V), V value); - template - T callDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2); + template + T callDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2); -//func0_t - template - T parallelCallDetectorMember(T (slsDetector::*somefunc)()); + //func0_t + template + T parallelCallDetectorMember(T (slsDetector::*somefunc)()); -//func1_t - template - T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1), P1 value); //Should probably be templated - - //func2_t - template - T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2); - + //func1_t + template + T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1), P1 value); //Should probably be templated - int parallelCallDetectorMember(int (slsDetector::*somefunc)(int, int, int), int v0, int v1, int v2); //Should probably be templated - - template - T minusOneIfDifferent(const std::vector&); + //func2_t + template + T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2); - /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ - std::string getSettingsDir(); - /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ - std::string setSettingsDir(std::string s); - /** + + int parallelCallDetectorMember(int (slsDetector::*somefunc)(int, int, int), int v0, int v1, int v2); //Should probably be templated + + template + T minusOneIfDifferent(const std::vector&); + + /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ + std::string getSettingsDir(); + /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ + std::string setSettingsDir(std::string s); + /** returns the location of the calibration files \sa sharedSlsDetector - */ - std::string getCalDir(); - /** + */ + std::string getCalDir(); + /** sets the location of the calibration files \sa sharedSlsDetector - */ - std::string setCalDir(std::string s); + */ + std::string setCalDir(std::string s); - std::string getNetworkParameter(networkParameter); + std::string getNetworkParameter(networkParameter); - /** + /** 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 - */ - std::string setNetworkParameter(networkParameter, std::string); - int setPort(portType, int); - int lockServer(int); - - std::string getLastClientIP(); + */ + std::string setNetworkParameter(networkParameter, std::string); + int setPort(portType, int); + int lockServer(int); - /** + std::string getLastClientIP(); + + /** configures mac for gotthard readout \returns OK or FAIL - */ - int configureMAC(); + */ + int configureMAC(); - int setNumberOfModules(int i=-1, dimension d=X); + int setNumberOfModules(int i=-1, dimension d=X); - /** 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 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); + /** + * 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); - int getMaxNumberOfModules(dimension d=X); - int setDynamicRange(int i=-1); + int getMaxNumberOfModules(dimension d=X); + int setDynamicRange(int i=-1); - uint32_t writeRegister(uint32_t addr, uint32_t val); - + uint32_t writeRegister(uint32_t addr, uint32_t val); - int writeAdcRegister(int addr, int val); - - uint32_t readRegister(uint32_t addr); + int writeAdcRegister(int addr, int val); - /** + + 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); + */ + 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); + */ + uint32_t clearBit(uint32_t addr, int n); - int setTrimEn(int nen, int *en=NULL); - int getTrimEn(int *en=NULL); + int setTrimEn(int nen, int *en=NULL); + int getTrimEn(int *en=NULL); - externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); - int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); + externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); + int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); - externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); + externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); - /** + /** Loads dark image or gain image to the detector \param index can be DARK_IMAGE or GAIN_IMAGE \fname file name to load data from \returns OK or FAIL - */ - int loadImageToDetector(imageType index,std::string const fname); + */ + int loadImageToDetector(imageType index,std::string const fname); - /** + /** sets the value of s angular conversion parameter \param c can be ANGULAR_DIRECTION, GLOBAL_OFFSET, FINE_OFFSET, BIN_SIZE \param v the value to be set \returns the actual value - */ + */ - double setAngularConversionParameter(angleConversionParameter c, double v); + double setAngularConversionParameter(angleConversionParameter c, double v); + + /** - /** - writes a data file \param name of the file to be written \param data array of data values \param err array of arrors on the data. If NULL no errors will be written - + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) \param dataformat format of the data: can be 'i' integer or 'f' double (default) \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector \returns OK or FAIL if it could not write the file or data=NULL \sa mythenDetector::writeDataFile - - */ - int writeDataFile(std::string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1); - - /** - + */ + int writeDataFile(std::string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1); + + + /** + writes a data file \param name of the file to be written \param data array of data values \returns OK or FAIL if it could not write the file or data=NULL \sa mythenDetector::writeDataFile - */ - int writeDataFile(std::string fname, int *data); - - /** - + */ + int writeDataFile(std::string fname, int *data); + + /** + reads a data file \param name of the file to be read \param data array of data values to be filled \param err array of arrors on the data. If NULL no errors are expected on the file - + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) \param dataformat format of the data: can be 'i' integer or 'f' double (default) \param nch number of channels to be written to file. if <=0 defaults to the number of installed channels of the detector \returns OK or FAIL if it could not read the file or data=NULL - + \sa mythenDetector::readDataFile - */ - int readDataFile(std::string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); + */ + int readDataFile(std::string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); - /** - + /** + reads a data file \param name of the file to be read \param data array of data values \returns OK or FAIL if it could not read the file or data=NULL \sa mythenDetector::readDataFile - */ - int readDataFile(std::string fname, int *data); + */ + int readDataFile(std::string fname, int *data); - /** + /** 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(std::string const fname,int startACQ=0); - + */ + int writeCounterBlockFile(std::string const fname,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); + */ + 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 + /** 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 setCounterBit(int i = -1); - int getMoveFlag(int imod); + int getMoveFlag(int imod); - slsDetector *getSlsDetector(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;}; - //additional way of accessing - slsDetector *operator()(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;}; + //additional way of accessing + slsDetector *operator()(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;}; - //receiver + //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 - */ - std::string checkReceiverOnline(); + */ + std::string checkReceiverOnline(); - /** + /** Sets up the file directory @param s file directory \returns file dir - */ - std::string setFilePath(std::string s=""); + */ + std::string setFilePath(std::string s=""); - /** + /** Sets up the file name @param s file name \returns file name - */ - std::string setFileName(std::string s=""); + */ + std::string setFileName(std::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); - /** + /** 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); - /** + /** Sets up the file index @param i file index \returns file index - */ - int setFileIndex(int i=-1); + */ + int setFileIndex(int i=-1); - /** + /** \returns file dir - */ - std::string getFilePath(){return setFilePath();}; + */ + std::string getFilePath(){return setFilePath();}; - /** + /** \returns file name - */ - std::string getFileName(){return setFileName();}; + */ + std::string getFileName(){return setFileName();}; - /** + /** \returns file name - */ - fileFormat getFileFormat(){return setFileFormat();}; + */ + fileFormat getFileFormat(){return setFileFormat();}; - /** + /** \returns file index - */ - int getFileIndex(){return setFileIndex();}; + */ + int getFileIndex(){return setFileIndex();}; - /** 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(); + */ + int getFramesCaughtByAnyReceiver(); - /** 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(); - /** - * Create Receiving Data Sockets - * @param destroy is true to destroy all the sockets - * @return OK or FAIL - */ - int createReceivingDataSockets(const bool destroy = false); + /** + * Create Receiving Data Sockets + * @param destroy is true to destroy all the sockets + * @return OK or FAIL + */ + int createReceivingDataSockets(const bool destroy = false); - /** Reads frames from receiver through a constant socket - */ - void readFrameFromReceiver(); + /** Reads frames from receiver through a constant socket + */ + void readFrameFromReceiver(); - /** Locks/Unlocks the connection to the receiver + /** 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); + */ + int lockReceiver(int lock=-1); - /** + /** Returns the IP of the last client connecting to the receiver - */ - std::string getReceiverLastClientIP(); + */ + std::string getReceiverLastClientIP(); - /** + /** Turns off the receiver server! - */ - int exitReceiver(); + */ + 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); + int fillModuleMask(int *mM); - /**checks error mask and returns error message if it exists - * @param myDet is the multidetector object - * @param critical is 1 if any of the messages is critical + /**checks error mask and returns error message if it exists + * @param myDet is the multidetector object + * @param critical is 1 if any of the messages is critical /returns error message else an empty std::string - */ - std::string getErrorMessage(int &critical); + */ + std::string getErrorMessage(int &critical); - /** Clears error mask of both multi and sls + /** Clears error mask of both multi and sls /returns error mask - */ - int64_t clearAllErrorMask(); + */ + int64_t clearAllErrorMask(); - /** Starts acquisition, calibrates pedestal and writes to fpga + /** Starts acquisition, calibrates pedestal and writes to fpga /returns number of frames - */ - int calibratePedestal(int frames = 0); + */ + int calibratePedestal(int frames = 0); - /** 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); + /** + * 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); - /** 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); - /** updates the multidetector offsets */ - void updateOffsets(); + /** updates the multidetector offsets */ + void updateOffsets(); - /** 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); - /** 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 */ + /******** CTB funcs */ - /** opens pattern file and sends pattern to CTB + /** opens pattern file and sends pattern to CTB @param fname pattern file to open @returns OK/FAIL - */ - int setCTBPattern(std::string fname); + */ + int setCTBPattern(std::string fname); - - /** Writes a pattern word to the CTB + + /** 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 + */ + 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); + */ + int setCTBPatLoops(int level,int &start, int &stop, int &n); - /** Sets the wait address in the CTB + /** 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); + */ + int setCTBPatWaitAddr(int level, int addr=-1); - /** Sets the wait time in the CTB + /** 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); + */ + 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); + */ + 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); - - /** + */ + 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); + */ + int pulseChip(int n=0); - /** + /** Set acquiring flag in shared memory \param b acquiring flag - */ - void setAcquiringFlag(bool b=false); - - /** + */ + void setAcquiringFlag(bool b=false); + + /** Get acquiring flag from shared memory \returns acquiring flag - */ - bool getAcquiringFlag(); + */ + bool getAcquiringFlag(); - /** - * Check if acquiring flag is set, set error if set - * \returns FAIL if not ready, OK if ready - */ - bool isAcquireReady(); + /** + * 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); + /** + * 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); private: + /** + * Initialize (open/create) shared memory for the sharedMultiDetector structure + * @param verify true to verify if shm size matches existing one + * @param update true to update last user pid, date etc + * @returns true if the shared memory was created now + */ + bool initSharedMemory(bool verify = true, bool update = true); + /** + * Initialize detector structure + * @param created true if shared memory was just created now + * @param verify true to verify if shm size matches existing one + * @param update true to update last user pid, date etc + */ + void initializeDetectorStructure(bool created, bool verify = true, bool update = true); + + /** + * Add single detector + * @param s hostname of the single detector + */ + void addSlsDetector (std::string s); + + /** + * Execute in command line and return result + * @param cmd command + * @returns result + */ + std::string exec(const char* cmd); /** * add gap pixels to the image (only for Eiger in 4 bit mode) @@ -1623,29 +1647,26 @@ private: int processImageWithGapPixels(char* image, char*& gpImage); + /** Multi detector Id */ + int detId; + + /** Shared Memory object */ + SharedMemory* sharedMemory; + + /** Shared memory structure */ + sharedMultiSlsDetector *thisMultiDetector; + + /** pointers to the slsDetector structures */ + std::vector detectors; /** data streaming (down stream) enabled in client (zmq sckets created) */ bool client_downstream; /** ZMQ Socket - Receiver to Client */ - ZmqSocket* zmqSocket[MAXDET]; - - protected: - - - /** Shared memory ID */ - int shmId; - - /** pointers to the slsDetector structures */ - slsDetector *detectors[MAXDET]; - - /** Shared memory structure */ - sharedMultiSlsDetector *thisMultiDetector; - - private: - ThreadPool* threadpool; - + std::vector zmqSocket; + /** Threadpool */ + ThreadPool* threadpool; }; diff --git a/slsDetectorSoftware/sharedMemory/SharedMemory.cpp b/slsDetectorSoftware/sharedMemory/SharedMemory.cpp new file mode 100644 index 000000000..e34fdc4c0 --- /dev/null +++ b/slsDetectorSoftware/sharedMemory/SharedMemory.cpp @@ -0,0 +1,165 @@ +#include "SharedMemory.h" +#include "sls_detector_exceptions.h" +#include "ansi.h" + +#include +#include // printf +#include // errno +#include // strerror +#include +#include // O_CREAT, O_TRUNC.. +#include // fstat +#include // shared memory +#include + + +SharedMemory::SharedMemory(int multiId, int singleId): + fd(-1), + shmSize(0) +{ + name = ConstructSharedMemoryName(multiId, singleId); +} + + + +SharedMemory::~SharedMemory(){ + if (fd >= 0) + close(fd); +} + + +bool SharedMemory::IsExisting(std::string name) { + bool ret = true; + int fd = shm_open(name.c_str(), O_RDWR, 0); + if ((fd < 0) && (errno == ENOENT)) { + ret = false; + } + close(fd); + return ret; +} + +std::string SharedMemory::GetName() { + return name; +} + + +void* SharedMemory::CreateSharedMemory(size_t sz){ + // create + fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + cprintf(RED, "Error: Create shared memory %s failed: %s\n", + name.c_str(), strerror(errno)); + throw SharedMemoryException(); + } + + // resize + if (ftruncate(fd, sz) < 0) { + cprintf(RED, "Error: Create shared memory %s failed at ftruncate: %s\n", + name.c_str(), strerror(errno)); + close(fd); + throw SharedMemoryException(); + } + + // map + return MapSharedMemory(sz); +} + +void* SharedMemory::OpenSharedMemory(size_t sz, bool verify){ + // open + fd = shm_open(name.c_str(), O_RDWR, 0); + if (fd < 0) { + cprintf(RED, "Error: Open existing shared memory %s failed: %s\n", + name.c_str(), strerror(errno)); + throw SharedMemoryException(); + } + + // verification required and size does not match + if (verify) + VerifySizeMatch(sz); + + // map + return MapSharedMemory(sz); +} + + +void SharedMemory::UnmapSharedMemory(void* addr) { + if (munmap(addr, shmSize) < 0) { + cprintf(RED, "Error: Unmapping shared memory %s failed: %s\n", + name.c_str(), strerror(errno)); + close(fd); + throw SharedMemoryException(); + } +} + +void SharedMemory::RemoveSharedMemory() { + RemoveSharedMemory(name.c_str()); +} + + +void* SharedMemory::MapSharedMemory(size_t sz) { + void* addr = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + cprintf(RED, "Error: Mapping shared memory %s failed: %s\n", + name.c_str(), strerror(errno)); + close(fd); + throw SharedMemoryException(); + } + shmSize = sz; + close(fd); + return addr; +} + + +std::string SharedMemory::ConstructSharedMemoryName(int multiId, int singleId) { + stringstream ss; + if (singleId < 0) + ss << "/slsDetectorPackage_multi_" << multiId; + else + ss << "/slsDetectorPackage_multi_" << multiId << "_single_" << singleId; + + std::string temp = ss.str(); + if (temp.length() > NAME_MAX) { + cprintf(RED, "Error: Shared memory initialization %s failed: %s\n", + name.c_str(), strerror(errno)); + throw SharedMemoryException(); + } + return temp; +} + + +int SharedMemory::VerifySizeMatch(size_t expectedSize) { + struct stat sb; + // could not fstat + if (fstat(fd, &sb) < 0) { + cprintf(RED, "Error: Could not verify existing shared memory %s size match " + "(could not fstat): %s\n", name.c_str(), strerror(errno)); + close(fd); + throw SharedMemoryException(); + } + + //size does not match + long unsigned int sz = (long unsigned int)sb.st_size; + if (sz != expectedSize) { + cprintf(RED, "Warning: Existing shared memory %s size does not match.\n", + name.c_str()); +#ifdef VERBOSE + cprintf(RED, " Expected %ld, found %ld\n", expectedSize, sz); +#endif + throw SharedMemoryException(); + return 1; + } + return 0; +} + +void SharedMemory::RemoveSharedMemory(std::string name) { + if (shm_unlink(name.c_str()) < 0) { + // silent exit if shm did not exist anyway + if (errno == ENOENT) + return; + cprintf(RED, "Error: Free Shared Memory %s Failed: %s\n", + name.c_str(), strerror(errno)); + throw SharedMemoryException(); + } + printf("Shared memory deleted %s \n", name.c_str()); +} + diff --git a/slsDetectorSoftware/sharedMemory/SharedMemory.h b/slsDetectorSoftware/sharedMemory/SharedMemory.h new file mode 100644 index 000000000..070b221f7 --- /dev/null +++ b/slsDetectorSoftware/sharedMemory/SharedMemory.h @@ -0,0 +1,117 @@ +#pragma once +/************************************************ + * @file SharedMemory.h + * @short functions basic implemenation of + * shared memory + ***********************************************/ +/** + *@short functions basic implemenation of shared memory + */ + +#include +#include + +class SharedMemory{ +public: + /** + * Constructor + * creates the single/multi detector shared memory name + * @param multiId multi detector id + * @param singleId sls detector id, -1 if a multi detector shared memory + */ + SharedMemory(int multiId, int singleId); + + /** + * Destructor + */ + ~SharedMemory(); + + /** + * Verify if it exists + * @param name of shared memory + * @return true if exists, else false + */ + static bool IsExisting(std::string name); + + /** + * Get shared memory name + */ + std::string GetName(); + + /** + * 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 + * @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); + + /** + * Unmap shared memory from an address + * throws a SharedMemoryException exception on failure + * @param addr double pointer to address to be mapped + */ + void UnmapSharedMemory(void* addr); + + /** + * Remove existing Shared memory + */ + void RemoveSharedMemory(); + + /** + * Maximum length of name as from man pages + */ + static const int NAME_MAX = 255; + +private: + /** + * Create Shared memory name + * throws exception if name created is longer than required 255(manpages) + * @param multiId multi detector id + * @param singleId sls detector id, -1 if a multi detector shared memory + * @returns shared memory name + */ + std::string ConstructSharedMemoryName(int multiId, int singleId); + + /** + * 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 + * @return 0 for success, 1 for fail + */ + int VerifySizeMatch(size_t expectedSize); + + /** + * Remove existing Shared memory + * @param name name of shared memory (should be less than NAME_MAX) + */ + void RemoveSharedMemory(std::string name); + + /** Shared memory name */ + std::string name; + + /** File descriptor */ + int fd; + + /** shm size */ + size_t shmSize; + +}; diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 11969bd3c..a9e540f32 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -262,7 +262,7 @@ slsDetector::slsDetector(int pos, detectorType type, int id, multiSlsDetector *p } -slsDetector::~slsDetector(){ +slsDetector:slsDetector(){ // Detach Memory address if (shmdt(thisDetector) == -1) {