diff --git a/CMakeLists.txt b/CMakeLists.txt index 116d270cf..d7e432b13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.8) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set (CALIBRATE OFF) option (USE_HDF5 "HDF5 File format" OFF) @@ -7,7 +7,12 @@ option (USE_TEXTCLIENT "Text Client" OFF) option (USE_RECEIVER "Receiver" OFF) option (USE_GUI "GUI" OFF) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -Wall -Wno-misleading-indentation") + +if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++98 -Wno-misleading-indentation") +else () + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++98") +endif () find_package(Qt4) find_package(Qwt 6) @@ -31,8 +36,10 @@ endif (USE_TEXTCLIENT) if (USE_RECEIVER) add_subdirectory(slsReceiverSoftware) + add_subdirectory(manual/manual-api) endif (USE_RECEIVER) + if (USE_GUI) if (QT4_FOUND AND QWT_FOUND) add_subdirectory(slsDetectorGui) diff --git a/Makefile b/Makefile index 0b76b91eb..8d4849b75 100755 --- a/Makefile +++ b/Makefile @@ -19,11 +19,12 @@ RECEIVERDIR = $(LIBRARYRXRDIR) CALWIZDIR = $(WD)/calibrationWizards MANDIR = $(WD)/manual CALIBDIR = $(WD)/slsDetectorCalibration +MANAPIDIR = $(MANDIR)/manual-api TABSPACE := "\t" -INCLUDES=-I. -I$(LIBRARYDIR)/commonFiles -I$(LIBRARYDIR)/slsDetector -I$(LIBRARYDIR)/usersFunctions -I$(LIBRARYDIR)/multiSlsDetector -I$(LIBRARYDIR)/slsDetectorUtils -I$(LIBRARYDIR)/slsDetectorCommand -I$(LIBRARYDIR)/slsDetectorAnalysis -I$(LIBRARYDIR)/slsReceiverInterface -I$(LIBRARYRXRDIR)/include -I$(LIBRARYDIR)/threadFiles -I$(ASM) +INCLUDES=-I. -I$(LIBRARYDIR)/commonFiles -I$(LIBRARYDIR)/slsDetector -I$(LIBRARYDIR)/usersFunctions -I$(LIBRARYDIR)/multiSlsDetector -I$(LIBRARYDIR)/slsDetectorUtils -I$(LIBRARYDIR)/slsDetectorCommand -I$(LIBRARYDIR)/slsDetectorAnalysis -I$(LIBRARYDIR)/slsReceiverInterface -I$(LIBRARYRXRDIR)/include -I$(LIBRARYDIR)/threadFiles -I$(LIBRARYDIR)/sharedMemory -I$(ASM) INCLUDESRXR += -I. -I$(LIBRARYRXRDIR)/include -I$(CALIBDIR) -I$(ASM) #LIBFLAGRXR += @@ -79,6 +80,7 @@ slsReceiver_static: receiver receiver: #libreceiver # cd $(RECEIVERDIR) && $(MAKE) receiver FLAGS='$(FLAGS)' DESTDIR='$(BINDIR)' LIBS='$(LDFLAGRXR)' INCLUDES='$(INCLUDESRXR)' LIBDIR='$(LIBDIR)' cd $(RECEIVERDIR) && $(MAKE) FLAGS='$(FLAGS)' DESTDIR='$(BINDIR)' LIBS='$(LDFLAGRXR)' INCLUDES='$(INCLUDESRXR)' LIBDIR='$(LIBDIR)' + cd $(MANAPIDIR) && $(MAKE) slsMultiReceiver @echo "" @echo "#######################################" @echo "# Back in slsDetectorPackage Makefile #" @@ -151,6 +153,7 @@ clean: cd $(DOCDIR) && rm -rf * rm -rf slsDetectorPackageDocs; rm -rf $(DETAILDOC) + rm -rf $(MANAPIDIR)/slsMultiReceiver #install_lib: diff --git a/cleansharedmemory.sh b/cleansharedmemory.sh index dd9238914..ab6ad287b 100644 --- a/cleansharedmemory.sh +++ b/cleansharedmemory.sh @@ -1 +1 @@ -for i in seq `ipcs -m | cut -d ' ' -f1`; do ipcrm -M $i; done; +rm /dev/shm/slsDetectorPackage*; diff --git a/examples/gotthard.config b/examples/gotthard.config index 5d2c4c8f7..f2c290df0 100644 --- a/examples/gotthard.config +++ b/examples/gotthard.config @@ -3,12 +3,8 @@ hostname bchip007 #0:port 1952 #0:stopport 1953 #0:rx_tcpport 1956 must also have this in receiver config file -0:settingsdir /home/l_maliakal_d/mySoft/newMythenSoftware/settingsdir/gotthard 0:angdir 1.000000 0:moveflag 0.000000 -0:lock 0 -0:caldir /home/l_maliakal_d/mySoft/newMythenSoftware/settingsdir/gotthard -0:ffdir /home/l_maliakal_d 0:extsig:0 off #0:detectorip 129.129.202.9 0:detectormac 00:aa:bb:cc:dd:ee @@ -20,7 +16,6 @@ hostname bchip007 master -1 sync none outdir /bigRAID/datadir_gotthard/rec_test_data -ffdir /home/l_maliakal_d headerbefore none headerafter none headerbeforepar none @@ -29,4 +24,4 @@ badchannels none angconv none globaloff 0.000000 binsize 0.001000 -threaded 1 + diff --git a/examples/jungfrau.config b/examples/jungfrau.config index 0b7e451d3..b5c8f734e 100644 --- a/examples/jungfrau.config +++ b/examples/jungfrau.config @@ -1,18 +1,15 @@ hostname bchip038+ -settingsdir /home/mySoft/slsDetectorsPackage/settingsdir/jungfrau -caldir /home/mySoft/slsDetectorsPackage/settingsdir/jungfrau -lock 0 - 0:rx_udpport 50004 0:rx_udpip 10.1.1.100 0:detectorip 10.1.1.10 - rx_hostname pcmoench01 powerchip 1 -timing auto + +#extsig:0 trigger_in_rising_edge +#timing trigger outdir /external_pool/jungfrau_data/softwaretest -threaded 1 + diff --git a/examples/jungfrau_two.config b/examples/jungfrau_two.config index fc2f6033b..16e50e57d 100644 --- a/examples/jungfrau_two.config +++ b/examples/jungfrau_two.config @@ -1,11 +1,6 @@ detsizechan 1024 1024 hostname bchip048+bchip052+ -settingsdir /home/mySoft/slsDetectorsPackage/settingsdir/jungfrau -caldir /home/mySoft/slsDetectorsPackage/settingsdir/jungfrau -lock 0 - - 0:rx_udpport 50004 0:rx_udpip 10.1.1.100 0:rx_udpmac F4:52:14:2F:32:00 @@ -22,9 +17,9 @@ lock 0 rx_hostname pcmoench01 powerchip 1 -extsig:0 trigger_in_rising_edge -timing auto +#extsig:0 trigger_in_rising_edge +#timing trigger outdir /external_pool/jungfrau_data/softwaretest -threaded 1 + diff --git a/examples/two_gotthard.config b/examples/two_gotthard.config index d3bf02cd6..3f9763d57 100644 --- a/examples/two_gotthard.config +++ b/examples/two_gotthard.config @@ -8,13 +8,11 @@ hostname bchip007+bchip009+ #0:port 1952 #0:stopport 1953 #0:rx_tcpport 1956 -0:settingsdir /home/l_msdetect/dhanya/slsDetectorsPackage/settingsdir/gotthard 0:angdir 1.000000 0:moveflag 0.000000 -0:lock 0 -0:caldir /home/l_msdetect/dhanya/slsDetectorsPackage/settingsdir/gotthard 0:ffdir /home/l_msdetect 0:extsig:0 off + 0:detectorip 10.1.1.2 #0:detectormac 00:aa:bb:cc:dd:ee #0:rx_udpport 50001 @@ -28,13 +26,11 @@ hostname bchip007+bchip009+ #1:port 1952 #1:stopport 1953 1:rx_tcpport 1957 -1:settingsdir /home/l_msdetect/dhanya/slsDetectorsPackage/settingsdir/gotthard 1:angdir 1.000000 1:moveflag 0.000000 -1:lock 0 -1:caldir /home/l_msdetect/dhanya/slsDetectorsPackage/settingsdir/gotthard 1:ffdir /home/l_msdetect 1:extsig:0 off + 1:detectorip 10.1.2.2 #1:detectormac 00:aa:bb:cc:dd:ee 1:rx_udpport 50004 @@ -56,4 +52,4 @@ badchannels none angconv none globaloff 0.000000 binsize 0.001000 -threaded 1 + diff --git a/manual/manual-api/CMakeLists.txt b/manual/manual-api/CMakeLists.txt new file mode 100644 index 000000000..0f7841626 --- /dev/null +++ b/manual/manual-api/CMakeLists.txt @@ -0,0 +1,35 @@ +set(SOURCES + mainReceiver.cpp +) + +include_directories( + ../../slsReceiverSoftware/include + ../../slsDetectorSoftware/slsDetectorAnalysis + ../../build/bin + ../../slsdetectorSoftware/slsDetector +) + +add_executable(slsMultiReceiver + ${SOURCES} +) + +target_link_libraries(slsMultiReceiver + slsReceiverShared + pthread + zmq + rt + ${HDF5_LIBRARIES} +) + +if (HDF5_FOUND) + target_link_libraries(slsMultiReceiver + ${HDF5_LIBRARIES} + ) +endif () + + +set_target_properties(slsMultiReceiver PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + +install(TARGETS slsMultiReceiver DESTINATION bin) diff --git a/manual/manual-api/Makefile b/manual/manual-api/Makefile index 3603e6ae8..42dcf7004 100644 --- a/manual/manual-api/Makefile +++ b/manual/manual-api/Makefile @@ -1,13 +1,21 @@ -INCLUDES = -I . +PKGDIR = ../.. +LIBDIR = $(PKGDIR)/build/bin +INCLUDES = -I . -I$(PKGDIR)/slsReceiverSoftware/include -I$(PKGDIR)/slsDetectorSoftware/slsDetectorAnalysis -I$(LIBDIR) -I$(PKGDIR)/slsDetectorSoftware/slsDetector SRC_DET = mainClient.cpp SRC_REC = mainReceiver.cpp -LIBDIR = . -LDFLAG_DET = -I. -L$(LIBDIR) -lSlsDetector -L/usr/lib64/ -pthread -lrt -L. -lzmq -LDFLAG_REC = -I. -L$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -pthread -lrt -L. -lzmq +ZMQLIBDIR = $(PKGDIR)/slsReceiverSoftware/include +LDFLAG_DET = -I. -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsDetector -L/usr/lib64/ -pthread -lrt -L$(ZMQLIBDIR) -Wl,-rpath=$(ZMQLIBDIR) -lzmq +LDFLAG_REC = -I. -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -pthread -lrt -L$(ZMQLIBDIR) -Wl,-rpath=$(ZMQLIBDIR) -lzmq DESTDIR ?= ../docs +HDF5 ?= no +HDF5_DIR ?= /opt/hdf5v1.10.0 -all: docs detUser detReceiver +ifeq ($(HDF5),yes) + LDFLAG_REC += -L$(HDF5_DIR)/lib -Wl,-rpath=$(HDF5_DIR)/lib -lhdf5 -lhdf5_cpp -lsz -lz -DHDF5C +endif + +all: docs detUser slsMultiReceiver #all: docs docs: createdocs docspdf docshtml removedocs @@ -35,18 +43,20 @@ detUser:$(SRC_DET) mkdir -p bin g++ -o bin/detUser $(SRC_DET) $(INCLUDES) $(LDFLAG_DET) -lm -lstdc++ -detReceiver:$(SRC_REC) +slsMultiReceiver:$(SRC_REC) echo "creating receiver" + echo $LDFLAG_REC mkdir -p bin - g++ -o bin/detReceiver $(SRC_REC) $(INCLUDES) $(LDFLAG_REC) -lm -lstdc++ - + g++ -o bin/slsMultiReceiver $(SRC_REC) $(INCLUDES) $(LDFLAG_REC) -lm -lstdc++ + cp bin/slsMultiReceiver $(LIBDIR) clean: echo "cleaning for manual-api" - rm -rf bin/detUser bin/detReceiver slsDetectorUsersDocs + rm -rf bin/detUser bin/slsMultiReceiver bin/detReceiver slsDetectorUsersDocs rm -rf slsDetectorUsersDocs rm -rf $(DESTDIR)/html/slsDetectorUsersDocs rm -rf $(DESTDIR)/pdf/slsDetectorUsersDocs.pdf + rm -rf $(LIBDIR)/slsMultiReceiver diff --git a/manual/manual-api/ansi.h b/manual/manual-api/ansi.h deleted file mode 120000 index a122db0ad..000000000 --- a/manual/manual-api/ansi.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/manual/manual-api/detectorData.h b/manual/manual-api/detectorData.h deleted file mode 120000 index a9649d01f..000000000 --- a/manual/manual-api/detectorData.h +++ /dev/null @@ -1 +0,0 @@ -../../slsDetectorSoftware/slsDetectorAnalysis/detectorData.h \ No newline at end of file diff --git a/manual/manual-api/libSlsDetector.so b/manual/manual-api/libSlsDetector.so deleted file mode 120000 index ca5cf8fcb..000000000 --- a/manual/manual-api/libSlsDetector.so +++ /dev/null @@ -1 +0,0 @@ -../../build/bin/libSlsDetector.so \ No newline at end of file diff --git a/manual/manual-api/libSlsReceiver.so b/manual/manual-api/libSlsReceiver.so deleted file mode 120000 index e2419f9cb..000000000 --- a/manual/manual-api/libSlsReceiver.so +++ /dev/null @@ -1 +0,0 @@ -../../build/bin/libSlsReceiver.so \ No newline at end of file diff --git a/manual/manual-api/libzmq.a b/manual/manual-api/libzmq.a deleted file mode 120000 index 2ecd6f21c..000000000 --- a/manual/manual-api/libzmq.a +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/libzmq.a \ No newline at end of file diff --git a/manual/manual-api/mainClient.cpp b/manual/manual-api/mainClient.cpp index 393a6bef1..b8d90cfdf 100644 --- a/manual/manual-api/mainClient.cpp +++ b/manual/manual-api/mainClient.cpp @@ -71,10 +71,6 @@ int main(int argc, char **argv) { /** - registering data callback */ pDetector->registerDataCallback(&dataCallback, NULL); - /** - if receiver exists, enable data streaming from receiver to get the data */ - pDetector->enableDataStreamingFromReceiver(1); - /** - create zmq sockets in client to enable data streaming in of data from receiver/different process */ - pDetector->enableDataStreamingToClient(1); /** - ensuring detector status is idle before starting acquisition. exiting if not idle */ diff --git a/manual/manual-api/mainReceiver.cpp b/manual/manual-api/mainReceiver.cpp index e39663d3d..fcc5620fe 100644 --- a/manual/manual-api/mainReceiver.cpp +++ b/manual/manual-api/mainReceiver.cpp @@ -54,7 +54,7 @@ void sigInterruptHandler(int p){ */ void printHelp() { cprintf(RESET, "Usage:\n" - "./detReceiver [start_tcp_port] [num_receivers] [1 for call back, 0 for none]\n\n"); + "./slsMultiReceiver(detReceiver) [start_tcp_port] [num_receivers] [1 for call back, 0 for none]\n\n"); exit(EXIT_FAILURE); } @@ -71,7 +71,7 @@ void printHelp() { */ int StartAcq(char* filepath, char* filename, uint64_t fileindex, uint32_t datasize, void*p){ cprintf(BLUE, "#### StartAcq: filepath:%s filename:%s fileindex:%llu datasize:%u ####\n", - filepath, filename, fileindex, datasize); + filepath, filename, (long long unsigned int)fileindex, datasize); cprintf(BLUE, "--StartAcq: returning 0\n"); return 0; @@ -83,41 +83,37 @@ int StartAcq(char* filepath, char* filename, uint64_t fileindex, uint32_t datasi * @param p pointer to object */ void AcquisitionFinished(uint64_t frames, void*p){ - cprintf(BLUE, "#### AcquisitionFinished: frames:%llu ####\n",frames); + cprintf(BLUE, "#### AcquisitionFinished: frames:%llu ####\n",(long long unsigned int)frames); } /** * Get Receiver Data Call back * Prints in different colors(for each receiver process) the different headers for each image call back. - * @param frameNumber frame number - * @param expLength real time exposure length (in 100ns) or sub frame number (Eiger 32 bit mode only) - * @param packetNumber number of packets caught for this frame - * @param bunchId bunch id from beamline - * @param timestamp time stamp in 10MHz clock (not implemented for most) - * @param modId module id (not implemented for most) - * @param xCoord x coordinates (detector id in 1D) - * @param yCoord y coordinates (not implemented) - * @param zCoord z coordinates (not implemented) - * @param debug debug values if any - * @param roundRNumber (not implemented) - * @param detType detector type see :: detectorType - * @param version version of standard header (structure format) + * @param metadata sls_receiver_header metadata * @param datapointer pointer to data * @param datasize data size in bytes. * @param p pointer to object */ -void GetData(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, - uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, - char* datapointer, uint32_t datasize, void* p){ +void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){ + slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata; + slsReceiverDefs::sls_detector_header detectorHeader = header->detHeader; - PRINT_IN_COLOR (modId?modId:xCoord, - "#### %d GetData: ####\n" - "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu\t\ttimestamp: %llu\t\tmodId: %u\t\t" - "xCoord: %u\t\tyCoord: %u\t\tzCoord: %u\t\tdebug: %u\t\troundRNumber: %u\t\tdetType: %u\t\t" - "version: %u\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", - xCoord, frameNumber, expLength, packetNumber, bunchId, timestamp, modId, - xCoord, yCoord, zCoord, debug, roundRNumber, detType, version, + PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.xCoord, + "#### %d GetData: ####\n" + "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu" + "\t\ttimestamp: %llu\t\tmodId: %u\t\t" + "xCoord: %u\t\tyCoord: %u\t\tzCoord: %u\t\tdebug: %u" + "\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u" + //"\t\tpacketsMask:%s" + "\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", + detectorHeader.xCoord, (long long unsigned int)detectorHeader.frameNumber, + detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId, + (long long unsigned int)detectorHeader.timestamp, detectorHeader.modId, + detectorHeader.xCoord, detectorHeader.yCoord, detectorHeader.zCoord, + detectorHeader.debug, detectorHeader.roundRNumber, + detectorHeader.detType, detectorHeader.version, + //header->packetsMask.to_string().c_str(), ((uint8_t)(*((uint8_t*)(datapointer)))), datasize); } @@ -126,36 +122,32 @@ void GetData(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, ui /** * Get Receiver Data Call back (modified) * Prints in different colors(for each receiver process) the different headers for each image call back. - * @param frameNumber frame number - * @param expLength real time exposure length (in 100ns) or sub frame number (Eiger 32 bit mode only) - * @param packetNumber number of packets caught for this frame - * @param bunchId bunch id from beamline - * @param timestamp time stamp in 10MHz clock (not implemented for most) - * @param modId module id (not implemented for most) - * @param xCoord x coordinates (detector id in 1D) - * @param yCoord y coordinates (not implemented) - * @param zCoord z coordinates (not implemented) - * @param debug debug values if any - * @param roundRNumber (not implemented) - * @param detType detector type see :: detectorType - * @param version version of standard header (structure format) + * @param metadata sls_receiver_header metadata * @param datapointer pointer to data * @param datasize data size in bytes. * @param revDatasize new data size in bytes after the callback. * This will be the size written/streamed. (only smaller value is allowed). * @param p pointer to object */ -void GetData(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, - uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, - char* datapointer, uint32_t &revDatasize, void* p){ +void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){ + slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata; + slsReceiverDefs::sls_detector_header detectorHeader = header->detHeader; - PRINT_IN_COLOR (modId?modId:xCoord, + PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.xCoord, "#### %d GetData: ####\n" - "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu\t\ttimestamp: %llu\t\tmodId: %u\t\t" - "xCoord: %u\t\tyCoord: %u\t\tzCoord: %u\t\tdebug: %u\t\troundRNumber: %u\t\tdetType: %u\t\t" - "version: %u\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", - xCoord, frameNumber, expLength, packetNumber, bunchId, timestamp, modId, - xCoord, yCoord, zCoord, debug, roundRNumber, detType, version, + "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu" + "\t\ttimestamp: %llu\t\tmodId: %u\t\t" + "xCoord: %u\t\tyCoord: %u\t\tzCoord: %u\t\tdebug: %u" + "\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u" + //"\t\tpacketsMask:%s" + "\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", + detectorHeader.xCoord, (long long unsigned int)detectorHeader.frameNumber, + detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId, + (long long unsigned int)detectorHeader.timestamp, detectorHeader.modId, + detectorHeader.xCoord, detectorHeader.yCoord, detectorHeader.zCoord, + detectorHeader.debug, detectorHeader.roundRNumber, + detectorHeader.detType, detectorHeader.version, + //header->packetsMask.to_string().c_str(), ((uint8_t)(*((uint8_t*)(datapointer)))), revDatasize); // if data is modified, eg ROI and size is reduced diff --git a/manual/manual-api/slsDetectorUsers.h b/manual/manual-api/slsDetectorUsers.h deleted file mode 120000 index 307c966ad..000000000 --- a/manual/manual-api/slsDetectorUsers.h +++ /dev/null @@ -1 +0,0 @@ -../../slsDetectorSoftware/slsDetector/slsDetectorUsers.h \ No newline at end of file diff --git a/manual/manual-api/slsReceiverUsers.h b/manual/manual-api/slsReceiverUsers.h deleted file mode 120000 index c8727f200..000000000 --- a/manual/manual-api/slsReceiverUsers.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/slsReceiverUsers.h \ No newline at end of file diff --git a/manual/manual-api/sls_receiver_defs.h b/manual/manual-api/sls_receiver_defs.h deleted file mode 120000 index 1de31caf5..000000000 --- a/manual/manual-api/sls_receiver_defs.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/manual/manual-api/sls_receiver_funcs.h b/manual/manual-api/sls_receiver_funcs.h deleted file mode 120000 index c2ea4ded9..000000000 --- a/manual/manual-api/sls_receiver_funcs.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/manual/manual-api/zmq.h b/manual/manual-api/zmq.h deleted file mode 120000 index f2002f1d8..000000000 --- a/manual/manual-api/zmq.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/zmq.h \ No newline at end of file diff --git a/manual/manual-client/Boards.png b/manual/manual-client/Boards.png new file mode 100644 index 000000000..6365ff013 Binary files /dev/null and b/manual/manual-client/Boards.png differ diff --git a/manual/manual-client/Eiger_short.pdf b/manual/manual-client/Eiger_short.pdf new file mode 100644 index 000000000..5bfa9ada2 Binary files /dev/null and b/manual/manual-client/Eiger_short.pdf differ diff --git a/manual/manual-client/Eiger_short.tex b/manual/manual-client/Eiger_short.tex index 2c704cf74..3108bc3e9 100644 --- a/manual/manual-client/Eiger_short.tex +++ b/manual/manual-client/Eiger_short.tex @@ -18,17 +18,28 @@ \tableofcontents \section{Usage} +\subsection{Short description} +Figure ~\ref{boards} show the readout board basic components on an Eiger half module. An half module can read up to 4 readout chips. +\begin{figure}[t] +\begin{center} +\includegraphics[width=1\textwidth]{Boards} +\end{center} +\caption{Picture with most relevant components of the EIGER readout system. The readout system starts with the Front End Boards (FEB) which performs data descrambling (also converts the packets from 12 $\to$ 16 bits) and rate correction. The BackEndBoard (BEB) has 2x2GB DDR2 memories and can perform data buffering (storing images on board) and data summation (16 bit $\to$ 32 bits). The controls to the detector are passed through the 1Gb, while in most installations, the data are sent out through the 10GB ethernet connection.} +\label{boards} +\end{figure} + + \subsection{Mandatory setup - Hardware} An EIGER single module (500~kpixels) needs: \begin{itemize} -\item A chilled (water+alcohol) at approximately 21~$^{\circ}$C, which needs to dissipate 85~W. For the 9M, a special cooling liquid is required: 2/3 deionized water and 1/3 ESA Type 48. +\item A chilled (water+alcohol) at 21~$^{\circ}$C for a single module (500k pixels), which needs to dissipate 85~W (every module, i.e. for two half boards). For the 9M, 1.5M, a special cooling liquid is required: 2/3 deionized water and 1/3 ESA Type 48. This is important as the high temperature generated by the boards accelerate the corrosion due to Cu/Al reaction and the blockage of the small channels where the liquid flows, in particular near the face of the detector and if it is a parallel flow and not a single loop. The 9M and 1.5M run at 19~$^{\circ}$C. \item A power supply (12~V, 8~A). For the 9~M, a special cpu is give to remotely switch on and off the detector: see section~\ref{bchip100}. -\item 2$\times$1~Gb/s Ethernet connectors to control the detector and, optionally, receive data at low rate. A DHCP server that gives IPs to the 1~Gb/s connectors of the detector is needed. Note that flow control has to be enabled on the switch you are using. -\item 2$\times$10~Gb/s transceivers to optionally, receive data at high rate. +\item 2$\times$1~Gb/s Ethernet connectors to control the detector and, optionally, receive data at low rate. A DHCP server that gives IPs to the 1~Gb/s connectors of the detector is needed. Note that flow control has to be enabled on the switch you are using, if you plan to read the data out from there. If not, you need to implement delays in the sending out of the data. +\item 2$\times$10~Gb/s transceivers to optionally, receive data at high rate. The 10Gb/s transceiver need to match the wavelength (long/short range) of the fibers chosen by the beamline infrastructure. \end{itemize} The equipment scales linearly with the number of modules. -Figure~\ref{fig:1} shows the relationship between the \textbf{Client} (which sits on a beamline control PC), the \textbf{Receiver} (which can run in multiple instances on one or more PCs which receive data from the detector. The receiver(s) does not necessary have to be running on the same PC as the client.) It is important that the receiver is closely connected to the detector (they have to be on the same network). Note that if you implement the 1Gb/s readout only: client, receiver and detector have to be all three in the same network. If you implement the 10Gb/s readout, then client, the 1~GbE of the detector and the receiver have to stay on the 1GbE. But the receiver data receiving device and the 10GbE detector can be on their private network, minimizing the missing packets. +Figure~\ref{fig:1} shows the relationship between the \textbf{Client} (which sits on a beamline control PC), the \textbf{Receiver} (which can run in multiple instances on one or more PCs which receive data from the detector. The receiver(s) does not necessary have to be running on the same PC as the client.) The username under which the receiver runs is the owner of the data files, if using our implementation. It is important that the receiver is closely connected to the detector (they have to be on the same network). Note that if you implement the 1Gb/s readout only: client, receiver and detector have to be all three in the same network. If you implement the 10Gb/s readout, then client, the 1~GbE of the detector and the receiver have to stay on the 1GbE. But the receiver data receiving device and the 10GbE detector can be on their private network, minimizing the missing packets. \begin{figure}[t] \begin{center} @@ -41,7 +52,7 @@ Figure~\ref{fig:1} shows the relationship between the \textbf{Client} (which sit The Client talks to control over 1~Gb Ethernet connection using TCP/IP to the detector and to the receiver. The detector sends data in UDP packets to the receiver. This data sending can be done over 1~Gb/s or 10~Gb/s. \begin{itemize} -\item \textbf{Switch on the detector only after having started the chiller: the 500k single module and the 1.5M at cSAXS have a hardware temperature sensor, which will power off the boards if the temperature is too high. Note that the detector will be power on again as soon as the temperature has been lowered. The 9M will not boot up without the correct waterflow and temperature has it has an integrated flowmeter.} +\item \textbf{Switch on the detector only after having started the chiller: the 500k single module and the 1.5M at cSAXS/OMNY have a hardware temperature sensor, which will power off the boards if the temperature is too high. Note that the detector will be power on again as soon as the temperature has been lowered. The 9M will not boot up without the correct waterflow and temperature has it has an integrated flowmeter.} \item \textbf{Switch on the detector only after having connected all the cables and network. EIGER is unable to get IP address after it has been switched on without a proper network set up. In that case switch off and on the detector again.} \end{itemize} @@ -73,28 +84,22 @@ You can also Check temperatures and water flow in a browser (from the same subne \subsection{Mandatory setup - Receiver} -The receiver is a process run on a PC closely connected to the detector. Open one receiver for every half module board (remember, a module has two receivers!!!) . Go to {\tt{slsDetectorsPackage/bin/}}, \textbf{slsReceiver} should be started on the machine expected to receive the data from the detector. +The receiver is a process run on a PC closely connected to the detector. Open one receiver for every half module board (remember, a module has two receivers!!!) . Go to {\tt{slsDetectorsPackage/build/bin/}}, \textbf{slsReceiver} should be started on the machine expected to receive the data from the detector. \begin{itemize} \item {\tt{./slsReceiver --rx\_tcpport xxxx}} \item {\tt{./slsReceiver --rx\_tcpport yyyy}} \end{itemize} -where xxxx, yyyy are the tcp port numbers. Use 1955 and 1956 for example. Note that in older version of the software {\tt{--mode 1}} was used only for the ``bottom'' half module. Now, the receiver for the bottom is open without arguments anymore, but still in the configuration file one needs to write {\tt{n:flippeddatax 1}}, where {\tt{n}} indicated the half module number, 1 if it is a module. +where xxxx, yyyy are the tcp port numbers. Use 1955 and 1956 for example. The receiver for the bottom is open without arguments but still in the configuration file one needs to write {\tt{n:flippeddatax 1}}, where {\tt{2n+1}} indicated the half module number, 1 if it is a module. \\ Open as many receiver as half module boards. A single module has two half module boards. -From the software version 3.0.1, one can decide weather start a zmq callback from the receiver to the client (for example to visualize data in the slsDetectorGui or another gui). If the zmq steam is not required (cased of the command line for example, one can switch off the streaming with {\tt{./sls\_detector\_put rx\_datastream 0}}, enable it with {\tt{./sls\_detector\_put rx\_datastream 1}}. In the case of inizialising the stream to use the slsDetectorGui, nothing needs to be taken care of by the user. If instead you want to stream the streaming on different channels, the zmq port of the client can be set stealing from the slsDetectorGui stream having {\tt{./sls\_detector\_put zmqport 300y}}. Note taht if this is done globally (not for every half module n independently, then the client automatically takes into account that for every half module, there are 2 zmq stream. The receiver stream {\tt{./sls\_detector\_put rx\_zmqport 300y}} has to match such that the GUI can work. +From the software version 3.0.1, one can decide weather start a zmq callback from the receiver to the client (for example to visualize data in the slsDetectorGui or another gui). If the zmq steam is not required (cased of the command line for example, one can switch off the streaming with {\tt{./sls\_detector\_put rx\_datastream 0}}, enable it with {\tt{./sls\_detector\_put rx\_datastream 1}}. In the case of inizialising the stream to use the slsDetectorGui, nothing needs to be taken care of by the user. If instead you want to stream the streaming on different channels, the zmq port of the client can be set stealing from the slsDetectorGui stream having {\tt{./sls\_detector\_put zmqport 300y}}. Note that if this is done globally (not for every half module n independently, then the client automatically takes into account that for every half module, there are 2 zmq stream. The receiver stream {\tt{./sls\_detector\_put rx\_zmqport 300y}} has to match such that the GUI can work. If one desires to set the zmqport manually, he offset has to be taken into account: {\tt{./sls\_detector\_put 0:rx\_zmqport 300y}}, {\tt{./sls\_detector\_put 1:rx\_zmqport 300y+2}} and so on.. There is an example code that can be compiled in {\tt{manual/manual-api/mainReceiver.cpp}} and gives the executable {\tt{./detReceiver}}, use it with two or more receivers to open all receivers in one single terminal: {\tt{./detReceiver startTCPPort numReceivers withCallback}}, where startTCPPort assumes the other ports are consecutively increased. - - - \subsection{Mandatory setup - Client} -\underline{In the case of cSAXS, the detector software is installed on:}\\ -\underline{/sls/X12SA/data/x12saop/EigerPackage/slsDetectorsPackage} - The command line interface consists in these main functions: \begin{description} \item[sls\_detector\_acquire] to acquire data from the detector @@ -166,15 +171,15 @@ Other important settings that are configured in the {\tt{setup.det}} file are: \begin{itemize} \item {\tt{tengiga 0/1}}, which sets whether the detector is enabled to send data through the 1~or the 10~Gb Ethernet. \item {\tt{flags parallel/nonparallel}}, which sets whether the detector is set in parallel acquisition and readout or in sequential mode. This changes the readout time of the chip and affects the frame rate capability (faster is {\tt{parallel}}, with higher noise but needed when the frame rate is $>2$~kHz. -\item {\tt{dr 32/16}} sets the detector in autosumming mode (32 bit counter or not autosumming, 12 bit out of the chip). This is strictly connected to what is required for the readout clock of chip. See next point. +\item {\tt{dr 32/16/8/4}} sets the detector in autosumming mode (32 bit counter or not autosumming, 12 bit out of the chip). This is strictly connected to what is required for the readout clock of chip. See next point. \item {\tt{clkdivider 0/1/2}}. Changes the readout clock: 200, 100, 50~MHz (also referred to as full, half, quarter speed). Note that autosumming mode ({\tt{dr 32}} only works at {clkdivider 2}=quarter speed). By selecting Refer to readout timing specifications in~section\ref{timing} for how to set the detector. -\item {\tt{flags continuous/storeinram}}. Allows to take frame continuously or storing them on memory. Normally {\tt{continuous}} should be used. Enabling the {\tt{stroreinram}} mode allows you to obtain the maximum frame rate, but at the expenses to have to receive the data all at the end of the acquisition. Refer to readout timing specifications in section~\ref{timing} for how to set the detector. +\item {\tt{flags continuous/storeinram}}. Allows to take frame continuously or storing them on memory. Users should use the {\tt{continuous}} flags. Enabling the {\tt{stroreinram}} flag makes the data to be sent out all at the end of the acquisition. Refer to readout timing specifications in section~\ref{timing} for how to set the detector. Examples will be given in section~\ref{}. \end{itemize} One should notice that, by default, by choosing the option {\tt{dr 32}}, then the software automatically sets the detector to {\tt{clkdivider 2}}. By choosing the option {\tt{dr 16}}, the software automatically sets the detector to {\tt{clkdivider 1}}. One needs to choose {\tt{clkdivider 0}} after setting the {\tt{dr 16}} option to have the fastest frame rate. We would recommend expert users (beamline people) to write their parameters file for the users. -\section{API versioning} +\section{API versioning} \label{api} The eigerDetectorServer running on the boards has a versioning API scheme that will make it crash if used with a wrong firmware. You can also check your versioning by hand with the code: \begin{verbatim} @@ -194,12 +199,18 @@ Killing and starting the server on the boards allows you to check the firmware v \section{Setting up the threshold} \begin{verbatim} sls_detector_put 0-trimen N xxxx yyyy zzzz -sls_detector_put 0-settings standard #[veryhighgain/highgain/lowgain/verylowgain] also possible -sls_detector_put 0-threshold energy_in_eV +sls_detector_put 0-settings standard +sls_detector_put 0-threshold energy_in_eV standard \end{verbatim} The first line requires to specify how many ({\tt{N}}) and at which energies in eV {\{tt{xxxx}}, {\tt{yyyy}}, {\tt{zzzz}} and so on) trimmed files were generated (to allow for an interpolation). This line should normally be included into the {\tt{mydetector.config}} file and should be set for you by one of the detector group. NORMALLY, in this new calibration scheme, only {\tt{settings standard}} will be provided to you, unless specific cases to be discussed. -The threshold at 6000 eV , for example would be set as:{\tt{sls\_detector\_put 0-threshold 6000}}. +The threshold at 6000 eV , for example would be set as:{\tt{sls\_detector\_put 0-threshold 6000 standard}}. + +For \E, at the moment normally only {\tt{standard}} settings are possible. + {\tt{lowgain}}, {\tt{verylowgain}}, {\tt{veryhighgain}} and {\tt{highgain}} are theoretically possible, but we never calibrate like this. They could be implemented later if needed. + +Notice that setting the threshold actually loads the trimbit files (and interpolate them between the closest calibration energies) so it is time consuming. +The threshold is expressed in (eV) as the proper threshold setting, i.e. normally is set to 50\% of the beam energy. We have added a special command, {\tt{thresholdnotb}}, which allows to scan the threshold energy without reloading the trimbits at every stage. One can either keep the trimbits at a specific value (es.32 if the range of energies to scan is large) or use the trimbits from a specific energy (like a central energy). \begin{verbatim} @@ -216,12 +227,7 @@ sls_detector_put 0-period 0[time_is_s] \end{verbatim} In this acquisition 10 consecutive 1~s frames will be acquired. Note that {\tt{period}} defines the sum of the acquisition time and the desired dead time before the next frame. If {\tt{period}} is set to 0, then the next frame will start as soon as the detector is ready to take another acquisition. \\ -For \E, at the moment 5 settings are possible: {\tt{standard}}, {\tt{lowgain}}, {\tt{verylowgain}}, {\tt{veryhighgain}} and {\tt{highgain}}. According to the setting chosen, one can reach different requirements (low noise or high rate). Refer to the settings requirements for your detector.\\ -Notice that the option {\tt{settings standard/highgain/lowgain/veryhighgain/verylowgain}} actually loads the trimbit files so it is time consuming. Only setting the {\tt{threshold}} does not load trimbit files. - -The threshold is expressed in (eV) as the proper threshold setting, i.e. normally is set to 50\% of the beam energy. - -\underline{At cSAXS, the {\tt{settingsdir}} and {\tt{caldir}} are in}\\\underline{/sls/X12SA/data/x12saop/EigerPackage/calibrations/}\\ +%\underline{At cSAXS, the {\tt{settingsdir}} and {\tt{caldir}} are in}\\\underline{/sls/X12SA/data/x12saop/EigerPackage/calibrations/}\\ You need to setup where the files will be written to \begin{verbatim} @@ -247,23 +253,28 @@ sls_detector_get receiver \end{verbatim} There is a more complex way of performing an acquisition, that is useful for debugging and in case one wants a non blocking behavior: -\begin{itemize} + +You can then reset to zero the number of frames caught, then start the receiver and the detector: +\begin{enumerate} +\item {\tt{sls\_detector\_put 0-resetframescaught 0}} \item {\tt{sls\_detector\_put 0-receiver start}} \item {\tt{sls\_detector\_put 0-status start}} -\end{itemize} +\end{enumerate} You can poll the detector status using: \begin{verbatim} sls_detector_get 0-status \end{verbatim} -When the detector is {\tt{idle}}, then you need to stop the receiver doing: -\begin{itemize} +When the detector is {\tt{idle}}, then the acquisition is done but the receiver could still be receiving data. If you want, you can check if the receiver is finished receiving as many frames as you were expecting (this is optional but required for many many frames acquisition or when using some delays to send data at very high frame rate. +\begin{enumerate} +\setcounter{enumi}{3} +\item {\tt{sls\_detector\_get framescaught}} +\end{enumerate} +Then you can stop the receiver as well now: +\begin{enumerate} +\setcounter{enumi}{4} \item {\tt{sls\_detector\_put 0-receiver stop}} -\end{itemize} -You can then reset to zero the number of frames caught, if you desire: -\begin{itemize} -\item {\tt{sls\_detector\_put 0-resetframescaught 0}} -\end{itemize} +\end{enumerate} The detector will not accept other commands while acquiring. If an acquisition wishes to be properly aborted, then: \begin{itemize} @@ -275,7 +286,7 @@ this same command can be used after a non proper abortion of the acquisition to IMPORTANT: to have faster readout and smaller dead time, one can configure {\tt{clkdivider}}, i.e. the speed at which the data are read, i.e. 200/100/50~MHz for {\tt{clkdivider 0/1/2}} and the dead time between frames through {\tt{flags parallel}}, i.e. acquire and read at the same time or acquire and then read out. The configuration of this timing variables allows to achieve different frame rates. NOTE THAT IN EIGER, WHATEVER YOU DO, THE FRAME RATE LIMITATIONS COME FROM THE NETWORK BOTTLENECK AS THE HARDWARE GOES FASTER THAN THE DATA OUT. -In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from the boards (independent on how the chip is set), the continuous frame rates are listed in table~\ref{tcont}: +In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from the boards (independent on how the chip is set), the continuous frame rates are listed in table~\ref{tcont}. \begin{table} \begin{tabular}{|c|c|c|c|} \hline @@ -294,10 +305,9 @@ GbE & dynamic range & continuos maximum frame rate(Hz) & minimum period ($\mu$s) 10 & 4 & \textbf{10240} & 98\\ \hline \end{tabular} -\caption{Frame rate limits for the CONTINUOS streaming out of images.} +\caption{Frame rate limits for the CONTINUOS streaming out of images, i.e. the data rate out is just below 1Gb/s or 10Gb/s.} \label{tcont}\end{table} -Note that in the {\tt{continuous}} flag mode, some buffering is still done on the memories, so a higher frame rate than the proper real continuous one can be achieved. Still, this extra buffering is possible till the memories are not saturated. -The number of images that can be stored on memories are listed in table~\ref{timgs}: + Note that in the {\tt{continuous}} flag mode, some buffering is still done on the memories, so a higher frame rate than the proper real continuous one can be achieved. Still, this extra buffering is possible till the memories are not saturated. The number of images that can be stored on the DDR2 on board memories are listed in table~\ref{timgs}. \begin{table} \begin{tabular}{|c|c|} \hline @@ -314,72 +324,184 @@ dynamic range & images\\ \label{timgs} \end{table} -The maximum frame rate achievable with 10~GbE, {\tt{dr 16}}, {\tt{flags continuous}}, {\tt{flags parallel}},{\tt{clkdivider 0}}, \textbf{6.1~kHz}. This is currently limited by the connection between the Front End Board and the Backend board. We expect the 32 bit mode limit to be \textbf{2~kHz} ({\tt{clkdivider 2}}). +The maximum frame rate achievable with 10~GbE, {\tt{dr 16}}, {\tt{flags continuous}}, {\tt{flags parallel}},{\tt{clkdivider 0}}, \textbf{6.1~kHz}. This is currently limited by the connection between the Front End Board and the Backend board. We expect the 32 bit mode limit, internally, to be \textbf{2~kHz} ({\tt{clkdivider 2}}). In dynamic range {\tt{dr 8}} the frame rate is \textbf{11~kHz} and for{\tt{dr 4}} is \textbf{22~kHz}. For 4 and 8 bit mode the frame rate are directly limited by the speed of the detector chip and not by the readout boards. -In table~\ref{tframes} is a list of all the readout times in the different configurations: +\subsection{Minimum time between frames and Maximum frame rate} + +We need to leave enough time between an exposure and the following. This time is a combination of the time required by the chip, by the readout boards and eventually extra time to reduce some appearance of cross talk noise between the digital and analog parts of the chip. +\textbf{It is essential to set the {\tt{period}} of the detector, defined as the {\tt{exptime}} plus an extra time, that needs to be at least the chip/board readout time. If this is set wrong (it is $<$ {\tt{exptime}} plus chip/board readout time), then the detector takes the minimum time it can, but you are in a not controlled frame rate situation.} + +The expected time difference between frames given by the pure chip readout time is in Table~\ref{tchipro}. \begin{tiny} \begin{table} \begin{flushleft} -\begin{tabular}{|c|c|c|c|c|c|c|c|} +\begin{tabular}{|c|c|c|c|} \hline -\tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{readout t($\mu$s)} & \tiny{max frame rate (kHz)} & \tiny{max exptime ($\mu$s)} & \tiny{min period ($\mu$s)} & \tiny{max imgs (nominal/our network)}\\ +\tiny{dr} & \tiny{clkdivider} & \tiny{expected chip readout t($\mu$s)} & \tiny{measured chip readout t($\mu$s)}\\ \hline -4 & 0 & parallel & 3.4 & 22 & 40 & 44 & 30k/50k\\ -\hline -4 & 0 & nonparallel & 44 & 21 & 3 & 49 & 30k/50k\\ -\hline -4 & 1 & parallel & 6 & 10.5 & 85 & 92 & 30k/100k\\ -\hline -4 & 1 & nonparallel & 88.7 & 10.5 & 3 & 93 & 30k/100k\\ -\hline -4 & 2 & parallel & 11.2 & 5.4 & 185 & 197 & infinite\\ -\hline -4 & 2 & nonparallel & 176.5 & 5.4 & 3 & 180 & infinite\\ +4 & 0 & 41 & 40\\ +4 & 1 & 82 & 84\\ +4 & 2 & 123 & 172\\ \hline \hline -8 & 0 & parallel & 3.4 & 11.1 & 85 & 89 & 15k/24k\\ -\hline -8 & 0 & nonparallel & 85.7 & 11.1 & 3 & 91 & 15k/24k\\ -\hline -8 & 1 & parallel & 6.1 & 5.7 & 174 & 181 & 15k/52k\\ -\hline -8 & 1 & nonparallel & 170.5 & 5.7 & 3 & 175 & 15k/52k\\ -\hline -8 & 2 & parallel & 11.2 & 2.9 & 330 & 342 & infinite\\ -\hline -8 & 2 & nonparallel & 340.3 & 2.9 & 3 & 344 & infinite\\ +8 & 0 & 82 & 82\\ +8 & 1 & 164 & 167\\ +8 & 2 & 328 & 336\\ \hline \hline -16 & 0 & parallel & 3.4 & 6 & 164 & 168 & 8k/12k\\ -\hline -16 & 0 & nonparallel & 126 & 3.4& 164 & 295 & 8k/23k\\ -\hline -16 & 1 & parallel & 6.1 & 2.9& 339 & 346 & 8k/28k\\ -\hline -16 & 1 & nonparallel & 255 & 1.7& 339 & 592 & infinite\\ -\hline -16 & 2 & parallel & 11 & 1.5& 66 & 78 & infinite \\ -\hline -16 & 2 & nonparallel & 504 & 0.85 & 7 & 512 & infinite\\ -\hline -\hline -32 & 2 & parallel & 11 & 2& & &\\ -\hline -32 & 2 & nonparallel & 504 & $<2$& & &\\ +12 & 0 & 123 &122\\ +12 & 1 & 246 & 251\\ +12 & 2 & 491 & 500\\ \hline \end{tabular} -\caption{Readout settings. The {\tiny{min exptime}} possible is 5$-$10~$\mu$s. This is due to the time to pass the pixel enable signal in the whole chip.} +\caption{Readout time required from the chip to readout the pixels. The numbers are obtained using equation~\ref{dtnonparallel}.} +\label{tchipro} +\end{flushleft} +\end{table} +\end{tiny} + +The {\tt{period}} is s is defined as: +\begin{equation} \label{period} +\textrm{period} = \textrm{exptime} + \textrm{minimum time between frames} +\end{equation} +where the 'minimum time between frames' and the minimum period will be discussed in Table~\ref{tframes}. +\begin{tiny} +\begin{table} +\begin{flushleft} +\begin{tabular}{|c|c|c|c|c|c|c|} +\hline +\tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{t between frames($\mu$s) } & \tiny{max frame rate (kHz)} & \tiny{min period ($\mu$s)} & \tiny{max imgs (nominal/our network)}\\ +\hline +4 & 0 & parallel & 3.4 & 22 & 44 & 30k/50k\\ +\hline +4 & 1 & parallel & 6 & 10.5 & 92 & 30k/100k\\ +\hline +4 & 2 & parallel & 11.2 & 5.4 & 197 & infinite\\ +\hline +\hline +8 & 0 & parallel & 3.4 & 11.1 & 89 & 15k/24k\\ +\hline +8 & 1 & parallel & 6.1 & 5.7 & 181 & 15k/52k\\ +\hline +8 & 2 & parallel & 11.2 & 2.9 & 342 & infinite\\ +\hline +\hline +16 & 0 & parallel & 3.4 & 6.1 & (126+38)* =164 & 8k/12k\\ +\hline +16 & 0 & nonparallel & 126 & 5.6 & (126+52)*= 179 & 8k/23k\\ +\hline +16 & 1 & parallel & 6.1 & 3.9 & 257 & 8k/28k\\ +\hline +16 & 1 & nonparallel & 255 & 3.3 & 303 & infinite\\ +\hline +16 & 2 & parallel & 11 & 1.9 & 526 & infinite \\ +\hline +16 & 2 & nonparallel & 504 & 1.8 & 555 & infinite\\ +\hline +%32 & 2 & parallel & 11 & 2& & &\\ +%\hline +%32 & 2 & nonparallel & 504 & $<2$& & &\\ +%\hline +\end{tabular} +\caption{Readout settings. The {\tiny{min exptime}} possible is 5$-$10~$\mu$s. This is due to the time to pass the pixel enable signal in the whole chip. The time between frames has been measured with the oscilloscope and the maximum frames rate has been tested with an external gating from a pulse generator at known frequence. The minimum period is obtained as 1/$\textrm{max frame rate}$.} \label{tframes} \end{flushleft} \end{table} \end{tiny} -\textbf{As if you run too fast, the detector could become noisier, it is important to match the detector settings to your frame rate. This can be done having more parameters files and load the one suitable with your experiment.} We experienced that {\tt{highgain}} settings could not be used at 6~kHz. -\textbf{We recommend to use the detector in 32 bit mode with {\tt{clkdivider 2}}, {\tt{flags parallel}}. We recommend to use the detector in 16 bit mode with {\tt{clkdivider 1}}, {\tt{flags parallel}}}. In general, choose first the desired dead time: this will tell you if you want to run in parallel or non parallel mode. Then, choose the maximum frame rate you want to aim, not exceeding what you aim for not to increase the noise. +\textbf{As if you run too fast, the detector could become noisier, it is important to match the detector settings to your frame rate. This can be done having more parameters files and load the one suitable with your experiment.} We experienced that with low energy settings could not reach 6~kHz and no noise. + +In 16 bit mode, it could make sense, in case of noise and low threshold to either reduce the frame rate: +\begin{equation} +\textrm{new period} = \textrm{exptime} + \textrm{minimum time between frames} + (\textrm{10$-$20 }\mu \textrm{s}) +\end{equation} +to let the signal settle or, if the frame rate is important, leave the {\tt{period}} at the same value but reduce the {\tt{exptime}}: +\begin{equation} +\textrm{new exptime} = \textrm{old exptime} - (\textrm{10$-$20 }\mu \textrm{s}) +\end{equation} + +In general, choose first the desired dead time: this will tell you if you want to run in parallel or non parallel mode, although most likely it is parallel mode. Then, choose the maximum frame rate you want to aim, not exceeding what you aim for not to increase the noise. In 4 and 8 bit modes it makes no sense to run nonparallel as the exposure time is too small compared to the readout time. + +\subsubsection{4 and 8 bit mode} +In {\tt{parallel}} mode, the minimum time between frames is due to the time required to latch the values of the counter with capacitors. These values are determined in firmware and they can be estimated as: + +\begin{equation} \label{dtparallel} +\textrm{time between frames, parallel} = 4 \mu s \cdot (clkdivider+1) +\end{equation} + +This time is independent on the {\tt{dr}}. + +In {\tt{nonparallel}} mode, it is easily possible to calculate the required asic readout time. +Indeed a block of (8*256) pixels are readout, the bits pixel are the {\tt{dr}} and the speed of readout is 5ns/bit *({\tt{clkdivider}}+1) : + +\begin{equation}\label{dtnonparallel} +\textrm{asics readout time} = 5ns/bit \cdot 2^{(clkdivider+1)} \cdot dr \cdot (8*256) + 4 \mu s \cdot (clkdivider+1) +\end{equation} + +While we expose the next frame, we still need to readout the previous frame, so we need to guarantee that the period is large enough at least to readout the frame. So the maximum frame rate has to be $1/(\textrm{asic readout time})$. The minimum period has to be equal to the asic readout time. + +\subsubsection{16 bit mode} + +A similar situation happens in 16 bit mode, where this is more complicated because of three things: +\begin{enumerate} +\item The chip actual {\tt{dr}} is 12 bit +\item The chip is readout as 12-bit/pixel, but the FEB inflates the pixel values to 16-bits when it passes to the BEB. This means that effectively the FEB to BEB connection limits the data throughput in the same way as if the {\tt{dr}} of the chip would really be 16 bits. +\item While in 4 and 8 bit mode it makes no sense to run in {\tt{nonparallel}} mode as the exptime/dead time ratio would be not advantageous, in 16 bit mode, one can choose how to run more freely. +\end{enumerate} + +If we are in parallel mode, the dead time between frames, is also here described by equation~\ref{dtparallel}. If we are in {\tt{nonparallel}} mode, the dead time between frames is defined by \ref{dtnonparallel} ONLY for {\tt{clkdivider}} 1 and 2. So the maximum frame rate has to be $1/(\textrm{chip readout time})$ in this case. Only for {\tt{clkdivider}} 0 we hit some limitation in the bandwidth of The FEB $\to$ BEB connection. In this case, the maximum frame rate is lowered compared to what expected. + +\subsubsection{32 bit mode} +The autosumming mode of Eiger is the intended for long exposure times (frame rate of order of 100Hz, PILATUS like). A single acquisition is broken down into many smaller 12-bit acquisitions, each of a {\tt{subexptime}} of 2.621440~ms by default. Normally, this is a good default value to sustain an intensity of $10^6$ photons/pixel/s with no saturation. To change the value of {\tt{subexptime}} see section~\ref{advanced}. + +The time between 12-bit subframes are listed in table~\ref{t32bitframe}. +\begin{tiny} +\begin{table} +\begin{flushleft} +\begin{tabular}{|c|c|c|c|c|c|} +\hline +\tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{t difference between subframes($\mu$s)} & \tiny{max internal subframe rate (kHz)} & \tiny{maximum frame rate (Hz)}\\ +\hline +32 & 2 & parallel & 12 & 2 & 170\\ +\hline +32 & 2 & nonparallel & 504 & $<2$ & 160\\ +\hline +\end{tabular} +\caption{Timing for the 32bit case. The maximum frame rate has been computed assuming 2 subframes of default {\tt{subexptime}} of 2.62144 ms.} +\label{t32bitframe} +\end{flushleft} +\end{table} +\end{tiny} + +\textbf{The exposure time brokend up rounding up to the full next complete subframe that can be started.} +The number of subframes composing a single 32bit acquisition can be calculated as: +\begin{equation} +\textrm{\# subframes}= (int) (\frac{\textrm{exptime (s)}}{\textrm{subexptime (s) + difference between frames (s)}}+0.5) +%\label{esubframes} +\end{equation} +This also means that {\tt{exptime}}$<${\tt{subexptime}} will be rounded to{\tt{subexptime}}. If you want shorter acquisitions, either reduce the {\tt{subexptime}} or switch two 16-bit mode (you can always sum offline if needed). + +The UDP header will contain, after you receive the data, the effective number of subframe per image (see section~\ref{UDP}) as "SubFrame Num or Exp Time", i.e. the number of subframes recorded (32 bit eiger). +The effective time the detector has recorded data can be computed as: +\begin{equation} +\textrm{effective exptime}=(\textrm{subexptime})\cdot (\textrm{\# subframes}) +%\label{esubframes} +\end{equation} + +In the future release, a configurable extra time difference between subframes will be introduced for the parallel mode, so that some noise appearing in detectors at low threshold can be removed. This will enlarge the time difference between frames form the default 12~$\mu$s to something configurable, expected to be 15-40~$\mu$s (for the 9M it is currently 200~$\mu$s due to a noisier module). + +\section{External triggering options}\label{triggering} +The detector can be setup such to receive external triggers. Connect a LEMO signal to the TRIGGER IN connector in the Power Distribution Board (see Fig.). The logic 0 for the board is passed by low level 0$-$0.7~V, the logic 1 is passed to the board with a signal between 1.2$-$5~V. Eiger is 50~$\Omega$ terminated. By default the positive polarity is used (negative should not be passed to the board). + +\begin{figure}[t] +\begin{center} +\includegraphics[width=.4\textwidth]{tiggerIN} +\end{center} +\caption{\textbf{Trigger INPUT} (looking at a single module from the back, top) is the \textbf{rightmost, down}.} +\label{triggerIN} +\end{figure} -\section{External triggering options} -The detector can be setup such to receive external triggers. Connect a LEMO signal to the TRIGGER IN connector in the Power Distribution Board. The logic 0 for the board is passed by low level 0$-$0.7~V, the logic 1 is passed to the board with a signal between 1.2$-$5~V. Eiger is 50~$\Omega$ terminated. By default the positive polarity is used (negative should not be passed to the board). \begin{verbatim} sls_detector_put 0-timing [auto/trigger/burst_trigger/gating] sls_detector_put 0-frames x @@ -390,17 +512,17 @@ No timeout is expected between the start of the acquisition and the arrival of t Here are the implemented options so far: \begin{itemize} -\item {\tt{auto}} is the software controlled acquisition, where {\tt{exptime}} and {\tt{period}} have to be set. -\item {\tt{trigger}} 1 frame taken for 1 trigger. You {\tt{frames}} needs to be 1 always, {\tt{cycles}} can be changed and defines how many triggers are considered. In the GUI this is called trigger exposure series. -\item {\tt{burst\_trigger}} gets only 1 trigger, but allows to take many frames. With {\tt{frames}} one can change the number of frames. {\tt{cycles}} needs to be 1. In the gui it is called trigger readout. -\item{\tt{gating}} allows to get a frame only when the trigger pulse is gating. Note that in this case the exp time and period only depend on the gating signal. {\tt{cycles}} allows to select how many gates to consider. +\item {\tt{auto}} is the software controlled acquisition (does not use triggers), where {\tt{exptime}} and {\tt{period}} have to be set. Set number of cycles (i.e. triggers) to 1 using {\tt{cycles}}. Set number of frames using {\tt{frames}}. +\item {\tt{trigger}} 1 frame taken for 1 trigger. Your {\tt{frames}} needs to be 1 always, {\tt{cycles}} can be changed and defines how many triggers are considered. {\tt{exptime}} needs to be set. In the GUI this is called trigger exposure series. +\item {\tt{burst\_trigger}} gets only 1 trigger, but allows to take many frames. With {\tt{frames}} one can change the number of frames. {\tt{cycles}} needs to be 1. {\tt{exptime}} and {\tt{period}} have to be set. In the gui it is called trigger readout. +\item{\tt{gating}} allows to get a frame only when the trigger pulse is gating. Note that in this case the exp time and period only depend on the gating signal. {\tt{cycles}} allows to select how many gates to consider. Set number of frames to 1 using {\tt{frames}}. \end{itemize} Hardware-wise, the ENABLE OUT signal outputs when the chips are really acquiring. This means that the single subframes will be output in 32 bit mode. The TRIGGER OUT outputs the sum-up-signal at the moment (which is useless). This will be changed in the future to output the envelop of the enable signal. We are planning to change some functionality, i.e. unify the {\tt{trigger}} and {\tt{burst}} trigger modes and make both {\tt{frames}} and {\tt{cycles}} configurable at the same time. -\section{Autosumming and rate corrections} +\section{Autosumming and rate corrections} \label{advanced} In the case of autosumming mode, i.e, {\tt{dr 32}}, the acquisition time ({\tt{exptime}} is broken in as many subframes as they fit into the acquisition time minus all the subframes readout times. By default the {\tt{subexptime}} is set to 2.621440~ms. This implies that 12 bit counter of \E will saturate when the rate is above or equal to 1.57~MHz/pixel. The minimum value is of order of 10~ns (although as explained values smaller than 500~$\mu$s do not make sense). The maximum value is 5.2~s. @@ -417,7 +539,7 @@ In the EIGER on board server, this look-up table is generated assuming that the n_d= n_i \cdot exp(-n_i \cdot \tau), \label{rate} \end{equation} -where $\tau$ represents an effective parameter for the dead time and the loss in efficiency. The look-up table is necessary as we are interested to obtain $c_i(c_d)$ and equation~\ref{rate} is not invertible. One needs to notice that the paralizable counter model to create a look-up tables applies only if photons arrive with a continuous pattern (like at the SLS). If photons are structured in fewer but intenser bunches, deviations may arise. This is the case for some operation modes at the ESRF. For those cases we are studying how to correct, probably from a simulated correction tables if an analytical curve cannot be found. +where $\tau$ represents an effective parameter for the dead time and the loss in efficiency. The look-up table is necessary as we are interested to obtain $c_i(c_d)$ and equation~\ref{rate} is not invertible. One needs to notice that the paralyzable counter model to create a look-up tables applies only if photons arrive with a continuous pattern (like at the SLS). If photons are structured in fewer but intenser bunches, deviations may arise. This is the case for some operation modes at the ESRF. For those cases we are studying how to correct, probably from a simulated correction tables if an analytical curve cannot be found. \textbf{In the new calibration scheme, $\tau$ is given as a function of the energy. It is loaded from the trimbit files and interpolation between two trimbit files are performed.} One needs to make sure the appropriate $\tau$ value is written in the trimbit files, then need to load the appropriate {\tt{settings}} and {\tt{vthreshold}} before. Online rate corrections can be activated for {\tt{dr=32}}. They are particularly useful in the autosumming mode as every single subframe is corrected before summing it. To correct for rate, the subframe duration has to be known to the correction algorithm. Rate corrections for {\tt{dr=16}} will be activated as well in the next firmware release. @@ -454,20 +576,37 @@ Here is a list of limits that should be checked: If \textbf{dr} is 32 and \textbf{clkdivider} is not 2, whatever the detector gets out is wrong (the boards cannot properly keep up) \item If the variable \textbf{frames} is greater than what the memory can store (table~\ref{timgs}) and the frame rate exceed the continuos streaming (table~\ref{tcont}), limits on the maximum number of images need to be implemented if the period is lower than the one listed in table~\ref{tcont}. Check table~\ref{tframes} to see the different cases. \item Running at a speed that does not support the frame rate you are asking: see table~\ref{tframes} to check if the frame rate (\textbf{period}) you are asking is compatible with the \textbf{clkdivider} you are asking. -\item Running at a redout time that does not support the frame rate you are asking. Check table~\ref{tframes} to check if the frame rate (\textbf{period}) you are asking is compatible with the \textbf{flags} you are asking. +\item Running at a readout time that does not support the frame rate you are asking. Check table~\ref{tframes} to check if the frame rate (\textbf{period}) you are asking is compatible with the \textbf{flags} you are asking. \item The minimum allowed value for \textbf{exptime} should be 10~$\mu$s. \item By default the {\textbf{subexptime}} is set to 2.621440~ms. Values smaller than 500~$\mu$s do not make sense. The maximum value is 5.2~s. This limits should be checked. \end{enumerate} +Here is a list of parameters that should be reset: +\begin{enumerate} +\item \textbf{resetframescaught} should be reset to zero after every acquisition taken with {\tt{receiver start}},{\tt{status start}},{\tt{receiver stop}}. If the acquisition is taken with {\tt{sls\_detector\_acquire}}, there is no need to reset this. +\item After changing the {\tt{timing}} mode of the detector, one should reset to '1' the unused value, in that specific timing mode, between \textbf{frames} and \textbf{cycles}. See section~\ref{triggering} for how to use the timing. At the present moment the detector will acquire more frames than planned if the variable not used between \textbf{frames} and \textbf{cycles} is not reset. In future releases, the unused variable will be ignored. Still resetting is a good practice. + +\end{enumerate} \section{1Gb/s, 10Gb/s links} \subsection{Checking the 1Gb/s, 10Gb/s physical links}\label{led} LEDs on the backpanel board at the back of each half module signal: \begin{itemize} -\item the 1Gb/s physical link is signaled by the most external LED (should be green) -\item the 10Gb/s physical link is signaled by the second most external LED next to the 1Gb/s one (should be green) +\item the 1Gb/s physical link is signaled by the most external LED (should be green). For top half modules is at the extreme left. For bottom half modules is at the extreme right. +\item the 10Gb/s physical link is signaled by the second most external LED next to the 1Gb/s one (should be green). \end{itemize} +\begin{figure}[t] +\begin{center} +\includegraphics[width=.7\textwidth]{LEDSim} +\end{center} +\caption{1 and 10GB LEDs position.} +\label{fLEDs} +\end{figure} + + + + \subsection{Delays in sending for 1Gb/s, 10Gb/s, 10Gb flow control, receiver fifo} Extremely advanced options allow to: @@ -486,10 +625,10 @@ Extremely advanced options allow to: \end{verbatim} As example: \begin{verbatim} -for X in \$(seq 0 4); do ./sls_detector_put \$X:txndelay_left \$((X*100000)); done +for X in $(seq 0 4); do ./sls_detector_put $X:txndelay_left $((X*100000)); done \end{verbatim} \begin{verbatim} -./sls_detector_put \$X:txndelay_right \$((X*100000)); X=\$((X+1)); done +./sls_detector_put $X:txndelay_right $((X*100000)); X=$((X+1)); done \end{verbatim} \item Set transmission delay of the entire frame. This is required as you want to finish sending the first frame to all receivers before starting sending the second frame to the receivers with shorter delay time. This value has to be greater than the maximum of the transmission delays of each port. @@ -539,9 +678,15 @@ Very important is to activate the flow control in 10Gb (in 1Gb it is on by defau \end{verbatim} Set the transmission delays as explained in the manual. +It can help to increase the fifo size of the receiver to {\tt{rx\_fifodepth}} to 1000 images +\begin{verbatim} +./sls_detector_put rx_fifodepth 1000 +\end{verbatim} +One needs to keep into account that in 16 bit mode for 1 image we expect each slsReceiver to allocate 0.5MB. So for 1000 images, we expect 500MB memory for each receiver. This can be monitored in Linux with "top" or "free -m". + \section{Offline processing and monitoring} -\subsection{Data out of the detector: UDP packets} +\subsection{Data out of the detector: UDP packets}\label{UDP} The current UDP header format is described in figure~\ref{UDPheader}. \begin{figure}[t] @@ -608,9 +753,9 @@ Header Version : 1 byte Note that if one wants to reconstruct the real time the detector was acquiring in 32 bit (autosumming mode), one would have to multiply the SubExptime (ns) for the SubFrame Number. \subsection{Offline image reconstruction} -The offline image reconstruction is in {\tt{slsDetectorsPackage/slsImageReconstruction}}. +The offline image reconstruction{\tt{slsImageReconstruction}} is not part of the package anymore. -The detector writes a raw file per receiver. An offline image reconstruction executable has been written to collate the possible files together and produce cbf files. The executable uses the CBFlib-0.9.5 library (downloaded from the web as it download some architecture dependent packages at installation).\\ +The detector writes 2 raw files per receiver. An offline image reconstruction executable has been written to collate the possible files together and produce cbf files. The executable uses the CBFlib-0.9.5 library (downloaded from the web as it download some architecture dependent packages at installation).\\ \underline{At cSAXS, the CBFlib-0.9.5 has been compiled -such that the required packages are}\\\underline{ downloaded in /sls/X12SA/data/x12saop/EigerPackage/CBFlib-0.9.5.}\\ To use it for a single module: @@ -626,7 +771,7 @@ cbfMaker [filename] [pixels x] [pixels y] ([singlemodulelongside_x] [start det]) \end{verbatim} eg. {\tt cbfMaker /scratch/run\_63\_d0\_f000000000000\_3.raw 3072 512 1 0}.\\ -The {\tt{[singlemodulelongside\_x]}} and {\tt{[start det]}} param are optional. Defaults are ``1'', the detector long side is on the x coordinate and start to reconstruct from module 0. +The {\tt{[singlemodulelongside\_x]}} {\tt{[option to interpolate gap pixels]}} param are optional. Defaults are ``1'', the detector long side is on the x coordinate and start to reconstruct from module 0. The executables: \begin{verbatim} bcfMaker1.5M [file_name_with_dir] @@ -694,7 +839,7 @@ Start the server again: \begin{verbatim} ./eigerDetectorServer & \end{verbatim} -\textbf{Note that the server appropiate for the software version used is located inside the package: {\tt{slsDetectorsPackage/serverBin/eigerDetectorServerxx.yy.}}}. +\textbf{Note that the server appropriate for the software version used is located inside the package: {\tt{slsDetectorsPackage/serverBin/eigerDetectorServerxx.yy.}}}. To copy the detector server on many boards, a script can be implemented on the lines of: \begin{verbatim} @@ -716,7 +861,7 @@ cd executables ./boot_recovery \end{verbatim} \end{enumerate} -In both case, after booting, only the central one should be on green and red alternating. +In both case, after booting, only the central LED should be on green and red alternating. From a terminal, do: \begin{verbatim} @@ -777,17 +922,9 @@ To load the special noise file look at {\tt{settingsdir/eiger/standard/eigernois sls_detector_put trimbits ../settingsdir/eiger/standard/eigernoise \end{verbatim} -\section{Running the (9M at cSAXS. For now)} -\begin{itemize} -\item login as {\tt{x12saop@xbl-daq-27}} -\item {\tt{setup\_eiger}} \#loads environmental variables and brings you to the right directory to execute commands -\item slsReceiverScript3 1991 36 \# from one shell.. opens 36 receivers -\item p config ../../eiger\_9m\_10gb\_xbl-daq-27\_withbottom.config -\end{itemize} - \section{Troubleshooting} \subsection{Cannot successfully finish an acquisition} -\subsubsection{only master module return from acquisition} +\subsubsection{Only master module return from acquisition} When no packets are received AND detector states in 'running status'. Widest list of causes. Query the status of each half module till the maximum number {\tt{N}}, {\tt{for i in \$(seq\ 0\ N); do sls\_detector\_get \$i:status; done}}, to check if there are half modules that are still running. @@ -798,7 +935,7 @@ If only the master modules return but ALL the other half modules do not: \item It can be that the synchronization cable is not connected or the termination board at the synchronization does not work. Check. \end{itemize} -\subsubsection{a few modules do not return from acquisition} +\subsubsection{A few modules do not return from acquisition} If only a few modules are still running but the others return, it is a real problem with a backend board or a synchronization bug. If you can, ssh into the board, kill and start the eigerDetectorServer again (see Section~\ref{server} for how to do this). Keep the terminal with the output from the eigerDetectorServer and repeat the acquisition. \begin{itemize} @@ -808,11 +945,33 @@ If you can, ssh into the board, kill and start the eigerDetectorServer again (se \subsection{No packets (or very little) are received} In both cases running \textbf{wireshark} set to receive UDP packets on the ethernet interface of the receiver (filter the UDPport$>=$xxxx, where xxxx is written in the configuration file) can help you understanding if NO packets are seen or some packets are seen. You have to set the buffer size of the receiving device in wireshark to 100Mbyte minimum. If no packets are received, check that your receiving interface and detector UDPIPs are correct (if in 10Gb). Most of the time in this case it is a basic configuration problem. -If some packets are received, but not all, then it is an optimization problem: +It can help looking at the receiver output, shown in an example here: +\begin{verbatim} +Missing Packets : 224064 +Complete Frames : 3499 +Last Frame Caught : 3499 +\end{verbatim} + +The {\tt{Last Frame Caught}}, meaning the packet from the last frame that was sent out by the detector, can help in understanding the problem: +\begin{enumerate} +\item If some packets are received, but not all, it could be a network optimization problem. In this case, the {\tt{Last Frame Caught}} will be a value close to the expected number of frames with missing frames distributed over the whole frame range. In this case: \begin{itemize} \item For receiving data over 1Gb, the switch must have FLOW CONTROL enabled \item If using 10GbE, check that the 10Gb link is active on the backpanel board. Then refer to Section~\ref{10g} to see how to configure the 10Gb ports on the receiving machine correctly. \end{itemize} +\item If the {\tt{Last Frame Caught}} value is much lower than the expected frames and you are missing a bunch of frames from a point onwards, and you are using {\tt{receiver start, status start}}: then it can be that you are stopping the receiver too early. In particular when you are using {\tt{delay}} it might be that there is some time between when the detector is already done and in {\tt{idle}} state but the receiver is still receiving data. Check with {\tt{./sls\_detector\_get framescaught}} if the receiver is already done before doing {\tt{./sls\_detector\_put receiver stop}}. +\item If the {\tt{Last Frame Caught}} value is much lower than the expected frames and you are missing a bunch of frames from a point onwards and you are running at a higher frame rate than the continuous framerate (see table~\ref{tcont}) with more images than the size of the memory (see table~\ref{timgs}). It might be that you are running out of memory to store images. There is no protection for this. see point~\ref{outmemory} + \end{enumerate} + +\subsection{'Got Frame Number Zero from Firmware'}\label{outmemory} +In this case, you have run out of memory size (see table~\ref{timgs} for the size) on the boards so you are trying to store on the DDR2 memories more images that they can contain and the network is not fast enough to send everything out from the 10GbE. +So if you see: +\begin{verbatim} +Got Frame Number Zero from Firmware. Discarding Packet +\end{verbatim} +it means that you run out of memory at the previous acquisition. The cure is taking 2 or 3 SINGLE images in a raw to clear out the memories. + + \subsection{The module seems dead, no lights on BEBs, no IP addresses} \begin{itemize} @@ -828,7 +987,7 @@ If the 1G LED (see Section~\ref{led}) on the backpanel board is not green: \item The IP address is assigned only at booting up of the boards. Try to reboot in case the board booted before it could have an IP address. \item Check that you did not run out of IP addresses \end{itemize} - Check that the board is not in recovery mode (i.e. the central LED on the back is stable green). In this case reboot the board with the soft reset or power cycle it. + Check that the board is not in recovery mode (i.e. the central LED on the back is stable green, see Fig~\ref{fLEDs}). In this case reboot the board with the soft reset or power cycle it. If the 1Gb LED on the backpanel board is green (see Section~\ref{led}): \begin{itemize} @@ -843,6 +1002,10 @@ It is connected to the TCPport which the receiver uses: %%%#To display only open UDP ports try the following command: netstat -vaun \end{itemize} +\subsection{The client ignores the commands} +Make sure that in the configuration file you do not have {\tt{lock 1}} activated, as this will let only one username from one IP address talk to the detector. +To deactivate it, you need to run {\tt{lock 0}} from the client session where you locked it. + \subsection{Zmq socket is blocked} It is connected to the TCPport which is used. In rare cases, it might be that the TCP port crashes. To find out which process uses the TCPPOrt do: \textbf{netstat -nlp | grep xxxx}, where xxxx is the tcpport number. To display open ports and established TCP connections, enter: \textbf{netstat -vatn}. Kill the process. @@ -855,14 +1018,18 @@ Note that occasionally if there is a shared memory of a different size (from an This needs to be cleaned with {\tt{ipcs -m}} and then {\tt{ipcrm -M xxx}}, where xxx are the keys with nattch 0. Alternative in the main slsDetectorFolder there is a script that can be used as {\tt{sh cleansharedmemory.sh}}. Note that you need to run the script with the account of the client user, as the shared memory belongs to the client. It is good procedure to implement an automatic cleanup of the shared memory if the client user changes often. \subsection{Measure the HV} -For every system but not the 9M: +For every system: \begin{itemize} \item Software-wise measure it (now the software returns the measured value), with {\tt{sls\_detector\_get vhighvoltage}}. The returned value is the HV (for proper Eiger setting is approximately 150~V) if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned. -\item Hardware-wise measure value of HV on C14 on the power distribution board. Check also that the small HV connector cable is really connected. +\item Hardware-wise (opening the detector) measure value of HV on C14 on the power distribution board. Check also that the small HV connector cable is really connected. \end{itemize} +The 2M system at ESRF has a HV enable signal that needs to be shortcut in order to overwrite vacuum protections (when not in vacuum). +The 1.5M for OMNY has a relay system that enables HV only when the vacuum is good. +For both systems, it makes sense not to set the HV while running the configuration file but set it at a later stage when sure about the vacuum. + \subsection{The image now has a vertical line} -Check if the vertical line has a length of 256 pixels and a width of 8 columns. In this case it is a dataline beeing bad. It can be either a wirebond problem or a frontend board problem. try to read the FEB temperature (see Section~\ref{}) and report the problem to the SLSDetector group. Most likely it will be a long term fix by checking the hardware. +Check if the vertical line has a length of 256 pixels and a width of 8 columns. In this case it is a dataline being bad. It can be either a wirebond problem or a frontend board problem. try to read the FEB temperature (see Section~\ref{}) and report the problem to the SLSDetector group. Most likely it will be a long term fix by checking the hardware. \subsection{The image now has more vertical lines} @@ -872,7 +1039,7 @@ If you see strange lines in vertical occurring at period patterns, it is a memor Depending on your network setup, to speed up the ssh to the boards from a pc with internal dhcp server running: \textbf{iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE; echo "1" > /proc/sys/net/ipv4/ip\_forward}, where eth1 has to be the 1Gb network device on the pc \subsection{Check firmware version installed on BEB} -Follow some steps described in Section~\label{server}. +You can either ask in the client as described in section~\ref{api}, or login to the boards directly. Follow some steps described in Section~\ref{server}. \begin{verbatim} ssh root@bebxxx #password is root killall eigerDetectorServer # kill server and stopserver @@ -882,7 +1049,7 @@ cd executables/ Scroll up in the terminal till you find {\tt{Firmware Version: xx}} \subsection{Check if half-module is a master, a slave, a top or a bottom} -Follow some steps described in Section~\label{server}. +Follow some steps described in Section~\ref{server}. \begin{verbatim} ssh root@bebxxx #password is root killall eigerDetectorServer # kill server and stopserver @@ -894,9 +1061,34 @@ Scroll up in the terminal till you find:\\ *************** MASTER/SLAVE ***************\\ *************** NORMAL/SPECIAL ***************\\ +\subsection{'Cannot connect to socket'} +This error is typically due to the detector server not running. For why, see section~\ref{servernot}. +\subsection{Detector server is not running}\label{servernot} +The detector server could not be running: either the detector was powered off, or it powered off itself due to too high temperature or, in the case of the 9M, if the waterflow sensor detected no flux and powered it off (the chiller stops occasionally as cSAXS). +If the powering and the temperature are OK, instead, it can be that the firmware version is incompatible to the server version and/or the client software version. So check the consistency of firmware/software/server versions. +\subsection{'Acquire has already started' error message} +If you see the client returning the following error message:\\ +``Acquire has already started. If previous acquisition terminated unexpectedly, reset busy flag to restart.(sls\_detector\_put busy 0)''\\ + You need to run the command: +\begin{verbatim} +./sls_detector_put busy 0 +\end{verbatim} + +\subsection{There is noise running the detector in 32-bit} +Short story (for now): You are running in {\tt{parallel}} mode, switch {\tt{flags}} to non {\tt{nonparallel}} mode. +Long story: If you are running the detector in 32-bit (autosumming), there might be some noise, particularly at lower thereshold energies. This is due to the fact that the analog part of the chips require some latency time to settle which is larger than the redout time. At the present moment it is possible to run the detector only in {\tt{parallel}} or {\tt{nonparallel}} mode, respectively with readout times between frames of 12~$\mu$s and 504~$\mu$s. If you switch {\tt{flags}} to non {\tt{nonparallel}} mode you will giveenough time for teh signals to settle. For future realeas we are planning to introduce some configurable delay, such that you can remain with the {\tt{parallel}} flag, but can obtain a configurable dead time between frames in the range 12$-$504~$\mu$s. + +\subsection{There is noise running the detector at high frame rate(4,8,16 bit)} +If are running in {\tt{parallel}} mode, in particular at low thereshold energies, you might encounter some noise. The reason is that the analog part of the chips require some latency time to settle which is larger than the redout time. +\begin{enumerate} +\item You can lower the frame rate and relax requirements on period: +At low frame rate, you normally leave enough time between the end of the acquisition and the starting of the next, so you should not see this effect. In any case setting a {\tt{period}}={\tt{exptime}}+readout time from Table~\ref{tchipro} +extra 20$\mu$s cures the problem. The 20$\mu$s could also be 10~$\mu$s, they are very hardware dependent. +\item The frame rate requirement are stingent (as for time resolved measurements): the only option here is to reduce the {\tt{exptime}} to let the extra 20~$\mu$s (or 10)~$\mu$s. The {\tt{period}} remains the same. +\end{enumerate} + \section{Client checks - command line} Guide on returned strings: @@ -1037,7 +1229,74 @@ where {\tt{number}} is a string that should be interpreted as an int for 0/1 me \end{enumerate} +\section{Complete data out rate tables} +In table~\ref{tframescomplete} is a list of all the readout times in the different configurations. +\begin{tiny} +\begin{table} +\begin{flushleft} +\begin{tabular}{|c|c|c|c|c|c|c|} +\hline +\tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{readout t($\mu$s)} & \tiny{max frame rate (kHz)} & \tiny{min period ($\mu$s)} & \tiny{max imgs (nominal/our network)}\\ +\hline +4 & 0 & parallel & 3.4 & 22 & 44 & 30k/50k\\ +\hline +4 & 0 & nonparallel & 44 & 21 & 49 & 30k/50k\\ +\hline +4 & 1 & parallel & 6 & 10.5 & 92 & 30k/100k\\ +\hline +4 & 1 & nonparallel & 88.7 & 10.5 & 93 & 30k/100k\\ +\hline +4 & 2 & parallel & 11.2 & 5.4 & 197 & infinite\\ +\hline +4 & 2 & nonparallel & 176.5 & 5.4 & 180 & infinite\\ +\hline +\hline +8 & 0 & parallel & 3.4 & 11.1 & 89 & 15k/24k\\ +\hline +8 & 0 & nonparallel & 85.7 & 11.1 & 91 & 15k/24k\\ +\hline +8 & 1 & parallel & 6.1 & 5.7 & 181 & 15k/52k\\ +\hline +8 & 1 & nonparallel & 170.5 & 5.7 & 175 & 15k/52k\\ +\hline +8 & 2 & parallel & 11.2 & 2.9 & 342 & infinite\\ +\hline +8 & 2 & nonparallel & 340.3 & 2.9 & 344 & infinite\\ +\hline +\hline +16 & 0 & parallel & 3.4 & 6.1 & 164 & 8k/12k\\ +\hline +16 & 0 & nonparallel & 126 & 5.6& 179 & 8k/23k\\ +\hline +16 & 1 & parallel & 6.1 & 3.9& 257 & 8k/28k\\ +\hline +16 & 1 & nonparallel & 255 & 3.3& 303 & infinite\\ +\hline +16 & 2 & parallel & 11 & 1.9 & 526 &infinite \\ +\hline +16 & 2 & nonparallel & 504 & 1.8 & 555 & infinite\\ +\hline +\hline +32 & 2 & parallel & 11 & 2 & &\\ +\hline +32 & 2 & nonparallel & 504 & $<2$ & &\\ +\hline +\end{tabular} +\caption{Readout settings. The {\tiny{min exptime}} possible is 5$-$10~$\mu$s. This is due to the time to pass the pixel enable signal in the whole chip.} +\label{tframescomplete} +\end{flushleft} +\end{table} +\end{tiny} + +Table~\ref{tx} shows the bandwidth of data trasnferring between the FEB and BEB and of the DDR2 memory access. the GTX lanes are only capable of 25.6~Gbit/s. This limits the 12/16 bit frame rate. The 2$\times$DDR2 memories have a bandwidth or 2$\cdot$25.6~Gb/s=51.2~Gb/s. Due to this memory access bandwidth, the 32 bit autosumming mode can only run in {\tt{clkdivider}} 2. +\begin{figure}[t] +\begin{center} +\includegraphics[width=1.\textwidth]{TansmissionRates} +\end{center} +\caption{Transmission bandwidth for the FEB $\to$BEB transfer (second column) and the DDR2 memories (fourth column). } +\label{tx} +\end{figure} \end{document} diff --git a/manual/manual-client/LEDSim.png b/manual/manual-client/LEDSim.png new file mode 100644 index 000000000..5e1b91745 Binary files /dev/null and b/manual/manual-client/LEDSim.png differ diff --git a/manual/manual-client/TansmissionRates.png b/manual/manual-client/TansmissionRates.png new file mode 100644 index 000000000..efb189d8b Binary files /dev/null and b/manual/manual-client/TansmissionRates.png differ diff --git a/manual/manual-client/tiggerIN.png b/manual/manual-client/tiggerIN.png new file mode 100644 index 000000000..0b7a43f7f Binary files /dev/null and b/manual/manual-client/tiggerIN.png differ diff --git a/settingsdir/gotthard/dynamicgain/calibration.sn b/settingsdir/gotthard/dynamicgain/calibration.sn deleted file mode 100755 index e5a59be31..000000000 --- a/settingsdir/gotthard/dynamicgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/gotthard/dynamicgain/settings.sn b/settingsdir/gotthard/dynamicgain/settings.sn deleted file mode 100755 index 12aef34b2..000000000 --- a/settingsdir/gotthard/dynamicgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 350 -Vib_test 2001 diff --git a/settingsdir/gotthard/highgain/calibration.sn b/settingsdir/gotthard/highgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/gotthard/highgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/gotthard/highgain/settings.sn b/settingsdir/gotthard/highgain/settings.sn deleted file mode 100644 index 12aef34b2..000000000 --- a/settingsdir/gotthard/highgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 350 -Vib_test 2001 diff --git a/settingsdir/gotthard/lowgain/calibration.sn b/settingsdir/gotthard/lowgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/gotthard/lowgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/gotthard/lowgain/settings.sn b/settingsdir/gotthard/lowgain/settings.sn deleted file mode 100644 index 12aef34b2..000000000 --- a/settingsdir/gotthard/lowgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 350 -Vib_test 2001 diff --git a/settingsdir/gotthard/mediumgain/calibration.sn b/settingsdir/gotthard/mediumgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/gotthard/mediumgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/gotthard/mediumgain/settings.sn b/settingsdir/gotthard/mediumgain/settings.sn deleted file mode 100644 index 12aef34b2..000000000 --- a/settingsdir/gotthard/mediumgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 350 -Vib_test 2001 diff --git a/settingsdir/gotthard/veryhighgain/calibration.sn b/settingsdir/gotthard/veryhighgain/calibration.sn deleted file mode 100644 index 66fd0867d..000000000 --- a/settingsdir/gotthard/veryhighgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 \ No newline at end of file diff --git a/settingsdir/gotthard/veryhighgain/settings.sn b/settingsdir/gotthard/veryhighgain/settings.sn deleted file mode 100644 index 12aef34b2..000000000 --- a/settingsdir/gotthard/veryhighgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 350 -Vib_test 2001 diff --git a/settingsdir/jungfrau/dynamicgain/calibration.sn b/settingsdir/jungfrau/dynamicgain/calibration.sn deleted file mode 100755 index e5a59be31..000000000 --- a/settingsdir/jungfrau/dynamicgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/jungfrau/dynamicgain/settings.sn b/settingsdir/jungfrau/dynamicgain/settings.sn deleted file mode 100755 index b179a3c52..000000000 --- a/settingsdir/jungfrau/dynamicgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -VDAC0 1220 -VDAC1 3000 -VDAC2 1053 -VDAC3 1450 -VDAC4 750 -VDAC5 1000 -VDAC6 480 -VDAC7 420 diff --git a/settingsdir/jungfrau/dynamichg0 b/settingsdir/jungfrau/dynamichg0 deleted file mode 120000 index 4eb508c5a..000000000 --- a/settingsdir/jungfrau/dynamichg0 +++ /dev/null @@ -1 +0,0 @@ -dynamicgain \ No newline at end of file diff --git a/settingsdir/jungfrau/fixgain1 b/settingsdir/jungfrau/fixgain1 deleted file mode 120000 index 4eb508c5a..000000000 --- a/settingsdir/jungfrau/fixgain1 +++ /dev/null @@ -1 +0,0 @@ -dynamicgain \ No newline at end of file diff --git a/settingsdir/jungfrau/fixgain2 b/settingsdir/jungfrau/fixgain2 deleted file mode 120000 index 4eb508c5a..000000000 --- a/settingsdir/jungfrau/fixgain2 +++ /dev/null @@ -1 +0,0 @@ -dynamicgain \ No newline at end of file diff --git a/settingsdir/jungfrau/forceswitchg1 b/settingsdir/jungfrau/forceswitchg1 deleted file mode 120000 index 4eb508c5a..000000000 --- a/settingsdir/jungfrau/forceswitchg1 +++ /dev/null @@ -1 +0,0 @@ -dynamicgain \ No newline at end of file diff --git a/settingsdir/jungfrau/forceswitchg2 b/settingsdir/jungfrau/forceswitchg2 deleted file mode 120000 index 4eb508c5a..000000000 --- a/settingsdir/jungfrau/forceswitchg2 +++ /dev/null @@ -1 +0,0 @@ -dynamicgain \ No newline at end of file diff --git a/settingsdir/moench/dynamicgain/calibration.sn b/settingsdir/moench/dynamicgain/calibration.sn deleted file mode 100755 index e5a59be31..000000000 --- a/settingsdir/moench/dynamicgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/moench/dynamicgain/settings.sn b/settingsdir/moench/dynamicgain/settings.sn deleted file mode 100755 index c9e071c7c..000000000 --- a/settingsdir/moench/dynamicgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -VDAC0 660 -VDAC1 650 -VDAC2 1480 -VDAC3 1520 -VDAC4 1320 -VDAC5 1350 -VDAC6 887 -VDAC7 2001 diff --git a/settingsdir/moench/highgain/calibration.sn b/settingsdir/moench/highgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/moench/highgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/moench/highgain/settings.sn b/settingsdir/moench/highgain/settings.sn deleted file mode 100644 index c9e071c7c..000000000 --- a/settingsdir/moench/highgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -VDAC0 660 -VDAC1 650 -VDAC2 1480 -VDAC3 1520 -VDAC4 1320 -VDAC5 1350 -VDAC6 887 -VDAC7 2001 diff --git a/settingsdir/moench/lowgain/calibration.sn b/settingsdir/moench/lowgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/moench/lowgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/moench/lowgain/settings.sn b/settingsdir/moench/lowgain/settings.sn deleted file mode 100644 index c9e071c7c..000000000 --- a/settingsdir/moench/lowgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -VDAC0 660 -VDAC1 650 -VDAC2 1480 -VDAC3 1520 -VDAC4 1320 -VDAC5 1350 -VDAC6 887 -VDAC7 2001 diff --git a/settingsdir/moench/mediumgain/calibration.sn b/settingsdir/moench/mediumgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/moench/mediumgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/moench/mediumgain/settings.sn b/settingsdir/moench/mediumgain/settings.sn deleted file mode 100644 index c9e071c7c..000000000 --- a/settingsdir/moench/mediumgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -VDAC0 660 -VDAC1 650 -VDAC2 1480 -VDAC3 1520 -VDAC4 1320 -VDAC5 1350 -VDAC6 887 -VDAC7 2001 diff --git a/settingsdir/moench/veryhighgain/calibration.sn b/settingsdir/moench/veryhighgain/calibration.sn deleted file mode 100644 index 66fd0867d..000000000 --- a/settingsdir/moench/veryhighgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 \ No newline at end of file diff --git a/settingsdir/moench/veryhighgain/settings.sn b/settingsdir/moench/veryhighgain/settings.sn deleted file mode 100644 index c9e071c7c..000000000 --- a/settingsdir/moench/veryhighgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -VDAC0 660 -VDAC1 650 -VDAC2 1480 -VDAC3 1520 -VDAC4 1320 -VDAC5 1350 -VDAC6 887 -VDAC7 2001 diff --git a/settingsdir/propix/dynamicgain/calibration.sn b/settingsdir/propix/dynamicgain/calibration.sn deleted file mode 100755 index e5a59be31..000000000 --- a/settingsdir/propix/dynamicgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/propix/dynamicgain/settings.sn b/settingsdir/propix/dynamicgain/settings.sn deleted file mode 100755 index 324a9774c..000000000 --- a/settingsdir/propix/dynamicgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 887 -Vib_test 2001 diff --git a/settingsdir/propix/highgain/calibration.sn b/settingsdir/propix/highgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/propix/highgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/propix/highgain/settings.sn b/settingsdir/propix/highgain/settings.sn deleted file mode 100644 index 324a9774c..000000000 --- a/settingsdir/propix/highgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 887 -Vib_test 2001 diff --git a/settingsdir/propix/lowgain/calibration.sn b/settingsdir/propix/lowgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/propix/lowgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/propix/lowgain/settings.sn b/settingsdir/propix/lowgain/settings.sn deleted file mode 100644 index 324a9774c..000000000 --- a/settingsdir/propix/lowgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 887 -Vib_test 2001 diff --git a/settingsdir/propix/mediumgain/calibration.sn b/settingsdir/propix/mediumgain/calibration.sn deleted file mode 100644 index e5a59be31..000000000 --- a/settingsdir/propix/mediumgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 diff --git a/settingsdir/propix/mediumgain/settings.sn b/settingsdir/propix/mediumgain/settings.sn deleted file mode 100644 index 324a9774c..000000000 --- a/settingsdir/propix/mediumgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 887 -Vib_test 2001 diff --git a/settingsdir/propix/veryhighgain/calibration.sn b/settingsdir/propix/veryhighgain/calibration.sn deleted file mode 100644 index 66fd0867d..000000000 --- a/settingsdir/propix/veryhighgain/calibration.sn +++ /dev/null @@ -1 +0,0 @@ -227 5.6 \ No newline at end of file diff --git a/settingsdir/propix/veryhighgain/settings.sn b/settingsdir/propix/veryhighgain/settings.sn deleted file mode 100644 index 324a9774c..000000000 --- a/settingsdir/propix/veryhighgain/settings.sn +++ /dev/null @@ -1,8 +0,0 @@ -Vref 660 -VcascN 650 -VcascP 1480 -Vout 1520 -Vcasc 1320 -Vin 1350 -Vref_comp 887 -Vib_test 2001 diff --git a/slsDetectorGui/CMakeLists.txt b/slsDetectorGui/CMakeLists.txt index 55c68ca60..bad299e19 100644 --- a/slsDetectorGui/CMakeLists.txt +++ b/slsDetectorGui/CMakeLists.txt @@ -105,11 +105,6 @@ set_target_properties(slsDetectorGui PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) -add_library(zmq STATIC IMPORTED ) - -set_target_properties(zmq PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../slsReceiverSoftware/include/libzmq.a -) target_link_libraries(slsDetectorGui slsDetectorShared diff --git a/slsDetectorGui/forms/form_tab_advanced.ui b/slsDetectorGui/forms/form_tab_advanced.ui index 6dfde0513..8240f6c91 100644 --- a/slsDetectorGui/forms/form_tab_advanced.ui +++ b/slsDetectorGui/forms/form_tab_advanced.ui @@ -51,7 +51,7 @@ QTabWidget::North - 3 + 4 Qt::ElideLeft @@ -77,7 +77,7 @@ 25 20 - 324 + 345 31 @@ -142,7 +142,7 @@ 230 15 - 242 + 259 44 @@ -198,7 +198,7 @@ Plots Trimbits from Detector. This will take time. 25 20 - 195 + 211 31 @@ -256,7 +256,7 @@ Plots Trimbits from Detector. This will take time. 25 25 696 - 195 + 208 @@ -977,7 +977,7 @@ An extension given by the modules serial number will be attached. 25 25 686 - 116 + 148 @@ -1357,7 +1357,7 @@ An extension given by the modules serial number will be attached. 35 15 686 - 116 + 146 @@ -1748,6 +1748,320 @@ An extension given by the modules serial number will be attached. + + + Acquisition + + + + + 14 + 13 + 367 + 110 + + + + + + + false + + + + 0 + 0 + + + + <nobr> +Exposure Time of a sub frame. Only for Eiger in 32 bit mode +</nobr><br><nobr> + #subexptime# +</nobr> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + 9 + + + -1.000000000000000 + + + 2000000000.000000000000000 + + + 1.000000000000000 + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + false + + + <html><head/><body><p>Number of storage cells. For Jungfrau only. </p><p>Default: 0. </p><p>Number of Images received: #frames * #cycles * (#storagecells+1) </p><p> #storagecells#</p><p><br/></p></body></html> + + + Number of Storage cells: + + + + + + + false + + + <nobr> +Exposure Time of a sub frame. Only for Eiger in 32 bit mode +</nobr><br><nobr> + #subexptime# +</nobr> + + + Sub Frame Exposure Time: + + + + + + + false + + + + 0 + 0 + + + + <nobr> +Exposure Time of a sub frame. Only for Eiger in 32 bit mode +</nobr><br><nobr> + #subexptime# +</nobr> + + + Qt::LeftToRight + + + 2 + + + + hr + + + + + min + + + + + s + + + + + ms + + + + + us + + + + + ns + + + + + + + + false + + + + 0 + 0 + + + + <html><head/><body><p>Number of storage cells. For Jungfrau only. </p><p>Default: 0. </p><p>Number of Images received: #frames * #cycles * (#storagecells+1) </p><p> #storagecells#</p><p><br/></p></body></html> + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + + + -1 + + + 15 + + + 0 + + + + + + + false + + + <nobr> +Period between sub frames. Only for Eiger in 32 bit mode. +</nobr><br><nobr> +Default value is 0. A value less than the required minimum is ignored. +</nobr><br><nobr> + #subperiod# +</nobr> + + + Sub Frame Period: + + + + + + + false + + + + 0 + 0 + + + + <nobr> +Period between sub frames. Only for Eiger in 32 bit mode. +</nobr><br><nobr> +Default value is 0. A value less than the required minimum is ignored. +</nobr><br><nobr> + #subperiod# +</nobr> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + 9 + + + -1.000000000000000 + + + 2000000000.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 0 + 0 + + + + <nobr> +Period between sub frames. Only for Eiger in 32 bit mode. +</nobr><br><nobr> +Default value is 0. A value less than the required minimum is ignored. +</nobr><br><nobr> + #subperiod# +</nobr> + + + Qt::LeftToRight + + + 2 + + + + hr + + + + + min + + + + + s + + + + + ms + + + + + us + + + + + ns + + + + + + + diff --git a/slsDetectorGui/forms/form_tab_measurement.ui b/slsDetectorGui/forms/form_tab_measurement.ui index f4ce14964..f8a6853cf 100644 --- a/slsDetectorGui/forms/form_tab_measurement.ui +++ b/slsDetectorGui/forms/form_tab_measurement.ui @@ -151,9 +151,9 @@ - 35 + 0 10 - 326 + 357 321 @@ -965,9 +965,9 @@ Frame period between exposures. 30 - 297 + 298 318 - 30 + 31 @@ -1049,9 +1049,6 @@ Frame period between exposures. :/icons/images/stop.png:/icons/images/stop.png - - Shift+Space - false diff --git a/slsDetectorGui/gitInfo.txt b/slsDetectorGui/gitInfo.txt index cd47a074f..2ca43a76e 100644 --- a/slsDetectorGui/gitInfo.txt +++ b/slsDetectorGui/gitInfo.txt @@ -1,18 +1,9 @@ Path: slsDetectorsPackage/slsDetectorGui URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -<<<<<<< HEAD -Repsitory UUID: ab06c33107ecfeb4741d49407903ff80286cf75b -Revision: 492 -Branch: developer -Last Changed Author: Anna_Bergamaschi -Last Changed Rev: 3731 -Last Changed Date: 2018-03-15 12:27:06.000000002 +0100 ./src/qTabMeasurement.cpp -======= -Repsitory UUID: fe2ba8621b33bc00f51c8cd4d33e98b7d4ebfa41 -Revision: 493 -Branch: developer +Repsitory UUID: 6bb7195a2c7dc9526088882e0244a7455d3c15b2 +Revision: 511 +Branch: 3.3.0-rc Last Changed Author: Dhanya_Thattil -Last Changed Rev: 3747 -Last Changed Date: 2018-03-27 17:30:53.000000002 +0200 ./include/qTabMeasurement.h ->>>>>>> 7cd35f24b87501374fbaf45693a2adf16dfae3e3 +Last Changed Rev: 3941 +Last Changed Date: 2018-07-17 16:15:43.000000002 +0200 ./src/qTabSettings.cpp diff --git a/slsDetectorGui/include/gitInfoGui.h b/slsDetectorGui/include/gitInfoGui.h index fccb5d12c..40b2a1e3c 100644 --- a/slsDetectorGui/include/gitInfoGui.h +++ b/slsDetectorGui/include/gitInfoGui.h @@ -1,7 +1,6 @@ #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" - -#define GITREPUUID "fe2ba8621b33bc00f51c8cd4d33e98b7d4ebfa41" +#define GITREPUUID "6bb7195a2c7dc9526088882e0244a7455d3c15b2" #define GITAUTH "Dhanya_Thattil" -#define GITREV 0x3747 -#define GITDATE 0x20180327 -#define GITBRANCH "developer" +#define GITREV 0x3941 +#define GITDATE 0x20180717 +#define GITBRANCH "3.3.0-rc" diff --git a/slsDetectorGui/include/qTabAdvanced.h b/slsDetectorGui/include/qTabAdvanced.h index a871d5649..e07305d77 100644 --- a/slsDetectorGui/include/qTabAdvanced.h +++ b/slsDetectorGui/include/qTabAdvanced.h @@ -198,6 +198,16 @@ private slots: */ void SetAllTrimbits(); + /** Set storage cells */ + void SetNumStoragecells(int value); + + /** Set sub frame exposure time */ + void SetSubExposureTime(); + + /** Set sub frame period */ + void SetSubPeriod(); + + private: /** The multi detector object */ multiSlsDetector *myDet; @@ -242,7 +252,11 @@ private: vector spinToY; int numRois; + /** sub period tool tip variables*/ + QString acqSubPeriodTip; + QString errSubPeriodTip; + void CheckAcqPeriodGreaterThanExp(); }; diff --git a/slsDetectorGui/slsDetectorPlotting/src/SlsQtNumberEntry.cxx b/slsDetectorGui/slsDetectorPlotting/src/SlsQtNumberEntry.cxx index 13a44e35f..7d061bbbf 100644 --- a/slsDetectorGui/slsDetectorPlotting/src/SlsQtNumberEntry.cxx +++ b/slsDetectorGui/slsDetectorPlotting/src/SlsQtNumberEntry.cxx @@ -137,13 +137,13 @@ void SlsQtNumberEntry::SetupNumberField(int type, int which_number_field){ num_field[i]->setAlignment(Qt::AlignRight); if(i==0){ - connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(RefreshFirstNumberEntry())); + connect(num_field[i],SIGNAL(editingFinished()),this,SLOT(RefreshFirstNumberEntry())); connect(num_field[i],SIGNAL(returnPressed()),this,SLOT(FirstValueEntered())); - connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(FirstValueEntered())); + connect(num_field[i],SIGNAL(editingFinished()),this,SLOT(FirstValueEntered())); }else{ - connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(RefreshSecondNumberEntry())); + connect(num_field[i],SIGNAL(editingFinished()),this,SLOT(RefreshSecondNumberEntry())); connect(num_field[i],SIGNAL(returnPressed()),this,SLOT(SecondValueEntered())); - connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(SecondValueEntered())); + connect(num_field[i],SIGNAL(editingFinished()),this,SLOT(SecondValueEntered())); } }else if(type==3){ spin_box[i] = new QSpinBox(); diff --git a/slsDetectorGui/src/qDetectorMain.cpp b/slsDetectorGui/src/qDetectorMain.cpp index 766dac696..c2f6013a3 100644 --- a/slsDetectorGui/src/qDetectorMain.cpp +++ b/slsDetectorGui/src/qDetectorMain.cpp @@ -521,7 +521,7 @@ void qDetectorMain::ExecuteUtilities(QAction *action){ } } else if(action==actionLoadTrimbits){ - QString fName = QString(myDet->getSettingsDir()); + QString fName = QString( (myDet->getSettingsDir()).c_str()); qDefs::checkErrorMessage(myDet,"qDetectorMain::ExecuteUtilities"); //gotthard if(actionLoadTrimbits->text().contains("Settings")){ @@ -568,7 +568,7 @@ void qDetectorMain::ExecuteUtilities(QAction *action){ cout << "Saving Settings" << endl; #endif //different output directory so as not to overwrite - QString fName = QString(myDet->getSettingsDir()); + QString fName = QString( (myDet->getSettingsDir()).c_str() ); qDefs::checkErrorMessage(myDet,"qDetectorMain::ExecuteUtilities"); fName = QFileDialog::getSaveFileName(this, tr("Save Current Detector Settings"),fName, @@ -585,7 +585,7 @@ void qDetectorMain::ExecuteUtilities(QAction *action){ #ifdef VERBOSE cout << "Saving Trimbits" << endl; #endif//different output directory so as not to overwrite - QString fName = QString(myDet->getSettingsDir()); + QString fName = QString( (myDet->getSettingsDir()).c_str() ); qDefs::checkErrorMessage(myDet,"qDetectorMain::ExecuteUtilities"); fName = QFileDialog::getSaveFileName(this, tr("Save Current Detector Trimbits"),fName, @@ -603,7 +603,7 @@ void qDetectorMain::ExecuteUtilities(QAction *action){ #ifdef VERBOSE cout << "Loading Calibration Data" << endl; #endif - QString fName = QString(myDet->getCalDir()); + QString fName = QString( (myDet->getCalDir()).c_str() ); qDefs::checkErrorMessage(myDet); //so that even nonexisting files can be selected @@ -626,7 +626,7 @@ void qDetectorMain::ExecuteUtilities(QAction *action){ #ifdef VERBOSE cout << "Saving Calibration Data" << endl; #endif//different output directory so as not to overwrite - QString fName = QString(myDet->getCalDir()); + QString fName = QString( (myDet->getCalDir()).c_str() ); qDefs::checkErrorMessage(myDet); fName = QFileDialog::getSaveFileName(this, tr("Save Current Detector Calibration Data"),fName, diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index 6ad3e2ec8..47749dddf 100644 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -563,9 +563,13 @@ void qDrawPlot::SetScanArgument(int scanArg){ // Number of Exposures - must be calculated here to get npixelsy for allframes/frameindex scans int numFrames = (isFrameEnabled)*((int)myDet->setTimer(slsDetectorDefs::FRAME_NUMBER,-1)); int numTriggers = (isTriggerEnabled)*((int)myDet->setTimer(slsDetectorDefs::CYCLES_NUMBER,-1)); + int numStoragecells = 0; + if (detType == slsDetectorDefs::JUNGFRAU) + numStoragecells = (int)myDet->setTimer(slsDetectorDefs::STORAGE_CELL_NUMBER, -1); numFrames = ((numFrames==0)?1:numFrames); numTriggers = ((numTriggers==0)?1:numTriggers); - number_of_frames = numFrames * numTriggers; + numStoragecells = ((numStoragecells<=0)?1:numStoragecells+1); + number_of_frames = numFrames * numTriggers * numStoragecells; cout << "\tNumber of Frames per Scan/Measurement:" << number_of_frames << endl; //get #scansets for level 0 and level 1 int numScan0 = myDet->getScanSteps(0); numScan0 = ((numScan0==0)?1:numScan0); @@ -2232,9 +2236,9 @@ void qDrawPlot::toDoublePixelData(double* dest, char* source,int size, int datab // only data plot else { for (ichan = 0; ichan < size; ++ichan) { - if ( (*((u_int16_t*)source)) == 0xFFFF ) + /*if ( (*((u_int16_t*)source)) == 0xFFFF ) dest[ichan] = 0xFFFF; - else + else*/ dest[ichan] = ((*((u_int16_t*)source)) & 0x3FFF); source += 2; } diff --git a/slsDetectorGui/src/qTabAdvanced.cpp b/slsDetectorGui/src/qTabAdvanced.cpp index f5226957b..d07f51bb0 100644 --- a/slsDetectorGui/src/qTabAdvanced.cpp +++ b/slsDetectorGui/src/qTabAdvanced.cpp @@ -72,6 +72,14 @@ void qTabAdvanced::SetupWidgetWindow(){ rxrOnlineTip = comboRxrOnline->toolTip(); errOnlineTip = QString("

It is offline!"); + acqSubPeriodTip = spinSubPeriod->toolTip(); + errSubPeriodTip = acqSubPeriodTip + + QString("

Sub Frame Period " + "should be greater than or equal to " + "Sub Frame Exposure Time.
"); + + + detType = myDet->getDetectorsType(); switch(detType){ case slsDetectorDefs::MYTHEN: @@ -91,6 +99,12 @@ void qTabAdvanced::SetupWidgetWindow(){ dispMAC->setEnabled(true); boxRxr->setEnabled(true); boxSetAllTrimbits->setEnabled(true); + lblSubExpTime->setEnabled(true); + spinSubExpTime->setEnabled(true); + comboSubExpTimeUnit->setEnabled(true); + lblSubPeriod->setEnabled(true); + spinSubPeriod->setEnabled(true); + comboSubPeriodUnit->setEnabled(true); break; case slsDetectorDefs::MOENCH: isEnergy = false; @@ -197,16 +211,35 @@ void qTabAdvanced::SetupWidgetWindow(){ //updates roi cout << "Getting ROI" << endl; - if (myDet->getDetectorsType() == slsDetectorDefs::GOTTHARD) + if (detType == slsDetectorDefs::GOTTHARD) updateROIList(); #ifdef VERYVERBOSE // print receiver configurations - if(myDet->getDetectorsType() != slsDetectorDefs::MYTHEN){ + if(detType != slsDetectorDefs::MYTHEN){ cout << endl; myDet->printReceiverConfiguration(); } #endif + // jungfrau + if (detType == slsReceiverDefs::JUNGFRAU) { + lblNumStoragecells->setEnabled(true); + spinNumStoragecells->setEnabled(true); + spinNumStoragecells->setValue((int)myDet->setTimer(slsDetectorDefs::STORAGE_CELL_NUMBER,-1)); + } else if (detType == slsDetectorDefs::EIGER) { + //subexptime + qDefs::timeUnit unit; + double time = qDefs::getCorrectTime(unit,((double)(myDet->setTimer(slsDetectorDefs::SUBFRAME_ACQUISITION_TIME,-1)*(1E-9)))); + spinSubExpTime->setValue(time); + comboSubExpTimeUnit->setCurrentIndex((int)unit); + //period + time = qDefs::getCorrectTime(unit,((double)(myDet->setTimer(slsDetectorDefs::SUBFRAME_PERIOD,-1)*(1E-9)))); + spinSubPeriod->setValue(time); + comboSubPeriodUnit->setCurrentIndex((int)unit); + + CheckAcqPeriodGreaterThanExp(); + } + Initialization(); qDefs::checkErrorMessage(det,"qTabAdvanced::SetupWidgetWindow"); @@ -288,11 +321,23 @@ void qTabAdvanced::Initialization(){ //roi - if (myDet->getDetectorsType() == slsDetectorDefs::GOTTHARD) { + if (detType == slsDetectorDefs::GOTTHARD) { connect(btnClearRoi, SIGNAL(clicked()), this, SLOT(clearROIinDetector())); connect(btnGetRoi, SIGNAL(clicked()), this, SLOT(updateROIList())); connect(btnSetRoi, SIGNAL(clicked()), this, SLOT(setROI())); } + + if(detType == slsReceiverDefs::JUNGFRAU) { + connect(spinNumStoragecells, SIGNAL(valueChanged(int)), this, SLOT(SetNumStoragecells(int))); + } else if (detType == slsDetectorDefs::EIGER) { + //Exposure Time + connect(spinSubExpTime,SIGNAL(valueChanged(double)), this, SLOT(SetSubExposureTime())); + connect(comboSubExpTimeUnit,SIGNAL(currentIndexChanged(int)), this, SLOT(SetSubExposureTime())); + //Frame Period between exposures + connect(spinSubPeriod,SIGNAL(valueChanged(double)), this, SLOT(SetSubPeriod())); + connect(comboSubPeriodUnit,SIGNAL(currentIndexChanged(int)),this, SLOT(SetSubPeriod())); + + } } @@ -1225,6 +1270,127 @@ void qTabAdvanced::updateAllTrimbitsFromServer(){ //------------------------------------------------------------------------------------------------------------------------------------------------- +void qTabAdvanced::SetNumStoragecells(int value) { +#ifdef VERBOSE + cout << "Setting number of stoarge cells to " << value << endl; +#endif + myDet->setTimer(slsDetectorDefs::STORAGE_CELL_NUMBER,value); + + disconnect(spinNumStoragecells,SIGNAL(valueChanged(int)),this, SLOT(SetNumStoragecells(int))); + spinNumStoragecells->setValue((int)myDet->setTimer(slsDetectorDefs::STORAGE_CELL_NUMBER,-1)); + connect(spinNumStoragecells,SIGNAL(valueChanged(int)), this, SLOT(SetNumStoragecells(int))); + + qDefs::checkErrorMessage(myDet,"qTabAdvanced::SetNumStoragecells"); +} + + +//------------------------------------------------------------------------------------------------------------------------------------------------- + + +void qTabAdvanced::SetSubExposureTime() { + disconnect(spinSubExpTime,SIGNAL(valueChanged(double)), this, SLOT(SetSubExposureTime())); + disconnect(comboSubExpTimeUnit,SIGNAL(currentIndexChanged(int)),this, SLOT(SetSubExposureTime())); + + //Get the value of timer in ns + double timeNS = qDefs::getNSTime( + (qDefs::timeUnit)comboSubExpTimeUnit->currentIndex(), + spinSubExpTime->value()); + + // set value +#ifdef VERBOSE + cout << "Setting sub frame acquisition time to " << timeNS << " clocks" << + "/" << spinSubExpTime->value() << + qDefs::getUnitString((qDefs::timeUnit)comboSubExpTimeUnit->currentIndex()) << endl; +#endif + myDet->setTimer(slsDetectorDefs::SUBFRAME_ACQUISITION_TIME,(int64_t)timeNS); + qDefs::checkErrorMessage(myDet,"qTabAdvanced::SetSubExposureTime"); + + // update value in gui + qDefs::timeUnit unit; + double time = qDefs::getCorrectTime(unit,((double)( + myDet->setTimer(slsDetectorDefs::SUBFRAME_ACQUISITION_TIME,-1)*(1E-9)))); + spinSubExpTime->setValue(time); + comboSubExpTimeUnit->setCurrentIndex((int)unit); + + + // highlight if period < exptime + CheckAcqPeriodGreaterThanExp(); + + connect(spinSubExpTime,SIGNAL(valueChanged(double)), this, SLOT(SetSubExposureTime())); + connect(comboSubExpTimeUnit,SIGNAL(currentIndexChanged(int)), this, SLOT(SetSubExposureTime())); + + + qDefs::checkErrorMessage(myDet,"qTabAdvanced::SetSubExposureTime"); +} + + +//------------------------------------------------------------------------------------------------------------------------------------------------- + + +void qTabAdvanced::SetSubPeriod() { + disconnect(spinSubPeriod,SIGNAL(valueChanged(double)), this, SLOT(SetSubPeriod())); + disconnect(comboSubPeriodUnit,SIGNAL(currentIndexChanged(int)),this, SLOT(SetSubPeriod())); + + //Get the value of timer in ns + double timeNS = qDefs::getNSTime( + (qDefs::timeUnit)comboSubPeriodUnit->currentIndex(), + spinSubPeriod->value()); + + // set value +#ifdef VERBOSE + cout << "Setting sub frame period to " << timeNS << " clocks" << + "/" << spinSubPeriod->value() << + qDefs::getUnitString((qDefs::timeUnit)comboSubPeriodUnit->currentIndex()) << endl; +#endif + myDet->setTimer(slsDetectorDefs::SUBFRAME_PERIOD,(int64_t)timeNS); + qDefs::checkErrorMessage(myDet,"qTabAdvanced::SetSubPeriod"); + + // update value in gui + qDefs::timeUnit unit; + double time = qDefs::getCorrectTime(unit,((double)( + myDet->setTimer(slsDetectorDefs::SUBFRAME_PERIOD,-1)*(1E-9)))); + spinSubPeriod->setValue(time); + comboSubPeriodUnit->setCurrentIndex((int)unit); + + // highlight if period < exptime + CheckAcqPeriodGreaterThanExp(); + + connect(spinSubPeriod,SIGNAL(valueChanged(double)), this, SLOT(SetSubPeriod())); + connect(comboSubPeriodUnit,SIGNAL(currentIndexChanged(int)),this, SLOT(SetSubPeriod())); + + + qDefs::checkErrorMessage(myDet,"qTabAdvanced::SetSubPeriod"); +} + + +//------------------------------------------------------------------------------------------------------------------------------------------------- + + +void qTabAdvanced::CheckAcqPeriodGreaterThanExp(){ + double exptimeNS = qDefs::getNSTime( + (qDefs::timeUnit)comboSubExpTimeUnit->currentIndex(), + spinSubExpTime->value()); + double acqtimeNS = qDefs::getNSTime( + (qDefs::timeUnit)comboSubPeriodUnit->currentIndex(), + spinSubPeriod->value()); + if(exptimeNS>acqtimeNS && acqtimeNS > 0) { + spinSubPeriod->setToolTip(errSubPeriodTip); + lblSubPeriod->setToolTip(errSubPeriodTip); + lblSubPeriod->setPalette(red); + lblSubPeriod->setText("Sub Frame Period:*"); + } + else { + spinSubPeriod->setToolTip(acqSubPeriodTip); + lblSubPeriod->setToolTip(acqSubPeriodTip); + lblSubPeriod->setPalette(lblExpTime->palette()); + lblSubPeriod->setText("Sub Frame Period:"); + } +} + + +//------------------------------------------------------------------------------------------------------------------------------------------------- + + void qTabAdvanced::Refresh(){ @@ -1407,13 +1573,52 @@ void qTabAdvanced::Refresh(){ #ifdef VERBOSE cout << "Getting ROI" << endl; #endif - if (myDet->getDetectorsType() == slsDetectorDefs::GOTTHARD) + if (detType == slsDetectorDefs::GOTTHARD) updateROIList(); //update alltirmbits from server if(boxSetAllTrimbits->isEnabled()) updateAllTrimbitsFromServer(); + // storage cells + if (detType == slsReceiverDefs::JUNGFRAU) { + disconnect(spinNumStoragecells,SIGNAL(valueChanged(int)),this, SLOT(SetNumStoragecells(int))); + spinNumStoragecells->setValue((int)myDet->setTimer(slsDetectorDefs::STORAGE_CELL_NUMBER,-1)); + connect(spinNumStoragecells,SIGNAL(valueChanged(int)), this, SLOT(SetNumStoragecells(int))); + } + + // sub exptime and sub period + else if (detType == slsReceiverDefs::EIGER) { + disconnect(spinSubExpTime,SIGNAL(valueChanged(double)), this, SLOT(SetSubExposureTime())); + disconnect(comboSubExpTimeUnit,SIGNAL(currentIndexChanged(int)),this, SLOT(SetSubExposureTime())); + disconnect(spinSubPeriod,SIGNAL(valueChanged(double)), this, SLOT(SetSubPeriod())); + disconnect(comboSubPeriodUnit,SIGNAL(currentIndexChanged(int)),this, SLOT(SetSubPeriod())); + +#ifdef VERBOSE + cout << "Getting Sub Exposure time and Sub Period" << endl; +#endif + // subexptime + qDefs::timeUnit unit; + double time = qDefs::getCorrectTime(unit,((double)( + myDet->setTimer(slsDetectorDefs::SUBFRAME_ACQUISITION_TIME,-1)*(1E-9)))); + spinSubExpTime->setValue(time); + comboSubExpTimeUnit->setCurrentIndex((int)unit); + + // subperiod + time = qDefs::getCorrectTime(unit,((double)(myDet->setTimer(slsDetectorDefs::SUBFRAME_PERIOD,-1)*(1E-9)))); + spinSubPeriod->setValue(time); + comboSubPeriodUnit->setCurrentIndex((int)unit); + + + // highlight if period < exptime + CheckAcqPeriodGreaterThanExp(); + + connect(spinSubExpTime,SIGNAL(valueChanged(double)), this, SLOT(SetSubExposureTime())); + connect(comboSubExpTimeUnit,SIGNAL(currentIndexChanged(int)), this, SLOT(SetSubExposureTime())); + connect(spinSubPeriod,SIGNAL(valueChanged(double)), this, SLOT(SetSubPeriod())); + connect(comboSubPeriodUnit,SIGNAL(currentIndexChanged(int)),this, SLOT(SetSubPeriod())); + } + #ifdef VERBOSE cout << "**Updated Advanced Tab" << endl << endl; #endif diff --git a/slsDetectorGui/src/qTabMeasurement.cpp b/slsDetectorGui/src/qTabMeasurement.cpp index fa246e84a..caa3995c9 100644 --- a/slsDetectorGui/src/qTabMeasurement.cpp +++ b/slsDetectorGui/src/qTabMeasurement.cpp @@ -211,7 +211,10 @@ void qTabMeasurement::GetModeFromDetector(bool startup){ if(mode==slsDetectorDefs::AUTO_TIMING){ int frames = spinNumFrames->value(); int triggers = spinNumTriggers->value(); - if((frames==1)&&(triggers==1)){ + int storagecells = 0; + if (detType == slsDetectorDefs::JUNGFRAU) + storagecells = myDet->setTimer(slsDetectorDefs::STORAGE_CELL_NUMBER, -1); + if((frames==1)&&(triggers==1)&&(storagecells==0)){ comboTimingMode->setCurrentIndex((int)None); SetTimingMode((int)None); }else{ @@ -630,6 +633,8 @@ void qTabMeasurement::SetTimingMode(int mode){ lblExpTime->setEnabled(true); spinExpTime->setEnabled(true); comboExpUnit->setEnabled(true); spinNumTriggers->setValue(1); spinNumFrames->setValue(1); + if (detType == slsDetectorDefs::JUNGFRAU) + myDet->setTimer(slsReceiverDefs::STORAGE_CELL_NUMBER, 0); if(myDet->setExternalCommunicationMode(slsDetectorDefs::AUTO_TIMING)==slsDetectorDefs::AUTO_TIMING) success = true; break; @@ -708,6 +713,8 @@ void qTabMeasurement::SetTimingMode(int mode){ "Number of Frames \t: 1\nNumber of Triggers \t: 1","qTabMeasurement::SetTimingMode"); spinNumFrames->setValue(1); spinNumTriggers->setValue(1); + if (detType == slsReceiverDefs::JUNGFRAU) + myDet->setTimer(slsDetectorDefs::STORAGE_CELL_NUMBER, 0); comboTimingMode->setCurrentIndex((int)None); return; } diff --git a/slsDetectorGui/src/qTabSettings.cpp b/slsDetectorGui/src/qTabSettings.cpp index f9219431e..aa3849f4e 100644 --- a/slsDetectorGui/src/qTabSettings.cpp +++ b/slsDetectorGui/src/qTabSettings.cpp @@ -38,7 +38,10 @@ void qTabSettings::SetupWidgetWindow(){ detType=myDet->getDetectorsType(); // Settings - SetupDetectorSettings(); + if (detType != slsReceiverDefs::JUNGFRAUCTB) { + SetupDetectorSettings(); + } else + comboSettings->setEnabled(false); //threshold if((detType == slsDetectorDefs::MYTHEN) || (detType == slsDetectorDefs::EIGER)) @@ -104,8 +107,7 @@ void qTabSettings::SetupDetectorSettings(){ int sett = (int)myDet->getSettings();cout<<"sett:"<(comboSettings->model()); @@ -167,7 +169,6 @@ void qTabSettings::SetupDetectorSettings(){ item[(int)VeryLowGain]->setEnabled(false); break; case slsDetectorDefs::JUNGFRAU: - case slsDetectorDefs::JUNGFRAUCTB: item[(int)Standard]->setEnabled(false); item[(int)Fast]->setEnabled(false); item[(int)HighGain]->setEnabled(false); @@ -209,7 +210,8 @@ void qTabSettings::SetupDetectorSettings(){ void qTabSettings::Initialization(){ // Settings - connect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); + if (detType != slsReceiverDefs::JUNGFRAUCTB) + connect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); // Number of Modules connect(spinNumModules, SIGNAL(valueChanged(int)), this, SLOT(SetNumberOfModules(int))); // Dynamic Range @@ -227,8 +229,7 @@ void qTabSettings::setSettings(int index){ disconnect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); int sett = (int)myDet->getSettings(); if(sett==-1) sett = Undefined; - if(detType == slsDetectorDefs::JUNGFRAUCTB && sett > slsDetectorDefs::UNDEFINED) sett = Uninitialized; - else if(sett == slsDetectorDefs::UNDEFINED) sett = Undefined; + if(sett == slsDetectorDefs::UNDEFINED) sett = Undefined; else if(sett == slsDetectorDefs::UNINITIALIZED) sett = Uninitialized; comboSettings->setCurrentIndex(sett); connect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); @@ -321,7 +322,8 @@ void qTabSettings::Refresh(){ cout << endl << "**Updating Settings Tab" << endl; #endif - disconnect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); + if (detType != slsReceiverDefs::JUNGFRAUCTB) + disconnect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); disconnect(spinNumModules, SIGNAL(valueChanged(int)), this, SLOT(SetNumberOfModules(int))); disconnect(spinThreshold, SIGNAL(valueChanged(int)), this, SLOT(SetEnergy())); @@ -340,35 +342,35 @@ void qTabSettings::Refresh(){ GetDynamicRange(); // Settings + if (detType != slsReceiverDefs::JUNGFRAUCTB) { #ifdef VERBOSE - cout << "Getting settings" << endl; + cout << "Getting settings" << endl; #endif - int sett = (int)myDet->getSettings(); - if(sett==-1) sett = Undefined;//slsDetectorDefs::UNDEFINED; - if(detType == slsDetectorDefs::JUNGFRAUCTB && sett > slsDetectorDefs::UNDEFINED) sett = Uninitialized; - else if(sett == slsDetectorDefs::UNDEFINED) sett = Undefined; - else if(sett == slsDetectorDefs::UNINITIALIZED) sett = Uninitialized; - comboSettings->setCurrentIndex(sett); + int sett = (int)myDet->getSettings(); + if(sett==-1) sett = Undefined;//slsDetectorDefs::UNDEFINED; + if(sett == slsDetectorDefs::UNDEFINED) sett = Undefined; + else if(sett == slsDetectorDefs::UNINITIALIZED) sett = Uninitialized; + comboSettings->setCurrentIndex(sett); - - //threshold - sett = comboSettings->currentIndex(); - if((detType==slsDetectorDefs::MYTHEN)||(detType==slsDetectorDefs::EIGER)){ - if((sett==Undefined)||(sett==Uninitialized)){ - lblThreshold->setEnabled(false); - spinThreshold->setEnabled(false); - }else{ - lblThreshold->setEnabled(true); - spinThreshold->setEnabled(true); + //threshold + sett = comboSettings->currentIndex(); + if((detType==slsDetectorDefs::MYTHEN)||(detType==slsDetectorDefs::EIGER)){ + if((sett==Undefined)||(sett==Uninitialized)){ + lblThreshold->setEnabled(false); + spinThreshold->setEnabled(false); + }else{ + lblThreshold->setEnabled(true); + spinThreshold->setEnabled(true); #ifdef VERBOSE - cout << "Getting threshold energy" << endl; + cout << "Getting threshold energy" << endl; #endif - spinThreshold->setValue(myDet->getThresholdEnergy()); + spinThreshold->setValue(myDet->getThresholdEnergy()); + } } - } +} - - connect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); + if (detType != slsReceiverDefs::JUNGFRAUCTB) + connect(comboSettings, SIGNAL(currentIndexChanged(int)), this, SLOT(setSettings(int))); connect(spinNumModules, SIGNAL(valueChanged(int)), this, SLOT(SetNumberOfModules(int))); connect(spinThreshold, SIGNAL(valueChanged(int)), this, SLOT(SetEnergy())); diff --git a/slsDetectorSoftware/CMakeLists.txt b/slsDetectorSoftware/CMakeLists.txt index 6513b012d..939d833e9 100644 --- a/slsDetectorSoftware/CMakeLists.txt +++ b/slsDetectorSoftware/CMakeLists.txt @@ -1,5 +1,6 @@ set(SOURCES multiSlsDetector/multiSlsDetector.cpp + sharedMemory/SharedMemory.cpp slsDetector/slsDetectorUsers.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp @@ -24,6 +25,7 @@ set(HEADERS include_directories( commonFiles multiSlsDetector +sharedMemory slsDetector slsDetectorUtils slsDetectorCommand @@ -39,12 +41,6 @@ add_definitions( -DDACS_INT ) -add_library(zmq STATIC IMPORTED ) - -set_target_properties(zmq PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../slsReceiverSoftware/include/libzmq.a -) - add_library(slsDetectorStatic STATIC ${SOURCES} ${HEADERS} @@ -63,6 +59,9 @@ set(PUBLICHEADERS commonFiles/sls_detector_defs.h commonFiles/sls_detector_funcs.h commonFiles/error_defs.h + commonFiles/sls_detector_exceptions.h + commonFiles/versionAPI.h + sharedMemory/SharedMemory.h slsDetector/slsDetectorUtils.h slsDetector/slsDetector.h slsDetector/slsDetectorActions.h diff --git a/slsDetectorSoftware/Makefile b/slsDetectorSoftware/Makefile index 850edef3f..1e2fa98ff 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 commonFiles/versionAPI.h @@ -43,7 +43,7 @@ gotthardVirtualServer: $(SRC_MYTHEN_SVC) cd gotthardDetectorServer && make -f Makefile.virtual DESTDIR=$(DESTDIR) -%.o : %.cpp %.h $(DEPSINCLUDES) Makefile +%.o : %.cpp %.h $(DEPSINCLUDES) Makefile $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -pthread -lrt $(LIBZMQ) $(FLAGS) diff --git a/slsDetectorSoftware/commonFiles/error_defs.h b/slsDetectorSoftware/commonFiles/error_defs.h index 03730964f..dc733c2d7 100644 --- a/slsDetectorSoftware/commonFiles/error_defs.h +++ b/slsDetectorSoftware/commonFiles/error_defs.h @@ -15,7 +15,7 @@ #include #include #include -using namespace std; +// /** Error flags */ /*Assumption: Only upto 63 detectors */ @@ -51,6 +51,7 @@ using namespace std; #define PREPARE_ACQUISITION 0x0000100000000000ULL #define CLEANUP_ACQUISITION 0x0000080000000000ULL #define REGISER_WRITE_READ 0x0000040000000000ULL +#define VERSION_COMPATIBILITY 0x0000020000000000ULL // 0xFFFFFF0000000000ULL // 0x000000FFFFFFFFFFULL @@ -86,13 +87,14 @@ using namespace std; #define RECEIVER_FLIPPED_DATA_NOT_SET 0x0000000020000000ULL #define THRESHOLD_NOT_SET 0x0000000040000000ULL #define RECEIVER_FILE_FORMAT 0x0000000080000000ULL -#define RECEIVER_SILENT_MODE_NOT_SET 0x0000000100000000ULL +#define RECEIVER_PARAMETER_NOT_SET 0x0000000100000000ULL #define RECEIVER_TIMER_NOT_SET 0x0000000200000000ULL #define RECEIVER_ENABLE_GAPPIXELS_NOT_SET 0x0000000400000000ULL #define RESTREAM_STOP_FROM_RECEIVER 0x0000000800000000ULL #define TEMPERATURE_CONTROL 0x0000001000000000ULL #define AUTO_COMP_DISABLE 0x0000002000000000ULL #define CONFIG_FILE 0x0000004000000000ULL +#define STORAGE_CELL_START 0x0000008000000000ULL // 0x000000FFFFFFFFFFULL @@ -111,9 +113,9 @@ public: * param errorMask error mask /returns error message from error mask */ - static string getErrorMessage(int64_t slsErrorMask){ + static std::string getErrorMessage(int64_t slsErrorMask){ - string retval = ""; + std::string retval = ""; if(slsErrorMask&CANNOT_CONNECT_TO_DETECTOR) retval.append("Cannot connect to Detector\n"); @@ -169,13 +171,16 @@ public: if(slsErrorMask®ISER_WRITE_READ) retval.append("Could not read/write register in detector\n"); + if(slsErrorMask&VERSION_COMPATIBILITY) + retval.append("Incompatible versions with detector or receiver. Please check log for more details.\n"); + if(slsErrorMask&COULD_NOT_CONFIGURE_MAC) retval.append("Could not configure mac\n"); if(slsErrorMask&COULDNOT_SET_NETWORK_PARAMETER) - retval.append("Could not set network parameter. Should be valid and in proper format\n"); + retval.append("Could not set network parameter.\n"); if(slsErrorMask&COULDNOT_SET_ROI) retval.append("Could not set the exact region of interest. Verify ROI set by detector.\n"); @@ -276,8 +281,8 @@ public: if(slsErrorMask&RECEIVER_TIMER_NOT_SET) retval.append("Could not set timer in receiver.\n"); - if(slsErrorMask&RECEIVER_SILENT_MODE_NOT_SET) - retval.append("Could not set silent mode in receiver.\n"); + if(slsErrorMask&RECEIVER_PARAMETER_NOT_SET) + retval.append("Could not set a paramater in receiver.\n"); if(slsErrorMask&RECEIVER_ENABLE_GAPPIXELS_NOT_SET) retval.append("Could not enable/disable gap pixels in receiver.\n"); diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h index 1d8d993bb..2d1338947 100755 --- a/slsDetectorSoftware/commonFiles/sls_detector_defs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -22,6 +22,9 @@ /** maximum rois */ #define MAX_ROIS 100 +/** maximum trim en */ +#define MAX_TRIMEN 100 + /** maximum unit size of program sent to detector */ #define MAX_FPGAPROGRAMSIZE (2 * 1024 *1024) @@ -196,7 +199,10 @@ enum networkParameter { RECEIVER_STREAMING_PORT, /**< receiever streaming TCP(ZMQ) port */ CLIENT_STREAMING_PORT, /**< client streaming TCP(ZMQ) port */ RECEIVER_STREAMING_SRC_IP,/**< receiever streaming TCP(ZMQ) ip */ - CLIENT_STREAMING_SRC_IP /**< client streaming TCP(ZMQ) ip */ + CLIENT_STREAMING_SRC_IP, /**< client streaming TCP(ZMQ) ip */ + ADDITIONAL_JSON_HEADER, /**< additional json header (ZMQ) */ + RECEIVER_UDP_SCKT_BUF_SIZE, /**< UDP socket buffer size */ + RECEIVER_REAL_UDP_SCKT_BUF_SIZE /**< real UDP socket buffer size */ }; /** @@ -288,7 +294,9 @@ enum idMode{ DETECTOR_SOFTWARE_VERSION, /** +#include +using namespace std; + + +struct SharedMemoryException : public exception { +public: + SharedMemoryException() {} + string GetMessage() const { return "Shared Memory Failed";}; +}; + +struct ThreadpoolException : public exception { +public: + ThreadpoolException() {} + string GetMessage() const { return "Threadpool Failed";}; +}; diff --git a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h index c4d2f5c5a..ed54ffc90 100644 --- a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h @@ -118,6 +118,9 @@ enum detFuncs{ F_TEMP_EVENT, /** < set temperature event */ F_AUTO_COMP_DISABLE, /** < auto comp disable mode */ + F_STORAGE_CELL_START, /** < storage cell start */ + + F_CHECK_VERSION, /** < check version compatibility */ /* Always append functions hereafter!!! */ /* Always append functions before!!! */ diff --git a/slsDetectorSoftware/commonFiles/versionAPI.h b/slsDetectorSoftware/commonFiles/versionAPI.h new file mode 100644 index 000000000..8c35add53 --- /dev/null +++ b/slsDetectorSoftware/commonFiles/versionAPI.h @@ -0,0 +1,5 @@ +/** API versions */ +#define APIRECEIVER 0x180517 +#define APIEIGER 0x180528 +#define APIJUNGFRAU 0x180628 +#define APIGOTTHARD 0x180529 diff --git a/slsDetectorSoftware/eigerDetectorServer/Beb.c b/slsDetectorSoftware/eigerDetectorServer/Beb.c index b5d0a0065..074980d8c 100644 --- a/slsDetectorSoftware/eigerDetectorServer/Beb.c +++ b/slsDetectorSoftware/eigerDetectorServer/Beb.c @@ -49,6 +49,7 @@ int Beb_activated = 1; uint32_t Beb_detid = 0; + int Beb_top =0; @@ -164,8 +165,10 @@ void Beb_GetModuleConfiguration(int* master, int* top, int* normal){ ret = Beb_Read32(csp0base, MODULE_CONFIGURATION_MASK); printf("Module Configuration OK\n"); printf("Beb: value =0x%x\n",ret); - if(ret&TOP_BIT_MASK) + if(ret&TOP_BIT_MASK) { *top = 1; + Beb_top = 1; + } if(ret&MASTER_BIT_MASK) *master = 1; if(ret&NORMAL_MODULE_BIT_MASK) @@ -412,6 +415,43 @@ int Beb_Activate(int enable){ } +int Beb_Set32bitOverflow(int val) { + if(!Beb_activated) + return val; + + //mapping new memory + u_int32_t* csp0base=0; + u_int32_t valueread = 0; + u_int32_t offset = FLOW_REG_OFFSET; + if(val>0) val = 1; + + //open file pointer + int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); + if(fd < 0){ + cprintf(BG_RED,"Could not read register to set overflow flag in 32 bit mode. FAIL\n"); + return -1; + } + else{ + if(val > -1){ + // reset bit + valueread = Beb_Read32(csp0base, offset); + Beb_Write32(csp0base, offset,valueread & ~FLOW_REG_OVERFLOW_32_BIT_MSK); + + // set bit + valueread = Beb_Read32(csp0base, offset); + Beb_Write32(csp0base, offset,valueread | + ((val << FLOW_REG_OVERFLOW_32_BIT_OFST) & FLOW_REG_OVERFLOW_32_BIT_MSK)); + } + + valueread = (Beb_Read32(csp0base, offset) & FLOW_REG_OVERFLOW_32_BIT_MSK) >> FLOW_REG_OVERFLOW_32_BIT_OFST; + } + //close file pointer + if(fd > 0) + Beb_close(fd,csp0base); + + return valueread; +} + int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val){ if(!Beb_activated) @@ -438,7 +478,7 @@ int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val){ strcpy(modename,"Transmission Delay Frame"); break; case FLOWCTRL_10G: - offset = TXM_FLOW_CONTROL_10G; + offset = FLOW_REG_OFFSET; strcpy(modename,"Flow Control for 10G"); if(val>0) val = 1; break; @@ -452,14 +492,29 @@ int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val){ } else{ if(val > -1){ - valueread = Beb_Read32(csp0base, offset); - //cprintf(BLUE, "%s value before:%d\n",modename,valueread); - Beb_Write32(csp0base, offset,val); - cprintf(BLUE,"%s value:%d\n", modename,valueread); + if (mode != FLOWCTRL_10G) { + valueread = Beb_Read32(csp0base, offset); + Beb_Write32(csp0base, offset,val); + } + // flow control reg has other bits for other control + else { + // reset bit + valueread = Beb_Read32(csp0base, offset); + Beb_Write32(csp0base, offset,valueread & ~FLOW_REG_TXM_FLOW_CNTRL_10G_MSK); + + // set bit + valueread = Beb_Read32(csp0base, offset); + Beb_Write32(csp0base, offset,valueread | + ((val << FLOW_REG_TXM_FLOW_CNTRL_10G_OFST) & FLOW_REG_TXM_FLOW_CNTRL_10G_MSK)); + + } + } valueread = Beb_Read32(csp0base, offset); - //cprintf(BLUE,"%s value:%d\n", modename,valueread); + if (mode == FLOWCTRL_10G) + valueread = (valueread & FLOW_REG_TXM_FLOW_CNTRL_10G_MSK) >> FLOW_REG_TXM_FLOW_CNTRL_10G_OFST; + } //close file pointer if(fd > 0) @@ -1161,7 +1216,7 @@ int Beb_SetDetectorPosition(int pos[]) { if(!Beb_activated) return OK; - pos[0] = Beb_swap_uint16(pos[0]); + pos[1] = Beb_swap_uint16(pos[1]); pos[2] = Beb_swap_uint16(pos[2]); int ret = FAIL; @@ -1176,37 +1231,37 @@ int Beb_SetDetectorPosition(int pos[]) { uint32_t value = 0; ret = OK; // x left + int posval = Beb_swap_uint16((Beb_top ? pos[0] : (pos[0]+1))); value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST); value &= UDP_HEADER_ID_MSK; // to keep previous id value - Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST, value | ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)); + Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST, value | ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST); - if((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) + if((value & UDP_HEADER_X_MSK) != ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) ret = FAIL; // x right + posval = Beb_swap_uint16((Beb_top ? (pos[0]+1) : pos[0])); value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST); value &= UDP_HEADER_ID_MSK; // to keep previous id value - Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST, value | ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)); + Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST, value | ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST); - if((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) + if((value & UDP_HEADER_X_MSK) != ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) ret = FAIL; // y left - int posval = Beb_swap_uint16(pos[1]); // overwriting z anyway, so no need to look at previous z value - Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST, ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)); + Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST, ((pos[1] << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST); - if(value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) + if(value != ((pos[1] << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) ret = FAIL; // y right - posval = Beb_swap_uint16(pos[1]+1); // overwriting z anyway, so no need to look at previous z value - Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST, ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)); + Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST, ((pos[1] << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST); - if(value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) + if(value != ((pos[1] << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) ret = FAIL; @@ -1235,8 +1290,8 @@ int Beb_SetDetectorPosition(int pos[]) { cprintf(BLUE, "Position set to...\n" "Left: [%d, %d, %d]\n" "Right:[%d, %d, %d]\n", - Beb_swap_uint16(pos[0]), pos[1], Beb_swap_uint16(pos[2]), - Beb_swap_uint16(pos[0]), pos[1]+1, Beb_swap_uint16(pos[2])); + (Beb_top ? pos[0] : (pos[0]+1)), Beb_swap_uint16(pos[1]), Beb_swap_uint16(pos[2]), + (Beb_top ? (pos[0]+1) : pos[0]), Beb_swap_uint16(pos[1]), Beb_swap_uint16(pos[2])); } return ret; diff --git a/slsDetectorSoftware/eigerDetectorServer/Beb.h b/slsDetectorSoftware/eigerDetectorServer/Beb.h index a0229dd3b..73718db03 100644 --- a/slsDetectorSoftware/eigerDetectorServer/Beb.h +++ b/slsDetectorSoftware/eigerDetectorServer/Beb.h @@ -51,6 +51,7 @@ struct BebInfo{ int Beb_SetMasterViaSoftware(); int Beb_SetSlaveViaSoftware(); int Beb_Activate(int enable); + int Beb_Set32bitOverflow(int val); int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val); int Beb_ResetToHardwareSettings(); u_int32_t Beb_GetFirmwareRevision(); diff --git a/slsDetectorSoftware/eigerDetectorServer/FebControl.c b/slsDetectorSoftware/eigerDetectorServer/FebControl.c index dbb4ebad0..f14995fe7 100644 --- a/slsDetectorSoftware/eigerDetectorServer/FebControl.c +++ b/slsDetectorSoftware/eigerDetectorServer/FebControl.c @@ -42,6 +42,7 @@ unsigned int Feb_Control_subFrameMode; unsigned int Feb_Control_nimages; double Feb_Control_exposure_time_in_sec; int64_t Feb_Control_subframe_exposure_time_in_10nsec; +int64_t Feb_Control_subframe_period_in_10nsec; double Feb_Control_exposure_period_in_sec; int64_t Feb_Control_RateTable_Tau_in_nsec = -1; @@ -1380,6 +1381,14 @@ int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10 } int64_t Feb_Control_GetSubFrameExposureTime(){return Feb_Control_subframe_exposure_time_in_10nsec*10;} +int Feb_Control_SetSubFramePeriod(int64_t the_subframe_period_in_10nsec){ + Feb_Control_subframe_period_in_10nsec = the_subframe_period_in_10nsec; + printf("Sub Frame Period set to: %lld\n",(long long int)Feb_Control_subframe_period_in_10nsec); + return 1; +} +int64_t Feb_Control_GetSubFramePeriod(){return Feb_Control_subframe_period_in_10nsec*10;} + + int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec){ Feb_Control_exposure_period_in_sec = the_exposure_period_in_sec; printf("Exposure period set to: %f\n",Feb_Control_exposure_period_in_sec); @@ -1510,9 +1519,11 @@ int Feb_Control_PrepareForAcquisition(){//return 1; reg_vals[4]=(Feb_Control_acquireNReadoutMode|Feb_Control_triggerMode|Feb_Control_externalEnableMode|Feb_Control_subFrameMode); reg_nums[5]=DAQ_REG_SUBFRAME_EXPOSURES; reg_vals[5]= Feb_Control_subframe_exposure_time_in_10nsec; //(1 means 10ns, 100 means 1000ns) + reg_nums[6]=DAQ_REG_SUBFRAME_PERIOD; + reg_vals[6]= Feb_Control_subframe_period_in_10nsec; //(1 means 10ns, 100 means 1000ns) // if(!Feb_Interface_WriteRegisters((Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1])),20,reg_nums,reg_vals,0,0)){ if(Feb_Control_activated){ - if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),6,reg_nums,reg_vals,0,0)){ + if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),7,reg_nums,reg_vals,0,0)){ printf("Trouble starting acquisition....\n");; return 0; } diff --git a/slsDetectorSoftware/eigerDetectorServer/FebControl.h b/slsDetectorSoftware/eigerDetectorServer/FebControl.h index 892d6b22c..02252cf62 100644 --- a/slsDetectorSoftware/eigerDetectorServer/FebControl.h +++ b/slsDetectorSoftware/eigerDetectorServer/FebControl.h @@ -164,6 +164,8 @@ int Feb_Control_GetModuleNumber(); int64_t Feb_Control_GetExposureTime_in_nsec(); int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec); int64_t Feb_Control_GetSubFrameExposureTime(); + int Feb_Control_SetSubFramePeriod(int64_t the_subframe_period_in_10nsec); + int64_t Feb_Control_GetSubFramePeriod(); int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec); double Feb_Control_GetExposurePeriod(); int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); diff --git a/slsDetectorSoftware/eigerDetectorServer/FebRegisterDefs.h b/slsDetectorSoftware/eigerDetectorServer/FebRegisterDefs.h index 87d4ae70a..1562fe1e4 100644 --- a/slsDetectorSoftware/eigerDetectorServer/FebRegisterDefs.h +++ b/slsDetectorSoftware/eigerDetectorServer/FebRegisterDefs.h @@ -6,19 +6,28 @@ //daq register definitions -#define DAQ_REG_CTRL 1 -#define DAQ_REG_CHIP_CMDS 2 -#define DAQ_REG_STATIC_BITS 3 -#define DAQ_REG_CLK_ROW_CLK_NTIMES 3 -#define DAQ_REG_SHIFT_IN_32 3 -#define DAQ_REG_READOUT_NROWS 3 -#define DAQ_REG_SEND_N_TESTPULSES 3 +#define DAQ_REG_CTRL 1 +#define DAQ_REG_CHIP_CMDS 2 +#define DAQ_REG_STATIC_BITS 3 +#define DAQ_REG_CLK_ROW_CLK_NTIMES 3 +#define DAQ_REG_SHIFT_IN_32 3 +#define DAQ_REG_READOUT_NROWS 3 +#define DAQ_REG_SEND_N_TESTPULSES 3 + +#define DAQ_REG_NEXPOSURES 3 +#define DAQ_REG_EXPOSURE_TIMER 4 // == (31 downto 3) * 10^(2 downto 0) +#define DAQ_REG_EXPOSURE_REPEAT_TIMER 5 // == (31 downto 3) * 10^(2 downto 0) +#define DAQ_REG_SUBFRAME_EXPOSURES 6 +#define DAQ_REG_SUBFRAME_PERIOD 7 //also pg and fifo status register + + +#define DAQ_REG_RO_OFFSET 12 +#define DAQ_REG_STATUS (0 + DAQ_REG_RO_OFFSET) //also pg and fifo status register +//temp so far +#define FEB_REG_STATUS (3 + DAQ_REG_RO_OFFSET) + + -#define DAQ_REG_NEXPOSURES 3 -#define DAQ_REG_EXPOSURE_TIMER 4 // == (31 downto 3) * 10^(2 downto 0) -#define DAQ_REG_EXPOSURE_REPEAT_TIMER 5 // == (31 downto 3) * 10^(2 downto 0) -#define DAQ_REG_SUBFRAME_EXPOSURES 6 -#define DAQ_REG_STATUS 7 //also pg and fifo status register #define DAQ_CTRL_RESET 0x80000000 #define DAQ_CTRL_START 0x40000000 @@ -130,7 +139,12 @@ #define TXM_DELAY_LEFT_OFFSET 0x180 #define TXM_DELAY_RIGHT_OFFSET 0x1A0 #define TXM_DELAY_FRAME_OFFSET 0x1C0 -#define TXM_FLOW_CONTROL_10G 0x140 +#define FLOW_REG_OFFSET 0x140 + +#define FLOW_REG_TXM_FLOW_CNTRL_10G_OFST (0) +#define FLOW_REG_TXM_FLOW_CNTRL_10G_MSK (0x1 << FLOW_REG_TXM_FLOW_CNTRL_10G_OFST) +#define FLOW_REG_OVERFLOW_32_BIT_OFST (2) +#define FLOW_REG_OVERFLOW_32_BIT_MSK (0x1 << FLOW_REG_OVERFLOW_32_BIT_OFST) //command memory #define LEFT_OFFSET 0x0 @@ -152,9 +166,6 @@ #define FRAME_NUM_RESET_OFFSET 0xA0 -//temp so far -#define FEB_REG_STATUS 0xa - //1g counters #define ONE_GIGA_LEFT_INDEX_LSB_COUNTER 0x04 #define ONE_GIGA_LEFT_INDEX_MSB_COUNTER 0x24 diff --git a/slsDetectorSoftware/eigerDetectorServer/Makefile.virtual b/slsDetectorSoftware/eigerDetectorServer/Makefile.virtual index ceff1fc75..1f4c400e5 100644 --- a/slsDetectorSoftware/eigerDetectorServer/Makefile.virtual +++ b/slsDetectorSoftware/eigerDetectorServer/Makefile.virtual @@ -6,7 +6,7 @@ LDLIBS += -lm -lstdc++ -pthread DESTDIR ?= bin -SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList_virtual.c +SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c diff --git a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_developer index c2c348a0a..e0c29547d 100755 Binary files a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualMaster b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualMaster index 0167b8fd3..6edbadf71 100755 Binary files a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualMaster and b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualMaster differ diff --git a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualSlave b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualSlave index 2a735216d..3145f01d0 100755 Binary files a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualSlave and b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer_virtualSlave differ diff --git a/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt b/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt index 37168cb6b..7c61c54a3 100644 --- a/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt +++ b/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsDetectorSoftware/eigerDetectorServer URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -Repsitory UUID: da010a03d725b6f18020d2142d58771534414274 -Revision: 328 +Repsitory UUID: 3b6ead77836f2b6d2a795a9a994259d1dc8c131d +Revision: 343 Branch: developer -Last Changed Author: Erik_Frojdh -Last Changed Rev: 3751 -Last Changed Date: 2018-04-03 16:29:39.000000002 +0200 ./xparameters.h +Last Changed Author: Dhanya_Thattil +Last Changed Rev: 3943 +Last Changed Date: 2018-07-17 16:15:43.000000002 +0200 ./Makefile.virtual diff --git a/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h b/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h index 37d82e952..baa181354 100644 --- a/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h +++ b/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h @@ -1,6 +1,6 @@ #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" -#define GITREPUUID "da010a03d725b6f18020d2142d58771534414274" -#define GITAUTH "Erik_Frojdh" -#define GITREV 0x3751 -#define GITDATE 0x20180403 +#define GITREPUUID "3b6ead77836f2b6d2a795a9a994259d1dc8c131d" +#define GITAUTH "Dhanya_Thattil" +#define GITREV 0x3943 +#define GITDATE 0x20180717 #define GITBRANCH "developer" diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c index 83caa23c9..4249cc815 100644 --- a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c @@ -1,16 +1,21 @@ -#ifdef SLS_DETECTOR_FUNCTION_LIST +//#ifdef SLS_DETECTOR_FUNCTION_LIST #include #include //to gethostname #include - - +#ifdef VIRTUAL +#include +#include +#endif #include "slsDetectorFunctionList.h" +#ifndef VIRTUAL #include "gitInfoEiger.h" #include "FebControl.h" #include "Beb.h" +#include "versionAPI.h" +#endif int default_tau_from_file= -1; @@ -21,8 +26,6 @@ const char* dac_names[16] = {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","V enum{E_PARALLEL, E_NON_PARALLEL, E_SAFE}; -//static const string dacNames[16] = {"Svp","Svn","Vtr","Vrf","Vrs","Vtgstv","Vcmp_ll","Vcmp_lr","Cal","Vcmp_rl","Vcmp_rr","Rxb_rb","Rxb_lb","Vcp","Vcn","Vis"}; - sls_detector_module *detectorModules=NULL; int *detectorChips=NULL; int *detectorChans=NULL; @@ -36,6 +39,7 @@ int eiger_photonenergy = 0; int eiger_dynamicrange = 0; int eiger_readoutmode = 0; int eiger_storeinmem = 0; +int eiger_overflow32 = 0; int eiger_readoutspeed = 0; int eiger_triggermode = 0; int eiger_extgating = 0; @@ -46,6 +50,27 @@ int eiger_nexposures = 1; int eiger_ncycles = 1; +#ifdef VIRTUAL +//values for virtual server +double eiger_virtual_exptime = 0; +int64_t eiger_virtual_subexptime = 0; +int64_t eiger_virtual_subperiod = 0; +double eiger_virtual_period = 0; +int eiger_virtual_counter_bit=1; +int eiger_virtual_ratecorrection_variable=0; +int64_t eiger_virtual_ratetable_tau_in_ns=-1; +int64_t eiger_virtual_ratetable_period_in_ns=-1; +int eiger_virtual_transmission_delay_left=0; +int eiger_virtual_transmission_delay_right=0; +int eiger_virtual_transmission_delay_frame=0; +int eiger_virtual_transmission_flowcontrol_10g=0; +int eiger_virtual_status=0; +int eiger_virtual_activate=1; +pthread_t eiger_virtual_tid; +int eiger_virtual_stop = 0; +#endif + + int send_to_ten_gig = 0; int ndsts_in_use=32; unsigned int nimages_per_request=1; @@ -61,21 +86,44 @@ enum masterFlags masterMode=IS_SLAVE; int top = 0; int master = 0; int normal = 0; +#ifndef VIRTUAL uint32_t detid = 0; - - - - - +#endif /* basic tests */ +int firmware_compatibility = OK; +int firmware_check_done = 0; +char firmware_message[MAX_STR_LENGTH]; + + +int isFirmwareCheckDone() { + return firmware_check_done; +} + +int getFirmwareCheckResult(char** mess) { + *mess = firmware_message; + return firmware_compatibility; +} + void checkFirmwareCompatibility(int flag){ + firmware_compatibility = OK; + firmware_check_done = 0; + memset(firmware_message, 0, MAX_STR_LENGTH); +#ifdef VIRTUAL + cprintf(BLUE,"\n\n" + "********************************************************\n" + "***************** EIGER Virtual Server *****************\n" + "********************************************************\n"); + firmware_check_done = 1; + return; +#endif uint32_t ipadd = getDetectorIP(); uint64_t macadd = getDetectorMAC(); int64_t fwversion = getDetectorId(DETECTOR_FIRMWARE_VERSION); int64_t swversion = getDetectorId(DETECTOR_SOFTWARE_VERSION); int64_t sw_fw_apiversion = getDetectorId(SOFTWARE_FIRMWARE_API_VERSION); + int64_t client_sw_apiversion = getDetectorId(CLIENT_SOFTWARE_API_VERSION); cprintf(BLUE,"\n\n" "********************************************************\n" @@ -88,34 +136,61 @@ void checkFirmwareCompatibility(int flag){ "Firmware Version:\t\t %lld\n" "Software Version:\t\t %llx\n" "F/w-S/w API Version:\t\t %lld\n" - "Required Firmware Version:\t %d\n\n" + "Required Firmware Version:\t %d\n" + "Client-Software API Version:\t 0x%llx\n" + "\n" "********************************************************\n", - ipadd, macadd, - fwversion,swversion, - sw_fw_apiversion,REQUIRED_FIRMWARE_VERSION); + (unsigned int)ipadd, + (long long unsigned int)macadd, + (long long int)fwversion, + (long long int)swversion, + (long long int)sw_fw_apiversion, + REQUIRED_FIRMWARE_VERSION, + (long long int)client_sw_apiversion); + + // return if flag is not zero, debug mode + if (flag) { + firmware_check_done = 1; + return; + } //cant read versions if(!fwversion || !sw_fw_apiversion){ - cprintf(RED,"FATAL ERROR: Cant read versions from FPGA. Please update firmware\n"); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(-1); + strcpy(firmware_message, + "FATAL ERROR: Cant read versions from FPGA. Please update firmware.\n"); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } //check for API compatibility - old server if(sw_fw_apiversion > REQUIRED_FIRMWARE_VERSION){ - cprintf(RED,"FATAL ERROR: This software version is incompatible.\n" - "Please update it to be compatible with this firmware\n\n"); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(-1); + sprintf(firmware_message, + "FATAL ERROR: This detector software software version (%lld) is incompatible.\n" + "Please update detector software (min. %lld) to be compatible with this firmware.\n", + (long long int)sw_fw_apiversion, + (long long int)REQUIRED_FIRMWARE_VERSION); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } //check for firmware compatibility - old firmware if( REQUIRED_FIRMWARE_VERSION > fwversion){ - cprintf(RED,"FATAL ERROR: This firmware version is incompatible.\n" - "Please update it to v%d to be compatible with this server\n\n", REQUIRED_FIRMWARE_VERSION); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(-1); + sprintf(firmware_message, + "FATAL ERROR: This firmware version (%lld) is incompatible.\n" + "Please update firmware (min. %lld) to be compatible with this server.\n", + (long long int)fwversion, + (long long int)REQUIRED_FIRMWARE_VERSION); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } + printf("Compatibility - success\n"); + firmware_check_done = 1; } @@ -125,6 +200,9 @@ void checkFirmwareCompatibility(int flag){ /* Ids */ int64_t getDetectorId(enum idMode arg){ +#ifdef VIRTUAL + return 0; +#else int64_t retval = -1; switch(arg){ @@ -137,25 +215,39 @@ int64_t getDetectorId(enum idMode arg){ return (int64_t)Beb_GetFirmwareSoftwareAPIVersion(); case DETECTOR_SOFTWARE_VERSION: return (GITDATE & 0xFFFFFF); + case CLIENT_SOFTWARE_API_VERSION: + return APIEIGER; default: break; } return retval; +#endif } u_int64_t getFirmwareVersion() { +#ifdef VIRTUAL + return 0; +#else return Beb_GetFirmwareRevision(); +#endif } u_int32_t getDetectorNumber(){ +#ifdef VIRTUAL + return 0; +#else return detid; +#endif } u_int64_t getDetectorMAC() { +#ifdef VIRTUAL + return 0; +#else char mac[255]=""; u_int64_t res=0; @@ -180,10 +272,14 @@ u_int64_t getDetectorMAC() { //printf("mac:%llx\n",res); return res; +#endif } u_int32_t getDetectorIP(){ +#ifdef VIRTUAL + return 0; +#endif char temp[50]=""; u_int32_t res=0; //execute and get address @@ -213,6 +309,12 @@ u_int32_t getDetectorIP(){ /* initialization */ void initControlServer(){ +#ifdef VIRTUAL + getModuleConfiguration(); + setupDetector(); + printf("\n"); + return; +#else //Feb and Beb Initializations getModuleConfiguration(); Feb_Interface_FebInterface(); @@ -230,22 +332,48 @@ void initControlServer(){ setupDetector(); - +#endif printf("\n"); } void initStopServer(){ +#ifdef VIRTUAL + getModuleConfiguration(); + printf("\n"); + return; +#else getModuleConfiguration(); Feb_Interface_FebInterface(); Feb_Control_FebControl(); Feb_Control_Init(master,top,normal,getDetectorNumber()); printf("FEB Initialization done\n"); - +#endif printf("\n"); } void getModuleConfiguration(){ +#ifdef VIRTUAL +#ifdef VIRTUAL_MASTER + master = 1; + top = 1; +#else + master = 0; + top = 1; +#endif +#ifdef VIRTUAL_9M + normal = 0; +#else + normal = 1; +#endif + if(top) printf("*************** TOP ***************\n"); + else printf("*************** BOTTOM ***************\n"); + if(master) printf("*************** MASTER ***************\n"); + else printf("*************** SLAVE ***************\n"); + if(normal) printf("*************** NORMAL ***************\n"); + else printf("*************** SPECIAL ***************\n"); + return; +#else int *m=&master; int *t=⊤ int *n=&normal; @@ -264,6 +392,7 @@ void getModuleConfiguration(){ pclose(sysFile); sscanf(output,"%u",&detid); printf("detector id: %u\n",detid); +#endif } @@ -328,11 +457,15 @@ void setupDetector() { //setting default measurement parameters setTimer(FRAME_NUMBER, DEFAULT_NUM_FRAMES); setTimer(ACQUISITION_TIME, DEFAULT_EXPTIME); - setTimer(SUBFRAME_ACQUISITION_TIME, DEFAULT_SUBFRAME_EXPOSURE_VAL); + setTimer(SUBFRAME_ACQUISITION_TIME, DEFAULT_SUBFRAME_EXPOSURE); + setTimer(SUBFRAME_PERIOD, DEFAULT_SUBFRAME_PERIOD); setTimer(FRAME_PERIOD, DEFAULT_PERIOD); + setTimer(CYCLES_NUMBER, DEFAULT_NUM_CYCLES); setDynamicRange(DEFAULT_DYNAMIC_RANGE); eiger_photonenergy = DEFAULT_PHOTON_ENERGY; - setReadOutFlags(DEFAULT_READOUT_FLAG); + setReadOutFlags(DEFAULT_READOUT_MODE); + setReadOutFlags(DEFAULT_READOUT_STOREINRAM_MODE); + setReadOutFlags(DEFAULT_READOUT_OVERFLOW32_MODE); setSpeed(CLOCK_DIVIDER, DEFAULT_CLK_SPEED);//clk_devider,half speed setIODelay(DEFAULT_IO_DELAY, DEFAULT_MOD_INDEX); setTiming(DEFAULT_TIMING_MODE); @@ -340,9 +473,13 @@ void setupDetector() { setRateCorrection(DEFAULT_RATE_CORRECTION); int enable[2] = {DEFAULT_EXT_GATING_ENABLE, DEFAULT_EXT_GATING_POLARITY}; setExternalGating(enable);//disable external gating +#ifndef VIRTUAL Feb_Control_SetInTestModeVariable(DEFAULT_TEST_MODE); +#endif setHighVoltage(DEFAULT_HIGH_VOLTAGE); +#ifndef VIRTUAL Feb_Control_CheckSetup(); +#endif } @@ -350,11 +487,19 @@ void setupDetector() { /* advanced read/write reg */ uint32_t writeRegister(uint32_t offset, uint32_t data) { +#ifdef VIRTUAL + return 0; +#else return Feb_Control_WriteRegister(offset, data); +#endif } uint32_t readRegister(uint32_t offset) { +#ifdef VIRTUAL + return 0; +#else return Feb_Control_ReadRegister(offset); +#endif } @@ -370,6 +515,13 @@ int getNModBoard(enum dimension arg){ } int setDynamicRange(int dr){ +#ifdef VIRTUAL + if(dr > 0){ + printf(" Setting dynamic range: %d\n",dr); + eiger_dynamicrange = dr; + } + return eiger_dynamicrange; +#else if(dr > 0){ printf(" Setting dynamic range: %d\n",dr); if(Feb_Control_SetDynamicRange(dr)){ @@ -387,6 +539,7 @@ int setDynamicRange(int dr){ dr= Feb_Control_GetDynamicRange(); return dr; +#endif } @@ -401,7 +554,9 @@ int setSpeed(enum speedVariable arg, int val){ if(val != -1){ printf(" Setting Read out Speed: %d\n",val); +#ifndef VIRTUAL if(Feb_Control_SetReadoutSpeed(val)) +#endif eiger_readoutspeed = val; } return eiger_readoutspeed; @@ -425,11 +580,36 @@ enum readOutFlags setReadOutFlags(enum readOutFlags val){ return -1; } printf(" Setting Read out Flag: %d\n",val); +#ifndef VIRTUAL if(Feb_Control_SetReadoutMode(val)) +#endif eiger_readoutmode = val; +#ifndef VIRTUAL else return -1; +#endif - }else{ + } + + else if (val&0xF00000) { + switch(val){ + case SHOW_OVERFLOW: val=1; printf(" Setting Read out Flag: Overflow in 32 bit mode\n"); break; + case NOOVERFLOW: val=0; printf(" Setting Read out Flag: No overflow in 32 bit mode\n"); break; + default: + cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); + return -1; + } + printf(" Setting Read out Flag: %d\n",val); +#ifndef VIRTUAL + if(Beb_Set32bitOverflow(val) != -1) +#endif + eiger_overflow32 = val; +#ifndef VIRTUAL + else return -1; +#endif + } + + + else{ switch(val){ case STORE_IN_RAM: val=1; printf(" Setting Read out Flag: Store in Ram\n"); break; case CONTINOUS_RO: val=0; printf(" Setting Read out Flag: Continuous Readout\n"); break; @@ -450,10 +630,19 @@ enum readOutFlags setReadOutFlags(enum readOutFlags val){ case E_SAFE: retval=SAFE; break; } + switch(eiger_overflow32){ + case 1: retval|=SHOW_OVERFLOW; break; + case 0: retval|=NOOVERFLOW; break; + } + + switch(eiger_storeinmem){ case 0: retval|=CONTINOUS_RO; break; case 1: retval|=STORE_IN_RAM; break; } + + + printf("Read out Flag: 0x%x\n",retval); return retval; } @@ -468,11 +657,11 @@ enum readOutFlags setReadOutFlags(enum readOutFlags val){ /* parameters - timer */ int64_t setTimer(enum timerIndex ind, int64_t val){ - switch(ind){ case FRAME_NUMBER: if(val >= 0){ printf(" Setting number of frames: %d * %d\n",(unsigned int)val,eiger_ncycles); +#ifndef VIRTUAL if(Feb_Control_SetNExposures((unsigned int)val*eiger_ncycles)){ eiger_nexposures = val; //SetDestinationParameters(EigerGetNumberOfExposures()*EigerGetNumberOfCycles()); @@ -482,33 +671,76 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ ndsts_in_use = 1; nimages_per_request = eiger_nexposures * eiger_ncycles; } +#else + eiger_nexposures = val; + nimages_per_request = eiger_nexposures * eiger_ncycles; +#endif }return eiger_nexposures; case ACQUISITION_TIME: if(val >= 0){ printf(" Setting exp time: %fs\n",val/(1E9)); +#ifndef VIRTUAL Feb_Control_SetExposureTime(val/(1E9)); +#else + eiger_virtual_exptime = (val/(1E9)); +#endif } +#ifndef VIRTUAL return (Feb_Control_GetExposureTime()*(1E9)); +#else + return eiger_virtual_exptime*1e9; +#endif case SUBFRAME_ACQUISITION_TIME: if(val >= 0){ printf(" Setting sub exp time: %lldns\n",(long long int)val/10); +#ifndef VIRTUAL Feb_Control_SetSubFrameExposureTime(val/10); +#else + eiger_virtual_subexptime = (val/(10)); +#endif } +#ifndef VIRTUAL return (Feb_Control_GetSubFrameExposureTime()); +#else + return eiger_virtual_subexptime*10; +#endif + case SUBFRAME_PERIOD: + if(val >= 0){ + printf(" Setting sub period: %lldns\n",(long long int)val/10); +#ifndef VIRTUAL + Feb_Control_SetSubFramePeriod(val/10); +#else + eiger_virtual_subperiod = (val/(1E9)); +#endif + } +#ifndef VIRTUAL + return (Feb_Control_GetSubFramePeriod()); +#else + return eiger_virtual_subperiod*1e9; +#endif case FRAME_PERIOD: if(val >= 0){ printf(" Setting acq period: %fs\n",val/(1E9)); +#ifndef VIRTUAL Feb_Control_SetExposurePeriod(val/(1E9)); +#else + eiger_virtual_period = (val/(1E9)); +#endif } +#ifndef VIRTUAL return (Feb_Control_GetExposurePeriod()*(1E9)); +#else + return eiger_virtual_period*1e9; +#endif case CYCLES_NUMBER: if(val >= 0){ printf(" Setting number of triggers: %d * %d\n",(unsigned int)val,eiger_nexposures); +#ifndef VIRTUAL if(Feb_Control_SetNExposures((unsigned int)val*eiger_nexposures)){ eiger_ncycles = val; //SetDestinationParameters(EigerGetNumberOfExposures()*EigerGetNumberOfCycles()); @@ -517,7 +749,12 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested nimages_per_request = eiger_nexposures * eiger_ncycles; } - }return eiger_ncycles; +#else + eiger_ncycles = val; + nimages_per_request = eiger_nexposures * eiger_ncycles; +#endif + } + return eiger_ncycles; default: cprintf(RED,"Warning: Timer Index not implemented for this detector: %d\n", ind); break; @@ -541,22 +778,27 @@ int setModule(sls_detector_module myMod, int delay){ printf("Setting module with settings %d\n",myMod.reg); //#endif + //copy module locally (module number, serial number, gain offset, + //dacs (pointless), trimbit values(if needed) + if (detectorModules) + if (copyModule(detectorModules,&myMod) == FAIL) + return FAIL; + + // settings setSettings( (enum detectorSettings)myMod.reg,-1); + // iodelay if(setIODelay(delay, -1)!= delay){ cprintf(RED,"could not set iodelay %d\n",delay); return FAIL; } - //copy module locally - if (detectorModules) - copyModule(detectorModules,&myMod); - - //set dac values + // dacs for(i=0;idacs)+i)); + } //trimbits unsigned int* tt; @@ -612,10 +858,13 @@ int getModule(sls_detector_module *myMod){ } } } +#endif - //copy to local copy as well - if (detectorModules) - copyModule(detectorModules,myMod); + //copy local module to myMod + if (detectorModules) { + if (copyModule(myMod, detectorModules) == FAIL) + return FAIL; + } else return FAIL; return OK; @@ -708,6 +957,14 @@ void setDAC(enum DACINDEX ind, int val, int imod, int mV, int retval[]){ else printf("in dac units\n"); #endif +#ifdef VIRTUAL + if (mV){ + retval[0] = (int)(((val-0)/(2048-0))*(4096-1) + 0.5); + retval[1] = val; + }else + retval[0] = val; + +#else if(val >= 0) Feb_Control_SetDAC(iname,val,mV); int k; @@ -715,7 +972,7 @@ void setDAC(enum DACINDEX ind, int val, int imod, int mV, int retval[]){ retval[0] = k; Feb_Control_GetDAC(iname,&k,1); retval[1] = k; - +#endif (detectorModules)->dacs[ind] = retval[0]; } @@ -723,6 +980,9 @@ void setDAC(enum DACINDEX ind, int val, int imod, int mV, int retval[]){ int getADC(enum ADCINDEX ind, int imod){ +#ifdef VIRTUAL + return 0; +#else int retval = -1; char tempnames[6][20]={"FPGA EXT", "10GE","DCDC", "SODL", "SODR", "FPGA"}; char cstore[255]; @@ -755,10 +1015,23 @@ int getADC(enum ADCINDEX ind, int imod){ printf("Temperature %s: %f°C\n",tempnames[ind],(double)retval/1000.00); return retval; +#endif } int setHighVoltage(int val){ +#ifdef VIRTUAL + if (master) { + // set + if(val!=-1){ + eiger_theo_highvoltage = val; + } + return eiger_theo_highvoltage; + } + + return SLAVE_HIGH_VOLTAGE_READ_VAL; +#else + if (master) { // set @@ -786,6 +1059,7 @@ int setHighVoltage(int val){ } return SLAVE_HIGH_VOLTAGE_READ_VAL; +#endif } @@ -806,7 +1080,9 @@ enum externalCommunicationMode setTiming( enum externalCommunicationMode arg){ case GATE_FIX_NUMBER: ret = 3; break; } printf(" Setting Triggering Mode: %d\n",(int)ret); +#ifndef VIRTUAL if(Feb_Control_SetTriggerMode(ret,1)) +#endif eiger_triggermode = ret; } @@ -831,7 +1107,7 @@ enum externalCommunicationMode setTiming( enum externalCommunicationMode arg){ /* configure mac */ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2, int ival) { - +#ifndef VIRTUAL char src_mac[50], src_ip[50],dst_mac[50], dst_ip[50]; int src_port = 0xE185; sprintf(src_ip,"%d.%d.%d.%d",(sourceip>>24)&0xff,(sourceip>>16)&0xff,(sourceip>>8)&0xff,(sourceip)&0xff); @@ -889,14 +1165,18 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested nimages_per_request=eiger_nexposures * eiger_ncycles; - +#endif return 0; } int setDetectorPosition(int pos[]) { +#ifdef VIRTUAL + return OK; +#else return Beb_SetDetectorPosition(pos); +#endif } @@ -908,7 +1188,9 @@ int setDetectorPosition(int pos[]) { int setIODelay(int val, int imod){ if(val!=-1){ printf(" Setting IO Delay: %d\n",val); +#ifndef VIRTUAL if(Feb_Control_SetIDelays(Feb_Control_GetModuleNumber(),val)) +#endif eiger_iodelay = val; } return eiger_iodelay; @@ -932,35 +1214,92 @@ int enableTenGigabitEthernet(int val){ int setCounterBit(int val){ if(val!=-1){ +#ifdef VIRTUAL + eiger_virtual_counter_bit = val; +#else Feb_Control_Set_Counter_Bit(val); +#endif #ifdef VERBOSE printf("Counter Bit:%d\n",val); #endif } - +#ifdef VIRTUAL + return eiger_virtual_counter_bit; +#else return Feb_Control_Get_Counter_Bit(); +#endif } int pulsePixel(int n, int x, int y){ +#ifndef VIRTUAL if(!Feb_Control_Pulse_Pixel(n,x,y)) return FAIL; +#endif return OK; } int pulsePixelNMove(int n, int x, int y){ +#ifndef VIRTUAL if(!Feb_Control_PulsePixelNMove(n,x,y)) return FAIL; +#endif return OK; } int pulseChip(int n){ +#ifndef VIRTUAL if(!Feb_Control_PulseChip(n)) return FAIL; +#endif return OK; } int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never be -1) +#ifdef VIRTUAL + //deactivating rate correction + if(custom_tau_in_nsec==0){ + eiger_virtual_ratecorrection_variable = 0; + return 0; + } + + //when dynamic range changes, use old tau + else if(custom_tau_in_nsec == -1) + custom_tau_in_nsec = eiger_virtual_ratetable_tau_in_ns; + + //get period = subexptime if 32bit , else period = exptime if 16 bit + int64_t actual_period = eiger_virtual_subexptime*10; //already in nsec + if(eiger_dynamicrange == 16) + actual_period = eiger_virtual_exptime; + + int64_t ratetable_period_in_nsec = eiger_virtual_ratetable_period_in_ns; + int64_t tau_in_nsec = eiger_virtual_ratetable_tau_in_ns; + + + + //same setting + if((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)){ + if(eiger_dynamicrange == 32) + printf("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", + (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec); + else + printf("Rate Table already created before: Same Tau %lldns, Same exptime %lldns\n", + (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec); + } + //different setting, calculate table + else{ + eiger_virtual_ratetable_tau_in_ns = custom_tau_in_nsec; + double period_in_sec = (double)(eiger_virtual_subexptime*10)/(double)1e9; + if(eiger_dynamicrange == 16) + period_in_sec = eiger_virtual_exptime; + eiger_virtual_ratetable_period_in_ns = period_in_sec*1e9; + } + //activating rate correction + eiger_virtual_ratecorrection_variable = 1; + printf("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns); + + return eiger_virtual_ratetable_tau_in_ns; +#else //deactivating rate correction if(custom_tau_in_nsec==0){ @@ -986,8 +1325,8 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never b //same setting if((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)){ if(dr == 32) - printf("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", - tau_in_nsec,ratetable_period_in_nsec); + printf("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", + tau_in_nsec,ratetable_period_in_nsec); else printf("Rate Table already created before: Same Tau %lldns, Same exptime %lldns\n", tau_in_nsec,ratetable_period_in_nsec); @@ -1009,10 +1348,15 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never b #endif return Feb_Control_Get_RateTable_Tau_in_nsec(); +#endif } int getRateCorrectionEnable(){ +#ifdef VIRTUAL + return eiger_virtual_ratecorrection_variable; +#else return Feb_Control_GetRateCorrectionVariable(); +#endif } int getDefaultSettingsTau_in_nsec(){ @@ -1028,12 +1372,18 @@ int64_t getCurrentTau(){ if(!getRateCorrectionEnable()) return 0; else +#ifndef VIRTUAL return Feb_Control_Get_RateTable_Tau_in_nsec(); +#else + return eiger_virtual_ratetable_tau_in_ns; +#endif } void setExternalGating(int enable[]){ if(enable>=0){ +#ifndef VIRTUAL Feb_Control_SetExternalEnableMode(enable[0], enable[1]);//enable = 0 or 1, polarity = 0 or 1 , where 1 is positive +#endif eiger_extgating = enable[0]; eiger_extgatingpolarity = enable[1]; } @@ -1042,20 +1392,22 @@ void setExternalGating(int enable[]){ } int setAllTrimbits(int val){ - int ichan; +#ifndef VIRTUAL if(!Feb_Control_SaveAllTrimbitsTo(val)){ cprintf(RED,"error in setting all trimbits to value\n"); return FAIL; - }else{ -#ifdef VERBOSE - printf("Copying register %x value %d\n",destMod->reg,val); + } #endif - if (detectorModules){ - for (ichan=0; ichan<(detectorModules->nchan); ichan++) { - *((detectorModules->chanregs)+ichan)=val; - } +#ifdef VERBOSE + printf("Copying register %x value %d\n",destMod->reg,val); +#endif + if (detectorModules){ + int ichan; + for (ichan=0; ichan<(detectorModules->nchan); ichan++) { + *((detectorModules->chanregs)+ichan)=val; } } + cprintf(GREEN, "All trimbits have been set to %d\n", val); return OK; } @@ -1077,17 +1429,61 @@ int getAllTrimbits(){ } int getBebFPGATemp(){ +#ifdef VIRTUAL + return 0; +#else return Beb_GetBebFPGATemp(); +#endif } int activate(int enable){ +#ifdef VIRTUAL + if (enable >=0) + eiger_virtual_activate = enable; + return eiger_virtual_activate; +#else int ret = Beb_Activate(enable); Feb_Control_activate(ret); return ret; +#endif } int setNetworkParameter(enum NETWORKINDEX mode, int value){ +#ifndef VIRTUAL return Beb_SetNetworkParameter(mode, value); +#else + if (value>-1) { + switch(mode){ + case TXN_LEFT: + eiger_virtual_transmission_delay_left = value; + break; + case TXN_RIGHT: + eiger_virtual_transmission_delay_right = value; + break; + case TXN_FRAME: + eiger_virtual_transmission_delay_frame = value; + break; + case FLOWCTRL_10G: + eiger_virtual_transmission_flowcontrol_10g = value; + if(value>0) value = 1; + break; + default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); + return -1; + } + } + switch(mode){ + case TXN_LEFT: + return eiger_virtual_transmission_delay_left; + case TXN_RIGHT: + return eiger_virtual_transmission_delay_right; + case TXN_FRAME: + return eiger_virtual_transmission_delay_frame; + case FLOWCTRL_10G: + return eiger_virtual_transmission_flowcontrol_10g; + default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); + return -1; + } +#endif } @@ -1100,17 +1496,30 @@ int setNetworkParameter(enum NETWORKINDEX mode, int value){ int prepareAcquisition(){ - +#ifndef VIRTUAL printf("Going to prepare for acquisition with counter_bit:%d\n",Feb_Control_Get_Counter_Bit()); Feb_Control_PrepareForAcquisition(); printf("Going to reset Frame Number\n"); Beb_ResetFrameNumber(); - +#endif return OK; + } int startStateMachine(){ +#ifdef VIRTUAL + eiger_virtual_status = 1; + eiger_virtual_stop = 0; + if(pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) { + cprintf(RED,"Could not start Virtual acquisition thread\n"); + eiger_virtual_status = 0; + return FAIL; + } + cprintf(GREEN,"***Virtual Acquisition started\n"); + return OK; +#else + int ret = OK,prev_flag; //get the DAQ toggle bit prev_flag = Feb_Control_AcquisitionStartedBit(); @@ -1135,21 +1544,48 @@ int startStateMachine(){ /*while(getRunStatus() == IDLE){printf("waiting for being not idle anymore\n");}*/ return ret; +#endif } +#ifdef VIRTUAL +void* start_timer(void* arg) { + eiger_virtual_status = 1; + int wait_in_s = nimages_per_request * eiger_virtual_period; + cprintf(GREEN,"going to wait for %d s\n", wait_in_s); + while(!eiger_virtual_stop && (wait_in_s >= 0)) { + usleep(1000 * 1000); + wait_in_s--; + } + cprintf(GREEN,"Virtual Timer Done***\n"); + + eiger_virtual_status = 0; + return NULL; +} +#endif + + int stopStateMachine(){ cprintf(BG_RED,"Going to stop acquisition\n"); +#ifdef VIRTUAL + eiger_virtual_stop = 0; + return OK; +#else + if((Feb_Control_StopAcquisition() == STATUS_IDLE) & Beb_StopAcquisition()) return OK; cprintf(BG_RED,"failed to stop acquisition\n"); return FAIL; +#endif } int startReadOut(){ printf("Requesting images...\n"); +#ifdef VIRTUAL + return OK; +#else //RequestImages(); int ret_val = 0; dst_requested[0] = 1; @@ -1170,10 +1606,20 @@ int startReadOut(){ return FAIL; else return OK; +#endif } enum runStatus getRunStatus(){ +#ifdef VIRTUAL + if(eiger_virtual_status == 0){ + printf("Status: IDLE\n"); + return IDLE; + }else{ + printf("Status: RUNNING...\n"); + return RUNNING; + } +#else int i = Feb_Control_AcquisitionInProgress(); switch (i) { @@ -1189,11 +1635,22 @@ enum runStatus getRunStatus(){ } return IDLE; +#endif } void readFrame(int *ret, char *mess){ +#ifdef VIRTUAL + while(eiger_virtual_status) { + //cprintf(RED,"Waiting for finished flag\n"); + usleep(5000); + } + *ret = (int)FINISHED; + strcpy(mess,"acquisition successfully finished\n"); + return; +#else + if(Feb_Control_WaitForFinishedFlag(5000) == STATUS_ERROR) { cprintf(RED,"Error: Waiting for finished flag\n"); *ret = FAIL; @@ -1217,6 +1674,7 @@ void readFrame(int *ret, char *mess){ printf("*****Done Waiting...\n"); *ret = (int)FINISHED; strcpy(mess,"acquisition successfully finished\n"); +#endif } @@ -1302,8 +1760,9 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod){ else printf("Not Copying trimbits\n"); #endif for (idac=0; idac<(srcMod->ndac); idac++) { - if (*((srcMod->dacs)+idac)>=0) + if (*((srcMod->dacs)+idac)>=0) { *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } } for (iadc=0; iadc<(srcMod->nadc); iadc++) { if (*((srcMod->adcs)+iadc)>=0) @@ -1355,4 +1814,4 @@ enum synchronizationMode setSynchronization(enum synchronizationMode arg){ -#endif +//#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList_virtual.c b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList_virtual.c deleted file mode 100644 index 5b2d92451..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList_virtual.c +++ /dev/null @@ -1,1001 +0,0 @@ -#ifdef SLS_DETECTOR_FUNCTION_LIST - - -#include -#include -#include //usleep -#include -#include - -#include "slsDetectorFunctionList.h" - - -int default_tau_from_file= -1; - -#define BEB_NUM 34 - -enum detectorSettings thisSettings; -const char* dac_names[16] = {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"}; - -enum{E_PARALLEL, E_NON_PARALLEL, E_SAFE}; - -sls_detector_module *detectorModules=NULL; -int *detectorChips=NULL; -int *detectorChans=NULL; -dacs_t *detectorDacs=NULL; -dacs_t *detectorAdcs=NULL; - -int eiger_highvoltage = 0; -int eiger_theo_highvoltage = 0; -int eiger_iodelay = 0; -int eiger_photonenergy = 0; -int eiger_dynamicrange = 0; -int eiger_readoutmode = 0; -int eiger_storeinmem = 0; -int eiger_readoutspeed = 0; -int eiger_triggermode = 0; -int eiger_extgating = 0; -int eiger_extgatingpolarity = 0; - - -int eiger_nexposures = 1; -int eiger_ncycles = 1; - -//values for virtual server -double eiger_virtual_exptime = 0; -int64_t eiger_virtual_subexptime = 0; -double eiger_virtual_period = 0; -int eiger_virtual_counter_bit=1; -int eiger_virtual_ratecorrection_variable=0; -int64_t eiger_virtual_ratetable_tau_in_ns=-1; -int64_t eiger_virtual_ratetable_period_in_ns=-1; -int eiger_virtual_transmission_delay_left=0; -int eiger_virtual_transmission_delay_right=0; -int eiger_virtual_transmission_delay_frame=0; -int eiger_virtual_transmission_flowcontrol_10g=0; -int eiger_virtual_status=0; -pthread_t eiger_virtual_tid; - -int send_to_ten_gig = 0; -int ndsts_in_use=32; -unsigned int nimages_per_request=1; -int on_dst=0; -int dst_requested[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - -int default_gain_values[3] = {517000,517000,517000}; -int default_offset_values[3] = {3851000,3851000,3851000}; - - -enum masterFlags masterMode=IS_SLAVE; -int top = 0; -int master = 0; -int normal = 0; - - - - - -/* basic tests */ - -void checkFirmwareCompatibility(int flag){ - cprintf(BLUE,"\n\n" - "********************************************************\n" - "***************** EIGER Virtual Server *****************\n" - "********************************************************\n"); -} - - - - - -/* Ids */ - -int64_t getDetectorId(enum idMode arg){ - return 0; -} - -u_int64_t getFirmwareVersion() { - return 0; -} - - - -u_int32_t getDetectorNumber(){ - return 0; -} - - -u_int64_t getDetectorMAC() { - return 0; -} - - -u_int32_t getDetectorIP(){ - return 0; -} - - - - - -/* initialization */ - -void initControlServer(){ - getModuleConfiguration(); - setupDetector(); - printf("\n"); -} - -void initStopServer(){ - getModuleConfiguration(); - printf("\n"); -} - - -void getModuleConfiguration(){ -#ifdef VIRTUAL_MASTER - master = 1; - top = 1; -#else - master = 0; - top = 1; -#endif -#ifdef VIRTUAL_9M - normal = 0; -#else - normal = 1; -#endif - if(top) printf("*************** TOP ***************\n"); - else printf("*************** BOTTOM ***************\n"); - if(master) printf("*************** MASTER ***************\n"); - else printf("*************** SLAVE ***************\n"); - if(normal) printf("*************** NORMAL ***************\n"); - else printf("*************** SPECIAL ***************\n"); -} - - - -/* set up detector */ - -void allocateDetectorStructureMemory(){ - printf("This Server is for 1 Eiger half module (250k)\n"); - - //Allocation of memory - detectorModules=malloc(sizeof(sls_detector_module)); - detectorChips=malloc(NCHIP*sizeof(int)); - detectorChans=malloc(NCHIP*NCHAN*sizeof(int)); - detectorDacs=malloc(NDAC*sizeof(dacs_t)); - detectorAdcs=malloc(NADC*sizeof(dacs_t)); -#ifdef VERBOSE - printf("modules from 0x%x to 0x%x\n",detectorModules, detectorModules+n); - printf("chips from 0x%x to 0x%x\n",detectorChips, detectorChips+n*NCHIP); - printf("chans from 0x%x to 0x%x\n",detectorChans, detectorChans+n*NCHIP*NCHAN); - printf("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs+n*NDAC); - printf("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs+n*NADC); -#endif - (detectorModules)->dacs=detectorDacs; - (detectorModules)->adcs=detectorAdcs; - (detectorModules)->chipregs=detectorChips; - (detectorModules)->chanregs=detectorChans; - (detectorModules)->ndac=NDAC; - (detectorModules)->nadc=NADC; - (detectorModules)->nchip=NCHIP; - (detectorModules)->nchan=NCHIP*NCHAN; - (detectorModules)->module=0; - (detectorModules)->gain=0; - (detectorModules)->offset=0; - (detectorModules)->reg=0; - thisSettings = UNINITIALIZED; - - // if trimval requested, should return -1 to acknowledge unknown - int ichan=0; - for (ichan=0; ichan<(detectorModules->nchan); ichan++) { - *((detectorModules->chanregs)+ichan) = -1; - } -} - - - -void setupDetector() { - - allocateDetectorStructureMemory(); - //set dacs - printf("Setting Default Dac values\n"); - { - int i = 0; - int retval[2]={-1,-1}; - const int defaultvals[NDAC] = DEFAULT_DAC_VALS; - for(i = 0; i < NDAC; ++i) { - setDAC((enum DACINDEX)i,defaultvals[i],0,0,retval); - if (retval[0] != defaultvals[i]) - cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]); - } - } - - //setting default measurement parameters - setTimer(FRAME_NUMBER, DEFAULT_NUM_FRAMES); - setTimer(ACQUISITION_TIME, DEFAULT_EXPTIME); - setTimer(SUBFRAME_ACQUISITION_TIME, DEFAULT_SUBFRAME_EXPOSURE_VAL); - setTimer(FRAME_PERIOD, DEFAULT_PERIOD); - setDynamicRange(DEFAULT_DYNAMIC_RANGE); - eiger_photonenergy = DEFAULT_PHOTON_ENERGY; - setReadOutFlags(DEFAULT_READOUT_FLAG); - setSpeed(CLOCK_DIVIDER, DEFAULT_CLK_SPEED);//clk_devider,half speed - setIODelay(DEFAULT_IO_DELAY, DEFAULT_MOD_INDEX); - setTiming(DEFAULT_TIMING_MODE); - //SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15); - setRateCorrection(DEFAULT_RATE_CORRECTION); - int enable[2] = {DEFAULT_EXT_GATING_ENABLE, DEFAULT_EXT_GATING_POLARITY}; - setExternalGating(enable);//disable external gating - setHighVoltage(DEFAULT_HIGH_VOLTAGE); -} - - - - -/* advanced read/write reg */ -uint32_t writeRegister(uint32_t offset, uint32_t data) { - return 0; -} - -uint32_t readRegister(uint32_t offset) { - return 0; -} - - -/* set parameters - nmod, dr, roi */ - -int setNMod(int nm, enum dimension dim){ - return NMOD; -} - - -int getNModBoard(enum dimension arg){ - return NMAXMOD; -} - -int setDynamicRange(int dr){ - if(dr > 0){ - printf(" Setting dynamic range: %d\n",dr); - eiger_dynamicrange = dr; - } - return eiger_dynamicrange; -} - - - - -/* parameters - readout */ - -int setSpeed(enum speedVariable arg, int val){ - - if (arg != CLOCK_DIVIDER) - return -1; - - if(val != -1){ - printf(" Setting Read out Speed: %d\n",val); - eiger_readoutspeed = val; - } - return eiger_readoutspeed; -} - - -enum readOutFlags setReadOutFlags(enum readOutFlags val){ - - enum readOutFlags retval = GET_READOUT_FLAGS; - if(val!=GET_READOUT_FLAGS){ - - - if(val&0xF0000){ - switch(val){ - case PARALLEL: val=E_PARALLEL; printf(" Setting Read out Flag: Parallel\n"); break; - case NONPARALLEL: val=E_NON_PARALLEL; printf(" Setting Read out Flag: Non Parallel\n"); break; - case SAFE: val=E_SAFE; printf(" Setting Read out Flag: Safe\n"); break; - - default: - cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); - return -1; - } - printf(" Setting Read out Flag: %d\n",val); - eiger_readoutmode = val; - }else{ - switch(val){ - case STORE_IN_RAM: val=1; printf(" Setting Read out Flag: Store in Ram\n"); break; - case CONTINOUS_RO: val=0; printf(" Setting Read out Flag: Continuous Readout\n"); break; - - default: - cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); - return -1; - } - printf(" Setting store in ram variable: %d\n",val); - eiger_storeinmem = val; - - } - } - - switch(eiger_readoutmode){ - case E_PARALLEL: retval=PARALLEL; break; - case E_NON_PARALLEL: retval=NONPARALLEL; break; - case E_SAFE: retval=SAFE; break; - } - - switch(eiger_storeinmem){ - case 0: retval|=CONTINOUS_RO; break; - case 1: retval|=STORE_IN_RAM; break; - } - printf("Read out Flag: 0x%x\n",retval); - return retval; -} - - - - - - - - -/* parameters - timer */ - -int64_t setTimer(enum timerIndex ind, int64_t val){ - - switch(ind){ - case FRAME_NUMBER: - if(val >= 0){ - printf(" Setting number of frames: %d * %d\n",(unsigned int)val,eiger_ncycles); - eiger_nexposures = val; - nimages_per_request = eiger_nexposures * eiger_ncycles; - }return eiger_nexposures; - - case ACQUISITION_TIME: - if(val >= 0){ - printf(" Setting exp time: %fs\n",val/(1E9)); - eiger_virtual_exptime = (val/(1E9)); - } - return eiger_virtual_exptime*1e9; - - case SUBFRAME_ACQUISITION_TIME: - if(val >= 0){ - printf(" Setting sub exp time: %lldns\n",(long long int)val/10); - eiger_virtual_subexptime = (val/(10)); - } - return eiger_virtual_subexptime*10; - - case FRAME_PERIOD: - if(val >= 0){ - printf(" Setting acq period: %fs\n",val/(1E9)); - eiger_virtual_period = (val/(1E9)); - } - return eiger_virtual_period*1e9; - - case CYCLES_NUMBER: - if(val >= 0){ - printf(" Setting number of triggers: %d * %d\n",(unsigned int)val,eiger_nexposures); - eiger_ncycles = (val/(1E9)); - nimages_per_request = eiger_nexposures * eiger_ncycles; - } - return eiger_ncycles; - default: - cprintf(RED,"Warning: Timer Index not implemented for this detector: %d\n", ind); - break; - } - - return -1; -} - - - - - -/* parameters - channel, chip, module, settings */ - - -int setModule(sls_detector_module myMod, int delay){ - int retval[2]; - int i; - - //#ifdef VERBOSE - printf("Setting module with settings %d\n",myMod.reg); - //#endif - - setSettings( (enum detectorSettings)myMod.reg,-1); - - if(setIODelay(delay, -1)!= delay){ - cprintf(RED,"could not set iodelay %d\n",delay); - return FAIL; - } - - //copy module locally - if (detectorModules) - copyModule(detectorModules,&myMod); - - //set dac values - for(i=0;i= 0) - eiger_photonenergy = ev; - return getThresholdEnergy(imod); -} - - - - - -/* parameters - dac, adc, hv */ - -void setDAC(enum DACINDEX ind, int val, int imod, int mV, int retval[]){ - - if(ind == VTHRESHOLD){ - int ret[5]; - setDAC(VCMP_LL,val,imod,mV,retval); - ret[0] = retval[mV]; - setDAC(VCMP_LR,val,imod,mV,retval); - ret[1] = retval[mV]; - setDAC(VCMP_RL,val,imod,mV,retval); - ret[2] = retval[mV]; - setDAC(VCMP_RR,val,imod,mV,retval); - ret[3] = retval[mV]; - setDAC(VCP,val,imod,mV,retval); - ret[4] = retval[mV]; - - - if((ret[0]== ret[1])&& - (ret[1]==ret[2])&& - (ret[2]==ret[3]) && - (ret[3]==ret[4])) - cprintf(GREEN,"vthreshold match\n"); - else{ - retval[0] = -1;retval[1] = -1; - cprintf(RED,"vthreshold mismatch 0:%d 1:%d 2:%d 3:%d\n", - ret[0],ret[1],ret[2],ret[3]); - } - return; - } - char iname[10]; - - if(((int)ind>=0)&&((int)ind= 0) - printf("Setting dac %d: %s to %d ",ind, iname,val); - else - printf("Getting dac %d: %s ",ind, iname); - if(mV) - printf("in mV\n"); - else - printf("in dac units\n"); -#endif - - if (mV){ - retval[0] = (int)(((val-0)/(2048-0))*(4096-1) + 0.5); - retval[1] = val; - }else - retval[0] = val; - - (detectorModules)->dacs[ind] = retval[0]; -} - - - -int getADC(enum ADCINDEX ind, int imod){ - return 0; -} - - -int setHighVoltage(int val){ - if (master) { - // set - if(val!=-1){ - eiger_theo_highvoltage = val; - } - return eiger_theo_highvoltage; - } - - return SLAVE_HIGH_VOLTAGE_READ_VAL; -} - - - - - - - -/* parameters - timing, extsig */ - -enum externalCommunicationMode setTiming( enum externalCommunicationMode arg){ - enum externalCommunicationMode ret=GET_EXTERNAL_COMMUNICATION_MODE; - if(arg != GET_EXTERNAL_COMMUNICATION_MODE){ - switch((int)arg){ - case AUTO_TIMING: ret = 0; break; - case TRIGGER_EXPOSURE: ret = 2; break; - case BURST_TRIGGER: ret = 1; break; - case GATE_FIX_NUMBER: ret = 3; break; - } - printf(" Setting Triggering Mode: %d\n",(int)ret); - eiger_triggermode = ret; - } - - ret = eiger_triggermode; - switch((int)ret){ - case 0: ret = AUTO_TIMING; break; - case 2: ret = TRIGGER_EXPOSURE; break; - case 1: ret = BURST_TRIGGER; break; - case 3: ret = GATE_FIX_NUMBER; break; - default: - printf("Unknown trigger mode found %d\n",ret); - ret = 0; - } - return ret; -} - - - - - - -/* configure mac */ - -int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2, int ival) { - return 0; -} - - - -int setDetectorPosition(int pos[]) { - return OK; -} - - - -/* eiger specific - iodelay, 10g, pulse, rate, temp, activate, delay nw parameter */ - -int setIODelay(int val, int imod){ - if(val!=-1){ - printf(" Setting IO Delay: %d\n",val); - eiger_iodelay = val; - } - return eiger_iodelay; -} - - -int enableTenGigabitEthernet(int val){ - if(val!=-1){ - if(val>0) - send_to_ten_gig = 1; - else - send_to_ten_gig = 0; - //configuremac called from client - } -#ifdef VERBOSE - printf("10Gbe:%d\n",send_to_ten_gig); -#endif - return send_to_ten_gig; -} - - -int setCounterBit(int val){ - if(val!=-1){ - eiger_virtual_counter_bit = val; -#ifdef VERBOSE - printf("Counter Bit:%d\n",val); -#endif - } - return eiger_virtual_counter_bit; -} - - -int pulsePixel(int n, int x, int y){ - return OK; -} - -int pulsePixelNMove(int n, int x, int y){ - return OK; -} - -int pulseChip(int n){ - return OK; -} - -int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never be -1) - //deactivating rate correction - if(custom_tau_in_nsec==0){ - eiger_virtual_ratecorrection_variable = 0; - return 0; - } - - //when dynamic range changes, use old tau - else if(custom_tau_in_nsec == -1) - custom_tau_in_nsec = eiger_virtual_ratetable_tau_in_ns; - - //get period = subexptime if 32bit , else period = exptime if 16 bit - int64_t actual_period = eiger_virtual_subexptime*10; //already in nsec - if(eiger_dynamicrange == 16) - actual_period = eiger_virtual_exptime; - - int64_t ratetable_period_in_nsec = eiger_virtual_ratetable_period_in_ns; - int64_t tau_in_nsec = eiger_virtual_ratetable_tau_in_ns; - - - - //same setting - if((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)){ - if(eiger_dynamicrange == 32) - printf("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", - (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec); - else - printf("Rate Table already created before: Same Tau %lldns, Same exptime %lldns\n", - (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec); - } - //different setting, calculate table - else{ - eiger_virtual_ratetable_tau_in_ns = custom_tau_in_nsec; - double period_in_sec = (double)(eiger_virtual_subexptime*10)/(double)1e9; - if(eiger_dynamicrange == 16) - period_in_sec = eiger_virtual_exptime; - eiger_virtual_ratetable_period_in_ns = period_in_sec*1e9; - } - //activating rate correction - eiger_virtual_ratecorrection_variable = 1; - printf("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns); - - return eiger_virtual_ratetable_tau_in_ns; -} - -int getRateCorrectionEnable(){ - return eiger_virtual_ratecorrection_variable; -} - -int getDefaultSettingsTau_in_nsec(){ - return default_tau_from_file; -} - -void setDefaultSettingsTau_in_nsec(int t){ - default_tau_from_file = t; - printf("Default tau set to %d\n",default_tau_from_file); -} - -int64_t getCurrentTau(){ - if(!getRateCorrectionEnable()) - return 0; - else - return eiger_virtual_ratetable_tau_in_ns; -} - -void setExternalGating(int enable[]){ - if(enable>=0){ - eiger_extgating = enable[0]; - eiger_extgatingpolarity = enable[1]; - } - enable[0] = eiger_extgating; - enable[1] = eiger_extgatingpolarity; -} - -int setAllTrimbits(int val){ - int ichan; -#ifdef VERBOSE - printf("Copying register %x value %d\n",destMod->reg,val); -#endif - if (detectorModules){ - for (ichan=0; ichan<(detectorModules->nchan); ichan++) { - *((detectorModules->chanregs)+ichan)=val; - } - } - - cprintf(GREEN, "All trimbits have been set to %d\n", val); - return OK; -} - -int getAllTrimbits(){ - int ichan=0; - int value = *((detectorModules->chanregs)); - if (detectorModules){ - for (ichan=0; ichan<(detectorModules->nchan); ichan++) { - if(*((detectorModules->chanregs)+ichan) != value) { - value= -1; - break; - } - - } - } - printf("Value of all Trimbits: %d\n", value); - return value; -} - -int getBebFPGATemp(){ - return 0; -} - -int activate(int enable){ - return enable; -} - -int setNetworkParameter(enum NETWORKINDEX mode, int value){ - if (value>-1) { - switch(mode){ - case TXN_LEFT: - eiger_virtual_transmission_delay_left = value; - break; - case TXN_RIGHT: - eiger_virtual_transmission_delay_right = value; - break; - case TXN_FRAME: - eiger_virtual_transmission_delay_frame = value; - break; - case FLOWCTRL_10G: - eiger_virtual_transmission_flowcontrol_10g = value; - if(value>0) value = 1; - break; - default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); - return -1; - } - } - switch(mode){ - case TXN_LEFT: - return eiger_virtual_transmission_delay_left; - case TXN_RIGHT: - return eiger_virtual_transmission_delay_right; - case TXN_FRAME: - return eiger_virtual_transmission_delay_frame; - case FLOWCTRL_10G: - return eiger_virtual_transmission_flowcontrol_10g; - default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); - return -1; - } -} - - - - - - - -/* aquisition */ - - -int prepareAcquisition(){ - return OK; -} - - -int startStateMachine(){ - - if(pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) { - cprintf(RED,"Could not start Virtual acquisition thread\n"); - return FAIL; - } - eiger_virtual_status = 1; - cprintf(GREEN,"***Virtual Acquisition started\n"); - return OK; -} - -void* start_timer(void* arg) { - double wait_in_s = nimages_per_request * eiger_virtual_period; - cprintf(GREEN,"going to wait for %f s\n", wait_in_s); - usleep(wait_in_s * 1000 * 1000); - cprintf(GREEN,"Virtual Timer Done***\n"); - - eiger_virtual_status = 0; - return NULL; -} - -int stopStateMachine(){ - cprintf(BG_RED,"Going to stop acquisition\n"); - return OK; -} - - -int startReadOut(){ - printf("Requesting images...\n"); - return OK; -} - - -enum runStatus getRunStatus(){ - if(eiger_virtual_status== 0){ - printf("Status: IDLE\n"); - return IDLE; - }else{ - printf("Status: RUNNING...\n"); - return RUNNING; - } - //}else printf("***** not master*** \n"); - - return IDLE; -} - - - -void readFrame(int *ret, char *mess){ - while(eiger_virtual_status) { - //cprintf(RED,"Waiting for finished flag\n"); - usleep(5000); - } - *ret = (int)FINISHED; - strcpy(mess,"acquisition successfully finished\n"); -} - - - - - - - - -/* common */ - - -int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod){ - - int ichip, idac, ichan, iadc; - int ret=OK; - -#ifdef VERBOSE - printf("Copying module %x to module %x\n",srcMod,destMod); -#endif - - if (srcMod->module>=0) { -#ifdef VERBOSE - printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); -#endif - destMod->module=srcMod->module; - } - if (srcMod->serialnumber>=0){ - - destMod->serialnumber=srcMod->serialnumber; - } - //no trimbit feature - if (destMod->nchip && ((srcMod->nchip)>(destMod->nchip))) { - printf("Number of chip of source is larger than number of chips of destination\n"); - return FAIL; - } - //no trimbit feature - if (destMod->nchan && ((srcMod->nchan)>(destMod->nchan))) { - printf("Number of channels of source is larger than number of channels of destination\n"); - return FAIL; - } - if ((srcMod->ndac)>(destMod->ndac)) { - printf("Number of dacs of source is larger than number of dacs of destination\n"); - return FAIL; - } - if ((srcMod->nadc)>(destMod->nadc)) { - printf("Number of dacs of source is larger than number of dacs of destination\n"); - return FAIL; - } - -#ifdef VERBOSE - printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); - printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); - printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); - printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); - -#endif - destMod->ndac=srcMod->ndac; - destMod->nadc=srcMod->nadc; - destMod->nchip=srcMod->nchip; - destMod->nchan=srcMod->nchan; - if (srcMod->reg>=0) - destMod->reg=srcMod->reg; -#ifdef VERBOSE - printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); -#endif - if (srcMod->gain>=0) - destMod->gain=srcMod->gain; - if (srcMod->offset>=0) - destMod->offset=srcMod->offset; - - if((destMod->nchip!=0) || (destMod->nchan!=0)) { - for (ichip=0; ichip<(srcMod->nchip); ichip++) { - if (*((srcMod->chipregs)+ichip)>=0) - *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); - } - for (ichan=0; ichan<(srcMod->nchan); ichan++) { - if (*((srcMod->chanregs)+ichan)>=0) - *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); - } - } -#ifdef VERBOSE - else printf("Not Copying trimbits\n"); -#endif - for (idac=0; idac<(srcMod->ndac); idac++) { - if (*((srcMod->dacs)+idac)>=0) - *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); - } - for (iadc=0; iadc<(srcMod->nadc); iadc++) { - if (*((srcMod->adcs)+iadc)>=0) - *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); - } - return ret; -} - - -int calculateDataBytes(){ - if(send_to_ten_gig) - return setDynamicRange(-1) * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE; - else - return setDynamicRange(-1) * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE; -} - - -int getTotalNumberOfChannels(){return ((int)getNumberOfChannelsPerModule() * (int)getTotalNumberOfModules());} -int getTotalNumberOfChips(){return ((int)getNumberOfChipsPerModule() * (int)getTotalNumberOfModules());} -int getTotalNumberOfModules(){return NMOD;} -int getNumberOfChannelsPerModule(){return ((int)getNumberOfChannelsPerChip() * (int)getTotalNumberOfChips());} -int getNumberOfChipsPerModule(){return NCHIP;} -int getNumberOfDACsPerModule(){return NDAC;} -int getNumberOfADCsPerModule(){return NADC;} -int getNumberOfChannelsPerChip(){return NCHAN;} -int getNumberOfGainsPerModule(){return NGAIN;} -int getNumberOfOffsetsPerModule(){return NOFFSET;} - - - - - - -/* sync */ - -enum masterFlags setMaster(enum masterFlags arg){ - return NO_MASTER; -} - - - -enum synchronizationMode setSynchronization(enum synchronizationMode arg){ - return NO_SYNCHRONIZATION; -} - - - - - - - -#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_defs.h index e6afb173b..dfc9befc1 100644 --- a/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_defs.h @@ -73,9 +73,13 @@ enum NETWORKINDEX {TXN_LEFT, TXN_RIGHT, TXN_FRAME,FLOWCTRL_10G}; #define DEFAULT_DELAY (0) #define DEFAULT_HIGH_VOLTAGE (0) #define DEFAULT_SETTINGS (DYNAMICGAIN) -#define DEFAULT_SUBFRAME_EXPOSURE_VAL (2621440) // 2.6ms +#define DEFAULT_SUBFRAME_EXPOSURE (2621440) // 2.6ms +#define DEFAULT_SUBFRAME_PERIOD (0) #define DEFAULT_DYNAMIC_RANGE (16) -#define DEFAULT_READOUT_FLAG (NONPARALLEL) + +#define DEFAULT_READOUT_MODE (NONPARALLEL) +#define DEFAULT_READOUT_STOREINRAM_MODE (CONTINOUS_RO) +#define DEFAULT_READOUT_OVERFLOW32_MODE (NOOVERFLOW) #define DEFAULT_CLK_SPEED (HALF_SPEED) #define DEFAULT_IO_DELAY (650) #define DEFAULT_TIMING_MODE (AUTO_TIMING) diff --git a/slsDetectorSoftware/eigerDetectorServer/updateAPIVersion.sh b/slsDetectorSoftware/eigerDetectorServer/updateAPIVersion.sh new file mode 100755 index 000000000..618a9b601 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/updateAPIVersion.sh @@ -0,0 +1,7 @@ +SRCFILE=gitInfoEiger.h +DSTFILE=versionAPI.h + +SRCPATTERN=GITDATE +DSTPATTERN=APIEIGER + +awk -v a="$SRCFILE" -v b="$DSTFILE" -v c="$SRCPATTERN" -v d="$DSTPATTERN" 'FNR==NR&&$2==c{x=$3} NR!=FNR{if($2==d){$3="0x"substr(x,5)}print > b}' $SRCFILE $DSTFILE \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/versionAPI.h b/slsDetectorSoftware/eigerDetectorServer/versionAPI.h new file mode 120000 index 000000000..d3bf8d6cf --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/versionAPI.h @@ -0,0 +1 @@ +../commonFiles/versionAPI.h \ No newline at end of file diff --git a/slsDetectorSoftware/f90Interface/externPostProcessing.h b/slsDetectorSoftware/f90Interface/externPostProcessing.h index 605865b91..9225d66f9 100644 --- a/slsDetectorSoftware/f90Interface/externPostProcessing.h +++ b/slsDetectorSoftware/f90Interface/externPostProcessing.h @@ -16,7 +16,7 @@ #include -using namespace std; + diff --git a/slsDetectorSoftware/gitInfo.txt b/slsDetectorSoftware/gitInfo.txt index 2a9dec6de..5e03ab8bc 100644 --- a/slsDetectorSoftware/gitInfo.txt +++ b/slsDetectorSoftware/gitInfo.txt @@ -1,18 +1,9 @@ Path: slsDetectorsPackage/slsDetectorSoftware URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -<<<<<<< HEAD -Repsitory UUID: ab06c33107ecfeb4741d49407903ff80286cf75b -Revision: 1846 -Branch: developer -Last Changed Author: Anna_Bergamaschi -Last Changed Rev: 3731 -Last Changed Date: 2018-03-15 12:30:34.000000002 +0100 ./threadFiles/ThreadPool.o -======= -Repsitory UUID: b8bdbf4da61f95b88893b02ddabc2491b16fa10f -Revision: 1852 -Branch: developer +Repsitory UUID: 6bb7195a2c7dc9526088882e0244a7455d3c15b2 +Revision: 1992 +Branch: 3.3.0-rc Last Changed Author: Dhanya_Thattil -Last Changed Rev: 3746 -Last Changed Date: 2018-03-27 10:47:02.000000002 +0200 ./slsDetector/slsDetector.o ->>>>>>> 7cd35f24b87501374fbaf45693a2adf16dfae3e3 +Last Changed Rev: 3941 +Last Changed Date: 2018-07-18 12:26:21.000000002 +0200 ./threadFiles/ThreadPool.o diff --git a/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c index 52a25b8bd..312165ef1 100755 --- a/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c +++ b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c @@ -303,13 +303,14 @@ void setMasterSlaveConfiguration(){ } } - cprintf(BLUE, "masterflags: %d\n" + cprintf(BLUE, + "masterflags: %d\n" "masterdefaultdelay:%d\n" "patternphase:%d\n" "adcphase:%d\n" "slavepatternphase:%d\n" "slaveadcphase:%d\n" - "rsttosw1delay:%d\n", + "rsttosw1delay:%d\n" "startacqdelay:%d\n", masterflags, masterdefaultdelay, @@ -906,20 +907,15 @@ int64_t getFrames(){ int64_t setExposureTime(int64_t value){ /* time is in ns */ if (value!=-1) { - double actualvalue = value*(1E-9*CLK_FREQ); - value*=(1E-9*CLK_FREQ); - if(fabs(actualvalue-value)>= 0.5){ - if(actualvalue > value) - value++; - else - value--; - } + value = (value * 1E-3 * CLK_FREQ ) + 0.5; } - return set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); + return (set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) / + (1E-3 * CLK_FREQ)) + 0.5; } int64_t getExposureTime(){ - return get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); + return (get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG) / + (1E-3 * CLK_FREQ)) + 0.5; } int64_t setGates(int64_t value){ @@ -933,23 +929,15 @@ int64_t getGates(){ int64_t setPeriod(int64_t value){ /* time is in ns */ if (value!=-1) { - double actualvalue = value*(1E-9*CLK_FREQ); - value*=(1E-9*CLK_FREQ); - if(fabs(actualvalue-value)>= 0.5){ - if(actualvalue > value) - value++; - else - value--; - } + value = (value * 1E-3 * CLK_FREQ ) + 0.5; } - - - - return set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); + return (set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG) / + (1E-3 * CLK_FREQ)) + 0.5; } int64_t getPeriod(){ - return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); + return (get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG) / + (1E-3 * CLK_FREQ)) + 0.5; } int64_t setDelay(int64_t value){ @@ -959,16 +947,10 @@ int64_t setDelay(int64_t value){ value += masterdefaultdelay; cprintf(BLUE,"Actual delay for master: %lld\n", (long long int) value); } - double actualvalue = value*(1E-9*CLK_FREQ); - value*=(1E-9*CLK_FREQ); - if(fabs(actualvalue-value)>= 0.5){ - if(actualvalue > value) - value++; - else - value--; - } + value = (value * 1E-3 * CLK_FREQ ) + 0.5; } - int64_t retval = set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); + int64_t retval = (set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG) / + (1E-3 * CLK_FREQ)) + 0.5; if (masterflags == IS_MASTER) { cprintf(BLUE,"Actual delay read from master: %lld\n", (long long int) retval); retval -= masterdefaultdelay; @@ -978,7 +960,8 @@ int64_t setDelay(int64_t value){ } int64_t getDelay(){ - return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); + return (get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG) / + (1E-3 * CLK_FREQ)) + 0.5; } int64_t setTrains(int64_t value){ @@ -996,37 +979,26 @@ int64_t setProbes(int64_t value){ int64_t setProgress() { - //????? eventually call after setting the registers - return 0; } int64_t getProgress() { - - //should be done in firmware!!!! - return 0; } int64_t getActualTime(){ - return get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG)/(1E-9*CLK_FREQ); + return (get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG) / + (1E-3 * CLK_FREQ)) + 0.5; } int64_t getMeasurementTime(){ int64_t v=get64BitReg(GET_MEASUREMENT_TIME_LSB_REG, GET_MEASUREMENT_TIME_MSB_REG); - /* u_int64_t mask=0x8000000000000000; - if (v & mask ) { -#ifdef VERBOSE - printf("no measurement time left\n"); -#endif - return -1E+9; - } else*/ - return v/(1E-9*CLK_FREQ); + return (v / (1E-3 * CLK_FREQ)) + 0.5; } diff --git a/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt b/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt index 68b17f2ed..221f5726a 100644 --- a/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt +++ b/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsDetectorSoftware/gotthardDetectorServer URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -Repsitory UUID: 675d69392a6497d42b23057c7c8783c8dad768d0 -Revision: 223 -Branch: 3.1.0-rc +Repsitory UUID: 711e0d771edb48e77fa23d965f026add268a31ee +Revision: 235 +Branch: 3.3.0-rc Last Changed Author: Dhanya_Thattil -Last Changed Rev: 3447 -Last Changed Date: 2018-02-27 14:04:08.000000002 +0100 ./server_funcs.c +Last Changed Rev: 3944 +Last Changed Date: 2018-07-26 13:38:23.000000002 +0200 ./server_defs.h diff --git a/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h index 6c3fb814c..51379f12f 100644 --- a/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h +++ b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h @@ -1,6 +1,6 @@ #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" -#define GITREPUUID "675d69392a6497d42b23057c7c8783c8dad768d0" +#define GITREPUUID "711e0d771edb48e77fa23d965f026add268a31ee" #define GITAUTH "Dhanya_Thattil" -#define GITREV 0x3447 -#define GITDATE 0x20180227 -#define GITBRANCH "3.1.0-rc" +#define GITREV 0x3944 +#define GITDATE 0x20180726 +#define GITBRANCH "3.3.0-rc" diff --git a/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServer_developer b/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServer_developer index 916668eda..6d3c38ff5 100755 Binary files a/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServer_developer and b/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServer_developer differ diff --git a/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c index 4670e4968..3e16ddc2e 100755 --- a/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c +++ b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c @@ -114,6 +114,28 @@ int initDetector() { } +int setDefaultDacs() { + printf("Setting Default Dac values\n"); + + int ret = OK; + int i = 0; + int retval[2]={-1,-1}; + const int defaultvals[NDAC] = DEFAULT_DAC_VALS; + + for(i = 0; i < NDAC; ++i) { + // if not already default, set it to default + if (setDACRegister(i, -1, -1) != defaultvals[i]) { + initDACbyIndexDACU(i, defaultvals[i], 0, 0, retval); + if (abs(retval[0] - defaultvals[i])<=3) { + cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]); + ret = FAIL; + } + } + } + + return ret; +} + int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) { diff --git a/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.h index 25ef63f3a..490758f7e 100755 --- a/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.h +++ b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.h @@ -18,6 +18,16 @@ // DAC definitions enum dacsVal{VREF_DS, VCASCN_PB, VCASCP_PB, VOUT_CM, VCASC_OUT, VIN_CM, VREF_COMP, IB_TESTC,HIGH_VOLTAGE, CONFGAIN}; +#define DEFAULT_DAC_VALS { \ + 660, /* VREF_DS */ \ + 650, /* VCASCN_PB */ \ + 1480, /* VCASCP_PB */ \ + 1520, /* VOUT_CM */ \ + 1320, /* VCASC_OUT */ \ + 1350, /* VIN_CM */ \ + 350, /* VREF_COMP */ \ + 2001 /* IB_TESTC */ \ + }; /* DAC adresses */ #define DACCS {0,0,1,1,2,2,3,3,4,4,5,5,6,6} @@ -84,6 +94,7 @@ enum adcVals{TEMP_FPGA, TEMP_ADC}; void showbits(int h); int initDetector(); +int setDefaultDacs(); int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan); int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip); int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod); diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_defs.h b/slsDetectorSoftware/gotthardDetectorServer/server_defs.h index 794e76546..6dc6bf59d 100755 --- a/slsDetectorSoftware/gotthardDetectorServer/server_defs.h +++ b/slsDetectorSoftware/gotthardDetectorServer/server_defs.h @@ -54,7 +54,7 @@ #define DEBUGOUT #endif -#define CLK_FREQ 32.1E+6 +#define CLK_FREQ 32.007729 #endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c index b3dee5d5d..912c137a1 100755 --- a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c @@ -11,6 +11,7 @@ #include "registers_g.h" #include "gitInfoGotthard.h" #include "AD9257.h" // include "commonServerFunctions.h" +#include "versionAPI.h" #define FIFO_DATA_REG_OFF 0x50<<11 #define CONTROL_REG 0x24<<11 @@ -87,9 +88,10 @@ int init_detector( int b) { setPhaseShiftOnce(); configureADC(); setADC(-1); //already does setdaqreg and clean fifo - setSettings(GET_SETTINGS,-1); + setSettings(DYNAMICGAIN,-1); + setDefaultDacs(); - //Initialization + //Initialization setFrames(1); setTrains(1); setExposureTime(1e6); @@ -195,6 +197,7 @@ int function_table() { flist[F_CLEANUP_ACQUISITION]=&stop_receiver; flist[F_CALIBRATE_PEDESTAL]=&calibrate_pedestal; flist[F_WRITE_ADC_REG]=&write_adc_register; + flist[F_CHECK_VERSION]= &check_version; return OK; } @@ -591,6 +594,8 @@ int get_id(int file_des) { case DETECTOR_SOFTWARE_VERSION: retval = (GITDATE & 0xFFFFFF); break; + case CLIENT_SOFTWARE_API_VERSION: + return APIGOTTHARD; default: printf("Required unknown id %d \n", arg); ret=FAIL; @@ -1660,19 +1665,43 @@ int set_settings(int file_des) { sprintf(mess,"Detector locked by %s\n",lastClientIP); } else { #ifdef MCB_FUNCS - retval=setSettings(arg[0],imod); -#endif + switch(isett) { + case GET_SETTINGS: + case UNINITIALIZED: + case DYNAMICGAIN: + case HIGHGAIN: + case LOWGAIN: + case MEDIUMGAIN: + case VERYHIGHGAIN: + break; + default: + ret = FAIL; + sprintf(mess,"Setting (%d) is not implemented for this detector.\n" + "Options are dynamicgain, highgain, lowgain, mediumgain and " + "veryhighgain.\n", isett); + cprintf(RED, "Warning: %s", mess); + break; + } + if (ret != FAIL) { + retval=setSettings(isett,imod); #ifdef VERBOSE - printf("Settings changed to %d\n",retval); -#endif - - if (retval==isett || isett<0) { - ret=OK; - } else { - ret=FAIL; - printf("Changing settings of module %d: wrote %d but read %d\n", imod, isett, retval); - } - + printf("Settings changed to %d\n",retval); +#endif + if (retval != isett && isett >= 0) { + ret=FAIL; + sprintf(mess, "Changing settings of module %d: wrote %d but read %d\n", imod, isett, retval); + printf("Warning: %s",mess); + } + + else { + ret = setDefaultDacs(); + if (ret == FAIL) { + strcpy(mess,"Could change settings, but could not set to default dacs\n"); + cprintf(RED, "Warning: %s", mess); + } + } + } +#endif } if (ret==OK && differentClients==1) ret=FORCE_UPDATE; @@ -3117,3 +3146,67 @@ int write_adc_register(int file_des) { } + + +int check_version(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"check version failed\n"); + + + + // receive arguments + int64_t arg=-1; + n = receiveData(file_des,&arg,sizeof(arg),INT64); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + // execute action + if (ret == OK) { +#ifdef VERBOSE + printf("Checking versioning compatibility with value %d\n",arg); +#endif + int64_t client_requiredVersion = arg; + int64_t det_apiVersion = APIGOTTHARD; + int64_t det_version = (GITDATE & 0xFFFFFF); + + // old client + if (det_apiVersion > client_requiredVersion) { + ret = FAIL; + sprintf(mess,"Client's detector SW API version: (0x%llx). " + "Detector's SW API Version: (0x%llx). " + "Incompatible, update client!\n", + client_requiredVersion, det_apiVersion); + cprintf(RED, "Warning: %s", mess); + } + + // old software + else if (client_requiredVersion > det_version) { + ret = FAIL; + sprintf(mess,"Detector SW Version: (0x%llx). " + "Client's detector SW API Version: (0x%llx). " + "Incompatible, update detector software!\n", + det_version, client_requiredVersion); + cprintf(RED, "Warning: %s", mess); + } + } + + + + // ret could be swapped during sendData + ret1 = ret; + // send ok / fail + n = sendData(file_des,&ret1,sizeof(ret),INT32); + // send return argument + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h index 8571ae50d..832ab3602 100755 --- a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h @@ -95,5 +95,5 @@ int calibrate_pedestal(int); int set_roi(int); int write_adc_register(int); - +int check_version(int); #endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/updateAPIVersion.sh b/slsDetectorSoftware/gotthardDetectorServer/updateAPIVersion.sh new file mode 100755 index 000000000..2d5d8d04d --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/updateAPIVersion.sh @@ -0,0 +1,7 @@ +SRCFILE=gitInfoGotthard.h +DSTFILE=versionAPI.h + +SRCPATTERN=GITDATE +DSTPATTERN=APIGOTTHARD + +awk -v a="$SRCFILE" -v b="$DSTFILE" -v c="$SRCPATTERN" -v d="$DSTPATTERN" 'FNR==NR&&$2==c{x=$3} NR!=FNR{if($2==d){$3="0x"substr(x,5)}print > b}' $SRCFILE $DSTFILE \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/versionAPI.h b/slsDetectorSoftware/gotthardDetectorServer/versionAPI.h new file mode 120000 index 000000000..d3bf8d6cf --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/versionAPI.h @@ -0,0 +1 @@ +../commonFiles/versionAPI.h \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/Makefile.virtual b/slsDetectorSoftware/jungfrauDetectorServer/Makefile.virtual index b3c6ce7f8..97b4812d6 100644 --- a/slsDetectorSoftware/jungfrauDetectorServer/Makefile.virtual +++ b/slsDetectorSoftware/jungfrauDetectorServer/Makefile.virtual @@ -1,6 +1,6 @@ CC = gcc CFLAGS += -Wall -DJUNGFRAUD -DVIRTUAL -DSLS_DETECTOR_FUNCTION_LIST -DDACS_INT -DSTOP_SERVER #-DVERBOSEI #-DVERBOSE -LDLIBS += -lm -lstdc++ +LDLIBS += -lm -lstdc++ -pthread PROGS = jungfrauDetectorServer_virtual DESTDIR ?= bin diff --git a/slsDetectorSoftware/jungfrauDetectorServer/RegisterDefs.h b/slsDetectorSoftware/jungfrauDetectorServer/RegisterDefs.h index 697f0eaf5..3d46be463 100644 --- a/slsDetectorSoftware/jungfrauDetectorServer/RegisterDefs.h +++ b/slsDetectorSoftware/jungfrauDetectorServer/RegisterDefs.h @@ -75,8 +75,8 @@ #define TIME_FROM_START_MSB_REG (0x11 << MEM_MAP_SHIFT) /* Get Delay 64 bit register */ -#define GET_DELAY_LSB_REG (0x12 << MEM_MAP_SHIFT) -#define GET_DELAY_MSB_REG (0x13 << MEM_MAP_SHIFT) +#define GET_DELAY_LSB_REG (0x12 << MEM_MAP_SHIFT) // different kind of delay +#define GET_DELAY_MSB_REG (0x13 << MEM_MAP_SHIFT) // different kind of delay /* Get Cycles 64 bit register */ #define GET_CYCLES_LSB_REG (0x14 << MEM_MAP_SHIFT) @@ -297,7 +297,35 @@ /** DAQ Register */ -#define DAQ_REG (0x5D << MEM_MAP_SHIFT) //TBD in firmware +#define DAQ_REG (0x5D << MEM_MAP_SHIFT) + +#define DAQ_SETTINGS_MSK (DAQ_HIGH_GAIN_MSK | DAQ_FIX_GAIN_MSK | DAQ_FRCE_SWTCH_GAIN_MSK) +#define DAQ_HIGH_GAIN_OFST (0) +#define DAQ_HIGH_GAIN_MSK (0x00000001 << DAQ_HIGH_GAIN_OFST) +#define DAQ_FIX_GAIN_DYNMC_VAL ((0x0 << DAQ_HIGH_GAIN_OFST) & DAQ_HIGH_GAIN_MSK) +#define DAQ_FIX_GAIN_HIGHGAIN_VAL ((0x1 << DAQ_HIGH_GAIN_OFST) & DAQ_HIGH_GAIN_MSK) +#define DAQ_FIX_GAIN_OFST (1) +#define DAQ_FIX_GAIN_MSK (0x00000003 << DAQ_FIX_GAIN_OFST) +#define DAQ_FIX_GAIN_STG_1_VAL ((0x1 << DAQ_FIX_GAIN_OFST) & DAQ_FIX_GAIN_MSK) +#define DAQ_FIX_GAIN_STG_2_VAL ((0x3 << DAQ_FIX_GAIN_OFST) & DAQ_FIX_GAIN_MSK) +#define DAQ_CMP_RST_OFST (4) +#define DAQ_CMP_RST_MSK (0x00000001 << DAQ_CMP_RST_OFST) +#define DAQ_STRG_CELL_SLCT_OFST (8) +#define DAQ_STRG_CELL_SLCT_MSK (0x0000000F << DAQ_STRG_CELL_SLCT_OFST) +#define DAQ_FRCE_SWTCH_GAIN_OFST (12) +#define DAQ_FRCE_SWTCH_GAIN_MSK (0x00000003 << DAQ_FRCE_SWTCH_GAIN_OFST) +#define DAQ_FRCE_GAIN_STG_1_VAL ((0x1 << DAQ_FRCE_SWTCH_GAIN_OFST) & DAQ_FRCE_SWTCH_GAIN_MSK) +#define DAQ_FRCE_GAIN_STG_2_VAL ((0x3 << DAQ_FRCE_SWTCH_GAIN_OFST) & DAQ_FRCE_SWTCH_GAIN_MSK) +#define DAQ_ELCTRN_CLLCTN_MDE_OFST (14) +#define DAQ_ELCTRN_CLLCTN_MDE_MSK (0x00000001 << DAQ_ELCTRN_CLLCTN_MDE_OFST) +#define DAQ_G2_CNNT_OFST (15) +#define DAQ_G2_CNNT_MSK (0x00000001 << DAQ_G2_CNNT_OFST) +#define DAQ_CRRNT_SRC_ENBL_OFST (16) +#define DAQ_CRRNT_SRC_ENBL_MSK (0x00000001 << DAQ_CRRNT_SRC_ENBL_OFST) +#define DAQ_CRRNT_SRC_CLMN_FIX_OFST (17) +#define DAQ_CRRNT_SRC_CLMN_FIX_MSK (0x00000001 << DAQ_CRRNT_SRC_CLMN_FIX_OFST) +#define DAQ_CRRNT_SRC_CLMN_SLCT_OFST (20) +#define DAQ_CRRNT_SRC_CLMN_SLCT_MSK (0x0000003F << DAQ_CRRNT_SRC_CLMN_SLCT_OFST) /** Chip Power Register */ #define CHIP_POWER_REG (0x5E << MEM_MAP_SHIFT) @@ -321,8 +349,8 @@ /* Set Delay 64 bit register */ -#define SET_DELAY_LSB_REG (0x60 << MEM_MAP_SHIFT) -#define SET_DELAY_MSB_REG (0x61 << MEM_MAP_SHIFT) +#define SET_DELAY_LSB_REG (0x60 << MEM_MAP_SHIFT) // different kind of delay +#define SET_DELAY_MSB_REG (0x61 << MEM_MAP_SHIFT) // different kind of delay /* Set Cycles 64 bit register */ #define SET_CYCLES_LSB_REG (0x62 << MEM_MAP_SHIFT) @@ -345,7 +373,7 @@ #define SET_TRIGGER_DELAY_MSB_REG (0x71 << MEM_MAP_SHIFT) /* Module Coordinates Register 0 */ -#define COORD_0 (0x7C << MEM_MAP_SHIFT) +#define COORD_0_REG (0x7C << MEM_MAP_SHIFT) #define COORD_0_Y_OFST (0) #define COORD_0_Y_MSK (0x0000FFFF << COORD_0_Y_OFST) @@ -353,18 +381,20 @@ #define COORD_0_X_MSK (0x0000FFFF << COORD_0_X_OFST) /* Module Coordinates Register 1 */ -#define COORD_1 (0x7D << MEM_MAP_SHIFT) +#define COORD_1_REG (0x7D << MEM_MAP_SHIFT) #define COORD_0_Z_OFST (0) #define COORD_0_Z_MSK (0x0000FFFF << COORD_0_Z_OFST) /* ASIC Control Register */ -#define ASIC_CTRL_REG (0x7F) +#define ASIC_CTRL_REG (0x7F << MEM_MAP_SHIFT) #define ASIC_CTRL_PRCHRG_TMR_OFST (0) #define ASIC_CTRL_PRCHRG_TMR_MSK (0x000000FF << ASIC_CTRL_PRCHRG_TMR_OFST) +#define ASIC_CTRL_PRCHRG_TMR_VAL ((0x1F << ASIC_CTRL_PRCHRG_TMR_OFST) & ASIC_CTRL_PRCHRG_TMR_MSK) #define ASIC_CTRL_DS_TMR_OFST (8) #define ASIC_CTRL_DS_TMR_MSK (0x000000FF << ASIC_CTRL_DS_TMR_OFST) +#define ASIC_CTRL_DS_TMR_VAL ((0x1F << ASIC_CTRL_DS_TMR_OFST) & ASIC_CTRL_DS_TMR_MSK) #endif //REGISTERS_G_H diff --git a/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 995b38685..954b478a1 100755 Binary files a/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_virtual b/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_virtual index cd39898fa..2a6a8c8c5 100755 Binary files a/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_virtual and b/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServer_virtual differ diff --git a/slsDetectorSoftware/jungfrauDetectorServer/gitInfo.txt b/slsDetectorSoftware/jungfrauDetectorServer/gitInfo.txt index 889923a98..6db843d23 100644 --- a/slsDetectorSoftware/jungfrauDetectorServer/gitInfo.txt +++ b/slsDetectorSoftware/jungfrauDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsDetectorSoftware/jungfrauDetectorServer URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -Repsitory UUID: da010a03d725b6f18020d2142d58771534414274 -Revision: 135 +Repsitory UUID: 3b6ead77836f2b6d2a795a9a994259d1dc8c131d +Revision: 159 Branch: developer -Last Changed Author: Erik_Frojdh -Last Changed Rev: 3751 -Last Changed Date: 2018-04-03 16:29:40.000000002 +0200 ./RegisterDefs.h +Last Changed Author: Dhanya_Thattil +Last Changed Rev: 3943 +Last Changed Date: 2018-07-17 16:15:43.000000002 +0200 ./RegisterDefs.h diff --git a/slsDetectorSoftware/jungfrauDetectorServer/gitInfoJungfrau.h b/slsDetectorSoftware/jungfrauDetectorServer/gitInfoJungfrau.h index 37d82e952..baa181354 100644 --- a/slsDetectorSoftware/jungfrauDetectorServer/gitInfoJungfrau.h +++ b/slsDetectorSoftware/jungfrauDetectorServer/gitInfoJungfrau.h @@ -1,6 +1,6 @@ #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" -#define GITREPUUID "da010a03d725b6f18020d2142d58771534414274" -#define GITAUTH "Erik_Frojdh" -#define GITREV 0x3751 -#define GITDATE 0x20180403 +#define GITREPUUID "3b6ead77836f2b6d2a795a9a994259d1dc8c131d" +#define GITAUTH "Dhanya_Thattil" +#define GITREV 0x3943 +#define GITDATE 0x20180717 #define GITBRANCH "developer" diff --git a/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorFunctionList.c index bcdd99749..f39c44890 100644 --- a/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -3,11 +3,14 @@ #include "slsDetectorFunctionList.h" #include "gitInfoJungfrau.h" - - #include "AD9257.h" // include "commonServerFunctions.h", which in turn includes "blackfin.h" #include "programfpga.h" +#include "versionAPI.h" +#ifdef VIRTUAL +#include +#include +#endif /* global variables */ //jungfrau doesnt require chips and chans (save memory) sls_detector_module *detectorModules=NULL; @@ -21,10 +24,28 @@ int highvoltage = 0; int dacValues[NDAC]; int32_t clkPhase[2] = {0, 0}; +#ifdef VIRTUAL +pthread_t pthread_virtual_tid; +int virtual_status = 0; +int virtual_stop = 0; +#endif /* basic tests */ +int firmware_compatibility = OK; +int firmware_check_done = 0; +char firmware_message[MAX_STR_LENGTH]; + +int isFirmwareCheckDone() { + return firmware_check_done; +} + +int getFirmwareCheckResult(char** mess) { + *mess = firmware_message; + return firmware_compatibility; +} + void checkFirmwareCompatibility(int flag) { #ifdef VIRTUAL cprintf(BLUE,"\n\n" @@ -32,23 +53,36 @@ void checkFirmwareCompatibility(int flag) { "************** Jungfrau Virtual Server *****************\n" "********************************************************\n\n"); if (mapCSP0() == FAIL) { - cprintf(BG_RED, "Dangerous to continue. Goodbye!\n"); - exit(EXIT_FAILURE); + strcpy(firmware_message, + "FATAL ERROR: Could not map to memory. Dangerous to continue.\n"); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } + firmware_check_done = 1; return; #endif defineGPIOpins(); resetFPGA(); if (mapCSP0() == FAIL) { - cprintf(BG_RED, "Dangerous to continue. Goodbye!\n"); - exit(EXIT_FAILURE); + strcpy(firmware_message, + "FATAL ERROR: Could not map to memory. Dangerous to continue.\n"); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } // does check only if flag is 0 (by default), set by command line if ((!flag) && ((checkType() == FAIL) || (testFpga() == FAIL) || (testBus() == FAIL))) { - cprintf(BG_RED, "Dangerous to continue. Goodbye!\n"); - exit(EXIT_FAILURE); + strcpy(firmware_message, + "FATAL ERROR: Could not pass basic tests of FPGA and bus. Dangerous to continue.\n"); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } uint16_t hversion = getHardwareVersionNumber(); @@ -58,6 +92,9 @@ void checkFirmwareCompatibility(int flag) { int64_t fwversion = getDetectorId(DETECTOR_FIRMWARE_VERSION); int64_t swversion = getDetectorId(DETECTOR_SOFTWARE_VERSION); int64_t sw_fw_apiversion = 0; + int64_t client_sw_apiversion = getDetectorId(CLIENT_SOFTWARE_API_VERSION); + + if (fwversion >= MIN_REQRD_VRSN_T_RD_API) sw_fw_apiversion = getDetectorId(SOFTWARE_FIRMWARE_API_VERSION); cprintf(BLUE,"\n\n" @@ -74,43 +111,64 @@ void checkFirmwareCompatibility(int flag) { "Software Version:\t\t 0x%llx\n" "F/w-S/w API Version:\t\t 0x%llx\n" "Required Firmware Version:\t 0x%x\n" + "Client-Software API Version:\t 0x%llx\n" "\n" "********************************************************\n", hversion, hsnumber, - ipadd, macadd, - fwversion, swversion, - sw_fw_apiversion, REQRD_FRMWR_VRSN + ipadd, + (long long unsigned int)macadd, + (long long int)fwversion, + (long long int)swversion, + (long long int)sw_fw_apiversion, + REQRD_FRMWR_VRSN, + (long long int)client_sw_apiversion ); // return if flag is not zero, debug mode - if (flag) - return; + if (flag) { + firmware_check_done = 1; + return; + } //cant read versions printf("Testing Firmware-software compatibility ...\n"); if(!fwversion || !sw_fw_apiversion){ - cprintf(RED,"FATAL ERROR: Cant read versions from FPGA. Please update firmware\n"); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(EXIT_FAILURE); + strcpy(firmware_message, + "FATAL ERROR: Cant read versions from FPGA. Please update firmware.\n"); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } //check for API compatibility - old server if(sw_fw_apiversion > REQRD_FRMWR_VRSN){ - cprintf(RED,"FATAL ERROR: This software version is incompatible.\n" - "Please update it to be compatible with this firmware\n\n"); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(EXIT_FAILURE); + sprintf(firmware_message, + "FATAL ERROR: This detector software software version (0x%llx) is incompatible.\n" + "Please update detector software (min. 0x%llx) to be compatible with this firmware.\n", + (long long int)sw_fw_apiversion, + (long long int)REQRD_FRMWR_VRSN); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } //check for firmware compatibility - old firmware if( REQRD_FRMWR_VRSN > fwversion){ - cprintf(RED,"FATAL ERROR: This firmware version is incompatible.\n" - "Please update it to v%d to be compatible with this server\n\n", REQRD_FRMWR_VRSN); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(EXIT_FAILURE); + sprintf(firmware_message, + "FATAL ERROR: This firmware version (0x%llx) is incompatible.\n" + "Please update firmware (min. 0x%llx) to be compatible with this server.\n", + (long long int)fwversion, + (long long int)REQRD_FRMWR_VRSN); + cprintf(RED,"%s\n\n", firmware_message); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; } printf("Compatibility - success\n"); + firmware_check_done = 1; } @@ -155,18 +213,21 @@ int testBus() { printf("\nTesting Bus...\n"); int ret = OK; - u_int32_t addr = SET_DELAY_LSB_REG; + u_int32_t addr = SET_TRIGGER_DELAY_LSB_REG; int times = 1000 * 1000; int i = 0; for (i = 0; i < times; ++i) { bus_w(addr, i * 100); - if (i * 100 != bus_r(SET_DELAY_LSB_REG)) { - cprintf(RED,"ERROR: Mismatch! Wrote 0x%x, read 0x%x\n", i * 100, bus_r(SET_DELAY_LSB_REG)); + if (i * 100 != bus_r(addr)) { + cprintf(RED,"ERROR: Mismatch! Wrote 0x%x, read 0x%x\n", + i * 100, bus_r(addr)); ret = FAIL; } } + bus_w(addr, 0); + if (ret == OK) printf("Successfully tested bus %d times\n", times); return ret; @@ -211,6 +272,8 @@ int64_t getDetectorId(enum idMode arg){ return getFirmwareAPIVersion(); case DETECTOR_SOFTWARE_VERSION: return (GITDATE & 0xFFFFFF); + case CLIENT_SOFTWARE_API_VERSION: + return APIJUNGFRAU; default: return retval; } @@ -254,7 +317,7 @@ u_int32_t getDetectorNumber(){ u_int64_t getDetectorMAC() { #ifdef VIRTUAL return 0; -#endif +#else char output[255],mac[255]=""; u_int64_t res=0; FILE* sysFile = popen("ifconfig eth0 | grep HWaddr | cut -d \" \" -f 11", "r"); @@ -269,6 +332,7 @@ u_int64_t getDetectorMAC() { } sscanf(mac,"%llx",&res); return res; +#endif } u_int32_t getDetectorIP(){ @@ -356,6 +420,13 @@ void allocateDetectorStructureMemory(){ (detectorModules)->offset=0; (detectorModules)->reg=0; thisSettings = UNINITIALIZED; + + { // initialize to -1 + int i = 0; + for (i = 0; i < NDAC; ++i) { + dacValues[i] = -1; + } + } } @@ -377,22 +448,16 @@ void setupDetector() { initDac(8); //only for old board compatibility //set dacs - printf("Setting Default Dac values\n"); - { - int i = 0; - int retval[2]={-1,-1}; - const int defaultvals[NDAC] = DEFAULT_DAC_VALS; - for(i = 0; i < NDAC; ++i) { - setDAC((enum DACINDEX)i,defaultvals[i],0,0,retval); - if (retval[0] != defaultvals[i]) - cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]); - } - } - bus_w(DAQ_REG, 0x0); /* Only once at server startup */ - setSpeed(CLOCK_DIVIDER, HALF_SPEED); - cleanFifos(); /* todo might work without */ - resetCore(); /* todo might work without */ + setDefaultDacs(); + bus_w(DAQ_REG, 0x0); /* Only once at server startup */ + + setSpeed(CLOCK_DIVIDER, HALF_SPEED); + cleanFifos(); + resetCore(); + + configureASICTimer(); + bus_w(ADC_PORT_INVERT_REG, ADC_PORT_INVERT_VAL); //Initialization of acquistion parameters setSettings(DEFAULT_SETTINGS,-1); @@ -402,6 +467,8 @@ void setupDetector() { setTimer(ACQUISITION_TIME, DEFAULT_EXPTIME); setTimer(FRAME_PERIOD, DEFAULT_PERIOD); setTimer(DELAY_AFTER_TRIGGER, DEFAULT_DELAY); + setTimer(STORAGE_CELL_NUMBER, DEFAULT_NUM_STRG_CLLS); + selectStoragecellStart(DEFAULT_STRG_CLL_STRT); /*setSpeed(CLOCK_DIVIDER, HALF_SPEED); depends if all the previous stuff works*/ setTiming(DEFAULT_TIMING_MODE); setHighVoltage(DEFAULT_HIGH_VOLTAGE); @@ -411,10 +478,31 @@ void setupDetector() { setThresholdTemperature(DEFAULT_TMP_THRSHLD); // reset temp event setTemperatureEvent(0); + + } - +int setDefaultDacs() { + int ret = OK; + printf("Setting Default Dac values\n"); + { + int i = 0; + int retval[2]={-1,-1}; + const int defaultvals[NDAC] = DEFAULT_DAC_VALS; + for(i = 0; i < NDAC; ++i) { + // if not already default, set it to default + if (dacValues[i] != defaultvals[i]) { + setDAC((enum DACINDEX)i,defaultvals[i],0,0,retval); + if (retval[0] != defaultvals[i]) { + cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]); + ret = FAIL; + } + } + } + } + return ret; +} @@ -433,9 +521,9 @@ int powerChip (int on){ } } - return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_ENABLE_MSK) >> CHIP_POWER_ENABLE_OFST); - /* temporary setup until new firmware fixes bug */ - //return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_STATUS_MSK) >> CHIP_POWER_STATUS_OFST); + //return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_ENABLE_MSK) >> CHIP_POWER_ENABLE_OFST); + /**temporary fix until power reg status can be read */ + return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_STATUS_MSK) >> CHIP_POWER_STATUS_OFST); } @@ -501,7 +589,11 @@ int getPhase() { return clkPhase[0]; } - +void configureASICTimer() { + printf("\nConfiguring ASIC Timer\n"); + bus_w(ASIC_CTRL_REG, (bus_r(ASIC_CTRL_REG) & ~ASIC_CTRL_PRCHRG_TMR_MSK) | ASIC_CTRL_PRCHRG_TMR_VAL); + bus_w(ASIC_CTRL_REG, (bus_r(ASIC_CTRL_REG) & ~ASIC_CTRL_DS_TMR_MSK) | ASIC_CTRL_DS_TMR_VAL); +} @@ -623,6 +715,15 @@ int setSpeed(enum speedVariable arg, int val) { /* parameters - timer */ +int selectStoragecellStart(int pos) { + if (pos >= 0) { + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_STRG_CELL_SLCT_MSK); + bus_w(DAQ_REG, bus_r(DAQ_REG) | ((pos << DAQ_STRG_CELL_SLCT_OFST) & DAQ_STRG_CELL_SLCT_MSK)); + } + return ((bus_r(DAQ_REG) & DAQ_STRG_CELL_SLCT_MSK) >> DAQ_STRG_CELL_SLCT_OFST); +} + + int64_t setTimer(enum timerIndex ind, int64_t val) { @@ -640,8 +741,10 @@ int64_t setTimer(enum timerIndex ind, int64_t val) { if(val >= 0){ printf("\nSetting exptime: %lldns\n", (long long int)val); val *= (1E-3 * CLK_RUN); + val -= ACQ_TIME_MIN_CLOCK; + if(val < 0) val = 0; } - retval = set64BitReg(val, SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) / (1E-3 * CLK_RUN); + retval = (set64BitReg(val, SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) + ACQ_TIME_MIN_CLOCK) / (1E-3 * CLK_RUN); printf("Getting exptime: %lldns\n", (long long int)retval); break; @@ -670,6 +773,16 @@ int64_t setTimer(enum timerIndex ind, int64_t val) { printf("Getting #cycles: %lld\n", (long long int)retval); break; + case STORAGE_CELL_NUMBER: + if(val >= 0) { + printf("\nSetting #storage cells to %lld\n", (long long int)val); + bus_w(CONTROL_REG, (bus_r(CONTROL_REG) & ~CONTROL_STORAGE_CELL_NUM_MSK) | + ((val << CONTROL_STORAGE_CELL_NUM_OFST) & CONTROL_STORAGE_CELL_NUM_MSK)); + } + retval = ((bus_r(CONTROL_REG) & CONTROL_STORAGE_CELL_NUM_MSK) >> CONTROL_STORAGE_CELL_NUM_OFST); + printf("Getting #storage cells: %lld\n", (long long int)retval); + break; + default: cprintf(RED,"Warning: Timer Index not implemented for this detector: %d\n", ind); break; @@ -697,12 +810,12 @@ int64_t getTimeLeft(enum timerIndex ind){ retval = get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG) / (1E-3 * CLK_SYNC); printf("Getting period left: %lldns\n", (long long int)retval); break; - +/* case DELAY_AFTER_TRIGGER: - retval = get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG) / (1E-3 * CLK_SYNC); + retval = get64BitReg(xxx) / (1E-3 * CLK_SYNC); printf("Getting delay left: %lldns\n", (long long int)retval); break; - +*/ case CYCLES_NUMBER: retval = get64BitReg(GET_CYCLES_LSB_REG, GET_CYCLES_MSB_REG); printf("Getting number of cycles left: %lld\n", (long long int)retval); @@ -781,38 +894,46 @@ int getModule(sls_detector_module *myMod){ enum detectorSettings setSettings(enum detectorSettings sett, int imod){ - if(sett == UNINITIALIZED){ + if(sett == UNINITIALIZED) return thisSettings; - } - - uint32_t val = -1; - const int defaultIndex[NUM_SETTINGS] = DEFAULT_SETT_INDX; - const int defaultvals[NUM_SETTINGS] = DEFAULT_SETT_VALS; - const char defaultNames[NUM_SETTINGS][100]=DEFAULT_SETT_NAMES; + // set settings if(sett != GET_SETTINGS) { + switch (sett) { + case DYNAMICGAIN: + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); + printf("\nConfigured settings - Dyanmic Gain, DAQ Reg: 0x%x\n", bus_r(DAQ_REG)); + break; + case DYNAMICHG0: + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); + bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_FIX_GAIN_HIGHGAIN_VAL); + printf("\nConfigured settings - Dyanmic High Gain 0, DAQ Reg: 0x%x\n", bus_r(DAQ_REG)); + break; + case FIXGAIN1: + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); + bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_FIX_GAIN_STG_1_VAL); + printf("\nConfigured settings - Fix Gain 1, DAQ Reg: 0x%x\n", bus_r(DAQ_REG)); + break; + case FIXGAIN2: + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); + bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_FIX_GAIN_STG_2_VAL); + printf("\nConfigured settings - Fix Gain 2, DAQ Reg: 0x%x\n", bus_r(DAQ_REG)); + break; + case FORCESWITCHG1: + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); + bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_FRCE_GAIN_STG_1_VAL); + printf("\nConfigured settings - Force Switch Gain 1, DAQ Reg: 0x%x\n", bus_r(DAQ_REG)); + break; + case FORCESWITCHG2: + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); + bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_FRCE_GAIN_STG_2_VAL); + printf("\nConfigured settings - Force Switch Gain 2, DAQ Reg: 0x%x\n", bus_r(DAQ_REG)); + break; + default: + cprintf(RED, "Error: This settings is not defined for this detector %d\n", (int)sett); + return -1; + } - // find gain val - { - int i; - for (i = 0; i < NUM_SETTINGS; ++i) { - if (sett == defaultIndex[i]) { - val = defaultvals[i]; - break; - } - } - - - //not found - if (val == -1) { - cprintf(RED, "Error: This settings is not defined for this detector %d\n", (int)sett); - return val; - } - - printf("\nConfiguring to settings %s (%d)\n" - " Writing to DAQ Register with val:0x%x\n", defaultNames[i], sett, val); - } - bus_w(DAQ_REG, val); thisSettings = sett; } @@ -823,35 +944,39 @@ enum detectorSettings setSettings(enum detectorSettings sett, int imod){ enum detectorSettings getSettings(){ - enum detectorSettings sett = -1; - const int defaultIndex[NUM_SETTINGS] = DEFAULT_SETT_INDX; - const int defaultvals[NUM_SETTINGS] = DEFAULT_SETT_VALS; - const char defaultNames[NUM_SETTINGS][100]=DEFAULT_SETT_NAMES; - - uint32_t val = bus_r(DAQ_REG); + uint32_t val = bus_r(DAQ_REG) & DAQ_SETTINGS_MSK; printf("\nGetting Settings\n Reading DAQ Register :0x%x\n", val); - //find setting - { - int i; - for (i = 0; i < NUM_SETTINGS; ++i) { - if (val == defaultvals[i]) { - sett = defaultIndex[i]; - break; - } - } - - - //not found - if (sett == -1) { - cprintf(RED, "Error: Undefined settings read for this detector (DAQ Reg val: 0x%x)\n", val); - thisSettings = UNDEFINED; - return sett; - } - - thisSettings = sett; - printf("Settings Read: %s (%d)\n", defaultNames[i], thisSettings); + switch(val) { + case DAQ_FIX_GAIN_DYNMC_VAL: + thisSettings = DYNAMICGAIN; + printf("Settings read: DYNAMICGAIN\n"); + break; + case DAQ_FIX_GAIN_HIGHGAIN_VAL: + thisSettings = DYNAMICHG0; + printf("Settings read: DYNAMICHG0\n"); + break; + case DAQ_FIX_GAIN_STG_1_VAL: + thisSettings = FIXGAIN1; + printf("Settings read: FIXGAIN1\n"); + break; + case DAQ_FIX_GAIN_STG_2_VAL: + thisSettings = FIXGAIN2; + printf("Settings read: FIXGAIN2\n"); + break; + case DAQ_FRCE_GAIN_STG_1_VAL: + thisSettings = FORCESWITCHG1; + printf("Settings read: FORCESWITCHG1\n"); + break; + case DAQ_FRCE_GAIN_STG_2_VAL: + thisSettings = FORCESWITCHG2; + printf("Settings read: FORCESWITCHG2\n"); + break; + default: + thisSettings = UNDEFINED; + printf("Settings read: Undefined. Value read:0x%x\n", val); } + return thisSettings; } @@ -1115,7 +1240,7 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t (unsigned int)((sourcemac>>16)&0xFF), (unsigned int)((sourcemac>>8)&0xFF), (unsigned int)((sourcemac>>0)&0xFF), - sourcemac); + (long long unsigned int)sourcemac); printf("Source Port : %d \t\t\t(0x%08x)\n",sourceport, sourceport); printf("Dest. IP : %d.%d.%d.%d \t\t(0x%08x)\n",(destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff, destip); @@ -1126,7 +1251,7 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t (unsigned int)((destmac>>16)&0xFF), (unsigned int)((destmac>>8)&0xFF), (unsigned int)((destmac>>0)&0xFF), - destmac); + (long long unsigned int)destmac); printf("Dest. Port : %d \t\t\t(0x%08x)\n",udpport, udpport); long int checksum=calcChecksum(sourceip, destip); @@ -1188,16 +1313,16 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t int setDetectorPosition(int pos[]) { int ret = OK; - bus_w(COORD_0, bus_r(COORD_0) | ((pos[0] << COORD_0_X_OFST) & COORD_0_X_MSK)); - if ((bus_r(COORD_0) & COORD_0_X_MSK) != ((pos[0] << COORD_0_X_OFST) & COORD_0_X_MSK)) + bus_w(COORD_0_REG, bus_r(COORD_0_REG) | ((pos[0] << COORD_0_X_OFST) & COORD_0_X_MSK)); + if ((bus_r(COORD_0_REG) & COORD_0_X_MSK) != ((pos[0] << COORD_0_X_OFST) & COORD_0_X_MSK)) ret = FAIL; - bus_w(COORD_0, bus_r(COORD_0) | ((pos[1] << COORD_0_Y_OFST) & COORD_0_Y_MSK)); - if ((bus_r(COORD_0) & COORD_0_Y_MSK) != ((pos[1] << COORD_0_Y_OFST) & COORD_0_Y_MSK)) + bus_w(COORD_0_REG, bus_r(COORD_0_REG) | ((pos[1] << COORD_0_Y_OFST) & COORD_0_Y_MSK)); + if ((bus_r(COORD_0_REG) & COORD_0_Y_MSK) != ((pos[1] << COORD_0_Y_OFST) & COORD_0_Y_MSK)) ret = FAIL; - bus_w(COORD_1, bus_r(COORD_1) | ((pos[2] << COORD_0_Z_OFST) & COORD_0_Z_MSK)); - if ((bus_r(COORD_1) & COORD_0_Z_MSK) != ((pos[2] << COORD_0_Z_OFST) & COORD_0_Z_MSK)) + bus_w(COORD_1_REG, bus_r(COORD_1_REG) | ((pos[2] << COORD_0_Z_OFST) & COORD_0_Z_MSK)); + if ((bus_r(COORD_1_REG) & COORD_0_Z_MSK) != ((pos[2] << COORD_0_Z_OFST) & COORD_0_Z_MSK)) ret = FAIL; if (ret == OK) @@ -1371,7 +1496,15 @@ int setNetworkParameter(enum NETWORKINDEX mode, int value) { int startStateMachine(){ #ifdef VIRTUAL - return OK; + virtual_status = 1; + virtual_stop = 0; + if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { + virtual_status = 0; + cprintf(RED,"Could not start Virtual acquisition thread\n"); + return FAIL; + } + cprintf(GREEN,"***Virtual Acquisition started\n"); + return OK; #endif printf("*******Starting State Machine*******\n"); @@ -1386,12 +1519,30 @@ int startStateMachine(){ } -int stopStateMachine(){ #ifdef VIRTUAL - return OK; -#endif - cprintf(BG_RED,"*******Stopping State Machine*******\n"); +void* start_timer(void* arg) { + int wait_in_s = (setTimer(FRAME_NUMBER, -1) * + setTimer(CYCLES_NUMBER, -1) * + (setTimer(STORAGE_CELL_NUMBER, -1) + 1) * + (setTimer(FRAME_PERIOD, -1)/(1E9))); + cprintf(GREEN,"going to wait for %d s\n", wait_in_s); + while(!virtual_stop && (wait_in_s >= 0)) { + usleep(1000 * 1000); + wait_in_s--; + } + cprintf(GREEN,"Virtual Timer Done***\n"); + virtual_status = 0; + return NULL; +} +#endif + +int stopStateMachine(){ + cprintf(BG_RED,"*******Stopping State Machine*******\n"); +#ifdef VIRTUAL + virtual_stop = 0; + return OK; +#endif //stop state machine bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_STOP_ACQ_MSK); usleep(100); @@ -1407,7 +1558,13 @@ int stopStateMachine(){ enum runStatus getRunStatus(){ #ifdef VIRTUAL - return IDLE; + if(virtual_status == 0){ + printf("Status: IDLE\n"); + return IDLE; + }else{ + printf("Status: RUNNING...\n"); + return RUNNING; + } #endif #ifdef VERBOSE printf("Getting status\n"); @@ -1453,9 +1610,13 @@ enum runStatus getRunStatus(){ void readFrame(int *ret, char *mess){ #ifdef VIRTUAL - *ret = (int)FAIL; - sprintf(mess,"virtual detector, no acquisition taken\n"); - return; + while(virtual_status) { + //cprintf(RED,"Waiting for finished flag\n"); + usleep(5000); + } + *ret = (int)FINISHED; + strcpy(mess,"acquisition successfully finished\n"); + return; #endif // wait for status to be done while(runBusy()){ @@ -1466,7 +1627,7 @@ void readFrame(int *ret, char *mess){ int64_t retval = getTimeLeft(FRAME_NUMBER) + 1; if ( retval > 0) { *ret = (int)FAIL; - sprintf(mess,"no data and run stopped: %lld frames left\n",retval); + sprintf(mess,"no data and run stopped: %lld frames left\n",(long long int)retval); cprintf(RED,"%s\n",mess); } else { *ret = (int)FINISHED; @@ -1479,7 +1640,7 @@ void readFrame(int *ret, char *mess){ u_int32_t runBusy(void) { #ifdef VIRTUAL - return 0; + return virtual_status; #endif u_int32_t s = ((bus_r(STATUS_REG) & RUN_BUSY_MSK) >> RUN_BUSY_OFST); #ifdef VERBOSE diff --git a/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorServer_defs.h index 61b5e7b31..e98896d43 100644 --- a/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorSoftware/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -8,8 +8,9 @@ #define GOODBYE (-200) +#define PROGRAMMING_MODE (-200) #define MIN_REQRD_VRSN_T_RD_API 0x171220 -#define REQRD_FRMWR_VRSN 0x171220 +#define REQRD_FRMWR_VRSN 0x180226 /* Struct Definitions */ @@ -40,22 +41,6 @@ enum DACINDEX {VB_COMP, VDD_PROT, VIN_COM, VREF_PRECH, VB_PIXBUF, VB_DS, VREF 420 /* VREF_COMP */ \ }; -#define NUM_SETTINGS 6 -#define DEFAULT_SETT_INDX {DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2}; -#define DEFAULT_SETT_VALS { 0x0f00, /* DYNAMICGAIN */ \ - 0x0f01, /* DYNAMICHG0 */ \ - 0x0f02, /* FIXGAIN1 */ \ - 0x0f06, /* FIXGAIN2 */ \ - 0x1f00, /* FORCESWITCHG1 */ \ - 0x3f00 /* FORCESWITCHG2 */ \ - }; -#define DEFAULT_SETT_NAMES { "Dynamic Gain", /* DYNAMICGAIN */ \ - "Dynamic High Gain 0", /* DYNAMICHG0 */ \ - "Fix Gain 1", /* FIXGAIN1 */ \ - "Fix Gain 2", /* FIXGAIN2 */ \ - "Force Switch Gain 1", /* FORCESWITCHG1*/ \ - "Force Switch Gain 2" /* FORCESWITCHG2*/ \ - }; enum NETWORKINDEX { TXN_FRAME }; @@ -87,22 +72,27 @@ enum NETWORKINDEX { TXN_FRAME }; #define DEFAULT_SETTINGS (DYNAMICGAIN) #define DEFAULT_TX_UDP_PORT (0x7e9a) #define DEFAULT_TMP_THRSHLD (65*1000) //milli degree Celsius +#define DEFAULT_NUM_STRG_CLLS (0) +#define DEFAULT_STRG_CLL_STRT (0xf) /* Defines in the Firmware */ #define FIX_PATT_VAL (0xACDC2014) #define ADC_PORT_INVERT_VAL (0x453b2a9c) #define MAX_TIMESLOT_VAL (0x1F) #define MAX_THRESHOLD_TEMP_VAL (127999) //millidegrees +#define MAX_STORAGE_CELL_VAL (15) //0xF +#define ACQ_TIME_MIN_CLOCK (2) #define SAMPLE_ADC_HALF_SPEED (SAMPLE_DECMT_FACTOR_2_VAL + SAMPLE_DGTL_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_0_VAL + SAMPLE_ADC_SAMPLE_0_VAL) /* 0x1000 */ #define SAMPLE_ADC_QUARTER_SPEED (SAMPLE_DECMT_FACTOR_4_VAL + SAMPLE_DGTL_SAMPLE_8_VAL + SAMPLE_ADC_DECMT_FACTOR_1_VAL + SAMPLE_ADC_SAMPLE_0_VAL) /* 0x2810 */ #define CONFIG_HALF_SPEED (CONFIG_TDMA_DISABLE_VAL + CONFIG_HALF_SPEED_20MHZ_VAL + CONFIG_MODE_1_X_10GBE_VAL) #define CONFIG_QUARTER_SPEED (CONFIG_TDMA_DISABLE_VAL + CONFIG_QUARTER_SPEED_10MHZ_VAL + CONFIG_MODE_1_X_10GBE_VAL) -#define ADC_OFST_HALF_SPEED_VAL (0x20) //adc pipeline -#define ADC_OFST_QUARTER_SPEED_VAL (0x0f) -#define ADC_PHASE_HALF_SPEED (0x48) //72 -#define ADC_PHASE_QUARTER_SPEED (0x48) //72 +#define ADC_OFST_HALF_SPEED_VAL (0x1f) //(0x20) +#define ADC_OFST_QUARTER_SPEED_VAL (0x0f) //(0x0f) +#define ADC_PHASE_HALF_SPEED (0x2D) //45 +#define ADC_PHASE_QUARTER_SPEED (0x2D) //45 +#define ADC_PORT_INVERT_VAL (0x453b2a9c) /* Maybe not required for jungfrau */ #define NTRIMBITS (6) diff --git a/slsDetectorSoftware/jungfrauDetectorServer/updateAPIVersion.sh b/slsDetectorSoftware/jungfrauDetectorServer/updateAPIVersion.sh new file mode 100755 index 000000000..ef65ec7e7 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/updateAPIVersion.sh @@ -0,0 +1,7 @@ +SRCFILE=gitInfoJungfrau.h +DSTFILE=versionAPI.h + +SRCPATTERN=GITDATE +DSTPATTERN=APIJUNGFRAU + +awk -v a="$SRCFILE" -v b="$DSTFILE" -v c="$SRCPATTERN" -v d="$DSTPATTERN" 'FNR==NR&&$2==c{x=$3} NR!=FNR{if($2==d){$3="0x"substr(x,5)}print > b}' $SRCFILE $DSTFILE \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/versionAPI.h b/slsDetectorSoftware/jungfrauDetectorServer/versionAPI.h new file mode 120000 index 000000000..d3bf8d6cf --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/versionAPI.h @@ -0,0 +1 @@ +../commonFiles/versionAPI.h \ No newline at end of file diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 6009bc8c9..697e1b0b6 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -6,311 +6,1039 @@ Author: $Author$ URL: $URL$ ID: $Id$ -********************************************************************/ - - + ********************************************************************/ #include "multiSlsDetector.h" +#include "SharedMemory.h" #include "slsDetector.h" -#include "multiSlsDetectorCommand.h" -#include "multiSlsDetectorClient.h" -#include "postProcessingFuncs.h" -#include "usersFunctions.h" +#include "sls_detector_exceptions.h" #include "ThreadPool.h" #include "ZmqSocket.h" +#include "multiSlsDetectorClient.h" +#include "multiSlsDetectorCommand.h" +#include "postProcessingFuncs.h" +#include "usersFunctions.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include //json header in zmq stream +#include +#include -char ans[MAX_STR_LENGTH]; - -int multiSlsDetector::freeSharedMemory() { - // Detach Memory address - for (int id=0; idnumberOfDetectors; ++id) { - if (detectors[id]) - detectors[id]->freeSharedMemory(); - } - - - 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; - +multiSlsDetector::multiSlsDetector(int id, bool verify, bool update) +: slsDetectorUtils(), + detId(id), + sharedMemory(0), + thisMultiDetector(0), + client_downstream(false), + threadpool(0) { + setupMultiDetector(verify, update); } -int multiSlsDetector::initSharedMemory(int id=0) { - - key_t mem_key=DEFAULT_SHM_KEY+MAXDET+id; - int shm_id; - int sz; - - - - sz=sizeof(sharedMultiSlsDetector); - - -#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 (shm_id < 0) { - std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; - return shm_id; - } - - /** - 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; - -} - - - - -multiSlsDetector::multiSlsDetector(int id) : slsDetectorUtils(), shmId(-1) -{ - - while (shmId<0) { - shmId=initSharedMemory(id); - ++id; - } - --id; - - for (int id=0; idalreadyExisting==0) { - - - thisMultiDetector->onlineFlag = ONLINE_FLAG; - thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG; - thisMultiDetector->numberOfDetectors=0; - thisMultiDetector->numberOfDetector[X]=0; - thisMultiDetector->numberOfDetector[Y]=0; - for (int id=0; iddetectorIds[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<correctionMask|=(1<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 */ - strcpy(thisMultiDetector->flatFieldFile,"none"); - /** set angular direction to 1*/ - thisMultiDetector->angDirection=1; - /** set fine offset to 0*/ - thisMultiDetector->fineOffset=0; - /** set global offset to 0*/ - thisMultiDetector->globalOffset=0; - - - - /** set threshold to -1*/ - thisMultiDetector->currentThresholdEV=-1; - // /** set clockdivider to 1*/ - // thisMultiDetector->clkDiv=1; - /** set number of positions to 0*/ - thisMultiDetector->numberOfPositions=0; - /** sets angular conversion file to none */ - strcpy(thisMultiDetector->angConvFile,"none"); - /** set binsize*/ - thisMultiDetector->binSize=0.001; - thisMultiDetector->stoppedFlag=0; - - thisMultiDetector->threadedProcessing=1; - - thisMultiDetector->actionMask=0; - - - for (int ia=0; iaactionMode[ia]=0; - strcpy(thisMultiDetector->actionScript[ia],"none"); - strcpy(thisMultiDetector->actionParameter[ia],"none"); - } - - - for (int iscan=0; iscanscanMode[iscan]=0; - strcpy(thisMultiDetector->scanScript[iscan],"none"); - strcpy(thisMultiDetector->scanParameter[iscan],"none"); - thisMultiDetector->nScanSteps[iscan]=0; - thisMultiDetector->scanPrecision[iscan]=0; - } - - thisMultiDetector->acquiringFlag = false; - thisMultiDetector->receiver_upstream = false; - thisMultiDetector->alreadyExisting=1; - } - - - //assigned before creating detector - stoppedFlag=&thisMultiDetector->stoppedFlag; - threadedProcessing=&thisMultiDetector->threadedProcessing; - actionMask=&thisMultiDetector->actionMask; - actionScript=thisMultiDetector->actionScript; - actionParameter=thisMultiDetector->actionParameter; - nScanSteps=thisMultiDetector->nScanSteps; - scanMode=thisMultiDetector->scanMode; - scanScript=thisMultiDetector->scanScript; - scanParameter=thisMultiDetector->scanParameter; - scanSteps=thisMultiDetector->scanSteps; - scanPrecision=thisMultiDetector->scanPrecision; - numberOfPositions=&thisMultiDetector->numberOfPositions; - detPositions=thisMultiDetector->detPositions; - angConvFile=thisMultiDetector->angConvFile; - correctionMask=&thisMultiDetector->correctionMask; - binSize=&thisMultiDetector->binSize; - fineOffset=&thisMultiDetector->fineOffset; - globalOffset=&thisMultiDetector->globalOffset; - angDirection=&thisMultiDetector->angDirection; - flatFieldDir=thisMultiDetector->flatFieldDir; - flatFieldFile=thisMultiDetector->flatFieldFile; - badChanFile=thisMultiDetector->badChanFile; - timerValue=thisMultiDetector->timerValue; - - expTime=&timerValue[ACQUISITION_TIME]; - - currentSettings=&thisMultiDetector->currentSettings; - currentThresholdEV=&thisMultiDetector->currentThresholdEV; - moveFlag=NULL; - - sampleDisplacement=thisMultiDetector->sampleDisplacement; - - filePath=thisMultiDetector->filePath; - fileName=thisMultiDetector->fileName; - fileIndex=&thisMultiDetector->fileIndex; - framesPerFile=&thisMultiDetector->framesPerFile; - fileFormatType=&thisMultiDetector->fileFormatType; - - - for (int i=0; inumberOfDetectors; ++i) { -#ifdef VERBOSE - cout << thisMultiDetector->detectorIds[i] << endl; -#endif - detectors[i]=new slsDetector(i, thisMultiDetector->detectorIds[i], this); - - - // setAngularConversionPointer(detectors[i]->getAngularConversionPointer(),detectors[i]->getNModsPointer(),detectors[i]->getNChans()*detectors[i]->getNChips(), i); - - } - // for (int i=thisMultiDetector->numberOfDetectors; ilastPID=getpid(); - - - getNMods(); - getMaxMods(); - client_downstream = false; - for(int i=0;i::const_iterator it = zmqSocket.begin(); it != zmqSocket.end(); ++it) { + delete(*it); } + zmqSocket.clear(); + + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + delete(*it); + } + detectors.clear(); + + if (sharedMemory) { + sharedMemory->UnmapSharedMemory(thisMultiDetector); + delete sharedMemory; + } + destroyThreadPool(); } -int multiSlsDetector::createThreadPool(){ - if(threadpool) +bool multiSlsDetector::isMultiSlsDetectorClass() { + return true; +} + +void multiSlsDetector::setupMultiDetector(bool verify, bool update) { + if (initSharedMemory(verify)) + // shared memory just created, so initialize the structure + initializeDetectorStructure(); + initializeMembers(verify); + if (update) + updateUserdetails(); +} + +std::string multiSlsDetector::concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos) { + if (pos >= 0 && pos < (int)detectors.size()) { + return (detectors[pos]->*somefunc)(pos); + } else { + std::string s; + for (unsigned int i = 0; i < detectors.size(); ++i) { + s += (detectors[i]->*somefunc)(pos) + "+"; + } + return s; + } +} + +template +T multiSlsDetector::callDetectorMember(T (slsDetector::*somefunc)()) +{ + //(Erik) to handle enums, probably a bad idea but follow previous code + T defaultValue = static_cast(-1); + std::vector values(detectors.size(), defaultValue); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + values[idet] = (detectors[idet]->*somefunc)(); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + return minusOneIfDifferent(values); +} + +std::string multiSlsDetector::callDetectorMember(string (slsDetector::*somefunc)()) { + string concatenatedValue, firstValue; + bool valueNotSame = false; + + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + string thisValue = (detectors[idet]->*somefunc)(); + ; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + + if (firstValue.empty()) { + concatenatedValue = thisValue; + firstValue = thisValue; + } else { + concatenatedValue += "+" + thisValue; + } + if (firstValue != thisValue) + valueNotSame = true; + } + if (valueNotSame) + return concatenatedValue; + else + return firstValue; +} + +template +T multiSlsDetector::callDetectorMember(T (slsDetector::*somefunc)(V), V value) { + //(Erik) to handle enums, probably a bad idea but follow previous code + T defaultValue = static_cast(-1); + std::vector values(detectors.size(), defaultValue); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + values[idet] = (detectors[idet]->*somefunc)(value); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + return minusOneIfDifferent(values); +} + +template +T multiSlsDetector::callDetectorMember(T (slsDetector::*somefunc)(P1, P2), + P1 par1, P2 par2) { + //(Erik) to handle enums, probably a bad idea but follow previous code + T defaultValue = static_cast(-1); + std::vector values(detectors.size(), defaultValue); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + values[idet] = (detectors[idet]->*somefunc)(par1, par2); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + return minusOneIfDifferent(values); +} + +template +T multiSlsDetector::parallelCallDetectorMember(T (slsDetector::*somefunc)()) { + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } else { + std::vector return_values(detectors.size(), -1); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + Task* task = new Task(new func0_t(somefunc, + detectors[idet], &return_values[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + return minusOneIfDifferent(return_values); + } +} + +template +T multiSlsDetector::parallelCallDetectorMember(T (slsDetector::*somefunc)(P1), + P1 value) { + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } else { + std::vector return_values(detectors.size(), -1); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + Task* task = new Task(new func1_t(somefunc, + detectors[idet], value, &return_values[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + return minusOneIfDifferent(return_values); + } +} + +template +T multiSlsDetector::parallelCallDetectorMember(T (slsDetector::*somefunc)(P1, P2), + P1 par1, P2 par2) { + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } else { + std::vector return_values(detectors.size(), -1); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + Task* task = new Task(new func2_t(somefunc, + detectors[idet], par1, par2, &return_values[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + return minusOneIfDifferent(return_values); + } +} + +int multiSlsDetector::parallelCallDetectorMember(int (slsDetector::*somefunc)(int, int, int), + int v0, int v1, int v2) { + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } else { + std::vector return_values(detectors.size(), -1); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + Task* task = new Task(new func3_t(somefunc, + detectors[idet], v0, v1, v2, &return_values[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + return minusOneIfDifferent(return_values); + } +} + +template +T multiSlsDetector::minusOneIfDifferent(const std::vector& return_values) { + T ret = static_cast(-100); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (ret == static_cast(-100)) + ret = return_values[idet]; + else if (ret != return_values[idet]) + ret = static_cast(-1); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + return ret; +} + + +int multiSlsDetector::decodeNMod(int i, int& id, int& im) { +#ifdef VERBOSE + cout << " Module " << i << " belongs to detector " << id << endl; + ; + cout << getMaxMods(); +#endif + + if (i < 0 || i >= getMaxMods()) { + id = -1; + im = -1; +#ifdef VERBOSE + cout << " A---------" << id << " position " << im << endl; +#endif + + return -1; + } + int nm; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + nm = detectors[idet]->getNMods(); + if (nm > i) { + id = idet; + im = i; +#ifdef VERBOSE + cout << " B---------" << id << " position " << im << endl; +#endif + return im; + } else { + i -= nm; + } + } + id = -1; + im = -1; +#ifdef VERBOSE + cout << " C---------" << id << " position " << im << endl; +#endif + return -1; +} + + +int multiSlsDetector::decodeNChannel(int offsetX, int offsetY, int& channelX, int& channelY) { + channelX = -1; + channelY = -1; + //loop over + for (unsigned int i = 0; i < detectors.size(); ++i) { + int x = detectors[i]->getDetectorOffset(X); + int y = detectors[i]->getDetectorOffset(Y); + //check x offset range + if ((offsetX >= x) && + (offsetX < (x + detectors[i]->getMaxNumberOfChannelsInclGapPixels(X)))) { + if (offsetY == -1) { + channelX = offsetX - x; + return i; + } else { + //check y offset range + if ((offsetY >= y) && + (offsetY < (y + detectors[i]->getMaxNumberOfChannelsInclGapPixels(Y)))) { + channelX = offsetX - x; + channelY = offsetY - y; + return i; + } + } + } + } + return -1; +} + + +double* multiSlsDetector::decodeData(int* datain, int& nn, double* fdata) { + double* dataout; + + if (fdata) + dataout = fdata; + else { + if (detectors[0]->getDetectorsType() == JUNGFRAUCTB) { + nn = thisMultiDetector->dataBytes / 2; + dataout = new double[nn]; + } else { + nn = thisMultiDetector->numberOfChannels; + dataout = new double[nn]; + } + } + + int n; + double* detp = dataout; + int* datap = datain; + + for (unsigned int i = 0; i < detectors.size(); ++i) { + detectors[i]->decodeData(datap, n, detp); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); +#ifdef VERBOSE + cout << "increment pointers " << endl; +#endif + datap += detectors[i]->getDataBytes() / sizeof(int); + detp += n; +#ifdef VERBOSE + cout << "done " << endl; +#endif + } + + return dataout; +} + + + +int multiSlsDetector::writeDataFile(string fname, double* data, double* err, + double* ang, char dataformat, int nch) { +#ifdef VERBOSE + cout << "using overloaded multiSlsDetector function to write formatted data file " + << getTotalNumberOfChannels() << endl; +#endif + + ofstream outfile; + int choff = 0, off = 0; //idata, + double *pe = err, *pa = ang; + int nch_left = nch, n; //, nd; + + if (nch_left <= 0) + nch_left = getTotalNumberOfChannels(); + + if (data == NULL) + return FAIL; + + outfile.open(fname.c_str(), ios_base::out); + if (outfile.is_open()) { + + for (unsigned int i = 0; i < detectors.size(); ++i) { + n = detectors[i]->getTotalNumberOfChannels(); + if (nch_left < n) + n = nch_left; +#ifdef VERBOSE + cout << " write " << i << " position " << off << " offset " << choff << endl; +#endif + fileIOStatic::writeDataFile(outfile, n, data + off, pe, pa, dataformat, choff); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + + nch_left -= n; + + choff += detectors[i]->getMaxNumberOfChannels(); + + off += n; + + if (pe) + pe = err + off; + + if (pa) + pa = ang + off; + } + outfile.close(); + return OK; + } else { + std::cout << "Could not open file " << fname << "for writing" << std::endl; + return FAIL; + } +} + +int multiSlsDetector::writeDataFile(string fname, int* data) { + ofstream outfile; + int choff = 0, off = 0; +#ifdef VERBOSE + cout << "using overloaded multiSlsDetector function to write raw data file " << endl; +#endif + + if (data == NULL) + return FAIL; + + outfile.open(fname.c_str(), ios_base::out); + if (outfile.is_open()) { + for (unsigned int i = 0; i < detectors.size(); ++i) { +#ifdef VERBOSE + cout << " write " << i << " position " << off << " offset " << choff << endl; +#endif + detectors[i]->writeDataFile(outfile, + detectors[i]->getTotalNumberOfChannels(), data + off, choff); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + choff += detectors[i]->getMaxNumberOfChannels(); + off += detectors[i]->getTotalNumberOfChannels(); + } + outfile.close(); + return OK; + } else { + std::cout << "Could not open file " << fname << "for writing" << std::endl; + return FAIL; + } +} + +int multiSlsDetector::readDataFile(string fname, double* data, double* err, + double* ang, char dataformat) { +#ifdef VERBOSE + cout << "using overloaded multiSlsDetector function to read formatted data file " << endl; +#endif + + ifstream infile; + int iline = 0; + string str; + int choff = 0, off = 0; + double *pe = err, *pa = ang; + +#ifdef VERBOSE + std::cout << "Opening file " << fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + + for (unsigned int i = 0; i < detectors.size(); ++i) { + iline += detectors[i]->readDataFile(detectors[i]->getTotalNumberOfChannels(), + infile, data + off, pe, pa, dataformat, choff); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + choff += detectors[i]->getMaxNumberOfChannels(); + off += detectors[i]->getTotalNumberOfChannels(); + if (pe) + pe = pe + off; + if (pa) + pa = pa + off; + } + + infile.close(); + } else { + std::cout << "Could not read file " << fname << std::endl; + return -1; + } + return iline; +} + +int multiSlsDetector::readDataFile(string fname, int* data) { +#ifdef VERBOSE + cout << "using overloaded multiSlsDetector function to read raw data file " << endl; +#endif + ifstream infile; + int iline = 0; + string str; + int choff = 0, off = 0; + +#ifdef VERBOSE + std::cout << "Opening file " << fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + + for (unsigned int i = 0; i < detectors.size(); ++i) { + iline += detectors[i]->readDataFile(infile, data + off, + detectors[i]->getTotalNumberOfChannels(), choff); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + choff += detectors[i]->getMaxNumberOfChannels(); + off += detectors[i]->getTotalNumberOfChannels(); + } + infile.close(); + } else { + std::cout << "Could not read file " << fname << std::endl; + return -1; + } + return iline; +} + + +string multiSlsDetector::getErrorMessage(int& critical) { + int64_t multiMask, slsMask = 0; + string retval = ""; + char sNumber[100]; + critical = 0; + + multiMask = getErrorMask(); + if (multiMask) { + if (multiMask & MULTI_DETECTORS_NOT_ADDED) { + retval.append("Detectors not added:\n" + string(getNotAddedList()) + + string("\n")); + critical = 1; + } + if (multiMask & MULTI_HAVE_DIFFERENT_VALUES) { + retval.append("A previous multi detector command gave different values\n" + "Please check the console\n"); + critical = 0; + } + if (multiMask & MULTI_CONFIG_FILE_ERROR) { + retval.append("Could not load Config File\n"); + critical = 0; + } + + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + //if the detector has error + if (multiMask & (1 << idet)) { + //append detector id + sprintf(sNumber, "%d", idet); + retval.append("Detector " + string(sNumber) + string(":\n")); + //get sls det error mask + slsMask = detectors[idet]->getErrorMask(); +#ifdef VERYVERBOSE + //append sls det error mask + sprintf(sNumber, "0x%lx", slsMask); + retval.append("Error Mask " + string(sNumber) + string("\n")); +#endif + //get the error critical level + if ((slsMask > 0xFFFFFFFF) | critical) + critical = 1; + //append error message + retval.append(errorDefs::getErrorMessage(slsMask)); + } + } + } + return retval; +} + +int64_t multiSlsDetector::clearAllErrorMask() { + clearErrorMask(); + clearNotAddedList(); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) + detectors[idet]->clearErrorMask(); + + return getErrorMask(); +} + +void multiSlsDetector::setErrorMaskFromAllDetectors() { + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } +} + +void multiSlsDetector::setAcquiringFlag(bool b) { + thisMultiDetector->acquiringFlag = b; +} + +bool multiSlsDetector::getAcquiringFlag() { + return thisMultiDetector->acquiringFlag; +} + +bool multiSlsDetector::isAcquireReady() { + if (thisMultiDetector->acquiringFlag) { + std::cout << "Acquire has already started. " + "If previous acquisition terminated unexpectedly, " + "reset busy flag to restart.(sls_detector_put busy 0)" << std::endl; + return FAIL; + } + thisMultiDetector->acquiringFlag = true; + return OK; +} + +int multiSlsDetector::checkVersionCompatibility(portType t) { + return parallelCallDetectorMember(&slsDetector::checkVersionCompatibility, t); +} + +int64_t multiSlsDetector::getId(idMode mode, int imod) { + int id, im; + int64_t ret; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->getId(mode, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + + return callDetectorMember(&slsDetector::getId, mode, imod); +} + + +slsDetector* multiSlsDetector::getSlsDetector(unsigned int pos) { + if (pos >= 0 && pos < detectors.size()) { + return detectors[pos]; + } + return 0; +} + +slsDetector *multiSlsDetector::operator()(int pos) { + if (pos >= 0 && pos < (int)detectors.size()) + return detectors[pos]; + return NULL; +} + + +void multiSlsDetector::freeSharedMemory(int multiId) { + // get number of detectors + int numDetectors = 0; + SharedMemory* shm = new SharedMemory(multiId, -1); + + // get number of detectors from multi shm + if (shm->IsExisting()) { + sharedMultiSlsDetector* mdet = (sharedMultiSlsDetector*)shm->OpenSharedMemory( + sizeof(sharedMultiSlsDetector)); + 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() { + // should be done before the detector list is deleted + clearAllErrorMask(); + + // clear sls detector vector shm + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + (*it)->freeSharedMemory(); + delete (*it); + } + detectors.clear(); + + // clear multi detector shm + if (sharedMemory) { + sharedMemory->UnmapSharedMemory(thisMultiDetector); + sharedMemory->RemoveSharedMemory(); + delete sharedMemory; + sharedMemory = 0; + } + thisMultiDetector = 0; + + // clear zmq vector + for (vector::const_iterator it = zmqSocket.begin(); it != zmqSocket.end(); ++it) { + delete(*it); + } + zmqSocket.clear(); + + // zmq + destroyThreadPool(); + client_downstream = false; +} + + +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() << "+"; + //PID + sstream << "\nPID: " << thisMultiDetector->lastPID + //user + << "\nUser: " << thisMultiDetector->lastUser + << "\nDate: " << thisMultiDetector->lastDate << endl; + + string s = sstream.str(); + return s; +} + + +bool multiSlsDetector::initSharedMemory(bool verify) { + + // 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()) { + thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->OpenSharedMemory(sz); + if (verify && thisMultiDetector->shmversion != MULTI_SHMVERSION) { + cprintf(RED, "Multi shared memory (%d) version mismatch " + "(expected 0x%x but got 0x%x)\n", detId, + MULTI_SHMVERSION, thisMultiDetector->shmversion); + sharedMemory->UnmapSharedMemory(thisMultiDetector);/** is this unncessary? */ + delete sharedMemory;/** is this unncessary? */ + sharedMemory = 0; + throw SharedMemoryException(); + } + } else { + try { + thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->CreateSharedMemory(sz); + created = true; + } catch(...) { + sharedMemory->RemoveSharedMemory(); + delete sharedMemory;/** is this unncessary? */ + sharedMemory = 0;/** is this unncessary? */ + thisMultiDetector = 0; + throw; + } + } + + return created; +} + + +void multiSlsDetector::initializeDetectorStructure() { + thisMultiDetector->shmversion = MULTI_SHMVERSION; + thisMultiDetector->numberOfDetectors = 0; + thisMultiDetector->numberOfDetector[X] = 0; + thisMultiDetector->numberOfDetector[Y] = 0; + thisMultiDetector->onlineFlag = 1; + thisMultiDetector->stoppedFlag = 0; + thisMultiDetector->masterPosition = -1; + thisMultiDetector->syncMode = GET_SYNCHRONIZATION_MODE; + 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] = 0; + thisMultiDetector->maxNumberOfChannelsPerDetector[Y] = 0; + for (int i = 0; i < MAX_TIMERS; ++i) { + thisMultiDetector->timerValue[i] = 0; + } + thisMultiDetector->currentSettings = GET_SETTINGS; + thisMultiDetector->currentThresholdEV = -1; + thisMultiDetector->progressIndex = 0; + thisMultiDetector->totalProgress = 1; + thisMultiDetector->fileIndex = 0; + strcpy(thisMultiDetector->fileName, "run"); + strcpy(thisMultiDetector->filePath, "/"); + thisMultiDetector->framesPerFile = 1; + thisMultiDetector->fileFormatType = ASCII; + thisMultiDetector->correctionMask = (1 << WRITE_FILE) | (1 << OVERWRITE_FILE); + thisMultiDetector->threadedProcessing = 1; + thisMultiDetector->tDead = 0; + strncpy(thisMultiDetector->flatFieldDir, getenv("HOME"), MAX_STR_LENGTH-1); + thisMultiDetector->flatFieldDir[MAX_STR_LENGTH-1] = 0; + strcpy(thisMultiDetector->flatFieldFile, "none"); + strcpy(thisMultiDetector->badChanFile, "none"); + strcpy(thisMultiDetector->angConvFile, "none"); + thisMultiDetector->angDirection = 1; + thisMultiDetector->fineOffset = 0; + thisMultiDetector->globalOffset = 0; + thisMultiDetector->binSize = 0.001; + for (int i = 0; i < 2; ++i) { + thisMultiDetector->sampleDisplacement[i] = 0.0; + } + thisMultiDetector->numberOfPositions = 0; + for (int i = 0; i < MAXPOS; ++i) { + thisMultiDetector->detPositions[i] = 0.0; + } + thisMultiDetector->actionMask = 0; + for (int i = 0; i < MAX_ACTIONS; ++i) { + strcpy(thisMultiDetector->actionScript[i], "none"); + strcpy(thisMultiDetector->actionParameter[i], "none"); + } + for (int i = 0; i < MAX_SCAN_LEVELS; ++i) { + thisMultiDetector->scanMode[i] = 0; + strcpy(thisMultiDetector->scanScript[i], "none"); + strcpy(thisMultiDetector-> scanParameter[i], "none"); + thisMultiDetector->nScanSteps[i] = 0; + { + double initValue = 0; + std::fill_n(thisMultiDetector->scanSteps[i], MAX_SCAN_STEPS, initValue); + } + thisMultiDetector->scanPrecision[i] = 0; + + } + thisMultiDetector->acquiringFlag = false; + thisMultiDetector->externalgui = false; + thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG; + thisMultiDetector->receiver_upstream = false; +} + +void multiSlsDetector::initializeMembers(bool verify) { + //slsDetectorUtils + stoppedFlag = &thisMultiDetector->stoppedFlag; + timerValue = thisMultiDetector->timerValue; + currentSettings = &thisMultiDetector->currentSettings; + currentThresholdEV = &thisMultiDetector->currentThresholdEV; + + //fileIO.h + filePath = thisMultiDetector->filePath; + fileName = thisMultiDetector->fileName; + fileIndex = &thisMultiDetector->fileIndex; + framesPerFile = &thisMultiDetector->framesPerFile; + fileFormatType = &thisMultiDetector->fileFormatType; + + //postprocessing + threadedProcessing = &thisMultiDetector->threadedProcessing; + correctionMask = &thisMultiDetector->correctionMask; + flatFieldDir = thisMultiDetector->flatFieldDir; + flatFieldFile = thisMultiDetector->flatFieldFile; + expTime = &timerValue[ACQUISITION_TIME]; + badChannelMask = NULL; + fdata = NULL; + thisData = NULL; + + //slsDetectorActions + actionMask = &thisMultiDetector->actionMask; + actionScript = thisMultiDetector->actionScript; + actionParameter = thisMultiDetector->actionParameter; + nScanSteps = thisMultiDetector->nScanSteps; + scanSteps = thisMultiDetector->scanSteps; + scanMode = thisMultiDetector->scanMode; + scanPrecision = thisMultiDetector->scanPrecision; + scanScript = thisMultiDetector->scanScript; + scanParameter = thisMultiDetector->scanParameter; + + //angularConversion.h + numberOfPositions = &thisMultiDetector->numberOfPositions; + detPositions = thisMultiDetector->detPositions; + angConvFile = thisMultiDetector->angConvFile; + binSize = &thisMultiDetector->binSize; + fineOffset = &thisMultiDetector->fineOffset; + globalOffset = &thisMultiDetector->globalOffset; + angDirection = &thisMultiDetector->angDirection; + moveFlag = NULL; + sampleDisplacement = thisMultiDetector->sampleDisplacement; + + //badChannelCorrections.h or postProcessing_Standalone.h + badChanFile = thisMultiDetector->badChanFile; + nBadChans = NULL; + badChansList = NULL; + nBadFF = NULL; + badFFList = NULL; + + //multiSlsDetector + for (vector::const_iterator it = zmqSocket.begin(); it != zmqSocket.end(); ++it) { + delete(*it); + } + zmqSocket.clear(); + + // 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); + } + + // depend on number of detectors + updateOffsets(); + createThreadPool(); +} + + +void multiSlsDetector::updateUserdetails() { + 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-1); + thisMultiDetector->lastUser[SHORT_STRING_LENGTH-1] = 0; + strncpy(thisMultiDetector->lastDate, exec("date").c_str(), DATE_LENGTH-1); + thisMultiDetector->lastDate[DATE_LENGTH-1] = 0; + } catch(...) { + strcpy(thisMultiDetector->lastUser, "errorreading"); + strcpy(thisMultiDetector->lastDate, "errorreading"); + } +} + + +std::string multiSlsDetector::exec(const char* cmd) { + int bufsize = 128; + char 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; +} + + +void multiSlsDetector::setHostname(const char* name) { + // this check is there only to allow the previous detsizechan command + if (thisMultiDetector->numberOfDetectors) { + cprintf(RED, "Warning: There are already detector(s) in shared memory." + "Freeing Shared memory now.\n"); + freeSharedMemory(); + setupMultiDetector(); + } + addMultipleDetectors(name); +} + + +string multiSlsDetector::getHostname(int pos) { + return concatResultOrPos(&slsDetector::getHostname, pos); +} + +void multiSlsDetector::addMultipleDetectors(const char* name) { + size_t p1 = 0; + string temp = string(name); + size_t p2 = temp.find('+', p1); + //single + if (p2 == string::npos) { + addSlsDetector(temp); + } + // multi + else { + while(p2 != string::npos) { + addSlsDetector(temp.substr(p1, p2-p1)); + temp = temp.substr(p2 + 1); + p2 = temp.find('+'); + } + } + + // a get to update shared memory online flag + setOnline(); + updateOffsets(); + createThreadPool(); +} + +void multiSlsDetector::addSlsDetector (std::string s) { +#ifdef VERBOSE + cout << "Adding detector " << s << endl; +#endif + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + if ((*it)->getHostname((it-detectors.begin())) == 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::getDetectorType(s.c_str(), DEFAULT_PORTNO); + if (type == GENERIC) { + cout << "Could not connect to Detector " << s << " to determine the type!" << endl; + setErrorMask(getErrorMask() | MULTI_DETECTORS_NOT_ADDED); + appendNotAddedList(s.c_str()); + return; + } + + + + int pos = (int)detectors.size(); + slsDetector* sdet = new slsDetector(type, detId, pos, false, this); + detectors.push_back(sdet); + thisMultiDetector->numberOfDetectors = detectors.size(); + + detectors[pos]->setHostname(s.c_str()); // also updates client + + thisMultiDetector->dataBytes += detectors[pos]->getDataBytes(); + thisMultiDetector->dataBytesInclGapPixels += detectors[pos]->getDataBytesInclGapPixels(); + thisMultiDetector->numberOfChannels += detectors[pos]->getTotalNumberOfChannels(); + thisMultiDetector->maxNumberOfChannels += detectors[pos]->getMaxNumberOfChannels(); +} + + +slsDetectorDefs::detectorType multiSlsDetector::getDetectorsType(int pos) { + detectorType dt = GENERIC; + if (pos >= 0 && pos < (int)detectors.size()) { + return detectors[pos]->getDetectorsType(); + } else + return detectors[0]->getDetectorsType();// needed?? + return dt; +} + + +std::string multiSlsDetector::sgetDetectorsType(int pos) { + return concatResultOrPos(&slsDetector::sgetDetectorsType, pos); +} + + +std::string multiSlsDetector::getDetectorType() { + return sgetDetectorsType(); +} + + +void multiSlsDetector::createThreadPool() { + if (threadpool) destroyThreadPool(); - int numthreads = thisMultiDetector->numberOfDetectors; - if(numthreads < 1){ + int numthreads = (int)detectors.size(); + if (numthreads < 1) { numthreads = 1; //create threadpool anyway, threads initialized only when >1 detector added } threadpool = new ThreadPool(numthreads); - switch(threadpool->initialize_threadpool()){ + switch (threadpool->initialize_threadpool()) { case 0: cerr << "Failed to initialize thread pool!" << endl; - return FAIL; + throw ThreadpoolException(); case 1: #ifdef VERBOSE cout << "Not initializing threads, not multi detector" << endl; @@ -322,1696 +1050,1538 @@ int multiSlsDetector::createThreadPool(){ #endif break; } - return OK; } -void multiSlsDetector::destroyThreadPool(){ - if(threadpool){ + +void multiSlsDetector::destroyThreadPool() { + if (threadpool) { delete threadpool; - threadpool=0; + threadpool = 0; #ifdef VERBOSE - cout<<"Destroyed Threadpool "<< threadpool << endl; + cout << "Destroyed Threadpool " << threadpool << endl; #endif } } -int multiSlsDetector::addSlsDetector(int id, int pos) { - int j=thisMultiDetector->numberOfDetectors; +int multiSlsDetector::getNumberOfDetectors() { + return (int)detectors.size(); +} +int multiSlsDetector::getNumberOfDetectors(dimension d) { + return thisMultiDetector->numberOfDetector[d]; +} - if (slsDetector::exists(id)==0) { - cout << "Detector " << id << " does not exist - You should first create it to determine type etc." << endl; - } +void multiSlsDetector::getNumberOfDetectors(int& nx, int& ny) { + nx=thisMultiDetector->numberOfDetector[X];ny=thisMultiDetector->numberOfDetector[Y]; +} +int multiSlsDetector::getNMods() { + int nm = 0; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + nm += (*it)->getNMods(); + } + return nm; +} + +int multiSlsDetector::getNMod(dimension d) { + int nm = 0; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + nm += (*it)->getNMod(d); + } + return nm; +} + +int multiSlsDetector::getMaxMods() { + int ret = 0; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + ret += (*it)->getMaxMods(); + } + return ret; +} + +int multiSlsDetector::getMaxMod(dimension d) { + int ret = 0, ret1; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + ret1 = (*it)->getNMaxMod(d); #ifdef VERBOSE - cout << "Adding detector " << id << " in position " << pos << endl; + cout << "detector " << (it-detectors.begin()) << " maxmods " << + ret1 << " in direction " << d << endl; +#endif + ret += ret1; + } +#ifdef VERBOSE + cout << "max mods in direction " << d << " is " << ret << endl; #endif - if (pos<0) - pos=j; + return ret; +} - if (pos>j) - pos=thisMultiDetector->numberOfDetectors; +int multiSlsDetector::getMaxNumberOfModules(dimension d) { + int ret = 0; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + ret += (*it)->getMaxNumberOfModules(d); + } + return ret; +} +int multiSlsDetector::setNumberOfModules(int p, dimension d) { + int ret = 0; + int nm = 0, mm = 0, nt = p; + thisMultiDetector->dataBytes = 0; + thisMultiDetector->dataBytesInclGapPixels = 0; + thisMultiDetector->numberOfChannels = 0; - //check that it is not already in the list + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (p < 0) + nm = p; + else { + mm = detectors[idet]->getMaxNumberOfModules(); + if (nt > mm) { + nm = mm; + nt -= nm; + } else { + nm = nt; + nt -= nm; + } + } + ret += detectors[idet]->setNumberOfModules(nm); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + thisMultiDetector->dataBytes += detectors[idet]->getDataBytes(); + thisMultiDetector->dataBytesInclGapPixels += detectors[idet]->getDataBytesInclGapPixels(); + thisMultiDetector->numberOfChannels += detectors[idet]->getTotalNumberOfChannels(); + } - for (int i=0; inumberOfDetectors; ++i) { - //check that it is not already in the list, in that case move to new position - if (detectors[i]) { - if (detectors[i]->getDetectorId()==id) { - cout << "Detector " << id << "already part of the multiDetector in position " << i << "!" << endl << "Remove it before adding it back in a new position!"<< endl; + if (p != -1) + updateOffsets(); + return ret; +} + +int multiSlsDetector::getChansPerMod(int imod) { + int id = -1, im = -1; + decodeNMod(imod, id, im); + if (id >= 0 && id < (int)detectors.size()) { + return detectors[id]->getChansPerMod(im); + } return -1; - } - } - } +} +int multiSlsDetector::getTotalNumberOfChannels() { + thisMultiDetector->numberOfChannels = 0; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + thisMultiDetector->numberOfChannels += (*it)->getTotalNumberOfChannels(); + } + return thisMultiDetector->numberOfChannels; +} +int multiSlsDetector::getTotalNumberOfChannels(dimension d) { + return thisMultiDetector->numberOfChannel[d]; +} - if (pos!=thisMultiDetector->numberOfDetectors) { - for (int ip=thisMultiDetector->numberOfDetectors-1; ip>=pos; --ip) { -#ifdef VERBOSE - cout << "Moving detector " << thisMultiDetector->detectorIds[ip] << " from position " << ip << " to " << ip+1 << endl; -#endif - thisMultiDetector->detectorIds[ip+1]=thisMultiDetector->detectorIds[ip]; - detectors[ip+1]=detectors[ip]; - } - } -#ifdef VERBOSE - cout << "Creating new detector " << pos << endl; -#endif +int multiSlsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d) { + return thisMultiDetector->numberOfChannelInclGapPixels[d]; +} - detectors[pos]=new slsDetector(pos, id, this); - thisMultiDetector->detectorIds[pos]=detectors[pos]->getDetectorId(); - ++thisMultiDetector->numberOfDetectors; +int multiSlsDetector::getMaxNumberOfChannels() { + thisMultiDetector->maxNumberOfChannels = 0; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + thisMultiDetector->maxNumberOfChannels += (*it)->getMaxNumberOfChannels(); + } + return thisMultiDetector->maxNumberOfChannels; +} - thisMultiDetector->dataBytes+=detectors[pos]->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels+=detectors[pos]->getDataBytesInclGapPixels(); +int multiSlsDetector::getMaxNumberOfChannels(dimension d) { + return thisMultiDetector->maxNumberOfChannel[d]; +} - thisMultiDetector->numberOfChannels+=detectors[pos]->getTotalNumberOfChannels(); - thisMultiDetector->maxNumberOfChannels+=detectors[pos]->getMaxNumberOfChannels(); +int multiSlsDetector::getMaxNumberOfChannelsInclGapPixels(dimension d) { + return thisMultiDetector->maxNumberOfChannelInclGapPixels[d]; +} +int multiSlsDetector::getMaxNumberOfChannelsPerDetector(dimension d) { + return thisMultiDetector->maxNumberOfChannelsPerDetector[d]; +} +int multiSlsDetector::setMaxNumberOfChannelsPerDetector(dimension d,int i) { + thisMultiDetector->maxNumberOfChannelsPerDetector[d] = i; + return thisMultiDetector->maxNumberOfChannelsPerDetector[d]; +} - getMaxMods(); - getNMods(); - getMaxMod(X); - getNMod(X); - getMaxMod(Y); - getNMod(Y); - -#ifdef VERBOSE - cout << "Detector added " << thisMultiDetector->numberOfDetectors<< endl; - - for (int ip=0; ipnumberOfDetectors; ++ip) { - cout << "Detector " << thisMultiDetector->detectorIds[ip] << " position " << ip << " " << detectors[ip]->getHostname() << endl; - } -#endif - - //set offsets - updateOffsets(); - if(createThreadPool() == FAIL) - exit(-1); - - - return thisMultiDetector->numberOfDetectors; - +int multiSlsDetector::getDetectorOffset(dimension d, int pos) { + if (pos < 0 || pos >= (int)detectors.size()) + return -1; + return detectors[pos]->getDetectorOffset(d); } -void multiSlsDetector::updateOffsets(){//cannot paralllize due to slsdetector calling this via parentdet-> +void multiSlsDetector::setDetectorOffset(dimension d, int off, int pos) { + if (pos < 0 || pos >= (int)detectors.size()) + detectors[pos]->setDetectorOffset(d, off); +} + + +void multiSlsDetector::updateOffsets() { + //cannot paralllize due to slsdetector calling this via parentdet-> #ifdef VERBOSE - cout << endl << "Updating Multi-Detector Offsets" << endl; + cout << endl + << "Updating Multi-Detector Offsets" << endl; #endif - int offsetX=0, offsetY=0, numX=0, numY=0, maxX=0, maxY=0; - int maxChanX = thisMultiDetector->maxNumberOfChannelsPerDetector[X]; - int maxChanY = thisMultiDetector->maxNumberOfChannelsPerDetector[Y]; - int prevChanX=0; - int prevChanY=0; + int offsetX = 0, offsetY = 0, numX = 0, numY = 0, maxX = 0, maxY = 0; + int maxChanX = thisMultiDetector->maxNumberOfChannelsPerDetector[X]; + int maxChanY = thisMultiDetector->maxNumberOfChannelsPerDetector[Y]; + int prevChanX = 0; + int prevChanY = 0; bool firstTime = true; - thisMultiDetector->numberOfChannel[X] = 0; - thisMultiDetector->numberOfChannel[Y] = 0; + thisMultiDetector->numberOfChannel[X] = 0; + thisMultiDetector->numberOfChannel[Y] = 0; thisMultiDetector->maxNumberOfChannel[X] = 0; thisMultiDetector->maxNumberOfChannel[Y] = 0; - thisMultiDetector->numberOfDetector[X] = 0; - thisMultiDetector->numberOfDetector[Y] = 0; - + thisMultiDetector->numberOfDetector[X] = 0; + thisMultiDetector->numberOfDetector[Y] = 0; // gap pixels - int offsetX_gp=0, offsetY_gp=0, numX_gp=0, numY_gp=0, maxX_gp=0, maxY_gp=0; - int prevChanX_gp=0, prevChanY_gp=0; - thisMultiDetector->numberOfChannelInclGapPixels[X] = 0; - thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0; + int offsetX_gp = 0, offsetY_gp = 0, numX_gp = 0, numY_gp = 0, maxX_gp = 0, maxY_gp = 0; + int prevChanX_gp = 0, prevChanY_gp = 0; + thisMultiDetector->numberOfChannelInclGapPixels[X] = 0; + thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0; thisMultiDetector->maxNumberOfChannelInclGapPixels[X] = 0; thisMultiDetector->maxNumberOfChannelInclGapPixels[Y] = 0; - - for (int i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { #ifdef VERBOSE - cout<<"offsetX:"<getTotalNumberOfChannels(Y) <<" maxChanY:"< 0) && ((offsetX + detectors[i]->getTotalNumberOfChannels(X)) > maxChanX)) - cout<<"\nDetector[" << i << "] exceeds maximum channels allowed for complete detector set in X dimension!" << endl; - if ((maxChanY > 0) && ((offsetY + detectors[i]->getTotalNumberOfChannels(Y)) > maxChanY)) - cout<<"\nDetector[" << i << "] exceeds maximum channels allowed for complete detector set in Y dimension!" << endl; - prevChanX = detectors[i]->getTotalNumberOfChannels(X); - prevChanY = detectors[i]->getTotalNumberOfChannels(Y); - prevChanX_gp = detectors[i]->getTotalNumberOfChannelsInclGapPixels(X); - prevChanY_gp = detectors[i]->getTotalNumberOfChannelsInclGapPixels(Y); - numX += detectors[i]->getTotalNumberOfChannels(X); - numY += detectors[i]->getTotalNumberOfChannels(Y); - numX_gp += detectors[i]->getTotalNumberOfChannelsInclGapPixels(X); - numY_gp += detectors[i]->getTotalNumberOfChannelsInclGapPixels(Y); - maxX += detectors[i]->getMaxNumberOfChannels(X); - maxY += detectors[i]->getMaxNumberOfChannels(Y); - maxX_gp += detectors[i]->getMaxNumberOfChannelsInclGapPixels(X); - maxY_gp += detectors[i]->getMaxNumberOfChannelsInclGapPixels(Y); - ++thisMultiDetector->numberOfDetector[X]; - ++thisMultiDetector->numberOfDetector[Y]; + //cout<<" totalchan:"<< detectors[idet]->getTotalNumberOfChannels(Y) + //<<" maxChanY:"< 0) && ((offsetX + detectors[idet]->getTotalNumberOfChannels(X)) + > maxChanX)) + cout << "\nDetector[" << idet << "] exceeds maximum channels " + "allowed for complete detector set in X dimension!" << endl; + if ((maxChanY > 0) && ((offsetY + detectors[idet]->getTotalNumberOfChannels(Y)) + > maxChanY)) + cout << "\nDetector[" << idet << "] exceeds maximum channels " + "allowed for complete detector set in Y dimension!" << endl; + prevChanX = detectors[idet]->getTotalNumberOfChannels(X); + prevChanY = detectors[idet]->getTotalNumberOfChannels(Y); + prevChanX_gp = detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); + prevChanY_gp = detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); + numX += detectors[idet]->getTotalNumberOfChannels(X); + numY += detectors[idet]->getTotalNumberOfChannels(Y); + numX_gp += detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); + numY_gp += detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); + maxX += detectors[idet]->getMaxNumberOfChannels(X); + maxY += detectors[idet]->getMaxNumberOfChannels(Y); + maxX_gp += detectors[idet]->getMaxNumberOfChannelsInclGapPixels(X); + maxY_gp += detectors[idet]->getMaxNumberOfChannelsInclGapPixels(Y); + ++thisMultiDetector->numberOfDetector[X]; + ++thisMultiDetector->numberOfDetector[Y]; #ifdef VERBOSE - cout<<"incrementing in both direction"< 0) && ((offsetY + prevChanY + detectors[i]->getTotalNumberOfChannels(Y)) <= maxChanY))){ - offsetY += prevChanY; - offsetY_gp += prevChanY_gp; - prevChanY = detectors[i]->getTotalNumberOfChannels(Y); - prevChanY_gp = detectors[i]->getTotalNumberOfChannelsInclGapPixels(Y); - numY += detectors[i]->getTotalNumberOfChannels(Y); - numY_gp += detectors[i]->getTotalNumberOfChannelsInclGapPixels(Y); - maxY += detectors[i]->getMaxNumberOfChannels(Y); - maxY_gp += detectors[i]->getMaxNumberOfChannelsInclGapPixels(Y); - ++thisMultiDetector->numberOfDetector[Y]; -#ifdef VERBOSE - cout<<"incrementing in y direction"< 0) && ((offsetX + prevChanX + detectors[i]->getTotalNumberOfChannels(X)) > maxChanX)) - cout<<"\nDetector[" << i << "] exceeds maximum channels allowed for complete detector set in X dimension!" << endl; - offsetY = 0; - offsetY_gp = 0; - prevChanY = detectors[i]->getTotalNumberOfChannels(Y); - prevChanY_gp = detectors[i]->getTotalNumberOfChannelsInclGapPixels(Y); - numY = 0; //assuming symmetry with this statement. whats on 1st column should be on 2nd column - numY_gp = 0; - maxY = 0; - maxY_gp = 0; - offsetX += prevChanX; - offsetX_gp += prevChanX_gp; - prevChanX = detectors[i]->getTotalNumberOfChannels(X); - prevChanX_gp = detectors[i]->getTotalNumberOfChannelsInclGapPixels(X); - numX += detectors[i]->getTotalNumberOfChannels(X); - numX_gp += detectors[i]->getTotalNumberOfChannelsInclGapPixels(X); - maxX += detectors[i]->getMaxNumberOfChannels(X); - maxX_gp += detectors[i]->getMaxNumberOfChannelsInclGapPixels(X); - ++thisMultiDetector->numberOfDetector[X]; -#ifdef VERBOSE - cout<<"incrementing in x direction"<getDataBytes() / (double)(detectors[i]->getMaxNumberOfChannels(X) * detectors[i]->getMaxNumberOfChannels(Y)); - thisMultiDetector->offsetX[i] = (bytesperchannel >= 1.0) ? offsetX_gp : offsetX; - thisMultiDetector->offsetY[i] = (bytesperchannel >= 1.0) ? offsetY_gp : offsetY; -#ifdef VERBOSE - cout << "Detector[" << i << "] has offsets (" << thisMultiDetector->offsetX[i] << ", " << thisMultiDetector->offsetY[i] << ")" << endl; -#endif - //offsetY has been reset sometimes and offsetX the first time, but remember the highest values - if(numX > thisMultiDetector->numberOfChannel[X]) - thisMultiDetector->numberOfChannel[X] = numX; - if(numY > thisMultiDetector->numberOfChannel[Y]) - thisMultiDetector->numberOfChannel[Y] = numY; - if(numX_gp > thisMultiDetector->numberOfChannelInclGapPixels[X]) - thisMultiDetector->numberOfChannelInclGapPixels[X] = numX_gp; - if(numY_gp > thisMultiDetector->numberOfChannelInclGapPixels[Y]) - thisMultiDetector->numberOfChannelInclGapPixels[Y] = numY_gp; - if(maxX > thisMultiDetector->maxNumberOfChannel[X]) - thisMultiDetector->maxNumberOfChannel[X] = maxX; - if(maxY > thisMultiDetector->maxNumberOfChannel[Y]) - thisMultiDetector->maxNumberOfChannel[Y] = maxY; - if(maxX_gp > thisMultiDetector->maxNumberOfChannelInclGapPixels[X]) - thisMultiDetector->maxNumberOfChannelInclGapPixels[X] = maxX_gp; - if(maxY_gp > thisMultiDetector->maxNumberOfChannelInclGapPixels[Y]) - thisMultiDetector->maxNumberOfChannelInclGapPixels[Y] = maxY_gp; } + + //incrementing in y direction + else if ((maxChanY == -1) || ((maxChanY > 0) && + ((offsetY + prevChanY + detectors[idet]->getTotalNumberOfChannels(Y)) + <= maxChanY))) { + offsetY += prevChanY; + offsetY_gp += prevChanY_gp; + prevChanY = detectors[idet]->getTotalNumberOfChannels(Y); + prevChanY_gp = detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); + numY += detectors[idet]->getTotalNumberOfChannels(Y); + numY_gp += detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); + maxY += detectors[idet]->getMaxNumberOfChannels(Y); + maxY_gp += detectors[idet]->getMaxNumberOfChannelsInclGapPixels(Y); + ++thisMultiDetector->numberOfDetector[Y]; +#ifdef VERBOSE + cout << "incrementing in y direction" << endl; +#endif + } + + //incrementing in x direction + else { + if ((maxChanX > 0) && + ((offsetX + prevChanX + detectors[idet]->getTotalNumberOfChannels(X)) + > maxChanX)) + cout << "\nDetector[" << idet << "] exceeds maximum channels " + "allowed for complete detector set in X dimension!" << endl; + offsetY = 0; + offsetY_gp = 0; + prevChanY = detectors[idet]->getTotalNumberOfChannels(Y); + prevChanY_gp = detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); + numY = 0; //assuming symmetry with this statement. + //whats on 1st column should be on 2nd column + numY_gp = 0; + maxY = 0; + maxY_gp = 0; + offsetX += prevChanX; + offsetX_gp += prevChanX_gp; + prevChanX = detectors[idet]->getTotalNumberOfChannels(X); + prevChanX_gp = detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); + numX += detectors[idet]->getTotalNumberOfChannels(X); + numX_gp += detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); + maxX += detectors[idet]->getMaxNumberOfChannels(X); + maxX_gp += detectors[idet]->getMaxNumberOfChannelsInclGapPixels(X); + ++thisMultiDetector->numberOfDetector[X]; +#ifdef VERBOSE + cout << "incrementing in x direction" << endl; +#endif + } + + double bytesperchannel = (double)detectors[idet]->getDataBytes() / + (double)(detectors[idet]->getMaxNumberOfChannels(X) + * detectors[idet]->getMaxNumberOfChannels(Y)); + detectors[idet]->setDetectorOffset(X, (bytesperchannel >= 1.0) ? offsetX_gp : offsetX); + detectors[idet]->setDetectorOffset(Y, (bytesperchannel >= 1.0) ? offsetY_gp : offsetY); + +#ifdef VERBOSE + cout << "Detector[" << idet << "] has offsets (" << + detectors[idet]->getDetectorOffset(X) << ", " << + detectors[idet]->getDetectorOffset(Y) << ")" << endl; +#endif + //offsetY has been reset sometimes and offsetX the first time, + //but remember the highest values + if (numX > thisMultiDetector->numberOfChannel[X]) + thisMultiDetector->numberOfChannel[X] = numX; + if (numY > thisMultiDetector->numberOfChannel[Y]) + thisMultiDetector->numberOfChannel[Y] = numY; + if (numX_gp > thisMultiDetector->numberOfChannelInclGapPixels[X]) + thisMultiDetector->numberOfChannelInclGapPixels[X] = numX_gp; + if (numY_gp > thisMultiDetector->numberOfChannelInclGapPixels[Y]) + thisMultiDetector->numberOfChannelInclGapPixels[Y] = numY_gp; + if (maxX > thisMultiDetector->maxNumberOfChannel[X]) + thisMultiDetector->maxNumberOfChannel[X] = maxX; + if (maxY > thisMultiDetector->maxNumberOfChannel[Y]) + thisMultiDetector->maxNumberOfChannel[Y] = maxY; + if (maxX_gp > thisMultiDetector->maxNumberOfChannelInclGapPixels[X]) + thisMultiDetector->maxNumberOfChannelInclGapPixels[X] = maxX_gp; + if (maxY_gp > thisMultiDetector->maxNumberOfChannelInclGapPixels[Y]) + thisMultiDetector->maxNumberOfChannelInclGapPixels[Y] = maxY_gp; } #ifdef VERBOSE cout << "Number of Channels in X direction:" << thisMultiDetector->numberOfChannel[X] << endl; - cout << "Number of Channels in Y direction:" << thisMultiDetector->numberOfChannel[Y] << endl << endl; - cout << "Number of Channels in X direction with Gap Pixels:" << thisMultiDetector->numberOfChannelInclGapPixels[X] << endl; - cout << "Number of Channels in Y direction with Gap Pixels:" << thisMultiDetector->numberOfChannelInclGapPixels[Y] << endl << endl; + cout << "Number of Channels in Y direction:" << thisMultiDetector->numberOfChannel[Y] << endl + << endl; + cout << "Number of Channels in X direction with Gap Pixels:" << + thisMultiDetector->numberOfChannelInclGapPixels[X] << endl; + cout << "Number of Channels in Y direction with Gap Pixels:" << + thisMultiDetector->numberOfChannelInclGapPixels[Y] << endl + << endl; #endif } - -string multiSlsDetector::setHostname(const char* name, int pos){ - - // int id=0; - string s; - if (pos>=0) { - addSlsDetector(name, pos); - if (detectors[pos]) - return detectors[pos]->getHostname(); - } else { - size_t p1=0; - s=string(name); - size_t p2=s.find('+',p1); - char hn[1000]; - if (p2==string::npos) { - strcpy(hn,s.c_str()); - addSlsDetector(hn, pos); - } else { - while (p2!=string::npos) { - strcpy(hn,s.substr(p1,p2-p1).c_str()); - addSlsDetector(hn, pos); - s=s.substr(p2+1); - p2=s.find('+'); - } - } - } -#ifdef VERBOSE - cout << "-----------------------------set online!" << endl; -#endif - setOnline(ONLINE_FLAG); - - return getHostname(pos); -} - -string multiSlsDetector::ssetDetectorsType(string name, int pos) { - - - // int id=0; - string s; - if (pos>=0) { - if (getDetectorType(name)!=GET_DETECTOR_TYPE) - addSlsDetector(name.c_str(), pos); - } else { - removeSlsDetector(); //reset detector list! - size_t p1=0; - s=string(name); - size_t p2=s.find('+',p1); - char hn[1000]; - if (p2==string::npos) { - strcpy(hn,s.c_str()); - addSlsDetector(hn, pos); - } else { - while (p2!=string::npos) { - strcpy(hn,s.substr(p1,p2-p1).c_str()); - if (getDetectorType(hn)!=GET_DETECTOR_TYPE) - addSlsDetector(hn, pos); - s=s.substr(p2+1); - p2=s.find('+'); - } - } - } - return sgetDetectorsType(pos); - -} - -string multiSlsDetector::getHostname(int pos) { - string s=string(""); -#ifdef VERBOSE - cout << "returning hostname" << pos << endl; -#endif - if (pos>=0) { - if (detectors[pos]) - return detectors[pos]->getHostname(); - } else { - for (int ip=0; ipnumberOfDetectors; ++ip) { -#ifdef VERBOSE - cout << "detector " << ip << endl; -#endif - if (detectors[ip]) { - s+=detectors[ip]->getHostname(); - s+=string("+"); - } -#ifdef VERBOSE - cout << s <=0) { - if (detectors[pos]) - return detectors[pos]->getDetectorsType(); - } else if (detectors[0]) - return detectors[0]->getDetectorsType(); - return s; -} - - -string multiSlsDetector::sgetDetectorsType(int pos) { - - string s=string(""); -#ifdef VERBOSE - cout << "returning type" << pos << endl; -#endif - if (pos>=0) { - if (detectors[pos]) - return detectors[pos]->sgetDetectorsType(); - } else { - for (int ip=0; ipnumberOfDetectors; ++ip) { -#ifdef VERBOSE - cout << "detector " << ip << endl; -#endif - if (detectors[ip]) { - s+=detectors[ip]->sgetDetectorsType(); - s+=string("+"); - } -#ifdef VERBOSE - cout << "type " << s << endl; -#endif - } - } - return s; - -} - - - - -int multiSlsDetector::getDetectorId(int pos) { - -#ifdef VERBOSE - cout << "Getting detector ID " << pos << endl; -#endif - - if (pos>=0) { - if (detectors[pos]) - return detectors[pos]->getDetectorId(); - } - return -1; -} - - - -int multiSlsDetector::setDetectorId(int ival, int pos){ - - if (pos>=0) { - addSlsDetector(ival, pos); - if (detectors[pos]) - return detectors[pos]->getDetectorId(); - } else { - return -1; - } - return -1; - -} - - -int multiSlsDetector::addSlsDetector(const char *name, int pos) { - - detectorType t=getDetectorType(string(name)); - int online=0; - slsDetector *s=NULL; - int id; -#ifdef VERBOSE - cout << "Adding detector "<numberOfDetectors; ++i) { - if (detectors[i]) { - if (detectors[i]->getHostname()==string(name)) { - cout << "Detector " << name << "already part of the multiDetector in position " << i << "!" << endl<< "Remove it before adding it back in a new position!"<< endl; - return -1; - } - } - } - - //checking that the detector doesn't already exists - - for (id=0; id0) { -#ifdef VERBOSE - cout << "Detector " << id << " already exists" << endl; -#endif - s=new slsDetector(pos, id, this); - if (s->getHostname()==string(name)) - break; - delete s; - s=NULL; - //++id; - } - } - - if (s==NULL) { - t=slsDetector::getDetectorType(name, DEFAULT_PORTNO); - if (t==GENERIC) { - cout << "Detector " << name << "does not exist in shared memory and could not connect to it to determine the type (which is not specified)!" << endl; - setErrorMask(getErrorMask()|MULTI_DETECTORS_NOT_ADDED); - appendNotAddedList(name); - return -1; - } -#ifdef VERBOSE - else - cout << "Detector type is " << t << endl; -#endif - online=1; - } - } -#ifdef VERBOSE - else - cout << "Adding detector by type " << getDetectorType(t) << endl; -#endif - - - - if (s==NULL) { - for (id=0; idsetTCPSocket(name); - setOnline(ONLINE_FLAG); - } - delete s; - } -#ifdef VERBOSE - cout << "Adding it to the multi detector structure" << endl; -#endif - return addSlsDetector(id, pos); - - -} - - -int multiSlsDetector::addSlsDetector(detectorType t, int pos) { - - int id; - - if (t==GENERIC) { - return -1; - } - - for (id=0; id=0 && posnumberOfDetectors) { - if (detectors[pos]) { - ox=thisMultiDetector->offsetX[pos]; - oy=thisMultiDetector->offsetY[pos]; - ret=OK; - } - } - return ret; -} - -int multiSlsDetector::setDetectorOffset(int pos, int ox, int oy) { - - - int ret=FAIL; - - if (pos>=0 && posnumberOfDetectors) { - if (detectors[pos]) { - if (ox!=-1) - thisMultiDetector->offsetX[pos]=ox; - if (oy!=-1) - thisMultiDetector->offsetY[pos]=oy; - ret=OK; - } - } - return ret; -} - - - -int multiSlsDetector::removeSlsDetector(char *name){ - for (int id=0; idnumberOfDetectors; ++id) { - if (detectors[id]) { - if (detectors[id]->getHostname()==string(name)) { - removeSlsDetector(id); - } - } - } - return thisMultiDetector->numberOfDetectors; -}; - - - - -int multiSlsDetector::removeSlsDetector(int pos) { - int j; - -#ifdef VERBOSE - cout << "Removing detector in position " << pos << endl; -#endif - - int mi=0, ma=thisMultiDetector->numberOfDetectors, single=0; - - if (pos>=0) { - mi=pos; - ma=pos+1; - single=1; - } - - // if (pos<0 ) - // pos=thisMultiDetector->numberOfDetectors-1; - - if (pos>=thisMultiDetector->numberOfDetectors) - return thisMultiDetector->numberOfDetectors; - - //j=pos; - for (j=mi; jdataBytes-=detectors[j]->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels-=detectors[j]->getDataBytesInclGapPixels(); - thisMultiDetector->numberOfChannels-=detectors[j]->getTotalNumberOfChannels(); - thisMultiDetector->maxNumberOfChannels-=detectors[j]->getMaxNumberOfChannels(); - - delete detectors[j]; - detectors[j]=0; - --thisMultiDetector->numberOfDetectors; - - - if (single) { - for (int i=j+1; inumberOfDetectors+1; ++i) { - detectors[i-1]=detectors[i]; - thisMultiDetector->detectorIds[i-1]=thisMultiDetector->detectorIds[i]; - } - detectors[thisMultiDetector->numberOfDetectors]=NULL; - thisMultiDetector->detectorIds[thisMultiDetector->numberOfDetectors]=-1; - } - } - } - - updateOffsets(); - if(createThreadPool() == FAIL) - exit(-1); - - return thisMultiDetector->numberOfDetectors; -} - - - - - - - - -int multiSlsDetector::setMaster(int i) { - - int ret=-1, slave=0; - masterFlags f; -#ifdef VERBOSE - cout << "settin master in position " << i << endl; -#endif - if (i>=0 && inumberOfDetectors) { - if (detectors[i]) { -#ifdef VERBOSE - cout << "detector position " << i << " "; -#endif - thisMultiDetector->masterPosition=i; - detectors[i]->setMaster(IS_MASTER); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++id) { - if (i!=id) { - if (detectors[id]) { -#ifdef VERBOSE - cout << "detector position " << id << " "; -#endif - detectors[id]->setMaster(IS_SLAVE); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++id) { - if (detectors[id]) { -#ifdef VERBOSE - cout << "detector position " << id << " "; -#endif - detectors[id]->setMaster(NO_MASTER); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++id) { - if (detectors[id]) { -#ifdef VERBOSE - cout << "detector position " << id << " "; -#endif - f=detectors[id]->setMaster(GET_MASTER); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<0 && ret<0) - ret=-2; - - if (ret<0) - ret=-1; - - thisMultiDetector->masterPosition=ret; - - return thisMultiDetector->masterPosition; -} - -// enum synchronyzationMode { -// 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 */ -// } - -/** - Sets/gets the synchronization mode of the various detectors - \param sync syncronization mode - \returns current syncronization mode -*/ -slsDetectorDefs::synchronizationMode multiSlsDetector::setSynchronization(synchronizationMode sync) { - - - synchronizationMode ret=GET_SYNCHRONIZATION_MODE, ret1=GET_SYNCHRONIZATION_MODE; - - for (int id=0; idnumberOfDetectors; ++id) { - if (detectors[id]) { - ret1=detectors[id]->setSynchronization(sync); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<syncMode=ret; - - return thisMultiDetector->syncMode; - -} - - - - - - - - - - - - - - - - - - - - - - - - - int multiSlsDetector::setOnline(int off) { + if (off != GET_ONLINE_FLAG) + thisMultiDetector->onlineFlag = parallelCallDetectorMember(&slsDetector::setOnline, off); + return thisMultiDetector->onlineFlag; +} - if (off!=GET_ONLINE_FLAG) { - thisMultiDetector->onlineFlag=off; - int ret=-100; - if(!threadpool){ +string multiSlsDetector::checkOnline() { + string offlineDetectors = ""; + for (vector::const_iterator it = detectors.begin(); it != detectors.end(); ++it) { + string tmp = (*it)->checkOnline(); + if (!tmp.empty()) + offlineDetectors += tmp + "+"; + } + return offlineDetectors; +} + + +int multiSlsDetector::setPort(portType t, int p) { + return callDetectorMember(&slsDetector::setPort, t, p); +} + +int multiSlsDetector::lockServer(int p) { + return callDetectorMember(&slsDetector::lockServer, p); +} + +string multiSlsDetector::getLastClientIP() { + return callDetectorMember(&slsDetector::getLastClientIP); +} + +int multiSlsDetector::exitServer() { + int ival = FAIL, iv; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iv = detectors[idet]->exitServer(); + if (iv == OK) + ival = iv; + } + return ival; +} + +int multiSlsDetector::readConfigurationFile(string const fname) { + + freeSharedMemory(); + setupMultiDetector(); + + + multiSlsDetectorClient* cmd; + string ans; + string str; + ifstream infile; + int iargval; + int interrupt = 0; + char* args[1000]; + + char myargs[1000][1000]; + + string sargname, sargval; + int iline = 0; + std::cout << "config file name " << fname << std::endl; + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + + while (infile.good() and interrupt == 0) { + sargname = "none"; + sargval = "0"; + getline(infile, str); + ++iline; + + // remove comments that come after + if (str.find('#') != string::npos) + str.erase(str.find('#')); +#ifdef VERBOSE + std::cout << "string:" << str << std::endl; +#endif + if (str.length() < 2) { +#ifdef VERBOSE + std::cout << "Empty line or Comment " << std::endl; +#endif + continue; + } else { + istringstream ssstr(str); + iargval = 0; + while (ssstr.good()) { + ssstr >> sargname; +#ifdef VERBOSE + std::cout << iargval << " " << sargname << std::endl; +#endif + strcpy(myargs[iargval], sargname.c_str()); + args[iargval] = myargs[iargval]; +#ifdef VERBOSE + std::cout << "--" << iargval << " " << args[iargval] << std::endl; +#endif + ++iargval; + } +#ifdef VERBOSE + cout << endl; + for (int ia = 0; ia < iargval; ia++) + cout << args[ia] << " ??????? "; + cout << endl; +#endif + cmd = new multiSlsDetectorClient(iargval, args, PUT_ACTION, this); + delete cmd; + } + ++iline; + } + + infile.close(); + } else { + std::cout << "Error opening configuration file " << fname << " for reading" << std::endl; + setErrorMask(getErrorMask() | MULTI_CONFIG_FILE_ERROR); + return FAIL; + } +#ifdef VERBOSE + std::cout << "Read configuration file of " << iline << " lines" << std::endl; +#endif + + setNumberOfModules(-1); + getMaxNumberOfModules(); + + if (getErrorMask()) { + int c; + cprintf(RED, "\n----------------\n Error Messages\n----------------\n%s\n", + getErrorMessage(c).c_str()); + return FAIL; + } + + return OK; +} + + +int multiSlsDetector::writeConfigurationFile(string const fname) { + + string names[] = { + "detsizechan", + "hostname", + "master", + "sync", + "outdir", + "ffdir", + "headerbefore", + "headerafter", + "headerbeforepar", + "headerafterpar", + "badchannels", + "angconv", + "globaloff", + "binsize", + "threaded" + }; + + int nvar = 15; + char* args[100]; + for (int ia = 0; ia < 100; ++ia) { + args[ia] = new char[1000]; + } + int ret = OK, ret1 = OK; + + ofstream outfile; + int iline = 0; + + outfile.open(fname.c_str(), ios_base::out); + if (outfile.is_open()) { + + slsDetectorCommand* cmd = new slsDetectorCommand(this); + + // complete size of detector + cout << iline << " " << names[iline] << endl; + strcpy(args[0], names[iline].c_str()); + outfile << names[iline] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl; + ++iline; + + // hostname of the detectors + cout << iline << " " << names[iline] << endl; + strcpy(args[0], names[iline].c_str()); + outfile << names[iline] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl; + ++iline; + + // single detector configuration + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + outfile << endl; + ret1 = detectors[idet]->writeConfigurationFile(outfile, idet); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret1 == FAIL) + ret = FAIL; + } + + outfile << endl; + //other configurations + while (iline < nvar) { + cout << iline << " " << names[iline] << endl; + strcpy(args[0], names[iline].c_str()); + outfile << names[iline] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl; + ++iline; + } + + delete cmd; + outfile.close(); +#ifdef VERBOSE + std::cout << "wrote " << iline << " lines to configuration file " << std::endl; +#endif + } else { + std::cout << "Error opening configuration file " << fname << " for writing" << std::endl; + setErrorMask(getErrorMask() | MULTI_CONFIG_FILE_ERROR); + ret = FAIL; + } + + for (int ia = 0; ia < 100; ++ia) { + delete[] args[ia]; + } + + return ret; +} + + + +string multiSlsDetector::getSettingsFile() { + return callDetectorMember(&slsDetector::getSettingsFile); +} + + +slsDetectorDefs::detectorSettings multiSlsDetector::getSettings(int pos) { + int ret = -100; + int posmin = 0, posmax = (int)detectors.size(); + if (pos >= 0) { + posmin = pos; + posmax = pos + 1; + } + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return GET_SETTINGS; + } else { + //return storage values + detectorSettings* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + iret[idet] = new detectorSettings(GET_SETTINGS); + Task* task = new Task(new func1_t(&slsDetector::getSettings, + detectors[idet], -1, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = GET_SETTINGS; + delete iret[idet]; + } else + ret = GET_SETTINGS; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + + thisMultiDetector->currentSettings = (detectorSettings)ret; + return (detectorSettings)ret; +} + + + +int multiSlsDetector::getThresholdEnergy(int pos) { + int i, posmin, posmax; + int ret1 = -100, ret; + + if (pos < 0) { + posmin = 0; + posmax = (int)detectors.size(); + } else { + posmin = pos; + posmax = pos + 1; + } + + for (i = posmin; i < posmax; ++i) { + ret = detectors[i]->getThresholdEnergy(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 == -100) + ret1 = ret; + else if (ret < (ret1 - 200) || ret > (ret1 + 200)) + ret1 = -1; + } + thisMultiDetector->currentThresholdEV = ret1; + return ret1; +} + + +int multiSlsDetector::setThresholdEnergy(int e_eV, int pos, detectorSettings isettings, int tb) { + int posmin, posmax; + int ret = -100; + if (pos < 0) { + posmin = 0; + posmax = (int)detectors.size(); + } else { + posmin = pos; + posmax = pos + 1; + } + + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return -1; - }else{ + } else { //return storage values - int* iret[thisMultiDetector->numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func1_t(&slsDetector::setOnline, - detectors[idet],off,iret[idet])); + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + iret[idet] = new int(-1); + Task* task = new Task(new func4_t(&slsDetector::setThresholdEnergy, + detectors[idet], e_eV, -1, isettings, tb, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (*iret[idet] < (ret - 200) || *iret[idet] > (ret + 200)) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + + thisMultiDetector->currentThresholdEV = ret; + return ret; +} + + +slsDetectorDefs::detectorSettings multiSlsDetector::setSettings(detectorSettings isettings, + int pos) { + int ret = -100; + int posmin = 0, posmax = (int)detectors.size(); + if (pos >= 0) { + posmin = pos; + posmax = pos + 1; + } + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return GET_SETTINGS; + } else { + //return storage values + detectorSettings* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (detectors[idet]) { + iret[idet] = new detectorSettings(GET_SETTINGS); + Task* task = new Task(new func2_t + (&slsDetector::setSettings, detectors[idet], isettings, -1, iret[idet])); threadpool->add_task(task); } } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; + for (int idet = posmin; idet < posmax; ++idet) { + if (detectors[idet]) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = GET_SETTINGS; delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } } - thisMultiDetector->onlineFlag=ret; - } - return thisMultiDetector->onlineFlag; -}; + thisMultiDetector->currentSettings = (detectorSettings)ret; + return (detectorSettings)ret; +} - -string multiSlsDetector::checkOnline() { - string retval1 = "",retval; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - retval=detectors[idet]->checkOnline(); - if(!retval.empty()){ - retval1.append(retval); - retval1.append("+"); - } - } - } - return retval1; -}; +string multiSlsDetector::getSettingsDir() { + return callDetectorMember(&slsDetector::getSettingsDir); +} +string multiSlsDetector::setSettingsDir(string s) { -int multiSlsDetector::activate(int const enable){ - int i; - int ret1=-100, ret; - - for (i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->activate(enable); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setSettingsDir(s); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } + } else { + size_t p1 = 0; + size_t p2 = s.find('+', p1); + int id = 0; + while (p2 != string::npos) { + detectors[id]->setSettingsDir(s.substr(p1, p2 - p1)); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + ++id; + s = s.substr(p2 + 1); + p2 = s.find('+'); + if (id >= (int)detectors.size()) + break; + } + } + return getSettingsDir(); +} + +string multiSlsDetector::getCalDir() { + return callDetectorMember(&slsDetector::getCalDir); +} + +string multiSlsDetector::setCalDir(string s) { + + if (s.find('+') == string::npos) { + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + detectors[idet]->setCalDir(s); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } else { + size_t p1 = 0; + size_t p2 = s.find('+', p1); + int id = 0; + while (p2 != string::npos) { + + if (detectors[id]) { + detectors[id]->setCalDir(s.substr(p1, p2 - p1)); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + } + ++id; + s = s.substr(p2 + 1); + p2 = s.find('+'); + if (id >= (int)detectors.size()) + break; + } + } + return getCalDir(); +} + + +int multiSlsDetector::loadSettingsFile(string fname, int imod) { + int ret = OK; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->loadSettingsFile(fname, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int* iret[detectors.size()]; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iret[idet] = new int(OK); + Task* task = new Task(new func2_t(&slsDetector::loadSettingsFile, + detectors[idet], fname, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + } else + ret = FAIL; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + + return ret; +} + +int multiSlsDetector::saveSettingsFile(string fname, int imod) { + int id = -1, im = -1, ret; + + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->saveSettingsFile(fname, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + + } + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + ret = detectors[idet]->saveSettingsFile(fname, imod); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + return ret; +} + + +int multiSlsDetector::loadCalibrationFile(string fname, int imod) { + int ret = OK; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->loadCalibrationFile(fname, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int* iret[detectors.size()]; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (detectors[idet]) { + iret[idet] = new int(OK); + Task* task = new Task(new func2_t(&slsDetector::loadCalibrationFile, + detectors[idet], fname, imod, iret[idet])); + threadpool->add_task(task); + } + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (detectors[idet]) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + } else + ret = FAIL; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + + return ret; +} + +int multiSlsDetector::saveCalibrationFile(string fname, int imod) { + int id = -1, im = -1, ret; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->saveCalibrationFile(fname, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + ret = detectors[idet]->saveCalibrationFile(fname, imod); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + return ret; +} + + + +int multiSlsDetector::setMaster(int i) { + int ret = -1, slave = 0; + masterFlags f; +#ifdef VERBOSE + cout << "settin master in position " << i << endl; +#endif + if (i >= 0 && i < (int)detectors.size()) { +#ifdef VERBOSE + cout << "detector position " << i << " "; +#endif + thisMultiDetector->masterPosition = i; + detectors[i]->setMaster(IS_MASTER); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (i != (int)idet) { +#ifdef VERBOSE + cout << "detector position " << idet << " "; +#endif + detectors[idet]->setMaster(IS_SLAVE); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + + } else if (i == -2) { + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { +#ifdef VERBOSE + cout << "detector position " << idet << " "; +#endif + detectors[idet]->setMaster(NO_MASTER); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + + // check return value + + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { +#ifdef VERBOSE + cout << "detector position " << idet << " "; +#endif + f = detectors[idet]->setMaster(GET_MASTER); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + + switch (f) { + case NO_MASTER: + if (ret != -1) + ret = -2; + break; + case IS_MASTER: + if (ret == -1) + ret = idet; + else + ret = -2; + break; + case IS_SLAVE: + slave = 1; + break; + default: + ret = -2; + } + + } + if (slave > 0 && ret < 0) + ret = -2; + + if (ret < 0) + ret = -1; + + thisMultiDetector->masterPosition = ret; + + return thisMultiDetector->masterPosition; +} + + +slsDetectorDefs::synchronizationMode multiSlsDetector::setSynchronization(synchronizationMode sync) { + synchronizationMode ret = GET_SYNCHRONIZATION_MODE, ret1 = GET_SYNCHRONIZATION_MODE; + + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + ret1 = detectors[idet]->setSynchronization(sync); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (idet == 0) + ret = ret1; + else if (ret != ret1) + ret = GET_SYNCHRONIZATION_MODE; + } + + thisMultiDetector->syncMode = ret; + + return thisMultiDetector->syncMode; +} + +slsDetectorDefs::runStatus multiSlsDetector::getRunStatus() { + runStatus s = IDLE, s1 = IDLE; + if (thisMultiDetector->masterPosition >= 0) { + s = detectors[thisMultiDetector->masterPosition]->getRunStatus(); + if (detectors[thisMultiDetector->masterPosition]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << thisMultiDetector->masterPosition)); + return s; + } + + for (unsigned int i = 0; i < detectors.size(); ++i) { + s1 = detectors[i]->getRunStatus(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (s1 == ERROR) { + return ERROR; + } + if (s1 != IDLE) + s = s1; + } + return s; +} + +int multiSlsDetector::prepareAcquisition() { + + int i = 0; + int ret = OK; + int posmin = 0, posmax = detectors.size(); + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return FAIL; + } else { + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + iret[idet] = new int(OK); + Task* task = new Task(new func0_t(&slsDetector::prepareAcquisition, + detectors[idet], iret[idet])); + threadpool->add_task(task); + } + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + } else + ret = FAIL; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + } + + //master + int ret1 = OK; + i = thisMultiDetector->masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret1 = detectors[i]->prepareAcquisition(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 != OK) + ret = FAIL; + } + + return ret; +} + +int multiSlsDetector::cleanupAcquisition() { + int i = 0; + int ret = OK, ret1 = OK; + int posmin = 0, posmax = detectors.size(); + + i = thisMultiDetector->masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret1 = detectors[i]->cleanupAcquisition(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 != OK) + ret = FAIL; + } + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return FAIL; + } else { + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + iret[idet] = new int(OK); + Task* task = new Task(new func0_t(&slsDetector::cleanupAcquisition, + detectors[idet], iret[idet])); + threadpool->add_task(task); + } + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + } else + ret = FAIL; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + } + return ret; +} + + +int multiSlsDetector::startAcquisition() { + if (getDetectorsType() == EIGER) { + if (prepareAcquisition() == FAIL) + return FAIL; + } + + int i = 0; + int ret = OK; + int posmin = 0, posmax = detectors.size(); + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return FAIL; + } else { + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + iret[idet] = new int(OK); + Task* task = new Task(new func0_t(&slsDetector::startAcquisition, + detectors[idet], iret[idet])); + threadpool->add_task(task); + } + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + } else + ret = FAIL; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + } + + //master + int ret1 = OK; + i = thisMultiDetector->masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret1 = detectors[i]->startAcquisition(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 != OK) + ret = FAIL; + } + return ret; +} + + +int multiSlsDetector::stopAcquisition() { + pthread_mutex_lock(&mg); // locks due to processing thread using threadpool when in use + int i = 0; + int ret = OK, ret1 = OK; + int posmin = 0, posmax = detectors.size(); + + i = thisMultiDetector->masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret1 = detectors[i]->stopAcquisition(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 != OK) + ret = FAIL; + } + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return FAIL; + } else { + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + iret[idet] = new int(OK); + Task* task = new Task(new func0_t(&slsDetector::stopAcquisition, + detectors[idet], iret[idet])); + threadpool->add_task(task); + } + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + } else + ret = FAIL; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + } + + *stoppedFlag = 1; + pthread_mutex_unlock(&mg); + return ret; +} + + +int multiSlsDetector::startReadOut() { + unsigned int i = 0; + int ret = OK, ret1 = OK; + i = thisMultiDetector->masterPosition; + if (i >= 0) { + ret = detectors[i]->startReadOut(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret != OK) + ret1 = FAIL; + } + for (i = 0; i < detectors.size(); ++i) { + ret = detectors[i]->startReadOut(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret != OK) + ret1 = FAIL; } return ret1; } +int* multiSlsDetector::startAndReadAll() { +#ifdef VERBOSE + cout << "Start and read all " << endl; +#endif + int* retval = NULL; + int i = 0; + if (thisMultiDetector->onlineFlag == ONLINE_FLAG) { -int multiSlsDetector::exists() { - return thisMultiDetector->alreadyExisting; + if (getDetectorsType() == EIGER) { + if (prepareAcquisition() == FAIL) + return NULL; + } + startAndReadAllNoWait(); + + while ((retval = getDataFromDetector())) { + ++i; +#ifdef VERBOSE + std::cout << i << std::endl; +#endif + dataQueue.push(retval); + } + + for (unsigned int id = 0; id < detectors.size(); ++id) { + if (detectors[id]) { + detectors[id]->disconnectControl(); + } + } + } +#ifdef VERBOSE + std::cout << "Recieved " << i << " frames" << std::endl; +#endif + return dataQueueFront(); } - - -// Initialization functions - - - - - -int multiSlsDetector::getThresholdEnergy(int pos) { - - - int i, posmin, posmax; - int ret1=-100, ret; - - if (pos<0) { - posmin=0; - posmax=thisMultiDetector->numberOfDetectors; - } else { - posmin=pos; - posmax=pos+1; - } - - for (i=posmin; igetThresholdEnergy(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<(ret1+200)) - ret1=-1; - - } - - } - thisMultiDetector->currentThresholdEV=ret1; - return ret1; - - -} - - -int multiSlsDetector::setThresholdEnergy(int e_eV, int pos, detectorSettings isettings, int tb) { - - int posmin, posmax; - int ret=-100; - if (pos<0) { - posmin=0; - posmax=thisMultiDetector->numberOfDetectors; - } else { - posmin=pos; - posmax=pos+1; - } - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return -1; - }else{ - //return storage values - int* iret[posmax-posmin]; - for(int idet=posmin; idet(&slsDetector::setThresholdEnergy, - detectors[idet],e_eV,-1,isettings,tb,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idet(ret+200)) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<currentThresholdEV=ret; - return ret; -} - - - - -slsDetectorDefs::detectorSettings multiSlsDetector::getSettings(int pos) { - - int posmin, posmax; - int ret=-100; - - if (pos<0) { - posmin=0; - posmax=thisMultiDetector->numberOfDetectors; - } else { - posmin=pos; - posmax=pos+1; - } - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return GET_SETTINGS; - }else{ - //return storage values - detectorSettings* iret[posmax-posmin]; - for(int idet=posmin; idet(&slsDetector::getSettings, - detectors[idet],-1,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<currentSettings=(detectorSettings)ret; - return (detectorSettings)ret; -} - -slsDetectorDefs::detectorSettings multiSlsDetector::setSettings(detectorSettings isettings, int pos) { - - int posmin, posmax; - int ret=-100; - - if (pos<0) { - posmin=0; - posmax=thisMultiDetector->numberOfDetectors; - } else { - posmin=pos; - posmax=pos+1; - } - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return GET_SETTINGS; - }else{ - //return storage values - detectorSettings* iret[posmax-posmin]; - for(int idet=posmin; idet(&slsDetector::setSettings, - detectors[idet],isettings,-1,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<currentSettings=(detectorSettings)ret; - return (detectorSettings)ret; - -} - - - -int multiSlsDetector::getChanRegs(double* retval,bool fromDetector){ - //nChansDet and currentNumChans is because of varying channel size per detector - int n = thisMultiDetector->numberOfChannels,nChansDet,currentNumChans=0; - double retval1[n]; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - // cout << "det " << idet << endl; - nChansDet = detectors[idet]->getChanRegs(retval1,fromDetector); - // cout << "returned" << endl; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return FAIL; - }else{ - int* iret[posmax-posmin]; - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - iret[idet]= new int(OK); - Task* task = new Task(new func0_t(&slsDetector::prepareAcquisition, - detectors[idet],iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) - ret = FAIL; - delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret1=detectors[i]->prepareAcquisition(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - - i=thisMultiDetector->masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret1=detectors[i]->cleanupAcquisition(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition) && (detectors[idet])){ - iret[idet]= new int(OK); - Task* task = new Task(new func0_t(&slsDetector::cleanupAcquisition, - detectors[idet],iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) - ret = FAIL; - delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return FAIL; - }else{ - int* iret[posmax-posmin]; - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - iret[idet]= new int(OK); - Task* task = new Task(new func0_t(&slsDetector::startAcquisition, - detectors[idet],iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) - ret = FAIL; - delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret1=detectors[i]->startAcquisition(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; + int i = 0; + int ret = OK; + int posmin = 0, posmax = detectors.size(); - i=thisMultiDetector->masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret1=detectors[i]->stopAcquisition(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition) && (detectors[idet])){ - iret[idet]= new int(OK); - Task* task = new Task(new func0_t(&slsDetector::stopAcquisition, - detectors[idet],iret[idet])); + } else { + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition){ + iret[idet] = new int(OK); + Task* task = new Task(new func0_t(&slsDetector::startAndReadAllNoWait, + detectors[idet], iret[idet])); threadpool->add_task(task); } } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) ret = FAIL; delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } } - *stoppedFlag=1; + //master + int ret1 = OK; + i = thisMultiDetector->masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret1 = detectors[i]->startAndReadAllNoWait(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 != OK) + ret = FAIL; + } pthread_mutex_unlock(&mg); return ret; -}; - - - - -int multiSlsDetector::startReadOut(){ - - int i=0; - int ret=OK, ret1=OK; - i=thisMultiDetector->masterPosition; - if (i>=0) { - if (detectors[i]) { - ret=detectors[i]->startReadOut(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->startReadOut(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<dataBytes/sizeof(int); - int n = 0; - int* retval= NULL; - int *retdet, *p=retval; - int nodatadet=-1; + int nel = thisMultiDetector->dataBytes / sizeof(int); + int n = 0; + int* retval = NULL; + int *retdet, *p = retval; + int nodatadet = -1; int nodatadetectortype = false; - detectorType types = getDetectorsType(); - if(types == EIGER || types == JUNGFRAU){ + detectorType types = getDetectorsType(); + if (types == EIGER || types == JUNGFRAU) { nodatadetectortype = true; } - if(!nodatadetectortype) - retval=new int[nel]; - p=retval; - // cout << "multi: " << thisMultiDetector->dataBytes << endl; + if (!nodatadetectortype) + retval = new int[nel]; + p = retval; - for (int id=0; idnumberOfDetectors; ++id) { - if (detectors[id]) { - retdet=detectors[id]->getDataFromDetector(p); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getDataBytes(); - if (retdet) {; + for (unsigned int id = 0; id < detectors.size(); ++id) { + retdet = detectors[id]->getDataFromDetector(p); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + if (!nodatadetectortype) { + n = detectors[id]->getDataBytes(); + if (retdet) { + ; #ifdef VERBOSE - cout << "Detector " << id << " returned " << n << " bytes " << endl; + cout << "Detector " << id << " returned " << n << " bytes " << endl; #endif - } else { - nodatadet=id; + } else { + nodatadet = id; #ifdef VERBOSE - cout << "Detector " << id << " does not have data left " << endl; + cout << "Detector " << id << " does not have data left " << endl; #endif - } - p+=n/sizeof(int); } + p += n / sizeof(int); } } //eiger returns only null - if(nodatadetectortype){ + if (nodatadetectortype) { return NULL; } - if (nodatadet>=0) { - for (int id=0; idnumberOfDetectors; ++id) { - if (id!=nodatadet) { + if (nodatadet >= 0) { + for (unsigned int id = 0; id < detectors.size(); ++id) { + if ((int)id != nodatadet) { if (detectors[id]) { -//#ifdef VERBOSE - cout << "Stopping detector "<< id << endl; -//#endif + //#ifdef VERBOSE + cout << "Stopping detector " << id << endl; + //#endif detectors[id]->stopAcquisition(); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getDataFromDetector())) { - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + while ((retdet = detectors[id]->getDataFromDetector())) { + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); #ifdef VERBOSE - cout << "Detector "<< id << " still sent data " << endl; + cout << "Detector " << id << " still sent data " << endl; #endif - delete [] retdet; + delete[] retdet; } - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); } } } - delete [] retval; + delete[] retval; return NULL; } return retval; -}; - - - -int* multiSlsDetector::readFrame(){ - int nel=thisMultiDetector->dataBytes/sizeof(int); - int n; - int* retval=new int[nel]; - int *retdet, *p=retval; - - /** probably it's always better to have one integer per channel in any case! */ - - for (int id=0; idnumberOfDetectors; ++id) { - if (detectors[id]) { - retdet=detectors[id]->readFrame(); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getDataBytes(); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<onlineFlag==ONLINE_FLAG) { - - for (int id=0; idnumberOfDetectors; ++id) { - if (detectors[id]) { - detectors[id]->readAllNoWait(); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++id) { - if (detectors[id]) { - detectors[id]->disconnectControl(); - } - } - - } - -#ifdef VERBOSE - std::cout<< "received "<< i<< " frames" << std::endl; - //#else - // std::cout << std::endl; -#endif - return dataQueueFront(); // check what we return! - -}; - -int* multiSlsDetector::startAndReadAll(){ - - /** Thread for each detector?!?!?! */ -#ifdef VERBOSE - cout << "Start and read all " << endl; -#endif - - - int* retval; - int i=0; - if (thisMultiDetector->onlineFlag==ONLINE_FLAG) { - - if (getDetectorsType() == EIGER) { - if (prepareAcquisition() == FAIL) - return NULL; - } - startAndReadAllNoWait(); - - while ((retval=getDataFromDetector())){ - ++i; -#ifdef VERBOSE - std::cout<< i << std::endl; - //#else - //std::cout << "-" << flush; -#endif - dataQueue.push(retval); - } - - for (int id=0; idnumberOfDetectors; ++id) { - if (detectors[id]) { - detectors[id]->disconnectControl(); - } - } - - } - -#ifdef VERBOSE - std::cout<< "MMMM recieved "<< i<< " frames" << std::endl; - //#else - // std::cout << std::endl; -#endif - return dataQueueFront(); // check what we return! - - -}; - - -int multiSlsDetector::startAndReadAllNoWait(){ - pthread_mutex_lock(&mg); // locks due to processing thread using threadpool when in use - int i=0; - int ret=OK; - int posmin=0, posmax=thisMultiDetector->numberOfDetectors; - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return FAIL; - }else{ - int* iret[posmax-posmin]; - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - iret[idet]= new int(OK); - Task* task = new Task(new func0_t(&slsDetector::startAndReadAllNoWait, - detectors[idet],iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) - ret = FAIL; - delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret1=detectors[i]->startAndReadAllNoWait(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<dataBytes / sizeof(int); + int n; + int* retval = new int[nel]; + int *retdet, *p = retval; - runStatus s = IDLE,s1 = IDLE; - if (thisMultiDetector->masterPosition>=0) - if (detectors[thisMultiDetector->masterPosition]){ - s = detectors[thisMultiDetector->masterPosition]->getRunStatus(); - if(detectors[thisMultiDetector->masterPosition]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition)); - return s; - } + for (unsigned int id = 0; id < detectors.size(); ++id) { + if (detectors[id]) { + retdet = detectors[id]->readFrame(); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + if (retdet) { + n = detectors[id]->getDataBytes(); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + memcpy(p, retdet, n); + delete[] retdet; + p += n / sizeof(int); + } else { +#ifdef VERBOSE + cout << "Detector " << id << " does not have data left " << endl; +#endif + delete[] retval; + return NULL; + } + } + } + dataQueue.push(retval); + return retval; +} - for (int i=0; inumberOfDetectors; ++i) { - s1=detectors[i]->getRunStatus(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<onlineFlag == ONLINE_FLAG) { + + for (unsigned int id = 0; id < detectors.size(); ++id) { + detectors[id]->readAllNoWait(); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + } + while ((retval = getDataFromDetector())) { + ++i; +#ifdef VERBOSE + std::cout << i << std::endl; +#endif + dataQueue.push(retval); + } + for (unsigned int id = 0; id < detectors.size(); ++id) { + detectors[id]->disconnectControl(); + } + } + +#ifdef VERBOSE + std::cout << "received " << i << " frames" << std::endl; +#endif + return dataQueueFront(); } int* multiSlsDetector::popDataQueue() { - int *retval=NULL; - if( !dataQueue.empty() ) { - retval=dataQueue.front(); - dataQueue.pop(); - } - return retval; + int* retval = NULL; + if (!dataQueue.empty()) { + retval = dataQueue.front(); + dataQueue.pop(); + } + return retval; } detectorData* multiSlsDetector::popFinalDataQueue() { - detectorData *retval=NULL; - if( !finalDataQueue.empty() ) { - retval=finalDataQueue.front(); - finalDataQueue.pop(); - } - return retval; + detectorData* retval = NULL; + if (!finalDataQueue.empty()) { + retval = finalDataQueue.front(); + finalDataQueue.pop(); + } + return retval; } void multiSlsDetector::resetDataQueue() { - int *retval=NULL; - while( !dataQueue.empty() ) { - retval=dataQueue.front(); - dataQueue.pop(); - delete [] retval; - } + int* retval = NULL; + while (!dataQueue.empty()) { + retval = dataQueue.front(); + dataQueue.pop(); + delete[] retval; + } } void multiSlsDetector::resetFinalDataQueue() { - detectorData *retval=NULL; - while( !finalDataQueue.empty() ) { - retval=finalDataQueue.front(); - finalDataQueue.pop(); - delete retval; - } - + detectorData* retval = NULL; + while (!finalDataQueue.empty()) { + retval = finalDataQueue.front(); + finalDataQueue.pop(); + delete retval; + } } +int multiSlsDetector::configureMAC() { + return callDetectorMember(&slsDetector::configureMAC); +} - -/* - set or read the acquisition timers - enum timerIndex { - FRAME_NUMBER, - ACQUISITION_TIME, - FRAME_PERIOD, - DELAY_AFTER_TRIGGER, - GATES_NUMBER, - PROBES_NUMBER - CYCLES_NUMBER, - GATE_INTEGRATED_TIME - } - */ -int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t){ - +int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t, int imod) { int64_t ret=-100; + // single (for gotthard 25 um) + if (imod != -1) { + if (imod >= 0 && imod < (int)detectors.size()) { + ret = detectors[imod]->setTimer(index,t,imod); + if(detectors[imod]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet){ if(detectors[idet]){ iret[idet]= new int64_t(-1); - Task* task = new Task(new func2_t(&slsDetector::setTimer, - detectors[idet],index,t,iret[idet])); + Task* task = new Task(new func3_t(&slsDetector::setTimer, + detectors[idet],index,t,imod,iret[idet])); threadpool->add_task(task); } } @@ -2042,316 +2612,304 @@ int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t){ } } } - - if (index==SAMPLES_JCTB) + if (index == SAMPLES_JCTB) setDynamicRange(); - thisMultiDetector->timerValue[index]=ret; + thisMultiDetector->timerValue[index] = ret; + return ret; +} + +int64_t multiSlsDetector::getTimeLeft(timerIndex index) { + int64_t ret = -100; + if (thisMultiDetector->masterPosition >= 0) + if (detectors[thisMultiDetector->masterPosition]) { + ret = detectors[thisMultiDetector->masterPosition]->getTimeLeft(index); + if (detectors[thisMultiDetector->masterPosition]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << thisMultiDetector->masterPosition)); + return ret; + } + return callDetectorMember(&slsDetector::getTimeLeft, index); +} + +int multiSlsDetector::setSpeed(speedVariable index, int value) { + int ret1 = -100, ret; + + for (unsigned i = 0; i < detectors.size(); ++i) { + ret = detectors[i]->setSpeed(index, value); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 == -100) + ret1 = ret; + else if (ret != ret1) + ret1 = FAIL; + } + + return ret1; +} + +int multiSlsDetector::setDynamicRange(int p) { + int ret = -100; + thisMultiDetector->dataBytes = 0; + thisMultiDetector->dataBytesInclGapPixels = 0; + thisMultiDetector->numberOfChannels = 0; + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } else { + //return storage values + int* iret[detectors.size()]; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iret[idet] = new int(-1); + Task* task = new Task(new func1_t(&slsDetector::setDynamicRange, + detectors[idet], p, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (iret[idet] != NULL) { + thisMultiDetector->dataBytes += detectors[idet]->getDataBytes(); + thisMultiDetector->dataBytesInclGapPixels += + detectors[idet]->getDataBytesInclGapPixels(); + thisMultiDetector->numberOfChannels += + detectors[idet]->getTotalNumberOfChannels(); + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + + //for usability for the user + if (getDetectorsType() == EIGER) { + if (p == 32) { + std::cout << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32" << std::endl; + setSpeed(CLOCK_DIVIDER, 2); + } else if (p == 16) { + std::cout << "Setting Clock to Half Speed for Dynamic Range of 16" << std::endl; + setSpeed(CLOCK_DIVIDER, 1); + } + if (p != -1) + updateOffsets(); + } + return ret; +} + +int multiSlsDetector::getDataBytes() { + int n_bytes = 0; + for (unsigned int ip = 0; ip < detectors.size(); ++ip) { + n_bytes += detectors[ip]->getDataBytes(); + } + return n_bytes; +} + + +dacs_t multiSlsDetector::setDAC(dacs_t val, dacIndex idac, int mV, int imod) { + dacs_t ret = -100; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 && id >= (int)detectors.size()) + return -1; + ret = detectors[id]->setDAC(val, idac, mV, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int posmin = 0, posmax = detectors.size(); + dacs_t* iret[posmax - posmin]; + + for (int idet = posmin; idet < posmax; ++idet) { + iret[idet] = new dacs_t(-1); + Task* task = new Task(new func4_t + (&slsDetector::setDAC, detectors[idet], val, idac, mV, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (iret[idet] != NULL) { + + // highvoltage of slave, ignore value + if ((idac == HV_NEW) && (*iret[idet] == -999)) + ; + else { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + } + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + if (ret == -100) + ret = -1; + + return ret; +} + +dacs_t multiSlsDetector::getADC(dacIndex idac, int imod) { + dacs_t ret = -100; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 && id >= (int)detectors.size()) + return -1; + ret = detectors[id]->getADC(idac, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int posmin = 0, posmax = detectors.size(); + dacs_t* iret[posmax - posmin]; + + for (int idet = posmin; idet < posmax; ++idet) { + iret[idet] = new dacs_t(-1); + Task* task = new Task(new func2_t(&slsDetector::getADC, + detectors[idet], idac, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (detectors[idet]) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + return ret; } +slsDetectorDefs::externalCommunicationMode multiSlsDetector::setExternalCommunicationMode( + externalCommunicationMode pol) { + externalCommunicationMode ret, ret1; + //(Dhanya) FIXME: why first detector or is it the master one? + if (detectors.size()) + ret = detectors[0]->setExternalCommunicationMode(pol); + if (detectors[0]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << 0)); - -int64_t multiSlsDetector::getTimeLeft(timerIndex index){ - int i; - int64_t ret1=-100, ret; - - - if (thisMultiDetector->masterPosition>=0) - if (detectors[thisMultiDetector->masterPosition]){ - ret1 = detectors[thisMultiDetector->masterPosition]->getTimeLeft(index); - if(detectors[thisMultiDetector->masterPosition]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition)); - return ret1; - } - - for (i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->getTimeLeft(index); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->setSpeed(index,value); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++ip) { - if (detectors[ip]) - ret+=detectors[ip]->getDataBytes(); - } - return ret; -} - - - - - - -// Flags -int multiSlsDetector::setDynamicRange(int n, int pos){ - - // cout << "multi " << endl; - int imi, ima, i; - int ret, ret1=-100; - - if (pos<0) { - imi=0; - ima=thisMultiDetector->numberOfDetectors; - } else { - imi=pos; - ima=pos+1; - } - - for (i=imi; idataBytes-=detectors[i]->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels-=detectors[i]->getDataBytesInclGapPixels(); - ret=detectors[i]->setDynamicRange(n); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<dataBytes+=detectors[i]->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels+=detectors[i]->getDataBytesInclGapPixels(); - } - } - - //for usability for the user - if (getDetectorsType() == EIGER){ - if(n == 32){ - std::cout << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32" << std::endl; - setSpeed(CLOCK_DIVIDER,2); - } - else if(n == 16){ - std::cout << "Setting Clock to Half Speed for Dynamic Range of 16" << std::endl; - setSpeed(CLOCK_DIVIDER,1); - } - if (n != -1) - updateOffsets(); - } - - return thisMultiDetector->dataBytes; -}; - - - - -void multiSlsDetector::verifyMinMaxROI(int n, ROI r[]){ - int temp; - for(int i=0;isetExternalCommunicationMode(pol); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret != ret1) + ret = GET_EXTERNAL_COMMUNICATION_MODE; } + setMaster(); + setSynchronization(); + return ret; } +slsDetectorDefs::externalSignalFlag multiSlsDetector::setExternalSignalFlags( + externalSignalFlag pol, int signalindex) { + externalSignalFlag ret, ret1; + //(Dhanya) FIXME: why first detector or is it the master one? + if (detectors.size()) + ret = detectors[0]->setExternalSignalFlags(pol, signalindex); + if (detectors[0]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << 0)); - -int multiSlsDetector::decodeNChannel(int offsetX, int offsetY, int &channelX, int &channelY){ - channelX=-1; - channelY=-1; - //loop over - for(int i=0;inumberOfDetectors;++i){ - if (detectors[i]) { - //check x offset range - if ((offsetX >= thisMultiDetector->offsetX[i]) && (offsetX < (thisMultiDetector->offsetX[i]+detectors[i]->getMaxNumberOfChannelsInclGapPixels(X)))){ - if(offsetY==-1){ - channelX = offsetX - thisMultiDetector->offsetX[i]; - return i; - }else{ - //check y offset range - if((offsetY >= thisMultiDetector->offsetY[i]) && (offsetY< (thisMultiDetector->offsetY[i]+detectors[i]->getMaxNumberOfChannelsInclGapPixels(Y)))){ - channelX = offsetX - thisMultiDetector->offsetX[i]; - channelY = offsetY - thisMultiDetector->offsetY[i]; - return i; - } - } - } - } + for (unsigned int idet = 1; idet < detectors.size(); ++idet) { + ret1 = detectors[idet]->setExternalSignalFlags(pol, signalindex); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret != ret1) + ret = GET_EXTERNAL_SIGNAL_FLAG; } - return -1; + setMaster(); + setSynchronization(); + return ret; +} + +int multiSlsDetector::setReadOutFlags(readOutFlags flag) { + int ret = -100, ret1; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + ret1 = detectors[idet]->setReadOutFlags(flag); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret == -100) + ret = ret1; + else if (ret != ret1) + ret = -1; + } + + return ret; } -int multiSlsDetector::setROI(int n,ROI roiLimits[]){ - int ret1=-100,ret; - int i,xmin,xmax,ymin,ymax,channelX,channelY,idet,lastChannelX,lastChannelY,index,offsetX,offsetY; - bool invalidroi=false; - int ndet = thisMultiDetector->numberOfDetectors; - ROI allroi[ndet][n]; - int nroi[ndet]; - for(i=0;igetMaxNumberOfChannelsInclGapPixels(X))-1; - lastChannelY = (detectors[idet]->getMaxNumberOfChannelsInclGapPixels(Y))-1; - - offsetX = thisMultiDetector->offsetX[idet]; - offsetY = thisMultiDetector->offsetY[idet]; - //at the end in x dir - if ((offsetX + lastChannelX) >= xmax) - lastChannelX = xmax - offsetX; - //at the end in y dir - if ((offsetY + lastChannelY) >= ymax) - lastChannelY = ymax - offsetY; - -#ifdef VERBOSE - cout<<"lastChannelX:"<writeRegister(addr, val); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (i == 0) + ret1 = ret; + else if (ret != ret1) { + // not setting it to -1 as it is a possible value + std::cout << "Error: Different Values for function writeRegister [" + << ret << "," << ret1 << "]" << endl; + setErrorMask(getErrorMask() | MULTI_HAVE_DIFFERENT_VALUES); } } -#ifdef VERBOSE - cout<<"Setting ROI :"<numberOfDetectors;++i){ - cout<<"detector "<numberOfDetectors; ++i) { - if (detectors[i]){ -#ifdef VERBOSE - cout << "detector " << i << ":" << endl; -#endif - ret = detectors[i]->setROI(nroi[i],allroi[i]); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<readRegister(addr); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (i == 0) + ret1 = ret; + else if (ret != ret1) { + // not setting it to -1 as it is a possible value + std::cout << "Error: Different Values for function readRegister [" + << ret << "," << ret1 << "]" << endl; + setErrorMask(getErrorMask() | MULTI_HAVE_DIFFERENT_VALUES); } } @@ -2360,74 +2918,473 @@ int multiSlsDetector::setROI(int n,ROI roiLimits[]){ -slsDetectorDefs::ROI* multiSlsDetector::getROI(int &n){ - n = 0; - int num = 0,i,j; - int ndet = thisMultiDetector->numberOfDetectors; - int maxroi = ndet*MAX_ROIS; +uint32_t multiSlsDetector::setBit(uint32_t addr, int n) { + uint32_t ret, ret1; + for (unsigned int i = 0; i < detectors.size(); ++i) { + ret1 = detectors[i]->setBit(addr, n); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (i == 0) + ret = ret1; + else if (ret != ret1) { + // not setting it to -1 as it is a possible value + std::cout << "Error: Different Values for function setBit [" + << ret << "," << ret1 << "]" << endl; + setErrorMask(getErrorMask() | MULTI_HAVE_DIFFERENT_VALUES); + } + } + + return ret; +} + +uint32_t multiSlsDetector::clearBit(uint32_t addr, int n) { + uint32_t ret, ret1; + for (unsigned int i = 0; i < detectors.size(); ++i) { + ret1 = detectors[i]->clearBit(addr, n); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (i == 0) + ret = ret1; + else if (ret != ret1) { + // not setting it to -1 as it is a possible value + std::cout << "Error: Different Values for function clearBit [" + << ret << "," << ret1 << "]" << endl; + setErrorMask(getErrorMask() | MULTI_HAVE_DIFFERENT_VALUES); + } + } + + return ret; +} + +string multiSlsDetector::setNetworkParameter(networkParameter p, string s) { + + if (s.find('+') == string::npos) { + + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return getNetworkParameter(p); + } else { + string* sret[detectors.size()]; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (p == RECEIVER_STREAMING_PORT || p == CLIENT_STREAMING_PORT) + s.append("multi\0"); + sret[idet] = new string("error"); + Task* task = new Task(new func2_t(&slsDetector::setNetworkParameter, + detectors[idet], p, s, sret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (sret[idet] != NULL) + delete sret[idet]; + //doing nothing with the return values + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + } + + } else { + size_t p1 = 0; + size_t p2 = s.find('+', p1); + int id = 0; + while (p2 != string::npos) { + detectors[id]->setNetworkParameter(p, s.substr(p1, p2 - p1)); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + ++id; + s = s.substr(p2 + 1); + p2 = s.find('+'); + if (id >= (int)detectors.size()) + break; + } + } + + return getNetworkParameter(p); +} + +string multiSlsDetector::getNetworkParameter(networkParameter p) { + string s0 = "", s1 = "", s; + string ans = ""; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + s = detectors[idet]->getNetworkParameter(p); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + + if (s0 == "") + s0 = s + string("+"); + else + s0 += s + string("+"); + + if (s1 == "") + s1 = s; + else if (s1 != s) + s1 = "bad"; + } + if (s1 == "bad") + ans = s0; + else + ans = s1; + return ans; +} + +int multiSlsDetector::digitalTest(digitalTestMode mode, int imod) { + + int id, im, ret; + + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->digitalTest(mode, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + + return -1; +} + +int multiSlsDetector::executeTrimming(trimMode mode, int par1, int par2, int imod) { + int ret = 100; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->executeTrimming(mode, par1, par2, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int* iret[detectors.size()]; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iret[idet] = new int(-1); + Task* task = new Task(new func4_t(&slsDetector::executeTrimming, + detectors[idet], mode, par1, par2, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + + return ret; +} + + +int multiSlsDetector::loadImageToDetector(imageType index, string const fname) { + + int ret = -100, ret1; + short int imageVals[thisMultiDetector->numberOfChannels]; + + ifstream infile; + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { +#ifdef VERBOSE + std::cout << std::endl + << "Loading "; + if (!index) + std::cout << "Dark"; + else + std::cout << "Gain"; + std::cout << " image from file " << fname << std::endl; +#endif + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (detectors[idet]->readDataFile(infile, imageVals) >= 0) { + ret1 = detectors[idet]->sendImageToDetector(index, imageVals); + if (ret == -100) + ret = ret1; + else if (ret != ret1) + ret = -1; + } + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + infile.close(); + } else { + std::cout << "Could not open file " << fname << std::endl; + return -1; + } + return ret; +} + +int multiSlsDetector::writeCounterBlockFile(string const fname, int startACQ) { + int ret = OK, ret1 = OK; + short int arg[thisMultiDetector->numberOfChannels]; + ofstream outfile; + outfile.open(fname.c_str(), ios_base::out); + if (outfile.is_open()) { +#ifdef VERBOSE + std::cout << std::endl + << "Reading Counter to \"" << fname; + if (startACQ == 1) + std::cout << "\" and Restarting Acquisition"; + std::cout << std::endl; +#endif + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + ret1 = detectors[idet]->getCounterBlock(arg, startACQ); + if (ret1 != OK) + ret = FAIL; + else { + ret1 = detectors[idet]->writeDataFile(outfile, arg); + if (ret1 != OK) + ret = FAIL; + } + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + outfile.close(); + } else { + std::cout << "Could not open file " << fname << std::endl; + return -1; + } + return ret; +} + +int multiSlsDetector::resetCounterBlock(int startACQ) { + return callDetectorMember(&slsDetector::resetCounterBlock, startACQ); +} + +int multiSlsDetector::setCounterBit(int i) { + return callDetectorMember(&slsDetector::setCounterBit, i); +} + +void multiSlsDetector::verifyMinMaxROI(int n, ROI r[]) { + int temp; + for (int i = 0; i < n; ++i) { + if ((r[i].xmax) < (r[i].xmin)) { + temp = r[i].xmax; + r[i].xmax = r[i].xmin; + r[i].xmin = temp; + } + if ((r[i].ymax) < (r[i].ymin)) { + temp = r[i].ymax; + r[i].ymax = r[i].ymin; + r[i].ymin = temp; + } + } +} + +int multiSlsDetector::setROI(int n, ROI roiLimits[]) { + int ret1 = -100, ret; + int i, xmin, xmax, ymin, ymax, channelX, channelY, idet, lastChannelX, + lastChannelY, index, offsetX, offsetY; + bool invalidroi = false; + int ndet = detectors.size(); + ROI allroi[ndet][n]; + int nroi[ndet]; + for (i = 0; i < ndet; ++i) + nroi[i] = 0; + + if ((n < 0) || (roiLimits == NULL)) + return FAIL; + + //ensures min < max + verifyMinMaxROI(n, roiLimits); +#ifdef VERBOSE + cout << "Setting ROI for " << n << "rois:" << endl; + for (i = 0; i < n; ++i) + cout << i << ":" << roiLimits[i].xmin << "\t" << roiLimits[i].xmax + << "\t" << roiLimits[i].ymin << "\t" << roiLimits[i].ymax << endl; +#endif + //for each roi + for (i = 0; i < n; ++i) { + xmin = roiLimits[i].xmin; + xmax = roiLimits[i].xmax; + ymin = roiLimits[i].ymin; + ymax = roiLimits[i].ymax; + + //check roi max values + idet = decodeNChannel(xmax, ymax, channelX, channelY); +#ifdef VERBOSE + cout << "Decoded Channel max vals: " << endl; + cout << "det:" << idet << "\t" << xmax << "\t" << ymax << "\t" + << channelX << "\t" << channelY << endl; +#endif + if (idet == -1) { + cout << "invalid roi" << endl; + continue; + } + + //split in x dir + while (xmin <= xmax) { + invalidroi = false; + ymin = roiLimits[i].ymin; + //split in y dir + while (ymin <= ymax) { + //get offset for each detector + idet = decodeNChannel(xmin, ymin, channelX, channelY); +#ifdef VERBOSE + cout << "Decoded Channel min vals: " << endl; + cout << "det:" << idet << "\t" << xmin << "\t" << ymin + << "\t" << channelX << "\t" << channelY << endl; +#endif + if (idet < 0 || idet >= (int)detectors.size()) { + cout << "invalid roi" << endl; + invalidroi = true; + break; + } + //get last channel for each det in x and y dir + lastChannelX = (detectors[idet]->getMaxNumberOfChannelsInclGapPixels(X)) - 1; + lastChannelY = (detectors[idet]->getMaxNumberOfChannelsInclGapPixels(Y)) - 1; + + offsetX = detectors[idet]->getDetectorOffset(X); + offsetY = detectors[idet]->getDetectorOffset(Y); + //at the end in x dir + if ((offsetX + lastChannelX) >= xmax) + lastChannelX = xmax - offsetX; + //at the end in y dir + if ((offsetY + lastChannelY) >= ymax) + lastChannelY = ymax - offsetY; + +#ifdef VERBOSE + cout << "lastChannelX:" << lastChannelX << "\t" + << "lastChannelY:" << lastChannelY << endl; +#endif + + //creating the list of roi for corresponding detector + index = nroi[idet]; + allroi[idet][index].xmin = channelX; + allroi[idet][index].xmax = lastChannelX; + allroi[idet][index].ymin = channelY; + allroi[idet][index].ymax = lastChannelY; + nroi[idet] = nroi[idet] + 1; + + ymin = lastChannelY + offsetY + 1; + if ((lastChannelY + offsetY) == ymax) + ymin = ymax + 1; + +#ifdef VERBOSE + cout << "nroi[idet]:" << nroi[idet] << "\tymin:" << ymin << endl; +#endif + + } + if (invalidroi) + break; + + xmin = lastChannelX + offsetX + 1; + if ((lastChannelX + offsetX) == xmax) + xmin = xmax + 1; + } + } + +#ifdef VERBOSE + cout << "Setting ROI :" << endl; + for (i = 0; i < detectors.size(); ++i) { + cout << "detector " << i << endl; + for (int j = 0; j < nroi[i]; ++j) { + cout << allroi[i][j].xmin << "\t" << allroi[i][j].xmax << "\t" + << allroi[i][j].ymin << "\t" << allroi[i][j].ymax << endl; + } + } +#endif + + //settings the rois for each detector + for (unsigned i = 0; i < detectors.size(); ++i) { +#ifdef VERBOSE + cout << "detector " << i << ":" << endl; +#endif + ret = detectors[i]->setROI(nroi[i], allroi[i]); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 == -100) + ret1 = ret; + else + ret1 = FAIL; + } + + return ret1; +} + + +slsDetectorDefs::ROI* multiSlsDetector::getROI(int& n) { + + n = 0; + int num = 0, i, j; + int ndet = detectors.size(); + int maxroi = ndet * MAX_ROIS; ROI temproi; ROI roiLimits[maxroi]; ROI* retval = new ROI[maxroi]; - ROI* temp=0; - int index=0; + ROI* temp = 0; + int index = 0; //get each detector's roi array - for (i=0; inumberOfDetectors; ++i){ - if (detectors[i]){ - temp = detectors[i]->getROI(index); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getROI(index); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); - if(temp){ -//#ifdef VERBOSE - if(index) - cout << "detector " << i << ":" << endl; -//#endif - for(j=0;joffsetX[i]; - roiLimits[n].xmax = temp[j].xmax + thisMultiDetector->offsetX[i]; - roiLimits[n].ymin = temp[j].ymin + thisMultiDetector->offsetY[i]; - roiLimits[n].ymax = temp[j].ymin + thisMultiDetector->offsetY[i]; - ++n; - } + if (temp) { + //#ifdef VERBOSE + if (index) + cout << "detector " << i << ":" << endl; + //#endif + for (j = 0; j < index; ++j) { + //#ifdef VERBOSE + cout << temp[j].xmin << "\t" << temp[j].xmax << "\t" + << temp[j].ymin << "\t" << temp[j].ymax << endl; + //#endif + int x = detectors[i]->getDetectorOffset(X); + int y = detectors[i]->getDetectorOffset(Y); + roiLimits[n].xmin = temp[j].xmin + x; + roiLimits[n].xmax = temp[j].xmax + x; + roiLimits[n].ymin = temp[j].ymin + y; + roiLimits[n].ymax = temp[j].ymin + y; + ++n; } } } - - //empty roi - if (!n) return NULL; - - + if (!n) + return NULL; #ifdef VERBOSE - cout<<"ROI :"<getDetectorsType()==JUNGFRAUCTB) { - nn=thisMultiDetector->dataBytes/2; - dataout=new double[nn]; - } else { - nn=thisMultiDetector->numberOfChannels; - dataout=new double[nn]; - } - } - - // int ich=0; - int n; - double *detp=dataout; - int *datap=datain; - - for (int i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { - detectors[i]->decodeData(datap, n, detp); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getDataBytes()/sizeof(int); - detp+=n; - // if (detectors[0]->getDetectorsType()==JUNGFRAUCTB) { - // detp+=detectors[i]->getDataBytes()/2; - // } else { - // detp+=detectors[i]->getTotalNumberOfChannels(); - // } -#ifdef VERBOSE - cout << "done " << endl; -#endif - // for (int j=0; jgetTotalNumberOfChannels(); ++j) { - // dataout[ich]=detp[j]; - // ++ich; - // } - //delete [] detp; - } - } - - - return dataout; -} - -//Correction -/* - enum correctionFlags { - DISCARD_BAD_CHANNELS, - AVERAGE_NEIGHBOURS_FOR_BAD_CHANNELS, - FLAT_FIELD_CORRECTION, - RATE_CORRECTION, - ANGULAR_CONVERSION - } -*/ - - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - - - - - - - - - - - - - - -int multiSlsDetector::setFlatFieldCorrection(string fname){ - double* data = new double[thisMultiDetector->numberOfChannels];// xmed[thisMultiDetector->numberOfChannels]; - double* ffcoefficients = new double[thisMultiDetector->numberOfChannels]; - double*fferrors = new double[thisMultiDetector->numberOfChannels]; - // int nmed=0; - // int idet=0, ichdet=-1; - char ffffname[MAX_STR_LENGTH*2]; - int nch;//nbad=0, - //int badlist[MAX_BADCHANS]; - //int im=0; - - if (fname=="default") { - fname=string(thisMultiDetector->flatFieldFile); - } - - - thisMultiDetector->correctionMask&=~(1<correctionMask&=~(1<flatFieldFile,"none"); - for (int i=0; inumberOfDetectors; ++i) { - if (detectors[i]){ - detectors[i]->setFlatFieldCorrection(NULL, NULL); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<flatFieldDir,fname.c_str()); - nch=readDataFile(string(ffffname),data); - - if (nch>thisMultiDetector->numberOfChannels) - nch=thisMultiDetector->numberOfChannels; - - if (nch>0) { - - //???? bad ff chans? - int nm=getNMods(); - int chpm[nm]; - int mMask[nm]; - for (int i=0; i=0) { - strcpy(thisMultiDetector->flatFieldFile,fname.c_str()); - - - thisMultiDetector->correctionMask|=(1<correctionMask&(1<numberOfDetectors; ++i) { - if (detectors[i]) { - for (int im=0; imgetNMods(); ++im) { - mM[imod]=im+off; - ++imod; + for (unsigned int i = 0; i < detectors.size(); ++i) { + ret = detectors[i]->writeAdcRegister(addr, val); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 == -100) + ret1 = ret; + else if (ret != ret1) { + // not setting it to -1 as it is a possible value + std::cout << "Error: Different Values for function " + "writeAdcRegister [" << ret << "," << ret1 << "]" << endl; + setErrorMask(getErrorMask() | MULTI_HAVE_DIFFERENT_VALUES); + } } - off+=detectors[i]->getMaxMods(); - } + + return ret1; +} + +int multiSlsDetector::activate(int const enable) { + return callDetectorMember(&slsDetector::activate, enable); +} + +int multiSlsDetector::getFlippedData(dimension d) { + return callDetectorMember(&slsDetector::getFlippedData, d); +} + +int multiSlsDetector::setFlippedData(dimension d, int value) { + return callDetectorMember(&slsDetector::setFlippedData, d, value); +} + +int multiSlsDetector::setAllTrimbits(int val, int imod) { + int ret = -100; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->setAllTrimbits(val, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + int* iret[detectors.size()]; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iret[idet] = new int(-1); + Task* task = new Task(new func2_t(&slsDetector::setAllTrimbits, + detectors[idet], val, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + return ret; +} - } - } - return getNMods(); +int multiSlsDetector::enableGapPixels(int val) { + if (val > 0 && getDetectorsType() != EIGER) { + std::cout << "Not implemented for this detector" << std::endl; + val = -1; + } + int ret = callDetectorMember(&slsDetector::enableGapPixels, val); + + if (val != -1) { + // update data bytes incl gap pixels + thisMultiDetector->dataBytesInclGapPixels = 0; + for (unsigned int i = 0; i < detectors.size(); ++i) { + thisMultiDetector->dataBytesInclGapPixels += + detectors[i]->getDataBytesInclGapPixels(); + } + // update offsets and number of channels incl gap pixels in multi level + updateOffsets(); + } + return ret; +} + +int multiSlsDetector::setTrimEn(int ne, int* ene) { + int ret = -100, ret1; + int* ene1 = 0; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + ret1 = detectors[idet]->setTrimEn(ne, ene); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret == -100) + ret = ret1; + else if (ret != ret1) + ret = -1; + + if (ene != NULL) { + if (ene1 == 0) { + ene1 = new int[ret1]; + for (int i = 0; i < ret1; ++i){ + ene1[i] = ene[i]; + } + }else if (ret != -1) { + // only check if it is not already a fail + for (int i = 0; i < ret; ++i){ + if (ene1[i] != ene[i]) + ret = -1; + } + } + } + } + return ret; +} + +int multiSlsDetector::getTrimEn(int* ene) { + int ret = -100, ret1; + int* ene1 = 0; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + ret1 = detectors[idet]->getTrimEn(ene); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret == -100) + ret = ret1; + else if (ret != ret1) + ret = -1; + + if (ene != NULL) { + if (ene1 == 0) { + ene1 = new int[ret1]; + for (int i = 0; i < ret1; ++i){ + ene1[i] = ene[i]; + } + }else if (ret != -1) { + // only check if it is not already a fail + for (int i = 0; i < ret; ++i){ + if (ene1[i] != ene[i]) + ret = -1; + } + } + } + } + + if (ene1) + delete [] ene1; + return ret; +} + +int multiSlsDetector::pulsePixel(int n, int x, int y) { + return parallelCallDetectorMember(&slsDetector::pulsePixel, n, x, y); +} + +int multiSlsDetector::pulsePixelNMove(int n, int x, int y) { + return parallelCallDetectorMember(&slsDetector::pulsePixelNMove, n, x, y); +} + +int multiSlsDetector::pulseChip(int n) { + return parallelCallDetectorMember(&slsDetector::pulseChip, n); +} + +int multiSlsDetector::setThresholdTemperature(int val, int imod) { + int ret = -100; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->setThresholdTemperature(val, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int posmin = 0, posmax = detectors.size(); + int* iret[posmax - posmin]; + + for (int idet = posmin; idet < posmax; ++idet) { + iret[idet] = new dacs_t(-1); + Task* task = new Task(new func2_t(&slsDetector::setThresholdTemperature, + detectors[idet], val, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + + return ret; +} + +int multiSlsDetector::setTemperatureControl(int val, int imod) { + int ret = -100; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->setTemperatureControl(val, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int posmin = 0, posmax = detectors.size(); + int* iret[posmax - posmin]; + + for (int idet = posmin; idet < posmax; ++idet) { + iret[idet] = new dacs_t(-1); + Task* task = new Task(new func2_t(&slsDetector::setTemperatureControl, + detectors[idet], val, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + + return ret; +} + +int multiSlsDetector::setTemperatureEvent(int val, int imod) { + int ret = -100; + + // single + { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + ret = detectors[id]->setTemperatureEvent(val, im); + if (detectors[id]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << id)); + return ret; + } + } + + // multi + if (!threadpool) { + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + } + + int posmin = 0, posmax = detectors.size(); + int* iret[posmax - posmin]; + + for (int idet = posmin; idet < posmax; ++idet) { + iret[idet] = new dacs_t(-1); + Task* task = new Task(new func2_t(&slsDetector::setTemperatureEvent, + detectors[idet], val, imod, iret[idet])); + threadpool->add_task(task); + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for (int idet = posmin; idet < posmax; ++idet) { + if (iret[idet] != NULL) { + if (ret == -100) + ret = *iret[idet]; + else if (ret != *iret[idet]) + ret = -1; + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + + return ret; +} + +int multiSlsDetector::setStoragecellStart(int pos) { + return parallelCallDetectorMember(&slsDetector::setStoragecellStart, pos); +} + +int multiSlsDetector::programFPGA(string fname) { + int ret = OK, ret1 = OK; + + for (unsigned int i = 0; i < detectors.size(); ++i) { + ret = detectors[i]->programFPGA(fname); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret == FAIL) + ret1 = FAIL; + } + return ret1; +} + +int multiSlsDetector::resetFPGA() { + int ret = OK, ret1 = OK; + + for (unsigned int i = 0; i < detectors.size(); ++i) { + ret = detectors[i]->resetFPGA(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret == FAIL) + ret1 = FAIL; + } + return ret1; +} + +int multiSlsDetector::powerChip(int ival) { + int ret = OK, ret1 = OK; + + for (unsigned int i = 0; i < detectors.size(); ++i) { + ret = detectors[i]->powerChip(ival); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret == FAIL) + ret1 = FAIL; + } + return ret1; +} + +int multiSlsDetector::setAutoComparatorDisableMode(int ival) { + int ret = OK, ret1 = OK; + + for (unsigned int i = 0; i < detectors.size(); ++i) { + ret = detectors[i]->setAutoComparatorDisableMode(ival); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret == FAIL) + ret1 = FAIL; + } + return ret1; +} + +double multiSlsDetector::getScanStep(int index, int istep) { + return thisMultiDetector->scanSteps[index][istep]; +} + +int multiSlsDetector::getChanRegs(double* retval, bool fromDetector) { + //nChansDet and currentNumChans is because of varying channel size per detector + int n = thisMultiDetector->numberOfChannels, nChansDet, currentNumChans = 0; + double retval1[n]; + + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + nChansDet = detectors[idet]->getChanRegs(retval1, fromDetector); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + + memcpy(retval + (currentNumChans), retval1, nChansDet * sizeof(double)); + currentNumChans += nChansDet; + } + return n; } -int multiSlsDetector::setFlatFieldCorrection(double *corr, double *ecorr) { - int ichdet=0; - double *p, *ep; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - if (corr!=NULL) - p=corr+ichdet; - else - p=NULL; - if (ecorr!=NULL) - ep=ecorr+ichdet; - else - ep=NULL; - detectors[idet]->setFlatFieldCorrection(p, ep); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels(); - } - } - return 0; +int multiSlsDetector::setChannel(int64_t reg, int ichan, int ichip, int imod) { + int ret, ret1 = -100; + int id = -1, im = -1; + int dmi = 0, dma = detectors.size(); + + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + dmi = id; + dma = id + 1; + } + for (int idet = dmi; idet < dma; ++idet) { + ret = detectors[idet]->setChannel(reg, ichan, ichip, im); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret1 == -100) + ret1 = ret; + else if (ret != ret1) + ret1 = -1; + } + return ret1; +} + +int multiSlsDetector::getMoveFlag(int imod) { + int id = -1, im = -1; + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return -1; + return detectors[id]->getMoveFlag(im); + } + + //default!!! + return 1; +} + +int multiSlsDetector::fillModuleMask(int* mM) { + int imod = 0, off = 0; + if (mM) { + for (unsigned int i = 0; i < detectors.size(); ++i) { + for (int im = 0; im < detectors[i]->getNMods(); ++im) { + mM[imod] = im + off; + ++imod; + } + off += detectors[i]->getMaxMods(); + } + } + return getNMods(); } - - - - - - - -int multiSlsDetector::getFlatFieldCorrection(double *corr, double *ecorr) { - int ichdet=0; - double *p, *ep; - int ff=1, dff; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - if (corr!=NULL) - p=corr+ichdet; - else - p=NULL; - if (ecorr!=NULL) - ep=ecorr+ichdet; - else - ep=NULL; - dff=detectors[idet]->getFlatFieldCorrection(p, ep); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels(); - } - } - return ff; +int multiSlsDetector::calibratePedestal(int frames) { + return callDetectorMember(&slsDetector::calibratePedestal, frames); } - - - - - - - - - - - - - -int multiSlsDetector::getNMods(){ - int nm=0; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - nm+=detectors[idet]->getNMods(); - } - } -#ifdef VERBOSE - cout << "total number of modules is " << nm << endl; -#endif - - return nm; -} - - -int multiSlsDetector::getNMod(dimension d){ - int nm=0; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - nm+=detectors[idet]->getNMod(d); - } - } -#ifdef VERBOSE - cout << "total number of modules in dimension " << d << " is " << nm << endl; -#endif - - return nm; -} - - - -int multiSlsDetector::getChansPerMod(int imod){ - int id=-1, im=-1; -#ifdef VERBOSE - cout << "get chans per mod " << imod << endl; -#endif - decodeNMod(imod, id, im); - if (id >=0) { - if (detectors[id]) { - return detectors[id]->getChansPerMod(im); - } - } - return -1; - -} - -int multiSlsDetector::getMoveFlag(int imod){ - int id=-1, im=-1; - decodeNMod(imod, id, im); - if (id>=0) { - if (detectors[id]) { - return detectors[id]->getMoveFlag(im); - } - } - //default!!! - return 1; -} - - - - -angleConversionConstant * multiSlsDetector::getAngularConversionPointer(int imod){ - int id=-1, im=-1; -#ifdef VERBOSE - cout << "get angular conversion pointer " << endl; -#endif - if (decodeNMod(imod, id, im)>=0) { - if (detectors[id]) { - return detectors[id]->getAngularConversionPointer(im); - } - } - return NULL; - -} - - - -int multiSlsDetector::flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout){ - - int ichdet=0; - double *perr=errin;//*pdata, - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { -#ifdef VERBOSE - cout << " detector " << idet << " offset " << ichdet << endl; -#endif - if (errin) - perr+=ichdet; - detectors[idet]->flatFieldCorrect(datain+ichdet, perr, dataout+ichdet, errout+ichdet); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels();//detectors[idet]->getNChans()*detectors[idet]->getNChips()*detectors[idet]->getNMods(); - } - } - return 0; -}; - - - - - - - - -int multiSlsDetector::setRateCorrection(double t){ +int multiSlsDetector::setRateCorrection(double t) { #ifdef VERBOSE - std::cout<< "Setting rate correction with dead time "<< thisMultiDetector->tDead << std::endl; + std::cout << "Setting rate correction with dead time " << + thisMultiDetector->tDead << std::endl; #endif - int ret=OK; - int posmax=thisMultiDetector->numberOfDetectors; + int ret = OK; + int posmax = detectors.size(); // eiger return value is ok/fail - if (getDetectorsType() == EIGER){ - if(!threadpool){ + if (getDetectorsType() == EIGER) { + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return FAIL; - }else{ + } else { int* iret[posmax]; - for(int idet=0; idet(&slsDetector::setRateCorrection, - detectors[idet],t,iret[idet])); - threadpool->add_task(task); - } + for (int idet = 0; idet < posmax; ++idet) { + iret[idet] = new int(OK); + Task* task = new Task(new func1_t + (&slsDetector::setRateCorrection, + detectors[idet], t, iret[idet])); + threadpool->add_task(task); } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } return ret; } - // mythen, others - if (t==0) { - thisMultiDetector->correctionMask&=~(1<correctionMask&(1<correctionMask &= ~(1 << RATE_CORRECTION); + return thisMultiDetector->correctionMask & (1 << RATE_CORRECTION); } else - thisMultiDetector->correctionMask|=(1<correctionMask |= (1 << RATE_CORRECTION); ret = -100; - if(!threadpool){ + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return -1; - }else{ + } else { int* iret[posmax]; - for(int idet=0; idet(&slsDetector::setRateCorrection, - detectors[idet],t,iret[idet])); - threadpool->add_task(task); - } + for (int idet = 0; idet < posmax; ++idet) { + iret[idet] = new int(-1); + Task* task = new Task(new func1_t + (&slsDetector::setRateCorrection, + detectors[idet], t, iret[idet])); + threadpool->add_task(task); } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } - return thisMultiDetector->correctionMask&(1<correctionMask & (1 << RATE_CORRECTION); } - -int multiSlsDetector::getRateCorrection(double &t){ - - if (getDetectorsType() == EIGER){ +int multiSlsDetector::getRateCorrection(double& t) { + if (getDetectorsType() == EIGER) { t = getRateCorrectionTau(); return t; } - if (thisMultiDetector->correctionMask&(1<correctionMask & (1 << RATE_CORRECTION)) { #ifdef VERBOSE - std::cout<< "Rate correction is enabled with dead time "<< thisMultiDetector->tDead << std::endl; + std::cout << "Rate correction is enabled with dead time " << + thisMultiDetector->tDead << std::endl; #endif return 1; } else - t=0; + t = 0; #ifdef VERBOSE - std::cout<< "Rate correction is disabled " << std::endl; + std::cout << "Rate correction is disabled " << std::endl; #endif return 0; -}; +} -double multiSlsDetector::getRateCorrectionTau(){ +double multiSlsDetector::getRateCorrectionTau() { - double ret=-100.0; - int posmax = thisMultiDetector->numberOfDetectors; + double ret = -100.0; + int posmax = detectors.size(); - if(!threadpool){ + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return -1; - }else{ + } else { double* iret[posmax]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new double(-1); - Task* task = new Task(new func0_t(&slsDetector::getRateCorrectionTau, - detectors[idet],iret[idet])); - threadpool->add_task(task); - } + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iret[idet] = new double(-1); + Task* task = new Task(new func0_t + (&slsDetector::getRateCorrectionTau, + detectors[idet], iret[idet])); + threadpool->add_task(task); } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idet 0.000000001) { - std::cout<< "Rate correction is different for different readouts " << std::endl; - ret=-1; - } - delete iret[idet]; - }else ret = -1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1< 0.000000001) { + std::cout << "Rate correction is different for " + "different readouts " << std::endl; + ret = -1; + } + delete iret[idet]; + } else + ret = -1; + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } if (getDetectorsType() == EIGER) return ret; - //only mythen - if (thisMultiDetector->correctionMask&(1<correctionMask & (1 << RATE_CORRECTION)) { #ifdef VERBOSE - std::cout<< "Rate correction is enabled with dead time "<< thisMultiDetector->tDead << std::endl; + std::cout << "Rate correction is enabled with dead time " << + thisMultiDetector->tDead << std::endl; #endif } else { #ifdef VERBOSE - std::cout<< "Rate correction is disabled " << std::endl; + std::cout << "Rate correction is disabled " << std::endl; #endif - ret=0; + ret = 0; } return ret; +} -}; - - - -int multiSlsDetector::getRateCorrection(){ - - if (getDetectorsType() == EIGER){ +int multiSlsDetector::getRateCorrection() { + if (getDetectorsType() == EIGER) { return getRateCorrectionTau(); } - - if (thisMultiDetector->correctionMask&(1<correctionMask & (1 << RATE_CORRECTION)) { + return 1; + } else + return 0; }; - - - -int multiSlsDetector::rateCorrect(double* datain, double *errin, double* dataout, double *errout){ - - int ichdet=0; - double *perr=errin; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - if (errin) - perr+=ichdet; - detectors[idet]->rateCorrect(datain+ichdet, perr, dataout+ichdet, errout+ichdet); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels(); - } - } - return 0; -}; - - -int multiSlsDetector::setBadChannelCorrection(string fname){ - - int badlist[MAX_BADCHANS];// badlistdet[MAX_BADCHANS]; - int nbad=0;//, nbaddet=0, choff=0, idet=0; - int ret=0; - - cout << thisMultiDetector->badChanFile << endl; - - if (fname=="default") - fname=string(thisMultiDetector->badChanFile); - - - - - - ret=setBadChannelCorrection(fname, nbad, badlist); - //#ifdef VERBOSE - cout << "multi: file contained " << ret << " badchans" << endl; - //#endif - if (ret==0) { - thisMultiDetector->correctionMask&=~(1<correctionMask|=(1<badChanFile,fname.c_str()); - } - - return setBadChannelCorrection(nbad,badlist,0); - -} - - - -int multiSlsDetector::setBadChannelCorrection(int nbad, int *badlist, int ff) { - - //#define VERBOSE - - int badlistdet[MAX_BADCHANS]; - int nbaddet=0, choff=0, idet=0; - if (nbad<1) - badlistdet[0]=0; - else - badlistdet[0]=badlist[0]; - - if (nbad>0) { - thisMultiDetector->correctionMask|=(1<=detectors[idet]->getMaxNumberOfChannels()) { - //#ifdef VERBOSE - cout << "setting " << nbaddet << " badchans to detector " << idet << endl; - //#endif - detectors[idet]->setBadChannelCorrection(nbaddet,badlistdet,0); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); - nbaddet=0; - ++idet; - if (detectors[idet]==NULL) - break; +int multiSlsDetector::rateCorrect(double* datain, double* errin, double* dataout, double* errout) { + int ichdet = 0; + double* perr = errin; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (errin) + perr += ichdet; + detectors[idet]->rateCorrect(datain + ichdet, perr, dataout + ichdet, + errout + ichdet); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + ichdet += detectors[idet]->getTotalNumberOfChannels(); } - badlistdet[nbaddet]=(badlist[ich]-choff); - ++nbaddet; -#ifdef VERBOSE - cout << nbaddet << " " << badlist[ich] << " " << badlistdet[nbaddet-1] << endl; -#endif - } - } - if (nbaddet>0) { - - if (detectors[idet]) { -#ifdef VERBOSE - cout << "setting " << nbaddet << " badchans to detector " << idet << endl; -#endif - detectors[idet]->setBadChannelCorrection(nbaddet,badlistdet,0); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); - nbaddet=0; - ++idet; - } - } - nbaddet=0; - for (int i=idet; inumberOfDetectors; ++i) { - #ifdef VERBOSE - cout << "setting " << 0 << " badchans to detector " << i << endl; - #endif - if (detectors[i]) { - detectors[i]->setBadChannelCorrection(nbaddet,badlistdet,0); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[idet]) { -#ifdef VERBOSE - cout << "setting " << 0 << " badchans to detector " << idet << endl; -#endif - detectors[idet]->setBadChannelCorrection(nbaddet,badlistdet,0); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<correctionMask&=~(1<correctionMask&(1<correctionMask&(1<numberOfChannels]; + double* ffcoefficients = new double[thisMultiDetector->numberOfChannels]; + double* fferrors = new double[thisMultiDetector->numberOfChannels]; + char ffffname[MAX_STR_LENGTH * 2]; + int nch; + if (fname == "default") { + fname = string(thisMultiDetector->flatFieldFile); + } + + thisMultiDetector->correctionMask &= ~(1 << FLAT_FIELD_CORRECTION); + + if (fname == "") { +#ifdef VERBOSE + std::cout << "disabling flat field correction" << std::endl; +#endif + thisMultiDetector->correctionMask &= ~(1 << FLAT_FIELD_CORRECTION); + for (unsigned int i = 0; i < detectors.size(); ++i) { + detectors[i]->setFlatFieldCorrection(NULL, NULL); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + } + } else { +#ifdef VERBOSE + std::cout << "Setting flat field correction from file " << fname << std::endl; +#endif + sprintf(ffffname, "%s/%s", thisMultiDetector->flatFieldDir, fname.c_str()); + nch = readDataFile(string(ffffname), data); + + if (nch > thisMultiDetector->numberOfChannels) + nch = thisMultiDetector->numberOfChannels; + + if (nch > 0) { + + int nm = getNMods(); + int chpm[nm]; + int mMask[nm]; + for (int i = 0; i < nm; ++i) { + chpm[i] = getChansPerMod(i); + mMask[i] = i; + } + fillModuleMask(mMask); + fillBadChannelMask(); + if ((postProcessingFuncs::calculateFlatField(&nm, chpm, mMask, + badChannelMask, data, ffcoefficients, fferrors)) >= 0) { + strcpy(thisMultiDetector->flatFieldFile, fname.c_str()); + + thisMultiDetector->correctionMask |= (1 << FLAT_FIELD_CORRECTION); + + setFlatFieldCorrection(ffcoefficients, fferrors); + + } else + std::cout << "Calculated flat field from file " << fname << + " is not valid " << nch << std::endl; + } else { + std::cout << "Flat field from file " << fname << " is not valid " + << nch << std::endl; + } + } + return thisMultiDetector->correctionMask & (1 << FLAT_FIELD_CORRECTION); +} +int multiSlsDetector::setFlatFieldCorrection(double* corr, double* ecorr) { + int ichdet = 0; + double *p, *ep; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (corr != NULL) + p = corr + ichdet; + else + p = NULL; + if (ecorr != NULL) + ep = ecorr + ichdet; + else + ep = NULL; + detectors[idet]->setFlatFieldCorrection(p, ep); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + ichdet += detectors[idet]->getTotalNumberOfChannels(); + } + return 0; +} + +int multiSlsDetector::getFlatFieldCorrection(double* corr, double* ecorr) { + int ichdet = 0; + double *p, *ep; + int ff = 1, dff; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + if (corr != NULL) + p = corr + ichdet; + else + p = NULL; + if (ecorr != NULL) + ep = ecorr + ichdet; + else + ep = NULL; + dff = detectors[idet]->getFlatFieldCorrection(p, ep); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (dff == 0) + ff = 0; + ichdet += detectors[idet]->getTotalNumberOfChannels(); + } + return ff; +} + +int multiSlsDetector::flatFieldCorrect(double* datain, double* errin, double* dataout, + double* errout) { + int ichdet = 0; + double* perr = errin; //*pdata, + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { +#ifdef VERBOSE + cout << " detector " << idet << " offset " << ichdet << endl; +#endif + if (errin) + perr += ichdet; + detectors[idet]->flatFieldCorrect(datain + ichdet, perr, + dataout + ichdet, errout + ichdet); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + ichdet += detectors[idet]->getTotalNumberOfChannels(); + } + return 0; +} + +int multiSlsDetector::setBadChannelCorrection(string fname) { + int badlist[MAX_BADCHANS]; + int nbad = 0; + int ret = 0; + + cout << thisMultiDetector->badChanFile << endl; + + if (fname == "default") + fname = string(thisMultiDetector->badChanFile); + + ret = setBadChannelCorrection(fname, nbad, badlist); + //#ifdef VERBOSE + cout << "multi: file contained " << ret << " badchans" << endl; + //#endif + if (ret == 0) { + thisMultiDetector->correctionMask &= ~(1 << DISCARD_BAD_CHANNELS); + nbad = 0; + } else { + thisMultiDetector->correctionMask |= (1 << DISCARD_BAD_CHANNELS); + strcpy(thisMultiDetector->badChanFile, fname.c_str()); + } + + return setBadChannelCorrection(nbad, badlist, 0); +} + +int multiSlsDetector::setBadChannelCorrection(int nbad, int* badlist, int ff) { + int badlistdet[MAX_BADCHANS]; + int nbaddet = 0, choff = 0, idet = 0; + if (nbad < 1) + badlistdet[0] = 0; + else + badlistdet[0] = badlist[0]; + + if (nbad > 0) { + thisMultiDetector->correctionMask |= (1 << DISCARD_BAD_CHANNELS); + + for (int ich = 0; ich < nbad; ++ich) { + if ((badlist[ich] - choff) >= detectors[idet]->getMaxNumberOfChannels()) { + //#ifdef VERBOSE + cout << "setting " << nbaddet << " badchans to detector " + << idet << endl; + //#endif + detectors[idet]->setBadChannelCorrection(nbaddet, badlistdet, 0); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + choff += detectors[idet]->getMaxNumberOfChannels(); + nbaddet = 0; + ++idet; + if (detectors[idet] == NULL) + break; + } + badlistdet[nbaddet] = (badlist[ich] - choff); + ++nbaddet; +#ifdef VERBOSE + cout << nbaddet << " " << badlist[ich] << " " + << badlistdet[nbaddet - 1] << endl; +#endif + } + if (nbaddet > 0) { +#ifdef VERBOSE + cout << "setting " << nbaddet << " badchans to detector " + << idet << endl; +#endif + detectors[idet]->setBadChannelCorrection(nbaddet, badlistdet, 0); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + choff += detectors[idet]->getMaxNumberOfChannels(); + nbaddet = 0; + ++idet; + } + nbaddet = 0; + for (unsigned int i = idet; i < detectors.size(); ++i) { +#ifdef VERBOSE + cout << "setting " << 0 << " badchans to detector " << i << endl; +#endif + detectors[i]->setBadChannelCorrection(nbaddet, badlistdet, 0); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + } + + } else { + nbaddet = 0; + for (unsigned int i = 0; i < detectors.size(); ++i) { +#ifdef VERBOSE + cout << "setting " << 0 << " badchans to detector " << idet << endl; +#endif + detectors[idet]->setBadChannelCorrection(nbaddet, badlistdet, 0); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + thisMultiDetector->correctionMask &= ~(1 << DISCARD_BAD_CHANNELS); + } +#ifdef VERBOSE + cout << (thisMultiDetector->correctionMask & (1 << DISCARD_BAD_CHANNELS)) << endl; +#endif + return thisMultiDetector->correctionMask & (1 << DISCARD_BAD_CHANNELS); +} + + +int multiSlsDetector::getBadChannelCorrection(int* bad) { + //int ichan; + int *bd, nd, ntot = 0, choff = 0; + ; + + if (((thisMultiDetector->correctionMask) & (1 << DISCARD_BAD_CHANNELS)) == 0) + return 0; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + nd = detectors[idet]->getBadChannelCorrection(); + if (nd > 0) { + bd = new int[nd]; + nd = detectors[idet]->getBadChannelCorrection(bd); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + + for (int id = 0; id < nd; ++id) { + if (bd[id] < detectors[idet]->getTotalNumberOfChannels()) { + if (bad) + bad[ntot] = choff + bd[id]; + ++ntot; + } + } + choff += detectors[idet]->getTotalNumberOfChannels(); + delete[] bd; + } else + ntot += nd; + } + return ntot; +} int multiSlsDetector::readAngularConversionFile(string fname) { + ifstream infile; + //int nm=0; + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { - ifstream infile; - //int nm=0; - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { #ifdef VERBOSE - cout << " detector " << idet << endl; + cout << " detector " << idet << endl; #endif - detectors[idet]->readAngularConversion(infile); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<readAngularConversion(infile); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } + infile.close(); + } else { + std::cout << "Could not open calibration file " << fname << std::endl; + return -1; + } + return 0; } - int multiSlsDetector::writeAngularConversion(string fname) { - - ofstream outfile; - // int nm=0; - outfile.open(fname.c_str(), ios_base::out); - if (outfile.is_open()) { - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - detectors[idet]->writeAngularConversion(outfile); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - detectors[idet]->getAngularConversion(dir1,a1); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getNMods(); - } - } - } - direction=dir; - - if (thisMultiDetector->correctionMask&(1<< ANGULAR_CONVERSION)) { - return 1; - } - return 0; - - -} - - - -dacs_t multiSlsDetector::setDAC(dacs_t val, dacIndex idac, int mV, int imod) { - dacs_t ret = -100; - - // single - { - int id=-1, im=-1; - if (decodeNMod(imod, id, im)>=0) { - if(detectors[id]){ - ret = detectors[id]->setDAC(val, idac, mV, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - dacs_t* iret[posmax-posmin]; - - for(int idet=posmin; idet(&slsDetector::setDAC, - detectors[idet],val, idac, mV, imod, iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if(detectors[id]){ - ret = detectors[id]->getADC(idac, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - dacs_t* iret[posmax-posmin]; - - for(int idet=posmin; idet(&slsDetector::getADC, - detectors[idet],idac, imod, iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if(detectors[id]){ - ret = detectors[id]->setThresholdTemperature(val, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - int* iret[posmax-posmin]; - - for(int idet=posmin; idet(&slsDetector::setThresholdTemperature, - detectors[idet], val, imod, iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if(detectors[id]){ - ret = detectors[id]->setTemperatureControl(val, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - int* iret[posmax-posmin]; - - for(int idet=posmin; idet(&slsDetector::setTemperatureControl, - detectors[idet], val, imod, iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if(detectors[id]){ - ret = detectors[id]->setTemperatureEvent(val, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - int* iret[posmax-posmin]; - - for(int idet=posmin; idet(&slsDetector::setTemperatureEvent, - detectors[idet], val, imod, iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - - if (decodeNMod(imod, id, im)>=0) { - dmi=id; - dma=id+1; - } - for (int idet=dmi; idetsetChannel(reg, ichan, ichip, im); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - - if (detectors[idet]) { - - detectors[idet]->setAngularConversionParameter(c,v); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfChannels]; - -// double *p=ang; -// int choff=0; - -// for (int idet=0; idetnumberOfDetectors; ++idet) { - -// if (detectors[idet]) { -// #ifdef EPICS -// // cout << "convert angle det " << idet << endl; -// if (idet<2) -// #endif -// p=detectors[idet]->convertAngles(pos); -// #ifdef EPICS -// else //////////// GOOD ONLY AT THE BEAMLINE!!!!!!!!!!!!! -// p=detectors[idet]->convertAngles(0); -// #endif -// for (int ich=0; ichgetTotalNumberOfChannels(); ich++) { -// ang[choff+ich]=p[ich]; -// } -// choff+=detectors[idet]->getTotalNumberOfChannels(); -// delete [] p; -// } -// } -// return ang; -// } - - -int multiSlsDetector::getBadChannelCorrection(int *bad) { - //int ichan; - int *bd, nd, ntot=0, choff=0;; - - if (((thisMultiDetector->correctionMask)&(1<< DISCARD_BAD_CHANNELS))==0) - return 0; - //else - // cout << "bad chans corr enabled "<< thisMultiDetector->correctionMask << endl; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - nd=detectors[idet]->getBadChannelCorrection(); - // cout << "det " << idet << " nbad " << nd << endl; - if (nd>0) { - bd = new int[nd]; - nd=detectors[idet]->getBadChannelCorrection(bd); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels()) { - if (bad) bad[ntot]=choff+bd[id]; - ++ntot; - } - } - choff+=detectors[idet]->getTotalNumberOfChannels(); - delete [] bd; - } else - ntot+=nd; - - } - } - return ntot; - -} - - -int multiSlsDetector::exitServer() { - - int ival=FAIL, iv; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - iv=detectors[idet]->exitServer(); - if (iv==OK) - ival=iv; - } - } - return ival; -} - - -/** returns the detector trimbit/settings directory */ -char* multiSlsDetector::getSettingsDir() { - string s0="", s1="", s; - - - //char ans[1000]; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - s=detectors[idet]->getSettingsDir(); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - detectors[idet]->setSettingsDir(s); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setSettingsDir(s.substr(p1,p2-p1)); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=thisMultiDetector->numberOfDetectors) - break; - } - - } - return getSettingsDir(); - - -} - - - - -int multiSlsDetector::setTrimEn(int ne, int *ene) { - - int ret=-100, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setTrimEn(ne,ene); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->getTrimEn(ene); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - s=detectors[idet]->getCalDir(); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - detectors[idet]->setCalDir(s); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setCalDir(s.substr(p1,p2-p1)); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=thisMultiDetector->numberOfDetectors) - break; - } - - } - return getCalDir(); - -} - -/** - returns the location of the calibration files - \sa sharedSlsDetector -*/ -string multiSlsDetector::getNetworkParameter(networkParameter p) { - string s0="", s1="",s ; - string ans=""; - //char ans[1000]; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - s=detectors[idet]->getNetworkParameter(p); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if (p == RECEIVER_STREAMING_PORT || p == CLIENT_STREAMING_PORT) - s.append("multi\0"); - sret[idet]=new string("error"); - Task* task = new Task(new func2_t(&slsDetector::setNetworkParameter, - detectors[idet],p,s,sret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(sret[idet]!= NULL) - delete sret[idet]; - //doing nothing with the return values - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setNetworkParameter(p,s.substr(p1,p2-p1)); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=thisMultiDetector->numberOfDetectors) - break; - } - - } - - return getNetworkParameter(p); - -} - -int multiSlsDetector::setPort(portType t, int p) { - - int ret=-100, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setPort(t,p); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->lockServer(p); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - s=detectors[idet]->getLastClientIP(); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setReadOutFlags(flag); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setExternalCommunicationMode(pol); - if(detectors[0]->getErrorMask()) - setErrorMask(getErrorMask()|(1<<0)); - - - for (int idet=1; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setExternalCommunicationMode(pol); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setExternalSignalFlags(pol,signalindex); - if(detectors[0]->getErrorMask()) - setErrorMask(getErrorMask()|(1<<0)); - - for (int idet=1; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setExternalSignalFlags(pol,signalindex); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - s=detectors[idet]->getSettingsFile(); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->configureMAC(); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfChannels]; - - ifstream infile; - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { -#ifdef VERBOSE - std::cout<< std::endl<< "Loading "; - if(!index) - std::cout<<"Dark"; - else - std::cout<<"Gain"; - std::cout<<" image from file " << fname << std::endl; -#endif - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - if(detectors[idet]->readDataFile(infile,imageVals)>=0){ - ret1=detectors[idet]->sendImageToDetector(index,imageVals); - if (ret==-100) - ret=ret1; - else if (ret!=ret1) - ret=-1; - } - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfChannels]; - ofstream outfile; - outfile.open(fname.c_str(), ios_base::out); - if (outfile.is_open()) { -#ifdef VERBOSE - std::cout<< std::endl<< "Reading Counter to \""<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->getCounterBlock(arg,startACQ); - if(ret1!=OK) - ret=FAIL; - else{ - ret1=detectors[idet]->writeDataFile(outfile,arg); - if(ret1!=OK) - ret=FAIL; - } - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->resetCounterBlock(startACQ); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setCounterBit(i); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<dataBytes=0; - thisMultiDetector->dataBytesInclGapPixels=0; - thisMultiDetector->numberOfChannels=0; - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return -1; - }else{ - //return storage values - int* iret[thisMultiDetector->numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func1_t(&slsDetector::setDynamicRange, - detectors[idet],p,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - thisMultiDetector->dataBytes+=detectors[idet]->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels+=detectors[idet]->getDataBytesInclGapPixels(); - thisMultiDetector->numberOfChannels+=detectors[idet]->getTotalNumberOfChannels(); - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->getMaxMods(); -#ifdef VERBOSE - cout << "detector " << idet << " maxmods " << ret1 << endl; -#endif - ret+=ret1; - } - } -#ifdef VERBOSE - cout << "max mods is " << ret << endl; -#endif - - return ret; - -} - - - - - int multiSlsDetector::getTotalNumberOfChannels(){thisMultiDetector->numberOfChannels=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; ++id) thisMultiDetector->numberOfChannels+=detectors[id]->getTotalNumberOfChannels(); return thisMultiDetector->numberOfChannels;}; - - //int multiSlsDetector::getTotalNumberOfChannels(dimension d){thisMultiDetector->numberOfChannel[d]=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; ++id) thisMultiDetector->numberOfChannel[d]+=detectors[id]->getTotalNumberOfChannels(d); return thisMultiDetector->numberOfChannel[d];}; - int multiSlsDetector::getTotalNumberOfChannels(dimension d){return thisMultiDetector->numberOfChannel[d];}; - - int multiSlsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d){return thisMultiDetector->numberOfChannelInclGapPixels[d];} - - int multiSlsDetector::getMaxNumberOfChannels(){thisMultiDetector->maxNumberOfChannels=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; ++id) thisMultiDetector->maxNumberOfChannels+=detectors[id]->getMaxNumberOfChannels();return thisMultiDetector->maxNumberOfChannels;}; - - // int multiSlsDetector::getMaxNumberOfChannels(dimension d){thisMultiDetector->maxNumberOfChannel[d]=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; ++id) thisMultiDetector->maxNumberOfChannel[d]+=detectors[id]->getMaxNumberOfChannels(d);return thisMultiDetector->maxNumberOfChannel[d];}; - int multiSlsDetector::getMaxNumberOfChannels(dimension d){return thisMultiDetector->maxNumberOfChannel[d];}; - - int multiSlsDetector::getMaxNumberOfChannelsInclGapPixels(dimension d){return thisMultiDetector->maxNumberOfChannelInclGapPixels[d];}; - - - - -int multiSlsDetector::getMaxMod(dimension d){ - - int ret=0, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->getNMaxMod(d); -#ifdef VERBOSE - cout << "detector " << idet << " maxmods " << ret1 << " in direction " << d << endl; -#endif - ret+=ret1; - } - } -#ifdef VERBOSE - cout << "max mods in direction "<< d << " is " << ret << endl; -#endif - - return ret; - -} - - -int multiSlsDetector::getMaxNumberOfModules(dimension d) { - - int ret=0, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->getMaxNumberOfModules(d); - ret+=ret1; - } - } - return ret; - -} - - -int multiSlsDetector::getFlippedData(dimension d){ - int ret=-100,ret1; - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->getFlippedData(d); - if(ret==-100) - ret=ret1; - else if (ret!=ret1) - ret=-1; - } - return ret; -} - -int multiSlsDetector::setNumberOfModules(int p, dimension d) { - - int ret=0;//, ret1; - int nm, mm, nt=p; - - thisMultiDetector->dataBytes=0; - thisMultiDetector->dataBytesInclGapPixels=0; - thisMultiDetector->numberOfChannels=0; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - - // cout << "detector " << idet << endl; - if (detectors[idet]) { - if (p<0) - nm=p; - else { - mm=detectors[idet]->getMaxNumberOfModules(); - //mm=detectors[idet]->getMaxMods(); - if (nt>mm) { - nm=mm; - nt-=nm; - } else { - nm=nt; - nt-=nm; - } - } - ret+=detectors[idet]->setNumberOfModules(nm); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<dataBytes+=detectors[idet]->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels+=detectors[idet]->getDataBytesInclGapPixels(); - thisMultiDetector->numberOfChannels+=detectors[idet]->getTotalNumberOfChannels(); - } - } - - if(p != -1) - updateOffsets(); - return ret; - -} - - - -int multiSlsDetector::setFlippedData(dimension d, int value){ - int ret=-100,ret1; - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setFlippedData(d,value); - if(ret==-100) - ret=ret1; - else if (ret!=ret1) - ret=-1; - } - return ret; -} - -int multiSlsDetector::enableGapPixels(int val) { - - if(val > 0 && getDetectorsType() != EIGER){ - std::cout << "Not implemented for this detector" << std::endl; - val = -1; - } - - int ret=-100,ret1; - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->enableGapPixels(val); - if(ret==-100) - ret=ret1; - else if (ret!=ret1) - ret=-1; - } - - if (val != -1) { - // update data bytes incl gap pixels - thisMultiDetector->dataBytesInclGapPixels=0; - for (int i = 0; i < thisMultiDetector->numberOfDetectors; ++i) { - if (detectors[i]) - thisMultiDetector->dataBytesInclGapPixels += detectors[i]->getDataBytesInclGapPixels(); - } - - // update offsets and number of channels incl gap pixels in multi level - updateOffsets(); - } - - return ret; -} - - - - -int multiSlsDetector::decodeNMod(int i, int &id, int &im) { -#ifdef VERBOSE - cout << " Module " << i << " belongs to detector " << id << endl;; - cout << getMaxMods(); -#endif - - if (i<0 || i>=getMaxMods()) { - id=-1; - im=-1; -#ifdef VERBOSE - cout << " A---------" << id << " position " << im << endl; -#endif - - return -1; - } - int nm; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - nm=detectors[idet]->getNMods(); - if (nm>i) { - id=idet; - im=i; -#ifdef VERBOSE - cout << " B---------" <=0) { - if (detectors[id]) { - ret = detectors[id]->getId(mode, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->getId(mode, imod); - if(ret==-100) - ret=ret1; - else if (ret!=ret1) - ret=-1; - } - return ret; - - return -1; - -} - -int multiSlsDetector::digitalTest(digitalTestMode mode, int imod) { - - int id, im, ret; - - if (decodeNMod(imod, id, im)>=0) { - if (detectors[id]) { - ret = detectors[id]->digitalTest(mode, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if (detectors[id]) { - ret = detectors[id]->executeTrimming(mode, par1, par2, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func4_t(&slsDetector::executeTrimming, - detectors[idet],mode,par1,par2,imod,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->programFPGA(fname); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->resetFPGA(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->powerChip(ival); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->setAutoComparatorDisableMode(ival); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if(detectors[id]){ - ret = detectors[id]->loadSettingsFile(fname, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(OK); - Task* task = new Task(new func2_t(&slsDetector::loadSettingsFile, - detectors[idet],fname,imod,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) - ret = FAIL; - delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if (detectors[id]) { - ret = detectors[id]->saveSettingsFile(fname, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret=detectors[idet]->saveSettingsFile(fname, imod); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if(detectors[id]){ - ret = detectors[id]->setAllTrimbits(val,im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func2_t(&slsDetector::setAllTrimbits, - detectors[idet],val,imod,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if(detectors[id]){ - ret = detectors[id]->loadCalibrationFile(fname, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(OK); - Task* task = new Task(new func2_t(&slsDetector::loadCalibrationFile, - detectors[idet],fname,imod,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) - ret = FAIL; - delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<=0) { - if (detectors[id]) { - ret = detectors[id]->saveCalibrationFile(fname, im); - if(detectors[id]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret=detectors[idet]->saveCalibrationFile(fname, imod); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->writeRegister(addr,val); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->writeAdcRegister(addr,val); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret=detectors[i]->readRegister(addr); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret1=detectors[i]->setBit(addr,n); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - ret1=detectors[i]->clearBit(addr,n); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++i) { - if (detectors[i]) { - std::cout << std::endl << "#Detector " << i << ":" << std::endl; - - ret=detectors[i]->printReceiverConfiguration(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - - for (int i=0; ifreeSharedMemory(); - } - } - thisMultiDetector->numberOfDetectors=0; - - multiSlsDetectorClient *cmd; - - - setAcquiringFlag(false); - clearAllErrorMask(); - - string ans; - string str; - ifstream infile; - int iargval; - int interrupt=0; - char *args[1000]; - - char myargs[1000][1000]; - - - string sargname, sargval; - int iline=0; - std::cout<< "config file name "<< fname << std::endl; - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { - - - while (infile.good() and interrupt==0) { - sargname="none"; - sargval="0"; - getline(infile,str); - ++iline; -#ifdef VERBOSE - std::cout<< str << std::endl; -#endif - if (str.find('#')!=string::npos) { -#ifdef VERBOSE - std::cout<< "Line is a comment " << std::endl; - std::cout<< str << std::endl; -#endif - continue; - } else if (str.length()<2) { -#ifdef VERBOSE - std::cout<< "Empty line " << std::endl; -#endif - continue; - } else { - istringstream ssstr(str); - iargval=0; - while (ssstr.good()) { - ssstr >> sargname; - //if (ssstr.good()) { -#ifdef VERBOSE - std::cout<< iargval << " " << sargname << std::endl; -#endif - - strcpy(myargs[iargval], sargname.c_str()); - args[iargval]=myargs[iargval]; - -#ifdef VERBOSE - std::cout<< "--" << iargval << " " << args[iargval] << std::endl; -#endif - - ++iargval; - //} - } - -#ifdef VERBOSE - cout << endl; - for (int ia=0; iaexecuteLine(1,args,GET_ACTION) << std::endl; - ++iline; - - // hostname of the detectors - cout << iline << " " << names[iline] << endl; - strcpy(args[0],names[iline].c_str()); - outfile << names[iline] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; - ++iline; - - // single detector configuration - for (int i=0; inumberOfDetectors; ++i) { - // sprintf(ext,".det%d",i); - if (detectors[i]) { - outfile << endl; - ret1 = detectors[i]->writeConfigurationFile(outfile,i); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<writeAngularConversion(outfile); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } - - outfile << endl; - //other configurations - while (iline < nvar) { - cout << iline << " " << names[iline] << endl; - strcpy(args[0],names[iline].c_str()); - outfile << names[iline] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; - ++iline; - } - - - - delete cmd; outfile.close(); -#ifdef VERBOSE - std::cout<< "wrote " <getAngularConversion(dir1, a1); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (dir == -100) + dir = dir1; + if (dir != dir1) + dir = 0; + if (angconv) { + a1 += detectors[idet]->getNMods(); + } } + direction = dir; + if (thisMultiDetector->correctionMask & (1 << ANGULAR_CONVERSION)) { + return 1; + } + return 0; +} + +double multiSlsDetector::setAngularConversionParameter(angleConversionParameter c, double v) { + double ret = slsDetectorUtils::setAngularConversionParameter(c, v); + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + detectors[idet]->setAngularConversionParameter(c, v); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + } return ret; } - - - - - - - - - - - - - -int multiSlsDetector::writeDataFile(string fname, double *data, double *err, double *ang, char dataformat, int nch) { - +angleConversionConstant* multiSlsDetector::getAngularConversionPointer(int imod) { + int id = -1, im = -1; #ifdef VERBOSE - cout << "using overloaded multiSlsDetector function to write formatted data file " << getTotalNumberOfChannels()<< endl; + cout << "get angular conversion pointer " << endl; #endif + if (decodeNMod(imod, id, im) >= 0) { + if (id < 0 || id >= (int)detectors.size()) + return NULL; + return detectors[id]->getAngularConversionPointer(im); + } + return NULL; +} - ofstream outfile; - int choff=0, off=0; //idata, - double *pe=err, *pa=ang; - int nch_left=nch, n;//, nd; - - if (nch_left<=0) - nch_left=getTotalNumberOfChannels(); - - - if (data==NULL) - return FAIL; - - outfile.open (fname.c_str(),ios_base::out); - if (outfile.is_open()) - { - - for (int i=0; inumberOfDetectors; ++i) { - - if (detectors[i]) { - n=detectors[i]->getTotalNumberOfChannels(); - if (nch_leftwriteDataFile(outfile,n, data+off, pe, pa, dataformat, choff); - fileIOStatic::writeDataFile(outfile,n, data+off, pe, pa, dataformat, choff); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); - - off+=n; - - if (pe) - pe=err+off; - - if (pa) - pa=ang+off; +int multiSlsDetector::printReceiverConfiguration() { + int ret, ret1 = -100; + std::cout << "Printing Receiver configurations for all detectors..." << std::endl; + for (unsigned int i = 0; i < detectors.size(); ++i) { + std::cout << std::endl + << "#Detector " << i << ":" << std::endl; + ret = detectors[i]->printReceiverConfiguration(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 == -100) + ret1 = ret; + else if (ret != ret1) + ret1 = -1; } - } - outfile.close(); - return OK; - } else { - std::cout<< "Could not open file " << fname << "for writing"<< std::endl; - return FAIL; - } + return ret1; } -int multiSlsDetector::writeDataFile(string fname, int *data) { - ofstream outfile; - int choff=0, off=0; - -#ifdef VERBOSE - cout << "using overloaded multiSlsDetector function to write raw data file " << endl; -#endif - - if (data==NULL) - return FAIL; - - outfile.open (fname.c_str(),ios_base::out); - if (outfile.is_open()) - { - for (int i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { -#ifdef VERBOSE - cout << " write " << i << " position " << off << " offset " << choff << endl; -#endif - detectors[i]->writeDataFile(outfile, detectors[i]->getTotalNumberOfChannels(), data+off, choff); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); - off+=detectors[i]->getTotalNumberOfChannels(); - } - } - - - outfile.close(); - return OK; - } else { - std::cout<< "Could not open file " << fname << "for writing"<< std::endl; - return FAIL; - } -} - - -int multiSlsDetector::readDataFile(string fname, double *data, double *err, double *ang, char dataformat){ - -#ifdef VERBOSE - cout << "using overloaded multiSlsDetector function to read formatted data file " << endl; -#endif - - ifstream infile; - int iline=0;//ichan, - //int interrupt=0; - string str; - int choff=0, off=0; - double *pe=err, *pa=ang; - -#ifdef VERBOSE - std::cout<< "Opening file "<< fname << std::endl; -#endif - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { - - for (int i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { - iline+=detectors[i]->readDataFile(detectors[i]->getTotalNumberOfChannels(), infile, data+off, pe, pa, dataformat, choff); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); - off+=detectors[i]->getTotalNumberOfChannels(); - if (pe) - pe=pe+off; - if (pa) - pa=pa+off; - } - } - - - infile.close(); - } else { - std::cout<< "Could not read file " << fname << std::endl; - return -1; - } - return iline; - -} - -int multiSlsDetector::readDataFile(string fname, int *data) { - -#ifdef VERBOSE - cout << "using overloaded multiSlsDetector function to read raw data file " << endl; -#endif - - ifstream infile; - int iline=0;//ichan, - //int interrupt=0; - string str; - int choff=0, off=0; - -#ifdef VERBOSE - std::cout<< "Opening file "<< fname << std::endl; -#endif - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { - - for (int i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { - iline+=detectors[i]->readDataFile(infile, data+off,detectors[i]->getTotalNumberOfChannels(), choff); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); - off+=detectors[i]->getTotalNumberOfChannels(); - } - } - infile.close(); - } else { - std::cout<< "Could not read file " << fname << std::endl; - return -1; - } - return iline; -} - - - - - -//receiver - - int multiSlsDetector::setReceiverOnline(int off) { - if (off != GET_ONLINE_FLAG) { - int ret=-100; - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return -1; - }else{ - //return storage values - int* iret[thisMultiDetector->numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func1_t(&slsDetector::setReceiverOnline, - detectors[idet],off,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<receiverOnlineFlag=ret; + thisMultiDetector->receiverOnlineFlag = parallelCallDetectorMember( + &slsDetector::setReceiverOnline, off); } return thisMultiDetector->receiverOnlineFlag; } - - string multiSlsDetector::checkReceiverOnline() { - string retval1 = "",retval; - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - retval=detectors[idet]->checkReceiverOnline(); - if(!retval.empty()){ - retval1.append(retval); - retval1.append("+"); - } - } - } - return retval1; + string retval1 = "", retval; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + retval = detectors[idet]->checkReceiverOnline(); + if (!retval.empty()) { + retval1.append(retval); + retval1.append("+"); + } + } + return retval1; } +int multiSlsDetector::lockReceiver(int lock) { + return callDetectorMember(&slsDetector::lockReceiver, lock); +} +string multiSlsDetector::getReceiverLastClientIP() { + return callDetectorMember(&slsDetector::getReceiverLastClientIP); +} +int multiSlsDetector::exitReceiver() { + //(Erik) logic is flawed should return fail if any fails? + int ival = FAIL, iv; + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iv = detectors[idet]->exitReceiver(); + if (iv == OK) + ival = iv; + } + return ival; +} + +std::string multiSlsDetector::getFilePath() { + return setFilePath(); +} string multiSlsDetector::setFilePath(string s) { - string ret="errorerror", ret1; - //if the sls file paths are different, it should be realized by always using setfilepath even if string empty - //if(!s.empty()){ - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setFilePath(s); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setFilePath(s); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret == "errorerror") + ret = ret1; + else if (ret != ret1) + ret = ""; + } + fileIO::setFilePath(ret); return fileIO::getFilePath(); } - +std::string multiSlsDetector::getFileName() { + return setFileName(); +} string multiSlsDetector::setFileName(string s) { string ret = "error"; - int posmax = thisMultiDetector->numberOfDetectors; + int posmax = detectors.size(); - if(!s.empty()){ + if (!s.empty()) { fileIO::setFileName(s); if (thisMultiDetector->receiverOnlineFlag == ONLINE_FLAG) - s=createReceiverFilePrefix(); + s = createReceiverFilePrefix(); } - if(!threadpool){ + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return string(""); } else { - string* sret[thisMultiDetector->numberOfDetectors]; - for(int idet=0; idet(&slsDetector::setFileName, - detectors[idet],s,sret[idet])); - threadpool->add_task(task); - } + string* sret[detectors.size()]; + for (int idet = 0; idet < posmax; ++idet) { + sret[idet] = new string("error"); + Task* task = new Task(new func1_t(&slsDetector::setFileName, + detectors[idet], s, sret[idet])); + threadpool->add_task(task); } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } - if ((thisMultiDetector->receiverOnlineFlag == ONLINE_FLAG) && ((ret != "error") || (ret != ""))) { + if ((thisMultiDetector->receiverOnlineFlag == ONLINE_FLAG) && + ((ret != "error") || (ret != ""))) { #ifdef VERBOSE - std::cout << "Complete file prefix from receiver: " << ret << std::endl; + std::cout << "Complete file prefix from receiver: " << ret << std::endl; #endif fileIO::setFileName(getNameFromReceiverFilePrefix(ret)); } @@ -5610,158 +4576,121 @@ string multiSlsDetector::setFileName(string s) { return ret; } +int multiSlsDetector::setReceiverFramesPerFile(int f) { + return parallelCallDetectorMember(&slsDetector::setReceiverFramesPerFile, f); +} +slsReceiverDefs::frameDiscardPolicy multiSlsDetector::setReceiverFramesDiscardPolicy(frameDiscardPolicy f) { + return callDetectorMember(&slsDetector::setReceiverFramesDiscardPolicy, f); +} + +int multiSlsDetector::setReceiverPartialFramesPadding(int f) { + return callDetectorMember(&slsDetector::setReceiverPartialFramesPadding, f); +} + +slsReceiverDefs::fileFormat multiSlsDetector::getFileFormat() { + return setFileFormat(); +} slsReceiverDefs::fileFormat multiSlsDetector::setFileFormat(fileFormat f) { - int ret=-100, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=(int)detectors[idet]->setFileFormat(f); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func1_t(&slsDetector::setFileIndex, - detectors[idet],i,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; - - if(!threadpool){ + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return FAIL; - }else{ - int* iret[posmax-posmin]; - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - iret[idet]= new int(OK); + } else { + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition){ + iret[idet] = new int(OK); Task* task = new Task(new func0_t(&slsDetector::startReceiver, - detectors[idet],iret[idet])); + detectors[idet], iret[idet])); threadpool->add_task(task); } } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) ret = FAIL; delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } } //master - int ret1=OK; - i=thisMultiDetector->masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret1=detectors[i]->startReceiver(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret1 = detectors[i]->startReceiver(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 != OK) + ret = FAIL; } return ret; } +int multiSlsDetector::stopReceiver() { + int i = 0; + int ret = OK, ret1 = OK; + int posmin = 0, posmax = detectors.size(); - - -int multiSlsDetector::stopReceiver(){ - int i=0; - int ret=OK,ret1=OK; - int posmin=0, posmax=thisMultiDetector->numberOfDetectors; - - i=thisMultiDetector->masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret1=detectors[i]->stopReceiver(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret1 = detectors[i]->stopReceiver(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (ret1 != OK) + ret = FAIL; } - if(!threadpool){ + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return FAIL; - }else{ - int* iret[posmax-posmin]; - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - iret[idet]= new int(OK); + } else { + int* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + iret[idet] = new int(OK); Task* task = new Task(new func0_t(&slsDetector::stopReceiver, - detectors[idet],iret[idet])); + detectors[idet], iret[idet])); threadpool->add_task(task); } } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] != OK) + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + if (iret[idet] != NULL) { + if (*iret[idet] != OK) ret = FAIL; delete iret[idet]; - }else ret = FAIL; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } } @@ -5769,78 +4698,68 @@ int multiSlsDetector::stopReceiver(){ return ret; } - -slsDetectorDefs::runStatus multiSlsDetector::startReceiverReadout(){ - int i=0; - runStatus s = IDLE,s1 = IDLE; - i=thisMultiDetector->masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - s1=detectors[i]->startReceiverReadout(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + s1 = detectors[i]->startReceiverReadout(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); } - for (i=0; inumberOfDetectors; ++i) { - if (detectors[i]) { - s=detectors[i]->startReceiverReadout(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<startReceiverReadout(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + if (s == ERROR) + s1 = ERROR; + if (s != IDLE) + s1 = s; } - /**stoppedFlag=1;*/ return s1; } -slsDetectorDefs::runStatus multiSlsDetector::getReceiverStatus(){ - int i=0; - runStatus ret=IDLE; - int posmin=0, posmax=thisMultiDetector->numberOfDetectors; +slsDetectorDefs::runStatus multiSlsDetector::getReceiverStatus() { + int i = 0; + runStatus ret = IDLE; + int posmin = 0, posmax = detectors.size(); - i=thisMultiDetector->masterPosition; - if (thisMultiDetector->masterPosition>=0) { - if (detectors[i]) { - ret=detectors[i]->getReceiverStatus(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition >= 0) { + ret = detectors[i]->getReceiverStatus(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + return ret; } - if(!threadpool){ + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return ERROR; - }else{ - runStatus* iret[posmax-posmin]; - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - iret[idet]= new runStatus(ERROR); + } else { + runStatus* iret[posmax - posmin]; + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition) { + iret[idet] = new runStatus(ERROR); Task* task = new Task(new func0_t(&slsDetector::getReceiverStatus, - detectors[idet],iret[idet])); + detectors[idet], iret[idet])); threadpool->add_task(task); } } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ - if(iret[idet] != NULL){ - if(*iret[idet] == (int)ERROR) + for (int idet = posmin; idet < posmax; ++idet) { + if (idet != thisMultiDetector->masterPosition){ + if (iret[idet] != NULL) { + if (*iret[idet] == (int)ERROR) ret = ERROR; - if(*iret[idet] != IDLE) + if (*iret[idet] != IDLE) ret = *iret[idet]; delete iret[idet]; - }else ret = ERROR; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } } @@ -5848,172 +4767,127 @@ slsDetectorDefs::runStatus multiSlsDetector::getReceiverStatus(){ return ret; } - int multiSlsDetector::getFramesCaughtByAnyReceiver() { - int ret = 0; - int i = thisMultiDetector->masterPosition; - - if (i >=0 ) { - if (detectors[i]){ - ret=detectors[i]->getFramesCaughtByReceiver(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<masterPosition; + if (i >= 0) { + ret = detectors[i]->getFramesCaughtByReceiver(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + // return master receivers frames caught + return ret; } - for (int i=0; inumberOfDetectors; ++i) - if (detectors[i]){ - ret=detectors[i]->getFramesCaughtByReceiver(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<getFramesCaughtByReceiver(); + if (detectors[0]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); + return ret; + } return -1; } int multiSlsDetector::getFramesCaughtByReceiver() { - int ret=0,ret1=0; - int posmax = thisMultiDetector->numberOfDetectors; + int ret = 0, ret1 = 0; + int posmax = detectors.size(); - if(!threadpool){ + if (!threadpool) { cout << "Error in creating threadpool. Exiting" << endl; return -1; - }else{ + } else { int* iret[posmax]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(0); - Task* task = new Task(new func0_t(&slsDetector::getFramesCaughtByReceiver, - detectors[idet],iret[idet])); - threadpool->add_task(task); - } + for (unsigned int idet = 0; idet < detectors.size(); ++idet) { + iret[idet] = new int(0); + Task* task = new Task(new func0_t(&slsDetector::getFramesCaughtByReceiver, + detectors[idet], iret[idet])); + threadpool->add_task(task); } threadpool->startExecuting(); threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); } } - if ((!thisMultiDetector->numberOfDetectors) || (ret == -1)) + if ((!detectors.size()) || (ret == -1)) return ret; - ret=(int)(ret1/thisMultiDetector->numberOfDetectors); + ret = (int)(ret1 / detectors.size()); return ret; } - int multiSlsDetector::getReceiverCurrentFrameIndex() { - int ret=0,ret1=0; - for (int i=0; inumberOfDetectors; ++i) - if (detectors[i]){ - ret1+=detectors[i]->getReceiverCurrentFrameIndex(); - if(detectors[i]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors) - return ret; - ret=(int)(ret1/thisMultiDetector->numberOfDetectors); - - return ret; -} - - - -int multiSlsDetector::resetFramesCaught() { - - int ret=OK; - int posmax = thisMultiDetector->numberOfDetectors; - - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return FAIL; - }else{ - int* iret[posmax]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(OK); - Task* task = new Task(new func0_t(&slsDetector::resetFramesCaught, - detectors[idet],iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - - for(int idet=0; idetgetErrorMask()) - setErrorMask(getErrorMask()|(1<getReceiverCurrentFrameIndex(); + if (detectors[i]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << i)); } + if (!detectors.size()) + return ret; + ret = (int)(ret1 / detectors.size()); return ret; } +int multiSlsDetector::resetFramesCaught() { + return parallelCallDetectorMember(&slsDetector::resetFramesCaught); +} +int multiSlsDetector::createReceivingDataSockets(const bool destroy) { + if (destroy) { + cprintf(MAGENTA, "Going to destroy data sockets\n"); + //close socket + for (vector::const_iterator it = zmqSocket.begin(); it != zmqSocket.end(); ++it) { + delete(*it); + } + zmqSocket.clear(); -int multiSlsDetector::createReceivingDataSockets(const bool destroy){ + client_downstream = false; + cout << "Destroyed Receiving Data Socket(s)" << endl; + return OK; + } - //number of sockets - int numSockets = thisMultiDetector->numberOfDetectors; + cprintf(MAGENTA, "Going to create data sockets\n"); + + int numSockets = detectors.size(); int numSocketsPerDetector = 1; - if(getDetectorsType() == EIGER){ + if (getDetectorsType() == EIGER) { numSocketsPerDetector = 2; } numSockets *= numSocketsPerDetector; - if(destroy){ - cprintf(MAGENTA,"Going to destroy data sockets\n"); - //close socket - for(int i=0;igetClientStreamingPort().c_str(),"%d",&portnum); - portnum += (i%numSocketsPerDetector); - cout<<"ip to be set to :"<getClientStreamingIP().c_str()<getClientStreamingIP().c_str(), portnum); - if (zmqSocket[i]->IsError()) { + sscanf(detectors[i / numSocketsPerDetector]->getClientStreamingPort().c_str(), + "%d", &portnum); + portnum += (i % numSocketsPerDetector); + //cout<<"ip to be set to :"<getClientStreamingIP().c_str()<getClientStreamingIP().c_str(), + portnum); + zmqSocket.push_back(z); + printf("Zmq Client[%d] at %s\n", i, z->GetZmqServerAddress()); + } catch (...) { cprintf(RED, "Error: Could not create Zmq socket on port %d\n", portnum); createReceivingDataSockets(true); return FAIL; } - printf("Zmq Client[%d] at %s\n",i, zmqSocket[i]->GetZmqServerAddress()); } client_downstream = true; @@ -6021,255 +4895,235 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy){ return OK; } +void multiSlsDetector::readFrameFromReceiver() { - - - - - - - -int multiSlsDetector::getData(const int isocket, char* image, const int size, - uint64_t &acqIndex, uint64_t &frameIndex, uint32_t &subframeIndex, - string &filename, uint64_t &fileIndex) { - - //fail is on parse error or end of acquisition - if (!zmqSocket[isocket]->ReceiveHeader(isocket, acqIndex, frameIndex, subframeIndex, filename, fileIndex)) - return FAIL; - - //receiving incorrect size is replaced by 0xFF - zmqSocket[isocket]->ReceiveData(isocket, image, size); - - return OK; -} - - - - - -void multiSlsDetector::readFrameFromReceiver(){ - - //determine number of sockets - int numSockets = thisMultiDetector->numberOfDetectors; - int numSocketsPerSLSDetector = 1; - bool jungfrau = false; - bool eiger = false; - /*double* gdata = NULL;*/ - slsDetectorDefs::detectorType myDetType = getDetectorsType(); - switch(myDetType){ - case EIGER: - eiger = true; - numSocketsPerSLSDetector = 2; - numSockets *= numSocketsPerSLSDetector; - break; - case JUNGFRAU: - jungfrau = true; - break; - default: - break; - } - - //gui variables - uint64_t currentAcquisitionIndex = -1; - uint64_t currentFrameIndex = -1; - uint32_t currentSubFrameIndex = -1; - uint64_t currentFileIndex = -1; - string currentFileName = ""; - - //getting sls values - int slsdatabytes = 0, slsmaxchannels = 0, slsmaxX = 0, slsmaxY=0; - double bytesperchannel = 0; + int nX = thisMultiDetector->numberOfDetector[X]; // to copy data in multi module + int nY = thisMultiDetector->numberOfDetector[Y]; // for eiger, to reverse the data bool gappixelsenable = false; - if(detectors[0]){ - slsmaxchannels = detectors[0]->getMaxNumberOfChannels(X) * detectors[0]->getMaxNumberOfChannels(Y); - slsdatabytes = detectors[0]->getDataBytes(); - bytesperchannel = (double)slsdatabytes/(double)slsmaxchannels; - - - // recalculate with gap pixels (for >= 8 bit mode) - if (bytesperchannel >= 1.0) { - slsdatabytes = detectors[0]->getDataBytesInclGapPixels(); - slsmaxchannels = detectors[0]->getMaxNumberOfChannelsInclGapPixels(X)*detectors[0]->getMaxNumberOfChannelsInclGapPixels(Y); - } - - slsmaxX = (bytesperchannel >= 1.0) ? detectors[0]->getTotalNumberOfChannelsInclGapPixels(X) : detectors[0]->getTotalNumberOfChannels(X); - slsmaxY = (bytesperchannel >= 1.0) ? detectors[0]->getTotalNumberOfChannelsInclGapPixels(Y) : detectors[0]->getTotalNumberOfChannels(Y); - gappixelsenable = detectors[0]->enableGapPixels(-1) >= 1 ? true: false; - } - // max channel values - int maxX = (bytesperchannel >= 1.0) ? thisMultiDetector->numberOfChannelInclGapPixels[X] : thisMultiDetector->numberOfChannel[X]; - int maxY = (bytesperchannel >= 1.0) ? thisMultiDetector->numberOfChannelInclGapPixels[Y] : thisMultiDetector->numberOfChannel[Y]; - int multidatabytes = (bytesperchannel >= 1.0) ? thisMultiDetector->dataBytesInclGapPixels : thisMultiDetector->dataBytes; - int dr = bytesperchannel * 8; - if (myDetType == JUNGFRAUCTB) { - maxY = (int)(thisMultiDetector->timerValue[SAMPLES_JCTB] * 2)/25; // for moench 03 - maxX = 400; - dr = 16; + bool eiger = false; + if (getDetectorsType() == EIGER) { + eiger = true; + nX *= 2; + gappixelsenable = detectors[0]->enableGapPixels(-1) >= 1 ? true : false; } - - - //getting multi values - //calculating offsets (for eiger interleaving ports) - int offsetX[numSockets]; int offsetY[numSockets]; - int bottom[numSockets]; - if(eiger){ - for(int i=0; ioffsetY[i/numSocketsPerSLSDetector] + slsmaxY)) * maxX * bytesperchannel; - //the left half or right half - if(!(i%numSocketsPerSLSDetector)) - offsetX[i] = thisMultiDetector->offsetX[i/numSocketsPerSLSDetector]; - else - offsetX[i] = thisMultiDetector->offsetX[i/numSocketsPerSLSDetector] + (slsmaxX/numSocketsPerSLSDetector); - offsetX[i] *= bytesperchannel; - bottom[i] = detectors[i/numSocketsPerSLSDetector]->getFlippedData(X);/*only for eiger*/ - } - } - - int expectedslssize = slsdatabytes/numSocketsPerSLSDetector; - char* image = new char[expectedslssize](); - char* multiframe = new char[multidatabytes](); - char* multiframegain = NULL; - char* multigappixels = NULL; // used only for 4 bit mode with gap pixels enabled - if (jungfrau) - multiframegain = new char[multidatabytes](); - - - bool runningList[numSockets]; - bool connectList[numSockets]; - for(int i = 0; i < numSockets; ++i) { - if(!zmqSocket[i]->Connect()) { + bool runningList[zmqSocket.size()], connectList[zmqSocket.size()]; + int numRunning = 0; + for (unsigned int i = 0; i < zmqSocket.size(); ++i) { + if (!zmqSocket[i]->Connect()) { connectList[i] = true; runningList[i] = true; + ++numRunning; } else { + // to remember the list it connected to, to disconnect later connectList[i] = false; - cprintf(RED,"Error: Could not connect to socket %s\n",zmqSocket[i]->GetZmqServerAddress()); + cprintf(RED, "Error: Could not connect to socket %s\n", + zmqSocket[i]->GetZmqServerAddress()); runningList[i] = false; } } - int numRunning = numSockets; - + int numConnected = numRunning; + bool data = false; + char* image = NULL; + char* multiframe = NULL; + char* multigappixels = NULL; + int multisize = 0; + // only first message header + uint32_t size = 0, nPixelsX = 0, nPixelsY = 0, dynamicRange = 0; + float bytesPerPixel = 0; + // header info every header + string currentFileName = ""; + uint64_t currentAcquisitionIndex = -1, currentFrameIndex = -1, currentFileIndex = -1; + uint32_t currentSubFrameIndex = -1, coordX = -1, coordY = -1, flippedDataX = -1; //wait for real time acquisition to start bool running = true; sem_wait(&sem_newRTAcquisition); - if(checkJoinThread()) + if (checkJoinThread()) running = false; + //exit when checkJoinThread() (all sockets done) + while (running) { - //exit when last message for each socket received - while(running){ - memset(multiframe,0xFF,slsdatabytes*thisMultiDetector->numberOfDetectors); //reset frame memory + // reset data + data = false; + if (multiframe != NULL) + memset(multiframe, 0xFF, multisize); //get each frame - for(int isocket=0; isocketReceiveHeader(isocket, doc, + SLS_DETECTOR_JSON_HEADER_VERSION)) { + zmqSocket[isocket]->CloseHeaderMessage(); + // parse error, version error or end of acquisition for socket + runningList[isocket] = false; + --numRunning; + continue; + } + + // if first message, allocate (all one time stuff) + if (image == NULL) { + // allocate + size = doc["size"].GetUint(); + multisize = size * zmqSocket.size(); + image = new char[size]; + multiframe = new char[multisize]; + memset(multiframe, 0xFF, multisize); + // dynamic range + dynamicRange = doc["bitmode"].GetUint(); + bytesPerPixel = (float)dynamicRange / 8; + // shape + nPixelsX = doc["shape"][0].GetUint(); + nPixelsY = doc["shape"][1].GetUint(); + +#ifdef VERBOSE + cprintf(BLUE, "(Debug) One Time Header Info:\n" + "size: %u\n" + "multisize: %u\n" + "dynamicRange: %u\n" + "bytesPerPixel: %f\n" + "nPixelsX: %u\n" + "nPixelsY: %u\n", + size, multisize, dynamicRange, bytesPerPixel, + nPixelsX, nPixelsY); +#endif + } + // each time, parse rest of header + currentFileName = doc["fname"].GetString(); + currentAcquisitionIndex = doc["acqIndex"].GetUint64(); + currentFrameIndex = doc["fIndex"].GetUint64(); + currentFileIndex = doc["fileIndex"].GetUint64(); + currentSubFrameIndex = doc["expLength"].GetUint(); + coordX = doc["xCoord"].GetUint(); + coordY = doc["yCoord"].GetUint(); + if (eiger) + coordY = (nY - 1) - coordY; + //cout << "X:" << doc["xCoord"].GetUint() <<" Y:"<CloseHeaderMessage(); } - //assemble data with interleaving - if(eiger){ + // DATA + data = true; + zmqSocket[isocket]->ReceiveData(isocket, image, size); - //bottom - if(bottom[isocket]){ - //if((((isocket/numSocketsPerSLSDetector)+1)%2) == 0){ - for(int i=0;ioffsetY[isocket] + i) * maxX) + thisMultiDetector->offsetX[isocket])* (int)bytesperchannel, - (char*)image+ (i*slsmaxX*(int)bytesperchannel), - (slsmaxX*(int)bytesperchannel)); - } } } - } + //send data to callback + if (data) { + // 4bit gap pixels + if (dynamicRange == 4 && gappixelsenable) { + int n = processImageWithGapPixels(multiframe, multigappixels); + nPixelsX = thisMultiDetector->numberOfChannelInclGapPixels[X]; + nPixelsY = thisMultiDetector->numberOfChannelInclGapPixels[Y]; + thisData = new detectorData(NULL, NULL, NULL, getCurrentProgress(), + currentFileName.c_str(), nPixelsX, nPixelsY, + multigappixels, n, dynamicRange, currentFileIndex); + } + // normal pixels + else { + thisData = new detectorData(NULL, NULL, NULL, getCurrentProgress(), + currentFileName.c_str(), nPixelsX, nPixelsY, + multiframe, multisize, dynamicRange, currentFileIndex); + } + dataReady(thisData, currentFrameIndex, + ((dynamicRange == 32) ? currentSubFrameIndex : -1), + pCallbackArg); + delete thisData; + setCurrentProgress(currentAcquisitionIndex + 1); + } //all done - if(!numRunning){ - // let main thread know that all dummy packets have been received (also from external process), + if (!numRunning) { + // let main thread know that all dummy packets have been received + //(also from external process), // main thread can now proceed to measurement finished call back sem_post(&sem_endRTAcquisition); // wait for next scan/measurement, else join thread sem_wait(&sem_newRTAcquisition); //done with complete acquisition - if(checkJoinThread()) - break; - else{ - //starting a new scan/measurement (got dummy data) - for(int i = 0; i < numSockets; ++i) - runningList[i] = true; - numRunning = numSockets; + if (checkJoinThread()) running = false; - } - } - - //send data to callback - if(running){ - if (gappixelsenable && bytesperchannel < 1) {//inside this function, allocate if it doesnt exist - int nx = thisMultiDetector->numberOfChannelInclGapPixels[X]; - int ny = thisMultiDetector->numberOfChannelInclGapPixels[Y]; - int n = processImageWithGapPixels(multiframe, multigappixels); - thisData = new detectorData(NULL,NULL,NULL,getCurrentProgress(),currentFileName.c_str(), nx, ny,multigappixels, n, dr, currentFileIndex); - } else { - thisData = new detectorData(NULL,NULL,NULL,getCurrentProgress(),currentFileName.c_str(),maxX,maxY,multiframe, multidatabytes, dr, currentFileIndex); + //starting a new scan/measurement (got dummy data) + for (unsigned int i = 0; i < zmqSocket.size(); ++i) + runningList[i] = connectList[i]; + numRunning = numConnected; } - dataReady(thisData, currentFrameIndex, (((dr == 32) && (eiger)) ? currentSubFrameIndex : -1), pCallbackArg); - delete thisData; - //cout<<"Send frame #"<< currentFrameIndex << " to gui"<Disconnect(); //free resources - delete [] image; - delete[] multiframe; - if (jungfrau) - delete [] multiframegain; + if (image != NULL) + delete[] image; + if (multiframe != NULL) + delete[] multiframe; if (multigappixels != NULL) - delete [] multigappixels; - + delete[] multigappixels; } - -/** eiger 4 bit mode */ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) { - int nxb = thisMultiDetector->numberOfDetector[X] * (512 + 3); - int nyb = thisMultiDetector->numberOfDetector[Y] * (256 + 1); + // eiger 4 bit mode + int nxb = thisMultiDetector->numberOfDetector[X] * (512 + 3); + int nyb = thisMultiDetector->numberOfDetector[Y] * (256 + 1); int gapdatabytes = nxb * nyb; int nxchip = thisMultiDetector->numberOfDetector[X] * 4; @@ -6281,12 +5135,10 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) { // fill value memset(gpImage, 0xFF, gapdatabytes); - const int b1chipx = 128; const int b1chipy = 256; - char* src = 0; - char* dst = 0; - + char* src = 0; + char* dst = 0; // copying line by line src = image; @@ -6297,7 +5149,7 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) { memcpy(dst, src, b1chipx); src += b1chipx; dst += b1chipx; - if ((col+1)%4) + if ((col + 1) % 4) ++dst; } } @@ -6305,8 +5157,6 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) { dst += (2 * nxb); } - - // vertical filling of values { uint8_t temp, g1, g2; @@ -6316,18 +5166,18 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) { for (int ichipy = 0; ichipy < b1chipy; ++ichipy) { //for each row in a chip for (int col = 0; col < nxchip; ++col) { dst += b1chipx; - mod = (col+1)%4; + mod = (col + 1) % 4; // copy gap pixel(chip 0, 1, 2) if (mod) { // neighbouring gap pixels to left - temp = (*((uint8_t*)(dst-1))); - g1 = ((temp & 0xF) / 2); - (*((uint8_t*)(dst-1))) = (temp & 0xF0) + g1; + temp = (*((uint8_t*)(dst - 1))); + g1 = ((temp & 0xF) / 2); + (*((uint8_t*)(dst - 1))) = (temp & 0xF0) + g1; // neighbouring gap pixels to right - temp = (*((uint8_t*)(dst+1))); - g2 = ((temp >> 4) / 2); - (*((uint8_t*)(dst+1))) = (g2 << 4) + (temp & 0x0F); + temp = (*((uint8_t*)(dst + 1))); + g2 = ((temp >> 4) / 2); + (*((uint8_t*)(dst + 1))) = (g2 << 4) + (temp & 0x0F); // gap pixels (*((uint8_t*)dst)) = (g1 << 4) + g2; @@ -6347,671 +5197,149 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) { { uint8_t temp, g1, g2; char* dst_prevline = 0; - dst = gpImage; + dst = gpImage; for (int row = 0; row < nychip; ++row) { // for each chip in a row - dst += (b1chipy * nxb); - // horizontal copying of gap pixels from neighboring past line (bottom parts) - if (row < nychip-1) { - dst_prevline = dst - nxb; - for (int gapline = 0; gapline < nxb; ++gapline) { - temp = (*((uint8_t*)dst_prevline)); - g1 = ((temp >> 4) / 2); - g2 = ((temp & 0xF) / 2); - (*((uint8_t*)dst_prevline)) = (g1 << 4) + g2; - (*((uint8_t*)dst)) = (*((uint8_t*)dst_prevline)); - ++dst; - ++dst_prevline; - } + dst += (b1chipy * nxb); + // horizontal copying of gap pixels from neighboring past line (bottom parts) + if (row < nychip - 1) { + dst_prevline = dst - nxb; + for (int gapline = 0; gapline < nxb; ++gapline) { + temp = (*((uint8_t*)dst_prevline)); + g1 = ((temp >> 4) / 2); + g2 = ((temp & 0xF) / 2); + (*((uint8_t*)dst_prevline)) = (g1 << 4) + g2; + (*((uint8_t*)dst)) = (*((uint8_t*)dst_prevline)); + ++dst; + ++dst_prevline; } + } - // horizontal copying of gap pixels from neihboring future line (top part) - if (row > 0) { - dst -= ((b1chipy + 1) * nxb); - dst_prevline = dst + nxb; - for (int gapline = 0; gapline < nxb; ++gapline) { - temp = (*((uint8_t*)dst_prevline)); - g1 = ((temp >> 4) / 2); - g2 = ((temp & 0xF) / 2); - temp = (g1 << 4) + g2; - (*((uint8_t*)dst_prevline)) = temp; - (*((uint8_t*)dst)) = temp; - ++dst; - ++dst_prevline; - } - dst += ((b1chipy + 1) * nxb); + // horizontal copying of gap pixels from neihboring future line (top part) + if (row > 0) { + dst -= ((b1chipy + 1) * nxb); + dst_prevline = dst + nxb; + for (int gapline = 0; gapline < nxb; ++gapline) { + temp = (*((uint8_t*)dst_prevline)); + g1 = ((temp >> 4) / 2); + g2 = ((temp & 0xF) / 2); + temp = (g1 << 4) + g2; + (*((uint8_t*)dst_prevline)) = temp; + (*((uint8_t*)dst)) = temp; + ++dst; + ++dst_prevline; } + dst += ((b1chipy + 1) * nxb); + } dst += nxb; } } - - - - - return gapdatabytes; } +int multiSlsDetector::enableWriteToFile(int enable) { + return callDetectorMember(&slsDetector::enableWriteToFile, enable); +} - - -int multiSlsDetector::lockReceiver(int lock) { - - int ret=-100, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->lockReceiver(lock); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - s=detectors[idet]->getReceiverLastClientIP(); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - iv=detectors[idet]->exitReceiver(); - if (iv==OK) - ival=iv; - } - } - return ival; -} - - - -int multiSlsDetector::enableWriteToFile(int enable){ - int ret=-100, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->enableWriteToFile(enable); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->overwriteFile(enable); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - //if the detector has error - if(multiMask&(1<getErrorMask(); -#ifdef VERYVERBOSE - //append sls det error mask - sprintf(sNumber,"0x%lx",slsMask); - retval.append("Error Mask " + string(sNumber)+string("\n")); -#endif - //get the error critical level - if((slsMask>0xFFFFFFFF)|critical) - critical = 1; - //append error message - retval.append(errorDefs::getErrorMessage(slsMask)); - - } - } - } - } - return retval; -} - - -int64_t multiSlsDetector::clearAllErrorMask(){ - clearErrorMask(); - clearNotAddedList(); - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]) - detectors[idet]->clearErrorMask(); - - return getErrorMask(); -} - - - -int multiSlsDetector::calibratePedestal(int frames){ - int ret=-100, ret1; - - for (int idet=0; idetnumberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->calibratePedestal(frames); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setReadReceiverFrequency(freq); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) { - if (detectors[idet]) { - ret1=detectors[idet]->setReceiverReadTimer(time_in_ms); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<= 0){ - + if (enable >= 0) { //destroy data threads if (!enable) createReceivingDataSockets(true); - //create data threads else { - if(createReceivingDataSockets() == FAIL){ + if (createReceivingDataSockets() == FAIL) { std::cout << "Could not create data threads in client." << std::endl; //only for the first det as theres no general one - setErrorMask(getErrorMask()|(1<<0)); - detectors[0]->setErrorMask((detectors[0]->getErrorMask())|(DATA_STREAMING)); + setErrorMask(getErrorMask() | (1 << 0)); + detectors[0]->setErrorMask((detectors[0]->getErrorMask()) | + (DATA_STREAMING)); } } } return client_downstream; } -int multiSlsDetector::enableDataStreamingFromReceiver(int enable){ - if(enable >= 0){ - int ret=-100; - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return -1; - }else{ - //return storage values - int* iret[thisMultiDetector->numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func1_t(&slsDetector::enableDataStreamingFromReceiver, - detectors[idet],enable,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<receiver_upstream = ret; +int multiSlsDetector::enableDataStreamingFromReceiver(int enable) { + if (enable >= 0) { + thisMultiDetector->receiver_upstream = parallelCallDetectorMember( + &slsDetector::enableDataStreamingFromReceiver, enable); } - return thisMultiDetector->receiver_upstream; } -int multiSlsDetector::enableReceiverCompression(int i){ - int ret=-100,ret1; - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->enableReceiverCompression(i); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->enableTenGigabitEthernet(i); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setReceiverFifoDepth(i); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setReceiverSilentMode(i); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1< 0) { + while (fread(&word, sizeof(word), 1, fd)) { + for (unsigned int idet = 0; idet < detectors.size(); ++idet) + detectors[idet]->setCTBWord(addr, word); + ++addr; + } - int addr=0; - - FILE *fd=fopen(fname.c_str(),"r"); - if (fd>0) { - while (fread(&word, sizeof(word), 1,fd)) { - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]){ - detectors[idet]->setCTBWord(addr,word); - } - // cout << hex << addr << " " << word << dec << endl; - ++addr; - } - - fclose(fd); - } else - return -1; - - - - - - return addr; + fclose(fd); + } else + return -1; + return addr; } - /** 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 multiSlsDetector::setCTBWord(int addr,uint64_t word) { - uint64_t ret=-100,ret1; - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setCTBWord(addr, word); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<setCTBPatLoops(level, start, stop, n); + if (detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask() | (1 << idet)); + if (ret == -100) + ret = ret1; + else if (ret != ret1) + ret = -1; + } return ret; } - - - - /** 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 multiSlsDetector::setCTBPatLoops(int level,int &start, int &stop, int &n) { - - - int ret=-100,ret1; - for (int idet=0; idetnumberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setCTBPatLoops(level, start, stop, n); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setCTBPatWaitAddr(level, addr); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors; ++idet) - if (detectors[idet]){ - ret1=detectors[idet]->setCTBPatWaitTime(level,t); - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func3_t(&slsDetector::pulsePixel, - detectors[idet],n,x,y,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func3_t(&slsDetector::pulsePixelNMove, - detectors[idet],n,x,y,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func1_t(&slsDetector::pulseChip, - detectors[idet],n,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<acquiringFlag = b; -} - -bool multiSlsDetector::getAcquiringFlag(){ - return thisMultiDetector->acquiringFlag; -} - - -bool multiSlsDetector::isAcquireReady() { - if (thisMultiDetector->acquiringFlag) { - std::cout << "Acquire has already started. If previous acquisition terminated unexpectedly, reset busy flag to restart.(sls_detector_put busy 0)" << std::endl; - return FAIL; - } - - thisMultiDetector->acquiringFlag = true; - return OK; + return callDetectorMember(&slsDetector::setCTBPatWaitTime, level, t); } diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h index a0875185d..ae6c03866 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -1,1577 +1,1897 @@ -/******************************************************************* - -Date: $Date$ -Revision: $Rev$ -Author: $Author$ -URL: $URL$ -ID: $Id$ - -********************************************************************/ - - - #ifndef MULTI_SLS_DETECTOR_H #define MULTI_SLS_DETECTOR_H +/** + @libdoc The multiSlsDetector class is used to operate several slsDetectors in parallel. + * @short This is the base class for multi detector system functionalities + * @author Anna Bergamaschi + */ + #include "slsDetectorUtils.h" class slsDetector; +class SharedMemory; class ThreadPool; class ZmqSocket; -//#include "sls_detector_defs.h" + +#include +#include - -//using namespace std; - - - -/** - * - * - @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 - -*/ +#define MULTI_SHMVERSION 0x180629 +#define SHORT_STRING_LENGTH 50 +#define DATE_LENGTH 30 class multiSlsDetector : public slsDetectorUtils { - //public virtual slsDetectorUtils { - - - 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; - - - /** 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; - - /** Number of detectors operated at once */ - int numberOfDetector[2]; - - /** Ids of the detectors to be operated at once */ - int detectorIds[MAXDET]; - - - /** 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]; - - /** total number of channels for all detectors */ - int maxNumberOfChannels; - - /** max number of channels for all detectors in one dimension*/ - int maxNumberOfChannel[2]; - - /** 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]; - - /** timer values */ - int64_t timerValue[MAX_TIMERS]; // needed?!?!?!? - - /** detector settings (standard, fast, etc.) */ - detectorSettings currentSettings; // needed?!?!?!? - /** detector threshold (eV) */ - int currentThresholdEV; // needed?!?!?!? - - - /** 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; - - /** corrections to be applied to the data \see ::correctionFlags */ - int correctionMask; - /** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */ - int threadedProcessing; - /** dead time (in ns) for rate corrections */ - double tDead; - - - - /** directory where the flat field files are stored */ - char flatFieldDir[MAX_STR_LENGTH]; - /** file used for flat field corrections */ - char flatFieldFile[MAX_STR_LENGTH]; - - - /** file with the bad channels */ - char badChanFile[MAX_STR_LENGTH]; - - - /** angular conversion file */ - char angConvFile[MAX_STR_LENGTH]; - - - - - - - - /** array of angular conversion constants for each module \see ::angleConversionConstant */ - //angleConversionConstant angOff[MAXMODS]; - /** angular direction (1 if it corresponds to the encoder direction i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */ - int angDirection; - /** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */ - double fineOffset; - /** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */ - double globalOffset; - /** bin size for data merging */ - double binSize; - - - - //X and Y displacement - double sampleDisplacement[2]; - - /** number of positions at which the detector should acquire */ - int numberOfPositions; - /** list of encoder positions at which the detector should acquire */ - double detPositions[MAXPOS]; - - - - - - - /** Scans and scripts */ - - int actionMask; - - //int actionMode[MAX_ACTIONS]; - 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; - - /* - @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(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;}; - - /** - * Creates all the threads in the threadpool - \returns OK or FAIL - */ - 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 - \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); - - /** 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(detectorType type, int pos=-1); - - /**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); - - /**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); - - - - - string setHostname(const char*, int pos=-1); - - - string getHostname(int pos=-1); - using slsDetectorBase::getDetectorType; - - 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);}; - - string sgetDetectorsType(int pos=-1); - string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(setDetectorsType(type, pos));}; // - string ssetDetectorsType(string s, int pos=-1);//{return getDetectorType(setDetectorsType(getDetectorType(s),pos));}; // should decode detector type - - - /** 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); - - - - /** 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); - - - /** returns the number of detectors in the multidetector structure - \returns number of detectors */ - 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 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];}; - - int getMaxMods(); - int getNMods(); - int getMaxMod(dimension d); - int getNMod(dimension d); - - int getChansPerMod(int imod=0); - - angleConversionConstant *getAngularConversionPointer(int imod=0); - - - int getTotalNumberOfChannels(); - - int getTotalNumberOfChannels(dimension d); - - int getTotalNumberOfChannelsInclGapPixels(dimension d); - - int getMaxNumberOfChannels(); - - int getMaxNumberOfChannels(dimension d); - - int getMaxNumberOfChannelsInclGapPixels(dimension d); - - int getMaxNumberOfChannelsPerDetector(dimension d){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); - - 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); - - /** 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); - - - - /** 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); - - /** - 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 *\/ */ - /* }; */ - - synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); - - - /** 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); - - /** 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 - */ - string checkOnline(); - - /** @short activates the detector (detector specific) - \param enable can be: -1 returns wether the detector is in active (1) or inactive (0) state - \returns 0 (inactive) or 1 (active) - */ - int activate(int const enable=GET_ONLINE_FLAG); - - /** - \returns 1 if the detector structure has already be initlialized with the given id and belongs to this multiDetector instance, 0 otherwise */ - int exists(); - - - /** - Prints receiver configuration - \returns OK or FAIL - */ - int printReceiverConfiguration(); - - /** - Purely virtual function - Should be implemented in the specific detector class - /sa mythenDetector::readConfigurationFile - */ - - int readConfigurationFile(string const fname); - /** - Purely virtual function - Should be implemented in the specific detector class - /sa mythenDetector::writeConfigurationFile - */ - int writeConfigurationFile(string const fname); - - - - /* I/O */ - - - - /* 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); - - /** - 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); - - /** - get detector settings - \param imod module number (-1 all) - \returns current settings - */ - 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); - - - /** - 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); - - - - - 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); - string getSettingsFile(); - - - int decodeNMod(int i, int &idet, int &imod); - - /** programs FPGA with pof file - \param fname file name - \returns OK or FAIL - */ - int programFPGA(string fname); - - /** resets FPGA - \returns OK or FAIL - */ - int resetFPGA(); - - /** power on/off the chip - \param ival on is 1, off is 0, -1 to get - \returns OK or FAIL - */ - int powerChip(int ival= -1); - - /** automatic comparator disable for Jungfrau only - \param ival on is 1, off is 0, -1 to get - \returns OK or FAIL - */ - int setAutoComparatorDisableMode(int ival= -1); - - /** loads the modules settings/trimbits reading from a file - file name extension is automatically generated! */ - int loadSettingsFile(string fname, int nmod=-1); - - /** gets the modules settings/trimbits and writes them to file - file name extension is automatically generated! */ - int saveSettingsFile(string fname, int nmod=-1); - - - /** sets all the trimbits to a particular value - \param val trimbit value - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int setAllTrimbits(int val, int imod=-1); - - - /** loads the modules calibration data reading from a file - file name extension is automatically generated! */ - int loadCalibrationFile(string fname, int nmod=-1); - - /** gets the modules calibration data and writes them to file - file name extension is automatically generated! */ - int saveCalibrationFile(string fname, int nmod=-1); - - - - - - - - - - - - - - - - - - - - // Acquisition functions - /** - prepares detector for acquisition - \returns OK if all detectors are properly started, FAIL otherwise - */ - int prepareAcquisition(); - - /** - prepares detector for acquisition - \returns OK if all detectors are properly started, FAIL otherwise - */ - int cleanupAcquisition(); - - /** - start detector acquisition (master is started as last) - \returns OK if all detectors are properly started, FAIL otherwise - */ - int startAcquisition(); - - /** - stop detector acquisition (master firtst) - \returns OK/FAIL - */ - int stopAcquisition(); - - /** - start readout (without exposure or interrupting exposure) (master first) - \returns OK/FAIL - */ - int startReadOut(); - - - - /** - start detector acquisition and read all data putting them a data queue - \returns pointer to the front of the data queue - \sa startAndReadAllNoWait getDataFromDetector dataQueue - */ - int* startAndReadAll(); - - /** - start detector acquisition and read out, but does not read data from socket - - */ - 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(); - /** - receives a data frame from the detector socket - \returns pointer to the data or NULL. If NULL disconnects the socket - \sa 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(); - - /** - 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(); - - - /** - pops the data from the data queue - \returns pointer to the popped data or NULL if the queue is empty. - \sa dataQueue - */ - 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(); - - - - - /** - resets the raw data queue - \sa dataQueue - */ - void resetDataQueue(); - - /** - resets the postprocessed data queue - \sa finalDataQueue - */ - void resetFinalDataQueue(); - - - - - - - - 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); - /** - 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); - - /* /\** */ - /* 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 - /** - 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 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); - -/** - verifies that min is less than max - \param n number of rois - \param r array of rois - */ - 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); - - /** - 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); - - - //Corrections - - - /** - set flat field corrections - \param fname name of the flat field file (or "" if disable) - \returns 0 if disable (or file could not be read), >0 otherwise - */ - int setFlatFieldCorrection(string fname=""); - - /** - set flat field corrections - \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) - \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) - \returns 0 if ff correction disabled, >0 otherwise - */ - int setFlatFieldCorrection(double *corr, double *ecorr=NULL); - - /** - get flat field corrections - \param corr if !=NULL will be filled with the correction coefficients - \param ecorr if !=NULL will be filled with the correction coefficients errors - \returns 0 if ff correction disabled, >0 otherwise - */ - int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL); - - - - - - - - - /** - set rate correction - \param t dead time in ns - if 0 disable correction, if >0 set dead time to t, if <0 set deadtime to default dead time for current settings - \returns 0 if rate correction disabled, >0 otherwise - */ - int setRateCorrection(double t=0); - - - /** - get rate correction - \param t reference for dead time - \returns 0 if rate correction disabled, >0 otherwise - */ - int getRateCorrection(double &t); - - - /** - get rate correction tau - \returns 0 if rate correction disabled, otherwise the tau used for the correction - */ - double getRateCorrectionTau(); - /** - get rate correction - \returns 0 if rate correction disabled, >0 otherwise - */ - int getRateCorrection(); - - /** - set bad channels correction - \param fname file with bad channel list ("" disable) - \returns 0 if bad channel disabled, >0 otherwise - */ - int setBadChannelCorrection(string fname=""); - - - 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); - - - - /** - 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); - - - - int readAngularConversionFile(string fname); - - int writeAngularConversion(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); - - - - - /** - flat field correct data - \param datain data - \param errin error on data (if<=0 will default to sqrt(datain) - \param dataout corrected data - \param errout error on corrected data - \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); - - /** - flat field correct data - \param datain data array - \param errin error array on data (if NULL will default to sqrt(datain) - \param dataout array of corrected data - \param errout error on corrected data (if not NULL) - \returns 0 - */ - int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); - - - - /** - rate correct data - \param datain data - \param errin error on data (if<=0 will default to sqrt(datain) - \param dataout corrected data - \param errout error on corrected data - \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); - - /** - 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); - - /** - turns off server - */ - int exitServer(); - - /** 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 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! - - /** 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); - - /** - 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); - - /** - 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); - - /** - 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); - - /** - 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); - - /** - configure channel - \param reg channel register - \param ichan channel number (-1 all) - \param ichip chip number (-1 all) - \param imod module number (-1 all) - \returns current register value - \sa ::sls_detector_channel - */ - int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); - /** - 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) ; - - - - /** - get run status - \returns status mask - */ - //virtual runStatus getRunStatus()=0; - runStatus getRunStatus(); - - - - - - /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ - char* getSettingsDir(); - /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ - char* setSettingsDir(string s); - /** - returns the location of the calibration files - \sa sharedSlsDetector - */ - char* getCalDir(); - /** - sets the location of the calibration files - \sa sharedSlsDetector - */ - char* setCalDir(string s); - - - 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 - - */ - string setNetworkParameter(networkParameter, std::string); - int setPort(portType, int); - int lockServer(int); - - string getLastClientIP(); - - /** - configures mac for gotthard readout - \returns OK or FAIL - */ - int configureMAC(); - - 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); - - /** - * 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); - - - - - - uint32_t writeRegister(uint32_t addr, uint32_t val); - - - 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); - - - /** - 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); - - - - 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); - - - 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,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); - - /** - - 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(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(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(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(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(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); - - /** set/get counter bit in detector - * @param i is -1 to get, 0 to reset and any other value to set the counter bit - /returns the counter bit in detector - */ - int setCounterBit(int i = -1); - - - int getMoveFlag(int imod); - - - 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;}; - - - - //receiver - - /** - calls setReceiverTCPSocket if online and sets the flag - */ - int setReceiverOnline(int const online=GET_ONLINE_FLAG); - - /** - Checks if the receiver is really online - */ - string checkReceiverOnline(); - - - /** - Sets up the file directory - @param s file directory - \returns file dir - */ - string setFilePath(string s=""); - - /** - Sets up the file name - @param s file name - \returns file name - */ - string setFileName(string s=""); - - /** - Sets up the file format - @param f file format - \returns 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); - - /** - \returns file dir - */ - string getFilePath(){return setFilePath();}; - - /** - \returns file name - */ - string getFileName(){return setFileName();}; - - /** - \returns file name - */ - fileFormat getFileFormat(){return setFileFormat();}; - - /** - \returns file index - */ - int getFileIndex(){return setFileIndex();}; - - - /** Starts the listening mode of receiver - \returns OK or FAIL - */ - int startReceiver(); - - /** Stops the listening mode of receiver - \returns OK or FAIL - */ - 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(); - - /** gets the status of the listening mode of receiver - \returns status - */ - runStatus getReceiverStatus(); - - /** gets the number of frames caught by receiver - \returns number of frames caught by receiver - */ - int getFramesCaughtByReceiver(); - - /** 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(); - - /** gets the current frame index of receiver - \returns current frame index of receiver - */ - int getReceiverCurrentFrameIndex(); - - /** - * 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); - - - - /** Reads frames from receiver through a constant socket - */ - void readFrameFromReceiver(); - /** Locks/Unlocks the connection to the receiver - /param lock sets (1), usets (0), gets (-1) the lock - /returns lock status of the receiver - */ - int lockReceiver(int lock=-1); - - /** - Returns the IP of the last client connecting to the receiver - */ - string getReceiverLastClientIP(); - - /** - Turns off the receiver server! - */ - int exitReceiver(); - - /** - 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); - - /** - 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 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 - /returns error message else an empty string - */ - string getErrorMessage(int &critical); - - /** Clears error mask of both multi and sls - /returns error mask - */ - int64_t clearAllErrorMask(); - - /** Starts acquisition, calibrates pedestal and writes to fpga - /returns number of frames - */ - int calibratePedestal(int frames = 0); - - /** 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); - - /** 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); - - - /** - * 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); - - - /** 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 - /returns data compression in receiver - */ - int enableReceiverCompression(int i = -1); - - /** 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); - - /** 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); - - /** 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); - - - - /******** CTB funcs */ - - /** opens pattern file and sends pattern to CTB - @param fname pattern file to open - @returns OK/FAIL - */ - int setCTBPattern(string fname); - - - /** Writes a pattern word to the CTB - @param addr address of the word, -1 is I/O control register, -2 is clk control register - @param word 64bit word to be written, -1 gets - @returns actual value - */ - uint64_t setCTBWord(int addr,uint64_t word=-1); - - /** Sets the pattern or loop limits in the CTB - @param level -1 complete pattern, 0,1,2, loop level - @param start start address if >=0 - @param stop stop address if >=0 - @param n number of loops (if level >=0) - @returns OK/FAIL - */ - int setCTBPatLoops(int level,int &start, int &stop, int &n); - - - /** Sets the wait address in the CTB - @param level 0,1,2, wait level - @param addr wait address, -1 gets - @returns actual value - */ - int setCTBPatWaitAddr(int level, int addr=-1); - - /** Sets the wait time in the CTB - @param level 0,1,2, wait level - @param t wait time, -1 gets - @returns actual value - */ - int setCTBPatWaitTime(int level, uint64_t t=-1); - - /** - Pulse Pixel - \param n is number of times to pulse - \param x is x coordinate - \param y is y coordinate - \returns OK or FAIL - */ - int pulsePixel(int n=0,int x=0,int y=0); - - /** - Pulse Pixel and move by a relative value - \param n is number of times to pulse - \param x is relative x value - \param y is relative y value - \returns OK or FAIL - */ - int pulsePixelNMove(int n=0,int x=0,int y=0); - - /** - Pulse Chip - \param n is number of times to pulse - \returns OK or FAIL - */ - int pulseChip(int n=0); - - /** - Set acquiring flag in shared memory - \param b acquiring flag - */ - void setAcquiringFlag(bool b=false); - - /** - Get acquiring flag from shared memory - \returns acquiring flag - */ - bool getAcquiringFlag(); - - /** - * Check if acquiring flag is set, set error if set - * \returns FAIL if not ready, OK if ready - */ - bool isAcquireReady(); - - private: /** - * Gets data from socket - * @param isocket socket index - * @param image image buffer - * @param size size of image - * @param acqIndex address of acquisition index - * @param frameIndex address of frame index - * @param subframeIndex address of subframe index - * @param filename address of file name - * @param fileindex address of file index + * @short structure allocated in shared memory to store detector settings for IPC and cache */ - int getData(const int isocket, char* image, const int size, - uint64_t &acqIndex, uint64_t &frameIndex, uint32_t &subframeIndex, - string &filename, uint64_t &fileIndex); + typedef struct sharedMultiSlsDetector { + /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/ + + /** shared memory version */ + int shmversion; + + /** last process id accessing the shared memory */ + pid_t lastPID; + + /** last user name accessing the shared memory */ + char lastUser[SHORT_STRING_LENGTH]; + + /** last time stamp when accessing the shared memory */ + char lastDate[SHORT_STRING_LENGTH]; + + /** number of sls detectors in shared memory */ + int numberOfDetectors; + + /** END OF FIXED PATTERN -----------------------------------------------*/ + + + + + /** Number of detectors operated at once */ + int numberOfDetector[2]; + + /** 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; + + /** 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]; + + /** total number of channels for all detectors */ + int maxNumberOfChannels; + + /** max number of channels for all detectors in one dimension*/ + int maxNumberOfChannel[2]; + + /** 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]; + + /** 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]; + + /** path of the output files */ + char filePath[MAX_STR_LENGTH]; + + /** max frames per file */ + int framesPerFile; + + /** file format*/ + fileFormat fileFormatType; + + /** corrections to be applied to the data \see ::correctionFlags */ + int correctionMask; + + /** threaded processing flag (i.e. if data are processed and written to + * file in a separate thread) */ + int threadedProcessing; + + /** dead time (in ns) for rate corrections */ + double tDead; + + /** directory where the flat field files are stored */ + char flatFieldDir[MAX_STR_LENGTH]; + + /** file used for flat field corrections */ + char flatFieldFile[MAX_STR_LENGTH]; + + /** file with the bad channels */ + char badChanFile[MAX_STR_LENGTH]; + + /** angular conversion file */ + char angConvFile[MAX_STR_LENGTH]; + + /** 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; + + //X and Y displacement + double sampleDisplacement[2]; + + /** number of positions at which the detector should acquire */ + int numberOfPositions; + + /** 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; + + + /** + * Constructor + * @param id multi detector id + * @param verify true to verify if shared memory version matches existing one + * @param update true to update last user pid, date etc + */ + multiSlsDetector(int id = 0, bool verify = true, bool update = true); + + /** + * Destructor + */ + virtual ~multiSlsDetector(); + + /** + * returns true. Used when reference is slsDetectorUtils and to determine + * if command can be implemented as slsDetector/multiSlsDetector object/ + */ + bool isMultiSlsDetectorClass(); + + /** + * Creates/open shared memory, initializes detector structure and members + * Called by constructor/ set hostname / read config file + * @param verify true to verify if shared memory version matches existing one + * @param update true to update last user pid, date etc + */ + void setupMultiDetector(bool verify = true, bool update = true); + + /** + * If specific position, then provide result with that detector at position pos + * else concatenate the result of all detectors + * @param somefunc function pointer + * @param pos positin of detector in array (-1 is for all) + * @returns result for detector at that position or concatenated string of all detectors + */ + std::string concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos); + + /** + * Loop serially through all the detectors in calling a particular method + * @param somefunc function pointer + * @returns -1 if values are different, otherwise result in calling method + */ + template + T callDetectorMember(T (slsDetector::*somefunc)()); + + /** + * Loop serially through all the detectors in calling a particular method + * with string as return + * @param somefunc function pointer + * @returns concatenated string of results ifdifferent, otherwise result in + * calling method + */ + std::string callDetectorMember(std::string(slsDetector::*somefunc)()); + + /** + * Loop serially through all the detectors in calling a particular method + * with an extra argument + * @param somefunc function pointer + * @param value argument for calling method + * @returns -1 if values are different, otherwise result in calling method + */ + template + T callDetectorMember(T (slsDetector::*somefunc)(V), V value); + + /** + * Loop serially through all the detectors in calling a particular method + * with two extra arguments + * @param somefunc function pointer + * @param par1 argument for calling method + * @param par2 second argument for calling method + * @returns -1 if values are different, otherwise result in calling method + */ + template + T callDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2); + + + /** + * Parallel calls to all the detectors in calling a particular method + * @param somefunc function pointer + * @returns -1 if values are different, otherwise result in calling method + */ + template + T parallelCallDetectorMember(T (slsDetector::*somefunc)()); + + /** + * Loop serially through all the detectors in calling a particular method + * with an extra argument + * @param somefunc function pointer + * @param value argument for calling method + * @returns -1 if values are different, otherwise result in calling method + */ + template + T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1), P1 value); + + /** + * Loop serially through all the detectors in calling a particular method + * with two extra arguments + * @param somefunc function pointer + * @param par1 argument for calling method + * @param par2 second argument for calling method + * @returns -1 if values are different, otherwise result in calling method + */ + template + T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2); + + /** + * Loop serially through all the detectors in calling a particular method + * with three int arguments + * @param somefunc function pointer + * @param v0 argument for calling method + * @param v1 second argument for calling method + * @param v2 third argument for calling method + * @returns -1 if values are different, otherwise result in calling method + */ + int parallelCallDetectorMember(int (slsDetector::*somefunc)(int, int, int), + int v0, int v1, int v2); + + /** + * Loop serially through all results and + * return a value if they are all same, else return -1 + * @param return_values vector of results + * @returns -1 if values are different, otherwise result + */ + template + T minusOneIfDifferent(const std::vector&); + + /** + * Calculate the detector position index in multi vector and the module index + * using an index for all entire modules in list (Mythen) + * @param i position index of all modules in list + * @param idet position index in multi vector list + * @param imod module index in the sls detector + */ + int decodeNMod(int i, int &idet, int &imod); + + /** + * Decodes which detector and the corresponding channel numbers for it + * Mainly useful in a multi detector setROI (Gotthard, Mythen?) + * @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); + + /** + * Decode data from the detector converting them to an array of doubles, + * one for each channel (Mythen only) + * @param datain data from the detector + * @param nn size of datain array + * @param fdata double array of decoded data + * @returns pointer to a double array with a data per channel + */ + double* decodeData(int *datain, int &nn, double *fdata=NULL); + + /** + * Writes a data file + * @param name of the file to be written + * @param data array of data values + * @param err array of errors 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); + + /** + * Writes a data file with an integer pointer to an array + * @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); + + /** + * 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'); + + + /** + * 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); + + /** + * Checks error mask and returns error message and its severity if it exists + * @param critical is 1 if any of the messages is critical + * @returns error message else an empty std::string + */ + std::string getErrorMessage(int &critical); + + /** + * Clears error mask of both multi and sls + * @returns error mask + */ + int64_t clearAllErrorMask(); + + /** + * Set Error Mask from all detectors + * if each had errors in the mask already + */ + void setErrorMaskFromAllDetectors(); + + /** + * Set acquiring flag in shared memory + * @param b acquiring flag + */ + void setAcquiringFlag(bool b=false); + + /** + * Get acquiring flag from shared memory + * @returns acquiring flag + */ + bool getAcquiringFlag(); + + /** + * Check if acquiring flag is set, set error if set + * @returns FAIL if not ready, OK if ready + */ + bool isAcquireReady(); + + /** + * Check version compatibility with detector/receiver software + * (if hostname/rx_hostname has been set/ sockets created) + * @param p port type control port or receiver port + * @returns FAIL for incompatibility, OK for compatibility + */ + int checkVersionCompatibility(portType t); + + /** + * Get ID or version numbers + * @param mode version type + * @param imod module number in entire module list (gets decoded) (-1 for all) + * @returns Id or version number of that type + */ + int64_t getId(idMode mode, int imod=0); + + /** + * 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); + + /** + * Accessing the sls detector from the multi list using position + * @param pos position in the multi list + * @returns slsDetector object + */ + slsDetector *operator()(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 + * Clears all the vectors and destroys threadpool to bring + * object back to state before object creation amap + */ + void freeSharedMemory(); + + /** + * Get user details of shared memory + * @returns string with user details + */ + std::string getUserDetails(); + + /** + * Sets the hostname of all sls detectors in shared memory + * Connects to them to set up online flag + * @param name concatenated hostname of all the sls detectors + */ + void setHostname(const char* name); + + /** + * Gets the hostname of detector at particular position + * or concatenated hostnames of all the sls detectors + * @param pos position of detector in array, -1 for all detectors + * @returns concatenated hostnames of all detectors or hostname of specific one + */ + std::string getHostname(int pos = -1); + + /** + * Appends detectors to the end of the list in shared memory + * Connects to them to set up online flag + * @param name concatenated hostname of the sls detectors to be appended to the list + */ + void addMultipleDetectors(const char* name); + + + using slsDetectorBase::getDetectorType; + /** + * Get Detector type for a particular sls detector or get the first one + * @param pos position of sls detector in array, if -1, returns first detector type + * @returns detector type of sls detector in position pos, if -1, returns the first det type + */ + detectorType getDetectorsType(int pos = -1); + + /** + * Concatenates string types of all sls detectors or + * returns the detector type of the first sls detector + * @param pos position of sls detector in array, if -1, returns first detector type + * @returns detector type of sls detector in position pos, if -1, concatenates + */ + std::string sgetDetectorsType(int pos=-1); + + /** + * Just to overload getDetectorType from users + * Concatenates string types of all sls detectors or + * returns the detector type of the first sls detector + * @returns detector type of sls detector in position pos, if -1, concatenates + */ + std::string getDetectorType(); + + /** + * Creates all the threads in the threadpool + * throws an exception if it cannot create threads + */ + void createThreadPool(); + + /** + * Destroys all the threads in the threadpool + */ + void destroyThreadPool(); + + /** + * Returns the number of detectors in the multidetector structure + * @returns number of detectors + */ + int getNumberOfDetectors(); + + /** + * Returns number of detectors in dimension d + * @param d dimension d + * @returns number of detectors in dimension d + */ + int getNumberOfDetectors(dimension d); + + /** + * 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); + + /** + * Returns sum of all modules per sls detector from shared memory (Mythen) + * Other detectors, it is 1 + * @returns sum of all modules per sls detector + */ + int getNMods(); + + /** + * Returns sum of all modules per sls detector in dimension d from shared memory (Mythen) + * Other detectors, it is 1 + * @param d dimension d + * @returns sum of all modules per sls detector in dimension d + */ + int getNMod(dimension d); + + /** + * Returns sum of all maximum modules per sls detector from shared memory (Mythen) + * Other detectors, it is 1 + * @returns sum of all maximum modules per sls detector + */ + int getMaxMods(); + + /** + * Returns sum of all maximum modules per sls detector in dimension d from shared memory (Mythen) + * Other detectors, it is 1 + * @param d dimension d + * @returns sum of all maximum modules per sls detector in dimension d + */ + int getMaxMod(dimension d); + + /** + * Returns the sum of all maximum modules per sls detector in dimension d Mythen) + * from the detector directly. + * Other detectors, it is 1 + * @param d dimension d + * @returns sum of all maximum modules per sls detector in dimension d + */ + int getMaxNumberOfModules(dimension d=X); + + /** + * Sets/Gets the sum of all modules per sls detector in dimension d (Mythen) + * from the detector directly. + * Other detectors, it is 1 + * @param i the number of modules to set to + * @param d dimension d + * @returns sum of all modules per sls detector in dimension d + */ + int setNumberOfModules(int i=-1, dimension d=X); + + /** + * Using module id, returns the number of channels per that module + * from shared memory (Mythen) + * @param imod module number of entire multi detector list + * @returns number of channels per module imod + */ + int getChansPerMod(int imod=0); + + /** + * Returns the total number of channels of all sls detectors from shared memory + * @returns the total number of channels of all sls detectors + */ + int getTotalNumberOfChannels(); + + /** + * Returns the total number of channels of all sls detectors in dimension d + * from shared memory + * @param d dimension d + * @returns the total number of channels of all sls detectors in dimension d + */ + int getTotalNumberOfChannels(dimension d); + + /** + * Returns the total number of channels of all sls detectors in dimension d + * including gap pixels from shared memory + * @param d dimension d + * @returns the total number of channels of all sls detectors in dimension d + * including gap pixels + */ + int getTotalNumberOfChannelsInclGapPixels(dimension d); + + /** + * Returns the maximum number of channels of all sls detectors + * from shared memory (Mythen) + * @returns the maximum number of channels of all sls detectors + */ + int getMaxNumberOfChannels(); + + /** + * Returns the maximum number of channels of all sls detectors in dimension d + * from shared memory (Mythen) + * @param d dimension d + * @returns the maximum number of channels of all sls detectors in dimension d + */ + int getMaxNumberOfChannels(dimension d); + + /** + * Returns the total number of channels of all sls detectors in dimension d + * including gap pixels from shared memory(Mythen) + * @param d dimension d + * @returns the maximum number of channels of all sls detectors in dimension d + * including gap pixels + */ + int getMaxNumberOfChannelsInclGapPixels(dimension d); + + /** + * Returns the maximum number of channels of all sls detectors in each dimension d + * from shared memory. multi detector shared memory variable to calculate + * offsets for each sls detector + * @param d dimension d + * @returns the maximum number of channels of all sls detectors in dimension d + */ + int getMaxNumberOfChannelsPerDetector(dimension d); + + /** + * Sets the maximum number of channels of all sls detectors in each dimension d + * from shared memory, multi detector shared memory variable to calculate + * offsets for each sls detector + * @param d dimension d + * @param i maximum number of channels for multi structure in dimension d + * @returns the maximum number of channels of all sls detectors in dimension d + */ + int setMaxNumberOfChannelsPerDetector(dimension d,int i); + + /** + * Get Detector offset from shared memory in dimension d + * @param d dimension d + * @param pos detector position in multi detector list + * @returns offset in dimension d, -1 if pos is not an actual position in list + */ + int getDetectorOffset(dimension d, int pos); + + /** + * Set Detector offset in shared memory in dimension d + * @param d dimension d + * @param off offset for detector + * @param pos detector position in multi detector list + */ + void setDetectorOffset(dimension d, int off, int pos); + + /** + * Updates the channel offsets in X and Y dimension for all the sls detectors + * It is required for decodeNMod and setting ROI + */ + void updateOffsets(); + + /** + * Checks if the multi detectors are online and sets the online flag + * @param online if GET_ONLINE_FLAG, only returns shared memory online flag, + * else sets the detector in online/offline state + * if OFFLINE_FLAG, (i.e. no communication to the detector - using only local structure - no data acquisition possible!); + * if ONLINE_FLAG, detector in online state (i.e. communication to the detector updating the local structure) + * @returns online/offline status + */ + int setOnline(int const online=GET_ONLINE_FLAG); + + /** + * Checks if each of the detectors are online/offline + * @returns empty string if they are all online, + * else returns concatenation of strings of all detectors that are offline + */ + std::string checkOnline(); + + /** + * Set/Gets TCP Port of detector or receiver + * @param t port type + * @param p port number (-1 gets) + * @returns port number + */ + int setPort(portType t, int p); + + /** + * Lock server for this client IP + * @param p 0 to unlock, 1 to lock + * @returns 1 for locked or 0 for unlocked + */ + int lockServer(int p); + + /** + * Get last client IP saved on detector server + * @returns last client IP saved on detector server + */ + std::string getLastClientIP(); + + /** + * Exit detector server + * @returns OK or FAIL + */ + int exitServer(); + + /** + * Load configuration from a configuration File + * @param fname configuration file name + * @return OK or FAIL + */ + int readConfigurationFile(std::string const fname); + + /** + * Write current configuration to a file + * @param fname configuration file name + * @returns OK or FAIL + */ + int writeConfigurationFile(std::string const fname); + + /** + * Returns the trimfile or settings file name (Useless??) + * @returns the trimfile or settings file name + */ + std::string getSettingsFile(); + + /** + * Get detector settings + * @param ipos position in multi list (-1 all) + * @returns current settings + */ + detectorSettings getSettings(int pos=-1); + + /** + * Load detector settings from the settings file picked from the trimdir/settingsdir + * Eiger only stores in shared memory ( a get will overwrite this) + * For Eiger, one must use threshold + * @param isettings settings + * @param ipos position in multi list (-1 all) + * @returns current settings + */ + detectorSettings setSettings(detectorSettings isettings, int pos=-1); + + /** + * Get threshold energy (Mythen and Eiger) + * @param imod module number (-1 all) + * @returns current threshold value for imod in ev (-1 failed) + */ + int getThresholdEnergy(int imod=-1); + + /** + * Set threshold energy (Mythen and Eiger) + * @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); + + /** + * Returns the detector trimbit/settings directory \sa sharedSlsDetector + * @returns the trimbit/settings directory + */ + std::string getSettingsDir(); + + /** + * Sets the detector trimbit/settings directory \sa sharedSlsDetector + * @param s trimbits/settings directory + * @returns the trimbit/settings directory + */ + std::string setSettingsDir(std::string s); + + /** + * Returns the calibration files directory \sa sharedSlsDetector (Mythen) + * @returns the calibration files directory + */ + std::string getCalDir(); + + /** + * Sets the calibration files directory \sa sharedSlsDetector (Mythen) + * @param s the calibration files directory + * @returns the calibration files directory + */ + std::string setCalDir(std::string s); + + /** + * Loads the modules settings/trimbits reading from a specific file + * file name extension is automatically generated. + * @param fname specific settings/trimbits file + * @param imod module number (-1 for all) + * returns OK or FAIL + */ + int loadSettingsFile(std::string fname, int imod=-1); + + /** + * Saves the modules settings/trimbits to a specific file + * file name extension is automatically generated. + * @param fname specific settings/trimbits file + * @param imod module number (-1 for all) + * returns OK or FAIL + */ + int saveSettingsFile(std::string fname, int imod=-1); + + /** + * Loads the modules calibration data reading from a specific file (Mythen) + * file name extension is automatically generated. + * @param fname specific calibration file + * @param imod module number (-1 for all) + * returns OK or FAIL + */ + int loadCalibrationFile(std::string fname, int imod=-1); + + /** + * Saves the modules calibration data to a specific file (Mythen) + * file name extension is automatically generated. + * @param fname specific calibration file + * @param imod module number (-1 for all) + * returns OK or FAIL + */ + int saveCalibrationFile(std::string fname, int imod=-1); + + /** + * Sets/gets the detector in position i as master of the structure (Mythen) + * (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); + + /** + * Sets/gets the synchronization mode of the various detector (Mythen) + * @param sync syncronization mode + * @returns current syncronization mode + */ + synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); + + /** + * Get Detector run status + * @returns status + */ + runStatus getRunStatus(); + + /** + * Prepares detector for acquisition (Eiger and Gotthard) + * For Gotthard, it sets the detector data transmission mode (CPU or receiver) + * @returns OK if all detectors are ready for acquisition, FAIL otherwise + */ + int prepareAcquisition(); + + /** + * Cleans up after acquisition (Gotthard only) + * For Gotthard, it sets the detector data transmission to default (via CPU) + * @returns OK or FAIL + */ + int cleanupAcquisition(); + + /** + * Start detector acquisition (Non blocking) + * @returns OK or FAIL if even one does not start properly + */ + int startAcquisition(); + + /** + * Stop detector acquisition + * @returns OK or FAIL + */ + int stopAcquisition(); + + /** + * Start readout (without exposure or interrupting exposure) (Mythen) + * @returns OK or FAIL + */ + int startReadOut(); + + /** + * Start detector acquisition and read all data (Blocking until end of acquisition) + * (Mythen, puts all data into a data queue. Others, data at receiver via udp packets) + * @returns pointer to the front of the data queue (return significant only for Mythen) + * \sa startAndReadAllNoWait getDataFromDetector dataQueue + */ + int* startAndReadAll(); + + /** + * Start detector acquisition and call read out, but not reading (data for Mythen, + * and status for other detectors) from the socket. + * (startAndReadAll calls this and getDataFromDetector. Client is not blocking, + * but server is blocked until getDataFromDetector is called. so not recommended + * for users) + * @returns OK or FAIL + */ + int startAndReadAllNoWait(); + + /** + * Reads from the detector socket (data frame for Mythen and status for other + * detectors) + * @returns pointer to the data or NULL. If NULL disconnects the socket + * (return significant only for Mythen) + * Other detectors return NULL + * \sa getDataFromDetector + */ + int* getDataFromDetector(); + + /** + * Requests and receives a single data frame from the detector + * (Mythen: and puts it in the data queue) + * @returns pointer to the data or NULL. (return Mythen significant) + * Other detectors return NULL + * \sa getDataFromDetector + */ + int* readFrame(); + + /** + * Requests and receives all data from the detector + * (Mythen: and puts them in a data queue) + * @returns pointer to the front of the queue or NULL (return Mythen significant) + * Other detectors return NULL + * \sa getDataFromDetector dataQueue + */ + int* readAll(); + + /** + * Pops the data from the data queue (Mythen) + * @returns pointer to the popped data or NULL if the queue is empty. + * \sa dataQueue + */ + int* popDataQueue(); + + /** + * Pops the data from the postprocessed data queue (Mythen) + * @returns pointer to the popped data or NULL if the queue is empty. + * \sa finalDataQueue + */ + detectorData* popFinalDataQueue(); + + /** + * Resets the raw data queue (Mythen) + * \sa dataQueue + */ + void resetDataQueue(); + + /** + * Resets the post processed data queue (Mythen) + * \sa finalDataQueue + */ + void resetFinalDataQueue(); + + /** + * Configures in detector the destination for UDP packets (Not Mythen) + * @returns OK or FAIL + */ + int configureMAC(); + + /** + * Set/get timer value (not all implemented for all detectors) + * @param index timer index + * @param t time in ns or number of...(e.g. frames, gates, probes) + * @param imod module number (gotthard delay can have different values) + * @returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t setTimer(timerIndex index, int64_t t=-1, int imod = -1); + + /** + * Set/get timer value left in acquisition (not all implemented for all detectors) + * @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); + + /** + * Set speed + * @param sp speed type (clkdivider option for Jungfrau and Eiger, others for Mythen/Gotthard) + * @param value (clkdivider 0,1,2 for full, half and quarter speed). Other values check manual + * @returns value of speed set + */ + int setSpeed(speedVariable sp, int value=-1); + + /** + * Set/get dynamic range and updates the number of dataBytes + * (Eiger: If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to 1) + * @param i dynamic range (-1 get) + * @returns current dynamic range + * \sa sharedSlsDetector + */ + int setDynamicRange(int i=-1); + + /** + * Recalculated number of data bytes for multi detector + * @returns tota number of data bytes for multi detector + */ + int getDataBytes(); + + /** + * Set/get 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 all modules) + * @returns current DAC value + */ + dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); + + /** + * Get adc value + * @param index adc(DAC) index + * @param imod module number (if -1 all modules) + * @returns current adc value (temperature for eiger and jungfrau in millidegrees) + */ + dacs_t getADC(dacIndex index, int imod=-1); + + /** + * Set/get timing mode + * @param pol timing mode (-1 gets) + * @returns current timing mode + */ + externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); + + /** + * Set/get external signal flags (to specify triggerinrising edge etc) (Gotthard, Mythen) + * @param pol external signal flag (-1 gets) + * @param signalindex singal index (0 - 3) + * @returns current timing mode + */ + externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); + + /** + * Set/get readout flags (Eiger, Mythen) + * @param flag readout flag (Eiger options: parallel, nonparallel, safe etc.) (-1 gets) + * @returns readout flag + */ + int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); + + /** + * Write in a register. For Advanced users + * @param addr address of register + * @param val value to write into register + * @returns value read after writing + */ + uint32_t writeRegister(uint32_t addr, uint32_t val); + + /** + * Read from a register. For Advanced users + * @param addr address of register + * @returns value read from register + */ + uint32_t readRegister(uint32_t addr); + + /** + * Set bit in a register. For Advanced users + * @param addr address of register + * @param n nth bit + * @returns value read from register + */ + uint32_t setBit(uint32_t addr, int n); + + /** + * Clear bit in a register. For Advanced users + * @param addr address of register + * @param n nth bit + * @returns value read from register + */ + uint32_t clearBit(uint32_t addr, int n); + + /** + * Set network parameter + * @param p network parameter type + * @param s network parameter value + * @returns network parameter value set (from getNetworkParameter) + */ + std::string setNetworkParameter(networkParameter p, std::string s); + + /** + * Get network parameter + * @param p network parameter type + * @returns network parameter value set (from getNetworkParameter) + */ + std::string getNetworkParameter(networkParameter); + + /** + * Execute a digital test (Gotthard, Mythen) + * @param mode testmode type + * @param imod module index (-1 for all) + * @returns result of test + */ + int digitalTest(digitalTestMode mode, int imod=0); + + /** + * Execute trimming (Mythen) + * @param mode trimming mode type + * @param par1 parameter 1 + * @param par2 parameter 2 + * @param imod module index (-1 for all) + * @returns result of trimming + */ + int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); + + /** + * Load dark or gain image to detector (Gotthard) + * @param index image type + * @param fname file name from which to load image + * @returns OK or FAIL + */ + int loadImageToDetector(imageType index,std::string const fname); + + /** + * Writes the counter memory block from the detector (Gotthard) + * @param fname file name to load data from + * @param startACQ is 1 to start acquisition after reading counter + * @returns OK or FAIL + */ + int writeCounterBlockFile(std::string const fname,int startACQ=0); + + /** + * Resets counter in detector (Gotthard) + * @param startACQ is 1 to start acquisition after resetting counter + * @returns OK or FAIL + */ + int resetCounterBlock(int startACQ=0); + + /** + * Set/get counter bit in detector (Gotthard) + * @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); + + /** + * Ensures that min is less than max in both dimensions (Gotthard) + * @param n number of rois + * @param r array of rois + */ + void verifyMinMaxROI(int n, ROI r[]); + + /** + * Set ROI (Gotthard) + * At the moment only one set allowed + * @param n number of rois + * @param roiLimits array of roi + * @returns OK or FAIL + */ + int setROI(int n=-1,ROI roiLimits[]=NULL); + + /** + * Get ROI from each detector and convert it to the multi detector scale (Gotthard) + * @param n number of rois + * @returns OK or FAIL + */ + ROI* getROI(int &n); + + /** + * Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert users + * @param addr address of adc register + * @param val value + * @returns return value (mostly -1 as it can't read adc register) + */ + int writeAdcRegister(int addr, int val); + + /** + * Activates the detector (Eiger only) + * @param enable active (1) or inactive (0), -1 gets + * @returns 0 (inactive) or 1 (active) + */ + int activate(int const enable=GET_ONLINE_FLAG); + + /** + * Returns the enable if data will be flipped across x or y axis (Eiger) + * @param d axis across which data is flipped + * @returns 1 for flipped, else 0 + */ + int getFlippedData(dimension d=X); + + /** + * Sets the enable which determines if + * data will be flipped across x or y axis (Eiger) + * @param d axis across which data is flipped + * @param value 0 or 1 to reset/set or -1 to get value + * @returns enable flipped data across x or y axis + */ + int setFlippedData(dimension d=X, int value=-1); + + /** + * Sets all the trimbits to a particular value (Eiger) + * @param val trimbit value + * @param imod module number, -1 means all modules + * @returns OK or FAIL + */ + int setAllTrimbits(int val, int imod=-1); + + /** + * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger) + * 4 bit mode gap pixels only in gui call back + * @param val 1 sets, 0 unsets, -1 gets + * @returns gap pixel enable or -1 for error + */ + int enableGapPixels(int val=-1); + + /** + * Sets the number of trim energies and their value (Eiger) + * \sa sharedSlsDetector + * @param nen number of energies + * @param en array of energies + * @returns number of trim energies + */ + int setTrimEn(int nen, int *en=NULL); + + /** + * Returns the number of trim energies and their value (Eiger) + * \sa sharedSlsDetector + * @param en array of energies + * @returns number of trim energies + */ + int getTrimEn(int *en=NULL); + + /** + * Pulse Pixel (Eiger) + * @param n is number of times to pulse + * @param x is x coordinate + * @param y is y coordinate + * @returns OK or FAIL + */ + int pulsePixel(int n=0,int x=0,int y=0); + + /** + * Pulse Pixel and move by a relative value (Eiger) + * @param n is number of times to pulse + * @param x is relative x value + * @param y is relative y value + * @returns OK or FAIL + */ + int pulsePixelNMove(int n=0,int x=0,int y=0); + + /** + * Pulse Chip (Eiger) + * @param n is number of times to pulse + * @returns OK or FAIL + */ + int pulseChip(int n=0); + + /** + * Set/gets threshold temperature (Jungfrau) + * @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); + + /** + * Enables/disables temperature control (Jungfrau) + * @param val value, -1 gets + * @param imod module number, -1 is all + * @returns temperature control enable + */ + int setTemperatureControl(int val=-1, int imod=-1); + + /** + * Resets/ gets over-temperature event (Jungfrau) + * @param val value, -1 gets + * @param imod module number, -1 is all + * @returns over-temperature event + */ + int setTemperatureEvent(int val=-1, int imod=-1); + + /** + * Set storage cell that stores first acquisition of the series (Jungfrau) + * @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); + + /** + * Programs FPGA with pof file (Jungfrau) + * @param fname file name + * @returns OK or FAIL + */ + int programFPGA(std::string fname); + + /** + * Resets FPGA (Jungfrau) + * @returns OK or FAIL + */ + int resetFPGA(); + + /** + * Power on/off Chip (Jungfrau) + * @param ival on is 1, off is 0, -1 to get + * @returns OK or FAIL + */ + int powerChip(int ival= -1); + + /** + * Automatic comparator disable (Jungfrau) + * @param ival on is 1, off is 0, -1 to get + * @returns OK or FAIL + */ + int setAutoComparatorDisableMode(int ival= -1); + + /** + * Get Scan steps (Mythen) + * @param index scan index + * @param istep step index + * @returns scan step value + */ + double getScanStep(int index, int istep); + + /** + * Returns the trimbits from the detector's shared memmory (Mythen, Eiger) + * @param retval is the array with the trimbits + * @param fromDetector is true if the trimbits shared memory have to be + * uploaded from detector + * @returns total number of channels for the detector + */ + int getChanRegs(double* retval,bool fromDetector); + + /** + * Configure channel (Mythen) + * @param reg channel register + * @param ichan channel number (-1 all) + * @param ichip chip number (-1 all) + * @param imod module number (-1 all) + * \sa ::sls_detector_channel + * @returns current register value + */ + int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); + + /** + * Get Move Flag (Mythen) + * @param imod module number (-1 all) + * @param istep step index + * @returns move flag + */ + int getMoveFlag(int imod); + + /** + * Fill Module mask for flat field corrections (Mythen) + * @param mM array + * @returns number of modules + */ + int fillModuleMask(int *mM); + + /** + * Calibrate Pedestal (ChipTestBoard) + * Starts acquisition, calibrates pedestal and writes to fpga + * @param frames number of frames + * @returns number of frames + */ + int calibratePedestal(int frames = 0); + + /** + * Set Rate correction (Mythen, Eiger) + * @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); + + /** + * Get rate correction (Mythen, Eiger) + * @param t reference for dead time + * @returns 0 if rate correction disabled, > 0 otherwise + */ + int getRateCorrection(double &t); + + /** + * Get rate correction tau (Mythen, Eiger) + * @returns 0 if rate correction disabled, otherwise the tau used for the correction + */ + double getRateCorrectionTau(); + + /** + * Get rate correction (Mythen, Eiger) + * @returns 0 if rate correction disabled, > 0 otherwise + */ + int getRateCorrection(); + + /** + * Rate correct data (Mythen) + * @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); + + /** + * Set flat field corrections (Mythen) + * @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=""); + + /** + * Set flat field corrections (Mythen) + * @param corr if !=NULL the flat field corrections will be filled with + * corr (NULL usets ff corrections) + * @param ecorr if !=NULL the flat field correction errors will be filled + * with ecorr (1 otherwise) + * @returns 0 if ff correction disabled, >0 otherwise + */ + int setFlatFieldCorrection(double *corr, double *ecorr=NULL); + + /** + * Get flat field corrections (Mythen) + * @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); + + /** + * Flat field correct data (Mythen) + * @param datain data array + * @param errin error array on data (if NULL will default to sqrt(datain) + * @param dataout array of corrected data + * @param errout error on corrected data (if not NULL) + * @returns 0 + */ + int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); + + /** + * Set bad channels correction (Mythen) + * @param fname file with bad channel list ("" disable) + * @returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(std::string fname=""); + + /** + * Set bad channels correction (Mythen) + * @param nch number of bad channels + * @param chs array of channels + * @param ff 0 if normal bad channels, 1 if ff bad channels + * @returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(int nch, int *chs, int ff); + + /** + * Get bad channels correction (Mythen) + * @param bad pointer to array that if bad!=NULL will be filled with the + * bad channel list + * @returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + int getBadChannelCorrection(int *bad=NULL); + + /** + * Reads an angular conversion file (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::readAngularConversion + * @param fname file to be read + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int readAngularConversionFile(std::string fname); + + /** + * Writes an angular conversion file (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::writeAngularConversion + * @param fname file to be written + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int writeAngularConversion(std::string fname); + + /** + * Get angular conversion (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::getAngularConversion + * @param direction reference to diffractometer + * @param angconv array that will be filled with the angular conversion constants + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; + + /** + * Sets the value of angular conversion parameter (Mythen, Gotthard) + * @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); + + /** + * Gets the value of angular conversion parameter (Mythen, Gotthard) + * @param imod module index (-1 for all) + * @returns the actual value + */ + angleConversionConstant *getAngularConversionPointer(int imod=0); + + /** + * Prints receiver configuration + * @returns OK or FAIL + */ + int printReceiverConfiguration(); + + /** + * Sets up receiver socket if online and sets the flag + * @param online online/offline flag (-1 gets) + * @returns online/offline flag + */ + int setReceiverOnline(int const online=GET_ONLINE_FLAG); + + /** + * Checks if the receiver is really online + * @returns empty string if all online, else concatenates hostnames of all + * detectors that are offline + */ + std::string checkReceiverOnline(); + + /** + * Locks/Unlocks the connection to the receiver + * @param lock sets (1), usets (0), gets (-1) the lock + * @returns lock status of the receiver + */ + int lockReceiver(int lock=-1); + + /** + * Returns the IP of the last client connecting to the receiver + * @returns IP of last client connecting to receiver + */ + std::string getReceiverLastClientIP(); + + /** + * Turns off the receiver server! + * @returns OK or FAIL + */ + int exitReceiver(); + + /** + * Returns output file directory + * @returns output file directory + */ + std::string getFilePath(); + + /** + * Sets up the file directory + * @param s file directory + * @returns file dir + */ + std::string setFilePath(std::string s=""); + + /** + * Returns file name prefix + * @returns file name prefix + */ + std::string getFileName(); + + /** + * Sets up the file name prefix + * @param s file name prefix + * @returns file name prefix + */ + 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); + + /** + * Sets the frames discard policy in receiver + * @param f frames discard policy + * @returns frames discard policy set in receiver + */ + frameDiscardPolicy setReceiverFramesDiscardPolicy(frameDiscardPolicy f = GET_FRAME_DISCARD_POLICY); + + /** + * Sets the partial frames padding enable in receiver + * @param f partial frames padding enable + * @returns partial frames padding enable in receiver + */ + int setReceiverPartialFramesPadding(int f = -1); + + /** + * Returns file format + * @returns file name + */ + fileFormat getFileFormat(); + + /** + * Sets up the file format + * @param f file format + * @returns file format + */ + fileFormat setFileFormat(fileFormat f=GET_FILE_FORMAT); + + /** + * Returns file index + * @returns file index + */ + int getFileIndex(); + + /** + * Sets up the file index + * @param i file index + * @returns file index + */ + int setFileIndex(int i=-1); + + /** + * Receiver starts listening to packets + * @returns OK or FAIL + */ + int startReceiver(); + + /** + * Stops the listening mode of receiver + * @returns OK or FAIL + */ + int stopReceiver(); + + /** + * Sets the receiver to start any readout remaining in the fifo and + * change status to transmitting (Mythen) + * The status changes to run_finished when fifo is empty + */ + runStatus startReceiverReadout(); + + /** + * Gets the status of the listening mode of receiver + * @returns status + */ + runStatus getReceiverStatus(); + + /** + * Gets the number of frames caught by receiver + * @returns number of frames caught by receiver + */ + int getFramesCaughtByReceiver(); + + /** + * 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(); + + /** + * Gets the current frame index of receiver + * @returns current frame index of receiver + */ + int getReceiverCurrentFrameIndex(); + + /** + * Resets framescaught in receiver + * Use this when using startAcquisition instead of acquire + * @returns OK or FAIL + */ + int resetFramesCaught(); + + /** + * Create Receiving Data Sockets + * @param destroy is true to destroy all the sockets + * @returns OK or FAIL + */ + int createReceivingDataSockets(const bool destroy = false); + + /** + * Reads frames from receiver through a constant socket + * Called during acquire() when call back registered or when using gui + */ + void readFrameFromReceiver(); + + /** + * 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); + + /** + * 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); + + /** + * Sets the read receiver frequency + * if data required from receiver randomly readRxrFrequency=0, + * else every nth frame to be sent to gui/callback + * @param freq is the receiver read frequency. Value 0 is 200 ms timer (other + * frames not sent), 1 is every frame, 2 is every second frame etc. + * @returns read receiver frequency + */ + int setReadReceiverFrequency(int freq=-1); + + /** + * 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); + + /** + * 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/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); + + /** + * 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); + + /** + * 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); + + /** + * 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); + + /** + * Opens pattern file and sends pattern to CTB + * @param fname pattern file to open + * @returns OK/FAIL + */ + int setCTBPattern(std::string fname); + + /** + * Writes a pattern word to the CTB + * @param addr address of the word, -1 is I/O control register, + * -2 is clk control register + * @param word 64bit word to be written, -1 gets + * @returns actual value + */ + uint64_t setCTBWord(int addr,uint64_t word=-1); + + /** + * Sets the pattern or loop limits in the CTB + * @param level -1 complete pattern, 0,1,2, loop level + * @param start start address if >=0 + * @param stop stop address if >=0 + * @param n number of loops (if level >=0) + * @returns OK/FAIL + */ + int setCTBPatLoops(int level,int &start, int &stop, int &n); + + /** + * Sets the wait address in the CTB + * @param level 0,1,2, wait level + * @param addr wait address, -1 gets + * @returns actual value + */ + int setCTBPatWaitAddr(int level, int addr=-1); + + /** + * Sets the wait time in the CTB + * @param level 0,1,2, wait level + * @param t wait time, -1 gets + * @returns actual value + */ + int setCTBPatWaitTime(int level, uint64_t t=-1); + + +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 shared memory was created in this call, else false + */ + bool initSharedMemory(bool verify = true); + + /** + * Initialize detector structure for the shared memory just created + */ + void initializeDetectorStructure(); + + /** + * Initialize class members (and from parent classes) + * @param verify true to verify if shm size matches existing one + */ + void initializeMembers(bool verify = true); + + /** + * Update user details in detector structure + */ + void updateUserdetails(); + + /** + * Execute in command line and return result + * @param cmd command + * @returns result + */ + std::string exec(const char* cmd); + + /** + * Add sls detector + * @param s hostname of the single detector + */ + void addSlsDetector (std::string s); + /** * add gap pixels to the image (only for Eiger in 4 bit mode) * @param image pointer to image without gap pixels @@ -1581,29 +1901,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/multiSlsDetector/multiSlsDetectorClient.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorClient.h index 8d59f13b4..040267cc1 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorClient.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorClient.h @@ -4,10 +4,11 @@ #include "multiSlsDetector.h" #include "multiSlsDetectorCommand.h" +#include "sls_detector_exceptions.h" #include -using namespace std; + int dummyCallback(detectorData* d, int p,void*) { cout << "got data " << p << endl; @@ -16,83 +17,136 @@ int dummyCallback(detectorData* d, int p,void*) { class multiSlsDetectorClient { - public: - multiSlsDetectorClient(int argc, char *argv[], int action, multiSlsDetector *myDetector=NULL) { \ - string answer; \ - multiSlsDetectorCommand *myCmd; \ - int id=-1, iv=0, pos=-1; \ - int del=0; \ - char cmd[100]; \ - if (action==slsDetectorDefs::READOUT_ACTION) { \ +public: + multiSlsDetectorClient(int argc, char *argv[], int action, multiSlsDetector *myDetector=NULL) { \ + string answer; \ + multiSlsDetectorCommand *myCmd; \ + int id = -1, pos = -1, iv = 0; \ + bool verify = true, update = true; \ + int del = 0; \ + char cmd[100] = ""; \ - if (argc!=0) { - iv=sscanf(argv[0],"%d-%s",&id,cmd); \ - if (iv>0 && id>=0 && strchr(argv[0],'-')) { - cout << "id " << id << endl; \ - if (iv>1) - argv[0]=cmd; - } - iv=sscanf(argv[0],"%d:",&pos); \ - if (iv>0 && pos>=0 && strchr(argv[0],':')) - cout << "pos " << pos << "is not allowed!" << endl; \ - } - if (id<0) - id=0; + if (action==slsDetectorDefs::PUT_ACTION && argc<2) { \ + cout << "Wrong usage - should be: "<< argv[0] << \ + "[id-][pos:]channel arg" << endl; \ + cout << endl; \ + return; \ + if (del) delete myDetector; \ + }; \ + if (action==slsDetectorDefs::GET_ACTION && argc<1) { \ + cout << "Wrong usage - should be: "<< argv[0] << \ + "[id-][pos:]channel arg" << endl; \ + cout << endl; \ + if (del) delete myDetector; \ + return; \ + }; \ - if (myDetector==NULL) { \ - myDetector=new multiSlsDetector(id); \ - //myDetector->registerDataCallback(&dummyCallback, NULL); - del=1; \ - }; - // cout << "noid" <executeLine(argc, argv, action); \ - cout << answer<< endl; \ - delete myCmd; \ - if (del) delete myDetector; \ - return; \ - }; \ - if (action==slsDetectorDefs::PUT_ACTION && argc<2) { \ - cout << "Wrong usage - should be: "<< argv[0] << \ - "[id-][pos:]channel arg" << endl; \ - cout << endl; \ - return; \ - if (del) delete myDetector; \ - }; - if (action==slsDetectorDefs::GET_ACTION && argc<1) { \ - cout << "Wrong usage - should be: "<< argv[0] << \ - "[id-][pos:]channel arg" << endl; \ - cout << endl; \ - if (del) delete myDetector; \ - return; \ - }; \ - if (myDetector==NULL) { \ - iv=sscanf(argv[0],"%d-%s",&id, cmd); \ - if (iv==2 && id>=0) { \ - myDetector=new multiSlsDetector(id); \ - argv[0]=cmd; \ - cout << id << "-" ; \ - } else { \ - myDetector=new multiSlsDetector(); \ - }; \ - del=1; \ - } \ - iv=sscanf(argv[0],"%d:%s",&pos, cmd); \ - if (iv==2 && pos>=0) { \ - argv[0]=cmd; \ - cout << pos << ":" ; \ - } ; \ - myCmd=new multiSlsDetectorCommand(myDetector); \ - answer=myCmd->executeLine(argc, argv, action, pos); \ - cout << argv[0] << " " ; \ - cout << answer<< endl; \ - delete myCmd; \ - if (del) delete myDetector; \ - }; - - + if (action==slsDetectorDefs::READOUT_ACTION) { \ + id = 0; \ + pos = -1; \ + if (argc) { \ + // multi id scanned + if (strchr(argv[0],'-')) { \ + iv=sscanf(argv[0],"%d-%s",&id, cmd); \ + //%s needn't be there (if not 1:), so 1 or 2 arguments scanned + if (iv >= 1 && id >= 0) { \ + argv[0] = cmd; \ + cout << id << "-" ; \ + } else { \ + id = 0; \ + } \ + } \ + // single id scanned + if (strchr(argv[0],':')) { \ + iv=sscanf(argv[0],"%d:",&pos); \ + if (iv == 1 && pos >= 0) { \ + cout << "pos " << pos << " is not allowed for readout!" << endl; \ + return; \ + } \ + } \ + } \ + } else { \ + // multi id scanned + iv=sscanf(argv[0],"%d-%s",&id, cmd); \ + // scan success + if (iv == 2 && id >= 0) { \ + argv[0] = cmd; \ + cout << id << "-" ; \ + } else { \ + id = 0; \ + } \ + // sls pos scanned + iv=sscanf(argv[0],"%d:%s", &pos, cmd); \ + // scan success + if (iv == 2 && pos >= 0) { \ + argv[0] = cmd; \ + cout << pos << ":" ; \ + } \ + if (iv != 2) { \ + pos = -1; \ + } \ + // remove the %d- and %d: + if (!strlen(cmd)) { \ + strcpy(cmd, argv[0]); \ + } \ + // special commands + string scmd = cmd; \ + // free without calling multiSlsDetector constructor + if (scmd == "free") { \ + if (pos != -1) \ + slsDetector::freeSharedMemory(id, pos); \ + else \ + multiSlsDetector::freeSharedMemory(id); \ + return; \ + } \ + // get user details without verify sharedMultiSlsDetector version + else if ((scmd == "user") && (action==slsDetectorDefs::GET_ACTION)) { \ + verify = false; \ + update = false; \ + myDetector=NULL; \ + } \ + } \ + + //cout<<"id:"<executeLine(argc, argv, action, pos); \ + } catch (const SharedMemoryException & e) { \ + cout << e.GetMessage() << endl; \ + delete myCmd; \ + if (del) delete myDetector; \ + return; \ + } catch (...) { \ + cout << " caught exception" << endl; \ + delete myCmd; \ + if (del) delete myDetector; \ + return; \ + } \ + if (action!=slsDetectorDefs::READOUT_ACTION) { \ + cout << argv[0] << " " ; \ + } \ + cout << answer<< endl; \ + delete myCmd; \ + if (del) delete myDetector; \ + }; + }; diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorCommand.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorCommand.h index a387046c6..6e5c68e93 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorCommand.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorCommand.h @@ -6,7 +6,7 @@ #include "slsDetector.h" #include "multiSlsDetector.h" #include "slsDetectorCommand.h" -using namespace std; + /** @short This class handles the command line I/Os, help etc. of the text clients */ @@ -27,7 +27,7 @@ class multiSlsDetectorCommand : public slsDetectorCommand { /* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ /* \returns answer string */ /* *\/ */ - + string executeLine(int narg, char *args[], int action, int id=-1) { \ string s; \ if (id>=0) { @@ -37,14 +37,14 @@ class multiSlsDetectorCommand : public slsDetectorCommand { s=cmd->executeLine(narg, args, action); \ if(d->getErrorMask()) \ myDet->setErrorMask((myDet->getErrorMask())|(1< +#include // printf +#include // errno +#include // strerror +#include +#include // O_CREAT, O_TRUNC.. +#include // fstat +#include // shared memory +#include +#include "stdlib.h" + +#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_" +#define SHM_SLS_PREFIX "_sls_" +#define SHM_ENV_NAME "SLSDETNAME" + +SharedMemory::SharedMemory(int multiId, int slsId): + fd(-1), + shmSize(0) +{ + name = ConstructSharedMemoryName(multiId, slsId); +} + + + +SharedMemory::~SharedMemory(){ + if (fd >= 0) + close(fd); +} + + +bool SharedMemory::IsExisting() { + bool ret = true; + int tempfd = shm_open(name.c_str(), O_RDWR, 0); + if ((tempfd < 0) && (errno == ENOENT)) { + ret = false; + } + close(tempfd); + 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 + void* addr = MapSharedMemory(sz); + printf("Shared memory created %s \n", name.c_str()); + return addr; +} + +void* SharedMemory::OpenSharedMemory(size_t sz){ + // 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(); + } + + 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() { + 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()); +} + + +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 slsId) { + + // using environment path + string sEnvPath = ""; + char* envpath = getenv(SHM_ENV_NAME); + if (envpath != NULL) { + sEnvPath.assign(envpath); + sEnvPath.insert(0,"_"); + } + + stringstream ss; + if (slsId < 0) + ss << SHM_MULTI_PREFIX << multiId << sEnvPath; + else + ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId << sEnvPath; + + 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; +} + diff --git a/slsDetectorSoftware/sharedMemory/SharedMemory.h b/slsDetectorSoftware/sharedMemory/SharedMemory.h new file mode 100644 index 000000000..ebec18606 --- /dev/null +++ b/slsDetectorSoftware/sharedMemory/SharedMemory.h @@ -0,0 +1,105 @@ +#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 slsId sls detector id, -1 if a multi detector shared memory + */ + SharedMemory(int multiId, int slsId); + + /** + * Destructor + */ + ~SharedMemory(); + + /** + * Verify if it exists + * @param name of shared memory + * @return true if exists, else false + */ + bool IsExisting(); + + /** + * 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 + */ + 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 or map + * @param sz of shared memory + */ + void* OpenSharedMemory(size_t sz); + + /** + * 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 slsId sls detector id, -1 if a multi detector shared memory + * @returns shared memory name + */ + std::string ConstructSharedMemoryName(int multiId, int slsId); + + /** + * Map shared memory to an address + * throws a SharedMemoryException exception on failure + * @param sz of shared memory + */ + void* MapSharedMemory(size_t sz); + + /** + * Verify if existing shared memory size matches expected size + * @param expectedSize expected size of shared memory, replaced with smaller size if size does not match + * @return 0 for success, 1 for fail + */ + int VerifySizeMatch(size_t expectedSize); + + /** Shared memory name */ + std::string name; + + /** File descriptor */ + int fd; + + /** shm size */ + size_t shmSize; + +}; diff --git a/slsDetectorSoftware/slsDetector/gitInfoLib.h b/slsDetectorSoftware/slsDetector/gitInfoLib.h index 6e7baa985..219fb2199 100644 --- a/slsDetectorSoftware/slsDetector/gitInfoLib.h +++ b/slsDetectorSoftware/slsDetector/gitInfoLib.h @@ -1,8 +1,6 @@ #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" - -#define GITREPUUID "b8bdbf4da61f95b88893b02ddabc2491b16fa10f" +#define GITREPUUID "6bb7195a2c7dc9526088882e0244a7455d3c15b2" #define GITAUTH "Dhanya_Thattil" -#define GITREV 0x3746 -#define GITDATE 0x20180327 - -#define GITBRANCH "developer" +#define GITREV 0x3941 +#define GITDATE 0x20180718 +#define GITBRANCH "3.3.0-rc" diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 1b4cdfcfd..a0506e93f 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -1,7 +1,15 @@ #include "slsDetector.h" +#include "multiSlsDetector.h" +#include "sls_detector_exceptions.h" +#include "SharedMemory.h" +#include "receiverInterface.h" +#include "gitInfoLib.h" +#include "versionAPI.h" #include "usersFunctions.h" #include "slsDetectorCommand.h" #include "postProcessingFuncs.h" + + #include #include #include @@ -9,1116 +17,1076 @@ #include #include #include -#include "gitInfoLib.h" - -int slsDetector::initSharedMemory(detectorType type, int id) { - /** - the shared memory key is set to DEFAULT_SHM_KEY+id - */ - key_t mem_key=DEFAULT_SHM_KEY+id; - int shm_id; - int nch, nm, nc, nd, ng, no; - int sz; - - //shmId=-1; -#ifdef VERBOSE - cout << "init shm"<< endl; -#endif - switch(type) { - case MYTHEN: - nch=128; // complete mythen system - nm=24; - nc=10; - nd=6; // dacs+adcs - ng=0; - no=0; - break; - case PICASSO: - nch=128; // complete mythen system - nm=24; - nc=12; - nd=6; // dacs+adcs - ng=0; - no=0; - break; - case GOTTHARD: - nch=128; - nm=1; - nc=10; - nd=13; // dacs+adcs - ng=0; - no=0; - break; - case PROPIX: - nch=22*22; - nm=1; - nc=1; - nd=13; // dacs+adcs - break; - case EIGER: - nch=256*256; // one EIGER half module - nm=1; //modules/detector - nc=4; //chips - nd=16; //dacs+adcs - ng=4; - no=4; - break; - case MOENCH: - nch=160*160; - nm=1; //modules/detector - nc=1; //chips - nd=9; //dacs+adcs - ng=0; - no=0; - break; - case JUNGFRAU: - nch=256*256; - nm=1; //modules/detector - nc=8; //chips - nd=16; //dacs+adcs - ng=0; - no=0; - break; - case JUNGFRAUCTB: - nch=36; //36? is using digital value as well - nm=1; //modules/detector - nc=1; //chips - nd=16; //dacs+adcs - ng=0; - no=0; - break; - default: - nch=0; // dum! - nm=0; //modules/detector - nc=0; //chips - nd=0; //dacs+adcs - ng=0; - no=0; - break; - } - /** - The size of the shared memory is: - size of shared structure + ffcoefficents +fferrors + modules+ dacs+adcs+chips+chans+gain+offset - */ +using namespace std; - sz=sizeof(sharedSlsDetector)+nm*(2*nch*nc*sizeof(double)+sizeof(sls_detector_module)+sizeof(int)*nc+sizeof(dacs_t)*nd+sizeof(int)*nch*nc+sizeof(int)*ng+sizeof(int)*no); -#ifdef VERBOSE - std::cout<<"Size of shared memory is "<< sz << "(type " << type << " - id " << mem_key << ")"<< std::endl; -#endif - shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory +slsDetector::slsDetector(detectorType type, int multiId, int id, bool verify, multiSlsDetector* m) +: slsDetectorUtils(), + detId(id), + sharedMemory(0), + thisDetector(0), + multiDet(m), + thisReceiver(0), + controlSocket(0), + stopSocket(0), + dataSocket(0), + ffcoefficients(0), + fferrors(0), + detectorModules(0), + dacs(0), + adcs(0), + chipregs(0), + chanregs(0), + gain(0), + offset(0) { + /* called from put hostname command, + * so sls shared memory will be created */ - if (shm_id < 0) { - std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; - return shm_id; - } + // ensure shared memory was not created before + SharedMemory* shm = new SharedMemory(multiId, id); + if (shm->IsExisting()) { + cprintf(YELLOW BOLD,"Warning: Weird, this shared memory should have been " + "deleted before! %s. Freeing it again.\n", shm->GetName().c_str()); + freeSharedMemory(multiId, id); + } + delete shm; - /** - thisDetector pointer is set to the memory address of the shared memory - */ - thisDetector = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ + initSharedMemory(true, type, multiId, verify); + initializeDetectorStructure(type); + initializeMembers(); + initializeDetectorStructurePointers(); +} - if (thisDetector == (void*)-1) { - std::cout<<"*** shmat error (server) ***" << std::endl; - return shm_id; - } -#ifdef VERBOSE - cout <<"shm done"<UnmapSharedMemory(thisDetector); + delete sharedMemory; + } + if(thisReceiver) + delete thisReceiver; + if(controlSocket) + delete controlSocket; + if(stopSocket) + delete stopSocket; + if(dataSocket) + delete dataSocket; + /* detectorModules, dacs..ffoerrors are offsets from the + * shared memory and created within shared memory structure. + * Deleting shared memory will also delete memory pointed to + * by these pointers + */ } -int slsDetector::freeSharedMemory() { - // Detach Memory address - if (shmdt(thisDetector) == -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; +bool slsDetector::isMultiSlsDetectorClass() { + return false; } +double* slsDetector::decodeData(int *datain, int &nn, double *fdata) { -slsDetector::slsDetector(int pos, int id, multiSlsDetector *p) :slsDetectorUtils(), - thisDetector(NULL), - detId(id), - posId(pos), - parentDet(p), - shmId(-1), - controlSocket(NULL), - stopSocket(NULL), - dataSocket(NULL), - ffcoefficients(NULL), - fferrors(NULL), - detectorModules(NULL), - dacs(NULL), - adcs(NULL), - chipregs(NULL), - chanregs(NULL), - gain(NULL), - offset(NULL), - thisReceiver(NULL) - - -{ - - - detectorType type=(detectorType)getDetectorType(id); - - while (shmId<0) { - /**Initlializes shared memory \sa initSharedMemory - - if it fails the detector id is incremented until it succeeds - */ - shmId=initSharedMemory(type,id); - ++id; - } - --id; -#ifdef VERBOSE - std::cout<< "Detector id is " << id << std::endl; -#endif - detId=id; - - - /**Initializes the detector stucture \sa initializeDetectorSize - */ - initializeDetectorSize(type); - - - -}; - - - - - -slsDetector::slsDetector(int pos, detectorType type, int id, multiSlsDetector *p): slsDetectorUtils(), - thisDetector(NULL), - detId(id), - posId(pos), - parentDet(p), - shmId(-1), - controlSocket(NULL), - stopSocket(NULL), - dataSocket(NULL), - ffcoefficients(NULL), - fferrors(NULL), - detectorModules(NULL), - dacs(NULL), - adcs(NULL), - chipregs(NULL), - chanregs(NULL), - gain(NULL), - offset(NULL), - thisReceiver(NULL) - -{ - while (shmId<0) { - /**Initlializes shared memory \sa initSharedMemory - - if it fails the detector id is incremented until it succeeds - */ - shmId=initSharedMemory(type,id); - ++id; - } - --id; -#ifdef VERBOSE - std::cout<< "Detector id is " << id << " type is " << type << std::endl; -#endif - detId=id; - - - /**Initializes the detector stucture \sa initializeDetectorSize - */ -#ifdef VERBOSE - cout << "init det size"<< endl; -#endif - initializeDetectorSize(type); - + double *dataout = 0; + if (fdata) { + dataout=fdata; + nn=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; + if (thisDetector->myDetectorType == JUNGFRAUCTB) + nn=thisDetector->dataBytes/2; + } else { + if (thisDetector->myDetectorType == JUNGFRAUCTB) { + nn=thisDetector->dataBytes/2; + dataout=new double[nn]; + } else { + dataout=new double[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + nn=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; + } + } + int ival = 0, ipos = 0, ichan=0, ibyte = 0; + char *ptr = (char*)datain; + char iptr = 0; + int nbits=thisDetector->dynamicRange; + int nch=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; + if (thisDetector->timerValue[PROBES_NUMBER]==0) { + if (thisDetector->myDetectorType==JUNGFRAUCTB) { + for (ichan=0; ichandataBytes; ++ibyte) { + iptr=ptr[ibyte]; + for (ipos=0; ipos<8; ++ipos) { + ival=(iptr>>(ipos))&0x1; + dataout[ichan]=ival; + ++ichan; + } + } + break; + case 4: + for (ibyte=0; ibytedataBytes; ++ibyte) { + iptr=ptr[ibyte]; + for (ipos=0; ipos<2; ++ipos) { + ival=(iptr>>(ipos*4))&0xf; + dataout[ichan]=ival; + ++ichan; + } + } + break; + case 8: + for (ichan=0; ichandataBytes; ++ichan) { + ival=ptr[ichan]&0xff; + dataout[ichan]=ival; + } + break; + case 16: + for (ichan=0; ichanmyDetectorType == MYTHEN) mask=0xffffff; + for (ichan=0; ichangetNumberOfDetectors();++i){ + multiDet->setErrorMask(multiDet->getErrorMask()|(0<setAcquiringFlag(b); +} - int retval=FAIL; - detectorType t=GENERIC; - int fnum=F_GET_DETECTOR_TYPE; - MySocketTCP *s= new MySocketTCP(name, cport); - char m[100]; -#ifdef VERBOSE - cout << "Getting detector type " << endl; -#endif - if (s->Connect()>=0) { - s->SendDataOnly(&fnum,sizeof(fnum)); - s->ReceiveDataOnly(&retval,sizeof(retval)); +bool slsDetector::getAcquiringFlag() { + return multiDet->getAcquiringFlag(); +} - if (retval!=FAIL) { - s->ReceiveDataOnly(&t,sizeof(t)); + +bool slsDetector::isAcquireReady() { + return multiDet->isAcquireReady(); +} + + +int slsDetector::checkVersionCompatibility(portType t) { + int fnum = F_CHECK_VERSION; + if (t == DATA_PORT) + fnum = F_RECEIVER_CHECK_VERSION; + int ret = FAIL; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); + int64_t arg = 0; + + // detector + if (t == CONTROL_PORT) { + + switch (thisDetector->myDetectorType) { + case EIGER: arg = APIEIGER; break; + case JUNGFRAU: arg = APIJUNGFRAU; break; + case GOTTHARD: arg = APIGOTTHARD; break; + default: + std::cout<< "Check version compatibility is not implemented for this " + "detector" << std::endl; + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + return FAIL; + } #ifdef VERBOSE - cout << "Detector type is "<< t << endl; + std::cout<< std::endl<< "Checking version compatibility with detector with " + "value " << hex << arg << std::endl; #endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + // control port + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + cprintf(RED, "Detector returned error: (Control Server) %s", mess); + if(strstr(mess,"Unrecognized Function")!=NULL) + std::cout << "The detector server is too old to get API version. " + "Please update detector server!" << std::endl; + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + thisDetector->detectorControlAPIVersion = 0; + } else { + thisDetector->detectorControlAPIVersion = arg; + } + disconnectControl(); + } + if (ret!= FAIL) { + ret = FAIL; - } else { - s->ReceiveDataOnly(m,sizeof(m)); - std::cout<< "Detector returned error: " << m << std::endl; - } - s->Disconnect(); - } else { - cout << "Cannot connect to server " << name << " over port " << cport << endl; - } + // stop port + if (connectStop() == OK){ + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + cprintf(RED, "Detector returned error: (Stop Server) %s", mess); + if(strstr(mess,"Unrecognized Function")!=NULL) + std::cout << "The detector server is too old to get API " + "version. Please update detector server!" << std::endl; + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + thisDetector->detectorStopAPIVersion = 0; + } else { + thisDetector->detectorStopAPIVersion = arg; + } + disconnectStop(); + } + } + } + } - -/* - //receiver - if((t != GENERIC) && (setReceiverOnline()==ONLINE_FLAG)) { - int k; - retval = FAIL; - if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ + // receiver + else { + arg = APIRECEIVER; #ifdef VERBOSE - std::cout << "Sending detector type to Receiver " << (int)thisDetector->myDetectorType << std::endl; + std::cout<< std::endl<< "Checking version compatibility with receiver with " + "value " << hex << arg << std::endl; #endif - if (connectData() == OK) - retval=thisReceiver->sendInt(fnum2,k,(int)t); - disconnectData(); - if(retval==FAIL){ - cout << "ERROR: Could not send detector type to receiver" << endl; - setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); - } - } - } -*/ - delete s; - return t; + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + // data port + if (connectData() == OK){ + // ignoring retval + int64_t retval = -1; + ret=thisReceiver->sendInt(fnum,retval,arg); + if (ret==FAIL){ + setErrorMask((getErrorMask())|(VERSION_COMPATIBILITY)); + if(strstr(mess,"Unrecognized Function")!=NULL) + std::cout << "The receiver software is too old to get API " + "version. Please update receiver software!" << std::endl; + thisDetector->receiverAPIVersion = 0; + } else { + thisDetector->receiverAPIVersion = arg; + } + disconnectData(); + } + } + } + return ret; } +int64_t slsDetector::getId( idMode mode, int imod) { - - - -int slsDetector::exists(int id) { - - key_t mem_key=DEFAULT_SHM_KEY+id; - int shm_id; - int sz; - - sz=sizeof(sharedSlsDetector); - + int64_t retval=-1; + int fnum=F_GET_ID,fnum2 = F_GET_RECEIVER_ID; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; #ifdef VERBOSE - cout << "getDetectorType: generic shared memory of size " << sz << endl; + std::cout<< std::endl; + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Getting id of "<< imod << std::endl; + else + std::cout<< "Getting id type "<< mode << std::endl; #endif - shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory - - if (shm_id < 0) { - std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; - return -1; - } - - /** - thisDetector pointer is set to the memory address of the shared memory - */ - - sharedSlsDetector* det = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ - - if (det == (void*)-1) { - std::cout<<"*** shmat error (server) ***" << std::endl; - return -1; - } - /** - shm_id returns -1 is shared memory initialization fails - */ - //shmId=shm_id; - - - - - if (det->alreadyExisting==0) { - // Detach Memory address - if (shmdt(det) == -1) { - perror("shmdt failed\n"); - return 0; - } + if (mode==THIS_SOFTWARE_VERSION) { + ret=OK; + retval=GITDATE; + } else if (mode==RECEIVER_VERSION) { + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + if (connectData() == OK){ + ret=thisReceiver->getInt(fnum2,retval); + disconnectData(); + } + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + } else { + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() != OK) + ret = FAIL; + else{ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + if (mode==MODULE_SERIAL_NUMBER) + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + } + if (ret==FAIL) { + std::cout<< "Get id failed " << std::endl; + return ret; + } else { #ifdef VERBOSE - printf("Shared memory %d detached\n", shm_id); + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Id of "<< imod <<" is " << hex <RemoveSharedMemory(); + delete shm; +} + +void slsDetector::freeSharedMemory() { + if (sharedMemory) { + sharedMemory->UnmapSharedMemory(thisDetector); + sharedMemory->RemoveSharedMemory(); + delete sharedMemory; + sharedMemory = 0; + } + thisDetector = 0; +} + +string slsDetector::getUserDetails() { + cprintf(RED, "Error: Get User details should not be called at this level\n"); + return string(""); +} + +void slsDetector::setHostname(const char *name) { + setTCPSocket(string(name)); + if (thisDetector->onlineFlag == ONLINE_FLAG) + updateDetector(); +} + +string slsDetector::getHostname(int pos) { + return string(thisDetector->hostname); +} + +void slsDetector::addMultipleDetectors(const char* name) { + cprintf(RED, "Error: Add Multiple Detectors should not be called at this level\n"); +} + +void slsDetector::initSharedMemory(bool created, detectorType type, int multiId, + bool verify) { + if (sharedMemory) + delete sharedMemory; + thisDetector = 0; + + // calculate shared memory size + int sz = calculateSharedMemorySize(type); + + // shared memory object with name + sharedMemory = new SharedMemory(multiId, detId); + // create + if (created) { + try { + thisDetector = (sharedSlsDetector*)sharedMemory->CreateSharedMemory(sz); + } catch(...) { + sharedMemory->RemoveSharedMemory(); + delete sharedMemory; + sharedMemory = 0; + thisDetector = 0; + throw; + } + } + // open and verify version + else { + thisDetector = (sharedSlsDetector*)sharedMemory->OpenSharedMemory(sz); + if (verify && thisDetector->shmversion != SLS_SHMVERSION) { + cprintf(RED, "Single shared memory (%d-%d:)version mismatch " + "(expected 0x%x but got 0x%x)\n", + multiId, detId, SLS_SHMVERSION, thisDetector->shmversion); + sharedMemory->UnmapSharedMemory(thisDetector); /** is this unncessary? */ + delete sharedMemory;/** is this unncessary? */ + sharedMemory = 0; + throw SharedMemoryException(); + } + } +} + + +void slsDetector::setDetectorSpecificParameters(detectorType type, detParameterList& list) { + switch (type) { + case MYTHEN: + list.nModMaxX = 24; + list.nModMaxY = 1; + list.nChanX = 128; + list.nChanY = 1; + list.nChipX = 10; + list.nChipY = 1; + list.nDacs = 6; + list.nAdcs = 0; + list.nGain = 0; + list.nOffset = 0; + list.dynamicRange = 24; + list.moveFlag = 1; + list.nGappixelsX = 0; + list.nGappixelsY = 0; + break; + case PICASSO: /** is this needed?*/ + list.nModMaxX = 24; + list.nModMaxY = 1; + list.nChanX = 128; + list.nChanY = 1; + list.nChipX = 12; + list.nChipY = 1; + list.nDacs = 6; + list.nAdcs = 0; + list.nGain = 0; + list.nOffset = 0; + list.dynamicRange = 24; + list.moveFlag = 0; + list.nGappixelsX = 0; + list.nGappixelsY = 0; + break; + case GOTTHARD: + list.nModMaxX = 1; + list.nModMaxY = 1; + list.nChanX = 128; + list.nChanY = 1; + list.nChipX = 10; + list.nChipY = 1; + list.nDacs = 8; + list.nAdcs = 5; + list.nGain = 0; + list.nOffset = 0; + list.dynamicRange = 16; + list.moveFlag = 0; + list.nGappixelsX = 0; + list.nGappixelsY = 0; + break; + case PROPIX: + list.nModMaxX = 1; + list.nModMaxY = 1; + list.nChanX = 22; + list.nChanY = 22; + list.nChipX = 1; + list.nChipY = 1; + list.nDacs = 8; + list.nAdcs = 5; + list.nGain = 0; + list.nOffset = 0; + list.dynamicRange = 16; + list.moveFlag = 0; + list.nGappixelsX = 0; + list.nGappixelsY = 0; + break; + case MOENCH: + list.nModMaxX = 1; + list.nModMaxY = 1; + list.nChanX = 160; + list.nChanY = 160; + list.nChipX = 1; + list.nChipY = 1; + list.nDacs = 8; + list.nAdcs = 1; + list.nGain = 0; + list.nOffset = 0; + list.dynamicRange = 16; + list.moveFlag = 0; + list.nGappixelsX = 0; + list.nGappixelsY = 0; + break; + case JUNGFRAU: + list.nModMaxX = 1; + list.nModMaxY = 1; + list.nChanX = 256; + list.nChanY = 256; + list.nChipX = 4; + list.nChipY = 2; + list.nDacs = 16; + list.nAdcs = 0; + list.nGain = 0; + list.nOffset = 0; + list.dynamicRange = 16; + list.moveFlag = 0; + list.nGappixelsX = 0; + list.nGappixelsY = 0; + break; + case JUNGFRAUCTB: + list.nModMaxX = 1; + list.nModMaxY = 1; + list.nChanX = 36; + list.nChanY = 1; + list.nChipX = 1; + list.nChipY = 1; + list.nDacs = 16; + list.nAdcs = 9;//???? When calculating size, only d+a=16 how come?FIXME + list.nGain = 0; + list.nOffset = 0; + list.dynamicRange =16; + list.moveFlag = 0; + list.nGappixelsX = 0; + list.nGappixelsY = 0; + break; + case EIGER: + list.nModMaxX = 1; + list.nModMaxY = 1; + list.nChanX = 256; + list.nChanY = 256; + list.nChipX = 4; + list.nChipY = 1; + list.nDacs = 16; + list.nAdcs = 0; + list.nGain = 0; // can be set back to 4 in case we require it again + list.nOffset = 0; // can be set back to 4 in case we require it again + list.dynamicRange = 16; + list.moveFlag = 0; + list.nGappixelsX = 6; + list.nGappixelsY = 1; + break; + default: + cprintf(RED,"Unknown detector type!\n"); + throw exception(); + } +} + + +int slsDetector::calculateSharedMemorySize(detectorType type) { + // get the detector parameters based on type + detParameterList detlist; + setDetectorSpecificParameters(type, detlist); + int nm = detlist.nModMaxX * detlist.nModMaxY; + int nch = detlist.nChanX * detlist.nChanY; + int nc = detlist.nChipX * detlist.nChipY; + int nd = detlist.nDacs + detlist.nAdcs; + int ng = detlist.nGain; + int no = detlist.nOffset; + + /** The size of the shared memory is + * size of shared structure + + * ffcoefficents+fferrors+modules+dacs+adcs+chips+chans+gain+offset */ + int sz = sizeof(sharedSlsDetector) + + nm * ( + 2 * nch * nc * sizeof(double) + + sizeof(sls_detector_module) + + sizeof(int) * nc + + sizeof(dacs_t) * nd + + sizeof(int) * nch * nc + + sizeof(int) * ng + + sizeof(int) * no); #ifdef VERBOSE - printf("Shared memory %d deleted\n", shm_id); + std::cout<<"Size of shared memory is " << sz << std::endl; #endif - return 0; - } - - return 1; + return sz; +} +void slsDetector::initializeDetectorStructure(detectorType type) { + thisDetector->shmversion = SLS_SHMVERSION; + thisDetector->onlineFlag = OFFLINE_FLAG; + thisDetector->stoppedFlag = 0; + strncpy(thisDetector->hostname, DEFAULT_HOSTNAME, MAX_STR_LENGTH-1); + thisDetector->hostname[MAX_STR_LENGTH-1] = 0; + thisDetector->offset[X] = 0; + thisDetector->offset[Y] = 0; + thisDetector->controlPort = DEFAULT_PORTNO; + thisDetector->stopPort = DEFAULT_PORTNO + 1; + thisDetector->myDetectorType = type; + strncpy(thisDetector->settingsDir, getenv("HOME"), MAX_STR_LENGTH-1); + thisDetector->settingsDir[MAX_STR_LENGTH-1] = 0; + strncpy(thisDetector->calDir, getenv("HOME"), MAX_STR_LENGTH-1); + thisDetector->calDir[MAX_STR_LENGTH-1] = 0; + thisDetector->nTrimEn = 0; + for(int i = 0; i < MAX_TRIMEN; ++i) + thisDetector->trimEnergies[i] = 0; + thisDetector->progressIndex = 0; + thisDetector->totalProgress = 1; + strcpy(thisDetector->filePath, "/"); + thisDetector->correctionMask = 0; + thisDetector->threadedProcessing = 1; + thisDetector->tDead = 0; + strncpy(thisDetector->flatFieldDir, getenv("HOME"), MAX_STR_LENGTH-1); + thisDetector->flatFieldDir[MAX_STR_LENGTH-1] = 0; + strcpy(thisDetector->flatFieldFile, "none"); + thisDetector->nBadChans = 0; + strcpy(thisDetector->badChanFile, "none"); + thisDetector->nBadFF = 0; + for (int i = 0; i < MAX_BADCHANS; ++i) { + thisDetector->badChansList[i] = 0; + thisDetector->badFFList[i] = 0; + } + strcpy(thisDetector->angConvFile, "none"); + memset(thisDetector->angOff, 0, MAXMODS * sizeof(angleConversionConstant)); + thisDetector->angDirection = 1; + thisDetector->fineOffset = 0; + thisDetector->globalOffset = 0; + thisDetector->numberOfPositions = 0; + for (int i = 0; i < MAXPOS; ++i) { + thisDetector->detPositions[i] = 0; + } + thisDetector->binSize = 0.001; + thisDetector->nROI = 0; + memset(thisDetector->roiLimits, 0, MAX_ROIS * sizeof(ROI)); + thisDetector->roFlags = NORMAL_READOUT; + strcpy(thisDetector->settingsFile, "none"); + thisDetector->currentSettings = UNINITIALIZED; + thisDetector->currentThresholdEV = -1; + thisDetector->timerValue[FRAME_NUMBER] = 1; + thisDetector->timerValue[ACQUISITION_TIME] = 0; + thisDetector->timerValue[FRAME_PERIOD] = 0; + thisDetector->timerValue[DELAY_AFTER_TRIGGER] = 0; + thisDetector->timerValue[GATES_NUMBER] = 0; + thisDetector->timerValue[PROBES_NUMBER] = 0; + thisDetector->timerValue[CYCLES_NUMBER] = 1; + thisDetector->timerValue[ACTUAL_TIME] = 0; + thisDetector->timerValue[MEASUREMENT_TIME] = 0; + thisDetector->timerValue[PROGRESS] = 0; + thisDetector->timerValue[MEASUREMENTS_NUMBER] = 1; + thisDetector->timerValue[FRAMES_FROM_START] = 0; + thisDetector->timerValue[FRAMES_FROM_START_PG] = 0; + thisDetector->timerValue[SAMPLES_JCTB] = 1; + thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME] = 0; + thisDetector->timerValue[STORAGE_CELL_NUMBER] = 0; + thisDetector->timerValue[SUBFRAME_PERIOD] = 0; + thisDetector->actionMask = 0; + for (int i = 0; i < MAX_ACTIONS; ++i) { + strcpy(thisDetector->actionScript[i], "none"); + strcpy(thisDetector->actionParameter[i], "none"); + } + for (int i = 0; i < MAX_SCAN_LEVELS; ++i) { + thisDetector->scanMode[i] = 0; + strcpy(thisDetector->scanScript[i], "none"); + strcpy(thisDetector->scanParameter[i], "none"); + thisDetector->nScanSteps[i] = 0; + { + double initValue = 0; + std::fill_n(thisDetector->scanSteps[i], MAX_SCAN_STEPS, initValue); + } + thisDetector->scanPrecision[i] = 0; + } + strcpy(thisDetector->receiver_hostname, "none"); + thisDetector->receiverTCPPort = DEFAULT_PORTNO+2; + thisDetector->receiverUDPPort = DEFAULT_UDP_PORTNO; + thisDetector->receiverUDPPort2 = DEFAULT_UDP_PORTNO + 1; + strcpy(thisDetector->receiverUDPIP, "none"); + strcpy(thisDetector->receiverUDPMAC, "none"); + strncpy(thisDetector->detectorMAC, DEFAULT_DET_MAC, MAX_STR_LENGTH-1); + thisDetector->detectorMAC[MAX_STR_LENGTH-1] = 0; + strncpy(thisDetector->detectorIP, DEFAULT_DET_IP, MAX_STR_LENGTH-1); + thisDetector->detectorIP[MAX_STR_LENGTH-1] = 0; + thisDetector->receiverOnlineFlag = OFFLINE_FLAG; + thisDetector->tenGigaEnable = 0; + thisDetector->flippedData[X] = 0; + thisDetector->flippedData[Y] = 0; + thisDetector->zmqport = DEFAULT_ZMQ_CL_PORTNO + + (detId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1)); + thisDetector->receiver_zmqport = DEFAULT_ZMQ_RX_PORTNO + + (detId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1)); + thisDetector->receiver_upstream = false; + thisDetector->receiver_read_freq = 0; + memset(thisDetector->zmqip, 0, MAX_STR_LENGTH); + memset(thisDetector->receiver_zmqip, 0, MAX_STR_LENGTH); + thisDetector->gappixels = 0; + memset(thisDetector->receiver_additionalJsonHeader, 0, MAX_STR_LENGTH); + thisDetector->receiver_framesPerFile = -1; + thisDetector->detectorControlAPIVersion = 0; + thisDetector->detectorStopAPIVersion = 0; + thisDetector->receiverAPIVersion = 0; + thisDetector->receiver_frameDiscardMode = NO_DISCARD; + thisDetector->receiver_framePadding = 1; + + // get the detector parameters based on type + detParameterList detlist; + setDetectorSpecificParameters(type, detlist); + thisDetector->nModMax[X] = detlist.nModMaxX; + thisDetector->nModMax[Y] = detlist.nModMaxY; + thisDetector->nChan[X] = detlist.nChanX; + thisDetector->nChan[Y] = detlist.nChanY; + thisDetector->nChip[X] = detlist.nChipX; + thisDetector->nChip[Y] = detlist.nChipY; + thisDetector->nDacs = detlist.nDacs; + thisDetector->nAdcs = detlist.nAdcs; + thisDetector->nGain = detlist.nGain; + thisDetector->nOffset = detlist.nOffset; + thisDetector->dynamicRange = detlist.dynamicRange; + thisDetector->moveFlag = detlist.moveFlag; + detlist.nGappixelsY = detlist.nGappixelsX; + thisDetector->nGappixels[Y] = detlist.nGappixelsY; + + + // derived parameters + thisDetector->nModsMax = thisDetector->nModMax[X] * thisDetector->nModMax[Y]; + thisDetector->nChans = thisDetector->nChan[X] * thisDetector->nChan[Y]; + thisDetector->nChips = thisDetector->nChip[X] * thisDetector->nChip[Y]; + // number of modules is initally the maximum number of modules + thisDetector->nMod[X] = thisDetector->nModMax[X]; + thisDetector->nMod[Y] = thisDetector->nModMax[Y]; + thisDetector->nMods = thisDetector->nModsMax; + + // calculating databytes + thisDetector->dataBytes = thisDetector->nMods * thisDetector->nChips * + thisDetector->nChans * thisDetector->dynamicRange/8; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + thisDetector->dynamicRange/8; + + // special for jctb and mythen in 24 bit/ with probes + if(thisDetector->myDetectorType==JUNGFRAUCTB){ + getTotalNumberOfChannels(); + } + else if(thisDetector->myDetectorType == MYTHEN){ + if (thisDetector->dynamicRange == 24 || thisDetector->timerValue[PROBES_NUMBER] > 0) { + thisDetector->dataBytes = thisDetector->nMods * thisDetector->nChips * + thisDetector->nChans * 4; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * + thisDetector->nChan[Y] + + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + 4; + } + } + + /** calculates the memory offsets for + * flat field coefficients and errors, + * module structures, dacs, adcs, chips and channels */ + thisDetector->ffoff = sizeof(sharedSlsDetector); + thisDetector->fferroff = thisDetector->ffoff + sizeof(double) * + thisDetector->nChans * thisDetector->nChips * thisDetector->nModsMax; + thisDetector->modoff = thisDetector->fferroff + sizeof(double) * + thisDetector->nChans * thisDetector->nChips * thisDetector->nModsMax; + thisDetector->dacoff = thisDetector->modoff + + sizeof(sls_detector_module) * thisDetector->nModsMax; + thisDetector->adcoff = thisDetector->dacoff + + sizeof(dacs_t) * thisDetector->nDacs * thisDetector->nModsMax; + thisDetector->chipoff = thisDetector->adcoff + + sizeof(dacs_t) * thisDetector->nAdcs * thisDetector->nModsMax; + thisDetector->chanoff = thisDetector->chipoff + + sizeof(int) * thisDetector->nChips * thisDetector->nModsMax; + thisDetector->gainoff = thisDetector->chanoff + + sizeof(int) * thisDetector->nGain * thisDetector->nModsMax; + thisDetector->offsetoff = thisDetector->gainoff + + sizeof(int) * thisDetector->nOffset * thisDetector->nModsMax; + +} + + +void slsDetector::initializeMembers() { + // slsdetector + // assign addresses + char *goff = (char*)thisDetector; + ffcoefficients = (double*)(goff + thisDetector->ffoff); + fferrors = (double*)(goff + thisDetector->fferroff); + detectorModules = (sls_detector_module*)(goff + thisDetector->modoff); + dacs = (dacs_t*)(goff + thisDetector->dacoff); + adcs = (dacs_t*)(goff + thisDetector->adcoff); + chipregs = (int*)(goff + thisDetector->chipoff); + chanregs = (int*)(goff + thisDetector->chanoff); + gain = (int*)(goff + thisDetector->gainoff); + offset = (int*)(goff + thisDetector->offsetoff); + if (thisReceiver) { + delete thisReceiver; + thisReceiver = 0; + } + thisReceiver = new receiverInterface(dataSocket); + + + // slsDetectorUtils + stoppedFlag = &thisDetector->stoppedFlag; + timerValue = thisDetector->timerValue; + currentSettings = &thisDetector->currentSettings; + currentThresholdEV = &thisDetector->currentThresholdEV; + + // fileIO + filePath = thisDetector->filePath; + fileName=multiDet->fileName; + fileIndex=multiDet->fileIndex; + framesPerFile=multiDet->framesPerFile; + fileFormatType=multiDet->fileFormatType; + + if (thisDetector->myDetectorType != MYTHEN) + fileIO::setFileFormat(BINARY); + switch(thisDetector->myDetectorType) { + case GOTTHARD: + case PROPIX: + fileIO::setFramesPerFile(MAX_FRAMES_PER_FILE); + break; + case EIGER: + fileIO::setFramesPerFile(EIGER_MAX_FRAMES_PER_FILE); + break; + case MOENCH: + fileIO::setFramesPerFile(MOENCH_MAX_FRAMES_PER_FILE); + break; + case JUNGFRAU: + fileIO::setFramesPerFile(JFRAU_MAX_FRAMES_PER_FILE); + break; + case JUNGFRAUCTB: + fileIO::setFramesPerFile(JFRAU_MAX_FRAMES_PER_FILE); + break; + default: + break; + } + + + //postProcessing + threadedProcessing = &thisDetector->threadedProcessing; + correctionMask = &thisDetector->correctionMask; + flatFieldDir = thisDetector->flatFieldDir; + flatFieldFile = thisDetector->flatFieldFile; + expTime = &timerValue[ACQUISITION_TIME]; + badChannelMask = NULL; + fdata = NULL; + thisData = NULL; + + + // slsDetectorActions + actionMask = &thisDetector->actionMask; + actionScript = thisDetector->actionScript; + actionParameter = thisDetector->actionParameter; + nScanSteps = thisDetector->nScanSteps; + scanSteps = thisDetector->scanSteps; + scanMode = thisDetector->scanMode; + scanPrecision = thisDetector->scanPrecision; + scanScript = thisDetector->scanScript; + scanParameter = thisDetector->scanParameter; + + // angularConversion + numberOfPositions = &thisDetector->numberOfPositions; + detPositions = thisDetector->detPositions; + angConvFile = thisDetector->angConvFile; + binSize = &thisDetector->binSize; + fineOffset = &thisDetector->fineOffset; + globalOffset = &thisDetector->globalOffset; + angDirection = &thisDetector->angDirection; + moveFlag = &thisDetector->moveFlag; + sampleDisplacement = NULL; + + // badChannelCorrections + badChanFile = thisDetector->badChanFile; + nBadChans = &thisDetector->nBadChans; + badChansList = thisDetector->badChansList; + nBadFF = &thisDetector->nBadFF; + badFFList = thisDetector->badFFList; + + //energyConversion + settingsFile = thisDetector->settingsFile; } +void slsDetector::initializeDetectorStructurePointers() { + sls_detector_module* thisMod; + for (int imod = 0; imod < thisDetector->nModsMax; ++imod) { -slsDetectorDefs::detectorType slsDetector::getDetectorType(int id) { - - detectorType t=GENERIC; - - - key_t mem_key=DEFAULT_SHM_KEY+id; - int shm_id; - int sz; - - sz=sizeof(sharedSlsDetector); - - -#ifdef VERBOSE - cout << "getDetectorType: generic shared memory of size " << sz << endl; -#endif - shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory - - if (shm_id < 0) { - std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; - return t; - } - - /** - thisDetector pointer is set to the memory address of the shared memory - */ - - sharedSlsDetector* det = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ - - if (det == (void*)-1) { - std::cout<<"*** shmat error (server) ***" << std::endl; - return t; - } - /** - shm_id returns -1 is shared memory initialization fails - */ - //shmId=shm_id; - - t=det->myDetectorType; - - - if (det->alreadyExisting==0) { - // Detach Memory address - if (shmdt(det) == -1) { - perror("shmdt failed\n"); - return t; - } -#ifdef VERBOSE - printf("Shared memory %d detached\n", shm_id); -#endif - // remove shared memory - if (shmctl(shm_id, IPC_RMID, 0) == -1) { - perror("shmctl(IPC_RMID) failed\n"); - return t; - } -#ifdef VERBOSE - printf("Shared memory %d deleted\n", shm_id); -#endif - } - -#ifdef VERBOSE - cout << "Detector type is " << t << endl; -#endif - - return t; + // initializes the ffcoefficients values to 0 + for (int i = 0; i < thisDetector->nChans * thisDetector->nChips; ++i) { + *(ffcoefficients + i + thisDetector->nChans * thisDetector->nChips * imod) = 0; + } + // initializes the fferrors values to 0 + for (int i = 0; i < thisDetector->nChans * thisDetector->nChips; ++i) { + *(fferrors + i + thisDetector->nChans * thisDetector->nChips * imod) = 0; + } + // set thisMod to point to one of the detector structure modules + thisMod = detectorModules + imod; + thisMod->module = imod; + thisMod->serialnumber = 0; + thisMod->nchan = thisDetector->nChans*thisDetector->nChips; + thisMod->nchip = thisDetector->nChips; + thisMod->ndac = thisDetector->nDacs; + thisMod->nadc = thisDetector->nAdcs; + thisMod->reg = 0; + // dacs, adcs, chipregs and chanregs for thisMod is not allocated in + // detectorModules in shared memory as they are already allocated separately + // in shared memory (below) + thisMod->gain = -1.; + thisMod->offset = -1.; + // initializes the dacs values to 0 + for (int i = 0; i < thisDetector->nDacs; ++i) { + *(dacs + i + thisDetector->nDacs * imod) = 0; + } + // initializes the adc values to 0 + for (int i = 0; i < thisDetector->nAdcs; ++i) { + *(adcs + i + thisDetector->nAdcs * imod) = 0; + } + // initializes the chip registers to 0 + for (int i = 0; i < thisDetector->nChips; ++i) { + *(chipregs + i + thisDetector->nChips * imod) = -1; + } + // initializes the channel registers to 0 + for (int i = 0; i < thisDetector->nChans * thisDetector->nChips; ++i) { + *(chanregs + i + thisDetector->nChans * thisDetector->nChips * imod) = -1; + } + // initializes the gain values to 0 + for (int i = 0; i < thisDetector->nGain; ++i) { + *(gain + i + thisDetector->nGain * imod) = 0; + } + // initializes the offset values to 0 + for (int i = 0; i < thisDetector->nOffset; ++i) { + *(offset + i + thisDetector->nOffset * imod) = 0; + } + } } -int slsDetector::initializeDetectorSize(detectorType type) { - char *goff; - goff=(char*)thisDetector; - - // cout << "init detector size" << endl; - - /** if the shared memory has newly be created, initialize the detector variables */ - if (thisDetector->alreadyExisting==0) { - - // cout << "detector not existing " << endl; - - /** set hostname to default */ - strcpy(thisDetector->hostname,DEFAULT_HOSTNAME); - - /** set receiver tcp port */ - thisDetector->receiverTCPPort=DEFAULT_PORTNO+2; - /** set receiver udp port */ - thisDetector->receiverUDPPort=DEFAULT_UDP_PORTNO; - /** set receiver udp port for Eiger */ - thisDetector->receiverUDPPort2=DEFAULT_UDP_PORTNO+1; - /** set receiver ip address/hostname */ - memset(thisDetector->receiver_hostname,0,MAX_STR_LENGTH); - strcpy(thisDetector->receiver_hostname,"none"); - /** set receiver udp ip address */ - memset(thisDetector->receiverUDPIP,0,MAX_STR_LENGTH); - strcpy(thisDetector->receiverUDPIP,"none"); - /** set receiver udp mac address */ - memset(thisDetector->receiverUDPMAC,0,MAX_STR_LENGTH); - strcpy(thisDetector->receiverUDPMAC,"none"); - /** set detector mac address */ - memset(thisDetector->detectorMAC,0,MAX_STR_LENGTH); - strcpy(thisDetector->detectorMAC,DEFAULT_DET_MAC); - /** set detector ip address */ - memset(thisDetector->detectorIP,0,MAX_STR_LENGTH); - strcpy(thisDetector->detectorIP,DEFAULT_DET_IP); - /** set zmq tcp src ip address in client */ - memset(thisDetector->zmqip,0,MAX_STR_LENGTH); - /** set zmq tcp src ip address in receiver*/ - memset(thisDetector->receiver_zmqip,0,MAX_STR_LENGTH); - - - /** sets onlineFlag to OFFLINE_FLAG */ - thisDetector->onlineFlag=OFFLINE_FLAG; - /** set ports to defaults */ - thisDetector->controlPort=DEFAULT_PORTNO; - thisDetector->stopPort=DEFAULT_PORTNO+1; - - /** set thisDetector->myDetectorType to type and according to this set nChans, nChips, nDacs, nAdcs, nModMax, dynamicRange, nMod*/ - thisDetector->myDetectorType=type; - thisDetector->gappixels = 0; - thisDetector->nGappixels[X]=0; - thisDetector->nGappixels[Y]=0; - switch(thisDetector->myDetectorType) { - case MYTHEN: - thisDetector->nChan[X]=128; - thisDetector->nChan[Y]=1; - thisDetector->nChip[X]=10; - thisDetector->nChip[Y]=1; - thisDetector->nDacs=6; - thisDetector->nAdcs=0; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=24; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=24; - thisDetector->moveFlag=1; -#ifdef VERBOSE - cout << "move flag" << thisDetector->moveFlag<< endl; -#endif - break; - case PICASSO: - thisDetector->nChan[X]=128; - thisDetector->nChan[Y]=1; - thisDetector->nChip[X]=12; - thisDetector->nChip[Y]=1; - thisDetector->nDacs=6; - thisDetector->nAdcs=0; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=6; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=24; - break; - case GOTTHARD: - thisDetector->nChan[X]=128; - thisDetector->nChan[Y]=1; - thisDetector->nChip[X]=10; - thisDetector->nChip[Y]=1; - thisDetector->nDacs=8; - thisDetector->nAdcs=5; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=1; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=16; - break; - case PROPIX: - thisDetector->nChan[X]=22; - thisDetector->nChan[Y]=22; - thisDetector->nChip[X]=1; - thisDetector->nChip[Y]=1; - thisDetector->nDacs=8; - thisDetector->nAdcs=5; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=1; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=16; - break; - case MOENCH: - thisDetector->nChan[X]=160; - thisDetector->nChan[Y]=160; - thisDetector->nChip[X]=1; - thisDetector->nChip[Y]=1; - thisDetector->nDacs=8; - thisDetector->nAdcs=1; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=1; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=16; - break; - case JUNGFRAU: - thisDetector->nChan[X]=256; - thisDetector->nChan[Y]=256; - thisDetector->nChip[X]=4; - thisDetector->nChip[Y]=2; - thisDetector->nDacs=16; - thisDetector->nAdcs=0; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=1; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=16; - break; - case JUNGFRAUCTB: - thisDetector->nChan[X]=36; - thisDetector->nChan[Y]=1; - thisDetector->nChip[X]=1; - thisDetector->nChip[Y]=1; - thisDetector->nDacs=16; - thisDetector->nAdcs=9; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=1; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=16; - break; - case EIGER: - thisDetector->nChan[X]=256; - thisDetector->nChan[Y]=256; - thisDetector->nChip[X]=4; - thisDetector->nChip[Y]=1; - thisDetector->nDacs=16; - thisDetector->nAdcs=0; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=1; - thisDetector->nModMax[Y]=1; - thisDetector->dynamicRange=16; - thisDetector->nGappixels[X]=6; - thisDetector->nGappixels[Y]=1; - break; - default: - thisDetector->nChan[X]=0; - thisDetector->nChan[Y]=0; - thisDetector->nChip[X]=0; - thisDetector->nChip[Y]=0; - thisDetector->nDacs=0; - thisDetector->nAdcs=0; - thisDetector->nGain=0; - thisDetector->nOffset=0; - thisDetector->nModMax[X]=0; - thisDetector->nModMax[Y]=0; - thisDetector->dynamicRange=32; - } - thisDetector->nChans=thisDetector->nChan[X]*thisDetector->nChan[Y]; - thisDetector->nChips=thisDetector->nChip[X]*thisDetector->nChip[Y]; - thisDetector->nModsMax=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; - /** number of modules is initally the maximum number of modules */ - thisDetector->nMod[X]=thisDetector->nModMax[X]; - thisDetector->nMod[Y]=thisDetector->nModMax[Y]; - thisDetector->nMods=thisDetector->nModsMax; - /** calculates the expected data size */ - thisDetector->timerValue[PROBES_NUMBER]=0; - thisDetector->timerValue[FRAME_NUMBER]=1; - thisDetector->timerValue[MEASUREMENTS_NUMBER]=1; - thisDetector->timerValue[CYCLES_NUMBER]=1; - thisDetector->timerValue[SAMPLES_JCTB]=1; - - // calculating databytes (special when with gap pixels, jctb, mythen in 24bit mode or using probes) - thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*thisDetector->dynamicRange/8; - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - thisDetector->dynamicRange/8; - - if(thisDetector->myDetectorType==JUNGFRAUCTB){ - getTotalNumberOfChannels(); - } - else if(thisDetector->myDetectorType==MYTHEN){ - if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) { - thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - 4; - } - } - - /** set trimDsdir, calDir to default to home directory*/ - strcpy(thisDetector->settingsDir,getenv("HOME")); - strcpy(thisDetector->calDir,getenv("HOME")); - - /** sets trimbit file */ - strcpy(thisDetector->settingsFile,"none"); - /** set progress Index to default to 0*/ - thisDetector->progressIndex=0; - /** set total number of frames to be acquired to default to 1*/ - thisDetector->totalProgress=1; - - /** set trimDsdir, calDir and filePath to default to root directory*/ - strcpy(thisDetector->filePath,"/"); - - /** set number of trim energies to 0*/ - thisDetector->nTrimEn=0; - /** set correction mask to 0*/ - thisDetector->correctionMask=0; - /** set deat time*/ - thisDetector->tDead=0; - /** sets bad channel list file to none */ - strcpy(thisDetector->badChanFile,"none"); - /** sets flat field correction directory */ - strcpy(thisDetector->flatFieldDir,getenv("HOME")); - /** sets flat field correction file */ - strcpy(thisDetector->flatFieldFile,"none"); - /** set number of bad chans to 0*/ - thisDetector->nBadChans=0; - /** set number of bad flat field chans to 0*/ - thisDetector->nBadFF=0; - /** set angular direction to 1*/ - thisDetector->angDirection=1; - /** set fine offset to 0*/ - thisDetector->fineOffset=0; - /** set global offset to 0*/ - thisDetector->globalOffset=0; - /** set number of rois to 0*/ - thisDetector->nROI=0; - /** set readoutflags to none*/ - thisDetector->roFlags=NORMAL_READOUT; - /** set current settings to uninitialized*/ - thisDetector->currentSettings=UNINITIALIZED; - /** set threshold to -1*/ - thisDetector->currentThresholdEV=-1; - // /** set clockdivider to 1*/ - // thisDetector->clkDiv=1; - /** set number of positions to 0*/ - thisDetector->numberOfPositions=0; - /** sets angular conversion file to none */ - strcpy(thisDetector->angConvFile,"none"); - /** set binsize*/ - thisDetector->binSize=0.001; - thisDetector->stoppedFlag=0; - thisDetector->threadedProcessing=1; - - thisDetector->actionMask=0; - - thisDetector->tenGigaEnable=0; - thisDetector->flippedData[0] = 0; - thisDetector->flippedData[1] = 0; - thisDetector->zmqport = 0; - thisDetector->receiver_zmqport = 0; - thisDetector->receiver_upstream = false; - thisDetector->receiver_read_freq = 0; - - for (int ia=0; iaactionScript[ia],"none"); - strcpy(thisDetector->actionParameter[ia],"none"); - } - - - for (int iscan=0; iscanscanMode[iscan]=0; - strcpy(thisDetector->scanScript[iscan],"none"); - strcpy(thisDetector->scanParameter[iscan],"none"); - thisDetector->nScanSteps[iscan]=0; - thisDetector->scanPrecision[iscan]=0; - } - - /* receiver*/ - /** sets receiver onlineFlag to OFFLINE_FLAG */ - thisDetector->receiverOnlineFlag=OFFLINE_FLAG; - - - /** calculates the memory offsets for flat field coefficients and errors, module structures, dacs, adcs, chips and channels */ - thisDetector->ffoff=sizeof(sharedSlsDetector); - thisDetector->fferroff=thisDetector->ffoff+sizeof(double)*thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax; - thisDetector->modoff= thisDetector->fferroff+sizeof(double)*thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax; - thisDetector->dacoff=thisDetector->modoff+sizeof(sls_detector_module)*thisDetector->nModsMax; - thisDetector->adcoff=thisDetector->dacoff+sizeof(dacs_t)*thisDetector->nDacs*thisDetector->nModsMax; - thisDetector->chipoff=thisDetector->adcoff+sizeof(dacs_t)*thisDetector->nAdcs*thisDetector->nModsMax; - thisDetector->chanoff=thisDetector->chipoff+sizeof(int)*thisDetector->nChips*thisDetector->nModsMax; - thisDetector->gainoff=thisDetector->chanoff+sizeof(int)*thisDetector->nGain*thisDetector->nModsMax; - thisDetector->offsetoff=thisDetector->gainoff+sizeof(int)*thisDetector->nOffset*thisDetector->nModsMax; - - if(thisDetector->myDetectorType==JUNGFRAUCTB) { - getTotalNumberOfChannels(); - } - - } - - - /** also in case thisDetector alread existed initialize the pointer for flat field coefficients and errors, module structures, dacs, adcs, chips and channels */ - ffcoefficients=(double*)(goff+thisDetector->ffoff); - fferrors=(double*)(goff+thisDetector->fferroff); - detectorModules=(sls_detector_module*)(goff+ thisDetector->modoff); -#ifdef VERBOSE - // for (int imod=0; imod< thisDetector->nModsMax; ++imod) - // std::cout<< hex << detectorModules+imod << dec <nBadChans; - badChansList=thisDetector->badChansList; - badChanFile=thisDetector->badChanFile; - nBadFF=&thisDetector->nBadFF; - badFFList=thisDetector->badFFList; - - dacs=(dacs_t*)(goff+thisDetector->dacoff); - adcs=(dacs_t*)(goff+thisDetector->adcoff); - chipregs=(int*)(goff+thisDetector->chipoff); - chanregs=(int*)(goff+thisDetector->chanoff); - gain=(int*)(goff+thisDetector->gainoff); - offset=(int*)(goff+thisDetector->offsetoff); - if (thisDetector->alreadyExisting==0) { - /** if thisDetector is new, initialize its structures \sa initializeDetectorStructure(); */ - initializeDetectorStructure(); - /** set thisDetector->alreadyExisting=1 */ - thisDetector->alreadyExisting=1; - } - -#ifdef VERBOSE - cout << "passing pointers" << endl; -#endif - - - stoppedFlag=&thisDetector->stoppedFlag; - threadedProcessing=&thisDetector->threadedProcessing; - actionMask=&thisDetector->actionMask; - actionScript=thisDetector->actionScript; - actionParameter=thisDetector->actionParameter; - nScanSteps=thisDetector->nScanSteps; - scanMode=thisDetector->scanMode; - scanScript=thisDetector->scanScript; - scanParameter=thisDetector->scanParameter; - scanSteps=thisDetector->scanSteps; - scanPrecision=thisDetector->scanPrecision; - numberOfPositions=&thisDetector->numberOfPositions; - detPositions=thisDetector->detPositions; - angConvFile=thisDetector->angConvFile; - correctionMask=&thisDetector->correctionMask; - binSize=&thisDetector->binSize; - fineOffset=&thisDetector->fineOffset; - globalOffset=&thisDetector->globalOffset; - angDirection=&thisDetector->angDirection; - flatFieldDir=thisDetector->flatFieldDir; - flatFieldFile=thisDetector->flatFieldFile; - badChanFile=thisDetector->badChanFile; - timerValue=thisDetector->timerValue; - expTime=&timerValue[ACQUISITION_TIME]; - - currentSettings=&thisDetector->currentSettings; - currentThresholdEV=&thisDetector->currentThresholdEV; - moveFlag=&thisDetector->moveFlag; - sampleDisplacement=NULL; - settingsFile=thisDetector->settingsFile; - - filePath=thisDetector->filePath; - pthread_mutex_lock(&ms); - fileName=parentDet->fileName; - fileIndex=parentDet->fileIndex; - framesPerFile=parentDet->framesPerFile; - fileFormatType=parentDet->fileFormatType; - if((thisDetector->myDetectorType==GOTTHARD)||(thisDetector->myDetectorType==PROPIX)){ - fileIO::setFramesPerFile(MAX_FRAMES_PER_FILE); - pthread_mutex_unlock(&ms); - setFileFormat(BINARY); - }else if (thisDetector->myDetectorType==EIGER){ - fileIO::setFramesPerFile(EIGER_MAX_FRAMES_PER_FILE); - pthread_mutex_unlock(&ms); - setFileFormat(BINARY); - }else if (thisDetector->myDetectorType==MOENCH){ - fileIO::setFramesPerFile(MOENCH_MAX_FRAMES_PER_FILE); - pthread_mutex_unlock(&ms); - setFileFormat(BINARY); - }else if (thisDetector->myDetectorType==JUNGFRAU){ - fileIO::setFramesPerFile(JFRAU_MAX_FRAMES_PER_FILE); - pthread_mutex_unlock(&ms); - setFileFormat(BINARY); - }else if (thisDetector->myDetectorType==JUNGFRAUCTB){ - setFramesPerFile(JFCTB_MAX_FRAMES_PER_FILE); - fileIO::setFramesPerFile(JFRAU_MAX_FRAMES_PER_FILE); - pthread_mutex_unlock(&ms); - setFileFormat(BINARY); - }else - pthread_mutex_unlock(&ms); - if (thisReceiver != NULL) - delete thisReceiver; - thisReceiver = new receiverInterface(dataSocket); - - // zmq ports - if (posId != -1) { - if (thisDetector->zmqport == 0) - thisDetector->zmqport = DEFAULT_ZMQ_CL_PORTNO + (posId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1)); - if (thisDetector->receiver_zmqport == 0) - thisDetector->receiver_zmqport = DEFAULT_ZMQ_RX_PORTNO + (posId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1)); - } - - // setAngularConversionPointer(thisDetector->angOff,&thisDetector->nMods, thisDetector->nChans*thisDetector->nChips); - -#ifdef VERBOSE - cout << "done" << endl; -#endif - - - /** modifies the last PID accessing the detector */ - thisDetector->lastPID=getpid(); - -#ifdef VERBOSE - cout << "Det size initialized " << endl; -#endif - - return OK; +slsDetectorDefs::sls_detector_module* slsDetector::createModule() { + return createModule(thisDetector->myDetectorType); } -int slsDetector::initializeDetectorStructure() { - sls_detector_module *thisMod; - //char *p2; - //p2=(char*)thisDetector; - /** for each of the detector modules up to the maximum number which can be installed initlialize the sls_detector_module structure \sa ::sls_detector_module*/ - for (int imod=0; imodnModsMax; ++imod) { +slsDetectorDefs::sls_detector_module* slsDetector::createModule(detectorType type) { + // get the detector parameters based on type + detParameterList detlist; + int nch = 0, nc = 0, nd = 0, na = 0; + try { + setDetectorSpecificParameters(type, detlist); + nch = detlist.nChanX * detlist.nChanY; + nc = detlist.nChipX * detlist.nChipY; + nd = detlist.nDacs; + na = detlist.nAdcs; + } catch(...) { + ;// FIXME do what here? + } + dacs_t *dacs=new dacs_t[nd]; + dacs_t *adcs=new dacs_t[na]; + int *chipregs=new int[nc]; + int *chanregs=new int[nch*nc]; - - - thisMod=detectorModules+imod; - thisMod->module=imod; - - /** sets the size of the module to nChans, nChips etc. */ - thisMod->nchan=thisDetector->nChans*thisDetector->nChips; - thisMod->nchip=thisDetector->nChips; - thisMod->ndac=thisDetector->nDacs; - thisMod->nadc=thisDetector->nAdcs; - - - /** initializes the serial number and register to 0 */ - thisMod->serialnumber=0; - thisMod->reg=0; - - /** initializes the dacs values to 0 */ - for (int idac=0; idacnDacs; ++idac) { - *(dacs+idac+thisDetector->nDacs*imod)=0; - } - - - /** initializes the adc values to 0 */ - for (int iadc=0; iadcnAdcs; ++iadc) { - *(adcs+iadc+thisDetector->nAdcs*imod)=0; - } - - - - /** initializes the chip registers to 0 */ - for (int ichip=0; ichipnChips; ++ichip) { - *(chipregs+ichip+thisDetector->nChips*imod)=-1; - } - - - /** initializes the channel registers to 0 */ - for (int ichan=0; ichannChans*thisDetector->nChips; ++ichan) { - *(chanregs+ichan+thisDetector->nChips*thisDetector->nChans*imod)=-1; - } - - /** initializes the gain values to 0 */ - for (int igain=0; igainnGain; ++igain) { - *(gain+igain+thisDetector->nGain*imod)=0; - } - - - /** initializes the offset values to 0 */ - for (int ioffset=0; ioffsetnOffset; ++ioffset) { - *(offset+ioffset+thisDetector->nOffset*imod)=0; - } - - /** initialize gain and offset to -1 */ - thisMod->gain=-1.; - thisMod->offset=-1.; - } - return 0; -} - -slsDetectorDefs::sls_detector_module* slsDetector::createModule(detectorType t) { - - sls_detector_module *myMod=(sls_detector_module*)malloc(sizeof(sls_detector_module)); - - - int nch, nc, nd, na=0; - // int nm = 0; - - switch(t) { - case MYTHEN: - nch=128; // complete mythen system -// nm=24; - nc=10; - nd=6; // dacs - break; - case PICASSO: - nch=128; // complete mythen system - // nm=24; - nc=12; - nd=6; // dacs+adcs - break; - case GOTTHARD: - nch=128; -// nm=1; - nc=10; - nd=8; // dacs+adcs - na=5; - break; - case PROPIX: - nch=22*22; -// nm=1; - nc=1; - nd=8; // dacs+adcs - na=5; - break; - case EIGER: - nch=256*256; // one EIGER half module -// nm=1; //modules/detector - nc=4*1; //chips - nd=16; //dacs - na=0; - break; - case MOENCH: - nch=160*160; -// nm=1; //modules/detector - nc=1; //chips - nd=8; //dacs - na=1; - break; - case JUNGFRAU: - nch=256*256;//32; - // nm=1; - nc=4*2; - nd=16; // dacs+adcs - na=0; - break; - case JUNGFRAUCTB: - nch=36; -// nm=1; - nc=1; - nd=8; // dacs+adcs - na=1; - break; - default: - nch=0; // dum! -// nm=0; //modules/detector - nc=0; //chips - nd=0; //dacs+adcs - na=0; - } - - dacs_t *dacs=new dacs_t[nd]; - dacs_t *adcs=new dacs_t[na]; - int *chipregs=new int[nc]; - int *chanregs=new int[nch*nc]; - myMod->ndac=nd; - myMod->nadc=na; - myMod->nchip=nc; - myMod->nchan=nch*nc; - - myMod->dacs=dacs; - myMod->adcs=adcs; - myMod->chipregs=chipregs; - myMod->chanregs=chanregs; - return myMod; + sls_detector_module *myMod = (sls_detector_module*)malloc(sizeof(sls_detector_module)); + myMod->ndac=nd; + myMod->nadc=na; + myMod->nchip=nc; + myMod->nchan=nch*nc; + myMod->dacs=dacs; + myMod->adcs=adcs; + myMod->chipregs=chipregs; + myMod->chanregs=chanregs; + return myMod; } void slsDetector::deleteModule(sls_detector_module *myMod) { - delete [] myMod->dacs; - delete [] myMod->adcs; - delete [] myMod->chipregs; - delete [] myMod->chanregs; - delete myMod; + delete [] myMod->dacs; + delete [] myMod->adcs; + delete [] myMod->chipregs; + delete [] myMod->chanregs; + delete myMod; +} + + + + +int slsDetector::connectControl() { + if (controlSocket){ + if (controlSocket->Connect() >= 0) + return OK; + else{ + std::cout << "cannot connect to detector" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); + return FAIL; + } + } + return UNDEFINED; +} + +void slsDetector::disconnectControl() { + if (controlSocket) + controlSocket->Disconnect(); +} + + + +int slsDetector::connectData() { + if (dataSocket){ + if (dataSocket->Connect() >= 0) + return OK; + else{ + std::cout << "cannot connect to receiver" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); + return FAIL;} + } + return UNDEFINED; +} + +void slsDetector::disconnectData() { + if (dataSocket) + dataSocket->Disconnect(); +} + + + +int slsDetector::connectStop() { + if (stopSocket){ + if (stopSocket->Connect() >= 0) + return OK; + else{ + std::cout << "cannot connect to stop server" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); + return FAIL; + } + } + return UNDEFINED; +} + +void slsDetector::disconnectStop() { + if (stopSocket) + stopSocket->Disconnect(); } @@ -1163,10 +1131,10 @@ int slsDetector::sendModule(sls_detector_module *myMod) { ts+=controlSocket->SendDataOnly(&(myMod->reg),sizeof(myMod->reg)); // only for sending structures like in old mythen server if (thisDetector->myDetectorType == MYTHEN) { - ts+=controlSocket->SendDataOnly(myMod->dacs,sizeof(myMod->ndac)); - ts+=controlSocket->SendDataOnly(myMod->adcs,sizeof(myMod->nadc)); - ts+=controlSocket->SendDataOnly(myMod->chipregs,sizeof(myMod->nchip)); - ts+=controlSocket->SendDataOnly(myMod->chanregs,sizeof(myMod->nchan)); + ts+=controlSocket->SendDataOnly(myMod->dacs,sizeof(myMod->ndac)); + ts+=controlSocket->SendDataOnly(myMod->adcs,sizeof(myMod->nadc)); + ts+=controlSocket->SendDataOnly(myMod->chipregs,sizeof(myMod->nchip)); + ts+=controlSocket->SendDataOnly(myMod->chanregs,sizeof(myMod->nchan)); } ts+=controlSocket->SendDataOnly(&(myMod->gain),sizeof(myMod->gain)); ts+=controlSocket->SendDataOnly(&(myMod->offset), sizeof(myMod->offset)); @@ -1217,11 +1185,11 @@ int slsDetector::receiveChip(sls_detector_chip* myChip) { int slsDetector::receiveModule(sls_detector_module* myMod) { - dacs_t *dacptr=myMod->dacs; - dacs_t *adcptr=myMod->adcs; - int *chipptr=myMod->chipregs; - int *chanptr=myMod->chanregs; - int ts=0; + dacs_t *dacptr=myMod->dacs; + dacs_t *adcptr=myMod->adcs; + int *chipptr=myMod->chipregs; + int *chanptr=myMod->chanregs; + int ts=0; //send module structure ts+=controlSocket->ReceiveDataOnly(&(myMod->module),sizeof(myMod->module)); ts+=controlSocket->ReceiveDataOnly(&(myMod->serialnumber),sizeof(myMod->serialnumber)); @@ -1230,12 +1198,12 @@ int slsDetector::receiveModule(sls_detector_module* myMod) { ts+=controlSocket->ReceiveDataOnly(&(myMod->ndac),sizeof(myMod->ndac)); ts+=controlSocket->ReceiveDataOnly(&(myMod->nadc),sizeof(myMod->nadc)); ts+=controlSocket->ReceiveDataOnly(&(myMod->reg),sizeof(myMod->reg)); - // only for sending structures like in old mythen server + // only for sending structures like in old mythen server if (thisDetector->myDetectorType == MYTHEN) { - ts+=controlSocket->ReceiveDataOnly(myMod->dacs,sizeof(myMod->ndac)); - ts+=controlSocket->ReceiveDataOnly(myMod->adcs,sizeof(myMod->nadc)); - ts+=controlSocket->ReceiveDataOnly(myMod->chipregs,sizeof(myMod->nchip)); - ts+=controlSocket->ReceiveDataOnly(myMod->chanregs,sizeof(myMod->nchan)); + ts+=controlSocket->ReceiveDataOnly(myMod->dacs,sizeof(myMod->ndac)); + ts+=controlSocket->ReceiveDataOnly(myMod->adcs,sizeof(myMod->nadc)); + ts+=controlSocket->ReceiveDataOnly(myMod->chipregs,sizeof(myMod->nchip)); + ts+=controlSocket->ReceiveDataOnly(myMod->chanregs,sizeof(myMod->nchan)); } ts+=controlSocket->ReceiveDataOnly(&(myMod->gain), sizeof(myMod->gain)); @@ -1248,550 +1216,461 @@ int slsDetector::receiveModule(sls_detector_module* myMod) { myMod->chanregs=chanptr; #ifdef VERBOSE - std::cout<< "received module " << myMod->module << " of size "<< ts << " register " << myMod->reg << std::endl; + std::cout<< "received module " << myMod->module << " of size "<< ts + << " register " << myMod->reg << std::endl; #endif - ts+=controlSocket->ReceiveDataOnly(myMod->dacs,sizeof(dacs_t)*(myMod->ndac)); + ts+=controlSocket->ReceiveDataOnly(myMod->dacs,sizeof(dacs_t)*(myMod->ndac)); #ifdef VERBOSE - std::cout<< "received dacs " << myMod->module << " of size "<< ts << std::endl; + std::cout<< "received dacs " << myMod->module << " of size "<< ts << std::endl; #endif - ts+=controlSocket->ReceiveDataOnly(myMod->adcs,sizeof(dacs_t)*(myMod->nadc)); + ts+=controlSocket->ReceiveDataOnly(myMod->adcs,sizeof(dacs_t)*(myMod->nadc)); #ifdef VERBOSE - std::cout<< "received adcs " << myMod->module << " of size "<< ts << std::endl; + std::cout<< "received adcs " << myMod->module << " of size "<< ts << std::endl; #endif - if(thisDetector->myDetectorType != JUNGFRAU){ - ts+=controlSocket->ReceiveDataOnly(myMod->chipregs,sizeof(int)*(myMod->nchip)); + if(thisDetector->myDetectorType != JUNGFRAU){ + ts+=controlSocket->ReceiveDataOnly(myMod->chipregs,sizeof(int)*(myMod->nchip)); #ifdef VERBOSE - std::cout<< "received chips " << myMod->module << " of size "<< ts << std::endl; + std::cout<< "received chips " << myMod->module << " of size "<< ts << std::endl; #endif - ts+=controlSocket->ReceiveDataOnly(myMod->chanregs,sizeof(int)*(myMod->nchan)); + ts+=controlSocket->ReceiveDataOnly(myMod->chanregs,sizeof(int)*(myMod->nchan)); #ifdef VERBOSE - std::cout<< "nchans= " << thisDetector->nChans << " nchips= " << thisDetector->nChips; - std::cout<< "mod - nchans= " << myMod->nchan << " nchips= " <nchip; - std::cout<< "received chans " << myMod->module << " of size "<< ts << std::endl; + std::cout<< "nchans= " << thisDetector->nChans << " nchips= " << thisDetector->nChips; + std::cout<< "mod - nchans= " << myMod->nchan << " nchips= " <nchip; + std::cout<< "received chans " << myMod->module << " of size "<< ts << std::endl; #endif - } - -#ifdef VERBOSE - std::cout<< "received module " << myMod->module << " of size "<< ts << " register " << myMod->reg << std::endl; -#endif - - return ts; -} - - -int slsDetector::setOnline(int off) { - int old=thisDetector->onlineFlag; - if (off!=GET_ONLINE_FLAG) { - thisDetector->onlineFlag=off; - if (thisDetector->onlineFlag==ONLINE_FLAG) { - setTCPSocket(); - if (thisDetector->onlineFlag==ONLINE_FLAG && old==OFFLINE_FLAG) { - cout << "Detector connecting for the first time - updating!" << endl; - updateDetector(); - } - else if(thisDetector->onlineFlag==OFFLINE_FLAG){ - std::cout << "cannot connect to detector" << endl; - setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); - } - } - } - return thisDetector->onlineFlag; -} - - - -string slsDetector::checkOnline() { - string retval = string(""); - if(!controlSocket){ - //this already sets the online/offline flag - setTCPSocket(); - if(thisDetector->onlineFlag==OFFLINE_FLAG) - return string(thisDetector->hostname); - else - return string(""); - } - //still cannot connect to socket, controlSocket=0 - if(controlSocket){ - if (connectControl() == FAIL) { - controlSocket->SetTimeOut(5); - thisDetector->onlineFlag=OFFLINE_FLAG; - delete controlSocket; - controlSocket=NULL; - retval = string(thisDetector->hostname); -#ifdef VERBOSE - std::cout<< "offline!" << std::endl; -#endif - } else { - thisDetector->onlineFlag=ONLINE_FLAG; - controlSocket->SetTimeOut(100); - disconnectControl(); -#ifdef VERBOSE - std::cout<< "online!" << std::endl; -#endif - } - } - return retval; -} - - - -int slsDetector::activate(int const enable){ - int fnum = F_ACTIVATE; - int fnum2 = F_RECEIVER_ACTIVATE; - int retval = -1; - int arg = enable; - char mess[MAX_STR_LENGTH]=""; - int ret = OK; - - if(thisDetector->myDetectorType != EIGER){ - std::cout<< "Not implemented for this detector" << std::endl; - setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE)); - return -1; } #ifdef VERBOSE - if(!enable) - std::cout<< "Deactivating Detector" << std::endl; - else if(enable == -1) - std::cout<< "Getting Detector activate mode" << std::endl; - else - std::cout<< "Activating Detector" << std::endl; + std::cout<< "received module " << myMod->module << " of size "<< ts << " register " + << myMod->reg << std::endl; +#endif + + return ts; +} + + +slsReceiverDefs::detectorType slsDetector::getDetectorTypeFromShm(int multiId, bool verify) { + SharedMemory* shm = new SharedMemory(multiId, detId); + // shm not created before + if (!shm->IsExisting()) { + cprintf(RED,"Shared memory %s does not exist.\n" + "Corrupted Multi Shared memory. Please free shared memory.\n", + shm->GetName().c_str()); + throw SharedMemoryException(); + } + + // map basic size of sls detector structure (no need of offsets, just version is required) + sharedSlsDetector* sdet = 0; + size_t sz = sizeof(sharedSlsDetector); + + // open, map, verify version, get type + sdet = (sharedSlsDetector*)shm->OpenSharedMemory(sz); + if (verify && sdet->shmversion != SLS_SHMVERSION) { + cprintf(RED, "Single shared memory (%d-%d:)version mismatch " + "(expected 0x%x but got 0x%x)\n", + multiId, detId, SLS_SHMVERSION, sdet->shmversion); + shm->UnmapSharedMemory(sdet); /** is this unncessary? */ + delete shm;/** is this unncessary? */ + throw SharedMemoryException(); + } + detectorType type = sdet->myDetectorType; + + // unmap + shm->UnmapSharedMemory(sdet); + delete shm; + + return type; +} + + +slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int cport) { + int fnum=F_GET_DETECTOR_TYPE; + int retval = FAIL; + detectorType t=GENERIC; + MySocketTCP *s= new MySocketTCP(name, cport); + char m[MAX_STR_LENGTH]; +#ifdef VERBOSE + cout << "Getting detector type " << endl; +#endif + if (s->Connect() >= 0) { + s->SendDataOnly(&fnum,sizeof(fnum)); + s->ReceiveDataOnly(&retval,sizeof(retval)); + if (retval!=FAIL) { + s->ReceiveDataOnly(&t,sizeof(t)); +#ifdef VERBOSE + cout << "Detector type is "<< t << endl; +#endif + } else { + s->ReceiveDataOnly(m,sizeof(m)); + std::cout<< "Detector returned error: " << m << std::endl; + } + s->Disconnect(); + } else { + cout << "Cannot connect to server " << name << " over port " << cport << endl; + } + delete s; + return t; +} + + +int slsDetector::setDetectorType(detectorType const type) { + + int arg, retval=FAIL; + int fnum=F_GET_DETECTOR_TYPE,fnum2=F_GET_RECEIVER_TYPE; + arg=int(type); + detectorType retType=type; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting detector type to " << arg << std::endl; #endif if (thisDetector->onlineFlag==ONLINE_FLAG) { if (connectControl() == OK){ controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (retval!=FAIL) + controlSocket->ReceiveDataOnly(&retType,sizeof(retType)); + else { controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE)); - } else { + } + disconnectControl(); + if (retval==FORCE_UPDATE) + updateDetector(); + } + } else { + if (type==GET_DETECTOR_TYPE) + retType=thisDetector->myDetectorType;//FIXME: throw exception? + else { + retType=type; + thisDetector->myDetectorType=type; + } + retval=OK; + } +#ifdef VERBOSE + std::cout<< "Detector type set to " << retType << std::endl; +#endif + if (retval==FAIL) { + std::cout<< "Set detector type failed " << std::endl; + retType=GENERIC; + } + else + thisDetector->myDetectorType=retType; + + + //receiver + if((retType != GENERIC) && (thisDetector->receiverOnlineFlag==ONLINE_FLAG) + && (arg != GENERIC)) { + retval = FAIL; + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending detector type to Receiver " << + (int)thisDetector->myDetectorType << std::endl; +#endif + if (connectData() == OK){ + retval=thisReceiver->sendInt(fnum2,arg,(int)thisDetector->myDetectorType); + disconnectData(); + } + if(retval==FAIL){ + cout << "ERROR: Could not send detector type to receiver" << endl; + setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); + } + } + } + + return retType; +} + + + +int slsDetector::setDetectorType(string const stype) { + return setDetectorType(getDetectorType(stype)); +} + + +slsDetectorDefs::detectorType slsDetector::getDetectorsType(int pos) { + return thisDetector->myDetectorType; +} + +string slsDetector::sgetDetectorsType(int pos) { + return getDetectorType(getDetectorsType(pos)); +} + + +string slsDetector::getDetectorType() { + return sgetDetectorsType(); +} + + +int slsDetector::getNMods() { + return thisDetector->nMods; +} + +int slsDetector::getNMod(dimension d) { + return thisDetector->nMod[d]; +} + + +int slsDetector::getMaxMods() { + return thisDetector->nModsMax; +} + + +int slsDetector::getNMaxMod(dimension d) { + return thisDetector->nModMax[d]; +} + + + +int slsDetector::getMaxNumberOfModules(dimension d) { + + int retval; + int fnum=F_GET_MAX_NUMBER_OF_MODULES; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + if (dY) { + std::cout<< "Get max number of modules in wrong dimension " << d << std::endl; + return ret; + } +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Getting max number of modules in dimension "<< d <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&d,sizeof(d)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; } disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } + } else { + ret=OK; + retval=thisDetector->nModMax[d]; } #ifdef VERBOSE - if(retval==1) - std::cout << "Detector Activated" << std::endl; - else if(retval==0) - std::cout << "Detector Deactivated" << std::endl; - else - std::cout << "Detector Activation unknown:" << retval << std::endl; + std::cout<< "Max number of modules in dimension "<< d <<" is " << retval << std::endl; #endif + if (ret==FAIL) { + std::cout<< "Get max number of modules failed " << retval << std::endl; + return retval; + } else { + thisDetector->nModMax[d]=retval; + thisDetector->nModsMax=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; + + + + } + return thisDetector->nModMax[d]; +} + + + +int slsDetector::setNumberOfModules(int n, dimension d) { + + int arg[2], retval=1; + int fnum=F_SET_NUMBER_OF_MODULES; + int ret=FAIL; + char mess[MAX_STR_LENGTH]="dummy"; + int connect; + + arg[0]=d; + arg[1]=n; + + + if (dY) { + std::cout<< "Set number of modules in wrong dimension " << d << std::endl; + return ret; + } + - if(ret!=FAIL){ - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ #ifdef VERBOSE - std::cout << "Activating/Deactivating Receiver: " << retval << std::endl; + std::cout<< std::endl; + std::cout<< "Setting number of modules of dimension "<< d << " to " << n << std::endl; #endif - if (connectData() == OK){ - ret=thisReceiver->sendInt(fnum2,retval,retval); - disconnectData(); + if (thisDetector->onlineFlag==ONLINE_FLAG) { + connect = connectControl(); + if (connect == UNDEFINED) + cout << "no control socket?" << endl; + else if (connect == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; } - if(ret==FAIL) - setErrorMask((getErrorMask())|(RECEIVER_ACTIVATE)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); } - } -#ifdef VERBOSE - if(retval==1) - std::cout << "Receiver Activated" << std::endl; - else if(retval==0) - std::cout << "Receiver Deactivated" << std::endl; - else - std::cout << "Receiver Activation unknown:" << retval << std::endl; -#endif - - - return retval; - -} - - -/* - configure the socket communication and check that the server exists - enum communicationProtocol{ - TCP, - UDP - }{}; - -*/ - -int slsDetector::setTCPSocket(string const name, int const control_port, int const stop_port){ - - char thisName[MAX_STR_LENGTH]; - int thisCP, thisSP; - int retval=OK; - - if (strcmp(name.c_str(),"")!=0) { -#ifdef VERBOSE - std::cout<< "setting hostname" << std::endl; -#endif - strcpy(thisName,name.c_str()); - strcpy(thisDetector->hostname,thisName); - if (controlSocket) { - delete controlSocket; - controlSocket=NULL; - } - if (stopSocket) { - delete stopSocket; - stopSocket=NULL; - } - } else - strcpy(thisName,thisDetector->hostname); - - if (control_port>0) { -#ifdef VERBOSE - std::cout<< "setting control port" << std::endl; -#endif - thisCP=control_port; - thisDetector->controlPort=thisCP; - if (controlSocket) { - delete controlSocket; - controlSocket=NULL; - } - } else - thisCP=thisDetector->controlPort; - - if (stop_port>0) { -#ifdef VERBOSE - std::cout<< "setting stop port" << std::endl; -#endif - thisSP=stop_port; - thisDetector->stopPort=thisSP; - if (stopSocket) { - delete stopSocket; - stopSocket=NULL; - } - } else - thisSP=thisDetector->stopPort; - - - if (!controlSocket) { - controlSocket= new MySocketTCP(thisName, thisCP); - if (controlSocket->getErrorStatus()){ -#ifdef VERBOSE - std::cout<< "Could not connect Control socket " << thisName << " " << thisCP << std::endl; -#endif - delete controlSocket; - controlSocket=NULL; - retval=FAIL; - } -#ifdef VERYVERBOSE - else - std::cout<< "Control socket connected " <getErrorStatus()){ -#ifdef VERBOSE - std::cout<< "Could not connect Stop socket "<onlineFlag=OFFLINE_FLAG; -#ifdef VERBOSE - std::cout<< "offline!" << std::endl; -#endif - } - return retval; -}; - - -/** connect to the control port */ -int slsDetector::connectControl() { - if (controlSocket){ - if (controlSocket->Connect() >= 0) - return OK; - else{ - std::cout << "cannot connect to detector" << endl; - setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); - return FAIL; + } else { + cout << "offline" << endl; + ret=OK; + if (n==GET_FLAG) + ; + else { + if (n<=0 || n>thisDetector->nModMax[d]) { + ret=FAIL; + } else { + thisDetector->nMod[d]=n; + } } + retval=thisDetector->nMod[d]; } - return UNDEFINED; -} -/** disconnect from the control port */ -int slsDetector::disconnectControl() { - if (controlSocket) - controlSocket->Disconnect(); - return OK; -} +#ifdef VERBOSE + std::cout<< "Number of modules in dimension "<< d <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Set number of modules failed " << std::endl; + } else { + thisDetector->nMod[d]=retval; + thisDetector->nMods=thisDetector->nMod[X]*thisDetector->nMod[Y]; + if (thisDetector->nModsMaxnMods) + thisDetector->nModsMax=thisDetector->nMods; -/** connect to the data port */ -int slsDetector::connectData() { - if (dataSocket){ - if (dataSocket->Connect() >= 0) - return OK; - else{ - std::cout << "cannot connect to receiver" << endl; - setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); - return FAIL;} - } - return UNDEFINED; -}; -/** disconnect from the data port */ -int slsDetector::disconnectData(){ - if (dataSocket) - dataSocket->Disconnect(); - return OK; -} -; + if (thisDetector->nModMax[X]nMod[X]) + thisDetector->nModMax[X]=thisDetector->nMod[X]; -/** connect to the stop port */ -int slsDetector::connectStop() { - if (stopSocket){ - if (stopSocket->Connect() >= 0) - return OK; - else{ - std::cout << "cannot connect to stop server" << endl; - setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); - return FAIL; + if (thisDetector->nModMax[Y]nMod[Y]) + thisDetector->nModMax[Y]=thisDetector->nMod[Y]; + + int dr=thisDetector->dynamicRange; + if ((thisDetector->myDetectorType==MYTHEN) && (dr==24)) + dr=32; + + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]* + thisDetector->nChips*thisDetector->nChans*dr/8; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * + thisDetector->nChan[X] + thisDetector->gappixels * + thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * + thisDetector->nChan[Y] + thisDetector->gappixels * + thisDetector->nGappixels[Y]) * + thisDetector->dynamicRange/8; + + if(thisDetector->myDetectorType==MYTHEN){ + if (thisDetector->timerValue[PROBES_NUMBER]!=0) { + thisDetector->dataBytes=thisDetector->nMod[X]* + thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + 4; + } } + + if(thisDetector->myDetectorType==JUNGFRAUCTB){ + getTotalNumberOfChannels(); + } + + +#ifdef VERBOSE +std::cout<< "Data size is " << thisDetector->dataBytes << std::endl; +std::cout<< "nModX " << thisDetector->nMod[X] << " nModY " << thisDetector->nMod[Y] + << " nChips " << thisDetector->nChips << " nChans " << thisDetector->nChans + << " dr " << dr << std::endl; +#endif } - return UNDEFINED; -}; -/** disconnect from the stop port */ -int slsDetector::disconnectStop(){ - if (stopSocket) - stopSocket->Disconnect(); - return OK; -} -; - - - - - - - - - - - - - - - - -/* Communication to server */ - -// General purpose functions - -/* - executes a system command on the server - e.g. mount an nfs disk, reboot and returns answer etc. -*/ -int slsDetector::execCommand(string cmd, string answer){ - - char arg[MAX_STR_LENGTH], retval[MAX_STR_LENGTH]; - int fnum=F_EXEC_COMMAND; - - int ret=FAIL; - - strcpy(arg,cmd.c_str()); - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Sending command " << arg << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - if (controlSocket->SendDataOnly(&fnum,sizeof(fnum))>=0) { - if (controlSocket->SendDataOnly(arg,MAX_STR_LENGTH)>=0) { - if (controlSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH)>=0) { - ret=OK; - answer=retval; - } + if(n != GET_FLAG){ + pthread_mutex_lock(&ms); + multiDet->updateOffsets(); + pthread_mutex_unlock(&ms); } - } - disconnectControl(); - } -#ifdef VERBOSE - std::cout<< "Detector answer is " << answer << std::endl; -#endif - } - return ret; -}; -// Detector configuration functions - -/* - the detector knows what type of detector it is - - enum detectorType{ - GET_DETECTOR_TYPE, - GENERIC, - MYTHEN, - PILATUS, - EIGER, - GOTTHARD, - AGIPD, - MOENCH - }; - -*/ -int slsDetector::setDetectorType(detectorType const type){ - - int arg, retval=FAIL; - int fnum=F_GET_DETECTOR_TYPE,fnum2=F_GET_RECEIVER_TYPE; - arg=int(type); - detectorType retType=type; - char mess[MAX_STR_LENGTH]=""; - strcpy(mess,"dummy"); - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting detector type to " << arg << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - if (retval!=FAIL) - controlSocket->ReceiveDataOnly(&retType,sizeof(retType)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (retval==FORCE_UPDATE) - updateDetector(); - } - } else { - if (type==GET_DETECTOR_TYPE) - retType=thisDetector->myDetectorType; - else { - retType=type; - thisDetector->myDetectorType=type; - } - retval=OK; - } -#ifdef VERBOSE - std::cout<< "Detector type set to " << retType << std::endl; -#endif - if (retval==FAIL) { - std::cout<< "Set detector type failed " << std::endl; - retType=GENERIC; - } - else - thisDetector->myDetectorType=retType; - - - //receiver - if((retType != GENERIC) && (thisDetector->receiverOnlineFlag==ONLINE_FLAG) && (arg != GENERIC)) { - retval = FAIL; - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Sending detector type to Receiver " << (int)thisDetector->myDetectorType << std::endl; -#endif - if (connectData() == OK){ - retval=thisReceiver->sendInt(fnum2,arg,(int)thisDetector->myDetectorType); - disconnectData(); - } - if(retval==FAIL){ - cout << "ERROR: Could not send detector type to receiver" << endl; - setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); - } - } - } - - - - return retType; -}; - -int slsDetector::setDetectorType(string const stype){ - return setDetectorType(getDetectorType(stype)); -}; - -slsDetectorDefs::detectorType slsDetector::getDetectorsType(int pos){ - return thisDetector->myDetectorType; + return thisDetector->nMod[d]; } - // /** number of rois defined */ - // int nROI; - // /** list of rois */ - // ROI roiLimits[MAX_ROIS]; - - // /** readout flags */ - // readOutFlags roFlags; + +int slsDetector::getChansPerMod(int imod) { + return thisDetector->nChans*thisDetector->nChips; +} + +int slsDetector::getChansPerMod( dimension d,int imod) { + return thisDetector->nChan[d]*thisDetector->nChip[d]; +} int slsDetector::getTotalNumberOfChannels() { #ifdef VERBOSE - cout << "total number of channels" << endl; + cout << "total number of channels" << endl; #endif - if(thisDetector->myDetectorType==JUNGFRAUCTB){ - if (thisDetector->roFlags&DIGITAL_ONLY) - thisDetector->nChan[X]=4; - else if (thisDetector->roFlags&ANALOG_AND_DIGITAL) - thisDetector->nChan[X]=36; - else - thisDetector->nChan[X]=32; - - if (thisDetector->nChan[X]>=32) { - if (thisDetector->nROI>0) { - thisDetector->nChan[X]-=32; - for (int iroi=0; iroinROI; ++iroi) - thisDetector->nChan[X]+=thisDetector->roiLimits[iroi].xmax-thisDetector->roiLimits[iroi].xmin+1; - } - } - thisDetector->nChans=thisDetector->nChan[X]; - thisDetector->dataBytes=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods*2*thisDetector->timerValue[SAMPLES_JCTB]; - thisDetector->dataBytesInclGapPixels = thisDetector->dataBytes; - } else { + if(thisDetector->myDetectorType==JUNGFRAUCTB){ + if (thisDetector->roFlags&DIGITAL_ONLY) + thisDetector->nChan[X]=4; + else if (thisDetector->roFlags&ANALOG_AND_DIGITAL) + thisDetector->nChan[X]=36; + else + thisDetector->nChan[X]=32; + + if (thisDetector->nChan[X]>=32) { + if (thisDetector->nROI>0) { + thisDetector->nChan[X]-=32; + for (int iroi=0; iroinROI; ++iroi) + thisDetector->nChan[X]+= + thisDetector->roiLimits[iroi].xmax- + thisDetector->roiLimits[iroi].xmin+1; + } + } + thisDetector->nChans=thisDetector->nChan[X]; + thisDetector->dataBytes=thisDetector->nChans*thisDetector->nChips* + thisDetector->nMods*2*thisDetector->timerValue[SAMPLES_JCTB]; + thisDetector->dataBytesInclGapPixels = thisDetector->dataBytes; + } else { #ifdef VERBOSE - cout << "det type is "<< thisDetector->myDetectorType << endl; - cout << "Total number of channels is "<< thisDetector->nChans*thisDetector->nChips*thisDetector->nMods << " data bytes is " << thisDetector->dataBytes << endl; // excluding gap pixels +cout << "det type is "<< thisDetector->myDetectorType << endl; +cout << "Total number of channels is "<< thisDetector->nChans*thisDetector->nChips* + thisDetector->nMods << " data bytes is " << thisDetector->dataBytes << endl; +// excluding gap pixels #endif - ; - } - return thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; +; + } + return thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; } int slsDetector::getTotalNumberOfChannels(dimension d) { - getTotalNumberOfChannels(); - return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nMod[d]; -}; + getTotalNumberOfChannels(); + return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nMod[d]; +} int slsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d) { getTotalNumberOfChannels(); - return (thisDetector->nChan[d] * thisDetector->nChip[d] + thisDetector->gappixels * thisDetector->nGappixels[d]) * thisDetector->nMod[d]; + return (thisDetector->nChan[d] * thisDetector->nChip[d] + thisDetector->gappixels + * thisDetector->nGappixels[d]) * thisDetector->nMod[d]; } -int slsDetector::getMaxNumberOfChannels(){ - if(thisDetector->myDetectorType==JUNGFRAUCTB) return 36*thisDetector->nChips*thisDetector->nModsMax; - return thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax; -}; +int slsDetector::getMaxNumberOfChannels() { + if(thisDetector->myDetectorType==JUNGFRAUCTB) return 36*thisDetector->nChips* + thisDetector->nModsMax; + return thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax; +} -int slsDetector::getMaxNumberOfChannels(dimension d){ - if(thisDetector->myDetectorType==JUNGFRAUCTB) { - if (d==X) return 36*thisDetector->nChip[d]*thisDetector->nModMax[d]; - else return 1*thisDetector->nChip[d]*thisDetector->nModMax[d]; - } - return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nModMax[d]; +int slsDetector::getMaxNumberOfChannels(dimension d) { + if(thisDetector->myDetectorType==JUNGFRAUCTB) { + if (d==X) return 36*thisDetector->nChip[d]*thisDetector->nModMax[d]; + else return 1*thisDetector->nChip[d]*thisDetector->nModMax[d]; + } + return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nModMax[d]; }; int slsDetector::getMaxNumberOfChannelsInclGapPixels(dimension d) { @@ -1799,3103 +1678,226 @@ int slsDetector::getMaxNumberOfChannelsInclGapPixels(dimension d) { if (d==X) return 36*thisDetector->nChip[d]*thisDetector->nModMax[d]; else return 1*thisDetector->nChip[d]*thisDetector->nModMax[d]; } - return (thisDetector->nChan[d] * thisDetector->nChip[d] + thisDetector->gappixels * thisDetector->nGappixels[d]) * thisDetector->nModMax[d]; -} - -/* needed to set/get the size of the detector */ -// if n=GET_FLAG returns the number of installed modules, -int slsDetector::setNumberOfModules(int n, dimension d){ - - int arg[2], retval=1; - int fnum=F_SET_NUMBER_OF_MODULES; - int ret=FAIL; - char mess[MAX_STR_LENGTH]="dummy"; - int connect; - - arg[0]=d; - arg[1]=n; - - - if (dY) { - std::cout<< "Set number of modules in wrong dimension " << d << std::endl; - return ret; - } - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting number of modules of dimension "<< d << " to " << n << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - connect = connectControl(); - if (connect == UNDEFINED) - cout << "no control socket?" << endl; - else if (connect == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } else { - cout << "offline" << endl; - ret=OK; - if (n==GET_FLAG) - ; - else { - if (n<=0 || n>thisDetector->nModMax[d]) { - ret=FAIL; - } else { - thisDetector->nMod[d]=n; - } - } - retval=thisDetector->nMod[d]; - } -#ifdef VERBOSE - std::cout<< "Number of modules in dimension "<< d <<" is " << retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Set number of modules failed " << std::endl; - } else { - thisDetector->nMod[d]=retval; - thisDetector->nMods=thisDetector->nMod[X]*thisDetector->nMod[Y]; - - - if (thisDetector->nModsMaxnMods) - thisDetector->nModsMax=thisDetector->nMods; - - if (thisDetector->nModMax[X]nMod[X]) - thisDetector->nModMax[X]=thisDetector->nMod[X]; - - if (thisDetector->nModMax[Y]nMod[Y]) - thisDetector->nModMax[Y]=thisDetector->nMod[Y]; - - int dr=thisDetector->dynamicRange; - if ((thisDetector->myDetectorType==MYTHEN) && (dr==24)) - dr=32; - - thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*dr/8; - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - thisDetector->dynamicRange/8; - - if(thisDetector->myDetectorType==MYTHEN){ - if (thisDetector->timerValue[PROBES_NUMBER]!=0) { - thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - 4; - } - } - - if(thisDetector->myDetectorType==JUNGFRAUCTB){ - getTotalNumberOfChannels(); - } - - -#ifdef VERBOSE - std::cout<< "Data size is " << thisDetector->dataBytes << std::endl; - std::cout<< "nModX " << thisDetector->nMod[X] << " nModY " << thisDetector->nMod[Y] << " nChips " << thisDetector->nChips << " nChans " << thisDetector->nChans<< " dr " << dr << std::endl; -#endif - } - - if(n != GET_FLAG){ - pthread_mutex_lock(&ms); - parentDet->updateOffsets(); - pthread_mutex_unlock(&ms); - } - - return thisDetector->nMod[d]; -}; - - - -int slsDetector::getMaxNumberOfModules(dimension d){ - - int retval; - int fnum=F_GET_MAX_NUMBER_OF_MODULES; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - if (dY) { - std::cout<< "Get max number of modules in wrong dimension " << d << std::endl; - return ret; - } -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Getting max number of modules in dimension "<< d <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&d,sizeof(d)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } else { - ret=OK; - retval=thisDetector->nModMax[d]; - } -#ifdef VERBOSE - std::cout<< "Max number of modules in dimension "<< d <<" is " << retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Get max number of modules failed " << retval << std::endl; - return retval; - } else { - thisDetector->nModMax[d]=retval; - thisDetector->nModsMax=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; - - - - } - return thisDetector->nModMax[d]; -}; - - - - - -int slsDetector::setFlippedData(dimension d, int value){ - int retval=-1; - int fnum=F_SET_FLIPPED_DATA_RECEIVER; - int ret=FAIL; - int args[2]={X,-1}; - - - if(thisDetector->myDetectorType!= EIGER){ - std::cout << "Flipped Data is not implemented in this detector" << std::endl; - setErrorMask((getErrorMask())|(RECEIVER_FLIPPED_DATA_NOT_SET)); - return -1; - } - -#ifdef VERBOSE - std::cout << std::endl; - std::cout << "Setting/Getting flipped data across axis " << d <<" with value " << value << std::endl; -#endif - if(value > -1){ - thisDetector->flippedData[d] = value; - args[1] = value; - }else - args[1] = thisDetector->flippedData[d]; - - args[0] = d; - - if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { - if (connectData() == OK){ - ret=thisReceiver->sendIntArray(fnum,retval,args); - - disconnectData(); - } - - if((args[1] != retval && args[1]>=0) || (ret==FAIL)){ - ret = FAIL; - setErrorMask((getErrorMask())|(RECEIVER_FLIPPED_DATA_NOT_SET)); - } - - if(ret==FORCE_UPDATE) - updateReceiver(); - } - - - return thisDetector->flippedData[d]; + return (thisDetector->nChan[d] * thisDetector->nChip[d] + thisDetector->gappixels * + thisDetector->nGappixels[d]) * thisDetector->nModMax[d]; } - - -int slsDetector::enableGapPixels(int val) { - - if(val > 0 && thisDetector->myDetectorType!= EIGER) - val = -1; - - if (val >= 0) { - val=(val>0)?1:0; - - // send to receiver - int ret=OK; - int retval=-1; - int fnum=F_ENABLE_GAPPIXELS_IN_RECEIVER; - int arg=val; - if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { - if (connectData() == OK){ - ret=thisReceiver->sendInt(fnum,retval,arg); - disconnectData(); - } - if((arg != retval) || (ret==FAIL)){ - ret = FAIL; - setErrorMask((getErrorMask())|(RECEIVER_ENABLE_GAPPIXELS_NOT_SET)); - } - - if(ret==FORCE_UPDATE) - updateReceiver(); - } - - - // update client - if (ret == OK) { - thisDetector->gappixels = val; - thisDetector->dataBytesInclGapPixels = 0; - - if (thisDetector->dynamicRange != 4) { - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - thisDetector->dynamicRange/8; - // set data bytes for other detector ( for future use) - if(thisDetector->myDetectorType==JUNGFRAUCTB) - getTotalNumberOfChannels(); - else if(thisDetector->myDetectorType==MYTHEN){ - if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) { - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - 4; - } - } - } - } - } - - return thisDetector->gappixels; +int slsDetector::getNChans() { + return thisDetector->nChans; } +int slsDetector::getNChans(dimension d) { + return thisDetector->nChan[d]; +} -/* - This function is used to set the polarity and meaning of the digital I/O signals (signal index) +int slsDetector::getNChips() { + return thisDetector->nChips; +} - enum externalSignalFlag { - GET_EXTERNAL_SIGNAL_FLAG, - SIGNAL_OFF, - GATE_ACTIVE_HIGH, - GATE_ACTIVE_LOW, - TRIGGER_RISING_EDGE, - TRIGGER_FALLING_EDGE - }{}; -*/ +int slsDetector::getNChips(dimension d) { + return thisDetector->nChip[d]; +} -slsDetectorDefs::externalSignalFlag slsDetector::setExternalSignalFlags(externalSignalFlag pol, int signalindex){ +int slsDetector::getDetectorOffset(dimension d) { + return thisDetector->offset[d]; +} +void slsDetector::setDetectorOffset(dimension d, int off) { + if (off >= 0) + thisDetector->offset[d] = off; +} - - - int arg[2]; - externalSignalFlag retval; - int ret=FAIL; - int fnum=F_SET_EXTERNAL_SIGNAL_FLAG; - char mess[MAX_STR_LENGTH]=""; - - arg[0]=signalindex; - arg[1]=pol; - - retval=GET_EXTERNAL_SIGNAL_FLAG; - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting signal "<< signalindex << " to flag" << pol << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } else { - retval=GET_EXTERNAL_SIGNAL_FLAG; - ret=FAIL; - } -#ifdef VERBOSE - std::cout<< "Signal "<< signalindex << " flag set to" << retval << std::endl; - if (ret==FAIL) { - std::cout<< "Set signal flag failed " << std::endl; - } -#endif - return retval; - - - - - - -}; - -/* - this function is used to select wether the detector is triggered or gated and in which mode - enum externalCommunicationMode{ - GET_EXTERNAL_COMMUNICATION_MODE, - AUTO, - TRIGGER_EXPOSURE, - TRIGGER_READOUT, - TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, - GATE_FIX_NUMBER, - GATE_FIX_DURATION, - GATE_WITH_START_TRIGGER, - BURST_TRIGGER, - //GATE_COINCIDENCE_WITH_INTERNAL_ENABLE - }; - -*/ - -slsDetectorDefs::externalCommunicationMode slsDetector::setExternalCommunicationMode( externalCommunicationMode pol){ - - - - - int arg[1]; - externalCommunicationMode retval; - int fnum=F_SET_EXTERNAL_COMMUNICATION_MODE; - char mess[MAX_STR_LENGTH]=""; - - arg[0]=pol; - - int ret=FAIL; - retval=GET_EXTERNAL_COMMUNICATION_MODE; - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting communication to mode " << pol << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } else { - retval=GET_EXTERNAL_COMMUNICATION_MODE; - ret=FAIL; - } -#ifdef VERBOSE - std::cout<< "Communication mode "<< " set to" << retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Setting communication mode failed" << std::endl; - } - return retval; - -}; - - -// Tests and identification -/* - Gets versions - - enum idMode{ - MODULE_SERIAL_NUMBER, - MODULE_FIRMWARE_VERSION, - DETECTOR_SERIAL_NUMBER, - DETECTOR_FIRMWARE_VERSION, - DETECTOR_SOFTWARE_VERSION, - THIS_SOFTWARE_VERSION, - RECEIVER_VERSION - }{}; -*/ - - - - - -int64_t slsDetector::getId( idMode mode, int imod){ - - int64_t retval=-1; - int fnum=F_GET_ID,fnum2 = F_GET_RECEIVER_ID; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<< std::endl; - if (mode==MODULE_SERIAL_NUMBER) - std::cout<< "Getting id of "<< imod << std::endl; - else - std::cout<< "Getting id type "<< mode << std::endl; -#endif - if (mode==THIS_SOFTWARE_VERSION) { - ret=OK; - retval=GITDATE; - } else if (mode==RECEIVER_VERSION) { - if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { - if (connectData() == OK){ - ret=thisReceiver->getInt(fnum2,retval); - disconnectData(); - } - if(ret==FORCE_UPDATE) - ret=updateReceiver(); - } - } else { - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() != OK) - ret = FAIL; - else{ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&mode,sizeof(mode)); - if (mode==MODULE_SERIAL_NUMBER) - controlSocket->SendDataOnly(&imod,sizeof(imod)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - } - if (ret==FAIL) { - std::cout<< "Get id failed " << std::endl; - return ret; - } else { -#ifdef VERBOSE - if (mode==MODULE_SERIAL_NUMBER) - std::cout<< "Id of "<< imod <<" is " << hex <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&mode,sizeof(mode)); - if ((mode==CHIP_TEST)|| (mode==DIGITAL_BIT_TEST)) - controlSocket->SendDataOnly(&imod,sizeof(imod)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } else { - ret=FAIL; - } -#ifdef VERBOSE - std::cout<< "Id "<< mode <<" is " << retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Get id failed " << std::endl; - return ret; - } else - return retval; -}; - - - -/* - analog test of the modules - enum analogTestMode { - COUNT_CALIBRATION_PULSES, - I_DON_T_KNOW - }{}; - -*/ -/* - int* slsDetector::analogTest(analogTestMode mode){ - std::cout<< "function not yet implemented " << std::endl; - }; -*/ -/* - enable analog output of channel -*/ -/* - int slsDetector::enableAnalogOutput(int ichan){ - int imod=ichan/(nChans*nChips); - ichan-=imod*(nChans*nChips); - int ichip=ichan/nChans; - ichan-=ichip*(nChans); - enableAnalogOutput(imod,ichip,ichan); - - }; - int slsDetector::enableAnalogOutput(int imod, int ichip, int ichan){ - std::cout<< "function not yet implemented " << std::endl; - }; -*/ -/* - give a train of calibration pulses -*/ -/* - int slsDetector::giveCalibrationPulse(double vcal, int npulses){ - std::cout<< "function not yet implemented " << std::endl; - }; -*/ -// Expert low level functions - - - -/* write or read register */ - -uint32_t slsDetector::writeRegister(uint32_t addr, uint32_t val){ - - uint32_t retval = 0; - int fnum=F_WRITE_REGISTER; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - uint32_t arg[2]; - arg[0]=addr; - arg[1]=val; - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Writing to register "<< hex<onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) +int slsDetector::setOnline(int off) { + int old=thisDetector->onlineFlag; + if (off!=GET_ONLINE_FLAG) { + thisDetector->onlineFlag=off; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + setTCPSocket(); + if (thisDetector->onlineFlag==ONLINE_FLAG && old==OFFLINE_FLAG) { + cout << "Detector connecting for the first time - updating!" << endl; updateDetector(); + } + else if(thisDetector->onlineFlag==OFFLINE_FLAG){ + std::cout << "cannot connect to detector" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); + } } } -#ifdef VERBOSE - std::cout<< "Register returned "<< retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Write to register failed " << std::endl; - setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); - } + return thisDetector->onlineFlag; +} + + +string slsDetector::checkOnline() { + string retval=""; + if(!controlSocket){ + //this already sets the online/offline flag + setTCPSocket(); + if(thisDetector->onlineFlag==OFFLINE_FLAG) + return string(thisDetector->hostname); + else + return string(""); + } + //still cannot connect to socket, controlSocket=0 + if(controlSocket){ + if (connectControl() == FAIL) { + controlSocket->SetTimeOut(5); + thisDetector->onlineFlag=OFFLINE_FLAG; + delete controlSocket; + controlSocket=NULL; + retval = string(thisDetector->hostname); +#ifdef VERBOSE + std::cout<< "offline!" << std::endl; +#endif + } else { + thisDetector->onlineFlag=ONLINE_FLAG; + controlSocket->SetTimeOut(100); + disconnectControl(); +#ifdef VERBOSE + std::cout<< "online!" << std::endl; +#endif + } + } + //still cannot connect to socket, stopSocket=0 + if(stopSocket){ + if (connectStop() == FAIL) { + stopSocket->SetTimeOut(5); + thisDetector->onlineFlag=OFFLINE_FLAG; + delete stopSocket; + stopSocket=NULL; + retval = string(thisDetector->hostname); +#ifdef VERBOSE + std::cout<< "stop offline!" << std::endl; +#endif + } else { + thisDetector->onlineFlag=ONLINE_FLAG; + stopSocket->SetTimeOut(100); + disconnectStop(); +#ifdef VERBOSE + std::cout<< "stop online!" << std::endl; +#endif + } + } return retval; } -int slsDetector::writeAdcRegister(int addr, int val){ - - int retval=-1; - int fnum=F_WRITE_ADC_REG; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - uint32_t arg[2]; - arg[0]=addr; - arg[1]=val; +int slsDetector::setTCPSocket(string const name, int const control_port, int const stop_port) { + char thisName[MAX_STR_LENGTH]; + int thisCP, thisSP; + int retval=OK; + + if (strcmp(name.c_str(),"")!=0) { #ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Writing to adc register "<< hex<onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); + strcpy(thisName,name.c_str()); + strcpy(thisDetector->hostname,thisName); + if (controlSocket) { + delete controlSocket; + controlSocket=NULL; } - } -#ifdef VERBOSE - std::cout<< "ADC Register returned "<< retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Write ADC to register failed " << std::endl; - setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); - } - return retval; - -}; - - - - -uint32_t slsDetector::readRegister(uint32_t addr){ - - uint32_t retval = 0; - int fnum=F_READ_REGISTER; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - uint32_t arg; - arg=addr; - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Reading register "<< hex<onlineFlag==ONLINE_FLAG) { - // if (connectControl() == OK){ if (stopSocket) { - if (connectStop() == OK) { - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->SendDataOnly(&arg,sizeof(arg)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectStop(); + delete stopSocket; + stopSocket=NULL; + } + } else + strcpy(thisName,thisDetector->hostname); + + if (control_port>0) { +#ifdef VERBOSE + std::cout<< "setting control port" << std::endl; +#endif + thisCP=control_port; + thisDetector->controlPort=thisCP; + if (controlSocket) { + delete controlSocket; + controlSocket=NULL; + } + } else + thisCP=thisDetector->controlPort; + + if (stop_port>0) { +#ifdef VERBOSE + std::cout<< "setting stop port" << std::endl; +#endif + thisSP=stop_port; + thisDetector->stopPort=thisSP; + if (stopSocket) { + delete stopSocket; + stopSocket=NULL; + } + } else + thisSP=thisDetector->stopPort; + + + if (!controlSocket) { + controlSocket= new MySocketTCP(thisName, thisCP); + if (controlSocket->getErrorStatus()){ +#ifdef VERBOSE + std::cout<< "Could not connect Control socket " << thisName << " " + << thisCP << std::endl; +#endif + delete controlSocket; + controlSocket=NULL; + retval=FAIL; + } +#ifdef VERYVERBOSE + else + std::cout<< "Control socket connected " <getErrorStatus()){ +#ifdef VERBOSE + std::cout<< "Could not connect Stop socket "<myDetectorType) { + case EIGER: + case JUNGFRAU: + case GOTTHARD: + if ((thisDetector->detectorControlAPIVersion == 0) || + (thisDetector->detectorStopAPIVersion == 0)) { + if (checkVersionCompatibility(CONTROL_PORT) == FAIL) + thisDetector->onlineFlag=OFFLINE_FLAG; } - } - } -#ifdef VERBOSE - std::cout<< "Register returned "<< retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Read register failed " << std::endl; - setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); - } - return retval; - -} - - -uint32_t slsDetector::setBit(uint32_t addr, int n) { - if (n<0 || n>31) { - std::cout << "Bit number out of Range" << std:: endl; - setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); - } - - // normal bit range - //TODO! (Erik) Check for errors! cannot use value since reg is 32bits - else { - uint32_t val = readRegister(addr); - writeRegister(addr,val | 1<31) { - std::cout << "Bit number out of Range" << std:: endl; - setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); - } - - // normal bit range - else { - uint32_t val = readRegister(addr); - writeRegister(addr,val & ~(1<myDetectorType == GOTTHARD) || (thisDetector->myDetectorType == PROPIX))) - index=HV_POT; - - arg[0]=index; - arg[1]=imod; - arg[2]=mV; - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting DAC "<< index << " of module " << imod << " to " << val << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - controlSocket->SendDataOnly(&val,sizeof(val)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - controlSocket->ReceiveDataOnly(retval,sizeof(retval)); - if (index < thisDetector->nDacs){ - - if (dacs) { - if (imod>=0) { - *(dacs+index+imod*thisDetector->nDacs)=retval[0]; - } - else { - for (imod=0; imodnModsMax; ++imod) - *(dacs+index+imod*thisDetector->nDacs)=retval[0]; - } - } - } - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - - } - } -#ifdef VERBOSE - std::cout<< "Dac set to "<< retval[0] << " dac units (" << retval[1] << "mV)" << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Set dac " << index << " of module " << imod << " to " << val << " failed." << std::endl; - } - if(mV) - return retval[1]; - - return retval[0]; -}; - - -dacs_t slsDetector::getADC(dacIndex index, int imod){ - - dacs_t retval; - int fnum=F_GET_ADC; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - int arg[2]; - arg[0]=index; - arg[1]=imod; - - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Getting ADC "<< index << " of module " << imod << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectStop() == OK){ - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->SendDataOnly(arg,sizeof(arg)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); - if (adcs) { - *(adcs+index+imod*thisDetector->nAdcs)=retval; - } - } else { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectStop(); - /*commented out to allow adc read during acquire, also not required - if (ret==FORCE_UPDATE) - updateDetector();*/ - } - } -#ifdef VERBOSE - std::cout<< "ADC returned "<< retval << std::endl; -#endif - if (ret==FAIL) { - std::cout<< "Get ADC failed " << std::endl; - } - - return retval; - - - -}; - - - - -int slsDetector::setThresholdTemperature(int val, int imod) { - - int retval = -1; - int fnum = F_THRESHOLD_TEMP; - int ret = FAIL; - char mess[MAX_STR_LENGTH] = ""; - - int arg[2]; - arg[0]=val; - arg[1]=imod; - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting/Getting Threshold Temperature to "<< val << " of module " << imod << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectStop() == OK){ - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->SendDataOnly(arg,sizeof(arg)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); -#ifdef VERBOSE - std::cout<< "Threshold Temperature returned "<< retval << std::endl; -#endif - } else { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL)); - } - disconnectStop(); - } - } - - return retval; -} - - - -int slsDetector::setTemperatureControl(int val, int imod) { - - int retval = -1; - int fnum = F_TEMP_CONTROL; - int ret = FAIL; - char mess[MAX_STR_LENGTH] = ""; - - int arg[2]; - arg[0]=val; - arg[1]=imod; - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting/Getting Threshold Temperature to "<< val << " of module " << imod << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectStop() == OK){ - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->SendDataOnly(arg,sizeof(arg)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); -#ifdef VERBOSE - std::cout<< "Threshold Temperature returned "<< retval << std::endl; -#endif - } else { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL)); - } - disconnectStop(); - } - } - - return retval; -} - - - - -int slsDetector::setTemperatureEvent(int val, int imod) { - - int retval = -1; - int fnum = F_TEMP_EVENT; - int ret = FAIL; - char mess[MAX_STR_LENGTH] = ""; - - int arg[2]; - arg[0]=val; - arg[1]=imod; - - -#ifdef VERBOSE - std::cout<< std::endl; - std::cout<< "Setting/Getting Threshold Temperature to "<< val << " of module " << imod << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectStop() == OK){ - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->SendDataOnly(arg,sizeof(arg)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); -#ifdef VERBOSE - std::cout<< "Threshold Temperature returned "<< retval << std::endl; -#endif - } else { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL)); - } - disconnectStop(); - } - } - - return retval; -} - - -/* - configure single channel - enum channelRegisterBit { - COMPARATOR_ENABLE_OFF, - ANALOG_SIGNAL_ENABLE_OFF, - CALIBRATION_ENABLE_OFF, - TRIMBIT_OFF // should always be the last! - } - -*/ - -int slsDetector::setChannel(int64_t reg, int ichan, int ichip, int imod){ - sls_detector_channel myChan; -#ifdef VERBOSE - std::cout<< "Setting channel "<< ichan << " " << ichip << " " << imod << " to " << reg << std::endl; -#endif - //int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, chamax=ichan+1; - - int ret; - - /* if (imod==-1) { - mmin=0; - mmax=thisDetector->nModsMax; - } - - if (ichip==-1) { - chimin=0; - chimax=thisDetector->nChips; - } - - if (ichan==-1) { - chamin=0; - chamax=thisDetector->nChans; - }*/ - - // for (int im=mmin; imonlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - sendChannel(&chan); - - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - - if (ret!=FAIL) { - if (chanregs) { - - int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, chamax=ichan+1; - - if (imod==-1) { - mmin=0; - mmax=thisDetector->nModsMax; - } - - if (ichip==-1) { - chimin=0; - chimax=thisDetector->nChips; - } - - if (ichan==-1) { - chamin=0; - chamax=thisDetector->nChans; - } - - - - - - - for (int im=mmin; imnChans*thisDetector->nChips+ichi*thisDetector->nChips+icha)=retval; - - } - } - } - - } - } -#ifdef VERBOSE - std::cout<< "Channel register returned "<< retval << std::endl; -#endif - return retval; - -} - - - - - - - - - - - - - - - - - - -slsDetectorDefs::sls_detector_channel slsDetector::getChannel(int ichan, int ichip, int imod){ - - - int fnum=F_GET_CHANNEL; - sls_detector_channel myChan; - int arg[3]; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - arg[0]=ichan; - arg[1]=ichip; - arg[2]=imod; - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - receiveChannel(&myChan); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - - if (ret!=FAIL) { - if (chanregs) { - *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip*thisDetector->nChips+ichan)=myChan.reg; - } - } - -#ifdef VERBOSE - std::cout<< "Returned channel "<< ichan << " " << ichip << " " << imod << " " << myChan.reg << std::endl; -#endif - return myChan; -} - -/* - configure chip - enum chipRegisterBit { - ENABLE_ANALOG_OUTPUT, - OUTPUT_WIDTH // should always be the last - }{}; -*/ -int slsDetector::setChip(int reg, int ichip, int imod){ - sls_detector_chip myChip; - -#ifdef VERBOSE - std::cout<< "Setting chip "<< ichip << " " << imod << " to " << reg << std::endl; -#endif - - - int chregs[thisDetector->nChans]; - int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1; - int ret=FAIL; - if (imod==-1) { - mmin=0; - mmax=thisDetector->nModsMax; - } - - if (ichip==-1) { - chimin=0; - chimax=thisDetector->nChips; - } - - myChip.nchan=thisDetector->nChans; - myChip.reg=reg; - for (int im=mmin; imnChans+im*thisDetector->nChans*thisDetector->nChips); - else { - for (int i=0; inChans; ++i) - chregs[i]=-1; - myChip.chanregs=chregs; - } - ret=setChip(myChip); - } - } - return ret; -} - -int slsDetector::setChip(sls_detector_chip chip){ - - int fnum=F_SET_CHIP; - int retval; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - int ichi=chip.chip; - int im=chip.module; - - - - - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - sendChip(&chip); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - - if (ret!=FAIL) { - if (chipregs) - *(chipregs+ichi+im*thisDetector->nChips)=retval; - } - -#ifdef VERBOSE - std::cout<< "Chip register returned "<< retval << std::endl; -#endif - return retval; -}; - - -slsDetectorDefs::sls_detector_chip slsDetector::getChip(int ichip, int imod){ - - int fnum=F_GET_CHIP; - sls_detector_chip myChip; - int chanreg[thisDetector->nChans]; - - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - - myChip.chip=ichip; - myChip.module=imod; - myChip.nchan=thisDetector->nChans; - myChip.chanregs=chanreg; - - int arg[2]; - arg[0]=ichip; - arg[1]=imod; - - - - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - receiveChip(&myChip); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - - if (ret!=FAIL) { - if (chipregs) - *(chipregs+ichip+imod*thisDetector->nChips)=myChip.reg; - if (chanregs) { - for (int ichan=0; ichannChans; ++ichan) - *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip*thisDetector->nChans+ichan)=*((myChip.chanregs)+ichan); - } - } -#ifdef VERBOSE - std::cout<< "Returned chip "<< ichip << " " << imod << " " << myChip.reg << std::endl; -#endif - - return myChip; -}; - -/* - configure module - enum moduleRegisterBit { - I_DON_T_KNOW, - OUTPUT_WIDTH // should always be the last - }{}; -*/ - -int slsDetector::setModule(int reg, int imod){ - sls_detector_module myModule; - - #ifdef VERBOSE - std::cout << "slsDetector set module " << std::endl; -#endif - int charegs[thisDetector->nChans*thisDetector->nChips]; - int chiregs[thisDetector->nChips]; - dacs_t das[thisDetector->nDacs], ads[thisDetector->nAdcs]; - int mmin=imod, mmax=imod+1; - int ret=FAIL; - - if (imod==-1) { - mmin=0; - mmax=thisDetector->nModsMax; - } - - - - for (int im=mmin; imnChans; - myModule.nchip=thisDetector->nChips; - myModule.ndac=thisDetector->nDacs; - myModule.nadc=thisDetector->nAdcs; - - myModule.reg=reg; - if (detectorModules) { - myModule.gain=(detectorModules+im)->gain; - myModule.offset=(detectorModules+im)->offset; - myModule.serialnumber=(detectorModules+im)->serialnumber; - } else { - myModule.gain=-1; - myModule.offset=-1; - myModule.serialnumber=-1; - } - - - for (int i=0; inAdcs; ++i) - ads[i]=-1; - - if (chanregs) - myModule.chanregs=chanregs+im*thisDetector->nChips*thisDetector->nChans; - else { - for (int i=0; inChans*thisDetector->nChips; ++i) - charegs[i]=-1; - myModule.chanregs=charegs; - } - if (chipregs) - myModule.chipregs=chanregs+im*thisDetector->nChips; - else { - for (int ichip=0; ichipnChips; ++ichip) - chiregs[ichip]=-1; - myModule.chipregs=chiregs; - } - if (dacs) - myModule.dacs=dacs+im*thisDetector->nDacs; - else { - for (int i=0; inDacs; ++i) - das[i]=-1; - myModule.dacs=das; - } - if (adcs) - myModule.adcs=adcs+im*thisDetector->nAdcs; - else { - for (int i=0; inAdcs; ++i) - ads[i]=-1; - myModule.adcs=ads; - } - ret=setModule(myModule,-1,-1,-1,0,0); - } - return ret; - - -}; - -int slsDetector::setModule(sls_detector_module module, int iodelay, int tau, int e_eV, int* gainval, int* offsetval, int tb){ - - int fnum=F_SET_MODULE; - int retval=-1; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - int imod=module.module; - - -#ifdef VERBOSE - std::cout << "slsDetector set module " << std::endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - //to exclude trimbits - if(!tb) { - module.nchan=0; - module.nchip=0; - } - sendModule(&module); - - //not included in module - if(gainval && (thisDetector->nGain)) - controlSocket->SendDataOnly(gainval,sizeof(int)*thisDetector->nGain); - if(offsetval && (thisDetector->nOffset)) - controlSocket->SendDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); - if(thisDetector->myDetectorType == EIGER) { - controlSocket->SendDataOnly(&iodelay,sizeof(iodelay)); - controlSocket->SendDataOnly(&tau,sizeof(tau)); - controlSocket->SendDataOnly(&e_eV,sizeof(e_eV)); - } - - - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - if(strstr(mess,"default tau")!=NULL) - setErrorMask((getErrorMask())|(RATE_CORRECTION_NO_TAU_PROVIDED)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - - if (ret!=FAIL) { - if (detectorModules) { - if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { - if(tb) { - (detectorModules+imod)->nchan=module.nchan; - (detectorModules+imod)->nchip=module.nchip; - } - (detectorModules+imod)->ndac=module.ndac; - (detectorModules+imod)->nadc=module.nadc; - if(tb) { - thisDetector->nChips=module.nchip; - thisDetector->nChans=module.nchan/module.nchip; - } - thisDetector->nDacs=module.ndac; - thisDetector->nAdcs=module.nadc; - - if(thisDetector->myDetectorType != JUNGFRAU){ - if(tb) { - for (int ichip=0; ichipnChips; ++ichip) { - if (chipregs) - chipregs[ichip+thisDetector->nChips*imod]=module.chipregs[ichip]; - - if (chanregs) { - for (int i=0; inChans; ++i) { - chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=module.chanregs[ichip*thisDetector->nChans+i]; - } - } - } - } - if (adcs) { - for (int i=0; inAdcs; ++i) - adcs[i+imod*thisDetector->nAdcs]=module.adcs[i]; - } - } - - if (dacs) { - for (int i=0; inDacs; ++i) - dacs[i+imod*thisDetector->nDacs]=module.dacs[i]; - } - - (detectorModules+imod)->gain=module.gain; - (detectorModules+imod)->offset=module.offset; - (detectorModules+imod)->serialnumber=module.serialnumber; - (detectorModules+imod)->reg=module.reg; - } - } - - if ((thisDetector->nGain) && (gainval) && (gain)) { - for (int i=0; inGain; ++i) - gain[i+imod*thisDetector->nGain]=gainval[i]; - } - - if ((thisDetector->nOffset) && (offsetval) && (offset)) { - for (int i=0; inOffset; ++i) - offset[i+imod*thisDetector->nOffset]=offsetval[i]; - } - - if (e_eV != -1) - thisDetector->currentThresholdEV = e_eV; - - } - -#ifdef VERBOSE - std::cout<< "Module register returned "<< retval << std::endl; -#endif - - return retval; -}; - - - - - -slsDetectorDefs::sls_detector_module *slsDetector::getModule(int imod){ - -#ifdef VERBOSE - std::cout << "slsDetector get module " << std::endl; -#endif - - int fnum=F_GET_MODULE; - sls_detector_module *myMod=createModule(); - - int* gainval=0, *offsetval=0; - if(thisDetector->nGain) - gainval=new int[thisDetector->nGain]; - if(thisDetector->nOffset) - offsetval=new int[thisDetector->nOffset]; - - //char *ptr, *goff=(char*)thisDetector; - - // int chanreg[thisDetector->nChans*thisDetector->nChips]; - //int chipreg[thisDetector->nChips]; - //double dac[thisDetector->nDacs], adc[thisDetector->nAdcs]; - - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - // int n; - -#ifdef VERBOSE - std::cout<< "getting module " << imod << std::endl; -#endif - - myMod->module=imod; - // myMod.nchan=thisDetector->nChans*thisDetector->nChips; - //myMod.chanregs=chanreg; - //myMod.nchip=thisDetector->nChips; - //myMod.chipregs=chipreg; - //myMod.ndac=thisDetector->nDacs; - //myMod.dacs=dac; - //myMod.ndac=thisDetector->nAdcs; - //myMod.dacs=adc; - - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&imod,sizeof(imod)); - - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - receiveModule(myMod); - - //extra gain and offset - eiger - if(thisDetector->nGain) - controlSocket->ReceiveDataOnly(gainval,sizeof(int)*thisDetector->nGain); - if(thisDetector->nOffset) - controlSocket->ReceiveDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - - if (ret!=FAIL) { - if (detectorModules) { - if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { - (detectorModules+imod)->nchan=myMod->nchan; - (detectorModules+imod)->nchip=myMod->nchip; - (detectorModules+imod)->ndac=myMod->ndac; - (detectorModules+imod)->nadc=myMod->nadc; - thisDetector->nChips=myMod->nchip; - thisDetector->nChans=myMod->nchan/myMod->nchip; - thisDetector->nDacs=myMod->ndac; - thisDetector->nAdcs=myMod->nadc; - - if(thisDetector->myDetectorType != JUNGFRAU){ - for (int ichip=0; ichipnChips; ++ichip) { - if (chipregs) - chipregs[ichip+thisDetector->nChips*imod]=myMod->chipregs[ichip]; - - if (chanregs) { - for (int i=0; inChans; ++i) { - chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=myMod->chanregs[ichip*thisDetector->nChans+i]; - } - } - } - - if (adcs) { - for (int i=0; inAdcs; ++i) - adcs[i+imod*thisDetector->nAdcs]=myMod->adcs[i]; - } - } - - if (dacs) { - for (int i=0; inDacs; ++i) - dacs[i+imod*thisDetector->nDacs]=myMod->dacs[i]; - } - (detectorModules+imod)->gain=myMod->gain; - (detectorModules+imod)->offset=myMod->offset; - (detectorModules+imod)->serialnumber=myMod->serialnumber; - (detectorModules+imod)->reg=myMod->reg; - } - } - - if ((thisDetector->nGain) && (gainval) && (gain)) { - for (int i=0; inGain; ++i) - gain[i+imod*thisDetector->nGain]=gainval[i]; - } - - if ((thisDetector->nOffset) && (offsetval) && (offset)) { - for (int i=0; inOffset; ++i) - offset[i+imod*thisDetector->nOffset]=offsetval[i]; - } - - } else { - deleteModule(myMod); - myMod=NULL; - } - - if(gainval) delete[]gainval; - if(offsetval) delete[]offsetval; - - return myMod; -} - - - - -// calibration functions -/* - really needed? - - int slsDetector::setCalibration(int imod, detectorSettings isettings, double gain, double offset){ - std::cout<< "function not yet implemented " << std::endl; - - - - return OK; - - } - int slsDetector::getCalibration(int imod, detectorSettings isettings, double &gain, double &offset){ - - std::cout<< "function not yet implemented " << std::endl; - - - - } -*/ - -/* - calibrated setup of the threshold -*/ - -int slsDetector::getThresholdEnergy(int imod){ - - int fnum= F_GET_THRESHOLD_ENERGY; - int retval; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; -#ifdef VERBOSE - std::cout<< "Getting threshold energy "<< std::endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&imod,sizeof(imod)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - std::cout<< "Detector returned error: "<< std::endl; - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< mess << std::endl; - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - thisDetector->currentThresholdEV=retval; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return thisDetector->currentThresholdEV; -}; - -int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isettings, int tb){ - - //currently only for eiger - if (thisDetector->myDetectorType == EIGER) { - setThresholdEnergyAndSettings(e_eV,isettings,tb); - return thisDetector->currentThresholdEV; - } - - int fnum= F_SET_THRESHOLD_ENERGY; - int retval; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; -#ifdef VERBOSE - std::cout<< "Setting threshold energy "<< std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&e_eV,sizeof(e_eV)); - controlSocket->SendDataOnly(&imod,sizeof(imod)); - controlSocket->SendDataOnly(&isettings,sizeof(isettings)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - std::cout<< "Detector returned error: "<< std::endl; - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< mess << std::endl; - } else { -#ifdef VERBOSE - std::cout<< "Detector returned OK "<< std::endl; -#endif - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - thisDetector->currentThresholdEV=retval; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } else { - thisDetector->currentThresholdEV=e_eV; - } - return thisDetector->currentThresholdEV; -}; - - - -int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb) { - - //if settings provided, use that, else use the shared memory variable - detectorSettings is = ((isettings != GET_SETTINGS) ? isettings: thisDetector->currentSettings); - string ssettings; - switch (is) { - case STANDARD: - ssettings="/standard"; - thisDetector->currentSettings=STANDARD; - break; - case HIGHGAIN: - ssettings="/highgain"; - thisDetector->currentSettings=HIGHGAIN; - break; - case LOWGAIN: - ssettings="/lowgain"; - thisDetector->currentSettings=LOWGAIN; - break; - case VERYHIGHGAIN: - ssettings="/veryhighgain"; - thisDetector->currentSettings=VERYHIGHGAIN; - break; - case VERYLOWGAIN: - ssettings="/verylowgain"; - thisDetector->currentSettings=VERYLOWGAIN; - break; - default: - printf("Error: Unknown settings %s for this detector!\n", getDetectorSettings(is).c_str()); - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); - return FAIL; - } - - //verify e_eV exists in trimEneregies[] - if (!thisDetector->nTrimEn || - (e_eV < thisDetector->trimEnergies[0]) || - (e_eV > thisDetector->trimEnergies[thisDetector->nTrimEn-1]) ) { - printf("Error: This energy %d not defined for this module!\n", e_eV); - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); - return FAIL; - } - - //find if interpolation required - bool interpolate = true; - for (int i = 0; i < thisDetector->nTrimEn; ++i) { - if (thisDetector->trimEnergies[i] == e_eV) { - interpolate = false; - break; - } - } - - //fill detector module structure - sls_detector_module *myMod = NULL; - int iodelay = -1; //not included in the module - int tau = -1; //not included in the module - - //normal - if(!interpolate) { - //find their directory names - ostringstream ostfn; - ostfn << thisDetector->settingsDir << ssettings << "/" << e_eV << "eV" << "/noise.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); - string settingsfname = ostfn.str(); -#ifdef VERBOSE - printf("Settings File is %s\n", settingsfname.c_str()); -#endif - //read the files - myMod=createModule(); - if (NULL == readSettingsFile(settingsfname,thisDetector->myDetectorType, iodelay, tau, myMod, tb)) { - if(myMod)deleteModule(myMod); - return FAIL; - } - } - - - //interpolate - else { - //find the trim values - int trim1 = -1, trim2 = -1; - for (int i = 0; i < thisDetector->nTrimEn; ++i) { - if (e_eV < thisDetector->trimEnergies[i]) { - trim2 = thisDetector->trimEnergies[i]; - trim1 = thisDetector->trimEnergies[i-1]; - break; - } - } - //find their directory names - ostringstream ostfn; - ostfn << thisDetector->settingsDir << ssettings << "/" << trim1 << "eV" << "/noise.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); - string settingsfname1 = ostfn.str(); - ostfn.str(""); ostfn.clear(); - ostfn << thisDetector->settingsDir << ssettings << "/" << trim2 << "eV" << "/noise.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); - string settingsfname2 = ostfn.str(); - //read the files -#ifdef VERBOSE - printf("Settings Files are %s and %s\n",settingsfname1.c_str(), settingsfname2.c_str()); -#endif - sls_detector_module *myMod1=createModule(); - sls_detector_module *myMod2=createModule(); - int iodelay1 = -1; //not included in the module - int tau1 = -1; //not included in the module - int iodelay2 = -1; //not included in the module - int tau2 = -1; //not included in the module - if (NULL == readSettingsFile(settingsfname1,thisDetector->myDetectorType, iodelay1, tau1, myMod1, tb)) { - setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); - deleteModule(myMod1); - deleteModule(myMod2); - return FAIL; - } - if (NULL == readSettingsFile(settingsfname2,thisDetector->myDetectorType, iodelay2, tau2, myMod2, tb)) { - setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); - deleteModule(myMod1); - deleteModule(myMod2); - return FAIL; - } - if (iodelay1 != iodelay2) { - printf("iodelays do not match between files\n"); - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); - deleteModule(myMod1); - deleteModule(myMod2); - return FAIL; - } - iodelay = iodelay1; - - //interpolate module - myMod = interpolateTrim(thisDetector->myDetectorType, myMod1, myMod2, e_eV, trim1, trim2, tb); - if (myMod == NULL) { - printf("Could not interpolate, different dac values in files\n"); - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); - } - //interpolate tau - tau = linearInterpolation(e_eV, trim1, trim2, tau1, tau2); - //printf("new tau:%d\n",tau); - - deleteModule(myMod1); - deleteModule(myMod2); - } - - - myMod->module=0; - myMod->reg=thisDetector->currentSettings; - setModule(*myMod, iodelay, tau, e_eV, 0, 0, tb); - deleteModule(myMod); - if (getSettings(-1) != is){ - std::cout << "Could not set settings in detector" << endl; - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); - return FAIL; - } - - return OK; -} - - - -/* - select detector settings -*/ -slsDetectorDefs::detectorSettings slsDetector::getSettings(int imod){ - - - int fnum=F_SET_SETTINGS; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - int retval; - int arg[2]; - arg[0]=GET_SETTINGS; - arg[1]=imod; -#ifdef VERBOSE - std::cout<< "Getting settings "<< std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else{ - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - thisDetector->currentSettings=(detectorSettings)retval; -#ifdef VERBOSE - std::cout<< "Settings are "<< retval << std::endl; -#endif - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return thisDetector->currentSettings; - -}; - - - -slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings isettings, int imod){ -#ifdef VERBOSE - std::cout<< "slsDetector setSettings "<< std::endl; -#endif - - //only set client shared memory variable for Eiger, settings threshold loads the module data (trimbits, dacs etc.) - if (thisDetector->myDetectorType == EIGER) { - switch(isettings) { - case STANDARD: - case HIGHGAIN: - case LOWGAIN: - case VERYHIGHGAIN: - case VERYLOWGAIN: - thisDetector->currentSettings = isettings; break; default: - printf("Unknown settings %s for this detector!\n", getDetectorSettings(isettings).c_str()); - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); break; } - return thisDetector->currentSettings; - } - sls_detector_module *myMod=createModule(); - int modmi=imod, modma=imod+1, im=imod; - string settingsfname, calfname; - string ssettings; - - //not included in module structure - int iodelay = -1; - int tau = -1; - int* gainval=0, *offsetval=0; - if(thisDetector->nGain) - gainval=new int[thisDetector->nGain]; - if(thisDetector->nOffset) - offsetval=new int[thisDetector->nOffset]; - - - int ret=0; - - - switch (isettings) { - case STANDARD: - if ( (thisDetector->myDetectorType == MYTHEN) || - (thisDetector->myDetectorType == EIGER)) { - ssettings="/standard"; - thisDetector->currentSettings=STANDARD; - } - break; - case FAST: - if (thisDetector->myDetectorType == MYTHEN) { - ssettings="/fast"; - thisDetector->currentSettings=FAST; - } - break; - case HIGHGAIN: - if ( (thisDetector->myDetectorType == MYTHEN) || - (thisDetector->myDetectorType == GOTTHARD) || - (thisDetector->myDetectorType == PROPIX) || - (thisDetector->myDetectorType == MOENCH) || - (thisDetector->myDetectorType == EIGER)) { - ssettings="/highgain"; - thisDetector->currentSettings=HIGHGAIN; - } - break; - case DYNAMICGAIN: - if ((thisDetector->myDetectorType == GOTTHARD) || - (thisDetector->myDetectorType == PROPIX) || - (thisDetector->myDetectorType == JUNGFRAU) || - (thisDetector->myDetectorType == MOENCH)) { - ssettings="/dynamicgain"; - thisDetector->currentSettings=DYNAMICGAIN; - } - break; - case LOWGAIN: - if ((thisDetector->myDetectorType == GOTTHARD) || - (thisDetector->myDetectorType == PROPIX) || - (thisDetector->myDetectorType == MOENCH) || - (thisDetector->myDetectorType == EIGER) ) { - ssettings="/lowgain"; - thisDetector->currentSettings=LOWGAIN; - } - break; - case MEDIUMGAIN: - if ((thisDetector->myDetectorType == GOTTHARD) || - (thisDetector->myDetectorType == PROPIX) || - (thisDetector->myDetectorType == MOENCH)) { - ssettings="/mediumgain"; - thisDetector->currentSettings=MEDIUMGAIN; - } - break; - case VERYHIGHGAIN: - if ((thisDetector->myDetectorType == GOTTHARD) || - (thisDetector->myDetectorType == PROPIX) || - (thisDetector->myDetectorType == MOENCH)|| - (thisDetector->myDetectorType == EIGER)) { - ssettings="/veryhighgain"; - thisDetector->currentSettings=VERYHIGHGAIN; - } - break; - case LOWNOISE: - break; - case DYNAMICHG0: - if (thisDetector->myDetectorType == JUNGFRAU) { - ssettings="/dynamichg0"; - thisDetector->currentSettings=DYNAMICHG0; - } - break; - case FIXGAIN1: - if (thisDetector->myDetectorType == JUNGFRAU) { - ssettings="/fixgain1"; - thisDetector->currentSettings=FIXGAIN1; - } - break; - case FIXGAIN2: - if (thisDetector->myDetectorType == JUNGFRAU) { - ssettings="/fixgain2"; - thisDetector->currentSettings=FIXGAIN2; - } - break; - case FORCESWITCHG1: - if (thisDetector->myDetectorType == JUNGFRAU) { - ssettings="/forceswitchg1"; - thisDetector->currentSettings=FORCESWITCHG1; - } - break; - case FORCESWITCHG2: - if (thisDetector->myDetectorType == JUNGFRAU) { - ssettings="/forceswitchg2"; - thisDetector->currentSettings=FORCESWITCHG2; - } - break; - case VERYLOWGAIN: - if (thisDetector->myDetectorType == EIGER) { - ssettings="/verylowgain"; - thisDetector->currentSettings=VERYLOWGAIN; - } - break; - default: - break; - } - - - if (isettings != thisDetector->currentSettings) { - printf("Unknown settings %s for this detector!\n", getDetectorSettings(isettings).c_str()); - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); - }else{ - if (imod<0) { - modmi=0; - // modma=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; - modma=thisDetector->nMod[X]*thisDetector->nMod[Y]; - } - - for (im=modmi; immodule=im; - - std::cout << std::endl << "Loading settings for module:" << im << std::endl; - - //create file names - switch(thisDetector->myDetectorType){ - case EIGER: - //settings is saved in myMod.reg - myMod->reg=thisDetector->currentSettings; - ostfn << thisDetector->settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); - oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); -#ifdef VERBOSE - std::cout<< thisDetector->settingsDir<calDir <settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); - oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); - break; - default: - //settings is saved in myMod.reg - myMod->reg=thisDetector->currentSettings; - ostfn << thisDetector->settingsDir << ssettings <<"/settings.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); - oscfn << thisDetector->calDir << ssettings << "/calibration.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); -#ifdef VERBOSE - std::cout<< thisDetector->settingsDir<calDir <myDetectorType, iodelay, tau, myMod)) { - //if it didnt open, try default settings file - ostringstream ostfn_default; - switch(thisDetector->myDetectorType){ - case EIGER: - case MYTHEN: - ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".trim"; - break; - default: - ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".settings"; - break; - } - settingsfname=ostfn_default.str(); -#ifdef VERBOSE - cout << settingsfname << endl; -#endif - if (NULL == readSettingsFile(settingsfname,thisDetector->myDetectorType, iodelay, tau, myMod)) { - //if default doesnt work, return error - std::cout << "Could not open settings file" << endl; - setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); - return thisDetector->currentSettings; - } - } - - - - //calibration file**** - if(thisDetector->myDetectorType != EIGER) { - calfname=oscfn.str(); -#ifdef VERBOSE - cout << "Specific file:"<< calfname << endl; -#endif - //extra gain and offset - if(thisDetector->nGain) - ret = readCalibrationFile(calfname,gainval, offsetval); - //normal gain and offset inside sls_detector_module - else - ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); - - //if it didnt open, try default - if(ret != OK){ - ostringstream oscfn_default; - oscfn_default << thisDetector->calDir << ssettings << ssettings << ".cal"; - calfname=oscfn_default.str(); -#ifdef VERBOSE - cout << "Default file:" << calfname << endl; -#endif - //extra gain and offset - if(thisDetector->nGain) - ret = readCalibrationFile(calfname,gainval, offsetval); - //normal gain and offset inside sls_detector_module - else - ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); - } - //if default doesnt work, return error - if(ret != OK){ - std::cout << "Could not open calibration file" << calfname << endl; - setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); - return thisDetector->currentSettings; - } - } - - //if everything worked, set module**** - setModule(*myMod,iodelay,tau,-1,gainval,offsetval); - } - } - - - - deleteModule(myMod); - if(gainval) delete [] gainval; - if(offsetval) delete [] offsetval; - - if (thisDetector->myDetectorType==MYTHEN){ - if (thisDetector->correctionMask&(1<-1 && isett<3) { - thisDetector->tDead=t[isett]; - } - } - } - - if (getSettings(imod) != isettings){ - std::cout << "Could not set settings" << endl; - setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); - } - - return thisDetector->currentSettings; -}; - - - -int slsDetector::getChanRegs(double* retval,bool fromDetector){ - int n=getTotalNumberOfChannels(); - if(fromDetector){ - for(int im=0;imReceiveDataOnly(lastClientIP,sizeof(lastClientIP)); -#ifdef VERBOSE - cout << "Updating detector last modified by " << lastClientIP << std::endl; -#endif - n += controlSocket->ReceiveDataOnly(&nm,sizeof(nm)); - thisDetector->nMod[X]=nm; - n += controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); - /// Should be overcome at a certain point! - - if (thisDetector->myDetectorType==MYTHEN) { - thisDetector->nModMax[X]=nm; - thisDetector->nModMax[Y]=1; - thisDetector->nModsMax=thisDetector->nModMax[Y]*thisDetector->nModMax[X]; - thisDetector->nMod[Y]=1; - } else { - thisDetector->nMod[Y]=nm; - } - - thisDetector->nMods=thisDetector->nMod[Y]*thisDetector->nMod[X]; - if (thisDetector->nModsMaxnMods) - thisDetector->nModsMax=thisDetector->nMods; - - if (thisDetector->nModMax[X]nMod[X]) - thisDetector->nModMax[X]=thisDetector->nMod[X]; - - if (thisDetector->nModMax[Y]nMod[Y]) - thisDetector->nModMax[Y]=thisDetector->nMod[Y]; - - n += controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); - thisDetector->dynamicRange=nm; - - n += controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); - thisDetector->dataBytes=nm; - - //t=setSettings(GET_SETTINGS); - n += controlSocket->ReceiveDataOnly( &t,sizeof(t)); - thisDetector->currentSettings=t; - - if((thisDetector->myDetectorType == EIGER) || (thisDetector->myDetectorType == MYTHEN)){ - //thr=getThresholdEnergy(); - n += controlSocket->ReceiveDataOnly( &thr,sizeof(thr)); - thisDetector->currentThresholdEV=thr; - } - - //retval=setFrames(tns); - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[FRAME_NUMBER]=retval; - - // retval=setExposureTime(tns); - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[ACQUISITION_TIME]=retval; - - if(thisDetector->myDetectorType == EIGER){ - //retval=setSubFrameExposureTime(tns); - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME]=retval; - } - - //retval=setPeriod(tns); - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[FRAME_PERIOD]=retval; - - if(thisDetector->myDetectorType != EIGER) { - //retval=setDelay(tns); - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[DELAY_AFTER_TRIGGER]=retval; - } - - // retval=setGates(tns); - if ((thisDetector->myDetectorType != JUNGFRAU) && (thisDetector->myDetectorType != EIGER)){ - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[GATES_NUMBER]=retval; - } - - //retval=setProbes(tns); - if (thisDetector->myDetectorType == MYTHEN){ - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[PROBES_NUMBER]=retval; - } - - //retval=setTrains(tns); - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - thisDetector->timerValue[CYCLES_NUMBER]=retval; - - //retval=setProbes(tns); - if (thisDetector->myDetectorType == JUNGFRAUCTB){ - n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); - if (retval>=0) - thisDetector->timerValue[SAMPLES_JCTB]=retval; - n += controlSocket->ReceiveDataOnly( &ro,sizeof(ro)); - - thisDetector->roFlags=ro; - - //retval=setProbes(tns); - getTotalNumberOfChannels(); - // thisDetector->dataBytes=getTotalNumberOfChannels()*thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; - } - - - if (!n) - printf("n: %d\n", n); - - return OK; - -} - - - - -int slsDetector::updateDetector() { - int fnum=F_UPDATE_CLIENT; - int ret=OK; - char mess[MAX_STR_LENGTH]=""; - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else - updateDetectorNoWait(); - disconnectControl(); - } - } - return ret; -} - - - -// Acquisition functions -/* change these funcs accepting also ok/fail */ - - -int slsDetector::prepareAcquisition() { - int fnum = F_PREPARE_ACQUISITION; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - if (thisDetector->onlineFlag==ONLINE_FLAG) { -#ifdef VERBOSE - std::cout << "Preparing Detector for Acquisition" << std::endl; -#endif - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(PREPARE_ACQUISITION)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - }else - std::cout << "cannot connect to detector" << endl; - - return ret; -} - -int slsDetector::cleanupAcquisition() { - int fnum = F_CLEANUP_ACQUISITION; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - - if (thisDetector->onlineFlag==ONLINE_FLAG) { -#ifdef VERBOSE - std::cout << "Cleaning up Detector after Acquisition " << std::endl; -#endif - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(CLEANUP_ACQUISITION)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - }else - std::cout << "cannot connect to detector" << endl; - - return ret; - -} - -int slsDetector::startAcquisition(){ - - - int fnum=F_START_ACQUISITION; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<< "Starting acquisition "<< std::endl; -#endif - thisDetector->stoppedFlag=0; - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return ret; - - - -}; - - -int slsDetector::stopAcquisition(){ - - // get status before stopping acquisition - runStatus s = ERROR, r = ERROR; - if (thisDetector->receiver_upstream) { - s = getRunStatus(); - r = getReceiverStatus(); - } - - int fnum=F_STOP_ACQUISITION; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<< "Stopping acquisition "<< std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (stopSocket) { - if (connectStop() == OK) { - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectStop(); - } - } - } - thisDetector->stoppedFlag=1; - - // if rxr streaming and acquisition finished, restream dummy stop packet - if ((thisDetector->receiver_upstream) && (s == IDLE) && (r == IDLE)) { - restreamStopFromReceiver(); - } - - return ret; - - -}; - -int slsDetector::startReadOut(){ - - int fnum=F_START_READOUT; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<< "Starting readout "<< std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return ret; -}; - - -slsDetectorDefs::runStatus slsDetector::getRunStatus(){ - int fnum=F_GET_RUN_STATUS; - int ret=FAIL; - char mess[MAX_STR_LENGTH]=""; - strcpy(mess,"aaaaa"); - runStatus retval=ERROR; -#ifdef VERBOSE - std::cout<< "Getting status "<< std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (stopSocket) { - if (connectStop() == OK) { - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - - //cout << "________:::____________" << ret << endl; - - if (ret==FAIL) { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; } else { - stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); - //cout << "____________________" << retval << endl; + thisDetector->onlineFlag=OFFLINE_FLAG; +#ifdef VERBOSE + std::cout<< "offline!" << std::endl; +#endif } - disconnectStop(); - } - } - } - return retval; - - -}; - - -int* slsDetector::readFrame(){ - - int fnum=F_READ_FRAME; - int* retval=NULL; - -#ifdef VERBOSE - std::cout<< "slsDetector: Reading frame "<< std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - retval=getDataFromDetector(); - if (retval) { - dataQueue.push(retval); - disconnectControl(); - } - } - } - return retval; -}; - - - - -int* slsDetector::getDataFromDetector(int *retval){ - int ret=FAIL; - char mess[MAX_STR_LENGTH]="Nothing"; - int nel=thisDetector->dataBytes/sizeof(int); - int n; - int *r=retval; - - int nodatadetectortype = false; - detectorType types = getDetectorsType(); - if(types == EIGER || types == JUNGFRAU){ - nodatadetectortype = true; - } - - - if (!nodatadetectortype && retval==NULL) - retval=new int[nel]; - - -#ifdef VERBOSE - std::cout<< "getting data "<< thisDetector->dataBytes << " " << nel<< std::endl; -#endif - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); -#ifdef VERBOSE - cout << "ret=" << ret << endl; -#endif - - if (ret!=OK) { - n= controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - // if(thisDetector->receiverOnlineFlag == OFFLINE_FLAG) - if (ret==FAIL) { - thisDetector->stoppedFlag=1; - std::cout<< "Detector returned: " << mess << " " << n << std::endl; - } else { - ; -#ifdef VERBOSE - std::cout<< "Detector successfully returned: " << mess << " " << n << std::endl; -#endif - } - if ((!nodatadetectortype) && (r==NULL)){ - delete [] retval; - } - return NULL; - } else if (!nodatadetectortype){ - - n=controlSocket->ReceiveDataOnly(retval,thisDetector->dataBytes); - -#ifdef VERBOSE - std::cout<< "Received "<< n << " data bytes" << std::endl; -#endif - if (n!=thisDetector->dataBytes) { - std::cout<< "wrong data size received from detector: received " << n << " but expected " << thisDetector->dataBytes << std::endl; - thisDetector->stoppedFlag=1; - ret=FAIL; - if (r==NULL) { - delete [] retval; - } - return NULL; - } - // for (int ib=0; ibdataBytes/8; ++ib) - // cout << ((*(((u_int64_t*)retval)+ib))>>17&1) ; - - - } - // cout << "get data returning " << endl; - // cout << endl; return retval; - -}; - - - - - - -int* slsDetector::readAll(){ - - int fnum=F_READ_ALL; - int* retval; // check what we return! - -#ifdef VERBOSE - int i=0; - std::cout<< "Reading all frames "<< std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - - while ((retval=getDataFromDetector())){ -#ifdef VERBOSE - ++i; - std::cout<< i << std::endl; -#endif - dataQueue.push(retval); - } - disconnectControl(); - } - } -#ifdef VERBOSE - std::cout<< "received "<< i<< " frames" << std::endl; -#endif - return dataQueue.front(); // check what we return! - -}; - - - - - -int slsDetector::readAllNoWait(){ - - int fnum= F_READ_ALL; - -#ifdef VERBOSE - std::cout<< "Reading all frames "<< std::endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - return OK; - } - } - return FAIL; -}; - - - - - - - - -int* slsDetector::startAndReadAll(){ - //cout << "Start and read all "<< endl; - - int* retval; - //#ifdef VERBOSE -#ifdef VERBOSE - int i=0; -#endif - //#endif - if(thisDetector->myDetectorType == EIGER) { - if (prepareAcquisition() == FAIL) - return NULL; - } - startAndReadAllNoWait(); - //#ifdef VERBOSE - // std::cout<< "started" << std::endl; - //#endif - while ((retval=getDataFromDetector())){ -#ifdef VERBOSE - ++i; - std::cout<< i << std::endl; - //#else - //std::cout<< "-" << flush; -#endif - dataQueue.push(retval); - - //std::cout<< "pushed" << std::endl; - } - disconnectControl(); - -#ifdef VERBOSE - std::cout<< "received "<< i<< " frames" << std::endl; - //#else - // std::cout << std::endl; -#endif - return dataQueue.front(); // check what we return! - /* while ((retval=getDataFromDetectorNoWait())) - ++i; - #ifdef VERBOSE - std::cout<< "Received " << i << " frames"<< std::endl; - #endif - return dataQueue.front(); // check what we return! - */ - -}; - - - -int slsDetector::startAndReadAllNoWait(){ - - int fnum= F_START_AND_READ_ALL; - -#ifdef VERBOSE - std::cout<< "Starting and reading all frames "<< std::endl; -#endif - thisDetector->stoppedFlag=0; - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - //std::cout<< "connected" << std::endl; - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - return OK; - } - } - return FAIL; -}; - -// int* slsDetector::getDataFromDetectorNoWait() { -// int *retval=getDataFromDetector(); -// if (thisDetector->onlineFlag==ONLINE_FLAG) { -// if (controlSocket) { -// if (retval==NULL){ -// disconnectControl(); - -// #ifdef VERBOSE -// std::cout<< "Run finished "<< std::endl; -// #endif -// } else { -// #ifdef VERBOSE -// std::cout<< "Frame received "<< std::endl; -// #endif -// } -// } -// } -// return retval; // check what we return! -// }; - - - - -/* - set or read the acquisition timers - enum timerIndex { - FRAME_NUMBER, - ACQUISITION_TIME, - FRAME_PERIOD, - DELAY_AFTER_TRIGGER, - GATES_NUMBER, - PROBES_NUMBER - CYCLES_NUMBER, - GATE_INTEGRATED_TIME - } -*/ -int64_t slsDetector::setTimer(timerIndex index, int64_t t){ - - - int fnum=F_SET_TIMER,fnum2=F_SET_RECEIVER_TIMER; - int64_t retval = -1; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; - - if (index!=MEASUREMENTS_NUMBER) { - - -#ifdef VERBOSE - std::cout<< "Setting timer "<< index << " to " << t << "ns/value" << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&index,sizeof(index)); - controlSocket->SendDataOnly(&t,sizeof(t)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(DETECTOR_TIMER_VALUE_NOT_SET)); - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - thisDetector->timerValue[index]=retval; - } - disconnectControl(); - if (ret==FORCE_UPDATE) { - updateDetector(); -#ifdef VERBOSE - std::cout<< "Updated!" << std::endl; -#endif - - } - } - } else { - //std::cout<< "offline " << std::endl; - if (t>=0) - thisDetector->timerValue[index]=t; - if((thisDetector->myDetectorType==GOTTHARD)|| - (thisDetector->myDetectorType==PROPIX)|| - (thisDetector->myDetectorType==JUNGFRAU)|| - (thisDetector->myDetectorType==MOENCH)) - thisDetector->timerValue[PROBES_NUMBER]=0; - if(thisDetector->myDetectorType==JUNGFRAUCTB && index==SAMPLES_JCTB) { - getTotalNumberOfChannels(); - // thisDetector->dataBytes=getTotalNumberOfChannels()*thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; - } - - } - } else { - if (t>=0) - thisDetector->timerValue[index]=t; - } -#ifdef VERBOSE - std::cout<< "Timer " << index << " set to "<< thisDetector->timerValue[index] << "ns" << std::endl; -#endif - - if ((thisDetector->myDetectorType==MYTHEN)&&(index==PROBES_NUMBER)) { - setDynamicRange(); - //cout << "Changing probes: data size = " << thisDetector->dataBytes <myDetectorType==JUNGFRAUCTB) && (index==SAMPLES_JCTB)) { - setDynamicRange(); - cout << "Changing samples: data size = " << thisDetector->dataBytes <myDetectorType==MYTHEN)&&(index==PROBES_NUMBER)) { - setDynamicRange(); - //cout << "Changing probes: data size = " << thisDetector->dataBytes <myDetectorType == EIGER) && - getRateCorrection(r) && - (t>=0) && - - (((index == SUBFRAME_ACQUISITION_TIME) && (thisDetector->dynamicRange == 32))|| - ((index == ACQUISITION_TIME) && (thisDetector->dynamicRange == 16))) - - && (t>=0) && getRateCorrection(r)){ - setRateCorrection(r); - } - } - - - - - //send acquisiton time/period/subexptime/frame/cycles/samples to receiver - if((index==FRAME_NUMBER)||(index==FRAME_PERIOD)||(index==CYCLES_NUMBER)||(index==ACQUISITION_TIME) || (index==SUBFRAME_ACQUISITION_TIME) || (index==SAMPLES_JCTB)){ - string timername = getTimerType(index); - if(ret != FAIL){ - int64_t args[2]; - retval = -1; - args[0] = index; - args[1] = thisDetector->timerValue[index]; - - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ - - //set #frames * #cycles - if((index==FRAME_NUMBER)||(index==CYCLES_NUMBER)){ - timername.assign("(Number of Frames) * (Number of cycles)"); -#ifdef VERBOSE - std::cout << "Setting/Getting " << timername << " " << index <<" to/from receiver " << args[1] << std::endl; -#endif - if(thisDetector->timerValue[CYCLES_NUMBER]==0) - args[1] = thisDetector->timerValue[FRAME_NUMBER]; - else - args[1] = thisDetector->timerValue[FRAME_NUMBER]*thisDetector->timerValue[CYCLES_NUMBER]; - } -#ifdef VERBOSE - // set period/exptime/subexptime - else std::cout << "Setting/Getting " << timername << " " << index << " to/from receiver " << args[1] << std::endl; -#endif - - char mess[MAX_STR_LENGTH]=""; - if (connectData() == OK){ - ret=thisReceiver->sendIntArray(fnum2,retval,args,mess); - disconnectData(); - } - if((args[1] != retval)|| (ret==FAIL)){ - ret = FAIL; - cout << "ERROR: " << timername << " in receiver set incorrectly to " << retval << " instead of " << args[1] << endl; - - if(strstr(mess,"receiver is not idle")==NULL) { - switch(index) { - case ACQUISITION_TIME: - setErrorMask((getErrorMask())|(RECEIVER_ACQ_TIME_NOT_SET)); - break; - case FRAME_PERIOD: - setErrorMask((getErrorMask())|(RECEIVER_ACQ_PERIOD_NOT_SET)); - break; - case SUBFRAME_ACQUISITION_TIME: - setErrorMask((getErrorMask())|(RECEIVER_TIMER_NOT_SET)); - break; - case SAMPLES_JCTB: - setErrorMask((getErrorMask())|(RECEIVER_TIMER_NOT_SET)); - break; - default: - setErrorMask((getErrorMask())|(RECEIVER_FRAME_NUM_NOT_SET)); - break; - } - } - } - if(ret==FORCE_UPDATE) - updateReceiver(); - } - } - } - return thisDetector->timerValue[index]; -}; - -int slsDetector::lockServer(int lock) { - int fnum=F_LOCK_SERVER; - int retval=-1; - int ret=OK; - char mess[MAX_STR_LENGTH]=""; - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&lock,sizeof(lock)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return retval; - - } -string slsDetector::getLastClientIP() { - int fnum=F_GET_LAST_CLIENT_IP; - char clientName[INET_ADDRSTRLEN]; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else { - controlSocket->ReceiveDataOnly(clientName,sizeof(clientName)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return string(clientName); - -} - - -int slsDetector::setPort(portType index, int num){ +int slsDetector::setPort(portType index, int num) { int fnum=F_SET_PORT, fnum2 = F_SET_RECEIVER_PORT; int retval; @@ -4912,13 +1914,15 @@ int slsDetector::setPort(portType index, int num){ retval=thisDetector->controlPort; #ifdef VERBOSE cout << "s="<< s<< endl; - cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort << endl; + cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort + << endl; #endif if (s==NULL) { #ifdef VERBOSE cout << "s=NULL"<< endl; - cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort << endl; + cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort + << endl; #endif setTCPSocket("",DEFAULT_PORTNO); } @@ -4927,7 +1931,8 @@ int slsDetector::setPort(portType index, int num){ } else { #ifdef VERBOSE cout << "still cannot connect!"<< endl; - cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort << endl; + cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort + << endl; #endif setTCPSocket("",retval); @@ -5012,13 +2017,13 @@ int slsDetector::setPort(portType index, int num){ } s->Disconnect(); }else{ - if (index == CONTROL_PORT){ - std::cout << "cannot connect to detector" << endl; - setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); - }else if (index == DATA_PORT){ - std::cout << "cannot connect to receiver" << endl; - setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); - } + if (index == CONTROL_PORT){ + std::cout << "cannot connect to detector" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); + }else if (index == DATA_PORT){ + std::cout << "cannot connect to receiver" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); + } } } } @@ -5094,14 +2099,383 @@ int slsDetector::setPort(portType index, int num){ #ifdef VERBOSE - cout << thisDetector->controlPort<< " " << thisDetector->receiverTCPPort << " " << thisDetector->stopPort << endl; + cout << thisDetector->controlPort<< " " << thisDetector->receiverTCPPort + << " " << thisDetector->stopPort << endl; #endif return retval; -}; +} + +int slsDetector::getControlPort() { + return thisDetector->controlPort; +} +int slsDetector::getStopPort() { + return thisDetector->stopPort; +} +int slsDetector::getReceiverPort() { + return thisDetector->receiverTCPPort; +} + + +int slsDetector::lockServer(int lock) { + int fnum=F_LOCK_SERVER; + int retval=-1; + int ret=OK; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&lock,sizeof(lock)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + +} + + +string slsDetector::getLastClientIP() { + + int fnum=F_GET_LAST_CLIENT_IP; + char clientName[INET_ADDRSTRLEN]; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(clientName,sizeof(clientName)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return string(clientName); + +} + + +int slsDetector::exitServer() { + + int retval; + int fnum=F_EXIT_SERVER; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + controlSocket->Connect(); + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + } + } + if (retval!=OK) { + std::cout<< std::endl; + std::cout<< "Shutting down the server" << std::endl; + std::cout<< std::endl; + } + return retval; + +} + + +int slsDetector::execCommand(string cmd, string answer) { + + char arg[MAX_STR_LENGTH], retval[MAX_STR_LENGTH]; + int fnum=F_EXEC_COMMAND; + + int ret=FAIL; + + strcpy(arg,cmd.c_str()); + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Sending command " << arg << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + if (controlSocket->SendDataOnly(&fnum,sizeof(fnum))>=0) { + if (controlSocket->SendDataOnly(arg,MAX_STR_LENGTH)>=0) { + if (controlSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH)>=0) { + ret=OK; + answer=retval; + } + } + } + disconnectControl(); + } +#ifdef VERBOSE + std::cout<< "Detector answer is " << answer << std::endl; +#endif + } + return ret; +} + + +int slsDetector::updateDetectorNoWait() { + + enum readOutFlags ro; + // int ret=OK; + enum detectorSettings t; + int thr, n = 0, nm; + // int it; + int64_t retval;// tns=-1; + char lastClientIP[INET_ADDRSTRLEN]; + + n += controlSocket->ReceiveDataOnly(lastClientIP,sizeof(lastClientIP)); +#ifdef VERBOSE + cout << "Updating detector last modified by " << lastClientIP << std::endl; +#endif + n += controlSocket->ReceiveDataOnly(&nm,sizeof(nm)); + thisDetector->nMod[X]=nm; + n += controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); + /// Should be overcome at a certain point! + + if (thisDetector->myDetectorType==MYTHEN) { + thisDetector->nModMax[X]=nm; + thisDetector->nModMax[Y]=1; + thisDetector->nModsMax=thisDetector->nModMax[Y]*thisDetector->nModMax[X]; + thisDetector->nMod[Y]=1; + } else { + thisDetector->nMod[Y]=nm; + } + + thisDetector->nMods=thisDetector->nMod[Y]*thisDetector->nMod[X]; + if (thisDetector->nModsMaxnMods) + thisDetector->nModsMax=thisDetector->nMods; + + if (thisDetector->nModMax[X]nMod[X]) + thisDetector->nModMax[X]=thisDetector->nMod[X]; + + if (thisDetector->nModMax[Y]nMod[Y]) + thisDetector->nModMax[Y]=thisDetector->nMod[Y]; + + n += controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); + thisDetector->dynamicRange=nm; + + n += controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); + thisDetector->dataBytes=nm; + + //t=setSettings(GET_SETTINGS); + n += controlSocket->ReceiveDataOnly( &t,sizeof(t)); + thisDetector->currentSettings=t; + + if((thisDetector->myDetectorType == EIGER) || + (thisDetector->myDetectorType == MYTHEN)){ + //thr=getThresholdEnergy(); + n += controlSocket->ReceiveDataOnly( &thr,sizeof(thr)); + thisDetector->currentThresholdEV=thr; + } + + //retval=setFrames(tns); + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[FRAME_NUMBER]=retval; + + // retval=setExposureTime(tns); + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[ACQUISITION_TIME]=retval; + + if(thisDetector->myDetectorType == EIGER){ + //retval=setSubFrameExposureTime(tns); + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME]=retval; + + //retval=setSubFramePeriod(tns); + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[SUBFRAME_PERIOD]=retval; + } + + //retval=setPeriod(tns); + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[FRAME_PERIOD]=retval; + + if(thisDetector->myDetectorType != EIGER) { + //retval=setDelay(tns); + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[DELAY_AFTER_TRIGGER]=retval; + } + + // retval=setGates(tns); + if ((thisDetector->myDetectorType != JUNGFRAU) && + (thisDetector->myDetectorType != EIGER)){ + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[GATES_NUMBER]=retval; + } + + //retval=setProbes(tns); + if (thisDetector->myDetectorType == MYTHEN){ + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[PROBES_NUMBER]=retval; + } + + //retval=setTrains(tns); + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[CYCLES_NUMBER]=retval; + + //retval=setProbes(tns); + if (thisDetector->myDetectorType == JUNGFRAUCTB){ + n += controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + if (retval>=0) + thisDetector->timerValue[SAMPLES_JCTB]=retval; + n += controlSocket->ReceiveDataOnly( &ro,sizeof(ro)); + + thisDetector->roFlags=ro; + + //retval=setProbes(tns); + getTotalNumberOfChannels(); + // thisDetector->dataBytes=getTotalNumberOfChannels()* + //thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; + } + + + if (!n) + printf("n: %d\n", n); + + return OK; + +} + + + + +int slsDetector::updateDetector() { + int fnum=F_UPDATE_CLIENT; + int ret=OK; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else + updateDetectorNoWait(); + disconnectControl(); + } + } + return ret; +} + + +int slsDetector::readConfigurationFile(string const fname) { + + + + string ans; + string str; + ifstream infile; + //char *args[1000]; + + string sargname, sargval; +#ifdef VERBOSE + int iline=0; + std::cout<< "config file name "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { +#ifdef VERBOSE + iline=readConfigurationFile(infile); +#else + readConfigurationFile(infile); +#endif + infile.close(); + } else { + std::cout<< "Error opening configuration file " << fname << + " for reading" << std::endl; + setErrorMask((getErrorMask())|(CONFIG_FILE)); + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Read configuration file of " << iline << " lines" << std::endl; +#endif + return OK; + +} + + +int slsDetector::readConfigurationFile(ifstream &infile) { + + + + + slsDetectorCommand *cmd=new slsDetectorCommand(this); + + string ans; + string str; + int iargval; + int interrupt=0; + char *args[100]; + char myargs[1000][1000]; + + string sargname, sargval; + int iline=0; + while (infile.good() and interrupt==0) { + sargname="none"; + sargval="0"; + getline(infile,str); + ++iline; +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + if (str.find('#')!=string::npos) { +#ifdef VERBOSE + std::cout<< "Line is a comment " << std::endl; + std::cout<< str << std::endl; +#endif + continue; + } else if (str.length()<2) { +#ifdef VERBOSE + std::cout<< "Empty line " << std::endl; +#endif + continue; + } else { + istringstream ssstr(str); + iargval=0; + while (ssstr.good()) { + ssstr >> sargname; + //if (ssstr.good()) { +#ifdef VERBOSE + std::cout<< iargval << " " << sargname << std::endl; +#endif + strcpy(myargs[iargval],sargname.c_str()); + args[iargval]=myargs[iargval]; + ++iargval; + //} + } + ans=cmd->executeLine(iargval,args,PUT_ACTION); +#ifdef VERBOSE + std::cout<< ans << std::endl; +#endif + } + ++iline; + } + delete cmd; + return OK; + +} @@ -5112,773 +2486,5250 @@ int slsDetector::setPort(portType index, int num){ +int slsDetector::writeConfigurationFile(string const fname) { + + ofstream outfile; +#ifdef VERBOSE + int ret; +#endif + outfile.open(fname.c_str(),ios_base::out); + if (outfile.is_open()) { +#ifdef VERBOSE + ret=writeConfigurationFile(outfile); +#else + writeConfigurationFile(outfile); +#endif + outfile.close(); + } + else { + std::cout<< "Error opening configuration file " << fname << + " for writing" << std::endl; + setErrorMask((getErrorMask())|(CONFIG_FILE)); + return FAIL; + } +#ifdef VERBOSE + std::cout<< "wrote " <myDetectorType; + string names[100]; + int nvar=0; + + // common config + names[nvar++] = "hostname"; + names[nvar++] = "port"; + names[nvar++] = "stopport"; + names[nvar++] = "settingsdir"; + names[nvar++] = "caldir"; + names[nvar++] = "ffdir"; + names[nvar++] = "outdir"; + names[nvar++] = "angdir"; + names[nvar++] = "moveflag"; + names[nvar++] = "lock"; + + // receiver config + if (type != MYTHEN) { + names[nvar++] = "detectormac"; + names[nvar++] = "detectorip"; + names[nvar++] = "zmqport"; + names[nvar++] = "rx_zmqport"; + names[nvar++] = "zmqip"; + names[nvar++] = "rx_zmqip"; + names[nvar++] = "rx_tcpport"; + names[nvar++] = "rx_udpport"; + names[nvar++] = "rx_udpport2"; + names[nvar++] = "rx_udpip"; + names[nvar++] = "rx_hostname"; + names[nvar++] = "r_readfreq"; + } + + // detector specific config + switch (type) { + case MYTHEN: + names[nvar++] = "nmod"; + names[nvar++] = "waitstates"; + names[nvar++] = "setlength"; + names[nvar++] = "clkdivider"; + names[nvar++] = "extsig"; + break; + case GOTTHARD: + case PROPIX: + names[nvar++] = "extsig"; + names[nvar++] = "vhighvoltage"; + break; + break; + case MOENCH: + names[nvar++] = "extsig"; + names[nvar++] = "vhighvoltage"; + break; + case EIGER: + names[nvar++] = "vhighvoltage"; + names[nvar++] = "trimen"; + names[nvar++] = "iodelay"; + names[nvar++] = "tengiga"; + break; + case JUNGFRAU: + names[nvar++] = "powerchip"; + names[nvar++] = "vhighvoltage"; + break; + case JUNGFRAUCTB: + names[nvar++] = "powerchip"; + names[nvar++] = "vhighvoltage"; + break; + default: + std::cout << "detector type " << + getDetectorType(thisDetector->myDetectorType) << " not implemented in " + "writing config file" << std::endl; + nvar = 0; + break; + } + + + + int nsig=4; + int iv=0; + char *args[100]; + char myargs[100][1000]; + + for (int ia=0; ia<100; ++ia) { + args[ia]=myargs[ia]; + } + + + for (iv=0; iv=0) + outfile << id << ":"; + + outfile << args[0] << " " << cmd->executeLine(1,args,GET_ACTION) + << std::endl; + } + } else { + strcpy(args[0],names[iv].c_str()); + if (id>=0) + outfile << id << ":"; + outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) + << std::endl; + } + } + + delete cmd; + return OK; +} + + + +string slsDetector::getSettingsFile() { + string s(thisDetector->settingsFile); + if (s.length()>6) { + if (s.substr(s.length()-6,3)==string(".sn") && s.substr(s.length()-3)!=string("xxx") ) + return s.substr(0,s.length()-6); + } + return string(thisDetector->settingsFile); +} + + +int slsDetector::writeSettingsFile(string fname, int imod, int iodelay, int tau) { + + return writeSettingsFile(fname,thisDetector->myDetectorType, detectorModules[imod], + iodelay, tau); + +} + +slsDetectorDefs::detectorSettings slsDetector::getSettings(int imod) { + + return sendSettingsOnly(GET_SETTINGS, imod); +} + + +slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings isettings, + int imod) { +#ifdef VERBOSE + std::cout<< "slsDetector setSettings " << isettings << std::endl; +#endif + + if (isettings == -1) + return getSettings(imod); + + detectorType detType = thisDetector->myDetectorType; + switch (detType) { + + // eiger: only set client shared memory variable for Eiger, + // settings threshold loads the module data (trimbits, dacs etc.) + case EIGER: + switch(isettings) { + case STANDARD: + case HIGHGAIN: + case LOWGAIN: + case VERYHIGHGAIN: + case VERYLOWGAIN: + thisDetector->currentSettings = isettings; + break; + default: + printf("Unknown settings %s for this detector!\n", + getDetectorSettings(isettings).c_str()); + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + break; + } + return thisDetector->currentSettings; + + // send only the settings, detector server will update dac values already in server + case GOTTHARD: + case PROPIX: + case JUNGFRAU: + case MOENCH: + return sendSettingsOnly(isettings); + break; + + // others send whole module to detector + default: + break; + } + + + + // MYTHEN ONLY (sends whole detector to module) + + sls_detector_module *myMod=createModule(); + int modmi=imod, modma=imod+1, im=imod; + string settingsfname, calfname; + string ssettings; + + //not included in module structure + int iodelay = -1; + int tau = -1; + int* gainval=0, *offsetval=0; + if(thisDetector->nGain) + gainval=new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval=new int[thisDetector->nOffset]; + + + switch (isettings) { + case STANDARD: + ssettings="/standard"; + thisDetector->currentSettings=STANDARD; + break; + case FAST: + ssettings="/fast"; + thisDetector->currentSettings=FAST; + break; + case HIGHGAIN: + ssettings="/highgain"; + thisDetector->currentSettings=HIGHGAIN; + break; + default: + break; + } + + + if (isettings != thisDetector->currentSettings) { + printf("Unknown settings %s for this detector!\n", + getDetectorSettings(isettings).c_str()); + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + }else{ + if (imod<0) { + modmi=0; + // modma=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; + modma=thisDetector->nMod[X]*thisDetector->nMod[Y]; + } + + for (im=modmi; immodule=im; + + std::cout << std::endl << "Loading settings for module:" << im << std::endl; + + //create file names + ostfn << thisDetector->settingsDir << ssettings <<"/noise.sn" + << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) + << setbase(10); + oscfn << thisDetector->calDir << ssettings << "/calibration.sn" + << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) + << setbase(10); + + + //settings file**** + settingsfname=ostfn.str(); +#ifdef VERBOSE + cout << "the settings file name is "<settingsDir << ssettings + << ssettings << ".trim"; + settingsfname=ostfn_default.str(); +#ifdef VERBOSE + cout << settingsfname << endl; +#endif + if (NULL == readSettingsFile(settingsfname,detType, iodelay, tau, + myMod)) { + //if default doesnt work, return error + std::cout << "Could not open settings file" << endl; + setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); + return thisDetector->currentSettings; + } + } + + + + //calibration file**** + int ret=0; + calfname=oscfn.str(); +#ifdef VERBOSE + cout << "Specific file:"<< calfname << endl; +#endif + //extra gain and offset + if(thisDetector->nGain) + ret = readCalibrationFile(calfname,gainval, offsetval); + //normal gain and offset inside sls_detector_module + else + ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); + + //if it didnt open, try default + if(ret != OK){ + ostringstream oscfn_default; + oscfn_default << thisDetector->calDir << ssettings << ssettings << ".cal"; + calfname=oscfn_default.str(); +#ifdef VERBOSE + cout << "Default file:" << calfname << endl; +#endif + //extra gain and offset + if(thisDetector->nGain) + ret = readCalibrationFile(calfname,gainval, offsetval); + //normal gain and offset inside sls_detector_module + else + ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); + } + //if default doesnt work, return error + if(ret != OK){ + std::cout << "Could not open calibration file" << calfname << endl; + setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); + return thisDetector->currentSettings; + } + + + //if everything worked, set module**** + setModule(*myMod,iodelay,tau,-1,gainval,offsetval); + } + } + + + + deleteModule(myMod); + if(gainval) delete [] gainval; + if(offsetval) delete [] offsetval; + + if (thisDetector->correctionMask&(1<-1 && isett<3) { + thisDetector->tDead=t[isett]; + } + } + + + if (getSettings(imod) != isettings){ + std::cout << "Could not set settings" << endl; + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + } + + return thisDetector->currentSettings; +} + + + +slsDetectorDefs::detectorSettings slsDetector::sendSettingsOnly(detectorSettings isettings, + int imod) { + int fnum = F_SET_SETTINGS; + int ret = FAIL; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); + int retval = -1; + int arg[2]; + arg[0] = isettings; + arg[1] = imod; +#ifdef VERBOSE + std::cout<< "Setting settings of module " << arg[1] << " to " << arg[0] << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + } else{ + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentSettings = (detectorSettings)retval; +#ifdef VERBOSE + std::cout<< "Settings are " << retval << std::endl; +#endif + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return thisDetector->currentSettings; +} + + + +int slsDetector::getThresholdEnergy(int imod) { + + int fnum= F_GET_THRESHOLD_ENERGY; + int retval; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; +#ifdef VERBOSE + std::cout<< "Getting threshold energy "<< std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + std::cout<< "Detector returned error: "<< std::endl; + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentThresholdEV=retval; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return thisDetector->currentThresholdEV; +} + +int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isettings, int tb) { + + //currently only for eiger + if (thisDetector->myDetectorType == EIGER) { + setThresholdEnergyAndSettings(e_eV,isettings,tb); + return thisDetector->currentThresholdEV; + } + + int fnum= F_SET_THRESHOLD_ENERGY; + int retval; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; +#ifdef VERBOSE + std::cout<< "Setting threshold energy "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&e_eV,sizeof(e_eV)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->SendDataOnly(&isettings,sizeof(isettings)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + std::cout<< "Detector returned error: "<< std::endl; + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< mess << std::endl; + } else { +#ifdef VERBOSE + std::cout<< "Detector returned OK "<< std::endl; +#endif + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentThresholdEV=retval; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + thisDetector->currentThresholdEV=e_eV; + } + return thisDetector->currentThresholdEV; +} + + + +int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb) { + + //if settings provided, use that, else use the shared memory variable + detectorSettings is = ((isettings != GET_SETTINGS) ? isettings: + thisDetector->currentSettings); + string ssettings; + switch (is) { + case STANDARD: + ssettings="/standard"; + thisDetector->currentSettings=STANDARD; + break; + case HIGHGAIN: + ssettings="/highgain"; + thisDetector->currentSettings=HIGHGAIN; + break; + case LOWGAIN: + ssettings="/lowgain"; + thisDetector->currentSettings=LOWGAIN; + break; + case VERYHIGHGAIN: + ssettings="/veryhighgain"; + thisDetector->currentSettings=VERYHIGHGAIN; + break; + case VERYLOWGAIN: + ssettings="/verylowgain"; + thisDetector->currentSettings=VERYLOWGAIN; + break; + default: + printf("Error: Unknown settings %s for this detector!\n", + getDetectorSettings(is).c_str()); + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + return FAIL; + } + + //verify e_eV exists in trimEneregies[] + if (!thisDetector->nTrimEn || + (e_eV < thisDetector->trimEnergies[0]) || + (e_eV > thisDetector->trimEnergies[thisDetector->nTrimEn-1]) ) { + printf("Error: This energy %d not defined for this module!\n", e_eV); + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + return FAIL; + } + + //find if interpolation required + bool interpolate = true; + for (int i = 0; i < thisDetector->nTrimEn; ++i) { + if (thisDetector->trimEnergies[i] == e_eV) { + interpolate = false; + break; + } + } + + //fill detector module structure + sls_detector_module *myMod = NULL; + int iodelay = -1; //not included in the module + int tau = -1; //not included in the module + + //normal + if(!interpolate) { + //find their directory names + ostringstream ostfn; + ostfn << thisDetector->settingsDir << ssettings << "/" << e_eV << "eV" + << "/noise.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); + string settingsfname = ostfn.str(); +#ifdef VERBOSE + printf("Settings File is %s\n", settingsfname.c_str()); +#endif + //read the files + myMod=createModule(); + if (NULL == readSettingsFile(settingsfname,thisDetector->myDetectorType, + iodelay, tau, myMod, tb)) { + if(myMod)deleteModule(myMod); + return FAIL; + } + } + + + //interpolate + else { + //find the trim values + int trim1 = -1, trim2 = -1; + for (int i = 0; i < thisDetector->nTrimEn; ++i) { + if (e_eV < thisDetector->trimEnergies[i]) { + trim2 = thisDetector->trimEnergies[i]; + trim1 = thisDetector->trimEnergies[i-1]; + break; + } + } + //find their directory names + ostringstream ostfn; + ostfn << thisDetector->settingsDir << ssettings << "/" << trim1 << "eV" + << "/noise.sn" << setfill('0') << setw(3) << dec << + getId(DETECTOR_SERIAL_NUMBER) << setbase(10); + string settingsfname1 = ostfn.str(); + ostfn.str(""); ostfn.clear(); + ostfn << thisDetector->settingsDir << ssettings << "/" << trim2 << "eV" + << "/noise.sn" << setfill('0') << setw(3) << dec << + getId(DETECTOR_SERIAL_NUMBER) << setbase(10); + string settingsfname2 = ostfn.str(); + //read the files +#ifdef VERBOSE + printf("Settings Files are %s and %s\n",settingsfname1.c_str(), + settingsfname2.c_str()); +#endif + sls_detector_module *myMod1=createModule(); + sls_detector_module *myMod2=createModule(); + int iodelay1 = -1; //not included in the module + int tau1 = -1; //not included in the module + int iodelay2 = -1; //not included in the module + int tau2 = -1; //not included in the module + if (NULL == readSettingsFile(settingsfname1,thisDetector->myDetectorType, + iodelay1, tau1, myMod1, tb)) { + setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); + deleteModule(myMod1); + deleteModule(myMod2); + return FAIL; + } + if (NULL == readSettingsFile(settingsfname2,thisDetector->myDetectorType, + iodelay2, tau2, myMod2, tb)) { + setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); + deleteModule(myMod1); + deleteModule(myMod2); + return FAIL; + } + if (iodelay1 != iodelay2) { + printf("iodelays do not match between files\n"); + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + deleteModule(myMod1); + deleteModule(myMod2); + return FAIL; + } + iodelay = iodelay1; + + //interpolate module + myMod = interpolateTrim(thisDetector->myDetectorType, myMod1, myMod2, + e_eV, trim1, trim2, tb); + if (myMod == NULL) { + printf("Could not interpolate, different dac values in files\n"); + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + deleteModule(myMod1); + deleteModule(myMod2); + return FAIL; + } + //interpolate tau + tau = linearInterpolation(e_eV, trim1, trim2, tau1, tau2); + //printf("new tau:%d\n",tau); + + deleteModule(myMod1); + deleteModule(myMod2); + } + + + myMod->module=0; + myMod->reg=thisDetector->currentSettings; + setModule(*myMod, iodelay, tau, e_eV, 0, 0, tb); + deleteModule(myMod); + if (getSettings(-1) != is){ + std::cout << "Could not set settings in detector" << endl; + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + return FAIL; + } + + return OK; +} + + + + +string slsDetector::getSettingsDir() { + return std::string(thisDetector->settingsDir); +} +string slsDetector::setSettingsDir(string s) { + sprintf(thisDetector->settingsDir, s.c_str()); return thisDetector->settingsDir; +} +string slsDetector::getCalDir() { + return thisDetector->calDir; +} +string slsDetector::setCalDir(string s) { + sprintf(thisDetector->calDir, s.c_str()); return thisDetector->calDir; +} + + + + + +int slsDetector::loadSettingsFile(string fname, int imod) { + + sls_detector_module *myMod=NULL; + + int iodelay = -1; + int tau = -1; + + string fn=fname; + fn=fname; + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType) { + case MYTHEN: + if (fname.find(".sn")==string::npos && fname.find(".trim")== + string::npos && fname.find(".settings")==string::npos) { + ostfn << ".sn" << setfill('0') << setw(3) << hex << + getId(MODULE_SERIAL_NUMBER, im); + } + break; + case EIGER: + if (fname.find(".sn")==string::npos && fname.find(".trim")== + string::npos && fname.find(".settings")==string::npos) { + ostfn << ".sn" << setfill('0') << setw(3) << dec << + getId(DETECTOR_SERIAL_NUMBER, im); + } + break; + default: + break; + } + fn=ostfn.str(); + myMod=readSettingsFile(fn, thisDetector->myDetectorType,iodelay, tau, myMod); + + if (myMod) { + myMod->module=im; + //settings is saved in myMod.reg for all except mythen + if(thisDetector->myDetectorType!=MYTHEN) + myMod->reg=-1; + setModule(*myMod,iodelay,tau,-1,0,0); + deleteModule(myMod); + } else + return FAIL; + } + return OK; +} + + +int slsDetector::saveSettingsFile(string fname, int imod) { + + sls_detector_module *myMod=NULL; + int ret=FAIL; + int iodelay = -1; + int tau = -1; + + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType) { + case MYTHEN: + ostfn << ".sn" << setfill('0') << setw(3) << hex << + getId(MODULE_SERIAL_NUMBER,im); + break; + case EIGER: + ostfn << ".sn" << setfill('0') << setw(3) << dec << + getId(DETECTOR_SERIAL_NUMBER); + break; + default: + break; + } + fn=ostfn.str(); + if ((myMod=getModule(im))) { + + if(thisDetector->myDetectorType == EIGER){ + iodelay = (int)setDAC((dacs_t)-1,IO_DELAY,0,-1); + tau = (int64_t)getRateCorrectionTau(); + } + ret=writeSettingsFile(fn, thisDetector->myDetectorType, *myMod, + iodelay, tau); + deleteModule(myMod); + } + } + return ret; +} + + + + +int slsDetector::loadCalibrationFile(string fname, int imod) { + + if(thisDetector->myDetectorType == EIGER) { + std::cout << "Not required for this detector!" << std::endl; + return FAIL; + } + + sls_detector_module *myMod=NULL; + string fn=fname; + + int* gainval=0; int* offsetval=0; + if(thisDetector->nGain){ + gainval=new int[thisDetector->nGain]; + for(int i=0;inGain;++i) + gainval[i] = -1; + } + if(thisDetector->nOffset){ + offsetval=new int[thisDetector->nOffset]; + for(int i=0;inOffset;++i) + offsetval[i] = -1; + } + + fn=fname; + + + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType) { + case MYTHEN: + if (fname.find(".sn")==string::npos && fname.find(".cal")==string::npos) { + ostfn << ".sn" << setfill('0') << setw(3) << hex << + getId(MODULE_SERIAL_NUMBER, im); + } + break; + case EIGER: + if (fname.find(".sn")==string::npos && fname.find(".cal")==string::npos) { + ostfn << "." << setfill('0') << setw(3) << dec << + getId(DETECTOR_SERIAL_NUMBER); + } + break; + default: + break; + } + fn=ostfn.str(); + if((myMod=getModule(im))){ + //extra gain and offset + if(thisDetector->nGain){ + if(readCalibrationFile(fn, gainval, offsetval)==FAIL) + return FAIL; + } //normal gain and offset inside sls_detector_module + else{ + if(readCalibrationFile(fn,myMod->gain, myMod->offset)==FAIL) + return FAIL; + } + setModule(*myMod,-1,-1,-1,gainval,offsetval); + + deleteModule(myMod); + if(gainval) delete[]gainval; + if(offsetval) delete[] offsetval; + } else + return FAIL; + } + return OK; +} + + +int slsDetector::saveCalibrationFile(string fname, int imod) { + + + sls_detector_module *myMod=NULL; + int ret=FAIL; + + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType) { + case MYTHEN: + ostfn << ".sn" << setfill('0') << setw(3) << hex << + getId(MODULE_SERIAL_NUMBER,im); + break; + case EIGER: + ostfn << ".sn" << setfill('0') << setw(3) << dec << + getId(DETECTOR_SERIAL_NUMBER); + break; + default: + break; + } + fn=ostfn.str(); + if ((myMod=getModule(im))) { + //extra gain and offset + if(thisDetector->nGain) + ret=writeCalibrationFile(fn,gain, offset); + //normal gain and offset inside sls_detector_module + else + ret=writeCalibrationFile(fn,myMod->gain, myMod->offset); + + deleteModule(myMod); + }else + return FAIL; + } + return ret; +} + + + + +slsDetectorDefs::masterFlags slsDetector::setMaster(masterFlags flag) { + + + int fnum=F_SET_MASTER; + masterFlags retval=GET_MASTER; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting master flags to "<< flag << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&flag,sizeof(flag)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + +#ifdef VERBOSE + std::cout<< "Master flag set to "<< retval << std::endl; +#endif + return retval; +} + + + + +slsDetectorDefs::synchronizationMode slsDetector::setSynchronization(synchronizationMode flag) { + + + + int fnum=F_SET_SYNCHRONIZATION_MODE; + synchronizationMode retval=GET_SYNCHRONIZATION_MODE; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting synchronization mode to "<< flag << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&flag,sizeof(flag)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + +#ifdef VERBOSE + std::cout<< "Readout flag set to "<< retval << std::endl; +#endif + return retval; + +} + int slsDetector::setTotalProgress() { - int nf=1, npos=1, nscan[MAX_SCAN_LEVELS]={1,1}, nc=1, nm=1; + int nf=1, npos=1, nscan[MAX_SCAN_LEVELS]={1,1}, nc=1, nm=1, ns=1; - if (thisDetector->timerValue[FRAME_NUMBER]) - nf=thisDetector->timerValue[FRAME_NUMBER]; + if (thisDetector->timerValue[FRAME_NUMBER]) + nf=thisDetector->timerValue[FRAME_NUMBER]; - if (thisDetector->timerValue[CYCLES_NUMBER]>0) - nc=thisDetector->timerValue[CYCLES_NUMBER]; + if (thisDetector->timerValue[CYCLES_NUMBER]>0) + nc=thisDetector->timerValue[CYCLES_NUMBER]; - if (thisDetector->numberOfPositions>0) - npos=thisDetector->numberOfPositions; + if (thisDetector->timerValue[STORAGE_CELL_NUMBER]>0) + ns=thisDetector->timerValue[STORAGE_CELL_NUMBER]+1; - if (timerValue[MEASUREMENTS_NUMBER]>0) - nm=timerValue[MEASUREMENTS_NUMBER]; + if (thisDetector->numberOfPositions>0) + npos=thisDetector->numberOfPositions; + + if (timerValue[MEASUREMENTS_NUMBER]>0) + nm=timerValue[MEASUREMENTS_NUMBER]; - if ((thisDetector->nScanSteps[0]>0) && (thisDetector->actionMask & (1 << MAX_ACTIONS))) - nscan[0]=thisDetector->nScanSteps[0]; + if ((thisDetector->nScanSteps[0]>0) && (thisDetector->actionMask & + (1 << MAX_ACTIONS))) + nscan[0]=thisDetector->nScanSteps[0]; - if ((thisDetector->nScanSteps[1]>0) && (thisDetector->actionMask & (1 << (MAX_ACTIONS+1)))) - nscan[1]=thisDetector->nScanSteps[1]; + if ((thisDetector->nScanSteps[1]>0) && (thisDetector->actionMask & + (1 << (MAX_ACTIONS+1)))) + nscan[1]=thisDetector->nScanSteps[1]; - thisDetector->totalProgress=nf*nc*npos*nm*nscan[0]*nscan[1]; + thisDetector->totalProgress=nf*nc*ns*npos*nm*nscan[0]*nscan[1]; #ifdef VERBOSE - cout << "nc " << nc << endl; - cout << "nm " << nm << endl; - cout << "nf " << nf << endl; - cout << "npos " << npos << endl; - cout << "nscan[0] " << nscan[0] << endl; - cout << "nscan[1] " << nscan[1] << endl; +cout << "nc " << nc << endl; +cout << "nm " << nm << endl; +cout << "nf " << nf << endl; +cout << "ns " << ns << endl; +cout << "npos " << npos << endl; +cout << "nscan[0] " << nscan[0] << endl; +cout << "nscan[1] " << nscan[1] << endl; - cout << "Set total progress " << thisDetector->totalProgress << endl; +cout << "Set total progress " << thisDetector->totalProgress << endl; #endif - return thisDetector->totalProgress; +return thisDetector->totalProgress; } - double slsDetector::getCurrentProgress() { - return 100.*((double)thisDetector->progressIndex)/((double)thisDetector->totalProgress); + return 100.*((double)thisDetector->progressIndex)/((double)thisDetector->totalProgress); +} + + + +slsDetectorDefs::runStatus slsDetector::getRunStatus() { + int fnum=F_GET_RUN_STATUS; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + strcpy(mess,"could not get run status"); + runStatus retval=ERROR; +#ifdef VERBOSE + std::cout<< "Getting status "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + + //cout << "________:::____________" << ret << endl; + + if (ret==FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + //cout << "____________________" << retval << endl; + } + disconnectStop(); + } + } + } + return retval; + + +} + + +int slsDetector::prepareAcquisition() { + int fnum = F_PREPARE_ACQUISITION; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Preparing Detector for Acquisition" << std::endl; +#endif + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PREPARE_ACQUISITION)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + }else + std::cout << "cannot connect to detector" << endl; + + return ret; +} + +int slsDetector::cleanupAcquisition() { + int fnum = F_CLEANUP_ACQUISITION; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Cleaning up Detector after Acquisition " << std::endl; +#endif + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(CLEANUP_ACQUISITION)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + }else + std::cout << "cannot connect to detector" << endl; + + return ret; + +} + + + +int slsDetector::startAcquisition() { + + + int fnum=F_START_ACQUISITION; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Starting acquisition "<< std::endl; +#endif + thisDetector->stoppedFlag=0; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return ret; + + + +} + + +int slsDetector::stopAcquisition() { + + // get status before stopping acquisition + runStatus s = ERROR, r = ERROR; + if (thisDetector->receiver_upstream) { + s = getRunStatus(); + r = getReceiverStatus(); + } + + int fnum=F_STOP_ACQUISITION; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Stopping acquisition "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectStop(); + } + } + } + thisDetector->stoppedFlag=1; + + // if rxr streaming and acquisition finished, restream dummy stop packet + if ((thisDetector->receiver_upstream) && (s == IDLE) && (r == IDLE)) { + restreamStopFromReceiver(); + } + + return ret; + + +} + +int slsDetector::startReadOut() { + + int fnum=F_START_READOUT; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Starting readout "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return ret; +} + + + +int* slsDetector::startAndReadAll() { + //cout << "Start and read all "<< endl; + + int* retval; + //#ifdef VERBOSE +#ifdef VERBOSE + int i=0; +#endif + //#endif + if(thisDetector->myDetectorType == EIGER) { + if (prepareAcquisition() == FAIL) + return NULL; + } + startAndReadAllNoWait(); + //#ifdef VERBOSE + // std::cout<< "started" << std::endl; + //#endif + while ((retval=getDataFromDetector())){ +#ifdef VERBOSE + ++i; + std::cout<< i << std::endl; + //#else + //std::cout<< "-" << flush; +#endif + dataQueue.push(retval); + + //std::cout<< "pushed" << std::endl; + } + disconnectControl(); + +#ifdef VERBOSE + std::cout<< "received "<< i<< " frames" << std::endl; + //#else + // std::cout << std::endl; +#endif + return dataQueue.front(); // check what we return! + /* while ((retval=getDataFromDetectorNoWait())) + ++i; + #ifdef VERBOSE + std::cout<< "Received " << i << " frames"<< std::endl; + #endif + return dataQueue.front(); // check what we return! + */ + +} + + + +int slsDetector::startAndReadAllNoWait() { + + int fnum= F_START_AND_READ_ALL; + +#ifdef VERBOSE + std::cout<< "Starting and reading all frames "<< std::endl; +#endif + thisDetector->stoppedFlag=0; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + //std::cout<< "connected" << std::endl; + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + return OK; + } + } + return FAIL; } +int* slsDetector::getDataFromDetector(int *retval) { + int ret=FAIL; + char mess[MAX_STR_LENGTH]="Nothing"; + int nel=thisDetector->dataBytes/sizeof(int); + int n; + int *r=retval; + + int nodatadetectortype = false; + detectorType types = getDetectorsType(); + if(types == EIGER || types == JUNGFRAU){ + nodatadetectortype = true; + } + + + if (!nodatadetectortype && retval==NULL) + retval=new int[nel]; + + +#ifdef VERBOSE + std::cout<< "getting data "<< thisDetector->dataBytes << " " << nel<< std::endl; +#endif + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); +#ifdef VERBOSE + cout << "ret=" << ret << endl; +#endif + + if (ret!=OK) { + n= controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + // if(thisDetector->receiverOnlineFlag == OFFLINE_FLAG) + if (ret==FAIL) { + thisDetector->stoppedFlag=1; + std::cout<< "Detector returned: " << mess << " " << n << std::endl; + } else { + ; +#ifdef VERBOSE + std::cout<< "Detector successfully returned: " << mess << " " << n + << std::endl; +#endif + } + if ((!nodatadetectortype) && (r==NULL)){ + delete [] retval; + } + return NULL; + } else if (!nodatadetectortype){ + + n=controlSocket->ReceiveDataOnly(retval,thisDetector->dataBytes); + +#ifdef VERBOSE + std::cout<< "Received "<< n << " data bytes" << std::endl; +#endif + if (n!=thisDetector->dataBytes) { + std::cout<< "wrong data size received from detector: received " << + n << " but expected " << thisDetector->dataBytes << std::endl; + thisDetector->stoppedFlag=1; + ret=FAIL; + if (r==NULL) { + delete [] retval; + } + return NULL; + } + // for (int ib=0; ibdataBytes/8; ++ib) + // cout << ((*(((u_int64_t*)retval)+ib))>>17&1) ; + + + } + // cout << "get data returning " << endl; + // cout << endl; + return retval; + +} + + + +int* slsDetector::readFrame() { + + int fnum=F_READ_FRAME; + int* retval=NULL; + +#ifdef VERBOSE + std::cout<< "slsDetector: Reading frame "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + retval=getDataFromDetector(); + if (retval) { + dataQueue.push(retval); + disconnectControl(); + } + } + } + return retval; +} +int* slsDetector::readAll() { + + int fnum=F_READ_ALL; + int* retval; // check what we return! + +#ifdef VERBOSE + int i=0; + std::cout<< "Reading all frames "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + + while ((retval=getDataFromDetector())){ +#ifdef VERBOSE + ++i; + std::cout<< i << std::endl; +#endif + dataQueue.push(retval); + } + disconnectControl(); + } + } +#ifdef VERBOSE + std::cout<< "received "<< i<< " frames" << std::endl; +#endif + return dataQueue.front(); // check what we return! + +} + + +int slsDetector::readAllNoWait() { + + int fnum= F_READ_ALL; + +#ifdef VERBOSE + std::cout<< "Reading all frames "<< std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + return OK; + } + } + return FAIL; +} + + + +int slsDetector::configureMAC() { + int i; + int ret=FAIL; + int fnum=F_CONFIGURE_MAC,fnum2=F_RECEIVER_SHORT_FRAME; + char mess[MAX_STR_LENGTH]=""; + char arg[6][50];memset(arg,0,sizeof(char)*6*50); + int retval=-1; + + // to send 3d positions to detector + bool sendpos = 0; + int pos[3]={0,0,0}; + + // only jungfrau and eiger, send x, y and z in detector udp header + if (thisDetector->myDetectorType == JUNGFRAU || + thisDetector->myDetectorType == EIGER) { + sendpos = true; + int max = multiDet->getNumberOfDetectors(X); + if(!detId) { + pos[0] = 0; + pos[1] = 0; + } else { + pos[1] = detId / max; + pos[0] = (detId % max) * ((thisDetector->myDetectorType == EIGER) ? 2 : 1); // for horiz. udp ports + } + } +#ifdef VERBOSE + cout << "SLS [" << detId << "] - (" << pos[0] << "," << pos[1] << "," << + pos[2] << ")" << endl; +#endif + + + //if udpip wasnt initialized in config file + if(!(strcmp(thisDetector->receiverUDPIP,"none"))){ + //hostname is an ip address + if(strchr(thisDetector->receiver_hostname,'.')!=NULL) + strcpy(thisDetector->receiverUDPIP,thisDetector->receiver_hostname); + //if hostname not ip, convert it to ip + else{ + struct addrinfo *result; + if (!dataSocket->ConvertHostnameToInternetAddress( + thisDetector->receiver_hostname, &result)) { + // on success + memset(thisDetector->receiverUDPIP, 0, MAX_STR_LENGTH); + // on failure, back to none + if (dataSocket->ConvertInternetAddresstoIpString(result, + thisDetector->receiverUDPIP, MAX_STR_LENGTH)) { + strcpy(thisDetector->receiverUDPIP, "none"); + } + } + } + } + strcpy(arg[0],thisDetector->receiverUDPIP); + strcpy(arg[1],thisDetector->receiverUDPMAC); + sprintf(arg[2],"%x",thisDetector->receiverUDPPort); + strcpy(arg[3],thisDetector->detectorMAC); + strcpy(arg[4],thisDetector->detectorIP); + sprintf(arg[5],"%x",thisDetector->receiverUDPPort2); +#ifdef VERBOSE + std::cout<< "Configuring MAC"<< std::endl; +#endif + + + + for(i=0;i<2;++i){ + if(!strcmp(arg[i],"none")){ + std::cout<< "Configure MAC Error. IP/MAC Addresses not set"<< std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + return FAIL; + } + } + +#ifdef VERBOSE + std::cout<< "IP/MAC Addresses valid "<< std::endl; +#endif + + + { + //converting IPaddress to hex + stringstream ss(arg[0]); + char cword[50]=""; + bzero(cword, 50); + string s; + while (getline(ss, s, '.')) { + sprintf(cword,"%s%02x",cword,atoi(s.c_str())); + } + bzero(arg[0], 50); + strcpy(arg[0],cword); +#ifdef VERBOSE + std::cout<<"receiver udp ip:"<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + if(sendpos) + controlSocket->SendDataOnly(pos,sizeof(pos)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + } + else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (thisDetector->myDetectorType == EIGER) { + //rewrite detectormac, detector ip + char arg[2][50]; + memset(arg,0,sizeof(arg)); + uint64_t idetectormac = 0; + uint32_t idetectorip = 0; + controlSocket->ReceiveDataOnly(arg,sizeof(arg)); + sscanf(arg[0], "%lx", &idetectormac); + sscanf(arg[1], "%x", &idetectorip); + sprintf(arg[0],"%02x:%02x:%02x:%02x:%02x:%02x", + (unsigned int)((idetectormac>>40)&0xFF), + (unsigned int)((idetectormac>>32)&0xFF), + (unsigned int)((idetectormac>>24)&0xFF), + (unsigned int)((idetectormac>>16)&0xFF), + (unsigned int)((idetectormac>>8)&0xFF), + (unsigned int)((idetectormac>>0)&0xFF)); + sprintf(arg[1],"%d.%d.%d.%d", + (idetectorip>>24)&0xff, + (idetectorip>>16)&0xff, + (idetectorip>>8)&0xff, + (idetectorip)&0xff); + if (strcasecmp(arg[0],thisDetector->detectorMAC)) { + memset(thisDetector->detectorMAC, 0, MAX_STR_LENGTH); + strcpy(thisDetector->detectorMAC, arg[0]); + cprintf(RESET,"%d: Detector MAC updated to %s\n", detId, + thisDetector->detectorMAC); + } + if (strcasecmp(arg[1],thisDetector->detectorIP)) { + memset(thisDetector->detectorIP, 0, MAX_STR_LENGTH); + strcpy(thisDetector->detectorIP, arg[1]); + cprintf(RESET,"%d: Detector IP updated to %s\n", detId, + thisDetector->detectorIP); + } + } + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + if (ret==FAIL) { + ret=FAIL; + std::cout<< "Configuring MAC failed " << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + } + else if (thisDetector->myDetectorType==GOTTHARD){ + //set frames per file - only for gotthard + pthread_mutex_lock(&ms); + if(retval==-1) + setFramesPerFile(MAX_FRAMES_PER_FILE); + else + setFramesPerFile(SHORT_MAX_FRAMES_PER_FILE); + pthread_mutex_unlock(&ms); + //connect to receiver + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending adc val to receiver " << retval << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum2,retval,retval); + disconnectData(); + } + if(ret==FAIL) + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + } + } + + return ret; +} +int64_t slsDetector::setTimer(timerIndex index, int64_t t, int imod) { + + + int fnum=F_SET_TIMER,fnum2=F_SET_RECEIVER_TIMER; + int64_t retval = -1; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + + if (index!=MEASUREMENTS_NUMBER) { + + +#ifdef VERBOSE + std::cout<< "Setting timer "<< index << " to " << t << "ns/value" << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&index,sizeof(index)); + controlSocket->SendDataOnly(&t,sizeof(t)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_TIMER_VALUE_NOT_SET)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->timerValue[index]=retval; + } + disconnectControl(); + if (ret==FORCE_UPDATE) { + updateDetector(); +#ifdef VERBOSE + std::cout<< "Updated!" << std::endl; +#endif + + } + } + } else { + //std::cout<< "offline " << std::endl; + if (t>=0) + thisDetector->timerValue[index]=t; + if((thisDetector->myDetectorType==GOTTHARD)|| + (thisDetector->myDetectorType==PROPIX)|| + (thisDetector->myDetectorType==JUNGFRAU)|| + (thisDetector->myDetectorType==MOENCH)) + thisDetector->timerValue[PROBES_NUMBER]=0; + if(thisDetector->myDetectorType==JUNGFRAUCTB && index==SAMPLES_JCTB) { + getTotalNumberOfChannels(); + // thisDetector->dataBytes=getTotalNumberOfChannels()* + //thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; + } + + } + } else { + if (t>=0) + thisDetector->timerValue[index]=t; + } +#ifdef VERBOSE + std::cout<< "Timer " << index << " set to "<< thisDetector->timerValue[index] + << "ns" << std::endl; +#endif + + if ((thisDetector->myDetectorType==MYTHEN)&&(index==PROBES_NUMBER)) { + setDynamicRange(); + //cout << "Changing probes: data size = " << thisDetector->dataBytes <myDetectorType==JUNGFRAUCTB) && (index==SAMPLES_JCTB)) { + setDynamicRange(); + cout << "Changing samples: data size = " << thisDetector->dataBytes <myDetectorType==MYTHEN)&&(index==PROBES_NUMBER)) { + setDynamicRange(); + //cout << "Changing probes: data size = " << thisDetector->dataBytes <myDetectorType == EIGER) && + getRateCorrection(r) && + (t>=0) && + + (((index == SUBFRAME_ACQUISITION_TIME) && + (thisDetector->dynamicRange == 32))|| + ((index == ACQUISITION_TIME) && + (thisDetector->dynamicRange == 16))) + + && (t>=0) && getRateCorrection(r)){ + setRateCorrection(r); + } + } -/* - important speed parameters - enum speedVariable { - CLOCK_DIVIDER, - WAIT_STATES, - SET_SIGNAL_LENGTH - }; -*/ + //send acquisiton time/period/subexptime/frame/cycles/samples to receiver + if((index==FRAME_NUMBER)||(index==FRAME_PERIOD)||(index==CYCLES_NUMBER)|| + (index==ACQUISITION_TIME) || (index==SUBFRAME_ACQUISITION_TIME) || + (index==SUBFRAME_PERIOD) || + (index==SAMPLES_JCTB) || (index==STORAGE_CELL_NUMBER)){ + string timername = getTimerType(index); + if(ret != FAIL){ + int64_t args[2]; + retval = -1; + args[0] = index; + args[1] = thisDetector->timerValue[index]; + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ + + //set #frames * #cycles + if((index==FRAME_NUMBER)||(index==CYCLES_NUMBER)|| + (index==STORAGE_CELL_NUMBER)){ + timername.assign("(Number of Frames) * (Number of cycles) " + "* (Number of storage cells)"); + args[1] = thisDetector->timerValue[FRAME_NUMBER] * + ((thisDetector->timerValue[CYCLES_NUMBER] > 0) ? + (thisDetector->timerValue[CYCLES_NUMBER]) : 1) * + ((thisDetector->timerValue[STORAGE_CELL_NUMBER] > 0) + ? (thisDetector->timerValue[STORAGE_CELL_NUMBER])+1 : 1); +#ifdef VERBOSE + std::cout << "Setting/Getting " << timername << " " << index + <<" to/from receiver " << args[1] << std::endl; +#endif + } +#ifdef VERBOSE + // set period/exptime/subexptime/subperiod + else std::cout << "Setting/Getting " << timername << " " << index + << " to/from receiver " << args[1] << std::endl; +#endif + + char mess[MAX_STR_LENGTH]=""; + if (connectData() == OK){ + ret=thisReceiver->sendIntArray(fnum2,retval,args,mess); + disconnectData(); + } + if((args[1] != retval)|| (ret==FAIL)){ + ret = FAIL; + cout << "ERROR: " << timername << " in receiver set incorrectly to " + << retval << " instead of " << args[1] << endl; + + if(strstr(mess,"receiver is not idle")==NULL) { + switch(index) { + case ACQUISITION_TIME: + setErrorMask((getErrorMask())|(RECEIVER_ACQ_TIME_NOT_SET)); + break; + case FRAME_PERIOD: + setErrorMask((getErrorMask())|(RECEIVER_ACQ_PERIOD_NOT_SET)); + break; + case SUBFRAME_ACQUISITION_TIME: + case SUBFRAME_PERIOD: + case SAMPLES_JCTB: + setErrorMask((getErrorMask())|(RECEIVER_TIMER_NOT_SET)); + break; + default: + setErrorMask((getErrorMask())|(RECEIVER_FRAME_NUM_NOT_SET)); + break; + } + } + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + } + } + return thisDetector->timerValue[index]; +} + + + +int64_t slsDetector::getTimeLeft(timerIndex index) { + + + int fnum=F_GET_TIME_LEFT; + int64_t retval; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Getting timer "<< index << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&index,sizeof(index)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectStop(); + } + } + } +#ifdef VERBOSE + std::cout<< "Time left is "<< retval << std::endl; +#endif + return retval; + +} + + int slsDetector::setSpeed(speedVariable sp, int value) { - int fnum=F_SET_SPEED; - int retval=-1; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; + int fnum=F_SET_SPEED; + int retval=-1; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; #ifdef VERBOSE - std::cout<< "Setting speed variable"<< sp << " to " << value << std::endl; + std::cout<< "Setting speed variable"<< sp << " to " << value << std::endl; #endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&sp,sizeof(sp)); - controlSocket->SendDataOnly(&value,sizeof(value)); + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&sp,sizeof(sp)); + controlSocket->SendDataOnly(&value,sizeof(value)); #ifdef VERBOSE - std::cout<< "Sent "<< n << " bytes " << std::endl; + std::cout<< "Sent "<< n << " bytes " << std::endl; #endif - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_SET_SPEED_PARAMETERS)); - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } - disconnectControl(); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_SET_SPEED_PARAMETERS)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "Speed set to "<< retval << std::endl; +#endif + return retval; + +} + + +int slsDetector::setDynamicRange(int n) { + + // cout << "single " << endl; + int fnum=F_SET_DYNAMIC_RANGE,fnum2=F_SET_RECEIVER_DYNAMIC_RANGE; + int retval=-1,retval1; + char mess[MAX_STR_LENGTH]=""; + int ret=OK, rateret=OK; + +#ifdef VERBOSE + std::cout<< "Setting dynamic range to "<< n << std::endl; +#endif + if ((thisDetector->myDetectorType == MYTHEN) &&(n==24)) + n=32; + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&n,sizeof(n)); + //rate correction is switched off if not 32 bit mode + if(thisDetector->myDetectorType == EIGER){ + controlSocket->ReceiveDataOnly(&rateret,sizeof(rateret)); + if (rateret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + if(strstr(mess,"Rate Correction")!=NULL){ + if(strstr(mess,"32")!=NULL) + setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32or16BIT)); + else + setErrorMask((getErrorMask())|(COULD_NOT_SET_RATE_CORRECTION)); + } + } + } + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else if(thisDetector->myDetectorType==MYTHEN){ + if (n>0) + thisDetector->dynamicRange=n; + retval=thisDetector->dynamicRange; + } + //cout << "detector returned dynamic range " << retval << endl; + if (ret!=FAIL && retval>0) { + /* checking the number of probes to chose the data size */ + + + + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]* + thisDetector->nChips*thisDetector->nChans*retval/8; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * + thisDetector->nChan[X] + thisDetector->gappixels * + thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * + thisDetector->nChan[Y] + thisDetector->gappixels * + thisDetector->nGappixels[Y]) * + retval/8; + if (thisDetector->myDetectorType==JUNGFRAUCTB) { + // thisDetector->nChip[X]=retval/16; + // thisDetector->nChips=thisDetector->nChip[X]*thisDetector->nChip[Y]; + // cout << thisDetector->nMod[X]*thisDetector->nMod[Y] << " " + //<< thisDetector->nChans*thisDetector->nChips << " " << retval<< " "; + getTotalNumberOfChannels(); + //thisDetector->dataBytes=getTotalNumberOfChannels()* + //retval/8*thisDetector->timerValue[SAMPLES_JCTB]; + //cout << "data bytes: "<< thisDetector->dataBytes << endl; + } + if(thisDetector->myDetectorType==MYTHEN){ + if (thisDetector->timerValue[PROBES_NUMBER]!=0) { + thisDetector->dataBytes=thisDetector->nMod[X]* + thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * + thisDetector->nChan[X] + thisDetector->gappixels * + thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * + thisDetector->nChan[Y] + thisDetector->gappixels * + thisDetector->nGappixels[Y]) * + 4; + } + + if (retval==32) + thisDetector->dynamicRange=24; + } + + thisDetector->dynamicRange=retval; + + +#ifdef VERBOSE + std::cout<< "Dynamic range set to "<< thisDetector->dynamicRange << std::endl; + std::cout<< "Data bytes "<< thisDetector->dataBytes << std::endl; +#endif + } + + + //receiver + if(ret != FAIL){ + retval = thisDetector->dynamicRange; + if((n==-1) && (ret!= FORCE_UPDATE)) n =-1; + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending/Getting dynamic range to/from receiver " << + n << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum2,retval1,n); + disconnectData(); + } + if ((ret==FAIL) || (retval1 != retval)){ + ret = FAIL; + cout << "ERROR:Dynamic range in receiver set incorrectly to " << + retval1 << " instead of " << retval << endl; + setErrorMask((getErrorMask())|(RECEIVER_DYNAMIC_RANGE)); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + } + + return thisDetector->dynamicRange; +} + + +int slsDetector::getDataBytes() { + return thisDetector->dataBytes; +} + + +int slsDetector::getDataBytesInclGapPixels() { + return thisDetector->dataBytesInclGapPixels; +} + + +dacs_t slsDetector::setDAC(dacs_t val, dacIndex index, int mV, int imod) { + + + dacs_t retval[2]; + retval[0] = -1; + retval[1] = -1; + int fnum=F_SET_DAC; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + int arg[3]; + + + if ( (index==HV_NEW) &&((thisDetector->myDetectorType == GOTTHARD) || + (thisDetector->myDetectorType == PROPIX))) + index=HV_POT; + + arg[0]=index; + arg[1]=imod; + arg[2]=mV; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting DAC "<< index << " of module " << imod << " to " << + val << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->SendDataOnly(&val,sizeof(val)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(retval,sizeof(retval)); + if (index < thisDetector->nDacs){ + + if (dacs) { + if (imod>=0) { + *(dacs+index+imod*thisDetector->nDacs)=retval[0]; + } + else { + for (imod=0; imodnModsMax; ++imod) + *(dacs+index+imod*thisDetector->nDacs)=retval[0]; + } + } + } + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + + } + } +#ifdef VERBOSE + std::cout<< "Dac set to "<< retval[0] << " dac units (" << retval[1] << "mV)" + << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Set dac " << index << " of module " << imod << " to " << + val << " failed." << std::endl; + } + if(mV) + return retval[1]; + + return retval[0]; +} + + + + +dacs_t slsDetector::getADC(dacIndex index, int imod) { + + dacs_t retval; + int fnum=F_GET_ADC; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + int arg[2]; + arg[0]=index; + arg[1]=imod; + + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Getting ADC "<< index << " of module " << imod << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectStop() == OK){ + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (adcs) { + *(adcs+index+imod*thisDetector->nAdcs)=retval; + } + } else { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectStop(); + /*commented out to allow adc read during acquire, also not required if (ret==FORCE_UPDATE) - updateDetector(); - } - } + updateDetector();*/ + } + } #ifdef VERBOSE - std::cout<< "Speed set to "<< retval << std::endl; + std::cout<< "ADC returned "<< retval << std::endl; #endif - return retval; + if (ret==FAIL) { + std::cout<< "Get ADC failed " << std::endl; + } + + return retval; + + + +} + + + +slsDetectorDefs::externalCommunicationMode slsDetector::setExternalCommunicationMode( + externalCommunicationMode pol) { + + + + + int arg[1]; + externalCommunicationMode retval; + int fnum=F_SET_EXTERNAL_COMMUNICATION_MODE; + char mess[MAX_STR_LENGTH]=""; + + arg[0]=pol; + + int ret=FAIL; + retval=GET_EXTERNAL_COMMUNICATION_MODE; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting communication to mode " << pol << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + retval=GET_EXTERNAL_COMMUNICATION_MODE; + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Communication mode "<< " set to" << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Setting communication mode failed" << std::endl; + } + return retval; + +} + + + +slsDetectorDefs::externalSignalFlag slsDetector::setExternalSignalFlags( + externalSignalFlag pol, int signalindex) { + + + + + int arg[2]; + externalSignalFlag retval; + int ret=FAIL; + int fnum=F_SET_EXTERNAL_SIGNAL_FLAG; + char mess[MAX_STR_LENGTH]=""; + + arg[0]=signalindex; + arg[1]=pol; + + retval=GET_EXTERNAL_SIGNAL_FLAG; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting signal "<< signalindex << " to flag" << pol << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + retval=GET_EXTERNAL_SIGNAL_FLAG; + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Signal "<< signalindex << " flag set to" << retval << std::endl; + if (ret==FAIL) { + std::cout<< "Set signal flag failed " << std::endl; + } +#endif + return retval; + + + + + } -int64_t slsDetector::getTimeLeft(timerIndex index){ +int slsDetector::setReadOutFlags(readOutFlags flag) { - int fnum=F_GET_TIME_LEFT; - int64_t retval; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; + int fnum=F_SET_READOUT_FLAGS; + readOutFlags retval; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; #ifdef VERBOSE - std::cout<< "Getting timer "<< index << std::endl; + std::cout<< "Setting readout flags to "<< flag << std::endl; #endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (stopSocket) { - if (connectStop() == OK) { - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->SendDataOnly(&index,sizeof(index)); - stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - stopSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&flag,sizeof(flag)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_SET_READOUT_FLAGS)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->roFlags=retval; + if (thisDetector->myDetectorType==JUNGFRAUCTB) { + + getTotalNumberOfChannels(); + //thisDetector->dataBytes=getTotalNumberOfChannels()* + //thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; + } + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } } else { - stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (flag!=GET_READOUT_FLAGS) + thisDetector->roFlags=flag; } - disconnectStop(); - } - } - } -#ifdef VERBOSE - std::cout<< "Time left is "<< retval << std::endl; -#endif - return retval; - -}; - - -// Flags -int slsDetector::setDynamicRange(int n){ - - // cout << "single " << endl; - int fnum=F_SET_DYNAMIC_RANGE,fnum2=F_SET_RECEIVER_DYNAMIC_RANGE; - int retval=-1,retval1; - char mess[MAX_STR_LENGTH]=""; - int ret=OK, rateret=OK; #ifdef VERBOSE - std::cout<< "Setting dynamic range to "<< n << std::endl; + std::cout<< "Readout flag set to "<< retval << std::endl; #endif - if ((thisDetector->myDetectorType == MYTHEN) &&(n==24)) - n=32; + return thisDetector->roFlags; +} + + +uint32_t slsDetector::writeRegister(uint32_t addr, uint32_t val) { + + uint32_t retval = 0; + int fnum=F_WRITE_REGISTER; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + uint32_t arg[2]; + arg[0]=addr; + arg[1]=val; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Writing to register "<< hex<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "Register returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Write to register failed " << std::endl; + setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); + } + + return retval; +} - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&n,sizeof(n)); - //rate correction is switched off if not 32 bit mode - if(thisDetector->myDetectorType == EIGER){ - controlSocket->ReceiveDataOnly(&rateret,sizeof(rateret)); - if (rateret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - if(strstr(mess,"Rate Correction")!=NULL){ - if(strstr(mess,"32")!=NULL) - setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32or16BIT)); - else - setErrorMask((getErrorMask())|(COULD_NOT_SET_RATE_CORRECTION)); - } - } - } - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) +uint32_t slsDetector::readRegister(uint32_t addr) { + + uint32_t retval = 0; + int fnum=F_READ_REGISTER; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + uint32_t arg; + arg=addr; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Reading register "<< hex<onlineFlag==ONLINE_FLAG) { + // if (connectControl() == OK){ + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectStop(); + } + } + } +#ifdef VERBOSE + std::cout<< "Register returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Read register failed " << std::endl; + setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); + } + return retval; + +} + + + + +uint32_t slsDetector::setBit(uint32_t addr, int n) { + if (n<0 || n>31) { + std::cout << "Bit number out of Range" << std:: endl; + setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); + } + + // normal bit range + //TODO! (Erik) Check for errors! cannot use value since reg is 32bits + else { + uint32_t val = readRegister(addr); + writeRegister(addr,val | 1<31) { + std::cout << "Bit number out of Range" << std:: endl; + setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); + } + + // normal bit range + else { + uint32_t val = readRegister(addr); + writeRegister(addr,val & ~(1<myDetectorType == EIGER) { + setReceiverUDPPort2(i); + return getReceiverUDPPort2(); + } else { + setReceiverUDPPort(i); + return getReceiverUDPPort(); + } + case DETECTOR_TXN_DELAY_LEFT: + case DETECTOR_TXN_DELAY_RIGHT: + case DETECTOR_TXN_DELAY_FRAME: + case FLOW_CONTROL_10G: + sscanf(value.c_str(),"%d",&i); + return setDetectorNetworkParameter(index, i); + case CLIENT_STREAMING_PORT: + return setClientStreamingPort(value); + case RECEIVER_STREAMING_PORT: + return setReceiverStreamingPort(value); + case CLIENT_STREAMING_SRC_IP: + return setClientStreamingIP(value); + case RECEIVER_STREAMING_SRC_IP: + return setReceiverStreamingIP(value); + case ADDITIONAL_JSON_HEADER: + return setAdditionalJsonHeader(value); + case RECEIVER_UDP_SCKT_BUF_SIZE: + sscanf(value.c_str(),"%d",&i); + setReceiverUDPSocketBufferSize(i); + return getReceiverUDPSocketBufferSize(); + + default: + return (char*)("unknown network parameter"); + } + +} + + + +string slsDetector::getNetworkParameter(networkParameter index) { + ostringstream ss;string s; + switch (index) { + case DETECTOR_MAC: + return getDetectorMAC(); + case DETECTOR_IP: + return getDetectorIP(); + case RECEIVER_HOSTNAME: + return getReceiver(); + case RECEIVER_UDP_IP: + return getReceiverUDPIP(); + case RECEIVER_UDP_MAC: + return getReceiverUDPMAC(); + case RECEIVER_UDP_PORT: + return getReceiverUDPPort(); + case RECEIVER_UDP_PORT2: + return getReceiverUDPPort2(); + case DETECTOR_TXN_DELAY_LEFT: + case DETECTOR_TXN_DELAY_RIGHT: + case DETECTOR_TXN_DELAY_FRAME: + case FLOW_CONTROL_10G: + return setDetectorNetworkParameter(index, -1); + case CLIENT_STREAMING_PORT: + return getClientStreamingPort(); + case RECEIVER_STREAMING_PORT: + return getReceiverStreamingPort(); + case CLIENT_STREAMING_SRC_IP: + return getClientStreamingIP(); + case RECEIVER_STREAMING_SRC_IP: + return getReceiverStreamingIP(); + case ADDITIONAL_JSON_HEADER: + return getAdditionalJsonHeader(); + case RECEIVER_UDP_SCKT_BUF_SIZE: + return getReceiverUDPSocketBufferSize(); + case RECEIVER_REAL_UDP_SCKT_BUF_SIZE: + return getReceiverRealUDPSocketBufferSize(); + + default: + return (char*)("unknown network parameter"); + } + +} + + + +string slsDetector::getDetectorMAC() { + return string(thisDetector->detectorMAC); +} + +string slsDetector::getDetectorIP() { + return string(thisDetector->detectorIP); +} + +string slsDetector::getReceiver() { + return string(thisDetector->receiver_hostname); +} + +string slsDetector::getReceiverUDPIP() { + return string(thisDetector->receiverUDPIP); +} + +string slsDetector::getReceiverUDPMAC() { + return string(thisDetector->receiverUDPMAC); +} +string slsDetector::getReceiverUDPPort() { + ostringstream ss; ss << thisDetector->receiverUDPPort; string s = ss.str(); + return s; +} +string slsDetector::getReceiverUDPPort2() { + ostringstream ss; ss << thisDetector->receiverUDPPort2; string s = ss.str(); + return s; +} +string slsDetector::getClientStreamingPort() { + ostringstream ss; ss << thisDetector->zmqport; string s = ss.str(); + return s; +} +string slsDetector::getReceiverStreamingPort() { + ostringstream ss; ss << thisDetector->receiver_zmqport; string s = ss.str(); + return s; +} +string slsDetector::getClientStreamingIP() { + return string(thisDetector->zmqip); +} +string slsDetector::getReceiverStreamingIP() { + return string(thisDetector->receiver_zmqip); +} +string slsDetector::getAdditionalJsonHeader() { + return string(thisDetector->receiver_additionalJsonHeader); +} +string slsDetector::getReceiverUDPSocketBufferSize() { + return setReceiverUDPSocketBufferSize(); +} + +string slsDetector::getReceiverRealUDPSocketBufferSize() { + + int fnum=F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE; + int ret = FAIL; + int retval = -1; + + if(thisDetector->receiverOnlineFlag == ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Getting real UDP Socket Buffer size to receiver " << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->getInt(fnum,retval); + disconnectData(); + } + if(ret==FAIL) { + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + printf("Warning: Could not get real socket buffer size\n"); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + ostringstream ss; + ss << retval; + string s = ss.str(); + return s; +} + + +string slsDetector::setDetectorMAC(string detectorMAC) { + if(detectorMAC.length()==17){ + if((detectorMAC[2]==':')&&(detectorMAC[5]==':')&&(detectorMAC[8]==':')&& + (detectorMAC[11]==':')&&(detectorMAC[14]==':')){ + strcpy(thisDetector->detectorMAC,detectorMAC.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) +#ifdef VERBOSE + std::cout << "Warning: Receiver hostname not set yet." << endl; +#else + ; +#endif + else if(setUDPConnection()==FAIL) + std::cout<< "Warning: UDP connection set up failed" << std::endl; + }else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: server MAC Address should be in xx:xx:xx:xx:xx:xx " + "format" << endl; + } + } + else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: server MAC Address should be in xx:xx:xx:xx:xx:xx " + "format" << std::endl; + } + + return string(thisDetector->detectorMAC); +} + + + +string slsDetector::setDetectorIP(string detectorIP) { + struct sockaddr_in sa; + //taking function arguments into consideration + if(detectorIP.length()){ + if(detectorIP.length()<16){ + int result = inet_pton(AF_INET, detectorIP.c_str(), &(sa.sin_addr)); + if(result!=0){ + strcpy(thisDetector->detectorIP,detectorIP.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) +#ifdef VERBOSE + std::cout << "Warning: Receiver hostname not set yet." << endl; +#else + ; +#endif + else if(setUDPConnection()==FAIL) + std::cout<< "Warning: UDP connection set up failed" << std::endl; + }else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: Detector IP Address should be VALID and in " + "xxx.xxx.xxx.xxx format" << std::endl; + } + } + } + return string(thisDetector->detectorIP); +} + + + +string slsDetector::setReceiver(string receiverIP) { + + if(receiverIP == "none") { + memset(thisDetector->receiver_hostname, 0, MAX_STR_LENGTH); + strcpy(thisDetector->receiver_hostname,"none"); + thisDetector->receiverOnlineFlag = OFFLINE_FLAG; + return string(thisDetector->receiver_hostname); + } + + if(getRunStatus()==RUNNING){ + cprintf(RED,"Acquisition already running, Stopping it.\n"); + stopAcquisition(); + } updateDetector(); - } - } else if(thisDetector->myDetectorType==MYTHEN){ - if (n>0) - thisDetector->dynamicRange=n; - retval=thisDetector->dynamicRange; - } - //cout << "detector returned dynamic range " << retval << endl; - if (ret!=FAIL && retval>0) { - /* checking the number of probes to chose the data size */ + + strcpy(thisDetector->receiver_hostname,receiverIP.c_str()); + + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Setting up receiver with" << endl; + std::cout << "detector type:" << slsDetectorBase::getDetectorType( + thisDetector->myDetectorType) << endl; + std::cout << "detector id:" << detId << endl; + std::cout << "detector hostname:" << thisDetector->hostname << endl; + std::cout << "file path:" << fileIO::getFilePath() << endl; + std::cout << "file name:" << fileIO::getFileName() << endl; + std::cout << "file index:" << fileIO::getFileIndex() << endl; + std::cout << "file format:" << fileIO::getFileFormat() << endl; + std::cout << "r_framesperfile:" << thisDetector->receiver_framesPerFile << endl; + std::cout << "r_discardpolicy:" << thisDetector->receiver_frameDiscardMode << endl; + std::cout << "r_padding:" << thisDetector->receiver_framePadding << endl; + pthread_mutex_lock(&ms); + std::cout << "write enable:" << multiDet->enableWriteToFileMask() << endl; + std::cout << "overwrite enable:" << multiDet->enableOverwriteMask() << endl; + pthread_mutex_unlock(&ms); + std::cout << "frame index needed:" << ((thisDetector->timerValue[FRAME_NUMBER] + *thisDetector->timerValue[CYCLES_NUMBER])>1) << endl; + std::cout << "frame period:" << thisDetector->timerValue[FRAME_PERIOD] << endl; + std::cout << "frame number:" << thisDetector->timerValue[FRAME_NUMBER] << endl; + std::cout << "sub exp time:" << thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME] + << endl; + std::cout << "sub period:" << thisDetector->timerValue[SUBFRAME_PERIOD] << endl; + std::cout << "dynamic range:" << thisDetector->dynamicRange << endl; + std::cout << "flippeddatax:" << thisDetector->flippedData[X] << endl; + std::cout << "10GbE:" << thisDetector->tenGigaEnable << endl; + std::cout << "Gap pixels: " << thisDetector->gappixels << endl; + std::cout << "rx streaming source ip:" << thisDetector->receiver_zmqip << endl; + std::cout << "rx additional json header:" << thisDetector->receiver_additionalJsonHeader << endl; + std::cout << "enable gap pixels:" << thisDetector->gappixels << endl; + std::cout << "rx streaming port:" << thisDetector->receiver_zmqport << endl; + std::cout << "r_readfreq:" << thisDetector->receiver_read_freq << endl; + std::cout << "rx_datastream:" << enableDataStreamingFromReceiver(-1) << endl << endl; + +#endif + if(setDetectorType()!= GENERIC){ + if(!detId) + sendMultiDetectorSize(); + setDetectorId(); + setDetectorHostname(); + setUDPConnection(); + //setReceiverUDPSocketBufferSize(atoi(getReceiverUDPSocketBufferSize().c_str())); + + setFilePath(fileIO::getFilePath()); + setFileName(fileIO::getFileName()); + setFileIndex(fileIO::getFileIndex()); + setFileFormat(fileIO::getFileFormat()); + setReceiverFramesPerFile(thisDetector->receiver_framesPerFile); + setReceiverFramesDiscardPolicy(thisDetector->receiver_frameDiscardMode); + setReceiverPartialFramesPadding(thisDetector->receiver_framePadding); + pthread_mutex_lock(&ms); + int imask = multiDet->enableWriteToFileMask(); + pthread_mutex_unlock(&ms); + enableWriteToFile(imask); + pthread_mutex_lock(&ms); + imask = multiDet->enableOverwriteMask(); + pthread_mutex_unlock(&ms); + overwriteFile(imask); + setTimer(FRAME_PERIOD,thisDetector->timerValue[FRAME_PERIOD]); + setTimer(FRAME_NUMBER,thisDetector->timerValue[FRAME_NUMBER]); + setTimer(ACQUISITION_TIME,thisDetector->timerValue[ACQUISITION_TIME]); + if(thisDetector->myDetectorType == EIGER) { + setTimer(SUBFRAME_ACQUISITION_TIME, + thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME]); + setTimer(SUBFRAME_PERIOD,thisDetector->timerValue[SUBFRAME_PERIOD]); + } + if(thisDetector->myDetectorType == JUNGFRAUCTB) + setTimer(SAMPLES_JCTB,thisDetector->timerValue[SAMPLES_JCTB]); + setDynamicRange(thisDetector->dynamicRange); + if(thisDetector->myDetectorType == EIGER){ + setFlippedData(X,-1); + activate(-1); + } + + if(thisDetector->myDetectorType == EIGER) + enableTenGigabitEthernet(thisDetector->tenGigaEnable); + + enableGapPixels(thisDetector->gappixels); + + // data streaming + setReadReceiverFrequency(thisDetector->receiver_read_freq); + setReceiverStreamingPort(getReceiverStreamingPort()); + setReceiverStreamingIP(getReceiverStreamingIP()); + setAdditionalJsonHeader(getAdditionalJsonHeader()); + enableDataStreamingFromReceiver(enableDataStreamingFromReceiver(-1)); + } + } + + return string(thisDetector->receiver_hostname); +} - thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*retval/8; - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - thisDetector->dynamicRange/8; - if (thisDetector->myDetectorType==JUNGFRAUCTB) { - // thisDetector->nChip[X]=retval/16; - // thisDetector->nChips=thisDetector->nChip[X]*thisDetector->nChip[Y]; - // cout << thisDetector->nMod[X]*thisDetector->nMod[Y] << " " << thisDetector->nChans*thisDetector->nChips << " " << retval<< " "; - getTotalNumberOfChannels(); - //thisDetector->dataBytes=getTotalNumberOfChannels()*retval/8*thisDetector->timerValue[SAMPLES_JCTB]; - //cout << "data bytes: "<< thisDetector->dataBytes << endl; - } - if(thisDetector->myDetectorType==MYTHEN){ - if (thisDetector->timerValue[PROBES_NUMBER]!=0) { - thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; - thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * - 4; - } - - if (retval==32) - thisDetector->dynamicRange=24; - } +string slsDetector::setReceiverUDPIP(string udpip) { + struct sockaddr_in sa; + //taking function arguments into consideration + if(udpip.length()){ + if(udpip.length()<16){ + int result = inet_pton(AF_INET, udpip.c_str(), &(sa.sin_addr)); + if(result==0){ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: Receiver UDP IP Address should be VALID " + "and in xxx.xxx.xxx.xxx format" << std::endl; + }else{ + strcpy(thisDetector->receiverUDPIP,udpip.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) { +#ifdef VERBOSE + std::cout << "Warning: Receiver hostname not set yet." << endl; +#else + ; +#endif + } + else if(setUDPConnection()==FAIL){ + std::cout<< "Warning: UDP connection set up failed" << std::endl; + } + } + } + } + return string(thisDetector->receiverUDPIP); +} - thisDetector->dynamicRange=retval; + + + +string slsDetector::setReceiverUDPMAC(string udpmac) { + if(udpmac.length()!=17){ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: receiver udp mac address should be in xx:xx:xx:xx:xx:xx " + "format" << std::endl; + } + else{ + if((udpmac[2]==':')&&(udpmac[5]==':')&&(udpmac[8]==':')&& + (udpmac[11]==':')&&(udpmac[14]==':')){ + strcpy(thisDetector->receiverUDPMAC,udpmac.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) +#ifdef VERBOSE + std::cout << "Warning: Receiver hostname not set yet." << endl; +#else + ; +#endif + /* else if(setUDPConnection()==FAIL){ commented out to be replaced by user + * defined udpmac + std::cout<< "Warning: UDP connection set up failed" << std::endl; + }*/ + }else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: receiver udp mac address should be in xx:xx:xx:xx:xx:xx " + "format" << std::endl; + } + } + + + return string(thisDetector->receiverUDPMAC); +} + + + +int slsDetector::setReceiverUDPPort(int udpport) { + thisDetector->receiverUDPPort = udpport; + if(!strcmp(thisDetector->receiver_hostname,"none")) +#ifdef VERBOSE + std::cout << "Warning: Receiver hostname not set yet." << endl; +#else + ; +#endif + else if(setUDPConnection()==FAIL){ + std::cout<< "Warning: UDP connection set up failed" << std::endl; + } + return thisDetector->receiverUDPPort; +} + +int slsDetector::setReceiverUDPPort2(int udpport) { + thisDetector->receiverUDPPort2 = udpport; + if(!strcmp(thisDetector->receiver_hostname,"none")) +#ifdef VERBOSE + std::cout << "Warning: Receiver hostname not set yet." << endl; +#else + ; +#endif + else if(setUDPConnection()==FAIL){ + std::cout<< "Warning: UDP connection set up failed" << std::endl; + } + return thisDetector->receiverUDPPort2; +} + + +string slsDetector::setClientStreamingPort(string port) { + int defaultport = 0; + int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; + int arg = 0; + + //multi command, calculate individual ports + size_t found = port.find("multi"); + if(found != string::npos) { + port.erase(found,5); + sscanf(port.c_str(),"%d",&defaultport); + arg = defaultport + (detId * numsockets); + } + else + sscanf(port.c_str(),"%d",&arg); + thisDetector->zmqport = arg; + + return getClientStreamingPort(); +} + + + + +string slsDetector::setReceiverStreamingPort(string port) { + int defaultport = 0; + int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; + int arg = 0; + + //multi command, calculate individual ports + size_t found = port.find("multi"); + if(found != string::npos) { + port.erase(found,5); + sscanf(port.c_str(),"%d",&defaultport); + arg = defaultport + (detId * numsockets); + } + else + sscanf(port.c_str(),"%d",&arg); + + thisDetector->receiver_zmqport = arg; + + // send to receiver + int fnum=F_SET_RECEIVER_STREAMING_PORT; + int ret = FAIL; + int retval=-1; + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending receiver streaming port to receiver " << arg << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if (ret==FAIL) { + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: Could not set receiver zmq port" << std::endl; + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return getReceiverStreamingPort(); +} + +string slsDetector::setClientStreamingIP(string sourceIP) { + + struct addrinfo *result; + // on failure to convert to a valid ip + if (dataSocket->ConvertHostnameToInternetAddress(sourceIP.c_str(), &result)) { + std::cout << "Warning: Could not convert zmqip into a valid IP" << sourceIP + << std::endl; + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + return getClientStreamingIP(); + } + // on success put IP as string into arg + else { + memset(thisDetector->zmqip, 0, MAX_STR_LENGTH); + dataSocket->ConvertInternetAddresstoIpString(result, thisDetector->zmqip, + MAX_STR_LENGTH); + } + + return getClientStreamingIP(); +} + + +string slsDetector::setReceiverStreamingIP(string sourceIP) { + + int fnum=F_RECEIVER_STREAMING_SRC_IP; + int ret = FAIL; + char arg[MAX_STR_LENGTH]; + memset(arg,0,sizeof(arg)); + char retval[MAX_STR_LENGTH]; + memset(retval,0, sizeof(retval)); + + // if empty, give rx_hostname + if (sourceIP.empty()) { + if(!strcmp(thisDetector->receiver_hostname,"none")) { + std::cout << "Receiver hostname not set yet. Cannot create rx_zmqip " + "from none\n" << endl; + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + return getReceiverStreamingIP(); + } + sourceIP.assign(thisDetector->receiver_hostname); + } + + // verify the ip + { + struct addrinfo *result; + // on failure to convert to a valid ip + if (dataSocket->ConvertHostnameToInternetAddress(sourceIP.c_str(), &result)) { + std::cout << "Warning: Could not convert rx_zmqip into a valid IP" << + sourceIP << std::endl; + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + return getReceiverStreamingIP(); + } + // on success put IP as string into arg + else { + dataSocket->ConvertInternetAddresstoIpString(result, arg, MAX_STR_LENGTH); + } + } + + // set it anyway, else it is lost + memset(thisDetector->receiver_zmqip, 0, MAX_STR_LENGTH); + strcpy(thisDetector->receiver_zmqip, arg); + + + // if zmqip is empty, update it + if (! strlen(thisDetector->zmqip)) + strcpy(thisDetector->zmqip, arg); + + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending receiver streaming source ip to receiver " << arg << + std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendString(fnum,retval,arg); + disconnectData(); + } + if(ret==FAIL) { + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: Could not set rx_zmqip" << std::endl; + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return getReceiverStreamingIP(); +} + + + +string slsDetector::setAdditionalJsonHeader(string jsonheader) { + + int fnum=F_ADDITIONAL_JSON_HEADER; + int ret = FAIL; + char arg[MAX_STR_LENGTH]; + memset(arg,0,sizeof(arg)); + char retval[MAX_STR_LENGTH]; + memset(retval,0, sizeof(retval)); + + strcpy(arg, jsonheader.c_str()); + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending additional json header " << arg << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendString(fnum,retval,arg); + disconnectData(); + } + if(ret==FAIL) { + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: Could not set additional json header" << std::endl; + } else + strcpy(thisDetector->receiver_additionalJsonHeader, retval); + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return getAdditionalJsonHeader(); +} + + +string slsDetector::setReceiverUDPSocketBufferSize(int udpsockbufsize) { + + int fnum=F_RECEIVER_UDP_SOCK_BUF_SIZE; + int ret = FAIL; + int retval = -1; + int arg = udpsockbufsize; + + if(thisDetector->receiverOnlineFlag == ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending UDP Socket Buffer size to receiver " << arg << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if(ret==FAIL) { + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + printf("Warning: Could not set udp socket buffer size\n"); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + ostringstream ss; + ss << retval; + string s = ss.str(); + return s; +} + + + + + +string slsDetector::setDetectorNetworkParameter(networkParameter index, int delay) { + int fnum = F_SET_NETWORK_PARAMETER; + int ret = FAIL; + int retval = -1; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Setting Transmission delay of mode "<< index << " to " << delay << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&index,sizeof(index)); + controlSocket->SendDataOnly(&delay,sizeof(delay)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_NETWORK_PARAMETER)); + } else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "Speed set to "<< retval << std::endl; +#endif + + ostringstream ss; + ss << retval; + string s = ss.str(); + return s; +} + + +int slsDetector::setUDPConnection() { + + int ret = FAIL; + int fnum = F_SETUP_RECEIVER_UDP; + char args[3][MAX_STR_LENGTH]; + memset(args,0,sizeof(args)); + char retval[MAX_STR_LENGTH]; + memset(retval,0,sizeof(retval)); + + //called before set up + if(!strcmp(thisDetector->receiver_hostname,"none")){ +#ifdef VERBOSE + std::cout << "Warning: Receiver hostname not set yet." << endl; +#endif + return FAIL; + } + + //if no udp ip given, use hostname + if(!strcmp(thisDetector->receiverUDPIP,"none")){ + //hostname is an ip address + if(strchr(thisDetector->receiver_hostname,'.')!=NULL) + strcpy(thisDetector->receiverUDPIP,thisDetector->receiver_hostname); + //if hostname not ip, convert it to ip + else{ + struct addrinfo *result; + if (!dataSocket->ConvertHostnameToInternetAddress( + thisDetector->receiver_hostname, &result)) { + // on success + memset(thisDetector->receiverUDPIP, 0, MAX_STR_LENGTH); + // on failure, back to none + if (dataSocket->ConvertInternetAddresstoIpString(result, + thisDetector->receiverUDPIP, MAX_STR_LENGTH)) { + strcpy(thisDetector->receiverUDPIP, "none"); + } + } + } + } + + + //copy arguments to args[][] + strcpy(args[0],thisDetector->receiverUDPIP); + sprintf(args[1],"%d",thisDetector->receiverUDPPort); + sprintf(args[2],"%d",thisDetector->receiverUDPPort2); +#ifdef VERBOSE + std::cout << "Receiver udp ip address: " << thisDetector->receiverUDPIP << std::endl; + std::cout << "Receiver udp port: " << thisDetector->receiverUDPPort << std::endl; + std::cout << "Receiver udp port2: " << thisDetector->receiverUDPPort2 << std::endl; +#endif + + //set up receiver for UDP Connection and get receivermac address + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Setting up UDP Connection for Receiver " << args[0] << "\t" << args[1] << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendUDPDetails(fnum,retval,args); + disconnectData(); + } + if(ret!=FAIL){ + strcpy(thisDetector->receiverUDPMAC,retval); + +#ifdef VERBOSE + std::cout << "Receiver mac address: " << thisDetector->receiverUDPMAC << std::endl; +#endif + if(ret==FORCE_UPDATE) + updateReceiver(); + + //configure detector with udp details, -100 is so it doesnt overwrite + //the previous value + if(configureMAC()==FAIL){ + setReceiverOnline(OFFLINE_FLAG); + std::cout << "could not configure mac" << endl; + } + } + }else + ret=FAIL; +#ifdef VERBOSE + printReceiverConfiguration(); +#endif + return ret; +} + + + +int slsDetector::digitalTest( digitalTestMode mode, int imod) { + + + int retval; + int fnum=F_DIGITAL_TEST; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Getting id of "<< mode << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + if ((mode==CHIP_TEST)|| (mode==DIGITAL_BIT_TEST)) + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Id "<< mode <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Get id failed " << std::endl; + return ret; + } else + return retval; +} + + + +int slsDetector::executeTrimming(trimMode mode, int par1, int par2, int imod) { + + int fnum= F_EXECUTE_TRIMMING; + int retval=FAIL; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + int arg[3]; + arg[0]=imod; + arg[1]=par1; + arg[2]=par2; #ifdef VERBOSE - std::cout<< "Dynamic range set to "<< thisDetector->dynamicRange << std::endl; - std::cout<< "Data bytes "<< thisDetector->dataBytes << std::endl; + std::cout<< "Trimming module " << imod << " with mode "<< mode << " parameters " + << par1 << " " << par2 << std::endl; #endif - } - - //receiver - if(ret != FAIL){ - retval = thisDetector->dynamicRange; - if((n==-1) && (ret!= FORCE_UPDATE)) n =-1; - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); #ifdef VERBOSE - std::cout << "Sending/Getting dynamic range to/from receiver " << n << std::endl; + std::cout<< "sending mode bytes= "<< controlSocket->SendDataOnly( + &mode,sizeof(mode)) << std::endl; #endif - if (connectData() == OK){ - ret=thisReceiver->sendInt(fnum2,retval1,n); - disconnectData(); - } - if ((ret==FAIL) || (retval1 != retval)){ - ret = FAIL; - cout << "ERROR:Dynamic range in receiver set incorrectly to " << retval1 << " instead of " << retval << endl; - setErrorMask((getErrorMask())|(RECEIVER_DYNAMIC_RANGE)); - } - if(ret==FORCE_UPDATE) - updateReceiver(); - } - } + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(arg,sizeof(arg)); - return thisDetector->dynamicRange; -}; + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { +#ifdef VERBOSE + std::cout<< "Detector trimmed "<< ret << std::endl; +#endif + /* + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->roFlags=retval; + */ + retval=ret; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return retval; + +} + + + +int slsDetector::loadImageToDetector(imageType index,string const fname) { + + int ret=FAIL; + short int arg[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + +#ifdef VERBOSE + std::cout<< std::endl<< "Loading "; + if(!index) + std::cout<<"Dark"; + else + std::cout<<"Gain"; + std::cout<<" image from file " << fname << std::endl; +#endif + + if(readDataFile(fname,arg)){ + ret = sendImageToDetector(index,arg); + return ret; + } + std::cout<< "Could not open file "<< fname << std::endl; + return ret; +} + + +int slsDetector::sendImageToDetector(imageType index,short int imageVals[]) { + + int ret=FAIL; + int retval; + int fnum=F_LOAD_IMAGE; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Sending image to detector " <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&index,sizeof(index)); + controlSocket->SendDataOnly(imageVals,thisDetector->dataBytes); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + +int slsDetector::writeCounterBlockFile(string const fname,int startACQ) { + + int ret=FAIL; + short int counterVals[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + +#ifdef VERBOSE + std::cout<< std::endl<< "Reading Counter to \""<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&startACQ,sizeof(startACQ)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(arg,thisDetector->dataBytes); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} -int slsDetector::setROI(int n,ROI roiLimits[]){ +int slsDetector::resetCounterBlock(int startACQ) { + + int ret=FAIL; + int fnum=F_RESET_COUNTER_BLOCK; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< std::endl<< "Resetting Counter"; + if(startACQ==1) + std::cout<<" and Restarting Acquisition"; + std::cout<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&startACQ,sizeof(startACQ)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + + +int slsDetector::setCounterBit(int i) { + int fnum=F_SET_COUNTER_BIT; + int ret = FAIL; + int retval=-1; + char mess[MAX_STR_LENGTH]=""; + + if(thisDetector->onlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + if(i ==-1) + std::cout<< "Getting counter bit from detector" << endl; + else if(i==0) + std::cout<< "Resetting counter bit in detector " << endl; + else + std::cout<< "Setting counter bit in detector " << endl; +#endif + if (connectControl() == OK){ + + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&i,sizeof(i)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_SET_COUNTER_BIT)); + } + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + + } + } + return retval; +} + + + + +int slsDetector::setROI(int n,ROI roiLimits[]) { int ret = FAIL; //sort ascending order int temp; for(int i=0;imyDetectorType==JUNGFRAUCTB) getTotalNumberOfChannels(); return ret; } -slsDetectorDefs::ROI* slsDetector::getROI(int &n){ - sendROI(-1,NULL); - n=thisDetector->nROI; - if(thisDetector->myDetectorType==JUNGFRAUCTB) getTotalNumberOfChannels(); - return thisDetector->roiLimits; +slsDetectorDefs::ROI* slsDetector::getROI(int &n) { + sendROI(-1,NULL); + n=thisDetector->nROI; + if(thisDetector->myDetectorType==JUNGFRAUCTB) getTotalNumberOfChannels(); + return thisDetector->roiLimits; +} + +int slsDetector::getNRoi(){ + return thisDetector->nROI; } -int slsDetector::sendROI(int n,ROI roiLimits[]){ - int ret=FAIL; - int fnum=F_SET_ROI; - char mess[MAX_STR_LENGTH]=""; - int arg = n; - int retvalsize=0; - ROI retval[MAX_ROIS]; - int nrec=-1; - if (roiLimits==NULL) - roiLimits=thisDetector->roiLimits; +int slsDetector::sendROI(int n,ROI roiLimits[]) { + int ret=FAIL; + int fnum=F_SET_ROI; + char mess[MAX_STR_LENGTH]=""; + int arg = n; + int retvalsize=0; + ROI retval[MAX_ROIS]; + int nrec=-1; + if (roiLimits==NULL) + roiLimits=thisDetector->roiLimits; - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&arg,sizeof(arg)); - if(arg==-1){; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + if(arg==-1){; #ifdef VERBOSE - cout << "Getting ROI from detector" << endl; + cout << "Getting ROI from detector" << endl; #endif - }else{ + }else{ #ifdef VERBOSE - cout << "Sending ROI of size " << arg << " to detector" << endl; + cout << "Sending ROI of size " << arg << " to detector" << endl; #endif - controlSocket->SendDataOnly(roiLimits,arg*sizeof(ROI)); - } - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - - if (ret!=FAIL){ - controlSocket->ReceiveDataOnly(&retvalsize,sizeof(retvalsize)); - nrec = controlSocket->ReceiveDataOnly(retval,retvalsize*sizeof(ROI)); - if(nrec!=(retvalsize*(int)sizeof(ROI))){ - ret=FAIL; - std::cout << " wrong size received: received " << nrec << "but expected " << retvalsize*sizeof(ROI) << endl; - } - }else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - //update client - if(ret!=FAIL){ - for(int i=0;iroiLimits[i]=retval[i]; - thisDetector->nROI = retvalsize; - } - - //#ifdef VERBOSE - for(int j=0;jnROI;++j) - cout<<"get"<< roiLimits[j].xmin<<"\t"<onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&flag,sizeof(flag)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_SET_READOUT_FLAGS)); - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - thisDetector->roFlags=retval; - if (thisDetector->myDetectorType==JUNGFRAUCTB) { - - getTotalNumberOfChannels(); - //thisDetector->dataBytes=getTotalNumberOfChannels()*thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; - } - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } else { - if (flag!=GET_READOUT_FLAGS) - thisDetector->roFlags=flag; - } - -#ifdef VERBOSE - std::cout<< "Readout flag set to "<< retval << std::endl; -#endif - return thisDetector->roFlags; -}; - -//Trimming -/* - enum trimMode { - NOISE_TRIMMING, - BEAM_TRIMMING, - IMPROVE_TRIMMING, - FIXEDSETTINGS_TRIMMING, - OFFLINE_TRIMMING - }{}; -*/ -int slsDetector::executeTrimming(trimMode mode, int par1, int par2, int imod){ - - int fnum= F_EXECUTE_TRIMMING; - int retval=FAIL; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; - int arg[3]; - arg[0]=imod; - arg[1]=par1; - arg[2]=par2; - - -#ifdef VERBOSE - std::cout<< "Trimming module " << imod << " with mode "<< mode << " parameters " << par1 << " " << par2 << std::endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); -#ifdef VERBOSE - std::cout<< "sending mode bytes= "<< controlSocket->SendDataOnly(&mode,sizeof(mode)) << std::endl; -#endif - controlSocket->SendDataOnly(&mode,sizeof(mode)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else { -#ifdef VERBOSE - std::cout<< "Detector trimmed "<< ret << std::endl; -#endif - /* - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - thisDetector->roFlags=retval; - */ - retval=ret; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return retval; - -}; - -double* slsDetector::decodeData(int *datain, int &nn, double *fdata) { - - - double *dataout; - if (fdata) { - dataout=fdata; - nn=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; - // printf("not allocating fdata!\n"); - if (thisDetector->myDetectorType==JUNGFRAUCTB) nn=thisDetector->dataBytes/2; - } else { - if (thisDetector->myDetectorType==JUNGFRAUCTB) { - nn=thisDetector->dataBytes/2; - dataout=new double[nn]; - - // std::cout<< "nn is "<< nn << std::endl; - } else { - dataout=new double[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; - nn=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; - } - - // printf("allocating fdata!\n"); - } - // const int bytesize=8; - - int ival=0; - char *ptr=(char*)datain; - char iptr; - - int nbits=thisDetector->dynamicRange; - int nch=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; - int ipos=0, ichan=0, ibyte; - - if (thisDetector->timerValue[PROBES_NUMBER]==0) { - if (thisDetector->myDetectorType==JUNGFRAUCTB) { - - for (ichan=0; ichandataBytes; ++ibyte) { - iptr=ptr[ibyte];//&0x1; - for (ipos=0; ipos<8; ++ipos) { - // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; - ival=(iptr>>(ipos))&0x1; - dataout[ichan]=ival; - ++ichan; - } - } - break; - case 4: - for (ibyte=0; ibytedataBytes; ++ibyte) { - iptr=ptr[ibyte]; - for (ipos=0; ipos<2; ++ipos) { - // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; - ival=(iptr>>(ipos*4))&0xf; - dataout[ichan]=ival; - ++ichan; - } - } - break; - case 8: - for (ichan=0; ichandataBytes; ++ichan) { - ival=ptr[ichan]&0xff; - dataout[ichan]=ival; - } - break; - case 16: - for (ichan=0; ichanmyDetectorType == MYTHEN) mask=0xffffff; - for (ichan=0; ichanSendDataOnly(roiLimits,arg*sizeof(ROI)); } - } - } else { - for (ichan=0; ichanReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL){ + controlSocket->ReceiveDataOnly(&retvalsize,sizeof(retvalsize)); + nrec = controlSocket->ReceiveDataOnly(retval,retvalsize*sizeof(ROI)); + if(nrec!=(retvalsize*(int)sizeof(ROI))){ + ret=FAIL; + std::cout << " wrong size received: received " << nrec << + "but expected " << retvalsize*sizeof(ROI) << endl; + } + }else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } - //#ifdef VERBOSE + //update client + if(ret!=FAIL){ + for(int i=0;iroiLimits[i]=retval[i]; + thisDetector->nROI = retvalsize; + } + + //#ifdef VERBOSE + for(int j=0;jnROI;++j) + cout<<"get"<< roiLimits[j].xmin<<"\t"<nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; - //double err[thisDetector->nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; - //double xmed[thisDetector->nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; - // int nmed=0; - int im=0; - int nch; - thisDetector->nBadFF=0; - - char ffffname[MAX_STR_LENGTH*2]; - if (fname=="default") { - fname=string(thisDetector->flatFieldFile); - } - - if (fname=="") { -#ifdef VERBOSE - std::cout<< "disabling flat field correction" << std::endl; -#endif - thisDetector->correctionMask&=~(1<flatFieldDir,fname.c_str()); - nch=readDataFile(string(ffffname),data); - if (nch>0) { - - //???? bad ff chans? - int nm=getNMods(); - int chpm[nm]; - int mMask[nm]; - for (int i=0; i=0) { - strcpy(thisDetector->flatFieldFile,fname.c_str()); - - - thisDetector->correctionMask|=(1<correctionMask&(1<nMod[Y]*thisDetector->nMod[X]*thisDetector->nChans*thisDetector->nChips; ++ichan) { - // #ifdef VERBOSE - // std::cout<< ichan << " "<< corr[ichan] << std::endl; - // #endif - ffcoefficients[ichan]=corr[ichan]; - if (ecorr!=NULL) - fferrors[ichan]=ecorr[ichan]; - else - fferrors[ichan]=1; - - cout << ichan << " " << ffcoefficients[ichan] << endl; - } - thisDetector->correctionMask|=(1<correctionMask&=~(1<correctionMask)&(1<correctionMask&(1<correctionMask&(1<nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ++ichan) { - // corr[ichan]=(ffcoefficients[ichan]*ffcoefficients[ichan])/(fferrors[ichan]*fferrors[ichan]); - corr[ichan]=ffcoefficients[ichan]; - if (ecorr) { - //ecorr[ichan]=ffcoefficients[ichan]/fferrors[ichan]; - ecorr[ichan]=fferrors[ichan]; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } } - } - } - return 1; - } else { #ifdef VERBOSE - std::cout<< "Flat field correction is disabled" << std::endl; + std::cout<< "ADC Register returned "<< retval << std::endl; #endif - if (corr) - for (int ichan=0; ichannMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ++ichan) { - corr[ichan]=1; - if (ecorr) - ecorr[ichan]=0; - } - return 0; - } + if (ret==FAIL) { + std::cout<< "Write ADC to register failed " << std::endl; + setErrorMask((getErrorMask())|(REGISER_WRITE_READ)); + } + return retval; } -int slsDetector::flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout){ +int slsDetector::activate(int const enable) { + int fnum = F_ACTIVATE; + int fnum2 = F_RECEIVER_ACTIVATE; + int retval = -1; + int arg = enable; + char mess[MAX_STR_LENGTH]=""; + int ret = OK; + + if(thisDetector->myDetectorType != EIGER){ + std::cout<< "Not implemented for this detector" << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE)); + return -1; + } + #ifdef VERBOSE - std::cout<< "Flat field correcting data" << std::endl; + if(!enable) + std::cout<< "Deactivating Detector" << std::endl; + else if(enable == -1) + std::cout<< "Getting Detector activate mode" << std::endl; + else + std::cout<< "Activating Detector" << std::endl; #endif - double e, eo; - if (thisDetector->correctionMask & (1<nMod[X]*thisDetector->nChans*thisDetector->nChips; ++ichan) { - if (errin==NULL) { - e=0; - } else { - e=errin[ichan]; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + if(retval==1) + std::cout << "Detector Activated" << std::endl; + else if(retval==0) + std::cout << "Detector Deactivated" << std::endl; + else + std::cout << "Detector Activation unknown:" << retval << std::endl; +#endif + + if(ret!=FAIL){ + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Activating/Deactivating Receiver: " << retval << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum2,retval,retval); + disconnectData(); + } + if(ret==FAIL) + setErrorMask((getErrorMask())|(RECEIVER_ACTIVATE)); + } + } +#ifdef VERBOSE + if(retval==1) + std::cout << "Receiver Activated" << std::endl; + else if(retval==0) + std::cout << "Receiver Deactivated" << std::endl; + else + std::cout << "Receiver Activation unknown:" << retval << std::endl; +#endif + + + return retval; + +} + + + +int slsDetector::getFlippedData(dimension d) { + return thisDetector->flippedData[d]; +} + + + +int slsDetector::setFlippedData(dimension d, int value) { + int retval=-1; + int fnum=F_SET_FLIPPED_DATA_RECEIVER; + int ret=FAIL; + int args[2]={X,-1}; + + + if(thisDetector->myDetectorType!= EIGER){ + std::cout << "Flipped Data is not implemented in this detector" << std::endl; + setErrorMask((getErrorMask())|(RECEIVER_FLIPPED_DATA_NOT_SET)); + return -1; + } + +#ifdef VERBOSE + std::cout << std::endl; + std::cout << "Setting/Getting flipped data across axis " << d <<" with value " + << value << std::endl; +#endif + if(value > -1){ + thisDetector->flippedData[d] = value; + args[1] = value; + }else + args[1] = thisDetector->flippedData[d]; + + args[0] = d; + + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + if (connectData() == OK){ + ret=thisReceiver->sendIntArray(fnum,retval,args); + + disconnectData(); + } + + if((args[1] != retval && args[1]>=0) || (ret==FAIL)){ + ret = FAIL; + setErrorMask((getErrorMask())|(RECEIVER_FLIPPED_DATA_NOT_SET)); + } + + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + + return thisDetector->flippedData[d]; +} + + + +int slsDetector::setAllTrimbits(int val, int imod) { + int fnum=F_SET_ALL_TRIMBITS; + int retval; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting all trimbits to "<< val << std::endl; +#endif + if (getDetectorsType() == MYTHEN) { + if (val>=0) { + setChannel((val<<((int)TRIMBIT_OFF))|((int)COMPARATOR_ENABLE)); // trimbit scan + } + return val; + } else { + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&val,sizeof(val)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(ALLTIMBITS_NOT_SET)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + } + +#ifdef VERBOSE + std::cout<< "All trimbits were set to "<< retval << std::endl; +#endif + return retval; +} + + + +int slsDetector::enableGapPixels(int val) { + + if(val > 0 && thisDetector->myDetectorType!= EIGER) + val = -1; + + if (val >= 0) { + val=(val>0)?1:0; + + // send to receiver + int ret=OK; + int retval=-1; + int fnum=F_ENABLE_GAPPIXELS_IN_RECEIVER; + int arg=val; + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if((arg != retval) || (ret==FAIL)){ + ret = FAIL; + setErrorMask((getErrorMask())|(RECEIVER_ENABLE_GAPPIXELS_NOT_SET)); + } + + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + + // update client + if (ret == OK) { + thisDetector->gappixels = val; + thisDetector->dataBytesInclGapPixels = 0; + + if (thisDetector->dynamicRange != 4) { + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * + thisDetector->nChan[X] + thisDetector->gappixels * + thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * + thisDetector->nChan[Y] + thisDetector->gappixels * + thisDetector->nGappixels[Y]) * + thisDetector->dynamicRange/8; + // set data bytes for other detector ( for future use) + if(thisDetector->myDetectorType==JUNGFRAUCTB) + getTotalNumberOfChannels(); + else if(thisDetector->myDetectorType==MYTHEN){ + if (thisDetector->dynamicRange==24 || + thisDetector->timerValue[PROBES_NUMBER]>0) { + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChip[X] * + thisDetector->nChan[X] + thisDetector->gappixels * + thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * + thisDetector->nChan[Y] + thisDetector->gappixels * + thisDetector->nGappixels[Y]) * + 4; + } + } + } + } + } + + return thisDetector->gappixels; +} + + + +int slsDetector::setTrimEn(int nen, int *en) { + if (en) { + for (int ien=0; ientrimEnergies[ien]=en[ien]; + thisDetector->nTrimEn=nen; + } + return (thisDetector->nTrimEn); +} + + +int slsDetector::getTrimEn(int *en) { + if (en) { + for (int ien=0; iennTrimEn; ien++) + en[ien]=thisDetector->trimEnergies[ien]; + } + return (thisDetector->nTrimEn); +} + + + + +int slsDetector::pulsePixel(int n,int x,int y) { + int ret=FAIL; + int fnum=F_PULSE_PIXEL; + char mess[MAX_STR_LENGTH]=""; + int arg[3]; + arg[0] = n; arg[1] = x; arg[2] = y; + +#ifdef VERBOSE + std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times at (" << + x << "," << "y)" << endl << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + +int slsDetector::pulsePixelNMove(int n,int x,int y) { + int ret=FAIL; + int fnum=F_PULSE_PIXEL_AND_MOVE; + char mess[MAX_STR_LENGTH]=""; + int arg[3]; + arg[0] = n; arg[1] = x; arg[2] = y; + +#ifdef VERBOSE + std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times and move " + "by deltax:" << x << " deltay:" << y << endl << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL_NMOVE)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + +int slsDetector::pulseChip(int n) { + int ret=FAIL; + int fnum=F_PULSE_CHIP; + char mess[MAX_STR_LENGTH]=""; + + +#ifdef VERBOSE + std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times" << endl << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&n,sizeof(n)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_PULSE_CHIP)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + + +int slsDetector::setThresholdTemperature(int val, int imod) { + + int retval = -1; + int fnum = F_THRESHOLD_TEMP; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = ""; + + int arg[2]; + arg[0]=val; + arg[1]=imod; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting/Getting Threshold Temperature to "<< val << " of module " + << imod << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectStop() == OK){ + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); +#ifdef VERBOSE +std::cout<< "Threshold Temperature returned "<< retval << std::endl; +#endif + } else { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL)); + } + disconnectStop(); + } + } + + return retval; +} + + + +int slsDetector::setTemperatureControl(int val, int imod) { + + int retval = -1; + int fnum = F_TEMP_CONTROL; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = ""; + + int arg[2]; + arg[0]=val; + arg[1]=imod; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting/Getting Threshold Temperature to "<< val << " of module " + << imod << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectStop() == OK){ + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); +#ifdef VERBOSE +std::cout<< "Threshold Temperature returned "<< retval << std::endl; +#endif + } else { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL)); + } + disconnectStop(); + } + } + + return retval; +} + + + + +int slsDetector::setTemperatureEvent(int val, int imod) { + + int retval = -1; + int fnum = F_TEMP_EVENT; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = ""; + + int arg[2]; + arg[0]=val; + arg[1]=imod; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting/Getting Threshold Temperature to "<< val << " of module " + << imod << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectStop() == OK){ + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); +#ifdef VERBOSE +std::cout<< "Threshold Temperature returned "<< retval << std::endl; +#endif + } else { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(TEMPERATURE_CONTROL)); + } + disconnectStop(); + } + } + + return retval; +} + + + +int slsDetector::setStoragecellStart(int pos) { + int ret=FAIL; + int fnum=F_STORAGE_CELL_START; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); + int retval=-1; + +#ifdef VERBOSE + std::cout<< "Sending storage cell start index " << pos << endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&pos,sizeof(pos)); + //check opening error + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(STORAGE_CELL_START)); + }else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return retval; +} + + + +int slsDetector::programFPGA(string fname) { + int ret=FAIL; + int fnum=F_PROGRAM_FPGA; + char mess[MAX_STR_LENGTH]=""; + size_t filesize=0; + char* fpgasrc = NULL; + + if(thisDetector->myDetectorType != JUNGFRAU && + thisDetector->myDetectorType != JUNGFRAUCTB){ + std::cout << "Not implemented for this detector" << std::endl; + return FAIL; + } + + + //check if it exists + struct stat st; + if(stat(fname.c_str(),&st)){ + std::cout << "Programming file does not exist" << endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + + // open src + FILE* src = fopen(fname.c_str(),"rb"); + if (src == NULL) { + std::cout << "Could not open source file for programming: " << fname << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + + // create temp destination file + char destfname[] = "/tmp/Jungfrau_MCB.XXXXXX"; + int dst = mkstemp(destfname); // create temporary file and open it in r/w + if (dst == -1) { + std::cout << "Could not create destination file in /tmp for programming: " + << destfname << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + + // convert src to dst rawbin +#ifdef VERBOSE + std::cout << "Converting " << fname << " to " << destfname << std::endl; +#endif + int filepos,x,y,i; + // Remove header (0...11C) + for (filepos=0; filepos < 0x11C; ++filepos) + fgetc(src); + // Write 0x80 times 0xFF (0...7F) + { + char c = 0xFF; + for (filepos=0; filepos < 0x80; ++filepos) + write(dst, &c, 1); + } + // Swap bits and write to file + for (filepos=0x80; filepos < 0x1000000; ++filepos) { + x = fgetc(src); + if (x < 0) break; + y=0; + for (i=0; i < 8; ++i) + y=y| ( (( x & (1<> i) << (7-i) ); // This swaps the bits + write(dst, &y, 1); + } + if (filepos < 0x1000000){ + std::cout << "Could not convert programming file. EOF before end of flash" + << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + if(fclose(src)){ + std::cout << "Could not close source file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + if(close(dst)){ + std::cout << "Could not close destination file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } +#ifdef VERBOSE + std::cout << "File has been converted to " << destfname << std::endl; +#endif + + //loading dst file to memory + FILE* fp = fopen(destfname,"r"); + if(fp == NULL){ + std::cout << "Could not open rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + if(fseek(fp,0,SEEK_END)){ + std::cout << "Seek error in rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + filesize = ftell(fp); + if(filesize <= 0){ + std::cout << "Could not get length of rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + rewind(fp); + fpgasrc = (char*)malloc(filesize+1); + if(fpgasrc == NULL){ + std::cout << "Could not allocate size of program" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + if(fread(fpgasrc, sizeof(char), filesize, fp) != filesize){ + std::cout << "Could not read rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + + if(fclose(fp)){ + std::cout << "Could not close destination file after converting" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + unlink(destfname); // delete temporary file +#ifdef VERBOSE + std::cout << "Successfully loaded the rawbin file to program memory" << std::endl; +#endif + + + // send program from memory to detector +#ifdef VERBOSE + std::cout<< "Sending programming binary to detector " << endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&filesize,sizeof(filesize)); + //check opening error + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + filesize = 0; + } + + + //erasing flash + if(ret!=FAIL){ + std::cout<< "This can take awhile. Please be patient..." << endl; + printf("Erasing Flash:%d%%\r",0); + std::cout << flush; + //erasing takes 65 seconds, printing here (otherwise need threads + //in server-unnecessary) + int count = 66; + while(count>0){ + usleep(1 * 1000 * 1000); + --count; + printf("Erasing Flash:%d%%\r",(int) (((double)(65-count)/65)*100)); + std::cout << flush; + } + std::cout< 0)){ + + unitprogramsize = MAX_FPGAPROGRAMSIZE; //2mb + if(unitprogramsize > filesize) //less than 2mb + unitprogramsize = filesize; +#ifdef VERBOSE + std::cout << "unitprogramsize:" << unitprogramsize << "\t filesize:" + << filesize << std::endl; +#endif + controlSocket->SendDataOnly(fpgasrc+currentPointer,unitprogramsize); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + filesize-=unitprogramsize; + currentPointer+=unitprogramsize; + + //print progress + printf("Writing to Flash:%d%%\r", + (int) (((double)(totalsize-filesize)/totalsize)*100)); + std::cout << flush; + }else{ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + } + } + std::cout<ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + } + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + + + //remapping stop server + if ((ret == FAIL) && + (strstr(mess,"not implemented") == NULL) && + (strstr(mess,"locked") == NULL) && + (strstr(mess,"-update") == NULL)) { + fnum=F_RESET_FPGA; + int stopret; + if (connectStop() == OK){ + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&stopret,sizeof(stopret)); + if (stopret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + } + disconnectControl(); + } + } + } + if (ret != FAIL) { + printf("You can now restart the detector servers in normal mode.\n"); + } + + //free resources + if(fpgasrc != NULL) + free(fpgasrc); + + return ret; +} + + +int slsDetector::resetFPGA() { + int ret=FAIL; + int fnum=F_RESET_FPGA; + char mess[MAX_STR_LENGTH]=""; + + if(thisDetector->myDetectorType != JUNGFRAU){ + std::cout << "Not implemented for this detector" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Sending reset to FPGA " << endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + // control server + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(RESET_ERROR)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return ret; + +} + + + +int slsDetector::powerChip(int ival) { + int ret=FAIL; + int fnum=F_POWER_CHIP; + char mess[MAX_STR_LENGTH]=""; + int retval=-1; + + if(thisDetector->myDetectorType != JUNGFRAU && + thisDetector->myDetectorType != JUNGFRAUCTB ){ + std::cout << "Not implemented for this detector" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Sending power on/off/get to the chip " << endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&ival,sizeof(ival)); + //check opening error + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(POWER_CHIP)); + }else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return retval; + +} + + +int slsDetector::setAutoComparatorDisableMode(int ival) { + int ret=FAIL; + int fnum=F_AUTO_COMP_DISABLE; + char mess[MAX_STR_LENGTH]=""; + int retval=-1; + + if(thisDetector->myDetectorType != JUNGFRAU){ + std::cout << "Not implemented for this detector" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Enabling/disabling Auto comp disable mode " << endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&ival,sizeof(ival)); + //check opening error + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(AUTO_COMP_DISABLE)); + }else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return retval; + +} + + + +int slsDetector::getChanRegs(double* retval,bool fromDetector) { + int n=getTotalNumberOfChannels(); + if(fromDetector){ + for(int im=0;imnChans*thisDetector->nChips]; + int chiregs[thisDetector->nChips]; + dacs_t das[thisDetector->nDacs], ads[thisDetector->nAdcs]; + int mmin=imod, mmax=imod+1; + int ret=FAIL; + + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + + + for (int im=mmin; imnChans; + myModule.nchip=thisDetector->nChips; + myModule.ndac=thisDetector->nDacs; + myModule.nadc=thisDetector->nAdcs; + + myModule.reg=reg; + if (detectorModules) { + myModule.gain=(detectorModules+im)->gain; + myModule.offset=(detectorModules+im)->offset; + myModule.serialnumber=(detectorModules+im)->serialnumber; + } else { + myModule.gain=-1; + myModule.offset=-1; + myModule.serialnumber=-1; + } + + + for (int i=0; inAdcs; ++i) + ads[i]=-1; + + if (chanregs) + myModule.chanregs=chanregs+im*thisDetector->nChips*thisDetector->nChans; + else { + for (int i=0; inChans*thisDetector->nChips; ++i) + charegs[i]=-1; + myModule.chanregs=charegs; + } + if (chipregs) + myModule.chipregs=chanregs+im*thisDetector->nChips; + else { + for (int ichip=0; ichipnChips; ++ichip) + chiregs[ichip]=-1; + myModule.chipregs=chiregs; + } + if (dacs) + myModule.dacs=dacs+im*thisDetector->nDacs; + else { + for (int i=0; inDacs; ++i) + das[i]=-1; + myModule.dacs=das; + } + if (adcs) + myModule.adcs=adcs+im*thisDetector->nAdcs; + else { + for (int i=0; inAdcs; ++i) + ads[i]=-1; + myModule.adcs=ads; + } + ret=setModule(myModule,-1,-1,-1,0,0); + } + return ret; + + +} + +int slsDetector::setModule(sls_detector_module module, int iodelay, int tau, + int e_eV, int* gainval, int* offsetval, int tb) { + + int fnum=F_SET_MODULE; + int retval=-1; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + int imod=module.module; + + +#ifdef VERBOSE + std::cout << "slsDetector set module " << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + //to exclude trimbits + if(!tb) { + module.nchan=0; + module.nchip=0; + } + sendModule(&module); + + //not included in module + if(gainval && (thisDetector->nGain)) + controlSocket->SendDataOnly(gainval,sizeof(int)*thisDetector->nGain); + if(offsetval && (thisDetector->nOffset)) + controlSocket->SendDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); + if(thisDetector->myDetectorType == EIGER) { + controlSocket->SendDataOnly(&iodelay,sizeof(iodelay)); + controlSocket->SendDataOnly(&tau,sizeof(tau)); + controlSocket->SendDataOnly(&e_eV,sizeof(e_eV)); + } + + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + if(strstr(mess,"default tau")!=NULL) + setErrorMask((getErrorMask())|(RATE_CORRECTION_NO_TAU_PROVIDED)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (detectorModules) { + if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { + if(tb) { + (detectorModules+imod)->nchan=module.nchan; + (detectorModules+imod)->nchip=module.nchip; + } + (detectorModules+imod)->ndac=module.ndac; + (detectorModules+imod)->nadc=module.nadc; + if(tb) { + thisDetector->nChips=module.nchip; + thisDetector->nChans=module.nchan/module.nchip; + } + thisDetector->nDacs=module.ndac; + thisDetector->nAdcs=module.nadc; + + if(thisDetector->myDetectorType != JUNGFRAU){ + if(tb) { + for (int ichip=0; ichipnChips; ++ichip) { + if (chipregs) + chipregs[ichip+thisDetector->nChips*imod]= + module.chipregs[ichip]; + + if (chanregs) { + for (int i=0; inChans; ++i) { + chanregs[i+ichip* + thisDetector->nChans+ + thisDetector->nChips*thisDetector->nChans* + imod]=module.chanregs[ichip*thisDetector->nChans+i]; + } + } + } + } + if (adcs) { + for (int i=0; inAdcs; ++i) + adcs[i+imod*thisDetector->nAdcs]=module.adcs[i]; + } + } + + if (dacs) { + for (int i=0; inDacs; ++i) + dacs[i+imod*thisDetector->nDacs]=module.dacs[i]; + } + + (detectorModules+imod)->gain=module.gain; + (detectorModules+imod)->offset=module.offset; + (detectorModules+imod)->serialnumber=module.serialnumber; + (detectorModules+imod)->reg=module.reg; + } + } + + if ((thisDetector->nGain) && (gainval) && (gain)) { + for (int i=0; inGain; ++i) + gain[i+imod*thisDetector->nGain]=gainval[i]; + } + + if ((thisDetector->nOffset) && (offsetval) && (offset)) { + for (int i=0; inOffset; ++i) + offset[i+imod*thisDetector->nOffset]=offsetval[i]; + } + + if (e_eV != -1) + thisDetector->currentThresholdEV = e_eV; + + } + +#ifdef VERBOSE + std::cout<< "Module register returned "<< retval << std::endl; +#endif + + return retval; +} + + + + + +slsDetectorDefs::sls_detector_module *slsDetector::getModule(int imod) { + +#ifdef VERBOSE + std::cout << "slsDetector get module " << std::endl; +#endif + + int fnum=F_GET_MODULE; + sls_detector_module *myMod=createModule(); + + int* gainval=0, *offsetval=0; + if(thisDetector->nGain) + gainval=new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval=new int[thisDetector->nOffset]; + + //char *ptr, *goff=(char*)thisDetector; + + // int chanreg[thisDetector->nChans*thisDetector->nChips]; + //int chipreg[thisDetector->nChips]; + //double dac[thisDetector->nDacs], adc[thisDetector->nAdcs]; + + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + // int n; + +#ifdef VERBOSE + std::cout<< "getting module " << imod << std::endl; +#endif + + myMod->module=imod; + // myMod.nchan=thisDetector->nChans*thisDetector->nChips; + //myMod.chanregs=chanreg; + //myMod.nchip=thisDetector->nChips; + //myMod.chipregs=chipreg; + //myMod.ndac=thisDetector->nDacs; + //myMod.dacs=dac; + //myMod.ndac=thisDetector->nAdcs; + //myMod.dacs=adc; + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + receiveModule(myMod); + + //extra gain and offset - eiger + if(thisDetector->nGain) + controlSocket->ReceiveDataOnly(gainval,sizeof(int)*thisDetector->nGain); + if(thisDetector->nOffset) + controlSocket->ReceiveDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (detectorModules) { + if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { + (detectorModules+imod)->nchan=myMod->nchan; + (detectorModules+imod)->nchip=myMod->nchip; + (detectorModules+imod)->ndac=myMod->ndac; + (detectorModules+imod)->nadc=myMod->nadc; + thisDetector->nChips=myMod->nchip; + thisDetector->nChans=myMod->nchan/myMod->nchip; + thisDetector->nDacs=myMod->ndac; + thisDetector->nAdcs=myMod->nadc; + + if(thisDetector->myDetectorType != JUNGFRAU){ + for (int ichip=0; ichipnChips; ++ichip) { + if (chipregs) + chipregs[ichip+thisDetector->nChips*imod]= + myMod->chipregs[ichip]; + + if (chanregs) { + for (int i=0; inChans; ++i) { + chanregs[i+ichip*thisDetector->nChans+ + thisDetector->nChips*thisDetector->nChans*imod]= + myMod->chanregs[ichip*thisDetector->nChans+i]; + } + } + } + + if (adcs) { + for (int i=0; inAdcs; ++i) + adcs[i+imod*thisDetector->nAdcs]=myMod->adcs[i]; + } + } + + if (dacs) { + for (int i=0; inDacs; ++i) { + dacs[i+imod*thisDetector->nDacs]=myMod->dacs[i]; + //cprintf(BLUE,"dac%d:%d\n",i, myMod->dacs[i]); + } + } + (detectorModules+imod)->gain=myMod->gain; + (detectorModules+imod)->offset=myMod->offset; + (detectorModules+imod)->serialnumber=myMod->serialnumber; + (detectorModules+imod)->reg=myMod->reg; + } + } + + if ((thisDetector->nGain) && (gainval) && (gain)) { + for (int i=0; inGain; ++i) + gain[i+imod*thisDetector->nGain]=gainval[i]; + } + + if ((thisDetector->nOffset) && (offsetval) && (offset)) { + for (int i=0; inOffset; ++i) + offset[i+imod*thisDetector->nOffset]=offsetval[i]; + } + + } else { + deleteModule(myMod); + myMod=NULL; + } + + if(gainval) delete[]gainval; + if(offsetval) delete[]offsetval; + + return myMod; +} + + + + +int slsDetector::setChannel(int64_t reg, int ichan, int ichip, int imod) { + sls_detector_channel myChan; +#ifdef VERBOSE + std::cout<< "Setting channel "<< ichan << " " << ichip << " " << imod << + " to " << reg << std::endl; +#endif + //int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, + //chamax=ichan+1; + + int ret; + + /* if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; } - postProcessingFuncs::flatFieldCorrect(datain[ichan],e,dataout[ichan],eo,ffcoefficients[ichan],fferrors[ichan]); - if (errout) - errout[ichan]=eo; - // #ifdef VERBOSE - // cout << ichan << " " <nChips; + } -int slsDetector::setRateCorrection(double t){ + if (ichan==-1) { + chamin=0; + chamax=thisDetector->nChans; + }*/ + + // for (int im=mmin; imonlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendChannel(&chan); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chanregs) { + + int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, + chamax=ichan+1; + + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + if (ichan==-1) { + chamin=0; + chamax=thisDetector->nChans; + } + + + + + + + for (int im=mmin; imnChans* + thisDetector->nChips+ichi*thisDetector->nChips+icha)=retval; + + } + } + } + + } + } +#ifdef VERBOSE + std::cout<< "Channel register returned "<< retval << std::endl; +#endif + return retval; + +} + + + + + +slsDetectorDefs::sls_detector_channel slsDetector::getChannel(int ichan, int ichip, + int imod) { + + + int fnum=F_GET_CHANNEL; + sls_detector_channel myChan; + int arg[3]; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + arg[0]=ichan; + arg[1]=ichip; + arg[2]=imod; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + receiveChannel(&myChan); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chanregs) { + *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip* + thisDetector->nChips+ichan)=myChan.reg; + } + } + +#ifdef VERBOSE + std::cout<< "Returned channel "<< ichan << " " << ichip << " " << imod << " " + << myChan.reg << std::endl; +#endif + return myChan; +} + + + +int slsDetector::setChip(int reg, int ichip, int imod) { + sls_detector_chip myChip; + +#ifdef VERBOSE + std::cout<< "Setting chip "<< ichip << " " << imod << " to " << reg << std::endl; +#endif + + + int chregs[thisDetector->nChans]; + int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1; + int ret=FAIL; + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + myChip.nchan=thisDetector->nChans; + myChip.reg=reg; + for (int im=mmin; imnChans+im* + thisDetector->nChans*thisDetector->nChips); + else { + for (int i=0; inChans; ++i) + chregs[i]=-1; + myChip.chanregs=chregs; + } + ret=setChip(myChip); + } + } + return ret; +} + +int slsDetector::setChip(sls_detector_chip chip) { + + int fnum=F_SET_CHIP; + int retval; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + int ichi=chip.chip; + int im=chip.module; + + + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendChip(&chip); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chipregs) + *(chipregs+ichi+im*thisDetector->nChips)=retval; + } + +#ifdef VERBOSE + std::cout<< "Chip register returned "<< retval << std::endl; +#endif + return retval; +} + + +slsDetectorDefs::sls_detector_chip slsDetector::getChip(int ichip, int imod) { + + int fnum=F_GET_CHIP; + sls_detector_chip myChip; + int chanreg[thisDetector->nChans]; + + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + + myChip.chip=ichip; + myChip.module=imod; + myChip.nchan=thisDetector->nChans; + myChip.chanregs=chanreg; + + int arg[2]; + arg[0]=ichip; + arg[1]=imod; + + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + receiveChip(&myChip); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chipregs) + *(chipregs+ichip+imod*thisDetector->nChips)=myChip.reg; + if (chanregs) { + for (int ichan=0; ichannChans; ++ichan) + *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip* + thisDetector->nChans+ichan)=*((myChip.chanregs)+ichan); + } + } +#ifdef VERBOSE + std::cout<< "Returned chip "<< ichip << " " << imod << " " << myChip.reg << std::endl; +#endif + + return myChip; +} + + + +int slsDetector::getMoveFlag(int imod) { + if (moveFlag) + return *moveFlag; + else return 1; +} + + +int slsDetector::fillModuleMask(int *mM) { + if (mM) + for (int i=0; ionlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&frames,sizeof(frames)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; +} + + + +int slsDetector::setRateCorrection(double t) { if (getDetectorsType() == EIGER){ int fnum=F_SET_RATE_CORRECT; @@ -5931,7 +7782,8 @@ int slsDetector::setRateCorrection(double t){ thisDetector->tDead=0; } #ifdef VERBOSE - std::cout<< "Setting rate correction with dead time "<< thisDetector->tDead << std::endl; + std::cout<< "Setting rate correction with dead time "<< thisDetector->tDead + << std::endl; #endif } return thisDetector->correctionMask&(1<myDetectorType == EIGER){ t = getRateCorrectionTau(); @@ -5949,7 +7801,8 @@ int slsDetector::getRateCorrection(double &t){ if (thisDetector->correctionMask&(1<tDead << std::endl; + std::cout<< "Rate correction is enabled with dead time "<< + thisDetector->tDead << std::endl; #endif t=thisDetector->tDead; return 1; @@ -5961,16 +7814,16 @@ int slsDetector::getRateCorrection(double &t){ return 0; }; -double slsDetector::getRateCorrectionTau(){ +double slsDetector::getRateCorrectionTau() { if(thisDetector->myDetectorType == EIGER){ int fnum=F_GET_RATE_CORRECT; int ret=FAIL; char mess[MAX_STR_LENGTH]=""; int64_t retval = -1; - #ifdef VERBOSE +#ifdef VERBOSE std::cout<< "Setting Rate Correction to " << arg << endl; - #endif +#endif if (thisDetector->onlineFlag==ONLINE_FLAG) { if (connectControl() == OK){ controlSocket->SendDataOnly(&fnum,sizeof(fnum)); @@ -5994,7 +7847,8 @@ double slsDetector::getRateCorrectionTau(){ //mythen only if (thisDetector->correctionMask&(1<tDead << std::endl; + std::cout<< "Rate correction is enabled with dead time "<< + thisDetector->tDead << std::endl; #endif return thisDetector->tDead; //return 1; @@ -6003,80 +7857,230 @@ double slsDetector::getRateCorrectionTau(){ std::cout<< "Rate correction is disabled " << std::endl; #endif return 0; -}; +} - - - -int slsDetector::getRateCorrection(){ +int slsDetector::getRateCorrection() { if (thisDetector->myDetectorType == EIGER){ double t = getRateCorrectionTau(); return (int)t; } - if (thisDetector->correctionMask&(1<correctionMask&(1<tDead; - double t=thisDetector->timerValue[ACQUISITION_TIME]; - // double data; - double e; - if (thisDetector->correctionMask&(1<tDead; + double t=thisDetector->timerValue[ACQUISITION_TIME]; + // double data; + double e; + if (thisDetector->correctionMask&(1<nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ++ichan) { + for (int ichan=0; ichannMod[X]*thisDetector->nMod[Y]* + thisDetector->nChans*thisDetector->nChips; ++ichan) { - if (errin==NULL) { - e=sqrt(datain[ichan]); - } else - e=errin[ichan]; + if (errin==NULL) { + e=sqrt(datain[ichan]); + } else + e=errin[ichan]; - postProcessingFuncs::rateCorrect(datain[ichan], e, dataout[ichan], errout[ichan], tau, t); - } - } + postProcessingFuncs::rateCorrect(datain[ichan], e, dataout[ichan], + errout[ichan], tau, t); + } + } - return 0; -}; + return 0; +} + + + +int slsDetector::setFlatFieldCorrection(string fname) { + double data[thisDetector->nModMax[X]*thisDetector->nModMax[Y]* + thisDetector->nChans*thisDetector->nChips]; + int im=0; + int nch; + thisDetector->nBadFF=0; + + char ffffname[MAX_STR_LENGTH*2]; + if (fname=="default") { + fname=string(thisDetector->flatFieldFile); + } + + if (fname=="") { +#ifdef VERBOSE + std::cout<< "disabling flat field correction" << std::endl; +#endif + thisDetector->correctionMask&=~(1<flatFieldDir,fname.c_str()); + nch=readDataFile(string(ffffname),data); + if (nch>0) { + + //???? bad ff chans? + int nm=getNMods(); + int chpm[nm]; + int mMask[nm]; + for (int i=0; i=0) { + strcpy(thisDetector->flatFieldFile,fname.c_str()); + + + thisDetector->correctionMask|=(1<correctionMask&(1<nMod[Y]*thisDetector->nMod[X]* + thisDetector->nChans*thisDetector->nChips; ++ichan) { + // #ifdef VERBOSE + // std::cout<< ichan << " "<< corr[ichan] << std::endl; + // #endif + ffcoefficients[ichan]=corr[ichan]; + if (ecorr!=NULL) + fferrors[ichan]=ecorr[ichan]; + else + fferrors[ichan]=1; + + cout << ichan << " " << ffcoefficients[ichan] << endl; + } + thisDetector->correctionMask|=(1<correctionMask&=~(1<correctionMask)& + (1<correctionMask&(1<correctionMask&(1<nMod[X]*thisDetector->nMod[Y]* + thisDetector->nChans*thisDetector->nChips; ++ichan) { + corr[ichan]=ffcoefficients[ichan]; + if (ecorr) { + //ecorr[ichan]=ffcoefficients[ichan]/fferrors[ichan]; + ecorr[ichan]=fferrors[ichan]; + } + } + } + return 1; + } else { +#ifdef VERBOSE + std::cout<< "Flat field correction is disabled" << std::endl; +#endif + if (corr) + for (int ichan=0; ichannMod[X]*thisDetector->nMod[Y]* + thisDetector->nChans*thisDetector->nChips; ++ichan) { + corr[ichan]=1; + if (ecorr) + ecorr[ichan]=0; + } + return 0; + } + +} -int slsDetector::setBadChannelCorrection(string fname){ - // int nbadmod; - int ret=0; - //int badchanlist[MAX_BADCHANS]; - //int off; +int slsDetector::flatFieldCorrect(double* datain, double *errin, double* dataout, + double *errout) { +#ifdef VERBOSE + std::cout<< "Flat field correcting data" << std::endl; +#endif + double e, eo; + if (thisDetector->correctionMask & (1<nMod[X]*thisDetector->nChans* + thisDetector->nChips; ++ichan) { + if (errin==NULL) { + e=0; + } else { + e=errin[ichan]; + } + postProcessingFuncs::flatFieldCorrect(datain[ichan],e,dataout[ichan], + eo,ffcoefficients[ichan],fferrors[ichan]); + if (errout) + errout[ichan]=eo; + } + } + return 0; - string fn=fname; +} - if (fname=="default") - fname=string(badChanFile); - if (nBadChans && badChansList) - ret=setBadChannelCorrection(fname, *nBadChans, badChansList); - if (ret) { - *correctionMask|=(1<0) { - thisDetector->correctionMask|=(1<nBadChans=0; - for (int ich=0 ;ich=0 && chs[ich]badChansList[ich]=chs[ich]; - ++thisDetector->nBadChans; - // cout << "det : " << thisDetector->nBadChans << " " << thisDetector->badChansList[ich] << endl; - } - } - } else - thisDetector->correctionMask&=~(1<0) { - thisDetector->nBadFF=nch; - for (int ich=0 ;ichbadFFList[ich]=chs[ich]; - } - } - } #ifdef VERBOSE - cout << "badchans flag is "<< (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) << endl; + cout << "setting " << nch << " bad chans " << endl; #endif - // fillBadChannelMask(); - if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { - return thisDetector->nBadChans+thisDetector->nBadFF; - } else - return 0; + if (ff==0) { + if (nch0) { + thisDetector->correctionMask|=(1<nBadChans=0; + for (int ich=0 ;ich=0 && chs[ich]badChansList[ich]=chs[ich]; + ++thisDetector->nBadChans; + } + } + } else + thisDetector->correctionMask&=~(1<0) { + thisDetector->nBadFF=nch; + for (int ich=0 ;ichbadFFList[ich]=chs[ich]; + } + } + } +#ifdef VERBOSE + cout << "badchans flag is "<< (thisDetector->correctionMask& + (1<< DISCARD_BAD_CHANNELS)) << endl; +#endif + // fillBadChannelMask(); + if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + return thisDetector->nBadChans+thisDetector->nBadFF; + } else + return 0; } - - - - - - int slsDetector::getBadChannelCorrection(int *bad) { - int ichan; - if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { - if (bad) { - for (ichan=0; ichannBadChans; ++ichan) - bad[ichan]=thisDetector->badChansList[ichan]; - for (int ich=0; ichnBadFF; ++ich) - bad[ichan+ich]=thisDetector->badFFList[ich]; - } - return thisDetector->nBadChans+thisDetector->nBadFF; - } else - return 0; + int ichan; + if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + if (bad) { + for (ichan=0; ichannBadChans; ++ichan) + bad[ichan]=thisDetector->badChansList[ichan]; + for (int ich=0; ichnBadFF; ++ich) + bad[ichan+ich]=thisDetector->badFFList[ich]; + } + return thisDetector->nBadChans+thisDetector->nBadFF; + } else + return 0; } - - - - - - - - -int slsDetector::exitServer(){ - - int retval; - int fnum=F_EXIT_SERVER; - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (controlSocket) { - controlSocket->Connect(); - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - disconnectControl(); - } - } - if (retval!=OK) { - std::cout<< std::endl; - std::cout<< "Shutting down the server" << std::endl; - std::cout<< std::endl; - } - return retval; - -}; - - -string slsDetector::setNetworkParameter(networkParameter index, string value) { - int i; - switch (index) { - case DETECTOR_MAC: - return setDetectorMAC(value); - case DETECTOR_IP: - return setDetectorIP(value); - case RECEIVER_HOSTNAME: - return setReceiver(value); - case RECEIVER_UDP_IP: - return setReceiverUDPIP(value); - case RECEIVER_UDP_MAC: - return setReceiverUDPMAC(value); - case RECEIVER_UDP_PORT: - sscanf(value.c_str(),"%d",&i); - setReceiverUDPPort(i); - return getReceiverUDPPort(); - case RECEIVER_UDP_PORT2: - sscanf(value.c_str(),"%d",&i); - if(thisDetector->myDetectorType == EIGER) { - setReceiverUDPPort2(i); - return getReceiverUDPPort2(); - } else { - setReceiverUDPPort(i); - return getReceiverUDPPort(); - } - case DETECTOR_TXN_DELAY_LEFT: - case DETECTOR_TXN_DELAY_RIGHT: - case DETECTOR_TXN_DELAY_FRAME: - case FLOW_CONTROL_10G: - sscanf(value.c_str(),"%d",&i); - return setDetectorNetworkParameter(index, i); - case CLIENT_STREAMING_PORT: - return setClientStreamingPort(value); - case RECEIVER_STREAMING_PORT: - return setReceiverStreamingPort(value); - case CLIENT_STREAMING_SRC_IP: - return setClientStreamingIP(value); - case RECEIVER_STREAMING_SRC_IP: - return setReceiverStreamingIP(value); - default: - return (char*)("unknown network parameter"); - } - -} - - - -string slsDetector::getNetworkParameter(networkParameter index) { - ostringstream ss;string s; - switch (index) { - case DETECTOR_MAC: - return getDetectorMAC(); - case DETECTOR_IP: - return getDetectorIP(); - case RECEIVER_HOSTNAME: - return getReceiver(); - case RECEIVER_UDP_IP: - return getReceiverUDPIP(); - case RECEIVER_UDP_MAC: - return getReceiverUDPMAC(); - case RECEIVER_UDP_PORT: - return getReceiverUDPPort(); - case RECEIVER_UDP_PORT2: - return getReceiverUDPPort2(); - case DETECTOR_TXN_DELAY_LEFT: - case DETECTOR_TXN_DELAY_RIGHT: - case DETECTOR_TXN_DELAY_FRAME: - case FLOW_CONTROL_10G: - return setDetectorNetworkParameter(index, -1); - case CLIENT_STREAMING_PORT: - return getClientStreamingPort(); - case RECEIVER_STREAMING_PORT: - return getReceiverStreamingPort(); - case CLIENT_STREAMING_SRC_IP: - return getClientStreamingIP(); - case RECEIVER_STREAMING_SRC_IP: - return getReceiverStreamingIP(); - default: - return (char*)("unknown network parameter"); - } - -} - -string slsDetector::setDetectorMAC(string detectorMAC){ - if(detectorMAC.length()==17){ - if((detectorMAC[2]==':')&&(detectorMAC[5]==':')&&(detectorMAC[8]==':')&& - (detectorMAC[11]==':')&&(detectorMAC[14]==':')){ - strcpy(thisDetector->detectorMAC,detectorMAC.c_str()); - if(!strcmp(thisDetector->receiver_hostname,"none")) -#ifdef VERBOSE - std::cout << "Warning: Receiver hostname not set yet." << endl; -#else - ; -#endif - else if(setUDPConnection()==FAIL) - std::cout<< "Warning: UDP connection set up failed" << std::endl; - }else{ - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: server MAC Address should be in xx:xx:xx:xx:xx:xx format" << endl; - } - } - else{ - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: server MAC Address should be in xx:xx:xx:xx:xx:xx format" << std::endl; - } - - return string(thisDetector->detectorMAC); -}; - - - -string slsDetector::setDetectorIP(string detectorIP){ - struct sockaddr_in sa; - //taking function arguments into consideration - if(detectorIP.length()){ - if(detectorIP.length()<16){ - int result = inet_pton(AF_INET, detectorIP.c_str(), &(sa.sin_addr)); - if(result!=0){ - strcpy(thisDetector->detectorIP,detectorIP.c_str()); - if(!strcmp(thisDetector->receiver_hostname,"none")) -#ifdef VERBOSE - std::cout << "Warning: Receiver hostname not set yet." << endl; -#else - ; -#endif - else if(setUDPConnection()==FAIL) - std::cout<< "Warning: UDP connection set up failed" << std::endl; - }else{ - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: Detector IP Address should be VALID and in xxx.xxx.xxx.xxx format" << std::endl; - } - } - } - return string(thisDetector->detectorIP); -} - - - -string slsDetector::setReceiver(string receiverIP){ - - if(receiverIP == "none") { - memset(thisDetector->receiver_hostname, 0, MAX_STR_LENGTH); - strcpy(thisDetector->receiver_hostname,"none"); - thisDetector->receiverOnlineFlag = OFFLINE_FLAG; - return string(thisDetector->receiver_hostname); - } - - if(getRunStatus()==RUNNING){ - cprintf(RED,"Acquisition already running, Stopping it.\n"); - stopAcquisition(); - } - updateDetector(); - - strcpy(thisDetector->receiver_hostname,receiverIP.c_str()); - - if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Setting up receiver with" << endl; - std::cout << "detector type:" << slsDetectorBase::getDetectorType(thisDetector->myDetectorType) << endl; - std::cout << "detector id:" << posId << endl; - std::cout << "detector hostname:" << thisDetector->hostname << endl; - std::cout << "file path:" << fileIO::getFilePath() << endl; - std::cout << "file name:" << fileIO::getFileName() << endl; - std::cout << "file index:" << fileIO::getFileIndex() << endl; - std::cout << "file format:" << fileIO::getFileFormat() << endl; - pthread_mutex_lock(&ms); - std::cout << "write enable:" << parentDet->enableWriteToFileMask() << endl; - std::cout << "overwrite enable:" << parentDet->enableOverwriteMask() << endl; - pthread_mutex_unlock(&ms); - std::cout << "frame index needed:" << ((thisDetector->timerValue[FRAME_NUMBER]*thisDetector->timerValue[CYCLES_NUMBER])>1) << endl; - std::cout << "frame period:" << thisDetector->timerValue[FRAME_PERIOD] << endl; - std::cout << "frame number:" << thisDetector->timerValue[FRAME_NUMBER] << endl; - std::cout << "sub exp time:" << thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME] << endl; - std::cout << "dynamic range:" << thisDetector->dynamicRange << endl << endl; - std::cout << "flippeddatax:" << thisDetector->flippedData[d] << endl; - std::cout << "10GbE:" << thisDetector->tenGigaEnable << endl << endl; - std::cout << "rx streaming source ip:" << thisDetector->receiver_zmqip << endl; - std::cout << "enable gap pixels:" << thisDetector->gappixels << endl; - std::cout << "rx streaming port:" << thisDetector->receiver_zmqport << endl; - std::cout << "r_readfreq:" << thisDetector->receiver_read_freq << endl << endl; - std::cout << "rx_datastream:" << enableDataStreamingFromReceiver(-1) << endl << endl; -/** enable compresison, */ -#endif - if(setDetectorType()!= GENERIC){ - if(!posId) - sendMultiDetectorSize(); - setDetectorId(); - setDetectorHostname(); - setUDPConnection(); - - setFilePath(fileIO::getFilePath()); - setFileName(fileIO::getFileName()); - setFileIndex(fileIO::getFileIndex()); - setFileFormat(fileIO::getFileFormat()); - pthread_mutex_lock(&ms); - int imask = parentDet->enableWriteToFileMask(); - pthread_mutex_unlock(&ms); - enableWriteToFile(imask); - pthread_mutex_lock(&ms); - imask = parentDet->enableOverwriteMask(); - pthread_mutex_unlock(&ms); - overwriteFile(imask); - setTimer(FRAME_PERIOD,thisDetector->timerValue[FRAME_PERIOD]); - setTimer(FRAME_NUMBER,thisDetector->timerValue[FRAME_NUMBER]); - setTimer(ACQUISITION_TIME,thisDetector->timerValue[ACQUISITION_TIME]); - if(thisDetector->myDetectorType == EIGER) - setTimer(SUBFRAME_ACQUISITION_TIME,thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME]); - if(thisDetector->myDetectorType == JUNGFRAUCTB) - setTimer(SAMPLES_JCTB,thisDetector->timerValue[SAMPLES_JCTB]); - setDynamicRange(thisDetector->dynamicRange); - if(thisDetector->myDetectorType == EIGER){ - setFlippedData(X,-1); - activate(-1); - } - - if(thisDetector->myDetectorType == EIGER) - enableTenGigabitEthernet(thisDetector->tenGigaEnable); - - enableGapPixels(enableGapPixels(-1)); - - // data streaming - setReadReceiverFrequency(thisDetector->receiver_read_freq); - setReceiverStreamingPort(getReceiverStreamingPort()); - setReceiverStreamingIP(getReceiverStreamingIP()); - enableDataStreamingFromReceiver(enableDataStreamingFromReceiver(-1)); - } - } - - return string(thisDetector->receiver_hostname); -} - - - - -string slsDetector::setReceiverUDPIP(string udpip){ - struct sockaddr_in sa; - //taking function arguments into consideration - if(udpip.length()){ - if(udpip.length()<16){ - int result = inet_pton(AF_INET, udpip.c_str(), &(sa.sin_addr)); - if(result==0){ - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: Receiver UDP IP Address should be VALID and in xxx.xxx.xxx.xxx format" << std::endl; - }else{ - strcpy(thisDetector->receiverUDPIP,udpip.c_str()); - if(!strcmp(thisDetector->receiver_hostname,"none")) { -#ifdef VERBOSE - std::cout << "Warning: Receiver hostname not set yet." << endl; -#else - ; -#endif - } - else if(setUDPConnection()==FAIL){ - std::cout<< "Warning: UDP connection set up failed" << std::endl; - } - } - } - } - return string(thisDetector->receiverUDPIP); -} - - - - -string slsDetector::setReceiverUDPMAC(string udpmac){ - if(udpmac.length()!=17){ - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: receiver udp mac address should be in xx:xx:xx:xx:xx:xx format" << std::endl; - } - else{ - if((udpmac[2]==':')&&(udpmac[5]==':')&&(udpmac[8]==':')&& - (udpmac[11]==':')&&(udpmac[14]==':')){ - strcpy(thisDetector->receiverUDPMAC,udpmac.c_str()); - if(!strcmp(thisDetector->receiver_hostname,"none")) -#ifdef VERBOSE - std::cout << "Warning: Receiver hostname not set yet." << endl; -#else - ; -#endif - /* else if(setUDPConnection()==FAIL){ commented out to be replaced by user defined udpmac - std::cout<< "Warning: UDP connection set up failed" << std::endl; - }*/ - }else{ - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: receiver udp mac address should be in xx:xx:xx:xx:xx:xx format" << std::endl; - } - } - - - return string(thisDetector->receiverUDPMAC); -} - - - -int slsDetector::setReceiverUDPPort(int udpport){ - thisDetector->receiverUDPPort = udpport; - if(!strcmp(thisDetector->receiver_hostname,"none")) -#ifdef VERBOSE - std::cout << "Warning: Receiver hostname not set yet." << endl; -#else - ; -#endif - else if(setUDPConnection()==FAIL){ - std::cout<< "Warning: UDP connection set up failed" << std::endl; - } - return thisDetector->receiverUDPPort; -} - -int slsDetector::setReceiverUDPPort2(int udpport){ - thisDetector->receiverUDPPort2 = udpport; - if(!strcmp(thisDetector->receiver_hostname,"none")) -#ifdef VERBOSE - std::cout << "Warning: Receiver hostname not set yet." << endl; -#else - ; -#endif - else if(setUDPConnection()==FAIL){ - std::cout<< "Warning: UDP connection set up failed" << std::endl; - } - return thisDetector->receiverUDPPort2; -} - - -string slsDetector::setClientStreamingPort(string port) { - int defaultport = 0; - int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; - int arg = 0; - - //multi command, calculate individual ports - size_t found = port.find("multi"); - if(found != string::npos) { - port.erase(found,5); - sscanf(port.c_str(),"%d",&defaultport); - arg = defaultport + (posId * numsockets); - } - else - sscanf(port.c_str(),"%d",&arg); - thisDetector->zmqport = arg; - - return getClientStreamingPort(); -} - - - - -string slsDetector::setReceiverStreamingPort(string port) { - int defaultport = 0; - int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; - int arg = 0; - - //multi command, calculate individual ports - size_t found = port.find("multi"); - if(found != string::npos) { - port.erase(found,5); - sscanf(port.c_str(),"%d",&defaultport); - arg = defaultport + (posId * numsockets); - } - else - sscanf(port.c_str(),"%d",&arg); - - thisDetector->receiver_zmqport = arg; - - // send to receiver - int fnum=F_SET_RECEIVER_STREAMING_PORT; - int ret = FAIL; - int retval=-1; - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Sending receiver streaming port to receiver " << arg << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendInt(fnum,retval,arg); - disconnectData(); - } - if (ret==FAIL) { - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: Could not set receiver zmq port" << std::endl; - } - if(ret==FORCE_UPDATE) - updateReceiver(); - } - - return getReceiverStreamingPort(); -} - -string slsDetector::setClientStreamingIP(string sourceIP) { - - struct addrinfo *result; - // on failure to convert to a valid ip - if (dataSocket->ConvertHostnameToInternetAddress(sourceIP.c_str(), &result)) { - std::cout << "Warning: Could not convert zmqip into a valid IP" << sourceIP << std::endl; - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - return getClientStreamingIP(); - } - // on success put IP as string into arg - else { - memset(thisDetector->zmqip, 0, MAX_STR_LENGTH); - dataSocket->ConvertInternetAddresstoIpString(result, thisDetector->zmqip, MAX_STR_LENGTH); - } - - return getClientStreamingIP(); -} - - -string slsDetector::setReceiverStreamingIP(string sourceIP) { - - int fnum=F_RECEIVER_STREAMING_SRC_IP; - int ret = FAIL; - char arg[MAX_STR_LENGTH]; - memset(arg,0,sizeof(arg)); - char retval[MAX_STR_LENGTH]; - memset(retval,0, sizeof(retval)); - - // if empty, give rx_hostname - if (sourceIP.empty()) { - if(!strcmp(thisDetector->receiver_hostname,"none")) { - std::cout << "Receiver hostname not set yet. Cannot create rx_zmqip from none\n" << endl; - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - return getReceiverStreamingIP(); - } - sourceIP.assign(thisDetector->receiver_hostname); - } - - // verify the ip - { - struct addrinfo *result; - // on failure to convert to a valid ip - if (dataSocket->ConvertHostnameToInternetAddress(sourceIP.c_str(), &result)) { - std::cout << "Warning: Could not convert rx_zmqip into a valid IP" << sourceIP << std::endl; - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - return getReceiverStreamingIP(); - } - // on success put IP as string into arg - else { - dataSocket->ConvertInternetAddresstoIpString(result, arg, MAX_STR_LENGTH); - } - } - - // set it anyway, else it is lost - memset(thisDetector->receiver_zmqip, 0, MAX_STR_LENGTH); - strcpy(thisDetector->receiver_zmqip, arg); - - - // if zmqip is empty, update it - if (! strlen(thisDetector->zmqip)) - strcpy(thisDetector->zmqip, arg); - - - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Sending receiver streaming source ip to receiver " << arg << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendString(fnum,retval,arg); - disconnectData(); - } - if(ret==FAIL) { - setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); - std::cout << "Warning: Could not set rx_zmqip" << std::endl; - } - if(ret==FORCE_UPDATE) - updateReceiver(); - } - - return getReceiverStreamingIP(); -} - - - -string slsDetector::setDetectorNetworkParameter(networkParameter index, int delay){ - int fnum = F_SET_NETWORK_PARAMETER; - int ret = FAIL; - int retval = -1; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<< "Setting Transmission delay of mode "<< index << " to " << delay << std::endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&index,sizeof(index)); - controlSocket->SendDataOnly(&delay,sizeof(delay)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(DETECTOR_NETWORK_PARAMETER)); - } else - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } -#ifdef VERBOSE - std::cout<< "Speed set to "<< retval << std::endl; -#endif - - ostringstream ss; - ss << retval; - string s = ss.str(); - return s; -} - - -int slsDetector::setUDPConnection(){ - - int ret = FAIL; - int fnum = F_SETUP_RECEIVER_UDP; - char args[3][MAX_STR_LENGTH]; - memset(args,0,sizeof(args)); - char retval[MAX_STR_LENGTH]; - memset(retval,0,sizeof(retval)); - - //called before set up - if(!strcmp(thisDetector->receiver_hostname,"none")){ -#ifdef VERBOSE - std::cout << "Warning: Receiver hostname not set yet." << endl; -#endif - return FAIL; - } - - //if no udp ip given, use hostname - if(!strcmp(thisDetector->receiverUDPIP,"none")){ - //hostname is an ip address - if(strchr(thisDetector->receiver_hostname,'.')!=NULL) - strcpy(thisDetector->receiverUDPIP,thisDetector->receiver_hostname); - //if hostname not ip, convert it to ip - else{ - struct addrinfo *result; - if (!dataSocket->ConvertHostnameToInternetAddress(thisDetector->receiver_hostname, &result)) { - // on success - memset(thisDetector->receiverUDPIP, 0, MAX_STR_LENGTH); - // on failure, back to none - if (dataSocket->ConvertInternetAddresstoIpString(result, thisDetector->receiverUDPIP, MAX_STR_LENGTH)) { - strcpy(thisDetector->receiverUDPIP, "none"); - } - } - } - } - - - //copy arguments to args[][] - strcpy(args[0],thisDetector->receiverUDPIP); - sprintf(args[1],"%d",thisDetector->receiverUDPPort); - sprintf(args[2],"%d",thisDetector->receiverUDPPort2); -#ifdef VERBOSE - std::cout << "Receiver udp ip address: " << thisDetector->receiverUDPIP << std::endl; - std::cout << "Receiver udp port: " << thisDetector->receiverUDPPort << std::endl; - std::cout << "Receiver udp port2: " << thisDetector->receiverUDPPort2 << std::endl; -#endif - - //set up receiver for UDP Connection and get receivermac address - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Setting up UDP Connection for Receiver " << args[0] << "\t" << args[1] << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendUDPDetails(fnum,retval,args); - disconnectData(); - } - if(ret!=FAIL){ - strcpy(thisDetector->receiverUDPMAC,retval); - -#ifdef VERBOSE - std::cout << "Receiver mac address: " << thisDetector->receiverUDPMAC << std::endl; -#endif - if(ret==FORCE_UPDATE) - updateReceiver(); - - //configure detector with udp details, -100 is so it doesnt overwrite the previous value - if(configureMAC()==FAIL){ - setReceiverOnline(OFFLINE_FLAG); - std::cout << "could not configure mac" << endl; - } - } - }else - ret=FAIL; -#ifdef VERBOSE - printReceiverConfiguration(); -#endif - return ret; -} - - - -int slsDetector::configureMAC(){ - int i; - int ret=FAIL; - int fnum=F_CONFIGURE_MAC,fnum2=F_RECEIVER_SHORT_FRAME; - char mess[MAX_STR_LENGTH]=""; - char arg[6][50];memset(arg,0,sizeof(char)*6*50); - int retval=-1; - - // to send 3d positions to detector - bool sendpos = 0; - int pos[3]={0,0,0}; - - // only jungfrau and eiger, send x, y and z in detector udp header - if (thisDetector->myDetectorType == JUNGFRAU || thisDetector->myDetectorType == EIGER) { - sendpos = true; - int max = parentDet->getNumberOfDetectors(X); - if(!posId) { - pos[0] = 0; - pos[1] = 0; - } else { - pos[0] = posId / max; - pos[1] = (posId % max) * ((thisDetector->myDetectorType == EIGER) ? 2 : 1); // for horiz. udp ports - } - } - - - //if udpip wasnt initialized in config file - if(!(strcmp(thisDetector->receiverUDPIP,"none"))){ - //hostname is an ip address - if(strchr(thisDetector->receiver_hostname,'.')!=NULL) - strcpy(thisDetector->receiverUDPIP,thisDetector->receiver_hostname); - //if hostname not ip, convert it to ip - else{ - struct addrinfo *result; - if (!dataSocket->ConvertHostnameToInternetAddress(thisDetector->receiver_hostname, &result)) { - // on success - memset(thisDetector->receiverUDPIP, 0, MAX_STR_LENGTH); - // on failure, back to none - if (dataSocket->ConvertInternetAddresstoIpString(result, thisDetector->receiverUDPIP, MAX_STR_LENGTH)) { - strcpy(thisDetector->receiverUDPIP, "none"); - } - } - } - } - strcpy(arg[0],thisDetector->receiverUDPIP); - strcpy(arg[1],thisDetector->receiverUDPMAC); - sprintf(arg[2],"%x",thisDetector->receiverUDPPort); - strcpy(arg[3],thisDetector->detectorMAC); - strcpy(arg[4],thisDetector->detectorIP); - sprintf(arg[5],"%x",thisDetector->receiverUDPPort2); -#ifdef VERBOSE - std::cout<< "Configuring MAC"<< std::endl; -#endif - - - - for(i=0;i<2;++i){ - if(!strcmp(arg[i],"none")){ - std::cout<< "Configure MAC Error. IP/MAC Addresses not set"<< std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); - return FAIL; - } - } - -#ifdef VERBOSE - std::cout<< "IP/MAC Addresses valid "<< std::endl; -#endif - - - { - //converting IPaddress to hex - stringstream ss(arg[0]); - char cword[50]=""; - bzero(cword, 50); - string s; - while (getline(ss, s, '.')) { - sprintf(cword,"%s%02x",cword,atoi(s.c_str())); - } - bzero(arg[0], 50); - strcpy(arg[0],cword); -#ifdef VERBOSE - std::cout<<"receiver udp ip:"<onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - if(sendpos) - controlSocket->SendDataOnly(pos,sizeof(pos)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); - } - else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - if (thisDetector->myDetectorType == EIGER) { - //rewrite detectormac, detector ip - char arg[2][50]; - memset(arg,0,sizeof(arg)); - uint64_t idetectormac = 0; - uint32_t idetectorip = 0; - controlSocket->ReceiveDataOnly(arg,sizeof(arg)); - sscanf(arg[0], "%lx", &idetectormac); - sscanf(arg[1], "%x", &idetectorip); - sprintf(arg[0],"%02x:%02x:%02x:%02x:%02x:%02x", - (unsigned int)((idetectormac>>40)&0xFF), - (unsigned int)((idetectormac>>32)&0xFF), - (unsigned int)((idetectormac>>24)&0xFF), - (unsigned int)((idetectormac>>16)&0xFF), - (unsigned int)((idetectormac>>8)&0xFF), - (unsigned int)((idetectormac>>0)&0xFF)); - sprintf(arg[1],"%d.%d.%d.%d", - (idetectorip>>24)&0xff, - (idetectorip>>16)&0xff, - (idetectorip>>8)&0xff, - (idetectorip)&0xff); - if (strcasecmp(arg[0],thisDetector->detectorMAC)) { - memset(thisDetector->detectorMAC, 0, MAX_STR_LENGTH); - strcpy(thisDetector->detectorMAC, arg[0]); - cprintf(RESET,"%d: Detector MAC updated to %s\n", detId, thisDetector->detectorMAC); - } - if (strcasecmp(arg[1],thisDetector->detectorIP)) { - memset(thisDetector->detectorIP, 0, MAX_STR_LENGTH); - strcpy(thisDetector->detectorIP, arg[1]); - cprintf(RESET,"%d: Detector IP updated to %s\n", detId, thisDetector->detectorIP); - } - } - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - if (ret==FAIL) { - ret=FAIL; - std::cout<< "Configuring MAC failed " << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); - } - else if (thisDetector->myDetectorType==GOTTHARD){ - //set frames per file - only for gotthard - pthread_mutex_lock(&ms); - if(retval==-1) - setFramesPerFile(MAX_FRAMES_PER_FILE); - else - setFramesPerFile(SHORT_MAX_FRAMES_PER_FILE); - pthread_mutex_unlock(&ms); - //connect to receiver - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Sending adc val to receiver " << retval << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendInt(fnum2,retval,retval); - disconnectData(); - } - if(ret==FAIL) - setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); - } - } - - return ret; -} - - - -//Corrections - - - - - - - -int slsDetector::getAngularConversion(int &direction, angleConversionConstant *angconv) { - direction=thisDetector->angDirection; - if (angconv) { - for (int imod=0; imodnMods; ++imod) { - (angconv+imod)->center=thisDetector->angOff[imod].center; - (angconv+imod)->r_conversion=thisDetector->angOff[imod].r_conversion; - (angconv+imod)->offset=thisDetector->angOff[imod].offset; - (angconv+imod)->ecenter=thisDetector->angOff[imod].ecenter; - (angconv+imod)->er_conversion=thisDetector->angOff[imod].er_conversion; - (angconv+imod)->eoffset=thisDetector->angOff[imod].eoffset; - } - } - if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) { - return 1; - } else { - return 0; - } -} - - - int slsDetector::readAngularConversionFile(string fname) { - return readAngularConversion(fname,thisDetector->nModsMax, thisDetector->angOff); + return readAngularConversion(fname,thisDetector->nModsMax, thisDetector->angOff); } int slsDetector::readAngularConversion(ifstream& ifs) { - return readAngularConversion(ifs,thisDetector->nModsMax, thisDetector->angOff); + return readAngularConversion(ifs,thisDetector->nModsMax, thisDetector->angOff); } int slsDetector:: writeAngularConversion(string fname) { - return writeAngularConversion(fname, thisDetector->nMods, thisDetector->angOff); + return writeAngularConversion(fname, thisDetector->nMods, thisDetector->angOff); } int slsDetector:: writeAngularConversion(ofstream &ofs) { - return writeAngularConversion(ofs, thisDetector->nMods, thisDetector->angOff); + return writeAngularConversion(ofs, thisDetector->nMods, thisDetector->angOff); } - - - - -int slsDetector::loadImageToDetector(imageType index,string const fname){ - - int ret=FAIL; - short int arg[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; - -#ifdef VERBOSE - std::cout<< std::endl<< "Loading "; - if(!index) - std::cout<<"Dark"; - else - std::cout<<"Gain"; - std::cout<<" image from file " << fname << std::endl; -#endif - - if(readDataFile(fname,arg)){ - ret = sendImageToDetector(index,arg); - return ret; - } - std::cout<< "Could not open file "<< fname << std::endl; - return ret; -} - - -int slsDetector::sendImageToDetector(imageType index,short int imageVals[]){ - - int ret=FAIL; - int retval; - int fnum=F_LOAD_IMAGE; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<<"Sending image to detector " <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&index,sizeof(index)); - controlSocket->SendDataOnly(imageVals,thisDetector->dataBytes); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return ret; -} -int slsDetector::getCounterBlock(short int arg[],int startACQ){ - - int ret=FAIL; - int fnum=F_READ_COUNTER_BLOCK; - char mess[MAX_STR_LENGTH]=""; - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&startACQ,sizeof(startACQ)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(arg,thisDetector->dataBytes); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return ret; -} - - -int slsDetector::writeCounterBlockFile(string const fname,int startACQ){ - - int ret=FAIL; - short int counterVals[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; - -#ifdef VERBOSE - std::cout<< std::endl<< "Reading Counter to \""<onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&startACQ,sizeof(startACQ)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return ret; -} - - - -int slsDetector::setCounterBit(int i){ - int fnum=F_SET_COUNTER_BIT; - int ret = FAIL; - int retval=-1; - char mess[MAX_STR_LENGTH]=""; - - if(thisDetector->onlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - if(i ==-1) - std::cout<< "Getting counter bit from detector" << endl; - else if(i==0) - std::cout<< "Resetting counter bit in detector " << endl; - else - std::cout<< "Setting counter bit in detector " << endl; -#endif - if (connectControl() == OK){ - - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&i,sizeof(i)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_SET_COUNTER_BIT)); - } - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - +int slsDetector::getAngularConversion(int &direction, angleConversionConstant *angconv) { + direction=thisDetector->angDirection; + if (angconv) { + for (int imod=0; imodnMods; ++imod) { + (angconv+imod)->center=thisDetector->angOff[imod].center; + (angconv+imod)->r_conversion=thisDetector->angOff[imod].r_conversion; + (angconv+imod)->offset=thisDetector->angOff[imod].offset; + (angconv+imod)->ecenter=thisDetector->angOff[imod].ecenter; + (angconv+imod)->er_conversion=thisDetector->angOff[imod].er_conversion; + (angconv+imod)->eoffset=thisDetector->angOff[imod].eoffset; } } - return retval; + if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) { + return 1; + } else { + return 0; + } } +angleConversionConstant* slsDetector::getAngularConversionPointer(int imod) { + return &thisDetector->angOff[imod]; +} - - -int slsDetector::printReceiverConfiguration(){ +int slsDetector::printReceiverConfiguration() { std::cout << "Detector IP:\t\t" << getNetworkParameter(DETECTOR_IP) << std::endl; std::cout << "Detector MAC:\t\t" << getNetworkParameter(DETECTOR_MAC) << std::endl; @@ -7232,7 +8204,8 @@ int slsDetector::printReceiverConfiguration(){ std::cout << "Receiver UDP Port:\t" << getNetworkParameter(RECEIVER_UDP_PORT) << std::endl; if(thisDetector->myDetectorType == EIGER) - std::cout << "Receiver UDP Port2:\t" << getNetworkParameter(RECEIVER_UDP_PORT2) << std::endl; + std::cout << "Receiver UDP Port2:\t" << getNetworkParameter(RECEIVER_UDP_PORT2) + << std::endl; std::cout << std::endl; return OK; @@ -7240,911 +8213,8 @@ int slsDetector::printReceiverConfiguration(){ -int slsDetector::readConfigurationFile(string const fname){ - - string ans; - string str; - ifstream infile; - //char *args[1000]; - - string sargname, sargval; -#ifdef VERBOSE - int iline=0; - std::cout<< "config file name "<< fname << std::endl; -#endif - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { -#ifdef VERBOSE - iline=readConfigurationFile(infile); -#else - readConfigurationFile(infile); -#endif - infile.close(); - } else { - std::cout<< "Error opening configuration file " << fname << " for reading" << std::endl; - setErrorMask((getErrorMask())|(CONFIG_FILE)); - return FAIL; - } -#ifdef VERBOSE - std::cout<< "Read configuration file of " << iline << " lines" << std::endl; -#endif - return OK; - -} - - -int slsDetector::readConfigurationFile(ifstream &infile){ - - - - - slsDetectorCommand *cmd=new slsDetectorCommand(this); - - string ans; - string str; - int iargval; - int interrupt=0; - char *args[100]; - char myargs[1000][1000]; - - string sargname, sargval; - int iline=0; - while (infile.good() and interrupt==0) { - sargname="none"; - sargval="0"; - getline(infile,str); - ++iline; -#ifdef VERBOSE - std::cout<< str << std::endl; -#endif - if (str.find('#')!=string::npos) { -#ifdef VERBOSE - std::cout<< "Line is a comment " << std::endl; - std::cout<< str << std::endl; -#endif - continue; - } else if (str.length()<2) { -#ifdef VERBOSE - std::cout<< "Empty line " << std::endl; -#endif - continue; - } else { - istringstream ssstr(str); - iargval=0; - while (ssstr.good()) { - ssstr >> sargname; - //if (ssstr.good()) { -#ifdef VERBOSE - std::cout<< iargval << " " << sargname << std::endl; -#endif - strcpy(myargs[iargval],sargname.c_str()); - args[iargval]=myargs[iargval]; - ++iargval; - //} - } - ans=cmd->executeLine(iargval,args,PUT_ACTION); -#ifdef VERBOSE - std::cout<< ans << std::endl; -#endif - } - ++iline; - } - delete cmd; - return OK; - -} - - - - - - - - - - -int slsDetector::writeConfigurationFile(string const fname){ - - ofstream outfile; -#ifdef VERBOSE - int ret; -#endif - outfile.open(fname.c_str(),ios_base::out); - if (outfile.is_open()) { -#ifdef VERBOSE - ret=writeConfigurationFile(outfile); -#else - writeConfigurationFile(outfile); -#endif - outfile.close(); - } - else { - std::cout<< "Error opening configuration file " << fname << " for writing" << std::endl; - setErrorMask((getErrorMask())|(CONFIG_FILE)); - return FAIL; - } -#ifdef VERBOSE - std::cout<< "wrote " <myDetectorType; - string names[100]; - int nvar=0; - - // common config - names[nvar++] = "hostname"; - names[nvar++] = "port"; - names[nvar++] = "stopport"; - names[nvar++] = "settingsdir"; - names[nvar++] = "caldir"; - names[nvar++] = "ffdir"; - names[nvar++] = "outdir"; - names[nvar++] = "angdir"; - names[nvar++] = "moveflag"; - names[nvar++] = "lock"; - - // receiver config - if (type != MYTHEN) { - names[nvar++] = "detectormac"; - names[nvar++] = "detectorip"; - names[nvar++] = "zmqport"; - names[nvar++] = "rx_zmqport"; - names[nvar++] = "zmqip"; - names[nvar++] = "rx_zmqip"; - names[nvar++] = "rx_tcpport"; - names[nvar++] = "rx_udpport"; - names[nvar++] = "rx_udpport2"; - names[nvar++] = "rx_udpip"; - names[nvar++] = "rx_hostname"; - names[nvar++] = "r_readfreq"; - } - - // detector specific config - switch (type) { - case MYTHEN: - names[nvar++] = "nmod"; - names[nvar++] = "waitstates"; - names[nvar++] = "setlength"; - names[nvar++] = "clkdivider"; - names[nvar++] = "extsig"; - break; - case GOTTHARD: - case PROPIX: - names[nvar++] = "extsig"; - names[nvar++] = "vhighvoltage"; - break; - break; - case MOENCH: - names[nvar++] = "extsig"; - names[nvar++] = "vhighvoltage"; - break; - case EIGER: - names[nvar++] = "vhighvoltage"; - names[nvar++] = "trimen"; - names[nvar++] = "iodelay"; - names[nvar++] = "tengiga"; - break; - case JUNGFRAU: - names[nvar++] = "powerchip"; - names[nvar++] = "vhighvoltage"; - break; - case JUNGFRAUCTB: - names[nvar++] = "powerchip"; - names[nvar++] = "vhighvoltage"; - break; - default: - std::cout << "detector type " << getDetectorType(thisDetector->myDetectorType) << " not implemented in writing config file" << std::endl; - nvar = 0; - break; - } - - - - int nsig=4;//-1; - int iv=0; - char *args[100]; - char myargs[100][1000]; - - for (int ia=0; ia<100; ++ia) { - args[ia]=myargs[ia]; - } - - - for (iv=0; iv=0) - outfile << id << ":"; - - outfile << args[0] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; - } - } else { - strcpy(args[0],names[iv].c_str()); - if (id>=0) - outfile << id << ":"; - outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; - } - } - - delete cmd; - return OK; -} - - - - - - - - - - - - - - - -int slsDetector::writeSettingsFile(string fname, int imod, int iodelay, int tau){ - - return writeSettingsFile(fname,thisDetector->myDetectorType, detectorModules[imod], iodelay, tau); - -}; - - - - -int slsDetector::programFPGA(string fname){ - int ret=FAIL; - int fnum=F_PROGRAM_FPGA; - char mess[MAX_STR_LENGTH]=""; - size_t filesize=0; - char* fpgasrc = NULL; - - if(thisDetector->myDetectorType != JUNGFRAU && thisDetector->myDetectorType != JUNGFRAUCTB){ - std::cout << "Not implemented for this detector" << std::endl; - return FAIL; - } - - - //check if it exists - struct stat st; - if(stat(fname.c_str(),&st)){ - std::cout << "Programming file does not exist" << endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } - //create destination file name,replaces original filename with Jungfrau.rawbin - string destfname; - size_t found = fname.find_last_of("/\\"); - if(found == string::npos) - destfname = ""; - else - destfname = fname.substr(0,found+1); - destfname.append("Jungfrau_MCB.rawbin"); -#ifdef VERBOSE - std::cout << "Converting " << fname << " to " << destfname << std::endl; -#endif - int filepos,x,y,i; - FILE* src = fopen(fname.c_str(),"rb"); - FILE* dst = fopen(destfname.c_str(),"wb"); - // Remove header (0...11C) - for (filepos=0; filepos < 0x11C; ++filepos) - fgetc(src); - // Write 0x80 times 0xFF (0...7F) - for (filepos=0; filepos < 0x80; ++filepos) - fputc(0xFF,dst); - // Swap bits and write to file - for (filepos=0x80; filepos < 0x1000000; ++filepos) { - x = fgetc(src); - if (x < 0) break; - y=0; - for (i=0; i < 8; ++i) - y=y| ( (( x & (1<> i) << (7-i) ); // This swaps the bits - fputc(y,dst); - } - if (filepos < 0x1000000){ - std::cout << "Could not convert programming file. EOF before end of flash" << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } -#ifdef VERBOSE - std::cout << "File has been converted to " << destfname << std::endl; -#endif - //loading file to memory - FILE* fp = fopen(destfname.c_str(),"r"); - if(fp == NULL){ - std::cout << "Could not open rawbin file" << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } - if(fseek(fp,0,SEEK_END)){ - std::cout << "Seek error in rawbin file" << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } - filesize = ftell(fp); - if(filesize <= 0){ - std::cout << "Could not get length of rawbin file" << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } - rewind(fp); - fpgasrc = (char*)malloc(filesize+1); - if(fpgasrc == NULL){ - std::cout << "Could not allocate size of program" << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } - if(fread(fpgasrc, sizeof(char), filesize, fp) != filesize){ - std::cout << "Could not read rawbin file" << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } - - if(fclose(fp)){ - std::cout << "Could not close rawbin file" << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - return FAIL; - } -#ifdef VERBOSE - std::cout << "Successfully loaded the rawbin file to program memory" << std::endl; -#endif - - - -#ifdef VERBOSE - std::cout<< "Sending programming binary to detector " << endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum));cprintf(BG_RED,"size of filesize:%lu\n",sizeof(filesize)); - controlSocket->SendDataOnly(&filesize,sizeof(filesize)); - //check opening error - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - filesize = 0; - } - - - //erasing flash - if(ret!=FAIL){ - std::cout<< "This can take awhile. Please be patient..." << endl; - printf("Erasing Flash:%d%%\r",0); - std::cout << flush; - //erasing takes 65 seconds, printing here (otherwise need threads in server-unnecessary) - int count = 66; - while(count>0){ - usleep(1 * 1000 * 1000); - --count; - printf("Erasing Flash:%d%%\r",(int) (((double)(65-count)/65)*100)); - std::cout << flush; - } - std::cout< 0)){ - - unitprogramsize = MAX_FPGAPROGRAMSIZE; //2mb - if(unitprogramsize > filesize) //less than 2mb - unitprogramsize = filesize; -#ifdef VERBOSE - std::cout << "unitprogramsize:" << unitprogramsize << "\t filesize:" << filesize << std::endl; -#endif - controlSocket->SendDataOnly(fpgasrc+currentPointer,unitprogramsize); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - filesize-=unitprogramsize; - currentPointer+=unitprogramsize; - - //print progress - printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100)); - std::cout << flush; - }else{ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - } - } - std::cout<ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - - //remapping stop server - fnum=F_RESET_FPGA; - int stopret; - if (connectStop() == OK){ - stopSocket->SendDataOnly(&fnum,sizeof(fnum)); - stopSocket->ReceiveDataOnly(&stopret,sizeof(stopret)); - disconnectControl(); - } - } - - //free resources - if(fpgasrc != NULL) - free(fpgasrc); - - return ret; -} - - -int slsDetector::resetFPGA(){ - int ret=FAIL; - int fnum=F_RESET_FPGA; - char mess[MAX_STR_LENGTH]=""; - - if(thisDetector->myDetectorType != JUNGFRAU){ - std::cout << "Not implemented for this detector" << std::endl; - return FAIL; - } -#ifdef VERBOSE - std::cout<< "Sending reset to FPGA " << endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - // control server - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(RESET_ERROR)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return ret; - -} - - - -int slsDetector::powerChip(int ival){ - int ret=FAIL; - int fnum=F_POWER_CHIP; - char mess[MAX_STR_LENGTH]=""; - int retval=-1; - - if(thisDetector->myDetectorType != JUNGFRAU && thisDetector->myDetectorType != JUNGFRAUCTB ){ - std::cout << "Not implemented for this detector" << std::endl; - return FAIL; - } -#ifdef VERBOSE - std::cout<< "Sending power on/off/get to the chip " << endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&ival,sizeof(ival)); - //check opening error - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(POWER_CHIP)); - }else - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return retval; - -} - - -int slsDetector::setAutoComparatorDisableMode(int ival){ - int ret=FAIL; - int fnum=F_AUTO_COMP_DISABLE; - char mess[MAX_STR_LENGTH]=""; - int retval=-1; - - if(thisDetector->myDetectorType != JUNGFRAU){ - std::cout << "Not implemented for this detector" << std::endl; - return FAIL; - } -#ifdef VERBOSE - std::cout<< "Enabling/disabling Auto comp disable mode " << endl; -#endif - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&ival,sizeof(ival)); - //check opening error - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(AUTO_COMP_DISABLE)); - }else - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - return retval; - -} - - -int slsDetector::loadSettingsFile(string fname, int imod) { - - sls_detector_module *myMod=NULL; - - int iodelay = -1; - int tau = -1; - - string fn=fname; - fn=fname; - int mmin=0, mmax=setNumberOfModules(); - if (imod>=0) { - mmin=imod; - mmax=imod+1; - } - for (int im=mmin; immyDetectorType) { - case MYTHEN: - if (fname.find(".sn")==string::npos && fname.find(".trim")==string::npos && fname.find(".settings")==string::npos) { - ostfn << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im); - } - break; - case EIGER: - if (fname.find(".sn")==string::npos && fname.find(".trim")==string::npos && fname.find(".settings")==string::npos) { - ostfn << ".sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER, im); - } - break; - default: - break; - } - fn=ostfn.str(); - myMod=readSettingsFile(fn, thisDetector->myDetectorType,iodelay, tau, myMod); - - if (myMod) { - myMod->module=im; - //settings is saved in myMod.reg for all except mythen - if(thisDetector->myDetectorType!=MYTHEN) - myMod->reg=-1; - setModule(*myMod,iodelay,tau,-1,0,0); - deleteModule(myMod); - } else - return FAIL; - } - return OK; -} - - -int slsDetector::saveSettingsFile(string fname, int imod) { - - sls_detector_module *myMod=NULL; - int ret=FAIL; - int iodelay = -1; - int tau = -1; - - int mmin=0, mmax=setNumberOfModules(); - if (imod>=0) { - mmin=imod; - mmax=imod+1; - } - for (int im=mmin; immyDetectorType) { - case MYTHEN: - ostfn << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER,im); - break; - case EIGER: - ostfn << ".sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER); - break; - default: - break; - } - fn=ostfn.str(); - if ((myMod=getModule(im))) { - - if(thisDetector->myDetectorType == EIGER){ - iodelay = (int)setDAC((dacs_t)-1,IO_DELAY,0,-1); - tau = (int64_t)getRateCorrectionTau(); - } - ret=writeSettingsFile(fn, thisDetector->myDetectorType, *myMod, iodelay, tau); - deleteModule(myMod); - } - } - return ret; -} - - - -int slsDetector::setAllTrimbits(int val, int imod){ - int fnum=F_SET_ALL_TRIMBITS; - int retval; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; - -#ifdef VERBOSE - std::cout<< "Setting all trimbits to "<< val << std::endl; -#endif - if (getDetectorsType() == MYTHEN) { - if (val>=0) { - setChannel((val<<((int)TRIMBIT_OFF))|((int)COMPARATOR_ENABLE)); // trimbit scan - } - return val; - } else { - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&val,sizeof(val)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(ALLTIMBITS_NOT_SET)); - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - } - -#ifdef VERBOSE - std::cout<< "All trimbits were set to "<< retval << std::endl; -#endif - return retval; -} - - - - -int slsDetector::loadCalibrationFile(string fname, int imod) { - - if(thisDetector->myDetectorType == EIGER) { - std::cout << "Not required for this detector!" << std::endl; - return FAIL; - } - - sls_detector_module *myMod=NULL; - string fn=fname; - - int* gainval=0; int* offsetval=0; - if(thisDetector->nGain){ - gainval=new int[thisDetector->nGain]; - for(int i=0;inGain;++i) - gainval[i] = -1; - } - if(thisDetector->nOffset){ - offsetval=new int[thisDetector->nOffset]; - for(int i=0;inOffset;++i) - offsetval[i] = -1; - } - - fn=fname; - - - int mmin=0, mmax=setNumberOfModules(); - if (imod>=0) { - mmin=imod; - mmax=imod+1; - } - for (int im=mmin; immyDetectorType) { - case MYTHEN: - if (fname.find(".sn")==string::npos && fname.find(".cal")==string::npos) { - ostfn << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im); - } - break; - case EIGER: - if (fname.find(".sn")==string::npos && fname.find(".cal")==string::npos) { - ostfn << "." << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER); - } - break; - default: - break; - } - fn=ostfn.str(); - if((myMod=getModule(im))){ - //extra gain and offset - if(thisDetector->nGain){ - if(readCalibrationFile(fn, gainval, offsetval)==FAIL) - return FAIL; - } //normal gain and offset inside sls_detector_module - else{ - if(readCalibrationFile(fn,myMod->gain, myMod->offset)==FAIL) - return FAIL; - } - setModule(*myMod,-1,-1,-1,gainval,offsetval); - - deleteModule(myMod); - if(gainval) delete[]gainval; - if(offsetval) delete[] offsetval; - } else - return FAIL; - } - return OK; -} - - -int slsDetector::saveCalibrationFile(string fname, int imod) { - - - sls_detector_module *myMod=NULL; - int ret=FAIL; - - int mmin=0, mmax=setNumberOfModules(); - if (imod>=0) { - mmin=imod; - mmax=imod+1; - } - for (int im=mmin; immyDetectorType) { - case MYTHEN: - ostfn << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER,im); - break; - case EIGER: - ostfn << ".sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER); - break; - default: - break; - } - fn=ostfn.str(); - if ((myMod=getModule(im))) { - //extra gain and offset - if(thisDetector->nGain) - ret=writeCalibrationFile(fn,gain, offset); - //normal gain and offset inside sls_detector_module - else - ret=writeCalibrationFile(fn,myMod->gain, myMod->offset); - - deleteModule(myMod); - }else - return FAIL; - } - return ret; -} - - - - -/* returns if the detector is Master, slave or nothing - \param flag can be GET_MASTER, NO_MASTER, IS_MASTER, IS_SLAVE - \returns master flag of the detector -*/ -slsDetectorDefs::masterFlags slsDetector::setMaster(masterFlags flag) { - - - int fnum=F_SET_MASTER; - masterFlags retval=GET_MASTER; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; - -#ifdef VERBOSE - std::cout<< "Setting master flags to "<< flag << std::endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&flag,sizeof(flag)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - -#ifdef VERBOSE - std::cout<< "Master flag set to "<< retval << std::endl; -#endif - return retval; -} - - - - -/* - Sets/gets the synchronization mode of the various detectors - \param sync syncronization mode can be GET_SYNCHRONIZATION_MODE, NO_SYNCHRONIZATION, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS - \returns current syncronization mode -*/ -slsDetectorDefs::synchronizationMode slsDetector::setSynchronization(synchronizationMode flag) { - - - - int fnum=F_SET_SYNCHRONIZATION_MODE; - synchronizationMode retval=GET_SYNCHRONIZATION_MODE; - char mess[MAX_STR_LENGTH]=""; - int ret=OK; - -#ifdef VERBOSE - std::cout<< "Setting synchronization mode to "<< flag << std::endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&flag,sizeof(flag)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - -#ifdef VERBOSE - std::cout<< "Readout flag set to "<< retval << std::endl; -#endif - return retval; - -} - - - - - - - - - - -/*receiver*/ int slsDetector::setReceiverOnline(int off) { if (off!=GET_ONLINE_FLAG) { // no receiver @@ -8169,108 +8239,390 @@ int slsDetector::setReceiverOnline(int off) { string slsDetector::checkReceiverOnline() { - string retval = ""; - //if it doesnt exits, create data socket - if(!dataSocket){ - //this already sets the online/offline flag - setReceiverTCPSocket(); - if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG) - return string(thisDetector->receiver_hostname); - else - return string(""); - } - //still cannot connect to socket, dataSocket=0 - if(dataSocket){ - if (connectData() == FAIL) { - dataSocket->SetTimeOut(5); - thisDetector->receiverOnlineFlag=OFFLINE_FLAG; - delete dataSocket; - dataSocket=NULL; + string retval = ""; + //if it doesnt exits, create data socket + if(!dataSocket){ + //this already sets the online/offline flag + setReceiverTCPSocket(); + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG) + return string(thisDetector->receiver_hostname); + else + return string(""); + } + //still cannot connect to socket, dataSocket=0 + if(dataSocket){ + if (connectData() == FAIL) { + dataSocket->SetTimeOut(5); + thisDetector->receiverOnlineFlag=OFFLINE_FLAG; + delete dataSocket; + dataSocket=NULL; #ifdef VERBOSE - std::cout<< "receiver offline!" << std::endl; + std::cout<< "receiver offline!" << std::endl; #endif - return string(thisDetector->receiver_hostname); - } else { - thisDetector->receiverOnlineFlag=ONLINE_FLAG; - dataSocket->SetTimeOut(100); - disconnectData(); + return string(thisDetector->receiver_hostname); + } else { + thisDetector->receiverOnlineFlag=ONLINE_FLAG; + dataSocket->SetTimeOut(100); + disconnectData(); #ifdef VERBOSE - std::cout<< "receiver online!" << std::endl; + std::cout<< "receiver online!" << std::endl; #endif - return string(""); - } - } - return retval; + return string(""); + } + } + return retval; } -int slsDetector::setReceiverTCPSocket(string const name, int const receiver_port){ +int slsDetector::setReceiverTCPSocket(string const name, int const receiver_port) { - char thisName[MAX_STR_LENGTH]; - int thisRP; - int retval=OK; + char thisName[MAX_STR_LENGTH]; + int thisRP; + int retval=OK; - //if receiver ip given - if (strcmp(name.c_str(),"")!=0) { + //if receiver ip given + if (strcmp(name.c_str(),"")!=0) { #ifdef VERBOSE - std::cout<< "setting receiver" << std::endl; + std::cout<< "setting receiver" << std::endl; #endif - strcpy(thisName,name.c_str()); - strcpy(thisDetector->receiver_hostname,thisName); - if (dataSocket){ - delete dataSocket; - dataSocket=NULL; - } - } else - strcpy(thisName,thisDetector->receiver_hostname); + strcpy(thisName,name.c_str()); + strcpy(thisDetector->receiver_hostname,thisName); + if (dataSocket){ + delete dataSocket; + dataSocket=NULL; + } + } else + strcpy(thisName,thisDetector->receiver_hostname); - //if receiverTCPPort given - if (receiver_port>0) { + //if receiverTCPPort given + if (receiver_port>0) { #ifdef VERBOSE - std::cout<< "setting data port" << std::endl; + std::cout<< "setting data port" << std::endl; #endif - thisRP=receiver_port; - thisDetector->receiverTCPPort=thisRP; - if (dataSocket){ - delete dataSocket; - dataSocket=NULL; - } - } else - thisRP=thisDetector->receiverTCPPort; + thisRP=receiver_port; + thisDetector->receiverTCPPort=thisRP; + if (dataSocket){ + delete dataSocket; + dataSocket=NULL; + } + } else + thisRP=thisDetector->receiverTCPPort; - //create data socket - if (!dataSocket) { - dataSocket=new MySocketTCP(thisName, thisRP); - if (dataSocket->getErrorStatus()){ + //create data socket + if (!dataSocket) { + dataSocket=new MySocketTCP(thisName, thisRP); + if (dataSocket->getErrorStatus()){ #ifdef VERBOSE - std::cout<< "Could not connect Data socket "<receiverOnlineFlag=OFFLINE_FLAG; -#ifdef VERBOSE - std::cout<< "offline!" << std::endl; -#endif - } - thisReceiver->setSocket(dataSocket); - return retval; -}; + } + //check if it connects + if (retval!=FAIL) { + checkReceiverOnline(); + thisReceiver->setSocket(dataSocket); + // check for version compatibility + switch (thisDetector->myDetectorType) { + case EIGER: + case JUNGFRAU: + case GOTTHARD: + if (thisDetector->receiverAPIVersion == 0){ + if (checkVersionCompatibility(DATA_PORT) == FAIL) + thisDetector->receiverOnlineFlag=OFFLINE_FLAG; + } + break; + default: + break; + } + } else { + thisDetector->receiverOnlineFlag=OFFLINE_FLAG; +#ifdef VERBOSE + std::cout<< "offline!" << std::endl; +#endif + } + return retval; +} + + + +int slsDetector::lockReceiver(int lock) { + int fnum=F_LOCK_RECEIVER; + int ret = FAIL; + int retval=-1; + int arg=lock; + + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Locking or Unlocking Receiver " << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return retval; +} + + + + + + +string slsDetector::getReceiverLastClientIP() { + int fnum=F_GET_LAST_RECEIVER_CLIENT_IP; + int ret = FAIL; + char retval[INET_ADDRSTRLEN]=""; + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Geting Last Client IP connected to Receiver " << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->getLastClientIP(fnum,retval); + disconnectData(); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return string(retval); +} + + +int slsDetector::exitReceiver() { + + int retval; + int fnum=F_EXIT_RECEIVER; + + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + if (dataSocket) { + dataSocket->Connect(); + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectData(); + } + } + if (retval!=OK) { + std::cout<< std::endl; + std::cout<< "Shutting down the receiver" << std::endl; + std::cout<< std::endl; + } + return retval; + +} + + +int slsDetector::updateReceiverNoWait() { + + int n = 0,ind; + char path[MAX_STR_LENGTH]; + char lastClientIP[INET_ADDRSTRLEN]; + + n += dataSocket->ReceiveDataOnly(lastClientIP,sizeof(lastClientIP)); +#ifdef VERBOSE + cout << "Updating receiver last modified by " << lastClientIP << std::endl; +#endif + + // filepath + n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); + pthread_mutex_lock(&ms); + fileIO::setFilePath(path); + pthread_mutex_unlock(&ms); + + // filename + n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); + pthread_mutex_lock(&ms); + fileIO::setFileName(path); + pthread_mutex_unlock(&ms); + + // index + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + pthread_mutex_lock(&ms); + fileIO::setFileIndex(ind); + pthread_mutex_unlock(&ms); + + //file format + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + pthread_mutex_lock(&ms); + fileIO::setFileFormat(ind); + pthread_mutex_unlock(&ms); + + // frames per file + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->receiver_framesPerFile = ind; + + // frame discard policy + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->receiver_frameDiscardMode = (frameDiscardPolicy)ind; + + // frame padding + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->receiver_framePadding = ind; + + // file write enable + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + pthread_mutex_lock(&ms); + multiDet->enableWriteToFileMask(ind); + pthread_mutex_unlock(&ms); + + // file overwrite enable + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + pthread_mutex_lock(&ms); + multiDet->enableOverwriteMask(ind); + pthread_mutex_unlock(&ms); + + // gap pixels + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->gappixels = ind; + + // receiver read frequency + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->receiver_read_freq = ind; + + // receiver streaming port + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->receiver_zmqport = ind; + + // streaming source ip + n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); + strcpy(thisDetector->receiver_zmqip, path); + + // additional json header + n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); + strcpy(thisDetector->receiver_additionalJsonHeader, path); + + // receiver streaming enable + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->receiver_upstream = ind; + + + + if (!n) printf("n: %d\n", n); + + return OK; + +} + + + + + +int slsDetector::updateReceiver() { + int fnum=F_UPDATE_RECEIVER_CLIENT; + int ret=OK; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { + if (connectData() == OK){ + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) { + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + else + updateReceiverNoWait(); + + //if ret is force update, do not update now as client is updating + //receiver currently + disconnectData(); + } + } + + return ret; +} + + + +void slsDetector::sendMultiDetectorSize() { + int fnum=F_SEND_RECEIVER_MULTIDETSIZE; + int ret = FAIL; + int retval = -1; + int arg[2]; + + pthread_mutex_lock(&ms); + multiDet->getNumberOfDetectors(arg[0],arg[1]); + pthread_mutex_unlock(&ms); + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending multi detector size to Receiver (" << arg[0] << "," + << arg[1] << ")" << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendIntArray(fnum,retval,arg); + disconnectData(); + } + if((ret==FAIL)){ + std::cout << "Could not set position Id" << std::endl; + setErrorMask((getErrorMask())|(RECEIVER_MULTI_DET_SIZE_NOT_SET)); + } + } +} + + +void slsDetector::setDetectorId() { + int fnum=F_SEND_RECEIVER_DETPOSID; + int ret = FAIL; + int retval = -1; + int arg = detId; + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending detector pos id to Receiver " << detId << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if((ret==FAIL) || (retval != arg)){ + std::cout << "Could not set position Id" << std::endl; + setErrorMask((getErrorMask())|(RECEIVER_DET_POSID_NOT_SET)); + } + } +} + + +void slsDetector::setDetectorHostname() { + int fnum=F_SEND_RECEIVER_DETHOSTNAME; + int ret = FAIL; + char retval[MAX_STR_LENGTH]=""; + + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending detector hostname to Receiver " << + thisDetector->hostname << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendString(fnum,retval,thisDetector->hostname); + disconnectData(); + } + if((ret==FAIL) || (strcmp(retval,thisDetector->hostname))) + setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTNAME_NOT_SET)); + } +} + + +string slsDetector::getFilePath() { + return setFilePath(); +} @@ -8326,6 +8678,9 @@ string slsDetector::setFilePath(string s) { } +string slsDetector::getFileName() { + return setFileName(); +} string slsDetector::setFileName(string s) { int fnum=F_SET_RECEIVER_FILE_NAME; @@ -8337,7 +8692,7 @@ string slsDetector::setFileName(string s) { /*if(!s.empty()){ pthread_mutex_lock(&ms); fileIO::setFileName(s); - s=parentDet->createReceiverFilePrefix(); + s=multiDet->createReceiverFilePrefix(); pthread_mutex_unlock(&ms); }*/ @@ -8356,7 +8711,7 @@ string slsDetector::setFileName(string s) { #endif /* pthread_mutex_lock(&ms); - fileIO::setFileName(parentDet->getNameFromReceiverFilePrefix(string(retval))); + fileIO::setFileName(multiDet->getNameFromReceiverFilePrefix(string(retval))); pthread_mutex_unlock(&ms); */ sretval = fileIO::getNameFromReceiverFilePrefix(string(retval)); @@ -8367,25 +8722,105 @@ string slsDetector::setFileName(string s) { return sretval; } else { - if(!s.empty()){ - pthread_mutex_lock(&ms); - fileIO::setFileName(s); - pthread_mutex_unlock(&ms); - } - pthread_mutex_lock(&ms); - s = fileIO::getFileName(); - pthread_mutex_unlock(&ms); + if(!s.empty()){ + pthread_mutex_lock(&ms); + fileIO::setFileName(s); + pthread_mutex_unlock(&ms); + } + pthread_mutex_lock(&ms); + s = fileIO::getFileName(); + pthread_mutex_unlock(&ms); - return s; + return s; } } +int slsDetector::setReceiverFramesPerFile(int f) { + int fnum = F_SET_RECEIVER_FRAMES_PER_FILE; + int ret = FAIL; + int retval = -1; + int arg = f; -slsReceiverDefs::fileFormat slsDetector::setFileFormat(fileFormat f){ + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending frames per file to receiver " << arg << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if(ret==FAIL) + setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET)); + else if(ret!=FAIL && retval > -1){ + thisDetector->receiver_framesPerFile = retval; + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return thisDetector->receiver_framesPerFile; +} + + +slsReceiverDefs::frameDiscardPolicy slsDetector::setReceiverFramesDiscardPolicy(frameDiscardPolicy f) { + int fnum = F_RECEIVER_DISCARD_POLICY; + int ret = FAIL; + int retval = -1; + int arg = f; + + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending frames discard policy to receiver " << arg << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if(ret==FAIL) + setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET)); + else if(ret!=FAIL && retval > -1){ + thisDetector->receiver_frameDiscardMode = (frameDiscardPolicy)retval; + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return thisDetector->receiver_frameDiscardMode; +} + +int slsDetector::setReceiverPartialFramesPadding(int f) { + int fnum = F_RECEIVER_PADDING_ENABLE; + int ret = FAIL; + int retval = -1; + int arg = f; + + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending partial frames enable to receiver " << arg << std::endl; +#endif + if (connectData() == OK){ + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + } + if(ret==FAIL) + setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET)); + else if(ret!=FAIL && retval > -1){ + thisDetector->receiver_framePadding = (bool)retval; + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return thisDetector->receiver_framePadding; +} + +slsReceiverDefs::fileFormat slsDetector::setFileFormat(fileFormat f) { int fnum=F_SET_RECEIVER_FILE_FORMAT; int ret = FAIL; int arg = -1; @@ -8426,7 +8861,13 @@ slsReceiverDefs::fileFormat slsDetector::setFileFormat(fileFormat f){ +slsReceiverDefs::fileFormat slsDetector::getFileFormat() { + return setFileFormat(); +} +int slsDetector::getFileIndex() { + return setFileIndex(); +} int slsDetector::setFileIndex(int i) { int fnum=F_SET_RECEIVER_FILE_INDEX; @@ -8466,7 +8907,8 @@ int slsDetector::setFileIndex(int i) { -int slsDetector::startReceiver(){ + +int slsDetector::startReceiver() { int fnum=F_START_RECEIVER; int ret = FAIL; char mess[MAX_STR_LENGTH] = ""; @@ -8494,7 +8936,8 @@ int slsDetector::startReceiver(){ // tell detector to send to receiver (if start receiver failed, this is not executed) - if(((thisDetector->myDetectorType == GOTTHARD || thisDetector->myDetectorType == PROPIX) && ret!= FAIL)) + if(((thisDetector->myDetectorType == GOTTHARD || + thisDetector->myDetectorType == PROPIX) && ret!= FAIL)) return prepareAcquisition(); // send data to receiver for these detectors @@ -8504,13 +8947,15 @@ int slsDetector::startReceiver(){ -int slsDetector::stopReceiver(){ +int slsDetector::stopReceiver() { int fnum=F_STOP_RECEIVER; int ret = FAIL; char mess[MAX_STR_LENGTH] = ""; - if(thisDetector->myDetectorType == GOTTHARD || thisDetector->myDetectorType == PROPIX) - cleanupAcquisition(); // reset (send data to receiver) for these detectors, so back to CPU (dont care about ok/fail at this point) + if(thisDetector->myDetectorType == GOTTHARD || + thisDetector->myDetectorType == PROPIX) + cleanupAcquisition(); // reset (send data to receiver) for these detectors, + //so back to CPU (dont care about ok/fail at this point) if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { #ifdef VERBOSE @@ -8532,7 +8977,7 @@ int slsDetector::stopReceiver(){ -slsDetectorDefs::runStatus slsDetector::startReceiverReadout(){ +slsDetectorDefs::runStatus slsDetector::startReceiverReadout() { int fnum=F_START_RECEIVER_READOUT; int ret = FAIL; int retval=-1; @@ -8559,7 +9004,7 @@ slsDetectorDefs::runStatus slsDetector::startReceiverReadout(){ -slsDetectorDefs::runStatus slsDetector::getReceiverStatus(){ +slsDetectorDefs::runStatus slsDetector::getReceiverStatus() { int fnum=F_GET_RECEIVER_STATUS; int ret = FAIL; int retval=-1; @@ -8585,7 +9030,7 @@ slsDetectorDefs::runStatus slsDetector::getReceiverStatus(){ -int slsDetector::getFramesCaughtByReceiver(){ +int slsDetector::getFramesCaughtByReceiver() { int fnum=F_GET_RECEIVER_FRAMES_CAUGHT; int ret = FAIL; int retval=-1; @@ -8607,7 +9052,13 @@ int slsDetector::getFramesCaughtByReceiver(){ -int slsDetector::getReceiverCurrentFrameIndex(){ +int slsDetector::getFramesCaughtByAnyReceiver() { + return getFramesCaughtByReceiver(); +} + + + +int slsDetector::getReceiverCurrentFrameIndex() { int fnum=F_GET_RECEIVER_FRAME_INDEX; int ret = FAIL; int retval=-1; @@ -8630,7 +9081,7 @@ int slsDetector::getReceiverCurrentFrameIndex(){ -int slsDetector::resetFramesCaught(){ +int slsDetector::resetFramesCaught() { int fnum=F_RESET_RECEIVER_FRAMES_CAUGHT; int ret = FAIL; char mess[MAX_STR_LENGTH] = ""; @@ -8651,241 +9102,15 @@ int slsDetector::resetFramesCaught(){ } -// int* slsDetector::readFrameFromReceiver(char* fName, int &acquisitionIndex, int &frameIndex, int &subFrameIndex){ -// int fnum=F_READ_RECEIVER_FRAME; -// int nel=thisDetector->dataBytes/sizeof(int); -// int* retval=new int[nel]; -// int ret=FAIL; -// int n; -// char mess[MAX_STR_LENGTH]="Nothing"; -// if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { -// #ifdef VERBOSE -// std::cout<< "slsDetector: Reading frame from receiver "<< thisDetector->dataBytes << " " <SendDataOnly(&fnum,sizeof(fnum)); -// dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); -// if (ret==FAIL) { -// n= dataSocket->ReceiveDataOnly(mess,sizeof(mess)); -// std::cout<< "Detector returned: " << mess << " " << n << std::endl; -// delete [] retval; -// disconnectData(); -// return NULL; -// } else { -// n=dataSocket->ReceiveDataOnly(fName,MAX_STR_LENGTH); -// n=dataSocket->ReceiveDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); -// n=dataSocket->ReceiveDataOnly(&frameIndex,sizeof(frameIndex)); -// if(thisDetector->myDetectorType == EIGER) -// n=dataSocket->ReceiveDataOnly(&subFrameIndex,sizeof(subFrameIndex)); -// n=dataSocket->ReceiveDataOnly(retval,thisDetector->dataBytes); -// #ifdef VERBOSE -// std::cout<< "Received "<< n << " data bytes" << std::endl; -// #endif -// if (n!=thisDetector->dataBytes) { -// std::cout<dataBytes << std::endl; -// ret=FAIL; -// delete [] retval; -// disconnectData(); -// return NULL; } -// //jungfrau masking adcval -// if(thisDetector->myDetectorType == JUNGFRAU){ -// for(unsigned int i=0;ireceiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Locking or Unlocking Receiver " << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendInt(fnum,retval,arg); - disconnectData(); - } - if(ret==FORCE_UPDATE) - updateReceiver(); - } - - return retval; -} -string slsDetector::getReceiverLastClientIP(){ - int fnum=F_GET_LAST_RECEIVER_CLIENT_IP; - int ret = FAIL; - char retval[INET_ADDRSTRLEN]=""; - - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Geting Last Client IP connected to Receiver " << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->getLastClientIP(fnum,retval); - disconnectData(); - } - if(ret==FORCE_UPDATE) - updateReceiver(); - } - - return string(retval); -} - - - -int slsDetector::updateReceiverNoWait() { - - int n = 0,ind; - char path[MAX_STR_LENGTH]; - char lastClientIP[INET_ADDRSTRLEN]; - - n += dataSocket->ReceiveDataOnly(lastClientIP,sizeof(lastClientIP)); -#ifdef VERBOSE - cout << "Updating receiver last modified by " << lastClientIP << std::endl; -#endif - - // filepath - n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); - pthread_mutex_lock(&ms); - fileIO::setFilePath(path); - pthread_mutex_unlock(&ms); - - // filename - n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); - pthread_mutex_lock(&ms); - fileIO::setFileName(path); - pthread_mutex_unlock(&ms); - - // index - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - pthread_mutex_lock(&ms); - fileIO::setFileIndex(ind); - pthread_mutex_unlock(&ms); - - //file format - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - pthread_mutex_lock(&ms); - fileIO::setFileFormat(ind); - pthread_mutex_unlock(&ms); - - // file write enable - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - pthread_mutex_lock(&ms); - parentDet->enableWriteToFileMask(ind); - pthread_mutex_unlock(&ms); - - // file overwrite enable - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - pthread_mutex_lock(&ms); - parentDet->enableOverwriteMask(ind); - pthread_mutex_unlock(&ms); - - // receiver read frequency - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - thisDetector->receiver_read_freq = ind; - - // receiver streaming port - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - thisDetector->receiver_zmqport = ind; - - // receiver streaming enable - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - thisDetector->receiver_upstream = ind; - - // streaming source ip - n += dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); - strcpy(thisDetector->receiver_zmqip, path); - - // gap pixels - n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - thisDetector->gappixels = ind; - - if (!n) printf("n: %d\n", n); - - return OK; - -} - - - - - -int slsDetector::updateReceiver() { - int fnum=F_UPDATE_RECEIVER_CLIENT; - int ret=OK; - char mess[MAX_STR_LENGTH]=""; - - if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { - if (connectData() == OK){ - dataSocket->SendDataOnly(&fnum,sizeof(fnum)); - dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret == FAIL) { - dataSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; - } - else - updateReceiverNoWait(); - - //if ret is force update, do not update now as client is updating receiver currently - disconnectData(); - } - } - - return ret; -} - - - - - - -int slsDetector::exitReceiver(){ - - int retval; - int fnum=F_EXIT_RECEIVER; - - if (thisDetector->receiverOnlineFlag==ONLINE_FLAG) { - if (dataSocket) { - dataSocket->Connect(); - dataSocket->SendDataOnly(&fnum,sizeof(fnum)); - dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); - disconnectData(); - } - } - if (retval!=OK) { - std::cout<< std::endl; - std::cout<< "Shutting down the receiver" << std::endl; - std::cout<< std::endl; - } - return retval; - -} - - - - - -int slsDetector::enableWriteToFile(int enable){ +int slsDetector::enableWriteToFile(int enable) { int fnum=F_ENABLE_RECEIVER_FILE_WRITE; int ret = FAIL; int retval=-1; @@ -8895,7 +9120,7 @@ int slsDetector::enableWriteToFile(int enable){ if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ if(enable>=0){ pthread_mutex_lock(&ms); - parentDet->enableWriteToFileMask(enable); + multiDet->enableWriteToFileMask(enable); pthread_mutex_unlock(&ms); } } @@ -8910,7 +9135,7 @@ int slsDetector::enableWriteToFile(int enable){ } if(ret!=FAIL){ pthread_mutex_lock(&ms); - parentDet->enableWriteToFileMask(retval); + multiDet->enableWriteToFileMask(retval); pthread_mutex_unlock(&ms); } if(ret==FORCE_UPDATE) @@ -8918,7 +9143,7 @@ int slsDetector::enableWriteToFile(int enable){ } pthread_mutex_lock(&ms); - retval = parentDet->enableWriteToFileMask(); + retval = multiDet->enableWriteToFileMask(); pthread_mutex_unlock(&ms); return retval; @@ -8927,7 +9152,7 @@ int slsDetector::enableWriteToFile(int enable){ -int slsDetector::overwriteFile(int enable){ +int slsDetector::overwriteFile(int enable) { int fnum=F_ENABLE_RECEIVER_OVERWRITE; int ret = FAIL; int retval=-1; @@ -8936,8 +9161,8 @@ int slsDetector::overwriteFile(int enable){ if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ if(enable>=0){ - pthread_mutex_lock(&ms); - parentDet->enableOverwriteMask(enable); + pthread_mutex_lock(&ms); + multiDet->enableOverwriteMask(enable); pthread_mutex_unlock(&ms); } } @@ -8952,7 +9177,7 @@ int slsDetector::overwriteFile(int enable){ } if(ret!=FAIL){ pthread_mutex_lock(&ms); - parentDet->enableOverwriteMask(retval); + multiDet->enableOverwriteMask(retval); pthread_mutex_unlock(&ms); } if(ret==FORCE_UPDATE) @@ -8960,7 +9185,7 @@ int slsDetector::overwriteFile(int enable){ } pthread_mutex_lock(&ms); - retval = parentDet->enableOverwriteMask(); + retval = multiDet->enableOverwriteMask(); pthread_mutex_unlock(&ms); return retval; @@ -8971,54 +9196,14 @@ int slsDetector::overwriteFile(int enable){ -int slsDetector::calibratePedestal(int frames){ - int ret=FAIL; - int retval=-1; - int fnum=F_CALIBRATE_PEDESTAL; - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<<"Calibrating Pedestal " <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&frames,sizeof(frames)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return retval; -} -int64_t slsDetector::clearAllErrorMask(){ - clearErrorMask(); - - pthread_mutex_lock(&ms); - for(int i=0;igetNumberOfDetectors();++i){ - if(parentDet->getDetectorId(i) == getDetectorId()) - parentDet->setErrorMask(parentDet->getErrorMask()|(0<= 0) { thisDetector->receiver_read_freq = freq; @@ -9037,7 +9222,8 @@ int slsDetector::setReadReceiverFrequency(int freq){ disconnectData(); } if((ret == FAIL) || (retval != freq)) { - cout << "could not set receiver read frequency to " << freq <<" Returned:" << retval << endl; + cout << "could not set receiver read frequency to " << freq + <<" Returned:" << retval << endl; setErrorMask((getErrorMask())|(RECEIVER_READ_FREQUENCY)); } @@ -9051,7 +9237,7 @@ int slsDetector::setReadReceiverFrequency(int freq){ -int slsDetector::setReceiverReadTimer(int time_in_ms){ +int slsDetector::setReceiverReadTimer(int time_in_ms) { int fnum=F_READ_RECEIVER_TIMER; int ret = FAIL; int arg = time_in_ms; @@ -9070,15 +9256,24 @@ int slsDetector::setReceiverReadTimer(int time_in_ms){ } if ((time_in_ms > 0) && (retval != time_in_ms)){ - cout << "could not set receiver read timer to " << time_in_ms <<" Returned:" << retval << endl; + cout << "could not set receiver read timer to " << time_in_ms + <<" Returned:" << retval << endl; setErrorMask((getErrorMask())|(RECEIVER_READ_TIMER)); } return retval; } +int slsDetector::enableDataStreamingToClient(int enable) { + cprintf(RED,"ERROR: Must be called from the multi Detector level\n"); + return 0; +} -int slsDetector::enableDataStreamingFromReceiver(int enable){ + + + + +int slsDetector::enableDataStreamingFromReceiver(int enable) { if (enable >= 0) { int fnum=F_STREAM_DATA_FROM_RECEIVER; @@ -9089,7 +9284,8 @@ int slsDetector::enableDataStreamingFromReceiver(int enable){ if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ #ifdef VERBOSE - std::cout << "***************Sending Data Streaming in Receiver " << arg << std::endl; + std::cout << "***************Sending Data Streaming in Receiver " + << arg << std::endl; #endif if (connectData() == OK){ ret=thisReceiver->sendInt(fnum,retval,arg); @@ -9097,7 +9293,8 @@ int slsDetector::enableDataStreamingFromReceiver(int enable){ } if(ret==FAIL) { retval = -1; - cout << "could not set data streaming in receiver to " << enable <<" Returned:" << retval << endl; + cout << "could not set data streaming in receiver to " << + enable <<" Returned:" << retval << endl; setErrorMask((getErrorMask())|(DATA_STREAMING)); } else { thisDetector->receiver_upstream = retval; @@ -9112,7 +9309,7 @@ int slsDetector::enableDataStreamingFromReceiver(int enable){ -int slsDetector::enableReceiverCompression(int i){ +int slsDetector::enableReceiverCompression(int i) { int fnum=F_ENABLE_RECEIVER_COMPRESSION; int ret = FAIL; int retval=-1; @@ -9120,7 +9317,8 @@ int slsDetector::enableReceiverCompression(int i){ if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ #ifdef VERBOSE - std::cout << "Getting/Enabling/Disabling Receiver Compression with argument " << i << std::endl; + std::cout << "Getting/Enabling/Disabling Receiver Compression with argument " + << i << std::endl; #endif if (connectData() == OK){ ret=thisReceiver->sendInt(fnum,retval,i); @@ -9134,76 +9332,10 @@ int slsDetector::enableReceiverCompression(int i){ -void slsDetector::sendMultiDetectorSize(){ - int fnum=F_SEND_RECEIVER_MULTIDETSIZE; - int ret = FAIL; - int retval = -1; - int arg[2]; - - pthread_mutex_lock(&ms); - parentDet->getNumberOfDetectors(arg[0],arg[1]); - pthread_mutex_unlock(&ms); - - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Sending multi detector size to Receiver (" << arg[0] << "," << arg[1] << ")" << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendIntArray(fnum,retval,arg); - disconnectData(); - } - if((ret==FAIL)){ - std::cout << "Could not set position Id" << std::endl; - setErrorMask((getErrorMask())|(RECEIVER_MULTI_DET_SIZE_NOT_SET)); - } - } -} - - -void slsDetector::setDetectorId(){ - int fnum=F_SEND_RECEIVER_DETPOSID; - int ret = FAIL; - int retval = -1; - int arg = posId; - - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Sending detector pos id to Receiver " << posId << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendInt(fnum,retval,arg); - disconnectData(); - } - if((ret==FAIL) || (retval != arg)){ - std::cout << "Could not set position Id" << std::endl; - setErrorMask((getErrorMask())|(RECEIVER_DET_POSID_NOT_SET)); - } - } -} - - -void slsDetector::setDetectorHostname(){ - int fnum=F_SEND_RECEIVER_DETHOSTNAME; - int ret = FAIL; - char retval[MAX_STR_LENGTH]=""; - - - if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -#ifdef VERBOSE - std::cout << "Sending detector hostname to Receiver " << thisDetector->hostname << std::endl; -#endif - if (connectData() == OK){ - ret=thisReceiver->sendString(fnum,retval,thisDetector->hostname); - disconnectData(); - } - if((ret==FAIL) || (strcmp(retval,thisDetector->hostname))) - setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTNAME_NOT_SET)); - } -} -int slsDetector::enableTenGigabitEthernet(int i){ +int slsDetector::enableTenGigabitEthernet(int i) { int ret=FAIL; int retval = -1; int fnum=F_ENABLE_TEN_GIGA,fnum2 = F_ENABLE_RECEIVER_TEN_GIGA; @@ -9221,7 +9353,7 @@ int slsDetector::enableTenGigabitEthernet(int i){ if (ret==FAIL){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(DETECTOR_TEN_GIGA)); + setErrorMask((getErrorMask())|(DETECTOR_TEN_GIGA)); } controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); disconnectControl(); @@ -9239,7 +9371,8 @@ int slsDetector::enableTenGigabitEthernet(int i){ ret = FAIL; retval=-1; #ifdef VERBOSE - std::cout << "Enabling / Disabling 10Gbe in receiver: " << i << std::endl; + std::cout << "Enabling / Disabling 10Gbe in receiver: " + << i << std::endl; #endif if (connectData() == OK){ ret=thisReceiver->sendInt(fnum2,retval,i); @@ -9259,7 +9392,7 @@ int slsDetector::enableTenGigabitEthernet(int i){ -int slsDetector::setReceiverFifoDepth(int i){ +int slsDetector::setReceiverFifoDepth(int i) { int fnum=F_SET_RECEIVER_FIFO_DEPTH; int ret = FAIL; int retval=-1; @@ -9284,7 +9417,7 @@ int slsDetector::setReceiverFifoDepth(int i){ -int slsDetector::setReceiverSilentMode(int i){ +int slsDetector::setReceiverSilentMode(int i) { int fnum=F_SET_RECEIVER_SILENT_MODE; int ret = FAIL; int retval=-1; @@ -9302,370 +9435,15 @@ int slsDetector::setReceiverSilentMode(int i){ disconnectData(); } if(ret==FAIL) - setErrorMask((getErrorMask())|(RECEIVER_SILENT_MODE_NOT_SET)); + setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET)); } return retval; } - /******** CTB funcs */ - /** opens pattern file and sends pattern to CTB - @param fname pattern file to open - @returns OK/FAIL - */ -int slsDetector::setCTBPattern(string fname) { - - - //int fnum=F_SET_CTB_PATTERN; - //int ret = FAIL; - //char retval[MAX_STR_LENGTH]=""; - - -// if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ -// #ifdef VERBOSE -// std::cout << "Sending detector hostname to Receiver " << thisDetector->hostname << std::endl; -// #endif -// if (connectData() == OK) -// ret=thisReceiver->sendString(fnum,retval,thisDetector->hostname); -// if((ret==FAIL) || (strcmp(retval,thisDetector->hostname))) -// setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTNAME_NOT_SET)); -// } - - - - uint64_t word; - - int addr=0; - - FILE *fd=fopen(fname.c_str(),"r"); - if (fd>0) { - while (fread(&word, sizeof(word), 1,fd)) { - setCTBWord(addr,word); - // cout << hex << addr << " " << word << dec << endl; - ++addr; - } - - fclose(fd); - } else - return -1; - - - - - - return addr; - - -} - - - /** 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 slsDetector::setCTBWord(int addr,uint64_t word) { - - //uint64_t ret; - - int ret=FAIL; - uint64_t retval=-1; - int fnum=F_SET_CTB_PATTERN; - int mode=0; //sets word - - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&mode,sizeof(mode)); - controlSocket->SendDataOnly(&addr,sizeof(addr)); - controlSocket->SendDataOnly(&word,sizeof(word)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return retval; - - -} - - /** 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 slsDetector::setCTBPatLoops(int level,int &start, int &stop, int &n) { - - - int retval[3], args[4]; - - args[0]=level; - args[1]=start; - args[2]=stop; - args[3]=n; - - - int ret=FAIL; - int fnum=F_SET_CTB_PATTERN; - int mode=1; //sets loop - - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&mode,sizeof(mode)); - controlSocket->SendDataOnly(&args,sizeof(args)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - start=retval[0]; - stop=retval[1]; - n=retval[2]; - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return ret; - - -} - - - /** Sets the wait address in the CTB - @param level 0,1,2, wait level - @param addr wait address, -1 gets - @returns actual value - */ -int slsDetector::setCTBPatWaitAddr(int level, int addr) { - - - - - int retval=-1; - - - int ret=FAIL; - int fnum=F_SET_CTB_PATTERN; - int mode=2; //sets loop - - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&mode,sizeof(mode)); - controlSocket->SendDataOnly(&level,sizeof(level)); - controlSocket->SendDataOnly(&addr,sizeof(addr)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return retval; - - - -} - - /** Sets the wait time in the CTB - @param level 0,1,2, wait level - @param t wait time, -1 gets - @returns actual value - */ -int slsDetector::setCTBPatWaitTime(int level, uint64_t t) { - - - - - - uint64_t retval=-1; - - - int ret=FAIL; - // uint64_t retval=-1; - int fnum=F_SET_CTB_PATTERN; - int mode=3; //sets loop - - char mess[MAX_STR_LENGTH]=""; - -#ifdef VERBOSE - std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&mode,sizeof(mode)); - controlSocket->SendDataOnly(&level,sizeof(level)); - controlSocket->SendDataOnly(&t,sizeof(t)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return retval; - - -} - -int slsDetector::pulsePixel(int n,int x,int y) { - int ret=FAIL; - int fnum=F_PULSE_PIXEL; - char mess[MAX_STR_LENGTH]=""; - int arg[3]; - arg[0] = n; arg[1] = x; arg[2] = y; - -#ifdef VERBOSE - std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times at (" << x << "," << "y)" << endl << endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return ret; -} - - -int slsDetector::pulsePixelNMove(int n,int x,int y) { - int ret=FAIL; - int fnum=F_PULSE_PIXEL_AND_MOVE; - char mess[MAX_STR_LENGTH]=""; - int arg[3]; - arg[0] = n; arg[1] = x; arg[2] = y; - -#ifdef VERBOSE - std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times and move by deltax:" << x << " deltay:" << y << endl << endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(arg,sizeof(arg)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL_NMOVE)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return ret; -} - - - -int slsDetector::pulseChip(int n) { - int ret=FAIL; - int fnum=F_PULSE_CHIP; - char mess[MAX_STR_LENGTH]=""; - - -#ifdef VERBOSE - std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times" << endl << endl; -#endif - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&n,sizeof(n)); - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL){ - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - setErrorMask((getErrorMask())|(COULD_NOT_PULSE_CHIP)); - } - disconnectControl(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - return ret; -} - - - -void slsDetector::setAcquiringFlag(bool b){ - parentDet->setAcquiringFlag(b); -} - -bool slsDetector::getAcquiringFlag(){ - return parentDet->getAcquiringFlag(); -} - - -bool slsDetector::isAcquireReady() { - return parentDet->isAcquireReady(); -} - - -int slsDetector::restreamStopFromReceiver(){ +int slsDetector::restreamStopFromReceiver() { int fnum=F_RESTREAM_STOP_FROM_RECEIVER; int ret = FAIL; char mess[MAX_STR_LENGTH] = ""; @@ -9689,3 +9467,209 @@ int slsDetector::restreamStopFromReceiver(){ return ret; } + + + + +int slsDetector::setCTBPattern(string fname) { + + uint64_t word; + + int addr=0; + + FILE *fd=fopen(fname.c_str(),"r"); + if (fd>0) { + while (fread(&word, sizeof(word), 1,fd)) { + setCTBWord(addr,word); + // cout << hex << addr << " " << word << dec << endl; + ++addr; + } + + fclose(fd); + } else + return -1; + + + + + + return addr; + + +} + + +uint64_t slsDetector::setCTBWord(int addr,uint64_t word) { + + //uint64_t ret; + + int ret=FAIL; + uint64_t retval=-1; + int fnum=F_SET_CTB_PATTERN; + int mode=0; //sets word + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&addr,sizeof(addr)); + controlSocket->SendDataOnly(&word,sizeof(word)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + +} + + +int slsDetector::setCTBPatLoops(int level,int &start, int &stop, int &n) { + + + int retval[3], args[4]; + + args[0]=level; + args[1]=start; + args[2]=stop; + args[3]=n; + + + int ret=FAIL; + int fnum=F_SET_CTB_PATTERN; + int mode=1; //sets loop + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&args,sizeof(args)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + start=retval[0]; + stop=retval[1]; + n=retval[2]; + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; + + +} + + +int slsDetector::setCTBPatWaitAddr(int level, int addr) { + + + + + int retval=-1; + + + int ret=FAIL; + int fnum=F_SET_CTB_PATTERN; + int mode=2; //sets loop + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&level,sizeof(level)); + controlSocket->SendDataOnly(&addr,sizeof(addr)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + + +} + + +int slsDetector::setCTBPatWaitTime(int level, uint64_t t) { + + + uint64_t retval=-1; + + int ret=FAIL; + // uint64_t retval=-1; + int fnum=F_SET_CTB_PATTERN; + int mode=3; //sets loop + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&level,sizeof(level)); + controlSocket->SendDataOnly(&t,sizeof(t)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + +} + + + diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 5dd98aafb..960b152ac 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -1,2137 +1,2470 @@ - - - #ifndef SLS_DETECTOR_H #define SLS_DETECTOR_H +/** + * + * @short complete detector functionalities for a single module detector. + * The slsDetector class takes care of the communication with the + * detector and all kind actions related with a single detector controller + * @author Anna Bergamaschi + */ -#include "multiSlsDetector.h" #include "slsDetectorUtils.h" #include "energyConversion.h" #include "angleConversionConstant.h" #include "MySocketTCP.h" - #include "angleConversionConstant.h" -#include "receiverInterface.h" - - -/** - * - * @short the slsDetector class takes care of the communication with the detector and all kind actions related with a single detector controller - * @author Anna Bergamaschi - * @version 0.1alpha - */ +class multiSlsDetector; +class SharedMemory; +class receiverInterface; +#define SLS_SHMVERSION 0x180629 #define NMODMAXX 24 #define NMODMAXY 24 #define NCHIPSMAX 10 #define NCHANSMAX 65536 #define NDACSMAX 16 - - /** - @short complete detector functionalities for a single module detector -*/ + * parameter list that has to be initialized depending on the detector type + */ +typedef struct detParameterList { + int nModMaxX; + int nModMaxY; + int nChanX; + int nChanY; + int nChipX; + int nChipY; + int nDacs; + int nAdcs; + int nGain; + int nOffset; + int dynamicRange; + int moveFlag; + int nGappixelsX; + int nGappixelsY; +} detParameterList; + + class slsDetector : public slsDetectorUtils, public energyConversion { +private: + /** + * @short structure allocated in shared memory to store detector settings for IPC and cache + */ + typedef struct sharedSlsDetector { + /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/ - public: - - /* /\** online flags enum \sa setOnline*\/ */ - /* enum {GET_ONLINE_FLAG=-1, /\**< returns wether the detector is in online or offline state *\/ */ - /* OFFLINE_FLAG=0, /\**< detector in offline state (i.e. no communication to the detector - using only local structure - no data acquisition possible!) *\/ */ - /* ONLINE_FLAG =1/\**< detector in online state (i.e. communication to the detector updating the local structure) *\/ */ - /* }; */ + /** shared memory version */ + int shmversion; + /** 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; - /** - @short Structure allocated in shared memory to store detector settings. - - Structure allocated in shared memory to store detector settings and be accessed in parallel by several applications on the same machine (take care of possible conflicts, particularly if things are run on different machines!) - - */ - typedef struct sharedSlsDetector { - /** already existing flag. If the detector does not yet exist (alreadyExisting=0) the sharedMemory will be created, otherwise it will simly be linked */ - int alreadyExisting; - - - - - /** last process id accessing the shared memory */ - - pid_t lastPID; - - - - - /** online flag - is set if the detector is connected, unset if socket connection is not possible */ - int onlineFlag; - - - /** stopped flag - is set if an acquisition error occurs or the detector is stopped manually. Is reset to 0 at the start of the acquisition */ - int stoppedFlag; - - /** is the hostname (or IP address) of the detector. needs to be set before startin the communication */ - char hostname[MAX_STR_LENGTH]; - - /** is the port used for control functions normally it should not be changed*/ - int controlPort; - /** is the port used to stop the acquisition normally it should not be changed*/ - int stopPort; - - /** detector type \ see :: detectorType*/ - detectorType myDetectorType; - - - /** path of the trimbits/settings files */ - char settingsDir[MAX_STR_LENGTH]; - /** path of the calibration files */ - char calDir[MAX_STR_LENGTH]; - /** number of energies at which the detector has been trimmed (unused) */ - int nTrimEn; - /** list of the energies at which the detector has been trimmed (unused) */ - int trimEnergies[100]; - - - /** indicator for the acquisition progress - set to 0 at the beginning of the acquisition and incremented every time that the data are written to file */ - int progressIndex; - /** total number of frames to be acquired */ - int totalProgress; - - /** path of the output files */ - char filePath[MAX_STR_LENGTH]; - - /* size of the detector */ - - /** number of installed modules of the detector (x and y directions) */ - int nMod[2]; - /** number of modules ( nMod[X]*nMod[Y]) \see nMod */ - int nMods; - /** maximum number of modules of the detector (x and y directions) */ - int nModMax[2]; - /** maximum number of modules (nModMax[X]*nModMax[Y]) \see nModMax */ - int nModsMax; - /** number of channels per chip */ - int nChans; - /** number of channels per chip in one direction */ - int nChan[2]; - /** number of chips per module*/ - int nChips; - /** number of chips per module in one direction */ - int nChip[2]; - /** number of dacs per module*/ - int nDacs; - /** number of adcs per module */ - int nAdcs; - /** number of extra gain values*/ - int nGain; - /** number of extra offset values */ - int nOffset; - /** dynamic range of the detector data */ - int dynamicRange; - /** size of the data that are transfered from the detector */ - int dataBytes; - - - - /** corrections to be applied to the data \see ::correctionFlags */ - int correctionMask; - /** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */ - int threadedProcessing; - /** dead time (in ns) for rate corrections */ - double tDead; - /** directory where the flat field files are stored */ - char flatFieldDir[MAX_STR_LENGTH]; - /** file used for flat field corrections */ - char flatFieldFile[MAX_STR_LENGTH]; - /** number of bad channels from bad channel list */ - int nBadChans; - /** file with the bad channels */ - char badChanFile[MAX_STR_LENGTH]; - /** list of bad channels */ - int badChansList[MAX_BADCHANS]; - /** number of bad channels from flat field i.e. channels which read 0 in the flat field file */ - int nBadFF; - /** list of bad channels from flat field i.e. channels which read 0 in the flat field file */ - int badFFList[MAX_BADCHANS]; - - /** file with the angular conversion factors */ - char angConvFile[MAX_STR_LENGTH]; - /** array of angular conversion constants for each module \see ::angleConversionConstant */ - angleConversionConstant angOff[MAXMODS]; - /** angular direction (1 if it corresponds to the encoder direction i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */ - int angDirection; - /** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */ - double fineOffset; - /** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */ - double globalOffset; - /** number of positions at which the detector should acquire */ - int numberOfPositions; - /** list of encoder positions at which the detector should acquire */ - double detPositions[MAXPOS]; - /** bin size for data merging */ - double binSize; - /** add encoder value flag (i.e. wether the detector is moving - 1 - or stationary - 0) */ - int moveFlag; - - - /* infos necessary for the readout to determine the size of the data */ - - /** number of rois defined */ - int nROI; - /** list of rois */ - ROI roiLimits[MAX_ROIS]; - - /** readout flags */ - readOutFlags roFlags; - - - /* detector setup - not needed */ - /** name root of the output files */ - char settingsFile[MAX_STR_LENGTH]; - /** detector settings (standard, fast, etc.) */ - detectorSettings currentSettings; - /** detector threshold (eV) */ - int currentThresholdEV; - /** timer values */ - int64_t timerValue[MAX_TIMERS]; - /** clock divider */ - //int clkDiv; - - - /** Scans and scripts */ - ////////////////////////// only in the multi detector class?!?!?!? additional shared memory class?!?!?!? - int actionMask; - - mystring actionScript[MAX_ACTIONS]; - - mystring actionParameter[MAX_ACTIONS]; - - - int scanMode[MAX_SCAN_LEVELS]; - mystring scanScript[MAX_SCAN_LEVELS]; - mystring scanParameter[MAX_SCAN_LEVELS]; - int nScanSteps[MAX_SCAN_LEVELS]; - mysteps scanSteps[MAX_SCAN_LEVELS]; - int scanPrecision[MAX_SCAN_LEVELS]; - - //////////////////////////////////////////////////////////////////////////////////////////////// - - - /*offsets*/ - /** memory offsets for the flat field coefficients */ - int ffoff; - /** memory offsets for the flat filed coefficient errors */ - int fferroff; - /** memory offsets for the module structures */ - int modoff; - /** memory offsets for the dac arrays */ - int dacoff; - /** memory offsets for the adc arrays */ - int adcoff; - /** memory offsets for the chip register arrays */ - int chipoff; - /** memory offsets for the channel register arrays -trimbits*/ - int chanoff; - /** memory offsets for the gain register arrays */ - int gainoff; - /** memory offsets for the offset register arrays -trimbits*/ - int offsetoff; - - - /* receiver*/ - /** ip address/hostname of the receiver for the client to connect to**/ - char receiver_hostname[MAX_STR_LENGTH]; - /** is the port used to communicate between client and the receiver*/ - int receiverTCPPort; - /** is the port used to communicate between detector and the receiver*/ - int receiverUDPPort; - /** is the port used to communicate between second half module of Eiger detector and the receiver*/ - int receiverUDPPort2; - /** ip address of the receiver for the detector to send packets to**/ - char receiverUDPIP[MAX_STR_LENGTH]; - /** mac address of receiver for the detector to send packets to **/ - char receiverUDPMAC[MAX_STR_LENGTH]; - /** mac address of the detector **/ - char detectorMAC[MAX_STR_LENGTH]; - /** ip address of the detector **/ - char detectorIP[MAX_STR_LENGTH]; - /** online flag - is set if the receiver is connected, unset if socket connection is not possible */ - int receiverOnlineFlag; - - /** 10 Gbe enable*/ - int tenGigaEnable; - - /** flipped data across x or y axis */ - int flippedData[2]; - /** tcp port from gui/different process to receiver (only data) */ - int zmqport; - /** tcp port from receiver to gui/different process (only data) */ - int receiver_zmqport; - /** data streaming (up stream) enable in receiver */ - bool receiver_upstream; - /* Receiver read frequency */ - int receiver_read_freq; - /** zmq tcp src ip address in client (only data) **/ - char zmqip[MAX_STR_LENGTH]; - /** zmq tcp src ip address in receiver (only data) **/ - char receiver_zmqip[MAX_STR_LENGTH]; - /** gap pixels enable */ - int gappixels; - /** gap pixels in each direction */ - int nGappixels[2]; - /** data bytes including gap pixels */ - int dataBytesInclGapPixels; - - - - } sharedSlsDetector; - - - - - - - - using slsDetectorUtils::getDetectorType; - - using postProcessing::flatFieldCorrect; - using postProcessing::rateCorrect; - using postProcessing::setBadChannelCorrection; + /** is the hostname (or IP address) of the detector. needs to be set + * before starting the communication */ + char hostname[MAX_STR_LENGTH]; - using angularConversion::readAngularConversion; - using angularConversion::writeAngularConversion; + /** END OF FIXED PATTERN -----------------------------------------------*/ - using slsDetectorUtils::getAngularConversion; - string getDetectorType(){return sgetDetectorsType();}; + /** Detector offset in the X & Y direction in the multi detector structure */ + int offset[2]; + /** is the port used for control functions */ + int controlPort; - /** (default) constructor - \param type is needed to define the size of the detector shared memory 9defaults to GENERIC i.e. the largest shared memory needed by any slsDetector is allocated - \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently - \param pos is the index of object in the parent multislsdet array - \param p is the parent multislsdet to access filename ,path etc + /** is the port used to stop the acquisition */ + int stopPort; - */ + /** detector type \ see :: detectorType*/ + detectorType myDetectorType; - slsDetector(int pos, detectorType type=GENERIC, int id=0, multiSlsDetector *p=NULL); + /** path of the trimbits/settings files */ + char settingsDir[MAX_STR_LENGTH]; - /** constructor - \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently - \param pos is the index of object in the parent multislsdet array - \param p is the parent multislsdet to access filename ,path etc - */ - slsDetector(int pos, int id, multiSlsDetector *p=NULL); + /** path of the calibration files */ + char calDir[MAX_STR_LENGTH]; + /** number of energies at which the detector has been trimmed */ + int nTrimEn; - slsDetector(int pos, char *name, int id=0, int cport=DEFAULT_PORTNO, multiSlsDetector *p=NULL); - //slsDetector(string const fname); - // ~slsDetector(){while(dataQueue.size()>0){}}; - /** destructor */ - virtual ~slsDetector(); + /** list of the energies at which the detector has been trimmed */ + int trimEnergies[MAX_TRIMEN]; - /** - * returns true. Used when reference is slsDetectorUtils and to determine if command can be implemented as slsDetector/multiSlsDetector object/ - */ - bool isMultiSlsDetectorClass(){return 0;}; + /** indicator for the acquisition progress - set to 0 at the beginning + * of the acquisition and incremented when each frame is processed */ + int progressIndex; - int setOnline(int const online=GET_ONLINE_FLAG); - - string checkOnline(); + /** total number of frames to be acquired */ + int totalProgress; - /** @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); + /** path of the output files */ + char filePath[MAX_STR_LENGTH]; + /** number of installed modules of the detector (x and y directions) */ + int nMod[2]; - /** returns if the detector already existed - \returns 1 if the detector structure has already be initlialized, 0 otherwise */ - int exists() {return thisDetector->alreadyExisting;}; - - /** returns 1 if the detetcor with id has already been allocated and initialized in shared memory - \param detector id - \returns 1 if the detector structure has already be initlialized, 0 otherwise */ - static int exists(int id); + /** number of modules ( nMod[X]*nMod[Y]) \see nMod */ + int nMods; - /** - configures mac for gotthard, moench readout - \returns OK or FAIL - */ - int configureMAC(); + /** maximum number of modules of the detector (x and y directions) */ + int nModMax[2]; - /** - Prints receiver configuration - \returns OK or FAIL - */ - int printReceiverConfiguration(); + /** maximum number of modules (nModMax[X]*nModMax[Y]) \see nModMax */ + int nModsMax; - /** - Reads the configuration file fname - \param fname file name - \returns OK or FAIL - */ - int readConfigurationFile(string const fname); + /** number of channels per chip */ + int nChans; - - int readConfigurationFile(ifstream &infile); + /** number of channels per chip in one direction */ + int nChan[2]; + /** number of chips per module*/ + int nChips; - - /** + /** number of chips per module in one direction */ + int nChip[2]; - Writes the configuration file fname - \param fname file name - \returns OK or FAIL + /** number of dacs per module*/ + int nDacs; - */ - int writeConfigurationFile(string const fname); - int writeConfigurationFile(ofstream &outfile, int id=-1); + /** number of adcs per module */ + int nAdcs; + /** number of extra gain values*/ + int nGain; + /** number of extra offset values */ + int nOffset; + /** dynamic range of the detector data */ + int dynamicRange; + /** size of the data that are transfered from the detector */ + int dataBytes; + /** corrections to be applied to the data \see ::correctionFlags */ + int correctionMask; + /** threaded processing flag + * (i.e. if data are processed in a separate thread) */ + int threadedProcessing; + /** dead time (in ns) for rate corrections */ + double tDead; - /** - configure the socket communication and initializes the socket instances + /** directory where the flat field files are stored */ + char flatFieldDir[MAX_STR_LENGTH]; - \param name hostname - if "" the current hostname is used - \param control_port port for control commands - if -1 the current is used - \param stop_port port for stop command - if -1 the current is used + /** file used for flat field corrections */ + char flatFieldFile[MAX_STR_LENGTH]; - \returns OK is connection succeded, FAIL otherwise - \sa sharedSlsDetector - */ - int setTCPSocket(string const name="", int const control_port=-1, int const stop_port=-1); + /** number of bad channels from bad channel list */ + int nBadChans; - /** - changes/gets the port number - \param type port type - \param num new port number (-1 gets) - \returns actual port number - */ - int setPort(portType type, int num=-1); - - /** returns the detector control port \sa sharedSlsDetector */ - int getControlPort() {return thisDetector->controlPort;}; - /** returns the detector stop port \sa sharedSlsDetector */ - int getStopPort() {return thisDetector->stopPort;}; - /** returns the receiver port \sa sharedSlsDetector */ - int getReceiverPort() {return thisDetector->receiverTCPPort;}; - - /** Locks/Unlocks the connection to the server - /param lock sets (1), usets (0), gets (-1) the lock - /returns lock status of the server - */ - int lockServer(int lock=-1); - - /** - Returns the IP of the last client connecting to the detector - */ - string getLastClientIP(); + /** file with the bad channels */ + char badChanFile[MAX_STR_LENGTH]; - /** returns the detector hostname \sa sharedSlsDetector */ - string getHostname(int ipos=-1) {return string(thisDetector->hostname);}; - /** returns the detector hostname \sa sharedSlsDetector */ - string setHostname(const char *name, int ipos=-1) {setTCPSocket(string(name)); return string(thisDetector->hostname);}; - /** connect to the control port */ - int connectControl(); - /** disconnect from the control port */ - int disconnectControl(); - - /** connect to the receiver port */ - int connectData(); - /** disconnect from the receiver port */ - int disconnectData(); - - /** connect to the stop port */ - int connectStop(); - /** disconnect from the stop port */ - int disconnectStop(); - - /** - sets the network parameters - must restart streaming in client/receiver if to do with zmq after calling this function - \param i network parameter type - \param s value to be set - \returns parameter - - */ - string setNetworkParameter(networkParameter index, string value); - - /** - gets the network parameters - \param i network parameter type can be RECEIVER_IP, RECEIVER_MAC, SERVER_MAC - \returns parameter - - */ - string getNetworkParameter(networkParameter index); + /** list of bad channels */ + int badChansList[MAX_BADCHANS]; - /* I/O */ + /** number of bad channels from flat field + * i.e. channels which read 0 in the flat field file */ + int nBadFF; - /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ - char* getSettingsDir() {return thisDetector->settingsDir;}; - /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ - char* setSettingsDir(string s) {sprintf(thisDetector->settingsDir, s.c_str()); return thisDetector->settingsDir;}; + /** list of bad channels from flat field + * i.e. channels which read 0 in the flat field file */ + int badFFList[MAX_BADCHANS]; + /** file with the angular conversion factors */ + char angConvFile[MAX_STR_LENGTH]; + /** array of angular conversion constants for each module + * \see ::angleConversionConstant */ + angleConversionConstant angOff[MAXMODS]; - /** - returns the location of the calibration files - \sa sharedSlsDetector - */ - char* getCalDir() {return thisDetector->calDir;}; - /** - sets the location of the calibration files - \sa sharedSlsDetector - */ - char* setCalDir(string s) {sprintf(thisDetector->calDir, s.c_str()); return thisDetector->calDir;}; - - - - /** returns the number of trim energies and their value \sa sharedSlsDetector - \param point to the array that will contain the trim energies (in ev) - \returns number of trim energies - - - unused! - - \sa sharedSlsDetector - */ - int getTrimEn(int *en=NULL) {if (en) {for (int ien=0; iennTrimEn; ien++) en[ien]=thisDetector->trimEnergies[ien];} return (thisDetector->nTrimEn);}; - - - /** sets the number of trim energies and their value \sa sharedSlsDetector - \param nen number of energies - \param en array of energies - \returns number of trim energies - - unused! - - \sa sharedSlsDetector - */ - int setTrimEn(int nen, int *en=NULL) {if (en) {for (int ien=0; ientrimEnergies[ien]=en[ien]; thisDetector->nTrimEn=nen;} return (thisDetector->nTrimEn);}; - - - //virtual int writeSettingsFile(string fname, sls_detector_module mod); - - /** - writes a trim/settings file for module number imod - the values will be read from the current detector structure - \param fname name of the file to be written - \param imod module number - \param iodelay io delay (detector specific) - \param tau tau (detector specific) - \returns OK or FAIL if the file could not be written - \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int) - */ - using energyConversion::writeSettingsFile; - int writeSettingsFile(string fname, int imod, int iodelay, int tau); - - - /** - returns currently the loaded trimfile/settingsfile name - */ - string getSettingsFile(){\ - string s(thisDetector->settingsFile); \ - if (s.length()>6) {\ - if (s.substr(s.length()-6,3)==string(".sn") && s.substr(s.length()-3)!=string("xxx") ) \ - return s.substr(0,s.length()-6); \ - } \ - return string(thisDetector->settingsFile);\ - }; - - - /** programs FPGA with pof file - \param fname file name - \returns OK or FAIL - */ - int programFPGA(string fname); - - /** resets FPGA - \returns OK or FAIL - */ - int resetFPGA(); - - /** power on/off the chip - \param ival on is 1, off is 0, -1 to get - \returns OK or FAIL - */ - int powerChip(int ival= -1); + /** 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; - /** 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); + /** 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; - /** loads the modules settings/trimbits reading from a file - \param fname file name . If not specified, extension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int loadSettingsFile(string fname, int imod=-1); + /** number of positions at which the detector should acquire */ + int numberOfPositions; + /** list of encoder positions at which the detector should acquire */ + double detPositions[MAXPOS]; - /** saves the modules settings/trimbits writing to a file - \param fname file name . Axtension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int saveSettingsFile(string fname, int imod=-1); + /** bin size for data merging */ + double binSize; - /** 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); + /** add encoder value flag (i.e. wether the detector is + * moving - 1 - or stationary - 0) */ + int moveFlag; + /** number of rois defined */ + int nROI; - /** loads the modules calibration data reading from a file - \param fname file name . If not specified, extension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int loadCalibrationFile(string fname, int imod=-1); + /** list of rois */ + ROI roiLimits[MAX_ROIS]; + /** readout flags */ + readOutFlags roFlags; - /** saves the modules calibration data writing to a file - \param fname file name . Axtension is automatically generated! - \param imod module number, -1 means all modules - \returns OK or FAIL - */ - int saveCalibrationFile(string fname, int imod=-1); + /** name root of the output files */ + char settingsFile[MAX_STR_LENGTH]; + /** detector settings (standard, fast, etc.) */ + detectorSettings currentSettings; - /** - - reads an angular conversion file - \param fname file to be read - \sa angleConversionConstant mythenDetector::readAngularConversion - */ - int readAngularConversionFile(string fname=""); + /** detector threshold (eV) */ + int currentThresholdEV; + /** timer values */ + int64_t timerValue[MAX_TIMERS]; - /** - - reads an angular conversion file - \param fname file to be read - \sa angleConversionConstant mythenDetector::readAngularConversion - */ - int readAngularConversion(ifstream& ifs); + /** action mask */ + int actionMask; + /** action script */ + mystring actionScript[MAX_ACTIONS]; + /** action parameter */ + mystring actionParameter[MAX_ACTIONS]; - /** - Pure virtual function - writes an angular conversion file - \param fname file to be written - \sa angleConversionConstant mythenDetector::writeAngularConversion - */ - int writeAngularConversion(string fname=""); + /** scan mode */ + int scanMode[MAX_SCAN_LEVELS]; + /** scan script */ + mystring scanScript[MAX_SCAN_LEVELS]; + /** scan parameter */ + mystring scanParameter[MAX_SCAN_LEVELS]; - /** - Pure virtual function - writes an angular conversion file - \param fname file to be written - \sa angleConversionConstant mythenDetector::writeAngularConversion - */ - int writeAngularConversion(ofstream &ofs); + /** n scan steps */ + int nScanSteps[MAX_SCAN_LEVELS]; + /** scan steps */ + mysteps scanSteps[MAX_SCAN_LEVELS]; + /** scan precision */ + int scanPrecision[MAX_SCAN_LEVELS]; + /** memory offsets for the flat field coefficients */ + int ffoff; + /** memory offsets for the flat filed coefficient errors */ + int fferroff; - /** Returns the number of channels per chip (without connecting to the detector) */ - int getNChans(){return thisDetector->nChans;}; // + /** memory offsets for the module structures */ + int modoff; - /** Returns the number of channels per chip (without connecting to the detector) in one direction */ - int getNChans(dimension d){return thisDetector->nChan[d];}; // + /** memory offsets for the dac arrays */ + int dacoff; - /** Returns the number of chips per module (without connecting to the detector) */ - int getNChips(){return thisDetector->nChips;}; // + /** memory offsets for the adc arrays */ + int adcoff; - /** Returns the number of chips per module (without connecting to the detector) */ - int getNChips(dimension d){return thisDetector->nChip[d];}; // + /** memory offsets for the chip register arrays */ + int chipoff; - /** Returns the number of modules (without connecting to the detector) */ - int getNMods(){return thisDetector->nMods;}; // - - /** Returns the number of modules in direction d (without connecting to the detector) */ - int getNMod(dimension d){return thisDetector->nMod[d];}; // + /** memory offsets for the channel register arrays -trimbits*/ + int chanoff; - int getChansPerMod(int imod=0){return thisDetector->nChans*thisDetector->nChips;}; + /** memory offsets for the gain register arrays */ + int gainoff; - int getChansPerMod( dimension d,int imod=0){return thisDetector->nChan[d]*thisDetector->nChip[d];}; + /** memory offsets for the offset register arrays -trimbits*/ + int offsetoff; - /** Returns the max number of modules in direction d (without connecting to the detector) */ - int getNMaxMod(dimension d){return thisDetector->nModMax[d];}; // + /** ip address/hostname of the receiver for client control via TCP */ + char receiver_hostname[MAX_STR_LENGTH]; - /** Returns the number of modules (without connecting to the detector) */ - int getMaxMods(){return thisDetector->nModsMax;}; // + /** is the TCP port used to communicate between client and the receiver */ + int receiverTCPPort; + /** is the UDP port used to send data from detector to receiver */ + int receiverUDPPort; - /** number of rois defined */ - int nROI; - /** list of rois */ - ROI roiLimits[MAX_ROIS]; - - /** readout flags */ - readOutFlags roFlags; + /** is the port used to communicate between second half module of + * Eiger detector and the receiver*/ + int receiverUDPPort2; + /** ip address of the receiver for the detector to send packets to**/ + char receiverUDPIP[MAX_STR_LENGTH]; - int getTotalNumberOfChannels(); - //{return thisDetector->nChans*thisDetector->nChips*thisDetector->nMods;}; + /** mac address of receiver for the detector to send packets to **/ + char receiverUDPMAC[MAX_STR_LENGTH]; - int getTotalNumberOfChannels(dimension d); - //{return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nMod[d];}; + /** mac address of the detector **/ + char detectorMAC[MAX_STR_LENGTH]; - int getTotalNumberOfChannelsInclGapPixels(dimension d); + /** ip address of the detector **/ + char detectorIP[MAX_STR_LENGTH]; - int getMaxNumberOfChannels();//{return thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax;}; + /** online flag - is set if the receiver is connected, + * unset if socket connection is not possible */ + int receiverOnlineFlag; - int getMaxNumberOfChannels(dimension d);//{return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nModMax[d];}; + /** 10 Gbe enable*/ + int tenGigaEnable; - int getMaxNumberOfChannelsInclGapPixels(dimension d); + /** flipped data across x or y axis */ + int flippedData[2]; - /** returns the enable if data will be flipped across x or y axis - * \param d axis across which data is flipped - * returns 1 or 0 - */ - int getFlippedData(dimension d=X){return thisDetector->flippedData[d];}; + /** tcp port from gui/different process to receiver (only data) */ + int zmqport; - /** Returns number of rois */ - int getNRoi(){return thisDetector->nROI;}; + /** tcp port from receiver to gui/different process (only data) */ + int receiver_zmqport; + /** data streaming (up stream) enable in receiver */ + bool receiver_upstream; + /* Receiver read frequency */ + int receiver_read_freq; - /* Communication to server */ + /** zmq tcp src ip address in client (only data) **/ + char zmqip[MAX_STR_LENGTH]; + /** zmq tcp src ip address in receiver (only data) **/ + char receiver_zmqip[MAX_STR_LENGTH]; - /** - executes a system command on the server - e.g. mount an nfs disk, reboot and returns answer etc. - \param cmd is the command to be executed - \param answer is the answer from the detector - \returns OK or FAIL depending on the command outcome - */ - int execCommand(string cmd, string answer); - - /** - sets/gets detector type - normally the detector knows what type of detector it is - \param type is the detector type (defaults to GET_DETECTOR_TYPE) - \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) - */ - int setDetectorType(detectorType type=GET_DETECTOR_TYPE); + /** gap pixels enable */ + int gappixels; - /** - sets/gets detector type - normally the detector knows what type of detector it is - \param type is the detector type ("Mythen", "Pilatus", "XFS", "Gotthard", Agipd", "Mönch") - \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) - */ - int setDetectorType(string type); - - /** - gets detector type - normally the detector knows what type of detector it is - \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH,-1 command failed) - */ - detectorType getDetectorsType(int pos=-1); - - detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorsType(pos);}; - - string sgetDetectorsType(int pos=-1){return getDetectorType(getDetectorsType(pos));}; - - string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(getDetectorsType(pos));}; - string ssetDetectorsType(string t, int pos=-1){return getDetectorType(getDetectorsType(pos));} - - // Detector configuration functions - /** - set/get the size of the detector - \param n number of modules - \param d dimension - \returns current number of modules in direction d - */ - - // Detector configuration functions - /** - set/get the size of the detector - \param n number of modules - \param d dimension - \returns current number of modules in direction d - */ - int setNumberOfModules(int n=GET_FLAG, dimension d=X); // if n=GET_FLAG returns the number of installed modules - - - /** sets the enable which determines if data will be flipped across x or y axis - * \param d axis across which data is flipped - * \param value 0 or 1 to reset/set or -1 to get value - * \return enable flipped data across x or y axis - */ - int setFlippedData(dimension d=X, int value=-1); - - /** - * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. 4 bit mode gap pixels only in gui call back - * @param val 1 sets, 0 unsets, -1 gets - * @return gap pixel enable or -1 for error - */ - int enableGapPixels(int val=-1); - - - /* - returns the instrinsic size of the detector (maxmodx, maxmody, nchans, nchips, ndacs - enum numberOf { - MAXMODX, - MAXMODY, - CHANNELS, - CHIPS, - DACS - } - */ - - - /** - get the maximum size of the detector - \param d dimension - \returns maximum number of modules that can be installed in direction d - */ - int getMaxNumberOfModules(dimension d=X); // - - - /** - set/get the use of an external signal - \param pol meaning of the signal \sa externalSignalFlag - \param signalIndex index of the signal - \returns current meaning of signal signalIndex - */ - externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); - - - /** - set/get the external communication mode - - obsolete \sa setExternalSignalFlags - \param pol value to be set \sa externalCommunicationMode - \returns current external communication mode - */ - externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); - - - // Tests and identification - - /** - get detector ids/versions for module - \param mode which id/version has to be read - \param imod module number for module serial number - \returns id - */ - int64_t getId(idMode mode, int imod=0); - /** - Digital test of the modules - \param mode test mode - \param imod module number for chip test or module firmware test - \returns OK or error mask - */ - int digitalTest(digitalTestMode mode, int imod=0); - /** - analog test - \param modte test mode - \return pointer to acquired data - - not yet implemented - */ - - int* analogTest(analogTestMode mode); - - /** - enable analog output of channel ichan - - not yet implemented - */ - int enableAnalogOutput(int ichan); - - /** - enable analog output of channel ichan, chip ichip, module imod - - not yet implemented - */ - int enableAnalogOutput(int imod, int ichip, int ichan); - - /** - give a train of calibration pulses - \param vcal pulse amplitude - \param npulses number of pulses - - not yet implemented - - */ - int giveCalibrationPulse(double vcal, int npulses); - - // Expert Initialization functions - - - /** - write register - \param addr address - \val value - \returns current register value - - */ - uint32_t writeRegister(uint32_t addr, uint32_t val); - - - /** - write register - \param addr address - \val value - \returns current register value - - */ - int writeAdcRegister(int addr, int val); - - /** - read register - \param addr address - \returns current register value - - */ - uint32_t readRegister(uint32_t addr); - - /** - sets a bit in a register - \param addr address - \param n nth bit ranging from 0 to 31 - \returns current register value - - DO NOT USE!!! ONLY EXPERT USER!!! - */ - uint32_t setBit(uint32_t addr, int n); - - - /** - clear a bit in a register - \param addr address - \param n nth bit ranging from 0 to 31 - \returns current register value - - DO NOT USE!!! ONLY EXPERT USER!!! - */ - uint32_t clearBit(uint32_t addr, int n); - - /** - set dacs value - \param val value (in V) - \param index DAC index - \param mV 0 in dac units or 1 in mV - \param imod module number (if -1 alla modules) - \returns current DAC value - */ - dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); - - /** - set dacs value - \param index ADC index - \param imod module number - \returns current ADC value (temperature for eiger and jungfrau in millidegrees) - */ - dacs_t getADC(dacIndex index, int imod=0); - - /** - 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); - - /** - 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); - - /** - 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); - - /** - configure channel - \param reg channel register - \param ichan channel number (-1 all) - \param ichip chip number (-1 all) - \param imod module number (-1 all) - \returns current register value - \sa ::sls_detector_channel - */ - int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); - - /** - configure channel - \param chan channel to be set - must contain correct channel, module and chip number - \returns current register value - */ - int setChannel(sls_detector_channel chan); - - /** - get channel - \param ichan channel number - \param ichip chip number - \param imod module number - \returns current channel structure for channel - */ - sls_detector_channel getChannel(int ichan, int ichip, int imod); - - - - /** - configure chip - \param reg chip register - \param ichip chip number (-1 all) - \param imod module number (-1 all) - \returns current register value - \sa ::sls_detector_chip - */ - int setChip(int reg, int ichip=-1, int imod=-1); - - /** - configure chip - \param chip chip to be set - must contain correct module and chip number and also channel registers - \returns current register value - \sa ::sls_detector_chip - */ - int setChip(sls_detector_chip chip); - - /** - get chip - \param ichip chip number - \param imod module number - \returns current chip structure for channel - - \bug probably does not return corretly! - */ - sls_detector_chip getChip(int ichip, int imod); - - - /** - configure module - \param imod module number (-1 all) - \returns current register value - \sa ::sls_detector_module - */ - int setModule(int reg, int imod=-1); - //virtual int setModule(int reg, int imod=-1); - - /** - configure chip - \param module module to be set - must contain correct module number and also channel and chip registers - \param iodelay iodelay (detector specific) - \param tau tau (detector specific) - \param e_eV threashold in eV (detector specific) - \param gainval pointer to extra gain values - \param offsetval pointer to extra offset values - \param tb 1 to include trimbits, 0 to exclude (used for eiger) - \returns current register value - \sa ::sls_detector_module - */ - int setModule(sls_detector_module module, int iodelay, int tau, int e_eV, int* gainval=0, int* offsetval=0, int tb=1); - //virtual int setModule(sls_detector_module module); - - /** - get module - \param imod module number - \returns pointer to module structure (which has bee created and must then be deleted) - */ - sls_detector_module *getModule(int imod); - //virtual sls_detector_module *getModule(int imod); - - // calibration functions - // int setCalibration(int imod, detectorSettings isettings, double gain, double offset); - //int getCalibration(int imod, detectorSettings isettings, double &gain, double &offset); - - - /* - calibrated setup of the threshold - */ - /** - get threshold energy - \param imod module number (-1 all) - \returns current threshold value for imod in ev (-1 failed) - */ - int getThresholdEnergy(int imod=-1); - - /** - set threshold energy - \param e_eV threshold in eV - \param imod module number (-1 all) - \param isettings ev. change settings - \param tb 1 to include trimbits, 0 to exclude - \returns current threshold value for imod in ev (-1 failed) - */ - int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS, int tb=1); - - /** - set threshold energy - \param e_eV threshold in eV - \param isettings ev. change settings - \param tb 1 to include trimbits, 0 to exclude - \returns OK if successful, else FAIL - */ - int setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb=1); - - /** - get detector settings - \param imod module number (-1 all) - \returns current settings - */ - detectorSettings getSettings(int imod=-1); - - /** - set detector settings - \param isettings settings - \param imod module number (-1 all) - \returns current settings - - in this function trimbits/settings and calibration files are searched in the settingsDir and calDir directories and the detector is initialized - */ - detectorSettings setSettings(detectorSettings isettings, int imod=-1); - //virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1); - - /** - gets the trimbits from shared memory *chanRegs - \param retval is the array with the trimbits - \param fromDetector is true if the trimbits shared memory have to be uploaded from detector - \returns the total number of channels for the detector - \sa ::sls_detector_module - */ - int getChanRegs(double* retval,bool fromDetector); - - /** - - updates the shared memory receiving the data from the detector (without asking and closing the connection - /returns OK - - */ - - int updateDetectorNoWait(); - - /** - - updates the shared memory receiving the data from the detector - /returns OK - - */ - - - int updateDetector(); - - // Acquisition functions - - /** - prepares detector for acquisition - \returns OK/FAIL - */ - int prepareAcquisition(); - - /** - prepares detector for acquisition - \returns OK/FAIL - */ - int cleanupAcquisition(); - - /** - start detector acquisition - \returns OK/FAIL - */ - int startAcquisition(); - - /** - stop detector acquisition - \returns OK/FAIL - */ - int stopAcquisition(); - - /** - start readout (without exposure or interrupting exposure) - \returns OK/FAIL - */ - int startReadOut(); - - /** - get run status - \returns status mask - */ - //virtual runStatus getRunStatus()=0; - runStatus getRunStatus(); - - /** - start detector acquisition and read all data putting them a data queue - \returns pointer to the front of the data queue - \sa startAndReadAllNoWait getDataFromDetector dataQueue - */ - int* startAndReadAll(); - - /** - start detector acquisition and read out, but does not read data from socket leaving socket opened - \returns OK or FAIL - - */ - int startAndReadAllNoWait(); - - /* /\** */ - /* receives a data frame from the detector socket */ - /* \returns pointer to the data or NULL. If NULL disconnects the socket */ - /* \sa getDataFromDetector */ - /* *\/ */ - /* int* getDataFromDetectorNoWait(); */ - - /** - asks and receives a data frame from the detector and puts it in the data queue - \returns pointer to the data or NULL. - \sa getDataFromDetector - */ - int* readFrame(); - - /** - asks and receives all data from the detector and puts them in a data queue - \returns pointer to the front of the queue or NULL. - \sa getDataFromDetector dataQueue - */ - int* readAll(); - - /** - asks and receives all data from the detector and leaves the socket opened - \returns OK or FAIL - */ - int readAllNoWait(); - - - - - - /** - set/get timer value - \param index timer index - \param t time in ns or number of...(e.g. frames, gates, probes) - \returns timer set value in ns or number of...(e.g. frames, gates, probes) - */ - int64_t setTimer(timerIndex index, int64_t t=-1); - - /** - get current timer value - \param index timer index - \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) - */ - int64_t getTimeLeft(timerIndex index); - - - - - /** sets/gets the value of important readout speed parameters - \param sp is the parameter to be set/get - \param value is the value to be set, if -1 get value - \returns current value for the specified parameter - \sa speedVariable - */ - int setSpeed(speedVariable sp, int value=-1); - - // Flags - /** - set/get dynamic range - \param n dynamic range (-1 get) - \returns current dynamic range - updates the size of the data expected from the detector - \sa sharedSlsDetector - */ - int setDynamicRange(int n=-1); - - /** - set/get dynamic range - \returns number of bytes sent by the detector - \sa sharedSlsDetector - */ - int getDataBytes(){return thisDetector->dataBytes;}; - - /** - * returns number of bytes sent by detector including gap pixels - * \sa sharedSlsDetector - */ - int getDataBytesInclGapPixels(){return thisDetector->dataBytesInclGapPixels;}; - - - /** - set roi - \param n number of rois - \param roiLimits array of roi - \returns success or failure - */ - int setROI(int n=-1,ROI roiLimits[]=NULL); - - /** - get roi from each detector and convert it to the multi detector scale - \param n number of roi - \returns an array of multidetector's rois - */ - slsDetectorDefs::ROI* getROI(int &n); - - - int sendROI(int n=-1,ROI roiLimits[]=NULL); - - /** - set/get readout flags - \param flag readout flag to be set - \returns current flag - */ - int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); - - /** - execute trimming - \param mode trim mode - \param par1 if noise, beam or fixed setting trimming it is count limit, if improve maximum number of iterations - \param par2 if noise or beam nsigma, if improve par2!=means vthreshold will be optimized, if fixed settings par2<0 trimwith median, par2>=0 trim with level - \param imod module number (-1 all) - \returns OK or FAIl (FAIL also if some channel are 0 or 63 - */ - int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); - - - //Corrections - - - /** - set flat field corrections - \param fname name of the flat field file (or "" if disable) - \returns 0 if disable (or file could not be read), >0 otherwise - */ - int setFlatFieldCorrection(string fname=""); - - /** - set flat field corrections - \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) - \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) - \returns 0 if ff correction disabled, >0 otherwise - */ - int setFlatFieldCorrection(double *corr, double *ecorr=NULL); - - - /** - get flat field corrections - \param corr if !=NULL will be filled with the correction coefficients - \param ecorr if !=NULL will be filled with the correction coefficients errors - \returns 0 if ff correction disabled, >0 otherwise - */ - int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL); - - - /** - set rate correction - \param t dead time in ns - if 0 disable correction, if >0 set dead time to t, if <0 set deadtime to default dead time for current settings - \returns 0 if rate correction disabled, >0 otherwise - */ - int setRateCorrection(double t=0); - - - /** - get rate correction - \param t reference for dead time - \returns 0 if rate correction disabled, >0 otherwise - */ - int getRateCorrection(double &t); - - - /** - get rate correction tau - \returns 0 if rate correction disabled, otherwise the tau used for the correction - */ - double getRateCorrectionTau(); - /** - get rate correction - \returns 0 if rate correction disabled, >0 otherwise - */ - int getRateCorrection(); - - /** - set bad channels correction - \param fname file with bad channel list ("" disable) - \returns 0 if bad channel disabled, >0 otherwise - */ - int setBadChannelCorrection(string fname=""); - - /** - set bad channels correction - \param nch number of bad channels - \param chs array of channels - \param ff 0 if normal bad channels, 1 if ff bad channels - \returns 0 if bad channel disabled, >0 otherwise - */ - int setBadChannelCorrection(int nch, int *chs, int ff=0); - - /** - get bad channels correction - \param bad pointer to array that if bad!=NULL will be filled with the bad channel list - \returns 0 if bad channel disabled or no bad channels, >0 otherwise - */ - int getBadChannelCorrection(int *bad=NULL); - - - /** - pure virtual function - get angular conversion - \param reference to diffractometer direction - \param angconv array that will be filled with the angular conversion constants - \returns 0 if angular conversion disabled, >0 otherwise - \sa mythenDetector::getAngularConversion - */ - int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; - - angleConversionConstant *getAngularConversionPointer(int imod=0) {return &thisDetector->angOff[imod];}; - - - - /** - decode data from the detector converting them to an array of doubles, one for each channle - \param datain data from the detector - \returns pointer to a double array with a data per channel - */ - double* decodeData(int *datain, int &nn, double *fdata=NULL); - - - - - - /** - flat field correct data - \param datain data array - \param errin error array on data (if NULL will default to sqrt(datain) - \param dataout array of corrected data - \param errout error on corrected data (if not NULL) - \returns 0 - */ - int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); - - - - - /** - rate correct data - \param datain data array - \param errin error array on data (if NULL will default to sqrt(datain) - \param dataout array of corrected data - \param errout error on corrected data (if not NULL) - \returns 0 - */ - int rateCorrect(double* datain, double *errin, double* dataout, double *errout); - - - /* /\** */ - /* pure virtual function */ - /* sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); */ - /* \param mp already merged postions */ - /* \param mv already merged data */ - /* \param me already merged errors (squared sum) */ - /* \param mm multiplicity of merged arrays */ - /* \returns OK or FAIL */ - /* \sa mythenDetector::resetMerging */ - /* *\/ */ - - /* int resetMerging(double *mp, double *mv,double *me, int *mm); */ - - /* /\** */ - /* pure virtual function */ - /* merge dataset */ - /* \param p1 angular positions of dataset */ - /* \param v1 data */ - /* \param e1 errors */ - /* \param mp already merged postions */ - /* \param mv already merged data */ - /* \param me already merged errors (squared sum) */ - /* \param mm multiplicity of merged arrays */ - /* \sa mythenDetector::addToMerging */ - /* *\/ */ - /* int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm); */ - - /* /\** pure virtual function */ - /* calculates the "final" positions, data value and errors for the emrged data */ - /* \param mp already merged postions */ - /* \param mv already merged data */ - /* \param me already merged errors (squared sum) */ - /* \param mm multiplicity of merged arrays */ - /* \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) */ - /* \sa mythenDetector::finalizeMerging */ - /* *\/ */ - /* int finalizeMerging(double *mp, double *mv,double *me, int *mm); */ - - /** - turns off server - */ - int exitServer(); - - - /** Allocates the memory for a sls_detector_module structure and initializes it - \returns myMod the pointer to the allocate dmemory location - - */ - sls_detector_module* createModule(){return createModule(thisDetector->myDetectorType);}; - - - /** Allocates the memory for a sls_detector_module structure and initializes it - \returns myMod the pointer to the allocate dmemory location - - */ - sls_detector_module* createModule(detectorType myDetectorType); - - /** frees the memory for a sls_detector_module structure - \param myMod the pointer to the memory to be freed - - */ - - void deleteModule(sls_detector_module *myMod); - - - /** calcualtes the total number of steps of the acquisition. - called when number of frames, number of cycles, number of positions and scan steps change - */ - int setTotalProgress(); - - /** returns the current progress in % */ - double getCurrentProgress(); - - - // double* convertAngles(double pos); - - - - - - /** - returns the detector type from hostname and controlport - \param - \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) - */ - static detectorType getDetectorType(const char *name, int cport=DEFAULT_PORTNO); - - /** - returns the detector type from hostname and controlport - \param - \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) - */ - static detectorType getDetectorType(int id); - - - /** - Returns detector id - \returns detector id - */ - - int getDetectorId(int i=-1) {return detId;}; + /** gap pixels in each direction */ + int nGappixels[2]; - /** - Receives a data frame from the detector socket - \returns pointer to the data (or NULL if failed) + /** data bytes including gap pixels */ + int dataBytesInclGapPixels; - */ - int* getDataFromDetector(int *retval=NULL); + /** additional json header */ + char receiver_additionalJsonHeader[MAX_STR_LENGTH]; - //int* + /** frames per file in receiver */ + int receiver_framesPerFile; + /** detector control server software API version */ + int64_t detectorControlAPIVersion; - /** returns if the detector is Master, slave or nothing - \param flag can be GET_MASTER, NO_MASTER, IS_MASTER, IS_SLAVE - \returns master flag of the detector - */ - masterFlags setMaster(masterFlags flag); + /** detector stop server software API version */ + int64_t detectorStopAPIVersion; - /** - Loads dark image or gain image from a file and sends it to the detector - \param index is 0 for dark image and 1 for gain image - \param fname file name to load data from + /** receiver server software API version */ + int64_t receiverAPIVersion; - */ - int loadImageToDetector(imageType index,string const fname); + /** receiver frames discard policy */ + frameDiscardPolicy receiver_frameDiscardMode; - /** - Called from loadImageToDetector to send the image to detector - \param index is 0 for dark image and 1 for gain image - \param arg image + /** receiver partial frames padding enable */ + bool receiver_framePadding; - */ - int sendImageToDetector(imageType index,short int imageVals[]); + } sharedSlsDetector; - /** - Sets/gets the synchronization mode of the various detectors - \param sync syncronization mode can be GET_SYNCHRONIZATION_MODE, NONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS - \returns current syncronization mode - */ - synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); - - /** - writes the counter memory block from the detector - \param startACQ is 1 to start acquisition after reading counter - \param fname file name to load data from - \returns OK or FAIL - */ - int writeCounterBlockFile(string const fname,int startACQ=0); - /** - gets counter memory block in detector - \param startACQ is 1 to start acquisition after reading counter - \param arg counter memory block from detector - \returns OK or FAIL - */ - int getCounterBlock(short int arg[],int startACQ=0); - /** - Resets counter in detector - \param startACQ is 1 to start acquisition after resetting counter - \returns OK or FAIL - */ - int resetCounterBlock(int startACQ=0); +public: - /** set/get counter bit in detector - * @param i is -1 to get, 0 to reset and any other value to set the counter bit - /returns the counter bit in detector - */ - int setCounterBit(int i = -1); - - - int getMoveFlag(int imod){if (moveFlag) return *moveFlag; else return 1;}; - - /** Frees the shared memory - should not be used*/ - int freeSharedMemory(); - - - - - - //receiver - - - /** - calls setReceiverTCPSocket if online and sets the flag - */ - int setReceiverOnline(int const online=GET_ONLINE_FLAG); - - /** - Checks if the receiver is really online - */ - string checkReceiverOnline(); - - /** - configure the socket communication and initializes the socket instances - - \param name receiver ip - if "" the current receiver hostname is used - \param receiver_port port for receiving data - if -1 the current is used - - \returns OK is connection succeded, FAIL otherwise - \sa sharedSlsDetector - */ - int setReceiverTCPSocket(string const name="", int const receiver_port=-1); - - - /** - Sets up the file directory - @param s fileDir file directory - \returns file dir - */ - string setFilePath(string s=""); - - /** - Sets up the file name - @param s file name - \returns file name - */ - string setFileName(string s=""); - - /** - Sets up the file format - @param f file format - \returns 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); - - /** - \returns file dir - */ - string getFilePath(){return setFilePath();}; - - /** - \returns file name - */ - string getFileName(){return setFileName();}; - - /** - \returns file name - */ - fileFormat getFileFormat(){return setFileFormat();}; - - /** - \returns file index - */ - int getFileIndex(){return setFileIndex();}; - - - /** Starts the listening mode of receiver - \returns OK or FAIL - */ - int startReceiver(); - - /** Stops the listening mode of receiver - \returns OK or FAIL - */ - 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(); - - - /** gets the status of the listening mode of receiver - \returns status - */ - runStatus getReceiverStatus(); - - /** gets the number of frames caught by receiver - \returns number of frames caught by receiver - */ - int getFramesCaughtByReceiver(); - - /** gets the number of frames caught by any one receiver (to avoid using threadpool) - \returns number of frames caught by any one receiver (master receiver if exists) - */ - int getFramesCaughtByAnyReceiver() {return getFramesCaughtByReceiver();}; - - /** gets the current frame index of receiver - \returns current frame index of receiver - */ - int getReceiverCurrentFrameIndex(); - - /** - * resets framescaught - * @param index frames caught by receiver - */ - int resetFramesCaught(); - - - /** Locks/Unlocks the connection to the receiver - /param lock sets (1), usets (0), gets (-1) the lock - /returns lock status of the receiver - */ - int lockReceiver(int lock=-1); - - /** - Returns the IP of the last client connecting to the receiver - */ - string getReceiverLastClientIP(); - - /** + using slsDetectorUtils::getDetectorType; + using postProcessing::flatFieldCorrect; + using postProcessing::rateCorrect; + using postProcessing::setBadChannelCorrection; + using angularConversion::readAngularConversion; + using angularConversion::writeAngularConversion; + using slsDetectorUtils::getAngularConversion; + + //FIXME: all pos or id arguments needed only for same multi signature + + /** + * Constructor called when creating new shared memory + * @param type detector type + * @param multiId multi detector shared memory id + * @param id sls detector id (position in detectors list) + * @param verify true to verify if shared memory version matches existing one + * @param m multiSlsDetector reference + */ + slsDetector(detectorType type, int multiId = 0, int id = 0, bool verify = true, multiSlsDetector* m = NULL); + + /** + * Constructor called when opening existing shared memory + * @param multiId multi detector shared memory id + * @param id sls detector id (position in detectors list) + * @param verify true to verify if shared memory version matches existing one + * @param m multiSlsDetector reference + */ + slsDetector(int multiId = 0, int id = 0, bool verify = true, multiSlsDetector* m = NULL); + + /** + * Destructor + */ + virtual ~slsDetector(); + + /** + * returns false. Used when reference is slsDetectorUtils and to determine + * if command can be implemented as slsDetector/multiSlsDetector object/ + */ + bool isMultiSlsDetectorClass(); + + /** + * Decode data from the detector converting them to an array of doubles, + * one for each channel (Mythen only) + * @param datain data from the detector + * @param nn size of datain array + * @param fdata double array of decoded data + * @returns pointer to a double array with a data per channel + */ + double* decodeData(int *datain, int &nn, double *fdata=NULL); + + /** + * Clears error mask and also the bit in parent det multi error mask + * @returns error mask + */ + int64_t clearAllErrorMask(); + + /** + * Set acquiring flag in shared memory + * @param b acquiring flag + */ + void setAcquiringFlag(bool b=false); + + /** + * Get acquiring flag from shared memory + * @returns acquiring flag + */ + bool getAcquiringFlag(); + + /** + * Check if acquiring flag is set, set error if set + * @returns FAIL if not ready, OK if ready + */ + bool isAcquireReady(); + + /** + * Check version compatibility with detector/receiver software + * (if hostname/rx_hostname has been set/ sockets created) + * @param p port type control port or receiver port + * @returns FAIL for incompatibility, OK for compatibility + */ + int checkVersionCompatibility(portType t); + + /** + * Get ID or version numbers + * @param mode version type + * @param imod module number in entire module list (gets decoded) (-1 for all) + * @returns Id or version number of that type + */ + int64_t getId(idMode mode, int imod=0); + + /** + * Free shared memory without creating objects + * If this is called, must take care to update + * multiSlsDetectors thisMultiDetector->numberofDetectors + * avoiding creating the constructor classes and mapping + * @param multiId multi detector Id + * @param slsId slsDetectorId or position of slsDetector in detectors list + */ + static void freeSharedMemory(int multiId, int slsId); + + /** + * Free shared memory and delete shared memory structure + * occupied by the sharedSlsDetector structure + * Is only safe to call if one deletes the slsDetector object afterward + * and frees multi shared memory/updates thisMultiDetector->numberOfDetectors + */ + void freeSharedMemory(); + + /** + * Get user details of shared memory + * Should only be called from multi detector level + * @returns string with user details + */ + std::string getUserDetails(); + + /** + * Sets the hostname of all sls detectors in shared memory + * Connects to them to set up online flag + * @param name hostname + */ + void setHostname(const char *name); + + /** + * Gets the hostname of detector + * @param pos insignificant + * @returns hostname + */ + string getHostname(int pos = -1); + + /** + * Appends detectors to the end of the list in shared memory + * Connects to them to set up online flag + * Should only be called from multi detector level + * @param name concatenated hostname of the sls detectors to be appended to the list + */ + void addMultipleDetectors(const char* name); + + /** + * Connect to the control port + * @returns OK, FAIL or undefined + */ + int connectControl(); + + /** + * Disconnect the control port + */ + void disconnectControl(); + + /** + * Connect to the data port + * @returns OK, FAIL or undefined + */ + int connectData(); + + /** + * Disconnect the data port + */ + void disconnectData(); + + /** + * Connect to the stop port + * @returns OK, FAIL or undefined + */ + int connectStop(); + + /** + * Disconnect the stop port + */ + void disconnectStop(); + + /** + * Get detector type by connecting to the detector without creating an object + * @param name hostname of detector + * @param cport TCP control port + * @returns detector tpe or GENERIC if failed + */ + static detectorType getDetectorType(const char *name, int cport=DEFAULT_PORTNO); + + /** + * Gets detector type from detector and set it in receiver + * @param type the detector type + * @returns detector type in receiver + */ + int setDetectorType(detectorType type=GET_DETECTOR_TYPE); + + /** + * Gets detector type (string) from detector and set it in receiver + * @param type string of detector type + * @returns detector type in receiver + */ + int setDetectorType(string stype); + + /** + * Get Detector type from shared memory variable + * @param pos insignificant + * @returns detector type from shared memory variable + */ + detectorType getDetectorsType(int pos = -1); + + /** + * Gets string version of detector type from shared memory variable + * @param pos insignificant + * @returns string version of detector type from shared memory variable + */ + string sgetDetectorsType(int pos=-1); + + /** + * Just to overload getDetectorType from users + * Gets string version of detector type from shared memory variable + * @returns gets string version of detector type from shared memory variable + */ + string getDetectorType(); + + /** + * Returns number of modules from shared memory (Mythen) + * Other detectors, it is 1 + * @returns number of modules + */ + int getNMods(); + + /** + * Returns number of modules in dimension d from shared memory (Mythen) + * Other detectors, it is 1 + * @param d dimension d + * @returns number of modules in dimension d + */ + int getNMod(dimension d); + + /** + * Returns maximum number of modules from shared memory (Mythen) + * Other detectors, it is 1 + * @returns maximum number of modules + */ + int getMaxMods(); + + /** + * Returns maximum number of modules in dimension d from shared memory (Mythen) + * Other detectors, it is 1 + * @param d dimension d + * @returns maximum number of modules in dimension d + */ + int getNMaxMod(dimension d); + + /** + * Returns maximum number of modules in dimension d (Mythen) + * from the detector directly. + * Other detectors, it is 1 + * @param d dimension d + * @returns maximum number of modules in dimension d + */ + int getMaxNumberOfModules(dimension d=X); // + + /** + * Sets/Gets the number of modules in dimension d (Mythen) + * from the detector directly. + * Other detectors, it is 1 + * @param i the number of modules to set to (-1 gets) + * @param d dimension d + * @returns the number of modules in dimension d + */ + int setNumberOfModules(int n=GET_FLAG, dimension d=X); + + /** + * returns the number of channels per that module + * from shared memory (Mythen) + * @param imod insignificant + * @returns number of channels per module + */ + int getChansPerMod(int imod=0); + + /** + * returns the number of channels per that module in dimension d + * from shared memory (Mythen) + * @param d dimension d + * @param imod insignificant + * @returns number of channels per module in dimension d + */ + int getChansPerMod( dimension d,int imod=0); + + /** + * Returns the total number of channels from shared memory + * @returns the total number of channels + */ + int getTotalNumberOfChannels(); + + /** + * Returns the total number of channels in dimension d from shared memory + * @param d dimension d + * @returns the total number of channels in dimension d + */ + int getTotalNumberOfChannels(dimension d); + + /** + * Returns the total number of channels of in dimension d including gap pixels + * from shared memory + * @param d dimension d + * @returns the total number of channels including gap pixels in dimension d + * including gap pixels + */ + int getTotalNumberOfChannelsInclGapPixels(dimension d); + + /** + * Returns the maximum number of channels from shared memory (Mythen) + * @returns the maximum number of channels + */ + int getMaxNumberOfChannels(); + + /** + * Returns the maximum number of channels in dimension d from shared memory (Mythen) + * @param d dimension d + * @returns the maximum number of channels in dimension d + */ + int getMaxNumberOfChannels(dimension d); + + /** + * Returns the maximum number of channels in dimension d from shared memory (Mythen) + * @param d dimension d + * @returns the maximum number of channels in dimension d + */ + int getMaxNumberOfChannelsInclGapPixels(dimension d); + + /** + * returns the number of channels per chip from shared memory (Mythen) + * @returns number of channels per chip + */ + int getNChans(); + + /** + * returns the number of channels per chip in dimension d from shared memory (Mythen) + * @param d dimension d + * @returns number of channels per chip in dimension d + */ + int getNChans(dimension d); + + /** + * returns the number of chips per module from shared memory (Mythen) + * @returns number of chips per module + */ + int getNChips(); + + /** + * returns the number of chips per module in dimension d from shared memory (Mythen) + * @param d dimension d + * @returns number of chips per module in dimension d + */ + int getNChips(dimension d); + + /** + * Get Detector offset from shared memory in dimension d + * @param d dimension d + * @returns offset in dimension d + */ + int getDetectorOffset(dimension d); + + /** + * Set Detector offset in shared memory in dimension d + * @param d dimension d + * @param off offset for detector + */ + void setDetectorOffset(dimension d, int off); + + /** + * Checks if the detector is online and sets the online flag + * @param online if GET_ONLINE_FLAG, only returns shared memory online flag, + * else sets the detector in online/offline state + * if OFFLINE_FLAG, (i.e. no communication to the detector - using only local structure - no data acquisition possible!); + * if ONLINE_FLAG, detector in online state (i.e. communication to the detector updating the local structure) + * @returns online/offline status + */ + int setOnline(int const online=GET_ONLINE_FLAG); + + /** + * Checks if each of the detector is online/offline + * @returns empty string if it is online + * else returns hostnameif it is offline + */ + string checkOnline(); + + /** + * Configure the TCP socket communciation and initializes the socket instances + * @param name hostname, empty if current hostname + * @param control_port TCP port for control commands, -1 if current is used + * @param stop_port TCP port for data commands, -1 if current is used + * @returns OK or FAIL + * \sa sharedSlsDetector + */ + int setTCPSocket(string const name="", int const control_port=-1, int const stop_port=-1); + + + /** + * Set/Gets TCP Port of detector or receiver + * @param t port type + * @param p port number (-1 gets) + * @returns port number + */ + int setPort(portType type, int num=-1); + + /** + * Returns the detector TCP control port \sa sharedSlsDetector + * @returns the detector TCP control port + */ + int getControlPort(); + + /** + * Returns the detector TCP stop port \sa sharedSlsDetector + * @returns the detector TCP stop port + */ + int getStopPort(); + + /** + * Returns the receiver TCP port \sa sharedSlsDetector + * @returns the receiver TCP port + */ + int getReceiverPort(); + + /** + * Lock server for this client IP + * @param p 0 to unlock, 1 to lock (-1 gets) + * @returns 1 for locked or 0 for unlocked + */ + int lockServer(int lock=-1); + + /** + * Get last client IP saved on detector server + * @returns last client IP saved on detector server + */ + string getLastClientIP(); + + /** + * Exit detector server + * @returns OK or FAIL + */ + int exitServer(); + + /** + * Executes a system command on the detector server + * e.g. mount an nfs disk, reboot and returns answer etc. + * @param cmd command to be executed + * @param answer is the answer from the detector + * @returns OK or FAIL + */ + int execCommand(string cmd, string answer); + + /** + * Updates some of the shared memory receiving the data from the detector + * @returns OK + */ + int updateDetectorNoWait(); + + /** + * Updates soem of the shared memory receiving the data from the detector + * calls updateDetectorNoWait + * @returns OK or FAIL or FORCE_RET + */ + int updateDetector(); + + /** + * Load configuration from a configuration File + * calls readConfigurationFile and gives it the stream + * @param fname configuration file name + * @return OK or FAIL + */ + int readConfigurationFile(string const fname); + + /** + * Load configuration from a stream + * @param infile stream + * @return OK or FAIL + */ + int readConfigurationFile(ifstream &infile); + + /** + * Write current configuration to a file + * calls writeConfigurationFile giving it a stream to write to + * @param fname configuration file name + * @returns OK or FAIL + */ + int writeConfigurationFile(string const fname); + + /** + * Write current configuration to a stream + * @param outfile outstream + * @param id detector id + * @returns OK or FAIL + */ + int writeConfigurationFile(ofstream &outfile, int id=-1); + + /** + * Returns the trimfile or settings file name (Useless??) + * @returns the trimfile or settings file name + */ + string getSettingsFile(); + + /** + * Writes a trim/settings file for module number imod, + * the values will be read from the current detector structure + * @param fname name of the file to be written + * @param imod module number + * @param iodelay io delay (detector specific) + * @param tau tau (detector specific) + * @returns OK or FAIL if the file could not be written + * \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int) + */ + using energyConversion::writeSettingsFile; + int writeSettingsFile(string fname, int imod, int iodelay, int tau); + + /** + * Get detector settings + * @param imod module number (-1 all) + * @returns current settings + */ + detectorSettings getSettings(int imod=-1); + + /** + * Load detector settings from the settings file picked from the trimdir/settingsdir + * Eiger only stores in shared memory ( a get will overwrite this) + * For Eiger, one must use threshold + * Gotthard, Propix, Jungfrau and Moench only sends the settings enum to the detector + * @param isettings settings + * @param imod module number (-1 all) + * @returns current settings + */ + detectorSettings setSettings(detectorSettings isettings, int imod=-1); + + /** + * Send detector settings only (set only for Jungfrau, Gotthard, Moench, get for all) + * Only the settings enum is sent to the detector, where it will + * initialize al the dacs already hard coded in the detector server + * @param isettings settings + * @param imod module number (-1 all) + * @returns current settings + */ + detectorSettings sendSettingsOnly(detectorSettings isettings, int imod=-1); + + /** + * Get threshold energy (Mythen and Eiger) + * @param imod module number (-1 all) + * @returns current threshold value for imod in ev (-1 failed) + */ + int getThresholdEnergy(int imod=-1); + + + /** + * Set threshold energy (Mythen and Eiger) + * For Eiger, calls setThresholdEneryAndSettings + * @param e_eV threshold in eV + * @param imod module number (-1 all) + * @param isettings ev. change settings + * @param tb 1 to include trimbits, 0 to exclude + * @returns current threshold value for imod in ev (-1 failed) + */ + int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS, int tb=1); + + /** + * Set threshold energy and settings (Eiger only) + * @param e_eV threshold in eV + * @param isettings ev. change settings + * @param tb 1 to include trimbits, 0 to exclude + * @returns OK if successful, else FAIL + */ + int setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb=1); + + /** + * Returns the detector trimbit/settings directory \sa sharedSlsDetector + * @returns the trimbit/settings directory + */ + std::string getSettingsDir(); + + /** + * Sets the detector trimbit/settings directory \sa sharedSlsDetector + * @param s trimbits/settings directory + * @returns the trimbit/settings directory + */ + std::string setSettingsDir(string s); + + /** + * Returns the calibration files directory \sa sharedSlsDetector (Mythen) + * @returns the calibration files directory + */ + std::string getCalDir(); + + /** + * Sets the calibration files directory \sa sharedSlsDetector (Mythen) + * @param s the calibration files directory + * @returns the calibration files directory + */ + std::string setCalDir(string s); + + /** + * Loads the modules settings/trimbits reading from a specific file + * file name extension is automatically generated. + * @param fname specific settings/trimbits file + * @param imod module index of the entire list, + * from which will be calculated the detector index and the module index (-1 for all) + * returns OK or FAIL + */ + int loadSettingsFile(string fname, int imod=-1); + + /** + * Saves the modules settings/trimbits to a specific file + * file name extension is automatically generated. + * @param fname specific settings/trimbits file + * @param imod module number (-1 for all) + * returns OK or FAIL + */ + int saveSettingsFile(string fname, int imod=-1); + + /** + * Loads the modules calibration data reading from a specific file (Mythen) + * file name extension is automatically generated. + * @param fname specific calibration file + * @param imod module number (-1 for all) + * returns OK or FAIL + */ + int loadCalibrationFile(string fname, int imod=-1); + + /** + * Saves the modules calibration data to a specific file (Mythen) + * file name extension is automatically generated. + * @param fname specific calibration file + * @param imod module number (-1 for all) + * returns OK or FAIL + */ + int saveCalibrationFile(string fname, int imod=-1); + + /** + * Sets/gets the detector in position i as master of the structure (Mythen) + * (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) + */ + masterFlags setMaster(masterFlags flag); + + /** + * Sets/gets the synchronization mode of the various detector (Mythen) + * @param sync syncronization mode + * @returns current syncronization mode + */ + synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); + + /** + * Calcualtes the total number of steps of the acquisition + * Called when number of frames, number of cycles, number of positions and scan steps change + * @returns the total number of steps of the acquisition + */ + int setTotalProgress(); + + /** + * Returns the current progress in % + * @returns the current progress in % + */ + double getCurrentProgress(); + + /** + * Get run status of the detector + * @returns the status of the detector + */ + runStatus getRunStatus(); + + /** + * Prepares detector for acquisition (Eiger and Gotthard) + * For Gotthard, it sets the detector data transmission mode (CPU or receiver) + * @returns OK or FAIL + */ + int prepareAcquisition(); + + /** + * Cleans up after acquisition (Gotthard only) + * For Gotthard, it sets the detector data transmission to default (via CPU) + * @returns OK or FAIL + */ + int cleanupAcquisition(); + + /** + * Start detector acquisition (Non blocking) + * @returns OK or FAIL if even one does not start properly + */ + int startAcquisition(); + + /** + * Stop detector acquisition + * @returns OK or FAIL + */ + int stopAcquisition(); + + /** + * Start readout (without exposure or interrupting exposure) (Mythen) + * @returns OK or FAIL + */ + int startReadOut(); + + /** + * Start detector acquisition and read all data (Blocking until end of acquisition) + * (Mythen, puts all data into a data queue. Others, data at receiver via udp packets) + * @returns pointer to the front of the data queue (return significant only for Mythen) + * \sa startAndReadAllNoWait getDataFromDetector dataQueue + */ + int* startAndReadAll(); + + /** + * Start detector acquisition and call read out, but not reading (data for Mythen, + * and status for other detectors) from the socket. + * (startAndReadAll calls this and getDataFromDetector. Client is not blocking, + * but server is blocked until getDataFromDetector is called. so not recommended + * for users) + * @returns OK or FAIL + */ + int startAndReadAllNoWait(); + + /** + * Reads from the detector socket (data frame for Mythen and status for other + * detectors) + * @returns pointer to the data or NULL. If NULL disconnects the socket + * (return significant only for Mythen) + * Other detectors return NULL + * \sa getDataFromDetector + */ + int* getDataFromDetector(int *retval=NULL); + + /** + * Requests and receives a single data frame from the detector + * (Mythen: and puts it in the data queue) + * @returns pointer to the data or NULL. (return Mythen significant) + * Other detectors return NULL + * \sa getDataFromDetector + */ + int* readFrame(); + + /** + * Receives all data from the detector + * (Mythen: and puts them in a data queue) + * @returns pointer to the front of the queue or NULL (return Mythen significant) + * Other detectors return NULL + * \sa getDataFromDetector dataQueue + */ + int* readAll(); + + /** + * Requests detector for all data, calls readAll afterwards + * (Mythen: and puts them in a data queue) + * @returns pointer to the front of the queue or NULL (return Mythen significant) + * Other detectors return NULL + * \sa getDataFromDetector dataQueue + */ + int readAllNoWait(); + + /** + * Configures in detector the destination for UDP packets (Not Mythen) + * @returns OK or FAIL + */ + int configureMAC(); + + /** + * Set/get timer value (not all implemented for all detectors) + * @param index timer index + * @param t time in ns or number of...(e.g. frames, gates, probes) + * \param imod module number (pointless in slsDetector) + * @returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t setTimer(timerIndex index, int64_t t=-1, int imod = -1); + + /** + * Set/get timer value left in acquisition (not all implemented for all detectors) + * @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); + + /** + * Set speed + * @param sp speed type (clkdivider option for Jungfrau and Eiger, others for Mythen/Gotthard) + * @param value (clkdivider 0,1,2 for full, half and quarter speed). Other values check manual + * @returns value of speed set + */ + int setSpeed(speedVariable sp, int value=-1); + + /** + * Set/get dynamic range and updates the number of dataBytes + * (Eiger: If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to 1) + * @param i dynamic range (-1 get) + * @returns current dynamic range + * \sa sharedSlsDetector + */ + int setDynamicRange(int n=-1); + + /** + * Recalculated number of data bytes + * @returns tota number of data bytes + */ + int getDataBytes(); + + /** + * Recalculated number of data bytes including gap pixels + * @returns tota number of data bytes including gap pixels + */ + int getDataBytesInclGapPixels(); + + /** + * Set/get 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 all modules) + * @returns current DAC value + */ + dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); + + /** + * Get adc value + * @param index adc(DAC) index + * @param imod module number (if -1 all modules) + * @returns current adc value (temperature for eiger and jungfrau in millidegrees) + */ + dacs_t getADC(dacIndex index, int imod=0); + + /** + * Set/get timing mode + * @param pol timing mode (-1 gets) + * @returns current timing mode + */ + externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); + + /** + * Set/get external signal flags (to specify triggerinrising edge etc) (Gotthard, Mythen) + * @param pol external signal flag (-1 gets) + * @param signalindex singal index (0 - 3) + * @returns current timing mode + */ + externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); + + /** + * Set/get readout flags (Eiger, Mythen) + * @param flag readout flag (Eiger options: parallel, nonparallel, safe etc.) (-1 gets) + * @returns readout flag + */ + int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); + + /** + * Write in a register. For Advanced users + * @param addr address of register + * @param val value to write into register + * @returns value read after writing + */ + uint32_t writeRegister(uint32_t addr, uint32_t val); + + /** + * Read from a register. For Advanced users + * @param addr address of register + * @returns value read from register + */ + uint32_t readRegister(uint32_t addr); + + /** + * Set bit in a register. For Advanced users + * @param addr address of register + * @param n nth bit + * @returns value read from register + */ + uint32_t setBit(uint32_t addr, int n); + + /** + * Clear bit in a register. For Advanced users + * @param addr address of register + * @param n nth bit + * @returns value read from register + */ + uint32_t clearBit(uint32_t addr, int n); + + /** + * Set network parameter + * @param p network parameter type + * @param s network parameter value + * @returns network parameter value set (from getNetworkParameter) + */ + string setNetworkParameter(networkParameter index, string value); + + /** + * Get network parameter + * @param p network parameter type + * @returns network parameter value set (from getNetworkParameter) + */ + string getNetworkParameter(networkParameter index); + + /** + * Returns the detector MAC address\sa sharedSlsDetector + * @returns the detector MAC address + */ + string getDetectorMAC(); + + /** + * Returns the detector IP address\sa sharedSlsDetector + * @returns the detector IP address + */ + string getDetectorIP(); + + /** + * Returns the receiver IP address\sa sharedSlsDetector + * @returns the receiver IP address + */ + string getReceiver(); + + /** + * Returns the receiver UDP IP address\sa sharedSlsDetector + * @returns the receiver UDP IP address + */ + string getReceiverUDPIP(); + + /** + * Returns the receiver UDP MAC address\sa sharedSlsDetector + * @returns the receiver UDP MAC address + */ + string getReceiverUDPMAC(); + + /** + * Returns the receiver UDP port\sa sharedSlsDetector + * @returns the receiver UDP port + */ + string getReceiverUDPPort(); + + /** + * Returns the receiver UDP port 2 of same interface\sa sharedSlsDetector + * @returns the receiver UDP port 2 of same interface + */ + string getReceiverUDPPort2(); + + /** + * Returns the client zmq port \sa sharedSlsDetector + * @returns the client zmq port + */ + string getClientStreamingPort(); + + /** + * Returns the receiver zmq port \sa sharedSlsDetector + * @returns the receiver zmq port + */ + string getReceiverStreamingPort(); + + /** + * Returns the client zmq ip \sa sharedSlsDetector + * @returns the client zmq ip, returns "none" if default setting and no custom ip set + */ + string getClientStreamingIP(); + + /** + * Returns the receiver zmq ip \sa sharedSlsDetector + * @returns the receiver zmq ip, returns "none" if default setting and no custom ip set + */ + string getReceiverStreamingIP(); + + /** + * Validates the format of the detector MAC address and sets it \sa sharedSlsDetector + * @param detectorMAC detector MAC address + * @returns the detector MAC address + */ + string setDetectorMAC(string detectorMAC); + + /** + * Validates the format of the detector IP address and sets it \sa sharedSlsDetector + * @param detectorIP detector IP address + * @returns the detector IP address + */ + string setDetectorIP(string detectorIP); + + /** + * Validates and sets the receiver. + * Also updates the receiver with all the shared memory parameters significant for the receiver + * Also configures the detector to the receiver as UDP destination + * @param receiver receiver hostname or IP address + * @returns the receiver IP address from shared memory + */ + string setReceiver(string receiver); + + /** + * Validates the format of the receiver UDP IP address and sets it \sa sharedSlsDetector + * @param udpip receiver UDP IP address + * @returns the receiver UDP IP address + */ + string setReceiverUDPIP(string udpip); + + /** + * Validates the format of the receiver UDP MAC address and sets it \sa sharedSlsDetector + * @param udpmac receiver UDP MAC address + * @returns the receiver UDP MAC address + */ + string setReceiverUDPMAC(string udpmac); + + /** + * Sets the receiver UDP port\sa sharedSlsDetector + * @param udpport receiver UDP port + * @returns the receiver UDP port + */ + int setReceiverUDPPort(int udpport); + + /** + * Sets the receiver UDP port 2\sa sharedSlsDetector + * @param udpport receiver UDP port 2 + * @returns the receiver UDP port 2 + */ + int setReceiverUDPPort2(int udpport); + + /** + * Sets the client zmq port\sa sharedSlsDetector + * @param port client zmq port (includes "multi" at the end if it should + * calculate individual ports) + * @returns the client zmq port + */ + string setClientStreamingPort(string port); + + /** + * Sets the receiver zmq port\sa sharedSlsDetector + * @param port receiver zmq port (includes "multi" at the end if it should + * calculate individual ports) + * @returns the receiver zmq port + */ + string setReceiverStreamingPort(string port); + + /** + * Sets the client zmq ip\sa sharedSlsDetector + * @param sourceIP client zmq ip + * @returns the client zmq ip, returns "none" if default setting and no custom ip set + */ + string setClientStreamingIP(string sourceIP); + + /** + * Sets the receiver zmq ip\sa sharedSlsDetector + * @param sourceIP receiver zmq ip. If empty, uses rx_hostname + * @returns the receiver zmq ip, returns "none" if default setting and no custom ip set + */ + string setReceiverStreamingIP(string sourceIP); + + /** + * Execute a digital test (Gotthard, Mythen) + * @param mode testmode type + * @param imod module index (-1 for all) + * @returns result of test + */ + int digitalTest(digitalTestMode mode, int imod=0); + + /** + * Execute trimming (Mythen) + * @param mode trimming mode type + * @param par1 parameter 1 + * @param par2 parameter 2 + * @param imod module index (-1 for all) + * @returns result of trimming + */ + int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); + + /** + * Load dark or gain image to detector (Gotthard) + * @param index image type, 0 for dark image and 1 for gain image + * @param fname file name from which to load image + * @returns OK or FAIL + */ + int loadImageToDetector(imageType index,string const fname); + + /** + * Called from loadImageToDetector to send the image to detector + * @param index image type, 0 for dark image and 1 for gain image + * @param imageVals image + * @returns OK or FAIL + */ + int sendImageToDetector(imageType index,short int imageVals[]); + + /** + * Writes the counter memory block from the detector (Gotthard) + * @param fname file name to load data from + * @param startACQ is 1 to start acquisition after reading counter + * @returns OK or FAIL + */ + int writeCounterBlockFile(string const fname,int startACQ=0); + + /** + * Gets counter memory block in detector (Gotthard) + * @param arg counter memory block from detector + * @param startACQ 1 to start acquisition afterwards, else 0 + * @returns OK or FAIL + */ + int getCounterBlock(short int arg[],int startACQ=0); + + /** + * Resets counter in detector + * @param startACQ is 1 to start acquisition after resetting counter + * @returns OK or FAIL + */ + int resetCounterBlock(int startACQ=0); + + /** + * Set/get counter bit in detector (Gotthard) + * @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); + + /** + * Set ROI (Gotthard) + * At the moment only one set allowed + * @param n number of rois + * @param roiLimits array of roi + * @returns OK or FAIL + */ + int setROI(int n=-1,ROI roiLimits[]=NULL); + + /** + * Get ROI from each detector and convert it to the multi detector scale (Gotthard) + * @param n number of rois + * @returns OK or FAIL + */ + slsDetectorDefs::ROI* getROI(int &n); + + /** + * Returns number of rois + * @returns number of ROIs + */ + int getNRoi(); + + /** + * Send ROI to the detector after calculating + * from setROI + * @param n number of ROIs (-1 to get) + * @param roiLimits ROI + * @returns OK or FAIL + */ + int sendROI(int n=-1,ROI roiLimits[]=NULL); + + /** + * Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert users + * @param addr address of adc register + * @param val value + * @returns return value (mostly -1 as it can't read adc register) + */ + int writeAdcRegister(int addr, int val); + + /** + * Activates the detector (Eiger only) + * @param enable active (1) or inactive (0), -1 gets + * @returns 0 (inactive) or 1 (active) + */ + int activate(int const enable=GET_ONLINE_FLAG); + + /** + * Returns the enable if data will be flipped across x or y axis (Eiger) + * @param d axis across which data is flipped + * @returns 1 for flipped, else 0 + */ + int getFlippedData(dimension d=X); + + /** + * Sets the enable which determines if + * data will be flipped across x or y axis (Eiger) + * @param d axis across which data is flipped + * @param value 0 or 1 to reset/set or -1 to get value + * @returns enable flipped data across x or y axis + */ + int setFlippedData(dimension d=X, int value=-1); + + /** + * Sets all the trimbits to a particular value (Eiger) + * @param val trimbit value + * @param imod module number, -1 means all modules + * @returns OK or FAIL + */ + int setAllTrimbits(int val, int imod=-1); + + /** + * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger) + * 4 bit mode gap pixels only in gui call back + * @param val 1 sets, 0 unsets, -1 gets + * @returns gap pixel enable or -1 for error + */ + int enableGapPixels(int val=-1); + + /** + * Sets the number of trim energies and their value (Eiger) + * \sa sharedSlsDetector + * @param nen number of energies + * @param en array of energies + * @returns number of trim energies + */ + int setTrimEn(int nen, int *en=NULL); + + /** + * Returns the number of trim energies and their value (Eiger) + * \sa sharedSlsDetector + * @param en array of energies + * @returns number of trim energies + */ + int getTrimEn(int *en=NULL); + + /** + * Pulse Pixel (Eiger) + * @param n is number of times to pulse + * @param x is x coordinate + * @param y is y coordinate + * @returns OK or FAIL + */ + int pulsePixel(int n=0,int x=0,int y=0); + + /** + * Pulse Pixel and move by a relative value (Eiger) + * @param n is number of times to pulse + * @param x is relative x value + * @param y is relative y value + * @returns OK or FAIL + */ + int pulsePixelNMove(int n=0,int x=0,int y=0); + + /** + * Pulse Chip (Eiger) + * @param n is number of times to pulse + * @returns OK or FAIL + */ + int pulseChip(int n=0); + + /** + * Set/gets threshold temperature (Jungfrau) + * @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); + + /** + * Enables/disables temperature control (Jungfrau) + * @param val value, -1 gets + * @param imod module number, -1 is all + * @returns temperature control enable + */ + int setTemperatureControl(int val=-1, int imod=-1); + + /** + * Resets/ gets over-temperature event (Jungfrau) + * @param val value, -1 gets + * @param imod module number, -1 is all + * @returns over-temperature event + */ + int setTemperatureEvent(int val=-1, int imod=-1); + + /** + * Set storage cell that stores first acquisition of the series (Jungfrau) + * @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); + + /** + * Programs FPGA with pof file (Jungfrau) + * @param fname file name + * @returns OK or FAIL + */ + int programFPGA(string fname); + + /** + * Resets FPGA (Jungfrau) + * @returns OK or FAIL + */ + int resetFPGA(); + + /** + * Power on/off Chip (Jungfrau) + * @param ival on is 1, off is 0, -1 to get + * @returns OK or FAIL + */ + int powerChip(int ival= -1); + + /** + * Automatic comparator disable (Jungfrau) + * @param ival on is 1, off is 0, -1 to get + * @returns OK or FAIL + */ + int setAutoComparatorDisableMode(int ival= -1); + + + /** + * Returns the trimbits from the detector's shared memmory (Mythen, Eiger) + * @param retval is the array with the trimbits + * @param fromDetector is true if the trimbits shared memory have to be + * uploaded from detector + * @returns total number of channels for the detector + */ + int getChanRegs(double* retval,bool fromDetector); + + /** + * Configure module (who calls this?) + * @param imod module number (-1 all) + * @returns current register value + * \sa ::sls_detector_module + */ + int setModule(int reg, int imod=-1); + + /** + * Configure Module (Mythen, Eiger) + * Called for loading trimbits and settings settings to the detector + * @param module module to be set - must contain correct module number and + * also channel and chip registers + * @param iodelay iodelay (detector specific) + * @param tau tau (detector specific) + * @param e_eV threashold in eV (detector specific) + * @param gainval pointer to extra gain values + * @param offsetval pointer to extra offset values + * @param tb 1 to include trimbits, 0 to exclude (used for eiger) + * @returns current register value + * \sa ::sls_detector_module + */ + int setModule(sls_detector_module module, int iodelay, int tau, int e_eV, + int* gainval=0, int* offsetval=0, int tb=1); + + + /** + * Get module structure from detector (all detectors) + * @param imod module number + * @returns pointer to module structure (which has been created and must then be deleted) + */ + sls_detector_module *getModule(int imod); + + /** + * Configure channel (Mythen) + * @param reg channel register + * @param ichan channel number (-1 all) + * @param ichip chip number (-1 all) + * @param imod module number (-1 all) + * @returns current register value + * \sa ::sls_detector_channel + */ + int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); + + /** + * Configure channel (Mythen) + * @param chan channel to be set - + * must contain correct channel, module and chip number + * @returns current register value + */ + int setChannel(sls_detector_channel chan); + + /** + * Get channel (Mythen) + * @param ichan channel number + * @param ichip chip number + * @param imod module number + * @returns current channel structure for channel + */ + sls_detector_channel getChannel(int ichan, int ichip, int imod); + + /** + * Configure chip (Mythen) + * @param reg chip register + * @param ichip chip number (-1 all) + * @param imod module number (-1 all) + * @returns current register value + * \sa ::sls_detector_chip + */ + int setChip(int reg, int ichip=-1, int imod=-1); + + /** + * Configure chip (Mythen) + * @param chip chip to be set + * must contain correct module and chip number and also channel registers + * @returns current register value + * \sa ::sls_detector_chip + */ + int setChip(sls_detector_chip chip); + + /** + * Get chip (Mythen) + * @param ichip chip number + * @param imod module number + * @returns current chip structure for channel + * \bug probably does not return corretly! + */ + sls_detector_chip getChip(int ichip, int imod); + + /** + * Get Move Flag (Mythen) + * @param imod module number (-1 all) + * @param istep step index + * @returns move flag + */ + int getMoveFlag(int imod); + + /** + * Fill Module mask for flat field corrections (Mythen) + * @param mM array + * @returns number of modules + */ + int fillModuleMask(int *mM); + + /** + * Calibrate Pedestal (ChipTestBoard) + * Starts acquisition, calibrates pedestal and writes to fpga + * @param frames number of frames + * @returns number of frames + */ + int calibratePedestal(int frames = 0); + + /** + * Set Rate correction (Mythen, Eiger) + * @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); + + /** + * Get rate correction (Mythen, Eiger) + * @param t reference for dead time + * @returns 0 if rate correction disabled, > 0 otherwise + */ + int getRateCorrection(double &t); + + /** + * Get rate correction tau (Mythen, Eiger) + * @returns 0 if rate correction disabled, otherwise the tau used for the correction + */ + double getRateCorrectionTau(); + + /** + * Get rate correction (Mythen, Eiger) + * @returns 0 if rate correction disabled, > 0 otherwise + */ + int getRateCorrection(); + + /** + * Rate correct data (Mythen) + * @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); + + /** + * Set flat field corrections (Mythen) + * @param fname name of the flat field file (or "" if disable) + * @returns 0 if disable (or file could not be read), >0 otherwise + */ + int setFlatFieldCorrection(string fname=""); + + /** + * Set flat field corrections (Mythen) + * @param corr if !=NULL the flat field corrections will be filled with + * corr (NULL usets ff corrections) + * @param ecorr if !=NULL the flat field correction errors will be filled + * with ecorr (1 otherwise) + * @returns 0 if ff correction disabled, >0 otherwise + */ + int setFlatFieldCorrection(double *corr, double *ecorr=NULL); + + /** + * Get flat field corrections (Mythen) + * @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); + + /** + * Flat field correct data (Mythen) + * @param datain data array + * @param errin error array on data (if NULL will default to sqrt(datain) + * @param dataout array of corrected data + * @param errout error on corrected data (if not NULL) + * @returns 0 + */ + int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); + + /** + * Set bad channels correction (Mythen) + * @param fname file with bad channel list ("" disable) + * @returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(string fname=""); + + /** + * Set bad channels correction (Mythen) + * @param nch number of bad channels + * @param chs array of channels + * @param ff 0 if normal bad channels, 1 if ff bad channels + * @returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(int nch, int *chs, int ff=0); + + /** + * Get bad channels correction (Mythen) + * @param bad pointer to array that if bad!=NULL will be filled with the + * bad channel list + * @returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + int getBadChannelCorrection(int *bad=NULL); + + /** + * Reads an angular conversion file (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::readAngularConversion + * @param fname file to be read + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int readAngularConversionFile(string fname=""); + + /** + * Reads an angular conversion file (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::readAngularConversion + * @param ifs input stream + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int readAngularConversion(ifstream& ifs); + + /** + * Writes an angular conversion file (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::writeAngularConversion + * @param fname file to be written + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int writeAngularConversion(string fname=""); + + /** + * Writes an angular conversion file (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::writeAngularConversion + * @param ofs output stream + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int writeAngularConversion(ofstream &ofs); + + /** + * Get angular conversion (Mythen, Gotthard) + * \sa angleConversionConstant mythenDetector::getAngularConversion + * @param direction reference to diffractometer + * @param angconv array that will be filled with the angular conversion constants + * @returns 0 if angular conversion disabled, >0 otherwise + */ + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; + + /** + * Return angular conversion pointer (Mythen, Gotthard) + * @param imod module number + * @returns angular conversion pointer + */ + angleConversionConstant *getAngularConversionPointer(int imod=0); + + /** + * Prints receiver configuration + * @returns OK or FAIL + */ + int printReceiverConfiguration(); + + /** + * Checks if receiver is online and set flag + * Also initializes the data socekt + * @param online 1 to set online, 0 to set offline, -1 gets + * @returns online, offline (from shared memory) + */ + int setReceiverOnline(int const online=GET_ONLINE_FLAG); + + /** + * Checks if the receiver is really online + * @returns empty string if online, else returns receiver hostname + */ + string checkReceiverOnline(); + + /** + * Configure the socket communication and initializes the socket instances + * @param name receiver ip - if "" the current receiver hostname is used + * @param receiver_port port for receiving data - if -1 the current is used + * @returns OK is connection succeded, FAIL otherwise + * \sa sharedSlsDetector + */ + int setReceiverTCPSocket(string const name="", int const receiver_port=-1); + + /** + * Locks/Unlocks the connection to the receiver + * @param lock sets (1), usets (0), gets (-1) the lock + * @returns lock status of the receiver + */ + int lockReceiver(int lock=-1); + + /** + * Returns the IP of the last client connecting to the receiver + * @returns the IP of the last client connecting to the receiver + */ + string getReceiverLastClientIP(); + + /** + * Exits the receiver TCP server + * @retutns OK or FAIL + */ + int exitReceiver(); + + /** updates the shared memory receiving the data from the detector (without asking and closing the connection /returns OK - */ - int updateReceiverNoWait(); + */ + int updateReceiverNoWait(); - /** - updates the shared memory receiving the data from the detector - /returns OK - */ - int updateReceiver(); + /** + * Updates the shared memory receiving the data from the detector + * @returns OK or FAIL + */ + int updateReceiver(); - /** - Turns off the receiver server! - */ - int exitReceiver(); + /** + * Send the multi detector size to the detector + */ + void sendMultiDetectorSize(); - /** - 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); + /** + * Send the detector pos id to the receiver + * for various file naming conventions for multi detectors in receiver + */ + void setDetectorId(); - /** - 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); + /** + * Send the detector host name to the receiver + * for various handshaking required with the detector + */ + void setDetectorHostname(); + + /** + * Returns output file directory + * @returns output file directory + */ + string getFilePath(); + + /** + * Sets up the file directory + * @param s file directory + * @returns file dir + */ + string setFilePath(string s=""); + + /** + * Returns file name prefix + * @returns file name prefix + */ + string getFileName(); + + /** + * Sets up the file name prefix + * @param s file name prefix + * @returns file name prefix + */ + string setFileName(string s=""); + + /** + * Sets the max frames per file in receiver + * @param f max frames per file + * @returns max frames per file in receiver + */ + int setReceiverFramesPerFile(int f = -1); + + /** + * Sets the frames discard policy in receiver + * @param f frames discard policy + * @returns frames discard policy set in receiver + */ + frameDiscardPolicy setReceiverFramesDiscardPolicy(frameDiscardPolicy f = GET_FRAME_DISCARD_POLICY); + + /** + * Sets the partial frames padding enable in receiver + * @param f partial frames padding enable + * @returns partial frames padding enable in receiver + */ + int setReceiverPartialFramesPadding(int f = -1); + + /** + * Returns file format + * @returns file name + */ + fileFormat getFileFormat(); + + /** + * Sets up the file format + * @param f file format + * @returns file format + */ + fileFormat setFileFormat(fileFormat f=GET_FILE_FORMAT); + + /** + * Returns file index + * @returns file index + */ + int getFileIndex(); + + /** + * Sets up the file index + * @param i file index + * @returns file index + */ + int setFileIndex(int i=-1); + + /** + * Receiver starts listening to packets + * @returns OK or FAIL + */ + int startReceiver(); + + /** + * Stops the listening mode of receiver + * @returns OK or FAIL + */ + int stopReceiver(); + + /** + * Sets the receiver to start any readout remaining in the fifo and + * change status to transmitting (Mythen) + * The status changes to run_finished when fifo is empty + */ + runStatus startReceiverReadout(); + + /** + * Gets the status of the listening mode of receiver + * @returns status + */ + runStatus getReceiverStatus(); + + /** + * Gets the number of frames caught by receiver + * @returns number of frames caught by receiver + */ + int getFramesCaughtByReceiver(); + + /** + * 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(); + + /** + * Gets the current frame index of receiver + * @returns current frame index of receiver + */ + int getReceiverCurrentFrameIndex(); + + /** + * Resets framescaught in receiver + * Use this when using startAcquisition instead of acquire + * @returns OK or FAIL + */ + int resetFramesCaught(); + + /** + * 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); + + /** + * 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); + + /** + * Sets the read receiver frequency + * if data required from receiver randomly readRxrFrequency=0, + * else every nth frame to be sent to gui/callback + * @param freq is the receiver read frequency. Value 0 is 200 ms timer (other + * frames not sent), 1 is every frame, 2 is every second frame etc. + * @returns read receiver frequency + */ + int setReadReceiverFrequency(int freq=-1); + + /** + * 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); + + /** + * 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/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); + + /** + * 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); + + /** + * 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); + + /** + * 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); + + /** + * If data streaming in receiver is enabled, + * restream the stop dummy packet from receiver + * Used usually for Moench, + * in case it is lost in network due to high data rate + * @returns OK if success else FAIL + */ + int restreamStopFromReceiver(); + + /** + * Opens pattern file and sends pattern to CTB + * @param fname pattern file to open + * @returns OK/FAIL + */ + int setCTBPattern(string fname); + + /** + * Writes a pattern word to the CTB + * @param addr address of the word, -1 is I/O control register, -2 is clk control register + * @param word 64bit word to be written, -1 gets + * @returns actual value + */ + uint64_t setCTBWord(int addr,uint64_t word=-1); + + /** + * Sets the pattern or loop limits in the CTB + * @param level -1 complete pattern, 0,1,2, loop level + * @param start start address if >=0 + * @param stop stop address if >=0 + * @param n number of loops (if level >=0) + * @returns OK/FAIL + */ + int setCTBPatLoops(int level,int &start, int &stop, int &n); + + /** + * Sets the wait address in the CTB + * @param level 0,1,2, wait level + * @param addr wait address, -1 gets + * @returns actual value + */ + int setCTBPatWaitAddr(int level, int addr=-1); + + /** + * Sets the wait time in the CTB + * @param level 0,1,2, wait level + * @param t wait time, -1 gets + * @returns actual value + */ + int setCTBPatWaitTime(int level, uint64_t t=-1); + +private: + + /** + * Get Detector Type from Shared Memory (opening shm without verifying size) + * @param multiId multi detector Id + * @param verify true to verify if shm size matches existing one + * @returns detector type + */ + detectorType getDetectorTypeFromShm(int multiId, bool verify = true); + + /** + * Initialize shared memory + * @param created true if shared memory must be created, else false to open + * @param type type of detector + * @param multiId multi detector Id + * @param verify true to verify if shm size matches existing one + * @returns true if the shared memory was created now + */ + void initSharedMemory(bool created, detectorType type, int multiId, bool verify = true); + + /** + * Sets detector parameters depending detector type + * @param type detector type + * @param list structure of parameters to initialize depending on detector type + */ + void setDetectorSpecificParameters(detectorType type, detParameterList& list); + + /** + * Calculate shared memory size based on detector type + * @param type type of detector + * @returns size of shared memory of sharedSlsDetector structure + */ + int calculateSharedMemorySize(detectorType type); + + /** + * Initialize detector structure to defaults + * Called when new shared memory is created + * @param type type of detector + */ + void initializeDetectorStructure(detectorType type); + + /** + * Initialize class members (and from parent classes) + * Also connect member pointers to detector structure pointers + * Called when shared memory created/existed + */ + void initializeMembers(); + + /** + * Initialize detector structure + * Called when new shared memory created + * Initializes the member pointers to defaults as well + */ + void initializeDetectorStructurePointers(); + + /** + * Allocates the memory for a sls_detector_module structure and initializes it + * Uses current detector type + * @returns myMod the pointer to the allocate dmemory location + */ + sls_detector_module* createModule(); + + /** + * Allocates the memory for a sls_detector_module structure and initializes it + * Has detector type + * @param type detector type + * @returns myMod the pointer to the allocate dmemory location + */ + sls_detector_module* createModule(detectorType type); + + /** + * Frees the memory for a sls_detector_module structure + * @param myMod the pointer to the memory to be freed + */ + void deleteModule(sls_detector_module *myMod); + + /** + * Send a sls_detector_channel structure over socket + * @param myChan channel structure to send + * @returns number of bytes sent to the detector + */ + int sendChannel(sls_detector_channel* myChan); + + /** + * Send a sls_detector_chip structure over socket + * @param myChip chip structure to send + * @returns number of bytes sent to the detector + */ + int sendChip(sls_detector_chip* myChip); + + /** + * Send a sls_detector_module structure over socket + * @param myMod module structure to send + * @returns number of bytes sent to the detector + */ + int sendModule(sls_detector_module* myMod); + + /** + * Receive a sls_detector_channel structure over socket + * @param myChan channel structure to receive + * @returns number of bytes received from the detector + */ + int receiveChannel(sls_detector_channel* myChan); + + /** + * Receive a sls_detector_chip structure over socket + * @param myChip chip structure to receive + * @returns number of bytes received from the detector + */ + int receiveChip(sls_detector_chip* myChip); + + /** + * Receive a sls_detector_module structure over socket + * @param myMod module structure to receive + * @returns number of bytes received from the detector + */ + int receiveModule(sls_detector_module* myMod); + + /** + * Returns the additional json header \sa sharedSlsDetector + * @returns the additional json header, returns "none" if default setting and no custom ip set + */ + string getAdditionalJsonHeader(); + + /** + * Returns the receiver UDP socket buffer size\sa sharedSlsDetector + * @returns the receiver UDP socket buffer size + */ + string getReceiverUDPSocketBufferSize() ; + + /** + * Returns the receiver real UDP socket buffer size\sa sharedSlsDetector + * @returns the receiver real UDP socket buffer size + */ + string getReceiverRealUDPSocketBufferSize(); + + /** + * Sets the additional json header\sa sharedSlsDetector + * @param jsonheader additional json header + * @returns additional json header, returns "none" if default setting and no custom ip set + */ + string setAdditionalJsonHeader(string jsonheader); + + /** + * Sets the receiver UDP socket buffer size + * @param udpsockbufsize additional json header + * @returns receiver udp socket buffer size + */ + string setReceiverUDPSocketBufferSize(int udpsockbufsize=-1); + + /** + * Sets the transmission delay for left, right or entire frame + * (Eiger, Jungfrau(only entire frame)) + * @param index type of delay + * @param delay delay + * @returns transmission delay + */ + string setDetectorNetworkParameter(networkParameter index, int delay); + /** + * Get MAC from the receiver using udpip and + * set up UDP connection in detector + * @returns Ok or FAIL + */ + int setUDPConnection(); - int fillModuleMask(int *mM); + /** slsDetector Id or position in the detectors list */ + int detId; + /** Shared Memory object */ + SharedMemory* sharedMemory; - /** Starts acquisition, calibrates pedestal and writes to fpga - /returns number of frames - */ - int calibratePedestal(int frames = 0); + /** Shared memory structure */ + sharedSlsDetector *thisDetector; + /** multiSlsDetector referece */ + multiSlsDetector *multiDet; - /** Clears error mask and also the bit in parent det multi error mask - /returns error mask - */ - int64_t clearAllErrorMask(); + receiverInterface *thisReceiver; + /** socket for control commands */ + MySocketTCP *controlSocket; - /** returns the detector MAC address\sa sharedSlsDetector */ - string getDetectorMAC() {return string(thisDetector->detectorMAC);}; - /** returns the detector IP address\sa sharedSlsDetector */ - string getDetectorIP() {return string(thisDetector->detectorIP);}; - /** returns the receiver IP address \sa sharedSlsDetector */ - string getReceiver() {return string(thisDetector->receiver_hostname);}; - /** returns the receiver UDP IP address \sa sharedSlsDetector */ - string getReceiverUDPIP() {return string(thisDetector->receiverUDPIP);}; - /** returns the receiver UDP MAC address \sa sharedSlsDetector */ - string getReceiverUDPMAC() {return string(thisDetector->receiverUDPMAC);}; - /** returns the receiver UDP IP address \sa sharedSlsDetector */ - string getReceiverUDPPort() {ostringstream ss; ss << thisDetector->receiverUDPPort; string s = ss.str(); return s;}; - /** returns the receiver UDP2 for Eiger IP address \sa sharedSlsDetector */ - string getReceiverUDPPort2() {ostringstream ss; ss << thisDetector->receiverUDPPort2; string s = ss.str(); return s;}; - /** returns the client zmq port \sa sharedSlsDetector */ - string getClientStreamingPort() {ostringstream ss; ss << thisDetector->zmqport; string s = ss.str(); return s;}; - /** returns the receiver zmq port \sa sharedSlsDetector */ - string getReceiverStreamingPort() {ostringstream ss; ss << thisDetector->receiver_zmqport; string s = ss.str(); return s;}; - /** gets the zmq source ip in client, returns "none" if default setting and no custom ip set*/ - string getClientStreamingIP(){return string(thisDetector->zmqip);}; - /** gets the zmq source ip in receiver, returns "none" if default setting and no custom ip set*/ - string getReceiverStreamingIP(){return string(thisDetector->receiver_zmqip);}; + /** socket for emergency stop */ + MySocketTCP *stopSocket; - /** validates the format of detector MAC address and sets it \sa sharedSlsDetector */ - string setDetectorMAC(string detectorMAC); - /** validates the format of detector IP address and sets it \sa sharedSlsDetector */ - string setDetectorIP(string detectorIP); - /** validates and sets the receiver IP address/hostname \sa sharedSlsDetector */ - string setReceiver(string receiver); - /** validates the format of receiver udp ip and sets it \sa sharedSlsDetector */ - string setReceiverUDPIP(string udpip); - /** validates the format of receiver udp mac and sets it \sa sharedSlsDetector */ - string setReceiverUDPMAC(string udpmac); - /** sets the receiver udp port \sa sharedSlsDetector */ - int setReceiverUDPPort(int udpport); - /** sets the receiver udp port2 for Eiger \sa sharedSlsDetector */ - int setReceiverUDPPort2(int udpport); - /** sets the zmq port in client (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ - string setClientStreamingPort(string port); - /** sets the zmq port in receiver (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ - string setReceiverStreamingPort(string port); - /** sets the zmq source ip in client */ - string setClientStreamingIP(string sourceIP); - /** sets the zmq source ip in receiver. if empty, uses rx_hostname*/ - string setReceiverStreamingIP(string sourceIP); + /** socket for data acquisition */ + MySocketTCP *dataSocket; - /** sets the transmission delay for left or right port or for an entire frame*/ - string setDetectorNetworkParameter(networkParameter index, int delay); + /** pointer to flat field coefficients in shared memory */ + double *ffcoefficients; - /** 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); + /** pointer to flat field coefficient errors in shared memory */ + double *fferrors; - /** 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); + /** pointer to detector module structures in shared memory */ + sls_detector_module *detectorModules; - /** - * Enable data streaming to client - * @param enable 0 to disable, 1 to enable, -1 to get the value - * @returns data streaming to client enable - */ - int enableDataStreamingToClient(int enable=-1) { - cprintf(RED,"ERROR: Must be called from the multi Detector level\n"); - return 0; - } + /** pointer to dac valuse in shared memory */ + dacs_t *dacs; - /** 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); + /** pointer to adc valuse in shared memory */ + dacs_t *adcs; - /** 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); + /** pointer to chip registers in shared memory */ + int *chipregs; - /** - * Send the multi detector size to the detector - */ - void sendMultiDetectorSize(); - - /** send the detector pos id to the receiver - * for various file naming conventions for multi detectors in receiver - */ - void setDetectorId(); - - /** send the detector host name to the receiver - * for various handshaking required with the detector - */ - void setDetectorHostname(); - - /** enable/disable or 10Gbe - * @param i is -1 to get, 0 to disable and 1 to enable - /returns if 10Gbe is enabled - */ - int enableTenGigabitEthernet(int i = -1); - - /** 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); - - /** 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); - - /******** CTB funcs */ - - /** opens pattern file and sends pattern to CTB - @param fname pattern file to open - @returns OK/FAIL - */ - int setCTBPattern(string fname); - - - /** Writes a pattern word to the CTB - @param addr address of the word, -1 is I/O control register, -2 is clk control register - @param word 64bit word to be written, -1 gets - @returns actual value - */ - uint64_t setCTBWord(int addr,uint64_t word=-1); - - /** Sets the pattern or loop limits in the CTB - @param level -1 complete pattern, 0,1,2, loop level - @param start start address if >=0 - @param stop stop address if >=0 - @param n number of loops (if level >=0) - @returns OK/FAIL - */ - int setCTBPatLoops(int level,int &start, int &stop, int &n); - - - /** Sets the wait address in the CTB - @param level 0,1,2, wait level - @param addr wait address, -1 gets - @returns actual value - */ - int setCTBPatWaitAddr(int level, int addr=-1); - - /** Sets the wait time in the CTB - @param level 0,1,2, wait level - @param t wait time, -1 gets - @returns actual value - */ - int setCTBPatWaitTime(int level, uint64_t t=-1); - - /** - Pulse Pixel - \param n is number of times to pulse - \param x is x coordinate - \param y is y coordinate - \returns OK or FAIL - */ - int pulsePixel(int n=0,int x=0,int y=0); - - /** - Pulse Pixel and move by a relative value - \param n is number of times to pulse - \param x is relative x value - \param y is relative y value - \returns OK or FAIL - */ - int pulsePixelNMove(int n=0,int x=0,int y=0); - - /** - Pulse Chip - \param n is number of times to pulse - \returns OK or FAIL - */ - int pulseChip(int n=0); - - /** - Set acquiring flag in shared memory - \param b acquiring flag - */ - void setAcquiringFlag(bool b=false); - - /** - Get acquiring flag from shared memory - \returns acquiring flag - */ - bool getAcquiringFlag(); - - /** - * Check if acquiring flag is set, set error if set - * \returns FAIL if not ready, OK if ready - */ - bool isAcquireReady(); - - /** - If data streaming in receiver is enabled, - restream the stop dummy packet from receiver - Used usually for Moench, - in case it is lost in network due to high data rate - \returns OK if success else FAIL - */ - int restreamStopFromReceiver(); - - - protected: - - - /** - address of the detector structure in shared memory - */ - sharedSlsDetector *thisDetector; - - - /** - detector ID - */ - int detId; - - /** - position ID - */ - int posId; - - - /** - * parent multi detector - * */ - - multiSlsDetector *parentDet; - - /** - shared memeory ID - */ - int shmId; - - /** - socket for control commands - */ - MySocketTCP *controlSocket; - - /** - socket for emergency stop - */ - MySocketTCP *stopSocket; - - /** - socket for data acquisition - */ - MySocketTCP *dataSocket; - - - /** pointer to flat field coefficients */ - double *ffcoefficients; - /** pointer to flat field coefficient errors */ - double *fferrors; - - - /** pointer to detector module structures */ - sls_detector_module *detectorModules; - /** pointer to dac valuse */ - dacs_t *dacs; - /** pointer to adc valuse */ - dacs_t *adcs; - /** pointer to chip registers */ - int *chipregs; - /** pointer to channal registers */ - int *chanregs; - /** pointer to gain values */ - int *gain; - /** pointer to offset values */ - int *offset; - - receiverInterface *thisReceiver; - - - /** Initializes the shared memory - \param type is needed to define the size of the shared memory - \param id is the detector id needed to define the shared memory id - \return shm_id shared memory id - */ - int initSharedMemory(detectorType type=GENERIC, int id=0); - - /** - Initializes the thisDetector structure - \param type is needed to define the number of channels, chips, modules etc. - \sa sharedSlsDetector - */ - int initializeDetectorSize(detectorType type); - /** - Initializes the module structures in thisDetector if the detector did not exists before - */ - int initializeDetectorStructure(); - /** - send a sls_detector_channel structure over socket - */ - int sendChannel(sls_detector_channel*); - /** - send a sls_detector_chip structure over socket - */ - int sendChip(sls_detector_chip*); - /** - send a sls_detector_module structure over socket - */ - int sendModule(sls_detector_module*); - /** - receive a sls_detector_channel structure over socket - */ - int receiveChannel(sls_detector_channel*); - /** - receive a sls_detector_chip structure over socket - */ - int receiveChip(sls_detector_chip*); - /** - receive a sls_detector_module structure over socket - */ - int receiveModule(sls_detector_module*); - - /** Gets MAC from receiver and sets up UDP Connection */ - int setUDPConnection(); + /** pointer to channal registers in shared memory */ + int *chanregs; + /** pointer to gain values in shared memory */ + int *gain; + /** pointer to offset values in shared memory */ + int *offset; }; #endif diff --git a/slsDetectorSoftware/slsDetector/slsDetectorActions.h b/slsDetectorSoftware/slsDetector/slsDetectorActions.h index b0b7dfe56..c2cff331c 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorActions.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorActions.h @@ -8,7 +8,7 @@ #include -using namespace std; +// /** @@ -38,7 +38,7 @@ class slsDetectorActions : public virtual slsDetectorBase \param par for script \returns 0 if action disabled, >0 otherwise */ - int setAction(int iaction, string fname="", string par=""); + int setAction(int iaction,std::string fname="",std::string par=""); /** set action script @@ -46,7 +46,7 @@ class slsDetectorActions : public virtual slsDetectorBase \param fname for script ("" disable) \returns 0 if action disabled, >0 otherwise */ - int setActionScript(int iaction, string fname=""); + int setActionScript(int iaction, std::string fname=""); /** @@ -55,7 +55,7 @@ class slsDetectorActions : public virtual slsDetectorBase \param par for script \returns 0 if action disabled, >0 otherwise */ - int setActionParameter(int iaction, string par=""); + int setActionParameter(int iaction, std::string par=""); /** @@ -63,14 +63,14 @@ class slsDetectorActions : public virtual slsDetectorBase \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} \returns action script */ - string getActionScript(int iaction); + std::string getActionScript(int iaction); /** returns action parameter \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} \returns action parameter */ - string getActionParameter(int iaction); + std::string getActionParameter(int iaction); /** returns action mode @@ -89,20 +89,20 @@ class slsDetectorActions : public virtual slsDetectorBase \param precision to write the scan varaible in the scan name (-1 unchanged) \returns 0 is scan disabled, >0 otherwise */ - int setScan(int index, string script="", int nvalues=-1, double *values=NULL, string par="", int precision=-1); + int setScan(int index, std::string script="", int nvalues=-1, double *values=NULL, std::string par="", int precision=-1); /** set scan script \param index of the scan (0,1) \param script fname for script ("" disables, "none" disables and overwrites current, "threshold" threshold scan, "trimbits", trimbits scan) \returns 0 is scan disabled, >0 otherwise */ - int setScanScript(int index, string script=""); + int setScanScript(int index, std::string script=""); /** set scan script parameter \param index of the scan (0,1) \param script parameter for scan \returns 0 is scan disabled, >0 otherwise */ - int setScanParameter(int index, string par=""); + int setScanParameter(int index, std::string par=""); /** set scan script parameter \param index of the scan (0,1) \param precision scan varaible precision to be printed in file name @@ -130,14 +130,14 @@ class slsDetectorActions : public virtual slsDetectorBase \param iscan can be (0,1) \returns scan script */ - string getScanScript(int iscan); + std::string getScanScript(int iscan); /** returns scan parameter \param iscan can be (0,1) \returns scan parameter */ - string getScanParameter(int iscan); + std::string getScanParameter(int iscan); /** returns scan mode @@ -273,7 +273,7 @@ class slsDetectorActions : public virtual slsDetectorBase int startIndex; int lastIndex; int nowIndex; - string fName; + std::string fName; diff --git a/slsDetectorSoftware/slsDetector/slsDetectorBase.h b/slsDetectorSoftware/slsDetector/slsDetectorBase.h index 11dd4ac0b..f54f25b4c 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorBase.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorBase.h @@ -54,8 +54,6 @@ #include - -using namespace std; /** @libdoc The slsDetectorBase contains also a set of purely virtual functions useful for the implementation of the derived classes @@ -83,7 +81,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef */ virtual detectorType getDetectorsType(int pos=-1)=0; - string getDetectorDeveloper(){return string("PSI");}; + std::string getDetectorDeveloper(){return std::string("PSI");}; // protected: /** @@ -91,14 +89,14 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param fname file with angular conversion constants ("" disable) \returns 0 if angular conversion disabled, >0 otherwise */ - virtual int setAngularConversionFile(string fname="")=0; + virtual int setAngularConversionFile(std::string fname="")=0; /** pure virtual function returns the angular conversion file */ - virtual string getAngularConversionFile()=0; + virtual std::string getAngularConversionFile()=0; @@ -108,7 +106,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param fname for script ("" disable) \returns 0 if action disabled, >0 otherwise */ - virtual int setActionScript(int iaction, string fname="")=0; + virtual int setActionScript(int iaction, std::string fname="")=0; /** set action @@ -116,21 +114,21 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param par for script ("" disable) \returns 0 if action disabled, >0 otherwise */ - virtual int setActionParameter(int iaction, string par="")=0; + virtual int setActionParameter(int iaction, std::string par="")=0; /** returns action script \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} \returns action script */ - virtual string getActionScript(int iaction)=0; + virtual std::string getActionScript(int iaction)=0; /** returns action parameter \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} \returns action parameter */ - virtual string getActionParameter(int iaction)=0; + virtual std::string getActionParameter(int iaction)=0; /** set scan script @@ -138,7 +136,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param script fname for script ("" disable, "none" disables and overwrites current, "threshold" makes threshold scan, "trimbits" make trimbits scan, "energy" makes energy scan) \returns 0 if scan disabled, >0 otherwise */ - virtual int setScanScript(int index, string script="")=0; + virtual int setScanScript(int index, std::string script="")=0; /** set scan script parameter @@ -146,7 +144,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param spar parameter to be passed to the scan script with syntax par=spar \returns 0 if scan disabled, >0 otherwise */ - virtual int setScanParameter(int index, string spar="")=0; + virtual int setScanParameter(int index, std::string spar="")=0; /** set scan precision @@ -169,14 +167,14 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param index is the scan index (0 or 1) \returns "none" if disables, "threshold" threshold scan, "trimbits" trimbits scan, "energy" energy scan or scan script name */ - virtual string getScanScript(int index)=0; + virtual std::string getScanScript(int index)=0; /** get scan script \param index is the scan index (0 or 1) \returns scan script parameter */ - virtual string getScanParameter(int index)=0; + virtual std::string getScanParameter(int index)=0; /** get scan precision @@ -199,7 +197,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param fname file name \returns OK or FAIL */ - virtual int writeConfigurationFile(string const fname)=0; + virtual int writeConfigurationFile(std::string const fname)=0; /** @@ -208,7 +206,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param fname file name to load data from \returns OK or FAIL */ - virtual int loadImageToDetector(imageType index,string const fname)=0; + virtual int loadImageToDetector(imageType index,std::string const fname)=0; /** \returns number of positions @@ -241,7 +239,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef virtual int getTotalNumberOfChannels(dimension d)=0; /** generates file name without extension */ - virtual string createFileName()=0; + virtual std::string createFileName()=0; virtual void incrementProgress()=0; @@ -254,12 +252,12 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef virtual double* decodeData(int *datain, int &nn, double *fdata=NULL)=0; - virtual string getCurrentFileName()=0; + virtual std::string getCurrentFileName()=0; - virtual int getFileIndexFromFileName(string fname)=0; + virtual int getFileIndexFromFileName(std::string fname)=0; - virtual int getIndicesFromFileName(string fname,int &index)=0; + virtual int getIndicesFromFileName(std::string fname,int &index)=0; virtual double *convertAngles()=0; /** @@ -282,9 +280,9 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef */ virtual int getRateCorrection()=0; - virtual int setFlatFieldCorrection(string fname="")=0; + virtual int setFlatFieldCorrection(std::string fname="")=0; - int setFlatFieldCorrectionFile(string fname=""){return setFlatFieldCorrection(fname);}; + int setFlatFieldCorrectionFile(std::string fname=""){return setFlatFieldCorrection(fname);}; /** set/get dynamic range @@ -369,16 +367,18 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef set/get timer value \param index timer index \param t time in ns or number of...(e.g. frames, gates, probes) + \param imod module number \returns timer set value in ns or number of...(e.g. frames, gates, probes) */ - virtual int64_t setTimer(timerIndex index, int64_t t=-1)=0; - int64_t setExposureTime(int64_t t=-1){return setTimer(ACQUISITION_TIME,t);}; - int64_t setSubFrameExposureTime(int64_t t=-1){return setTimer(SUBFRAME_ACQUISITION_TIME,t);}; - int64_t setExposurePeriod(int64_t t=-1){return setTimer(FRAME_PERIOD,t);}; - int64_t setDelayAfterTrigger(int64_t t=-1){return setTimer(DELAY_AFTER_TRIGGER,t);}; - int64_t setNumberOfGates(int64_t t=-1){return setTimer(GATES_NUMBER,t);}; - int64_t setNumberOfFrames(int64_t t=-1){return setTimer(FRAME_NUMBER,t);}; - int64_t setNumberOfCycles(int64_t t=-1){return setTimer(CYCLES_NUMBER,t);}; + virtual int64_t setTimer(timerIndex index, int64_t t=-1, int imod = -1)=0; + int64_t setExposureTime(int64_t t=-1, int imod = -1){return setTimer(ACQUISITION_TIME,t,imod);}; + int64_t setSubFrameExposureTime(int64_t t=-1, int imod = -1){return setTimer(SUBFRAME_ACQUISITION_TIME,t,imod);}; + int64_t setSubFramePeriod(int64_t t=-1, int imod = -1){return setTimer(SUBFRAME_PERIOD,t,imod);}; + int64_t setExposurePeriod(int64_t t=-1, int imod = -1){return setTimer(FRAME_PERIOD,t,imod);}; + int64_t setDelayAfterTrigger(int64_t t=-1, int imod = -1){return setTimer(DELAY_AFTER_TRIGGER,t,imod);}; + int64_t setNumberOfGates(int64_t t=-1, int imod = -1){return setTimer(GATES_NUMBER,t,imod);}; + int64_t setNumberOfFrames(int64_t t=-1, int imod = -1){return setTimer(FRAME_NUMBER,t,imod);}; + int64_t setNumberOfCycles(int64_t t=-1, int imod = -1){return setTimer(CYCLES_NUMBER,t,imod);}; /** sets/gets the value of important readout speed parameters @@ -406,6 +406,15 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef } \ }; + void setOverflowMode(int value){ \ + if(value>=0){ \ + switch(value){ \ + case 1: setReadOutFlags(SHOW_OVERFLOW);break; \ + case 0: setReadOutFlags(NOOVERFLOW);break; \ + } \ + } \ + }; + /** get readout mode of detector (eiger specific) \returns 0 for nonparallel, 1 for parallel, 2 for safe @@ -416,6 +425,18 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef if (ret&PARALLEL) return 1; \ if (ret&SAFE) return 2; \ return -1; \ + } + + + /** + get readout overflow mode of detector (eiger specific) + \returns 1 for show overflow, 0 for do not show overflow + */ + int getOverflowMode(){ \ + int ret = setReadOutFlags(); \ + if (ret&SHOW_OVERFLOW) return 1; \ + if (ret&NOOVERFLOW) return 0; \ + return -1; \ } \ /** @@ -496,6 +517,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef virtual int setThresholdEnergy(int e_eV, int imod, detectorSettings isettings=GET_SETTINGS, int tb=1)=0; int setThresholdEnergy(int e_eV){return setThresholdEnergy(e_eV,-1);}; + int setThresholdEnergy(int e_ev, int tb, int isettings, int id){return setThresholdEnergy(e_ev, id, (detectorSettings)isettings, tb);} /** @@ -509,12 +531,12 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef \param fname file name \returns OK or FAIL */ - virtual int readConfigurationFile(string const fname)=0; + virtual int readConfigurationFile(std::string const fname)=0; - virtual int dumpDetectorSetup(string const fname, int level)=0; - int dumpDetectorSetup(string const fname){return dumpDetectorSetup(fname,0);}; - virtual int retrieveDetectorSetup(string const fname, int level)=0; - int retrieveDetectorSetup(string const fname){return retrieveDetectorSetup(fname,0);}; + virtual int dumpDetectorSetup(std::string const fname, int level)=0; + int dumpDetectorSetup(std::string const fname){return dumpDetectorSetup(fname,0);}; + virtual int retrieveDetectorSetup(std::string const fname, int level)=0; + int retrieveDetectorSetup(std::string const fname){return retrieveDetectorSetup(fname,0);}; /** @short \returns the default output file index @@ -576,6 +598,7 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef */ virtual void readFrameFromReceiver()=0; + /** * Enable data streaming to client * @param enable 0 to disable, 1 to enable, -1 to get the value @@ -604,29 +627,29 @@ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; virtual runStatus startReceiverReadout()=0; - /** returns detector type string from detector type index - \param t string can be Mythen, Pilatus, Eiger, Gotthard, Agipd, Unknown + /** returns detector type std::string from detector type index + \param t std::string can be Mythen, Pilatus, Eiger, Gotthard, Agipd, Unknown \returns MYTHEN, PILATUS, EIGER, GOTTHARD, AGIPD, MÖNCH, GENERIC */ - static string getDetectorType(detectorType t){\ + static std::string getDetectorType(detectorType t){\ switch (t) {\ - case MYTHEN: return string("Mythen"); \ - case PILATUS: return string("Pilatus"); \ - case EIGER: return string("Eiger"); \ - case GOTTHARD: return string("Gotthard"); \ - case AGIPD: return string("Agipd"); \ - case MOENCH: return string("Moench"); \ - case JUNGFRAU: return string("Jungfrau"); \ - case JUNGFRAUCTB: return string("JungfrauCTB"); \ - case PROPIX: return string("Propix"); \ - default: return string("Unknown"); \ + case MYTHEN: return std::string("Mythen"); \ + case PILATUS: return std::string("Pilatus"); \ + case EIGER: return std::string("Eiger"); \ + case GOTTHARD: return std::string("Gotthard"); \ + case AGIPD: return std::string("Agipd"); \ + case MOENCH: return std::string("Moench"); \ + case JUNGFRAU: return std::string("Jungfrau"); \ + case JUNGFRAUCTB: return std::string("JungfrauCTB"); \ + case PROPIX: return std::string("Propix"); \ + default: return std::string("Unknown"); \ }}; - /** returns detector type index from detector type string + /** returns detector type index from detector type std::string \param type can be MYTHEN, PILATUS, EIGER, GOTTHARD, AGIPD, GENERIC \returns Mythen, Pilatus, Eiger, Gotthard, Agipd, Mönch, Unknown */ - static detectorType getDetectorType(string const type){\ + static detectorType getDetectorType(std::string const type){\ if (type=="Mythen") return MYTHEN;\ if (type=="Pilatus") return PILATUS; \ if (type=="Eiger") return EIGER; \ @@ -640,11 +663,11 @@ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; - /** returns synchronization type index from string + /** returns synchronization type index from std::string \param type can be none, gating, trigger, complementary \returns ONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS */ - static synchronizationMode getSyncType(string const type){\ + static synchronizationMode getSyncType(std::string const type){\ if (type=="none") return NO_SYNCHRONIZATION;\ if (type=="gating") return MASTER_GATES;\ if (type=="trigger") return MASTER_TRIGGERS; \ @@ -652,55 +675,55 @@ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; return GET_SYNCHRONIZATION_MODE; \ }; - /** returns synchronization type string from index + /** returns synchronization type std::string from index \param s can be NONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS \returns none, gating, trigger, complementary, unknown */ - static string getSyncType(synchronizationMode s ){\ + static std::string getSyncType(synchronizationMode s ){\ switch(s) { \ - case NO_SYNCHRONIZATION: return string("none"); \ - case MASTER_GATES: return string("gating"); \ - case MASTER_TRIGGERS: return string("trigger"); \ - case SLAVE_STARTS_WHEN_MASTER_STOPS: return string("complementary"); \ - default: return string("unknown"); \ + case NO_SYNCHRONIZATION: return std::string("none"); \ + case MASTER_GATES: return std::string("gating"); \ + case MASTER_TRIGGERS: return std::string("trigger"); \ + case SLAVE_STARTS_WHEN_MASTER_STOPS: return std::string("complementary"); \ + default: return std::string("unknown"); \ }}; - /** returns string from external signal type index + /** returns std::string from external signal type index \param f can be SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW, TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE, RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, =TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE, RO_TRIGGER_OUT_FALLING_EDGE, OUTPUT_LOW, OUTPUT_HIGH, MASTER_SLAVE_SYNCHRONIZATION, GET_EXTERNAL_SIGNAL_FLAG - \returns string off, gate_in_active_high, gate_in_active_low, trigger_in_rising_edge, trigger_in_falling_edge, ro_trigger_in_rising_edge, ro_trigger_in_falling_edge, gate_out_active_high, gate_out_active_low, trigger_out_rising_edge, trigger_out_falling_edge, ro_trigger_out_rising_edge, ro_trigger_out_falling_edge, gnd, vcc, sync, unknown + \returns std::string off, gate_in_active_high, gate_in_active_low, trigger_in_rising_edge, trigger_in_falling_edge, ro_trigger_in_rising_edge, ro_trigger_in_falling_edge, gate_out_active_high, gate_out_active_low, trigger_out_rising_edge, trigger_out_falling_edge, ro_trigger_out_rising_edge, ro_trigger_out_falling_edge, gnd, vcc, sync, unknown */ - static string externalSignalType(externalSignalFlag f){\ + static std::string externalSignalType(externalSignalFlag f){\ switch(f) { \ - case SIGNAL_OFF: return string( "off"); \ - case GATE_IN_ACTIVE_HIGH: return string( "gate_in_active_high"); \ - case GATE_IN_ACTIVE_LOW: return string( "gate_in_active_low"); \ - case TRIGGER_IN_RISING_EDGE: return string( "trigger_in_rising_edge"); \ - case TRIGGER_IN_FALLING_EDGE: return string( "trigger_in_falling_edge"); \ - case RO_TRIGGER_IN_RISING_EDGE: return string( "ro_trigger_in_rising_edge"); \ - case RO_TRIGGER_IN_FALLING_EDGE: return string( "ro_trigger_in_falling_edge"); \ - case GATE_OUT_ACTIVE_HIGH: return string( "gate_out_active_high"); \ - case GATE_OUT_ACTIVE_LOW: return string( "gate_out_active_low"); \ - case TRIGGER_OUT_RISING_EDGE: return string( "trigger_out_rising_edge"); \ - case TRIGGER_OUT_FALLING_EDGE: return string( "trigger_out_falling_edge"); \ - case RO_TRIGGER_OUT_RISING_EDGE: return string( "ro_trigger_out_rising_edge"); \ - case RO_TRIGGER_OUT_FALLING_EDGE: return string( "ro_trigger_out_falling_edge"); \ - case MASTER_SLAVE_SYNCHRONIZATION: return string("sync"); \ - case OUTPUT_LOW: return string("gnd"); \ - case OUTPUT_HIGH: return string("vcc"); \ - default: return string( "unknown"); \ + case SIGNAL_OFF: return std::string( "off"); \ + case GATE_IN_ACTIVE_HIGH: return std::string( "gate_in_active_high"); \ + case GATE_IN_ACTIVE_LOW: return std::string( "gate_in_active_low"); \ + case TRIGGER_IN_RISING_EDGE: return std::string( "trigger_in_rising_edge"); \ + case TRIGGER_IN_FALLING_EDGE: return std::string( "trigger_in_falling_edge"); \ + case RO_TRIGGER_IN_RISING_EDGE: return std::string( "ro_trigger_in_rising_edge"); \ + case RO_TRIGGER_IN_FALLING_EDGE: return std::string( "ro_trigger_in_falling_edge"); \ + case GATE_OUT_ACTIVE_HIGH: return std::string( "gate_out_active_high"); \ + case GATE_OUT_ACTIVE_LOW: return std::string( "gate_out_active_low"); \ + case TRIGGER_OUT_RISING_EDGE: return std::string( "trigger_out_rising_edge"); \ + case TRIGGER_OUT_FALLING_EDGE: return std::string( "trigger_out_falling_edge"); \ + case RO_TRIGGER_OUT_RISING_EDGE: return std::string( "ro_trigger_out_rising_edge"); \ + case RO_TRIGGER_OUT_FALLING_EDGE: return std::string( "ro_trigger_out_falling_edge"); \ + case MASTER_SLAVE_SYNCHRONIZATION: return std::string("sync"); \ + case OUTPUT_LOW: return std::string("gnd"); \ + case OUTPUT_HIGH: return std::string("vcc"); \ + default: return std::string( "unknown"); \ } }; - /** returns external signal type index from string + /** returns external signal type index from std::string \param sval off, gate_in_active_high, gate_in_active_low, trigger_in_rising_edge, trigger_in_falling_edge, ro_trigger_in_rising_edge, ro_trigger_in_falling_edge, gate_out_active_high, gate_out_active_low, trigger_out_rising_edge, trigger_out_falling_edge, ro_trigger_out_rising_edge, ro_trigger_out_falling_edge, gnd, vcc, sync, unknown \returns can be SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW, TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE, RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE, RO_TRIGGER_OUT_FALLING_EDGE, OUTPUT_LOW, OUTPUT_HIGH, MASTER_SLAVE_SYNCHRONIZATION, GET_EXTERNAL_SIGNAL_FLAG (if unknown) */ - static externalSignalFlag externalSignalType(string sval){\ + static externalSignalFlag externalSignalType(std::string sval){\ if (sval=="off") return SIGNAL_OFF;\ if (sval=="gate_in_active_high") return GATE_IN_ACTIVE_HIGH; \ if (sval=="gate_in_active_low") return GATE_IN_ACTIVE_LOW;\ @@ -719,39 +742,39 @@ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; if (sval=="vcc") return OUTPUT_HIGH;\ return GET_EXTERNAL_SIGNAL_FLAG ;}; - /** returns detector settings string from index + /** returns detector settings std::string from index \param s can be STANDARD, FAST, HIGHGAIN, DYNAMICGAIN, LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN, LOWNOISE, DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2, GET_SETTINGS \returns standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain, lownoise, dynamichg0, fixgain1, fixgain2, forceswitchg1, forceswitchg2, verylowgain, undefined */ - static string getDetectorSettings(detectorSettings s){\ + static std::string getDetectorSettings(detectorSettings s){\ switch(s) { \ - case STANDARD: return string("standard"); \ - case FAST: return string("fast"); \ - case HIGHGAIN: return string("highgain"); \ - case DYNAMICGAIN: return string("dynamicgain"); \ - case LOWGAIN: return string("lowgain"); \ - case MEDIUMGAIN: return string("mediumgain"); \ - case VERYHIGHGAIN: return string("veryhighgain"); \ - case LOWNOISE: return string("lownoise"); \ - case DYNAMICHG0: return string("dynamichg0"); \ - case FIXGAIN1: return string("fixgain1"); \ - case FIXGAIN2: return string("fixgain2"); \ - case FORCESWITCHG1: return string("forceswitchg1");\ - case FORCESWITCHG2: return string("forceswitchg2");\ - case VERYLOWGAIN: return string("verylowgain");\ - default: return string("undefined"); \ + case STANDARD: return std::string("standard"); \ + case FAST: return std::string("fast"); \ + case HIGHGAIN: return std::string("highgain"); \ + case DYNAMICGAIN: return std::string("dynamicgain"); \ + case LOWGAIN: return std::string("lowgain"); \ + case MEDIUMGAIN: return std::string("mediumgain"); \ + case VERYHIGHGAIN: return std::string("veryhighgain"); \ + case LOWNOISE: return std::string("lownoise"); \ + case DYNAMICHG0: return std::string("dynamichg0"); \ + case FIXGAIN1: return std::string("fixgain1"); \ + case FIXGAIN2: return std::string("fixgain2"); \ + case FORCESWITCHG1: return std::string("forceswitchg1");\ + case FORCESWITCHG2: return std::string("forceswitchg2");\ + case VERYLOWGAIN: return std::string("verylowgain");\ + default: return std::string("undefined"); \ }}; - /** returns detector settings string from index + /** returns detector settings std::string from index \param s can be standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain, lownoise, dynamichg0, fixgain1, fixgain2, forceswitchg1, forceswitchg2, undefined \returns setting index STANDARD, FAST, HIGHGAIN, DYNAMICGAIN, LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN,LOWNOISE, DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2, VERYLOWGAIN, GET_SETTINGS */ - static detectorSettings getDetectorSettings(string s){ \ + static detectorSettings getDetectorSettings(std::string s){ \ if (s=="standard") return STANDARD; \ if (s=="fast") return FAST; \ if (s=="highgain") return HIGHGAIN; \ @@ -771,31 +794,31 @@ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; /** - returns external communication mode string from index + returns external communication mode std::string from index \param f can be AUTO_TIMING, TRIGGER_EXPOSURE, TRIGGER_READOUT, GATE_FIX_NUMBER, GATE_WITH_START_TRIGGER, BURST_TRIGGER, GET_EXTERNAL_COMMUNICATION_MODE \returns auto, trigger, ro_trigger, gating, triggered_gating, unknown */ - static string externalCommunicationType(externalCommunicationMode f){ \ + static std::string externalCommunicationType(externalCommunicationMode f){ \ switch(f) { \ - case AUTO_TIMING: return string( "auto"); \ - case TRIGGER_EXPOSURE: return string("trigger"); \ - case TRIGGER_READOUT: return string("ro_trigger"); \ - case GATE_FIX_NUMBER: return string("gating"); \ - case GATE_WITH_START_TRIGGER: return string("triggered_gating"); \ - case BURST_TRIGGER: return string("burst_trigger"); \ - default: return string( "unknown"); \ + case AUTO_TIMING: return std::string( "auto"); \ + case TRIGGER_EXPOSURE: return std::string("trigger"); \ + case TRIGGER_READOUT: return std::string("ro_trigger"); \ + case GATE_FIX_NUMBER: return std::string("gating"); \ + case GATE_WITH_START_TRIGGER: return std::string("triggered_gating"); \ + case BURST_TRIGGER: return std::string("burst_trigger"); \ + default: return std::string( "unknown"); \ } }; /** - returns external communication mode index from string + returns external communication mode index from std::string \param sval can be auto, trigger, ro_trigger, gating, triggered_gating \returns AUTO_TIMING, TRIGGER_EXPOSURE, TRIGGER_READOUT, GATE_FIX_NUMBER, GATE_WITH_START_TRIGGER, BURST_TRIGGER, GET_EXTERNAL_COMMUNICATION_MODE */ - static externalCommunicationMode externalCommunicationType(string sval){\ + static externalCommunicationMode externalCommunicationType(std::string sval){\ if (sval=="auto") return AUTO_TIMING;\ if (sval=="trigger") return TRIGGER_EXPOSURE; \ if (sval=="ro_trigger") return TRIGGER_READOUT;\ @@ -805,64 +828,66 @@ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; return GET_EXTERNAL_COMMUNICATION_MODE; \ }; - /** returns string from run status index + /** returns std::string from run status index \param s can be ERROR, WAITING, RUNNING, TRANSMITTING, RUN_FINISHED - \returns string error, waiting, running, data, finished + \returns std::string error, waiting, running, data, finished */ - static string runStatusType(runStatus s){\ + static std::string runStatusType(runStatus s){\ switch (s) { \ - case ERROR: return string("error"); \ - case WAITING: return string("waiting"); \ - case RUNNING: return string("running");\ - case TRANSMITTING: return string("data"); \ - case RUN_FINISHED: return string("finished"); \ - default: return string("idle"); \ + case ERROR: return std::string("error"); \ + case WAITING: return std::string("waiting"); \ + case RUNNING: return std::string("running");\ + case TRANSMITTING: return std::string("data"); \ + case RUN_FINISHED: return std::string("finished"); \ + default: return std::string("idle"); \ }}; - /** returns string from file format index + /** returns std::string from file format index \param s can be RAW, HDF5 - \returns string raw, hdf5 + \returns std::string raw, hdf5 */ - static string fileFormats(fileFormat f){\ + static std::string fileFormats(fileFormat f){\ switch (f) { \ - case BINARY: return string("binary"); \ - case ASCII: return string("ascii"); \ - case HDF5: return string("hdf5"); \ - default: return string("unknown"); \ + case BINARY: return std::string("binary"); \ + case ASCII: return std::string("ascii"); \ + case HDF5: return std::string("hdf5"); \ + default: return std::string("unknown"); \ }}; - /** returns string from timer index - \param s can be FRAME_NUMBER,ACQUISITION_TIME,FRAME_PERIOD, DELAY_AFTER_TRIGGER,GATES_NUMBER,PROBES_NUMBER, CYCLES_NUMBER, ACTUAL_TIME,MEASUREMENT_TIME, PROGRESS,MEASUREMENTS_NUMBER,FRAMES_FROM_START,FRAMES_FROM_START_PG,SAMPLES_JCTB,SUBFRAME_ACQUISITION_TIME - \returns string frame_number,acquisition_time,frame_period, delay_after_trigger,gates_number,probes_number, cycles_number, actual_time,measurement_time, progress,measurements_number,frames_from_start,frames_from_start_pg,samples_jctb,subframe_acquisition_time + /** returns std::string from timer index + \param s can be FRAME_NUMBER,ACQUISITION_TIME,FRAME_PERIOD, DELAY_AFTER_TRIGGER,GATES_NUMBER,PROBES_NUMBER, CYCLES_NUMBER, ACTUAL_TIME,MEASUREMENT_TIME, PROGRESS,MEASUREMENTS_NUMBER,FRAMES_FROM_START,FRAMES_FROM_START_PG,SAMPLES_JCTB,SUBFRAME_ACQUISITION_TIME,STORAGE_CELL_NUMBER, SUBFRAME_PERIOD + \returns std::string frame_number,acquisition_time,frame_period, delay_after_trigger,gates_number,probes_number, cycles_number, actual_time,measurement_time, progress,measurements_number,frames_from_start,frames_from_start_pg,samples_jctb,subframe_acquisition_time,storage_cell_number, subframe_period */ - static string getTimerType(timerIndex t){ \ + static std::string getTimerType(timerIndex t){ \ switch (t) { \ - case FRAME_NUMBER: return string("frame_number"); \ - case ACQUISITION_TIME: return string("acquisition_time"); \ - case FRAME_PERIOD: return string("frame_period"); \ - case DELAY_AFTER_TRIGGER: return string("delay_after_trigger"); \ - case GATES_NUMBER: return string("gates_number"); \ - case PROBES_NUMBER: return string("probes_number"); \ - case CYCLES_NUMBER: return string("cycles_number"); \ - case ACTUAL_TIME: return string("actual_time"); \ - case MEASUREMENT_TIME: return string("measurement_time"); \ - case PROGRESS: return string("progress"); \ - case MEASUREMENTS_NUMBER: return string("measurements_number"); \ - case FRAMES_FROM_START: return string("frames_from_start"); \ - case FRAMES_FROM_START_PG: return string("frames_from_start_pg"); \ - case SAMPLES_JCTB: return string("samples_jctb"); \ - case SUBFRAME_ACQUISITION_TIME: return string("subframe_acquisition_time"); \ - default: return string("unknown"); \ + case FRAME_NUMBER: return std::string("frame_number"); \ + case ACQUISITION_TIME: return std::string("acquisition_time"); \ + case FRAME_PERIOD: return std::string("frame_period"); \ + case DELAY_AFTER_TRIGGER: return std::string("delay_after_trigger"); \ + case GATES_NUMBER: return std::string("gates_number"); \ + case PROBES_NUMBER: return std::string("probes_number"); \ + case CYCLES_NUMBER: return std::string("cycles_number"); \ + case ACTUAL_TIME: return std::string("actual_time"); \ + case MEASUREMENT_TIME: return std::string("measurement_time"); \ + case PROGRESS: return std::string("progress"); \ + case MEASUREMENTS_NUMBER: return std::string("measurements_number"); \ + case FRAMES_FROM_START: return std::string("frames_from_start"); \ + case FRAMES_FROM_START_PG: return std::string("frames_from_start_pg"); \ + case SAMPLES_JCTB: return std::string("samples_jctb"); \ + case SUBFRAME_ACQUISITION_TIME: return std::string("subframe_acquisition_time"); \ + case SUBFRAME_PERIOD: return std::string("subframe_period"); \ + case STORAGE_CELL_NUMBER: return std::string("storage_cell_number"); \ + default: return std::string("unknown"); \ }}; /** - @short returns adc index from string + @short returns adc index from std::string \param s can be temp_fpga, temp_fpgaext, temp_10ge, temp_dcdc, temp_sodl, temp_sodr, temp_fpgafl, temp_fpgafr \returns TEMPERATURE_FPGA, TEMPERATURE_FPGAEXT, TEMPERATURE_10GE, TEMPERATURE_DCDC, TEMPERATURE_SODL, TEMPERATURE_SODR, TEMPERATURE_FPGA2, TEMPERATURE_FPGA3, -1 when unknown mode */ - static int getADCIndex(string s){ + static int getADCIndex(std::string s){ if (s=="temp_fpga") return TEMPERATURE_FPGA; if (s=="temp_fpgaext") return TEMPERATURE_FPGAEXT; if (s=="temp_10ge") return TEMPERATURE_10GE; @@ -876,11 +901,11 @@ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; /** - @short returns dac index from string + @short returns dac index from std::string \param s can be vcmp_ll, vcmp_lr, vcmp_rl, vcmp_rr, vthreshold, vrf, vrs, vtr, vcall, vcp \returns E_Vcmp_ll, E_Vcmp_lr, E_Vcmp_rl, E_Vcmp_rr, THRESHOLD, E_Vrf, E_Vrs, E_Vtr, E_cal, E_Vcp , -1 when unknown mode */ - static int getDACIndex(string s){ + static int getDACIndex(std::string s){ if (s=="vcmp_ll") return E_Vcmp_ll; if (s=="vcmp_lr") return E_Vcmp_lr; if (s=="vcmp_rl") return E_Vcmp_rl; diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp index 01b349d32..7d503d296 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -6,6 +6,8 @@ #include #include +using namespace std; + /*! \mainpage Introduction This program is intended to control the SLS detectors via command line interface. @@ -262,38 +264,31 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { ++i; /*! \page config - - \b add Adds a detector at the end of the multi-detector structure. \c put argument is the hostname or IP adress. Returns the chained list of detector hostnames. - */ - descrToFuncMap[i].m_pFuncName="add";//OK - descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdd; - ++i; - - /*! \page config - - remove i Removes controller \c i from the multi-detector structure. Can be used for partial readout of the detector. - */ - descrToFuncMap[i].m_pFuncName="remove";//OK - descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRemove; - ++i; - - /*! \page config - - type Sets/gets detector type. \c Returns \c (string). Normally not used. Using hostname is enough. - */ - descrToFuncMap[i].m_pFuncName="type"; //OK - descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname; - ++i; - - /*! \page config - - hostname \c put adds the hostname (ot IP adress) at the end of the multi-detector structure. If used for a single controlled (i:) replaces the current hostname. Returns the list of the hostnames of the multi-detector structure. \c Returns \c (string) + - hostname \c put frees shared memory and sets the hostname (or IP adress). Only allowed at multi detector level. \c Returns the list of the hostnames of the multi-detector structure. \c (string) */ descrToFuncMap[i].m_pFuncName="hostname"; //OK descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname; ++i; /*! \page config - - id[:i] Returns the id of the detector structure. i is the detector position in a multi detector system. If used a \c put, configures the id of the detector structure. i is the detector position in a multi detector system and l is the id of the detector to be added. + - \b add appends a hostname (or IP address) at the end of the multi-detector structure. Only allowed at multi detector level. Cannot get. \c Returns the current list of detector hostnames. \c (string) */ - descrToFuncMap[i].m_pFuncName="id"; //OK - descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdId; + descrToFuncMap[i].m_pFuncName="add";//OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname; + ++i; + + /*! \page config + - replace \c Sets the hostname (or IP adress) for a single detector. Only allowed at single detector level. Cannot get. \c Returns the hostnames for that detector \c (string) + */ + descrToFuncMap[i].m_pFuncName="replace"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname; + ++i; + + /*! \page config + - user \c Returns user details from shared memory. Only allowed at multi detector level. Cannot put. \c (string) + */ + descrToFuncMap[i].m_pFuncName="user"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdUser; ++i; /*! \page config @@ -414,7 +409,7 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { */ /*! \page config - - flags [flag] sets/gets the readout flags to mode. Options: none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, unknown. Used for MYTHEN and EIGER only. \c Returns \c (string). put takes one string and \c returns concatenation of all active flags separated by spaces. + - flags [flag] sets/gets the readout flags to mode. Options: none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, overflow, nooverflow, unknown. Used for MYTHEN and EIGER only. \c Returns \c (string). put takes one string and \c returns concatenation of all active flags separated by spaces. */ descrToFuncMap[i].m_pFuncName="flags"; descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; @@ -505,6 +500,22 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { Commands to check versions of each subsystem */ + /*! \page config + - checkdetversion Checks the version compatibility with detector software (if hostname is in shared memory). Only get! Only for Eiger, Jungfrau & Gotthard. \c Returns \c ("compatible", "incompatible") + */ + descrToFuncMap[i].m_pFuncName="checkdetversion"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + ++i; + + + /*! \page config + - checkrecversion Checks the version compatibility with receiver software (if rx_hostname is in shared memory). Only get! Only for Eiger, Jungfrau & Gotthard. \c Returns \c ("compatible", "incompatible") + */ + descrToFuncMap[i].m_pFuncName="checkrecversion"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + ++i; + + /*! \page config - moduleversion:[i] Gets the firmware version of module i. Used for MYTHEN only. Only get! \c Returns \c (long int) in hexadecimal or "undefined module number" */ @@ -586,6 +597,13 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; ++i; + /*! \page timing + - subperiod [i] sets/gets sub frame period in s. Used in EIGER only in 32 bit mode. \c Returns \c (double with 9 decimal digits) + */ + descrToFuncMap[i].m_pFuncName="subperiod"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + ++i; + /*! \page timing - delay [i] sets/gets delay in s. Used in MYTHEN, GOTTHARD only. \c Returns \c (double with 9 decimal digits) */ @@ -635,6 +653,20 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; ++i; + /*! \page timing + - storagecells [i] sets/gets number of storage cells per acquisition. For very advanced users only! For JUNGFRAU only. Range: 0-15. The #images = #frames * #cycles * (#storagecells +1). \c Returns \c (long long int) + */ + descrToFuncMap[i].m_pFuncName="storagecells"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + ++i; + + /*! \page timing + - storagecell_start [i] sets/gets the storage cell that stores the first acquisition of the series. Default is 0. For very advanced users only! For JUNGFRAU only. Range: 0-15. \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="storagecell_start"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + ++i; + /* read only timers */ /*! \page timing @@ -1733,7 +1765,6 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { - /* Acquisition actions */ /*! \page actions Actions @@ -1957,6 +1988,21 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; ++i; + /*! \page network + - rx_udpsocksize [size] sets/gets the UDP socket buffer size. Already trying to set by default to 100mb, 2gb for Jungfrau. Does not remember in client shared memory, so must be initialized each time after setting receiver hostname in config file.\c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="rx_udpsocksize"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + ++i; + + /*! \page network + - rx_realudpsocksize [size] gets the actual UDP socket buffer size. Usually double the set udp socket buffer size due to kernel bookkeeping. Get only. \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="rx_realudpsocksize"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + ++i; + + /*! \page network - detectormac [mac] sets/gets the mac address of the detector UDP interface from where the detector will stream data. Use single-detector command. Normally unused. \c Returns \c (string) */ @@ -2034,6 +2080,13 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; i++; + /*! \page network + - rx_jsonaddheader [t] sets/gets additional json header to be streamed out with the zmq from receiver. Default is empty. \c t must be in the format "\"label1\":\"value1\",\"label2\":\"value2\"" etc. Use only if it needs to be processed by an intermediate process. \c Returns \c (string) + */ + descrToFuncMap[i].m_pFuncName="rx_jsonaddheader"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + /*! \page network - configuremac [i] configures the MAC of the detector with these parameters: detectorip, detectormac, rx_udpip, rx_udpmac, rx_udpport, rx_udpport2 (if applicable). This command is already included in \c rx_hsotname. Only put!. \c Returns \c (int) */ @@ -2174,6 +2227,34 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; ++i; + /*! \page receiver + - r_framesperfile sets/gets the frames per file in receiver. 0 means infinite or all frames in a single file. \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="r_framesperfile"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + ++i; + + /*! \page receiver + - r_framesperfile sets/gets the frames per file in receiver. 0 means infinite or all frames in a single file. \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="r_framesperfile"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + ++i; + + /*! \page receiver + - r_discardpolicy sets/gets the frame discard policy in the receiver. 0 - no discard (default), 1 - discard only empty frames, 2 - discard any partial frame(fastest). \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="r_discardpolicy"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + ++i; + + /*! \page receiver + - r_padding sets/gets the frame padding in the receiver. 0 does not pad partial frames(fastest), 1 (default) pads partial frames. \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="r_padding"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + ++i; + /* pattern generator */ /*! \page ctb Chiptest board @@ -2436,7 +2517,10 @@ string slsDetectorCommand::cmdAcquire(int narg, char *args[], int action) { if (action==HELP_ACTION) { return helpAcquire(narg,args,HELP_ACTION); } - + if (!myDet->getNumberOfDetectors()) { + cprintf(RED, "Error: This shared memory has no detectors added. Aborting.\n"); + return string("acquire unsuccessful"); + } myDet->setOnline(ONLINE_FLAG); int r_online = myDet->setReceiverOnline(ONLINE_FLAG); @@ -2640,86 +2724,16 @@ string slsDetectorCommand::cmdFree(int narg, char *args[], int action) { if (action==HELP_ACTION) { return helpFree(narg,args,HELP_ACTION); } - myDet->freeSharedMemory(); - return("freed"); + + return("Error: Should have been freed before creating constructor\n"); } string slsDetectorCommand::helpFree(int narg, char *args[], int action) { - return string("free \t frees the shared memory\n"); - } -string slsDetectorCommand::cmdAdd(int narg, char *args[], int action) { -#ifdef VERBOSE - cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); -#endif - int ivar, ival; - string var=string(args[0]); - ostringstream os; - if (action==HELP_ACTION) { - return helpAdd(narg,args,HELP_ACTION); - } else if (action==PUT_ACTION) { - size_t p=string(args[0]).find(':'); - if (p==string::npos) - ivar=-1; - else { - istringstream vvstr(var.substr(p+1)); - vvstr >> ivar; - if (vvstr.fail()) - ivar=-1; //append at the end - } - - if (sscanf(args[1],"%d",&ival)) { - // add by detector id - os<< myDet->addSlsDetector(ival, ivar)<< endl;; - } else { - //add by hostname - os<< myDet->addSlsDetector(args[1], ivar)<< endl; - } - return os.str(); - } - return string("cannot get"); - -} - - -string slsDetectorCommand::helpAdd(int narg, char *args[], int action){ - return string("add[:i] det \t adds a detector in position i to the multi detector structure. i is the detector position, default is appended. det can either be the detector hostname or the detector id. Returns -1 if it fails or the total number of detectors in the multidetector structure\n"); -} - -string slsDetectorCommand::cmdRemove(int narg, char *args[], int action){ -#ifdef VERBOSE - cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); -#endif - - - ostringstream os; - int ival;//ivar, - string var=string(args[0]); - - if (action==HELP_ACTION) { - return helpRemove(narg,args,HELP_ACTION); - } else if (action==PUT_ACTION) { - if (sscanf(args[1],"%d",&ival)) { - // remove detector in position ival - os << myDet->removeSlsDetector(ival); - } else { - // remove detector by hostname - os<< myDet->removeSlsDetector(args[1]); - } - return os.str(); - } - return string("cannot get"); - -} - -string slsDetectorCommand::helpRemove(int narg, char *args[], int action){ - return string("remove det \t removes a detector. det can either be the detector hostname or the detector position. Returns the total number of detectors in the multidetector structure\n"); -} - string slsDetectorCommand::cmdHostname(int narg, char *args[], int action){ #ifdef VERBOSE cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); @@ -2728,131 +2742,96 @@ string slsDetectorCommand::cmdHostname(int narg, char *args[], int action){ if (action==HELP_ACTION) { return helpHostname(narg,args,HELP_ACTION); } - - ostringstream os; - int ivar=-1;//, ival; - string var=string(args[0]); - char hostname[1000]; - - - size_t p=string(args[0]).find(':'); - if (p==string::npos) - ivar=-1; - else { - istringstream vvstr(var.substr(p+1)); - vvstr >> ivar; - if (vvstr.fail()) - ivar=-1; + if (action==GET_ACTION) { + if ((cmd == "add") || (cmd == "replace")) + return string("cannot get"); } - - - p=string(args[0]).find("hostname"); - - if (p==string::npos) { - //type - // cout << "should add by type!" << endl; - - if (action==PUT_ACTION) { - //add by type - if (ivar==-1) { - strcpy(hostname,""); - for (int id=1; id2) - strcat(hostname,"+"); - } - } else - strcpy(hostname,args[1]); - - myDet->ssetDetectorsType(hostname, ivar); + if (action==PUT_ACTION) { + if (((cmd == "add") || (cmd == "hostname")) && + (!myDet->isMultiSlsDetectorClass())) { + return string ("Wrong usage - setting hostname/add only from " + "multiDetector level"); } - return myDet->sgetDetectorsType(ivar); - } else { - if (action==PUT_ACTION) { - //add by hostname - if (ivar==-1) { - strcpy(hostname,""); - for (int id=1; id2) - strcat(hostname,"+"); - } - } else - strcpy(hostname,args[1]); - myDet->setHostname(hostname, ivar); + if ((cmd == "replace") && (myDet->isMultiSlsDetectorClass())) { + return string ("Wrong usage - replace only from " + "single detector level"); + } + char hostname[1000]; + strcpy(hostname,""); + // if each argument is a hostname + for (int id=1; id2) + strcat(hostname,"+"); } - return string(myDet->getHostname(ivar)); + if (cmd == "add") + myDet->addMultipleDetectors(hostname); + else + myDet->setHostname(hostname); } + return myDet->getHostname(); } string slsDetectorCommand::helpHostname(int narg, char *args[], int action){ - ostringstream os; - if (action==GET_ACTION || action==HELP_ACTION) - os << string("hostname[:i] \t returns the hostname(s) of the detector structure. i is the detector position in a multi detector system\n"); - if (action==PUT_ACTION || action==HELP_ACTION) - os << string("hostname[:i] name [name name]\t configures the hostnames of the detector structure. i is the detector position in a multi detector system\n"); + if (action==GET_ACTION || action==HELP_ACTION) { + os << string("hostname \t returns the hostname(s) of the multi detector structure.\n"); + os << string("add \t cannot get\n"); + os << string("replace \t cannot get\n"); + } + if (action==PUT_ACTION || action==HELP_ACTION) { + os << string("hostname name [name name]\t frees shared memory and " + "sets the hostname (or IP adress). Only allowed at multi detector level.\n"); + os << string ("add det [det det]\t appends a hostname (or IP address) at " + "the end of the multi-detector structure. Only allowed at multi detector level." + "Returns hostnames in the multi detector structure\n"); + os << string ("replace det \t Sets the hostname (or IP adress) for a " + "single detector. Only allowed at single detector level. " + "Returns the hostnames for that detector\n"); + } return os.str(); } -string slsDetectorCommand::cmdId(int narg, char *args[], int action){ +string slsDetectorCommand::cmdUser(int narg, char *args[], int action){ #ifdef VERBOSE cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); #endif - if (action==HELP_ACTION) { - return helpId(narg,args,HELP_ACTION); + return helpHostname(narg,args,HELP_ACTION); } - - ostringstream os; - int ivar, ival; - string var=string(args[0]); - // char answer[1000]; - - - size_t p=string(args[0]).find(':'); - if (p==string::npos) - ivar=-1; - else { - istringstream vvstr(var.substr(p+1)); - vvstr >> ivar; - if (vvstr.fail()) - ivar=-1; - } - if (action==PUT_ACTION) { - //add by hostname - istringstream vvstr(args[1]); - - vvstr >> ival; - if (vvstr.fail()) - ival=-1; - - myDet->setDetectorId(ival, ivar); + return string("cannot put"); } - os << myDet->getDetectorId(ivar); - - return os.str(); - + if (!myDet->isMultiSlsDetectorClass()) { + return string ("Wrong usage - getting user details only from " + "multiDetector level"); + } + return myDet->getUserDetails(); } -string slsDetectorCommand::helpId(int narg, char *args[], int action){ + + +string slsDetectorCommand::helpUser(int narg, char *args[], int action){ ostringstream os; - if (action==GET_ACTION || action==HELP_ACTION) - os << string("id[:i] \t returns the id of the detector structure. i is the detector position in a multi detector system\n"); - if (action==PUT_ACTION || action==HELP_ACTION) - os << string("id:i l]\t configures the id of the detector structure. i is the detector position in a multi detector system and l is the id of the detector to be added\n"); - + if (action==GET_ACTION || action==HELP_ACTION) { + os << string("user \t returns user details from shared memory without updating shared memory. " + "Only allowed at multi detector level.\n"); + } + if (action==PUT_ACTION || action==HELP_ACTION) { + os << string("user \t cannot put\n"); + } return os.str(); } + + string slsDetectorCommand::cmdMaster(int narg, char *args[], int action){ #ifdef VERBOSE cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); @@ -2980,9 +2959,9 @@ string slsDetectorCommand::cmdSettingsDir(int narg, char *args[], int action){ if (action==PUT_ACTION) { myDet->setSettingsDir(string(args[1])); } - if (myDet->getSettingsDir()==NULL) + if (myDet->getSettingsDir()=="") return string("undefined"); - return string(myDet->getSettingsDir()); + return myDet->getSettingsDir(); } @@ -3010,9 +2989,9 @@ string slsDetectorCommand::cmdCalDir(int narg, char *args[], int action){ if (action==PUT_ACTION) { myDet->setCalDir(string(args[1])); } - if (myDet->getCalDir()==NULL) + if ( (myDet->getCalDir()).empty() ) return string("undefined"); - return string(myDet->getCalDir()); + return myDet->getCalDir(); } @@ -3050,12 +3029,18 @@ string slsDetectorCommand::cmdTrimEn(int narg, char *args[], int action){ } } int npos=myDet->getTrimEn(); - sprintf(answer,"%d",npos); - int opos[npos]; - myDet->getTrimEn(opos); - for (int ip=0; ipgetTrimEn(opos); + if (npos != -1) { + for (int ip=0; ipenableDataStreamingFromReceiver(); if (prev_streaming) myDet->enableDataStreamingFromReceiver(0); + } else if (cmd=="rx_jsonaddheader") { + t=ADDITIONAL_JSON_HEADER; } else return ("unknown network parameter")+cmd; @@ -4132,6 +4130,13 @@ string slsDetectorCommand::helpNetworkParameter(int narg, char *args[], int acti os << "rx_zmqip ip \n sets/gets the 0MQ (TCP) ip of the receiver from where data is streamed from (eg. to GUI or another process for further processing). " "Default is ip of rx_hostname and works for GUI. This is usually used to stream out to an external process for further processing." "restarts streaming in receiver with new port" << std::endl; + os << "rx_jsonaddheader [t]\n sets additional json header to be streamed " + "out with the zmq from receiver. Default is empty. t must be in the format '\"label1\":\"value1\",\"label2\":\"value2\"' etc." + "Use only if it needs to be processed by an intermediate process." << std::endl; + os << "rx_udpsocksize [t]\n sets the UDP socket buffer size. Different defaults for Jungfrau. " + "Does not remember in client shared memory, " + "so must be initialized each time after setting receiver " + "hostname in config file." << std::endl; } if (action==GET_ACTION || action==HELP_ACTION) { os << "detectormac \n gets detector mac "<< std::endl; @@ -4148,6 +4153,11 @@ string slsDetectorCommand::helpNetworkParameter(int narg, char *args[], int acti os << "rx_zmqport \n gets the 0MQ (TCP) port of the receiver from where data is streamed from"<< std::endl; os << "zmqip \n gets the 0MQ (TCP) ip of the client to where final data is streamed to.If no custom ip, empty until first time connect to receiver" << std::endl; os << "rx_zmqip \n gets/gets the 0MQ (TCP) ip of the receiver from where data is streamed from. If no custom ip, empty until first time connect to receiver" << std::endl; + os << "rx_jsonaddheader \n gets additional json header to be streamed " + "out with the zmq from receiver." << std::endl; + os << "rx_udpsocksize \n gets the UDP socket buffer size." << std::endl; + os << "rx_realudpsocksize \n gets the actual UDP socket buffer size. Usually double the set udp socket buffer size due to kernel bookkeeping." << std::endl; + } return os.str(); @@ -4578,7 +4588,10 @@ string slsDetectorCommand::cmdSettings(int narg, char *args[], int action) { if (cmd=="settings") { detectorSettings sett = GET_SETTINGS; if (action==PUT_ACTION) { - sett = myDet->setSettings(myDet->getDetectorSettings(string(args[1]))); + sett = myDet->getDetectorSettings(string(args[1])); + if (sett == -1) + return string ("unknown settings scanned " + string(args[1])); + sett = myDet->setSettings(sett); if (myDet->getDetectorsType() == EIGER) { return myDet->getDetectorSettings(sett); } @@ -4626,12 +4639,16 @@ string slsDetectorCommand::cmdSettings(int narg, char *args[], int action) { #ifdef VERBOSE std::cout<< " trimfile " << sval << std::endl; #endif + int ret = OK; if (action==GET_ACTION) { //create file names - myDet->saveSettingsFile(sval, -1); + ret = myDet->saveSettingsFile(sval, -1); } else if (action==PUT_ACTION) { - myDet->loadSettingsFile(sval,-1); + ret = myDet->loadSettingsFile(sval,-1); } + if (ret == OK) + return sval; + else return string("not successful"); } return myDet->getSettingsFile(); } else if (cmd=="trim") { @@ -4816,6 +4833,24 @@ string slsDetectorCommand::cmdSN(int narg, char *args[], int action) { sprintf(answer,"0x%lx", retval); return string(answer); } + + if (cmd=="checkdetversion") { + int retval = myDet->checkVersionCompatibility(CONTROL_PORT); + if (retval < 0) + sprintf(answer, "%d", -1); + sprintf(answer,"%s", retval == OK ? "compatible" : "incompatible"); + return string(answer); + } + + if (cmd=="checkrecversion") { + myDet->setReceiverOnline(ONLINE_FLAG); + int retval = myDet->checkVersionCompatibility(DATA_PORT); + if (retval < 0) + sprintf(answer, "%d", -1); + sprintf(answer,"%s", retval == OK ? "compatible" : "incompatible"); + return string(answer); + } + return string("unknown id mode ")+cmd; } @@ -4824,6 +4859,8 @@ string slsDetectorCommand::helpSN(int narg, char *args[], int action) { ostringstream os; if (action==GET_ACTION || action==HELP_ACTION) { + os << "checkdetversion \n gets the version compatibility with detector software (if hostname is in shared memory). Only for Eiger, Jungfrau & Gotthard. Prints compatible/ incompatible."<< std::endl; + os << "checkrecversion \n gets the version compatibility with receiver software (if rx_hostname is in shared memory). Only for Eiger, Jungfrau & Gotthard. Prints compatible/ incompatible."<< std::endl; os << "moduleversion:i \n gets the firmwareversion of the module i"<< std::endl; os << "modulenumber:i \n gets the serial number of the module i"<< std::endl; os << "detectornumber \n gets the serial number of the detector (MAC)"<< std::endl; @@ -5593,6 +5630,8 @@ string slsDetectorCommand::cmdTimer(int narg, char *args[], int action) { index=SUBFRAME_ACQUISITION_TIME; else if (cmd=="period") index=FRAME_PERIOD; + else if (cmd=="subperiod") + index=SUBFRAME_PERIOD; else if (cmd=="delay") index=DELAY_AFTER_TRIGGER; else if (cmd=="gates") @@ -5607,6 +5646,19 @@ string slsDetectorCommand::cmdTimer(int narg, char *args[], int action) { index=MEASUREMENTS_NUMBER; else if (cmd=="samples") index=SAMPLES_JCTB; + else if (cmd=="storagecells") + index=STORAGE_CELL_NUMBER; + else if (cmd=="storagecell_start") { + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) { + int ival =-1; + if (!sscanf(args[1],"%d", &ival)) + return string("cannot scan storage cell start value ")+string(args[1]); + myDet->setStoragecellStart(ival); + } + sprintf(answer,"%d", myDet->setStoragecellStart()); + return string(answer); + } else return string("could not decode timer ")+cmd; @@ -5616,12 +5668,11 @@ string slsDetectorCommand::cmdTimer(int narg, char *args[], int action) { ;//printf("value:%0.9lf\n",val); else return string("cannot scan timer value ")+string(args[1]); - if (index==ACQUISITION_TIME || index==SUBFRAME_ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER) { - // t=(int64_t)(val*1E+9); for precision of eg.0.0000325, following done - val*=1E9; - t = (int64_t)val; - if(fabs(val-t)) // to validate precision loss - t = t + val - t; //even t += vak-t loses precision + if (index==ACQUISITION_TIME || index==SUBFRAME_ACQUISITION_TIME || + index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER || + index == SUBFRAME_PERIOD) { + // +0.5 for precision of eg.0.0000325 + t = ( val * 1E9 + 0.5); }else t=(int64_t)val; } @@ -5631,7 +5682,9 @@ string slsDetectorCommand::cmdTimer(int narg, char *args[], int action) { ret=myDet->setTimer(index,t); - if ((ret!=-1) && (index==ACQUISITION_TIME || index==SUBFRAME_ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER)) { + if ((ret!=-1) && (index==ACQUISITION_TIME || index==SUBFRAME_ACQUISITION_TIME + || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER || + index == SUBFRAME_PERIOD)) { rval=(double)ret*1E-9; sprintf(answer,"%0.9f",rval); } @@ -5658,6 +5711,9 @@ string slsDetectorCommand::helpTimer(int narg, char *args[], int action) { os << "cycles t \t sets the number of cycles (e.g. number of triggers)" << std::endl; os << "probes t \t sets the number of probes to accumulate (max 3! cycles should be set to 1, frames to the number of pump-probe events)" << std::endl; os << "samples t \t sets the number of samples expected from the jctb" << std::endl; + os << "storagecells t \t sets number of storage cells per acquisition. For very advanced users only! For JUNGFRAU only. Range: 0-15. The #images = #frames * #cycles * (#storagecells+1)." << std::endl; + os << "storagecell_start t \t sets the storage cell that stores the first acquisition of the series. Default is 0. For very advanced users only! For JUNGFRAU only. Range: 0-15." << std::endl; + os << "subperiod t \t sets sub frame period in s. Used in EIGER only in 32 bit mode. " << std::endl; os << std::endl; @@ -5671,8 +5727,10 @@ string slsDetectorCommand::helpTimer(int narg, char *args[], int action) { os << "frames \t gets the number of frames per cycle (e.g. after each trigger)" << std::endl; os << "cycles \t gets the number of cycles (e.g. number of triggers)" << std::endl; os << "probes \t gets the number of probes to accumulate" << std::endl; - os << "samples t \t gets the number of samples expected from the jctb" << std::endl; - + os << "samples \t gets the number of samples expected from the jctb" << std::endl; + os << "storagecells \t gets number of storage cells per acquisition.For JUNGFRAU only." << std::endl; + os << "storagecell_start \t gets the storage cell that stores the first acquisition of the series." << std::endl; + os << "subperiod \t gets sub frame period in s. Used in EIGER in 32 bit only." << std::endl; os << std::endl; } @@ -5915,6 +5973,10 @@ string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action) { flag=DIGITAL_ONLY; else if (sval=="analog_digital") flag=ANALOG_AND_DIGITAL; + else if (sval=="overflow") + flag=SHOW_OVERFLOW; + else if (sval=="nooverflow") + flag=NOOVERFLOW; else return string("could not scan flag ")+string(args[1]); } @@ -5943,6 +6005,10 @@ string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action) { strcat(answer,"digital " ); if (retval & ANALOG_AND_DIGITAL) strcat(answer,"analog_digital "); + if (retval & SHOW_OVERFLOW) + strcat(answer,"overflow "); + if (retval & NOOVERFLOW) + strcat(answer,"nooverflow "); if(strlen(answer)) return string(answer); @@ -6047,7 +6113,7 @@ string slsDetectorCommand::helpAdvanced(int narg, char *args[], int action) { if (action==PUT_ACTION || action==HELP_ACTION) { os << "extsig:i mode \t sets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl; - os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, unknown" << std::endl; + os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, overlow, nooverflow, unknown." << std::endl; os << "programfpga f \t programs the fpga with file f (with .pof extension)." << std::endl; os << "resetfpga f \t resets fpga, f can be any value" << std::endl; @@ -6060,9 +6126,8 @@ string slsDetectorCommand::helpAdvanced(int narg, char *args[], int action) { os << "extsig:i \t gets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl; - os << "flags \t gets the readout flags. can be none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, unknown" << std::endl; + os << "flags \t gets the readout flags. can be none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, overflow, nooverflow, unknown" << std::endl; os << "led \t returns led status (0 off, 1 on)" << std::endl; - os << "flags \t gets the readout flags. can be none, storeinram, tot, continous, parallel, nonparallel, safe, unknown" << std::endl; os << "powerchip \t gets if the chip has been powered on or off" << std::endl; os << "auto_comp_disable \t Currently not implemented. gets if the automatic comparator diable mode is enabled/disabled" << std::endl; @@ -6279,6 +6344,43 @@ string slsDetectorCommand::cmdReceiver(int narg, char *args[], int action) { } + else if(cmd=="r_framesperfile") { + if (action==PUT_ACTION){ + if (sscanf(args[1],"%d",&ival)) { + myDet->setReceiverFramesPerFile(ival); + } else return string("could not scan max frames per file\n"); + } + char answer[100]; + memset(answer, 0, 100); + sprintf(answer,"%d", myDet->setReceiverFramesPerFile()); + return string(answer); + } + + else if(cmd=="r_discardpolicy") { + if (action==PUT_ACTION){ + if (sscanf(args[1],"%d",&ival) && (ival >= 0) && (ival < NUM_DISCARD_POLICIES)) { + myDet->setReceiverFramesDiscardPolicy((frameDiscardPolicy)ival); + } else return string("could not scan frames discard policy\n"); + } + char answer[100]; + memset(answer, 0, 100); + sprintf(answer,"%d",myDet->setReceiverFramesDiscardPolicy()); + return string(answer); + } + + else if(cmd=="r_padding") { + if (action==PUT_ACTION){ + if (sscanf(args[1],"%d",&ival)) { + myDet->setReceiverPartialFramesPadding(ival); + } else return string("could not scan receiver padding enable\n"); + } + char answer[100]; + memset(answer, 0, 100); + sprintf(answer,"%d",myDet->setReceiverPartialFramesPadding()); + return string(answer); + } + + return string("could not decode command"); @@ -6296,6 +6398,9 @@ string slsDetectorCommand::helpReceiver(int narg, char *args[], int action) { os << "tengiga \t sets system to be configure for 10Gbe if set to 1, else 1Gbe if set to 0" << std::endl; os << "rx_fifodepth [val]\t sets receiver fifo depth to val" << std::endl; os << "r_silent [i]\t sets receiver in silent mode, ie. it will not print anything during real time acquisition. 1 sets, 0 unsets." << std::endl; + os << "r_framesperfile s\t sets the number of frames per file in receiver. 0 means infinite or all frames in a single file." << std::endl; + os << "r_discardpolicy s\t sets the frame discard policy in the receiver. 0 - no discard (default), 1 - discard only empty frames, 2 - discard any partial frame(fastest)." << std::endl; + os << "r_padding s\t enables/disables partial frames to be padded in the receiver. 0 does not pad partial frames(fastest), 1 (default) pads partial frames." << std::endl; } if (action==GET_ACTION || action==HELP_ACTION){ os << "receiver \t returns the status of receiver - can be running or idle" << std::endl; @@ -6305,6 +6410,9 @@ string slsDetectorCommand::helpReceiver(int narg, char *args[], int action) { os << "tengiga \t returns 1 if the system is configured for 10Gbe else 0 for 1Gbe" << std::endl; os << "rx_fifodepth \t returns receiver fifo depth" << std::endl; os << "r_silent \t returns receiver silent mode enable. 1 is silent, 0 not silent." << std::endl; + os << "r_framesperfile \t gets the number of frames per file in receiver. 0 means infinite or all frames in a single file." << std::endl; + os << "r_discardpolicy \t gets the frame discard policy in the receiver. 0 - no discard (default), 1 - discard only empty frames, 2 - discard any partial frame(fastest)." << std::endl; + os << "r_padding \t gets partial frames padding enable in the receiver. 0 does not pad partial frames(fastest), 1 (default) pads partial frames." << std::endl; } return os.str(); } diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.h b/slsDetectorSoftware/slsDetector/slsDetectorCommand.h index 0c69ac923..a4a43e2a4 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.h @@ -5,7 +5,7 @@ #include "sls_detector_defs.h" #include "slsDetectorUtils.h" -using namespace std; + /** @short This class handles the command line I/Os, help etc. of the text clients */ @@ -26,68 +26,66 @@ class slsDetectorCommand : public virtual slsDetectorDefs { /* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ /* \returns answer string */ /* *\/ */ - virtual string executeLine(int narg, char *args[], int action); + virtual std::string executeLine(int narg, char *args[], int action); /* /\** */ /* returns the help for the executeLine command */ /* \param os output stream to return the help to */ /* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ /* *\/ */ - string helpLine(int narg, char *args[], int action=HELP_ACTION); - static string helpAcquire(int narg, char *args[], int action); - static string helpData(int narg, char *args[], int action); - static string helpFrame(int narg, char *args[], int action); - static string helpStatus(int narg, char *args[], int action); - static string helpDataStream(int narg, char *args[], int action); - static string helpFree(int narg, char *args[], int action); - static string helpAdd(int narg, char *args[], int action); - static string helpRemove(int narg, char *args[], int action); - static string helpHostname(int narg, char *args[], int action); - static string helpId(int narg, char *args[], int action); - static string helpMaster(int narg, char *args[], int action); - static string helpSync(int narg, char *args[], int action); - static string helpExitServer(int narg, char *args[], int action); - static string helpSettingsDir(int narg, char *args[], int action); - static string helpCalDir(int narg, char *args[], int action); - static string helpTrimEn(int narg, char *args[], int action); - static string helpOutDir(int narg, char *args[], int action); - static string helpFileName(int narg, char *args[], int action); - static string helpFileIndex(int narg, char *args[], int action); - static string helpFlatField(int narg, char *args[], int action); - static string helpRateCorr(int narg, char *args[], int action); - static string helpBadChannels(int narg, char *args[], int action); - static string helpAngConv(int narg, char *args[], int action); - static string helpThreaded(int narg, char *args[], int action); - static string helpPositions(int narg, char *args[], int action); - static string helpScripts(int narg, char *args[], int action); - static string helpScans(int narg, char *args[], int action); - static string helpNetworkParameter(int narg, char *args[], int action); - static string helpPort(int narg, char *args[], int action); - static string helpLock(int narg, char *args[], int action); - static string helpLastClient(int narg, char *args[], int action); - static string helpOnline(int narg, char *args[], int action); - static string helpConfigureMac(int narg, char *args[], int action); - static string helpDetectorSize(int narg, char *args[], int action); - static string helpSettings(int narg, char *args[], int action); - static string helpSN(int narg, char *args[], int action); - static string helpDigiTest(int narg, char *args[], int action); - static string helpRegister(int narg, char *args[], int action); - static string helpDAC(int narg, char *args[], int action); - static string helpTimer(int narg, char *args[], int action); - static string helpTiming(int narg, char *args[], int action); - static string helpTimeLeft(int narg, char *args[], int action); - static string helpSpeed(int narg, char *args[], int action); - static string helpAdvanced(int narg, char *args[], int action); - static string helpConfiguration(int narg, char *args[], int action); - static string helpImage(int narg, char *args[], int action); - static string helpCounter(int narg, char *args[], int action); - static string helpADC(int narg, char *args[], int action); - static string helpTempControl(int narg, char *args[], int action); - static string helpEnablefwrite(int narg, char *args[], int action); - static string helpOverwrite(int narg, char *args[], int action); - static string helpReceiver(int narg, char *args[], int action); - static string helpPattern(int narg, char *args[], int action); - static string helpPulse(int narg, char *args[], int action); + std::string helpLine(int narg, char *args[], int action=HELP_ACTION); + static std::string helpAcquire(int narg, char *args[], int action); + static std::string helpData(int narg, char *args[], int action); + static std::string helpFrame(int narg, char *args[], int action); + static std::string helpStatus(int narg, char *args[], int action); + static std::string helpDataStream(int narg, char *args[], int action); + static std::string helpFree(int narg, char *args[], int action); + static std::string helpHostname(int narg, char *args[], int action); + static std::string helpUser(int narg, char *args[], int action); + static std::string helpMaster(int narg, char *args[], int action); + static std::string helpSync(int narg, char *args[], int action); + static std::string helpExitServer(int narg, char *args[], int action); + static std::string helpSettingsDir(int narg, char *args[], int action); + static std::string helpCalDir(int narg, char *args[], int action); + static std::string helpTrimEn(int narg, char *args[], int action); + static std::string helpOutDir(int narg, char *args[], int action); + static std::string helpFileName(int narg, char *args[], int action); + static std::string helpFileIndex(int narg, char *args[], int action); + static std::string helpFlatField(int narg, char *args[], int action); + static std::string helpRateCorr(int narg, char *args[], int action); + static std::string helpBadChannels(int narg, char *args[], int action); + static std::string helpAngConv(int narg, char *args[], int action); + static std::string helpThreaded(int narg, char *args[], int action); + static std::string helpPositions(int narg, char *args[], int action); + static std::string helpScripts(int narg, char *args[], int action); + static std::string helpScans(int narg, char *args[], int action); + static std::string helpNetworkParameter(int narg, char *args[], int action); + static std::string helpPort(int narg, char *args[], int action); + static std::string helpLock(int narg, char *args[], int action); + static std::string helpLastClient(int narg, char *args[], int action); + static std::string helpOnline(int narg, char *args[], int action); + static std::string helpConfigureMac(int narg, char *args[], int action); + static std::string helpDetectorSize(int narg, char *args[], int action); + static std::string helpSettings(int narg, char *args[], int action); + static std::string helpSN(int narg, char *args[], int action); + static std::string helpDigiTest(int narg, char *args[], int action); + static std::string helpRegister(int narg, char *args[], int action); + static std::string helpDAC(int narg, char *args[], int action); + static std::string helpTimer(int narg, char *args[], int action); + static std::string helpTiming(int narg, char *args[], int action); + static std::string helpTimeLeft(int narg, char *args[], int action); + static std::string helpSpeed(int narg, char *args[], int action); + static std::string helpAdvanced(int narg, char *args[], int action); + static std::string helpConfiguration(int narg, char *args[], int action); + static std::string helpImage(int narg, char *args[], int action); + static std::string helpCounter(int narg, char *args[], int action); + static std::string helpADC(int narg, char *args[], int action); + static std::string helpTempControl(int narg, char *args[], int action); + static std::string helpEnablefwrite(int narg, char *args[], int action); + static std::string helpOverwrite(int narg, char *args[], int action); + static std::string helpReceiver(int narg, char *args[], int action); + static std::string helpPattern(int narg, char *args[], int action); + static std::string helpPulse(int narg, char *args[], int action); @@ -105,75 +103,72 @@ class slsDetectorCommand : public virtual slsDetectorDefs { slsDetectorUtils *myDet; - string cmdUnderDevelopment(int narg, char *args[], int action); - string cmdUnknown(int narg, char *args[], int action); - string cmdAcquire(int narg, char *args[], int action); - string cmdData(int narg, char *args[], int action); - string cmdFrame(int narg, char *args[], int action); - string cmdStatus(int narg, char *args[], int action); - string cmdDataStream(int narg, char *args[], int action); - string cmdFree(int narg, char *args[], int action); - string cmdAdd(int narg, char *args[], int action); - string cmdRemove(int narg, char *args[], int action); - string cmdHostname(int narg, char *args[], int action); - string cmdId(int narg, char *args[], int action); - string cmdMaster(int narg, char *args[], int action); - string cmdSync(int narg, char *args[], int action); - string cmdHelp(int narg, char *args[], int action); - string cmdExitServer(int narg, char *args[], int action); - string cmdSettingsDir(int narg, char *args[], int action); - string cmdCalDir(int narg, char *args[], int action); - string cmdTrimEn(int narg, char *args[], int action); - string cmdOutDir(int narg, char *args[], int action); - string cmdFileName(int narg, char *args[], int action); - string cmdFileIndex(int narg, char *args[], int action); - string cmdFlatField(int narg, char *args[], int action); - string cmdRateCorr(int narg, char *args[], int action); - string cmdBadChannels(int narg, char *args[], int action); - string cmdAngConv(int narg, char *args[], int action); - string cmdThreaded(int narg, char *args[], int action); - string cmdPositions(int narg, char *args[], int action); - string cmdScripts(int narg, char *args[], int action); - string cmdScans(int narg, char *args[], int action); - string cmdNetworkParameter(int narg, char *args[], int action); - string cmdPort(int narg, char *args[], int action); - string cmdLock(int narg, char *args[], int action); - string cmdLastClient(int narg, char *args[], int action); - string cmdOnline(int narg, char *args[], int action); - string cmdConfigureMac(int narg, char *args[], int action); - string cmdDetectorSize(int narg, char *args[], int action); - string cmdSettings(int narg, char *args[], int action); - string cmdSN(int narg, char *args[], int action); - string cmdDigiTest(int narg, char *args[], int action); - string cmdRegister(int narg, char *args[], int action); - string cmdDAC(int narg, char *args[], int action); - string cmdTiming(int narg, char *args[], int action); - string cmdTimer(int narg, char *args[], int action); - string cmdTimeLeft(int narg, char *args[], int action); - string cmdSpeed(int narg, char *args[], int action); - string cmdAdvanced(int narg, char *args[], int action); - string cmdConfiguration(int narg, char *args[], int action); - string cmdImage(int narg, char *args[], int action); - string cmdCounter(int narg, char *args[], int action); - string cmdADC(int narg, char *args[], int action); - string cmdTempControl(int narg, char *args[], int action); - string cmdEnablefwrite(int narg, char *args[], int action); - string cmdOverwrite(int narg, char *args[], int action); - string cmdReceiver(int narg, char *args[], int action); - string cmdPattern(int narg, char *args[], int action); - string cmdPulse(int narg, char *args[], int action); + std::string cmdUnderDevelopment(int narg, char *args[], int action); + std::string cmdUnknown(int narg, char *args[], int action); + std::string cmdAcquire(int narg, char *args[], int action); + std::string cmdData(int narg, char *args[], int action); + std::string cmdFrame(int narg, char *args[], int action); + std::string cmdStatus(int narg, char *args[], int action); + std::string cmdDataStream(int narg, char *args[], int action); + std::string cmdFree(int narg, char *args[], int action); + std::string cmdHostname(int narg, char *args[], int action); + std::string cmdUser(int narg, char *args[], int action); + std::string cmdMaster(int narg, char *args[], int action); + std::string cmdSync(int narg, char *args[], int action); + std::string cmdHelp(int narg, char *args[], int action); + std::string cmdExitServer(int narg, char *args[], int action); + std::string cmdSettingsDir(int narg, char *args[], int action); + std::string cmdCalDir(int narg, char *args[], int action); + std::string cmdTrimEn(int narg, char *args[], int action); + std::string cmdOutDir(int narg, char *args[], int action); + std::string cmdFileName(int narg, char *args[], int action); + std::string cmdFileIndex(int narg, char *args[], int action); + std::string cmdFlatField(int narg, char *args[], int action); + std::string cmdRateCorr(int narg, char *args[], int action); + std::string cmdBadChannels(int narg, char *args[], int action); + std::string cmdAngConv(int narg, char *args[], int action); + std::string cmdThreaded(int narg, char *args[], int action); + std::string cmdPositions(int narg, char *args[], int action); + std::string cmdScripts(int narg, char *args[], int action); + std::string cmdScans(int narg, char *args[], int action); + std::string cmdNetworkParameter(int narg, char *args[], int action); + std::string cmdPort(int narg, char *args[], int action); + std::string cmdLock(int narg, char *args[], int action); + std::string cmdLastClient(int narg, char *args[], int action); + std::string cmdOnline(int narg, char *args[], int action); + std::string cmdConfigureMac(int narg, char *args[], int action); + std::string cmdDetectorSize(int narg, char *args[], int action); + std::string cmdSettings(int narg, char *args[], int action); + std::string cmdSN(int narg, char *args[], int action); + std::string cmdDigiTest(int narg, char *args[], int action); + std::string cmdRegister(int narg, char *args[], int action); + std::string cmdDAC(int narg, char *args[], int action); + std::string cmdTiming(int narg, char *args[], int action); + std::string cmdTimer(int narg, char *args[], int action); + std::string cmdTimeLeft(int narg, char *args[], int action); + std::string cmdSpeed(int narg, char *args[], int action); + std::string cmdAdvanced(int narg, char *args[], int action); + std::string cmdConfiguration(int narg, char *args[], int action); + std::string cmdImage(int narg, char *args[], int action); + std::string cmdCounter(int narg, char *args[], int action); + std::string cmdADC(int narg, char *args[], int action); + std::string cmdTempControl(int narg, char *args[], int action); + std::string cmdEnablefwrite(int narg, char *args[], int action); + std::string cmdOverwrite(int narg, char *args[], int action); + std::string cmdReceiver(int narg, char *args[], int action); + std::string cmdPattern(int narg, char *args[], int action); + std::string cmdPulse(int narg, char *args[], int action); int numberOfCommands; - string cmd; + std::string cmd; - typedef string (slsDetectorCommand::*MemFuncGetter)(int narg, char *args[], int action); + typedef std::string (slsDetectorCommand::*MemFuncGetter)(int narg, char *args[], int action); struct FuncTable { - string m_pFuncName; - //const char* m_pFuncName; + std::string m_pFuncName; MemFuncGetter m_pFuncPtr; }; diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp index 11a3f800b..c35d64dd4 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp @@ -4,6 +4,8 @@ #include "multiSlsDetectorCommand.h" +using namespace std; + slsDetectorUsers::slsDetectorUsers(int id) : myDetector(NULL){ myDetector=new multiSlsDetector(id); @@ -151,43 +153,62 @@ int slsDetectorUsers::setThresholdEnergy(int e_eV){ return myDetector->setThresholdEnergy(e_eV); } -double slsDetectorUsers::setExposureTime(double t, bool inseconds){ - int64_t tms = (int64_t)(t * (1E+9)); - if (t < 0) tms = -1; - if(!inseconds) - return myDetector->setExposureTime((int64_t)t); - else - return ((1E-9) * (double)myDetector->setExposureTime(tms)); +int slsDetectorUsers::setThresholdEnergy(int e_ev, int tb, int isettings, int id) { + return myDetector->slsDetectorBase::setThresholdEnergy(e_ev, tb, isettings, id); } -double slsDetectorUsers::setExposurePeriod(double t, bool inseconds){ - int64_t tms = (int64_t)(t * (1E+9)); - if (t < 0) tms = -1; - if(!inseconds) - return myDetector->setExposurePeriod((int64_t)t); - else - return ((1E-9) * (double)myDetector->setExposurePeriod(tms)); +double slsDetectorUsers::setExposureTime(double t, bool inseconds, int imod){ + if(!inseconds) + return myDetector->setExposureTime((int64_t)t,imod); + else { + // + 0.5 to round for precision lost from converting double to int64_t + int64_t tms = (int64_t)(t * (1E+9) + 0.5); + if (t < 0) tms = -1; + tms = myDetector->setExposureTime(tms,imod); + if (tms < 0) + return -1; + return ((1E-9) * (double)tms); + } } -double slsDetectorUsers::setDelayAfterTrigger(double t, bool inseconds){ - int64_t tms = (int64_t)(t * (1E+9)); - if (t < 0) tms = -1; - if(!inseconds) - return myDetector->setDelayAfterTrigger((int64_t)t); - else - return ((1E-9) * (double)myDetector->setDelayAfterTrigger(tms)); +double slsDetectorUsers::setExposurePeriod(double t, bool inseconds, int imod){ + if(!inseconds) + return myDetector->setExposurePeriod((int64_t)t,imod); + else { + // + 0.5 to round for precision lost from converting double to int64_t + int64_t tms = (int64_t)(t * (1E+9) + 0.5); + if (t < 0) tms = -1; + tms = myDetector->setExposurePeriod(tms,imod); + if (tms < 0) + return -1; + return ((1E-9) * (double)tms); + } } -int64_t slsDetectorUsers::setNumberOfGates(int64_t t){ - return myDetector->setNumberOfGates(t); +double slsDetectorUsers::setDelayAfterTrigger(double t, bool inseconds, int imod){ + if(!inseconds) + return myDetector->setDelayAfterTrigger((int64_t)t,imod); + else { + // + 0.5 to round for precision lost from converting double to int64_t + int64_t tms = (int64_t)(t * (1E+9) + 0.5); + if (t < 0) tms = -1; + tms = myDetector->setDelayAfterTrigger(tms,imod); + if (tms < 0) + return -1; + return ((1E-9) * (double)tms); + } +} + +int64_t slsDetectorUsers::setNumberOfGates(int64_t t, int imod){ + return myDetector->setNumberOfGates(t,imod); } -int64_t slsDetectorUsers::setNumberOfFrames(int64_t t){ - return myDetector->setNumberOfFrames(t); +int64_t slsDetectorUsers::setNumberOfFrames(int64_t t, int imod){ + return myDetector->setNumberOfFrames(t,imod); } -int64_t slsDetectorUsers::setNumberOfCycles(int64_t t){ - return myDetector->setNumberOfCycles(t); +int64_t slsDetectorUsers::setNumberOfCycles(int64_t t, int imod){ + return myDetector->setNumberOfCycles(t,imod); } int slsDetectorUsers::setTimingMode(int pol){ @@ -343,6 +364,12 @@ int slsDetectorUsers::setParallelMode(int value) { return myDetector->getParallelMode(); } +int slsDetectorUsers::setOverflowMode(int value) { + if(value >= 0) + myDetector->setOverflowMode(value); + return myDetector->getOverflowMode(); +} + int slsDetectorUsers::setAllTrimbits(int val, int id) { return myDetector->setAllTrimbits(val, id); } @@ -399,3 +426,26 @@ int slsDetectorUsers::setFlowControl10G(int i) { int slsDetectorUsers::setTenGigabitEthernet(int i) { return myDetector->enableTenGigabitEthernet(i); } + +int slsDetectorUsers::getNMods() { + return myDetector->getNMods(); +} + +double slsDetectorUsers::setSubFrameExposureTime(double t, bool inseconds){ + int64_t tms = (int64_t)(t * (1E+9)); + if (t < 0) tms = -1; + if(!inseconds) + return myDetector->setSubFrameExposureTime((int64_t)t); + else + return ((1E-9) * (double)myDetector->setSubFrameExposureTime(tms)); +} + +double slsDetectorUsers::setSubFrameExposurePeriod(double t, bool inseconds){ + int64_t tms = (int64_t)(t * (1E+9)); + if (t < 0) tms = -1; + if(!inseconds) + return myDetector->setSubFramePeriod((int64_t)t); + else + return ((1E-9) * (double)myDetector->setSubFramePeriod(tms)); +} + diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h index 9b6c2c297..0b795f356 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h @@ -22,7 +22,7 @@ class multiSlsDetectorCommand; #include -using namespace std; + @@ -100,7 +100,7 @@ class slsDetectorUsers @short useful to define subset of working functions \returns "PSI" or "Dectris" */ - string getDetectorDeveloper(); + std::string getDetectorDeveloper(); @@ -138,20 +138,20 @@ class slsDetectorUsers /** @short returns the default output files path */ - string getFilePath(); + std::string getFilePath(); /** @short sets the default output files path \param s file path \returns file path */ - string setFilePath(string s); + std::string setFilePath(std::string s); /** @short \returns the default output files root name */ - string getFileName(); + std::string getFileName(); /** @short sets the default output files path @@ -159,7 +159,7 @@ class slsDetectorUsers \returns the default output files root name */ - string setFileName(string s); + std::string setFileName(std::string s); /** @short @@ -178,27 +178,27 @@ class slsDetectorUsers @short get flat field corrections file directory \returns flat field correction file directory */ - string getFlatFieldCorrectionDir(); + std::string getFlatFieldCorrectionDir(); /** @short set flat field corrections file directory \param dir flat field correction file directory \returns flat field correction file directory */ - string setFlatFieldCorrectionDir(string dir); + std::string setFlatFieldCorrectionDir(std::string dir); /** @short get flat field corrections file name \returns flat field correction file name */ - string getFlatFieldCorrectionFile(); + std::string getFlatFieldCorrectionFile(); /** @short set flat field correction file \param fname name of the flat field file (or "" if disable) \returns 0 if disable (or file could not be read), >0 otherwise */ - int setFlatFieldCorrectionFile(string fname=""); + int setFlatFieldCorrectionFile(std::string fname=""); @@ -310,52 +310,68 @@ class slsDetectorUsers */ int setThresholdEnergy(int e_eV); + /** + @short set threshold energy with choice to load trimbits (eiger only) + \param e_ev threshold in ev + \param tb 1 loads trimbits, 0 does not load trimbits + \param isettings settings index (-1 uses current setting) + \param id module index (-1 for all) + \returns current threshold value in ev (-1 failed) + */ + int setThresholdEnergy(int e_ev, int tb, int isettings = -1, int id = -1); + /** @short set/get exposure time value \param t time in sn (-1 gets) \param inseconds true if the value is in s, else ns + \param imod module number (-1 for all) \returns timer set value in ns, or s if specified */ - double setExposureTime(double t=-1, bool inseconds=false); + double setExposureTime(double t=-1, bool inseconds=false, int imod = -1); /** @short set/get exposure period \param t time in ns (-1 gets) \param inseconds true if the value is in s, else ns + \param imod module number (-1 for all) \returns timer set value in ns, or s if specified */ - double setExposurePeriod(double t=-1, bool inseconds=false); + double setExposurePeriod(double t=-1, bool inseconds=false, int imod = -1); /** @short set/get delay after trigger \param t time in ns (-1 gets) \param inseconds true if the value is in s, else ns + \param imod module number (-1 for all) \returns timer set value in ns, or s if specified */ - double setDelayAfterTrigger(double t=-1, bool inseconds=false); + double setDelayAfterTrigger(double t=-1, bool inseconds=false, int imod = -1); /** @short set/get number of gates \param t number of gates (-1 gets) + \param imod module number (-1 for all) \returns number of gates */ - int64_t setNumberOfGates(int64_t t=-1); + int64_t setNumberOfGates(int64_t t=-1, int imod = -1); /** @short set/get number of frames i.e. number of exposure per trigger \param t number of frames (-1 gets) + \param imod module number (-1 for all) \returns number of frames */ - int64_t setNumberOfFrames(int64_t t=-1); + int64_t setNumberOfFrames(int64_t t=-1, int imod = -1); /** @short set/get number of cycles i.e. number of triggers \param t number of frames (-1 gets) + \param imod module number (-1 for all) \returns number of frames */ - int64_t setNumberOfCycles(int64_t t=-1); + int64_t setNumberOfCycles(int64_t t=-1, int imod = -1); /** @@ -370,7 +386,7 @@ class slsDetectorUsers \param fname file name \returns OK or FAIL */ - int readConfigurationFile(string const fname); + int readConfigurationFile(std::string const fname); /** @@ -379,20 +395,20 @@ class slsDetectorUsers \returns OK or FAIL */ - int dumpDetectorSetup(string const fname); + int dumpDetectorSetup(std::string const fname); /** @short Loads the detector setup from file \param fname file to read from \returns OK or FAIL */ - int retrieveDetectorSetup(string const fname); + int retrieveDetectorSetup(std::string const fname); /** @short useful for data plotting etc. \returns Mythen, Eiger, Gotthard etc. */ - string getDetectorType(); + std::string getDetectorType(); /** @short sets the mode by which gui requests data from receiver @@ -433,7 +449,7 @@ class slsDetectorUsers \param var optional parameter - unused. */ - virtual void addFrame(double *data, double pos, double i0, double t, string fname, double var); + virtual void addFrame(double *data, double pos, double i0, double t, std::string fname, double var); /** @short finalizes the data set returning the array of angles, values and errors to be used as final data - can be overcome by the user's functions thanks to the virtual property @@ -478,18 +494,18 @@ class slsDetectorUsers /** (for expert users) * Set/Get receiver streaming out ZMQ IP * By default, it is the IP of receiver hostname - * @param ip sets, empty string gets + * @param ip sets, empty std::string gets * @returns receiver streaming out ZMQ IP */ - string setReceiverDataStreamingOutIP(string ip=""); + std::string setReceiverDataStreamingOutIP(std::string ip=""); /** (for expert users) * Set/Get client streaming in ZMQ IP * By default, it is the IP of receiver hostname - * @param i sets, empty string gets + * @param i sets, empty std::string gets * @returns client streaming in ZMQ IP */ - string setClientDataStreamingInIP(string ip=""); + std::string setClientDataStreamingInIP(std::string ip=""); /** get get Module Firmware Version @@ -580,18 +596,18 @@ class slsDetectorUsers \param narg value to be set \param args value to be set \param pos position of detector in multislsdetector list - \returns answer string + \returns answer std::string */ - string putCommand(int narg, char *args[], int pos=-1); + std::string putCommand(int narg, char *args[], int pos=-1); /** @short gets parameters in command interface http://www.psi.ch/detectors/UsersSupportEN/slsDetectorClientHowTo.pdf \param narg value to be set \param args value to be set \param pos position of detector in multislsdetector list - \returns answer string + \returns answer std::string */ - string getCommand(int narg, char *args[], int pos=-1); + std::string getCommand(int narg, char *args[], int pos=-1); /************************************************************************ @@ -612,6 +628,13 @@ class slsDetectorUsers */ int setParallelMode(int value); + /** + * @short show saturated for overflow in subframes in 32 bit mode (eiger only) + * \param value 0 for do not show saturatd, 1 for show saturated (-1 gets) + * \returns overflow mode enable in 32 bit mode + */ + int setOverflowMode(int value); + /** @short sets all trimbits to value (only available for eiger) \param val value to be set (-1 gets) @@ -622,20 +645,20 @@ class slsDetectorUsers /** @short set dac value - \param dac dac as string. can be vcmp_ll, vcmp_lr, vcmp_rl, vcmp_rr, vthreshold, vrf, vrs, vtr, vcall, vcp. others not supported + \param dac dac as std::string. can be vcmp_ll, vcmp_lr, vcmp_rl, vcmp_rr, vthreshold, vrf, vrs, vtr, vcall, vcp. others not supported \param val value to be set (-1 gets) \param id module index (-1 for all) - \returns dac value or -1 (if id=-1 & dac value is different for all modules) or -9999 if dac string does not match + \returns dac value or -1 (if id=-1 & dac value is different for all modules) or -9999 if dac std::string does not match */ - int setDAC(string dac, int val, int id = -1); + int setDAC(std::string dac, int val, int id = -1); /** @short get adc value - \param adc adc as string. can be temp_fpga, temp_fpgaext, temp_10ge, temp_dcdc, temp_sodl, temp_sodr, temp_fpgafl, temp_fpgafr. others not supported + \param adc adc as std::string. can be temp_fpga, temp_fpgaext, temp_10ge, temp_dcdc, temp_sodl, temp_sodr, temp_fpgafl, temp_fpgafr. others not supported \param id module index (-1 for all) - \returns adc value in millidegree Celsius or -1 (if id=-1 & adc value is different for all modules) or -9999 if adc string does not match + \returns adc value in millidegree Celsius or -1 (if id=-1 & adc value is different for all modules) or -9999 if adc std::string does not match */ - int getADC(string adc, int id = -1); + int getADC(std::string adc, int id = -1); /** @short start receiver listening mode @@ -705,35 +728,57 @@ class slsDetectorUsers */ int setTenGigabitEthernet(int i = -1); + /** + * returns total number of detector modules + * @returns the total number of detector modules + */ + int getNMods(); + + /** + * Set sub frame exposure time (only for Eiger) + * @param i sub frame exposure time (-1 gets) + * @param inseconds true if the value is in s, else ns + * @returns sub frame exposure time in ns, or s if specified + */ + double setSubFrameExposureTime(double t=-1, bool inseconds=false); + + /** + * Set sub frame period (only for Eiger) + * @param i sub frame period (-1 gets) + * @param inseconds true if the value is in s, else ns + * @returns sub frame period in ns, or s if specified + */ + double setSubFrameExposurePeriod(double t=-1, bool inseconds=false); + /************************************************************************ STATIC FUNCTIONS *********************************************************************/ - /** @short returns string from run status index + /** @short returns std::string from run status index \param s run status index - \returns string error, waiting, running, data, finished or unknown when wrong index + \returns std::string error, waiting, running, data, finished or unknown when wrong index */ - static string runStatusType(int s){ \ + static std::string runStatusType(int s){ \ switch (s) { \ - case 0: return string("idle"); \ - case 1: return string("error"); \ - case 2: return string("waiting"); \ - case 3: return string("finished"); \ - case 4: return string("data"); \ - case 5: return string("running"); \ - default: return string("unknown"); \ + case 0: return std::string("idle"); \ + case 1: return std::string("error"); \ + case 2: return std::string("waiting"); \ + case 3: return std::string("finished"); \ + case 4: return std::string("data"); \ + case 5: return std::string("running"); \ + default: return std::string("unknown"); \ }}; - /** @short returns detector settings string from index + /** @short returns detector settings std::string from index \param s can be standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain - \returns setting index (-1 unknown string) + \returns setting index (-1 unknown std::string) */ - static int getDetectorSettings(string s){ \ + static int getDetectorSettings(std::string s){ \ if (s=="standard") return 0; \ if (s=="fast") return 1; \ if (s=="highgain") return 2; \ @@ -743,47 +788,48 @@ class slsDetectorUsers if (s=="veryhighgain") return 6; \ return -1; }; - /** @short returns detector settings string from index + /** @short returns detector settings std::string from index \param s settings index \returns standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain, undefined when wrong index */ - static string getDetectorSettings(int s){\ + static std::string getDetectorSettings(int s){\ switch(s) { \ - case 0: return string("standard");\ - case 1: return string("fast");\ - case 2: return string("highgain");\ - case 3: return string("dynamicgain"); \ - case 4: return string("lowgain"); \ - case 5: return string("mediumgain"); \ - case 6: return string("veryhighgain"); \ - default: return string("undefined"); \ + case 0: return std::string("standard");\ + case 1: return std::string("fast");\ + case 2: return std::string("highgain");\ + case 3: return std::string("dynamicgain"); \ + case 4: return std::string("lowgain"); \ + case 5: return std::string("mediumgain"); \ + case 6: return std::string("veryhighgain"); \ + default: return std::string("undefined"); \ }}; /** - @short returns external communication mode string from index + @short returns external communication mode std::string from index \param f index for communication mode \returns auto, trigger, ro_trigger, gating, triggered_gating, unknown when wrong mode */ - static string getTimingMode(int f){ \ + static std::string getTimingMode(int f){ \ switch(f) { \ - case 0: return string( "auto"); \ - case 1: return string("trigger"); \ - case 2: return string("ro_trigger"); \ - case 3: return string("gating"); \ - case 4: return string("triggered_gating"); \ - default: return string( "unknown"); \ + case 0: return std::string( "auto"); \ + case 1: return std::string("trigger"); \ + case 2: return std::string("ro_trigger"); \ + case 3: return std::string("gating"); \ + case 4: return std::string("triggered_gating"); \ + case 5: return std::string("burst_trigger"); \ + default: return std::string( "unknown"); \ } }; /** - @short returns external communication mode string from index + @short returns external communication mode std::string from index \param s index for communication mode \returns auto, trigger, ro_trigger, gating, triggered_gating, unknown when wrong mode */ - static int getTimingMode(string s){ \ + static int getTimingMode(std::string s){ \ if (s== "auto") return 0; \ if (s== "trigger") return 1; \ if (s== "ro_trigger") return 2; \ diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp b/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp index bece17e07..e81ee57f5 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp @@ -9,7 +9,9 @@ #include #include #include //clock() +#include using namespace std; + slsDetectorUtils::slsDetectorUtils() { diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h index a84b71850..1f8b1ab03 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h @@ -31,7 +31,7 @@ extern "C" { #include #include #include -using namespace std; + //#include "slsDetectorActions_Standalone.h" @@ -110,7 +110,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { */ int setReceiverDataStreamingOutPort(int i) { \ if (i >= 0) { \ - ostringstream ss; ss << i; string s = ss.str(); \ + std::ostringstream ss; ss << i; std::string s = ss.str(); \ int prev_streaming = enableDataStreamingFromReceiver(); \ setNetworkParameter(RECEIVER_STREAMING_PORT, s); \ if (prev_streaming) { \ @@ -126,7 +126,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { */ int setClientDataStreamingInPort(int i){ \ if (i >= 0) { \ - ostringstream ss; ss << i; string s = ss.str(); \ + std::ostringstream ss; ss << i; std::string s = ss.str(); \ int prev_streaming = enableDataStreamingToClient(); \ setNetworkParameter(CLIENT_STREAMING_PORT, s); \ if (prev_streaming) { \ @@ -140,7 +140,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { * @param i sets, -1 gets * @returns receiver streaming out ZMQ port */ - string setReceiverDataStreamingOutIP(string ip) { \ + std::string setReceiverDataStreamingOutIP(std::string ip) { \ if (ip.length()) { \ int prev_streaming = enableDataStreamingFromReceiver(); \ setNetworkParameter(RECEIVER_STREAMING_SRC_IP, ip); \ @@ -155,7 +155,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { * @param i sets, -1 gets * @returns client streaming in ZMQ port */ - string setClientDataStreamingInIP(string ip){ \ + std::string setClientDataStreamingInIP(std::string ip){ \ if (ip.length()) { \ int prev_streaming = enableDataStreamingToClient(); \ setNetworkParameter(CLIENT_STREAMING_SRC_IP, ip); \ @@ -199,47 +199,24 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \param pos position in the multi detector structure (is -1 returns concatenated hostnames divided by a +) \returns hostname */ - virtual string getHostname(int pos=-1)=0; + virtual std::string getHostname(int pos=-1)=0; /** sets the detector hostname \param name hostname - \param pos position in the multi detector structure (is -1 expects concatenated hostnames divided by a +) - \returns hostname */ - virtual string setHostname(const char* name, int pos=-1)=0; + virtual void setHostname(const char* name)=0; + /** adds the detector hostnames to the end of the list + \param name hostname + */ + virtual void addMultipleDetectors(const char* name)=0; /** returns the detector type \param pos position in the multi detector structure (is -1 returns type of detector with id -1) \returns type */ - virtual string sgetDetectorsType(int pos=-1)=0; - - /** returns the detector type - \param pos position in the multi detector structure (is -1 returns type of detector with id -1) - \returns type - */ - virtual detectorType setDetectorsType(detectorType t=GET_DETECTOR_TYPE, int pos=-1)=0; - virtual string ssetDetectorsType(detectorType t=GET_DETECTOR_TYPE, int pos=-1)=0; - virtual string ssetDetectorsType(string s, int pos=-1)=0; - - - - /** Gets the detector id (shared memory id) of an slsDetector - \param i position in the multiSlsDetector structure - \return id or -1 if FAIL - */ - virtual int getDetectorId(int i=-1)=0; - - /** Sets the detector id (shared memory id) of an slsDetector in a multiSlsDetector structure - \param ival id to be set - \param i position in the multiSlsDetector structure - \return id or -1 if FAIL (e.g. in case of an slsDetector) - */ - virtual int setDetectorId(int ival, int i=-1){return -1;}; - - + virtual std::string sgetDetectorsType(int pos=-1)=0; /** gets the network parameters (implemented for gotthard) @@ -247,7 +224,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \returns parameter */ - virtual string getNetworkParameter(networkParameter i)=0; + virtual std::string getNetworkParameter(networkParameter i)=0; /** sets the network parameters @@ -257,14 +234,14 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \returns parameter */ - virtual string setNetworkParameter(networkParameter i, string s)=0; + virtual std::string setNetworkParameter(networkParameter i, std::string s)=0; int setFlowControl10G(int i = -1) { - string sret=""; + std::string sret=""; if (i != -1) { - ostringstream o; + std::ostringstream o; o << ((i >= 1) ? 1 : 0); - string sval = o.str(); + std::string sval = o.str(); sret = setNetworkParameter(FLOW_CONTROL_10G, sval); } else sret = getNetworkParameter(FLOW_CONTROL_10G); @@ -284,7 +261,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { checks if the detector(s) are online/offline \returns hostname if offline */ - virtual string checkOnline()=0; + virtual std::string checkOnline()=0; /** Digital test of the modules @@ -308,7 +285,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { /** returns currently the loaded trimfile/settingsfile name */ - virtual string getSettingsFile()=0; + virtual std::string getSettingsFile()=0; /** @@ -318,6 +295,13 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { */ virtual int64_t getTimeLeft(timerIndex index)=0; + /** + * 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 + */ + virtual int setStoragecellStart(int pos=-1)=0; + /** sets the number of trim energies and their value \sa sharedSlsDetector @@ -375,7 +359,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { - int setBadChannelCorrection(string fname, int &nbadtot, int *badchanlist, int off=0); + int setBadChannelCorrection(std::string fname, int &nbadtot, int *badchanlist, int off=0); @@ -398,32 +382,29 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { /** returns the detector trimbit/settings directory */ - virtual char* getSettingsDir()=0; + virtual std::string getSettingsDir()=0; /** sets the detector trimbit/settings directory */ - virtual char* setSettingsDir(string s)=0; + virtual std::string setSettingsDir(std::string s)=0; /** returns the location of the calibration files */ - virtual char* getCalDir()=0; + virtual std::string getCalDir()=0; /** sets the location of the calibration files */ - virtual char* setCalDir(string s)=0; + virtual std::string setCalDir(std::string s)=0; /** Frees the shared memory - should not be used except for debugging*/ - virtual int freeSharedMemory()=0; - - - /** 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) - \returns the actual number of detectors or -1 if it failed (always for slsDetector) - */ - virtual int addSlsDetector(int id, int pos=-1){return -1;}; + virtual void freeSharedMemory()=0; + /** + * Get user details of shared memory + * @returns string with user details + */ + virtual std::string getUserDetails() = 0; /** adds the detector name in position pos \param name of the detector to be added (should already exist in shared memory or at least be online) @@ -433,19 +414,6 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { virtual int addSlsDetector(char* name, int pos=-1){return -1;}; - /** - 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 or -1 if it failed (always for slsDetector) - */ - virtual int removeSlsDetector(int pos=-1){return -1;}; - - /**removes the detector in position pos from the multidetector - \param name is the name of the detector - \returns the actual number of detectors or -1 if it failed (always for slsDetector) - */ - virtual int removeSlsDetector(char* name){return -1;}; - /** Turns off the server - do not use except for debugging! */ @@ -460,7 +428,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \fname file name to load data from \returns OK or FAIL */ - virtual int loadImageToDetector(imageType index,string const fname)=0; + virtual int loadImageToDetector(imageType index,std::string const fname)=0; /** @@ -469,7 +437,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \fname file fname to load data from \returns OK or FAIL */ - virtual int writeCounterBlockFile(string const fname,int startACQ=0)=0; + virtual int writeCounterBlockFile(std::string const fname,int startACQ=0)=0; /** @@ -599,7 +567,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { /** Returns the IP of the last client connecting to the detector */ - virtual string getLastClientIP()=0; + virtual std::string getLastClientIP()=0; @@ -616,13 +584,13 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \param imod module number, -1 means all modules \returns OK or FAIL */ - virtual int loadSettingsFile(string fname, int imod=-1)=0; + virtual int loadSettingsFile(std::string fname, int imod=-1)=0; /** programs FPGA with pof file \param fname file name \returns OK or FAIL */ - virtual int programFPGA(string fname)=0; + virtual int programFPGA(std::string fname)=0; /** resets FPGA \returns OK or FAIL @@ -646,7 +614,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \param imod module number, -1 means all modules \returns OK or FAIL */ - virtual int saveSettingsFile(string fname, int imod=-1)=0; + virtual int saveSettingsFile(std::string fname, int imod=-1)=0; /** sets all the trimbits to a particular value \param val trimbit value @@ -716,7 +684,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \param fname file name \returns OK or FAIL */ - virtual int writeConfigurationFile(string const fname)=0; + virtual int writeConfigurationFile(std::string const fname)=0; void registerGetPositionCallback( double (*func)(void*),void *arg){get_position=func; POarg=arg;}; @@ -740,7 +708,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \returns OK or FAIL */ - int dumpDetectorSetup(string const fname, int level=0); + int dumpDetectorSetup(std::string const fname, int level=0); /** @@ -750,7 +718,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { \returns OK or FAIL */ - int retrieveDetectorSetup(string const fname, int level=0); + int retrieveDetectorSetup(std::string const fname, int level=0); static int dummyAcquisitionFinished(double prog,int status,void* p){cout <<"Acquisition finished callback! " << prog << " " << status << endl; return 0;} static int dummyMeasurementFinished(int im,int findex,void* p){cout <<"Measurement finished callback! " << im << " " << findex << endl; return 0;} @@ -764,12 +732,12 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { /** Checks if the receiver is really online */ - virtual string checkReceiverOnline()=0; + virtual std::string checkReceiverOnline()=0; /** Returns the IP of the last client connecting to the receiver */ - virtual string getReceiverLastClientIP()=0; + virtual std::string getReceiverLastClientIP()=0; /** @@ -777,14 +745,35 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { @param fileName fileDir file directory \returns file dir */ - virtual string setFilePath(string s="")=0; + virtual std::string setFilePath(std::string s="")=0; /** Sets up the file name @param fileName file name \returns file name */ - virtual string setFileName(string s="")=0; + virtual std::string setFileName(std::string s="")=0; + + /** + Sets the max frames per file in receiver + @param f max frames per file + \returns max frames per file in receiver + */ + virtual int setReceiverFramesPerFile(int f = -1) = 0; + + /** + Sets the frames discard policy in receiver + @param f frames discard policy + \returns frames discard policy set in receiver + */ + virtual frameDiscardPolicy setReceiverFramesDiscardPolicy(frameDiscardPolicy f = GET_FRAME_DISCARD_POLICY) = 0; + + /** + Sets the partial frames padding enable in receiver + @param f partial frames padding enable + \returns partial frames padding enable in receiver + */ + virtual int setReceiverPartialFramesPadding(int f = -1) = 0; /** Sets up the file format @@ -796,12 +785,12 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { /** \returns file dir */ - virtual string getFilePath()=0; + virtual std::string getFilePath()=0; /** \returns file name */ - virtual string getFileName()=0; + virtual std::string getFileName()=0; /** \returns file name @@ -935,7 +924,7 @@ virtual int setReceiverSilentMode(int i = -1)=0; @param fname pattern file to open @returns OK/FAIL */ - virtual int setCTBPattern(string fname)=0; + virtual int setCTBPattern(std::string fname)=0; /** Writes a pattern word to the CTB @@ -1014,6 +1003,14 @@ virtual int setReceiverSilentMode(int i = -1)=0; virtual bool isAcquireReady() = 0; + /** + * Check version compatibility with detector/receiver software + * (if hostname/rx_hostname has been set/ sockets created) + * \param p port type control port or data (receiver) port + * \returns FAIL for incompatibility, OK for compatibility + */ + virtual int checkVersionCompatibility(portType t) = 0; + protected: diff --git a/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.h b/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.h index 1056c9879..b94f6366f 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.h @@ -12,7 +12,7 @@ #include #include -using namespace std; +; /** @short class handling the data file I/O flags */ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/angCalLogClass.h b/slsDetectorSoftware/slsDetectorAnalysis/angCalLogClass.h index fdaeb308a..b366b58a1 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/angCalLogClass.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/angCalLogClass.h @@ -13,7 +13,7 @@ #include "sls_detector_defs.h" #endif -using namespace std; +; class angCalLogClass { @@ -27,7 +27,7 @@ class angCalLogClass { char *argv[2]; \ argv[0]=cmd; \ sprintf(cmd,"_%d.angcal",det->getFileIndex()); \ - outfile.open(string(det->getFilePath()+string("/")+det->getFileName()+string(cmd)).c_str()); \ + outfile.open( std::string(det->getFilePath()+ std::string("/")+det->getFileName()+ std::string(cmd)).c_str()); \ outfile.precision(8); myDet=new slsDetectorCommand(det); \ if (outfile.is_open()) { \ @@ -44,12 +44,12 @@ class angCalLogClass { #endif - int addStep(double pos, string fname) {std::cout.precision(5); outfile << pos << " " << fname << endl; return 0;}; + int addStep(double pos, std::string fname) {std::cout.precision(5); outfile << pos << " " << fname << endl; return 0;}; // - int readHeader(ifstream &infile, int &maxmod, int &nmod, int &chanspermod, char *angconvfile, double &globaloff, double &fineoff, int &angdir, char *ffdir, char *fffile, char *badfile ) { \ + int readHeader(std::ifstream &infile, int &maxmod, int &nmod, int &chanspermod, char *angconvfile, double &globaloff, double &fineoff, int &angdir, char *ffdir, char *fffile, char *badfile ) { \ nmod=0; chanspermod=0; globaloff=0; fineoff=0; angdir=1; \ strcpy(angconvfile,"none"); strcpy(ffdir,"none"); strcpy(fffile,"none"); strcpy(badfile,"none"); \ char line[1000], myvar[100], myarg[100]; \ @@ -57,14 +57,14 @@ class angCalLogClass { for (int iv=0; iv= 360./getBinSize(); \param mp already merged postions @@ -250,19 +250,19 @@ class angularConversion : public virtual slsDetectorBase, public angularConversi \returns angular conversion flag */ - int setAngularConversionFile(string fname); + int setAngularConversionFile(std::string fname); /** returns the angular conversion file */ - string getAngularConversionFile(){if (setAngularCorrectionMask()) return string(angConvFile); else return string("none");}; + std::string getAngularConversionFile(){if (setAngularCorrectionMask()) return std::string(angConvFile); else return std::string("none");}; /** reads teh angular conversion file for the (multi)detector and writes it to shared memory */ - virtual int readAngularConversionFile(string fname="")=0; + virtual int readAngularConversionFile(std::string fname="")=0; diff --git a/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.h b/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.h index 4ecd9d57d..ec1b47d6b 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.h @@ -19,7 +19,7 @@ class angleConversionConstant; -using namespace std; +; /** @short Angular conversion constants needed for a detector module @@ -47,7 +47,7 @@ class angularConversionStatic - //virtual int readAngularConversion(string fname)=0; + //virtual int readAngularConversion(std::string fname)=0; @@ -60,7 +60,7 @@ class angularConversionStatic \param angOff pointer to array of angleConversionConstants \returns OK or FAIL */ - static int readAngularConversion(string fname, int nmod, angleConversionConstant *angOff); + static int readAngularConversion(std::string fname, int nmod, angleConversionConstant *angOff); /** reads an angular conversion file @@ -70,7 +70,7 @@ class angularConversionStatic \returns OK or FAIL */ - static int readAngularConversion(ifstream& ifs, int nmod, angleConversionConstant *angOff); + static int readAngularConversion(std::ifstream& ifs, int nmod, angleConversionConstant *angOff); /** writes an angular conversion file \param fname file to be written @@ -78,7 +78,7 @@ class angularConversionStatic \param angOff pointer to array of angleConversionConstants \returns OK or FAIL */ - static int writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff); + static int writeAngularConversion(std::string fname, int nmod, angleConversionConstant *angOff); /** writes an angular conversion file @@ -87,7 +87,7 @@ class angularConversionStatic \param angOff pointer to array of angleConversionConstants \returns OK or FAIL */ - static int writeAngularConversion(ofstream& ofs, int nmod, angleConversionConstant *angOff); + static int writeAngularConversion(std::ofstream& ofs, int nmod, angleConversionConstant *angOff); /** sets the arrays of the merged data to 0. NB The array should be created with size nbins >= 360./getBinSize(); diff --git a/slsDetectorSoftware/slsDetectorAnalysis/badChannelCorrections.h b/slsDetectorSoftware/slsDetectorAnalysis/badChannelCorrections.h index 72e6d3590..5cc290e1c 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/badChannelCorrections.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/badChannelCorrections.h @@ -7,30 +7,30 @@ #include #include -using namespace std; +// class badChannelCorrections{ public: - static int readBadChannelCorrectionFile(string fname, int &nbad, int *badlist){ ifstream infile(fname.c_str()); int nb=-1; if (infile.is_open()) {nb=readBadChannelCorrectionFile(infile,nbad,badlist); infile.close();}; return nb;}; + static int readBadChannelCorrectionFile(std::string fname, int &nbad, int *badlist){ std::ifstream infile(fname.c_str()); int nb=-1; if (infile.is_open()) {nb=readBadChannelCorrectionFile(infile,nbad,badlist); infile.close();}; return nb;}; - static int readBadChannelCorrectionFile(ifstream &infile, int &nbad, int *badlist, int moff=0){ \ + static int readBadChannelCorrectionFile(std::ifstream &infile, int &nbad, int *badlist, int moff=0){ \ int interrupt=0; \ int ich; \ int chmin,chmax; \ - string str; \ + std::string str; \ nbad=0; \ while (infile.good() and interrupt==0) { \ getline(infile,str); \ - istringstream ssstr; \ + std::istringstream ssstr; \ ssstr.str(str); \ if (ssstr.bad() || ssstr.fail() || infile.eof()) { \ interrupt=1; \ break; \ } \ - if (str.find('-')!=string::npos) { \ + if (str.find('-')!=std::string::npos) { \ ssstr >> chmin ; \ ssstr.str(str.substr(str.find('-')+1,str.size())); \ ssstr >> chmax; \ @@ -47,7 +47,7 @@ class badChannelCorrections{ return nbad; }; - static int setBadChannelCorrection(ifstream &infile, int &nbad, int *badlist, int moff){ \ + static int setBadChannelCorrection(std::ifstream &infile, int &nbad, int *badlist, int moff){ \ int retval=readBadChannelCorrectionFile(infile,nbad,badlist); \ for (int ich=0; ichgetFileIndex()); \ - outfile.open(string(det->getFilePath()+string("/")+det->getFileName()+string(cmd)).c_str()); \ + outfile.open(std::string(det->getFilePath()+std::string("/")+det->getFileName()+std::string(cmd)).c_str()); \ myDet=new slsDetectorCommand(det); \ strcpy(cmd,vars[0]); \ outfile << cmd << " " << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ @@ -58,12 +58,12 @@ class enCalLogClass { #endif - int addStep(double threshold, string fname) {outfile << threshold << " " << fname << endl; return 0;}; + int addStep(double threshold, std::string fname) {outfile << threshold << " " << fname << endl; return 0;}; // - int readHeader(ifstream &infile, char *settings, int &nmod, int &chanspermod, int *mods ) { \ + int readHeader(std::ifstream &infile, char *settings, int &nmod, int &chanspermod, int *mods ) { \ nmod=0; strcpy(settings,"unknown"); chanspermod=0; \ char line[1000],myarg[100]; \ int dum; \ @@ -75,9 +75,9 @@ class enCalLogClass { break; \ case 1: \ sscanf(line,"type %s", myarg); \ - if (string(myarg).find("Mythen")!=string::npos) \ + if (std::string(myarg).find("Mythen")!=std::string::npos) \ chanspermod=1280; \ - else if (string(myarg).find("Gotthard")!=string::npos) \ + else if (std::string(myarg).find("Gotthard")!=std::string::npos) \ chanspermod=1280; \ else \ chanspermod=65535; \ @@ -101,7 +101,7 @@ class enCalLogClass { return 0; \ }; - int getStep(ifstream &infile, double &threshold, char *datafname){ \ + int getStep(std::ifstream &infile, double &threshold, char *datafname){ \ char line[1000]; \ float v; infile.getline(line,1000); \ @@ -122,7 +122,7 @@ class enCalLogClass { #ifndef MYROOT slsDetectorCommand *myDet; #endif - ofstream outfile; + std::ofstream outfile; char vars[4][100]; }; diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyCalibration.h b/slsDetectorSoftware/slsDetectorAnalysis/energyCalibration.h index 8741efbf9..1d954e0fe 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/energyCalibration.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyCalibration.h @@ -16,7 +16,7 @@ class TGraphErrors; #endif -using namespace std; + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp index cb709058d..91a555caa 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp @@ -149,8 +149,8 @@ slsDetectorDefs::sls_detector_module* energyConversion::interpolateTrim(detector enum eiger_DacIndex{SVP,VTR,VRF,VRS,SVN,VTGSTV,VCMP_LL,VCMP_LR,CAL,VCMP_RL,RXB_RB,RXB_LB,VCMP_RR,VCP,VCN,VIS}; //Copy other dacs - int num_dacs_to_copy = 9; - int dacs_to_copy[] = {SVP,VTR,SVN,VTGSTV,CAL,RXB_RB,RXB_LB,VCN,VIS}; + int dacs_to_copy[] = {SVP,VTR,SVN,VTGSTV,RXB_RB,RXB_LB,VCN,VIS}; + int num_dacs_to_copy = sizeof(dacs_to_copy) / sizeof(dacs_to_copy[0]); for (int i = 0; i < num_dacs_to_copy; ++i) { if(a->dacs[dacs_to_copy[i]] != b->dacs[dacs_to_copy[i]]) { deleteModule(myMod); @@ -159,9 +159,19 @@ slsDetectorDefs::sls_detector_module* energyConversion::interpolateTrim(detector myMod->dacs[dacs_to_copy[i]] = a->dacs[dacs_to_copy[i]]; } + + //Copy irrelevant dacs (without failing): CAL + if (a->dacs[CAL] != b->dacs[CAL]) { + printf("Warning: DAC CAL differs in both energies (%d, %d)! ", + a->dacs[CAL], b->dacs[CAL]); + printf("Taking first: %d\n", a->dacs[CAL]); + } + myMod->dacs[CAL] = a->dacs[CAL]; + + //Interpolate vrf, vcmp, vcp - int num_dacs_to_interpolate = 7; int dacs_to_interpolate[] = {VRF,VCMP_LL,VCMP_LR,VCMP_RL,VCMP_RR,VCP, VRS}; + int num_dacs_to_interpolate = sizeof(dacs_to_interpolate) / sizeof(dacs_to_interpolate[0]); for (int i = 0; i < num_dacs_to_interpolate; ++i) { myMod->dacs[dacs_to_interpolate[i]] = linearInterpolation(energy, e1, e2, a->dacs[dacs_to_interpolate[i]], b->dacs[dacs_to_interpolate[i]]); diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h index 0e36e837c..518c75c34 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h @@ -13,7 +13,7 @@ #include #include -using namespace std; + /** @short class handling the energy calibration and trim files IO */ @@ -39,7 +39,7 @@ class energyConversion \returns OK if successful, else FAIL or -1 */ - static int readCalibrationFile(string fname, double &gain, double &offset); + static int readCalibrationFile(std::string fname, double &gain, double &offset); /** writes a calibration file @@ -48,7 +48,7 @@ class energyConversion \param offset \returns OK if successful, else FAIL or -1 */ - static int writeCalibrationFile(string fname, double gain, double offset); + static int writeCalibrationFile(std::string fname, double gain, double offset); /** reads a calibration file @@ -57,7 +57,7 @@ class energyConversion \param offset reference to the offset variable \returns OK if successful, else FAIL or -1 */ - static int readCalibrationFile(string fname, int *gain, int *offset); + static int readCalibrationFile(std::string fname, int *gain, int *offset); /** writes a calibration file @@ -66,7 +66,7 @@ class energyConversion \param offset reference to the offset variable \returns OK if successful, else FAIL or -1 */ - static int writeCalibrationFile(string fname, int *gain, int *offset); + static int writeCalibrationFile(std::string fname, int *gain, int *offset); @@ -108,7 +108,7 @@ class energyConversion \returns the pointer to myMod or NULL if reading the file failed */ - sls_detector_module* readSettingsFile(string fname, detectorType myDetectorType, int& iodelay, int& tau, sls_detector_module* myMod=NULL, int tb=1); + sls_detector_module* readSettingsFile(std::string fname, detectorType myDetectorType, int& iodelay, int& tau, sls_detector_module* myMod=NULL, int tb=1); /** writes a trim/settings file @@ -121,7 +121,7 @@ class energyConversion \sa ::sls_detector_module mythenDetector::writeSettingsFile(string, sls_detector_module) */ - int writeSettingsFile(string fname, detectorType myDetectorType, sls_detector_module mod, int iodelay, int tau); + int writeSettingsFile(std::string fname, detectorType myDetectorType, sls_detector_module mod, int iodelay, int tau); /** allocates the momery for a detector module structure \param myDetectorType detector type (needed for number of channels, chips, dacs etc.) diff --git a/slsDetectorSoftware/slsDetectorAnalysis/fileIO.cpp b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.cpp index c1e0d06b7..051094145 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/fileIO.cpp +++ b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.cpp @@ -1,6 +1,6 @@ #include "fileIO.h" - +using namespace std; /* I/O */ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/fileIO.h b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.h index 7d074275e..2bc416991 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/fileIO.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.h @@ -14,7 +14,7 @@ #include #include -using namespace std; +// /** @short class handling the data file I/O flags */ @@ -50,14 +50,14 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { using fileIOStatic::writeDataFile; using fileIOStatic::createFileName; - int getFileIndexFromFileName(string fname){ + int getFileIndexFromFileName(std::string fname){ int ret; pthread_mutex_lock(&mf); ret=fileIOStatic::getFileIndexFromFileName(fname); pthread_mutex_unlock(&mf); return ret; }; - int getIndicesFromFileName(string fname, int &index){ + int getIndicesFromFileName(std::string fname, int &index){ int ret; pthread_mutex_lock(&mf); ret=fileIOStatic::getIndicesFromFileName(fname,index); @@ -67,7 +67,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { - int getVariablesFromFileName(string fname, int &index, int &p_index, double &sv0, double &sv1){ + int getVariablesFromFileName(std::string fname, int &index, int &p_index, double &sv0, double &sv1){ int ret; pthread_mutex_lock(&mf); @@ -76,7 +76,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { return ret; }; - int getVariablesFromFileName(string fname, int &index, int &f_index, int &p_index, double &sv0, double &sv1, int &detindex){ + int getVariablesFromFileName(std::string fname, int &index, int &f_index, int &p_index, double &sv0, double &sv1, int &detindex){ int ret; @@ -91,11 +91,11 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param s file path \return actual file path */ - virtual string setFilePath(string s) { + virtual std::string setFilePath(std::string s) { pthread_mutex_lock(&mf); sprintf(filePath, s.c_str()); pthread_mutex_unlock(&mf); - return string(filePath); + return std::string(filePath); }; /** @@ -103,11 +103,11 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param s file name to be set \returns actual file name */ - virtual string setFileName(string s) { + virtual std::string setFileName(std::string s) { pthread_mutex_lock(&mf); sprintf(fileName, s.c_str()); pthread_mutex_unlock(&mf); - return string(fileName);}; + return std::string(fileName);}; /** sets the default output file index @@ -160,14 +160,22 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param i detector index to be set \returns actual detector index */ - virtual int setDetectorIndex(int i) {detIndex=i;return detIndex;}; + virtual int setDetectorIndex(int i) { + pthread_mutex_lock(&mf); + detIndex=i; + pthread_mutex_unlock(&mf); + return detIndex;}; /** sets the default file format \param i file format to be set \returns actual file frame format */ - virtual fileFormat setFileFormat(int i) {*fileFormatType=(fileFormat)i; return *fileFormatType;}; + virtual fileFormat setFileFormat(int i) { + pthread_mutex_lock(&mf); + *fileFormatType=(fileFormat)i; + pthread_mutex_unlock(&mf); + return *fileFormatType; }; @@ -175,11 +183,11 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \returns the output files path */ - virtual string getFilePath() {return string(filePath);}; + virtual std::string getFilePath() {return std::string(filePath);}; /** \returns the output files root name */ - virtual string getFileName() {return string(fileName);}; + virtual std::string getFileName() {return std::string(fileName);}; /** \returns the output file index @@ -212,9 +220,9 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { virtual fileFormat getFileFormat() {return *fileFormatType;}; - string createFileName(); + std::string createFileName(); - string createReceiverFilePrefix(); + std::string createReceiverFilePrefix(); /** @@ -227,7 +235,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \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 */ - virtual int writeDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1); + virtual int writeDataFile(std::string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1); /** @@ -244,7 +252,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \returns OK or FAIL if it could not write the file or data=NULL */ - virtual int writeDataFile(ofstream &outfile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1, int offset=0); + virtual int writeDataFile(std::ofstream &outfile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1, int offset=0); /** @@ -253,7 +261,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param data array of data values \returns OK or FAIL if it could not write the file or data=NULL */ - virtual int writeDataFile(string fname, int *data); + virtual int writeDataFile(std::string fname, int *data); virtual int writeDataFile(void *data, int iframe=-1); @@ -266,7 +274,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param offset start channel number \returns OK or FAIL if it could not write the file or data=NULL */ - virtual int writeDataFile(ofstream &outfile, int *data, int offset=0); + virtual int writeDataFile(std::ofstream &outfile, int *data, int offset=0); @@ -276,7 +284,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param data array of data values \returns OK or FAIL if it could not write the file or data=NULL */ - virtual int writeDataFile(string fname, short int *data); + virtual int writeDataFile(std::string fname, short int *data); @@ -291,7 +299,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param offset start channel number \returns OK or FAIL if it could not write the file or data=NULL */ - virtual int writeDataFile(ofstream &outfile, short int *data, int offset=0); + virtual int writeDataFile(std::ofstream &outfile, short int *data, int offset=0); /** @@ -304,7 +312,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param dataformat format of the data: can be 'i' integer or 'f' double (default) \returns OK or FAIL if it could not read the file or data=NULL */ - virtual int readDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); + virtual int readDataFile(std::string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); /** reads a data file @@ -316,7 +324,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param offset start channel number to be expected \returns OK or FAIL if it could not read the file or data=NULL */ - int readDataFile(ifstream& infile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0); + int readDataFile(std::ifstream& infile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0); /** reads a raw data file @@ -324,7 +332,7 @@ class fileIO : public fileIOStatic, public virtual slsDetectorBase { \param data array of data values \returns OK or FAIL if it could not read the file or data=NULL yes */ - virtual int readDataFile(string fname, int *data); + virtual int readDataFile(std::string fname, int *data); /** reads a raw data file @@ -333,7 +341,7 @@ yes */ \param offset first channel number to be expected \returns OK or FAIL if it could not read the file or data=NULL */ - int readDataFile(ifstream &infile, int *data, int offset=0); + int readDataFile(std::ifstream &infile, int *data, int offset=0); /** @@ -342,7 +350,7 @@ yes */ \param data array of data values \returns OK or FAIL if it could not read the file or data=NULL */ - virtual int readDataFile(string fname, short int *data); + virtual int readDataFile(std::string fname, short int *data); /** reads a short int raw data file \param infile input file stream @@ -350,12 +358,12 @@ yes */ \param offset first channel number to be expected \returns OK or FAIL if it could not read the file or data=NULL */ - int readDataFile(ifstream &infile, short int *data, int offset=0); + int readDataFile(std::ifstream &infile, short int *data, int offset=0); virtual int getDataBytes ( )=0; friend class slsDetector; - string getCurrentFileName(){return currentFileName;}; + std::string getCurrentFileName(){return currentFileName;}; protected: @@ -368,12 +376,12 @@ yes */ void incrementDetectorIndex() { (detIndex)++; }; - string getCurrentReceiverFilePrefix(){return currentReceiverFilePrefix;}; + std::string getCurrentReceiverFilePrefix(){return currentReceiverFilePrefix;}; - string currentFileName; + std::string currentFileName; - string currentReceiverFilePrefix; + std::string currentReceiverFilePrefix; /** output directory */ @@ -397,7 +405,7 @@ yes */ FILE *filefd; - ofstream fstream; + std::ofstream fstream; int nframes; // int fformat; diff --git a/slsDetectorSoftware/slsDetectorAnalysis/fileIOStatic.h b/slsDetectorSoftware/slsDetectorAnalysis/fileIOStatic.h index ae909b06b..c76800791 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/fileIOStatic.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/fileIOStatic.h @@ -14,8 +14,11 @@ #define MYROOT #endif +using std::endl; +using std::cout; + #include "sls_detector_defs.h" -using namespace std; +// /** @short class handling the data file I/O flags */ @@ -56,11 +59,11 @@ class fileIOStatic { \param detindex detector id \returns file name without extension */ - static string createFileName(char *filepath, char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos, int findex, int frameindex=-1, int detindex=-1){ \ - ostringstream osfn; \ + static std::string createFileName(char *filepath, char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos, int findex, int frameindex=-1, int detindex=-1){ \ + std::ostringstream osfn; \ osfn << filepath << "/" << filename; \ - if ( aMask& (1 << (slsDetectorDefs::MAX_ACTIONS))) osfn << "_S" << fixed << setprecision(prec0) << sv0; \ - if (aMask & (1 << (slsDetectorDefs::MAX_ACTIONS+1))) osfn << "_s" << fixed << setprecision(prec1) << sv1; \ + if ( aMask& (1 << (slsDetectorDefs::MAX_ACTIONS))) osfn << "_S" << std::fixed << std::setprecision(prec0) << sv0; \ + if (aMask & (1 << (slsDetectorDefs::MAX_ACTIONS+1))) osfn << "_s" << std::fixed << std::setprecision(prec1) << sv1; \ if (pindex>0 && pindex<=npos) osfn << "_p" << pindex; \ if(detindex>=0) osfn << "_d"<< detindex; \ if(frameindex>=0) osfn << "_f" << frameindex; \ @@ -86,11 +89,11 @@ class fileIOStatic { \param detindex detector id \returns file name without extension */ - static string createReceiverFilePrefix(char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos,int detindex=-1){ \ - ostringstream osfn; \ + static std::string createReceiverFilePrefix(char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos,int detindex=-1){ \ + std::ostringstream osfn; \ osfn << filename; \ - if ( aMask& (1 << (slsDetectorDefs::MAX_ACTIONS))) osfn << "_S" << fixed << setprecision(prec0) << sv0; \ - if (aMask & (1 << (slsDetectorDefs::MAX_ACTIONS+1))) osfn << "_s" << fixed << setprecision(prec1) << sv1; \ + if ( aMask& (1 << (slsDetectorDefs::MAX_ACTIONS))) osfn << "_S" << std::fixed << std::setprecision(prec0) << sv0; \ + if (aMask & (1 << (slsDetectorDefs::MAX_ACTIONS+1))) osfn << "_s" << std::fixed << std::setprecision(prec1) << sv1; \ if (pindex>0 && pindex<=npos) osfn << "_p" << pindex; \ if(detindex!=-1) osfn << "_d"<< detindex; \ return osfn.str(); \ @@ -101,13 +104,13 @@ class fileIOStatic { \param fname file name \returns file index */ - static int getFileIndexFromFileName(string fname){ \ + static int getFileIndexFromFileName(std::string fname){ \ int i; \ size_t dot=fname.rfind("."); \ - if (dot==string::npos) \ + if (dot==std::string::npos) \ return -1; \ size_t uscore=fname.rfind("_"); \ - if (uscore==string::npos) return -1; \ + if (uscore==std::string::npos) return -1; \ if (sscanf( fname.substr(uscore+1,dot-uscore-1).c_str(),"%d",&i)) return i; \ cout << "******************************** cannot parse file index" << endl; \ return 0; \ @@ -118,11 +121,11 @@ class fileIOStatic { \param index reference to index \returns frame index */ - static int getIndicesFromFileName(string fname,int &index){ \ + static int getIndicesFromFileName(std::string fname,int &index){ \ int i; \ - string s; \ + std::string s; \ size_t uscore=fname.rfind("_"); \ - if (uscore==string::npos) return -1; \ + if (uscore==std::string::npos) return -1; \ s=fname; \ if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)){ \ index=i; \ @@ -146,16 +149,16 @@ class fileIOStatic { \param sv1 reference to scan variable 1 \returns file index */ - static int getVariablesFromFileName(string fname, int &index, int &p_index, double &sv0, double &sv1) { \ + static int getVariablesFromFileName(std::string fname, int &index, int &p_index, double &sv0, double &sv1) { \ int i; \ double f; \ - string s; \ + std::string s; \ index=-1; \ p_index=-1; \ sv0=-1; \ sv1=-1; \ size_t uscore=fname.rfind("_"); \ - if (uscore==string::npos) return -1; \ + if (uscore==std::string::npos) return -1; \ s=fname; \ if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)) { \ index=i; \ @@ -201,16 +204,16 @@ class fileIOStatic { \param detindex reference to detector id \returns file index */ - static int getVariablesFromFileName(string fname, int &index, int &f_index, int &p_index, double &sv0, double &sv1, int &detindex) { \ + static int getVariablesFromFileName(std::string fname, int &index, int &f_index, int &p_index, double &sv0, double &sv1, int &detindex) { \ int i; \ double f; \ - string s; \ + std::string s; \ index=-1; \ p_index=-1; \ sv0=-1; \ sv1=-1; \ size_t uscore=fname.rfind("_"); \ - if (uscore==string::npos) return -1; \ + if (uscore==std::string::npos) return -1; \ s=fname; \ if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)) { \ index=i; \ @@ -262,7 +265,7 @@ class fileIOStatic { \param detindex reference to detector id \returns file name */ - static int verifySameFrame(string fname, int index, int f_index, int p_index, double sv0, double sv1, int detindex) { \ + static int verifySameFrame(std::string fname, int index, int f_index, int p_index, double sv0, double sv1, int detindex) { \ int new_index=-1; int new_f_index=-1; int new_p_index=-1; @@ -283,10 +286,10 @@ class fileIOStatic { \param fname complete file name prefix \returns file name */ - static string getNameFromReceiverFilePrefix(string fname) { \ + static std::string getNameFromReceiverFilePrefix(std::string fname) { \ int i; \ double f; \ - string s; \ + std::string s; \ s=fname; \ size_t uscore=s.rfind("_"); \ if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"d%d",&i)) \ @@ -313,14 +316,14 @@ class fileIOStatic { \param fname complete file name \returns file name without file name prefix, detector index or extension */ - static string getReceiverFileNameToConcatenate(string fname) { \ + static std::string getReceiverFileNameToConcatenate(std::string fname) { \ int i;double f; \ - string s=fname; \ + std::string s=fname; \ if(fname.empty()) return fname; \ size_t dot=s.find("."); size_t uscore=s.rfind("_"); \ - if (uscore==string::npos) return "??"; \ + if (uscore==std::string::npos) return "??"; \ if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)) \ s=fname.substr(0,uscore); \ uscore=s.rfind("_"); \ @@ -358,13 +361,13 @@ class fileIOStatic { */ - static int writeDataFile(string fname, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'){ \ - ofstream outfile; \ + static int writeDataFile(std::string fname, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'){ \ + std::ofstream outfile; \ if (data==NULL) { \ cout << "No data to write!" << endl; \ return slsDetectorDefs::FAIL; \ } \ - outfile.open (fname.c_str(),ios_base::out); \ + outfile.open (fname.c_str(),std::ios_base::out); \ if (outfile.is_open()) { \ writeDataFile(outfile, nch, data, err, ang, dataformat, 0); \ outfile.close(); \ @@ -389,7 +392,7 @@ class fileIOStatic { \param offset start channel number \returns OK or FAIL if it could not write the file or data=NULL */ - static int writeDataFile(ofstream &outfile, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0){ + static int writeDataFile(std::ofstream &outfile, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0){ int idata; \ if (data==NULL || nch==0) { \ cout << "No data to write!" << endl; \ @@ -426,10 +429,10 @@ class fileIOStatic { \param data array of data values \returns OK or FAIL if it could not write the file or data=NULL */ - static int writeDataFile(string fname,int nch, int *data){ \ - ofstream outfile; \ + static int writeDataFile(std::string fname,int nch, int *data){ \ + std::ofstream outfile; \ if (data==NULL) return slsDetectorDefs::FAIL; \ - outfile.open (fname.c_str(),ios_base::out); \ + outfile.open (fname.c_str(),std::ios_base::out); \ if (outfile.is_open()) { \ writeDataFile(outfile, nch, data, 0); \ outfile.close(); \ @@ -447,7 +450,7 @@ class fileIOStatic { \param data array of data values \returns OK or FAIL if it could not write the file or data=NULL */ - static int writeBinaryDataFile(string fname, size_t nbytes, void *data){ \ + static int writeBinaryDataFile(std::string fname, size_t nbytes, void *data){ \ FILE *sfilefd; \ if (data==NULL) return slsDetectorDefs::FAIL; \ sfilefd = fopen(fname.c_str(), "w"); \ @@ -473,7 +476,7 @@ class fileIOStatic { \param offset start channel number \returns OK or FAIL if it could not write the file or data=NULL */ - static int writeDataFile(ofstream &outfile,int nch, int *data, int offset=0){ \ + static int writeDataFile(std::ofstream &outfile,int nch, int *data, int offset=0){ \ if (data==NULL) return slsDetectorDefs::FAIL; \ for (int ichan=0; ichan> ichan >> fdata; \ if (ssstr.fail() || ssstr.bad()) { \ @@ -617,11 +620,11 @@ class fileIOStatic { \param nch number of channels \returns OK or FAIL if it could not read the file or data=NULL */ - static int readDataFile(string fname, int *data, int nch) { \ - ifstream infile; \ + static int readDataFile(std::string fname, int *data, int nch) { \ + std::ifstream infile; \ int iline=0; \ - string str; \ - infile.open(fname.c_str(), ios_base::in); \ + std::string str; \ + infile.open(fname.c_str(), std::ios_base::in); \ if (infile.is_open()) { \ iline=readDataFile(infile, data, nch, 0); \ infile.close(); \ @@ -641,13 +644,13 @@ class fileIOStatic { \param offset start channel value \returns OK or FAIL if it could not read the file or data=NULL */ - static int readDataFile(ifstream &infile, int *data, int nch, int offset) { \ + static int readDataFile(std::ifstream &infile, int *data, int nch, int offset) { \ int ichan, idata, iline=0; \ int interrupt=0; \ - string str; \ + std::string str; \ while (infile.good() and interrupt==0) { \ getline(infile,str); \ - istringstream ssstr(str); \ + std::istringstream ssstr(str); \ ssstr >> ichan >> idata; \ if (ssstr.fail() || ssstr.bad()) { \ interrupt=1; \ @@ -673,11 +676,11 @@ class fileIOStatic { \param nch number of channels \returns OK or FAIL if it could not read the file or data=NULL */ - static int readDataFile(string fname, short int *data, int nch){ \ - ifstream infile; \ + static int readDataFile(std::string fname, short int *data, int nch){ \ + std::ifstream infile; \ int iline=0; \ - string str; \ - infile.open(fname.c_str(), ios_base::in); \ + std::string str; \ + infile.open(fname.c_str(), std::ios_base::in); \ if (infile.is_open()) { \ iline=readDataFile(infile, data, nch, 0); \ infile.close(); \ @@ -696,14 +699,14 @@ class fileIOStatic { \param offset start channel value \returns OK or FAIL if it could not read the file or data=NULL */ - static int readDataFile(ifstream &infile, short int *data, int nch, int offset) { \ + static int readDataFile(std::ifstream &infile, short int *data, int nch, int offset) { \ int ichan, iline=0; \ short int idata; \ int interrupt=0; \ - string str; \ + std::string str; \ while (infile.good() and interrupt==0) { \ getline(infile,str); \ - istringstream ssstr(str); \ + std::istringstream ssstr(str); \ ssstr >> ichan >> idata; \ if (ssstr.fail() || ssstr.bad()) { \ interrupt=1; \ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/movingStat.h b/slsDetectorSoftware/slsDetectorAnalysis/movingStat.h index d6a2b2e33..f81fab696 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/movingStat.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/movingStat.h @@ -16,7 +16,7 @@ #include #include -using namespace std; +; typedef double double32_t; diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.cpp b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.cpp index f25eef9bc..86f9faaf8 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.cpp +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.cpp @@ -8,7 +8,7 @@ #endif #include - +using namespace std; //#define VERBOSE static void* startProcessData(void *n){ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.h index 00c5f914b..7903688dd 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.h @@ -7,7 +7,6 @@ #include "angularConversion.h" #include "badChannelCorrections.h" #include "fileIO.h" -#include #include #include @@ -22,8 +21,7 @@ class postProcessingFuncs; - -using namespace std; +// #define MAX_BADCHANS 20000 @@ -77,7 +75,7 @@ class postProcessing : public angularConversion, public fileIO, public badChanne \param fname file with bad channel list ("" disable) \returns 0 if bad channel disabled, >0 otherwise */ - virtual int setBadChannelCorrection(string fname="")=0; + virtual int setBadChannelCorrection(std::string fname="")=0; /** @@ -87,7 +85,7 @@ class postProcessing : public angularConversion, public fileIO, public badChanne \param badlist array of badchannels \returns 0 if bad channel disabled, >0 otherwise */ - virtual int setBadChannelCorrection(string fname, int &nbad, int *badlist, int off=0)=0; + virtual int setBadChannelCorrection(std::string fname, int &nbad, int *badlist, int off=0)=0; using badChannelCorrections::setBadChannelCorrection; /** @@ -118,26 +116,26 @@ class postProcessing : public angularConversion, public fileIO, public badChanne /** returns the bad channel list file */ - string getBadChannelCorrectionFile() {if ((*correctionMask)&(1<< DISCARD_BAD_CHANNELS)) return string(badChanFile); else return string("none");}; + std::string getBadChannelCorrectionFile() {if ((*correctionMask)&(1<< DISCARD_BAD_CHANNELS)) return std::string(badChanFile); else return std::string("none");}; /** get flat field corrections file directory \returns flat field correction file directory */ - string getFlatFieldCorrectionDir(){return string(flatFieldDir);}; + std::string getFlatFieldCorrectionDir(){return std::string(flatFieldDir);}; /** set flat field corrections file directory \param flat field correction file directory \returns flat field correction file directory */ - string setFlatFieldCorrectionDir(string dir){strcpy(flatFieldDir,dir.c_str()); return string(flatFieldDir);}; + std::string setFlatFieldCorrectionDir(std::string dir){strcpy(flatFieldDir,dir.c_str()); return std::string(flatFieldDir);}; /** get flat field corrections file name \returns flat field correction file name */ - string getFlatFieldCorrectionFile(){ if ((*correctionMask)&(1< dataQueue; + std::queue dataQueue; /** queue containing the postprocessed data */ - queue finalDataQueue; + std::queue finalDataQueue; /** data queue size */ int queuesize; diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.h index 51e19a7df..7edfddc0b 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.h @@ -25,7 +25,7 @@ class angularConversion; class fileIO; -using namespace std; +; #define MAX_BADCHANS 2000 diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.cpp b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.cpp index 03b290a8e..f92d132ad 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.cpp +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.cpp @@ -1,6 +1,6 @@ #include "postProcessingFuncs.h" #include "angleConversionConstant.h" - +using namespace std; //#define VERBOSE postProcessingFuncs::postProcessingFuncs(int *nModules,int *chPerMod,int modMask[],int badCh[], double ffcoeff[], double fferr[], double* t, int *dir, double angRadius[], double angOffset[], double angCentre[], double* to, double* bs, double *sX, double *sY): @@ -303,16 +303,17 @@ int postProcessingFuncs::initDataset(int *nModules,int *chPerMod,int modMask[],i totalChans=0; - - chansPerMod=new int [nMods]; + if (nMods) + chansPerMod=new int [nMods]; - - moduleMask=new int [nMods]; + if (nMods) + moduleMask=new int [nMods]; nBins=0; if (angRadius && angOffset && angCenter && (binSize>0)) { // cout << "??????? creating angConv"<< endl; - angConv=new angleConversionConstant*[nMods]; + if (nMods) + angConv=new angleConversionConstant*[nMods]; nBins=(int)(360./binSize)+1; } //#ifdef VERBOSE @@ -380,11 +381,15 @@ int postProcessingFuncs::initDataset(int *nModules,int *chPerMod,int modMask[],i void postProcessingFuncs::deletePointers() { - delete [] chansPerMod; - chansPerMod=NULL; + if(chansPerMod != NULL) { + delete [] chansPerMod; + chansPerMod=NULL; + } - delete [] moduleMask; - moduleMask=NULL; + if (moduleMask != NULL) { + delete [] moduleMask; + moduleMask=NULL; + } if (badChannelMask) { diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.h index daf779e87..abffb54eb 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.h @@ -17,7 +17,7 @@ #include "angularConversionStatic.h" class angleConversionConstant; -using namespace std; + class postProcessingFuncs : public virtual angularConversionStatic diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.h index 2006553d4..213ed6de4 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.h @@ -18,7 +18,7 @@ class angularConversion; -using namespace std; +; #define MAX_BADCHANS 2000 diff --git a/slsDetectorSoftware/slsDetectorAnalysis/singlePhotonFilter.h b/slsDetectorSoftware/slsDetectorAnalysis/singlePhotonFilter.h index 3a9a398f5..45a23719d 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/singlePhotonFilter.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/singlePhotonFilter.h @@ -34,7 +34,7 @@ #include "runningStat.h" #include "movingStat.h" #include "single_photon_hit.h" -using namespace std; + typedef double double32_t; diff --git a/slsDetectorSoftware/slsDetectorClient/Makefile b/slsDetectorSoftware/slsDetectorClient/Makefile index 44ccbf7e4..9c26be641 100644 --- a/slsDetectorSoftware/slsDetectorClient/Makefile +++ b/slsDetectorSoftware/slsDetectorClient/Makefile @@ -105,7 +105,7 @@ htmldoc: clean: # cd manual && make clean - rm -rf $(BIN)/sls_detector_put $(BIN)/sls_detector_get $(BIN)/sls_detector_acquire $(BIN)/sls_detector_help + rm -rf $(BIN)/sls_detector_put $(BIN)/sls_detector_get $(BIN)/sls_detector_acquire $(BIN)/sls_detector_help $(BIN)/gui_client install: clients diff --git a/slsDetectorSoftware/slsDetectorServer/blackfin.h b/slsDetectorSoftware/slsDetectorServer/blackfin.h index 841dee257..f95cd4ffe 100755 --- a/slsDetectorSoftware/slsDetectorServer/blackfin.h +++ b/slsDetectorSoftware/slsDetectorServer/blackfin.h @@ -73,7 +73,7 @@ int64_t get64BitReg(int aLSB, int aMSB){ vMSB=bus_r(aMSB); v64=vMSB; v64=(v64<<32) | vLSB; - printf(" reg64(%x,%x) %x %x %llx\n", aLSB, aMSB, vLSB, vMSB, v64); + printf(" reg64(%x,%x) %x %x %llx\n", aLSB, aMSB, vLSB, vMSB, (long long unsigned int)v64); return v64; } @@ -148,7 +148,9 @@ int mapCSP0(void) { return FAIL; } #endif - printf("CSPOBASE mapped from 0x%llx to 0x%llx\n",CSP0BASE, CSP0BASE+MEM_SIZE); + printf("CSPOBASE mapped from 0x%llx to 0x%llx\n", + (long long unsigned int)CSP0BASE, + (long long unsigned int)(CSP0BASE+MEM_SIZE)); printf("Status Register: %08x\n",bus_r(STATUS_REG)); }else diff --git a/slsDetectorSoftware/slsDetectorServer/programfpga.h b/slsDetectorSoftware/slsDetectorServer/programfpga.h index db7b1cfb8..b37f521de 100755 --- a/slsDetectorSoftware/slsDetectorServer/programfpga.h +++ b/slsDetectorSoftware/slsDetectorServer/programfpga.h @@ -11,7 +11,8 @@ /* global variables */ #define CTRL_SRVR_INIT_TIME_US (300 * 1000) int gpioDefined=0; -char mtdvalue[10]; +#define MTDSIZE 10 +char mtdvalue[MTDSIZE]; @@ -67,9 +68,10 @@ void eraseFlash(){ printf("\nErasing Flash\n"); #endif char command[255]; + memset(command, 0, 255); sprintf(command,"flash_eraseall %s",mtdvalue); system(command); - printf("flash erased\n"); + printf("Flash erased\n"); } /** @@ -85,14 +87,24 @@ int startWritingFPGAprogram(FILE** filefp){ //getting the drive char output[255]; + memset(output, 0, 255); FILE* fp = popen("awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r"); - fgets(output, sizeof(output), fp); + if (fp == NULL) { + cprintf(RED,"popen returned NULL. Need that to get mtd drive.\n"); + return 1; + } + if (fgets(output, sizeof(output), fp) == NULL) { + cprintf(RED,"fgets returned NULL. Need that to get mtd drive.\n"); + return 1; + } pclose(fp); + //cprintf(RED,"output: %s\n", output); + memset(mtdvalue, 0, MTDSIZE); strcpy(mtdvalue,"/dev/"); char* pch = strtok(output,":"); if(pch == NULL){ cprintf(RED,"Could not get mtd value\n"); - return FAIL; + return 1; } strcat(mtdvalue,pch); printf ("\nFlash drive found: %s\n",mtdvalue); @@ -105,7 +117,7 @@ int startWritingFPGAprogram(FILE** filefp){ cprintf(RED,"Unable to open %s in write mode\n",mtdvalue); return 1; } - printf("flash ready for writing\n"); + printf("Flash ready for writing\n"); return 0; } @@ -161,12 +173,12 @@ int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp){ #ifdef VERY_VERBOSE printf("\nWriting of FPGA Program\n"); cprintf(BLUE,"address of fpgasrc:%p\n",(void *)fpgasrc); - cprintf(BLUE,"fsize:%d\n",fsize); + cprintf(BLUE,"fsize:%lu\n",fsize); cprintf(BLUE,"pointer:%p\n",(void*)filefp); #endif if(fwrite((void*)fpgasrc , sizeof(char) , fsize , filefp )!= fsize){ - cprintf(RED,"Could not write FPGA source to flash\n"); + cprintf(RED,"Could not write FPGA source to flash (size:%lu)\n", fsize); return 1; } #ifdef VERY_VERBOSE diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h index 3e65ff53f..6c990b5f6 100644 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h @@ -17,6 +17,11 @@ Here are the definitions, but the actual implementation should be done for each // basic tests +#if defined(EIGERD) || defined(JUNGFRAUD) || defined(GOTTHARD) +int isFirmwareCheckDone(); +int getFirmwareCheckResult(char** mess); +#endif + void checkFirmwareCompatibility(int flag); #if defined(MYTHEN3D) || defined(JUNGFRAUD) int checkType(); @@ -58,6 +63,9 @@ void getModuleConfiguration(); // set up detector void allocateDetectorStructureMemory(); void setupDetector(); +#ifdef JUNGFRAUD +int setDefaultDacs(); +#endif // advanced read/write reg @@ -85,6 +93,7 @@ int configureFrequency(int val, int i); int autoCompDisable(int on); int adcPhase(int st); int getPhase(); +void configureASICTimer(); #endif // parameters - nmod, dr, roi @@ -105,6 +114,9 @@ int executeTrimming(enum trimMode mode, int par1, int par2, int imod); #endif // parameters - timer +#ifdef JUNGFRAUD +int selectStoragecellStart(int pos); +#endif int64_t setTimer(enum timerIndex ind, int64_t val); #ifndef EIGERD int64_t getTimeLeft(enum timerIndex ind); diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer.c b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer.c index c11201893..fd4b0e443 100755 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer.c +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer.c @@ -20,55 +20,73 @@ void error(char *msg){ } int main(int argc, char *argv[]){ - int portno, b; - int retval=OK; + int portno = DEFAULT_PORTNO; + int retval = OK; int sd, fd; int debugflag = 0; + int controlserver = 1; // if socket crash, ignores SISPIPE, prevents global signal handler // subsequent read/write to socket gives error - must handle locally signal(SIGPIPE, SIG_IGN); // circumvent the basic tests - if(argc > 1) { - if(!strcasecmp(argv[1],"-debug")){ - debugflag = 1; - argc=1; - } - } + { + int i; + for (i = 1; i < argc; ++i) { + if(!strcasecmp(argv[i],"-stopserver")) { + cprintf(BLUE,"Detected stop server\n"); + controlserver = 0; + } + else if(!strcasecmp(argv[i],"-devel")){ + cprintf(BLUE,"Detected developer mode\n"); + debugflag = 1; + } +#ifdef JUNGFRAUD + else if(!strcasecmp(argv[i],"-update")){ + cprintf(BLUE,"Detected update mode\n"); + debugflag = PROGRAMMING_MODE; + } +#endif + else if(strchr(argv[i],'-') != NULL) { + cprintf(RED,"cannot scan program argument %s\n", argv[1]); + return -1; + } + } + } #ifdef STOP_SERVER char cmd[100]; + memset(cmd, 0, 100); #endif - if (argc==1) { + if (controlserver) { portno = DEFAULT_PORTNO; cprintf(BLUE, "********************************************************\n" "********* opening control server on port %d **********\n" "********************************************************\n\n" , portno); - b=1; - basictests(debugflag); #ifdef STOP_SERVER - sprintf(cmd,"%s %d &",argv[0],DEFAULT_PORTNO+1); - //cprintf(BLUE,"cmd:%s\n", cmd); - system(cmd); + { + int i; + for (i = 0; i < argc; ++i) + sprintf(cmd, "%s %s", cmd, argv[i]); + sprintf(cmd,"%s -stopserver&", cmd); + cprintf(BLUE,"cmd:%s\n", cmd); + system(cmd); + } #endif } else { portno = DEFAULT_PORTNO+1; - if ( sscanf(argv[1],"%d",&portno) == 0) { - printf("could not open stop server: unknown port\n"); - return 1; - } cprintf(BLUE, "********************************************************\n" "*********** opening stop server on port %d ***********\n" "********************************************************\n\n" , portno); - b=0; } - init_detector(b); //defined in slsDetectorServer_funcs + setModeFlag(debugflag); //defined in slsDetectorServer_funcs + init_detector(controlserver); //defined in slsDetectorServer_funcs sd=bindSocket(portno); //defined in communication_funcs sockfd=sd; @@ -83,7 +101,7 @@ int main(int argc, char *argv[]){ printf("function table assigned \n"); #endif - if (b) + if (controlserver) printf("\nControl Server Ready...\n\n"); else printf("\nStop Server Ready...\n\n"); diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c index fab206e9b..405a1d9e9 100755 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c @@ -52,8 +52,11 @@ int printSocketReadError() { return FAIL; } -void basictests(int flag) { +void setModeFlag(int flag) { debugflag = flag; +} + +void basictests() { #ifdef SLS_DETECTOR_FUNCTION_LIST checkFirmwareCompatibility(debugflag); #endif @@ -68,6 +71,10 @@ void init_detector(int controlserver) { #ifdef SLS_DETECTOR_FUNCTION_LIST if (controlserver) { isControlServer = 1; + basictests(); +#ifdef JUNGFRAUD + if (debugflag != PROGRAMMING_MODE) +#endif initControlServer(); #ifdef EIGERD dhcpipad = getDetectorIP(); @@ -102,6 +109,14 @@ int decode_function(int file_des) { #ifdef VERBOSE printf(" calling function fnum=%d, (%s) located at 0x%x\n", fnum, getFunctionName((enum detFuncs)fnum), (unsigned int)flist[fnum]); +#endif +#ifdef JUNGFRAUD + if ((debugflag == PROGRAMMING_MODE) && + ((fnum != F_PROGRAM_FPGA) && (fnum != F_GET_DETECTOR_TYPE) && + (fnum != F_RESET_FPGA) && (fnum != F_UPDATE_CLIENT))) { + sprintf(mess,"This Function %s cannot be executed. ", getFunctionName((enum detFuncs)fnum)); + ret=(M_nofuncMode)(file_des); + } else #endif if (fnum<0 || fnum>=NUM_DET_FUNCTIONS) { cprintf(BG_RED,"Unknown function enum %d\n", fnum); @@ -193,6 +208,8 @@ const char* getFunctionName(enum detFuncs func) { case F_TEMP_CONTROL: return "F_TEMP_CONTROL"; case F_TEMP_EVENT: return "F_TEMP_EVENT"; case F_AUTO_COMP_DISABLE: return "F_AUTO_COMP_DISABLE"; + case F_STORAGE_CELL_START: return "F_STORAGE_CELL_START"; + case F_CHECK_VERSION: return "F_CHECK_VERSION"; default: return "Unknown Function"; } @@ -276,6 +293,8 @@ void function_table() { flist[F_TEMP_CONTROL] = &temp_control; flist[F_TEMP_EVENT] = &temp_event; flist[F_AUTO_COMP_DISABLE] = &auto_comp_disable; + flist[F_STORAGE_CELL_START] = &storage_cell_start; + flist[F_CHECK_VERSION] = &check_version; // check if (NUM_DET_FUNCTIONS >= TOO_MANY_FUNCTIONS_DEFINED) { @@ -313,6 +332,21 @@ int M_nofunc(int file_des){ +int M_nofuncMode(int file_des){ + int ret=FAIL,ret1=FAIL; + int n=0; + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + strcat(mess, "On-board detector server in update mode. Restart detector server in normal mode (without any arguments) to continue.\n"); + cprintf(BG_RED,"Error: %s",mess); + n = sendData(file_des,&ret1,sizeof(ret1),INT32); + n = sendData(file_des,mess,sizeof(mess),OTHER); // mess is defined at function call + + // return ok / fail + return ret; +} @@ -2240,20 +2274,19 @@ int set_settings(int file_des) { sprintf(mess,"set settings failed\n"); #ifdef MYTHEN3D - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Set Settings) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Set Settings) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); #else - // receive arguments n = receiveData(file_des,&arg,sizeof(arg),INT32); if (n < 0) return printSocketReadError(); - imod=arg[1]; isett=arg[0]; + imod=arg[1]; // execute action if (differentClients && lockStatus && isett!=GET_SETTINGS) { @@ -2262,20 +2295,57 @@ int set_settings(int file_des) { cprintf(RED, "Warning: %s", mess); } #ifdef SLS_DETECTOR_FUNCTION_LIST - else if (imod>=getTotalNumberOfModules()) { + +#ifdef MYTHEND + if ( (ret != FAIL) && (imod>=getTotalNumberOfModules())) { ret = FAIL; sprintf(mess,"Module number %d out of range\n",imod); cprintf(RED, "Warning: %s", mess); } - else { +#endif + switch(isett) { + case GET_SETTINGS: + case UNINITIALIZED: +#ifdef JUNGFRAUD + case DYNAMICGAIN: + case DYNAMICHG0: + case FIXGAIN1: + case FIXGAIN2: + case FORCESWITCHG1: + case FORCESWITCHG2: + break; + default: + ret = FAIL; + sprintf(mess,"Setting (%d) is not implemented for this detector.\n" + "Options are dynamicgain, dynamichg0, fixgain1, fixgain2, " + "forceswitchg1 and forceswitchg2.\n", isett); + cprintf(RED, "Warning: %s", mess); + break; +// other detectors +// #elif GOTTHARDD, MOENCHD, PROPIXD +#else + break; + default: + ret = FAIL; +#ifdef EIGERD + sprintf(mess,"Cannot set settings via SET_SETTINGS, use SET_MODULE\n"); +#else + sprintf(mess,"Setting (%d) is not implemented for this detector\n", isett); +#endif + cprintf(RED, "Warning: %s", mess); + break; +#endif + } + + if (ret != FAIL) { #ifdef VERBOSE - printf("Changing settings of module %d to %d\n", imod, isett); + printf("Changing settings of module %d to %d\n", imod, isett); #endif retval=setSettings(isett, imod); #ifdef VERBOSE printf("Settings changed to %d\n", isett); #endif - if (retval==isett || isett<0) { + if (retval == isett || isett < 0) { ret=OK; } else { ret = FAIL; @@ -2283,6 +2353,17 @@ int set_settings(int file_des) { cprintf(RED, "Warning: %s", mess); } } + // set to default dacs, +//# also for #elif GOTTHARDD, MOENCHD, PROPIXD +#ifdef JUNGFRAUD + if (ret == OK && isett >= 0) { + ret = setDefaultDacs(); + if (ret == FAIL) { + strcpy(mess,"Could change settings, but could not set to default dacs\n"); + cprintf(RED, "Warning: %s", mess); + } + } +#endif #endif #endif @@ -2708,6 +2789,14 @@ int set_timer(int file_des) { printf("setting timer %d to %lld ns\n",ind,tns); #endif switch(ind) { +#ifdef JUNGFRAUD + case STORAGE_CELL_NUMBER: + if (tns > MAX_STORAGE_CELL_VAL) { + ret=FAIL; + strcpy(mess,"Max Storage cell number should not exceed 15\n"); + break; + } +#endif #ifdef EIGERD case SUBFRAME_ACQUISITION_TIME: if (tns > ((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) ){ @@ -2715,6 +2804,16 @@ int set_timer(int file_des) { strcpy(mess,"Sub Frame exposure time should not exceed 5.368 seconds\n"); break; } + retval = setTimer(ind,tns); + break; + case SUBFRAME_PERIOD: + if (tns > ((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) ){ + ret=FAIL; + strcpy(mess,"Sub Frame Period should not exceed 5.368 seconds\n"); + break; + } + retval = setTimer(ind,tns); + break; #endif #ifdef MYTHEN case PROBES_NUMBER: @@ -2740,6 +2839,8 @@ int set_timer(int file_des) { cprintf(RED, "%s", mess); break; } + + #if defined(MYTHEND) || defined(GOTTHARD) if (ret == OK && ind==FRAME_NUMBER) { ret=allocateRAM(); @@ -2803,39 +2904,53 @@ int get_time_left(int file_des) { printf("getting time left on timer %d \n",ind); #endif #ifdef SLS_DETECTOR_FUNCTION_LIST - switch(ind) { + +#ifdef JUNGFRAUD + if (ind == DELAY_AFTER_TRIGGER) { + ret = FAIL; + sprintf(mess,"Timer Left Index (%d) is not implemented for this release.\n", (int)ind); + cprintf(RED, "%s", mess); + } else { +#endif + + switch(ind) { #ifdef MYTHEND - case PROBES_NUMBER: + case PROBES_NUMBER: #elif JUNGFRAUD - case FRAMES_FROM_START: - case FRAMES_FROM_START_PG: + case FRAMES_FROM_START: + case FRAMES_FROM_START_PG: #elif MYTHEN3D - case GATES_NUMBER: - case PROBES_NUMBER: - case SAMPLES_JCTB: + case GATES_NUMBER: + case PROBES_NUMBER: + case SAMPLES_JCTB: #endif #ifndef JUNGFRAUD - case GATES_NUMBER: + case GATES_NUMBER: #endif - case FRAME_NUMBER: - case ACQUISITION_TIME: - case FRAME_PERIOD: - case DELAY_AFTER_TRIGGER: - case CYCLES_NUMBER: - case PROGRESS: - case ACTUAL_TIME: - case MEASUREMENT_TIME: - retval=getTimeLeft(ind); - break; - default: - ret = FAIL; - sprintf(mess,"Timer Left Index (%d) is not implemented for this detector\n", (int)ind); - cprintf(RED, "%s", mess); - break; - } + case FRAME_NUMBER: + case ACQUISITION_TIME: + case FRAME_PERIOD: + case DELAY_AFTER_TRIGGER: + case CYCLES_NUMBER: + case PROGRESS: + case ACTUAL_TIME: + case MEASUREMENT_TIME: + retval=getTimeLeft(ind); + break; + default: + ret = FAIL; + sprintf(mess,"Timer Left Index (%d) is not implemented for this detector\n", (int)ind); + cprintf(RED, "%s", mess); + break; + } #ifdef VERBOSE - printf("Time left on timer %d is %lld\n",ind, retval); + printf("Time left on timer %d is %lld\n",ind, retval); #endif + +#ifdef JUNGFRAUD + } // end of if (ind == DELAY_AFTER_TRIGGER) +#endif + #endif if (ret==OK && differentClients) ret=FORCE_UPDATE; @@ -3003,6 +3118,8 @@ int set_readout_flags(int file_des) { case PARALLEL: case NONPARALLEL: case SAFE: + case SHOW_OVERFLOW: + case NOOVERFLOW: #endif retval=setReadOutFlags(arg); break; @@ -3535,6 +3652,12 @@ int send_update(int file_des) { #endif n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); + +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(SUBFRAME_PERIOD,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); #endif @@ -3679,7 +3802,10 @@ int configure_mac(int file_des) { // change mac to hardware mac, (for 1 gbe) change ip to hardware ip if (idetectormacadd != getDetectorMAC()){ printf("*************************************************\n"); - printf("WARNING: actual detector mac address %llx does not match the one from client %llx\n",getDetectorMAC(),idetectormacadd); + printf("WARNING: actual detector mac address %llx does not match " + "the one from client %llx\n", + (long long unsigned int)getDetectorMAC(), + (long long unsigned int)idetectormacadd); idetectormacadd = getDetectorMAC(); printf("WARNING: Matched detectormac to the hardware mac now\n"); printf("*************************************************\n"); @@ -3737,7 +3863,7 @@ int configure_mac(int file_des) { #ifdef EIGERD char arg[2][50]; memset(arg,0,sizeof(arg)); - sprintf(arg[0],"%llx",idetectormacadd); + sprintf(arg[0],"%llx",(long long unsigned int)idetectormacadd); sprintf(arg[1],"%x",detipad); n += sendData(file_des,arg,sizeof(arg),OTHER); #endif @@ -4913,7 +5039,6 @@ int program_fpga(int file_des) { int n=0; sprintf(mess,"program FPGA failed\n"); - #ifndef JUNGFRAUD //to receive any arguments while (n > 0) @@ -4922,78 +5047,48 @@ int program_fpga(int file_des) { sprintf(mess,"Function (Program FPGA) is not implemented for this detector\n"); cprintf(RED, "Warning: %s", mess); #else - - size_t filesize = 0; - size_t totalsize = 0; - size_t unitprogramsize = 0; - char* fpgasrc = NULL; - FILE* fp = NULL; - - // receive arguments - filesize - n = receiveData(file_des,&filesize,sizeof(filesize),INT32); - if (n < 0) return printSocketReadError(); - totalsize = filesize; -#ifdef VERY_VERBOSE - printf("\n\n Total size is:%d\n",totalsize); -#endif - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); + if (!debugflag) { + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret=FAIL; + sprintf(mess,"FPGA cannot be programmed in this mode. " + "Restart on-board detector server with -update for update mode to continue.\n"); cprintf(RED, "Warning: %s", mess); } -#ifdef SLS_DETECTOR_FUNCTION_LIST + else { - //opening file pointer to flash and telling FPGA to not touch flash - if(startWritingFPGAprogram(&fp) != OK) { - ret=FAIL; - sprintf(mess,"Could not write to flash. Error at startup.\n"); - cprintf(RED,"%s",mess); + printf("Programming FPGA..."); + size_t filesize = 0; + size_t totalsize = 0; + size_t unitprogramsize = 0; + char* fpgasrc = NULL; + FILE* fp = NULL; + + // receive arguments - filesize + n = receiveData(file_des,&filesize,sizeof(filesize),INT32); + if (n < 0) return printSocketReadError(); + totalsize = filesize; +#ifdef VERY_VERBOSE + printf("\n\n Total size is:%d\n",totalsize); +#endif + + // execute action + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + //opening file pointer to flash and telling FPGA to not touch flash + if(startWritingFPGAprogram(&fp) != OK) { + ret=FAIL; + sprintf(mess,"Could not write to flash. Error at startup.\n"); + cprintf(RED,"%s",mess); + } - //---------------- first ret ---------------- - // ret could be swapped during sendData - ret1 = ret; - // send ok / fail - n = sendData(file_des,&ret1,sizeof(ret),INT32); - // send return argument - if (ret==FAIL) { - n += sendData(file_des,mess,sizeof(mess),OTHER); - } - //---------------- first ret ---------------- - - if(ret!=FAIL) { - //erasing flash - eraseFlash(); - fpgasrc = (char*)malloc(MAX_FPGAPROGRAMSIZE); - } - - //writing to flash part by part - while(ret != FAIL && filesize){ - - unitprogramsize = MAX_FPGAPROGRAMSIZE; //2mb - if(unitprogramsize > filesize) //less than 2mb - unitprogramsize = filesize; - #ifdef VERY_VERBOSE - printf("unit size to receive is:%d\n",unitprogramsize); - printf("filesize:%d currentpointer:%d\n",filesize,currentPointer); - #endif - - //receive - n = receiveData(file_des,fpgasrc,unitprogramsize,OTHER); - if (n < 0) return printSocketReadError(); - - if(!(unitprogramsize - filesize)){ - fpgasrc[unitprogramsize]='\0'; - filesize-=unitprogramsize; - unitprogramsize++; - }else - filesize-=unitprogramsize; - - ret = writeFPGAProgram(fpgasrc,unitprogramsize,fp); - - //---------------- middle rets ---------------- + //---------------- first ret ---------------- // ret could be swapped during sendData ret1 = ret; // send ok / fail @@ -5001,37 +5096,81 @@ int program_fpga(int file_des) { // send return argument if (ret==FAIL) { n += sendData(file_des,mess,sizeof(mess),OTHER); - cprintf(RED,"Failure: Breaking out of program receiving\n"); } - //---------------- middle rets ---------------- + //---------------- first ret ---------------- - if(ret != FAIL){ - //print progress - printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100) ); - fflush(stdout); + if(ret!=FAIL) { + //erasing flash + eraseFlash(); + fpgasrc = (char*)malloc(MAX_FPGAPROGRAMSIZE); + } + + //writing to flash part by part + while(ret != FAIL && filesize){ + + unitprogramsize = MAX_FPGAPROGRAMSIZE; //2mb + if(unitprogramsize > filesize) //less than 2mb + unitprogramsize = filesize; +#ifdef VERY_VERBOSE + printf("unit size to receive is:%d\n",unitprogramsize); + printf("filesize:%d currentpointer:%d\n",filesize,currentPointer); +#endif + + //receive + n = receiveData(file_des,fpgasrc,unitprogramsize,OTHER); + if (n < 0) return printSocketReadError(); + + if(!(unitprogramsize - filesize)){ + fpgasrc[unitprogramsize]='\0'; + filesize-=unitprogramsize; + unitprogramsize++; + }else + filesize-=unitprogramsize; + + ret = writeFPGAProgram(fpgasrc,unitprogramsize,fp); + + //---------------- middle rets ---------------- + // ret could be swapped during sendData + ret1 = ret; + // send ok / fail + n = sendData(file_des,&ret1,sizeof(ret),INT32); + // send return argument + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + cprintf(RED,"Failure: Breaking out of program receiving\n"); + } + //---------------- middle rets ---------------- + + if(ret != FAIL){ + //print progress + printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100) ); + fflush(stdout); + } + } + + printf("\n"); + + //closing file pointer to flash and informing FPGA + stopWritingFPGAprogram(fp); + + //free resources + if(fpgasrc != NULL) + free(fpgasrc); + if(fp!=NULL) + fclose(fp); +#ifdef VERY_VERBOSE + printf("Done with program receiving command\n"); +#endif + + if (isControlServer) { + basictests(debugflag); + initControlServer(); } } - - printf("\n"); - - //closing file pointer to flash and informing FPGA - stopWritingFPGAprogram(fp); - - //free resources - if(fpgasrc != NULL) - free(fpgasrc); - if(fp!=NULL) - fclose(fp); -#ifdef VERY_VERBOSE - printf("Done with program receiving command\n"); -#endif - if (isControlServer) - basictests(debugflag); - init_detector(isControlServer); - } #endif if (ret==OK) ret=FORCE_UPDATE; + } #endif // ret could be swapped during sendData @@ -5061,8 +5200,7 @@ int reset_fpga(int file_des) { while (n > 0) n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); ret = FAIL; - sprintf(mess,"Function (Start Readout) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + sprintf(mess,"Function (Reset FPGA) is not implemented for this detector\n"); cprintf(RED, "%s", mess); #else // execute action @@ -5073,9 +5211,14 @@ int reset_fpga(int file_des) { } #ifdef SLS_DETECTOR_FUNCTION_LIST else { - if (isControlServer) - basictests(debugflag); - initControlServer(isControlServer); + if (isControlServer) { + basictests(debugflag); // mapping of control server at lease +#ifdef JUNGFRAUD + if (debugflag != PROGRAMMING_MODE) +#endif + initControlServer(); + } + else initStopServer(); //remapping of stop server ret = FORCE_UPDATE; } #endif @@ -5516,8 +5659,6 @@ int auto_comp_disable(int file_des) { sprintf(mess,"Function (Auto Comp Disable) is not yet implemented for this detector\n"); cprintf(RED, "%s", mess); - /* will be connected after teh fpga upgrade - // receive arguments int arg=-1; n = receiveData(file_des,&arg,sizeof(arg),INT32); @@ -5550,7 +5691,6 @@ int auto_comp_disable(int file_des) { #endif if (ret==OK && differentClients) ret=FORCE_UPDATE; - */ #endif // ret could be swapped during sendData @@ -5567,3 +5707,167 @@ int auto_comp_disable(int file_des) { return ret; } + + + + +int storage_cell_start(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"storage cell start failed\n"); + +#ifndef JUNGFRAUD + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Storage cell start) is not implemented for this detector\n"); + cprintf(RED, "%s", mess); +#else + + // receive arguments + int arg=-1; + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + if (differentClients && lockStatus && arg!=-1) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else if (arg > MAX_STORAGE_CELL_VAL) { + ret=FAIL; + strcpy(mess,"Max Storage cell number should not exceed 15\n"); + cprintf(RED, "Warning: %s", mess); + } else { +#ifdef VERBOSE + printf("Storage cell start to %d\n", arg); +#endif + retval=selectStoragecellStart(arg); + +#ifdef VERBOSE + printf("Storage cell start: %d\n",retval); +#endif + if (retval==arg || arg<0) { + ret=OK; + } else { + sprintf(mess,"Storage cell start select failed, wrote %d but read %d\n", arg, retval); + cprintf(RED, "Warning: %s", mess); + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // ret could be swapped during sendData + ret1 = ret; + // send ok / fail + n = sendData(file_des,&ret1,sizeof(ret),INT32); + // send return argument + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + +int check_version(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"check version failed\n"); + +#if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(GOTTHARD) + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret=FAIL; + sprintf(mess,"Function (Check Version Compatibility) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + + // receive arguments + int64_t arg=-1; + n = receiveData(file_des,&arg,sizeof(arg),INT64); + if (n < 0) return printSocketReadError(); + + // execute action +#ifdef SLS_DETECTOR_FUNCTION_LIST + + // check software- firmware compatibility and basic tests + if (isControlServer) { +#ifdef VERBOSE + printf("Checking software-firmware compatibility and basic test result\n"); +#endif + // check if firmware check is done + if (!isFirmwareCheckDone()) { + usleep(3 * 1000 * 1000); + if (!isFirmwareCheckDone()) { + ret = FAIL; + strcpy(mess,"Firmware Software Compatibility Check (Server Initialization) " + "still not done done in server. Unexpected.\n"); + cprintf(RED, "Warning: %s", mess); + } + } + // check firmware check result + if (ret == OK) { + char* firmware_message = NULL; + if (getFirmwareCheckResult(&firmware_message) == FAIL) { + ret = FAIL; + strcpy(mess, firmware_message); + cprintf(RED, "Warning: %s", mess); + } + } + } + + if (ret == OK) { +#ifdef VERBOSE + printf("Checking versioning compatibility with value %d\n",arg); +#endif + int64_t client_requiredVersion = arg; + int64_t det_apiVersion = getDetectorId(CLIENT_SOFTWARE_API_VERSION); + int64_t det_version = getDetectorId(DETECTOR_SOFTWARE_VERSION); + + // old client + if (det_apiVersion > client_requiredVersion) { + ret = FAIL; + sprintf(mess,"Client's detector SW API version: (0x%llx). " + "Detector's SW API Version: (0x%llx). " + "Incompatible, update client!\n", + client_requiredVersion, det_apiVersion); + cprintf(RED, "Warning: %s", mess); + } + + // old software + else if (client_requiredVersion > det_version) { + ret = FAIL; + sprintf(mess,"Detector SW Version: (0x%llx). " + "Client's detector SW API Version: (0x%llx). " + "Incompatible, update detector software!\n", + det_version, client_requiredVersion); + cprintf(RED, "Warning: %s", mess); + } + } +#endif +#endif + + // ret could be swapped during sendData + ret1 = ret; + // send ok / fail + n = sendData(file_des,&ret1,sizeof(ret),INT32); + // send return argument + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h index e593b0bf4..a8ab6b927 100755 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h @@ -6,12 +6,14 @@ // initialization functions int printSocketReadError(); -void basictests(int); +void setModeFlag(int); +void basictests(); void init_detector(int); int decode_function(int); const char* getFunctionName(enum detFuncs func); void function_table(); int M_nofunc(int); +int M_nofuncMode(int); // functions called by client int exec_command(int); @@ -92,5 +94,7 @@ int threshold_temp(int); int temp_control(int); int temp_event(int); int auto_comp_disable(int); +int storage_cell_start(int); +int check_version(int); #endif diff --git a/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp index a87747cf6..a8bbd4a0b 100644 --- a/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp +++ b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp @@ -15,24 +15,24 @@ receiverInterface::receiverInterface(MySocketTCP *socket):dataSocket(socket){} -receiverInterface::~receiverInterface(){ - delete dataSocket; -} +receiverInterface::~receiverInterface(){} int receiverInterface::sendString(int fnum, char retval[], char arg[]){ int ret = slsDetectorDefs::FAIL; - char mess[MAX_STR_LENGTH] = ""; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->SendDataOnly(arg,MAX_STR_LENGTH); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ dataSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; + cprintf(RED, "Receiver returned error: %s", mess); } - dataSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH); + if(strstr(mess,"Unrecognized Function")==NULL) + dataSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH); return ret; } @@ -42,14 +42,15 @@ int receiverInterface::sendString(int fnum, char retval[], char arg[]){ int receiverInterface::sendUDPDetails(int fnum, char retval[], char arg[3][MAX_STR_LENGTH]){ char args[3][MAX_STR_LENGTH]; int ret = slsDetectorDefs::FAIL; - char mess[MAX_STR_LENGTH] = ""; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->SendDataOnly(arg,sizeof(args)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ dataSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; + cprintf(RED, "Receiver returned error: %s", mess); } else dataSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH); @@ -60,16 +61,18 @@ int receiverInterface::sendUDPDetails(int fnum, char retval[], char arg[3][MAX_S int receiverInterface::sendInt(int fnum, int &retval, int arg){ int ret = slsDetectorDefs::FAIL; - char mess[MAX_STR_LENGTH] = ""; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->SendDataOnly(&arg,sizeof(arg)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ dataSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; + cprintf(RED, "Receiver returned error: %s", mess); } - dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if(strstr(mess,"Unrecognized Function")==NULL) + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); return ret; } @@ -78,15 +81,17 @@ int receiverInterface::sendInt(int fnum, int &retval, int arg){ int receiverInterface::getInt(int fnum, int &retval){ int ret = slsDetectorDefs::FAIL; - char mess[MAX_STR_LENGTH] = ""; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ dataSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; + cprintf(RED, "Receiver returned error: %s", mess); } - dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if(strstr(mess,"Unrecognized Function")==NULL) + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); return ret; } @@ -95,16 +100,18 @@ int receiverInterface::getInt(int fnum, int &retval){ int receiverInterface::sendInt(int fnum, int64_t &retval, int64_t arg){ int ret = slsDetectorDefs::FAIL; - char mess[MAX_STR_LENGTH] = ""; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->SendDataOnly(&arg,sizeof(arg)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ dataSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; + cprintf(RED, "Receiver returned error: %s", mess); } - dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if(strstr(mess,"Unrecognized Function")==NULL) + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); return ret; } @@ -113,16 +120,18 @@ int receiverInterface::sendInt(int fnum, int64_t &retval, int64_t arg){ int receiverInterface::sendIntArray(int fnum, int64_t &retval, int64_t arg[2], char mess[]){ int64_t args[2]; - char messs[MAX_STR_LENGTH]; int ret = slsDetectorDefs::FAIL; + memset(mess, 0, MAX_STR_LENGTH); + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->SendDataOnly(arg,sizeof(args)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ - dataSocket->ReceiveDataOnly(mess,sizeof(messs)); - std::cout<< "Receiver returned error: " << mess << std::endl; + dataSocket->ReceiveDataOnly(mess,MAX_STR_LENGTH); + cprintf(RED, "Receiver returned error: %s", mess); } - dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if(strstr(mess,"Unrecognized Function")==NULL) + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); return ret; } @@ -132,15 +141,18 @@ int receiverInterface::sendIntArray(int fnum, int64_t &retval, int64_t arg[2], c int receiverInterface::sendIntArray(int fnum, int &retval, int arg[2]){ int args[2]; int ret = slsDetectorDefs::FAIL; - char mess[MAX_STR_LENGTH] = ""; + char mess[MAX_STR_LENGTH]; + memset(mess, 0, MAX_STR_LENGTH); + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->SendDataOnly(arg,sizeof(args)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ dataSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Receiver returned error: " << mess << std::endl; + cprintf(RED, "Receiver returned error: %s", mess); } - dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if(strstr(mess,"Unrecognized Function")==NULL) + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); return ret; } @@ -172,12 +184,13 @@ int receiverInterface::getLastClientIP(int fnum, char retval[]){ int receiverInterface::executeFunction(int fnum,char mess[]){ int ret = slsDetectorDefs::FAIL; + memset(mess, 0, MAX_STR_LENGTH); dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==slsDetectorDefs::FAIL){ dataSocket->ReceiveDataOnly(mess,MAX_STR_LENGTH); - std::cout<< "Receiver returned error: " << mess << std::endl; + cprintf(RED, "Receiver returned error: %s", mess); } return ret; diff --git a/slsDetectorSoftware/threadFiles/CondVar.h b/slsDetectorSoftware/threadFiles/CondVar.h index b823ef31d..3bf69d146 100644 --- a/slsDetectorSoftware/threadFiles/CondVar.h +++ b/slsDetectorSoftware/threadFiles/CondVar.h @@ -8,7 +8,6 @@ #include "Global.h" -using namespace std; class CondVar { public: diff --git a/slsDetectorSoftware/threadFiles/Multi.h b/slsDetectorSoftware/threadFiles/Multi.h index b7216c579..cf34396a8 100644 --- a/slsDetectorSoftware/threadFiles/Multi.h +++ b/slsDetectorSoftware/threadFiles/Multi.h @@ -4,7 +4,6 @@ #include "Global.h" #include -using namespace std; class Single; class ThreadPool; @@ -15,10 +14,10 @@ public: Multi(); ~Multi(); - string executeCommand(int argc,char* argv[]); + std::string executeCommand(int argc,char* argv[]); int printNumber(int inum); - string printString(string s); + std::string printString(std::string s); char* printCharArray(char a[]); int createThreadPool(); diff --git a/slsDetectorSoftware/threadFiles/Mutex.h b/slsDetectorSoftware/threadFiles/Mutex.h index a88df0d4e..33e108777 100644 --- a/slsDetectorSoftware/threadFiles/Mutex.h +++ b/slsDetectorSoftware/threadFiles/Mutex.h @@ -10,7 +10,7 @@ #include "Global.h" -using namespace std; +// class Mutex { diff --git a/slsDetectorSoftware/threadFiles/Single.h b/slsDetectorSoftware/threadFiles/Single.h index d8e9e2104..599bb7de7 100644 --- a/slsDetectorSoftware/threadFiles/Single.h +++ b/slsDetectorSoftware/threadFiles/Single.h @@ -3,7 +3,7 @@ #include "Multi.h" #include -using namespace std; +// class Single { public: diff --git a/slsDetectorSoftware/threadFiles/Task.h b/slsDetectorSoftware/threadFiles/Task.h index 76312995c..585f4a119 100644 --- a/slsDetectorSoftware/threadFiles/Task.h +++ b/slsDetectorSoftware/threadFiles/Task.h @@ -6,16 +6,12 @@ #include #include #include -#include - +#include +#include #include "Global.h" #include "sls_detector_defs.h" -#include -#include -using namespace std; - class slsDetector; template @@ -109,8 +105,8 @@ private: class SuperTask: public virtual slsDetectorDefs { public: SuperTask(): - m1(0),m2(0),m3(0),m4(0),m5(0),m6(0),m7(0),m8(0),m9(0),m10(0),m11(0),m12(0),m13(0),m14(0),m15(0),m16(0),m17(0),m18(0){}; - ~SuperTask(){}; + m1(0),m2(0),m3(0),m4(0),m5(0),m6(0),m7(0),m8(0),m9(0),m10(0),m11(0),m12(0),m13(0),m14(0),m15(0),m16(0),m17(0),m18(0),m19(0){}; + virtual ~SuperTask(){}; protected: /** Function signature defined * First argument is Return type, the remaining are arguments @@ -121,18 +117,19 @@ protected: func0_t * m4; func1_t * m5; func1_t * m6; - func1_t * m7; + func1_t * m7; func1_t * m8; func2_t * m9; - func2_t * m10; + func2_t * m10; func2_t * m11; func2_t * m12; - func2_t * m13; - func2_t * m14; + func3_t * m13; + func2_t * m14; func3_t * m15; func4_t * m16; func4_t * m17; func4_t * m18; + func1_t * m19; }; class Task: public virtual SuperTask { @@ -146,20 +143,47 @@ public: Task(func0_t * t): SuperTask(),fnum(4){m4 = t;}; Task(func1_t * t): SuperTask(),fnum(5){m5 = t;}; Task(func1_t * t): SuperTask(),fnum(6){m6 = t;}; - Task(func1_t * t): SuperTask(),fnum(7){m7 = t;}; + Task(func1_t * t): SuperTask(),fnum(7){m7 = t;}; Task(func1_t * t): SuperTask(),fnum(8){m8 = t;}; Task(func2_t * t): SuperTask(),fnum(9){m9 = t;}; - Task(func2_t * t): SuperTask(),fnum(10){m10 = t;}; + Task(func2_t * t): SuperTask(),fnum(10){m10 = t;}; Task(func2_t * t): SuperTask(),fnum(11){m11 = t;}; Task(func2_t * t): SuperTask(),fnum(12){m12 = t;}; - Task(func2_t * t): SuperTask(),fnum(13){m13 = t;}; - Task(func2_t * t): SuperTask(),fnum(14){m14 = t;}; + Task(func3_t * t): SuperTask(),fnum(13){m13 = t;}; + Task(func2_t * t): SuperTask(),fnum(14){m14 = t;}; Task(func3_t * t): SuperTask(),fnum(15){m15 = t;}; Task(func4_t * t): SuperTask(),fnum(16){m16 = t;}; Task(func4_t * t): SuperTask(),fnum(17){m17 = t;}; Task(func4_t * t): SuperTask(),fnum(18){m18 = t;}; + Task(func1_t * t): SuperTask(),fnum(19){m19 = t;}; - ~Task(){} + virtual ~Task(){ + switch(fnum) { + case 1: delete m1; break; + case 2: delete m2; break; + case 3: delete m3; break; + case 4: delete m4; break; + case 5: delete m5; break; + case 6: delete m6; break; + case 7: delete m7; break; + case 8: delete m8; break; + case 9: delete m9; break; + case 10: delete m10; break; + case 11: delete m11; break; + case 12: delete m12; break; + case 13: delete m13; break; + case 14: delete m14; break; + case 15: delete m15; break; + case 16: delete m16; break; + case 17: delete m17; break; + case 18: delete m18; break; + case 19: delete m19; break; + default: + cprintf(RED, "Error: Task not defined. Abort!\n"); + break; + } + + }; void operator()(){ switch(fnum) { @@ -181,6 +205,7 @@ public: case 16: (*m16)(); break; case 17: (*m17)(); break; case 18: (*m18)(); break; + case 19: (*m19)(); break; default: cprintf(RED, "Error: Task not defined. Abort!\n"); break; diff --git a/slsDetectorSoftware/threadFiles/ThreadPool.cpp b/slsDetectorSoftware/threadFiles/ThreadPool.cpp index 63ca4824a..224038f5c 100644 --- a/slsDetectorSoftware/threadFiles/ThreadPool.cpp +++ b/slsDetectorSoftware/threadFiles/ThreadPool.cpp @@ -1,6 +1,6 @@ #include "ThreadPool.h" #include - +using namespace std; ThreadPool::ThreadPool(int pool_size) : m_pool_size(pool_size){ #ifdef VERBOSE cout << "Constructed ThreadPool of size " << m_pool_size << endl; diff --git a/slsDetectorSoftware/threadFiles/ThreadPool.h b/slsDetectorSoftware/threadFiles/ThreadPool.h index 34a4504cc..45dcc711e 100644 --- a/slsDetectorSoftware/threadFiles/ThreadPool.h +++ b/slsDetectorSoftware/threadFiles/ThreadPool.h @@ -14,7 +14,7 @@ #include "CondVar.h" #include "Global.h" #include -using namespace std; +// class ThreadPool diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index a7de05eed..0cfbc8819 100644 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -28,7 +28,6 @@ if (USE_HDF5) ) list (APPEND SOURCES src/HDF5File.cpp - src/HDF5FileStatic.cpp ) endif () endif (USE_HDF5) @@ -42,10 +41,11 @@ include_directories( include ) -add_library(zmq STATIC IMPORTED ) +add_library(zmq STATIC IMPORTED GLOBAL) +set(ZMQ_STATIC_ARCHIVE ${CMAKE_CURRENT_SOURCE_DIR}/include/libzmq.a) set_target_properties(zmq PROPERTIES - IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/include/libzmq.a + IMPORTED_LOCATION ${ZMQ_STATIC_ARCHIVE} ) add_library(slsReceiverStatic STATIC @@ -68,6 +68,7 @@ set(PUBLICHEADERS include/sls_receiver_funcs.h include/MySocketTCP.h include/genericSocket.h + include/logger.h ) @@ -101,4 +102,8 @@ install(TARGETS slsReceiverShared slsReceiverStatic slsReceiver RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib - PUBLIC_HEADER DESTINATION include) \ No newline at end of file + PUBLIC_HEADER DESTINATION include) + + +install(FILES ${ZMQ_STATIC_ARCHIVE} +DESTINATION lib) \ No newline at end of file diff --git a/slsReceiverSoftware/Makefile b/slsReceiverSoftware/Makefile index e3d6e3af3..4fe92b278 100644 --- a/slsReceiverSoftware/Makefile +++ b/slsReceiverSoftware/Makefile @@ -30,7 +30,7 @@ DEPSINCLUDES = $(INCDIR)/ansi.h $(INCDIR)/sls_receiver_defs.h $(INCDIR)/sls_rece ifeq ($(HDF5),yes) - SRC_CLNT += HDF5File.cpp HDF5FileStatic.cpp + SRC_CLNT += HDF5File.cpp endif MAIN_SRC = main.cpp diff --git a/slsReceiverSoftware/gitInfo.txt b/slsReceiverSoftware/gitInfo.txt index 811a55fc1..176ad8c05 100644 --- a/slsReceiverSoftware/gitInfo.txt +++ b/slsReceiverSoftware/gitInfo.txt @@ -1,18 +1,9 @@ Path: slsDetectorsPackage/slsReceiverSoftware URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -<<<<<<< HEAD -Repsitory UUID: ab06c33107ecfeb4741d49407903ff80286cf75b -Revision: 765 -Branch: developer -Last Changed Author: Anna_Bergamaschi -Last Changed Rev: 3731 -Last Changed Date: 2018-03-15 12:27:06.000000002 +0100 ./src/slsReceiverTCPIPInterface.cpp -======= -Repsitory UUID: b8bdbf4da61f95b88893b02ddabc2491b16fa10f -Revision: 767 -Branch: developer +Repsitory UUID: 6bb7195a2c7dc9526088882e0244a7455d3c15b2 +Revision: 809 +Branch: 3.3.0-rc Last Changed Author: Dhanya_Thattil -Last Changed Rev: 3746 -Last Changed Date: 2018-03-27 10:43:44.000000002 +0200 ./src/slsReceiverTCPIPInterface.cpp ->>>>>>> 7cd35f24b87501374fbaf45693a2adf16dfae3e3 +Last Changed Rev: 3941 +Last Changed Date: 2018-07-18 12:11:38.000000002 +0200 ./include/HDF5FileStatic.h diff --git a/slsReceiverSoftware/include/BinaryFile.h b/slsReceiverSoftware/include/BinaryFile.h index 3d1e46d0b..9cb585396 100644 --- a/slsReceiverSoftware/include/BinaryFile.h +++ b/slsReceiverSoftware/include/BinaryFile.h @@ -21,7 +21,7 @@ class BinaryFile : private virtual slsReceiverDefs, public File, public BinaryFi * Constructor * creates the File Writer * @param ind self index - * @param maxf max frames per file + * @param maxf pointer to max frames per file * @param nd pointer to number of detectors in each dimension * @param fname pointer to file name prefix * @param fpath pointer to file path @@ -34,7 +34,7 @@ class BinaryFile : private virtual slsReceiverDefs, public File, public BinaryFi * @param portno pointer to udp port number for logging * @param smode pointer to silent mode */ - BinaryFile(int ind, uint32_t maxf, + BinaryFile(int ind, uint32_t* maxf, int* nd, char* fname, char* fpath, uint64_t* findex, bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, bool* smode); @@ -63,12 +63,14 @@ class BinaryFile : private virtual slsReceiverDefs, public File, public BinaryFi * @param nx number of pixels in x direction * @param ny number of pixels in y direction * @param at acquisition time - * @param at sub exposure time + * @param st sub exposure time + * @param sp sub period * @param ap acquisition period * @returns OK or FAIL */ int CreateMasterFile(bool en, uint32_t size, - uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t ap); + uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp, + uint64_t ap); /** * Close Current File diff --git a/slsReceiverSoftware/include/BinaryFileStatic.h b/slsReceiverSoftware/include/BinaryFileStatic.h index fda193213..2aa9cc54f 100644 --- a/slsReceiverSoftware/include/BinaryFileStatic.h +++ b/slsReceiverSoftware/include/BinaryFileStatic.h @@ -16,6 +16,8 @@ #include using namespace std; +#define MAX_MASTER_FILE_LENGTH 2000 + class BinaryFileStatic { @@ -44,7 +46,7 @@ class BinaryFileStatic { { ostringstream osfn; osfn << fpath << "/" << fnameprefix; - if (dindex >= 0) osfn << "_d" << ((unitindex >= numunits) ? unitindex : (dindex * numunits + unitindex)); //if unit index > numunits, all receivers in one program (userReceiver) + if (dindex >= 0) osfn << "_d" << (dindex * numunits + unitindex); if (frindexenable) osfn << "_f" << setfill('0') << setw(12) << fnum; osfn << "_" << findex; osfn << ".raw"; @@ -84,10 +86,9 @@ class BinaryFileStatic { * @param fd file pointer * @param buf buffer to write from * @param bsize size of buffer - * @param fnum current image number * @returns number of elements written */ - static int WriteDataFile(FILE* fd, char* buf, int bsize, uint64_t fnum) + static int WriteDataFile(FILE* fd, char* buf, int bsize) { if (!fd) return 0; @@ -106,15 +107,20 @@ class BinaryFileStatic { * @param nPixelsX number of pixels in x direction * @param nPixelsY number of pixels in y direction * @param nf number of images + * @param maxf maximum frames per file * @param acquisitionTime acquisition time * @param acquisitionPeriod acquisition period * @param subexposuretime sub exposure time + * @param subperiod sub period * @param version version of software for binary writing * @returns 0 for success and 1 for fail */ static int CreateMasterDataFile(FILE*& fd, string fname, bool owenable, - uint32_t dr, bool tenE, uint32_t size, uint32_t nPixelsX, uint32_t nPixelsY, uint64_t nf, - uint64_t acquisitionTime, uint64_t subexposuretime, uint64_t acquisitionPeriod, double version) + uint32_t dr, bool tenE, uint32_t size, + uint32_t nPixelsX, uint32_t nPixelsY, uint64_t nf, + uint32_t maxf, + uint64_t acquisitionTime, uint64_t subexposuretime, + uint64_t subperiod, uint64_t acquisitionPeriod, double version) { if(!owenable){ if (NULL == (fd = fopen((const char *) fname.c_str(), "wx"))){ @@ -128,34 +134,37 @@ class BinaryFileStatic { return 1; } time_t t = time(0); - char message[MAX_STR_LENGTH]; + char message[MAX_MASTER_FILE_LENGTH]; sprintf(message, - "Version : %.1f\n" - "Dynamic Range : %d\n" - "Ten Giga : %d\n" - "Image Size : %d bytes\n" - "x : %d pixels\n" - "y : %d pixels\n" - "Total Frames : %lld\n" - "Exptime (ns) : %lld\n" - "SubExptime (ns) : %lld\n" - "Period (ns) : %lld\n" - "Timestamp : %s\n\n" + "Version : %.1f\n" + "Dynamic Range : %d\n" + "Ten Giga : %d\n" + "Image Size : %d bytes\n" + "x : %d pixels\n" + "y : %d pixels\n" + "Max. Frames Per File : %u\n" + "Total Frames : %lld\n" + "Exptime (ns) : %lld\n" + "SubExptime (ns) : %lld\n" + "SubPeriod(ns) : %lld\n" + "Period (ns) : %lld\n" + "Timestamp : %s\n\n" "#Frame Header\n" - "Frame Number : 8 bytes\n" - "SubFrame Number/ExpLength : 4 bytes\n" - "Packet Number : 4 bytes\n" - "Bunch ID : 8 bytes\n" - "Timestamp : 8 bytes\n" - "Module Id : 2 bytes\n" - "X Coordinate : 2 bytes\n" - "Y Coordinate : 2 bytes\n" - "Z Coordinate : 2 bytes\n" - "Debug : 4 bytes\n" - "Round Robin Number : 2 bytes\n" - "Detector Type : 1 byte\n" - "Header Version : 1 byte\n" + "Frame Number : 8 bytes\n" + "SubFrame Number/ExpLength : 4 bytes\n" + "Packet Number : 4 bytes\n" + "Bunch ID : 8 bytes\n" + "Timestamp : 8 bytes\n" + "Module Id : 2 bytes\n" + "X Coordinate : 2 bytes\n" + "Y Coordinate : 2 bytes\n" + "Z Coordinate : 2 bytes\n" + "Debug : 4 bytes\n" + "Round Robin Number : 2 bytes\n" + "Detector Type : 1 byte\n" + "Header Version : 1 byte\n" + "Packets Caught Mask : 64 bytes\n" , version, dr, @@ -163,14 +172,16 @@ class BinaryFileStatic { size, nPixelsX, nPixelsY, + maxf, (long long int)nf, (long long int)acquisitionTime, (long long int)subexposuretime, + (long long int)subperiod, (long long int)acquisitionPeriod, ctime(&t)); - if (strlen(message) > MAX_STR_LENGTH) { + if (strlen(message) > MAX_MASTER_FILE_LENGTH) { cprintf(RED,"Master File Size %d is greater than max str size %d\n", - (int)strlen(message), MAX_STR_LENGTH); + (int)strlen(message), MAX_MASTER_FILE_LENGTH); return 1; } diff --git a/slsReceiverSoftware/include/DataProcessor.h b/slsReceiverSoftware/include/DataProcessor.h index db559e0d2..055cdff5e 100644 --- a/slsReceiverSoftware/include/DataProcessor.h +++ b/slsReceiverSoftware/include/DataProcessor.h @@ -24,6 +24,8 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { /** * Constructor * Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofDataProcessors + * @param ind self index + * @param dtype detector type * @param f address of Fifo pointer * @param ftype pointer to file format type * @param fwenable file writer enable @@ -32,19 +34,17 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { * @param dr pointer to dynamic range * @param freq pointer to streaming frequency * @param timer pointer to timer if streaming frequency is random + * @param fp pointer to frame padding enable * @param dataReadycb pointer to data ready call back function + * @param dataModifyReadycb pointer to data ready call back function with modified * @param pDataReadycb pointer to arguments of data ready call back function. To write/stream a smaller size of processed data, change this value (only smaller value is allowed). */ - DataProcessor(Fifo*& f, fileFormat* ftype, bool fwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr, + DataProcessor(int ind, detectorType dtype, Fifo*& f, fileFormat* ftype, + bool fwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr, uint32_t* freq, uint32_t* timer, - void (*dataReadycb)(uint64_t, uint32_t, uint32_t, uint64_t, - uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, - uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, void*), - void (*dataModifyReadycb)(uint64_t, uint32_t, uint32_t, uint64_t, - uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, - uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t &, void*), + bool* fp, + void (*dataReadycb)(char*, char*, uint32_t, void*), + void (*dataModifyReadycb)(char*, char*, uint32_t &, void*), void *pDataReadycb); /** @@ -54,32 +54,13 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { ~DataProcessor(); - //*** static functions *** - /** - * Get ErrorMask - * @return ErrorMask - */ - static uint64_t GetErrorMask(); - - /** - * Get RunningMask - * @return RunningMask - */ - static uint64_t GetRunningMask(); - - /** - * Reset RunningMask - */ - static void ResetRunningMask(); - - /** - * Set Silent Mode - * @param mode 1 sets 0 unsets - */ - static void SetSilentMode(bool mode); - - //*** non static functions *** //*** getters *** + /** + * Returns if the thread is currently running + * @returns true if thread is running, else false + */ + bool IsRunning(); + /** * Get acquisition started flag * @return acquisition started flag @@ -172,30 +153,35 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { * Set up file writer object and call backs * @param fwe file write enable * @param nd pointer to number of detectors in each dimension + * @param maxf pointer to max frames per file * @param fname pointer to file name prefix * @param fpath pointer to file path * @param findex pointer to file index * @param owenable pointer to over write enable * @param dindex pointer to detector index - * @param nunits pointer to number of theads/ units per detector + * @param nunits pointer to number of threads/ units per detector * @param nf pointer to number of images in acquisition * @param dr pointer to dynamic range * @param portno pointer to udp port number * @param g address of GeneralData (Detector Data) pointer */ - void SetupFileWriter(bool fwe, int* nd, char* fname, char* fpath, uint64_t* findex, - bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, GeneralData* g = 0); + void SetupFileWriter(bool fwe, int* nd, uint32_t* maxf, char* fname, + char* fpath, uint64_t* findex, + bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, + uint32_t* portno, GeneralData* g = 0); /** * Create New File * @param en ten giga enable * @param nf number of frames * @param at acquisition time - * @param at sub exposure time + * @param st sub exposure time + * @param sp sub period * @param ap acquisition period * @returns OK or FAIL */ - int CreateNewFile(bool en, uint64_t nf, uint64_t at, uint64_t st, uint64_t ap); + int CreateNewFile(bool en, uint64_t nf, uint64_t at, uint64_t st, + uint64_t sp, uint64_t ap); /** * Closes files @@ -204,15 +190,22 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { /** * End of Acquisition + * @param anyPacketsCaught true if any packets are caught, else false * @param numf number of images caught */ - void EndofAcquisition(uint64_t numf); + void EndofAcquisition(bool anyPacketsCaught, uint64_t numf); /** * Update pixel dimensions in file writer */ void SetPixelDimension(); + /** + * Set Silent Mode + * @param mode 1 sets 0 unsets + */ + void SetSilentMode(bool mode); + private: @@ -222,12 +215,6 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { */ std::string GetType(); - /** - * Returns if the thread is currently running - * @returns true if thread is running, else false - */ - bool IsRunning(); - /** * Record First Indices (firstAcquisitionIndex, firstMeasurementIndex) * @param fnum frame index to record @@ -282,6 +269,12 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { */ bool CheckCount(); + /** + * Pad Missing Packets from the bit mask + * @param buf buffer + */ + void PadMissingPackets(char* buf); + /** * Processing Function (inserting gap pixels) eiger specific * @param buf pointer to image @@ -292,17 +285,8 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { /** type of thread */ static const std::string TypeName; - /** Total Number of DataProcessor Objects */ - static int NumberofDataProcessors; - - /** Mask of errors on any object eg.thread creation */ - static uint64_t ErrorMask; - - /** Mask of all listener objects running */ - static uint64_t RunningMask; - - /** mutex to update static items among objects (threads)*/ - static pthread_mutex_t Mutex; + /** Object running status */ + bool runningFlag; /** GeneralData (Detector Data) object */ const GeneralData* generalData; @@ -310,11 +294,11 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { /** Fifo structure */ Fifo* fifo; - /** Silent Mode */ - static bool SilentMode; - //individual members + /** Detector Type */ + detectorType myDetectorType; + /** File writer implemented as binary or hdf5 File */ File* file; @@ -354,7 +338,6 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { - //acquisition start /** Aquisition Started flag */ bool acquisitionStartedFlag; @@ -380,55 +363,32 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject { uint64_t currentFrameIndex; + /** Silent Mode */ + bool silentMode; + + /** frame padding */ + bool* framePadding; //call back /** * Call back for raw data * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format + * sls_receiver_header frame metadata * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes. */ - void (*rawDataReadyCallBack)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + void (*rawDataReadyCallBack)(char*, char*, uint32_t, void*); /** * Call back for raw data (modified) * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format + * sls_receiver_header frame metadata * dataPointer is the pointer to the data * revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value). */ - void (*rawDataModifyReadyCallBack)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + void (*rawDataModifyReadyCallBack)(char*, char*, uint32_t &, void*); void *pRawDataReady; diff --git a/slsReceiverSoftware/include/DataStreamer.h b/slsReceiverSoftware/include/DataStreamer.h index a08183a1e..6b7f4a5ee 100644 --- a/slsReceiverSoftware/include/DataStreamer.h +++ b/slsReceiverSoftware/include/DataStreamer.h @@ -20,12 +20,15 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { /** * Constructor * Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofDataStreamers + * @param ind self index * @param f address of Fifo pointer * @param dr pointer to dynamic range * @param sEnable pointer to short frame enable * @param fi pointer to file index + * @param fd flipped data enable for x and y dimensions + * @param ajh additional json header */ - DataStreamer(Fifo*& f, uint32_t* dr, int* sEnable, uint64_t* fi); + DataStreamer(int ind, Fifo*& f, uint32_t* dr, int* sEnable, uint64_t* fi, int* fd, char* ajh); /** * Destructor @@ -33,34 +36,12 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { */ ~DataStreamer(); - - //*** static functions *** - /** - * Get RunningMask - * @return RunningMask - */ - static uint64_t GetErrorMask(); - - /** - * Get RunningMask - * @return RunningMask - */ - static uint64_t GetRunningMask(); - - /** - * Reset RunningMask - */ - static void ResetRunningMask(); - - /** - * Set Silent Mode - * @param mode 1 sets 0 unsets - */ - static void SetSilentMode(bool mode); - - //*** non static functions *** //*** getters *** - + /** + * Returns if the thread is currently running + * @returns true if thread is running, else false + */ + bool IsRunning(); //*** setters *** @@ -105,12 +86,12 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { /** * Creates Zmq Sockets + * (throws an exception if it couldnt create zmq sockets) * @param nunits pointer to number of theads/ units per detector * @param port streaming port start index * @param srcip streaming source ip - * @return OK or FAIL */ - int CreateZmqSockets(int* nunits, uint32_t port, const char* srcip); + void CreateZmqSockets(int* nunits, uint32_t port, const char* srcip); /** * Shuts down and deletes Zmq Sockets @@ -121,7 +102,13 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { * Restream stop dummy packet * @return OK or FAIL */ - int restreamStop(); + int RestreamStop(); + + /** + * Set Silent Mode + * @param mode 1 sets 0 unsets + */ + void SetSilentMode(bool mode); private: @@ -131,12 +118,6 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { */ std::string GetType(); - /** - * Returns if the thread is currently running - * @returns true if thread is running, else false - */ - bool IsRunning(); - /** * Record First Indices (firstAcquisitionIndex, firstMeasurementIndex) * @param fnum frame index to record @@ -165,29 +146,20 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { /** * Create and send Json Header - * @param header header of image + * @param rheader header of image * @param size data size (could have been modified in call back) * @param nx number of pixels in x dim * @param ny number of pixels in y dim * @param dummy true if its a dummy header * @returns 0 if error, else 1 */ - int SendHeader(sls_detector_header* header, uint32_t size = 0, uint32_t nx = 0, uint32_t ny = 0, bool dummy = true); + int SendHeader(sls_receiver_header* rheader, uint32_t size = 0, uint32_t nx = 0, uint32_t ny = 0, bool dummy = true); /** type of thread */ static const std::string TypeName; - /** Total Number of DataStreamer Objects */ - static int NumberofDataStreamers; - - /** Mask of errors on any object eg.thread creation */ - static uint64_t ErrorMask; - - /** Mask of all listener objects running */ - static uint64_t RunningMask; - - /** mutex to update static items among objects (threads)*/ - static pthread_mutex_t Mutex; + /** Object running status */ + bool runningFlag; /** GeneralData (Detector Data) object */ const GeneralData* generalData; @@ -195,9 +167,6 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { /** Fifo structure */ Fifo* fifo; - /** Silent Mode */ - static bool SilentMode; - /** ZMQ Socket - Receiver to Client */ @@ -229,5 +198,14 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { /** Complete buffer used for roi, eg. shortGotthard */ char* completeBuffer; + + /** flipped data across both dimensions enable */ + int* flippedData; + + /** additional json header */ + char* additionJsonHeader; + + /** Silent Mode */ + bool silentMode; }; diff --git a/slsReceiverSoftware/include/Fifo.h b/slsReceiverSoftware/include/Fifo.h index df02c2d04..5fad6a3cc 100644 --- a/slsReceiverSoftware/include/Fifo.h +++ b/slsReceiverSoftware/include/Fifo.h @@ -20,11 +20,11 @@ class Fifo : private virtual slsReceiverDefs { /** * Constructor * Calls CreateFifos that creates fifos and allocates memory + * @param ind self index * @param fifoItemSize size of each fifo item * @param depth fifo depth - * @param success true if successful, else false */ - Fifo(uint32_t fifoItemSize, uint32_t depth, bool &success); + Fifo(int ind, uint32_t fifoItemSize, uint32_t depth); /** * Destructor @@ -88,9 +88,6 @@ class Fifo : private virtual slsReceiverDefs { void DestroyFifos(); - /** Total Number of Fifo Class Objects */ - static int NumberofFifoClassObjects; - /** Self Index */ int index; diff --git a/slsReceiverSoftware/include/File.h b/slsReceiverSoftware/include/File.h index cf024bc26..375f39a78 100644 --- a/slsReceiverSoftware/include/File.h +++ b/slsReceiverSoftware/include/File.h @@ -21,7 +21,7 @@ class File : private virtual slsReceiverDefs { * Constructor * creates the File Writer * @param ind self index - * @param maxf max frames per file + * @param maxf pointer to max frames per file * @param nd pointer to number of detectors in each dimension * @param fname pointer to file name prefix * @param fpath pointer to file path @@ -34,7 +34,7 @@ class File : private virtual slsReceiverDefs { * @param portno pointer to udp port number for logging * @param smode pointer to silent mode */ - File(int ind, uint32_t maxf, + File(int ind, uint32_t* maxf, int* nd, char* fname, char* fpath, uint64_t* findex, bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, bool* smode); @@ -64,6 +64,7 @@ class File : private virtual slsReceiverDefs { /** * Get Member Pointer Values before the object is destroyed * @param nd pointer to number of detectors in each dimension + * @param maxf pointer to max frames per file * @param fname pointer to file name prefix * @param fpath pointer to file path * @param findex pointer to file index @@ -74,22 +75,18 @@ class File : private virtual slsReceiverDefs { * @param dr pointer to dynamic range * @param portno pointer to dynamic range */ - void GetMemberPointerValues(int* nd, char*& fname, char*& fpath, uint64_t*& findex, bool*& owenable, + void GetMemberPointerValues(int* nd, uint32_t*& maxf, char*& fname, char*& fpath, + uint64_t*& findex, bool*& owenable, int*& dindex, int*& nunits, uint64_t*& nf, uint32_t*& dr, uint32_t*& portno); - /** - * Set Max frames per file - * @param maxf maximum frames per file - */ - void SetMaxFramesPerFile(uint32_t maxf); - /** * Create file * @param fnum current frame index to include in file name * @returns OK or FAIL */ virtual int CreateFile(uint64_t fnum){ - cprintf(RED,"This is a generic function CreateFile that should be overloaded by a derived class\n"); + cprintf(RED,"This is a generic function CreateFile that should be " + "overloaded by a derived class\n"); return OK; } @@ -97,14 +94,16 @@ class File : private virtual slsReceiverDefs { * Close Current File */ virtual void CloseCurrentFile() { - cprintf(RED,"This is a generic function CloseCurrentFile that should be overloaded by a derived class\n"); + cprintf(RED,"This is a generic function CloseCurrentFile that should be " + "overloaded by a derived class\n"); } /** * Close Files */ virtual void CloseAllFiles() { - cprintf(RED,"This is a generic function that should be overloaded by a derived class\n"); + cprintf(RED,"This is a generic function that should be overloaded " + "by a derived class\n"); } /** @@ -115,7 +114,8 @@ class File : private virtual slsReceiverDefs { * @param OK or FAIL */ virtual int WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t nump) { - cprintf(RED,"This is a generic function WriteToFile that should be overloaded by a derived class\n"); + cprintf(RED,"This is a generic function WriteToFile that " + "should be overloaded by a derived class\n"); return FAIL; } @@ -126,13 +126,16 @@ class File : private virtual slsReceiverDefs { * @param nx number of pixels in x direction * @param ny number of pixels in y direction * @param at acquisition time - * @param at sub exposure time + * @param st sub exposure time + * @param sp sub period * @param ap acquisition period * @returns OK or FAIL */ virtual int CreateMasterFile(bool en, uint32_t size, - uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t ap) { - cprintf(RED,"This is a generic function CreateMasterFile that should be overloaded by a derived class\n"); + uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, + uint64_t sp, uint64_t ap) { + cprintf(RED,"This is a generic function CreateMasterFile that " + "should be overloaded by a derived class\n"); return OK; } @@ -143,15 +146,18 @@ class File : private virtual slsReceiverDefs { * @param ny number of pixels in y direction */ virtual void SetNumberofPixels(uint32_t nx, uint32_t ny) { - cprintf(RED,"This is a generic function SetNumberofPixels that should be overloaded by a derived class\n"); + cprintf(RED,"This is a generic function SetNumberofPixels that " + "should be overloaded by a derived class\n"); } /** * End of Acquisition + * @param anyPacketsCaught true if any packets are caught, else false * @param numf number of images caught */ - virtual void EndofAcquisition(uint64_t numf) { - cprintf(RED,"This is a generic function EndofAcquisition that should be overloaded by a derived class\n"); + virtual void EndofAcquisition(bool anyPacketsCaught, uint64_t numf) { + cprintf(RED,"This is a generic function EndofAcquisition that " + "should be overloaded by a derived class\n"); } protected: @@ -163,7 +169,7 @@ class File : private virtual slsReceiverDefs { int index; /** Maximum frames per file */ - uint32_t maxFramesPerFile; + uint32_t* maxFramesPerFile; /** Master File Name */ std::string masterFileName; diff --git a/slsReceiverSoftware/include/GeneralData.h b/slsReceiverSoftware/include/GeneralData.h index 6809b156c..82a9ae795 100644 --- a/slsReceiverSoftware/include/GeneralData.h +++ b/slsReceiverSoftware/include/GeneralData.h @@ -83,6 +83,9 @@ public: /** if standard header implemented in firmware */ bool standardheader; + /** default udp socket buffer size */ + uint32_t defaultUdpSocketBufferSize; + @@ -109,7 +112,8 @@ public: nPixelsXComplete(0), nPixelsYComplete(0), imageSizeComplete(0), - standardheader(false) + standardheader(false), + defaultUdpSocketBufferSize(RECEIVE_SOCKET_BUFFER_SIZE) {}; /** Destructor */ @@ -214,6 +218,7 @@ public: FILE_LOG(logDEBUG) << "Complete Pixels Y: " << nPixelsYComplete; FILE_LOG(logDEBUG) << "Complete Image Size: " << imageSizeComplete; FILE_LOG(logDEBUG) << "Standard Header: " << standardheader; + FILE_LOG(logDEBUG) << "UDP Socket Buffer Size: " << defaultUdpSocketBufferSize; }; }; @@ -236,7 +241,7 @@ class GotthardData : public GeneralData { frameIndexOffset = 1; packetIndexMask = 1; maxFramesPerFile = MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 50000; }; }; @@ -258,7 +263,7 @@ class ShortGotthardData : public GeneralData { imageSize = dataSize*packetsPerFrame; frameIndexMask = 0xFFFFFFFF; maxFramesPerFile = SHORT_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 50000; nPixelsXComplete = 1280; nPixelsYComplete = 1; @@ -322,7 +327,7 @@ class PropixData : public GeneralData { frameIndexOffset = 1; packetIndexMask = 1; maxFramesPerFile = MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 50000; }; }; @@ -349,7 +354,7 @@ class Moench02Data : public GeneralData { frameIndexOffset = 8; packetIndexMask = 0xFF; maxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 2500; }; @@ -381,7 +386,7 @@ class Moench03Data : public GeneralData { frameIndexOffset = (6+8); packetIndexMask = 0xFFFFFFFF; maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 2500; }; }; @@ -419,7 +424,7 @@ private: imageSize = nPixelsX * nPixelsY * 2; frameIndexMask = 0xFFFFFF; maxFramesPerFile = JFCTB_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 2500; }; @@ -491,9 +496,10 @@ class JungfrauData : public GeneralData { packetsPerFrame = 128; imageSize = dataSize*packetsPerFrame; maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 2500; standardheader = true; + defaultUdpSocketBufferSize = (2000 * 1024 * 1024); }; }; @@ -514,7 +520,7 @@ class EigerData : public GeneralData { packetsPerFrame = 256; imageSize = dataSize*packetsPerFrame; maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_detector_header); + fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsReceiverDefs::sls_receiver_header); defaultFifoDepth = 100; threadsPerReceiver = 2; headerPacketSize = 40; diff --git a/slsReceiverSoftware/include/HDF5File.h b/slsReceiverSoftware/include/HDF5File.h index 200d5c0d2..2e0a44354 100644 --- a/slsReceiverSoftware/include/HDF5File.h +++ b/slsReceiverSoftware/include/HDF5File.h @@ -17,7 +17,6 @@ #ifndef H5_NO_NAMESPACE using namespace H5; #endif -#include class HDF5File : private virtual slsReceiverDefs, public File, public HDF5FileStatic { @@ -27,7 +26,7 @@ class HDF5File : private virtual slsReceiverDefs, public File, public HDF5FileSt * Constructor * creates the File Writer * @param ind self index - * @param maxf max frames per file + * @param maxf pointer to max frames per file * @param nd pointer to number of detectors in each dimension * @param fname pointer to file name prefix * @param fpath pointer to file path @@ -42,7 +41,7 @@ class HDF5File : private virtual slsReceiverDefs, public File, public HDF5FileSt * @param ny number of pixels in y direction * @param smode pointer to silent mode */ - HDF5File(int ind, uint32_t maxf, + HDF5File(int ind, uint32_t* maxf, int* nd, char* fname, char* fpath, uint64_t* findex, bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, uint32_t nx, uint32_t ny, @@ -99,18 +98,21 @@ class HDF5File : private virtual slsReceiverDefs, public File, public HDF5FileSt * @param nx number of pixels in x direction * @param ny number of pixels in y direction * @param at acquisition time - * @param at sub exposure time + * @param st sub exposure time + * @param sp sub period * @param ap acquisition period * @returns OK or FAIL */ int CreateMasterFile(bool en, uint32_t size, - uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t ap); + uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp, + uint64_t ap); /** * End of Acquisition + * @param anyPacketsCaught true if any packets are caught, else false * @param numf number of images caught */ - void EndofAcquisition(uint64_t numf); + void EndofAcquisition(bool anyPacketsCaught, uint64_t numf); /** * Create Virtual File @@ -171,11 +173,20 @@ class HDF5File : private virtual slsReceiverDefs, public File, public HDF5FileSt /** Number of files in an acquisition - to verify need of virtual file */ int numFilesinAcquisition; + /** parameter names */ + vector parameterNames; + + /** parameter data types */ + vector parameterDataTypes; + /** Dataspace of parameters */ DataSpace* dataspace_para; /** Dataset array for parameters */ - DataSet* dataset_para[HDF5FileStatic::NumberofParameters]; + vector dataset_para; + + /** Number of Images (including extended during acquisition) */ + uint64_t extNumImages; }; #endif diff --git a/slsReceiverSoftware/include/HDF5FileStatic.h b/slsReceiverSoftware/include/HDF5FileStatic.h index d66c776bf..457f2347c 100644 --- a/slsReceiverSoftware/include/HDF5FileStatic.h +++ b/slsReceiverSoftware/include/HDF5FileStatic.h @@ -18,9 +18,11 @@ using namespace H5; #include #include +#include #include #include //malloc #include +#include //memset using namespace std; class HDF5FileStatic: public virtual slsReceiverDefs { @@ -51,7 +53,7 @@ public: { ostringstream osfn; osfn << fpath << "/" << fnameprefix; - if (dindex >= 0) osfn << "_d" << ((unitindex >= numunits) ? unitindex : (dindex * numunits + unitindex)); //if unit index > numunits, all receivers in one program (userReceiver) + if (dindex >= 0) osfn << "_d" << (dindex * numunits + unitindex); if (frindexenable) osfn << "_f" << setfill('0') << setw(12) << fnum; osfn << "_" << findex; osfn << ".h5"; @@ -112,7 +114,7 @@ public: } } catch(Exception error) { cprintf(RED,"Error in closing HDF5 handles of index %d\n", ind); - error.printError(); + error.printErrorStack(); } } @@ -130,7 +132,7 @@ public: } } catch(Exception error) { cprintf(RED,"Error in closing master HDF5 handles\n"); - error.printError(); + error.printErrorStack(); } } @@ -177,7 +179,7 @@ public: } catch(Exception error){ cprintf(RED,"Error in writing to file in object %d\n",ind); - error.printError(); + error.printErrorStack(); return 1; } return 0; @@ -187,32 +189,98 @@ public: /** * Write Parameter Arrays as datasets (to virtual file) + * @param ind self index + * @param dspace_para parameter dataspace + * @param fnum current frame number + * @param dset_para vector or dataset pointers of parameters + * @param rheader sls_receiver_header pointer + * @param parameterDataTypes parameter datatypes */ static int WriteParameterDatasets(int ind, DataSpace* dspace_para, uint64_t fnum, - DataSet* dset_para[],sls_detector_header* header) + vector dset_para,sls_receiver_header* rheader, + vector parameterDataTypes) { + sls_detector_header header = rheader->detHeader; hsize_t count[1] = {1}; hsize_t start[1] = {fnum}; try{ Exception::dontPrint(); //to handle errors dspace_para->selectHyperslab( H5S_SELECT_SET, count, start); DataSpace memspace(H5S_SCALAR); - dset_para[0]->write(&header->frameNumber, ParameterDataTypes[0], memspace, *dspace_para); - dset_para[1]->write(&header->expLength, ParameterDataTypes[1], memspace, *dspace_para); - dset_para[2]->write(&header->packetNumber, ParameterDataTypes[2], memspace, *dspace_para); - dset_para[3]->write(&header->bunchId, ParameterDataTypes[3], memspace, *dspace_para); - dset_para[4]->write(&header->timestamp, ParameterDataTypes[4], memspace, *dspace_para); - dset_para[5]->write(&header->modId, ParameterDataTypes[5], memspace, *dspace_para); - dset_para[6]->write(&header->xCoord, ParameterDataTypes[6], memspace, *dspace_para); - dset_para[7]->write(&header->yCoord, ParameterDataTypes[7], memspace, *dspace_para); - dset_para[8]->write(&header->zCoord, ParameterDataTypes[8], memspace, *dspace_para); - dset_para[9]->write(&header->debug, ParameterDataTypes[9], memspace, *dspace_para); - dset_para[10]->write(&header->roundRNumber, ParameterDataTypes[10], memspace, *dspace_para); - dset_para[11]->write(&header->detType, ParameterDataTypes[11], memspace, *dspace_para); - dset_para[12]->write(&header->version, ParameterDataTypes[12], memspace, *dspace_para); + dset_para[0]->write(&header.frameNumber, parameterDataTypes[0], memspace, *dspace_para); + dset_para[1]->write(&header.expLength, parameterDataTypes[1], memspace, *dspace_para); + dset_para[2]->write(&header.packetNumber, parameterDataTypes[2], memspace, *dspace_para); + dset_para[3]->write(&header.bunchId, parameterDataTypes[3], memspace, *dspace_para); + dset_para[4]->write(&header.timestamp, parameterDataTypes[4], memspace, *dspace_para); + dset_para[5]->write(&header.modId, parameterDataTypes[5], memspace, *dspace_para); + dset_para[6]->write(&header.xCoord, parameterDataTypes[6], memspace, *dspace_para); + dset_para[7]->write(&header.yCoord, parameterDataTypes[7], memspace, *dspace_para); + dset_para[8]->write(&header.zCoord, parameterDataTypes[8], memspace, *dspace_para); + dset_para[9]->write(&header.debug, parameterDataTypes[9], memspace, *dspace_para); + dset_para[10]->write(&header.roundRNumber, parameterDataTypes[10], memspace, *dspace_para); + dset_para[11]->write(&header.detType, parameterDataTypes[11], memspace, *dspace_para); + dset_para[12]->write(&header.version, parameterDataTypes[12], memspace, *dspace_para); + + // contiguous bitset + if (sizeof(sls_bitset) == sizeof(bitset_storage)) { + dset_para[13]->write((char*)&(rheader->packetsMask), parameterDataTypes[13], memspace, *dspace_para); + } + + // not contiguous bitset + else { + // get contiguous representation of bit mask + bitset_storage storage; + memset(storage, 0 , sizeof(bitset_storage)); + sls_bitset bits = rheader->packetsMask; + for (int i = 0; i < MAX_NUM_PACKETS; ++i) + storage[i >> 3] |= (bits[i] << (i & 7)); + // write bitmask + dset_para[13]->write((char*)storage, parameterDataTypes[13], memspace, *dspace_para); + } } catch(Exception error){ cprintf(RED,"Error in writing parameters to file in object %d\n",ind); + error.printErrorStack(); + return 1; + } + return 0; + } + + + + /** + * Extend datasets in #images dimension (x dimension) + * @param ind self index + * @param dpace data space pointer address + * @param dset data set pointer + * @param dspace_para parameter dataspace address pointer + * @param dset dataset parameter pointer + * @param initialNumImages initial number of images + * @returns 0 for success and 1 for fail + */ + static int ExtendDataset(int ind, DataSpace*& dspace, DataSet* dset, + DataSpace*& dspace_para, vector dset_para, + uint64_t initialNumImages) { + try{ + Exception::dontPrint(); //to handle errors + + hsize_t dims[3]; + dspace->getSimpleExtentDims(dims); + dims[0] += initialNumImages; + + dset->extend(dims); + delete dspace; + dspace = new DataSpace(dset->getSpace()); + + hsize_t dims_para[1] = {dims[0]}; + for (unsigned int i = 0; i < dset_para.size(); ++i) + dset_para[i]->extend(dims_para); + delete dspace_para; + dspace_para = new DataSpace(dset_para[0]->getSpace()); + + } + catch(Exception error){ + cprintf(RED,"Error in extending dataset in object %d\n",ind); error.printError(); return 1; } @@ -230,15 +298,20 @@ public: * @param nx number of pixels in x direction * @param ny number of pixels in y direction * @param nf number of images + * @param maxf maximum frames per file * @param acquisitionTime acquisition time * @param subexposuretime sub exposure time + * @param subperiod sub period * @param acquisitionPeriod acquisition period * @param version version of software for hdf5 writing * @returns 0 for success and 1 for fail */ static int CreateMasterDataFile(H5File*& fd, string fname, bool owenable, - uint32_t dr, bool tenE, uint32_t size, uint32_t nPixelsx, uint32_t nPixelsy, uint64_t nf, - uint64_t acquisitionTime, uint64_t subexposuretime, uint64_t acquisitionPeriod, double version) + uint32_t dr, bool tenE, uint32_t size, + uint32_t nPixelsx, uint32_t nPixelsy, uint64_t nf, + uint32_t maxf, + uint64_t acquisitionTime, uint64_t subexposuretime, + uint64_t subperiod, uint64_t acquisitionPeriod, double version) { try { Exception::dontPrint(); //to handle errors @@ -246,9 +319,13 @@ public: FileAccPropList flist; flist.setFcloseDegree(H5F_CLOSE_STRONG); if(!owenable) - fd = new H5File( fname.c_str(), H5F_ACC_EXCL, NULL, flist ); + fd = new H5File( fname.c_str(), H5F_ACC_EXCL, + FileCreatPropList::DEFAULT, + flist ); else - fd = new H5File( fname.c_str(), H5F_ACC_TRUNC, NULL, flist ); + fd = new H5File( fname.c_str(), H5F_ACC_TRUNC, + FileCreatPropList::DEFAULT, + flist ); //variables DataSpace dataspace = DataSpace (H5S_SCALAR); @@ -297,6 +374,10 @@ public: dataset = group5.createDataSet ( "number of pixels in y axis", PredType::NATIVE_INT, dataspace ); dataset.write ( &nPixelsy, PredType::NATIVE_INT); + //Maximum frames per file + dataset = group5.createDataSet ( "maximum frames per file", PredType::NATIVE_INT, dataspace ); + dataset.write ( &maxf, PredType::NATIVE_INT); + //Total Frames dataset = group5.createDataSet ( "total frames", PredType::STD_U64LE, dataspace ); dataset.write ( &nf, PredType::STD_U64LE); @@ -313,6 +394,12 @@ public: attribute = dataset.createAttribute("unit",strdatatype, dataspace); attribute.write(strdatatype, string("ns")); + //SubPeriod + dataset = group5.createDataSet ( "sub period", PredType::STD_U64LE, dataspace ); + dataset.write ( &subperiod, PredType::STD_U64LE); + attribute = dataset.createAttribute("unit",strdatatype, dataspace); + attribute.write(strdatatype, string("ns")); + //Period dataset = group5.createDataSet ( "acquisition period", PredType::STD_U64LE, dataspace ); dataset.write ( &acquisitionPeriod, PredType::STD_U64LE); @@ -328,7 +415,7 @@ public: } catch(Exception error) { cprintf(RED,"Error in creating master HDF5 handles\n"); - error.printError(); + error.printErrorStack(); return 1; } return 0; @@ -340,12 +427,12 @@ public: * Create File * @param ind object index for debugging * @param owenable overwrite enable - * @param numf number of images * @param fname complete file name * @param frindexenable frame index enable * @param fnum current image number - * @param nx number of pixels in x dir - * @param ny number of pixels in y dir + * @param nDimx number of pixels in x dim (#frames) + * @param nDimy number of pixels in y dim (height y dir) + * @param nDimz number of pixels in z dim (width x dir) * @param dtype data type * @param fd file pointer * @param dspace dataspace pointer @@ -353,19 +440,18 @@ public: * @param version version of software for hdf5 writing * @param maxchunkedimages maximum chunked images * @param dspace_para dataspace of parameters - * @param para1 parameter 1 name - * @param dset_para1 dataset of parameter 1 - * @param dtype_para1 datatype of parameter 1 - * @param para2 parameter 2 name - * @param dset_para2 dataset of parameter 2 - * @param dtype_para2 datatype of parameter 2 + * @param dset_para vector of datasets of parameters + * @param parameterNames parameter names + * @param parameterDataTypes parameter datatypes * @returns 0 for success and 1 for fail */ static int CreateDataFile(int ind, bool owenable, string fname, bool frindexenable, uint64_t fnum, uint64_t nDimx, uint32_t nDimy, uint32_t nDimz, DataType dtype, H5File*& fd, DataSpace*& dspace, DataSet*& dset, double version, uint64_t maxchunkedimages, - DataSpace*& dspace_para, DataSet* dset_para[]) + DataSpace*& dspace_para, vector& dset_para, + vector parameterNames, + vector parameterDataTypes) { try { Exception::dontPrint(); //to handle errors @@ -374,9 +460,13 @@ public: FileAccPropList fapl; fapl.setFcloseDegree(H5F_CLOSE_STRONG); if(!owenable) - fd = new H5File( fname.c_str(), H5F_ACC_EXCL, NULL,fapl ); + fd = new H5File( fname.c_str(), H5F_ACC_EXCL, + FileCreatPropList::DEFAULT, + fapl ); else - fd = new H5File( fname.c_str(), H5F_ACC_TRUNC, NULL, fapl ); + fd = new H5File( fname.c_str(), H5F_ACC_TRUNC, + FileCreatPropList::DEFAULT, + fapl ); //attributes - version double dValue=version; @@ -386,7 +476,9 @@ public: //dataspace hsize_t srcdims[3] = {nDimx, nDimy, nDimz}; - dspace = new DataSpace (3,srcdims); + hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz}; + dspace = new DataSpace (3,srcdims,srcdimsmax); + //dataset name ostringstream osfn; @@ -395,24 +487,34 @@ public: string dsetname = osfn.str(); //dataset - //chunked dataset if greater than max_chunked_images - if(nDimx > maxchunkedimages){ - DSetCreatPropList plist; - hsize_t chunk_dims[3] ={maxchunkedimages, nDimy, nDimz}; - plist.setChunk(3, chunk_dims); - dset = new DataSet (fd->createDataSet(dsetname.c_str(), dtype, *dspace, plist)); - }else - dset = new DataSet (fd->createDataSet(dsetname.c_str(), dtype, *dspace)); + //fill value + DSetCreatPropList plist; + int fill_value = -1; + plist.setFillValue(dtype, &fill_value); + // always create chunked dataset as unlimited is only supported with chunked layout + hsize_t chunk_dims[3] ={maxchunkedimages, nDimy, nDimz}; + plist.setChunk(3, chunk_dims); + dset = new DataSet (fd->createDataSet(dsetname.c_str(), dtype, *dspace, plist)); //create parameter datasets hsize_t dims[1] = {nDimx}; - dspace_para = new DataSpace (1,dims); - for (int i = 0; i < NumberofParameters; ++i) - dset_para[i] = new DataSet(fd->createDataSet(ParameterNames[i], ParameterDataTypes[i], *dspace_para)); + hsize_t dimsmax[1] = {H5S_UNLIMITED}; + dspace_para = new DataSpace (1,dims,dimsmax); + + // always create chunked dataset as unlimited is only supported with chunked layout + DSetCreatPropList paralist; + hsize_t chunkpara_dims[3] = {maxchunkedimages}; + paralist.setChunk(1, chunkpara_dims); + + for (unsigned int i = 0; i < parameterNames.size(); ++i){ + DataSet* ds = new DataSet(fd->createDataSet(parameterNames[i], + parameterDataTypes[i], *dspace_para, paralist)); + dset_para.push_back(ds); + } } catch(Exception error){ cprintf(RED,"Error in creating HDF5 handles in object %d\n",ind); - error.printError(); + error.printErrorStack(); fd->close(); return 1; } @@ -434,16 +536,14 @@ public: * @param maxFramesPerFile maximum frames per file * @param numf number of frames caught * @param srcDataseName source dataset name - * @param srcP1DatasetName source parameter 1 dataset name - * @param srcP2DatasetName source parameter 2 dataset name * @param dataType datatype of data dataset - * @param p1DataType datatype of parameter 1 - * @param p2DataType datatype of parameter 2 * @param numDety number of readouts in Y dir * @param numDetz number of readouts in Z dir * @param nDimy number of objects in y dimension in source file (Number of pixels in y dir) * @param nDimz number of objects in z dimension in source file (Number of pixels in x dir) * @param version version of software for hdf5 writing + * @param parameterNames parameter names + * @param parameterDataTypes parameter datatypes * @returns 0 for success and 1 for fail */ static int CreateVirtualDataFile( @@ -453,7 +553,9 @@ public: uint32_t maxFramesPerFile, uint64_t numf, string srcDataseName, DataType dataType, int numDety, int numDetz, uint32_t nDimy, uint32_t nDimz, - double version) + double version, + vector parameterNames, + vector parameterDataTypes) { //virtual names string virtualFileName = CreateVirtualFileName(fpath, fnameprefix, findex); @@ -462,52 +564,77 @@ public: //file hid_t dfal = H5Pcreate (H5P_FILE_ACCESS); if (dfal < 0) - return CloseFileOnError(fd, string("Error in creating file access property for virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating file access property for virtual file ") + + virtualFileName + string("\n")); if (H5Pset_fclose_degree (dfal, H5F_CLOSE_STRONG) < 0) - return CloseFileOnError(fd, string("Error in setting strong file close degree for virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in setting strong file close degree for virtual file ") + + virtualFileName + string("\n")); fd = H5Fcreate( virtualFileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, dfal); if (fd < 0) - return CloseFileOnError(fd, string("Error in creating virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating virtual file ") + virtualFileName + string("\n")); //attributes - version hid_t dataspace_attr = H5Screate (H5S_SCALAR); if (dataspace_attr < 0) - return CloseFileOnError(fd, string("Error in creating dataspace for attribute in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating dataspace for attribute in virtual file ") + + virtualFileName + string("\n")); hid_t attrid = H5Acreate2 (fd, "version", H5T_NATIVE_DOUBLE, dataspace_attr, H5P_DEFAULT, H5P_DEFAULT); if (attrid < 0) - return CloseFileOnError(fd, string("Error in creating attribute in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating attribute in virtual file ") + + virtualFileName + string("\n")); double attr_data = version; if (H5Awrite (attrid, H5T_NATIVE_DOUBLE, &attr_data) < 0) - return CloseFileOnError(fd, string("Error in writing attribute in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in writing attribute in virtual file ") + + virtualFileName + string("\n")); if (H5Aclose (attrid) < 0) - return CloseFileOnError(fd, string("Error in closing attribute in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in closing attribute in virtual file ") + + virtualFileName + string("\n")); //virtual dataspace hsize_t vdsdims[3] = {numf, numDety * nDimy, numDetz * nDimz}; hid_t vdsDataspace = H5Screate_simple(3, vdsdims ,NULL); if (vdsDataspace < 0) - return CloseFileOnError(fd, string("Error in creating virtual dataspace in virtual file ") + virtualFileName + string("\n")); - hsize_t vdsdims_para[2] = {numf, numDety * numDetz}; + return CloseFileOnError(fd, + string("Error in creating virtual dataspace in virtual file ") + + virtualFileName + string("\n")); + hsize_t vdsdims_para[2] = {numf, (unsigned int) numDety * numDetz}; hid_t vdsDataspace_para = H5Screate_simple(2, vdsdims_para, NULL); if (vdsDataspace_para < 0) - return CloseFileOnError(fd, string("Error in creating virtual dataspace (parameters) in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating virtual dataspace (parameters) in virtual file ") + + virtualFileName + string("\n")); //fill values hid_t dcpl = H5Pcreate (H5P_DATASET_CREATE); if (dcpl < 0) - return CloseFileOnError(fd, string("Error in creating file creation properties in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating file creation properties in virtual file ") + + virtualFileName + string("\n")); int fill_value = -1; if (H5Pset_fill_value (dcpl, GetDataTypeinC(dataType), &fill_value) < 0) - return CloseFileOnError(fd, string("Error in creating fill value in virtual file ") + virtualFileName + string("\n")); - hid_t dcpl_para[NumberofParameters]; - for (int i = 0; i < NumberofParameters; ++i) { + return CloseFileOnError(fd, + string("Error in creating fill value in virtual file ") + + virtualFileName + string("\n")); + hid_t dcpl_para[parameterNames.size()]; + for (unsigned int i = 0; i < parameterNames.size(); ++i) { dcpl_para[i] = H5Pcreate (H5P_DATASET_CREATE); if (dcpl_para[i] < 0) - return CloseFileOnError(fd, string("Error in creating file creation properties (parameters) in virtual file ") + virtualFileName + string("\n")); - if (H5Pset_fill_value (dcpl_para[i], GetDataTypeinC(ParameterDataTypes[i]), &fill_value) < 0) - return CloseFileOnError(fd, string("Error in creating fill value (parameters) in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating file creation properties (parameters) in virtual file ") + + virtualFileName + string("\n")); + if (H5Pset_fill_value (dcpl_para[i], GetDataTypeinC(parameterDataTypes[i]), &fill_value) < 0) + return CloseFileOnError(fd, + string("Error in creating fill value (parameters) in virtual file ") + + virtualFileName + string("\n")); } //hyperslab @@ -517,7 +644,8 @@ public: uint64_t framesSaved = 0; for (int j = 0; j < numMajorHyperslab; j++) { - uint64_t nDimx = ((numf - framesSaved) > maxFramesPerFile) ? maxFramesPerFile : (numf-framesSaved); + uint64_t nDimx = ((numf - framesSaved) > maxFramesPerFile) + ? maxFramesPerFile : (numf-framesSaved); hsize_t offset[3] = {framesSaved, 0, 0}; hsize_t count[3] = {nDimx, nDimy, nDimz}; hsize_t offset_para[2] = {framesSaved, 0}; @@ -531,7 +659,8 @@ public: error = true; break; } - if (H5Sselect_hyperslab (vdsDataspace_para, H5S_SELECT_SET, offset_para, NULL, count_para, NULL) < 0) { + if (H5Sselect_hyperslab (vdsDataspace_para, H5S_SELECT_SET, + offset_para, NULL, count_para, NULL) < 0) { cprintf(RED,"could not select hyperslab for parameters\n"); error = true; break; @@ -541,6 +670,14 @@ public: string srcFileName = HDF5FileStatic::CreateFileName(fpath, fnameprefix, findex, frindexenable, framesSaved, dindex, numunits, i); + // find relative path + string relative_srcFileName = srcFileName; + { + size_t i = srcFileName.rfind('/', srcFileName.length()); + if (i != string::npos) + relative_srcFileName = (srcFileName.substr(i+1, srcFileName.length() - i)); + } + //source dataset name ostringstream osfn; osfn << "/data"; @@ -549,23 +686,31 @@ public: //source dataspace hsize_t srcdims[3] = {nDimx, nDimy, nDimz}; - hid_t srcDataspace = H5Screate_simple(3, srcdims, NULL); + hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz}; + hid_t srcDataspace = H5Screate_simple(3, srcdims, srcdimsmax); if (srcDataspace < 0) - return CloseFileOnError(fd, string("Error in creating source dataspace in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating source dataspace in virtual file ") + + virtualFileName + string("\n")); hsize_t srcdims_para[1] = {nDimx}; - hid_t srcDataspace_para = H5Screate_simple(1, srcdims_para, NULL); + hsize_t srcdimsmax_para[1] = {H5S_UNLIMITED}; + hid_t srcDataspace_para = H5Screate_simple(1, srcdims_para, srcdimsmax_para); if (srcDataspace_para < 0) - return CloseFileOnError(fd, string("Error in creating source dataspace (parameters) in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating source dataspace (parameters) in virtual file ") + + virtualFileName + string("\n")); //mapping - if (H5Pset_virtual(dcpl, vdsDataspace, srcFileName.c_str(), srcDatasetName.c_str(), srcDataspace) < 0) { + if (H5Pset_virtual(dcpl, vdsDataspace, relative_srcFileName.c_str(), + srcDatasetName.c_str(), srcDataspace) < 0) { cprintf(RED,"could not set mapping for paramter 1\n"); error = true; break; } - for (int k = 0; k < NumberofParameters; ++k) { - if (H5Pset_virtual(dcpl_para[k], vdsDataspace_para, srcFileName.c_str(), ParameterNames[k], srcDataspace_para) < 0) { + for (unsigned int k = 0; k < parameterNames.size(); ++k) { + if (H5Pset_virtual(dcpl_para[k], vdsDataspace_para, relative_srcFileName.c_str(), + parameterNames[k], srcDataspace_para) < 0) { cprintf(RED,"could not set mapping for paramter %d\n", k); error = true; break; @@ -584,29 +729,37 @@ public: framesSaved += nDimx; } if (error) - return CloseFileOnError(fd, string("Error in mapping files in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in mapping files in virtual file ") + + virtualFileName + string("\n")); //dataset - string virtualDatasetName = string("/virtual_") + srcDataseName; - hid_t vdsdataset = H5Dcreate2 (fd, virtualDatasetName.c_str(), GetDataTypeinC(dataType), vdsDataspace, H5P_DEFAULT, dcpl, H5P_DEFAULT); + string virtualDatasetName = srcDataseName; + hid_t vdsdataset = H5Dcreate2 (fd, virtualDatasetName.c_str(), + GetDataTypeinC(dataType), vdsDataspace, H5P_DEFAULT, dcpl, H5P_DEFAULT); if (vdsdataset < 0) - return CloseFileOnError(fd, string("Error in creating virutal dataset in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating virutal dataset in virtual file ") + + virtualFileName + string("\n")); //virtual parameter dataset - for (int i = 0; i < NumberofParameters; ++i) { + for (unsigned int i = 0; i < parameterNames.size(); ++i) { hid_t vdsdataset_para = H5Dcreate2 (fd, - (string("/virtual_") + string (ParameterNames[i])).c_str(), - GetDataTypeinC(ParameterDataTypes[i]), vdsDataspace_para, H5P_DEFAULT, dcpl_para[i], H5P_DEFAULT); + parameterNames[i], + GetDataTypeinC(parameterDataTypes[i]), vdsDataspace_para, + H5P_DEFAULT, dcpl_para[i], H5P_DEFAULT); if (vdsdataset_para < 0) - return CloseFileOnError(fd, string("Error in creating virutal dataset (parameters) in virtual file ") + virtualFileName + string("\n")); + return CloseFileOnError(fd, + string("Error in creating virutal dataset (parameters) in virtual file ") + + virtualFileName + string("\n")); } //close H5Fclose(fd); fd = 0; //link - return LinkVirtualInMaster(masterFileName, virtualFileName, virtualDatasetName); + return LinkVirtualInMaster(masterFileName, virtualFileName, virtualDatasetName, parameterNames); } @@ -678,9 +831,13 @@ public: FileAccPropList fapl; fapl.setFcloseDegree(H5F_CLOSE_STRONG); if(!owenable) - newfd = new H5File( newFileName.c_str(), H5F_ACC_EXCL, NULL,fapl ); + newfd = new H5File( newFileName.c_str(), H5F_ACC_EXCL, + FileCreatPropList::DEFAULT, + fapl ); else - newfd = new H5File( newFileName.c_str(), H5F_ACC_TRUNC, NULL, fapl ); + newfd = new H5File( newFileName.c_str(), H5F_ACC_TRUNC, + FileCreatPropList::DEFAULT, + fapl ); //dataspace and dataset DataSpace* newDataspace; if (rank == 3) { @@ -697,7 +854,7 @@ public: oldfd->close(); } catch(Exception error){ cprintf(RED,"Error in copying virtual files\n"); - error.printError(); + error.printErrorStack(); free(data_out); oldfd->close(); newfd->close(); @@ -715,9 +872,11 @@ public: * @param masterFileName master file name * @param virtualfname virtual file name * @param virtualDatasetname virtual dataset name + * @param parameterNames parameter names * @returns 0 for success and 1 for fail */ - static int LinkVirtualInMaster(string masterFileName, string virtualfname, string virtualDatasetname) { + static int LinkVirtualInMaster(string masterFileName, string virtualfname, + string virtualDatasetname, vector parameterNames) { char linkname[100]; hid_t vfd = 0; @@ -739,6 +898,14 @@ public: return CloseFileOnError( vfd, string("Error in opening virtual file\n")); } + // find relative path + string relative_virtualfname = virtualfname; + { + size_t i = virtualfname.rfind('/', virtualfname.length()); + if (i != string::npos) + relative_virtualfname = (virtualfname.substr(i+1, virtualfname.length() - i)); + } + //**data dataset** hid_t vdset = H5Dopen2( vfd, virtualDatasetname.c_str(), H5P_DEFAULT); if (vdset < 0) { @@ -746,7 +913,7 @@ public: return CloseFileOnError( vfd, string("Error in opening virtual data dataset\n")); } sprintf(linkname, "/entry/data/%s",virtualDatasetname.c_str()); - if(H5Lcreate_external( virtualfname.c_str(), virtualDatasetname.c_str(), + if(H5Lcreate_external( relative_virtualfname.c_str(), virtualDatasetname.c_str(), mfd, linkname, H5P_DEFAULT, H5P_DEFAULT) < 0) { H5Fclose(mfd); mfd = 0; return CloseFileOnError( vfd, string("Error in creating link to data dataset\n")); @@ -754,14 +921,15 @@ public: H5Dclose(vdset); //**paramter datasets** - for (int i = 0; i < NumberofParameters; ++i){ - hid_t vdset_para = H5Dopen2( vfd, (string("/virtual_") + string (ParameterNames[i])).c_str(), H5P_DEFAULT); + for (unsigned int i = 0; i < parameterNames.size(); ++i){ + hid_t vdset_para = H5Dopen2( vfd, (string (parameterNames[i])).c_str(), H5P_DEFAULT); if (vdset_para < 0) { H5Fclose(mfd); mfd = 0; return CloseFileOnError( vfd, string("Error in opening virtual parameter dataset to create link\n")); } - sprintf(linkname, "/entry/data/%s",(string("/virtual_") + string (ParameterNames[i])).c_str()); - if(H5Lcreate_external( virtualfname.c_str(), (string("/virtual_") + string (ParameterNames[i])).c_str(), + sprintf(linkname, "/entry/data/%s",(string (parameterNames[i])).c_str()); + + if(H5Lcreate_external( relative_virtualfname.c_str(), (string (parameterNames[i])).c_str(), mfd, linkname, H5P_DEFAULT, H5P_DEFAULT) < 0) { H5Fclose(mfd); mfd = 0; return CloseFileOnError( vfd, string("Error in creating link to virtual parameter dataset\n")); @@ -803,18 +971,12 @@ public: else if (dtype == PredType::STD_U64LE) return H5T_STD_U64LE; else { - cprintf(RED, "Invalid Data type\n"); - return H5T_STD_U64LE; + hid_t s = H5Tcopy(H5T_C_S1); + H5Tset_size(s, MAX_NUM_PACKETS); + return s; } } - - static const int NumberofParameters = 13; - -private: - static const char * const ParameterNames[]; - static const DataType ParameterDataTypes[]; - }; diff --git a/slsReceiverSoftware/include/Listener.h b/slsReceiverSoftware/include/Listener.h index 217ea41e8..56396aac4 100644 --- a/slsReceiverSoftware/include/Listener.h +++ b/slsReceiverSoftware/include/Listener.h @@ -21,16 +21,23 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { /** * Constructor * Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofListerners + * @param ind self index * @param dtype detector type * @param f address of Fifo pointer * @param s pointer to receiver status * @param portno pointer to udp port number * @param e ethernet interface - * @param act pointer to activated * @param nf pointer to number of images to catch * @param dr pointer to dynamic range + * @param us pointer to udp socket buffer size + * @param as pointer to actual udp socket buffer size + * @param fpf pointer to frames per file + * @param fdp frame discard policy */ - Listener(detectorType dtype, Fifo*& f, runStatus* s, uint32_t* portno, char* e, int* act, uint64_t* nf, uint32_t* dr); + Listener(int ind, detectorType dtype, Fifo*& f, runStatus* s, + uint32_t* portno, char* e, uint64_t* nf, uint32_t* dr, + uint32_t* us, uint32_t* as, uint32_t* fpf, + frameDiscardPolicy* fdp); /** * Destructor @@ -39,33 +46,13 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { ~Listener(); - //*** static functions *** - /** - * Get ErrorMask - * @return ErrorMask - */ - static uint64_t GetErrorMask(); - - /** - * Get RunningMask - * @return RunningMask - */ - static uint64_t GetRunningMask(); - - /** - * Reset RunningMask - */ - static void ResetRunningMask(); - - /** - * Set Silent Mode - * @param mode 1 sets 0 unsets - */ - static void SetSilentMode(bool mode); - - - //*** non static functions *** //*** getters *** + /** + * Returns if the thread is currently running + * @returns true if thread is running, else false + */ + bool IsRunning(); + /** * Get acquisition started flag * @return acquisition started flag @@ -142,7 +129,19 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { */ void ShutDownUDPSocket(); + /** + * Set Silent Mode + * @param mode 1 sets 0 unsets + */ + void SetSilentMode(bool mode); + /** + * Create & closes a dummy UDP socket + * to set & get actual buffer size + * @param s UDP socket buffer size to be set + * @return OK or FAIL of dummy socket creation + */ + int CreateDummySocketForUDPSocketBufferSize(uint32_t s); private: @@ -153,12 +152,6 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { */ std::string GetType(); - /** - * Returns if the thread is currently running - * @returns true if thread is running, else false - */ - bool IsRunning(); - /** * Record First Indices (firstAcquisitionIndex, firstMeasurementIndex) * @param fnum frame index to record @@ -184,17 +177,11 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { * Listen to the UDP Socket for an image, * place them in the right order * @param buffer - * @returns number of bytes of relevant data, can be image size or 0 + * @returns number of bytes of relevant data, can be image size or 0 (stop acquisition) + * or -1 to discard image */ uint32_t ListenToAnImage(char* buf); - /** - * Create an image (for deactivated detectors), - * @param buffer - * @returns image size or 0 - */ - uint32_t CreateAnImage(char* buf); - /** * Print Fifo Statistics */ @@ -205,17 +192,8 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { /** type of thread */ static const std::string TypeName; - /** Total Number of Listener Objects */ - static int NumberofListeners; - - /** Mask of errors on any object eg.thread creation */ - static uint64_t ErrorMask; - - /** Mask of all listener objects running */ - static uint64_t RunningMask; - - /** Mutex to update static items among objects (threads)*/ - static pthread_mutex_t Mutex; + /** Object running status */ + bool runningFlag; /** GeneralData (Detector Data) object */ const GeneralData* generalData; @@ -223,9 +201,6 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { /** Fifo structure */ Fifo* fifo; - /** Silent Mode */ - static bool SilentMode; - // individual members /** Detector Type */ @@ -243,15 +218,24 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { /** ethernet interface */ char* eth; - /** if the detector is activated */ - int* activated; - /** Number of Images to catch */ uint64_t* numImages; /** Dynamic Range */ uint32_t* dynamicRange; + /** UDP Socket Buffer Size */ + uint32_t* udpSocketBufferSize; + + /** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */ + uint32_t* actualUDPSocketBufferSize; + + /** frames per file */ + uint32_t* framesPerFile; + + /** frame discard policy */ + frameDiscardPolicy* frameDiscardMode; + // acquisition start /** Aquisition Started flag */ @@ -293,6 +277,9 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { /** if the udp socket is connected */ bool udpSocketAlive; + /** Semaphore to synchonize deleting udp socket */ + sem_t semaphore_socket; + // for print progress during acqusition /** number of packets for statistic */ @@ -300,5 +287,8 @@ class Listener : private virtual slsReceiverDefs, public ThreadObject { /** number of images for statistic */ uint32_t numFramesStatistic; + + /** Silent Mode */ + bool silentMode; }; diff --git a/slsReceiverSoftware/include/UDPBaseImplementation.h b/slsReceiverSoftware/include/UDPBaseImplementation.h index 144fff951..a31c93165 100644 --- a/slsReceiverSoftware/include/UDPBaseImplementation.h +++ b/slsReceiverSoftware/include/UDPBaseImplementation.h @@ -97,6 +97,24 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ uint64_t getFileIndex() const; + /** + * Get Frames per File (0 means infinite) + * @return Frames per File + */ + uint32_t getFramesPerFile() const; + + /** + * Get Frame Discard Policy + * @return Frame Discard Policy + */ + frameDiscardPolicy getFrameDiscardPolicy() const; + + /** + * Get Partial Frame Padding Enable + * @return Partial Frame Padding Enable + */ + bool getFramePaddingEnable() const; + /** * Get Scan Tag * @return scan tag //FIXME: needed? (unsigned integer?) @@ -206,6 +224,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ uint64_t getSubExpTime() const; + /** + * Get Sub Period + * @return Sub Period + */ + uint64_t getSubPeriod() const; + /* * Get Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames FIXME: (Not implemented) @@ -271,6 +295,24 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ char *getStreamingSourceIP() const; + /** + * Get additional json header + * @return additional json header + */ + char *getAdditionalJsonHeader() const; + + /** (not saved in client shared memory) + * Get UDP Socket Buffer Size + * @return UDP Socket Buffer Size + */ + uint32_t getUDPSocketBufferSize() const; + + + /** (not saved in client shared memory) + * Get actual UDP Socket Buffer Size + * @return actual UDP Socket Buffer Size + */ + uint32_t getActualUDPSocketBufferSize() const; /************************************************************************* * Setters *************************************************************** @@ -332,6 +374,24 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ void setFileIndex(const uint64_t i); + /** + * Set Frames per File (0 means infinite) + * @param i Frames per File + */ + void setFramesPerFile(const uint32_t i); + + /** + * Set Frame Discard Policy + * @param i Frame Discard Policy + */ + void setFrameDiscardPolicy(const frameDiscardPolicy i); + + /** + * Set Partial Frame Padding Enable + * @param i Partial Frame Padding Enable + */ + void setFramePaddingEnable(const bool i); + /** * Set Scan Tag * @param i scan tag //FIXME: needed? (unsigned integer?) @@ -427,6 +487,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ void setSubExpTime(const uint64_t i); + /** + * Set Sub Period + * @param i Period + * @return OK or FAIL + */ + void setSubPeriod(const uint64_t i); + /** * Set Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames @@ -555,6 +622,18 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ void setStreamingSourceIP(const char* c); + /** + * Set additional json header + */ + void setAdditionalJsonHeader(const char* c); + + /** (not saved in client shared memory) + * Set UDP Socket Buffer Size + * @param s UDP Socket Buffer Size + * @return OK or FAIL if dummy socket could be created + */ + int setUDPSocketBufferSize(const uint32_t s); + /* * Restream stop dummy packet from receiver * @return OK or FAIL @@ -583,52 +662,25 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter */ void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); - /** - * Call back for raw data - * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format - * dataPointer is the pointer to the data - * dataSize in bytes is the size of the data in bytes. - */ - void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, void*),void *arg); + /** + * Call back for raw data + * args to raw data ready callback are + * sls_receiver_header frame metadata + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes. + */ + void registerCallBackRawDataReady(void (*func)(char* , + char*, uint32_t, void*),void *arg); /** * Call back for raw data (modified) * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format + * sls_receiver_header frame metadata * dataPointer is the pointer to the data - * revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value). + * revDatasize is the reference of data size in bytes. + * Can be modified to the new size to be written/streamed. (only smaller value). */ - void registerCallBackRawDataModifyReady(void (*func)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + void registerCallBackRawDataModifyReady(void (*func)(char* , char*, uint32_t &,void*),void *arg); @@ -652,6 +704,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter uint64_t acquisitionTime; /** Sub Exposure Time */ uint64_t subExpTime; + /** Sub Period */ + uint64_t subPeriod; /** Frame Number */ uint64_t numberOfFrames; /** Samples Number */ @@ -674,12 +728,20 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter runStatus status; /** Activated/Deactivated */ int activated; + /** frame discard policy */ + frameDiscardPolicy frameDiscardMode; + /** frame padding */ + bool framePadding; //***connection parameters*** /** Ethernet Interface */ char eth[MAX_STR_LENGTH]; /** Server UDP Port Number*/ uint32_t udpPortNum[MAX_NUMBER_OF_LISTENING_THREADS]; + /** udp socket buffer size */ + uint32_t udpSocketBufferSize; + /** actual UDP Socket Buffer Size (halved due to kernel bookkeeping) */ + uint32_t actualUDPSocketBufferSize; //***file parameters*** /** File format */ @@ -690,6 +752,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter char filePath[MAX_STR_LENGTH]; /** File Index */ uint64_t fileIndex; + /** Frames per file (0 means infinite) */ + uint32_t framesPerFile; /** Scan Tag */ int scanTag; /** File Write enable */ @@ -712,6 +776,8 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter uint32_t streamingPort; /** streaming port */ char streamingSrcIP[MAX_STR_LENGTH]; + /** additional json header */ + char additionalJsonHeader[MAX_STR_LENGTH]; //***receiver parameters*** uint32_t silentMode; @@ -743,53 +809,24 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter void *pAcquisitionFinished; - /** - * Call back for raw data - * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format - * dataPointer is the pointer to the data - * dataSize in bytes is the size of the data in bytes. - */ - void (*rawDataReadyCallBack)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, void*); - + /** + * Call back for raw data + * args to raw data ready callback are + * sls_receiver_header frame metadata + * dataPointer is the pointer to the data + * dataSize in bytes is the size of the data in bytes. + */ + void (*rawDataReadyCallBack)(char* , + char*, uint32_t, void*); /** * Call back for raw data (modified) * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format + * sls_receiver_header frame metadata * dataPointer is the pointer to the data * revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value). */ - void (*rawDataModifyReadyCallBack)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + void (*rawDataModifyReadyCallBack)(char* , char*, uint32_t &, void*); void *pRawDataReady; diff --git a/slsReceiverSoftware/include/UDPInterface.h b/slsReceiverSoftware/include/UDPInterface.h index a058ea301..bb27cdad0 100644 --- a/slsReceiverSoftware/include/UDPInterface.h +++ b/slsReceiverSoftware/include/UDPInterface.h @@ -51,6 +51,7 @@ class UDPInterface { * -setGapPixelsEnable * -setStreamingPort * -setStreamingSourceIP + * -setAdditionalJsonHeader * -setDataStreamEnable * * @@ -180,10 +181,28 @@ class UDPInterface { /** * Get File Index - * @return NULL or file index of acquisition + * @return file index of acquisition */ virtual uint64_t getFileIndex() const = 0; + /** + * Get Frames per File (0 means infinite) + * @return Frames per File + */ + virtual uint32_t getFramesPerFile() const = 0; + + /** + * Get Frame Discard Policy + * @return Frame Discard Policy + */ + virtual slsReceiverDefs::frameDiscardPolicy getFrameDiscardPolicy() const = 0; + + /** + * Get Partial Frame Padding Enable + * @return Partial Frame Padding Enable + */ + virtual bool getFramePaddingEnable() const = 0; + /** * Get Scan Tag * @return scan tag //FIXME: needed? (unsigned integer?) @@ -293,6 +312,12 @@ class UDPInterface { */ virtual uint64_t getSubExpTime() const = 0; + /** + * Get Sub Period + * @return Sub Period + */ + virtual uint64_t getSubPeriod() const = 0; + /* * Get Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames FIXME: (for Leo? Not implemented) @@ -331,7 +356,7 @@ class UDPInterface { */ virtual slsReceiverDefs::runStatus getStatus() const = 0; - /** + /** (not saved in client shared memory) * Get Silent Mode * @return silent mode */ @@ -357,6 +382,24 @@ class UDPInterface { */ virtual char *getStreamingSourceIP() const = 0; + /** + * Get additional json header + * @return additional json header + */ + virtual char *getAdditionalJsonHeader() const = 0; + + + /** (not saved in client shared memory) + * Get UDP Socket Buffer Size + * @return UDP Socket Buffer Size + */ + virtual uint32_t getUDPSocketBufferSize() const = 0; + + /** (not saved in client shared memory) + * Get actual UDP Socket Buffer Size + * @return actual UDP Socket Buffer Size + */ + virtual uint32_t getActualUDPSocketBufferSize() const = 0; /************************************************************************* * Setters *************************************************************** @@ -418,6 +461,24 @@ class UDPInterface { */ virtual void setFileIndex(const uint64_t i) = 0; + /** + * Set Frames per File (0 means infinite) + * @param i Frames per File + */ + virtual void setFramesPerFile(const uint32_t i) = 0; + + /** + * Set Frame Discard Policy + * @param i Frame Discard Policy + */ + virtual void setFrameDiscardPolicy(const slsReceiverDefs::frameDiscardPolicy i) = 0; + + /** + * Set Partial Frame Padding Enable + * @param i Partial Frame Padding Enable + */ + virtual void setFramePaddingEnable(const bool i) = 0; + /** * Set Scan Tag * @param i scan tag //FIXME: needed? (unsigned integer?) @@ -512,6 +573,13 @@ class UDPInterface { */ virtual void setSubExpTime(const uint64_t i) = 0; + /** + * Set Sub Period + * @param i Period + * @return OK or FAIL + */ + virtual void setSubPeriod(const uint64_t i) = 0; + /** * Set Number of Frames expected by receiver from detector * The data receiver status will change from running to idle when it gets this number of frames FIXME: (for Leo? Not implemented) @@ -643,6 +711,18 @@ class UDPInterface { */ virtual void setStreamingSourceIP(const char* c) = 0; + /** + * Set additional json header + */ + virtual void setAdditionalJsonHeader(const char* c) = 0; + + /** (not saved in client shared memory) + * Set UDP Socket Buffer Size + * @param s UDP Socket Buffer Size + * @return OK or FAIL if dummy socket could be created + */ + virtual int setUDPSocketBufferSize(const uint32_t s) = 0; + /* * Restream stop dummy packet from receiver * @return OK or FAIL @@ -675,49 +755,21 @@ class UDPInterface { /** * Call back for raw data * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format + * sls_receiver_header frame metadata * dataPointer is the pointer to the data * dataSize in bytes is the size of the data in bytes. */ - virtual void registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + virtual void registerCallBackRawDataReady(void (*func)(char* , char*, uint32_t, void*),void *arg) = 0; /** * Call back for raw data (modified) * args to raw data ready callback are - * frameNumber is the frame number - * expLength is the subframe number (32 bit eiger) or real time exposure time in 100ns (others) - * packetNumber is the packet number - * bunchId is the bunch id from beamline - * timestamp is the time stamp with 10 MHz clock - * modId is the unique module id (unique even for left, right, top, bottom) - * xCoord is the x coordinate in the complete detector system - * yCoord is the y coordinate in the complete detector system - * zCoord is the z coordinate in the complete detector system - * debug is for debugging purposes - * roundRNumber is the round robin set number - * detType is the detector type see :: detectorType - * version is the version number of this structure format + * sls_receiver_header frame metadata * dataPointer is the pointer to the data * revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value). */ - virtual void registerCallBackRawDataModifyReady(void (*func)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, + virtual void registerCallBackRawDataModifyReady(void (*func)(char* , char*, uint32_t &,void*),void *arg) = 0; diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 6f0f71a70..21f653291 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -35,6 +35,7 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase //*** Overloaded Functions called by TCP Interface *** + /** * Get Total Frames Caught for an entire acquisition (including all scans) * @return total number of frames caught for entire acquisition @@ -184,6 +185,13 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase */ void closeFiles(); + /** (not saved in client shared memory) + * Set UDP Socket Buffer Size + * @param s UDP Socket Buffer Size + * @return OK or FAIL if dummy socket could be created + */ + int setUDPSocketBufferSize(const uint32_t s); + /** * Restream stop dummy packet from receiver * @return OK or FAIL diff --git a/slsReceiverSoftware/include/ZmqSocket.h b/slsReceiverSoftware/include/ZmqSocket.h index 8fc063670..c26a62c7b 100644 --- a/slsReceiverSoftware/include/ZmqSocket.h +++ b/slsReceiverSoftware/include/ZmqSocket.h @@ -48,7 +48,8 @@ public: portno (portnumber), server (false), contextDescriptor (NULL), - socketDescriptor (NULL) + socketDescriptor (NULL), + headerMessage(0) { char ip[MAX_STR_LENGTH] = ""; memset(ip, 0, MAX_STR_LENGTH); @@ -57,7 +58,7 @@ public: struct addrinfo *result; if ((ConvertHostnameToInternetAddress(hostname_or_ip, &result)) || (ConvertInternetAddresstoIpString(result, ip, MAX_STR_LENGTH))) - return; + throw std::exception(); // construct address sprintf (serverAddress, "tcp://%s:%d", ip, portno); @@ -68,29 +69,32 @@ public: // create context contextDescriptor = zmq_ctx_new(); if (contextDescriptor == NULL) - return; + throw std::exception(); // create publisher socketDescriptor = zmq_socket (contextDescriptor, ZMQ_SUB); if (socketDescriptor == NULL) { - PrintError (); - Close (); + PrintError (); + Close (); + throw std::exception(); } //Socket Options provided above // an empty string implies receiving any messages if ( zmq_setsockopt(socketDescriptor, ZMQ_SUBSCRIBE, "", 0)) { - PrintError (); - Close(); + PrintError (); + Close(); + throw std::exception(); } //ZMQ_LINGER default is already -1 means no messages discarded. use this options if optimizing required //ZMQ_SNDHWM default is 0 means no limit. use this to optimize if optimizing required // eg. int value = -1; int value = 0; - if (zmq_setsockopt(socketDescriptor, ZMQ_LINGER, &value,sizeof(value))) { - PrintError (); - Close(); - } + if (zmq_setsockopt(socketDescriptor, ZMQ_LINGER, &value,sizeof(value))) { + PrintError (); + Close(); + throw std::exception(); + } }; /** @@ -104,18 +108,19 @@ public: portno (portnumber), server (true), contextDescriptor (NULL), - socketDescriptor (NULL) + socketDescriptor (NULL), + headerMessage(0) { // create context contextDescriptor = zmq_ctx_new(); if (contextDescriptor == NULL) - return; + throw std::exception(); // create publisher socketDescriptor = zmq_socket (contextDescriptor, ZMQ_PUB); if (socketDescriptor == NULL) { PrintError (); Close (); - return; + throw std::exception(); } //Socket Options provided above @@ -129,7 +134,7 @@ public: if (zmq_bind (socketDescriptor, serverAddress) < 0) { PrintError (); Close (); - return; + throw std::exception(); } //sleep for a few milliseconds to allow a slow-joiner @@ -144,11 +149,6 @@ public: Close(); }; - /** - * Returns error status - * @returns true if error else false - */ - bool IsError() { if (socketDescriptor == NULL) return true; return false; }; /** * Returns Server Address @@ -274,7 +274,8 @@ public: uint64_t bunchId = 0, uint64_t timestamp = 0, uint16_t modId = 0, uint16_t xCoord = 0, uint16_t yCoord = 0, uint16_t zCoord = 0, uint32_t debug = 0, uint16_t roundRNumber = 0, - uint8_t detType = 0, uint8_t version = 0) { + uint8_t detType = 0, uint8_t version = 0, int* flippedData = 0, + char* additionalJsonHeader = 0) { char buf[MAX_STR_LENGTH] = ""; @@ -303,17 +304,32 @@ public: "\"debug\":%u, " "\"roundRNumber\":%u, " "\"detType\":%u, " - "\"version\":%u" - "}\n\0"; + "\"version\":%u, " + + //additional stuff + "\"flippedDataX\":%u" + + ;//"}\n\0"; int length = sprintf(buf, jsonHeaderFormat, jsonversion, dynamicrange, fileIndex, npixelsx, npixelsy, imageSize, acqIndex, fIndex, (fname == NULL)? "":fname, dummy?0:1, - frameNumber, expLength, packetNumber, bunchId, timestamp, + + frameNumber, expLength, packetNumber, bunchId, timestamp, modId, xCoord, yCoord, zCoord, debug, roundRNumber, - detType, version); + detType, version, + + //additional stuff + ((flippedData == 0 ) ? 0 :flippedData[0]) + ); + if (additionalJsonHeader && strlen(additionalJsonHeader)) { + length = sprintf(buf, "%s, %s}\n%c", buf, additionalJsonHeader, '\0'); + } else { + length = sprintf(buf, "%s}\n%c", buf, '\0'); + } + #ifdef VERBOSE //if(!index) - FILE_LOG(logINFO) << index << ": Streamer: buf:" << buf; + cprintf(BLUE,"%d : Streamer: buf: %s\n", index, buf); #endif if(zmq_send (socketDescriptor, buf, length, dummy?0:ZMQ_SNDMORE) < 0) { @@ -365,19 +381,16 @@ public: /** - * Receive Header + * Receive Header (Important to close message after parsing header) * @param index self index for debugging - * @param acqIndex address of acquisition index - * @param frameIndex address of frame index - * @param subframeIndex address of subframe index - * @param filename address of file name - * @param fileindex address of file index - * @returns 0 if error or end of acquisition, else 1 + * @param document parsed document reference + * @param version version that has to match, -1 to not care + * @returns 0 if error or end of acquisition, else 1 (call CloseHeaderMessage after parsing header) */ - int ReceiveHeader(const int index, uint64_t &acqIndex, - uint64_t &frameIndex, uint32_t &subframeIndex, std::string &filename, uint64_t &fileIndex) + int ReceiveHeader(const int index, Document& document, uint32_t version) { zmq_msg_t message; + headerMessage= &message; zmq_msg_init (&message); int len = ReceiveMessage(index, message); if ( len > 0 ) { @@ -385,11 +398,10 @@ public: #ifdef ZMQ_DETAIL cprintf( BLUE,"Header %d [%d] Length: %d Header:%s \n", index, portno, len, (char*) zmq_msg_data (&message) ); #endif - if ( ParseHeader (index, len, message, acqIndex, frameIndex, subframeIndex, filename, fileIndex, dummy)) { + if ( ParseHeader (index, len, message, document, dummy, version)) { #ifdef ZMQ_DETAIL cprintf( RED,"Parsed Header %d [%d] Length: %d Header:%s \n", index, portno, len, (char*) zmq_msg_data (&message) ); #endif - zmq_msg_close (&message); if (dummy) { #ifdef ZMQ_DETAIL cprintf(RED,"%d [%d] Received end of acquisition\n", index, portno ); @@ -402,10 +414,79 @@ public: return 1; } } - zmq_msg_close(&message); return 0; }; + + /** + * Close Header Message. Call this function if ReceiveHeader returned 1 + */ + void CloseHeaderMessage() { + if (headerMessage) + zmq_msg_close(headerMessage); + headerMessage = 0; + }; + /** + * Parse Header + * @param index self index for debugging + * @param length length of message + * @param message message + * @param document parsed document reference + * @param dummy true if end of acqusition, else false, loaded upon parsing + * @param version version that has to match, -1 to not care + * @returns true if successful else false + */ + int ParseHeader(const int index, int length, zmq_msg_t& message, + Document& document, bool& dummy, uint32_t version) + { + if ( document.Parse( (char*) zmq_msg_data (&message), zmq_msg_size (&message)).HasParseError() ) { + cprintf( RED,"%d Could not parse. len:%d: Message:%s \n", index, length, (char*) zmq_msg_data (&message) ); + fflush ( stdout ); + char* buf = (char*) zmq_msg_data (&message); + for ( int i= 0; i < length; ++i ) { + cprintf(RED,"%02x ",buf[i]); + } + printf("\n"); + fflush( stdout ); + return 0; + } + + if (document["jsonversion"].GetUint() != version) { + cprintf( RED, "version mismatch. required %u, got %u\n", version, document["jsonversion"].GetUint()); + return 0; + } + + dummy = false; + int temp = document["data"].GetUint(); + dummy = temp ? false : true; + + return 1; + /* + int temp = d["data"].GetUint(); + dummy = temp ? false : true; + if (!dummy) { + acqIndex = d["acqIndex"].GetUint64(); + frameIndex = d["fIndex"].GetUint64(); + fileIndex = d["fileIndex"].GetUint64(); + subframeIndex = d["expLength"].GetUint(); + filename = d["fname"].GetString(); + } +#ifdef VERYVERBOSE + cprintf(BLUE,"%d Dummy:%d\n" + "\tAcqIndex:%lu\n" + "\tFrameIndex:%lu\n" + "\tSubIndex:%u\n" + "\tFileIndex:%lu\n" + "\tBitMode:%u\n" + "\tDetType:%u\n", + index, (int)dummy, acqIndex, frameIndex, subframeIndex, fileIndex, + d["bitmode"].GetUint(),d["detType"].GetUint()); +#endif + return 1; + */ + }; + + /** * Receive Data * @param index self index for debugging @@ -446,65 +527,6 @@ public: }; - /** - * Parse Header - * @param index self index for debugging - * @param length length of message - * @param message message - * @param acqIndex address of acquisition index - * @param frameIndex address of frame index - * @param subframeIndex address of subframe index - * @param filename address of file name - * @param fileindex address of file index - * @param dummy true if end of acquisition else false - * @returns true if successfull else false - */ - int ParseHeader(const int index, int length, zmq_msg_t& message, uint64_t &acqIndex, - uint64_t &frameIndex, uint32_t &subframeIndex, std::string &filename, uint64_t &fileIndex, bool& dummy) - { - - acqIndex = -1; - frameIndex = -1; - subframeIndex = -1; - fileIndex = -1; - dummy = true; - - Document d; - if ( d.Parse( (char*) zmq_msg_data (&message), zmq_msg_size (&message)).HasParseError() ) { - cprintf( RED,"%d Could not parse. len:%d: Message:%s \n", index, length, (char*) zmq_msg_data (&message) ); - fflush ( stdout ); - char* buf = (char*) zmq_msg_data (&message); - for ( int i= 0; i < length; ++i ) { - cprintf(RED,"%02x ",buf[i]); - } - printf("\n"); - fflush( stdout ); - return 0; - } - - int temp = d["data"].GetUint(); - dummy = temp ? false : true; - if (!dummy) { - acqIndex = d["acqIndex"].GetUint64(); - frameIndex = d["fIndex"].GetUint64(); - fileIndex = d["fileIndex"].GetUint64(); - subframeIndex = d["expLength"].GetUint(); - filename = d["fname"].GetString(); - } -#ifdef VERYVERBOSE - cprintf(BLUE,"%d Dummy:%d\n" - "\tAcqIndex:%lu\n" - "\tFrameIndex:%lu\n" - "\tSubIndex:%u\n" - "\tFileIndex:%lu\n" - "\tBitMode:%u\n" - "\tDetType:%u\n", - index, (int)dummy, acqIndex, frameIndex, subframeIndex, fileIndex, - d["bitmode"].GetUint(),d["detType"].GetUint()); -#endif - return 1; - }; - /** * Print error @@ -580,4 +602,7 @@ private: /** Server Address */ char serverAddress[1000]; + /** Header Message pointer */ + zmq_msg_t* headerMessage; + }; diff --git a/slsReceiverSoftware/include/circularFifo.h b/slsReceiverSoftware/include/circularFifo.h index ab00444c9..6a6b39b35 100644 --- a/slsReceiverSoftware/include/circularFifo.h +++ b/slsReceiverSoftware/include/circularFifo.h @@ -28,36 +28,47 @@ public: CircularFifo(unsigned int Size) : tail(0), head(0){ Capacity = Size + 1; array.resize(Capacity); - sem_init(&free_mutex,0,0); + sem_init(&data_mutex,0,0); + sem_init(&free_mutex,0,Size); } virtual ~CircularFifo() { - sem_destroy(&free_mutex); + sem_destroy(&data_mutex); + sem_destroy(&free_mutex); } - bool push(Element*& item_); - bool pop(Element*& item_); + bool push(Element*& item_, bool no_block=false); + bool pop(Element*& item_, bool no_block=false); bool isEmpty() const; bool isFull() const; - int getSemValue(); + int getDataValue() const; + int getFreeValue() const; private: - volatile unsigned int tail; // input index vector array; - volatile unsigned int head; // output index + unsigned int tail; // input index + unsigned int head; // output index unsigned int Capacity; - sem_t free_mutex; - + mutable sem_t data_mutex; + mutable sem_t free_mutex; unsigned int increment(unsigned int idx_) const; }; template -int CircularFifo::getSemValue() +int CircularFifo::getDataValue() const { - int value; - sem_getvalue(&free_mutex, &value); - return value; + int value; + sem_getvalue(&data_mutex, &value); + return value; +} + +template +int CircularFifo::getFreeValue() const +{ + int value; + sem_getvalue(&free_mutex, &value); + return value; } @@ -66,21 +77,20 @@ int CircularFifo::getSemValue() * will happen, it is up to the caller to handle this case * * \param item_ copy by reference the input item +* \param no_block if true, return immediately if fifo is full * \return whether operation was successful or not */ template -bool CircularFifo::push(Element*& item_) +bool CircularFifo::push(Element*& item_, bool no_block) { - unsigned int nextTail = increment(tail); + // check for fifo full + if (no_block && isFull()) + return false; - if(nextTail != head) - { - array[tail] = item_; - tail = nextTail; - sem_post(&free_mutex); - return true; - } - // queue was full - return false; + sem_wait(&free_mutex); + array[tail] = item_; + tail = increment(tail); + sem_post(&data_mutex); + return true; } /** Consumer only: Removes and returns item from the queue @@ -88,15 +98,19 @@ bool CircularFifo::push(Element*& item_) * It is up to the caller to handle this case * * \param item_ return by reference the wanted item +* \param no_block if true, return immediately if fifo is full * \return whether operation was successful or not */ template -bool CircularFifo::pop(Element*& item_) +bool CircularFifo::pop(Element*& item_, bool no_block) { - sem_wait(&free_mutex); + // check for fifo empty + if (no_block && isEmpty()) + return false; + sem_wait(&data_mutex); item_ = array[head]; head = increment(head); - + sem_post(&free_mutex); return true; } @@ -108,7 +122,7 @@ bool CircularFifo::pop(Element*& item_) template bool CircularFifo::isEmpty() const { - return (head == tail); + return (getDataValue() == 0); } /** Useful for testing and Producer check of status @@ -119,9 +133,7 @@ bool CircularFifo::isEmpty() const template bool CircularFifo::isFull() const { - int tailCheck = increment(tail); - //int tailCheck = (tail+1) % Capacity; - return (tailCheck == head); + return (getFreeValue() == 0); } /** Increment helper function for index of the circular queue diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 8ca367989..fd196f8cc 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -49,6 +49,8 @@ class sockaddr_in; #include #include #include +#include // capabilities +#include #endif @@ -59,11 +61,11 @@ class sockaddr_in; #include #include #include +#include "logger.h" using namespace std; #define DEFAULT_PACKET_SIZE 1286 -/*#define SOCKET_BUFFER_SIZE (100*1024*1024) //100MB*/ -#define SOCKET_BUFFER_SIZE (2000*1024*1024) //100MB +#define SOCKET_BUFFER_SIZE (100*1024*1024) //100 MB #define DEFAULT_BACKLOG 5 @@ -81,7 +83,8 @@ enum communicationProtocol{ - genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : + genericSocket(const char* const host_ip_or_name, unsigned short int const port_number, + communicationProtocol p, int ps = DEFAULT_PACKET_SIZE) : portno(port_number), protocol(p), is_a_server(0), @@ -91,7 +94,8 @@ enum communicationProtocol{ nsending(0), nsent(0), total_sent(0),// sender (client): where to? ip - header_packet_size(0) + header_packet_size(0), + actual_udp_socket_buffer_size(0) { memset(&serverAddress, 0, sizeof(serverAddress)); memset(&clientAddress, 0, sizeof(clientAddress)); @@ -121,7 +125,7 @@ enum communicationProtocol{ return SOCK_DGRAM; default: - cerr << "unknown protocol " << p << endl; + cprintf(RED, "unknown protocol %d\n", p); return -1; } } @@ -140,7 +144,9 @@ enum communicationProtocol{ */ - genericSocket(unsigned short int const port_number, communicationProtocol p, int ps = DEFAULT_PACKET_SIZE, const char *eth=NULL, int hsize=0): + genericSocket(unsigned short int const port_number, communicationProtocol p, + int ps = DEFAULT_PACKET_SIZE, const char *eth=NULL, int hsize=0, + uint32_t buf_size=SOCKET_BUFFER_SIZE): portno(port_number), protocol(p), is_a_server(1), @@ -150,7 +156,8 @@ enum communicationProtocol{ nsending(0), nsent(0), total_sent(0), - header_packet_size(hsize) + header_packet_size(hsize), + actual_udp_socket_buffer_size(0) { @@ -188,7 +195,7 @@ enum communicationProtocol{ socketDescriptor = socket(AF_INET, getProtocol(),0); //tcp if (socketDescriptor < 0) { - cerr << "Can not create socket "<= real_size) { + actual_udp_socket_buffer_size = ret_size; +#ifdef VEBOSE + FILE_LOG(logINFO) << "[Port " << port_number << "] UDP rx socket buffer size is sufficient (" << ret_size << ")"; +#endif + } + + // not sufficient, enhance size + else { + // set buffer size (could not set) + if (setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, &desired_size, optlen) == -1) { + FILE_LOG(logWARNING) << "[Port " << port_number << "] Could not set rx socket buffer size to " + << desired_size << ". (No Root Privileges?)"; + } + // confirm size + else if (getsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1) { + FILE_LOG(logWARNING) << "[Port " << port_number << "] Could not get rx socket buffer size"; + } + else if (ret_size >= real_size) { + actual_udp_socket_buffer_size = ret_size; + FILE_LOG(logINFO) << "[Port " << port_number << "] UDP rx socket buffer size modified to " << ret_size; + } + // buffer size too large + else { + actual_udp_socket_buffer_size = ret_size; + // force a value larger than system limit (if run in a privileged context (capability CAP_NET_ADMIN set)) + int ret = setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUFFORCE, &desired_size, optlen); + getsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen); + if (ret == -1) { + FILE_LOG(logWARNING) << "[Port " << port_number << "] " + "Could not force rx socket buffer size to " + << desired_size << ".\n Real size: " << ret_size << + ". (No Root Privileges?)\n" + " To remove this warning: set rx_udpsocksize from client to <= " << + (ret_size/2) << " (Real size:" << ret_size << ")."; + } else { + FILE_LOG(logINFO) << "[Port " << port_number << "] UDP rx socket buffer size modified to " << ret_size; + } + } + } + } if(bind(socketDescriptor,(struct sockaddr *) &serverAddress,sizeof(serverAddress))<0){ - cerr << "Can not bind socket "<< endl; + cprintf(RED, "Can not bind socket\n"); socketDescriptor=-1; return; } @@ -240,8 +290,13 @@ enum communicationProtocol{ - - + /** + * Returns actual udp socket buffer size/2. + * Halving is because of kernel book keeping + */ + int getActualUDPSocketBufferSize(){ + return actual_udp_socket_buffer_size; + } @@ -313,7 +368,7 @@ enum communicationProtocol{ if(is_a_server && protocol==TCP){ //server tcp; the server will wait for the clients connection if (socketDescriptor>0) { if ((file_des = accept(socketDescriptor,(struct sockaddr *) &clientAddress, &clientAddress_length)) < 0) { - cerr << "Error: with server accept, connection refused"< #ifdef __cplusplus +#include #include #endif #include "ansi.h" @@ -22,7 +23,7 @@ typedef int int32_t; #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 -#define EIGER_MAX_FRAMES_PER_FILE 2000 +#define EIGER_MAX_FRAMES_PER_FILE 10000 #define JFRAU_MAX_FRAMES_PER_FILE 10000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 @@ -36,6 +37,9 @@ typedef int int32_t; #define DEFAULT_ZMQ_CL_PORTNO 30001 #define DEFAULT_ZMQ_RX_PORTNO 30001 +#define SLS_DETECTOR_HEADER_VERSION 0x1 +#define SLS_DETECTOR_JSON_HEADER_VERSION 0x2 + /** \file sls_receiver_defs.h This file contains all the basic definitions common to the slsReceiver class @@ -108,6 +112,8 @@ public: FRAMES_FROM_START_PG, SAMPLES_JCTB, SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */ + STORAGE_CELL_NUMBER, /** sls_bitset; + + typedef struct { + sls_detector_header detHeader; /**< is the detector header */ + sls_bitset packetsMask; /**< is the packets caught bit mask */ + } sls_receiver_header; + + typedef uint8_t bitset_storage[MAX_NUM_PACKETS/8]; + +#endif + /** + * frameDiscardPolicy + */ + enum frameDiscardPolicy { + GET_FRAME_DISCARD_POLICY = -1, /**< to get the missing packet mode */ + NO_DISCARD, /**< pad incomplete packets with -1, default mode */ + DISCARD_EMPTY_FRAMES, /**< discard incomplete frames, fastest mode, save space, not suitable for multiple modules */ + DISCARD_PARTIAL_FRAMES, /**< ignore missing packets, must check with packetsMask for data integrity, fast mode and suitable for multiple modules */ + NUM_DISCARD_POLICIES + }; + /** format @@ -247,6 +279,19 @@ public: default: return std::string("unknown"); \ }}; + /** + * Returns string of frame discard policy index + * @param f can be NO_DISCARD, DISCARD_EMPTY_FRAMES, DISCARD_PARTIAL_FRAMES + * @returns No Discard, Discard Empty Frames, Discard Partial Frames, unknown + */ + static std::string getFrameDiscardPolicyType(frameDiscardPolicy f) { \ + switch (f) { \ + case NO_DISCARD: return std::string("No Discard"); \ + case DISCARD_EMPTY_FRAMES: return std::string("Discard Empty Frames"); \ + case DISCARD_PARTIAL_FRAMES: return std::string("Discard Partial Frames"); \ + default: return std::string("unknown"); \ + }}; \ + #endif #ifdef __cplusplus diff --git a/slsReceiverSoftware/include/sls_receiver_funcs.h b/slsReceiverSoftware/include/sls_receiver_funcs.h index aef4d8a20..a083c80bf 100644 --- a/slsReceiverSoftware/include/sls_receiver_funcs.h +++ b/slsReceiverSoftware/include/sls_receiver_funcs.h @@ -63,7 +63,13 @@ enum recFuncs{ F_SET_RECEIVER_SILENT_MODE, /** < sets the receiver silent mode */ F_ENABLE_GAPPIXELS_IN_RECEIVER, /** < sets gap pixels in the receiver */ F_RESTREAM_STOP_FROM_RECEIVER, /** < restream stop from receiver */ - + F_ADDITIONAL_JSON_HEADER, /** < additional json header */ + F_RECEIVER_UDP_SOCK_BUF_SIZE, /** < UDP socket buffer size */ + F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE, /** < real UDP socket buffer size */ + F_SET_RECEIVER_FRAMES_PER_FILE, /** < receiver frames per file */ + F_RECEIVER_CHECK_VERSION, /** < check receiver version compatibility */ + F_RECEIVER_DISCARD_POLICY, /** < frames discard policy */ + F_RECEIVER_PADDING_ENABLE, /** < partial frames padding enable */ /* Always append functions hereafter!!! */ diff --git a/slsReceiverSoftware/include/versionAPI.h b/slsReceiverSoftware/include/versionAPI.h new file mode 120000 index 000000000..a4d75aa2a --- /dev/null +++ b/slsReceiverSoftware/include/versionAPI.h @@ -0,0 +1 @@ +../../slsDetectorSoftware/commonFiles/versionAPI.h \ No newline at end of file diff --git a/slsReceiverSoftware/src/BinaryFile.cpp b/slsReceiverSoftware/src/BinaryFile.cpp index 4e6ff5de9..10d5acd9b 100644 --- a/slsReceiverSoftware/src/BinaryFile.cpp +++ b/slsReceiverSoftware/src/BinaryFile.cpp @@ -14,7 +14,7 @@ using namespace std; FILE* BinaryFile::masterfd = 0; -BinaryFile::BinaryFile(int ind, uint32_t maxf, +BinaryFile::BinaryFile(int ind, uint32_t* maxf, int* nd, char* fname, char* fpath, uint64_t* findex, bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, bool* smode): @@ -34,7 +34,7 @@ BinaryFile::~BinaryFile() { void BinaryFile::PrintMembers() { File::PrintMembers(); - FILE_LOG(logINFO) << "Max Frames Per File: " << maxFramesPerFile; + FILE_LOG(logINFO) << "Max Frames Per File: " << *maxFramesPerFile; FILE_LOG(logINFO) << "Number of Frames in File: " << numFramesInFile; } @@ -70,33 +70,68 @@ void BinaryFile::CloseAllFiles() { } int BinaryFile::WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t nump) { - if (numFramesInFile >= maxFramesPerFile) { + // check if maxframesperfile = 0 for infinite + if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) { CloseCurrentFile(); CreateFile(fnum); } numFramesInFile++; numActualPacketsInFile += nump; - if (BinaryFileStatic::WriteDataFile(filefd, buffer, buffersize, fnum) == buffersize) - return OK; - cprintf(RED,"%d Error: Write to file failed for image number %lld\n", index, (long long int)fnum); - return FAIL; + + // write to file + int ret = 0; + + // contiguous bitset + if (sizeof(sls_bitset) == sizeof(bitset_storage)) { + ret = BinaryFileStatic::WriteDataFile(filefd, buffer, buffersize); + } + + // not contiguous bitset + else { + // write detector header + ret = BinaryFileStatic::WriteDataFile(filefd, buffer, sizeof(sls_detector_header)); + + // get contiguous representation of bit mask + bitset_storage storage; + memset(storage, 0 , sizeof(bitset_storage)); + sls_bitset bits = *(sls_bitset*)(buffer + sizeof(sls_detector_header)); + for (int i = 0; i < MAX_NUM_PACKETS; ++i) + storage[i >> 3] |= (bits[i] << (i & 7)); + // write bitmask + ret += BinaryFileStatic::WriteDataFile(filefd, (char*)storage, sizeof(bitset_storage)); + + // write data + ret += BinaryFileStatic::WriteDataFile(filefd, + buffer + sizeof(sls_detector_header), buffersize - sizeof(sls_receiver_header)); + } + + // if write error + if (ret != buffersize) { + cprintf(RED,"%d Error: Write to file failed for image number %lld\n", + index, (long long int)fnum); + return FAIL; + } + return OK; } int BinaryFile::CreateMasterFile(bool en, uint32_t size, - uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t ap) { + uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp, + uint64_t ap) { //beginning of every acquisition numFramesInFile = 0; numActualPacketsInFile = 0; if (master && (*detIndex==0)) { - masterFileName = BinaryFileStatic::CreateMasterFileName(filePath, fileNamePrefix, *fileIndex); + masterFileName = BinaryFileStatic::CreateMasterFileName(filePath, + fileNamePrefix, *fileIndex); if(!silentMode) { FILE_LOG(logINFO) << "Master File: " << masterFileName; } - return BinaryFileStatic::CreateMasterDataFile(masterfd, masterFileName, *overWriteEnable, - *dynamicRange, en, size, nx, ny, *numImages, - at, st, ap, BINARY_WRITER_VERSION); + return BinaryFileStatic::CreateMasterDataFile(masterfd, masterFileName, + *overWriteEnable, + *dynamicRange, en, size, nx, ny, *numImages, *maxFramesPerFile, + at, st, sp, ap, BINARY_WRITER_VERSION); } return OK; } diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 99835b6ed..fd4d8dec1 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -22,31 +22,21 @@ using namespace std; const string DataProcessor::TypeName = "DataProcessor"; -int DataProcessor::NumberofDataProcessors(0); -uint64_t DataProcessor::ErrorMask(0x0); - -uint64_t DataProcessor::RunningMask(0x0); - -pthread_mutex_t DataProcessor::Mutex = PTHREAD_MUTEX_INITIALIZER; - -bool DataProcessor::SilentMode(false); - - -DataProcessor::DataProcessor(Fifo*& f, fileFormat* ftype, bool fwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr, +DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo*& f, + fileFormat* ftype, bool fwenable, + bool* dsEnable, bool* gpEnable, uint32_t* dr, uint32_t* freq, uint32_t* timer, - void (*dataReadycb)(uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, - uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t, void*), - void (*dataModifyReadycb)(uint64_t, uint32_t, uint32_t, uint64_t, - uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, - uint32_t, uint16_t, uint8_t, uint8_t, - char*, uint32_t &, void*), + bool* fp, + void (*dataReadycb)(char*, char*, uint32_t, void*), + void (*dataModifyReadycb)(char*, char*, uint32_t &, void*), void *pDataReadycb) : - ThreadObject(NumberofDataProcessors), + ThreadObject(ind), + runningFlag(0), generalData(0), fifo(f), + myDetectorType(dtype), file(0), dataStreamEnable(dsEnable), fileFormatType(ftype), @@ -65,18 +55,16 @@ DataProcessor::DataProcessor(Fifo*& f, fileFormat* ftype, bool fwenable, bool* d numTotalFramesCaught(0), numFramesCaught(0), currentFrameIndex(0), + silentMode(false), + framePadding(fp), rawDataReadyCallBack(dataReadycb), rawDataModifyReadyCallBack(dataModifyReadycb), pRawDataReady(pDataReadycb) { - if(ThreadObject::CreateThread()){ - pthread_mutex_lock(&Mutex); - ErrorMask ^= (1<Print(); #endif if (file) { - file->SetMaxFramesPerFile(generalData->maxFramesPerFile); if (file->GetFileType() == HDF5) { file->SetNumberofPixels(generalData->nPixelsX, generalData->nPixelsY); } @@ -236,24 +200,30 @@ void DataProcessor::SetFileFormat(const fileFormat f) { if (file && file->GetFileType() != f) { //remember the pointer values before they are destroyed int nd[MAX_DIMENSIONS];nd[0] = 0; nd[1] = 0; + uint32_t* maxf = 0; char* fname=0; char* fpath=0; uint64_t* findex=0; - bool* owenable=0; int* dindex=0; int* nunits=0; uint64_t* nf = 0; uint32_t* dr = 0; uint32_t* port = 0; - file->GetMemberPointerValues(nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, port); + bool* owenable=0; int* dindex=0; int* nunits=0; uint64_t* nf = 0; + uint32_t* dr = 0; uint32_t* port = 0; + file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, + owenable, dindex, nunits, nf, dr, port); //create file writer with same pointers - SetupFileWriter(fileWriteEnable, nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, port); + SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex, + owenable, dindex, nunits, nf, dr, port); } } -void DataProcessor::SetupFileWriter(bool fwe, int* nd, char* fname, char* fpath, uint64_t* findex, - bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, +void DataProcessor::SetupFileWriter(bool fwe, int* nd, uint32_t* maxf, + char* fname, char* fpath, uint64_t* findex, + bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, + uint32_t* portno, GeneralData* g) { fileWriteEnable = fwe; if (g) generalData = g; // fix xcoord as detector is not providing it right now - xcoordin1D = ((NumberofDataProcessors > (*nunits)) ? index : ((*dindex) * (*nunits)) + index); + xcoordin1D = ((*dindex) * (*nunits)) + index; if (file) { @@ -264,28 +234,30 @@ void DataProcessor::SetupFileWriter(bool fwe, int* nd, char* fname, char* fpath, switch(*fileFormatType){ #ifdef HDF5C case HDF5: - file = new HDF5File(index, generalData->maxFramesPerFile, + file = new HDF5File(index, maxf, nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, portno, - generalData->nPixelsX, generalData->nPixelsY, &SilentMode); + generalData->nPixelsX, generalData->nPixelsY, &silentMode); break; #endif default: - file = new BinaryFile(index, generalData->maxFramesPerFile, + file = new BinaryFile(index, maxf, nd, fname, fpath, findex, owenable, - dindex, nunits, nf, dr, portno, &SilentMode); + dindex, nunits, nf, dr, portno, &silentMode); break; } } } // only the first file -int DataProcessor::CreateNewFile(bool en, uint64_t nf, uint64_t at, uint64_t st, uint64_t ap) { +int DataProcessor::CreateNewFile(bool en, uint64_t nf, uint64_t at, uint64_t st, + uint64_t sp, uint64_t ap) { if (file == NULL) return FAIL; file->CloseAllFiles(); - if (file->CreateMasterFile(en, generalData->imageSize, generalData->nPixelsX, generalData->nPixelsY, - at, st, ap) == FAIL) + if (file->CreateMasterFile(en, generalData->imageSize, + generalData->nPixelsX, generalData->nPixelsY, + at, st, sp, ap) == FAIL) return FAIL; if (file->CreateFile(currentFrameIndex) == FAIL) return FAIL; @@ -298,9 +270,9 @@ void DataProcessor::CloseFiles() { file->CloseAllFiles(); } -void DataProcessor::EndofAcquisition(uint64_t numf) { +void DataProcessor::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) { if (file && file->GetFileType() == HDF5) { - file->EndofAcquisition(numf); + file->EndofAcquisition(anyPacketsCaught, numf); } } @@ -309,7 +281,8 @@ void DataProcessor::ThreadExecution() { char* buffer=0; fifo->PopAddress(buffer); #ifdef FIFODEBUG - if (!index) cprintf(BLUE,"DataProcessor %d, pop 0x%p buffer:%s\n", index,(void*)(buffer),buffer); + if (!index) cprintf(BLUE,"DataProcessor %d, pop 0x%p buffer:%s\n", + index,(void*)(buffer),buffer); #endif //check dummy @@ -351,13 +324,14 @@ void DataProcessor::StopProcessing(char* buf) { #endif } -/** buf includes only the standard header */ + void DataProcessor::ProcessAnImage(char* buf) { - sls_detector_header* header = (sls_detector_header*) (buf + FIFO_HEADER_NUMBYTES); - uint64_t fnum = header->frameNumber; + sls_receiver_header* rheader = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); + sls_detector_header header = rheader->detHeader; + uint64_t fnum = header.frameNumber; currentFrameIndex = fnum; - uint32_t nump = header->packetNumber; + uint32_t nump = header.packetNumber; if (nump == generalData->packetsPerFrame) { numFramesCaught++; numTotalFramesCaught++; @@ -387,64 +361,48 @@ void DataProcessor::ProcessAnImage(char* buf) { } if (*gapPixelsEnable && (*dynamicRange!=4)) - InsertGapPixels(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_detector_header), *dynamicRange); + InsertGapPixels(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), + *dynamicRange); // x coord is 0 for detector in pos [0,0,0] if (xcoordin1D) { // do nothing as detector has correctly send them - if (header->xCoord || header->yCoord || header->zCoord) + if (header.xCoord || header.yCoord || header.zCoord) ; // detector has send all 0's when there should have been a value greater than 0 in some dimension else - header->xCoord = xcoordin1D; + header.xCoord = xcoordin1D; } + // frame padding + if (*framePadding && nump < generalData->packetsPerFrame) + PadMissingPackets(buf); + // normal call back if (rawDataReadyCallBack) { rawDataReadyCallBack( - header->frameNumber, - header->expLength, - header->packetNumber, - header->bunchId, - header->timestamp, - header->modId, - header->xCoord, - header->yCoord, - header->zCoord, - header->debug, - header->roundRNumber, - header->detType, - header->version, - buf + FIFO_HEADER_NUMBYTES + sizeof(sls_detector_header), + (char*)rheader, + buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), (uint32_t)(*((uint32_t*)buf)), pRawDataReady); } - else if (rawDataModifyReadyCallBack) {cprintf(BG_GREEN,"Calling rawdatamodify\n"); + // call back with modified size + else if (rawDataModifyReadyCallBack) { uint32_t revsize = (uint32_t)(*((uint32_t*)buf)); rawDataModifyReadyCallBack( - header->frameNumber, - header->expLength, - header->packetNumber, - header->bunchId, - header->timestamp, - header->modId, - header->xCoord, - header->yCoord, - header->zCoord, - header->debug, - header->roundRNumber, - header->detType, - header->version, - buf + FIFO_HEADER_NUMBYTES + sizeof(sls_detector_header), + (char*)rheader, + buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), revsize, pRawDataReady); (*((uint32_t*)buf)) = revsize; } - + // write to file if (file) - file->WriteToFile(buf + FIFO_HEADER_NUMBYTES, sizeof(sls_detector_header) + (uint32_t)(*((uint32_t*)buf)), fnum-firstMeasurementIndex, nump); + file->WriteToFile(buf + FIFO_HEADER_NUMBYTES, + sizeof(sls_receiver_header) + (uint32_t)(*((uint32_t*)buf)), + fnum-firstMeasurementIndex, nump); @@ -469,10 +427,13 @@ bool DataProcessor::CheckTimer() { struct timespec end; clock_gettime(CLOCK_REALTIME, &end); #ifdef VERBOSE - cprintf(BLUE,"%d Timer elapsed time:%f seconds\n", index, ( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) / 1000000000.0); + cprintf(BLUE,"%d Timer elapsed time:%f seconds\n", index, + ( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) + / 1000000000.0); #endif //still less than streaming timer, keep waiting - if((( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) / 1000000000.0) < ((double)*streamingTimerInMs/1000.00)) + if((( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) + / 1000000000.0) < ((double)*streamingTimerInMs/1000.00)) return false; //restart timer @@ -499,6 +460,60 @@ void DataProcessor::SetPixelDimension() { } } +void DataProcessor::SetSilentMode(bool mode) { + silentMode = mode; +} + +void DataProcessor::PadMissingPackets(char* buf) { + FILE_LOG(logDEBUG) << index << ": Padding Missing Packets"; + + uint32_t pperFrame = generalData->packetsPerFrame; + sls_receiver_header* header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); + uint32_t nmissing = pperFrame - header->detHeader.packetNumber; + sls_bitset pmask = header->packetsMask; + + uint32_t dsize = generalData->dataSize; + uint32_t fifohsize = generalData->fifoBufferHeaderSize; + uint32_t corrected_dsize = dsize - ((pperFrame * dsize) - generalData->imageSize); +#ifdef VERBOSE + cprintf(RED,"bitmask:%s\n", pmask.to_string().c_str()); +#endif + for (unsigned int pnum = 0; pnum < pperFrame; ++pnum) { + + // not missing packet + if (pmask[pnum]) + continue; + + // done with padding, exit loop earlier + if (!nmissing) + break; + + FILE_LOG(logDEBUG) << "padding for " << index << " for pnum: " << pnum << endl; + + // missing packet + switch(myDetectorType) { + //for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes data + // 2nd packet: 4 bytes fnum, previous 1*2 bytes data + 640*2 bytes data !! + case GOTTHARD: + if(!pnum) + memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize-2); + else + memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize+2); + break; + case JUNGFRAUCTB: + if (pnum == (pperFrame-1)) + memset(buf + fifohsize + (pnum * dsize), 0xFF, corrected_dsize); + else + memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize); + break; + default: + memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize); + break; + } + --nmissing; + } +} + /** eiger specific */ void DataProcessor::InsertGapPixels(char* buf, uint32_t dr) { diff --git a/slsReceiverSoftware/src/DataStreamer.cpp b/slsReceiverSoftware/src/DataStreamer.cpp index 3dfced933..aca101686 100644 --- a/slsReceiverSoftware/src/DataStreamer.cpp +++ b/slsReceiverSoftware/src/DataStreamer.cpp @@ -15,19 +15,10 @@ using namespace std; const string DataStreamer::TypeName = "DataStreamer"; -int DataStreamer::NumberofDataStreamers(0); -uint64_t DataStreamer::ErrorMask(0x0); - -uint64_t DataStreamer::RunningMask(0x0); - -pthread_mutex_t DataStreamer::Mutex = PTHREAD_MUTEX_INITIALIZER; - -bool DataStreamer::SilentMode(false); - - -DataStreamer::DataStreamer(Fifo*& f, uint32_t* dr, int* sEnable, uint64_t* fi) : - ThreadObject(NumberofDataStreamers), +DataStreamer::DataStreamer(int ind, Fifo*& f, uint32_t* dr, int* sEnable, uint64_t* fi, int* fd, char* ajh) : + ThreadObject(ind), + runningFlag(0), generalData(0), fifo(f), zmqSocket(0), @@ -38,18 +29,17 @@ DataStreamer::DataStreamer(Fifo*& f, uint32_t* dr, int* sEnable, uint64_t* fi) : measurementStartedFlag(false), firstAcquisitionIndex(0), firstMeasurementIndex(0), - completeBuffer(0) + completeBuffer(0), + flippedData(fd), + additionJsonHeader(ajh), + silentMode(false) { - if(ThreadObject::CreateThread()){ - pthread_mutex_lock(&Mutex); - ErrorMask ^= (1<IsError()) { + try { + zmqSocket = new ZmqSocket(portnum, (strlen(srcip)?srcip:NULL)); + } catch (...) { cprintf(RED, "Error: Could not create Zmq socket on port %d for Streamer %d\n", portnum, index); - return FAIL; + throw; } FILE_LOG(logINFO) << index << " Streamer: Zmq Server started at " << zmqSocket->GetZmqServerAddress(); - return OK; } @@ -214,7 +180,7 @@ void DataStreamer::StopProcessing(char* buf) { if (!index) cprintf(RED,"DataStreamer %d: Dummy\n", index); #endif - sls_detector_header* header = (sls_detector_header*) (buf); + sls_receiver_header* header = (sls_receiver_header*) (buf); //send dummy header and data if (!SendHeader(header, 0, 0, 0, true)) cprintf(RED,"Error: Could not send zmq dummy header for streamer %d\n", index); @@ -229,8 +195,8 @@ void DataStreamer::StopProcessing(char* buf) { /** buf includes only the standard header */ void DataStreamer::ProcessAnImage(char* buf) { - sls_detector_header* header = (sls_detector_header*) (buf + FIFO_HEADER_NUMBYTES); - uint64_t fnum = header->frameNumber; + sls_receiver_header* header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); + uint64_t fnum = header->detHeader.frameNumber; #ifdef VERBOSE cprintf(MAGENTA,"DataStreamer %d: fnum:%lu\n", index,fnum); #endif @@ -249,7 +215,7 @@ void DataStreamer::ProcessAnImage(char* buf) { cprintf(RED,"Error: Could not send zmq header for fnum %lld and streamer %d\n", (long long int) fnum, index); - memcpy(completeBuffer + ((generalData->imageSize)**shortFrameEnable), buf + FIFO_HEADER_NUMBYTES + sizeof(sls_detector_header), (uint32_t)(*((uint32_t*)buf)) ); // new size possibly from callback + memcpy(completeBuffer + ((generalData->imageSize)**shortFrameEnable), buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), (uint32_t)(*((uint32_t*)buf)) ); // new size possibly from callback if (!zmqSocket->SendData(completeBuffer, generalData->imageSizeComplete)) cprintf(RED,"Error: Could not send zmq data for fnum %lld and streamer %d\n", (long long int) fnum, index); @@ -263,7 +229,7 @@ void DataStreamer::ProcessAnImage(char* buf) { cprintf(RED,"Error: Could not send zmq header for fnum %lld and streamer %d\n", (long long int) fnum, index); - if (!zmqSocket->SendData(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_detector_header), (uint32_t)(*((uint32_t*)buf)) )) // new size possibly from callback + if (!zmqSocket->SendData(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), (uint32_t)(*((uint32_t*)buf)) )) // new size possibly from callback cprintf(RED,"Error: Could not send zmq data for fnum %lld and streamer %d\n", (long long int) fnum, index); } @@ -271,27 +237,31 @@ void DataStreamer::ProcessAnImage(char* buf) { -int DataStreamer::SendHeader(sls_detector_header* header, uint32_t size, uint32_t nx, uint32_t ny, bool dummy) { +int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32_t nx, uint32_t ny, bool dummy) { if (dummy) return zmqSocket->SendHeaderData(index, dummy,SLS_DETECTOR_JSON_HEADER_VERSION); - uint64_t frameIndex = header->frameNumber - firstMeasurementIndex; - uint64_t acquisitionIndex = header->frameNumber - firstAcquisitionIndex; + sls_detector_header header = rheader->detHeader; + + uint64_t frameIndex = header.frameNumber - firstMeasurementIndex; + uint64_t acquisitionIndex = header.frameNumber - firstAcquisitionIndex; return zmqSocket->SendHeaderData(index, dummy, SLS_DETECTOR_JSON_HEADER_VERSION, *dynamicRange, *fileIndex, nx, ny, size, acquisitionIndex, frameIndex, fileNametoStream, - header->frameNumber, header->expLength, header->packetNumber, header->bunchId, header->timestamp, - header->modId, header->xCoord, header->yCoord, header->zCoord, - header->debug, header->roundRNumber, - header->detType, header->version - ); + header.frameNumber, header.expLength, header.packetNumber, header.bunchId, header.timestamp, + header.modId, header.xCoord, header.yCoord, header.zCoord, + header.debug, header.roundRNumber, + header.detType, header.version, + flippedData, + additionJsonHeader + ); } -int DataStreamer::restreamStop() { +int DataStreamer::RestreamStop() { //send dummy header int ret = zmqSocket->SendHeaderData(index, true, SLS_DETECTOR_JSON_HEADER_VERSION); if (!ret) { @@ -300,3 +270,9 @@ int DataStreamer::restreamStop() { } return OK; } + + +void DataStreamer::SetSilentMode(bool mode) { + silentMode = mode; +} + diff --git a/slsReceiverSoftware/src/Fifo.cpp b/slsReceiverSoftware/src/Fifo.cpp index 2c071356a..64027a4ba 100644 --- a/slsReceiverSoftware/src/Fifo.cpp +++ b/slsReceiverSoftware/src/Fifo.cpp @@ -12,10 +12,9 @@ #include using namespace std; -int Fifo::NumberofFifoClassObjects(0); -Fifo::Fifo(uint32_t fifoItemSize, uint32_t depth, bool &success): - index(NumberofFifoClassObjects), +Fifo::Fifo(int ind, uint32_t fifoItemSize, uint32_t depth): + index(ind), memory(0), fifoBound(0), fifoFree(0), @@ -24,9 +23,8 @@ Fifo::Fifo(uint32_t fifoItemSize, uint32_t depth, bool &success): status_fifoBound(0), status_fifoFree(depth){ FILE_LOG(logDEBUG) << __AT__ << " called"; - NumberofFifoClassObjects++; if(CreateFifos(fifoItemSize) == FAIL) - success = false; + throw std::exception(); } @@ -34,7 +32,6 @@ Fifo::~Fifo() { FILE_LOG(logDEBUG) << __AT__ << " called"; //cprintf(BLUE,"Fifo Object %d: Goodbye\n", index); DestroyFifos(); - NumberofFifoClassObjects--; } @@ -50,28 +47,24 @@ int Fifo::CreateFifos(uint32_t fifoItemSize) { fifoFree = new CircularFifo(fifoDepth); fifoStream = new CircularFifo(fifoDepth); //allocate memory - memory = (char*) calloc (fifoItemSize * fifoDepth, sizeof(char)); - memset(memory,0,fifoItemSize * fifoDepth* sizeof(char)); + size_t mem_len = fifoItemSize * fifoDepth * sizeof(char); + memory = (char*) malloc (mem_len); if (memory == NULL){ FILE_LOG(logERROR) << "Could not allocate memory for fifos"; - memory = 0; return FAIL; } - FILE_LOG(logDEBUG) << "Memory Allocated " << index << ": " << (fifoItemSize * fifoDepth) << " bytes"; + memset(memory, 0, mem_len); + FILE_LOG(logDEBUG) << "Memory Allocated " << index << ": " << mem_len << " bytes"; { //push free addresses into fifoFree fifo char* buffer = memory; - while (buffer < (memory + fifoItemSize * (fifoDepth-1))) { + for (int i = 0; i < fifoDepth; ++i) { //sprintf(buffer,"memory"); -#ifdef FIFODEBUG - cprintf(MAGENTA,"Fifofree %d: value:%d, pop 0x%p\n", index, fifoFree->getSemValue(), (void*)(buffer)); -#endif FreeAddress(buffer); buffer += fifoItemSize; } } - - FILE_LOG(logDEBUG) << "Fifo Reconstructed Depth " << index << ": " << fifoDepth; + FILE_LOG(logINFO) << "Fifo " << index << " reconstructed Depth (rx_fifodepth): " << fifoFree->getDataValue(); return OK; } @@ -79,7 +72,6 @@ int Fifo::CreateFifos(uint32_t fifoItemSize) { void Fifo::DestroyFifos(){ FILE_LOG(logDEBUG) << __AT__ << " called"; - if(memory) { free(memory); memory = 0; @@ -100,25 +92,22 @@ void Fifo::DestroyFifos(){ void Fifo::FreeAddress(char*& address) { - while(!fifoFree->push(address)); + fifoFree->push(address); } void Fifo::GetNewAddress(char*& address) { - int temp = fifoFree->getSemValue(); + int temp = fifoFree->getDataValue(); if (temp < status_fifoFree) status_fifoFree = temp; fifoFree->pop(address); - /*temp = fifoFree->getSemValue(); - if (temp < status_fifoFree) - status_fifoFree = temp;*/ } void Fifo::PushAddress(char*& address) { - int temp = fifoBound->getSemValue(); + int temp = fifoBound->getDataValue(); if (temp > status_fifoBound) status_fifoBound = temp; while(!fifoBound->push(address)); - /*temp = fifoBound->getSemValue(); + /*temp = fifoBound->getDataValue(); if (temp > status_fifoBound) status_fifoBound = temp;*/ } @@ -128,7 +117,7 @@ void Fifo::PopAddress(char*& address) { } void Fifo::PushAddressToStream(char*& address) { - while(!fifoStream->push(address)); + fifoStream->push(address); } void Fifo::PopAddressToStream(char*& address) { @@ -141,7 +130,6 @@ int Fifo::GetMaxLevelForFifoBound() { return temp; } - int Fifo::GetMinLevelForFifoFree() { int temp = status_fifoFree; status_fifoFree = fifoDepth; diff --git a/slsReceiverSoftware/src/File.cpp b/slsReceiverSoftware/src/File.cpp index 0e8f4a4a9..c46269ba4 100644 --- a/slsReceiverSoftware/src/File.cpp +++ b/slsReceiverSoftware/src/File.cpp @@ -10,7 +10,7 @@ using namespace std; -File::File(int ind, uint32_t maxf, +File::File(int ind, uint32_t* maxf, int* nd, char* fname, char* fpath, uint64_t* findex, bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, bool* smode): @@ -42,7 +42,7 @@ string File::GetCurrentFileName() { void File::PrintMembers() { FILE_LOG(logINFO) << "\nGeneral Writer Variables:" << endl << "Index: " << index << endl - << "Max Frames Per File: " << maxFramesPerFile << endl + << "Max Frames Per File: " << *maxFramesPerFile << endl << "Number of Detectors in x dir: " << numDetX << endl << "Number of Detectors in y dir: " << numDetY << endl << "File Name Prefix: " << fileNamePrefix << endl @@ -61,11 +61,12 @@ void File::PrintMembers() { } -void File::GetMemberPointerValues(int* nd, char*& fname, char*& fpath, uint64_t*& findex, bool*& owenable, +void File::GetMemberPointerValues(int* nd, uint32_t*& maxf, char*& fname, char*& fpath, uint64_t*& findex, bool*& owenable, int*& dindex, int*& nunits, uint64_t*& nf, uint32_t*& dr, uint32_t*& portno) { nd[0] = numDetX; nd[1] = numDetY; + maxf = maxFramesPerFile; fname = fileNamePrefix; fpath = filePath; findex = fileIndex; @@ -77,7 +78,4 @@ void File::GetMemberPointerValues(int* nd, char*& fname, char*& fpath, uint64_t* portno = udpPortNumber; } -void File::SetMaxFramesPerFile(uint32_t maxf) { - maxFramesPerFile = maxf; -} diff --git a/slsReceiverSoftware/src/HDF5File.cpp b/slsReceiverSoftware/src/HDF5File.cpp index 26de3f8f8..01c16f72a 100644 --- a/slsReceiverSoftware/src/HDF5File.cpp +++ b/slsReceiverSoftware/src/HDF5File.cpp @@ -21,14 +21,13 @@ hid_t HDF5File::virtualfd = 0; -HDF5File::HDF5File(int ind, uint32_t maxf, - int* nd, char* fname, char* fpath, uint64_t* findex, - bool* frindexenable, bool* owenable, +HDF5File::HDF5File(int ind, uint32_t* maxf, + int* nd, char* fname, char* fpath, uint64_t* findex, bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, uint32_t nx, uint32_t ny, bool* smode): - File(ind, maxf, nd, fname, fpath, findex, frindexenable, owenable, dindex, nunits, nf, dr, portno, smode), + File(ind, maxf, nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, portno, smode), filefd(0), dataspace(0), dataset(0), @@ -38,13 +37,59 @@ HDF5File::HDF5File(int ind, uint32_t maxf, numFramesInFile(0), numActualPacketsInFile(0), numFilesinAcquisition(0), - dataspace_para(0) + dataspace_para(0), + extNumImages(0) { #ifdef VERBOSE PrintMembers(); #endif - for (int i = 0; i < HDF5FileStatic::NumberofParameters; ++i) - dataset_para[i] = 0; + dataset_para.clear(); + parameterNames.clear(); + parameterDataTypes.clear(); + + parameterNames.push_back("frame number"); + parameterDataTypes.push_back(PredType::STD_U64LE); + + parameterNames.push_back("exp length or sub exposure time"); + parameterDataTypes.push_back(PredType::STD_U32LE); + + parameterNames.push_back("packets caught"); + parameterDataTypes.push_back(PredType::STD_U32LE); + + parameterNames.push_back("bunch id"); + parameterDataTypes.push_back(PredType::STD_U64LE); + + parameterNames.push_back("timestamp"); + parameterDataTypes.push_back(PredType::STD_U64LE); + + parameterNames.push_back("mod id"); + parameterDataTypes.push_back(PredType::STD_U16LE); + + parameterNames.push_back("x Coord"); + parameterDataTypes.push_back(PredType::STD_U16LE); + + parameterNames.push_back("y Coord"); + parameterDataTypes.push_back(PredType::STD_U16LE); + + parameterNames.push_back("z Coord"); + parameterDataTypes.push_back(PredType::STD_U16LE); + + parameterNames.push_back("debug"); + parameterDataTypes.push_back(PredType::STD_U32LE); + + parameterNames.push_back("round robin number"); + parameterDataTypes.push_back(PredType::STD_U16LE); + + parameterNames.push_back("detector type"); + parameterDataTypes.push_back(PredType::STD_U8LE); + + parameterNames.push_back("detector header version"); + parameterDataTypes.push_back(PredType::STD_U8LE); + + parameterNames.push_back("packets caught bit mask"); + StrType strdatatype(PredType::C_S1, sizeof(bitset_storage)); + parameterDataTypes.push_back(strdatatype); + } @@ -97,13 +142,16 @@ int HDF5File::CreateFile(uint64_t fnum) { //first time if(!fnum) UpdateDataType(); - uint64_t framestosave = ((*numImages - fnum) > maxFramesPerFile) ? maxFramesPerFile : (*numImages-fnum); + uint64_t framestosave = ((*maxFramesPerFile == 0) ? *numImages : // infinite images + (((extNumImages - fnum) > (*maxFramesPerFile)) ? // save up to maximum at a time + (*maxFramesPerFile) : (extNumImages-fnum))); pthread_mutex_lock(&Mutex); if (HDF5FileStatic::CreateDataFile(index, *overWriteEnable, currentFileName, (*numImages > 1), fnum, framestosave, nPixelsY, ((*dynamicRange==4) ? (nPixelsX/2) : nPixelsX), datatype, filefd, dataspace, dataset, HDF5_WRITER_VERSION, MAX_CHUNKED_IMAGES, - dataspace_para, dataset_para) == FAIL) { + dataspace_para, dataset_para, + parameterNames, parameterDataTypes) == FAIL) { pthread_mutex_unlock(&Mutex); return FAIL; } @@ -111,9 +159,9 @@ int HDF5File::CreateFile(uint64_t fnum) { if (dataspace == NULL) cprintf(RED,"Got nothing!\n"); - if(!silentMode) + if(!silentMode) { FILE_LOG(logINFO) << *udpPortNumber << ": HDF5 File created: " << currentFileName; - + } return OK; } @@ -138,21 +186,39 @@ void HDF5File::CloseAllFiles() { int HDF5File::WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t nump) { - if (numFramesInFile >= maxFramesPerFile) { + // check if maxframesperfile = 0 for infinite + if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) { CloseCurrentFile(); CreateFile(fnum); } numFramesInFile++; numActualPacketsInFile += nump; pthread_mutex_lock(&Mutex); - if (HDF5FileStatic::WriteDataFile(index, buffer + sizeof(sls_detector_header), - fnum%maxFramesPerFile, nPixelsY, ((*dynamicRange==4) ? (nPixelsX/2) : nPixelsX), + + // extend dataset (when receiver start followed by many status starts (jungfrau))) + if (fnum >= extNumImages) { + if (HDF5FileStatic::ExtendDataset(index, dataspace, dataset, + dataspace_para, dataset_para, *numImages) == OK) { + if (!silentMode) { + cprintf(BLUE,"%d Extending HDF5 dataset by %llu, Total x Dimension: %llu\n", + index, (long long unsigned int)extNumImages, + (long long unsigned int)(extNumImages + *numImages)); + } + extNumImages += *numImages; + } + } + + if (HDF5FileStatic::WriteDataFile(index, buffer + sizeof(sls_receiver_header), + // infinite then no need for %maxframesperfile + ((*maxFramesPerFile == 0) ? fnum : fnum%(*maxFramesPerFile)), + nPixelsY, ((*dynamicRange==4) ? (nPixelsX/2) : nPixelsX), dataspace, dataset, datatype) == OK) { - sls_detector_header* header = (sls_detector_header*) (buffer); + sls_receiver_header* header = (sls_receiver_header*) (buffer); /*header->xCoord = ((*detIndex) * (*numUnitsPerDetector) + index); */ if (HDF5FileStatic::WriteParameterDatasets(index, dataspace_para, - fnum%maxFramesPerFile, - dataset_para, header) == OK) { + // infinite then no need for %maxframesperfile + ((*maxFramesPerFile == 0) ? fnum : fnum%(*maxFramesPerFile)), + dataset_para, header, parameterDataTypes) == OK) { pthread_mutex_unlock(&Mutex); return OK; } @@ -164,20 +230,27 @@ int HDF5File::WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t int HDF5File::CreateMasterFile(bool en, uint32_t size, - uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t ap) { + uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp, + uint64_t ap) { //beginning of every acquisition numFramesInFile = 0; numActualPacketsInFile = 0; + extNumImages = *numImages; if (master && (*detIndex==0)) { virtualfd = 0; - masterFileName = HDF5FileStatic::CreateMasterFileName(filePath, fileNamePrefix, *fileIndex); - if(!silentMode) + masterFileName = HDF5FileStatic::CreateMasterFileName(filePath, + fileNamePrefix, *fileIndex); + if(!silentMode) { FILE_LOG(logINFO) << "Master File: " << masterFileName; + } pthread_mutex_lock(&Mutex); - int ret = HDF5FileStatic::CreateMasterDataFile(masterfd, masterFileName, *overWriteEnable, - *dynamicRange, en, size, nx, ny, *numImages, at, st, ap, HDF5_WRITER_VERSION); + int ret = HDF5FileStatic::CreateMasterDataFile(masterfd, masterFileName, + *overWriteEnable, + *dynamicRange, en, size, nx, ny, *numImages, *maxFramesPerFile, + at, st, sp, ap, + HDF5_WRITER_VERSION); pthread_mutex_unlock(&Mutex); return ret; } @@ -185,11 +258,11 @@ int HDF5File::CreateMasterFile(bool en, uint32_t size, } -void HDF5File::EndofAcquisition(uint64_t numf) { +void HDF5File::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) { //not created before - if (!virtualfd) { + if (!virtualfd && anyPacketsCaught) { - //only one file and one sub image + //only one file and one sub image (link current file in master) if (((numFilesinAcquisition == 1) && (numDetY*numDetX) == 1)) { //dataset name ostringstream osfn; @@ -197,11 +270,12 @@ void HDF5File::EndofAcquisition(uint64_t numf) { if ((*numImages > 1)) osfn << "_f" << setfill('0') << setw(12) << 0; string dsetname = osfn.str(); pthread_mutex_lock(&Mutex); - HDF5FileStatic::LinkVirtualInMaster(masterFileName, currentFileName, dsetname); + HDF5FileStatic::LinkVirtualInMaster(masterFileName, currentFileName, + dsetname, parameterNames); pthread_mutex_unlock(&Mutex); } - //link current file in master file + //create virutal file else CreateVirtualFile(numf); } @@ -211,16 +285,18 @@ void HDF5File::EndofAcquisition(uint64_t numf) { int HDF5File::CreateVirtualFile(uint64_t numf) { if (master && (*detIndex==0)) { - pthread_mutex_lock(&Mutex); int ret = HDF5FileStatic::CreateVirtualDataFile( virtualfd, masterFileName, filePath, fileNamePrefix, *fileIndex, (*numImages > 1), *detIndex, *numUnitsPerDetector, - maxFramesPerFile, numf, + // infinite images in 1 file, then maxfrperfile = numf + ((*maxFramesPerFile == 0) ? numf+1 : *maxFramesPerFile), + numf+1, "data", datatype, numDetY, numDetX, nPixelsY, ((*dynamicRange==4) ? (nPixelsX/2) : nPixelsX), - HDF5_WRITER_VERSION); + HDF5_WRITER_VERSION, + parameterNames, parameterDataTypes); pthread_mutex_unlock(&Mutex); return ret; } diff --git a/slsReceiverSoftware/src/HDF5FileStatic.cpp b/slsReceiverSoftware/src/HDF5FileStatic.cpp deleted file mode 100644 index f4df3d7c9..000000000 --- a/slsReceiverSoftware/src/HDF5FileStatic.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************ - * @file HDF5File.cpp - * @short sets/gets properties for the HDF5 file, - * creates/closes the file and writes data to it - ***********************************************/ -#include "HDF5FileStatic.h" - -const char * const HDF5FileStatic::ParameterNames[] = { - "frameNumber", - "expLength", - "packetNumber", - "bunchId", - "timestamp", - "modId", - "xCoord", - "yCoord", - "zCoord", - "debug", - "roundRNumber", - "detType", - "version"}; -const DataType HDF5FileStatic::ParameterDataTypes[] = { - PredType::STD_U64LE, - PredType::STD_U32LE, - PredType::STD_U32LE, - PredType::STD_U64LE, - PredType::STD_U64LE, - PredType::STD_U16LE, - PredType::STD_U16LE, - PredType::STD_U16LE, - PredType::STD_U16LE, - PredType::STD_U32LE, - PredType::STD_U16LE, - PredType::STD_U8LE, - PredType::STD_U8LE}; - - diff --git a/slsReceiverSoftware/src/Listener.cpp b/slsReceiverSoftware/src/Listener.cpp index 2ec7c9254..052345e2a 100644 --- a/slsReceiverSoftware/src/Listener.cpp +++ b/slsReceiverSoftware/src/Listener.cpp @@ -18,19 +18,13 @@ using namespace std; const string Listener::TypeName = "Listener"; -int Listener::NumberofListeners(0); -uint64_t Listener::ErrorMask(0x0); - -uint64_t Listener::RunningMask(0x0); - -pthread_mutex_t Listener::Mutex = PTHREAD_MUTEX_INITIALIZER; - -bool Listener::SilentMode(false); - - -Listener::Listener(detectorType dtype, Fifo*& f, runStatus* s, uint32_t* portno, char* e, int* act, uint64_t* nf, uint32_t* dr) : - ThreadObject(NumberofListeners), +Listener::Listener(int ind, detectorType dtype, Fifo*& f, runStatus* s, + uint32_t* portno, char* e, uint64_t* nf, uint32_t* dr, + uint32_t* us, uint32_t* as, uint32_t* fpf, + frameDiscardPolicy* fdp) : + ThreadObject(ind), + runningFlag(0), generalData(0), fifo(f), myDetectorType(dtype), @@ -38,9 +32,12 @@ Listener::Listener(detectorType dtype, Fifo*& f, runStatus* s, uint32_t* portno, udpSocket(0), udpPortNumber(portno), eth(e), - activated(act), numImages(nf), dynamicRange(dr), + udpSocketBufferSize(us), + actualUDPSocketBufferSize(as), + framesPerFile(fpf), + frameDiscardMode(fdp), acquisitionStartedFlag(false), measurementStartedFlag(false), firstAcquisitionIndex(0), @@ -51,53 +48,34 @@ Listener::Listener(detectorType dtype, Fifo*& f, runStatus* s, uint32_t* portno, carryOverFlag(0), carryOverPacket(0), listeningPacket(0), - udpSocketAlive(0) + udpSocketAlive(0), + numPacketsStatistic(0), + numFramesStatistic(0), + silentMode(false) { - if(ThreadObject::CreateThread()){ - pthread_mutex_lock(&Mutex); - ErrorMask ^= (1<packetSize, (strlen(eth)?eth:NULL), generalData->headerPacketSize); + + udpSocket = new genericSocket(*udpPortNumber, genericSocket::UDP, + generalData->packetSize, (strlen(eth)?eth:NULL), generalData->headerPacketSize, + *udpSocketBufferSize); int iret = udpSocket->getErrorStatus(); if(!iret){ FILE_LOG(logINFO) << index << ": UDP port opened at port " << *udpPortNumber; @@ -230,6 +204,11 @@ int Listener::CreateUDPSockets() { return FAIL; } udpSocketAlive = true; + sem_init(&semaphore_socket,1,0); + + // doubled due to kernel bookkeeping (could also be less due to permissions) + *actualUDPSocketBufferSize = udpSocket->getActualUDPSocketBufferSize(); + return OK; } @@ -242,10 +221,62 @@ void Listener::ShutDownUDPSocket() { FILE_LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber; fflush(stdout); //delete socket at stoplistening + sem_wait(&semaphore_socket); + delete udpSocket; + udpSocket = 0; + sem_destroy(&semaphore_socket); } } +void Listener::SetSilentMode(bool mode) { + silentMode = mode; +} + + +int Listener::CreateDummySocketForUDPSocketBufferSize(uint32_t s) { + FILE_LOG(logINFO) << "Testing UDP Socket Buffer size with test port " << *udpPortNumber; + uint32_t temp = *udpSocketBufferSize; + *udpSocketBufferSize = s; + + //if eth is mistaken with ip address + if (strchr(eth,'.') != NULL){ + memset(eth, 0, MAX_STR_LENGTH); + } + + // shutdown if any open + if(udpSocket){ + udpSocket->ShutDownSocket(); + delete udpSocket; + } + + //create dummy socket + udpSocket = new genericSocket(*udpPortNumber, genericSocket::UDP, + generalData->packetSize, (strlen(eth)?eth:NULL), generalData->headerPacketSize, + *udpSocketBufferSize); + int iret = udpSocket->getErrorStatus(); + if (iret){ + FILE_LOG(logERROR) << "Could not create a test UDP socket on port " << *udpPortNumber << " error: " << iret; + return FAIL; + } + // doubled due to kernel bookkeeping (could also be less due to permissions) + *actualUDPSocketBufferSize = udpSocket->getActualUDPSocketBufferSize(); + if (*actualUDPSocketBufferSize != (s*2)) { + *udpSocketBufferSize = temp; + } + + + // shutdown socket + if(udpSocket){ + udpSocketAlive = false; + udpSocket->ShutDownSocket(); + delete udpSocket; + udpSocket = 0; + } + + return OK; +} + void Listener::ThreadExecution() { char* buffer; @@ -257,7 +288,7 @@ void Listener::ThreadExecution() { #endif //udpsocket doesnt exist - if (*activated && !udpSocketAlive && !carryOverFlag) { + if (!udpSocketAlive && !carryOverFlag) { //FILE_LOG(logERROR) << "Listening_Thread " << index << ": UDP Socket not created or shut down earlier"; (*((uint32_t*)buffer)) = 0; StopListening(buffer); @@ -266,21 +297,12 @@ void Listener::ThreadExecution() { //get data if ((*status != TRANSMITTING && udpSocketAlive) || carryOverFlag) { - if (*activated) - rc = ListenToAnImage(buffer); - else - rc = CreateAnImage(buffer + generalData->fifoBufferHeaderSize); + rc = ListenToAnImage(buffer); } - /*//done acquiring (removing this, else the last incomplete image will not be sent, directly going to dummy msg) - if ((*status == TRANSMITTING) || ( (!(*activated)) && (rc == 0)) ) { - StopListening(buffer); - return; - }*/ - //error check, (should not be here) if not transmitting yet (previous if) rc should be > 0 - if (rc <= 0) { + if (rc == 0) { //cprintf(RED,"%d Socket shut down while waiting for future packet. udpsocketalive:%d\n",index, udpSocketAlive ); if (!udpSocketAlive) { (*((uint32_t*)buffer)) = 0; @@ -290,6 +312,14 @@ void Listener::ThreadExecution() { return; } + // discarding image + else if (rc < 0) { + FILE_LOG(logDEBUG) << index << " discarding fnum:" << currentFrameIndex; + fifo->FreeAddress(buffer); + currentFrameIndex++; + return; + } + (*((uint32_t*)buffer)) = rc; (*((uint64_t*)(buffer + FIFO_HEADER_NUMBYTES ))) = currentFrameIndex; //for those returning earlier currentFrameIndex++; @@ -298,9 +328,11 @@ void Listener::ThreadExecution() { fifo->PushAddress(buffer); //Statistics - if(!SilentMode) { + if(!silentMode) { numFramesStatistic++; - if (numFramesStatistic >= generalData->maxFramesPerFile) + if (numFramesStatistic >= + //second condition also for infinite #number of frames + (((*framesPerFile) == 0) ? STATISTIC_FRAMENUMBER_INFINITE : (*framesPerFile)) ) PrintFifoStatistics(); } } @@ -311,10 +343,8 @@ void Listener::StopListening(char* buf) { (*((uint32_t*)buf)) = DUMMY_PACKET_VALUE; fifo->PushAddress(buf); StopRunning(); - if (udpSocket) { - delete udpSocket; - udpSocket = 0; - } + + sem_post(&semaphore_socket); #ifdef VERBOSE cprintf(GREEN,"%d: Listening Packets (%u) : %llu\n", index, *udpPortNumber, numPacketsCaught); cprintf(GREEN,"%d: Listening Completed\n", index); @@ -335,15 +365,16 @@ uint32_t Listener::ListenToAnImage(char* buf) { uint32_t pperFrame = generalData->packetsPerFrame; bool isHeaderEmpty = true; sls_detector_header* old_header = 0; - sls_detector_header* new_header = 0; + sls_receiver_header* new_header = 0; bool standardheader = generalData->standardheader; uint32_t corrected_dsize = dsize - ((pperFrame * dsize) - generalData->imageSize); //reset to -1 memset(buf, 0, fifohsize); - memset(buf + fifohsize, 0xFF, generalData->imageSize); - new_header = (sls_detector_header*) (buf + FIFO_HEADER_NUMBYTES); + /*memset(buf + fifohsize, 0xFF, generalData->imageSize);*/ + new_header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); + //look for carry over @@ -367,7 +398,17 @@ uint32_t Listener::ListenToAnImage(char* buf) { cprintf(RED,"Error:(Weird), With carry flag: Frame number %lu less than current frame number %lu\n", fnum, currentFrameIndex); return 0; } - new_header->packetNumber = numpackets; + switch(*frameDiscardMode) { + case DISCARD_EMPTY_FRAMES: + if (!numpackets) + return -1; + break; + case DISCARD_PARTIAL_FRAMES: + return -1; + default: + break; + } + new_header->detHeader.packetNumber = numpackets; return generalData->imageSize; } @@ -393,7 +434,8 @@ uint32_t Listener::ListenToAnImage(char* buf) { } carryOverFlag = false; - numpackets++; //number of packets in this image (each time its copied to buf) + ++numpackets; //number of packets in this image (each time its copied to buf) + new_header->packetsMask[pnum] = 1; //writer header if(isHeaderEmpty) { @@ -403,11 +445,9 @@ uint32_t Listener::ListenToAnImage(char* buf) { } // -------------------old header ------------------------------------------------------------------------------ else { - memset(new_header, 0, sizeof(sls_detector_header)); - new_header->frameNumber = fnum; - new_header->packetNumber = pperFrame; - new_header->detType = (uint8_t) generalData->myDetectorType; - new_header->version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; + new_header->detHeader.frameNumber = fnum; + new_header->detHeader.detType = (uint8_t) generalData->myDetectorType; + new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; } //------------------------------------------------------------------------------------------------------------ isHeaderEmpty = false; @@ -425,10 +465,21 @@ uint32_t Listener::ListenToAnImage(char* buf) { if (udpSocketAlive){ rc = udpSocket->ReceiveDataOnly(listeningPacket); } + // end of acquisition if(rc <= 0) { if (numpackets == 0) return 0; //empty image - new_header->packetNumber = numpackets; //number of packets caught + switch(*frameDiscardMode) { + case DISCARD_EMPTY_FRAMES: + if (!numpackets) + return -1; + break; + case DISCARD_PARTIAL_FRAMES: + return -1; + default: + break; + } + new_header->detHeader.packetNumber = numpackets; //number of packets caught return generalData->imageSize; //empty packet now, but not empty image } @@ -473,7 +524,17 @@ uint32_t Listener::ListenToAnImage(char* buf) { carryOverFlag = true; memcpy(carryOverPacket,listeningPacket, generalData->packetSize); - new_header->packetNumber = numpackets; //number of packets caught + switch(*frameDiscardMode) { + case DISCARD_EMPTY_FRAMES: + if (!numpackets) + return -1; + break; + case DISCARD_PARTIAL_FRAMES: + return -1; + default: + break; + } + new_header->detHeader.packetNumber = numpackets; //number of packets caught return generalData->imageSize; } @@ -497,7 +558,9 @@ uint32_t Listener::ListenToAnImage(char* buf) { memcpy(buf + fifohsize + (pnum * dsize), listeningPacket + hsize, dsize); break; } - numpackets++; //number of packets in this image (each time its copied to buf) + ++numpackets; //number of packets in this image (each time its copied to buf) + new_header->packetsMask[pnum] = 1; + if(isHeaderEmpty) { // -------------------------- new header ---------------------------------------------------------------------- if (standardheader) { @@ -505,38 +568,21 @@ uint32_t Listener::ListenToAnImage(char* buf) { } // -------------------old header ------------------------------------------------------------------------------ else { - memset(new_header, 0, sizeof(sls_detector_header)); - new_header->frameNumber = fnum; - new_header->packetNumber = pperFrame; - new_header->detType = (uint8_t) generalData->myDetectorType; - new_header->version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; + new_header->detHeader.frameNumber = fnum; + new_header->detHeader.detType = (uint8_t) generalData->myDetectorType; + new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; } //------------------------------------------------------------------------------------------------------------ isHeaderEmpty = false; } } - new_header->packetNumber = numpackets; //number of packets caught + // complete image + new_header->detHeader.packetNumber = numpackets; //number of packets caught return generalData->imageSize; } -uint32_t Listener::CreateAnImage(char* buf) { - - if (!measurementStartedFlag) - RecordFirstIndices(0); - - if (currentFrameIndex == *numImages) - return 0; - - //update parameters - numPacketsCaught++; //record immediately to get more time before socket shutdown - - //reset data to -1 - memset(buf, 0xFF, generalData->dataSize); - - return generalData->imageSize; -} void Listener::PrintFifoStatistics() { diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index cf3c3265d..69f25ce98 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -47,6 +47,7 @@ void UDPBaseImplementation::initializeMembers(){ acquisitionPeriod = 0; acquisitionTime = 0; subExpTime = 0; + subPeriod = 0; numberOfFrames = 0; numberOfSamples = 0; dynamicRange = 16; @@ -59,18 +60,23 @@ void UDPBaseImplementation::initializeMembers(){ //***receiver parameters*** status = IDLE; activated = true; + frameDiscardMode = NO_DISCARD; + framePadding = false; //***connection parameters*** strcpy(eth,""); for(int i=0;i= 0 && i < NUM_DISCARD_POLICIES) + frameDiscardMode = i; + + FILE_LOG(logINFO) << "Frame Discard Policy: " << getFrameDiscardPolicyType(frameDiscardMode); +} + +void UDPBaseImplementation::setFramePaddingEnable(const bool i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + framePadding = i; + FILE_LOG(logINFO) << "Frame Padding: " << framePadding; +} + //FIXME: needed? void UDPBaseImplementation::setScanTag(const int i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; @@ -448,6 +602,13 @@ void UDPBaseImplementation::setSubExpTime(const uint64_t i){ FILE_LOG(logINFO) << "Sub Exposure Time: " << (double)subExpTime/(1E9) << "s"; } +void UDPBaseImplementation::setSubPeriod(const uint64_t i){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + subPeriod = i; + FILE_LOG(logINFO) << "Sub Exposure Time: " << (double)subPeriod/(1E9) << "s"; +} + int UDPBaseImplementation::setNumberOfFrames(const uint64_t i){ FILE_LOG(logDEBUG) << __AT__ << " starting"; @@ -597,6 +758,19 @@ void UDPBaseImplementation::setStreamingSourceIP(const char c[]){ FILE_LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP; } +void UDPBaseImplementation::setAdditionalJsonHeader(const char c[]){ + FILE_LOG(logDEBUG) << __AT__ << " starting"; + strcpy(additionalJsonHeader, c); + FILE_LOG(logINFO) << "Additional JSON Header: " << additionalJsonHeader; +} + +int UDPBaseImplementation::setUDPSocketBufferSize(const uint32_t s) { + FILE_LOG(logDEBUG) << __AT__ << " starting"; + + udpSocketBufferSize = s; + return OK; +} + int UDPBaseImplementation::restreamStop() { FILE_LOG(logERROR) << __AT__ << " doing nothing..."; @@ -615,17 +789,13 @@ void UDPBaseImplementation::registerCallBackAcquisitionFinished(void (*func)(uin pAcquisitionFinished=arg; } -void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(uint64_t, - uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, +void UDPBaseImplementation::registerCallBackRawDataReady(void (*func)(char* , char*, uint32_t, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } -void UDPBaseImplementation::registerCallBackRawDataModifyReady(void (*func)(uint64_t, - uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, +void UDPBaseImplementation::registerCallBackRawDataModifyReady(void (*func)(char* , char*, uint32_t&, void*),void *arg){ rawDataModifyReadyCallBack=func; pRawDataReady=arg; diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ecf061c44..40ecfe1aa 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -15,6 +15,7 @@ #include //system #include //strcpy #include //eperm +#include using namespace std; @@ -111,6 +112,7 @@ int64_t UDPStandardImplementation::getAcquisitionIndex() const { } + int UDPStandardImplementation::setGapPixelsEnable(const bool b) { if (gapPixelsEnable != b) { gapPixelsEnable = b; @@ -150,12 +152,13 @@ void UDPStandardImplementation::setFileFormat(const fileFormat f){ void UDPStandardImplementation::setFileWriteEnable(const bool b){ - if (fileWriteEnable != b){ fileWriteEnable = b; for (unsigned int i = 0; i < dataProcessor.size(); ++i) { - dataProcessor[i]->SetupFileWriter(fileWriteEnable, (int*)numDet, fileName, filePath, &fileIndex, - &overwriteEnable, &detID, &numThreads, &numberOfFrames, &dynamicRange, &udpPortNum[i], generalData); + dataProcessor[i]->SetupFileWriter(fileWriteEnable, (int*)numDet, + &framesPerFile, fileName, filePath, &fileIndex, &overwriteEnable, + &detID, &numThreads, &numberOfFrames, &dynamicRange, &udpPortNum[i], + generalData); } } @@ -180,6 +183,8 @@ int UDPStandardImplementation::setShortFrameEnable(const int i) { generalData = new ShortGotthardData(); else generalData = new GotthardData(); + framesPerFile = generalData->maxFramesPerFile; + numberofJobs = -1; //changes to imagesize has to be noted to recreate fifo structure if (SetupFifoStructure() == FAIL) return FAIL; @@ -216,27 +221,23 @@ int UDPStandardImplementation::setDataStreamEnable(const bool enable) { dataStreamer.clear(); if (enable) { - bool error = false; - for ( int i = 0; i < numThreads; ++i ) { - dataStreamer.push_back(new DataStreamer(fifo[i], &dynamicRange, &shortFrameEnable, &fileIndex)); - dataStreamer[i]->SetGeneralData(generalData); - if (dataStreamer[i]->CreateZmqSockets(&numThreads, streamingPort, streamingSrcIP) == FAIL) { - error = true; - break; - } - } - if (DataStreamer::GetErrorMask() || error) { - if (DataStreamer::GetErrorMask()) - cprintf(RED,"Error: Could not create data callback threads\n"); - else - cprintf(RED,"Error: Could not create zmq sockets\n"); - for (vector::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it) - delete(*it); - dataStreamer.clear(); - dataStreamEnable = false; - return FAIL; - } - SetThreadPriorities(); + for ( int i = 0; i < numThreads; ++i ) { + try { + DataStreamer* s = new DataStreamer(i, fifo[i], &dynamicRange, + &shortFrameEnable, &fileIndex, flippedData, additionalJsonHeader); + dataStreamer.push_back(s); + dataStreamer[i]->SetGeneralData(generalData); + dataStreamer[i]->CreateZmqSockets(&numThreads, streamingPort, streamingSrcIP); + } + catch(...) { + for (vector::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it) + delete(*it); + dataStreamer.clear(); + dataStreamEnable = false; + return FAIL; + } + } + SetThreadPriorities(); } } FILE_LOG(logINFO) << "Data Send to Gui: " << dataStreamEnable; @@ -311,9 +312,12 @@ int UDPStandardImplementation::setFifoDepth(const uint32_t i) { void UDPStandardImplementation::setSilentMode(const uint32_t i){ silentMode = i; - Listener::SetSilentMode(i); - DataProcessor::SetSilentMode(i); - DataStreamer::SetSilentMode(i); + for (vector::const_iterator it = listener.begin(); it != listener.end(); ++it) + (*it)->SetSilentMode(i); + for (vector::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it) + (*it)->SetSilentMode(i); + for (vector::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it) + (*it)->SetSilentMode(i); FILE_LOG(logINFO) << "Silent Mode: " << i; } @@ -351,6 +355,8 @@ int UDPStandardImplementation::setDetectorType(const detectorType d) { } numThreads = generalData->threadsPerReceiver; fifoDepth = generalData->defaultFifoDepth; + udpSocketBufferSize = generalData->defaultUdpSocketBufferSize; + framesPerFile = generalData->maxFramesPerFile; //local network parameters SetLocalNetworkParameters(); @@ -363,21 +369,32 @@ int UDPStandardImplementation::setDetectorType(const detectorType d) { } //create threads - for ( int i=0; i < numThreads; ++i ) { - listener.push_back(new Listener(myDetectorType, fifo[i], &status, &udpPortNum[i], eth, &activated, &numberOfFrames, &dynamicRange)); - dataProcessor.push_back(new DataProcessor(fifo[i], &fileFormatType, - fileWriteEnable, &dataStreamEnable, &gapPixelsEnable, &dynamicRange, &frameToGuiFrequency, &frameToGuiTimerinMS, - rawDataReadyCallBack, rawDataModifyReadyCallBack, pRawDataReady)); - if (Listener::GetErrorMask() || DataProcessor::GetErrorMask()) { - FILE_LOG(logERROR) << "Could not create listener/dataprocessor threads (index:" << i << ")"; - for (vector::const_iterator it = listener.begin(); it != listener.end(); ++it) - delete(*it); - listener.clear(); - for (vector::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it) - delete(*it); - dataProcessor.clear(); - return FAIL; - } + for ( int i = 0; i < numThreads; ++i ) { + + try { + Listener* l = new Listener(i, myDetectorType, fifo[i], &status, + &udpPortNum[i], eth, &numberOfFrames, &dynamicRange, + &udpSocketBufferSize, &actualUDPSocketBufferSize, &framesPerFile, + &frameDiscardMode); + listener.push_back(l); + + DataProcessor* p = new DataProcessor(i, myDetectorType, fifo[i], &fileFormatType, + fileWriteEnable, &dataStreamEnable, &gapPixelsEnable, + &dynamicRange, &frameToGuiFrequency, &frameToGuiTimerinMS, + &framePadding, + rawDataReadyCallBack, rawDataModifyReadyCallBack, pRawDataReady); + dataProcessor.push_back(p); + } + catch (...) { + FILE_LOG(logERROR) << "Could not create listener/dataprocessor threads (index:" << i << ")"; + for (vector::const_iterator it = listener.begin(); it != listener.end(); ++it) + delete(*it); + listener.clear(); + for (vector::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it) + delete(*it); + dataProcessor.clear(); + return FAIL; + } } //set up writer and callbacks @@ -388,6 +405,9 @@ int UDPStandardImplementation::setDetectorType(const detectorType d) { SetThreadPriorities(); + // check udp socket buffer size + setUDPSocketBufferSize(udpSocketBufferSize); + FILE_LOG(logDEBUG) << " Detector type set to " << getDetectorType(d); return OK; } @@ -396,12 +416,13 @@ int UDPStandardImplementation::setDetectorType(const detectorType d) { void UDPStandardImplementation::setDetectorPositionId(const int i){ - detID = i; FILE_LOG(logINFO) << "Detector Position Id:" << detID; for (unsigned int i = 0; i < dataProcessor.size(); ++i) { - dataProcessor[i]->SetupFileWriter(fileWriteEnable, (int*)numDet, fileName, filePath, &fileIndex, - &overwriteEnable, &detID, &numThreads, &numberOfFrames, &dynamicRange, &udpPortNum[i], generalData); + dataProcessor[i]->SetupFileWriter(fileWriteEnable, (int*)numDet, + &framesPerFile, fileName, filePath, &fileIndex, &overwriteEnable, + &detID, &numThreads, &numberOfFrames, &dynamicRange, &udpPortNum[i], + generalData); } } @@ -474,14 +495,20 @@ void UDPStandardImplementation::stopReceiver(){ //set status to transmitting startReadout(); - //wait for the processes to be done - while(Listener::GetRunningMask()){ - usleep(5000); - } - while(DataProcessor::GetRunningMask()){ - usleep(5000); + //wait for the processes (Listener and DataProcessor) to be done + bool running = true; + while(running) { + running = false; + for (vector::const_iterator it = listener.begin(); it != listener.end(); ++it) + if ((*it)->IsRunning()) + running = true; + for (vector::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it) + if ((*it)->IsRunning()) + running = true; + usleep(5000); } + //create virtual file if (fileWriteEnable && fileFormatType == HDF5) { uint64_t maxIndexCaught = 0; @@ -491,13 +518,19 @@ void UDPStandardImplementation::stopReceiver(){ if((*it)->GetMeasurementStartedFlag()) anycaught = true; } - if (anycaught) - dataProcessor[0]->EndofAcquisition(maxIndexCaught); //to create virtual file + //to create virtual file & set files/acquisition to 0 (only hdf5 at the moment) + dataProcessor[0]->EndofAcquisition(anycaught, maxIndexCaught); } - while(DataStreamer::GetRunningMask()){ - usleep(5000); - } + //wait for the processes (DataStreamer) to be done + running = true; + while(running) { + running = false; + for (vector::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it) + if ((*it)->IsRunning()) + running = true; + usleep(5000); + } status = RUN_FINISHED; FILE_LOG(logINFO) << "Status: " << runStatusType(status); @@ -509,7 +542,7 @@ void UDPStandardImplementation::stopReceiver(){ tot += dataProcessor[i]->GetNumFramesCaught(); uint64_t missingpackets = numberOfFrames*generalData->packetsPerFrame-listener[i]->GetPacketsCaught(); - if (missingpackets) { + if ((int)missingpackets > 0) { cprintf(RED, "\n[Port %d]\n",udpPortNum[i]); cprintf(RED, "Missing Packets\t\t: %lld\n",(long long int)missingpackets); cprintf(RED, "Complete Frames\t\t: %lld\n",(long long int)dataProcessor[i]->GetNumFramesCaught()); @@ -591,19 +624,27 @@ void UDPStandardImplementation::shutDownUDPSockets() { void UDPStandardImplementation::closeFiles() { uint64_t maxIndexCaught = 0; + bool anycaught = false; for (vector::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it) { (*it)->CloseFiles(); maxIndexCaught = max(maxIndexCaught, (*it)->GetProcessedMeasurementIndex()); + if((*it)->GetMeasurementStartedFlag()) + anycaught = true; } - if (maxIndexCaught) - dataProcessor[0]->EndofAcquisition(maxIndexCaught); + //to create virtual file & set files/acquisition to 0 (only hdf5 at the moment) + dataProcessor[0]->EndofAcquisition(anycaught, maxIndexCaught); } +int UDPStandardImplementation::setUDPSocketBufferSize(const uint32_t s) { + if (listener.size()) + return listener[0]->CreateDummySocketForUDPSocketBufferSize(s); + return FAIL; +} int UDPStandardImplementation::restreamStop() { bool ret = OK; for (vector::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it) { - if ((*it)->restreamStop() == FAIL) + if ((*it)->RestreamStop() == FAIL) ret = FAIL; } @@ -617,28 +658,28 @@ int UDPStandardImplementation::restreamStop() { void UDPStandardImplementation::SetLocalNetworkParameters() { - //to increase socket receiver buffer size and max length of input queue by changing kernel settings - if (myDetectorType == EIGER) - return; - - char command[255]; - - //to increase Socket Receiver Buffer size - sprintf(command,"echo $((%d)) > /proc/sys/net/core/rmem_max",RECEIVE_SOCKET_BUFFER_SIZE); - if (system(command)) { - FILE_LOG(logWARNING) << "No root privileges to change Socket Receiver Buffer size (net.core.rmem_max)"; - return; - } - FILE_LOG(logINFO) << "Socket Receiver Buffer size (/proc/sys/net/core/rmem_max) modified to " << RECEIVE_SOCKET_BUFFER_SIZE ; - // to increase Max length of input packet queue - sprintf(command,"echo %d > /proc/sys/net/core/netdev_max_backlog",MAX_SOCKET_INPUT_PACKET_QUEUE); - if (system(command)) { - FILE_LOG(logWARNING) << "No root privileges to change Max length of input packet queue (net.core.rmem_max)"; - return; + int max_back_log; + const char *proc_file_name = "/proc/sys/net/core/netdev_max_backlog"; + { + ifstream proc_file(proc_file_name); + proc_file >> max_back_log; + } + + if (max_back_log < MAX_SOCKET_INPUT_PACKET_QUEUE) { + ofstream proc_file(proc_file_name); + if (proc_file.good()) { + proc_file << MAX_SOCKET_INPUT_PACKET_QUEUE << endl; + cprintf(GREEN, "Max length of input packet queue " + "[/proc/sys/net/core/netdev_max_backlog] modified to %d\n", + MAX_SOCKET_INPUT_PACKET_QUEUE); + } else { + const char *msg = "Could not change max length of " + "input packet queue [net.core.netdev_max_backlog]. (No Root Privileges?)"; + FILE_LOG(logWARNING) << msg; + } } - FILE_LOG(logINFO) << "Max length of input packet queue (/proc/sys/net/core/netdev_max_backlog) modified to " << MAX_SOCKET_INPUT_PACKET_QUEUE ; } @@ -647,7 +688,7 @@ void UDPStandardImplementation::SetThreadPriorities() { for (vector::const_iterator it = listener.begin(); it != listener.end(); ++it){ if ((*it)->SetThreadPriority(LISTENER_PRIORITY) == FAIL) { - FILE_LOG(logWARNING) << "No root privileges to prioritize listener threads"; + FILE_LOG(logWARNING) << "Could not prioritize listener threads. (No Root Privileges?)"; return; } } @@ -667,18 +708,20 @@ int UDPStandardImplementation::SetupFifoStructure() { delete(*it); fifo.clear(); for ( int i = 0; i < numThreads; i++ ) { + //create fifo structure - bool success = true; - fifo.push_back( new Fifo ( - (generalData->imageSize) * numberofJobs + (generalData->fifoBufferHeaderSize), - fifoDepth, success)); - if (!success) { - cprintf(RED,"Error: Could not allocate memory for fifo structure of index %d\n", i); - for (vector::const_iterator it = fifo.begin(); it != fifo.end(); ++it) - delete(*it); - fifo.clear(); - return FAIL; - } + try { + Fifo* f = new Fifo (i, + (generalData->imageSize) * numberofJobs + (generalData->fifoBufferHeaderSize), + fifoDepth); + fifo.push_back(f); + } catch (...) { + cprintf(RED,"Error: Could not allocate memory for fifo structure of index %d\n", i); + for (vector::const_iterator it = fifo.begin(); it != fifo.end(); ++it) + delete(*it); + fifo.clear(); + return FAIL; + } //set the listener & dataprocessor threads to point to the right fifo if(listener.size())listener[i]->SetFifo(fifo[i]); if(dataProcessor.size())dataProcessor[i]->SetFifo(fifo[i]); @@ -686,17 +729,13 @@ int UDPStandardImplementation::SetupFifoStructure() { } FILE_LOG(logINFO) << "Memory Allocated Per Fifo: " << ( ((generalData->imageSize) * numberofJobs + (generalData->fifoBufferHeaderSize)) * fifoDepth) << " bytes" ; - FILE_LOG(logINFO) << " Fifo structure(s) reconstructed: " << numThreads; + FILE_LOG(logINFO) << numThreads << " Fifo structure(s) reconstructed"; return OK; } void UDPStandardImplementation::ResetParametersforNewMeasurement() { - Listener::ResetRunningMask(); - DataProcessor::ResetRunningMask(); - DataStreamer::ResetRunningMask(); - for (vector::const_iterator it = listener.begin(); it != listener.end(); ++it) (*it)->ResetParametersforNewMeasurement(); for (vector::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it) @@ -733,7 +772,7 @@ int UDPStandardImplementation::SetupWriter() { bool error = false; for (unsigned int i = 0; i < dataProcessor.size(); ++i) if (dataProcessor[i]->CreateNewFile(tengigaEnable, - numberOfFrames, acquisitionTime, subExpTime, acquisitionPeriod) == FAIL) { + numberOfFrames, acquisitionTime, subExpTime, subPeriod, acquisitionPeriod) == FAIL) { error = true; break; } diff --git a/slsReceiverSoftware/src/main.cpp b/slsReceiverSoftware/src/main.cpp index 91c22db9a..dba13f4c2 100644 --- a/slsReceiverSoftware/src/main.cpp +++ b/slsReceiverSoftware/src/main.cpp @@ -40,19 +40,26 @@ void AcquisitionFinished(uint64_t frames, void*p){ } -void GetData(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, - uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, - char* datapointer, uint32_t* datasize, void* p){ +void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){ + slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata; + slsReceiverDefs::sls_detector_header detectorHeader = header->detHeader; - PRINT_IN_COLOR (xCoord, + PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.xCoord, "#### %d GetData: ####\n" - "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu\t\ttimestamp: %llu\t\tmodId: %u\t\t" - "xCoord: %u\t\tyCoord: %u\t\tzCoord: %u\t\tdebug: %u\t\troundRNumber: %u\t\tdetType: %u\t\t" - "version: %u\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", - xCoord, frameNumber, expLength, packetNumber, bunchId, timestamp, modId, - xCoord, yCoord, zCoord, debug, roundRNumber, detType, version, - ((uint8_t)(*((uint8_t*)(datapointer)))), *datasize); - + "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu" + "\t\ttimestamp: %llu\t\tmodId: %u\t\t" + "xCoord: %u\t\tyCoord: %u\t\tzCoord: %u\t\tdebug: %u" + "\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u" + //"\t\tpacketsMask:%s" + "\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", + detectorHeader.xCoord, detectorHeader.frameNumber, + detectorHeader.expLength, detectorHeader.packetNumber, detectorHeader.bunchId, + detectorHeader.timestamp, detectorHeader.modId, + detectorHeader.xCoord, detectorHeader.yCoord, detectorHeader.zCoord, + detectorHeader.debug, detectorHeader.roundRNumber, + detectorHeader.detType, detectorHeader.version, + //header->packetsMask.to_string().c_str(), + ((uint8_t)(*((uint8_t*)(datapointer)))), datasize); } */ @@ -121,13 +128,13 @@ int main(int argc, char *argv[]) { /** args to raw data ready callback are - framenum + sls_receiver_header frame metadata datapointer file descriptor guidatapointer (NULL, no data required) NEVER DELETE THE DATA POINTER REMEMBER THAT THE CALLBACK IS BLOCKING - registerCallBackRawDataReady(void (*func)(int, char*, FILE*, char*, void*),void *arg); + registerCallBackRawDataReady(void (*func)(char*, char*, uint32_t, void*),void *arg); */ //receiver->registerCallBackRawDataReady(rawDataReadyCallBack,NULL); diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 838554bb3..370fcd030 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -42,7 +42,8 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success): {0, 0, 0, 0} }; - + //initialize global optind variable (required when instantiating multiple receivers in the same process) + optind = 1; // getopt_long stores the option index here. int option_index = 0; int c = 0; @@ -104,7 +105,6 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success): } if (success==OK){ - FILE_LOG(logINFO) << "SLS Receiver starting TCP Server on port " << tcpip_port_no << endl; tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); } } @@ -150,9 +150,7 @@ void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t, voi } -void slsReceiver::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, - uint32_t, uint16_t, uint8_t, uint8_t, +void slsReceiver::registerCallBackRawDataReady(void (*func)(char*, char*, uint32_t, void*),void *arg){ //tcpipInterface if(udp_interface) @@ -162,9 +160,7 @@ void slsReceiver::registerCallBackRawDataReady(void (*func)(uint64_t, uint32_t, } -void slsReceiver::registerCallBackRawDataModifyReady(void (*func)(uint64_t, uint32_t, - uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, uint16_t, - uint32_t, uint16_t, uint8_t, uint8_t, +void slsReceiver::registerCallBackRawDataModifyReady(void (*func)(char*, char*, uint32_t &, void*),void *arg){ //tcpipInterface if(udp_interface) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index ae24c75f4..07c0f84ac 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -8,6 +8,7 @@ #include "gitInfoReceiver.h" #include "slsReceiverUsers.h" #include "slsReceiver.h" +#include "versionAPI.h" #include //EXIT #include @@ -37,6 +38,7 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* fnum(-1), lockStatus(0), killTCPServerThread(0), + tcpThreadCreated(false), portNumber(DEFAULT_PORTNO+2), mySock(NULL) { @@ -133,6 +135,7 @@ int slsReceiverTCPIPInterface::start(){ FILE_LOG(logERROR) << "Could not create TCP Server thread"; return FAIL; } + tcpThreadCreated = true; //#ifdef VERYVERBOSE FILE_LOG(logDEBUG) << "TCP Server thread created successfully."; //#endif @@ -141,19 +144,22 @@ int slsReceiverTCPIPInterface::start(){ void slsReceiverTCPIPInterface::stop(){ - FILE_LOG(logINFO) << "Shutting down TCP Socket"; - killTCPServerThread = 1; - if(mySock) mySock->ShutDownSocket(); - FILE_LOG(logDEBUG) << "TCP Socket closed"; - pthread_join(TCPServer_thread, NULL); - killTCPServerThread = 0; - FILE_LOG(logINFO) << "TCP Server Thread closed"; + if (tcpThreadCreated) { + FILE_LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber; + killTCPServerThread = 1; + if(mySock) mySock->ShutDownSocket(); + FILE_LOG(logDEBUG) << "TCP Socket closed on port " << portNumber; + pthread_join(TCPServer_thread, NULL); + tcpThreadCreated = false; + killTCPServerThread = 0; + FILE_LOG(logDEBUG) << "Exiting TCP Server Thread on port " << portNumber; + } } int64_t slsReceiverTCPIPInterface::getReceiverVersion(){ - int64_t retval = GITDATE; + int64_t retval = GITDATE & 0xFFFFFF; return retval; } @@ -170,17 +176,13 @@ void slsReceiverTCPIPInterface::registerCallBackAcquisitionFinished(void (*func) pAcquisitionFinished=arg; } -void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(uint64_t, - uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, +void slsReceiverTCPIPInterface::registerCallBackRawDataReady(void (*func)(char* , char*, uint32_t, void*),void *arg){ rawDataReadyCallBack=func; pRawDataReady=arg; } -void slsReceiverTCPIPInterface::registerCallBackRawDataModifyReady(void (*func)(uint64_t, - uint32_t, uint32_t, uint64_t, uint64_t, uint16_t, uint16_t, uint16_t, - uint16_t, uint32_t, uint16_t, uint8_t, uint8_t, +void slsReceiverTCPIPInterface::registerCallBackRawDataModifyReady(void (*func)(char* , char*, uint32_t &,void*),void *arg){ rawDataModifyReadyCallBack=func; pRawDataReady=arg; @@ -196,6 +198,7 @@ void* slsReceiverTCPIPInterface::startTCPServerThread(void *this_pointer){ void slsReceiverTCPIPInterface::startTCPServer(){ cprintf(BLUE,"Created [ TCP server Tid: %ld ]\n", (long)syscall(SYS_gettid)); + FILE_LOG(logINFO) << "SLS Receiver starting TCP Server on port " << portNumber << endl; #ifdef VERYVERBOSE FILE_LOG(logDEBUG5) << "Starting Receiver TCP Server"; @@ -293,6 +296,14 @@ const char* slsReceiverTCPIPInterface::getFunctionName(enum recFuncs func) { case F_RECEIVER_STREAMING_SRC_IP: return "F_RECEIVER_STREAMING_SRC_IP"; case F_ENABLE_GAPPIXELS_IN_RECEIVER:return "F_ENABLE_GAPPIXELS_IN_RECEIVER"; case F_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER"; + case F_ADDITIONAL_JSON_HEADER: return "F_ADDITIONAL_JSON_HEADER"; + case F_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_UDP_SOCK_BUF_SIZE"; + case F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE"; + case F_SET_RECEIVER_FRAMES_PER_FILE:return "F_SET_RECEIVER_FRAMES_PER_FILE"; + case F_RECEIVER_CHECK_VERSION: return "F_RECEIVER_CHECK_VERSION"; + case F_RECEIVER_DISCARD_POLICY: return "F_RECEIVER_DISCARD_POLICY"; + case F_RECEIVER_PADDING_ENABLE: return "F_RECEIVER_PADDING_ENABLE"; + default: return "Unknown Function"; } } @@ -341,6 +352,13 @@ int slsReceiverTCPIPInterface::function_table(){ flist[F_RECEIVER_STREAMING_SRC_IP] = &slsReceiverTCPIPInterface::set_streaming_source_ip; flist[F_ENABLE_GAPPIXELS_IN_RECEIVER] = &slsReceiverTCPIPInterface::enable_gap_pixels; flist[F_RESTREAM_STOP_FROM_RECEIVER] = &slsReceiverTCPIPInterface::restream_stop; + flist[F_ADDITIONAL_JSON_HEADER] = &slsReceiverTCPIPInterface::set_additional_json_header; + flist[F_RECEIVER_UDP_SOCK_BUF_SIZE] = &slsReceiverTCPIPInterface::set_udp_socket_buffer_size; + flist[F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE]= &slsReceiverTCPIPInterface::get_real_udp_socket_buffer_size; + flist[F_SET_RECEIVER_FRAMES_PER_FILE] = &slsReceiverTCPIPInterface::set_frames_per_file; + flist[F_RECEIVER_CHECK_VERSION] = &slsReceiverTCPIPInterface::check_version_compatibility; + flist[F_RECEIVER_DISCARD_POLICY] = &slsReceiverTCPIPInterface::set_discard_policy; + flist[F_RECEIVER_PADDING_ENABLE] = &slsReceiverTCPIPInterface::set_padding_enable; #ifdef VERYVERBOSE for (int i = 0; i < NUM_REC_FUNCTIONS ; i++) { @@ -358,20 +376,22 @@ int slsReceiverTCPIPInterface::decode_function(){ ret = FAIL; #ifdef VERYVERBOSE cprintf(RESET,"\n"); - FILE_LOG(logDEBUG1) << "waiting to receive data"; #endif + FILE_LOG(logDEBUG1) << "waiting to receive data"; int n = mySock->ReceiveDataOnly(&fnum,sizeof(fnum)); if (n <= 0) { -#ifdef VERYVERBOSE - FILE_LOG(logDEBUG1) << "ERROR reading from socket. Received " << n << " bytes, fd: " << file_des << " fnum:" << fnum << " (" << getFunctionName((enum recFuncs)fnum) << ")"; -#endif + FILE_LOG(logDEBUG1) << "ERROR reading from socket. " + "Received " << n << " bytes," << + "fnum:" << fnum << " " + "(" << getFunctionName((enum recFuncs)fnum) << ")"; return FAIL; } -#ifdef VERYVERBOSE else FILE_LOG(logDEBUG1) << "Received " << n << " bytes"; - FILE_LOG(logDEBUG1) << "calling function fnum: "<< fnum << " (" << getFunctionName((enum recFuncs)fnum) << ") located at " << flist[fnum]; -#endif + + FILE_LOG(logDEBUG1) << "calling function fnum: "<< fnum << " " + "(" << getFunctionName((enum recFuncs)fnum) << ") " + "located at " << flist[fnum]; if (fnum < REC_FUNC_START_INDEX || fnum >= NUM_REC_FUNCTIONS) { FILE_LOG(logERROR) << "Unknown function enum " << fnum; @@ -420,7 +440,7 @@ void slsReceiverTCPIPInterface::functionNotImplemented() { } -int slsReceiverTCPIPInterface::M_nofunc(){ +int slsReceiverTCPIPInterface::M_nofunc(){printf("111 \n"); ret = FAIL; memset(mess, 0, sizeof(mess)); int n = 0; @@ -429,7 +449,7 @@ int slsReceiverTCPIPInterface::M_nofunc(){ while (n > 0) n = mySock->ReceiveDataOnly(mess,MAX_STR_LENGTH); - sprintf(mess,"Unrecognized Function\n"); + strcpy(mess,"Unrecognized Function. Please do not proceed.\n"); FILE_LOG(logERROR) << mess; // send ok / fail @@ -678,6 +698,24 @@ int slsReceiverTCPIPInterface::send_update() { #endif n += mySock->SendDataOnly(&ind,sizeof(ind)); + //frames per file +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + ind=(int)receiverBase->getFramesPerFile(); +#endif + n += mySock->SendDataOnly(&ind,sizeof(ind)); + + //frame discard policy +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + ind=(int)receiverBase->getFrameDiscardPolicy(); +#endif + n += mySock->SendDataOnly(&ind,sizeof(ind)); + + //frame padding +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + ind=(int)receiverBase->getFramePaddingEnable(); +#endif + n += mySock->SendDataOnly(&ind,sizeof(ind)); + // file write enable #ifdef SLS_RECEIVER_UDP_FUNCTIONS ind=(int)receiverBase->getFileWriteEnable(); @@ -690,6 +728,12 @@ int slsReceiverTCPIPInterface::send_update() { #endif n += mySock->SendDataOnly(&ind,sizeof(ind)); + // gap pixels +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + ind=(int)receiverBase->getGapPixelsEnable(); +#endif + n += mySock->SendDataOnly(&ind,sizeof(ind)); + // receiver read frequency #ifdef SLS_RECEIVER_UDP_FUNCTIONS ind=(int)receiverBase->getFrameToGuiFrequency(); @@ -702,12 +746,6 @@ int slsReceiverTCPIPInterface::send_update() { #endif n += mySock->SendDataOnly(&ind,sizeof(ind)); - // data streaming enable -#ifdef SLS_RECEIVER_UDP_FUNCTIONS - ind=(int)receiverBase->getDataStreamEnable(); -#endif - n += mySock->SendDataOnly(&ind,sizeof(ind)); - // streaming source ip #ifdef SLS_RECEIVER_UDP_FUNCTIONS path = receiverBase->getStreamingSourceIP(); @@ -716,11 +754,19 @@ int slsReceiverTCPIPInterface::send_update() { if (path != NULL) delete[] path; - // gap pixels enable + // additional json header #ifdef SLS_RECEIVER_UDP_FUNCTIONS - ind = (int)receiverBase->getGapPixelsEnable(); + path = receiverBase->getAdditionalJsonHeader(); #endif - mySock->SendDataOnly(&ind,sizeof(ind)); + mySock->SendDataOnly(path,MAX_STR_LENGTH); + if (path != NULL) + delete[] path; + + // data streaming enable +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + ind=(int)receiverBase->getDataStreamEnable(); +#endif + n += mySock->SendDataOnly(&ind,sizeof(ind)); if (!lockStatus) strcpy(mySock->lastClientIP,mySock->thisClientIP); @@ -1033,11 +1079,15 @@ int slsReceiverTCPIPInterface::set_timer() { break; case FRAME_NUMBER: case CYCLES_NUMBER: + case STORAGE_CELL_NUMBER: receiverBase->setNumberOfFrames(index[1]); break; case SUBFRAME_ACQUISITION_TIME: receiverBase->setSubExpTime(index[1]); break; + case SUBFRAME_PERIOD: + receiverBase->setSubPeriod(index[1]); + break; case SAMPLES_JCTB: if (myDetectorType != JUNGFRAUCTB) { ret = FAIL; @@ -1064,11 +1114,15 @@ int slsReceiverTCPIPInterface::set_timer() { break; case FRAME_NUMBER: case CYCLES_NUMBER: + case STORAGE_CELL_NUMBER: retval=receiverBase->getNumberOfFrames(); break; case SUBFRAME_ACQUISITION_TIME: retval=receiverBase->getSubExpTime(); break; + case SUBFRAME_PERIOD: + retval=receiverBase->getSubPeriod(); + break; case SAMPLES_JCTB: if (myDetectorType != JUNGFRAUCTB) { ret = FAIL; @@ -1172,7 +1226,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { } } #ifdef VERYVERBOSE - FILE_LOG(logDEBUG1) << "dynamic range" << dr; + FILE_LOG(logDEBUG1) << "dynamic range: " << retval; #endif #endif @@ -2549,3 +2603,357 @@ int slsReceiverTCPIPInterface::restream_stop(){ // return ok/fail return ret; } + + + +int slsReceiverTCPIPInterface::set_additional_json_header() { + ret = OK; + memset(mess, 0, sizeof(mess)); + char arg[MAX_STR_LENGTH]; + memset(arg, 0, sizeof(arg)); + char* retval=NULL; + + // receive arguments + if (mySock->ReceiveDataOnly(arg,MAX_STR_LENGTH) < 0 ) + return printSocketReadError(); + + // execute action +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (receiverBase == NULL) + invalidReceiverObject(); + else { + // set + if (mySock->differentClients && lockStatus) + receiverlocked(); + else if (receiverBase->getStatus() != IDLE) + receiverNotIdle(); + else { + receiverBase->setAdditionalJsonHeader(arg); + } + + //get + retval = receiverBase->getAdditionalJsonHeader(); + } +#endif +#ifdef VERYVERBOSE + FILE_LOG(logDEBUG1) << "additional json header:" << retval; +#endif + + if (ret == OK && mySock->differentClients) + ret = FORCE_UPDATE; + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) + mySock->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(retval,MAX_STR_LENGTH); + delete[] retval; + + // return ok/fail + return ret; +} + + + +int slsReceiverTCPIPInterface::set_udp_socket_buffer_size() { + ret = OK; + memset(mess, 0, sizeof(mess)); + int index = -1; + int retval = -1; + + // receive arguments + if (mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ) + return printSocketReadError(); + + // execute action +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (receiverBase == NULL) + invalidReceiverObject(); + else { + // set + if(index >= 0) { + if (mySock->differentClients && lockStatus) + receiverlocked(); + else if (receiverBase->getStatus() != IDLE) + receiverNotIdle(); + else { + if (receiverBase->setUDPSocketBufferSize(index) == FAIL) { + ret = FAIL; + strcpy(mess, "Could not create dummy UDP Socket to test buffer size\n"); + FILE_LOG(logERROR) << mess; + } + } + } + //get + retval=receiverBase->getUDPSocketBufferSize(); + if(index >= 0 && ((retval != index) || ((int)receiverBase->getActualUDPSocketBufferSize() != (index*2)))) { + ret = FAIL; + strcpy(mess, "Could not set UDP Socket buffer size (No CAP_NET_ADMIN privileges?)\n"); + FILE_LOG(logERROR) << mess; + } + } +#endif +#ifdef VERYVERBOSE + FILE_LOG(logDEBUG1) << "UDP Socket Buffer Size:" << retval; +#endif + + if (ret == OK && mySock->differentClients) + ret = FORCE_UPDATE; + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) + mySock->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(&retval,sizeof(retval)); + + // return ok/fail + return ret; +} + + + +int slsReceiverTCPIPInterface::get_real_udp_socket_buffer_size(){ + ret = OK; + int retval = -1; + + // execute action +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (receiverBase == NULL) + invalidReceiverObject(); + else retval = receiverBase->getActualUDPSocketBufferSize(); +#endif + + if (ret == OK && mySock->differentClients) + ret = FORCE_UPDATE; + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + mySock->SendDataOnly(&retval,sizeof(retval)); + + // return ok/fail + return ret; +} + + + +int slsReceiverTCPIPInterface::set_frames_per_file() { + ret = OK; + memset(mess, 0, sizeof(mess)); + int index = -1; + int retval = -1; + + // receive arguments + if (mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ) + return printSocketReadError(); + + // execute action +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (receiverBase == NULL) + invalidReceiverObject(); + else { + // set + if(index >= 0) { + if (mySock->differentClients && lockStatus) + receiverlocked(); + else if (receiverBase->getStatus() != IDLE) + receiverNotIdle(); + else { + receiverBase->setFramesPerFile(index); + } + } + //get + retval=receiverBase->getFramesPerFile(); + if(index >= 0 && retval != index) { + ret = FAIL; + strcpy(mess, "Could not set frames per file\n"); + FILE_LOG(logERROR) << mess; + } + } +#endif +#ifdef VERYVERBOSE + FILE_LOG(logDEBUG1) << "frames per file:" << retval; +#endif + + if (ret == OK && mySock->differentClients) + ret = FORCE_UPDATE; + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) + mySock->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(&retval,sizeof(retval)); + + // return ok/fail + return ret; +} + + + + + + +int slsReceiverTCPIPInterface::check_version_compatibility() { + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t arg = -1; + int64_t retval = -1; + + // receive arguments + if (mySock->ReceiveDataOnly(&arg,sizeof(arg)) < 0 ) + return printSocketReadError(); + + + // execute action + FILE_LOG(logDEBUG1) << "Checking versioning compatibility with value " << arg; + + int64_t client_requiredVersion = arg; + int64_t rx_apiVersion = APIRECEIVER; + int64_t rx_version = getReceiverVersion(); + + // old client + if (rx_apiVersion > client_requiredVersion) { + ret = FAIL; + sprintf(mess,"This client is incompatible.\n" + "Client's receiver API Version: (0x%llx). Receiver API Version: (0x%llx).\n" + "Incompatible, update client!\n", + (long long unsigned int)client_requiredVersion, + (long long unsigned int)rx_apiVersion); + FILE_LOG(logERROR) << mess; + } + + // old software + else if (client_requiredVersion > rx_version) { + ret = FAIL; + sprintf(mess,"This receiver is incompatible.\n" + "Receiver Version: (0x%llx). Client's receiver API Version: (0x%llx).\n" + "Incompatible, update receiver!\n", + (long long unsigned int)rx_version, + (long long unsigned int)client_requiredVersion); + FILE_LOG(logERROR) << mess; + } + else FILE_LOG(logINFO) << "Compatibility with Client: Successful"; + + if (ret == OK && mySock->differentClients) + ret = FORCE_UPDATE; + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) + mySock->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(&retval,sizeof(retval)); // sending crap (because of thisReceiver interface) + + // return ok/fail + return ret; +} + + + + +int slsReceiverTCPIPInterface::set_discard_policy() { + ret = OK; + memset(mess, 0, sizeof(mess)); + int index = -1; + int retval = -1; + + // receive arguments + if (mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ) + return printSocketReadError(); + + // execute action +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (receiverBase == NULL) + invalidReceiverObject(); + else { + // set + if(index >= 0) { + if (mySock->differentClients && lockStatus) + receiverlocked(); + else if (receiverBase->getStatus() != IDLE) + receiverNotIdle(); + else { + receiverBase->setFrameDiscardPolicy((frameDiscardPolicy)index); + } + } + //get + retval=receiverBase->getFrameDiscardPolicy(); + if(index >= 0 && retval != index) { + ret = FAIL; + strcpy(mess, "Could not set frame discard policy\n"); + FILE_LOG(logERROR) << mess; + } + } +#endif +#ifdef VERYVERBOSE + FILE_LOG(logDEBUG1) << "frame discard policy:" << retval; +#endif + + if (ret == OK && mySock->differentClients) + ret = FORCE_UPDATE; + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) + mySock->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(&retval,sizeof(retval)); + + // return ok/fail + return ret; +} + + + + +int slsReceiverTCPIPInterface::set_padding_enable() { + ret = OK; + memset(mess, 0, sizeof(mess)); + int index = -1; + int retval = -1; + + // receive arguments + if (mySock->ReceiveDataOnly(&index,sizeof(index)) < 0 ) + return printSocketReadError(); + + // execute action +#ifdef SLS_RECEIVER_UDP_FUNCTIONS + if (receiverBase == NULL) + invalidReceiverObject(); + else { + // set + if(index >= 0) { + if (mySock->differentClients && lockStatus) + receiverlocked(); + else if (receiverBase->getStatus() != IDLE) + receiverNotIdle(); + else { + index = (index == 0) ? 0 : 1; + receiverBase->setFramePaddingEnable(index); + } + } + //get + retval=(int)receiverBase->getFramePaddingEnable(); + if(index >= 0 && retval != index) { + ret = FAIL; + strcpy(mess, "Could not set frame padding enable\n"); + FILE_LOG(logERROR) << mess; + } + } +#endif +#ifdef VERYVERBOSE + FILE_LOG(logDEBUG1) << "Frame Padding Enable:" << retval; +#endif + + if (ret == OK && mySock->differentClients) + ret = FORCE_UPDATE; + + // send answer + mySock->SendDataOnly(&ret,sizeof(ret)); + if (ret == FAIL) + mySock->SendDataOnly(mess,sizeof(mess)); + mySock->SendDataOnly(&retval,sizeof(retval)); + + // return ok/fail + return ret; +} + + + diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index ab19b9bac..6b38ccd98 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -29,14 +29,12 @@ void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(uint64_t receiver->registerCallBackAcquisitionFinished(func,arg); } -void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, - uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, +void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(char* header, char* datapointer, uint32_t datasize, void*), void *arg){ receiver->registerCallBackRawDataReady(func,arg); } -void slsReceiverUsers::registerCallBackRawDataModifyReady(void (*func)(uint64_t frameNumber, uint32_t expLength, uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, - uint16_t modId, uint16_t xCoord, uint16_t yCoord, uint16_t zCoord, uint32_t debug, uint16_t roundRNumber, uint8_t detType, uint8_t version, +void slsReceiverUsers::registerCallBackRawDataModifyReady(void (*func)(char* header, char* datapointer, uint32_t& revDatasize, void*), void *arg){ receiver->registerCallBackRawDataModifyReady(func,arg); } diff --git a/slsReceiverSoftware/updateAPIVersion.sh b/slsReceiverSoftware/updateAPIVersion.sh new file mode 100755 index 000000000..389b2929e --- /dev/null +++ b/slsReceiverSoftware/updateAPIVersion.sh @@ -0,0 +1,7 @@ +SRCFILE=include/gitInfoReceiver.h +DSTFILE=include/versionAPI.h + +SRCPATTERN=GITDATE +DSTPATTERN=APIRECEIVER + +awk -v a="$SRCFILE" -v b="$DSTFILE" -v c="$SRCPATTERN" -v d="$DSTPATTERN" 'FNR==NR&&$2==c{x=$3} NR!=FNR{if($2==d){$3="0x"substr(x,5)}print > b}' $SRCFILE $DSTFILE \ No newline at end of file