diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 45d13c716..cce136b8c 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -153,6 +153,7 @@ class Detector(CppDetectorApi): @property def rx_version(self): + """Receiver version in format [0xYYMMDD].""" return element_if_equal(self.getReceiverVersion()) @property @@ -337,11 +338,11 @@ class Detector(CppDetectorApi): self.startDetector() def rx_start(self): - """Start receiver""" + """Starts receiver listener for detector data packets and create a data file (if file write enabled).""" self.startReceiver() def rx_stop(self): - """Stop receiver""" + """Stops receiver listener for detector data packets and closes current data file (if file write enabled).""" self.stopReceiver() def stop(self): @@ -351,6 +352,7 @@ class Detector(CppDetectorApi): # Time @property def rx_framescaught(self): + """Number of frames caught by receiver.""" return element_if_equal(self.getFramesCaught()) @property @@ -369,6 +371,24 @@ class Detector(CppDetectorApi): @property def rx_hostname(self): + """ Sets receiver hostname or IP address. Used for TCP control communication between client and receiver to configure receiver. Also updates receiver with detector parameters. + Notes + ----- + Also resets any prior receiver property (not on detector). \n + Can concatenate receiver hostnames for every module. \n + If port included, then its the receiver tcp port for every receiver hostname. + Example + -------- + >>> d.rx_hostname + 'mpc1922' + >>> d.rx_hostname = 'mpc1922' + >>> d.rx_hostname = 'mpc1922:2000' + >>> d.rx_hostname = 'mpc1922:2000+mpc1922:2002' + >>> d.rx_hostname + 'mpc1922' + >>> d.rx_tcpport + [2000, 2002] + """ return element_if_equal(self.getRxHostname()) @rx_hostname.setter @@ -377,6 +397,21 @@ class Detector(CppDetectorApi): @property def rx_tcpport(self): + """ + TCP port for client-receiver communication. + Notes + ----- + Default is 1954. \n + Must be different if multiple receivers on same pc. \n + Must be first command to set a receiver parameter to be able to communicate. \n + Multi command will automatically increment port for individual modules, which must be set via setRxPort. + Example + ------- + >>> d.rx_tcpport + 2010 + >>> d.rx_tcpport + [2000, 2002] + """ return element_if_equal(self.getRxPort()) @rx_tcpport.setter @@ -385,6 +420,7 @@ class Detector(CppDetectorApi): @property def rx_fifodepth(self): + """Sets the number of frames in the receiver fifo depth (buffer between listener and writer threads).""" return element_if_equal(self.getRxFifoDepth()) @rx_fifodepth.setter @@ -393,6 +429,7 @@ class Detector(CppDetectorApi): @property def rx_silent(self): + """When enabled, switches off receiver text output during acquisition. """ return element_if_equal(self.getRxSilentMode()) @rx_silent.setter @@ -401,6 +438,20 @@ class Detector(CppDetectorApi): @property def rx_discardpolicy(self): + """ + Frame discard policy of receiver. Enum: frameDiscardPolicy + Notes + ----- + Options: NO_DISCARD, DISCARD_EMPTY_FRAMES, DISCARD_PARTIAL_FRAMES \n + Default: NO_DISCARD \n + DISCARD_PARTIAL_FRAMES is the fastest. + + Example + -------- + >>> d.rx_discardpolicy = slsdet.frameDiscardPolicy.NO_DISCARD + >>> d.rx_discardpolicy + frameDiscardPolicy.NO_DISCARD + """ return element_if_equal(self.getRxFrameDiscardPolicy()) @rx_discardpolicy.setter @@ -409,6 +460,12 @@ class Detector(CppDetectorApi): @property def rx_padding(self): + """Partial frames padding enable in the receiver. + Notes + ------ + Default: enabled \n + Disabling is fastest. + """ return element_if_equal(self.getPartialFramesPadding()) @rx_padding.setter @@ -426,6 +483,7 @@ class Detector(CppDetectorApi): @property def rx_lastclient(self): + """Client IP Address that last communicated with the receiver.""" return element_if_equal(self.getRxLastClientIP()) # FILE @@ -448,10 +506,12 @@ class Detector(CppDetectorApi): @property def fformat(self): - """ File format of data file in receiver. + """ File format of data file in receiver. Enum: fileFormat Note ----- + Options: BINARY, HDF5 + Default: BINARY For HDF5, package must be compiled with HDF5 flags. Default is binary. Example @@ -541,6 +601,13 @@ class Detector(CppDetectorApi): @property def rx_framesperfile(self): + """Sets the number of frames per file in receiver. + + Notes + ----- + Default: depends on detector type. \n + 0 is infinite or all frames in single file. + """ return element_if_equal(self.getFramesPerFile()) @rx_framesperfile.setter @@ -565,6 +632,13 @@ class Detector(CppDetectorApi): @property def rx_readfreq(self): + """Frequency of frames streamed out from receiver via zmq. + Notes + ----- + Default: 1, Means every frame is streamed out. \n + If 2, every second frame is streamed out. \n + If 0, streaming timer is the timeout, after which current frame is sent out. (default timeout is 200 ms). Usually used for gui purposes. + """ return element_if_equal(self.getRxZmqFrequency()) @rx_readfreq.setter @@ -573,6 +647,21 @@ class Detector(CppDetectorApi): @property def rx_zmqport(self): + """ + Zmq port for data to be streamed out of the receiver. + Notes + ----- + Also restarts receiver zmq streaming if enabled. \n + Default is 30001. \n + Modified only when using an intermediate process after receiver. \n + Must be different for every detector (and udp port). \n + Multi command will automatically increment for individual modules, use setRxZmqPort. + Exmaples + -------- + >>> d.rx_zmqport + [30001, 30002, 30003, 300004] + >>> d.rx_zmqport = ????? + """ return element_if_equal(self.getRxZmqPort()) @rx_zmqport.setter @@ -589,6 +678,20 @@ class Detector(CppDetectorApi): @property def rx_zmqip(self): + """ + Zmq Ip Address from which data is to be streamed out of the receiver. + Notes + ----- + Also restarts receiver zmq streaming if enabled. \n + Default is from rx_hostname. \n + Modified only when using an intermediate process after receiver. + + Example + ------- + >>> d.rx_zmqip + 192.168.0.101 + >>> d.rx_zmqip = ????? + """ return element_if_equal(self.getRxZmqIP()) @rx_zmqip.setter @@ -737,10 +840,18 @@ class Detector(CppDetectorApi): @property def rx_status(self): + """Gets receiver listener status. Enum: runStatus + Notes + ----- + Options: IDLE, TRANSMITTING, RUNNING + >>> d.rx_status + runStatus.IDLE + """ return element_if_equal(self.getReceiverStatus()) @property def rx_udpsocksize(self): + """UDP socket buffer size in receiver. Tune rmem_default and rmem_max accordingly.""" return element_if_equal(self.getRxUDPSocketBufferSize()) @rx_udpsocksize.setter @@ -749,6 +860,7 @@ class Detector(CppDetectorApi): @property def rx_realudpsocksize(self): + """Gets actual udp socket buffer size. Double the size of rx_udpsocksize due to kernel bookkeeping.""" return element_if_equal(self.getRxRealUDPSocketBufferSize()) @property @@ -771,6 +883,7 @@ class Detector(CppDetectorApi): @property def rx_lock(self): + """Lock receiver to one client IP, 1 locks, 0 unlocks. Default is unlocked.""" return element_if_equal(self.getRxLock()) @rx_lock.setter @@ -928,10 +1041,12 @@ class Detector(CppDetectorApi): @property def rx_frameindex(self): + """Current frame index received in receiver during acquisition.""" return element_if_equal(self.getRxCurrentFrameIndex()) @property def rx_missingpackets(self): + """Gets the number of missing packets for each port in receiver.""" return element_if_equal(self.getNumMissingPackets()) """ @@ -1220,7 +1335,12 @@ class Detector(CppDetectorApi): @property def romode(self): """ - [CTB] Readout mode. Default is analog. Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL + [CTB] Readout mode of detector. Enum: readoutMode + + Notes + ------ + Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL + Default: ANALOG_ONLY Examples -------- @@ -1319,6 +1439,7 @@ class Detector(CppDetectorApi): @property def rx_dbitoffset(self): + """[Ctb] Offset in bytes in digital data to skip in receiver.""" return element_if_equal(self.getRxDbitOffset()) @rx_dbitoffset.setter diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index ffc3c9849..92064b6a7 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -408,10 +408,12 @@ class Detector { * acquisition */ void clearAcquiringFlag(); - /** Non Blocking: Start receiver listener*/ + /** Non Blocking: Start receiver listener and create data file if file write + * enabled */ void startReceiver(); - /** Non Blocking: Stop receiver listener */ + /** Non Blocking: Stops receiver listener for detector data packets and + closes current data file (if file write enabled). */ void stopReceiver(); /** Non blocking: start detector acquisition @@ -421,12 +423,15 @@ class Detector { /** Non blocking: abort detector acquisition */ void stopDetector(); + /** IDLE, ERROR, WAITING, RUN_FINISHED, TRANSMITTING, RUNNING, STOPPED */ Result getDetectorStatus(Positions pos = {}) const; + /** Options: IDLE, TRANSMITTING, RUNNING */ Result getReceiverStatus(Positions pos = {}) const; Result getFramesCaught(Positions pos = {}) const; + /** Gets the number of missing packets for each port in receiver. */ Result> getNumMissingPackets(Positions pos = {}) const; @@ -610,22 +615,24 @@ class Detector { Result getRxHostname(Positions pos = {}) const; /** - * Validates and sets the receiver. - * Updates local receiver cache parameters - * Configures the detector to the receiver as UDP destination - * receiver is receiver hostname or IP address, can include tcp port eg. - * hostname:port + * Sets receiver hostname or IP address for each module. \n Used for TCP + * control communication between client and receiver to configure receiver. + * Also updates receiver with detector parameters. \n Also resets any prior + * receiver property (not on detector). \n receiver is receiver hostname or + * IP address, can include tcp port eg. hostname:port */ void setRxHostname(const std::string &receiver, Positions pos = {}); - /** multiple rx hostnames (same as setRxHostname) */ + /** multiple rx hostnames. Single element will set it for all */ void setRxHostname(const std::vector &name); Result getRxPort(Positions pos = {}) const; - /** Receiver TCP port (for client communication with Receiver) - * module_id is -1 for all detectors, ports for each module is calculated - * (increments) */ + /** TCP port for client-receiver communication. \n + * Default is 1954. \n Must be different if multiple receivers on same pc. + * \n Must be first command to set a receiver parameter to be able to + * communicate. \n Multi command will automatically increment port for + * individual modules.*/ void setRxPort(int port, int module_id = -1); Result getRxFifoDepth(Positions pos = {}) const; @@ -635,15 +642,15 @@ class Detector { Result getRxSilentMode(Positions pos = {}) const; - /** receiver prints hardly any information while acquiring */ + /** Switch on or off receiver text output during acquisition */ void setRxSilentMode(bool value, Positions pos = {}); Result getRxFrameDiscardPolicy(Positions pos = {}) const; /** - * default NO_DISCARD * Options: NO_DISCARD, DISCARD_EMPTY_FRAMES, DISCARD_PARTIAL_FRAMES + * Default: NO_DISCARD * discard partial frames is the fastest */ void setRxFrameDiscardPolicy(defs::frameDiscardPolicy f, @@ -651,22 +658,28 @@ class Detector { Result getPartialFramesPadding(Positions pos = {}) const; - /** padding enabled. Disabling padding is the fastest */ + /** Default: padding enabled. Disabling padding is the fastest */ void setPartialFramesPadding(bool value, Positions pos = {}); Result getRxUDPSocketBufferSize(Positions pos = {}) const; + /** UDP socket buffer size in receiver. Tune rmem_default and rmem_max + * accordingly */ void setRxUDPSocketBufferSize(int64_t udpsockbufsize, Positions pos = {}); + /** TODO: - * Linux kernel allocates twice the amount you set for bookkeeping purposes + * Gets actual udp socket buffer size. Double the size of rx_udpsocksize due + * to kernel bookkeeping. */ Result getRxRealUDPSocketBufferSize(Positions pos = {}) const; Result getRxLock(Positions pos = {}); - /** locks receiver server to client IP */ + /** Lock receiver to one client IP, 1 locks, 0 unlocks. Default is unlocked. + */ void setRxLock(bool value, Positions pos = {}); + /** Client IP Address that last communicated with the receiver */ Result getRxLastClientIP(Positions pos = {}) const; Result> @@ -718,7 +731,8 @@ class Detector { Result getFramesPerFile(Positions pos = {}) const; - /** 0 will set frames per file to unlimited */ + /** Default depends on detector type. \n 0 will set frames per file to + * unlimited */ void setFramesPerFile(int n, Positions pos = {}); /************************************************** @@ -741,12 +755,11 @@ class Detector { Result getRxZmqFrequency(Positions pos = {}) const; - /** freq is nth frame streamed out of receiver. - * If 0, streaming timer is the timeout, - * after which current frame sent out. Default is 0 at 200 ms. - * Default is 1: send every frame. - * If you want just to see some frames for gui purposes, set to 0 (200ms - * default timer). + /** Frequency of frames streamed out from receiver via zmq. \n Default: 1, + * Means every frame is streamed out. \n If 2, every second frame is + * streamed out. \n If 0, streaming timer is the timeout, after which + * current frame is sent out. (default timeout is 200 ms). Usually used for + * gui purposes. */ void setRxZmqFrequency(int freq, Positions pos = {}); @@ -769,14 +782,21 @@ class Detector { Result getRxZmqPort(Positions pos = {}) const; - /** - * module_id is -1 for all detectors, ports for each module is calculated - * (increments) Restarts receiver zmq sockets only if it was already enabled + /** Zmq port for data to be streamed out of the receiver. \n + * Also restarts receiver zmq streaming if enabled. \n Default is 30001. \n + * Modified only when using an intermediate process after receiver. \n Must + * be different for every detector (and udp port). \n module_id is -1 for + * all detectors, ports for each module is calculated (increments) Restarts + * receiver zmq sockets only if it was already enabled */ void setRxZmqPort(int port, int module_id = -1); Result getRxZmqIP(Positions pos = {}) const; + /** Zmq Ip Address from which data is to be streamed out of the receiver. \n + * Also restarts receiver zmq streaming if enabled. \n Default is from + * rx_hostname. \n Modified only when using an intermediate process between + * receiver. */ void setRxZmqIP(const IpAddr ip, Positions pos = {}); Result getClientZmqPort(Positions pos = {}) const; diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 5a155f02f..ce5554045 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -970,7 +970,8 @@ std::string CmdProxy::ReceiverStatus(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "running, idle]\n\tReceiver listener status." << '\n'; + os << "running, idle, transmitting]\n\tReceiver listener status." + << '\n'; } else if (action == defs::GET_ACTION) { if (!args.empty()) { WrongNumberOfParameters(0); @@ -1149,7 +1150,7 @@ std::string CmdProxy::UDPDestinationIP2(int action) { } /* Receiver Config */ -std::string CmdProxy::ReceiveHostname(int action) { +std::string CmdProxy::ReceiverHostname(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { @@ -1160,7 +1161,8 @@ std::string CmdProxy::ReceiveHostname(int action) { "tcp port.\n\t" "Used for TCP control communication between client and receiver " "to configure receiver. Also updates receiver with detector " - "parameters." + "parameters. Also resets any prior receiver property (not on " + "detector). " << '\n'; } else if (action == defs::GET_ACTION) { if (!args.empty()) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 29dd50221..169b81672 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -812,7 +812,7 @@ class CmdProxy { {"txndelay_right", &CmdProxy::txndelay_right}, /* Receiver Config */ - {"rx_hostname", &CmdProxy::ReceiveHostname}, + {"rx_hostname", &CmdProxy::ReceiverHostname}, {"rx_tcpport", &CmdProxy::rx_tcpport}, {"rx_fifodepth", &CmdProxy::rx_fifodepth}, {"rx_silent", &CmdProxy::rx_silent}, @@ -1046,7 +1046,7 @@ class CmdProxy { std::string UDPDestinationIP(int action); std::string UDPDestinationIP2(int action); /* Receiver Config */ - std::string ReceiveHostname(int action); + std::string ReceiverHostname(int action); /* File */ /* ZMQ Streaming Parameters (Receiver<->Client) */ /* Eiger Specific */ @@ -1751,7 +1751,7 @@ class CmdProxy { INTEGER_COMMAND(rx_fifodepth, getRxFifoDepth, setRxFifoDepth, StringTo, "[n_frames]\n\tSet the number of frames in the receiver " - "fifo (buffer between listener and writer threads)."); + "fifo depth (buffer between listener and writer threads)."); INTEGER_COMMAND( rx_silent, getRxSilentMode, setRxSilentMode, StringTo, @@ -1768,21 +1768,21 @@ class CmdProxy { INTEGER_COMMAND(rx_padding, getPartialFramesPadding, setPartialFramesPadding, StringTo, "[0, 1]\n\tPartial frames padding enable in the " - "receiver. 0 does not pad partial frames(fastest), 1 " - "(default) pads partial frames"); + "receiver. Default: enabled. Disabling is fastest."); INTEGER_COMMAND( rx_udpsocksize, getRxUDPSocketBufferSize, setRxUDPSocketBufferSize, StringTo, "[n_size]\n\tUDP socket buffer size in receiver. Tune rmem_default and " - "rmem_max accordingly. rx_hostname sets it to defaults."); + "rmem_max accordingly."); GET_COMMAND(rx_realudpsocksize, getRxRealUDPSocketBufferSize, "\n\tActual udp socket buffer size. Double the size of " "rx_udpsocksize due to kernel bookkeeping."); INTEGER_COMMAND(rx_lock, getRxLock, setRxLock, StringTo, - "[0, 1]\n\tLock receiver to one IP, 1: locks"); + "[0, 1]\n\tLock receiver to one client IP, 1 locks, 0 " + "unlocks. Default is unlocked. 1: locks"); GET_COMMAND( rx_lastclient, getRxLastClientIP, @@ -1848,8 +1848,11 @@ class CmdProxy { INTEGER_COMMAND( rx_readfreq, getRxZmqFrequency, setRxZmqFrequency, StringTo, - "[nth frame]\n\tStream out every nth frame. Default is 1. 0 means " - "streaming every 200 ms and discarding frames in this interval."); + "[nth frame]\n\tFrequency of frames streamed out from receiver via " + "zmq\n\tDefault: 1, Means every frame is streamed out. \n\tIf 2, every " + "second frame is streamed out. \n\tIf 0, streaming timer is the " + "timeout, after which current frame is sent out. (default timeout is " + "200 ms). Usually used for gui purposes."); INTEGER_COMMAND(rx_zmqstartfnum, getRxZmqStartingFrame, setRxZmqStartingFrame, StringTo, @@ -1880,7 +1883,7 @@ class CmdProxy { "[x.x.x.x]\n\tZmq Ip Address from which data is to be streamed out of " "the receiver. Also restarts receiver zmq streaming if enabled. " "Default is from rx_hostname. Modified only when using an intermediate " - "process between receiver and client(gui)."); + "process between receiver."); INTEGER_COMMAND( zmqip, getClientZmqIp, setClientZmqIp, IpAddr, @@ -2162,9 +2165,10 @@ class CmdProxy { "[0-63]\n\t[Ctb] Sampling source signal for digital data. " "For advanced users only."); - INTEGER_COMMAND( - rx_dbitoffset, getRxDbitOffset, setRxDbitOffset, StringTo, - "[n_bytes]\n\t[Ctb] Offset in bytes in digital data in receiver."); + INTEGER_COMMAND(rx_dbitoffset, getRxDbitOffset, setRxDbitOffset, + StringTo, + "[n_bytes]\n\t[Ctb] Offset in bytes in digital data to " + "skip in receiver."); INTEGER_COMMAND(led, getLEDEnable, setLEDEnable, StringTo, "[0, 1]\n\t[Ctb] Switches on/off all LEDs."); @@ -2267,8 +2271,9 @@ class CmdProxy { "CTB] Timestamp at a frame start." "\n\t[Gotthard2] only in continuous mode."); - GET_COMMAND(rx_frameindex, getRxCurrentFrameIndex, - "\n\tCurrent frame index received in receiver."); + GET_COMMAND( + rx_frameindex, getRxCurrentFrameIndex, + "\n\tCurrent frame index received in receiver during acquisition."); }; } // namespace sls diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 91f5001b3..08300c353 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1607,6 +1607,8 @@ Result Detector::getReadoutMode(Positions pos) const { return pimpl->Parallel(&Module::getReadoutMode, pos); } +/** Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL \n + * Default: ANALOG_ONLY */ void Detector::setReadoutMode(defs::readoutMode value, Positions pos) { pimpl->Parallel(&Module::setReadoutMode, pos, value); }