diff --git a/python/slsdet/__init__.py b/python/slsdet/__init__.py index 517c0f48d..f6df36332 100755 --- a/python/slsdet/__init__.py +++ b/python/slsdet/__init__.py @@ -10,7 +10,7 @@ from .gotthard import Gotthard from .moench import Moench import _slsdet - +xy = _slsdet.xy defs = _slsdet.slsDetectorDefs from .enums import * diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 53f20f977..ed0c8a519 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -10,6 +10,7 @@ detectorType = slsDetectorDefs.detectorType from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask from .utils import Geometry, to_geo, element, reduce_time, is_iterable +from _slsdet import xy from . import utils as ut from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy from .registers import Register, Adc_register @@ -131,7 +132,15 @@ class Detector(CppDetectorApi): @property def hostname(self): - """Frees shared memory and sets hostname (or IP address) of all modules concatenated by + """ + """Frees shared memory and sets hostname (or IP address) of all modules concatenated by + + Virtual servers can already use the port in hostname separated by ':' and ports incremented by 2 to accomodate the stop server as well. + Example + ------- + >>> d.hostname = 'beb031+beb032+' + >>> d.hostname = 'localhost:1912+localhost:1914+' + >>> d.hostname + ['localhost'] + """ return self.getHostname() @hostname.setter @@ -165,16 +174,35 @@ class Detector(CppDetectorApi): @property def firmwareversion(self): + """ + Fimware version of detector in format [0xYYMMDD] or an increasing 2 digit number for Eiger. + Example + ------- + >>> hex(d.firmwareversion) + '0x200910' + """ return element_if_equal(self.getFirmwareVersion()) @property def detectorserverversion(self): + """ + On-board detector server software version in format [0xYYMMDD] + Example + ------- + >>> hex(d.detectorserverversion) + '0x200910' + """ # TODO! handle hex print return element_if_equal(self.getDetectorServerVersion()) @property def clientversion(self): - """Client software version in format [YYMMDD]""" + """Client software version in format [YYMMDD] + Example + ------- + >>> hex(d.clientversion) + '0x200810' + """ return self.getClientVersion() @property @@ -206,6 +234,7 @@ class Detector(CppDetectorApi): @property def drlist(self): + """List of possible dynamic ranges for this detector""" return self.getDynamicRangeList() @property @@ -219,8 +248,28 @@ class Detector(CppDetectorApi): @property def detsize(self): + """ + Sets the detector size in both dimensions (number of channels). + Note + ----- + This value is used to calculate row and column positions for each module and included into udp data packet header. \n + By default, it adds modules in y dimension for 2d detectors and in x dimension for 1d detectors. + Example + ------- + >>> d.detsize + Geometry(x=3840, y=1) + >>> d.detsize = [1024, 512] + Geometry(x=1024, y = 512) + """ return to_geo(self.getDetectorSize()) + @detsize.setter + def detsize(self, size): + if isinstance(size, xy): + self.setDetectorSize(size) + else: + self.setDetectorSize(xy(*size)) + @property def settings(self): """ @@ -247,8 +296,8 @@ class Detector(CppDetectorApi): Note ----- - Cannot be set in modular level. ???? - In scan mode, number of frames is set to number of steps. + Cannot be set in modular level. \n + In scan mode, number of frames is set to number of steps. \n [Gotthard2] Burst mode has a maximum of 2720 frames. """ return element_if_equal(self.getNumberOfFrames()) @@ -260,6 +309,10 @@ class Detector(CppDetectorApi): @property @element def framesl(self): + """ + [Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench] Number of frames left in acquisition.\n + [Gotthard2] only in continuous mode. + """ return self.getNumberOfFramesLeft() @property @@ -393,9 +446,9 @@ class Detector(CppDetectorApi): Example ----------- - >>> d.delay + >>> d.delayl 181.23 - >>> d.getDelayAfterTrigger() + >>> d.getDelayAfterTriggerLeft() [datetime.timedelta(seconds=181, microseconds=230000)] """ return ut.reduce_time(self.getDelayAfterTriggerLeft()) @@ -623,7 +676,11 @@ class Detector(CppDetectorApi): @property @element def findex(self): - """File or Acquisition index in receiver.""" + """File or Acquisition index in receiver. + Note + ---- + File name: [file name prefix]_d[detector index]_f[sub file index]_[acquisition/file index].[raw/h5]. + """ return self.getAcquisitionIndex() @findex.setter @@ -651,8 +708,7 @@ class Detector(CppDetectorApi): @property def fpath(self): - """Directory where output data files are written in receiver. - + """Directory where output data files are written in receiver. Default is "/". Note ---- If path does not exist, it will try to create it. @@ -1225,7 +1281,7 @@ class Detector(CppDetectorApi): def dacvalues(self): """Gets the dac values for every dac for this detector.""" return { - dac.name.lower(): np.array(self.getDAC(dac, False)) + dac.name.lower(): element_if_equal(np.array(self.getDAC(dac, False))) for dac in self.getDacList() } @@ -1264,6 +1320,11 @@ class Detector(CppDetectorApi): @property @element def adcinvert(self): + """[Ctb][Moench][Jungfrau] ADC Inversion Mask. + Note + ----- + [Jungfrau][Moench] Inversions on top of the default mask. + """ return self.getADCInvert() @adcinvert.setter @@ -1831,6 +1892,7 @@ class Detector(CppDetectorApi): @property @element def bursts(self): + """[Gotthard2] Number of bursts per aquire. Only in auto timing mode and burst mode.""" return self.getNumberOfBursts() @bursts.setter @@ -1840,6 +1902,11 @@ class Detector(CppDetectorApi): @property @element def filter(self): + """[Gotthard2] Set filter resistor. + Note + ---- + Default is 0. Options: 0-3. + """ return self.getFilter() @filter.setter @@ -1878,6 +1945,7 @@ class Detector(CppDetectorApi): @property @element def cdsgain(self): + """[Gotthard2] Enable or disable CDS gain. Default is disabled. """ return self.getCDSGain() @cdsgain.setter @@ -1888,6 +1956,11 @@ class Detector(CppDetectorApi): @property @element def burstmode(self): + """[Gotthard2] Burst mode of detector. Enum: burstMode + Note + ---- + BURST_INTERNAL (default), BURST_EXTERNAL, CONTINUOUS_INTERNAL, CONTINUOUS_EXTERNAL + """ return self.getBurstMode() @burstmode.setter @@ -1896,6 +1969,22 @@ class Detector(CppDetectorApi): @property def burstperiod(self): + """ + [Gotthard2] Period between 2 bursts. Only in burst mode and auto timing mode. + Note + ----- + :getter: always returns in seconds. To get in datetime.delta, use getBurstPeriod + + Example + ----------- + >>> d.burstperiod = 1.05 + >>> d.burstperiod = datetime.timedelta(minutes = 3, seconds = 1.23) + >>> d.burstperiod + 181.23 + >>> d.getBurstPeriod() + [datetime.timedelta(seconds=181, microseconds=230000)] + + """ return ut.reduce_time(self.getBurstPeriod()) @burstperiod.setter @@ -2031,6 +2120,7 @@ class Detector(CppDetectorApi): @property @element def adcenable(self): + """[Ctb][Moench] ADC Enable Mask for 1Gb. Enable for each 32 ADC channel.""" return self.getADCEnableMask() @adcenable.setter @@ -2040,6 +2130,10 @@ class Detector(CppDetectorApi): @property @element def adcenable10g(self): + """[Ctb][Moench] ADC Enable Mask for 10Gb mode for each 32 ADC channel. + Note + ----- + If any of a consecutive 4 bits are enabled, the complete 4 bits are enabled.""" return self.getTenGigaADCEnableMask() @adcenable10g.setter @@ -2603,6 +2697,19 @@ class Detector(CppDetectorApi): @property def clkdiv(self): + """ + [Gotthard2][Mythen3] Clock Divider of 5 clocks. Must be greater than 1. + Example + ------- + >>> d.clkdiv[0] = 20 + >>> d.clkdiv + 0: 20 + 1: 10 + 2: 20 + 3: 10 + 4: 10 + 5: 5 + """ return ClkDivProxy(self) @@ -2612,6 +2719,18 @@ class Detector(CppDetectorApi): @property def exptimel(self): + """[Gotthard] Exposure time left for current frame. + Note + ----- + :getter: always returns in seconds. To get in datetime.delta, use getExptimeLeft + + Example + ----------- + >>> d.exptimel + 181.23 + >>> d.getExptimeLeft() + [datetime.timedelta(seconds=181, microseconds=230000)] + """ t = self.getExptimeLeft() return reduce_time(t) @@ -2623,6 +2742,7 @@ class Detector(CppDetectorApi): @property @element def gates(self): + """[Mythen3] Number of external gates in gating or trigger_gating mode (external gating).""" return self.getNumberOfGates() @gates.setter @@ -2632,6 +2752,16 @@ class Detector(CppDetectorApi): @property def clkfreq(self): + """ + [Gotthard2][Mythen3] Frequency of clock in Hz. + Note + ----- + :setter: Not implemented. Use clkdiv to set frequency + Example + ------- + >>> d.clkfreq[0] + 50000000 + """ return ClkFreqProxy(self) """ @@ -2640,6 +2770,14 @@ class Detector(CppDetectorApi): @property def initialchecks(self): + """ + Enable or disable intial compatibility and other checks at detector start up. + Note + ---- + It is enabled by default. Must come before 'hostname' command to take effect. \n + Can be used to reprogram fpga when current firmware is incompatible. \n + Advanced user function! + """ return self.getInitialChecks() @initialchecks.setter diff --git a/python/slsdet/utils.py b/python/slsdet/utils.py index 687063bda..24ba172e6 100755 --- a/python/slsdet/utils.py +++ b/python/slsdet/utils.py @@ -41,7 +41,7 @@ def to_geo(value): if isinstance(value, _slsdet.xy): return Geometry(x = value.x, y = value.y) else: - raise ValueError("Can only convert sls_detector.xy") + raise ValueError("Can only convert slsdet.xy") def all_equal(mylist): """If all elements are equal return true otherwise false""" diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 817fdccf5..fba922b86 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -4223,6 +4223,7 @@ int copy_detector_server(int file_des) { strcat(cmd, sname); executeCommand(cmd, retvals, logDEBUG1); +#if !defined(GOTTHAR2D) && !defined(MYTHEN3D) // edit /etc/inittab // find line numbers in /etc/inittab where DetectorServer strcpy(cmd, "sed -n '/DetectorServer/=' /etc/inittab"); @@ -4247,6 +4248,7 @@ int copy_detector_server(int file_des) { executeCommand(cmd, retvals, logDEBUG1); LOG(logINFO, ("/etc/inittab modified to have %s\n", sname)); +#endif } } #endif diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index 7cf67d811..d05230cab 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -58,7 +58,7 @@ class Detector { Result getHostname(Positions pos = {}) const; - /**Frees shared memory, adds detectors to the list */ + /**Frees shared memory, adds detectors to the list. */ void setHostname(const std::vector &hostname); /** connects to n servers at local host starting at specific control port */ @@ -98,8 +98,10 @@ class Detector { defs::xy getDetectorSize() const; /** - * Sets the detector size in both dimensions. \n - * This value is used to calculate row and column positions for each module. + * Sets the detector size in both dimensions (number of channels). \n + * This value is used to calculate row and column positions for each module + * and included into udp data packet header. \n By default, it adds modules + * in y dimension for 2d detectors and in x dimension for 1d detectors. */ void setDetectorSize(const defs::xy value); @@ -183,7 +185,8 @@ class Detector { Result getNumberOfFrames(Positions pos = {}) const; /** In trigger mode, number of frames per trigger. In scan mode, number of - * frames is set to number of steps */ + * frames is set to number of steps \n [Gotthard2] Burst mode has a maximum + * of 2720 frames. */ void setNumberOfFrames(int64_t value); Result getNumberOfTriggers(Positions pos = {}) const; @@ -228,8 +231,8 @@ class Detector { Result getDynamicRange(Positions pos = {}) const; /** - * [Eiger] Options: 4, 8, 16, 32. If i is 32, also sets clkdivider to 2, if - * 16, sets clkdivider to 1 \n [Mythen3] Options: 8, 16, 32 \n + * [Eiger] Options: 4, 8, 16, 32. If i is 32, also sets clkdivider to 2, + * else sets clkdivider to 1 \n [Mythen3] Options: 8, 16, 32 \n * [Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16 */ void setDynamicRange(int value); @@ -313,7 +316,7 @@ class Detector { /** [Mythen3][Gotthard2] */ Result getClockPhase(int clkIndex, Positions pos = {}); - /** [Mythen3][Gotthard2] */ + /** [Mythen3][Gotthard2] absolute phase shift */ void setClockPhase(int clkIndex, int value, Positions pos = {}); /** [Mythen3][Gotthard2] */ @@ -328,7 +331,7 @@ class Detector { /** [Mythen3][Gotthard2] */ Result getClockDivider(int clkIndex, Positions pos = {}); - /** [Mythen3][Gotthard2] */ + /** [Mythen3][Gotthard2] Must be greater than 1. */ void setClockDivider(int clkIndex, int value, Positions pos = {}); Result getHighVoltage(Positions pos = {}) const; @@ -350,9 +353,9 @@ class Detector { Result getImageTestMode(Positions pos = {}); /** [Gotthard] If 1, adds channel intensity with precalculated values. - * Default is 0 - * [Eiger virtual] If 1, pixels are saturated. If 0, increasing intensity - * Only for virtual servers */ + * Default is 0 \n + * [Eiger][Jungfrau] Only for virtual servers, if 1, pixels are saturated. + * If 0, increasing intensity */ void setImageTestMode(const int value, Positions pos = {}); /** gets list of temperature indices for this detector */ @@ -430,8 +433,8 @@ class Detector { */ void acquire(); - /** If acquisition aborted, use this to clear before starting next - * acquisition */ + /** If acquisition aborted during blocking acquire, use this to clear + * acquiring flag in shared memory before starting next acquisition */ void clearAcquiringFlag(); /** Non Blocking: Start receiver listener and create data file if file write @@ -738,7 +741,7 @@ class Detector { Result getFilePath(Positions pos = {}) const; - /** If path does not exist, it will try to create it */ + /** Default is "/"If path does not exist, it will try to create it */ void setFilePath(const std::string &fpath, Positions pos = {}); Result getFileNamePrefix(Positions pos = {}) const; @@ -751,7 +754,10 @@ class Detector { Result getAcquisitionIndex(Positions pos = {}) const; - /** file or Acquisition index in receiver */ + /** file or Acquisition index in receiver \n + * File name: [file name prefix]_d[detector index]_f[sub file + * index]_[acquisition/file index].[raw/h5]. + */ void setAcquisitionIndex(int64_t i, Positions pos = {}); Result getFileWrite(Positions pos = {}) const; @@ -906,7 +912,7 @@ class Detector { /** [Eiger] */ Result getBottom(Positions pos = {}) const; - /** [Eiger] for client call back (gui) purposes */ + /** [Eiger] for client call back (gui) purposes to flip bottom image */ void setBottom(bool value, Positions pos = {}); /**[Eiger] Returns energies in eV where the module is trimmed */ @@ -954,13 +960,14 @@ class Detector { /** [Eiger] */ Result getActive(Positions pos = {}) const; - /** [Eiger] */ + /** [Eiger] activated by default at hostname command. Deactivated does not + * send data or communicated with FEB or BEB */ void setActive(const bool active, Positions pos = {}); /** [Eiger] */ Result getRxPadDeactivatedMode(Positions pos = {}) const; - /** [Eiger] Pad deactivated modules in receiver */ + /** [Eiger] Pad deactivated modules in receiver. Enabled by default */ void setRxPadDeactivatedMode(bool pad, Positions pos = {}); /** [Eiger] Advanced */ @@ -1033,7 +1040,7 @@ class Detector { * automatically after 93.75% of exposure time (only for longer than * 100us).\n * Default is false or this mode disabled(comparator enabled throughout). - * true enables " "mode. 0 disables mode. + * true enables mode. 0 disables mode. */ void setAutoCompDisable(bool value, Positions pos = {}); @@ -1080,7 +1087,8 @@ class Detector { */ void setROI(defs::ROI value, int module_id); - /** [Gotthard] Clear ROI */ + /** [Gotthard] Clear ROI to all channels enabled. Default is all channels + * enabled. */ void clearROI(Positions pos = {}); /** [Gotthard] */ @@ -1104,13 +1112,15 @@ class Detector { /** [Gotthard2] only in burst mode and auto timing mode */ Result getBurstPeriod(Positions pos = {}) const; - /** [Gotthard2] only in burst mode and auto timing mode */ + /** [Gotthard2] Period between 2 bursts. Only in burst mode and auto timing + * mode */ void setBurstPeriod(ns value, Positions pos = {}); /** [Gotthard2] offset channel, increment channel */ Result> getInjectChannel(Positions pos = {}); /** [Gotthard2] + * Inject channels with current source for calibration. * offsetChannel is starting channel to be injected * incrementChannel is determines succeeding channels to be injected */ void setInjectChannel(const int offsetChannel, const int incrementChannel, @@ -1149,7 +1159,7 @@ class Detector { /** [Gotthard2] */ Result getFilter(Positions pos = {}) const; - /** default 0 */ + /** [Gotthard2] Set filter resister. Options: 0-3. Default: 0 */ void setFilter(int value, Positions pos = {}); /** [Gotthard2] */ @@ -1174,7 +1184,8 @@ class Detector { Result getADCConfiguration(const int chipIndex, const int adcIndex, Positions pos = {}) const; - /** [Gotthard2] */ + /** [Gotthard2] configures one chip at a time for specific adc, chipIndex + * and adcIndex is -1 for all */ void setADCConfiguration(const int chipIndex, const int adcIndex, const int value, Positions pos = {}); @@ -1283,7 +1294,8 @@ class Detector { /** [CTB][Moench] */ Result getTenGigaADCEnableMask(Positions pos = {}) const; - /** [CTB][Moench] */ + /** [CTB][Moench] If any of a consecutive 4 bits are enabled, the " + "complete 4 bits are enabled */ void setTenGigaADCEnableMask(uint32_t mask, Positions pos = {}); ///@{ @@ -1337,13 +1349,13 @@ class Detector { /** [CTB] */ Result getExternalSamplingSource(Positions pos = {}) const; - /** [CTB] Value between 0-63 */ + /** [CTB] Value between 0-63 \n For advanced users only.*/ void setExternalSamplingSource(int value, Positions pos = {}); /** [CTB] */ Result getExternalSampling(Positions pos = {}) const; - /** [CTB] */ + /** [CTB] For advanced users only. */ void setExternalSampling(bool value, Positions pos = {}); /** [CTB] */ @@ -1504,9 +1516,10 @@ class Detector { void resetFPGA(Positions pos = {}); /** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2] - * Advanced user Function! - * Copy detector server fname from tftp folder of hostname to detector - * Also changes respawn server, which is effective after a reboot. + * Advanced user Function! \n + * Copy detector server fname from tftp folder of hostname to detector \n + * [Jungfrau][Gotthard][CTB][Moench] Also changes respawn server, which is + * effective after a reboot. */ void copyDetectorServer(const std::string &fname, const std::string &hostname, Positions pos = {}); @@ -1517,13 +1530,14 @@ class Detector { /** * [Jungfrau][Gotthard][CTB][Moench] - * Advanced user Function! + * Advanced user Function! \n * Updates the firmware, detector server and then reboots detector - * controller blackfin. - * sname is name of detector server binary found on tftp folder of host - * pc - * hostname is name of pc to tftp from - * fname is programming file name + * controller blackfin. \n + * [Mythen3][Gotthard2] Will still have old server starting up as the new + * server is not respawned \n + sname is name of detector server binary found on + * tftp folder of host pc hostname is name of pc to tftp from fname is + * programming file name */ void updateFirmwareAndServer(const std::string &sname, const std::string &hostname, @@ -1543,12 +1557,16 @@ class Detector { /** Advanced user Function! */ void clearBit(uint32_t addr, int bitnr, Positions pos = {}); + /** Advanced user Function! */ + Result getBit(uint32_t addr, int bitnr, Positions pos = {}); + /** [Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench] Advanced user * Function! */ void executeFirmwareTest(Positions pos = {}); /** [Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench] Advanced user - * Function! */ + * Function! Writes different values in a R/W register and confirms the + * writes to check bus */ void executeBusTest(Positions pos = {}); /** [Gotthard][Jungfrau][CTB][Moench] Advanced user Function! not possible @@ -1558,14 +1576,17 @@ class Detector { /** Advanced user Function! */ bool getInitialChecks() const; - /** initial compaibility and other server start up checks - * default enabled Advanced user Function! */ + /** Enables/disabled initial compaibility and other server start up checks. + * \n Default is enabled. Must come before 'hostname' command to take + * effect. \n Can be used to reprogram fpga when current firmware is + * incompatible. \n Advanced user Function! */ void setInitialChecks(const bool value); /** [CTB][Moench][Jungfrau] Advanced user Function! */ Result getADCInvert(Positions pos = {}) const; - /** [CTB][Moench][Jungfrau] Advanced user Function! */ + /** [CTB][Moench][Jungfrau] Advanced user Function! \n + [Jungfrau] Inversions on top of default mask */ void setADCInvert(uint32_t value, Positions pos = {}); ///@{ @@ -1606,11 +1627,11 @@ class Detector { Result getNumberOfFramesFromStart(Positions pos = {}) const; /** [Jungfrau][Mythen3][CTB][Moench] Get time from detector start - * [Gotthard2] only in continuous mode */ + * [Gotthard2] not in burst and auto mode */ Result getActualTime(Positions pos = {}) const; /** [Jungfrau][Mythen3][CTB][Moench] Get timestamp at a frame start - * [Gotthard2] only in continuous mode */ + * [Gotthard2] not in burst and auto mode */ Result getMeasurementTime(Positions pos = {}) const; /** get user details from shared memory (hostname, type, PID, User, Date) diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 6cb26f3de..103bc7df3 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -122,7 +122,9 @@ std::string CmdProxy::Hostname(int action) { os << cmd << ' '; if (action == defs::HELP_ACTION) { os << "\n\tFrees shared memory and sets hostname (or IP address) of " - "all modules concatenated by +." + "all modules concatenated by +.\n\t Virtual servers can already " + "use the port in hostname separated by ':' and ports incremented " + "by 2 to accomodate the stop server as well." << '\n'; } else if (action == defs::GET_ACTION) { if (!args.empty()) { @@ -220,8 +222,8 @@ std::string CmdProxy::FirmwareVersion(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "\n\tFimware version of detector in format [0xYYMMDD] or integer " - "for Eiger." + os << "\n\tFimware version of detector in format [0xYYMMDD] or an " + "increasing 2 digit number for Eiger." << '\n'; } else if (action == defs::GET_ACTION) { if (!args.empty()) { @@ -315,9 +317,9 @@ std::string CmdProxy::DetectorSize(int action) { os << cmd << ' '; if (action == defs::HELP_ACTION) { os << "[nx] [ny]\n\tDetector size, ie. Number of channels in x and y " - "dim. If 0, then hostname adds all modules in y dim. This is " - "used to calculate module coordinates included in UDP data " - "packet header." + "dim. This is used to calculate module coordinates included in " + "UDP data. \n\tBy default, it adds module in y dimension for 2d " + "detectors and in x dimension for 1d detectors packet header." << '\n'; } else if (action == defs::GET_ACTION) { if (!args.empty()) { @@ -480,7 +482,8 @@ std::string CmdProxy::DynamicRange(int action) { if (action == defs::HELP_ACTION) { os << "[value]\n\tDynamic Range or number of bits per " "pixel in detector.\n\t" - "[Eiger] Options: 4, 8, 16, 32\n\t" + "[Eiger] Options: 4, 8, 16, 32. If set to 32, also sets " + "clkdivider to 2, else to 0.\n\t" "[Mythen3] Options: 8, 16, 32\n\t" "[Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16" << '\n'; @@ -838,7 +841,7 @@ std::string CmdProxy::ExternalSignal(int action) { "[trigger_in_rising_edge|trigger_in_falling_edge|inversion_on|" "inversion_off]\n\t where 0 is master input trigger signal, 1-3 " "is master input gate signals, 4 is busy out signal and 5-7 is " - "master output gate signals" + "master output gate signals." << '\n'; } else if (action == defs::GET_ACTION) { if (args.size() != 1) { @@ -1584,7 +1587,7 @@ std::string CmdProxy::ClearROI(int action) { os << cmd << ' '; if (action == defs::HELP_ACTION) { os << "\n\t[Gotthard] Resets Region of interest in detector. All " - "channels enabled. Default is all channels." + "channels enabled. Default is all channels enabled." << '\n'; } else if (action == defs::GET_ACTION) { throw sls::RuntimeError("Cannot get"); @@ -2450,10 +2453,9 @@ std::string CmdProxy::CopyDetectorServer(int action) { if (action == defs::HELP_ACTION) { os << "[server_name] " "[pc_host_name]\n\t[Jungfrau][Ctb][Moench][Mythen3][Gotthard2] " - "Copies " - "detector " - "server via tftp from pc and changes respawn server name in " - "/etc/inittab of detector." + "Copies detector server via tftp from pc. " + "\n\t[Jungfrau][Ctb][Moench]Also changes respawn server, which " + "is effective after a reboot." << '\n'; } else if (action == defs::GET_ACTION) { throw sls::RuntimeError("Cannot get"); @@ -2554,16 +2556,13 @@ std::string CmdProxy::BitOperations(int action) { os << cmd << ' '; if (action == defs::HELP_ACTION) { if (cmd == "setbit") { - os << "[address] [value\n\t[Moench] Minimum energy threshold (soft " - "setting) for processor." + os << "[reg address in hex] [bit index]\n\tSets bit in address." << '\n'; } else if (cmd == "clearbit") { - os << "[n_value]\n\t[Moench] Maximum energy threshold (soft " - "setting) for processor." + os << "[reg address in hex] [bit index]\n\tClears bit in address." << '\n'; } else if (cmd == "getbit") { - os << "[n_value]\n\t[Moench] Maximum energy threshold (soft " - "setting) for processor." + os << "[reg address in hex] [bit index]\n\tGets bit in address." << '\n'; } else { throw sls::RuntimeError( @@ -2587,12 +2586,8 @@ std::string CmdProxy::BitOperations(int action) { if (cmd == "setbit" || cmd == "clearbit") { throw sls::RuntimeError("Cannot get"); } - auto t = det->readRegister(addr, std::vector{det_id}); - Result result(t.size()); - for (unsigned int i = 0; i < t.size(); ++i) { - result[i] = ((t[i] >> bitnr) & 0x1); - } - os << OutString(result) << '\n'; + auto t = det->getBit(addr, bitnr, std::vector{det_id}); + os << OutString(t) << '\n'; } else if (action == defs::PUT_ACTION) { if (cmd == "getbit") { throw sls::RuntimeError("Cannot put"); @@ -2617,7 +2612,8 @@ std::string CmdProxy::InitialChecks(int action) { os << "[0, 1]\n\tEnable or disable intial compatibility and other " "checks at detector start up. It is enabled by default. Must " "come before 'hostname' command to take effect. Can be used to " - "reprogram fpga when current firmware is incompatible." + "reprogram fpga when current firmware is " + "incompatible.\n\tAdvanced User function!" << '\n'; } else if (action == defs::GET_ACTION) { if (det_id != -1) { @@ -2651,7 +2647,8 @@ std::string CmdProxy::ExecuteCommand(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[command]\n\tExecutes command on detector server." << '\n'; + os << "[command]\n\tExecutes command on detector server console." + << '\n'; } else if (action == defs::GET_ACTION) { throw sls::RuntimeError("Cannot get."); } else if (action == defs::PUT_ACTION) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 4e71d8815..06ebcfb41 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -597,6 +597,7 @@ class CmdProxy { {"detectorversion", "firmwareversion"}, {"softwareversion", "detectorserverversion"}, {"receiverversion", "rx_version"}, + {"detectornumber", "serialnumber"}, {"thisversion", "clientversion"}, {"detsizechan", "detsize"}, @@ -703,7 +704,7 @@ class CmdProxy { {"firmwareversion", &CmdProxy::FirmwareVersion}, {"detectorserverversion", &CmdProxy::detectorserverversion}, {"rx_version", &CmdProxy::rx_version}, - {"detectornumber", &CmdProxy::detectornumber}, + {"serialnumber", &CmdProxy::serialnumber}, {"type", &CmdProxy::type}, {"nmod", &CmdProxy::nmod}, {"detsize", &CmdProxy::DetectorSize}, @@ -1176,8 +1177,8 @@ class CmdProxy { GET_COMMAND_HEX(rx_version, getReceiverVersion, "\n\tReceiver version in format [0xYYMMDD]."); - GET_COMMAND_HEX(detectornumber, getSerialNumber, - "\n\tReceiver version in format [0xYYMMDD]."); + GET_COMMAND_HEX(serialnumber, getSerialNumber, + "\n\tSerial number of detector."); GET_COMMAND(type, getDetectorType, "\n\tReturns detector type. Can be Eiger, Jungfrau, Gotthard, " @@ -1222,8 +1223,8 @@ class CmdProxy { INTEGER_COMMAND_NOID( frames, getNumberOfFrames, setNumberOfFrames, StringTo, "[n_frames]\n\tNumber of frames per acquisition. In " - "trigger mode, number of frames per trigger. Cannot be set in modular " - "level. In scan mode, number of frames is set to number of " + "trigger mode, number of frames per trigger. \n\tCannot be set in " + "modular level. \n\tIn scan mode, number of frames is set to number of " "steps.\n\t[Gotthard2] Burst mode has a maximum of 2720 frames."); INTEGER_COMMAND_NOID(triggers, getNumberOfTriggers, setNumberOfTriggers, @@ -1587,7 +1588,8 @@ class CmdProxy { DAC_COMMAND( adcvpp, getDAC, setDAC, defs::ADC_VPP, "[dac or mV value][(optional unit) mV] \n\t[Ctb][Moench] Vpp of " - "ADC.\n\t 0 -> 1V ; 1 -> 1.14V ; 2 -> 1.33V ; 3 -> 1.6V ; 4 -> 2V."); + "ADC.\n\t 0 -> 1V ; 1 -> 1.14V ; 2 -> 1.33V ; 3 -> 1.6V ; 4 -> 2V. " + "\n\tAdvanced User function! "); DAC_COMMAND(vb_ds, getDAC, setDAC, defs::VB_DS, "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for " @@ -1667,9 +1669,10 @@ class CmdProxy { /* acquisition */ - EXECUTE_SET_COMMAND_NOID(clearbusy, clearAcquiringFlag, - "\n\tClears Acquiring Flag for unexpected acquire " - "command terminations."); + EXECUTE_SET_COMMAND_NOID( + clearbusy, clearAcquiringFlag, + "\n\tIf acquisition aborted during acquire command, use this to clear " + "acquiring flag in shared memory before starting next acquisition"); EXECUTE_SET_COMMAND_NOID( rx_start, startReceiver, @@ -1899,10 +1902,10 @@ class CmdProxy { "[binary|hdf5]\n\tFile format of data file. For HDF5, package must be " "compiled with HDF5 flags. Default is binary."); - STRING_COMMAND( - fpath, getFilePath, setFilePath, - "[path]\n\tDirectory where output data files are written in receiver. " - "If path does not exist, it will try to create it."); + STRING_COMMAND(fpath, getFilePath, setFilePath, + "[path]\n\tDirectory where output data files are written in " + "receiver. Default is '/'. \n\tIf path does not exist, it " + "will try to create it."); STRING_COMMAND(fname, getFileNamePrefix, setFileNamePrefix, "[name]\n\tFile name prefix for output data file. Default " @@ -2012,8 +2015,9 @@ class CmdProxy { INTEGER_COMMAND_VEC_ID( flippeddatax, getBottom, setBottom, StringTo, "[0, 1]\n\t[Eiger] Top or Bottom Half of Eiger module. 1 is bottom, 0 " - "is top. Used to let Receivers and Gui know to flip the bottom image " - "over the x axis. Files are not written without the flip however."); + "is top. Used to let Gui (via zmq from receiver) know to flip the " + "bottom image over the x axis. Files are not written without the flip " + "however."); INTEGER_COMMAND_VEC_ID( readnlines, getPartialReadout, setPartialReadout, StringTo, @@ -2105,9 +2109,10 @@ class CmdProxy { "timing mode and burst mode. Use timing command to set timing mode and " "burstmode command to set burst mode."); - TIME_COMMAND(burstperiod, getBurstPeriod, setBurstPeriod, - "[duration] [(optional unit) ns|us|ms|s]\n\t[Gotthard2] Burst " - "period. Only in burst mode and auto timing mode."); + TIME_COMMAND( + burstperiod, getBurstPeriod, setBurstPeriod, + "[duration] [(optional unit) ns|us|ms|s]\n\t[Gotthard2] " + "Period between 2 bursts. Only in burst mode and auto timing mode."); INTEGER_COMMAND_VEC_ID( cdsgain, getCDSGain, setCDSGain, StringTo, @@ -2169,13 +2174,13 @@ class CmdProxy { INTEGER_COMMAND_HEX(adcenable, getADCEnableMask, setADCEnableMask, StringTo, "[bitmask]\n\t[Ctb][Moench] ADC Enable Mask for 1Gb " - "Mode for each 32 ADC channel."); + "Enable for each 32 ADC channel."); INTEGER_COMMAND_HEX( adcenable10g, getTenGigaADCEnableMask, setTenGigaADCEnableMask, StringTo, "[bitmask]\n\t[Ctb][Moench] ADC Enable Mask for 10Gb mode for each 32 " - "ADC channel. However, if any of consecutive 4 bits are enabled, the " + "ADC channel. However, if any of a consecutive 4 bits are enabled, the " "complete 4 bits are enabled."); /* CTB Specific */ @@ -2258,8 +2263,8 @@ class CmdProxy { INTEGER_COMMAND_VEC_ID( extsampling, getExternalSampling, setExternalSampling, StringTo, - "[0, 1]\n\t[Ctb] Enable for external sampling signal to extsamplingsrc " - "signal for digital data. For advanced users only."); + "[0, 1]\n\t[Ctb] Enable for external sampling signal for digital data " + "to signal by extsampling src command. For advanced users only."); INTEGER_COMMAND_VEC_ID( extsamplingsrc, getExternalSamplingSource, setExternalSamplingSource, @@ -2319,7 +2324,8 @@ class CmdProxy { EXECUTE_SET_COMMAND( bustest, executeBusTest, "\n\t[Jungfrau][Gotthard][Mythen3][Gotthard2][Ctb][Moench] Bus test, " - "ie. keeps writing and reading back different values in R/W register."); + "ie. Writes different values in a R/W register and confirms the " + "writes to check bus.\n\tAdvanced User function!"); INTEGER_COMMAND_HEX( adcinvert, getADCInvert, setADCInvert, StringTo, @@ -2355,13 +2361,13 @@ class CmdProxy { "[(optional unit) " "ns|us|ms|s]\n\t[Jungfrau][Mythen3][Gotthard2][Moench][" "CTB] Time from detector start up." - "\n\t[Gotthard2] only in continuous mode."); + "\n\t[Gotthard2] not in burst and auto mode."); TIME_GET_COMMAND(timestamp, getMeasurementTime, "[(optional unit) " "ns|us|ms|s]\n\t[Jungfrau][Mythen3][Gotthard2][Moench][" "CTB] Timestamp at a frame start." - "\n\t[Gotthard2] only in continuous mode."); + "\n\t[Gotthard2] not in burst and auto mode."); GET_COMMAND( rx_frameindex, getRxCurrentFrameIndex, diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 05815ef6c..c43d5aa0b 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -384,7 +384,6 @@ Result Detector::getClockFrequency(int clkIndex, Positions pos) { return pimpl->Parallel(&Module::getClockFrequency, pos, clkIndex); } - Result Detector::getClockPhase(int clkIndex, Positions pos) { return pimpl->Parallel(&Module::getClockPhase, pos, clkIndex, false); } @@ -1883,6 +1882,10 @@ void Detector::clearBit(uint32_t addr, int bitnr, Positions pos) { pimpl->Parallel(&Module::clearBit, pos, addr, bitnr); } +Result Detector::getBit(uint32_t addr, int bitnr, Positions pos) { + return pimpl->Parallel(&Module::getBit, pos, addr, bitnr); +} + void Detector::executeFirmwareTest(Positions pos) { pimpl->Parallel(&Module::executeFirmwareTest, pos); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index e24d39e53..10002f113 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -2195,21 +2195,29 @@ uint32_t Module::writeRegister(uint32_t addr, uint32_t val) { return sendToDetectorStop(F_WRITE_REGISTER, args); } -uint32_t Module::setBit(uint32_t addr, int n) { +void Module::setBit(uint32_t addr, int n) { if (n < 0 || n > 31) { throw RuntimeError("Bit number " + std::to_string(n) + " out of Range"); } else { uint32_t val = readRegister(addr); - return writeRegister(addr, val | 1 << n); + writeRegister(addr, val | 1 << n); } } -uint32_t Module::clearBit(uint32_t addr, int n) { +void Module::clearBit(uint32_t addr, int n) { if (n < 0 || n > 31) { throw RuntimeError("Bit number " + std::to_string(n) + " out of Range"); } else { uint32_t val = readRegister(addr); - return writeRegister(addr, val & ~(1 << n)); + writeRegister(addr, val & ~(1 << n)); + } +} + +int Module::getBit(uint32_t addr, int n) { + if (n < 0 || n > 31) { + throw RuntimeError("Bit number " + std::to_string(n) + " out of Range"); + } else { + return ((readRegister(addr) >> n) & 0x1); } } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 9d1dd28bd..4303ce1fe 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -497,8 +497,9 @@ class Module : public virtual slsDetectorDefs { void rebootController(); uint32_t readRegister(uint32_t addr) const; uint32_t writeRegister(uint32_t addr, uint32_t val); - uint32_t setBit(uint32_t addr, int n); - uint32_t clearBit(uint32_t addr, int n); + void setBit(uint32_t addr, int n); + void clearBit(uint32_t addr, int n); + int getBit(uint32_t addr, int n); void executeFirmwareTest(); void executeBusTest(); void writeAdcRegister(uint32_t addr, uint32_t val); diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index a169cf5d5..ff6fc3854 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -101,11 +101,11 @@ TEST_CASE("detectorserverversion", "[.cmd][.new]") { REQUIRE_THROWS(proxy.Call("detectorserverversion", {"0"}, -1, PUT)); } -TEST_CASE("detectornumber", "[.cmd][.new]") { +TEST_CASE("serialnumber", "[.cmd][.new]") { Detector det; CmdProxy proxy(&det); - REQUIRE_NOTHROW(proxy.Call("detectornumber", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("detectornumber", {"0"}, -1, PUT)); + REQUIRE_NOTHROW(proxy.Call("serialnumber", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("serialnumber", {"0"}, -1, PUT)); } TEST_CASE("type", "[.cmd][.new]") { @@ -334,10 +334,10 @@ TEST_CASE("exptime", "[.cmd][.time]") { REQUIRE(oss.str() == "exptime 0\n"); } { - //Get exptime of single module - std::ostringstream oss; - proxy.Call("exptime", {}, 0, GET, oss); - REQUIRE(oss.str() == "exptime 0ns\n"); + // Get exptime of single module + std::ostringstream oss; + proxy.Call("exptime", {}, 0, GET, oss); + REQUIRE(oss.str() == "exptime 0ns\n"); } det.setExptime(-1, prev_val); }