merging refactor (replacing)
0
manual/Makefile
Normal file → Executable file
0
manual/index.html
Normal file → Executable file
@ -1,26 +0,0 @@
|
||||
INCLUDES = -I .
|
||||
SRC_TEST = main.cpp
|
||||
LIBDIR = ../../bin
|
||||
ZLIBDIR = ../../slsReceiverSoftware/include
|
||||
|
||||
LBITS := $(shell getconf LONG_BIT)
|
||||
SERVER_TYPE = "64 bits compile server detected..."
|
||||
LDFLAG_DET = -I. -L$(LIBDIR) -L$(ZLIBDIR) -lSlsReceiver -lSlsDetector -L/usr/lib64/ -pthread -lrt -L. -lzmq
|
||||
|
||||
all: manual-acq
|
||||
|
||||
manual-acq:$(SRC_TEST)
|
||||
@echo "------------------------------------------------------------"
|
||||
@echo "creating test software"
|
||||
@echo $(SERVER_TYPE)
|
||||
@echo "------------------------------------------------------------"
|
||||
|
||||
mkdir -p bin
|
||||
g++ -o bin/manual-acq $(SRC_TEST) $(INCLUDES) $(LDFLAG_DET) -lm -lstdc++
|
||||
cp bin/manual-acq ../../bin
|
||||
|
||||
clean:
|
||||
@echo "------------------------------------------------------------"
|
||||
@echo "cleaning test software"
|
||||
@echo "------------------------------------------------------------"
|
||||
rm -rf bin/manual-acq
|
@ -1 +0,0 @@
|
||||
../../slsReceiverSoftware/include/ansi.h
|
@ -1,21 +0,0 @@
|
||||
hostname bchip065+bchip195+
|
||||
|
||||
0:rx_tcpport 1954
|
||||
0:rx_udpport 50005
|
||||
0:detectorip 10.1.2.185
|
||||
0:rx_udpip 10.1.2.102
|
||||
|
||||
1:rx_tcpport 1955
|
||||
1:rx_udpport 50006
|
||||
1:detectorip 10.1.2.186
|
||||
1:rx_udpip 10.1.2.102
|
||||
|
||||
rx_hostname pc1875
|
||||
|
||||
outdir /home/l_msdetect/dhanya/outdir
|
||||
|
||||
vhighvoltage 0
|
||||
|
||||
enablefwrite 0
|
||||
|
||||
timing auto
|
@ -1 +0,0 @@
|
||||
../../slsReceiverSoftware/include/libzmq.a
|
@ -1,900 +0,0 @@
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sls_receiver_defs.h"
|
||||
#include "slsReceiverUsers.h"
|
||||
|
||||
#include "sls_detector_defs.h"
|
||||
#include "slsDetectorUsers.h"
|
||||
|
||||
//#define GOTTHARD_25_TEST
|
||||
//#define JUNGFRAU_TEST
|
||||
#define GOTTHARD_TEST
|
||||
|
||||
//======================================================================================================
|
||||
// test configuration
|
||||
//======================================================================================================
|
||||
int acquisition_nb = 1; // number of acquisition to make
|
||||
int acquisition_nb_ok = 0; // number of correct acquisition
|
||||
uint64_t last_acquisition_received_frames; // number of received frames during the last acquisition
|
||||
std::vector <int> acquisition_nb_list;
|
||||
|
||||
bool use_trace = false; // activate the acquisition log
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// GOTTHARD 25um
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
#ifdef GOTTHARD_25_TEST
|
||||
const int receivers_nb = 2; // number of receivers
|
||||
const int receivers_rx_tcpport[receivers_nb] = {1954, 1955}; // tcp port for each receiver
|
||||
|
||||
const int detector_id = 0; // detector identifier for slsDetectorUsers constructor
|
||||
const std::string detector_config_file_name = "gotthard25.config"; // configuration file name (must be present in the same folder of this application)
|
||||
|
||||
const long detector_receiver_fifo_depth = 2500;
|
||||
double detector_exposure_time_sec = 0.005;
|
||||
double detector_exposure_period_sec = 0.10;
|
||||
const double detector_delay_after_trigger_sec = 0.0;
|
||||
const std::string detector_trig_mode = "auto"; // "auto" or "trigger"
|
||||
int64_t detector_nb_frames_per_cycle = 10;
|
||||
const int64_t detector_nb_cycles = 1;
|
||||
int detector_module_index[receivers_nb] = {0, 1};
|
||||
#else
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// GOTTHARD
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
#ifdef GOTTHARD_TEST
|
||||
const int receivers_nb = 1; // number of receivers
|
||||
const int receivers_rx_tcpport[receivers_nb] = {1954}; // tcp port for each receiver
|
||||
|
||||
const int detector_id = 0; // detector identifier for slsDetectorUsers constructor
|
||||
const std::string detector_config_file_name = "gotthard25.config"; // configuration file name (must be present in the same folder of this application)
|
||||
|
||||
const long detector_receiver_fifo_depth = 2500;
|
||||
double detector_exposure_time_sec = 0.005;
|
||||
double detector_exposure_period_sec = 0.1;
|
||||
const double detector_delay_after_trigger_sec = 0.0;
|
||||
const std::string detector_trig_mode = "auto"; // "auto" or "trigger"
|
||||
int64_t detector_nb_frames_per_cycle = 10;
|
||||
const int64_t detector_nb_cycles = 1;
|
||||
int detector_module_index[receivers_nb] = {0};
|
||||
#else
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// JUNGFRAU
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
#ifdef JUNGFRAU_TEST
|
||||
const int receivers_nb = 1; // number of receivers
|
||||
const int receivers_rx_tcpport[receivers_nb] = {1954}; // tcp port for each receiver
|
||||
|
||||
const int detector_id = 0; // detector identifier for slsDetectorUsers constructor
|
||||
const std::string detector_config_file_name = "jungfrau_nanoscopium_switch.config"; // configuration file name (must be present in the same folder of this application)
|
||||
|
||||
const long detector_receiver_fifo_depth = 2500;
|
||||
double detector_exposure_time_sec = 0.0005;
|
||||
double detector_exposure_period_sec = 0.001;
|
||||
const double detector_delay_after_trigger_sec = 0.0;
|
||||
const std::string detector_trig_mode = "auto"; // "auto" or "trigger"
|
||||
int64_t detector_nb_frames_per_cycle = 10000;
|
||||
const int64_t detector_nb_cycles = 1;
|
||||
const int detector_clock_divider = 1;
|
||||
int detector_module_index[receivers_nb] = {0};
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// test instances
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
std::vector<slsReceiverUsers *> receivers;
|
||||
slsDetectorUsers * detector = NULL;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// tools functions
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
/** Define Colors to print data call back in different colors for different recievers */
|
||||
#define PRINT_IN_COLOR(c,f, ...) printf ("\033[%dm" f RESET, 30 + c+1, ##__VA_ARGS__)
|
||||
|
||||
#define PRINT_SEPARATOR() cprintf(MAGENTA, "============================================\n")
|
||||
|
||||
/************************************************************************
|
||||
* \brief cleans the shared memory used by the camera
|
||||
************************************************************************/
|
||||
void clean_shared_memory()
|
||||
{
|
||||
std::string cmd = "rm /dev/shm/slsDetectorPackage*;";
|
||||
std::system(cmd.c_str());
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* \brief converts a version id to a string
|
||||
* \return version in string format (uppercase & hexa)
|
||||
*******************************************************************/
|
||||
std::string convertVersionToString(int64_t in_version)
|
||||
{
|
||||
std::stringstream tempStream;
|
||||
tempStream << "0x" << std::uppercase << std::hex << in_version;
|
||||
return tempStream.str();
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
// Related to commands (put & get)
|
||||
//==================================================================
|
||||
/*******************************************************************
|
||||
* \brief Converts a standard string to args arguments
|
||||
* \param in_command command in command line format
|
||||
* \param out_argv output c-strings c-array
|
||||
* \param out_argc output number of arguments of out_argv
|
||||
*******************************************************************/
|
||||
void convertStringToArgs(const std::string & in_command,
|
||||
char * * & out_argv ,
|
||||
int & out_argc )
|
||||
{
|
||||
out_argv = NULL;
|
||||
out_argc = 0 ;
|
||||
|
||||
// filling a string vector with the command line elements
|
||||
std::vector<std::string> elements;
|
||||
std::stringstream ss(in_command);
|
||||
|
||||
while (ss)
|
||||
{
|
||||
std::string element;
|
||||
ss >> element;
|
||||
|
||||
if(element.size() > 0)
|
||||
{
|
||||
elements.push_back(element);
|
||||
}
|
||||
}
|
||||
|
||||
// setting argc value
|
||||
out_argc = elements.size();
|
||||
|
||||
// allocating argv array
|
||||
out_argv = new char * [out_argc];
|
||||
|
||||
// filling argv array
|
||||
for (int element_index = 0; element_index < out_argc; element_index++)
|
||||
{
|
||||
out_argv[element_index] = new char[elements[element_index].size() + 1]; // adding the allocation of end of c-string
|
||||
strcpy(out_argv[element_index], elements[element_index].c_str()); // copying the string including the eos
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* \brief Releases args arguments
|
||||
* \param in_out_argv output c-strings c-array*(static_cast<int *>(p))
|
||||
* \param in_out_argc output number of arguments of out_argv
|
||||
*******************************************************************/
|
||||
void releaseArgs(char * * & in_out_argv ,
|
||||
int & in_out_argc )
|
||||
{
|
||||
if(in_out_argv != NULL)
|
||||
{
|
||||
// releasing the c_strings array content
|
||||
for (int element_index = 0; element_index < in_out_argc; element_index++)
|
||||
{
|
||||
delete [] in_out_argv[element_index];
|
||||
}
|
||||
|
||||
// releasing the c_strings array
|
||||
delete [] in_out_argv;
|
||||
|
||||
in_out_argv = NULL;
|
||||
in_out_argc = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* \brief Executes a set command
|
||||
* \param in_command command in command line format
|
||||
* \param in_module_index module index
|
||||
* \return the command result
|
||||
*******************************************************************/
|
||||
std::string setCmd(const std::string & in_command, int in_module_index=-1)
|
||||
{
|
||||
std::cout << "setCmd - execute set command:\"" << in_command << "\"" << std::endl;
|
||||
|
||||
char * * argv ;
|
||||
int argc ;
|
||||
std::string result;
|
||||
|
||||
convertStringToArgs(in_command, argv, argc);
|
||||
|
||||
if(argc > 0)
|
||||
{
|
||||
result = detector->putCommand(argc, argv, in_module_index);
|
||||
}
|
||||
|
||||
releaseArgs(argv, argc);
|
||||
|
||||
std::cout << "result=\"" << result << "\"" << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* \brief Executes a get command
|
||||
* \param in_command command in command line format
|
||||
* \param in_module_index module index
|
||||
* \return the command result
|
||||
*******************************************************************/
|
||||
std::string getCmd(const std::string & in_command, int in_module_index=-1)
|
||||
{
|
||||
std::cout << "getCmd - execute get command:\"" << in_command << "\"" << std::endl;
|
||||
|
||||
char * * argv ;
|
||||
int argc ;
|
||||
std::string result;
|
||||
|
||||
convertStringToArgs(in_command, argv, argc);
|
||||
|
||||
if(argc > 0)
|
||||
{
|
||||
result = detector->getCommand(argc, argv, in_module_index);
|
||||
}
|
||||
|
||||
releaseArgs(argv, argc);
|
||||
|
||||
std::cout << "result=\"" << result << "\"" << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// Receivers callbacks
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* Start Acquisition Call back
|
||||
* slsReceiver writes data if file write enabled.
|
||||
* Users get data to write using call back if registerCallBackRawDataReady is registered.
|
||||
* @param filepath file path
|
||||
* @param filename file name
|
||||
* @param fileindex file index
|
||||
* @param datasize data size in bytes
|
||||
* @param p pointer to object
|
||||
* \returns ignored
|
||||
*/
|
||||
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);
|
||||
|
||||
cprintf(BLUE, "--StartAcq: returning 0\n");
|
||||
last_acquisition_received_frames = 0LL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquisition Finished Call back
|
||||
* @param frames Number of frames caught
|
||||
* @param p pointer to object
|
||||
*/
|
||||
void AcquisitionFinished(uint64_t frames, void*p){
|
||||
cprintf(BLUE, "#### AcquisitionFinished: frames:%llu ####\n",frames);
|
||||
last_acquisition_received_frames = frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Receiver Data Call back
|
||||
* Prints in different colors(for each receiver process) the different headers for each image call back.
|
||||
* @param metadata sls_receiver_header metadata
|
||||
* @param datapointer pointer to data
|
||||
* @param datasize data size in bytes.
|
||||
* @param p pointer to object
|
||||
*/
|
||||
void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p)
|
||||
{
|
||||
if(use_trace)
|
||||
{
|
||||
slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata;
|
||||
const slsReceiverDefs::sls_detector_header & detectorHeader = header->detHeader;
|
||||
|
||||
PRINT_IN_COLOR (*(static_cast<int *>(p)),
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu"
|
||||
"\t\ttimestamp: %llu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %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",
|
||||
*(static_cast<int *>(p)),
|
||||
(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.row,
|
||||
detectorHeader.column,
|
||||
detectorHeader.reserved,
|
||||
detectorHeader.debug,
|
||||
detectorHeader.roundRNumber,
|
||||
detectorHeader.detType,
|
||||
detectorHeader.version,
|
||||
//header->packetsMask.to_string().c_str(),
|
||||
((uint8_t)(*((uint8_t*)(datapointer)))),
|
||||
datasize);
|
||||
}
|
||||
|
||||
if((datapointer != NULL) && (datasize > 0))
|
||||
{
|
||||
char * buffer = new char[datasize];
|
||||
memcpy(buffer, datapointer, datasize);
|
||||
delete [] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// CreateReceivers
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CreateReceivers(void)
|
||||
{
|
||||
// preparing the args for receivers creation
|
||||
char temp_port[10];
|
||||
const int argc = 3;
|
||||
char * args[argc] = {(char*)"slsReceiver", (char*)"--rx_tcpport", temp_port};
|
||||
|
||||
// creating the receivers instances
|
||||
for(int i = 0 ; i < receivers_nb ; i++)
|
||||
{
|
||||
int ret = slsReceiverDefs::OK;
|
||||
|
||||
// changing the udp port in the args
|
||||
sprintf(temp_port, "%d", receivers_rx_tcpport[i]);
|
||||
|
||||
// creating the receiver using the args
|
||||
slsReceiverUsers * receiver = new slsReceiverUsers(argc, args, ret);
|
||||
|
||||
// managing a failed result
|
||||
if(ret==slsReceiverDefs::FAIL)
|
||||
{
|
||||
delete receiver;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// adding the receiver to the receivers container
|
||||
receivers.push_back(receiver);
|
||||
|
||||
std::cout << "receiver (" << i << ") created - port (" << receivers_rx_tcpport[i] << ")" << std::endl;
|
||||
|
||||
// registering callbacks
|
||||
// Call back for start acquisition
|
||||
cprintf(BLUE, "Registering StartAcq()\n");
|
||||
receiver->registerCallBackStartAcquisition(StartAcq, NULL);
|
||||
|
||||
// Call back for acquisition finished
|
||||
cprintf(BLUE, "Registering AcquisitionFinished()\n");
|
||||
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, NULL);
|
||||
|
||||
// Call back for raw data
|
||||
cprintf(BLUE, "Registering GetData() \n");
|
||||
receiver->registerCallBackRawDataReady(GetData, NULL);//&(detector_module_index[i]));
|
||||
|
||||
// starting tcp server thread
|
||||
if (receiver->start() == slsReceiverDefs::FAIL)
|
||||
{
|
||||
delete receiver;
|
||||
cprintf(BLUE,"Could not start receiver (%d)\n", i);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// ReleaseReceivers
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void ReleaseReceivers(void)
|
||||
{
|
||||
// deleting the receivers instances
|
||||
for(int i = 0 ; i < receivers.size() ; i++)
|
||||
{
|
||||
slsReceiverUsers * receiver = receivers[i];
|
||||
|
||||
// stoping tcp server thread
|
||||
receiver->stop();
|
||||
|
||||
delete receiver;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// CreateDetector
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void CreateDetector(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
// create the detector instance
|
||||
detector = new slsDetectorUsers(result, detector_id);
|
||||
|
||||
if(result == slsDetectorDefs::FAIL)
|
||||
{
|
||||
std::cout << "slsDetectorUsers constructor failed! Could not initialize the camera!" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// configuration file is used to properly configure advanced settings in the shared memory
|
||||
result = detector->readConfigurationFile(detector_config_file_name);
|
||||
|
||||
if(result == slsDetectorDefs::FAIL)
|
||||
{
|
||||
std::cout << "readConfigurationFile failed! Could not initialize the camera!" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// set detector in shared memory online (in case no config file was used) */
|
||||
detector->setOnline(slsDetectorDefs::ONLINE_FLAG);
|
||||
|
||||
// set receiver in shared memory online (in case no config file was used) */
|
||||
detector->setReceiverOnline(slsDetectorDefs::ONLINE_FLAG);
|
||||
|
||||
// disabling the file write by the camera
|
||||
detector->enableWriteToFile(slsDetectorDefs::DISABLED);
|
||||
|
||||
// logging some versions informations
|
||||
std::cout << "Detector developer : " << detector->getDetectorDeveloper() << std::endl;
|
||||
std::cout << "Detector type : " << detector->getDetectorType() << std::endl;
|
||||
std::cout << "Detector Firmware Version : " << convertVersionToString(detector->getDetectorFirmwareVersion()) << std::endl;
|
||||
std::cout << "Detector Software Version : " << convertVersionToString(detector->getDetectorSoftwareVersion()) << std::endl;
|
||||
|
||||
// ensuring detector status is idle
|
||||
int status = detector->getDetectorStatus();
|
||||
|
||||
if((status != slsDetectorDefs::IDLE) && (status != slsDetectorDefs::STOPPED))
|
||||
{
|
||||
std::cout << "Detector not ready: " << slsDetectorUsers::runStatusType(status) << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// ReleaseDetector
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void ReleaseDetector(void)
|
||||
{
|
||||
if(detector != NULL)
|
||||
{
|
||||
detector->setReceiverOnline(slsDetectorDefs::OFFLINE_FLAG);
|
||||
detector->setOnline(slsDetectorDefs::OFFLINE_FLAG);
|
||||
|
||||
delete detector;
|
||||
detector = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// RunAcquisition
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
int RunAcquisition(void)
|
||||
{
|
||||
std::string trig_mode_label;
|
||||
|
||||
double exposure_time ;
|
||||
double exposure_period;
|
||||
double delay_after_trigger;
|
||||
|
||||
int64_t nb_frames_per_cycle;
|
||||
int64_t nb_cycles;
|
||||
int64_t nb_frames;
|
||||
#ifdef JUNGFRAU_TEST
|
||||
int clock_divider;
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// setting the receiver fifo depth (number of frames in the receiver memory)
|
||||
detector->setReceiverFifoDepth(detector_receiver_fifo_depth);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
detector->setExposureTime (detector_exposure_time_sec , true); // in seconds
|
||||
detector->setExposurePeriod (detector_exposure_period_sec, true); // in seconds
|
||||
detector->setDelayAfterTrigger(detector_delay_after_trigger_sec, true); // in seconds
|
||||
|
||||
exposure_time = detector->setExposureTime (-1, true); // in seconds
|
||||
exposure_period = detector->setExposurePeriod (-1, true); // in seconds
|
||||
delay_after_trigger = detector->setDelayAfterTrigger(-1, true, 0); // in seconds
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// initing the number of frames per cycle and number of cycles
|
||||
// to avoid problems during the trigger mode change.
|
||||
detector->setNumberOfFrames(1);
|
||||
detector->setNumberOfCycles(1);
|
||||
|
||||
// conversion of trigger mode label to trigger mode index
|
||||
int trigger_mode_index = slsDetectorUsers::getTimingMode(detector_trig_mode);
|
||||
|
||||
// apply the trigger change
|
||||
detector->setTimingMode(trigger_mode_index);
|
||||
|
||||
// converting trigger mode index to trigger mode label
|
||||
trig_mode_label = slsDetectorUsers::getTimingMode(trigger_mode_index);
|
||||
|
||||
// setting the number of cycles
|
||||
nb_cycles = detector->setNumberOfCycles(detector_nb_cycles);
|
||||
|
||||
// setting the number of frames per cycle
|
||||
nb_frames_per_cycle = detector->setNumberOfFrames(detector_nb_frames_per_cycle);
|
||||
|
||||
// setting the gain mode
|
||||
detector->setSettings(slsDetectorUsers::getDetectorSettings("dynamicgain"));
|
||||
#ifndef JUNGFRAU_TEST
|
||||
detector->setSettings(slsDetectorUsers::getDetectorSettings("mediumgain"));
|
||||
#else
|
||||
detector->setSettings(slsDetectorUsers::getDetectorSettings("dynamichg0"));
|
||||
#endif
|
||||
// computing the number of frames
|
||||
nb_frames = nb_cycles * nb_frames_per_cycle;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
#ifdef JUNGFRAU_TEST
|
||||
// clock divider
|
||||
detector->setClockDivider(detector_clock_divider);
|
||||
clock_divider = detector->setClockDivider(-1);
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::cout << "receiver fifo depth : " << detector_receiver_fifo_depth << std::endl;
|
||||
std::cout << "Exposure time in seconds : " << exposure_time << std::endl;
|
||||
std::cout << "Exposure period in seconds : " << exposure_period << std::endl;
|
||||
std::cout << "Delay after trigger in seconds : " << delay_after_trigger << std::endl;
|
||||
std::cout << "Trigger mode : " << trig_mode_label << std::endl;
|
||||
std::cout << "Nb frames per cycle : " << nb_frames_per_cycle << std::endl;
|
||||
std::cout << "Nb cycles : " << nb_cycles << std::endl;
|
||||
std::cout << "Nb frames : " << nb_frames << std::endl;
|
||||
#ifdef JUNGFRAU_TEST
|
||||
std::cout << "Clock divider : " << clock_divider << std::endl;
|
||||
#endif
|
||||
std::cout << "Estimated frame rate : " << (1.0 / exposure_period) << std::endl;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// reset the number of caught frames in the sdk
|
||||
detector->resetFramesCaughtInReceiver();
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
const unsigned int sleep_time_sec = 1; // sleep the thread in seconds
|
||||
|
||||
// starting receiver listening mode
|
||||
if(detector->startReceiver() == slsDetectorDefs::FAIL)
|
||||
{
|
||||
std::cout << "Could not start the receiver listening mode!" << std::endl;
|
||||
return slsDetectorDefs::FAIL;
|
||||
}
|
||||
|
||||
// starting real time acquisition in non blocking mode
|
||||
// returns OK if all detectors are properly started, FAIL otherwise
|
||||
if(detector->startAcquisition() == slsDetectorDefs::FAIL)
|
||||
{
|
||||
detector->stopReceiver();
|
||||
std::cout << "Could not start real time acquisition!" << std::endl;
|
||||
return slsDetectorDefs::FAIL;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// checking if the hardware acquisition is running
|
||||
int status = detector->getDetectorStatus();
|
||||
if((status == slsDetectorDefs::IDLE ) ||
|
||||
(status == slsDetectorDefs::STOPPED) ||
|
||||
(status == slsDetectorDefs::ERROR ))
|
||||
{
|
||||
// we stop the treatment
|
||||
break;
|
||||
}
|
||||
else
|
||||
// hardware acquisition is running, we are waiting for new frames not using the cpu during this time
|
||||
{
|
||||
usleep(sleep_time_sec * 1000 * 1000); // sleep the thread in seconds
|
||||
}
|
||||
}
|
||||
|
||||
// stopping receiver listening mode
|
||||
if(detector->stopReceiver() == slsDetectorDefs::FAIL)
|
||||
{
|
||||
std::cout << "Could not stop real time acquisition!" << std::endl;
|
||||
return slsDetectorDefs::FAIL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "receiver fifo depth : " << detector_receiver_fifo_depth << std::endl;
|
||||
std::cout << "Exposure time in seconds : " << exposure_time << std::endl;
|
||||
std::cout << "Exposure period in seconds : " << exposure_period << std::endl;
|
||||
std::cout << "Delay after trigger in seconds : " << delay_after_trigger << std::endl;
|
||||
std::cout << "Trigger mode : " << trig_mode_label << std::endl;
|
||||
std::cout << "Nb frames per cycle : " << nb_frames_per_cycle << std::endl;
|
||||
std::cout << "Nb cyles : " << nb_cycles << std::endl;
|
||||
std::cout << "Nb frames : " << nb_frames << std::endl;
|
||||
#ifdef JUNGFRAU_TEST
|
||||
std::cout << "Clock divider : " << clock_divider << std::endl;
|
||||
#endif
|
||||
std::cout << "Estimated frame rate : " << (1.0 / exposure_period) << std::endl;
|
||||
|
||||
if(last_acquisition_received_frames == nb_frames)
|
||||
{
|
||||
acquisition_nb_ok++;
|
||||
return slsDetectorDefs::OK;
|
||||
}
|
||||
|
||||
PRINT_SEPARATOR();
|
||||
return slsDetectorDefs::FAIL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// test
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
void Test(void)
|
||||
{
|
||||
try
|
||||
{
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "CreateReceivers" << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
|
||||
CreateReceivers();
|
||||
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "CreateDetector" << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
|
||||
CreateDetector();
|
||||
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "RunAcquisition" << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
|
||||
for(int acquisition_index = 0 ; acquisition_index < acquisition_nb ; acquisition_index++)
|
||||
{
|
||||
cprintf(MAGENTA, "Acquisition number : %d\n", acquisition_index);
|
||||
if (RunAcquisition() == slsDetectorDefs::FAIL) {
|
||||
acquisition_nb_list.push_back(acquisition_index);
|
||||
}
|
||||
}
|
||||
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "ReleaseDetector" << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
|
||||
ReleaseDetector();
|
||||
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "ReleaseReceivers" << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
|
||||
ReleaseReceivers();
|
||||
|
||||
PRINT_SEPARATOR();
|
||||
if (acquisition_nb - acquisition_nb_ok)
|
||||
cprintf(BOLD RED, "Correct acquisition(s) %d/%d\n", acquisition_nb_ok, acquisition_nb);
|
||||
else
|
||||
cprintf(BOLD GREEN, "Correct acquisition(s) %d/%d\n", acquisition_nb_ok, acquisition_nb);
|
||||
if (acquisition_nb - acquisition_nb_ok) {
|
||||
cprintf(RED, "Acquisition(s) gone wrong :\n");
|
||||
for (int list_index = 0; list_index < acquisition_nb_list.size(); ++list_index) {
|
||||
cprintf(RED, "%d\n", acquisition_nb_list[list_index]);
|
||||
}
|
||||
}
|
||||
PRINT_SEPARATOR();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "unknown exception!" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
std::string roi_result =
|
||||
"detector 0:\n"
|
||||
"0 255 -1 -1\n"
|
||||
"detector 1:\n"
|
||||
"1024 1279 -1 -1\n"
|
||||
"\n"
|
||||
"xmin xmax ymin ymax\n"
|
||||
"0 255 -1 -1\n"
|
||||
"2304 2559 -1 -1\n"
|
||||
"roi 2\n";
|
||||
|
||||
#include <vector>
|
||||
|
||||
// use example :
|
||||
// std::vector<slsReceiverDefs::ROI> rois;
|
||||
// get_rois_from_string(roi_result, rois);
|
||||
/*******************************************************************
|
||||
* \brief Cuts the string in pieces
|
||||
* \param[in] in_string source string
|
||||
* \param[in] in_delimitor line delimitor
|
||||
* \param[out] out_lines line container result
|
||||
*******************************************************************/
|
||||
void split_string_line(const std::string & in_string, const char in_delimitor, std::vector<std::string> & out_lines)
|
||||
{
|
||||
std::stringstream ss(in_string);
|
||||
std::string sub_string;
|
||||
|
||||
while (getline(ss, sub_string, in_delimitor))
|
||||
{
|
||||
out_lines.push_back(sub_string);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* \brief retrieve the ROIs from a string
|
||||
* \param[in] in_rois_string string from "get roi" command
|
||||
* \param[out] out_rois ROI container result (empty if no set ROI)
|
||||
*******************************************************************/
|
||||
void get_rois_from_string(const std::string & in_rois_string, std::vector<slsReceiverDefs::ROI> & out_rois)
|
||||
{
|
||||
out_rois.clear();
|
||||
|
||||
try
|
||||
{
|
||||
// cuts the string in lines
|
||||
std::vector<std::string> lines;
|
||||
split_string_line(in_rois_string, '\n', lines);
|
||||
|
||||
if(lines.size() >= 1)
|
||||
{
|
||||
// checks if no ROI ?
|
||||
if(lines[0] != "roi 0")
|
||||
{
|
||||
for(int roi_index = 0 ; roi_index < 2 ; roi_index++)
|
||||
{
|
||||
if(lines.size() >= ((roi_index + 1) * 2)) // two lines per ROI definition
|
||||
{
|
||||
std::stringstream detector_name;
|
||||
detector_name << "detector " << roi_index << ":";
|
||||
|
||||
// checks the first line
|
||||
if(lines[roi_index * 2] == detector_name.str())
|
||||
{
|
||||
std::stringstream ss(lines[(roi_index * 2) + 1]);
|
||||
|
||||
slsReceiverDefs::ROI roi;
|
||||
ss >> roi.xmin;
|
||||
ss >> roi.xmax;
|
||||
ss >> roi.ymin;
|
||||
ss >> roi.ymax;
|
||||
|
||||
out_rois.push_back(roi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
out_rois.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// read_simple_option
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
bool read_simple_option(int argc, char* argv[], const char * in_option_name)
|
||||
{
|
||||
int option_index = 1;
|
||||
|
||||
while(option_index < argc)
|
||||
{
|
||||
if (strcmp(argv[option_index], in_option_name) == 0)
|
||||
{
|
||||
std::cout << "Found option:" << in_option_name << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
option_index++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// read_option_value
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
template <typename T> bool read_option_value(int argc, char* argv[], const char * in_option_name, T & out_option_value)
|
||||
{
|
||||
int option_index = 1;
|
||||
|
||||
while(option_index < argc)
|
||||
{
|
||||
if (strcmp(argv[option_index], in_option_name) == 0)
|
||||
{
|
||||
option_index++;
|
||||
|
||||
if(option_index < argc)
|
||||
{
|
||||
std::stringstream ss(std::string(argv[option_index]));
|
||||
ss >> out_option_value;
|
||||
std::cout << "Found option: " << in_option_name << " " << out_option_value << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
option_index++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
// main
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
if(read_simple_option(argc, argv, "-help") || read_simple_option(argc, argv, "--help"))
|
||||
{
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "Options:" << std::endl;
|
||||
std::cout << "-clean -> clean shared memory" << std::endl;
|
||||
std::cout << "-trace -> activate acquisition log" << std::endl;
|
||||
std::cout << "-exp <value> -> set exposure time value in seconds (for example: -exp 0.0005)" << std::endl;
|
||||
std::cout << "-period <value> -> set period time value in seconds (for example: -period 0.001)" << std::endl;
|
||||
std::cout << "-frames <value> -> set number of frames (for example: -frames 10000)" << std::endl;
|
||||
std::cout << "-acq <value> -> set number of acquisition (for example: -acq 10)" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "example: ./manual-acq -clean -trace -acq 1 -exp 0.0005 -period 0.001 -frames 1000" << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(read_simple_option(argc, argv, "-clean"))
|
||||
{
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "Cleaning shared memory" << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
|
||||
clean_shared_memory();
|
||||
}
|
||||
|
||||
if(read_simple_option(argc, argv, "-trace"))
|
||||
{
|
||||
PRINT_SEPARATOR();
|
||||
std::cout << "Activating acquisition log..." << std::endl;
|
||||
PRINT_SEPARATOR();
|
||||
|
||||
use_trace = true;
|
||||
}
|
||||
|
||||
int64_t frames_value;
|
||||
|
||||
if(read_option_value(argc, argv, "-frames", frames_value))
|
||||
{
|
||||
detector_nb_frames_per_cycle = frames_value;
|
||||
}
|
||||
|
||||
double exp_value;
|
||||
|
||||
if(read_option_value(argc, argv, "-exp", exp_value))
|
||||
{
|
||||
detector_exposure_time_sec = exp_value;
|
||||
}
|
||||
|
||||
double period_value;
|
||||
|
||||
if(read_option_value(argc, argv, "-period", period_value))
|
||||
{
|
||||
detector_exposure_period_sec = period_value;
|
||||
}
|
||||
|
||||
int acq_nb;
|
||||
|
||||
if(read_option_value(argc, argv, "-acq", acq_nb))
|
||||
{
|
||||
acquisition_nb = acq_nb;
|
||||
}
|
||||
|
||||
Test();
|
||||
|
||||
std::cout << "====================== ENDING ======================" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
@ -1 +0,0 @@
|
||||
../../slsDetectorSoftware/slsDetector/slsDetectorUsers.h
|
@ -1 +0,0 @@
|
||||
../../slsReceiverSoftware/include/slsReceiverUsers.h
|
@ -1 +0,0 @@
|
||||
../../slsDetectorSoftware/commonFiles/sls_detector_defs.h
|
@ -1 +0,0 @@
|
||||
../../slsDetectorSoftware/commonFiles/sls_detector_funcs.h
|
@ -1 +0,0 @@
|
||||
../../slsReceiverSoftware/include/sls_receiver_defs.h
|
@ -1 +0,0 @@
|
||||
../../slsReceiverSoftware/include/sls_receiver_funcs.h
|
@ -1 +0,0 @@
|
||||
../../slsReceiverSoftware/include/zmq.h
|
9
manual/manual-api/CMakeLists.txt
Normal file → Executable file
@ -3,8 +3,8 @@ set(SOURCES
|
||||
)
|
||||
|
||||
include_directories(
|
||||
../../slsSupportLib/include
|
||||
../../slsReceiverSoftware/include
|
||||
../../slsDetectorSoftware/slsDetectorAnalysis
|
||||
../../build/bin
|
||||
../../slsdetectorSoftware/slsDetector
|
||||
)
|
||||
@ -16,15 +16,12 @@ add_executable(slsMultiReceiver
|
||||
target_link_libraries(slsMultiReceiver
|
||||
slsReceiverShared
|
||||
pthread
|
||||
zmq
|
||||
${ZeroMQ_LIBRARIES}
|
||||
rt
|
||||
${HDF5_LIBRARIES}
|
||||
)
|
||||
|
||||
if (HDF5_FOUND)
|
||||
target_link_libraries(slsMultiReceiver
|
||||
${HDF5_LIBRARIES}
|
||||
)
|
||||
target_link_libraries(slsMultiReceiver ${HDF5_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
|
||||
|
4
manual/manual-api/Makefile
Normal file → Executable file
@ -1,9 +1,9 @@
|
||||
PKGDIR = ../..
|
||||
LIBDIR = $(PKGDIR)/bin
|
||||
INCLUDES = -I . -I$(PKGDIR)/slsReceiverSoftware/include -I$(PKGDIR)/slsDetectorSoftware/slsDetectorAnalysis -I$(LIBDIR) -I$(PKGDIR)/slsDetectorSoftware/slsDetector
|
||||
INCLUDES = -I . -I$(PKGDIR)/slsSupportLib/include -I$(LIBDIR) -I$(PKGDIR)/slsDetectorSoftware/slsDetector -I$(PKGDIR)/slsReceiversoftware/include
|
||||
SRC_DET = mainClient.cpp
|
||||
SRC_REC = mainReceiver.cpp
|
||||
ZMQLIBDIR = $(PKGDIR)/slsReceiverSoftware/include
|
||||
ZMQLIBDIR = $(PKGDIR)/slsSupportLib/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
|
||||
|
0
manual/manual-api/mainClient.cpp
Normal file → Executable file
42
manual/manual-api/mainReceiver.cpp
Normal file → Executable file
@ -16,7 +16,7 @@ It is linked in manual/manual-api from slsReceiverSoftware/include ]
|
||||
|
||||
*/
|
||||
|
||||
#include "sls_receiver_defs.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include "slsReceiverUsers.h"
|
||||
|
||||
#include <iostream>
|
||||
@ -96,20 +96,20 @@ void AcquisitionFinished(uint64_t frames, void*p){
|
||||
* @param p pointer to object
|
||||
*/
|
||||
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;
|
||||
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata;
|
||||
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
|
||||
|
||||
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row,
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu"
|
||||
"\t\ttimestamp: %llu\t\tmodId: %u\t\t"
|
||||
"frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu"
|
||||
"\t\ttimestamp: %lu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %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.row, (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.row, (long unsigned int)detectorHeader.frameNumber,
|
||||
detectorHeader.expLength, detectorHeader.packetNumber, (long unsigned int)detectorHeader.bunchId,
|
||||
(long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
|
||||
detectorHeader.debug, detectorHeader.roundRNumber,
|
||||
detectorHeader.detType, detectorHeader.version,
|
||||
@ -130,8 +130,8 @@ void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
|
||||
* @param p pointer to object
|
||||
*/
|
||||
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;
|
||||
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata;
|
||||
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
|
||||
|
||||
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row,
|
||||
"#### %d GetData: ####\n"
|
||||
@ -187,7 +187,7 @@ int main(int argc, char *argv[]) {
|
||||
sa.sa_flags=0; // no flags
|
||||
sa.sa_handler=sigInterruptHandler; // handler function
|
||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGINT, &sa, NULL) == -1) {
|
||||
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGINT\n");
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ int main(int argc, char *argv[]) {
|
||||
asa.sa_flags=0; // no flags
|
||||
asa.sa_handler=SIG_IGN; // handler function
|
||||
sigemptyset(&asa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGPIPE, &asa, NULL) == -1) {
|
||||
if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGPIPE\n");
|
||||
}
|
||||
|
||||
@ -221,10 +221,10 @@ int main(int argc, char *argv[]) {
|
||||
char temp[10];
|
||||
sprintf(temp,"%d",startTCPPort + i);
|
||||
char* args[] = {(char*)"ignored", (char*)"--rx_tcpport", temp};
|
||||
int ret = slsReceiverDefs::OK;
|
||||
int ret = slsDetectorDefs::OK;
|
||||
/** - create slsReceiverUsers object with appropriate arguments */
|
||||
slsReceiverUsers *receiver = new slsReceiverUsers(3, args, ret);
|
||||
if(ret==slsReceiverDefs::FAIL){
|
||||
if(ret==slsDetectorDefs::FAIL){
|
||||
delete receiver;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -236,22 +236,22 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
/** - Call back for start acquisition */
|
||||
cprintf(BLUE, "Registering StartAcq()\n");
|
||||
receiver->registerCallBackStartAcquisition(StartAcq, NULL);
|
||||
receiver->registerCallBackStartAcquisition(StartAcq, nullptr);
|
||||
|
||||
/** - Call back for acquisition finished */
|
||||
cprintf(BLUE, "Registering AcquisitionFinished()\n");
|
||||
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, NULL);
|
||||
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, nullptr);
|
||||
|
||||
/* - Call back for raw data */
|
||||
cprintf(BLUE, "Registering GetData() \n");
|
||||
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,NULL);
|
||||
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,NULL);
|
||||
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,nullptr);
|
||||
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** - start tcp server thread */
|
||||
if (receiver->start() == slsReceiverDefs::FAIL){
|
||||
if (receiver->start() == slsDetectorDefs::FAIL){
|
||||
delete receiver;
|
||||
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
exit(EXIT_FAILURE);
|
||||
@ -272,7 +272,7 @@ int main(int argc, char *argv[]) {
|
||||
sa.sa_flags=0; // no flags
|
||||
sa.sa_handler=SIG_IGN; // handler function
|
||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
|
||||
if (sigaction(SIGINT, &sa, NULL) == -1) {
|
||||
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGINT\n");
|
||||
}
|
||||
|
||||
@ -283,7 +283,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
/** - Parent process waits for all child processes to exit */
|
||||
for(;;) {
|
||||
pid_t childPid = waitpid (-1, NULL, 0);
|
||||
pid_t childPid = waitpid (-1, nullptr, 0);
|
||||
|
||||
// no child closed
|
||||
if (childPid == -1) {
|
||||
|
0
manual/manual-api/slsDetectorUsers.doxy
Normal file → Executable file
0
manual/manual-calwiz/Advanced.png
Normal file → Executable file
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
0
manual/manual-calwiz/Constant_step.png
Normal file → Executable file
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
0
manual/manual-calwiz/GUI_Advanced.eps
Normal file → Executable file
0
manual/manual-calwiz/GUI_ThresholdScan.eps
Normal file → Executable file
0
manual/manual-calwiz/Makefile
Normal file → Executable file
0
manual/manual-calwiz/addEnergy.eps
Normal file → Executable file
0
manual/manual-calwiz/addEnergy.png
Normal file → Executable file
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
0
manual/manual-calwiz/ancCal.tex
Normal file → Executable file
0
manual/manual-calwiz/angleFit.eps
Normal file → Executable file
0
manual/manual-calwiz/angleFit.png
Normal file → Executable file
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
0
manual/manual-calwiz/angularCalibrationHowTo.tex
Normal file → Executable file
0
manual/manual-calwiz/calibrateModule.eps
Normal file → Executable file
0
manual/manual-calwiz/calibrateModule.png
Normal file → Executable file
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
0
manual/manual-calwiz/calibrationWizardsHowTo.tex
Normal file → Executable file
0
manual/manual-calwiz/enCal.tex
Normal file → Executable file
0
manual/manual-calwiz/enable_angcal.eps
Normal file → Executable file
0
manual/manual-calwiz/eneble_angcal.png
Normal file → Executable file
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
0
manual/manual-calwiz/energyCalibrationHowTo.tex
Normal file → Executable file
0
manual/manual-calwiz/fig4.eps
Normal file → Executable file
0
manual/manual-calwiz/fig5.eps
Normal file → Executable file
0
manual/manual-calwiz/fig7.eps
Normal file → Executable file
0
manual/manual-calwiz/fig8.eps
Normal file → Executable file
0
manual/manual-calwiz/installation.tex
Normal file → Executable file
0
manual/manual-calwiz/peakFit.eps
Normal file → Executable file
0
manual/manual-calwiz/peakFit.png
Normal file → Executable file
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
0
manual/manual-calwiz/position_scan.eps
Normal file → Executable file
0
manual/manual-calwiz/position_scan.png
Normal file → Executable file
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
0
manual/manual-calwiz/setupAngcal.eps
Normal file → Executable file
0
manual/manual-calwiz/setupAngcal.png
Normal file → Executable file
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
0
manual/manual-calwiz/spectrum_expl.eps
Normal file → Executable file
0
manual/manual-calwiz/thr_scan_expl.eps
Normal file → Executable file
0
manual/manual-calwiz/thr_scan_fluo.eps
Normal file → Executable file
0
manual/manual-client/Boards.png
Normal file → Executable file
Before Width: | Height: | Size: 432 KiB After Width: | Height: | Size: 432 KiB |
0
manual/manual-client/Client2.eps
Normal file → Executable file
0
manual/manual-client/Client2.png
Normal file → Executable file
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
0
manual/manual-client/EIGERUDPHeader.png
Normal file → Executable file
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
BIN
manual/manual-client/Eiger-Chips.png
Executable file
After Width: | Height: | Size: 34 KiB |
187
manual/manual-client/Eiger_short.tex
Normal file → Executable file
@ -6,6 +6,7 @@
|
||||
\usepackage{verbatim}
|
||||
\usepackage{xspace}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{xcolor}
|
||||
\newcommand{\E}{EIGER\xspace}
|
||||
\newcommand{\p}{sls\_detector\_put}
|
||||
\newcommand{\g}{sls\_detector\_get}
|
||||
@ -24,7 +25,7 @@ Figure ~\ref{boards} show the readout board basic components on an Eiger half mo
|
||||
\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.}
|
||||
\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 10~GB ethernet connection.}
|
||||
\label{boards}
|
||||
\end{figure}
|
||||
|
||||
@ -156,6 +157,14 @@ outdir /sls/X12SA/data/x12saop/Data10/Eiger0.5M
|
||||
threaded 1
|
||||
\end{verbatim}
|
||||
|
||||
The geometry on af an EIGER module, showing the quadrants corresponding to the udp ports and the 2 receivers is shown in figure~\ref{fig:eigerports}.
|
||||
\begin{figure}[t]
|
||||
\begin{center}
|
||||
\includegraphics[width=0.9\textwidth]{Eiger-Chips}
|
||||
\end{center}
|
||||
\caption{Geometry of UDP ports and receivers in a singel module.}
|
||||
\label{fig:eigerports}
|
||||
\end{figure}
|
||||
|
||||
In the case you are developing your own receiver, then you need to remove the 1Gb receiver hostname {\tt{rx\_hostname}} and substitute it with the mac address of the device:
|
||||
\begin{verbatim}
|
||||
@ -163,7 +172,6 @@ configuremac 0
|
||||
rx_udpmac xx:xx:...
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
One can configure all the detector settings in a parameter file {\tt{setup.det}}, which is loaded by doing:
|
||||
\begin{verbatim}
|
||||
sls_detector_put 0-parameters setup.det
|
||||
@ -412,18 +420,9 @@ where the 'minimum time between frames' and the minimum period will be discussed
|
||||
\hline
|
||||
4 & 0 & \tiny {parallel} & 3.4 & 22 & 44 & 44.01 & 30k/50k\\
|
||||
\hline
|
||||
4 & 1 & \tiny {parallel} & 6 & 10.5 & 92 & 92.02 & 30k/100k\\
|
||||
\hline
|
||||
4 & 2 & \tiny {parallel} & 11.2 & 5.4 & 197& 197.01 & infinite\\
|
||||
\hline
|
||||
\hline
|
||||
8 & 0 & \tiny {parallel} & 3.4 & 11.1 & 89 & 89.01 & 15k/24k\\
|
||||
\hline
|
||||
8 & 1 & \tiny {parallel} & 6.1 & 5.7 & 181 & 181.01 & 15k/52k\\
|
||||
\hline
|
||||
8 & 2 & \tiny {parallel} & 11.2 & 2.9 & 342 & 342.01 & infinite\\
|
||||
\hline
|
||||
\hline
|
||||
16 & 0 & \tiny {parallel} & 3.4 & 6.1 & (126+38)* =164 & 164.02 & 8k/12k\\
|
||||
\hline
|
||||
16 & 0 & \tiny {nonparallel} & 127 & 5.6 & (126+52)*= 179 & 179.01& 8k/23k\\
|
||||
@ -432,14 +431,6 @@ where the 'minimum time between frames' and the minimum period will be discussed
|
||||
\hline
|
||||
16 & 1 & \tiny {nonparallel} & 255 & 3.3 & 303 & 303.01 & infinite\\
|
||||
\hline
|
||||
16 & 2 & \tiny {parallel} & 11.2 & 1.9 & 526 & 526.2 & infinite \\
|
||||
\hline
|
||||
16 & 2 & \tiny {nonparallel} & 505 & 1.8 & 555 & 555.01& 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 ($\Delta$t) has been measured with the oscilloscope and the maximum frames rate (max FR) has been tested with an external gating from a pulse generator at known frequency. The minimum period is obtained as 1/$\textrm{max frame rate}$.}
|
||||
\label{tframes}
|
||||
@ -450,7 +441,6 @@ where the 'minimum time between frames' and the minimum period will be discussed
|
||||
\textbf{From software version 4.0.0, there is a very useful function {\tt{sls\_detector\_get measuredperiod}} which return the measured period AFTER the acquisition. This is important to check that the settings to obtain the targeted frame rate was correct.}
|
||||
|
||||
\textbf{If you run too fast, the detector could become noisier (see problem shooting), 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})
|
||||
@ -460,7 +450,54 @@ to let the signal settle or, if the frame rate is important, leave the {\tt{pe
|
||||
\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.
|
||||
In general, 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.
|
||||
|
||||
Here below are the final tables for settting the detcetor correctly:
|
||||
|
||||
\begin{itemize}
|
||||
\item CONTINUOUS redout (imagesnot stored on board memories, frames can be achieved. {\tt{flags parallel}}, {\tt{clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s:
|
||||
\begin{center}
|
||||
\begin{tabular}{ |c| c| }
|
||||
\hline
|
||||
max frame rate & settings\\
|
||||
\hline
|
||||
\textcolor{red}{170 Hz} & \textcolor{red}{32-bit} \\
|
||||
& Nframes=infinite\\
|
||||
\hline
|
||||
\textcolor{red}{2.56 kHz} & \textcolor{red}{16-bit}\\
|
||||
& Nframes=infinite\\
|
||||
\hline
|
||||
\textcolor{red}{5.1 kHz} & \textcolor{red}{8-bit}\\
|
||||
& Nframes=infinite\\
|
||||
\hline
|
||||
\textcolor{red}{10.2 kHz} & \textcolor{red}{4-bit}\\
|
||||
& Nframes=infinite\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
\item BUFFERED redout (images stored on board memories, such that the maximum frame rate can be achieved for a limited amount of frames. {\tt{flags parallel}}, {\tt{clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s:
|
||||
\begin{center}
|
||||
\begin{tabular}{ |c| c| }
|
||||
\hline
|
||||
max frame rate & settings\\
|
||||
\hline
|
||||
\textcolor{red}{170 Hz} & \textcolor{red}{32-bit} \\
|
||||
& Nframes=infinite\\
|
||||
\hline
|
||||
\textcolor{red}{6.1 kHz} & \textcolor{red}{16-bit}\\
|
||||
& Nframes=7600\\
|
||||
\hline
|
||||
\textcolor{red}{11.1 kHz} & \textcolor{red}{8-bit}\\
|
||||
& Nframes=15000\\
|
||||
\hline
|
||||
\textcolor{red}{22 kHz} & \textcolor{red}{4-bit}\\
|
||||
& Nframes=30000\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
\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:
|
||||
@ -712,7 +749,7 @@ To activate back a module, do:
|
||||
\end{verbatim}
|
||||
|
||||
\end{itemize}
|
||||
\subsection{Setting up 10Gb correctly: experience so far}\label{10g}
|
||||
\section{Setting up the PC settings for 10Gb}\label{10g}
|
||||
|
||||
For configuring well the 10Gb card not to loose packets,
|
||||
\begin{itemize}
|
||||
@ -734,13 +771,74 @@ Very important is to activate the flow control in 10Gb (in 1Gb it is on by defau
|
||||
\begin{verbatim}
|
||||
./sls_detector_put flowcontrol_10g 1
|
||||
\end{verbatim}
|
||||
Set the transmission delays as explained in the manual.
|
||||
You ned to check that flow control is setup on the reeceiving interfaces. Check with:
|
||||
\begin{verbatim}
|
||||
ethtool -a eth1
|
||||
\end{verbatim}
|
||||
.RX should be ON. Set the transmission delays as explained in the manual if necessary. These transmission delays should help matching teh writing speed performance of your disk. You can check how fast you are writing using the {\tt{dstat}} command.
|
||||
|
||||
Now setup the computer server propery:
|
||||
Check the size of:
|
||||
\begin{verbatim}
|
||||
sysctl -a | grep backlog
|
||||
sysctl -a | grep rmem
|
||||
\end{verbatim}
|
||||
Set it correctly with:
|
||||
\begin{verbatim}
|
||||
sysctl net.core.netdev_max_backlog=250000
|
||||
sysctl net.core.rmem_default=$((100*1024*1024))
|
||||
sysctl net.core.rmem_max=$((100*1024*1024))
|
||||
\end{verbatim}
|
||||
|
||||
Other way to setup the same, increase the socket receiving buffer size and the maximum length of the input queue:
|
||||
\begin{verbatim}
|
||||
echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max
|
||||
echo 250000 > /proc/sys/net/core/netdev_max_backlog
|
||||
\end{verbatim}
|
||||
to make the settings permanent, edit /etc/sysctl.conf:
|
||||
\begin{verbatim}
|
||||
# 100MiB
|
||||
net.core.rmem_max = 104857600
|
||||
net.core.netdev_max_backlog = 250000
|
||||
\end{verbatim}
|
||||
and run \textbf{sysctl -p}.
|
||||
|
||||
Last, you can disable power saving in the CPU frequency (chose the appropriate command for your system):
|
||||
\begin{verbatim}
|
||||
cpupower frequency-info
|
||||
cpupower frequency-set -g performance
|
||||
\end{verbatim}
|
||||
or
|
||||
\begin{verbatim}
|
||||
cpufreq-info
|
||||
for i in `seq 0 7`; do cpufreq-set -c $i -g performance; done
|
||||
\end{verbatim}
|
||||
|
||||
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".
|
||||
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". To receive the max number of images possible on the detector, a minimum of 8~GB of memories are required.
|
||||
For very high frame rate, very long measurements, we had to increase the {\tt{rx\_fifodepth}} to 10000 images but this only in 4, 8, 16 bit mode. In 32 bit mode it will assign 40~GB of memory, which is more than what normal PC would have. So make sure you do not require too much memory.
|
||||
|
||||
Last, it is very important that not too many files are created. There is high possibility to loose packets in the time to close and open files for the writer. IN 3.1.x, the default number of images written per file, in Eiger is 2000. This is defined by the line:
|
||||
\begin{verbatim}
|
||||
#define EIGER_MAX_FRAMES_PER_FILE 2000
|
||||
\end{verbatim}
|
||||
in {\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}. In 4.0.x, this is interactively defined using the command: {\tt{r\_framesperfile}}. By default it is 10000.
|
||||
|
||||
If you do not have a large disk, you can write to memory if your pc is not fast enough:
|
||||
\begin{verbatim}
|
||||
mount -t tmpfs none /ramdisk_folder
|
||||
\end{verbatim}
|
||||
or
|
||||
\begin{verbatim}
|
||||
mount -t tmpfs none /mnt/ramdisk -o size=10G
|
||||
\end{verbatim}
|
||||
check how many GB memory you can allocate, to avoid swapping otherwise
|
||||
|
||||
|
||||
|
||||
|
||||
\section{Offline processing and monitoring}
|
||||
|
||||
@ -820,9 +918,14 @@ Checkout the {\tt{developer}} branch if in a 3.1.X release or the {\tt{v4.0.0}}
|
||||
|
||||
Three possible conversions are possible: into \textbf{cbf}, \textbf{hdf5} and \textbf{root} format. The detector writes 4 raw files per receiver. An offline image reconstruction executable has been written to collate the possible files together and produce output files. By default an interpolation between the values of the large pixels is performed. Gap pixels between modules are also inserted.
|
||||
|
||||
Note that the number of images per file is hardcoded and needs to match whatever you are using in {\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}:
|
||||
\begin{verbatim}
|
||||
#define EIGER_MAX_FRAMES_PER_FILE 2000
|
||||
\end{verbatim}
|
||||
The default is 2000.
|
||||
|
||||
\subsubsection{cbf}
|
||||
The cbf executable executable uses the CBFlib-0.9.5 library (downloaded from the web as it download some architecture dependent packages at installation).Edit the Makefile to correclty point at it.\\
|
||||
The cbf executable executable uses the CBFlib-0.9.5 library (downloaded from the web as it downloads architecture dependent packages at installation).Edit the Makefile to correclty point at it.\\
|
||||
\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:
|
||||
@ -833,7 +936,7 @@ eg.
|
||||
{\tt{cbfMaker /scratch/run\_63\_d1\_f000000000000\_3.raw}}\\
|
||||
|
||||
To use it any geometry:\\
|
||||
{\tt{cbfMaker [filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
|
||||
{\tt{cbfMaker [filename] [outdir, def=same as filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
|
||||
eg.
|
||||
{\tt cbfMaker /scratch/run\_63\_d0\_f000000000000\_3.raw 3072 512 1 2 ``Eiger'' 0}.\\
|
||||
|
||||
@ -877,7 +980,7 @@ make cbfMaker; make cbfMakerOMNY;
|
||||
\end{verbatim}
|
||||
|
||||
\subsubsection{hdf5}
|
||||
In case of HDF5 output file, we rely on having the HDF5 1.10.1 library installed. Edit the Makefile to correclty point at it. Different compression methods are being tried so different external filters might be to be installed. This work is not finished yet.
|
||||
In case of HDF5 output file, we rely on having the HDF5 1.10.1 library installed and {\tt{HDF5-External-Filter-Plugins}} installed. With HDF5 1.10.3, no need of the external plugings package is needed, but a small modification to the file is needed. Edit the Makefile to correclty point at it. Different compression methods are being tried so different external filters might be to be installed. This work is not finished yet.
|
||||
|
||||
To choose HDF5, with ZLIB implementation, open {\tt{slsImageReconstruction/src/main\_csaxs.cpp}} and make sure that
|
||||
\begin{verbatim}
|
||||
@ -889,7 +992,7 @@ are not commented out. All other options need to be commented out. Copile the co
|
||||
make hdf5Maker; make hdf5MakerOMNY;
|
||||
\end{verbatim}
|
||||
|
||||
If you are at cSAXS. all images collected will be written in a single file. If you are not at CSAXS, most likely you want to have all the images written in a single raw file into an HDF5 file. The multiple HDF5 files are then linked in a master file, with many subdatasets (can be read by albula) or by a virtual file with a single dataset. If you want a mster o virtual file, uncomment this option:
|
||||
If you are at cSAXS. all images collected will be written in a single file. If you are not at CSAXS, most likely you want to have all the images written in a single raw file into an HDF5 file. The multiple HDF5 files are then linked in a master file, with many subdatasets (can be read by albula) or by a virtual file with a single dataset. If you want a master o virtual file, uncomment this option:
|
||||
\begin{verbatim}
|
||||
#define MASTERVIRTUAL
|
||||
\end{verbatim}
|
||||
@ -911,7 +1014,7 @@ The data will be written as TH2D in root format. Edit the {\tt{Makefile}} to poi
|
||||
\begin{verbatim}
|
||||
make image
|
||||
\end{verbatim}
|
||||
There is no program other executable that alredy keeps into account the geometry for it.
|
||||
There is no program other executable that already keeps into account the geometry for it.
|
||||
To use it any geometry:\\
|
||||
{\tt{image [filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
|
||||
eg.
|
||||
@ -979,9 +1082,9 @@ ssh root@$i sync; done
|
||||
|
||||
\section{Loading firmware bitfiles}
|
||||
|
||||
\textbf{As a new procedure, the first thing to do is to kill the server on the boards, copy the new one there without starting it.} Note taht failure to do this step before may cause the linux on the baords to crash and not being able to ping it (this if the registers between the old and new firmware change).
|
||||
\textbf{As a new procedure, the first thing to do is to kill the server on the boards, copy the new one there without starting it.} Note that failure to do this step before may cause the linux on the boards to crash and not being able to ping it (this if the registers between the old and new firmware change).
|
||||
|
||||
This is teh procedure from a terminal;
|
||||
This is the procedure from a terminal;
|
||||
\begin{verbatim}
|
||||
for i in beb111 beb070;
|
||||
do ssh root@$i killall eigerDetectorServer;
|
||||
@ -1059,19 +1162,19 @@ To load the special noise file look at {\tt{settingsdir/eiger/standard/eigernois
|
||||
\begin{verbatim}
|
||||
sls_detector_put trimbits ../settingsdir/eiger/standard/eigernoise
|
||||
\end{verbatim}
|
||||
To exit from this pattern noise, just set the theshold to something known.
|
||||
To exit from this pattern noise, just set the threshold to something known.
|
||||
\begin{verbatim}
|
||||
\item sls_detector_put threshold 50000 standard
|
||||
\end{verbatim}
|
||||
where 5000 would be a value in eV and {/tt{standard}} is important in this case.
|
||||
|
||||
\section{(Fast) threshold scans during beam operation}\label{sec:fastthresholdscan}
|
||||
Occasionally you might need to do threshold scans during your data taking (for example for Laue experiments or to get any spectral information). Settinng the threshold in thsi case would be not optimal as you would change thrimbits at every energy and this could give you a ``step'' behaviour. What you could do is to use the
|
||||
Occasionally you might need to do threshold scans during your data taking (for example for Laue experiments or to get any spectral information). Setting the threshold in this case would be not optimal as you would change trimbits at every energy and this could give you a ``step'' behaviour. What you could do is to use the
|
||||
\begin{verbatim}
|
||||
\item sls_detector_put thresholdnotb 50000
|
||||
\end{verbatim}
|
||||
which set the threshold to an energy but does not change trimbits. We suggest that before using this function you load the {\tt{threshold}} at an energy in the middle of your scan range and then change {\tt{thresholdnotb}}.
|
||||
We have also been requested if we could speed up the threshold scan. At the moment no specific function has been integrated in firware, but one could use the software thrigger option to perform what you need:
|
||||
We have also been requested if we could speed up the threshold scan. At the moment no specific function has been integrated in firmware, but one could use the software trigger option to perform what you need:
|
||||
\begin{verbatim}
|
||||
./sls_detector_put exptime 0.01
|
||||
./sls_detector_put timing trigger
|
||||
@ -1084,8 +1187,8 @@ We have also been requested if we could speed up the threshold scan. At the mome
|
||||
for i in $(seq 0 20);
|
||||
do
|
||||
#./sls_detector_put thresholdnotb 5000 ##this is still too slow as it loads the module
|
||||
./sls_detector_put 0:vrf 3199 #need to know the appropriat vrf at every energy
|
||||
./sls_detector_put 1:vrf 3199 #need to know the appropriat vrf at every energy
|
||||
./sls_detector_put 0:vrf 3199 #need to know the appropriate vrf at every energy
|
||||
./sls_detector_put 1:vrf 3199 #need to know the appropriate vrf at every energy
|
||||
./sls_detector_put status trigger
|
||||
#sleep 0.005
|
||||
done
|
||||
@ -1244,7 +1347,7 @@ Scroll up in the terminal till you find:\\
|
||||
*************** MASTER/SLAVE ***************\\
|
||||
*************** NORMAL/SPECIAL ***************\\
|
||||
|
||||
There is also an easier way, that is that only the master module will reaturn the real value of the HV. If you have more than 1 detector system, then you will have more than 1 physical master, as the HV needs to be applied to all the systems.
|
||||
There is also an easier way, that is that only the master module will return the real value of the HV. If you have more than 1 detector system, then you will have more than 1 physical master, as the HV needs to be applied to all the systems.
|
||||
|
||||
\begin{verbatim}
|
||||
for i in $(seq 0 36); do sls_detector_put $i:vhighvoltage; done
|
||||
@ -1254,10 +1357,14 @@ for i in $(seq 0 36); do sls_detector_put $i:vhighvoltage; done
|
||||
\subsection{'Cannot connect to socket'}
|
||||
This error is typically due to the detector server not running. For why, see section~\ref{servernot}.
|
||||
|
||||
\subsection{Running at low frame rate, the communication to receiver stops}
|
||||
If running in 32-bit mode (or even in 16-bit mode), if more memory than what your machine can handle is asked for, the receiver process could be terminated by the kernel of your machine. It would loook like you had executed a clean control-c on the receiver executable. This has been the case, when setting up by mistake
|
||||
\tt{rx\_fifodepth} to 10000 images in 32 bit mode. In 32 bit mode it will assign 40~GB of memory, which is more than what normal PC would have. So make sure you do not require too much memory. The same is tru also for smaller values of {\tt{rx\_fifodepth}} if your machine has not much memory.
|
||||
|
||||
\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.
|
||||
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. In software packages 3.x.y, the eigerDetectorServer was killed automatically. So check the consistency of firmware/software/server versions if using this version of the software. From 4.x.y onwards, the server, if associated to a wrong firmware, does not kill itself.
|
||||
|
||||
\subsection{'Acquire has already started' error message}
|
||||
If you see the client returning the following error message:\\
|
||||
@ -1268,10 +1375,10 @@ If you see the client returning the following error message:\\
|
||||
\end{verbatim}
|
||||
|
||||
\subsection{There is noise running the detector in 32-bit}
|
||||
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 readout time. 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 give enough time for the signals to settle. From release 4.0.0, there is a configurable delay that can be set through the {\tt{subdeadtime}} variable, such that you can remain with the {\tt{parallel}} flag, but can obtain a configurable dead time between frames. Ask the SLS detector group for an appropriate dead time for your detector, but typically a dead time of 20-50~$\mu$s should be enough. Note that this {\tt{subdeadtime}} need to include the 12~$\mu$s minimum readout time, so it has to be larger than 12~$\mu$s to do anything.
|
||||
If you are running the detector in 32-bit (autosumming), there might be some noise, particularly at lower threshold 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 readout time. 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 give enough time for the signals to settle. From release 4.0.0, there is a configurable delay that can be set through the {\tt{subdeadtime}} variable, such that you can remain with the {\tt{parallel}} flag, but can obtain a configurable dead time between frames. Ask the SLS detector group for an appropriate dead time for your detector, but typically a dead time of 20-50~$\mu$s should be enough. Note that this {\tt{subdeadtime}} need to include the 12~$\mu$s minimum readout time, so it has to be larger than 12~$\mu$s to do anything.
|
||||
|
||||
\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 readout time.
|
||||
If are running in {\tt{parallel}} mode, in particular at low threshold 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 readout 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.
|
||||
|
0
manual/manual-client/GapPixels.png
Normal file → Executable file
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
0
manual/manual-client/LEDSim.png
Normal file → Executable file
Before Width: | Height: | Size: 863 KiB After Width: | Height: | Size: 863 KiB |
0
manual/manual-client/Makefile
Normal file → Executable file
0
manual/manual-client/TansmissionRates.png
Normal file → Executable file
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
0
manual/manual-client/commands.txt
Normal file → Executable file
0
manual/manual-client/libs.txt
Normal file → Executable file
0
manual/manual-client/slsDetectorClient.doxy
Normal file → Executable file
0
manual/manual-client/slsDetectorClientHowTo.tex
Normal file → Executable file
0
manual/manual-client/tiggerIN.png
Normal file → Executable file
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 167 KiB |