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<