Compare commits

...

1 Commits

Author SHA1 Message Date
193f2b9011 Split slsReceiver into slsListener and slsReceiver 2019-03-25 17:52:30 +01:00
49 changed files with 1832 additions and 92 deletions

View File

@ -32,7 +32,8 @@ endif()
option (SLS_USE_HDF5 "HDF5 File format" OFF)
option (SLS_USE_TEXTCLIENT "Text Client" OFF)
option (SLS_USE_RECEIVER "Receiver" OFF)
option (SLS_USE_RECEIVER "Receiver High Level API" OFF)
option (SLS_USE_LISTENER "Receiver Low Level API" OFF)
option (SLS_USE_GUI "GUI" OFF)
option (SLS_USE_TESTS "TESTS" ON)
option (SLS_USE_INTEGRATION_TESTS "Integration Tests" ON)
@ -87,14 +88,20 @@ if (SLS_USE_TEXTCLIENT)
add_subdirectory(slsDetectorSoftware)
endif (SLS_USE_TEXTCLIENT)
# This logic could be moved in slsReceiverSoftware/CMakeLists.txt
if (SLS_USE_RECEIVER)
set(SLS_USE_LISTENER ON)
if (SLS_USE_HDF5)
find_package(HDF5 1.10 COMPONENTS CXX REQUIRED)
endif (SLS_USE_HDF5)
add_subdirectory(slsReceiverSoftware)
add_subdirectory(slsReceiverSoftware/slsReceiver)
add_subdirectory(manual/manual-api)
endif (SLS_USE_RECEIVER)
if (SLS_USE_LISTENER)
add_subdirectory(slsReceiverSoftware/slsListener)
endif (SLS_USE_LISTENER)
if (SLS_USE_GUI)
find_package(Qt4 REQUIRED)
find_package(Qwt 6 REQUIRED)

View File

@ -1,90 +1,2 @@
set(SOURCES
src/slsReceiverImplementation.cpp
src/slsReceiverTCPIPInterface.cpp
src/slsReceiver.cpp
src/slsReceiverUsers.cpp
src/File.cpp
src/BinaryFile.cpp
src/ThreadObject.cpp
src/Listener.cpp
src/DataProcessor.cpp
src/DataStreamer.cpp
src/Fifo.cpp
)
# HDF5
if (SLS_USE_HDF5)
if (HDF5_FOUND)
include_directories(
${HDF5_INCLUDE_DIRS}
)
add_definitions(
-DHDF5C ${HDF5_DEFINITIONS}
)
list (APPEND SOURCES
src/HDF5File.cpp
)
endif ()
endif (SLS_USE_HDF5)
# include_directories(
# ${SLS_SUPPORT_LIB_INCLUDE_DIRS}
# )
add_library(slsReceiverShared SHARED
${SOURCES}
${HEADERS}
)
target_link_libraries(slsReceiverShared PUBLIC
slsSupportLib
)
target_include_directories(slsReceiverShared PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
#What is included in slsReceiverLib?
set(PUBLICHEADERS
include/slsReceiverUsers.h
)
set_target_properties(slsReceiverShared PROPERTIES
LIBRARY_OUTPUT_NAME SlsReceiver
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
PUBLIC_HEADER "${PUBLICHEADERS}"
)
add_executable(slsReceiver
src/main.cpp
)
set_target_properties(slsReceiver PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
target_link_libraries(slsReceiver PUBLIC
slsSupportLib
slsReceiverShared
pthread
${ZeroMQ_LIBRARIES}
rt
)
if (HDF5_FOUND)
target_link_libraries(slsReceiver PUBLIC ${HDF5_LIBRARIES})
endif ()
install(TARGETS slsReceiverShared
EXPORT "${TARGETS_EXPORT_NAME}"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${ZMQ_STATIC_ARCHIVE}
DESTINATION lib)
add_subdirectory(slsListener)
add_subdirectory(slsReceiver)

View File

@ -0,0 +1,35 @@
set(SOURCES
src/Listener.cpp
)
add_library(slsListenerShared SHARED
${SOURCES}
${HEADERS}
)
target_link_libraries(slsListenerShared PUBLIC
slsSupportLib
)
target_include_directories(slsListenerShared PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
#What is included in slsReceiverLib?
set(PUBLICHEADERS
include/Listener.h
)
set_target_properties(slsListenerShared PROPERTIES
LIBRARY_OUTPUT_NAME slsListener
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
PUBLIC_HEADER "${PUBLICHEADERS}"
)
install(TARGETS slsListenerShared
EXPORT "${TARGETS_EXPORT_NAME}"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

View File

@ -0,0 +1,275 @@
#pragma once
/************************************************
* @file Listener.h
* @short creates the listener thread that
* listens to udp sockets, writes data to memory
* & puts pointers to their memory addresses into fifos
***********************************************/
/**
*@short creates & manages a listener thread each
*/
#include "sls_detector_defs.h"
#include "logger.h"
#include <memory>
#include <semaphore.h>
class GeneralData;
class genericSocket;
class Listener : private virtual slsDetectorDefs {
public:
/**
* Constructor
* Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofListerners
* @param ind self index
* @param dtype detector type
* @param f address of Fifo pointer
* @param s pointer to receiver status
* @param portno pointer to udp port number
* @param e ethernet interface
* @param nf pointer to number of images to catch
* @param dr pointer to dynamic range
* @param us pointer to udp socket buffer size
* @param as pointer to actual udp socket buffer size
* @param fpf pointer to frames per file
* @param fdp frame discard policy
* @param act pointer to activated
* @param depaden pointer to deactivated padding enable
* @param sm pointer to silent mode
*/
Listener(int ind, detectorType dtype, runStatus* s,
uint32_t* portno, char* e, uint64_t* nf, uint32_t* dr,
int64_t* us, int64_t* as, uint32_t* fpf,
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm);
/**
* Destructor
* Calls Base Class DestroyThread() and decrements NumberofListerners
*/
~Listener();
/**
* Populate a buffer with an image
* \note This is a blocking call
*/
void getImage(char* buffer);
/**
* Get acquisition started flag
* @return acquisition started flag
*/
bool GetAcquisitionStartedFlag();
/**
* Get measurement started flag
* @return measurement started flag
*/
bool GetMeasurementStartedFlag();
/**
* Get Packets caught in a real time acquisition (start and stop of receiver)
* @return Packets caught in a real time acquisition
*/
uint64_t GetPacketsCaught();
/**
* Get Last Frame index caught
* @return last frame index caught
*/
uint64_t GetLastFrameIndexCaught();
/**
* Reset parameters for new acquisition (including all scans)
*/
void ResetParametersforNewAcquisition();
/**
* Reset parameters for new measurement (eg. for each scan)
*/
void ResetParametersforNewMeasurement();
/**
* Set GeneralData pointer to the one given
* @param g address of GeneralData (Detector Data) pointer
*/
void SetGeneralData(GeneralData* g);
/**
* Creates UDP Sockets
* @return OK or FAIL
*/
int CreateUDPSockets();
/**
* Shuts down and deletes UDP Sockets
*/
void ShutDownUDPSocket();
/**
* Create & closes a dummy UDP socket
* to set & get actual buffer size
* @param s UDP socket buffer size to be set
* @return OK or FAIL of dummy socket creation
*/
int CreateDummySocketForUDPSocketBufferSize(int64_t s);
/**
* Set hard coded (calculated but not from detector) row and column
* r is in row index if detector has not send them yet in firmware,
* c is in col index for jungfrau and eiger (for missing packets/deactivated eiger)
* c when used is in 2d
*/
void SetHardCodedPosition(uint16_t r, uint16_t c);
private:
/**
* Record First Indices (firstAcquisitionIndex, firstMeasurementIndex)
* @param fnum frame index to record
*/
void RecordFirstIndices(uint64_t fnum);
/**
* Pushes non empty buffers into fifo/ frees empty buffer,
* pushes dummy buffer into fifo
* and reset running mask by calling StopRunning()
* @param buf address of buffer
*/
void StopListening(char* buf);
/**
* Listen to the UDP Socket for an image,
* place them in the right order
* @param buffer
* @returns number of bytes of relevant data, can be image size or 0 (stop acquisition)
* or -1 to discard image
*/
uint32_t ListenToAnImage(char* buf);
/** type of thread */
static const std::string TypeName;
/** Self Index */
int index;
/** GeneralData (Detector Data) object */
GeneralData* generalData;
// individual members
/** Detector Type */
detectorType myDetectorType;
/** Receiver Status */
runStatus* status;
/** UDP Socket - Detector to Receiver */
std::unique_ptr<genericSocket> udpSocket;
/** UDP Port Number */
uint32_t* udpPortNumber;
/** ethernet interface */
char* eth;
/** Number of Images to catch */
uint64_t* numImages;
/** Dynamic Range */
uint32_t* dynamicRange;
/** UDP Socket Buffer Size */
int64_t* udpSocketBufferSize;
/** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */
int64_t* actualUDPSocketBufferSize;
/** frames per file */
uint32_t* framesPerFile;
/** frame discard policy */
frameDiscardPolicy* frameDiscardMode;
/** Activated/Deactivated */
bool* activated;
/** Deactivated padding enable */
bool* deactivatedPaddingEnable;
/** Silent Mode */
bool* silentMode;
/** row hardcoded as 1D or 2d,
* if detector does not send them yet or
* missing packets/deactivated (eiger/jungfrau sends 2d pos) **/
uint16_t row;
/** column hardcoded as 2D,
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
uint16_t column;
// acquisition start
/** Aquisition Started flag */
bool acquisitionStartedFlag;
/** Measurement Started flag */
bool measurementStartedFlag;
/** Frame Number of First Frame of an entire Acquisition (including all scans) */
uint64_t firstAcquisitionIndex;
/** Frame Number of First Frame for each real time acquisition (eg. for each scan) */
uint64_t firstMeasurementIndex;
// for acquisition summary
/** Number of complete Packets caught for each real time acquisition (eg. for each scan (start& stop of receiver)) */
volatile uint64_t numPacketsCaught;
/** Last Frame Index caught from udp network */
uint64_t lastCaughtFrameIndex;
// parameters to acquire image
/** Current Frame Index, default value is 0
* ( always check acquisitionStartedFlag for validity first)
*/
uint64_t currentFrameIndex;
/** True if there is a packet carry over from previous Image */
bool carryOverFlag;
/** Carry over packet buffer */
std::unique_ptr<char []> carryOverPacket;
/** Listening buffer for one packet - might be removed when we can peek and eiger fnum is in header */
std::unique_ptr<char []> listeningPacket;
/** if the udp socket is connected */
bool udpSocketAlive;
/** Semaphore to synchonize deleting udp socket */
sem_t semaphore_socket;
// for print progress during acqusition
/** number of packets for statistic */
uint32_t numPacketsStatistic;
/** number of images for statistic */
uint32_t numFramesStatistic;
/**
* starting packet number is odd or evern, accordingly increment frame number
* to get first packet number as 0
* (pecific to gotthard, can vary between modules, hence defined here) */
bool oddStartingPacket;
};

View File

@ -0,0 +1,527 @@
/************************************************
* @file Listener.cpp
* @short creates the listener thread that
* listens to udp sockets, writes data to memory
* & puts pointers to their memory addresses into fifos
***********************************************/
#include "Listener.h"
#include "GeneralData.h"
#include "genericSocket.h"
#include "container_utils.h" // For sls::make_unique<>
#include "sls_detector_exceptions.h"
#include <iostream>
#include <errno.h>
#include <cstring>
const std::string Listener::TypeName = "Listener";
Listener::Listener(int ind, detectorType dtype, runStatus* s,
uint32_t* portno, char* e, uint64_t* nf, uint32_t* dr,
int64_t* us, int64_t* as, uint32_t* fpf,
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm) :
index(ind),
generalData(nullptr),
myDetectorType(dtype),
status(s),
udpSocket(nullptr),
udpPortNumber(portno),
eth(e),
numImages(nf),
dynamicRange(dr),
udpSocketBufferSize(us),
actualUDPSocketBufferSize(as),
framesPerFile(fpf),
frameDiscardMode(fdp),
activated(act),
deactivatedPaddingEnable(depaden),
silentMode(sm),
row(0),
column(0),
acquisitionStartedFlag(false),
measurementStartedFlag(false),
firstAcquisitionIndex(0),
firstMeasurementIndex(0),
numPacketsCaught(0),
lastCaughtFrameIndex(0),
currentFrameIndex(0),
carryOverFlag(0),
udpSocketAlive(0),
numPacketsStatistic(0),
numFramesStatistic(0),
oddStartingPacket(true)
{
FILE_LOG(logDEBUG) << "Listener " << ind << " created";
}
/** getters */
bool Listener::GetAcquisitionStartedFlag(){
return acquisitionStartedFlag;
}
bool Listener::GetMeasurementStartedFlag(){
return measurementStartedFlag;
}
uint64_t Listener::GetPacketsCaught() {
return numPacketsCaught;
}
uint64_t Listener::GetLastFrameIndexCaught() {
return lastCaughtFrameIndex;
}
void Listener::ResetParametersforNewAcquisition() {
acquisitionStartedFlag = false;
firstAcquisitionIndex = 0;
currentFrameIndex = 0;
lastCaughtFrameIndex = 0;
}
void Listener::ResetParametersforNewMeasurement() {
measurementStartedFlag = false;
numPacketsCaught = 0;
firstMeasurementIndex = 0;
carryOverFlag = false;
carryOverPacket = sls::make_unique<char[]>(generalData->packetSize);
memset(carryOverPacket.get(),0,generalData->packetSize);
listeningPacket = sls::make_unique<char[]>(generalData->packetSize);
memset(carryOverPacket.get(),0,generalData->packetSize);
numPacketsStatistic = 0;
numFramesStatistic = 0;
}
void Listener::RecordFirstIndices(uint64_t fnum) {
//listen to this fnum, later +1
currentFrameIndex = fnum;
measurementStartedFlag = true;
firstMeasurementIndex = fnum;
//start of entire acquisition
if (!acquisitionStartedFlag) {
acquisitionStartedFlag = true;
firstAcquisitionIndex = fnum;
}
if(!(*silentMode)) {
if (!index) {
FILE_LOG(logINFOBLUE) << index <<
" First Acquisition Index: " << firstAcquisitionIndex;
FILE_LOG(logDEBUG1) << index << " First Measurement Index: " << firstMeasurementIndex;
}
}
}
void Listener::SetGeneralData(GeneralData* g) {
generalData = g;
generalData->Print();
}
int Listener::CreateUDPSockets() {
if (!(*activated)) {
return OK;
}
//if eth is mistaken with ip address
if (strchr(eth,'.') != nullptr){
memset(eth, 0, MAX_STR_LENGTH);
}
if(!strlen(eth)){
FILE_LOG(logWARNING) << "eth is empty. Listening to all";
}
ShutDownUDPSocket();
try{
udpSocket = sls::make_unique<genericSocket>(*udpPortNumber, genericSocket::UDP,
generalData->packetSize, (strlen(eth)?eth:nullptr), generalData->headerPacketSize,
*udpSocketBufferSize);
FILE_LOG(logINFO) << index << ": UDP port opened at port " << *udpPortNumber;
} catch (...) {
FILE_LOG(logERROR) << "Could not create UDP socket on port " << *udpPortNumber;
return FAIL;
}
udpSocketAlive = true;
// doubled due to kernel bookkeeping (could also be less due to permissions)
*actualUDPSocketBufferSize = udpSocket->getActualUDPSocketBufferSize();
return OK;
}
void Listener::ShutDownUDPSocket() {
if(udpSocket){
udpSocketAlive = false;
udpSocket->ShutDownSocket();
FILE_LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber;
fflush(stdout);
}
}
int Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) {
FILE_LOG(logINFO) << "Testing UDP Socket Buffer size with test port " << *udpPortNumber;
if (!(*activated)) {
*actualUDPSocketBufferSize = (s*2);
return OK;
}
int64_t temp = *udpSocketBufferSize;
*udpSocketBufferSize = s;
//if eth is mistaken with ip address
if (strchr(eth,'.') != nullptr){
memset(eth, 0, MAX_STR_LENGTH);
}
//create dummy socket
try {
genericSocket g(*udpPortNumber, genericSocket::UDP,
generalData->packetSize, (strlen(eth)?eth:nullptr), generalData->headerPacketSize,
*udpSocketBufferSize);
// doubled due to kernel bookkeeping (could also be less due to permissions)
*actualUDPSocketBufferSize = g.getActualUDPSocketBufferSize();
if (*actualUDPSocketBufferSize != (s*2)) {
*udpSocketBufferSize = temp;
}
} catch (...) {
FILE_LOG(logERROR) << "Could not create a test UDP socket on port " << *udpPortNumber;
return FAIL;
}
return OK;
}
void Listener::SetHardCodedPosition(uint16_t r, uint16_t c) {
row = r;
column = c;
}
void Listener::getImage(char* buffer) {
int rc = 0;
//udpsocket doesnt exist
if (*activated && !udpSocketAlive && !carryOverFlag) {
//FILE_LOG(logERROR) << "Listening_Thread " << index << ": UDP Socket not created or shut down earlier";
(*((uint32_t*)buffer)) = 0;
throw std::runtime_error("UDP Socket not created or shut down earlier");
}
//get data
if ((*status != TRANSMITTING && (!(*activated) || udpSocketAlive)) || carryOverFlag) {
rc = ListenToAnImage(buffer);
}
//error check, (should not be here) if not transmitting yet (previous if) rc should be > 0
if (rc == 0)
return;
// discarding image
else if (rc < 0) {
FILE_LOG(logDEBUG) << index << " discarding fnum:" << currentFrameIndex;
currentFrameIndex++;
return;
}
(*((uint32_t*)buffer)) = rc;
(*((uint64_t*)(buffer + FIFO_HEADER_NUMBYTES ))) = currentFrameIndex; //for those returning earlier
currentFrameIndex++;
}
/* buf includes the fifo header and packet header */
uint32_t Listener::ListenToAnImage(char* buf) {
int rc = 0;
uint64_t fnum = 0, bid = 0;
uint32_t pnum = 0, snum = 0;
uint32_t numpackets = 0;
uint32_t dsize = generalData->dataSize;
uint32_t hsize = generalData->headerSizeinPacket; //(includes empty header)
uint32_t esize = generalData->emptyHeader;
uint32_t fifohsize = generalData->fifoBufferHeaderSize;
uint32_t pperFrame = generalData->packetsPerFrame;
bool isHeaderEmpty = true;
sls_detector_header* old_header = nullptr;
sls_receiver_header* new_header = nullptr;
bool standardheader = generalData->standardheader;
uint32_t corrected_dsize = dsize - ((pperFrame * dsize) - generalData->imageSize);
//reset to -1
std::memset(buf, 0, fifohsize);
/*memset(buf + fifohsize, 0xFF, generalData->imageSize);*/
new_header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES);
// deactivated (eiger)
if (!(*activated)) {
// no padding
if (!(*deactivatedPaddingEnable))
return 0;
// padding without setting bitmask (all missing packets padded in dataProcessor)
if (currentFrameIndex >= *numImages)
return 0;
//(eiger) first fnum starts at 1
if (!currentFrameIndex) {
++currentFrameIndex;
}
new_header->detHeader.frameNumber = currentFrameIndex;
new_header->detHeader.row = row;
new_header->detHeader.column = column;
new_header->detHeader.detType = (uint8_t) generalData->myDetectorType;
new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION;
return generalData->imageSize;
}
//look for carry over
if (carryOverFlag) {
FILE_LOG(logDEBUG3) << index << "carry flag";
//check if its the current image packet
// -------------------------- new header ----------------------------------------------------------------------
if (standardheader) {
old_header = (sls_detector_header*) (&carryOverPacket[esize]);
fnum = old_header->frameNumber;
pnum = old_header->packetNumber;
}
// -------------------old header -----------------------------------------------------------------------------
else {
generalData->GetHeaderInfo(index, &carryOverPacket[esize],
*dynamicRange, oddStartingPacket, fnum, pnum, snum, bid);
}
//------------------------------------------------------------------------------------------------------------
if (fnum != currentFrameIndex) {
if (fnum < currentFrameIndex) {
FILE_LOG(logERROR) << "(Weird), With carry flag: Frame number " <<
fnum << " less than current frame number " << currentFrameIndex;
return 0;
}
switch(*frameDiscardMode) {
case DISCARD_EMPTY_FRAMES:
if (!numpackets)
return -1;
break;
case DISCARD_PARTIAL_FRAMES:
return -1;
default:
break;
}
new_header->detHeader.packetNumber = numpackets;
if(isHeaderEmpty) {
new_header->detHeader.row = row;
new_header->detHeader.column = column;
}
return generalData->imageSize;
}
//copy packet
switch(myDetectorType) {
//for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes data
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data + 640*2 bytes data !!
case GOTTHARD:
if(!pnum)
memcpy(buf + fifohsize , &carryOverPacket[hsize+4], dsize-2);
else
memcpy(buf + fifohsize + dsize - 2, &carryOverPacket[hsize], dsize+2);
break;
case CHIPTESTBOARD:
case MOENCH:
if (pnum == (pperFrame-1))
memcpy(buf + fifohsize + (pnum * dsize), &carryOverPacket[hsize], corrected_dsize);
else
memcpy(buf + fifohsize + (pnum * dsize), &carryOverPacket[hsize], dsize);
break;
default:
memcpy(buf + fifohsize + (pnum * dsize), &carryOverPacket[hsize], dsize);
break;
}
carryOverFlag = false;
++numpackets; //number of packets in this image (each time its copied to buf)
new_header->packetsMask[((pnum < MAX_NUM_PACKETS) ? pnum : MAX_NUM_PACKETS)] = 1;
//writer header
if(isHeaderEmpty) {
// -------------------------- new header ----------------------------------------------------------------------
if (standardheader) {
memcpy((char*)new_header, (char*)old_header, sizeof(sls_detector_header));
}
// -------------------old header ------------------------------------------------------------------------------
else {
new_header->detHeader.frameNumber = fnum;
new_header->detHeader.row = row;
new_header->detHeader.column = column;
new_header->detHeader.detType = (uint8_t) generalData->myDetectorType;
new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION;
}
//------------------------------------------------------------------------------------------------------------
isHeaderEmpty = false;
}
}
//until last packet isHeaderEmpty to account for gotthard short frame, else never entering this loop)
while ( numpackets < pperFrame) {
//listen to new packet
rc = 0;
if (udpSocketAlive){
rc = udpSocket->ReceiveDataOnly(&listeningPacket[0]);
}
// end of acquisition
if(rc <= 0) {
if (numpackets == 0) return 0; //empty image
switch(*frameDiscardMode) {
case DISCARD_EMPTY_FRAMES:
if (!numpackets)
return -1;
break;
case DISCARD_PARTIAL_FRAMES:
return -1;
default:
break;
}
new_header->detHeader.packetNumber = numpackets; //number of packets caught
if(isHeaderEmpty) {
new_header->detHeader.row = row;
new_header->detHeader.column = column;
}
return generalData->imageSize; //empty packet now, but not empty image
}
//update parameters
numPacketsCaught++; //record immediately to get more time before socket shutdown
numPacketsStatistic++;
// -------------------------- new header ----------------------------------------------------------------------
if (standardheader) {
old_header = (sls_detector_header*) (&listeningPacket[esize]);
fnum = old_header->frameNumber;
pnum = old_header->packetNumber;
}
// -------------------old header -----------------------------------------------------------------------------
else {
// set first packet to be odd or even (check required when switching from roi to no roi)
if (myDetectorType == GOTTHARD && !measurementStartedFlag) {
oddStartingPacket = generalData->SetOddStartingPacket(index, &listeningPacket[esize]);
}
generalData->GetHeaderInfo(index, &listeningPacket[esize],
*dynamicRange, oddStartingPacket, fnum, pnum, snum, bid);
}
//------------------------------------------------------------------------------------------------------------
// Eiger Firmware in a weird state
if (myDetectorType == EIGER && fnum == 0) {
FILE_LOG(logERROR) << "[" << *udpPortNumber << "]: Got Frame Number "
"Zero from Firmware. Discarding Packet";
numPacketsCaught--;
return 0;
}
lastCaughtFrameIndex = fnum;
FILE_LOG(logDEBUG5) << "Listening " << index << ": currentfindex:" << currentFrameIndex <<
", fnum:" << fnum << ", pnum:" << pnum << ", numpackets:" << numpackets;
if (!measurementStartedFlag)
RecordFirstIndices(fnum);
if (pnum >= pperFrame ) {
FILE_LOG(logERROR) << "Bad packet " << pnum <<
"(fnum: " << fnum << "), throwing away. "
"Packets caught so far: " << numpackets;
return 0; // bad packet
}
//future packet by looking at image number (all other detectors)
if (fnum != currentFrameIndex) {
carryOverFlag = true;
memcpy(carryOverPacket.get(), &listeningPacket[0], generalData->packetSize);
switch(*frameDiscardMode) {
case DISCARD_EMPTY_FRAMES:
if (!numpackets)
return -1;
break;
case DISCARD_PARTIAL_FRAMES:
return -1;
default:
break;
}
new_header->detHeader.packetNumber = numpackets; //number of packets caught
if(isHeaderEmpty) {
new_header->detHeader.row = row;
new_header->detHeader.column = column;
}
return generalData->imageSize;
}
//copy packet
switch(myDetectorType) {
//for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes data
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data + 640*2 bytes data !!
case GOTTHARD:
if(!pnum)
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize+4], dsize-2);
else
memcpy(buf + fifohsize + (pnum * dsize) - 2, &listeningPacket[hsize], dsize+2);
break;
case CHIPTESTBOARD:
case MOENCH:
if (pnum == (pperFrame-1))
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize], corrected_dsize);
else
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize], dsize);
break;
default:
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize], dsize);
break;
}
++numpackets; //number of packets in this image (each time its copied to buf)
new_header->packetsMask[((pnum < MAX_NUM_PACKETS) ? pnum : MAX_NUM_PACKETS)] = 1;
if(isHeaderEmpty) {
// -------------------------- new header ----------------------------------------------------------------------
if (standardheader) {
memcpy((char*)new_header, (char*)old_header, sizeof(sls_detector_header));
}
// -------------------old header ------------------------------------------------------------------------------
else {
new_header->detHeader.frameNumber = fnum;
new_header->detHeader.row = row;
new_header->detHeader.column = column;
new_header->detHeader.detType = (uint8_t) generalData->myDetectorType;
new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION;
}
//------------------------------------------------------------------------------------------------------------
isHeaderEmpty = false;
}
}
// complete image
new_header->detHeader.packetNumber = numpackets; //number of packets caught
return generalData->imageSize;
}

View File

@ -0,0 +1,90 @@
set(SOURCES
src/slsReceiverImplementation.cpp
src/slsReceiverTCPIPInterface.cpp
src/slsReceiver.cpp
src/slsReceiverUsers.cpp
src/File.cpp
src/BinaryFile.cpp
src/ThreadObject.cpp
src/Listener.cpp
src/DataProcessor.cpp
src/DataStreamer.cpp
src/Fifo.cpp
)
# HDF5
if (SLS_USE_HDF5)
if (HDF5_FOUND)
include_directories(
${HDF5_INCLUDE_DIRS}
)
add_definitions(
-DHDF5C ${HDF5_DEFINITIONS}
)
list (APPEND SOURCES
src/HDF5File.cpp
)
endif ()
endif (SLS_USE_HDF5)
# include_directories(
# ${SLS_SUPPORT_LIB_INCLUDE_DIRS}
# )
add_library(slsReceiverShared SHARED
${SOURCES}
${HEADERS}
)
target_link_libraries(slsReceiverShared PUBLIC
slsSupportLib
)
target_include_directories(slsReceiverShared PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
#What is included in slsReceiverLib?
set(PUBLICHEADERS
include/slsReceiverUsers.h
)
set_target_properties(slsReceiverShared PROPERTIES
LIBRARY_OUTPUT_NAME SlsReceiver
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
PUBLIC_HEADER "${PUBLICHEADERS}"
)
add_executable(slsReceiver
src/main.cpp
)
set_target_properties(slsReceiver PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
target_link_libraries(slsReceiver PUBLIC
slsSupportLib
slsReceiverShared
pthread
${ZeroMQ_LIBRARIES}
rt
)
if (HDF5_FOUND)
target_link_libraries(slsReceiver PUBLIC ${HDF5_LIBRARIES})
endif ()
install(TARGETS slsReceiverShared
EXPORT "${TARGETS_EXPORT_NAME}"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${ZMQ_STATIC_ARCHIVE}
DESTINATION lib)

View File

@ -0,0 +1,9 @@
Path: slsDetectorsPackage/slsReceiverSoftware
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: def79807f6f40ed1797b8154240adbc0e35c95e0
Revision: 840
Branch: refactor
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4039
Last Changed Date: 2018-10-02 10:40:58.000000002 +0200

View File

@ -0,0 +1,702 @@
#pragma once
/************************************************
* @file GeneralData.h
* @short abstract for setting/getting properties of detector data
***********************************************/
/**
*@short abstract for setting/getting properties of detector data
*/
#include "sls_detector_defs.h"
#include "receiver_defs.h"
#include <math.h> //ceil
#include <vector>
class GeneralData {
public:
/** DetectorType */
slsDetectorDefs::detectorType myDetectorType;
/** Number of Pixels in x axis */
uint32_t nPixelsX;
/** Number of Pixels in y axis */
uint32_t nPixelsY;
/** emptybuffer (mainly for jungfrau) */
uint32_t emptyHeader;
/** Size of header in Packet */
uint32_t headerSizeinPacket;
/** Size of just data in 1 packet (in bytes) */
uint32_t dataSize;
/** Size of 1 packet (in bytes) */
uint32_t packetSize;
/** Number of packets in an image (for each listening UDP port) */
uint32_t packetsPerFrame;
/** Image size (in bytes, for each listening UDP port) */
uint32_t imageSize;
/** Frame Number Mask */
uint64_t frameIndexMask;
/** Frame Index Offset */
uint32_t frameIndexOffset;
/** Packet Index Mask */
uint32_t packetIndexMask;
/** Packet Index Offset */
uint32_t packetIndexOffset;
/** Max Frames per binary file */
uint32_t maxFramesPerFile;
/** Header size of data saved into fifo buffer at a time*/
uint32_t fifoBufferHeaderSize;
/** Default Fifo depth */
uint32_t defaultFifoDepth;
/** Threads per receiver */
uint32_t threadsPerReceiver;
/** Size of a header packet */
uint32_t headerPacketSize;
/** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in x axis */
uint32_t nPixelsXComplete;
/** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in y axis */
uint32_t nPixelsYComplete;
/** Streaming (for ROI - mainly short Gotthard) - Image size (in bytes) */
uint32_t imageSizeComplete;
/** if standard header implemented in firmware */
bool standardheader;
/** default udp socket buffer size */
uint32_t defaultUdpSocketBufferSize;
/** Cosntructor */
GeneralData():
myDetectorType(slsDetectorDefs::GENERIC),
nPixelsX(0),
nPixelsY(0),
emptyHeader(0),
headerSizeinPacket(0),
dataSize(0),
packetSize(0),
packetsPerFrame(0),
imageSize(0),
frameIndexMask(0),
frameIndexOffset(0),
packetIndexMask(0),
packetIndexOffset(0),
maxFramesPerFile(0),
fifoBufferHeaderSize(0),
defaultFifoDepth(0),
threadsPerReceiver(1),
headerPacketSize(0),
nPixelsXComplete(0),
nPixelsYComplete(0),
imageSizeComplete(0),
standardheader(false),
defaultUdpSocketBufferSize(RECEIVE_SOCKET_BUFFER_SIZE)
{};
/** Destructor */
virtual ~GeneralData(){};
/**
* Get Header Infomation (frame number, packet number)
* @param index thread index for debugging purposes
* @param packetData pointer to data
* @param dynamicRange dynamic range to assign subframenumber if 32 bit mode
* @param oddStartingPacket odd starting packet (gotthard)
* @param frameNumber frame number
* @param packetNumber packet number
* @param subFrameNumber sub frame number if applicable
* @param bunchId bunch id
*/
virtual void GetHeaderInfo(int index, char* packetData, uint32_t dynamicRange, bool oddStartingPacket,
uint64_t& frameNumber, uint32_t& packetNumber, uint32_t& subFrameNumber, uint64_t& bunchId) const
{
subFrameNumber = -1;
bunchId = -1;
frameNumber = ((uint32_t)(*((uint32_t*)(packetData))));
frameNumber++;
packetNumber = frameNumber&packetIndexMask;
frameNumber = (frameNumber & frameIndexMask) >> frameIndexOffset;
}
/**
* Set ROI
* @param i ROI
*/
virtual void SetROI(std::vector<slsDetectorDefs::ROI> i) {
FILE_LOG(logERROR) << "SetROI is a generic function that should be overloaded by a derived class";
};
/**
* Get Adc configured
* @param index thread index for debugging purposes
* @param i pointer to a vector of ROI pointers
* @returns adc configured
*/
virtual int GetAdcConfigured(int index, std::vector<slsDetectorDefs::ROI>* i) const{
FILE_LOG(logERROR) << "GetAdcConfigured is a generic function that should be overloaded by a derived class";
return 0;
};
/**
* Setting dynamic range changes member variables
* @param dr dynamic range
* @param tgEnable true if 10GbE is enabled, else false
*/
virtual void SetDynamicRange(int dr, bool tgEnable) {
FILE_LOG(logERROR) << "SetDynamicRange is a generic function that should be overloaded by a derived class";
};
/**
* Setting ten giga enable changes member variables
* @param tgEnable true if 10GbE is enabled, else false
* @param dr dynamic range
*/
virtual void SetTenGigaEnable(bool tgEnable, int dr) {
FILE_LOG(logERROR) << "SetTenGigaEnable is a generic function that should be overloaded by a derived class";
};
/**
* Setting packets per frame changes member variables
* @param ns number of samples
*/
virtual void setNumberofSamples(const uint64_t ns) {
FILE_LOG(logERROR) << "setNumberofSamples is a generic function that should be overloaded by a derived class";
};
/**
* Enable Gap Pixels changes member variables
* @param enable true if gap pixels enable, else false
*/
virtual void SetGapPixelsEnable(bool b, int dr) {
FILE_LOG(logERROR) << "SetGapPixelsEnable is a generic function that should be overloaded by a derived class";
};
/**
* Set odd starting packet (gotthard)
* @param index thread index for debugging purposes
* @param packetData pointer to data
* @returns true or false for odd starting packet number
*/
virtual bool SetOddStartingPacket(int index, char* packetData) {
cprintf(RED,"SetOddStartingPacket is a generic function that should be overloaded by a derived class\n");
return false;
};
/**
* Set databytes (ctb, moench)
* @param f readout flags
* @param r roi
* @param s number of samples
* @param t tengiga enable
*/
virtual void setImageSize(std::vector<slsDetectorDefs::ROI> r, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
cprintf(RED,"setImageSize is a generic function that should be overloaded by a derived class\n");
};
/**
* Print all variables
*/
virtual void Print(TLogLevel level = logDEBUG1) const {
FILE_LOG(level) << "\n\nDetector Data Variables:";
FILE_LOG(level) << "myDetectorType: " << slsDetectorDefs::detectorTypeToString(myDetectorType);
FILE_LOG(level) << "Pixels X: " << nPixelsX;
FILE_LOG(level) << "Pixels Y: " << nPixelsY;
FILE_LOG(level) << "Empty Header: " << emptyHeader;
FILE_LOG(level) << "Header Size in Packet: " << headerSizeinPacket;
FILE_LOG(level) << "Data Size: " << dataSize;
FILE_LOG(level) << "Packet Size: " << packetSize;
FILE_LOG(level) << "Packets per Frame: " << packetsPerFrame;
FILE_LOG(level) << "Image Size: " << imageSize;
FILE_LOG(level) << "Frame Index Mask: " << frameIndexMask;
FILE_LOG(level) << "Frame Index Offset: " << frameIndexOffset;
FILE_LOG(level) << "Packet Index Mask: " << packetIndexMask;
FILE_LOG(level) << "Packet Index Offset: " << packetIndexOffset;
FILE_LOG(level) << "Max Frames Per File: " << maxFramesPerFile;
FILE_LOG(level) << "Fifo Buffer Header Size: " << fifoBufferHeaderSize;
FILE_LOG(level) << "Default Fifo Depth: " << defaultFifoDepth;
FILE_LOG(level) << "Threads Per Receiver: " << threadsPerReceiver;
FILE_LOG(level) << "Header Packet Size: " << headerPacketSize;
FILE_LOG(level) << "Complete Pixels X: " << nPixelsXComplete;
FILE_LOG(level) << "Complete Pixels Y: " << nPixelsYComplete;
FILE_LOG(level) << "Complete Image Size: " << imageSizeComplete;
FILE_LOG(level) << "Standard Header: " << standardheader;
FILE_LOG(level) << "UDP Socket Buffer Size: " << defaultUdpSocketBufferSize;
};
};
class GotthardData : public GeneralData {
private:
const int nChip = 10;
const int nChan = 128;
const int nChipsPerAdc = 2;
public:
/** Constructor */
GotthardData(){
myDetectorType = slsDetectorDefs::GOTTHARD;
nPixelsX = 1280;
nPixelsY = 1;
headerSizeinPacket = 4;
dataSize = 1280;
packetSize = GOTTHARD_PACKET_SIZE;
packetsPerFrame = 2;
imageSize = dataSize*packetsPerFrame;
frameIndexMask = 0xFFFFFFFE;
frameIndexOffset = 1;
packetIndexMask = 1;
maxFramesPerFile = MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 50000;
};
/**
* Get Header Infomation (frame number, packet number)
* @param index thread index for debugging purposes
* @param packetData pointer to data
* @param dynamicRange dynamic range to assign subframenumber if 32 bit mode
* @param oddStartingPacket odd starting packet (gotthard)
* @param frameNumber frame number
* @param packetNumber packet number
* @param subFrameNumber sub frame number if applicable
* @param bunchId bunch id
*/
void GetHeaderInfo(int index, char* packetData, uint32_t dynamicRange, bool oddStartingPacket,
uint64_t& frameNumber, uint32_t& packetNumber, uint32_t& subFrameNumber, uint64_t& bunchId) const
{
if (nPixelsX == 1280) {
subFrameNumber = -1;
bunchId = -1;
frameNumber = ((uint32_t)(*((uint32_t*)(packetData))));
if (oddStartingPacket)
frameNumber++;
packetNumber = frameNumber&packetIndexMask;
frameNumber = (frameNumber & frameIndexMask) >> frameIndexOffset;
} else {
subFrameNumber = -1;
bunchId = -1;
frameNumber = ((uint32_t)(*((uint32_t*)(packetData))));
packetNumber = 0;
}
}
/**
* Set ROI
* @param i ROI
*/
void SetROI(std::vector<slsDetectorDefs::ROI> i) {
// all adcs
if(!i.size()) {
nPixelsX = 1280;
dataSize = 1280;
packetSize = GOTTHARD_PACKET_SIZE;
packetsPerFrame = 2;
imageSize = dataSize*packetsPerFrame;
frameIndexMask = 0xFFFFFFFE;
frameIndexOffset = 1;
packetIndexMask = 1;
maxFramesPerFile = MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 50000;
nPixelsXComplete = 0;
nPixelsYComplete = 0;
imageSizeComplete = 0;
}
// single adc
else {
nPixelsX = 256;
dataSize = 512;
packetSize = 518;
packetsPerFrame = 1;
imageSize = dataSize*packetsPerFrame;
frameIndexMask = 0xFFFFFFFF;
frameIndexOffset = 0;
packetIndexMask = 0;
maxFramesPerFile = SHORT_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 25000;
nPixelsXComplete = 1280;
nPixelsYComplete = 1;
imageSizeComplete = 1280 * 2;
}
};
/**
* Get Adc configured
* @param index thread index for debugging purposes
* @param i pointer to a vector of ROI
* @returns adc configured
*/
int GetAdcConfigured(int index, std::vector<slsDetectorDefs::ROI>* i) const{
int adc = -1;
// single adc
if(i->size()) {
// gotthard can have only one adc per detector enabled (or all)
// so just looking at the first roi is enough (more not possible at the moment)
//if its for 1 adc or general
if ((i->at(0).xmin == 0) && (i->at(0).xmax == nChip * nChan))
adc = -1;
else {
//adc = mid value/numchans also for only 1 roi
adc = ((((i->at(0).xmax) + (i->at(0).xmin))/2)/
(nChan * nChipsPerAdc));
if((adc < 0) || (adc > 4)) {
FILE_LOG(logWARNING) << index << ": Deleting ROI. "
"Adc value should be between 0 and 4";
adc = -1;
}
}
}
FILE_LOG(logINFO) << "Adc Configured: " << adc;
return adc;
};
/**
* Set odd starting packet (gotthard)
* @param index thread index for debugging purposes
* @param packetData pointer to data
* @returns true or false for odd starting packet number
*/
bool SetOddStartingPacket(int index, char* packetData) {
bool oddStartingPacket = true;
// care only if no roi
if (nPixelsX == 1280) {
uint32_t fnum = ((uint32_t)(*((uint32_t*)(packetData))));
uint32_t firstData = ((uint32_t)(*((uint32_t*)(packetData + 4))));
// first packet
if (firstData == 0xCACACACA) {
// packet number should be 0, but is 1 => so odd starting packet
if (fnum & packetIndexMask) {
oddStartingPacket = true;
} else {
oddStartingPacket = false;
}
}
// second packet
else {
// packet number should be 1, but is 0 => so odd starting packet
if (!(fnum & packetIndexMask)) {
oddStartingPacket = true;
} else {
oddStartingPacket = false;
}
}
}
return oddStartingPacket;
};
};
class EigerData : public GeneralData {
public:
/** Constructor */
EigerData(){
myDetectorType = slsDetectorDefs::EIGER;
nPixelsX = (256*2);
nPixelsY = 256;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = 1024;
packetSize = headerSizeinPacket + dataSize;
packetsPerFrame = 256;
imageSize = dataSize*packetsPerFrame;
maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 100;
threadsPerReceiver = 2;
headerPacketSize = 40;
standardheader = true;
};
/**
* Setting dynamic range changes member variables
* @param dr dynamic range
* @param tgEnable true if 10GbE is enabled, else false
*/
void SetDynamicRange(int dr, bool tgEnable) {
packetsPerFrame = (tgEnable ? 4 : 16) * dr;
imageSize = dataSize*packetsPerFrame;
}
/**
* Setting ten giga enable changes member variables
* @param tgEnable true if 10GbE is enabled, else false
* @param dr dynamic range
*/
void SetTenGigaEnable(bool tgEnable, int dr) {
dataSize = (tgEnable ? 4096 : 1024);
packetSize = headerSizeinPacket + dataSize;
packetsPerFrame = (tgEnable ? 4 : 16) * dr;
imageSize = dataSize*packetsPerFrame;
};
/**
* Enable Gap Pixels changes member variables
* @param enable true if gap pixels enable, else false
* @param dr dynamic range
*/
void SetGapPixelsEnable(bool b, int dr) {
if (dr == 4)
b = 0;
switch((int)b) {
case 1:
nPixelsX = (256 * 2) + 3;
nPixelsY = 256 + 1;
imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit
((dr > 4) ? 1 : // 8 bit
0.5))); // 4 bit
break;
default:
nPixelsX = (256*2);
nPixelsY = 256;
imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit
((dr > 4) ? 1 : // 8 bit
0.5))); // 4 bit
break;
}
};
};
class JungfrauData : public GeneralData {
public:
/** Constructor */
JungfrauData(){
myDetectorType = slsDetectorDefs::JUNGFRAU;
nPixelsX = (256*4);
nPixelsY = 512;
emptyHeader = 6;
headerSizeinPacket = emptyHeader + sizeof(slsDetectorDefs::sls_detector_header);
dataSize = 8192;
packetSize = headerSizeinPacket + dataSize;
packetsPerFrame = 128;
imageSize = dataSize*packetsPerFrame;
maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 2500;
standardheader = true;
defaultUdpSocketBufferSize = (2000 * 1024 * 1024);
};
};
class ChipTestBoardData : public GeneralData {
private:
/** Number of analog channels */
const int NCHAN_ANALOG = 32;
/** Number of digital channels */
const int NCHAN_DIGITAL = 4;
/** Number of bytes per pixel */
const int NUM_BYTES_PER_PIXEL = 2;
public:
/** Constructor */
ChipTestBoardData(){
myDetectorType = slsDetectorDefs::CHIPTESTBOARD;
nPixelsX = 36; // total number of channels
nPixelsY = 1; // number of samples
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = UDP_PACKET_DATA_BYTES;
packetSize = headerSizeinPacket + dataSize;
//packetsPerFrame = 1;
imageSize = nPixelsX * nPixelsY * 2;
packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES);
maxFramesPerFile = CTB_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 2500;
standardheader = true;
};
/**
* Set databytes (ctb, moench)
* @param f readout flags
* @param r roi
* @param s number of samples
* @param t tengiga enable
*/
void setImageSize(std::vector<slsDetectorDefs::ROI> r, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
int nchans = 0;
if (f != slsDetectorDefs::GET_READOUT_FLAGS) {
// analog channels
if (f == slsDetectorDefs::NORMAL_READOUT || f & slsDetectorDefs::ANALOG_AND_DIGITAL) {
nchans += NCHAN_ANALOG;
// if roi
if (r.size()) {
nchans = 0;
for (auto &roi : r) {
nchans += (roi.xmax - roi.xmin + 1);
}
}
}
// digital channels
if (f & slsDetectorDefs::DIGITAL_ONLY || f & slsDetectorDefs::ANALOG_AND_DIGITAL) {
nchans += NCHAN_DIGITAL;
}
}
nPixelsX = nchans;
nPixelsY = s;
// 10G
if (t) {
headerSizeinPacket = 22;
dataSize = 8192;
packetSize = headerSizeinPacket + dataSize;
imageSize = nPixelsX * nPixelsY * 2;
packetsPerFrame = ceil((double)imageSize / (double)packetSize);
standardheader = false; }
// 1g udp (via fifo readout)
else {
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = UDP_PACKET_DATA_BYTES;
packetSize = headerSizeinPacket + dataSize;
imageSize = nPixelsX * nPixelsY * 2;
packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES);
standardheader = true;
}
}
};
class MoenchData : public GeneralData {
private:
/** Number of analog channels */
const int NCHAN_ANALOG = 32;
/** Number of bytes per pixel */
const int NUM_BYTES_PER_PIXEL = 2;
/** Structure of an jungfrau ctb packet header (10G Udp) */
typedef struct {
unsigned char emptyHeader[6];
unsigned char reserved[4];
unsigned char packetNumber[1];
unsigned char frameNumber[3];
unsigned char bunchid[8];
} jfrauctb_packet_header_t;
public:
/** Constructor */
MoenchData(){
myDetectorType = slsDetectorDefs::MOENCH;
nPixelsX = 32; // total number of channels
nPixelsY = 1; // number of samples
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = UDP_PACKET_DATA_BYTES;
packetSize = headerSizeinPacket + dataSize;
//packetsPerFrame = 1;
imageSize = nPixelsX * nPixelsY * 2;
packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES);
frameIndexMask = 0xFFFFFF;
maxFramesPerFile = CTB_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 2500;
standardheader = true;
};
/**
* Get Header Infomation (frame number, packet number)
* @param index thread index for debugging purposes
* @param packetData pointer to data
* @param dynamicRange dynamic range to assign subframenumber if 32 bit mode
* @param oddStartingPacket odd starting packet (gotthard)
* @param frameNumber frame number * @param packetNumber packet number
* @param subFrameNumber sub frame number if applicable
* @param bunchId bunch id
*/
void GetHeaderInfo(int index, char* packetData, uint32_t dynamicRange, bool oddStartingPacket,
uint64_t& frameNumber, uint32_t& packetNumber, uint32_t& subFrameNumber, uint64_t& bunchId) const {
subFrameNumber = -1;
jfrauctb_packet_header_t* header = (jfrauctb_packet_header_t*)(packetData);
frameNumber = (uint64_t)((*( (uint32_t*) header->frameNumber)) & frameIndexMask);
packetNumber = (uint32_t)(*( (uint8_t*) header->packetNumber));
bunchId = (*((uint64_t*) header->bunchid));
}
/**
* Set databytes (ctb, moench)
* @param f readout flags
* @param r roi
* @param s number of samples
* @param t tengiga enable
*/
void setImageSize(std::vector<slsDetectorDefs::ROI> r, int s, bool t,
slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
int nchans = NCHAN_ANALOG;
// if roi
if (r.size()) {
nchans = 0;
for (auto &roi : r) {
nchans += abs(roi.xmax - roi.xmin) + 1;
}
}
nPixelsX = nchans;
nPixelsY = s;
// 10G
if (t) {
headerSizeinPacket = 22;
dataSize = 8192;
packetSize = headerSizeinPacket + dataSize;
imageSize = nPixelsX * nPixelsY * 2;
packetsPerFrame = ceil((double)imageSize / (double)packetSize);
standardheader = false;
}
// 1g udp (via fifo readout)
else {
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = UDP_PACKET_DATA_BYTES;
packetSize = headerSizeinPacket + dataSize;
imageSize = nPixelsX * nPixelsY * 2;
packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES);
standardheader = true;
}
}
};

View File

@ -0,0 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "def79807f6f40ed1797b8154240adbc0e35c95e0"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4039
#define GITDATE 0x20181002
#define GITBRANCH "refactor"

View File

@ -0,0 +1,6 @@
#define GITURL ""
#define GITREPUUID ""
#define GITAUTH ""
#define GITREV ""
#define GITDATE ""
#define GITBRANCH ""

View File

@ -0,0 +1,50 @@
#pragma once
#include "sls_detector_defs.h"
#include <stdint.h>
#define MAX_DIMENSIONS 2
//socket
#define GOODBYE -200
#define RECEIVE_SOCKET_BUFFER_SIZE (100*1024*1024)
#define MAX_SOCKET_INPUT_PACKET_QUEUE 250000
//files
#define DO_NOTHING 0
#define DO_EVERYTHING 1
#define STATISTIC_FRAMENUMBER_INFINITE 20000
//binary
#define FILE_BUFFER_SIZE (16*1024*1024) //16mb
//fifo
#define FIFO_HEADER_NUMBYTES 4
//hdf5
#define MAX_CHUNKED_IMAGES 1
//versions
#define HDF5_WRITER_VERSION 3.0 //1 decimal places
#define BINARY_WRITER_VERSION 3.0 //1 decimal places
//parameters to calculate fifo depth
#define SAMPLE_TIME_IN_NS 100000000//100ms
#define MAX_JOBS_PER_THREAD 1000
//to differentiate between gotthard and short gotthard
#define GOTTHARD_PACKET_SIZE 1286
#define DUMMY_PACKET_VALUE 0xFFFFFFFF
#define LISTENER_PRIORITY 90
#define PROCESSOR_PRIORITY 70
#define STREAMER_PRIORITY 10
#define TCP_PRIORITY 10

View File

@ -0,0 +1,86 @@
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
# This flag is only useful for Objective-C code. When set to YES local
# methods, which are defined in the implementation section but not in
# the interface are included in the documentation.
# If set to NO (the default) only methods in the interface are included.
EXTRACT_LOCAL_METHODS = YES
# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base
# name of the file that contains the anonymous namespace. By default
# anonymous namespace are hidden.
EXTRACT_ANON_NSPACES = NO
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these classes will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
# friend (class|struct|union) declarations.
# If set to NO (the default) these declarations will be included in the
# documentation.
HIDE_FRIEND_COMPOUNDS = NO
INTERNAL_DOCS = NO
SHOW_INCLUDE_FILES = NO
SHOW_FILES = NO
SHOW_NAMESPACES = NO
COMPACT_LATEX = YES
PAPER_TYPE = a4
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_HIDE_INDICES = YES
PREDEFINED = __cplusplus
INPUT = include/slsReceiverUsers.h
OUTPUT_DIRECTORY = slsReceiverUsersDocs

View File

@ -0,0 +1,7 @@
SRCFILE=include/gitInfoReceiver.h
DSTFILE=include/versionAPI.h
SRCPATTERN=GITDATE
DSTPATTERN=APIRECEIVER
awk -v a="$SRCFILE" -v b="$DSTFILE" -v c="$SRCPATTERN" -v d="$DSTPATTERN" 'FNR==NR&&$2==c{x=$3} NR!=FNR{if($2==d){$3="0x"substr(x,5)}print > b}' $SRCFILE $DSTFILE

View File

@ -0,0 +1,28 @@
MAINDIR=slsDetectorPackage
SPECDIR=slsReceiverSoftware
TMPFILE=include/gitInfoReceiverTmp.h
INCLFILE=include/gitInfoReceiver.h
WD=$PWD
#evaluate the variables
EVALFILE=../evalVersionVariables.sh
source $EVALFILE
#get modified date
#RDATE1='git log --pretty=format:"%ci" -1'
RDATE1="find . -type f -exec stat --format '%Y :%y %n' '{}' \; | sort -nr | cut -d: -f2- | egrep -v 'gitInfo|build|.git|updateGitVersion' | head -n 1"
RDATE=`eval $RDATE1`
NEWDATE=$(sed "s/-//g" <<< $RDATE | awk '{print $1;}')
NEWDATE=${NEWDATE/#/0x}
#get old date from INCLFILE
OLDDATE=$(more $INCLFILE | grep '#define GITDATE' | awk '{print $3}')
#update INCLFILE if changes
if [ "$OLDDATE" != "$NEWDATE" ]; then
echo Path: ${MAINDIR}/${SPECDIR} $'\n'URL: ${GITREPO} $'\n'Repository Root: ${GITREPO} $'\n'Repsitory UUID: ${REPUID} $'\n'Revision: ${FOLDERREV} $'\n'Branch: ${BRANCH} $'\n'Last Changed Author: ${AUTH1}_${AUTH2} $'\n'Last Changed Rev: ${REV} $'\n'Last Changed Date: ${RDATE} > gitInfo.txt
cd ..
./genVersionHeader.sh $SPECDIR/gitInfo.txt $SPECDIR/$TMPFILE $SPECDIR/$INCLFILE
cd $WD
fi