diff --git a/slsDetectorCalibration/circularFifo.h b/slsDetectorCalibration/circularFifo.h new file mode 100644 index 000000000..f0b4eeb34 --- /dev/null +++ b/slsDetectorCalibration/circularFifo.h @@ -0,0 +1,156 @@ +#pragma once +/* CircularFifo.h +* Code & platform dependent issues with it was originally +* published at http://www.kjellkod.cc/threadsafecircularqueue +* 2009-11-02 +* @author Kjell Hedstr�m, hedstrom@kjellkod.cc +* modified by the sls detetor group +* */ + +//#include "sls_receiver_defs.h" +#include +#include +#include + +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; + + + +/** Circular Fifo (a.k.a. Circular Buffer) +* Thread safe for one reader, and one writer */ +template +class CircularFifo { +public: + + CircularFifo(unsigned int Size) : tail(0), head(0){ + Capacity = Size + 1; + array.resize(Capacity); + sem_init(&data_mutex,0,0); + sem_init(&free_mutex,0,Size); + } + virtual ~CircularFifo() { + sem_destroy(&data_mutex); + sem_destroy(&free_mutex); + } + + bool push(Element*& item_, bool no_block=false); + bool pop(Element*& item_, bool no_block=false); + + bool isEmpty() const; + bool isFull() const; + + int getDataValue() const; + int getFreeValue() const; + +private: + std::vector array; + unsigned int tail; // input index + unsigned int head; // output index + unsigned int Capacity; + mutable sem_t data_mutex; + mutable sem_t free_mutex; + unsigned int increment(unsigned int idx_) const; +}; + +template +int CircularFifo::getDataValue() const +{ + int value; + sem_getvalue(&data_mutex, &value); + return value; +} + +template +int CircularFifo::getFreeValue() const +{ + int value; + sem_getvalue(&free_mutex, &value); + return value; +} + + +/** Producer only: Adds item to the circular queue. +* If queue is full at 'push' operation no update/overwrite +* will happen, it is up to the caller to handle this case +* +* \param item_ copy by reference the input item +* \param no_block if true, return immediately if fifo is full +* \return whether operation was successful or not */ +template +bool CircularFifo::push(Element*& item_, bool no_block) +{ + // check for fifo full + if (no_block && isFull()) + return false; + + sem_wait(&free_mutex); + array[tail] = item_; + tail = increment(tail); + sem_post(&data_mutex); + return true; +} + +/** Consumer only: Removes and returns item from the queue +* If queue is empty at 'pop' operation no retrieve will happen +* It is up to the caller to handle this case +* +* \param item_ return by reference the wanted item +* \param no_block if true, return immediately if fifo is full +* \return whether operation was successful or not */ +template +bool CircularFifo::pop(Element*& item_, bool no_block) +{ + // check for fifo empty + if (no_block && isEmpty()) + return false; + + sem_wait(&data_mutex); + item_ = array[head]; + head = increment(head); + sem_post(&free_mutex); + return true; +} + +/** Useful for testinng and Consumer check of status + * Remember that the 'empty' status can change quickly + * as the Procuder adds more items. + * + * \return true if circular buffer is empty */ +template +bool CircularFifo::isEmpty() const +{ + return (getDataValue() == 0); +} + +/** Useful for testing and Producer check of status + * Remember that the 'full' status can change quickly + * as the Consumer catches up. + * + * \return true if circular buffer is full. */ +template +bool CircularFifo::isFull() const +{ + return (getFreeValue() == 0); +} + +/** Increment helper function for index of the circular queue +* index is inremented or wrapped +* +* \param idx_ the index to the incremented/wrapped +* \return new value for the index */ +template +unsigned int CircularFifo::increment(unsigned int idx_) const +{ + // increment or wrap + // ================= + // index++; + // if(index == array.lenght) -> index = 0; + // + //or as written below: + // index = (index+1) % array.length + idx_ = (idx_+1) % Capacity; + return idx_; +} + diff --git a/slsDetectorCalibration/dataStructures/moench03T1ZmqDataNew.h b/slsDetectorCalibration/dataStructures/moench03T1ZmqDataNew.h index 22f6d126c..c04d035d2 100644 --- a/slsDetectorCalibration/dataStructures/moench03T1ZmqDataNew.h +++ b/slsDetectorCalibration/dataStructures/moench03T1ZmqDataNew.h @@ -14,6 +14,8 @@ class moench03T1ZmqDataNew : public slsDetectorData { const int nSamples; const int offset; + + double ghost[200][25]; double xtalk; @@ -29,17 +31,22 @@ class moench03T1ZmqDataNew : public slsDetectorData { */ // moench03T1ZmqDataNew(int ns=5000): slsDetectorData(400, 400, ns*32*2+sizeof(int)), nSamples(ns), offset(sizeof(int)), xtalk(0.00021) { - moench03T1ZmqDataNew(int ns=5000, int oo=0): slsDetectorData(400, 400, ns*32*2+oo), nSamples(ns), offset(oo), xtalk(0.00021) { - + moench03T1ZmqDataNew(int ns=5000, int oo=2*2): slsDetectorData(400, 400, ns*32*2+oo), nSamples(ns), offset(oo), xtalk(0.00021) { + cout << "M0.3" << endl; int nadc=32; int sc_width=25; int sc_height=200; - - int adc_nr[32]={300,325,350,375,300,325,350,375, \ + + int adc_nr[32]={300,325,350,375,300,325,350,375, \ 200,225,250,275,200,225,250,275,\ 100,125,150,175,100,125,150,175,\ 0,25,50,75,0,25,50,75}; - + + /* int adc_nr[32]={350,375,150,175,350,375,150,175, \ + 300,325,100,125,300,325,100,125,\ + 250,275,50,75,250,275,50,75,\ + 200,225,0,25,200,225,0,25}; + */ int row, col; int isample; @@ -50,11 +57,11 @@ class moench03T1ZmqDataNew : public slsDetectorData { int i; int adc4(0); - for (int ip=0; ip { } } } - } + // } int ii=0; diff --git a/slsDetectorCalibration/moenchExecutables/moenchZmqProcess.cpp b/slsDetectorCalibration/moenchExecutables/moenchZmqProcess.cpp index 47e424306..b79c28f60 100644 --- a/slsDetectorCalibration/moenchExecutables/moenchZmqProcess.cpp +++ b/slsDetectorCalibration/moenchExecutables/moenchZmqProcess.cpp @@ -1,6 +1,8 @@ //#define WRITE_QUAD #define DEVELOPER #undef CORR +#undef MOENCH04 + #define C_GHOST 0.0004 #define CM_ROWS 20 @@ -28,6 +30,7 @@ #include #include "tiffIO.h" + #include //json header in zmq stream #include @@ -135,9 +138,11 @@ int main(int argc, char *argv[]) { //slsDetectorData *det=new moench03T1ZmqDataNew(); #ifndef MOENCH04 + cout << "This is a Moench03" << endl; moench03T1ZmqDataNew *det=new moench03T1ZmqDataNew(); #endif #ifdef MOENCH04 + cout << "This is a Moench04" << endl; moench04CtbZmq10GbData *det=new moench04CtbZmq10GbData(); #endif cout << endl << " det" <pop(ptr); } - virtual int isBusy() {if (fifoData->isEmpty() && busy==0) return 0; else return 1;} + virtual int isBusy() {if (fifoData->isEmpty() && busy==0) return 0; return 1;} //protected: /** Implement this method in your subclass with the code you want your thread to run. */