From 6693d0833103670722b0fcbdc54eda0948208168 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 14 Nov 2017 11:53:37 +0100 Subject: [PATCH 01/15] fixed help of acquire doing an actual acquisition --- slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp index 83960ada2..2888450c7 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -2302,6 +2302,10 @@ string slsDetectorCommand::cmdAcquire(int narg, char *args[], int action) { #endif + if (action==HELP_ACTION) { + return helpAcquire(narg,args,HELP_ACTION); + } + myDet->setOnline(ONLINE_FLAG); int r_online = myDet->setReceiverOnline(ONLINE_FLAG); From dda86cfe9b83d53b534b227f6e5b8a95afa1e586 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 14 Nov 2017 16:26:17 +0100 Subject: [PATCH 02/15] somewhere in separating zmq rxr and client --- .../commonFiles/sls_detector_defs.h | 3 +- .../multiSlsDetector/multiSlsDetector.cpp | 6 ++-- .../slsDetector/slsDetector.cpp | 29 +++++++++++++++++-- slsDetectorSoftware/slsDetector/slsDetector.h | 15 +++++++--- .../slsDetector/slsDetectorCommand.cpp | 21 ++++++++++++-- 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h index 386255bae..66fc70a2a 100755 --- a/slsDetectorSoftware/commonFiles/sls_detector_defs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -193,7 +193,8 @@ enum networkParameter { FLOW_CONTROL_10G, /**< flow control for 10GbE */ FLOW_CONTROL_WR_PTR, /**< memory write pointer for flow control */ FLOW_CONTROL_RD_PTR, /**< memory read pointer for flow control */ - RECEIVER_STREAMING_PORT /**< receiever streaming TCP(ZMQ) port */ + RECEIVER_STREAMING_PORT, /**< receiever streaming TCP(ZMQ) port */ + CLIENT_STREAMING_PORT /**< client streaming TCP(ZMQ) port */ }; /** diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 67973eda8..4d698604f 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -3690,7 +3690,7 @@ string multiSlsDetector::setNetworkParameter(networkParameter p, string s){ // disable data streaming before changing zmq port (but only if they were on) int prev_streaming = 0; - if (p == RECEIVER_STREAMING_PORT) { + if (p == RECEIVER_STREAMING_PORT || p == CLIENT_STREAMING_PORT) { prev_streaming = getStreamingSocketsCreatedInClient(); enableDataStreamingFromReceiver(0); } @@ -3704,7 +3704,7 @@ string multiSlsDetector::setNetworkParameter(networkParameter p, string s){ string* sret[thisMultiDetector->numberOfDetectors]; for(int idet=0; idetnumberOfDetectors; ++idet){ if(detectors[idet]){ - if (p == RECEIVER_STREAMING_PORT) + if (p == RECEIVER_STREAMING_PORT || p == CLIENT_STREAMING_PORT) s.append("multi\0"); sret[idet]=new string("error"); Task* task = new Task(new func2_t(&slsDetector::setNetworkParameter, @@ -3748,7 +3748,7 @@ string multiSlsDetector::setNetworkParameter(networkParameter p, string s){ } //enable data streaming if it was on - if (p == RECEIVER_STREAMING_PORT && prev_streaming) + if ((p == RECEIVER_STREAMING_PORT || p == CLIENT_STREAMING_PORT) && prev_streaming) enableDataStreamingFromReceiver(1); return getNetworkParameter(p); diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 380223a02..ced0c34e5 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -5930,6 +5930,9 @@ string slsDetector::setNetworkParameter(networkParameter index, string value) { case FLOW_CONTROL_10G: sscanf(value.c_str(),"%d",&i); return setDetectorNetworkParameter(index, i); + case CLIENT_STREAMING_PORT: + setClientStreamingPort(value); + return getClientStreamingPort(); case RECEIVER_STREAMING_PORT: setReceiverStreamingPort(value); return getReceiverStreamingPort(); @@ -6221,6 +6224,28 @@ int slsDetector::setReceiverUDPPort2(int udpport){ } +int slsDetector::setReceiverStreamingPort(string port) { + int defaultport = 0; + int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; + int arg = 0; + + //multi command, calculate individual ports + size_t found = port.find("multi"); + if(found != string::npos) { + port.erase(found,5); + sscanf(port.c_str(),"%d",&defaultport); + arg = defaultport + (posId * numsockets); + } + else + sscanf(port.c_str(),"%d",&arg); + thisDetector->zmqport = arg; + + return thisDetector->zmqport; +} + + + + int slsDetector::setReceiverStreamingPort(string port) { int defaultport = 0; int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; @@ -6249,12 +6274,12 @@ int slsDetector::setReceiverStreamingPort(string port) { disconnectData(); } if(ret!=FAIL) - thisDetector->zmqport = retval; + thisDetector->receiver_zmqport = retval; if(ret==FORCE_UPDATE) updateReceiver(); } - return thisDetector->zmqport; + return thisDetector->receiver_zmqport; } string slsDetector::setDetectorNetworkParameter(networkParameter index, int delay){ diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 97a40e9f2..728041162 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -269,8 +269,11 @@ class slsDetector : public slsDetectorUtils, public energyConversion { bool acquiringFlag; /** flipped data across x or y axis */ int flippedData[2]; - /** tcp port between receiver and gui (only data) */ + /** tcp port from gui/different process to receiver (only data) */ int zmqport; + /** tcp port from receiver to gui/different process (only data) */ + int receiver_zmqport; + } sharedSlsDetector; @@ -1733,8 +1736,10 @@ class slsDetector : public slsDetectorUtils, public energyConversion { string getReceiverUDPPort() {ostringstream ss; ss << thisDetector->receiverUDPPort; string s = ss.str(); return s;}; /** returns the receiver UDP2 for Eiger IP address \sa sharedSlsDetector */ string getReceiverUDPPort2() {ostringstream ss; ss << thisDetector->receiverUDPPort2; string s = ss.str(); return s;}; - /** returns the zmq port \sa sharedSlsDetector */ - string getReceiverStreamingPort() {ostringstream ss; ss << thisDetector->zmqport; string s = ss.str(); return s;}; + /** returns the client zmq port \sa sharedSlsDetector */ + string getClientStreamingPort() {ostringstream ss; ss << thisDetector->zmqport; string s = ss.str(); return s;}; + /** returns the receiver zmq port \sa sharedSlsDetector */ + string getReceiverStreamingPort() {ostringstream ss; ss << thisDetector->receiver_zmqport; string s = ss.str(); return s;}; /** validates the format of detector MAC address and sets it \sa sharedSlsDetector */ string setDetectorMAC(string detectorMAC); @@ -1750,7 +1755,9 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int setReceiverUDPPort(int udpport); /** sets the receiver udp port2 for Eiger \sa sharedSlsDetector */ int setReceiverUDPPort2(int udpport); - /** sets the zmq port in client and receiver (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ + /** sets the zmq port in client (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ + int setClientStreamingPort(string port); + /** sets the zmq port in receiver (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ int setReceiverStreamingPort(string port); /** sets the transmission delay for left or right port or for an entire frame*/ string setDetectorNetworkParameter(networkParameter index, int delay); diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp index 2888450c7..1d91e41d8 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -1894,12 +1894,19 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { ++i; /*! \page network - - zmqport [port] sets/gets the 0MQ (TCP) port of the receiver from where data is streamed to the client. Use single-detector command to set individually or multi-detector command to calculate based on \c port for the rest. \c Returns \c (int) + - zmqport [port] sets/gets the 0MQ (TCP) port of the client to where final data is streamed to (eg. for GUI). Use single-detector command to set individually or multi-detector command to calculate based on \c port for the rest. \c Returns \c (int) */ descrToFuncMap[i].m_pFuncName="zmqport"; // descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; ++i; + /*! \page network + - rx_zmqport [port] sets/gets the 0MQ (TCP) port of the receiver from where data is streamed from (eg. to GUI or another process for further processing). Use single-detector command to set individually or multi-detector command to calculate based on \c port for the rest. \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="rx_zmqport"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + ++i; + /*! \page network - configuremac [i] configures the MAC of the detector with these parameters: detectorip, detectormac, rx_udpip, rx_udpmac, rx_udpport, rx_udpport2 (if applicable). This command is already included in \c rx_hsotname. Only put!. \c Returns \c (int) */ @@ -3946,6 +3953,12 @@ string slsDetectorCommand::cmdNetworkParameter(int narg, char *args[], int actio return ("cannot parse argument") + string(args[1]); } }else if (cmd=="zmqport") { + t=CLIENT_STREAMING_PORT; + if (action==PUT_ACTION){ + if (!(sscanf(args[1],"%d",&i))) + return ("cannot parse argument") + string(args[1]); + } + }else if (cmd=="rx_zmqport") { t=RECEIVER_STREAMING_PORT; if (action==PUT_ACTION){ if (!(sscanf(args[1],"%d",&i))) @@ -3976,7 +3989,8 @@ string slsDetectorCommand::helpNetworkParameter(int narg, char *args[], int acti os << "txndelay_right port \n sets detector transmission delay of the right port"<< std::endl; os << "txndelay_frame port \n sets detector transmission delay of the entire frame"<< std::endl; os << "flowcontrol_10g port \n sets flow control for 10g for eiger"<< std::endl; - os << "zmqport port \n sets zmq port (data from receiver to client); setting via multidetector command calculates port for individual detectors"<< std::endl; + os << "zmqport port \n sets zmq port (data to client from receiver/different process); setting via multidetector command calculates port for individual detectors"<< std::endl; + os << "rx_zmqport port \n sets zmq port (data from receiver to client/different process); setting via multidetector command calculates port for individual detectors"<< std::endl; } if (action==GET_ACTION || action==HELP_ACTION) { os << "detectormac \n gets detector mac "<< std::endl; @@ -3989,7 +4003,8 @@ string slsDetectorCommand::helpNetworkParameter(int narg, char *args[], int acti os << "txndelay_right \n gets detector transmission delay of the right port"<< std::endl; os << "txndelay_frame \n gets detector transmission delay of the entire frame"<< std::endl; os << "flowcontrol_10g \n gets flow control for 10g for eiger"<< std::endl; - os << "zmqport \n gets zmq port (data from receiver to client)"<< std::endl; + os << "zmqport \n gets zmq port (data to client from receiver/different process)"<< std::endl; + os << "rx_zmqport \n gets zmq port (data from receiver to client/different process)"<< std::endl; } return os.str(); From 2b0d07387abbad6b33432a6dd8474fae8cbef427 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 15 Nov 2017 17:16:47 +0100 Subject: [PATCH 03/15] in between separating datastreaming in client and receiver --- .../multiSlsDetector/multiSlsDetector.h | 19 ++++-- .../slsDetector/slsDetector.cpp | 25 ++------ slsDetectorSoftware/slsDetector/slsDetector.h | 7 +- .../slsDetector/slsDetectorCommand.cpp | 64 ++++--------------- .../slsDetector/slsDetectorUtils.h | 6 +- 5 files changed, 40 insertions(+), 81 deletions(-) diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h index 2d0ff72a5..96d35eb28 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -207,6 +207,9 @@ class multiSlsDetector : public slsDetectorUtils { /** receiver online flag - is set if the receiver is connected, unset if socket connection is not possible */ int receiverOnlineFlag; + /** data streaming (up stream) enable in receiver */ + bool receiver_datastream; + } sharedMultiSlsDetector; @@ -1342,17 +1345,19 @@ class multiSlsDetector : public slsDetectorUtils { /** - * Get Streaming sockets created in client from reciever - /returns 1 if sockets created, else 0 + * Enable data streaming to client + * @param enable 0 to disable, 1 to enable, -1 to get the value + * @returns data streaming to client enable */ - int getStreamingSocketsCreatedInClient(); + int enableDataStreamingToClient(int enable=-1); /** Enable or disable streaming data from receiver to client - * @param enable 0 to disable 1 to enable -1 to only get the value - * @returns data streaming + * @param enable 0 to disable 1 to enable -1 to only get the value + * @returns data streaming to receiver enable */ int enableDataStreamingFromReceiver(int enable=-1); + /** updates the multidetector offsets */ void updateOffsets(); @@ -1489,8 +1494,8 @@ private: int getData(const int isocket, const bool masking, int* image, const int size, uint64_t &acqIndex, uint64_t &frameIndex, uint32_t &subframeIndex, string &filename); - /** Ensures if sockets created successfully */ - bool dataSocketsStarted; + /** data streaming (down stream) enabled in client (zmq sckets created) */ + bool client_datastream; /** ZMQ Socket - Receiver to Client */ ZmqSocket* zmqSocket[MAXDET]; diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index ced0c34e5..a61be6d5e 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -777,7 +777,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->acquiringFlag = false; thisDetector->flippedData[0] = 0; thisDetector->flippedData[1] = 0; - thisDetector->zmqport = 0; + thisDetector->zmqport = DEFAULT_ZMQ_CL_PORTNO + (posId * (thisDetector->myDetectorType == EIGER) ? 2 : 1); + thisDetector->receiver_zmqport = DEFAULT_ZMQ_RX_PORTNO + (posId * (thisDetector->myDetectorType == EIGER) ? 2 : 1); for (int ia=0; iaactionScript[ia],"none"); @@ -6067,7 +6068,7 @@ string slsDetector::setReceiver(string receiverIP){ std::cout << "dynamic range:" << thisDetector->dynamicRange << endl << endl; std::cout << "flippeddatax:" << thisDetector->flippedData[d] << endl; std::cout << "10GbE:" << thisDetector->tenGigaEnable << endl << endl; - std::cout << "streaming port:" << thisDetector->zmqport << endl; + std::cout << "rx streaming port:" << thisDetector->receiver_zmqport << endl; //std::cout << "dataStreaming:" << enableDataStreamingFromReceiver(-1) << endl << endl; /** enable compresison, */ @@ -6113,19 +6114,7 @@ string slsDetector::setReceiver(string receiverIP){ // data streaming setReceiverStreamingPort(getReceiverStreamingPort()); - int clientSockets = parentDet->getStreamingSocketsCreatedInClient(); - int recSockets = enableDataStreamingFromReceiver(-1); - if(clientSockets != recSockets) { - pthread_mutex_lock(&ms); - if(clientSockets) - printf("Enabling Data Streaming\n"); - else - printf("Disabling Data Streaming\n"); - // push client state to receiver - /*parentDet->enableDataStreamingFromReceiver(clientSockets);*/ - enableDataStreamingFromReceiver(clientSockets); - pthread_mutex_unlock(&ms); - } + enableDataStreamingFromReceiver(enableDataStreamingFromReceiver(-1)); } } @@ -6224,7 +6213,7 @@ int slsDetector::setReceiverUDPPort2(int udpport){ } -int slsDetector::setReceiverStreamingPort(string port) { +int slsDetector::setClientStreamingPort(string port) { int defaultport = 0; int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; int arg = 0; @@ -8268,9 +8257,9 @@ int slsDetector::updateReceiverNoWait() { parentDet->enableOverwriteMask(ind); pthread_mutex_unlock(&ms); - // streaming port + // receiver streaming port n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); - thisDetector->zmqport = ind; + thisDetector->receiver_zmqport = ind; if (!n) printf("n: %d\n", n); diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 728041162..0ec9c4a99 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -273,7 +273,8 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int zmqport; /** tcp port from receiver to gui/different process (only data) */ int receiver_zmqport; - + /** data streaming (up stream) enable in receiver */ + bool receiver_datastream; } sharedSlsDetector; @@ -1781,8 +1782,8 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int setReceiverReadTimer(int time_in_ms=500); /** Enable or disable streaming data from receiver to client - * @param enable 0 to disable 1 to enable -1 to only get the value - * @returns data streaming + * @param enable 0 to disable 1 to enable -1 to only get the value + * @returns data streaming to receiver enable */ int enableDataStreamingFromReceiver(int enable=-1); diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp index 1d91e41d8..a45a19363 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -255,13 +255,6 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { commands to configure detector data structure */ - /*! \page config - - externalgui sets/gets external gui flag. 1 sets and enables the 0MQ data stream (0MQ threads created) from receiver to client, while 0 unsets and disables. \c Returns \c (int) - */ - descrToFuncMap[i].m_pFuncName="externalgui"; // - descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDataStream; - ++i; - /*! \page config - \b free Free shared memory on the control PC */ @@ -1907,6 +1900,13 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; ++i; + /*! \page network + - rx_datastream enables/disables data streaming from receiver. 1 enables 0MQ data stream from receiver (creates streamer threads), while 0 disables (destroys streamer threads). \c Returns \c (int) + */ + descrToFuncMap[i].m_pFuncName="rx_datastream"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDataStream; + ++i; + /*! \page network - configuremac [i] configures the MAC of the detector with these parameters: detectorip, detectormac, rx_udpip, rx_udpmac, rx_udpport, rx_udpport2 (if applicable). This command is already included in \c rx_hsotname. Only put!. \c Returns \c (int) */ @@ -2316,16 +2316,6 @@ string slsDetectorCommand::cmdAcquire(int narg, char *args[], int action) { myDet->setOnline(ONLINE_FLAG); int r_online = myDet->setReceiverOnline(ONLINE_FLAG); - if ((!myDet->getExternalGuiFlag()) && (r_online == ONLINE_FLAG)) { - // command line: must be off, if receiver on or there was -1, then - if (myDet->enableDataStreamingFromReceiver(-1) != 0){ - //switch it off, if error - if (myDet->enableDataStreamingFromReceiver(0) != 0) { - return string("could not disable data streaming in receiver\n"); - } - } - } - if(myDet->acquire() == FAIL) return string("acquire unsuccessful"); if(r_online){ @@ -2490,18 +2480,11 @@ string slsDetectorCommand::cmdDataStream(int narg, char *args[], int action) { if (action==PUT_ACTION) { if (!sscanf(args[1],"%d",&ival)) - return string ("cannot scan externalgui mode"); - myDet->setExternalGuiFlag(ival>0?true:false); + return string ("cannot scan rx_datastream mode"); myDet->enableDataStreamingFromReceiver(ival); } - int retval = myDet->getExternalGuiFlag(); - //if external gui on and datastreaming off - if (retval && !myDet->enableDataStreamingFromReceiver()) { - retval=-1; - printf("Error: data streaming in receiver is switched off while external gui flag in shared memory is off.\n"); - } - sprintf(ans,"%d",myDet->getExternalGuiFlag()); + sprintf(ans,"%d",myDet->enableDataStreamingFromReceiver()); return string(ans); } @@ -2510,9 +2493,9 @@ string slsDetectorCommand::helpDataStream(int narg, char *args[], int action) { ostringstream os; if (action==GET_ACTION || action==HELP_ACTION) - os << string("externalgui \t gets external gui flag. 1/0 means the 0MQ data stream (0MQ threads created) from receiver to client is enabled/disabled. -1 for inconsistency. \n"); + os << string("rx_datastream \t enables/disables data streaming from receiver. 1 is 0MQ data stream from receiver enabled, while 0 is 0MQ disabled. -1 for inconsistency between multiple receivers. \n"); if (action==PUT_ACTION || action==HELP_ACTION) - os << string("externalgui i\t sets external gui flag. 1/0 means the 0MQ data stream (0MQ threads created) from receiver to client is enabled/disabled. \n"); + os << string("rx_datastream i\t enables/disables data streaming from receiver. i is 1 enables 0MQ data stream from receiver (creates streamer threads), while 0 disables (destroys streamer threads). \n"); return os.str(); } @@ -5899,33 +5882,14 @@ string slsDetectorCommand::cmdReceiver(int narg, char *args[], int action) { myDet->setOnline(ONLINE_FLAG); - int receivers = myDet->setReceiverOnline(ONLINE_FLAG); + myDet->setReceiverOnline(ONLINE_FLAG); if(cmd=="receiver"){ if (action==PUT_ACTION) { - if(!strcasecmp(args[1],"start")) { - //to ensure data streaming enable is the same across client and receiver - if ((!myDet->getExternalGuiFlag()) && (receivers == ONLINE_FLAG)) { - //if it was not off - if (myDet->enableDataStreamingFromReceiver(-1) != 0){ - //switch it off, if error - if (myDet->enableDataStreamingFromReceiver(0) != 0) { - return string("could not disable data streaming in receiver\n"); - } - } - } + if(!strcasecmp(args[1],"start")) myDet->startReceiver(); - } - else if(!strcasecmp(args[1],"stop")){ - //myDet->stopReceiver(); - // myDet->startReceiverReadout(); - /*runStatus s = myDet->getReceiverStatus(); - while(s != RUN_FINISHED){ - usleep(50000); - s = myDet->getReceiverStatus(); - }*/ + else if(!strcasecmp(args[1],"stop")) myDet->stopReceiver(); - } else return helpReceiver(narg, args, action); } diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h index d297cfe27..faa4b473d 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h @@ -749,9 +749,9 @@ virtual ROI* getROI(int &n)=0; */ virtual int setReadReceiverFrequency(int getFromReceiver, int freq=-1)=0; -/** Enable or disable streaming of data from receiver to client - * @param enable 0 to disable 1 to enable -1 to only get the value - * @returns data streaming +/** Enable or disable streaming data from receiver to client + * @param enable 0 to disable 1 to enable -1 to only get the value + * @returns data streaming to receiver enable */ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; From fd34bab34b2c94c05edf6f6fb58b246ac5d4be74 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 15 Nov 2017 17:19:07 +0100 Subject: [PATCH 04/15] in between separating datastreaming in client and receiver --- .../multiSlsDetector/multiSlsDetector.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 4d698604f..6e53af4af 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -3690,8 +3690,13 @@ string multiSlsDetector::setNetworkParameter(networkParameter p, string s){ // disable data streaming before changing zmq port (but only if they were on) int prev_streaming = 0; + switch (p) { + case RECEIVER_STREAMING_PORT: + prev_streaming = enableDataStreamingFromReceiver(); + enableDataStreamingFromReceiver(0); + } if (p == RECEIVER_STREAMING_PORT || p == CLIENT_STREAMING_PORT) { - prev_streaming = getStreamingSocketsCreatedInClient(); + prev_streaming = enableDataStreamingToClient(); enableDataStreamingFromReceiver(0); } @@ -6150,7 +6155,7 @@ int multiSlsDetector::setReceiverReadTimer(int time_in_ms){ return ret; } -int multiSlsDetector::getStreamingSocketsCreatedInClient() { +int multiSlsDetector::enableDataStreamingToClient() { return dataSocketsStarted; } From 7dee07b9c571ad6e33c448dbd8efeb0a4dbb3c75 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 16 Nov 2017 09:12:54 +0100 Subject: [PATCH 05/15] somewhere --- slsDetectorSoftware/commonFiles/error_defs.h | 2 +- .../multiSlsDetector/multiSlsDetector.cpp | 150 +++++++++--------- .../slsDetector/slsDetector.cpp | 19 ++- 3 files changed, 93 insertions(+), 78 deletions(-) diff --git a/slsDetectorSoftware/commonFiles/error_defs.h b/slsDetectorSoftware/commonFiles/error_defs.h index 922d1b08d..272626053 100644 --- a/slsDetectorSoftware/commonFiles/error_defs.h +++ b/slsDetectorSoftware/commonFiles/error_defs.h @@ -240,7 +240,7 @@ public: retval.append("Could not activate/deactivate receiver\n"); if(slsErrorMask&DATA_STREAMING) - retval.append("Could not set/reset Data Streaming\n"); + retval.append("Could not enable/disable Data Streaming\n"); if(slsErrorMask&RESET_ERROR) retval.append("Could not reset the FPGA\n"); diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 6e53af4af..9c29efcfc 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -209,6 +209,7 @@ multiSlsDetector::multiSlsDetector(int id) : slsDetectorUtils(), shmId(-1) thisMultiDetector->receiver_read_freq = 0; thisMultiDetector->acquiringFlag = false; thisMultiDetector->externalgui = false; + thisMultiDetector->receiver_datastream = false; thisMultiDetector->alreadyExisting=1; } @@ -274,7 +275,7 @@ multiSlsDetector::multiSlsDetector(int id) : slsDetectorUtils(), shmId(-1) getNMods(); getMaxMods(); - dataSocketsStarted = false; + client_datastream = false; for(int i=0;igetReceiverStreamingPort().c_str(),"%d",&portnum); - if (portnum == 0) { - portnum = DEFAULT_ZMQ_PORTNO + - (i/numSocketsPerDetector)*numSocketsPerDetector + (i%numSocketsPerDetector); // *num and /num is not same cuz its integers - }else{ - portnum += (i%numSocketsPerDetector); - } + uint32_t portnum = 0; + sscanf(detectors[i/numSocketsPerDetector]->getClientStreamingPort().c_str(),"%d",&portnum); + portnum += (i%numSocketsPerDetector); zmqSocket[i] = new ZmqSocket(detectors[i/numSocketsPerDetector]->getReceiver().c_str(), portnum); if (zmqSocket[i]->IsError()) { @@ -5692,7 +5700,7 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy){ printf("Zmq Client[%d] at %s\n",i, zmqSocket[i]->GetZmqServerAddress()); } - dataSocketsStarted = true; + client_datastream = true; cout << "Receiving Data Socket(s) created" << endl; return OK; } @@ -6155,71 +6163,63 @@ int multiSlsDetector::setReceiverReadTimer(int time_in_ms){ return ret; } -int multiSlsDetector::enableDataStreamingToClient() { - return dataSocketsStarted; +int multiSlsDetector::enableDataStreamingToClient(int enable) { + if(enable >= 0){ + + //destroy data threads + if (!enable) + createReceivingDataSockets(true); + + //create data threads + else { + if(createReceivingDataSockets() == FAIL){ + std::cout << "Could not create data threads in client." << std::endl; + //only for the first det as theres no general one + setErrorMask(getErrorMask()|(1<<0)); + detectors[0]->setErrorMask((detectors[0]->getErrorMask())|(DATA_STREAMING)); + } + } + } + return client_datastream; } -int multiSlsDetector::enableDataStreamingFromReceiver(int enable){//cannot parrallize due to serReceiver calling parentdet->enabledatastremain - - //create client sockets only if no external gui - if (!thisMultiDetector->externalgui) { - if(enable >= 0){ - - //destroy data threads - if(dataSocketsStarted) - createReceivingDataSockets(true); - - //create data threads - if(enable > 0){ - if(createReceivingDataSockets() == FAIL){ - std::cout << "Could not create data threads in client. Aborting creating data sockets in receiver" << std::endl; - //only for the first det as theres no general one - setErrorMask(getErrorMask()|(1<<0)); - detectors[0]->setErrorMask((detectors[0]->getErrorMask())|(DATA_STREAMING)); - return -1; +int multiSlsDetector::enableDataStreamingFromReceiver(int enable){ + if(enable >= 0){ + int ret=-100; + if(!threadpool){ + cout << "Error in creating threadpool. Exiting" << endl; + return -1; + }else{ + //return storage values + int* iret[thisMultiDetector->numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; ++idet){ + if(detectors[idet]){ + iret[idet]= new int(-1); + Task* task = new Task(new func1_t(&slsDetector::enableDataStreamingFromReceiver, + detectors[idet],enable,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->startExecuting(); + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; ++idet){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if (ret==-100) + ret=*iret[idet]; + else if (ret!=*iret[idet]) + ret=-1; + delete iret[idet]; + }else ret=-1; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<receiver_datastream = ret; } - - int ret=-100; - if(!threadpool){ - cout << "Error in creating threadpool. Exiting" << endl; - return -1; - }else{ - //return storage values - int* iret[thisMultiDetector->numberOfDetectors]; - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - iret[idet]= new int(-1); - Task* task = new Task(new func1_t(&slsDetector::enableDataStreamingFromReceiver, - detectors[idet],enable,iret[idet])); - threadpool->add_task(task); - } - } - threadpool->startExecuting(); - threadpool->wait_for_tasks_to_complete(); - for(int idet=0; idetnumberOfDetectors; ++idet){ - if(detectors[idet]){ - if(iret[idet] != NULL){ - if (ret==-100) - ret=*iret[idet]; - else if (ret!=*iret[idet]) - ret=-1; - delete iret[idet]; - }else ret=-1; - if(detectors[idet]->getErrorMask()) - setErrorMask(getErrorMask()|(1<externalgui) { - if (ret != dataSocketsStarted) - ret = -1; - } - return ret; + return thisMultiDetector->receiver_datastream; } int multiSlsDetector::enableReceiverCompression(int i){ diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index a61be6d5e..543bcbfe3 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -777,8 +777,9 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->acquiringFlag = false; thisDetector->flippedData[0] = 0; thisDetector->flippedData[1] = 0; - thisDetector->zmqport = DEFAULT_ZMQ_CL_PORTNO + (posId * (thisDetector->myDetectorType == EIGER) ? 2 : 1); - thisDetector->receiver_zmqport = DEFAULT_ZMQ_RX_PORTNO + (posId * (thisDetector->myDetectorType == EIGER) ? 2 : 1); + thisDetector->zmqport = 0; + thisDetector->receiver_zmqport = 0; + thisDetector->receiver_datastream = false; for (int ia=0; iaactionScript[ia],"none"); @@ -923,6 +924,14 @@ int slsDetector::initializeDetectorSize(detectorType type) { delete thisReceiver; thisReceiver = new receiverInterface(dataSocket); + // zmq ports + if (posId != -1) { + if (thisDetector->zmqport == 0) + thisDetector->zmqport = DEFAULT_ZMQ_CL_PORTNO + (posId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1)); + if (thisDetector->receiver_zmqport == 0) + thisDetector->receiver_zmqport = DEFAULT_ZMQ_RX_PORTNO + (posId * ((thisDetector->myDetectorType == EIGER) ? 2 : 1)); + } + // setAngularConversionPointer(thisDetector->angOff,&thisDetector->nMods, thisDetector->nChans*thisDetector->nChips); #ifdef VERBOSE @@ -5967,6 +5976,8 @@ string slsDetector::getNetworkParameter(networkParameter index) { case DETECTOR_TXN_DELAY_FRAME: case FLOW_CONTROL_10G: return setDetectorNetworkParameter(index, -1); + case CLIENT_STREAMING_PORT: + return getClientStreamingPort(); case RECEIVER_STREAMING_PORT: return getReceiverStreamingPort(); default: @@ -8261,6 +8272,10 @@ int slsDetector::updateReceiverNoWait() { n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); thisDetector->receiver_zmqport = ind; + // receiver streaming enable + n += dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + thisDetector->receiver_datastream = ind; + if (!n) printf("n: %d\n", n); return OK; From f192164e32492fddbc927d7f5aabcfee17805374 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 16 Nov 2017 12:27:58 +0100 Subject: [PATCH 06/15] fixed setdac bug that comes rarely, moved serialize spi to 32bit --- ...0.6.2 => jungfrauDetectorServerv3.0.0.6.3} | Bin 105300 -> 105236 bytes .../slsDetectorServer/commonServerFunctions.h | 26 +++++++++--------- .../slsDetectorFunctionList.h | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) rename slsDetectorSoftware/jungfrauDetectorServer/bin/{jungfrauDetectorServerv3.0.0.6.2 => jungfrauDetectorServerv3.0.0.6.3} (52%) diff --git a/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.2 b/slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.3 similarity index 52% rename from slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.2 rename to slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.3 index 1c2630d2b301fc1736f073374beb05514c393b9b..c8fbf44aa451aed016e01ea43ab625e24b83e4b7 100755 GIT binary patch delta 28433 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 m~g3(I?3{yIf`BlZ%<0FXTezoGWBq*O06^8#*Am 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 diff --git a/slsDetectorSoftware/slsDetectorServer/commonServerFunctions.h b/slsDetectorSoftware/slsDetectorServer/commonServerFunctions.h index e201bef17..4122fb7cf 100755 --- a/slsDetectorSoftware/slsDetectorServer/commonServerFunctions.h +++ b/slsDetectorSoftware/slsDetectorServer/commonServerFunctions.h @@ -6,7 +6,7 @@ #endif /* global variables */ -void serializeToSPI(u_int32_t addr, u_int32_t val, u_int16_t csmask, int numbitstosend, u_int16_t clkmask, u_int16_t digoutmask, int digofset) { +void serializeToSPI(u_int32_t addr, u_int32_t val, u_int32_t csmask, int numbitstosend, u_int32_t clkmask, u_int32_t digoutmask, int digofset) { #ifdef VERBOSE if (numbitstosend == 16) printf("Writing to SPI Register: 0x%04x\n",val); @@ -14,15 +14,15 @@ void serializeToSPI(u_int32_t addr, u_int32_t val, u_int16_t csmask, int numbits printf("Writing to SPI Register: 0x%08x\n", val); #endif - u_int16_t valw; + u_int32_t valw; // start point - valw = 0xffff; /**todo testwith old board 0xff for adc_spi */ // old board compatibility (not using specific bits) - bus_w16 (addr, valw); + valw = 0xffffffff; // old board compatibility (not using specific bits) + bus_w (addr, valw); // chip sel bar down - valw &= ~csmask; /* todo with test: done a bit different, not with previous value */ - bus_w16 (addr, valw); + valw &= ~csmask; /* todo with test: done a bit different, not with previous value */ + bus_w (addr, valw); { int i = 0; @@ -30,30 +30,30 @@ void serializeToSPI(u_int32_t addr, u_int32_t val, u_int16_t csmask, int numbits // clk down valw &= ~clkmask; - bus_w16 (addr, valw); + bus_w (addr, valw); // write data (i) valw = ((valw & ~digoutmask) + // unset bit (((val >> (numbitstosend - 1 - i)) & 0x1) << digofset)); // each bit from val starting from msb - bus_w16 (addr, valw); + bus_w (addr, valw); // clk up valw |= clkmask ; - bus_w16 (addr, valw); + bus_w (addr, valw); } } // chip sel bar up valw |= csmask; /* todo with test: not done for spi */ - bus_w16 (addr, valw); + bus_w (addr, valw); //clk down valw &= ~clkmask; - bus_w16 (addr, valw); + bus_w (addr, valw); // stop point = start point of course - valw = 0xffff; /**todo testwith old board 0xff for adc_spi */ // old board compatibility (not using specific bits) - bus_w16 (addr, valw); + valw = 0xffffffff; // old board compatibility (not using specific bits) + bus_w (addr, valw); } diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h index 145af32fa..04f769c5d 100644 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h @@ -124,7 +124,7 @@ int setThresholdEnergy(int ev, int imod); // parameters - dac, adc, hv #ifdef JUNGFRAUD -void serializeToSPI(u_int32_t addr, u_int32_t val, u_int16_t csmask, int numbitstosend, u_int16_t clkmask, u_int16_t digoutmask, int digofset); +void serializeToSPI(u_int32_t addr, u_int32_t val, u_int32_t csmask, int numbitstosend, u_int32_t clkmask, u_int32_t digoutmask, int digofset); void initDac(int dacnum); extern void setAdc(int addr, int val); // AD9257.h int voltageToDac(int value); From 8e0414d1b9f880ded77893da27ad1d151c8e48d2 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 16 Nov 2017 15:01:22 +0100 Subject: [PATCH 07/15] separating zmqport, enabling in client and receiver works --- slsDetectorSoftware/slsDetector/slsDetector.cpp | 8 ++++---- slsDetectorSoftware/slsDetector/slsDetector.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 543bcbfe3..d57c6fda4 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -6224,7 +6224,7 @@ int slsDetector::setReceiverUDPPort2(int udpport){ } -int slsDetector::setClientStreamingPort(string port) { +string slsDetector::setClientStreamingPort(string port) { int defaultport = 0; int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; int arg = 0; @@ -6240,13 +6240,13 @@ int slsDetector::setClientStreamingPort(string port) { sscanf(port.c_str(),"%d",&arg); thisDetector->zmqport = arg; - return thisDetector->zmqport; + return getClientStreamingPort(); } -int slsDetector::setReceiverStreamingPort(string port) { +string slsDetector::setReceiverStreamingPort(string port) { int defaultport = 0; int numsockets = (thisDetector->myDetectorType == EIGER) ? 2:1; int arg = 0; @@ -6279,7 +6279,7 @@ int slsDetector::setReceiverStreamingPort(string port) { updateReceiver(); } - return thisDetector->receiver_zmqport; + return getReceiverStreamingPort(); } string slsDetector::setDetectorNetworkParameter(networkParameter index, int delay){ diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 0ec9c4a99..b6e3f7ac0 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -1757,9 +1757,9 @@ class slsDetector : public slsDetectorUtils, public energyConversion { /** sets the receiver udp port2 for Eiger \sa sharedSlsDetector */ int setReceiverUDPPort2(int udpport); /** sets the zmq port in client (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ - int setClientStreamingPort(string port); + string setClientStreamingPort(string port); /** sets the zmq port in receiver (includes "multi" at the end if it should calculate individual ports \sa sharedSlsDetector */ - int setReceiverStreamingPort(string port); + string setReceiverStreamingPort(string port); /** sets the transmission delay for left or right port or for an entire frame*/ string setDetectorNetworkParameter(networkParameter index, int delay); From 4097c37b31eeb6123d6ecfc4e5de5b5818d2e4fc Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 16 Nov 2017 16:01:31 +0100 Subject: [PATCH 08/15] in between --- .../multiSlsDetector/multiSlsDetector.h | 2 +- slsDetectorSoftware/slsDetector/slsDetector.h | 2 +- .../slsDetector/slsDetectorBase.h | 1 - .../slsDetector/slsDetectorUsers.cpp | 12 +++++ .../slsDetector/slsDetectorUsers.h | 35 ++++++++++++--- .../slsDetector/slsDetectorUtils.h | 45 ++++++++++++++++++- 6 files changed, 88 insertions(+), 9 deletions(-) diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h index 96d35eb28..7f82c9642 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -1353,7 +1353,7 @@ class multiSlsDetector : public slsDetectorUtils { /** Enable or disable streaming data from receiver to client * @param enable 0 to disable 1 to enable -1 to only get the value - * @returns data streaming to receiver enable + * @returns data streaming from receiver enable */ int enableDataStreamingFromReceiver(int enable=-1); diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index b6e3f7ac0..06fb35123 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -1783,7 +1783,7 @@ class slsDetector : public slsDetectorUtils, public energyConversion { /** Enable or disable streaming data from receiver to client * @param enable 0 to disable 1 to enable -1 to only get the value - * @returns data streaming to receiver enable + * @returns data streaming from receiver enable */ int enableDataStreamingFromReceiver(int enable=-1); diff --git a/slsDetectorSoftware/slsDetector/slsDetectorBase.h b/slsDetectorSoftware/slsDetector/slsDetectorBase.h index 7d8683fdc..f8a8b4626 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorBase.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorBase.h @@ -425,7 +425,6 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef */ int setHighVoltage(int val){return setDAC(val, HV_NEW, 0, -1);} \ - /** set dacs value \param val value diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp index 95d9369ec..828c9f65b 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp @@ -227,6 +227,18 @@ int slsDetectorUsers::enableDataStreamingFromReceiver(int i){ return myDetector->enableDataStreamingFromReceiver(i); } +int slsDetectorUsers::enableDataStreamingToClient(int i){ + return myDetector->enableDataStreamingToClient(i); +} + +int slsDetectorUsers::setReceiverDataStreamingOutPort(int i, int imod){ + return myDetector->setReceiverDataStreamingOutPort(i, imod); +} + +int slsDetectorUsers::setClientDataStreamingInPort(int i, int imod){ + return myDetector->setClientDataStreamingInPort(i, imod); +} + int64_t slsDetectorUsers::getModuleFirmwareVersion(){ return myDetector->getModuleFirmwareVersion(); } diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h index ea8011326..f0cee1730 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h @@ -439,13 +439,38 @@ class slsDetectorUsers virtual void finalizeDataset(double *a, double *v, double *e, int &np); - /** - Enable data streaming from receiver (zmq) - \param i 1 to set, 0 to reset and -1 to get - \returns data streaming enable - */ + /** Enable or disable streaming data from receiver (creates transmitting sockets) + * @param enable 0 to disable 1 to enable -1 to only get the value + * @returns data streaming from receiver enable + */ int enableDataStreamingFromReceiver(int i=-1); + /** + * Enable data streaming to client (creates receiving sockets) + * @param i 0 to disable, 1 to enable, -1 to get the value + * @returns data streaming to client enable + */ + int enableDataStreamingToClient(int i=-1); + + /** + * Set/Get receiver streaming out ZMQ port + * If imod is -1, when setting it calculates and sets the port for all individual detectors + * and when getting it returns only the port of individual detector in first position + * @param i sets, -1 gets + * @param imod module index, -1 for all + * @returns receiver streaming out ZMQ port () + */ + int setReceiverDataStreamingOutPort(int i, int imod=-1); + + /** + * Set/Get client streaming in ZMQ port + * If imod is -1, when setting it calculates and sets the port for all individual detectors + * and when getting it returns only the port of individual detector in first position + * @param i sets, -1 gets + * @param imod module index, -1 for all + * @returns client streaming in ZMQ port + */ + int setClientDataStreamingInPort(int i, int imod=-1); /** get get Module Firmware Version diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h index faa4b473d..0a6bdafc8 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h @@ -30,6 +30,7 @@ extern "C" { #include #include #include +#include using namespace std; @@ -88,6 +89,48 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { int enableFlatFieldCorrection(int i=-1) {if (i>0) setFlatFieldCorrectionFile("default"); else if (i==0) setFlatFieldCorrectionFile(""); return getFlatFieldCorrection();}; int enablePixelMaskCorrection(int i=-1) {if (i>0) setBadChannelCorrection("default"); else if (i==0) setBadChannelCorrection(""); return getBadChannelCorrection();}; int enableCountRateCorrection(int i=-1) {if (i>0) setRateCorrection(i); else if (i==0) setRateCorrection(0); return getRateCorrection();}; + + /** + * Set/Get receiver streaming out ZMQ port + * @param i sets, -1 gets + * @param imod module index, -1 for all + * @returns receiver streaming out ZMQ port + */ + int setReceiverDataStreamingOutPort(int i, int imod) { \ + // single module + if (imod < 0) { \ + if (i >= 0) { \ + ostringstream ss; ss << i; string s = ss.str(); \ + getSlsDetector(imod)->setReceiverStreamingPort(RECEIVER_STREAMING_PORT, s); \ + } \ + return atoi(getSlsDetector(imod)->getReceiverStreamingPort().c_str()); \ + } \ + // multimodule + if (i >= 0) \ + setNetworkParameter(RECEIVER_STREAMING_PORT, s); \ + return atoi(getSlsDetector(0)->getNetworkParameter(RECEIVER_STREAMING_PORT).c_str());}; \ + + /** + * Set/Get client streaming in ZMQ port + * @param i sets, -1 gets + * @param imod module index, -1 for all + * @returns client streaming in ZMQ port + */ + int setClientDataStreamingInPort(int i, int imod=-1){ \ + // single module + if (imod < 0) { \ + if (i >= 0) { \ + ostringstream ss; ss << i; string s = ss.str(); \ + getSlsDetector(imod)->setReceiverStreamingPort(CLIENT_STREAMING_PORT, s); \ + } \ + return atoi(getSlsDetector(imod)->getReceiverStreamingPort().c_str()); \ + } \ + // multimodule + if (i >= 0) \ + setNetworkParameter(CLIENT_STREAMING_PORT, s); \ + return atoi(getSlsDetector(0)->getNetworkParameter(CLIENT_STREAMING_PORT).c_str());}; \ + }; + // string getFilePath(){return fileIO::getFilePath();};; // string setFilePath(string s){return fileIO::setFilePath(s);}; @@ -751,7 +794,7 @@ virtual int setReadReceiverFrequency(int getFromReceiver, int freq=-1)=0; /** Enable or disable streaming data from receiver to client * @param enable 0 to disable 1 to enable -1 to only get the value - * @returns data streaming to receiver enable + * @returns data streaming from receiver enable */ virtual int enableDataStreamingFromReceiver(int enable=-1)=0; From f647bdaa48f670d072afd7928e2925adf5966c1f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 17 Nov 2017 08:46:43 +0100 Subject: [PATCH 09/15] updated users class to reflect zmq changes (separation), fixed warnings --- slsDetectorSoftware/slsDetector/slsDetector.h | 2 +- .../slsDetector/slsDetectorUsers.cpp | 8 ++-- .../slsDetector/slsDetectorUsers.h | 12 ++---- .../slsDetector/slsDetectorUtils.h | 43 ++++++------------- 4 files changed, 22 insertions(+), 43 deletions(-) diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 06fb35123..3e058fad7 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -1643,7 +1643,7 @@ class slsDetector : public slsDetectorUtils, public energyConversion { /** gets the number of frames caught by any one receiver (to avoid using threadpool) \returns number of frames caught by any one receiver (master receiver if exists) */ - int getFramesCaughtByAnyReceiver() {getFramesCaughtByReceiver();}; + int getFramesCaughtByAnyReceiver() {return getFramesCaughtByReceiver();}; /** gets the current frame index of receiver \returns current frame index of receiver diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp index 828c9f65b..c783d349f 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp @@ -231,12 +231,12 @@ int slsDetectorUsers::enableDataStreamingToClient(int i){ return myDetector->enableDataStreamingToClient(i); } -int slsDetectorUsers::setReceiverDataStreamingOutPort(int i, int imod){ - return myDetector->setReceiverDataStreamingOutPort(i, imod); +int slsDetectorUsers::setReceiverDataStreamingOutPort(int i){ + return myDetector->setReceiverDataStreamingOutPort(i); } -int slsDetectorUsers::setClientDataStreamingInPort(int i, int imod){ - return myDetector->setClientDataStreamingInPort(i, imod); +int slsDetectorUsers::setClientDataStreamingInPort(int i){ + return myDetector->setClientDataStreamingInPort(i); } int64_t slsDetectorUsers::getModuleFirmwareVersion(){ diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h index f0cee1730..dbaa75340 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h @@ -454,23 +454,19 @@ class slsDetectorUsers /** * Set/Get receiver streaming out ZMQ port - * If imod is -1, when setting it calculates and sets the port for all individual detectors - * and when getting it returns only the port of individual detector in first position + * For multi modules, it calculates (increments) and sets the ports * @param i sets, -1 gets - * @param imod module index, -1 for all * @returns receiver streaming out ZMQ port () */ - int setReceiverDataStreamingOutPort(int i, int imod=-1); + int setReceiverDataStreamingOutPort(int i=-1); /** * Set/Get client streaming in ZMQ port - * If imod is -1, when setting it calculates and sets the port for all individual detectors - * and when getting it returns only the port of individual detector in first position + * For multi modules, it calculates (increments) and sets the ports * @param i sets, -1 gets - * @param imod module index, -1 for all * @returns client streaming in ZMQ port */ - int setClientDataStreamingInPort(int i, int imod=-1); + int setClientDataStreamingInPort(int i=-1); /** get get Module Firmware Version diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h index 0a6bdafc8..9f47b3080 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h @@ -90,48 +90,31 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { int enablePixelMaskCorrection(int i=-1) {if (i>0) setBadChannelCorrection("default"); else if (i==0) setBadChannelCorrection(""); return getBadChannelCorrection();}; int enableCountRateCorrection(int i=-1) {if (i>0) setRateCorrection(i); else if (i==0) setRateCorrection(0); return getRateCorrection();}; + /** * Set/Get receiver streaming out ZMQ port + * For multi modules, it calculates (increments) and sets the ports * @param i sets, -1 gets - * @param imod module index, -1 for all * @returns receiver streaming out ZMQ port */ - int setReceiverDataStreamingOutPort(int i, int imod) { \ - // single module - if (imod < 0) { \ - if (i >= 0) { \ - ostringstream ss; ss << i; string s = ss.str(); \ - getSlsDetector(imod)->setReceiverStreamingPort(RECEIVER_STREAMING_PORT, s); \ - } \ - return atoi(getSlsDetector(imod)->getReceiverStreamingPort().c_str()); \ - } \ - // multimodule - if (i >= 0) \ - setNetworkParameter(RECEIVER_STREAMING_PORT, s); \ - return atoi(getSlsDetector(0)->getNetworkParameter(RECEIVER_STREAMING_PORT).c_str());}; \ + int setReceiverDataStreamingOutPort(int i) { \ + if (i >= 0) { ostringstream ss; ss << i; string s = ss.str(); \ + setNetworkParameter(RECEIVER_STREAMING_PORT, s);} \ + return atoi(getNetworkParameter(RECEIVER_STREAMING_PORT).c_str());}; \ /** * Set/Get client streaming in ZMQ port + * For multi modules, it calculates (increments) and sets the ports * @param i sets, -1 gets - * @param imod module index, -1 for all * @returns client streaming in ZMQ port */ - int setClientDataStreamingInPort(int i, int imod=-1){ \ - // single module - if (imod < 0) { \ - if (i >= 0) { \ - ostringstream ss; ss << i; string s = ss.str(); \ - getSlsDetector(imod)->setReceiverStreamingPort(CLIENT_STREAMING_PORT, s); \ - } \ - return atoi(getSlsDetector(imod)->getReceiverStreamingPort().c_str()); \ - } \ - // multimodule - if (i >= 0) \ - setNetworkParameter(CLIENT_STREAMING_PORT, s); \ - return atoi(getSlsDetector(0)->getNetworkParameter(CLIENT_STREAMING_PORT).c_str());}; \ - }; + int setClientDataStreamingInPort(int i){ \ + if (i >= 0) { ostringstream ss; ss << i; string s = ss.str(); \ + setNetworkParameter(CLIENT_STREAMING_PORT, s);} \ + return atoi(getNetworkParameter(CLIENT_STREAMING_PORT).c_str());}; \ - // string getFilePath(){return fileIO::getFilePath();};; + +// string getFilePath(){return fileIO::getFilePath();};; // string setFilePath(string s){return fileIO::setFilePath(s);}; // string getFileName(){return fileIO::getFileName();}; From 428855d8018e306d9bd83e82e1f9f7c85d7d7909 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 17 Nov 2017 14:02:00 +0100 Subject: [PATCH 10/15] in between --- .../commonFiles/sls_detector_defs.h | 3 +- .../multiSlsDetector/multiSlsDetector.cpp | 8 +++++ .../slsDetector/slsDetector.cpp | 8 +++-- .../slsDetector/slsDetectorCommand.cpp | 36 +++++++++++++------ 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h index a22877146..b0d960f62 100755 --- a/slsDetectorSoftware/commonFiles/sls_detector_defs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -195,7 +195,8 @@ enum networkParameter { FLOW_CONTROL_RD_PTR, /**< memory read pointer for flow control */ RECEIVER_STREAMING_PORT, /**< receiever streaming TCP(ZMQ) port */ CLIENT_STREAMING_PORT, /**< client streaming TCP(ZMQ) port */ - RECEIVER_STREAMING_SRC_IP /**< receiever streaming TCP(ZMQ) ip */ + RECEIVER_STREAMING_SRC_IP,/**< receiever streaming TCP(ZMQ) ip */ + CLIENT_STREAMING_SRC_IP /**< client streaming TCP(ZMQ) ip */ }; /** diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index f65166098..614de212a 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -3741,6 +3741,11 @@ string multiSlsDetector::setNetworkParameter(networkParameter p, string s){ case RECEIVER_STREAMING_SRC_IP: prev_streaming = enableDataStreamingFromReceiver(); enableDataStreamingFromReceiver(0); + break; + case CLIENT_STREAMING_SRC_IP: + prev_streaming = enableDataStreamingToClient(); + enableDataStreamingToClient(0); + break; default: break; } @@ -3809,6 +3814,9 @@ string multiSlsDetector::setNetworkParameter(networkParameter p, string s){ case RECEIVER_STREAMING_SRC_IP: enableDataStreamingFromReceiver(1); break; + case CLIENT_STREAMING_SRC_IP: + enableDataStreamingToClient(1); + break; default: break; } } diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 7ca65dfb7..a93a6e262 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -6035,6 +6035,8 @@ string slsDetector::setNetworkParameter(networkParameter index, string value) { return getReceiverStreamingPort(); case RECEIVER_STREAMING_SRC_IP: return setReceiverStreamingSourceIP(value); + case CLIENT_STREAMING_SRC_IP: + return setClientStreamingSourceIP(value); default: return (char*)("unknown network parameter"); } @@ -6069,8 +6071,10 @@ string slsDetector::getNetworkParameter(networkParameter index) { return getClientStreamingPort(); case RECEIVER_STREAMING_PORT: return getReceiverStreamingPort(); - case RECEIVER_STREAMING_SRC_IP: - return getReceiverStreamingSourceIP(); +case RECEIVER_STREAMING_SRC_IP: + return getReceiverStreamingSourceIP(); +case CLIENT_STREAMING_SRC_IP: + return getClientStreamingSourceIP(); default: return (char*)("unknown network parameter"); } diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp index 82f00b44c..cba73ed7a 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -1895,7 +1895,7 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { ++i; /*! \page network - - zmqport [port] sets/gets the 0MQ (TCP) port of the client to where final data is streamed to (eg. for GUI). Use single-detector command to set individually or multi-detector command to calculate based on \c port for the rest. \c Returns \c (int) + - zmqport [port] sets/gets the 0MQ (TCP) port of the client to where final data is streamed to (eg. for GUI). The default already connects with rx_zmqport for the GUI. This command to change from default can be used from command line when sockets are not already open as the command line is not aware/create the 0mq sockets in the client side. Use single-detector command to set individually or multi-detector command to calculate based on \c port for the rest. \c Returns \c (int) */ descrToFuncMap[i].m_pFuncName="zmqport"; // descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; @@ -1909,19 +1909,25 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { ++i; /*! \page network - - rx_datastream enables/disables data streaming from receiver. 1 enables 0MQ data stream from receiver (creates streamer threads), while 0 disables (destroys streamer threads). \c Returns \c (int) + - rx_datastream enables/disables data streaming from receiver. 1 enables 0MQ data stream from receiver (creates streamer threads), while 0 disables (destroys streamer threads). Switching to Gui enables data streaming in receiver and switching back to command line acquire will require disabling data streaming in receiver for fast applications \c Returns \c (int) */ descrToFuncMap[i].m_pFuncName="rx_datastream"; // descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDataStream; ++i; /*! \page network - - zmqsrcip [ip] sets/gets the 0MQ (TCP) ip of the receiver from where data is streamed to the client. Default is ip of rx_hostname. Use this only with external gui. \c Returns \c (string) + - zmqsrcip [ip] sets/gets the 0MQ (TCP) ip of the client to where final data is streamed to (eg. for GUI). Default is ip of rx_hostname and works for GUI. This command to change from default can be used from command line when sockets are not already open as the command line is not aware/create the 0mq sockets in the client side. This is usually used to stream in from an external process. \c Returns \c (string) */ descrToFuncMap[i].m_pFuncName="zmqsrcip"; // descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; i++; + /*! \page network + - rx_zmqsrcip [ip] sets/gets the 0MQ (TCP) ip of the receiver from where data is streamed from (eg. to GUI or another process for further processing). Default is ip of rx_hostname and works for GUI. This is usually used to stream out to an external process for further processing. \c Returns \c (string) + */ + descrToFuncMap[i].m_pFuncName="rx_zmqsrcip"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; /*! \page network - configuremac [i] configures the MAC of the detector with these parameters: detectorip, detectormac, rx_udpip, rx_udpmac, rx_udpport, rx_udpport2 (if applicable). This command is already included in \c rx_hsotname. Only put!. \c Returns \c (int) @@ -3964,7 +3970,9 @@ string slsDetectorCommand::cmdNetworkParameter(int narg, char *args[], int actio return ("cannot parse argument") + string(args[1]); } }else if (cmd=="zmqsrcip") { - t=RECEIVER_STREAMING_SRC_IP; + t=CLIENT_STREAMING_SRC_IP; + }else if (cmd=="rx_zmqsrcip") { + t=RECEIVER_STREAMING_SRC_IP; } else return ("unknown network parameter")+cmd; @@ -3991,9 +3999,16 @@ string slsDetectorCommand::helpNetworkParameter(int narg, char *args[], int acti os << "txndelay_right port \n sets detector transmission delay of the right port"<< std::endl; os << "txndelay_frame port \n sets detector transmission delay of the entire frame"<< std::endl; os << "flowcontrol_10g port \n sets flow control for 10g for eiger"<< std::endl; - os << "zmqport port \n sets zmq port (data to client from receiver/different process); setting via multidetector command calculates port for individual detectors"<< std::endl; - os << "rx_zmqport port \n sets zmq port (data from receiver to client/different process); setting via multidetector command calculates port for individual detectors"<< std::endl; - os << "zmqsrcip ip \n sets/gets the 0MQ (TCP) ip of the receiver from where data is streamed to the client. Default is ip of rx_hostname. Use this only with external gui." << std::endl; + os << "zmqport port \n sets the 0MQ (TCP) port of the client to where final data is streamed to (eg. for GUI). The default already connects with rx_zmqport for the GUI. " + "This command to change from default can be used from command line when sockets are not already open as the command line is not aware/create the 0mq sockets in the client side. " + "Use single-detector command to set individually or multi-detector command to calculate based on port for the rest."<< std::endl; + os << "rx_zmqport port \n sets the 0MQ (TCP) port of the receiver from where data is streamed from (eg. to GUI or another process for further processing). " + "Use single-detector command to set individually or multi-detector command to calculate based on port for the rest."<< std::endl; + os << "zmqsrcip ip \n sets the 0MQ (TCP) ip of the client to where final data is streamed to (eg. for GUI). Default is ip of rx_hostname and works for GUI. " + "This command to change from default can be used from command line when sockets are not already open as the command line is not aware/create the 0mq sockets in the client side. " + "This is usually used to stream in from an external process." << std::endl; + os << "rx_zmqsrcip ip \n sets/gets the 0MQ (TCP) ip of the receiver from where data is streamed from (eg. to GUI or another process for further processing). " + "Default is ip of rx_hostname and works for GUI. This is usually used to stream out to an external process for further processing." << std::endl; } if (action==GET_ACTION || action==HELP_ACTION) { os << "detectormac \n gets detector mac "<< std::endl; @@ -4006,9 +4021,10 @@ string slsDetectorCommand::helpNetworkParameter(int narg, char *args[], int acti os << "txndelay_right \n gets detector transmission delay of the right port"<< std::endl; os << "txndelay_frame \n gets detector transmission delay of the entire frame"<< std::endl; os << "flowcontrol_10g \n gets flow control for 10g for eiger"<< std::endl; - os << "zmqport \n gets zmq port (data to client from receiver/different process)"<< std::endl; - os << "rx_zmqport \n gets zmq port (data from receiver to client/different process)"<< std::endl; - os << "zmqsrcip \n gets zmq source ip (data from receiver to client), none if default setting and no custom ip" << std::endl; + os << "zmqport \n gets the 0MQ (TCP) port of the client to where final data is streamed to"<< std::endl; + os << "rx_zmqport \n gets the 0MQ (TCP) port of the receiver from where data is streamed from"<< std::endl; + os << "zmqsrcip \n gets the 0MQ (TCP) ip of the client to where final data is streamed to, none if default setting and no custom ip" << std::endl; + os << "rx_zmqsrcip \n gets/gets the 0MQ (TCP) ip of the receiver from where data is streamed from, none if default setting and no custom ip" << std::endl; } return os.str(); From 23b415d837bf810a7683252280f0de8406f035a0 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 17 Nov 2017 14:04:03 +0100 Subject: [PATCH 11/15] streaming port set return same as get simple change --- slsDetectorSoftware/slsDetector/slsDetector.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index d57c6fda4..1c6e97d5d 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -5941,11 +5941,9 @@ string slsDetector::setNetworkParameter(networkParameter index, string value) { sscanf(value.c_str(),"%d",&i); return setDetectorNetworkParameter(index, i); case CLIENT_STREAMING_PORT: - setClientStreamingPort(value); - return getClientStreamingPort(); + return setClientStreamingPort(value); case RECEIVER_STREAMING_PORT: - setReceiverStreamingPort(value); - return getReceiverStreamingPort(); + return setReceiverStreamingPort(value); default: return (char*)("unknown network parameter"); } From 99037449f4b1d8bd1675762d954033bce9cd2133 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 20 Nov 2017 14:23:32 +0100 Subject: [PATCH 12/15] in between moench stuff --- .../jctbDetectorServer/firmware_funcs.c | 2 +- .../jctbDetectorServer/gitInfo.txt | 8 ++++---- .../jctbDetectorServer/gitInfoMoench.h | 8 ++++---- .../jctbDetectorServer/jctbDetectorServer | Bin 118716 -> 118844 bytes .../slsDetector/slsDetector.cpp | 19 ++++++++++++------ slsDetectorSoftware/slsDetector/slsDetector.h | 4 ++-- 6 files changed, 24 insertions(+), 17 deletions(-) diff --git a/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c b/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c index 66843d3dc..8c5ddce01 100755 --- a/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c +++ b/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c @@ -4044,7 +4044,7 @@ void initializeDetector(){ setFrames(-1); setTrains(-1); setExposureTime(-1); - setPeriod(-1); + setPeriod(1 * 1000 * 1000);//1ms setDelay(-1); setGates(-1); diff --git a/slsDetectorSoftware/jctbDetectorServer/gitInfo.txt b/slsDetectorSoftware/jctbDetectorServer/gitInfo.txt index cab8f9b7e..0a672768b 100644 --- a/slsDetectorSoftware/jctbDetectorServer/gitInfo.txt +++ b/slsDetectorSoftware/jctbDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsDetectorSoftware/jctbDetectorServer URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git -Repsitory UUID: 2ed351b29db70212973e15b26f604a0a7fef6fcc -Revision: 14 +Repsitory UUID: 9701f00f9e6e9ed5563b6b5c4ace2f4a431b1db7 +Revision: 16 Branch: developer Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 1582 -Last Changed Date: 2017-09-21 16:35:15.000000002 +0200 ./firmware_funcs.c +Last Changed Rev: 1669 +Last Changed Date: 2017-11-20 11:32:02.000000002 +0100 ./firmware_funcs.c diff --git a/slsDetectorSoftware/jctbDetectorServer/gitInfoMoench.h b/slsDetectorSoftware/jctbDetectorServer/gitInfoMoench.h index f9d5ebc89..e1929acee 100644 --- a/slsDetectorSoftware/jctbDetectorServer/gitInfoMoench.h +++ b/slsDetectorSoftware/jctbDetectorServer/gitInfoMoench.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_detector_software.git" //#define SVNREPPATH "" -#define SVNREPUUID "2ed351b29db70212973e15b26f604a0a7fef6fcc" -//#define SVNREV 0x1582 +#define SVNREPUUID "9701f00f9e6e9ed5563b6b5c4ace2f4a431b1db7" +//#define SVNREV 0x1669 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x1582 -#define SVNDATE 0x20170921 +#define SVNREV 0x1669 +#define SVNDATE 0x20171120 // diff --git a/slsDetectorSoftware/jctbDetectorServer/jctbDetectorServer b/slsDetectorSoftware/jctbDetectorServer/jctbDetectorServer index 548f90505bd849ef0dcd2e056b376696d3733292..53ce70ae64cb937d90006f62e0913491acbaae0d 100755 GIT binary patch delta 41261 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%0D$;NH2Z}4n;q-}o-&tf;Mv|E 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 delta 40889 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[CYCLES_NUMBER]=1; thisDetector->timerValue[SAMPLES_JCTB]=1; + // calculating databytes (special when with gap pixels, jctb, mythen in 24bit mode or using probes) thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*thisDetector->dynamicRange/8; - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y) * thisDetector->dynamicRange/8; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + thisDetector->dynamicRange/8; - if(thisDetector->myDetectorType==JUNGFRAUCTB) { - getTotalNumberOfChannels(); - // thisDetector->dataBytes=getTotalNumberOfChannels()*thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; + if(thisDetector->myDetectorType==JUNGFRAUCTB){ + getTotalNumberOfChannels(); // recalculates nchans and databytes + thisDetector->dataBytesInclGapPixels = thisDetector->dataBytes; } - if(thisDetector->myDetectorType==MYTHEN){ + else if(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) { thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y) * thisDetector->nChans*4; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + 4; } } diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 1ef903b0b..035226c6a 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -114,7 +114,7 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int nModMax[2]; /** maximum number of modules (nModMax[X]*nModMax[Y]) \see nModMax */ int nModsMax; - /** number of channels per chip */ + /** number of channels per chip (used mainly in databytes calculation) */ int nChans; /** number of channels per chip in one direction */ int nChan[2]; @@ -664,7 +664,7 @@ class slsDetector : public slsDetectorUtils, public energyConversion { /** Returns the number of modules in direction d (without connecting to the detector) */ int getNMod(dimension d){return thisDetector->nMod[d];}; // - int getChansPerMod(int imod=0){return thisDetector->nChans*thisDetector->nChips;}; + int getChansPerMod(int imod=0){return thisDetector->nChan[X]*thisDetector->nChan[Y]*thisDetector->nChips;}; int getChansPerMod( dimension d,int imod=0){return thisDetector->nChan[d]*thisDetector->nChip[d];}; From a0c014eb7d6a5bb08ffbb8148b0c992b15b605e3 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 20 Nov 2017 15:14:01 +0100 Subject: [PATCH 13/15] changed rate correction back to what it was before in users class, enabling sets defaults --- slsDetectorSoftware/slsDetector/slsDetectorUsers.h | 2 +- slsDetectorSoftware/slsDetector/slsDetectorUtils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h index dbaa75340..fbfd48ec1 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h @@ -204,7 +204,7 @@ class slsDetectorUsers /** @short enable/disable count rate corrections - \param i 0 disables, 1 enable, -1 gets + \param i 0 disables, 1 enables with default values, -1 gets \returns 0 if count corrections disabled, 1 if enabled */ int enableCountRateCorrection(int i=-1); diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h index 9f47b3080..4bed0764c 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h @@ -88,7 +88,7 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { int enableFlatFieldCorrection(int i=-1) {if (i>0) setFlatFieldCorrectionFile("default"); else if (i==0) setFlatFieldCorrectionFile(""); return getFlatFieldCorrection();}; int enablePixelMaskCorrection(int i=-1) {if (i>0) setBadChannelCorrection("default"); else if (i==0) setBadChannelCorrection(""); return getBadChannelCorrection();}; - int enableCountRateCorrection(int i=-1) {if (i>0) setRateCorrection(i); else if (i==0) setRateCorrection(0); return getRateCorrection();}; + int enableCountRateCorrection(int i=-1) {if (i>0) setRateCorrection(-1); else if (i==0) setRateCorrection(0); return getRateCorrection();}; /** From b7ca7f531913db5419a9da786541f4ea7fba957f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 20 Nov 2017 17:15:13 +0100 Subject: [PATCH 14/15] just cleanuped code --- .../slsDetector/slsDetector.cpp | 57 ++++++++++--------- slsDetectorSoftware/slsDetector/slsDetector.h | 4 +- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 79e71ffdf..62bf74342 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -722,8 +722,7 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->dynamicRange/8; if(thisDetector->myDetectorType==JUNGFRAUCTB){ - getTotalNumberOfChannels(); // recalculates nchans and databytes - thisDetector->dataBytesInclGapPixels = thisDetector->dataBytes; + getTotalNumberOfChannels(); } else if(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) { @@ -831,16 +830,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->gainoff=thisDetector->chanoff+sizeof(int)*thisDetector->nGain*thisDetector->nModsMax; thisDetector->offsetoff=thisDetector->gainoff+sizeof(int)*thisDetector->nOffset*thisDetector->nModsMax; - //update?!?!?!? - if(thisDetector->myDetectorType==JUNGFRAUCTB) { - // cout << "here2" << endl; getTotalNumberOfChannels(); - //thisDetector->nChan[X]=32; - //thisDetector->nChans=thisDetector->nChan[X]*thisDetector->nChan[Y]; - - //thisDetector->dataBytes=getTotalNumberOfChannels()*thisDetector->dynamicRange/8*thisDetector->timerValue[SAMPLES_JCTB]; - } } @@ -1765,11 +1756,7 @@ int slsDetector::getTotalNumberOfChannels() { } thisDetector->nChans=thisDetector->nChan[X]; thisDetector->dataBytes=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods*2*thisDetector->timerValue[SAMPLES_JCTB]; - // cout << "Total number of channels is "<< thisDetector->nChans*thisDetector->nChips*thisDetector->nMods << " data bytes is " << thisDetector->dataBytes << endl; - thisDetector->dataBytesInclGapPixels = - (thisDetector->nChan[X]*thisDetector->nChip[X]*thisDetector->nMod[X]) + (thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nChan[Y]*thisDetector->nChip[Y]*thisDetector->nMod[Y]) + (thisDetector->gappixels * thisDetector->nGappixels[Y]) * - 2*thisDetector->timerValue[SAMPLES_JCTB]; + thisDetector->dataBytesInclGapPixels = thisDetector->dataBytes; } else { #ifdef VERBOSE cout << "det type is "<< thisDetector->myDetectorType << endl; @@ -1787,7 +1774,7 @@ int slsDetector::getTotalNumberOfChannels(dimension d) { int slsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d) { getTotalNumberOfChannels(); - return (thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nMod[d]) + (thisDetector->gappixels * thisDetector->nGappixels[d]); + return (thisDetector->nChan[d] * thisDetector->nChip[d] + thisDetector->gappixels * thisDetector->nGappixels[d]) * thisDetector->nMod[d]; } @@ -1809,7 +1796,7 @@ int slsDetector::getMaxNumberOfChannelsInclGapPixels(dimension d) { if (d==X) return 36*thisDetector->nChip[d]*thisDetector->nModMax[d]; else return 1*thisDetector->nChip[d]*thisDetector->nModMax[d]; } - return (thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nModMax[d]) + (thisDetector->gappixels * thisDetector->nGappixels[d]); + return (thisDetector->nChan[d] * thisDetector->nChip[d] + thisDetector->gappixels * thisDetector->nGappixels[d]) * thisDetector->nModMax[d]; } /* needed to set/get the size of the detector */ @@ -1892,19 +1879,23 @@ int slsDetector::setNumberOfModules(int n, dimension d){ dr=32; thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*dr/8; - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y) *dr/8; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + thisDetector->dynamicRange/8; if(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->timerValue[PROBES_NUMBER]!=0) { thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y) *4; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + 4; } } if(thisDetector->myDetectorType==JUNGFRAUCTB){ getTotalNumberOfChannels(); - //thisDetector->dataBytes=getTotalNumberOfChannels()*thisDetector->nChans*dr/8*thisDetector->nChips*thisDetector->timerValue[SAMPLES_JCTB]; - } @@ -2061,13 +2052,19 @@ int slsDetector::enableGapPixels(int val) { thisDetector->dataBytesInclGapPixels = 0; if (thisDetector->dynamicRange != 4) { - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y) * (thisDetector->dynamicRange/8); - // set data bytes for other detector ( for future use) + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + thisDetector->dynamicRange/8; + // set data bytes for other detector ( for future use) if(thisDetector->myDetectorType==JUNGFRAUCTB) getTotalNumberOfChannels(); - if(thisDetector->myDetectorType==MYTHEN){ + else if(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) { - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y) * thisDetector->nChans*4; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + 4; } } } @@ -5155,7 +5152,10 @@ int slsDetector::setDynamicRange(int n){ thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*retval/8; - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y)*retval/8; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + thisDetector->dynamicRange/8; if (thisDetector->myDetectorType==JUNGFRAUCTB) { // thisDetector->nChip[X]=retval/16; @@ -5168,7 +5168,10 @@ int slsDetector::setDynamicRange(int n){ if(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->timerValue[PROBES_NUMBER]!=0) { thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; - thisDetector->dataBytesInclGapPixels = getTotalNumberOfChannelsInclGapPixels(X)*getTotalNumberOfChannelsInclGapPixels(Y)*4; + thisDetector->dataBytesInclGapPixels = + (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + 4; } if (retval==32) diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 035226c6a..1ef903b0b 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -114,7 +114,7 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int nModMax[2]; /** maximum number of modules (nModMax[X]*nModMax[Y]) \see nModMax */ int nModsMax; - /** number of channels per chip (used mainly in databytes calculation) */ + /** number of channels per chip */ int nChans; /** number of channels per chip in one direction */ int nChan[2]; @@ -664,7 +664,7 @@ class slsDetector : public slsDetectorUtils, public energyConversion { /** Returns the number of modules in direction d (without connecting to the detector) */ int getNMod(dimension d){return thisDetector->nMod[d];}; // - int getChansPerMod(int imod=0){return thisDetector->nChan[X]*thisDetector->nChan[Y]*thisDetector->nChips;}; + int getChansPerMod(int imod=0){return thisDetector->nChans*thisDetector->nChips;}; int getChansPerMod( dimension d,int imod=0){return thisDetector->nChan[d]*thisDetector->nChip[d];}; From bd228fac275969f3c8ce6d2f5b25d0493a02210f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Mon, 20 Nov 2017 17:19:03 +0100 Subject: [PATCH 15/15] bug fix in cleanup code, indexing --- .../slsDetector/slsDetector.cpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 62bf74342..168df8fa9 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -717,8 +717,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { // calculating databytes (special when with gap pixels, jctb, mythen in 24bit mode or using probes) thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*thisDetector->dynamicRange/8; thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * thisDetector->dynamicRange/8; if(thisDetector->myDetectorType==JUNGFRAUCTB){ @@ -728,8 +728,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) { thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * 4; } } @@ -1880,16 +1880,16 @@ int slsDetector::setNumberOfModules(int n, dimension d){ thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*dr/8; thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * thisDetector->dynamicRange/8; if(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->timerValue[PROBES_NUMBER]!=0) { thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * 4; } } @@ -2053,8 +2053,8 @@ int slsDetector::enableGapPixels(int val) { if (thisDetector->dynamicRange != 4) { thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * thisDetector->dynamicRange/8; // set data bytes for other detector ( for future use) if(thisDetector->myDetectorType==JUNGFRAUCTB) @@ -2062,8 +2062,8 @@ int slsDetector::enableGapPixels(int val) { else if(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) { thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * 4; } } @@ -5153,8 +5153,8 @@ int slsDetector::setDynamicRange(int n){ thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*retval/8; thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * thisDetector->dynamicRange/8; if (thisDetector->myDetectorType==JUNGFRAUCTB) { @@ -5169,8 +5169,8 @@ int slsDetector::setDynamicRange(int n){ if (thisDetector->timerValue[PROBES_NUMBER]!=0) { thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; thisDetector->dataBytesInclGapPixels = - (thisDetector->nMod[X] * thisDetector->nChips[X] * thisDetector->nChans[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * - (thisDetector->nMod[Y] * thisDetector->nChips[Y] * thisDetector->nChans[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * + (thisDetector->nMod[X] * thisDetector->nChip[X] * thisDetector->nChan[X] + thisDetector->gappixels * thisDetector->nGappixels[X]) * + (thisDetector->nMod[Y] * thisDetector->nChip[Y] * thisDetector->nChan[Y] + thisDetector->gappixels * thisDetector->nGappixels[Y]) * 4; }