Compare commits

...

433 Commits

Author SHA1 Message Date
193f2b9011 Split slsReceiver into slsListener and slsReceiver 2019-03-25 17:52:30 +01:00
6cb043b2d9 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-21 16:30:25 +01:00
fa34ad435b server: pll fix 2019-03-21 16:30:18 +01:00
c5178bc4de manual 2019-03-21 16:29:36 +01:00
c89fad45a9 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-21 15:09:19 +01:00
6c4fad01d4 manual 2019-03-21 15:09:10 +01:00
eb3dff3a6c eiger server 2019-03-21 14:15:52 +01:00
d9503bebf9 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-21 14:13:15 +01:00
b99606211b ctb server: altera pll odd division fix 2019-03-21 14:13:07 +01:00
039e658773 manual 2019-03-21 11:46:38 +01:00
92ca22fc09 manual 2019-03-20 18:34:44 +01:00
d4ac6fe160 gitinfo as public 2019-03-20 17:48:01 +01:00
8cb0f3a29c Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-20 17:41:57 +01:00
c16f9b8c30 specify detector or receiver in error 2019-03-20 17:41:46 +01:00
050854de36 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-20 17:34:37 +01:00
cb80cf5f09 receiver missing packets made to have signed for getting more packets than expected 2019-03-20 17:34:29 +01:00
83e43b1bcf format ColumnLimit changed to 100 2019-03-20 17:31:19 +01:00
2a01688683 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-20 17:07:29 +01:00
3ff01bf609 removed minor warnings for unused ret 2019-03-20 17:07:02 +01:00
4b2c6af4f5 reorganizing of slsDetectorSoftware 2019-03-20 17:07:02 +01:00
03402d0e9e Error handling with exceptions in slsDetector and multiSlsDetector (#14)
* less error mask

* removing error mask from slsDetector

* removed ErrorMask

* setonline, setreceiveornline bug fix
2019-03-20 16:23:41 +01:00
9d489dc962 servers, gitinfo script updated; ctb/moench server: delay uses sync clock, 2019-03-20 14:39:24 +01:00
44f0dfc3c0 ctbserver: updated firmware version and api 2019-03-19 18:58:42 +01:00
685fcc31b6 setonline, setreceiveronline was never really setting offline flag, so was never really updating detector first time 2019-03-19 18:42:45 +01:00
ce6289afda Merge pull request #13 from slsdetectorgroup/except
new socket overload
2019-03-19 18:01:09 +01:00
4e56107015 new socket overload 2019-03-19 17:49:20 +01:00
430e0e3fb5 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-19 17:32:17 +01:00
d8c0fb522a ctb/ moench server fix: usleep of 10 for reading from fifo removed 2019-03-19 17:32:07 +01:00
ce25c06b41 Merge pull request #12 from slsdetectorgroup/except
refactor getID
2019-03-19 16:58:43 +01:00
6759b2eeb8 refactor getID 2019-03-19 16:27:07 +01:00
38bf540c1a fixed segfault on loading trimbits 2019-03-18 18:10:50 +01:00
43012e4f28 more const more python 2019-03-18 17:38:44 +01:00
98655ee7e3 added missing py file 2019-03-18 12:20:48 +01:00
43d478076c Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-18 12:06:49 +01:00
4036e6af8d const qualified multi calls, python fixes 2019-03-18 12:06:39 +01:00
fad73a57aa minor 2019-03-18 09:19:04 +01:00
c0d5303b70 removed pycache 2019-03-15 17:59:36 +01:00
3356c2d3f6 all python version 2019-03-15 15:01:44 +01:00
3f45d39c8d deploy on all branches 2019-03-15 14:37:01 +01:00
4e94995142 conda build 2019-03-15 14:23:51 +01:00
c93b78c74f working 2019-03-15 13:50:50 +01:00
73af4a744f added pybind11 v2.2 as submodule 2019-03-15 11:05:12 +01:00
6ddde83c81 python 2019-03-15 11:01:36 +01:00
bb93147537 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-15 10:37:54 +01:00
1eff8485dd receiver listener bug fix from previous commit 2019-03-15 10:37:47 +01:00
c153be95d1 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-15 10:15:50 +01:00
4943983d10 det id const and ini shm in constructor 2019-03-15 10:15:42 +01:00
5fe7a86361 switching udpsocketbuffersize from uitn64_t to int64_t, printing socket exception into tcp error mess, changing an exception message 2019-03-15 10:00:22 +01:00
7522a655df removing warning in gcc 2019-03-14 17:38:40 +01:00
836eb8cde2 explicit override 2019-03-14 17:15:58 +01:00
9f724f0c0d using only sls exceptions 2019-03-14 17:09:44 +01:00
bad44f5bf4 moving SharedMemory into namespace sls 2019-03-14 16:51:38 +01:00
40d2f66146 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-14 16:37:46 +01:00
9639e480d9 new exceptions 2019-03-14 16:37:36 +01:00
8520492e4b lock server bug: sending lockstatus converts to littleendian for eiger, lastclient should have other as datatype for eiger 2019-03-14 14:14:14 +01:00
be33102164 checkonline, checkrecieveronline, retval has offline hostnames, online flag should be set no matter what the outcome 2019-03-14 13:18:42 +01:00
5235a87e93 Merge branch 'detshm' into refactor 2019-03-14 12:42:08 +01:00
cb687d805e merge conflict 2019-03-14 12:41:37 +01:00
327d08a016 removing comments, added one check for nullptr, updated current threshold when getting module, removing unsued function from header file (writesettingsfile) 2019-03-14 12:40:01 +01:00
1960460e43 upgraded catch to 2.7 2019-03-14 10:47:43 +01:00
e42e8f5bf6 option for sanitizers 2019-03-14 10:44:31 +01:00
c9422befff fixed loading trimbits 2019-03-14 10:21:18 +01:00
c56efdec8a Merge branch 'refactor' into detshm 2019-03-14 09:11:27 +01:00
14131f93f1 sanitizer compile fail 2019-03-14 09:06:44 +01:00
d21ceb0e75 only construct shared memory from a type with exact size 2019-03-13 17:43:48 +01:00
9a08c85b2a changed the shared memory of slsDetector 2019-03-13 17:38:27 +01:00
85134443de initial 2019-03-13 16:29:29 +01:00
7d3d2a8b31 ctb and moench server: pll vco clock changed from 400 to 800,ctb server: max adc clock from 40 to 65MHz 2019-03-13 16:03:11 +01:00
75ce111344 Merge branch 'shm' into refactor 2019-03-13 15:21:12 +01:00
f8aa0e3d6d removed minor commented lines 2019-03-13 15:19:32 +01:00
2dcef909ca Merge branch 'refactor' into shm 2019-03-13 14:22:26 +01:00
ec18db868f ctb, moench, jungfrau server: changing phase only changes one clock in one direction. ctb and moench phase shift connected to adc clk, instead of run clk 2019-03-13 08:37:45 +01:00
7e793539ca removed typedef for shared struct 2019-03-12 14:42:27 +01:00
d4e4fb8ffe move constructor deleted copy constructor 2019-03-12 14:37:06 +01:00
48e4cec56f minor 2019-03-12 11:52:13 +01:00
3b2c734efd adding tests 2019-03-12 11:43:28 +01:00
507a22ac05 default args 2019-03-12 10:14:24 +01:00
a01d68a61f initial changes 2019-03-12 08:22:07 +01:00
6765fd0dc8 ctb moench: bugfix for fifofull, should not read pattern, same as executing it 2019-03-08 16:59:44 +01:00
ae5938799f Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-08 16:16:53 +01:00
19b21dac88 Listener bug fix: switching to make_unique ptr side effects, the dummy socket still alive when destructor of listener called 2019-03-08 16:16:40 +01:00
b8f071dcf6 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-08 15:13:23 +01:00
182f65bc2f always compile commands 2019-03-08 15:13:11 +01:00
1103f56256 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-03-08 09:14:39 +01:00
0553755439 receiver bug fix: with refactor, the callbacks were getting reset upon initialization. fixed 2019-03-08 09:14:29 +01:00
65b8ab5b89 manual 2019-03-07 17:40:56 +01:00
658438df3b ctb moench server update: (fw update): det id changed, status reg looks at anyfifofull instead of somefifofull, datapresent looks at corresponding analog/digital fifo empty, usleep after read strobe to sync different clock 2019-03-07 17:36:35 +01:00
999a2f4d15 Merge pull request #8 from slsdetectorgroup/use-unique-ptr
In Listener, remove raw pointers allocations, use `unique_ptr` instead.
2019-03-06 17:48:28 +01:00
2532df37cc client: added basic fail handling where ommitted 2019-03-06 17:37:13 +01:00
ca817c6ae9 client: update roi on updatedetector, (ctb, moench)moved nchans and databyte calculated to updatenumberofchannels and called for any update in roi, readoutflag or #samples changed (get should not update). ctb,moench server: roi fixed, . gotthard server: bug fix waiting to finish, ad9252 spi call fix. receiver: updated for moench and 10g 2019-03-06 17:25:18 +01:00
0765b330f1 ctb and moench, exptime connects to set pattern wait time with level 0 2019-03-06 15:17:54 +01:00
abc7a9bd2f moench has only analog readout 2019-03-06 14:52:21 +01:00
2676e8b43d receiver: readout flag bug fix, clent:send roi for ctb and moench 2019-03-06 10:55:51 +01:00
d3c1193a71 ctb/moench server, fixed frequency configuring bug, readpattern sleep, detectormode command, jsonheader set even if rxr offline, set speed returnvalue is value not ok/fail, rxr printout missingpackets 64 bit 2019-03-06 10:25:16 +01:00
db232ad00d in Listener, remove raw pointers allocations, use unique_ptr instead.
Add an overload of sls::make_unique for array types.
2019-03-06 09:07:51 +01:00
ceb515d517 Merge pull request #7 from slsdetectorgroup/fix-sprintf-warnings
Fix sprintf warnings
2019-03-05 16:26:18 +01:00
04c8a2871d Fix sprintf warnings 2019-03-05 14:34:01 +01:00
1803a5aecc Merge pull request #6 from slsdetectorgroup/fix-typos
Fix typos
2019-03-05 14:19:19 +01:00
c40db94474 Fix typos 2019-03-05 10:43:20 +01:00
c56561bc9f updated ctb and moench, moench not tested 2019-03-05 09:38:10 +01:00
08bd2378f4 slsReceiver bug fix affecting Jungfrau receivers as root (optlen size as int), but setting buffer size is uint32_t size. setting it to uint64_t 2019-03-04 09:41:20 +01:00
8939e23622 jungfrau feature:storagecell_delay added 2019-03-01 15:26:38 +01:00
93192c6e84 bugfix receiver: setImagesize only for ctb, moench 2019-03-01 15:22:39 +01:00
d2d50a56df eiger server/client bug fix: readout flag of -1 2019-03-01 14:08:28 +01:00
8c067437e6 ctb moench: added feature set pattern mask and set pattern bit mask, removed CTB prefix for all the patern functions 2019-03-01 12:28:11 +01:00
35b1ad39f7 ctb moench: feature to set digital io pin delay, changed print from unsuccessful to failed, maxpatternlength in server is inclusive 2019-03-01 10:45:01 +01:00
bb81613900 ctb, moench: implemented led enable feature 2019-03-01 09:00:04 +01:00
ebee9e308e ctb server: reserved not required, as the additional space in last packet can be calcualted 2019-02-28 16:14:45 +01:00
debf3a1b01 ctb readout works with receiver for digital readout, allocate ram in server only if 1g udp, free addr info only when setting new udp detals upon configuring ,brough readout flags to receiver 2019-02-28 16:07:47 +01:00
96584ce397 ctb: enable tengiga in server and moved everything to list implementation 2019-02-28 11:32:10 +01:00
7f2197fc4f slsReceiver & client: 10genable allowed for moench and ctb, ctb server: better way to divide to packets to send via udp 2019-02-28 10:09:54 +01:00
302d9f0633 ctb server: back to 10g def 2019-02-28 08:51:07 +01:00
f80483de6e ctb server: (bug fixes, udp sending feature instead of tcp, better debugging prints,
digital readout mode (fifoempty flag in status register is always up, so it is idle for this readout mode),
pattern loop bugs, max_pattern_length redefined in server side, do not update period for ctb and moench in setreceiver
2019-02-28 08:46:26 +01:00
1fe473e830 client: for set port functions, moved forceupdate outside to automatically close previous function call 2019-02-25 14:45:14 +01:00
966896b942 moench: get zmq goes to the receiver instead of shm, setand get threshold energey updates zmq and shm value, setand get roi anyways goes to the ddetector, so only updates zmq or gets it from rxr 2019-02-25 12:57:44 +01:00
4c7a9cd838 moench: set threshold energy and set roi sets jsonheader 2019-02-25 12:34:35 +01:00
c218e391bb client: rx_tcpport fixed 2019-02-25 11:43:10 +01:00
43ad8b69b3 client: stop and control port get fixed 2019-02-25 09:35:07 +01:00
4c35dd9b5b Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-02-25 09:16:27 +01:00
15fc55f914 client: must print detector or receiver returning error 2019-02-25 09:16:20 +01:00
eecfcae312 ctbserver: dac -1 check limit error 2019-02-25 08:58:35 +01:00
c723b29f9b address and undefined behaviour sanitizers on debug 2019-02-22 19:55:56 +01:00
9b81143c68 Merge branch 'ctbFixes' into refactor 2019-02-22 13:58:51 +01:00
20edf61e30 ctb server: removed unnecessary prints, resulting in a bug fix for slow adc temp 2019-02-22 13:53:59 +01:00
a1a6a5dbaa ctb server: slow adc temp fixed 2019-02-22 13:22:40 +01:00
a8121ae108 ctb server: vio should be off at start up 2019-02-22 09:03:30 +01:00
40d15264c5 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-02-21 16:25:07 +01:00
b2e6b78e20 Merge branch 'ctbBugFixes' into refactor 2019-02-21 16:24:56 +01:00
f5244faa02 moench: adding enums for zmq parameters, needs modification in naming 2019-02-21 16:01:24 +01:00
421dbdb9b5 ctb server: including moench as well for programfpga and other client ctb implementations 2019-02-21 16:00:40 +01:00
617f3d2600 ctb server: modified program fpag in case of errors 2019-02-21 15:56:51 +01:00
a4f1b7670f ctb server bug fixes:update client, get period left, getid(api and serial number), restrict setting vchip, allow write adc 2019-02-21 09:37:49 +01:00
09546a8632 ctb server:
- allowed flags resetfpga and programfpga for moench and ctb
- set a minimum voltage for vio as it powers the fpga (1200mV)
- changed the min and max for vchip and power regulators due to tolerance
- fixed pattern read function
- fixed minor bugs with input of ctb patterns(waittime) and mode other than 1
- fixed calibration current register for i2c for tolerance (/1.2268)
- fixed current readout of i2c
- added digital, analog and normal readouts for flags
2019-02-20 15:36:34 +01:00
29d4eb8b41 catch by ref 2019-02-20 10:29:15 +01:00
775bde76c9 ctb server: power regulator adjusted for precision 2019-02-20 09:34:55 +01:00
d876cb6da6 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-02-20 08:47:13 +01:00
69f361468e ctb: power regulators (set dac, get dac, get adc of voltage and current) works 2019-02-20 08:45:34 +01:00
b52c6b05b8 link and format 2019-02-16 16:46:09 +01:00
c93f88b7e5 ctb server: fixed dacs, power regulators and vchip 2019-02-15 17:08:49 +01:00
d0e1289c1b replaced sprintf on the same buffer with strcat 2019-02-15 15:39:13 +01:00
4a8a72c447 ctb server: vlimit not impl, adc in degrees 2019-02-14 18:28:32 +01:00
501c579f6b users: added json parameter for moench api 2019-02-14 18:03:49 +01:00
722883531d reverted json_emin, emax, framemode and detectormode. All json parameters for moench will go through rx_jsonpara using strings 2019-02-14 17:43:28 +01:00
d2ba206216 Merge branch 'findzmq' into refactor 2019-02-14 17:35:07 +01:00
6be47d936f conflicts resolved 2019-02-14 17:32:33 +01:00
9aaca14b01 CMakeLists.txt: reordering and removing those we dont use anymore, removed all the Makefiles (except the ones for the detector servers) 2019-02-14 16:15:43 +01:00
aaae6d854c changed remaining cmake options to have SLS_ prefix 2019-02-14 15:42:04 +01:00
c91c2c224a Merge branch 'add-cmake-packages' of https://github.com/esrf-bliss/slsDetectorPackage into esrf-bliss-add-cmake-packages 2019-02-14 10:36:41 +01:00
2fdfd33f97 gitignore: added .o files for the servers 2019-02-14 09:30:50 +01:00
230b26a680 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-02-13 20:19:16 +01:00
46aa7769cc client: added command line and for APIfor framemode and detectormode. Refactorinng required in the future 2019-02-13 20:19:08 +01:00
59f3f0c764 cleaner cmake 2019-02-13 15:59:42 +01:00
d46d96ecca fixed linking zmq 2019-02-13 15:35:40 +01:00
82584dd1a8 cmake 2019-02-13 15:13:21 +01:00
b65e0a1f01 include dirs 2019-02-13 15:12:33 +01:00
f9417a23e0 FindZeroMq 2019-02-13 14:53:23 +01:00
fd95550724 client: fix for json header values being integer 2019-02-13 12:43:56 +01:00
c064dc84ae Add generation and install of CMake packages 2019-02-13 10:45:01 +01:00
01e3cb8d5e Cherry pick commit from 4.0.1 about CMake packages 2019-02-13 09:44:45 +01:00
c6ac0f8ebc Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-02-13 09:37:45 +01:00
f9be8b89ac added functionality to set additional json header key value pairs for prototype ctb, server fixed for eiger compile from ctb integration 2019-02-13 09:37:31 +01:00
75a75b6cf6 Merge pull request #3 from esrf-bliss/add-slsReceiver-ctor-overload
merge for Add slsReceiver ctor overload and sls::make_unique
2019-02-13 09:10:33 +01:00
f125b94a7d Use sls::make_unique<> 2019-02-13 08:59:26 +01:00
b18391330e Add slsReceiverUsers(int tcpip_port_no) overload
Use std::unique_ptr<> instead of raw pointers
2019-02-12 17:01:46 +01:00
2bcf88e434 added receiverUsers as public header 2019-02-12 15:26:08 +01:00
031a11c4f7 removed all the warnings and errors from the merge, also removed added -wextra compiler flag, (yet to add additional commands for moench) 2019-02-12 11:09:19 +01:00
a64b34610a merge from developer (without the additional json header implementations) 2019-02-12 09:35:24 +01:00
985b2eba4d ctb registers updated 2019-02-07 18:05:15 +01:00
a5ee9fbdba ctb bug fixes: pattern generator, vchip, dacs 2019-02-07 16:51:18 +01:00
166541bd15 ctb adc phase get fix 2019-02-06 19:05:11 +01:00
140996fae6 ctb adc fix, update detector fix, acq error fix 2019-02-06 18:50:50 +01:00
3f43767d38 ctb client updated 2019-02-06 17:45:19 +01:00
a76cc90972 adc command line bug, ctb api added to client 2019-02-06 17:25:36 +01:00
0c1a3b7756 eiger bug fix: multi hv and eiger should not return -1 if different, ctb : dacs are 24 not 16 2019-02-06 17:07:13 +01:00
076faa62e0 ctb server: server starts up good. Need to debug each function in detail 2019-02-06 15:50:44 +01:00
bb37915419 stdexcept added to compile 2019-02-05 14:44:49 +01:00
536c853d79 hack for receiver port 2019-01-25 19:41:33 +01:00
f1d055138c moved updateDetector/Receiver 2019-01-25 19:12:28 +01:00
82ce6b639c more cout 2019-01-25 16:53:19 +01:00
7d9417dffe fixed debug couts 2019-01-25 16:48:04 +01:00
89ee1d5bcf new socket for slsDetector 2019-01-25 16:44:29 +01:00
a1c0d28ddb changed constructor 2019-01-24 11:12:24 +01:00
c3472f295b split client and server interface 2019-01-23 12:07:44 +01:00
99a1c609f1 starting to add new Socket interface 2019-01-23 11:47:13 +01:00
3eca4c0535 typo 2019-01-21 14:44:06 +01:00
b200138730 data types and format 2019-01-21 14:43:24 +01:00
a4fec1e750 format and no check before delete 2019-01-21 12:10:00 +01:00
46036e5dde braces around statements 2019-01-21 11:41:19 +01:00
d2ed245d1d format and removed nullptr check before delete 2019-01-21 11:18:27 +01:00
b74aed91dc consistent naming between header and source file 2019-01-21 11:11:39 +01:00
e1ec60c9c1 cleaning up tests for command line parser 2019-01-21 10:45:43 +01:00
603b217b54 clang-tidy modernize 2019-01-18 15:15:39 +01:00
449e4da892 removed potential memory leak in readSettingsFile 2019-01-18 15:13:17 +01:00
1ec9d950d5 malloc to new 2019-01-18 15:00:52 +01:00
1b28cc88ff step one project reorganization 2019-01-18 14:41:04 +01:00
8d6ee6ff46 moved shm deleted .project 2019-01-18 11:40:10 +01:00
10539f8533 new getDetectorType functions 2019-01-18 10:53:49 +01:00
13d6d3f866 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-17 17:30:46 +01:00
eff17371a5 removed virtual 2019-01-17 17:30:36 +01:00
13f9b9929a slsreceiver: removed option to start receiver with config file, redundant as the only option is receiver tcp port 2019-01-17 15:17:08 +01:00
b07492be6f removing multiSlsDetectorCommand and using namespace std 2019-01-17 14:45:51 +01:00
c05829031f removed get from the users class and changed put 2019-01-17 14:20:03 +01:00
76da6a07aa using new CmdLineParser 2019-01-16 18:46:34 +01:00
db0807bf7b adding cmdline parser 2019-01-16 16:50:19 +01:00
b19b2a044c minor 2019-01-16 15:22:18 +01:00
1ebe0f5624 spelling 2019-01-16 15:18:49 +01:00
49f71ffca7 project wide nullptr fix 2019-01-16 15:15:29 +01:00
80a1a3d796 moved ClientInterface to src 2019-01-16 15:10:24 +01:00
683a859d4c cleanup 2019-01-16 14:56:01 +01:00
37ebeaed7b Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-16 14:27:21 +01:00
0f688bb249 unique_ptr in multiSlsDetectorClient 2019-01-16 14:27:08 +01:00
1ce8f3d092 udpSocket might still exist when error in creation, will conver to unique ptr later 2019-01-16 13:37:00 +01:00
10a34cce2d Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-16 13:29:11 +01:00
7fe9251a3b ctb server compiles 2019-01-16 13:28:50 +01:00
901785b818 only destroy sem if it was initialized 2019-01-16 11:51:50 +01:00
68545f2b26 removed pointer in multiSlsDetectorClient 2019-01-16 10:56:51 +01:00
fe09f6d062 cleaning up slsDetectorCommand 2019-01-16 10:29:10 +01:00
9d9251293d Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-15 20:06:19 +01:00
d240ab7a29 moench server compiles 2019-01-15 20:06:11 +01:00
dd93117b06 strcpy to sls::strcpy_safe 2019-01-15 17:36:21 +01:00
4b9e41e23b Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-15 17:16:19 +01:00
dd5bd60429 moench server: list.h fixed 2019-01-15 17:16:00 +01:00
5e032c2c3e added tests for compiler version 2019-01-15 17:03:04 +01:00
7303734b19 removing static libs and changing flags 2019-01-15 16:56:33 +01:00
8bc9fa54fc insignificant print 2019-01-15 13:18:40 +01:00
a9fb476543 changing signature from std::string to const std::string& for client receiver ip functions 2019-01-15 13:14:43 +01:00
f2669adda7 Merge branch 'refactor' into networkParameterFix 2019-01-15 12:12:53 +01:00
29c09ab381 bugfix udpport mixup for udpport2 in commands 2019-01-15 12:12:14 +01:00
8738700e8a insignificant 2019-01-15 11:58:59 +01:00
c1c302f740 removing networkPArameter function complete 2019-01-14 20:42:15 +01:00
bc9d5718c9 typo 2019-01-14 15:38:48 +01:00
991567ba1c strcpy and cleanup of configuremac 2019-01-14 15:33:35 +01:00
f0b29cfecc signatures fixed for setnetworkparameter 2019-01-14 15:26:58 +01:00
3c41ec4a7a in the process of splitting network parameter function 2019-01-14 10:03:40 +01:00
172c9218d1 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-11 16:56:43 +01:00
b7582e93d3 working on removing undefined beaviour in configureMAC 2019-01-11 16:56:31 +01:00
5ae31bc438 receiver bug fix: dataprocess gappixels enable check to create tempbuffer always true 2019-01-11 15:21:16 +01:00
1941e90697 moench basic tearing down 2019-01-11 15:19:08 +01:00
363f4f1da0 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-11 14:49:09 +01:00
1bbb352743 jungfrau server: pll moved out to remove redundancy 2019-01-11 14:48:58 +01:00
5ea5e83236 removing local variable in slsDetector::setTCPSocket and adding some const string& 2019-01-11 14:38:56 +01:00
b46fb5e9c4 deduce parallel call only on function signature and some const& 2019-01-11 12:33:11 +01:00
0841df98d4 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-11 11:27:52 +01:00
1bd0b33806 functions not overriding base and unitialized use 2019-01-11 11:27:48 +01:00
de2ebad2ed receiver: removed unused silentmode from DataStreamer 2019-01-11 11:19:16 +01:00
2a988c7ffa Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-11 11:11:56 +01:00
94979b5824 changes to moench 2019-01-11 11:11:50 +01:00
c6a597c3ec minor changes and removed W flag not found 2019-01-11 11:07:50 +01:00
288ef0a514 acquiringDone not used, removing 2019-01-10 17:35:06 +01:00
818be3bb85 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-10 16:38:50 +01:00
d01e8d24c2 const std::string& for filenames etc. 2019-01-10 16:38:37 +01:00
b38a41493b bug fix, clock divider hangs due to incorrect number of arguments 2019-01-10 16:27:23 +01:00
37c22dfeb2 range based loops and bool literals 2019-01-10 16:07:47 +01:00
15235ab4fc default initializer for slsDetector 2019-01-10 16:02:29 +01:00
230c335c29 using default initializer arguments for multiSlsDetector 2019-01-10 15:53:09 +01:00
0f50b9f161 clang-tidy nullptr 2019-01-10 15:28:43 +01:00
58f97d4f46 clang-tidy push_back -> emplace_back 2019-01-10 15:24:58 +01:00
42ed65076c jungfrau server works now, need to be tested with pedestals for dac 2019-01-10 12:22:43 +01:00
b5b5ce5c37 eiger server works 2019-01-10 11:03:31 +01:00
55c57e4c3f Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-10 10:35:58 +01:00
52785c6642 gotthard server works 2019-01-10 10:35:49 +01:00
f815e7ffb6 long -> int64_t 2019-01-10 09:33:59 +01:00
0a2c1d1406 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2019-01-09 17:41:19 +01:00
b1570bde9c updated max1932, modified ltc2620 2019-01-09 17:41:10 +01:00
93ec5f5ef7 minor 2019-01-09 16:22:14 +01:00
feaa276284 range based loops 2019-01-09 14:20:48 +01:00
26f8ca3221 clang-tidy fix from NULL 0 etc to nullptr 2019-01-09 12:02:49 +01:00
b7aac059c3 moved string stuff to string_utils.h/.cpp 2019-01-09 11:19:16 +01:00
81a49babda gotthard server fixed: also for revision 1 boards 2019-01-08 11:52:14 +01:00
553633651a insignificant 2019-01-08 07:52:24 +01:00
bf4ba9d08b some minor modifications 2019-01-08 06:57:04 +01:00
4b007b003a gotthard server works, fine tuning left 2019-01-08 06:52:28 +01:00
06a6d53a3f gotthard, cmakefiles language line removed 2019-01-04 16:34:34 +01:00
bfda07d262 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-12-19 17:16:54 +01:00
a013734af8 moench and lookinginto max1932 2018-12-19 17:16:41 +01:00
84a67870a0 slight cleanup of dumpDetectorSetup 2018-12-19 16:38:18 +01:00
f161d68efc fix in ltc, added moench, separated servers, left to do max1932, client side for moench and more detailed in ctb server side 2018-12-19 16:38:18 +01:00
1ca8bf204a added string_utils and strcpy_safe 2018-12-19 15:44:21 +01:00
89d9204e1c changed fd and some unused store 2018-12-19 12:24:02 +01:00
88b9a93b3e fixed 2018-12-19 11:51:42 +01:00
1af2d95462 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-12-19 11:45:24 +01:00
d07f53cd6f removed using namespace std in slsDetectorCommand.cpp 2018-12-19 11:31:49 +01:00
6533a474d1 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-12-18 18:07:27 +01:00
7a432befa3 removed gui from meta.yaml 2018-12-17 15:19:14 +01:00
f68321af43 disable GUI in conda build 2018-12-17 15:05:22 +01:00
2dd8093905 added project to CMakeLists and path for installing 2018-12-17 14:55:19 +01:00
659faa9aaa added it back 2018-12-12 16:31:36 +01:00
feeaebb7e4 removed branch condition 2018-12-12 16:28:58 +01:00
547efc48e3 added conda recipe 2018-12-12 16:27:35 +01:00
1c59c5c4f4 in between 2018-12-12 11:20:39 +01:00
79693a38f5 in between 2018-12-12 11:20:27 +01:00
87f7563035 gothard server bug fix: conf gain val instead of always dynamic gain 2018-12-05 10:35:57 +01:00
a4de4bb475 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-12-04 16:05:17 +01:00
b3393fc18b few gotthard bug fixes, including cs mask for adc 2018-12-04 16:02:24 +01:00
4e65a1d964 gotthard server: minor fixes 2018-12-04 14:12:11 +01:00
98b5e893b1 rd strobe fifo for only analog fifos 2018-12-03 14:33:32 +01:00
8f3f9caf2b almost done with ctb update, need to do slow adcs, split to moench and ctb 2018-11-30 10:39:26 +01:00
d0665ce075 tests for socket 2018-11-29 12:21:02 +01:00
284ce30a81 starting tests 2018-11-28 14:45:50 +01:00
c19c787904 adcreg command line print 2018-11-12 15:14:37 +01:00
e3a0c1373c created AD9252 for old gotthard modules in use, it runs in both roi and non roi for old and new modules, data needs to be checked by Jiaguo to confirm some parts of the code that has FIXME to be checked later 2018-11-12 13:51:51 +01:00
8942098a90 gotthard works, data to be authenticated when personnel available 2018-11-09 15:25:26 +01:00
89fa30ee4b client compiles 2018-11-08 18:10:03 +01:00
2e37eda9d9 gotthard compiles 2018-11-08 18:09:11 +01:00
a37be4b2e3 fixed eiger server compiler errors 2018-11-08 17:22:59 +01:00
7a99d4155a fixed jungfrau server compile errors 2018-11-08 17:20:41 +01:00
91dd176a0f gotthard server done editing 2018-11-08 17:15:48 +01:00
a99584a0da removed ndac from sls_detector_module and from the servers (not used), fixed setting module by eiger bug in sending number of channels 2018-11-02 17:08:25 +01:00
d1c8d0b01c jungfrau virtual server compiles 2018-11-02 14:52:27 +01:00
833f0c164c reciever hdf5 compiling error fixed 2018-11-02 14:31:36 +01:00
742d4e6cb7 bug fix for mac addr format check 2018-11-02 14:13:59 +01:00
d55c39ef08 minor print fixe 2018-11-02 14:09:40 +01:00
a47db85350 gappixels only for eiger in receiver 2018-11-02 13:56:59 +01:00
b43be57b6e jungfrau server works 2018-11-02 13:50:00 +01:00
92123069ce virtual eiger server compiled 2018-10-31 15:13:31 +01:00
17027962ea log fix for eiger server 2018-10-31 15:02:43 +01:00
e0cbbde01d log fix for servers. eiger server done 2018-10-31 14:57:22 +01:00
aec8c031de kept the same client interface:tb changed when fixing error codes/exceptions, modified multi print, fixed roi bug in indexing to sls 2018-10-31 14:30:30 +01:00
3d40d5d058 format 2018-10-30 14:57:30 +01:00
af550b4c70 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-30 14:46:19 +01:00
70a1b87603 merge conflict resolved 2018-10-30 14:31:20 +01:00
dfa8cf7381 runs, prints right in reciever 2018-10-30 13:35:20 +01:00
92fc837eb4 compiles, but doesnt run 2018-10-29 15:23:52 +01:00
33ac63d14a still updating slsdetector.cpp 2018-10-26 17:40:18 +02:00
cf87b6ca83 still updating slsdetector.cpp 2018-10-25 16:24:05 +02:00
261849d69c eiger server compiles, client side of interface to do 2018-10-23 16:20:40 +02:00
129e12fd97 moved test framework 2018-10-22 11:21:18 +02:00
ab2eb607c8 replced usleep with chrono and thread 2018-10-19 15:47:36 +02:00
5671f1c87b using split in add multiple detectors 2018-10-19 10:30:31 +02:00
ff440f1325 clang-format on multi detector 2018-10-19 10:23:06 +02:00
dfad145e14 still in the process of interfacing det and client 2018-10-18 18:08:34 +02:00
500304024d added base clang format 2018-10-18 17:06:43 +02:00
86fb843021 in the process of rewriting detector client interface 2018-10-18 10:58:48 +02:00
c95bc84458 formatting 2018-10-17 18:13:01 +02:00
058de39d40 const qualifying 2018-10-17 17:51:26 +02:00
b44039361d renamed joinThread getter setter 2018-10-17 17:47:19 +02:00
0070a79838 removed command threaded 2018-10-17 17:35:55 +02:00
1d14dc6ff4 void signature of processData 2018-10-17 16:58:09 +02:00
1d65063088 using std::mutex and std::thread in multi detector 2018-10-17 16:56:01 +02:00
5c2ff84c0e removed unused variable numberofJobs in receiver implementation 2018-10-17 11:39:27 +02:00
42c4e3e1a1 cleanup 2018-10-16 17:47:48 +02:00
014dfaa251 moved to vector of unique pointer in slsReceiverImplementation 2018-10-16 17:30:43 +02:00
b50d359ee6 better name 2018-10-16 15:53:01 +02:00
b5a2c91873 removed printf with same source and dest 2018-10-16 15:50:51 +02:00
3c9b1884d3 removed conditional operator and moved to range for 2018-10-16 15:25:15 +02:00
66e79dc9a9 refactoring startReadout 2018-10-16 15:08:59 +02:00
5b8dfd7943 range based for loops for reset acq count 2018-10-16 14:34:34 +02:00
178b832223 funcs name only in c++, bug fix:slsdetectorusers not deleting multislsdetectorcommand object, bug fix: programfpga does not delete fpgasrc malloc if returning in failure 2018-10-12 17:37:39 +02:00
8df63b7767 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-12 17:03:28 +02:00
8382d0f5f9 receiver tcp interface updated 2018-10-12 17:03:19 +02:00
1e2ffae690 setNetworkParameter dont split strings 2018-10-12 11:56:47 +02:00
f6357a667f setSettingsDir works as the other functions 2018-10-12 11:39:11 +02:00
4cdd766a8e cleaning readConfigFile 2018-10-12 09:57:46 +02:00
c3289a973f cleaned up read config file slightly 2018-10-11 17:45:57 +02:00
e921dbb6a7 minor 2018-10-11 16:46:34 +02:00
1895ee1ebe minor 2018-10-11 16:19:44 +02:00
22e8c52bd8 more style 2018-10-11 16:08:02 +02:00
c31c851e88 moved communication, jungfrau 2018-10-11 15:58:49 +02:00
565739f6a2 eiger server, moved comunication_funcs 2018-10-11 15:55:08 +02:00
43c6cae25b Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-11 15:53:42 +02:00
d2c8c0a2eb gotthard server, moved communication_funcs to slsDetectorServer 2018-10-11 15:53:30 +02:00
d96cbe02a2 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-11 15:52:48 +02:00
795e147e7d stylistic cleanup 2018-10-11 15:52:39 +02:00
f806759af3 const string& 2018-10-11 15:25:29 +02:00
316ba01297 size of writeConfigFile 2018-10-11 15:19:26 +02:00
a28932bb6c Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-11 14:43:47 +02:00
4d69b6d3a1 added address sanitizer for debug mode 2018-10-11 14:43:32 +02:00
302f31678f updated gotthard binary, not run 2018-10-11 14:40:52 +02:00
32924def33 updated jungfrau server binary 2018-10-11 14:33:13 +02:00
ee20932392 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-11 14:20:58 +02:00
0ee7f67965 detector servers moved out of slsdetector software, eiger server compiles with new headers 2018-10-11 14:20:50 +02:00
c24a9b223c combined all the funcs into one, servers need to be recompiled 2018-10-11 13:57:47 +02:00
f7809bda3b Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-11 13:54:37 +02:00
5682466356 remove pointers and try block from get detector type 2018-10-11 13:54:25 +02:00
b82fca2c8e removed warnings 2018-10-11 13:32:24 +02:00
576de404d4 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-11 12:25:27 +02:00
5a356534e6 refactor receiver client interface, moved defs into one sls_detector_defs.h 2018-10-11 12:25:18 +02:00
f735c86b93 removing more pointers 2018-10-11 12:14:46 +02:00
6aa0029580 changing pointers to local variables 2018-10-11 12:08:07 +02:00
2216574d34 check empty instead of strcmp 2018-10-11 11:51:54 +02:00
d0950ba001 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-10 18:11:23 +02:00
f69e9d0df4 refactored client interface (client ot receiveR) 2018-10-10 18:09:14 +02:00
8dc0d72028 minor formatting 2018-10-10 17:46:28 +02:00
5f6f276f70 moved initDetectorStructure into initSharedMemory 2018-10-10 17:41:13 +02:00
fd7060ef6c removed pointer to shared memory in some multi functions 2018-10-10 14:18:47 +02:00
e1d570e8ce client specifies index of receiver returned error, skeleton of including clientinterface in receiver 2018-10-10 13:15:16 +02:00
6d9530ee1d Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-10 12:24:20 +02:00
b981fe78ef connected command to execute command in receiver pc 2018-10-10 12:23:55 +02:00
2cd0841ea3 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-10 12:17:36 +02:00
74bd223fda minor cleanup 2018-10-10 12:17:28 +02:00
6147383677 commented out concatResultOrPos which seems not to be used 2018-10-10 12:01:30 +02:00
5e7e7d3c33 moved client interface to common folder as receiver wills tart using it as well 2018-10-10 12:00:47 +02:00
938dd5e06c Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-10 11:55:49 +02:00
d685cb8ff4 moved detectors and zmqSocket to unique pointers 2018-10-10 11:55:37 +02:00
78bfc9d0a5 insignificant, renamed recieverInterface to have a capital letter in class name 2018-10-10 11:43:35 +02:00
4b166b726e bug fix, start receiver fail does not return 2018-10-10 11:24:17 +02:00
9ca163dfc9 adding std::launch:async parameter to make it parallel by default for sl7 (seems default for fedora) 2018-10-10 10:51:32 +02:00
f2da42a305 overwrite enabled by default 2018-10-10 10:28:38 +02:00
64f4188a00 removed ms mutex , not used anyway 2018-10-10 10:16:41 +02:00
17a6322f7c receiver runs but does not overwrite due to wx, async doesnt seems parallel problem, acquire gets stuck 2018-10-10 10:12:58 +02:00
8151f1d5fe receiver compiles 2018-10-09 18:02:47 +02:00
7d5b24fe33 solved errors with client compile, rxr yet to do 2018-10-09 13:43:50 +02:00
4bcc24a59f some more changes, yet to do receiver 2018-10-09 12:31:12 +02:00
45b00c4e7d gotthard server updated, yet to run 2018-10-09 10:24:17 +02:00
923a7e8936 eiger and jungfrau server compiles, gotthard and receiver left to do 2018-10-08 14:38:35 +02:00
b9f97f42a6 recovered readme.md 2018-10-08 10:47:16 +02:00
f7a6938366 client moved everythign from common files to slsSupportLin/include 2018-10-08 10:45:56 +02:00
70f55ff788 removed MySocketTCP.cpp 2018-10-08 10:24:57 +02:00
7ffa72092f moved patterngenerator to slsDetectorServers, removed commitVersions 2018-10-08 10:12:28 +02:00
1c78400369 client compiles, more changes required 2018-10-08 09:34:08 +02:00
b5c35ddeac slsdetector and users updated to reflect new signatures, not yet compiled 2018-10-05 15:28:25 +02:00
ab8b07f2ee client multi is updated with argument c++11 threading, need to update sls detector with arguments and removing imod 2018-10-04 17:24:37 +02:00
1c70f9ec65 mutli.cpp updated half (without masking multi error and no check on detectors boundaries for adding exceptions later. done upto savecalibrationfile 2018-10-03 17:56:04 +02:00
251a7c2446 Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-03 15:28:22 +02:00
cf37725e04 updated command.cpp to have all the indices including default ones 2018-10-03 15:28:08 +02:00
287cd118b0 example 2018-10-03 14:56:56 +02:00
21ca289ebf Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor 2018-10-03 14:51:44 +02:00
02acaf13c5 added example 2018-10-03 14:51:35 +02:00
c6d2902539 updating indices in slsdetectorcommand 2018-10-03 14:31:43 +02:00
2aa7e7d2ff added catch for unit testing 2018-10-03 14:04:40 +02:00
fefdf8e7d6 slsSupportLib and parallel call using variadic templates 2018-10-03 14:02:41 +02:00
6bfc212f19 client multi.cpp some more changes 2018-10-03 12:53:50 +02:00
a1b24a637b client multi.cpp modified common out of bounds error 2018-10-03 12:47:20 +02:00
40ae74bb99 client multi.cpp getid and checkversioncompatibility are examples of how it might look like 2018-10-03 12:31:00 +02:00
586c664a43 client multi.h comments and some signature updated 2018-10-03 11:57:18 +02:00
fdcd633769 client: multi added indices for detpos in function signature for required 2018-10-03 11:41:50 +02:00
70ea4b48c3 client: removed slsDetectorutils and postprocessing. yet to compile, yet to add detpos index for every multi sls detector command and call from command interface, removed multiple threading, yet to interface with eriks single template for multiple threading 2018-10-03 11:15:39 +02:00
dafbc970e3 client stage2 ongoing, utils removed but not compile ready; left to do imod for every multi, connect client to multi 2018-10-02 18:13:00 +02:00
100c1b81f8 moved all the common header files from receiverSoftware to commonFiles 2018-10-02 16:32:37 +02:00
757bc89d05 moved common files outside slsDetectorSoftware 2018-10-02 16:07:53 +02:00
97934e323c removed actions 2018-10-02 15:51:58 +02:00
f4cfafb2bb removed calibration folder 2018-10-02 15:17:41 +02:00
c248b12455 refactored ONLY THE CLIENT first stage, compiles 2018-10-02 15:15:35 +02:00
925 changed files with 76237 additions and 141192 deletions

6
.clang-format Normal file
View File

@ -0,0 +1,6 @@
BasedOnStyle: LLVM
IndentWidth: 4
UseTab: Never
ColumnLimit: 100
AlignConsecutiveAssignments: false

7
.clang-tidy Normal file
View File

@ -0,0 +1,7 @@
---
Checks: '*, -google-runtime-references, -hicpp-no-array-decay, -cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-bounds-pointer-arithmetic, -fuchsia*,-readability-else-after-return,-readability-avoid-const-params-in-decls,-hicpp-signed-bitwise,-cppcoreguidelines-pro-bounds-constant-array-index,-llvm-header-guard,-readability-static-accessed-through-instance,-google-readability-todo'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
FormatStyle: none
...

6
.gitignore vendored
View File

@ -6,6 +6,12 @@ bin/
*.log
*.out
*.toc
*.o
build
docs/
RELEASE.txt
*.pyc
*/__pycache__/*

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "python/pybind11"]
path = python/pybind11
url = https://github.com/pybind/pybind11.git

48
.travis.yml Normal file
View File

@ -0,0 +1,48 @@
sudo: false
language: cpp
os: linux
env:
matrix:
- CONDA_PY=3.6
- CONDA_PY=3.7
dist: trusty
install:
- sudo apt-get update
- ldd --version
- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH"
- rm -f miniconda.sh
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda config --add channels conda-forge
- conda config --add channels slsdetectorgroup
- conda update conda
- conda update --all
- conda install conda-build anaconda-client
# Useful for debugging any issues with conda
- conda info -a
# Replace dep1 dep2 ... with your dependencies
- conda create -q -n test-environment python=$CONDA_PY
- source activate test-environment
- conda-build .
script:
- echo "No test scripts to be run!"
deploy:
provider: script
script: find $HOME/miniconda/conda-bld/${TRAVIS_OS_NAME}-64 -name "*.tar.bz2" -exec anaconda -t $CONDA_TOKEN upload --force {} \;
on:
all_branches: true

View File

@ -1,57 +1,134 @@
cmake_minimum_required(VERSION 2.8)
# cmake_minimum_required(VERSION 3.5)
project(slsDetectorPackage)
include(cmake/project_version.cmake)
# Include additional modules that are used unconditionally
include(GNUInstallDirs)
# If conda build, always set lib dir to 'lib'
if($ENV{CONDA_BUILD})
set(CMAKE_INSTALL_LIBDIR "lib")
endif()
# Set lower / upper case project names
string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER)
string(TOLOWER "${PROJECT_NAME}" PROJECT_NAME_LOWER)
# Set targets export name (used by slsDetectorPackage and dependencies)
set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWER}-targets")
#set(namespace "${PROJECT_NAME}::")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
set (CALIBRATE OFF)
option (USE_HDF5 "HDF5 File format" OFF)
option (USE_TEXTCLIENT "Text Client" OFF)
option (USE_RECEIVER "Receiver" OFF)
option (USE_GUI "GUI" OFF)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++98 -Wno-misleading-indentation")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++98")
endif ()
# Check if project is being used directly or via add_subdirectory
set(SLS_MASTER_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(SLS_MASTER_PROJECT ON)
endif()
find_package(Qt4)
find_package(Qwt 6)
find_package(CBF)
find_package(Doxygen)
# find_package(PNG REQUIRED)
if (USE_HDF5)
find_package(HDF5 1.10 COMPONENTS CXX)
endif (USE_HDF5)
option (SLS_USE_HDF5 "HDF5 File format" OFF)
option (SLS_USE_TEXTCLIENT "Text Client" OFF)
option (SLS_USE_RECEIVER "Receiver High Level API" OFF)
option (SLS_USE_LISTENER "Receiver Low Level API" OFF)
option (SLS_USE_GUI "GUI" OFF)
option (SLS_USE_TESTS "TESTS" ON)
option (SLS_USE_INTEGRATION_TESTS "Integration Tests" ON)
option(SLS_USE_SANITIZER "Sanitizers for debugging" OFF)
option(SLS_USE_PYTHON "Python bindings" OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#Testing for minimum version for compilers
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# clang does not support -Wno-misleading-indentation
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.2)
message(FATAL_ERROR "Clang version must be at least 3.2!")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
message(FATAL_ERROR "GCC version must be at least 4.8!")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-misleading-indentation -Wno-stringop-truncation -Wno-class-memaccess")
endif()
# Suppressed warnings in GCC
# -Wno-stringop-truncation happens when we do sls::strcpy_safe truncates string instead of overwrite buffer
# -Wno-class-memaccess - on memcpy in rapidjson should be investigated upgrade implementation?
# -Wno-misleading-indentation - until clang format
#set (CMAKE_CXX_STANDARD 11)
#set (CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11 ")
if(SLS_USE_SANITIZER)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address,undefined")
set (CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address,undefiend")
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INSTALL_RPATH "$ORIGIN")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
if (USE_TEXTCLIENT)
add_subdirectory(slsDetectorSoftware)
endif (USE_TEXTCLIENT)
if (USE_RECEIVER)
add_subdirectory(slsReceiverSoftware)
add_subdirectory(manual/manual-api)
endif (USE_RECEIVER)
if (USE_GUI)
if (QT4_FOUND AND QWT_FOUND)
add_subdirectory(slsDetectorGui)
endif()
endif (USE_GUI)
find_package(Doxygen)
find_package(ZeroMQ 4 REQUIRED)
if (CALIBRATE)
if (DEFINED ENV{ROOTSYS})
find_package(ROOT)
if (ROOT_FOUND)
add_subdirectory(calibrationWizards)
endif()
# Support library containing functionallity common to
# detector and receiver
add_subdirectory(slsSupportLib)
if (SLS_USE_TEXTCLIENT)
add_subdirectory(slsDetectorSoftware)
endif (SLS_USE_TEXTCLIENT)
# This logic could be moved in slsReceiverSoftware/CMakeLists.txt
if (SLS_USE_RECEIVER)
set(SLS_USE_LISTENER ON)
if (SLS_USE_HDF5)
find_package(HDF5 1.10 COMPONENTS CXX REQUIRED)
endif (SLS_USE_HDF5)
add_subdirectory(slsReceiverSoftware/slsReceiver)
add_subdirectory(manual/manual-api)
endif (SLS_USE_RECEIVER)
if (SLS_USE_LISTENER)
add_subdirectory(slsReceiverSoftware/slsListener)
endif (SLS_USE_LISTENER)
if (SLS_USE_GUI)
find_package(Qt4 REQUIRED)
find_package(Qwt 6 REQUIRED)
if (QT4_FOUND AND QWT_FOUND)
add_subdirectory(slsDetectorGui)
endif()
endif(CALIBRATE)
endif (SLS_USE_GUI)
if (SLS_USE_TESTS)
enable_testing()
endif(SLS_USE_TESTS)
if (SLS_USE_INTEGRATION_TESTS)
add_subdirectory(integrationTests)
endif (SLS_USE_INTEGRATION_TESTS)
if (SLS_USE_PYTHON)
add_subdirectory(python)
endif(SLS_USE_PYTHON)
if(SLS_MASTER_PROJECT)
# Set install dir CMake packages
set(CMAKE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/cmake/sls)
# Set the list of exported targets
set(PROJECT_LIBRARIES slsSupportLib slsDetectorShared slsReceiverShared)
# Generate and install package config file and version
include(cmake/package_config.cmake)
endif()

235
Makefile
View File

@ -1,235 +0,0 @@
# do not change below this line#
# Include common definitions
include Makefile.include
INSTALLROOT ?= $(PWD)
BINDIR ?= $(INSTALLROOT)/bin
DOCDIR ?= $(INSTALLROOT)/manual/docs
LIBDIR ?= $(INSTALLROOT)/bin
INCDIR ?= $(INSTALLROOT)/include
DETAILDOC ?= $(INSTALLROOT)/docs
WD = $(shell pwd)
LIBRARYDIR = $(WD)/slsDetectorSoftware
LIBRARYRXRDIR = $(WD)/slsReceiverSoftware
CLIENTDIR = $(LIBRARYDIR)/slsDetectorClient
GUIDIR = $(WD)/slsDetectorGui
RECEIVERDIR = $(LIBRARYRXRDIR)
CALWIZDIR = $(WD)/calibrationWizards
MANDIR = $(WD)/manual
CALIBDIR = $(WD)/slsDetectorCalibration
MANAPIDIR = $(MANDIR)/manual-api
TABSPACE := "\t"
INCLUDES=-I. -I$(LIBRARYDIR)/commonFiles -I$(LIBRARYDIR)/slsDetector -I$(LIBRARYDIR)/usersFunctions -I$(LIBRARYDIR)/multiSlsDetector -I$(LIBRARYDIR)/slsDetectorUtils -I$(LIBRARYDIR)/slsDetectorCommand -I$(LIBRARYDIR)/slsDetectorAnalysis -I$(LIBRARYDIR)/slsReceiverInterface -I$(LIBRARYRXRDIR)/include -I$(LIBRARYDIR)/threadFiles -I$(LIBRARYDIR)/sharedMemory -I$(ASM)
INCLUDESRXR += -I. -I$(LIBRARYRXRDIR)/include -I$(CALIBDIR) -I$(ASM)
#LIBFLAGRXR +=
$(info )
$(info #######################################)
$(info # In slsDetectorsPackage Makefile #)
$(info #######################################)
$(info )
.PHONY: all nonstatic static lib libreceiver textclient receiver gui stextclient sreceiver
#all: lib textclient receiver gui
all: textclient receiver gui
nonstatic: lib libreceiver textclient receiver gui
static: lib libreceiver stextclient sreceiver gui
lib:
cd $(LIBRARYDIR) && $(MAKE) FLAGS='$(FLAGS)' DESTDIR='$(LIBDIR)' LIBRARYDIR='$(LIBRARYDIR)' LIBS='$(LDFLAGDET)' INCLUDES='$(INCLUDES)' LIBDIR='$(LIBDIR)'
libreceiver:
cd $(LIBRARYRXRDIR) && $(MAKE) FLAGS='$(FLAGS)' DESTDIR='$(LIBDIR)' LIBS='$(LDFLAGRXR)' INCLUDES='$(INCLUDESRXR)' LIBDIR='$(LIBDIR)'
stextclient: slsDetectorClient_static
slsDetectorClient: textclient
slsDetectorClient_static: #lib
cd $(CLIENTDIR) && $(MAKE) static_clients FLAGS='$(FLAGS)' DESTDIR='$(BINDIR)' LIBRARYDIR='$(LIBRARYDIR)' LIBS='$(LDFLAGDET)' INCLUDES='$(INCLUDES)' LIBDIR='$(LIBDIR)'
@echo ""
@echo "#######################################"
@echo "# Back in slsDetectorPackage Makefile #"
@echo "#######################################"
@echo ""
textclient: #lib
cd $(CLIENTDIR) && $(MAKE) FLAGS='$(FLAGS)' DESTDIR='$(BINDIR)' LIBRARYDIR='$(LIBRARYDIR)' LIBS='$(LDFLAGDET)' INCLUDES='$(INCLUDES)' LIBDIR='$(LIBDIR)'
@echo ""
@echo "#######################################"
@echo "# Back in slsDetectorPackage Makefile #"
@echo "#######################################"
@echo ""
slsReceiver: receiver
slsReceiver_static: receiver
receiver: #libreceiver
# cd $(RECEIVERDIR) && $(MAKE) receiver FLAGS='$(FLAGS)' DESTDIR='$(BINDIR)' LIBS='$(LDFLAGRXR)' INCLUDES='$(INCLUDESRXR)' LIBDIR='$(LIBDIR)'
cd $(RECEIVERDIR) && $(MAKE) FLAGS='$(FLAGS)' DESTDIR='$(BINDIR)' LIBS='$(LDFLAGRXR)' INCLUDES='$(INCLUDESRXR)' LIBDIR='$(LIBDIR)'
cd $(MANAPIDIR) && $(MAKE) slsMultiReceiver
@echo ""
@echo "#######################################"
@echo "# Back in slsDetectorPackage Makefile #"
@echo "#######################################"
@echo ""
sreceiver: #libreceiver
cd $(RECEIVERDIR) && $(MAKE) static_receiver FLAGS='$(FLAGS)' DESTDIR='$(BINDIR)' LIBS='$(LDFLAGRXR)' INCLUDES='$(INCLUDESRXR)' LIBDIR='$(LIBDIR)'
@echo ""
@echo "#######################################"
@echo "# Back in slsDetectorPackage Makefile #"
@echo "#######################################"
@echo ""
slsDetectorGUI: #lib
cd $(GUIDIR) && $(MAKE) DESTDIR='$(BINDIR)' LIBRARYDIR='$(LIBRARYDIR)' INCLUDES='$(INCLUDES)' LDFLAGDET='$(LDFLAGDETONLY)' LIBDIR='$(LIBDIR)'
@echo ""
@echo "#######################################"
@echo "# Back in slsDetectorPackage Makefile #"
@echo "#######################################"
@echo ""
calWiz:
cd $(CALWIZDIR) && $(MAKE) DESTDIR=$(BINDIR) #FLAGS=$(FLAGS) LDFLAGDET=$(LDFLAGDET) INCLUDES=$(INCLUDES)
gui: slsDetectorGUI
doc:
$(shell test -d $(DOCDIR) || mkdir -p $(DOCDIR))
cd manual && make all DESTDIR=$(DOCDIR)
htmldoc:
make doc
$(shell test -d $(DOCDIR) || mkdir -p $(DOCDIR))
cd manual && make html DESTDIR=$(DOCDIR)
detaildoc: createdocs docspdf docshtml removedocs
createdocs: $(LIBRARYDIR)/doxy.config
doxygen $(LIBRARYDIR)/doxy.config
docspdf:
cd slsDetectorPackageDocs/latex && make
$(shell test -d $(DETAILDOC) || mkdir -p $(DETAILDOC))
$(shell test -d $(DETAILDOC)/pdf || mkdir -p $(DETAILDOC)/pdf)
mv slsDetectorPackageDocs/latex/refman.pdf $(DETAILDOC)/pdf/slsDetectorPackageDocs.pdf
docshtml:
$(shell test -d $(DETAILDOC) || mkdir -p $(DETAILDOC))
$(shell test -d $(DETAILDOC)/html || mkdir -p $(DETAILDOC)/html)
$(shell test -d $(DETAILDOC)/html/slsDetectorPackageDocs && rm -r $(DETAILDOC)/html/slsDetectorPackageDocs)
mv slsDetectorPackageDocs/html $(DETAILDOC)/html/slsDetectorPackageDocs
removedocs:
rm -rf slsDetectorPackageDocs;
clean:
cd $(BINDIR) && rm -rf sls_detector_* slsDetectorGui slsReceiver angularCalibrationWizard energyCalibrationWizard
cd $(LIBDIR) && rm -rf libSlsDetector.so libSlsDetector.a libSlsReceiver.so libSlsReceiver.a
cd $(LIBRARYDIR) && $(MAKE) clean
cd $(LIBRARYRXRDIR) && $(MAKE) clean
cd $(CLIENTDIR) && $(MAKE) clean
cd $(GUIDIR) && $(MAKE) clean
cd $(CALWIZDIR) && $(MAKE) clean
cd manual && $(MAKE) clean
cd $(DOCDIR) && rm -rf *
rm -rf slsDetectorPackageDocs;
rm -rf $(DETAILDOC)
rm -rf $(MANAPIDIR)/slsMultiReceiver
#install_lib:
# cd $(LIBRARYDIR) && $(MAKE) install DESTDIR=$(LIBDIR) INCLUDES=$(INCLUDES)
# cd $(LIBRARYDIR) && $(MAKE) install_inc DESTDIR=$(INCDIR)
mythen_virtual:
cd $(LIBRARYDIR) && $(MAKE) mythenVirtualServer DESTDIR=$(BINDIR)
gotthard_virtual:
cd $(LIBRARYDIR) && $(MAKE) gotthardVirtualServer DESTDIR=$(BINDIR)
install_client: textclient slsReceiver
install_gui: gui
confinstall:
make conf;\
make install
install_lib:
make lib;\
make libreceiver; \
make textclient; \
make slsReceiver; \
make doc; \
make htmldoc; \
cd $(LIBRARYDIR) && $(MAKE) install_inc DESTDIR=$(INCDIR); \
cd $(LIBRARYRXRDIR) && $(MAKE) install_inc DESTDIR=$(INCDIR);
install:
make install_lib; \
make gui; \
make calWiz; \
cd $(LIBRARYDIR) && $(MAKE) install_inc DESTDIR=$(INCDIR);\
cd $(LIBRARYRXRDIR) && $(MAKE) install_inc DESTDIR=$(INCDIR);
conf:
set -e; \
. ./configure; \
@echo "INSTALLROOT is $(INSTALLROOT)"
@echo "BINDIR is $(BINDIR)"
@echo "LIBDIR is $(LIBDIR)"
@echo "INCDIR is $(INCDIR)"
@echo "DOCDIR is $(DOCDIR)"
help:
@echo "Targets:"
@echo "make all compile library, text clients, data reciever"
@echo "make lib compile library"
@echo "make libreceiver compile receiver library"
@echo "make textclient compile the slsDetectorClient dynamically linking the libraries"
@echo "make stextclient compile slsDetectorClient statically linking the libraries"
@echo "make receiver compile the slsReciever dynamically linking the libraries"
@echo "make sreceiver compile the slsReciever statically linking the libraries"
@echo "make gui compile slsDetectorGUI - requires a working Qt4 and Qwt installation"
@echo "make calWiz compile the calibration wizards - requires a working Root installation"
@echo "make doc compile pdf documentation"
@echo "make htmldoc compile html (and pdf) documentation"
@echo "make install_lib installs the libraries, the text clients, the documentation and the includes for the API"
@echo "make install installs all software, including the gui, the cal wizards and the includes for the API"
@echo "make confinstall installs all software, including the gui, the cal wizards and the includes for the API, prompting for the install paths"
@echo "make clean remove object files and executables"
@echo "make help lists possible targets"
@echo ""
@echo ""
@echo "Makefile variables"
@echo "DEBUG=1,2 set debug level to 1 (VERBOSE) or 2 (VERYVERBOSE)"
@echo ""
@echo ""
@echo "Variables - to change them run <source configure> :"
@echo "INSTALLROOT=<yourdir>: installation root di r, default $PWD"
@echo "BINDIR=<yourbin>: binary installation dir below INSTALLROOT, default bin"
@echo "LIBDIR=<yourlib>: library installation dir below INSTALLROOT, default lib"
@echo "INCDIR=<yourincludes>: header installation dir below INSTALLROOT, default include"
@echo "DOCDIR=<yourdoc>: documentation installation dir below INSTALLROOT, default doc"

View File

@ -1,58 +0,0 @@
##############################################################
# Generic
##############################################################
CC = g++
CXX = $(CC)
ASM=$(shell echo "/lib/modules/`uname -r`/build/include")
LDFLAGDETONLY = -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsDetector
LDFLAGDET = -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsDetector -L/usr/lib64/ -pthread
LDFLAGRXR = -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -pthread
FLAGS= -Wall -pthread #-DEIGER_DEBUG2
# -DVERBOSE
# Setting up the verbose flags
ifeq ($(DEBUG),1)
FLAGS = -Wall -DVERBOSE
endif
ifeq ($(DEBUG),2)
FLAGS = -Wall -DVERYVERBOSE
endif
##############################################################
# HDF5 specific. Set this to yes, if you want to compile
# HDF5 code: in this case, you need HDF5 libraries
##############################################################
HDF5 = no
HDF5_DIR = /opt/hdf5v1.10.0
ifeq ($(HDF5),yes)
LDFLAGRXR = -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsReceiver -L$(HDF5_DIR)/lib -Wl,-rpath=$(HDF5_DIR)/lib -lhdf5 -lhdf5_cpp -lsz -lz -DHDF5C -L/usr/lib64/ -pthread
INCLUDESRXR = -I$(HDF5_DIR)/include
endif
##############################################################
# ROOTSLS specific. Set this to yes, if you want to compile
# ROOTSLS code: in this case, you need also root libraries
##############################################################
ROOTSLS = no
ROOTFLAGS = $(shell root-config --cflags --glibs) -DMYROOT1 #-DALLFILE_DEBUG #-DMYROOT1
ifeq ($(ROOTSLS),yes)
LDFLAGRXR = -L$(LIBDIR) -lSlsReceiver $(ROOTFLAGS) -DROOTSLS
endif
define colorecho
@tput setaf 6
@echo $1
@tput sgr0
endef

View File

@ -75,13 +75,13 @@ Use cmake to create out-of-source builds, by creating a build folder parallel to
$ cd ..
$ mkdir slsDetectorPackage-build
$ cd slsDetectorPackage-build
$ cmake ../slsDetectorPackage -DCMAKE_BUILD_TYPE=Debug -DUSE_HDF5=OFF
$ cmake ../slsDetectorPackage -DCMAKE_BUILD_TYPE=Debug -DSLS_USE_HDF5=OFF
$ make
```
Use the following as an example to compile statically and using specific hdf5 folder
```
$ HDF5_ROOT=/opt/hdf5v1.10.0 cmake ../slsDetectorPackage -DCMAKE_BUILD_TYPE=Debug -DUSE_HDF5=ON
$ HDF5_ROOT=/opt/hdf5v1.10.0 cmake ../slsDetectorPackage -DCMAKE_BUILD_TYPE=Debug -DSLS_USE_HDF5=ON
```
After compiling, the libraries and executables will be found at `bin` directory
```

View File

@ -1,508 +0,0 @@
SLS Detector Package 4.0.0 released on 27.09.2018
=================================================
INTRODUCTION
This document describes the differences between 4.0.0 and 3.1.4 releases.
Download
--------
The Source Code (Default C++ API):
https://github.com/slsdetectorgroup/slsDetectorPackage
The Conda Lib Package:
https://github.com/slsdetectorgroup/sls_detector_lib
The Conda GUI Package:
https://github.com/slsdetectorgroup/sls_detector_gui
The Python Interface (including the package):
https://github.com/slsdetectorgroup/sls_detector
Documentation
-------------
Manual (HTML & PDF):
https://www.psi.ch/detectors/documentation
slsDetectorPackage/manual/docs/
Command Line Documentation:
manual/docs/html/slsDetectorClientDocs/index.html
manual/docs/pdf/slsDetectorClientDocs.pdf
C++ API Documentation:
manual/docs/html/slsDetectorUsersDocs/index.html
manual/docs/pdf/slsDetectorUsersDocs.pdf
C++ API Example:
manual/manual-api/mainClient.cpp
manual/manual-api/mainReceiver.cpp
Python API Documentation:
https://slsdetectorgroup.github.io/sls_detector/
Further Documentation:
https://www.psi.ch/detectors/users-support
Support
-------
General Software related:
dhanya.thattil@psi.ch
anna.bergamaschi@psi.ch
Python related:
erik.frojdh@psi.ch
CONTENTS
1. Firmware Requirements
2. Changes in User Interface
3. New/Modified Commands
4. Other New Features
5. Resolved Issues
6. Known Issues
7. Next Major Release Plans
1. Firmware Requirements
========================
Gotthard
========
Minimum compatible version : 11.01.2013
Latest version : 08.02.2018 (50um and 25um Master)
09.02.2018 (25 um Slave)
Eiger
=====
Minimum compatible version : 22
Latest version : 22
Jungfrau
========
Minimum compatible version : 15.06.2018
Latest version : 15.06.2018
Detector Upgrade
================
Gotthard Cannot be upgraded remotely. Requires programming via USB blaster
Eiger Can be upgraded remotely via bit files
Jungfrau Can be upgraded remotely using sls_detector_put programfpga <pof>
Instructions available at
https://www.psi.ch/detectors/installation-instructions
under Detector Upgrade -> [Detector Type] -> Firmware.
Please refer to the link below for more details on the firmware versions.
https://www.psi.ch/detectors/firmware.
2. Changes in User Interface
============================
Client
------
1. Shared Memory:
POSIX shared memory has been implemented and they are typically created in
/dev/shm/ folder.
A multiSlsDetector object will create a shared memory segment with naming style:
slsDetectorPackage_x_[_z]
and an slsDetector object will create a shared memory segment with naming style:
slsDetectorPackage_x_sls_y[_z]
where
x is the multi detector id
y is the sls detector id
z is the environment variable SLSDETNAME, if set.
They can be deleted directly.
Environment variable SLSDETNAME included for user-friendliness
of using 2 different detectors from the same client pc. One needn't use
different multi detector id if the SLSDETNAME is different for both consoles.
Constructor will fail if shared memory size is different (different package
releases/detectors). Loading config file cleans shared memory.
2. Exceptions in constructors:
All constructors that have an error throws an exception. For this release,
this is caught within the package and interfaced as error codes or messages
to the users using command line or API.
As a result:
- slsDetectorsUsers constructor signature now includes a success flag.
- If one uses multiSlsDetector, slsDetector, ZmqSocket classes directly,
catch exceptions from constructors.
- In future releases, the exception will be thrown
outside the package for the users to handle it.
3. API Compatibility:
Client now checks API version of Detector Server - Client and Receiver - Client
when connecting for the first time to detector server or receiver server
and the online flags have not been set in shm.
Upon failure, error messages will ensue and further commands will not
be executed. Detector servers referred to are only for Eiger, Jungfrau and Gotthard.
Previously, the detector server would exit on mismatched Firmware-Detector
server mismatch. They now wait for client to ask for compatibility check,
which is done the first time client connects to the detector and the
online flag in shm has not been set.
4. Commands "type", "id" and "replace" are removed.
Receiver
--------
1. Reciever Header Structure in file writing and call back:
sls_receiver_header structure added to sls_receiver_defs.h for image headers
in file writing.
#define MAX_NUM_PACKETS 512
typedef std::bitset<MAX_NUM_PACKETS> sls_bitset;
typedef struct {
sls_detector_header detHeader; /**< is the detector header */
sls_bitset packetsMask; /**< is the packets caught bit mask */
} sls_receiver_header;
It includes the detector header structure + bitmask of 512 bits,
where each bit represents a packet caught. This is useful in saving time
in writing to file by not padding missing packets and still retaining useful data.
The binary and HDF5 writer version number changed from 1.0 to 2.0.
The detector header version remains as 1.0.
registerCallBackRawDataReady modified to give this structure pointer,
instead of individual structure member pointers.
2. ZmqSocket class:
If one uses ZmqSocket.h, then the json header has to be parsed outside
the class to allow the user to remove the restriction in extracting all data
from the json header.
3. Receiver Call back with modified size:
registerCallBackRawDataModifyReady call back that is similar to the receiver
registerCallBackRawDataReady has been added to allow the call back to
specify an updated size of image after call back. This is in view to process
an image in call back (including extract only a region of the image) and
provide this updated size in callback. This new resized/processed image
will be written to file or streamed out via zmq. This is useful in ROI
selection in the receiver.
This also means that the call back is now called before writing to file.
3. New/Modified Commands
========================
Client
------
1. add (modified):
appends detector to end of multi detector list.
2. replace:
sets hostname/ip address for a single detector.
3. user:
get user details from shared memory.
4. checkdetversion:
checks client version compatibility with detector server.
5. checkrecversion:
checks client version compatibility with receiver server.
Receiver
--------
1. rx_zmqip:
sets/gets the zmq (TCP) ip of the receiver from where data is streamed
out from. (Eg. to the gui or intermediate process). By default, it is
the same as the zmqip.
2. zmqip:
sets/gets the zmq (TCP) ip, where client listens to, to reconstuct images.
(Eg. from receiver or intermediate process). By default, it is the same
as rx_zmqip.
3. rx_jsonaddheader:
sets/gets additional json header to be streamed out with the zmq from
receiver. Default is empty. Eg. p rx_jsonaddheader \"what\":\"nothing\"
4. r_discardpolicy:
sets/gets the frame discard policy in the receiver.
nodiscard - no discard (default),
discardempty - discard only empty frames,
discardpartial - discard any partial frame(fastest)
5. r_padding:
sets/gets the frame padding in the receiver.
0 does not pad partial frames(fastest),
1 (default) pads partial frames.
One can look at bitmask in the sls_receiver_header to process the unpadded
partial frames later.
6. activate (modified):
Extra option added to pad or unpad images in receivers when deactivated.
activate i [padding option], where i is activate/deactivate and padding
option is "padding" (default) or "nopadding".
7. rx_udpsocksize:
sets/gets the UDP socket buffer size. Already attempts to set by default
to 100mb, 2gb for Jungfrau. Does not remember custom values in client
shared memory, so must be initialized each time after setting receiver
hostname in config file.
8. rx_realudpsocksize:
gets the actual UDP socket buffer size. Usually double the set udp socket
buffer size due to kernel bookkeeping.
9. r_framesperfile:
sets/gets the frames per file in receiver. 0 means infinite or all frames
in a single file. Default of Eiger changed from 2k to 10k.
Eiger Specific
--------------
1. status trigger:
To trigger internally via software, one can use "status trigger".
2. subdeadtime:
sets/gets sub frame dead time in s in 32 bit mode. Subperiod is set in
the detector by subexptime + subdeadtime. This value is normally a
constant set by an expert catered to individual detector modules in the
config file. Receiver files writes master file metadata subperiod
instead of subdeadtime.
3. gappixels:
enables/disables gap pixels in system (detector & receiver). 1 sets,
0 unsets. In Receiver, 4 bit gap pixels mode is not implemented, but is
implemented in client data call back. Gap pixels are at module level
and not at multi module level.
4. measuredperiod:
gets the measured frame period (time between last frame and the previous
one) in s. Makes sense only for acquisitions of more than 1 frame.
5. measuredsubperiod:
gets the measured subframe period (time between last subframe and the
previous one) in s in 32 bit mode.
6. flags(modified):
extra flags "nooverflow" (default) and "overflow" for sub images in 32
bit mode. If set to overflow, it will set MSB of pixel data high if
there was any saturation in any of the sub images 32 bit mode.
Jungfrau Specific
-----------------
1. storagecells:
sets/gets number of additional storage cells per acquisition. For very
advanced users only. Range: 0-15. Default: 0.
The #images = #frames * #cycles * (#storagecells +1).
2. storage_start:
sets/gets the storage cell that stores the first acquisition of the series.
For very advanced users only. Range: 0-15. Default: 15(0xf).
4. Other New Features
=====================
Client
------
1. (Jungfrau & Gotthard) Settingsdir and caldir is removed from config file.
Default dacs are stored in detector server. Hence, these folders
are also removed from slsDetectorPackage/settingsdir. Eiger and Mythen
continue to have them.
2. Depending on 1d position of detectors and detsizechan in config file,
row and column (previously xcoord and ycoord) are given to detector
servers (Eiger and Jungfrau) to encode into the udp header.
3. (Eiger) Setting threshold energy changes such as CAL dac is irrelevant
when interpolating between two energies and VRS dac is interpolated, not copied.
4. Users API updated with the following functions:
- setReceiverFramesDiscardPolicy
- setReceiverPartialFramesPadding
- setReceiverFramesPerFile
- sendSoftwareTrigger
- setSubFrameExposureDeadTime
- setSubFrameExposureTime
- enableGapPixels
- getMeasuredPeriod
- getMeasuredSubFramePeriod
- setOverflowMode
- setNumberOfStorageCells
- setStoragecellStart
- setThresholdEnergy (overloaded)
- resetFramesCaughtInReceiver
- setReceiverFifoDepth
- setFlowControl10G
- setTenGigabitEthernet
- getNMods
- setReceiverDataStreamingOutIP
- setClientDataStreamingInIP
SlsReceiver
-----------
1. slsMultiReceiver executable added that creates multiple receiver child processes.
./slsMultiReceiver [start_tcp_port] [num_receivers] [1 for call back, 0 for none]
2. Default row and column (previously xcoord and ycoord) are hardcoded
for missing packets. (Eiger and Jungfrau)
Gui
---
1. (Jungfrau) Gain plot included. Option under 2D options in Plot tab.
2. Option to maintain aspect ratio
3. Start and Stop separated to prevent multiple click syndrome.
Detector Server
---------------
1. (Jungfrau) To use programfpga command, one must start server with -update
mode and then restart server without -update mode.
2. (Jungfrau) ASIC Timer configured at server start up and changed a few
startup values for firmware v0.7 such as adc phase, ADC_PORT_INVERT_VAL
and ADC offset half speed value.
3. (Jungfrau) Minimum exposure time of 50 us was implemented.
4. (Eiger and Jungfrau) They can be configured to have x and y coord values
of the detector in their udp header.
5. Resolved Issues
==================
Client
------
memory leak for multi threading
1. Compiler flag -std=c++98 enforced. Debug flag removed.
2. If trimen gives different list from different detectors, it returns a -1.
3. Version format for each submodule of the package changed to just date YYMMDD.
Users class fixed to give correct version, instead of -1.
4. Getting settings in users class gave -1. Fixed now.
5. (Jungfrau) Programming FPGA now creates the rawbin file from pof in tmp
rather than source file location (for permission issues).
6. (Gotthard) ROI segmentation fault fixed.
Receiver
--------
1. Silent feature of receiver fixed.
2. Socket descriptor misused earlier for success flag, instead exceptions
used that are handled inside the package.
3. Global optind variable initialized to instantiate multiple receivers
in same process. Also removed static members to enable this feature.
4. Socket buffer size attempts to set for each acquiistion and provide
warning if no capabilities. Warnings can be removed using instruction with
error provided. Default Jungfrau UDP socket buffer size if 2 GB, default is
100 MB.
5. Refactored code a bit for performance and robustness, blocking push
in buffer between listener and dataprocessor
Detector Server
---------------
1. (Jungfrau) Stop server also mapped during a reset. Reading power status
instead of user input register for power.
2. (Eiger) Bug fix for saving trimbits to file (Advanced users).
3. (Gotthard 25um) config.txt is not read again after detector startup,
no matter the number of times the detector server is restarted.
6. Known Issues
===============
Receiver
--------
1. HDF5 compression and filters are not implemented yet.
Detector Server
---------------
1. (Eiger) Registers mapped differently between firmware v20 and v22.
So, please ensure correct on-board server before switching between
firmware versions. Else one cannot ping it anymore. Will need to flash firmware
again to recover.
2. (Gotthard) To switch back to all ADC from single ADC ROI, one must take
even number of images for the receiver to understand complete images.
This will be fixed in the next firmware upgrade.
7. Next Major Release Plans
===========================
Client
------
1. Exceptions thrown to the user to be handled.
2. Compilation using c++11.
3. Support of Mythen II restricted to this major and its minor releases.
4. Restructuring and refactoring of client code.

14934
catch/catch.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
rm /dev/shm/slsDetectorPackage*;

112
cmake/FindZeroMQ.cmake Normal file
View File

@ -0,0 +1,112 @@
# This file is originally from https://github.com/zeromq/azmq and distributed
# under Boost Software Lincese 1.0
# Boost Software License - Version 1.0 - August 17th, 2003
# Permission is hereby granted, free of charge, to any person or organization
# obtaining a copy of the software and accompanying documentation covered by
# this license (the "Software") to use, reproduce, display, distribute,
# execute, and transmit the Software, and to prepare derivative works of the
# Software, and to permit third-parties to whom the Software is furnished to
# do so, all subject to the following:
# The copyright notices in the Software and this entire statement, including
# the above license grant, this restriction and the following disclaimer,
# must be included in all copies of the Software, in whole or in part, and
# all derivative works of the Software, unless such copies or derivative
# works are solely in the form of machine-executable object code generated by
# a source language processor.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
# SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
# FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
# --------------------------------------------------------------------------------
# Find ZeroMQ Headers/Libs
# Variables
# ZMQ_ROOT - set this to a location where ZeroMQ may be found
#
# ZeroMQ_FOUND - True of ZeroMQ found
# ZeroMQ_INCLUDE_DIRS - Location of ZeroMQ includes
# ZeroMQ_LIBRARIES - ZeroMQ libraries
include(FindPackageHandleStandardArgs)
if (NOT ZMQ_ROOT)
set(ZMQ_ROOT "$ENV{ZMQ_ROOT}")
endif()
if (NOT ZMQ_ROOT)
find_path(_ZeroMQ_ROOT NAMES include/zmq.h)
else()
set(_ZeroMQ_ROOT "${ZMQ_ROOT}")
endif()
find_path(ZeroMQ_INCLUDE_DIRS NAMES zmq.h HINTS ${_ZeroMQ_ROOT}/include)
if (ZeroMQ_INCLUDE_DIRS)
set(_ZeroMQ_H ${ZeroMQ_INCLUDE_DIRS}/zmq.h)
function(_zmqver_EXTRACT _ZeroMQ_VER_COMPONENT _ZeroMQ_VER_OUTPUT)
set(CMAKE_MATCH_1 "0")
set(_ZeroMQ_expr "^[ \\t]*#define[ \\t]+${_ZeroMQ_VER_COMPONENT}[ \\t]+([0-9]+)$")
file(STRINGS "${_ZeroMQ_H}" _ZeroMQ_ver REGEX "${_ZeroMQ_expr}")
string(REGEX MATCH "${_ZeroMQ_expr}" ZeroMQ_ver "${_ZeroMQ_ver}")
set(${_ZeroMQ_VER_OUTPUT} "${CMAKE_MATCH_1}" PARENT_SCOPE)
endfunction()
_zmqver_EXTRACT("ZMQ_VERSION_MAJOR" ZeroMQ_VERSION_MAJOR)
_zmqver_EXTRACT("ZMQ_VERSION_MINOR" ZeroMQ_VERSION_MINOR)
_zmqver_EXTRACT("ZMQ_VERSION_PATCH" ZeroMQ_VERSION_PATCH)
message(STATUS "ZeroMQ version: ${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}.${ZeroMQ_VERSION_PATCH}")
# We should provide version to find_package_handle_standard_args in the same format as it was requested,
# otherwise it can't check whether version matches exactly.
if (ZeroMQ_FIND_VERSION_COUNT GREATER 2)
set(ZeroMQ_VERSION "${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}.${ZeroMQ_VERSION_PATCH}")
else()
# User has requested ZeroMQ version without patch part => user is not interested in specific patch =>
# any patch should be an exact match.
set(ZeroMQ_VERSION "${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}")
endif()
if (NOT ${CMAKE_CXX_PLATFORM_ID} STREQUAL "Windows")
find_library(ZeroMQ_LIBRARIES NAMES zmq HINTS ${_ZeroMQ_ROOT}/lib)
else()
find_library(
ZeroMQ_LIBRARY_RELEASE
NAMES
libzmq
"libzmq-${CMAKE_VS_PLATFORM_TOOLSET}-mt-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}"
HINTS
${_ZeroMQ_ROOT}/lib
)
find_library(
ZeroMQ_LIBRARY_DEBUG
NAMES
libzmq_d
"libzmq-${CMAKE_VS_PLATFORM_TOOLSET}-mt-gd-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}"
HINTS
${_ZeroMQ_ROOT}/lib)
# On Windows we have to use corresponding version (i.e. Release or Debug) of ZeroMQ because of `errno` CRT global variable
# See more at http://www.drdobbs.com/avoiding-the-visual-c-runtime-library/184416623
set(ZeroMQ_LIBRARIES optimized "${ZeroMQ_LIBRARY_RELEASE}" debug "${ZeroMQ_LIBRARY_DEBUG}")
endif()
endif()
find_package_handle_standard_args(ZeroMQ FOUND_VAR ZeroMQ_FOUND
REQUIRED_VARS ZeroMQ_INCLUDE_DIRS ZeroMQ_LIBRARIES
VERSION_VAR ZeroMQ_VERSION)
if (ZeroMQ_FOUND)
mark_as_advanced(ZeroMQ_INCLUDE_DIRS ZeroMQ_LIBRARIES ZeroMQ_VERSION
ZeroMQ_VERSION_MAJOR ZeroMQ_VERSION_MINOR ZeroMQ_VERSION_PATCH)
endif()

View File

@ -0,0 +1,31 @@
# This cmake code creates the configuration that is found and used by
# find_package() of another cmake project
# get lower and upper case project name for the configuration files
# configure and install the configuration files
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${CMAKE_SOURCE_DIR}/cmake/project-config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME_LOWER}
PATH_VARS CMAKE_INSTALL_DIR)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
install(FILES
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
COMPONENT devel
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME_LOWER})
if (PROJECT_LIBRARIES OR PROJECT_STATIC_LIBRARIES)
install(
EXPORT "${TARGETS_EXPORT_NAME}"
FILE ${PROJECT_NAME_LOWER}-targets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME_LOWER})
endif ()

View File

@ -0,0 +1,24 @@
# Config file for @PROJECT_NAME_LOWER@
#
# It defines the following variables:
#
# @PROJECT_NAME_UPPER@_INCLUDE_DIRS - include directory
# @PROJECT_NAME_UPPER@_LIBRARIES - all dynamic libraries
# @PROJECT_NAME_UPPER@_STATIC_LIBRARIES - all static libraries
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
set(SLS_USE_HDF5 "@SLS_USE_HDF5@")
# Add optional dependencies here
find_dependency(Threads)
if (SLS_USE_HDF5)
find_dependency(HDF5)
endif ()
set_and_check(@PROJECT_NAME_UPPER@_CMAKE_INCLUDE_DIRS "@PACKAGE_CMAKE_INSTALL_DIR@")
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")

View File

@ -0,0 +1,14 @@
#include "project_version.h"
/// project version as major.minor.patch string
const char* @PROJECT_NAME@_runtime_project_version(){ return "@PROJECT_VERSION@"; }
/// package version as string, possibly with git commit: v1.2.3+4+g56789abc
const char* @PROJECT_NAME@_runtime_package_version(){ return "@PACKAGE_VERSION@"; }
/// project version as integer: major * 10000 + minor * 100 + patch
int @PROJECT_NAME@_runtime_version_int() { return @PROJECT_VERSION_INT@; }
/// project version as integer: major
int @PROJECT_NAME@_runtime_version_major(){ return @PACKAGE_VERSION_MAJOR@; }
/// project version as integer: minor
int @PROJECT_NAME@_runtime_version_minor(){ return @PACKAGE_VERSION_MINOR@; }
/// project version as integer: patch
int @PROJECT_NAME@_runtime_version_patch(){ return @PACKAGE_VERSION_PATCH@; }

154
cmake/project_version.cmake Normal file
View File

@ -0,0 +1,154 @@
#
# Sets PROJECT_VERSION and PACKAGE_VERSION
#
# Don't set PROJECT_VERSION to empty string when no VERSION is given to project() command.
#if(POLICY CMP0048)
# cmake_policy(SET CMP0048 OLD)
#endif()
# Split a version number into separate components
# version the version number to split
# major variable name to store the major version in
# minor variable name to store the minor version in
# patch variable name to store the patch version in
# extra variable name to store a version suffix in
function(version_split version major minor patch extra)
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" version_valid ${version})
if(version_valid)
string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" "\\1;\\2;\\3;\\4" VERSION_MATCHES ${version})
list(GET VERSION_MATCHES 0 version_major)
set(${major} ${version_major} PARENT_SCOPE)
list(GET VERSION_MATCHES 1 version_minor)
set(${minor} ${version_minor} PARENT_SCOPE)
list(GET VERSION_MATCHES 2 version_patch)
set(${patch} ${version_patch} PARENT_SCOPE)
list(GET VERSION_MATCHES 3 version_extra)
set(${extra} ${version_extra} PARENT_SCOPE)
else(version_valid)
message(AUTHOR_WARNING "Bad version ${version}; falling back to 0 (have you made an initial release?)")
set(${major} "0" PARENT_SCOPE)
set(${minor} "0" PARENT_SCOPE)
set(${patch} "0" PARENT_SCOPE)
set(${extra} "" PARENT_SCOPE)
endif(version_valid)
endfunction(version_split)
##############################
# get PROJECT_VERSION from git
##############################
find_program(GIT_CMD git)
mark_as_advanced(GIT_CMD)
if (GIT_CMD)
execute_process(COMMAND ${GIT_CMD} rev-parse --show-toplevel
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_TOPLEVEL
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
if (GIT_CMD AND NOT "${GIT_TOPLEVEL}" STREQUAL "")
execute_process(COMMAND ${GIT_CMD} rev-parse --short HEAD
WORKING_DIRECTORY ${GIT_TOPLEVEL}
OUTPUT_VARIABLE GIT_SHA1
OUTPUT_STRIP_TRAILING_WHITESPACE)
#message(STATUS "GIT_SHA1: " ${GIT_SHA1})
execute_process(COMMAND ${GIT_CMD} describe --match "*[0-9].[0-9]*" HEAD
WORKING_DIRECTORY ${GIT_TOPLEVEL}
OUTPUT_VARIABLE GIT_DESCRIBE
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
#message(STATUS "GIT_DESCRIBE: " ${GIT_DESCRIBE})
if (GIT_DESCRIBE)
string(REGEX REPLACE "v?([0-9.]+).*" "\\1" GIT_VERSION ${GIT_DESCRIBE})
message(STATUS "GIT_VERSION: " ${GIT_VERSION})
# as package version we use the full version from git describe: 1.7.1+7+ge324c81
if (GIT_DESCRIBE MATCHES ".*-g.*")
# convert a git describe string to usable debian version, e.g. v1.7.1-7-ge324c81 to 1.7.1+7+ge324c81
string(REGEX REPLACE "v?([0-9]*.[0-9.]*).*-([0-9]*)-([a-g0-9]*)" "\\1+\\2+\\3" GIT_FULL_VERSION ${GIT_DESCRIBE})
else()
# current HEAD is git tag (i.e. releaase), directly use the version
set(GIT_FULL_VERSION ${GIT_VERSION})
endif()
else ()
# no (suitable) tag found
set(GIT_VERSION "0.0.0")
# get number of commits in repo
execute_process(COMMAND ${GIT_CMD} rev-list --count HEAD
WORKING_DIRECTORY ${GIT_TOPLEVEL}
OUTPUT_VARIABLE GIT_COMMIT_COUNT
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(GIT_FULL_VERSION 0.0.0+${GIT_COMMIT_COUNT}+g${GIT_SHA1})
endif ()
endif ()
# get version from package.xml if it exists
if (EXISTS "${PROJECT_SOURCE_DIR}/package.xml")
file(STRINGS "${PROJECT_SOURCE_DIR}/package.xml" PACKAGE_XML_VERSION_LINE REGEX <version>[0-9.]*</version>)
string(REGEX REPLACE .*<version>\([0-9.]*\)</version>.* \\1 PACKAGE_XML_VERSION "${PACKAGE_XML_VERSION_LINE}")
MESSAGE(STATUS "PACKAGE_XML_VERSION: " ${PACKAGE_XML_VERSION})
endif ()
# set version (if not already manually specified)
# check versions from different sources and set actually used version
if (NOT PROJECT_VERSION)
# set PROJECT_VERSION to MAJOR.MINOR.PATCH
# PACKAGE_VERSION can have extra info
if (GIT_VERSION)
set(PROJECT_VERSION ${GIT_VERSION})
set(PACKAGE_VERSION ${GIT_FULL_VERSION})
elseif (PACKAGE_XML_VERSION)
set(PROJECT_VERSION ${PACKAGE_XML_VERSION})
set(PACKAGE_VERSION ${PROJECT_VERSION})
else ()
message(WARNING "PROJECT_VERSION not set. Defaulting to 0.0.0")
set(PROJECT_VERSION "0.0.0")
endif ()
endif ()
if (NOT PACKAGE_VERSION)
message(WARNING "PACKAGE_VERSION not set! Falling back to (${PROJECT_VERSION})")
set(PACKAGE_VERSION ${PROJECT_VERSION})
endif ()
# warn if versions don't match
if (GIT_VERSION AND NOT GIT_VERSION MATCHES ${PROJECT_VERSION})
message(WARNING "Version from git (${GIT_VERSION}) doesn't match PROJECT_VERSION (${PROJECT_VERSION})")
endif()
if (PACKAGE_XML_VERSION AND NOT PACKAGE_XML_VERSION MATCHES ${PROJECT_VERSION})
message(WARNING "Version from package.xml (${PACKAGE_XML_VERSION}) doesn't match PROJECT_VERSION (${PROJECT_VERSION})")
endif()
message(STATUS "PROJECT_VERSION: " ${PROJECT_VERSION})
message(STATUS "PACKAGE_VERSION: " ${PACKAGE_VERSION})
version_split(${PROJECT_VERSION} PACKAGE_VERSION_MAJOR PACKAGE_VERSION_MINOR PACKAGE_VERSION_PATCH extra)
#message(STATUS "PACKAGE_VERSION_MAJOR: " ${PACKAGE_VERSION_MAJOR})
#message(STATUS "PACKAGE_VERSION_MINOR: " ${PACKAGE_VERSION_MINOR})
#message(STATUS "PACKAGE_VERSION_PATCH: " ${PACKAGE_VERSION_PATCH})
# generate an integer version number: major * 10000 + minor * 100 + patch
math(EXPR PROJECT_VERSION_INT "${PACKAGE_VERSION_MAJOR} * 10000 + ${PACKAGE_VERSION_MINOR} * 100 + ${PACKAGE_VERSION_PATCH}")
# make PROJECT_VERSION available as define in the project source
#add_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}")
#add_definitions(-DPROJECT_VERSION_INT=${PROJECT_VERSION_INT})
#add_definitions(-DPACKAGE_VERSION="${PACKAGE_VERSION}")
#add_definitions(-DPACKAGE_VERSION_MAJOR=${PACKAGE_VERSION_MAJOR})
#add_definitions(-DPACKAGE_VERSION_MINOR=${PACKAGE_VERSION_MINOR})
#add_definitions(-DPACKAGE_VERSION_PATCH=${PACKAGE_VERSION_PATCH})
# set ABI version to major.minor, which will be used for the SOVERSION
set(abiversion "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}")
# generate a version.h file in the binary output dir, don't forget to install it...
string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER)
# These files provide compile-time and runtime version information about your project.
# To offer the version info to the users of your library, you need to
# adapt the following lines in your respective CMakeLists.txt:
# add_library(<yourlibraryname> SHARED <your code files> ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/project_version.cc)
# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/project_version.h COMPONENT dev DESTINATION include/<your-include-dir>)
# To use it within your library or tests you need to add the include directory:
# > target_include_directories(yourtarget PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME})
configure_file(${CMAKE_CURRENT_LIST_DIR}/project_version.h.in ${PROJECT_NAME}/project_version.h @ONLY)
configure_file(${CMAKE_CURRENT_LIST_DIR}/project_version.cc.in ${PROJECT_NAME}/project_version.cc @ONLY)

View File

@ -0,0 +1,34 @@
#ifndef @PROJECT_NAME_UPPER@_VERSION_H_
#define @PROJECT_NAME_UPPER@_VERSION_H_
/// project version as major.minor.patch string
#define @PROJECT_NAME_UPPER@_VERSION "@PROJECT_VERSION@"
/// project version as integer: major * 10000 + minor * 100 + patch
#define @PROJECT_NAME_UPPER@_VERSION_INT @PROJECT_VERSION_INT@
#define @PROJECT_NAME_UPPER@_VERSION_MAJOR @PACKAGE_VERSION_MAJOR@
#define @PROJECT_NAME_UPPER@_VERSION_MINOR @PACKAGE_VERSION_MINOR@
#define @PROJECT_NAME_UPPER@_VERSION_PATCH @PACKAGE_VERSION_PATCH@
/// package version as string, possibly with git commit: v1.2.3+4+g56789abc
#define @PROJECT_NAME_UPPER@_PACKAGE_VERSION "@PACKAGE_VERSION@"
///runtime versions, where the above values are linked into a lib and therefore reflect the version
///of the library itself (not the version of the header at compile time of the user code)
const char* @PROJECT_NAME@_runtime_project_version();
const char* @PROJECT_NAME@_runtime_package_version();
int @PROJECT_NAME@_runtime_version_int();
int @PROJECT_NAME@_runtime_version_major();
int @PROJECT_NAME@_runtime_version_minor();
int @PROJECT_NAME@_runtime_version_patch();
///Check consistency of runtime vs compile-time version number. I.e. the header used
///for compilation was from the same version as the linked library.
inline bool @PROJECT_NAME@_check_version_consistency(bool major_minor_only)
{
return @PROJECT_NAME@_runtime_version_major() == @PROJECT_NAME_UPPER@_VERSION_MAJOR &&
@PROJECT_NAME@_runtime_version_minor() == @PROJECT_NAME_UPPER@_VERSION_MINOR &&
(major_minor_only ||
@PROJECT_NAME@_runtime_version_patch() == @PROJECT_NAME_UPPER@_VERSION_PATCH);
}
#endif

13
cmk.sh
View File

@ -116,20 +116,21 @@ done
if [ $TEXTCLIENT -eq 0 ] && [ $RECEIVER -eq 0 ] && [ $GUI -eq 0 ]; then
CMAKE_POST+=" -DUSE_TEXTCLIENT=ON -DUSE_RECEIVER=ON -DUSE_GUI=ON "
# CMAKE_POST+=" -DSLS_USE_TEXTCLIENT=ON -DSLS_USE_RECEIVER=ON -DSLS_USE_GUI=ON "
CMAKE_POST+=" -DSLS_USE_TEXTCLIENT=ON -DSLS_USE_RECEIVER=ON "
echo "Compile Option: TextClient, Receiver and GUI"
else
if [ $TEXTCLIENT -eq 1 ]; then
CMAKE_POST+=" -DUSE_TEXTCLIENT=ON "
CMAKE_POST+=" -DSLS_USE_TEXTCLIENT=ON "
echo "Compile Option: TextClient"
fi
if [ $RECEIVER -eq 1 ]; then
CMAKE_POST+=" -DUSE_RECEIVER=ON "
CMAKE_POST+=" -DSLS_USE_RECEIVER=ON "
echo "Compile Option: Receiver"
fi
if [ $GUI -eq 1 ]; then
CMAKE_POST+=" -DUSE_GUI=ON "
CMAKE_POST+=" -DSLS_USE_GUI=ON "
echo "Compile Option: GUI"
fi
fi
@ -161,10 +162,10 @@ fi
#hdf5 rebuild
if [ $HDF5 -eq 1 ]; then
CMAKE_PRE+="HDF5_ROOT="$HDF5DIR
CMAKE_POST+=" -DUSE_HDF5=ON "
CMAKE_POST+=" -DSLS_USE_HDF5=ON "
#normal mode rebuild
else
CMAKE_POST+=" -DUSE_HDF5=OFF "
CMAKE_POST+=" -DSLS_USE_HDF5=OFF "
fi

View File

@ -1,15 +0,0 @@
sh updateSvnVersion.sh
cd slsDetectorGui
git commit -a -m "updating versions"
git push origin developer:developer
cd ../slsDetectorSoftware
git commit -a -m "updating versions"
git push origin developer:developer
cd ../slsReceiverSoftware
git commit -a -m "updating versions"
git push origin developer:developer
cd ..

15
conda-recepie/build.sh Normal file
View File

@ -0,0 +1,15 @@
mkdir build
mkdir install
cd build
cmake .. \
-DCMAKE_PREFIX_PATH=$CONDA_PREFIX \
-DCMAKE_INSTALL_PREFIX=install \
-DSLS_USE_TEXTCLIENT=ON \
-DSLS_USE_RECEIVER=ON \
-DSLS_USE_GUI=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DSLS_USE_HDF5=OFF\
cmake --build . -- -j10
cmake --build . --target install

15
conda-recepie/copy_gui.sh Normal file
View File

@ -0,0 +1,15 @@
mkdir $PREFIX/lib
mkdir $PREFIX/bin
mkdir $PREFIX/include
#No libs for gui?
#Binaries
cp build/bin/gui_client $PREFIX/bin/.
cp build/bin/slsDetectorGui $PREFIX/bin/.
#Which headers do we need for development??
# cp include/some_lib.h $PREFIX/include/.

22
conda-recepie/copy_lib.sh Normal file
View File

@ -0,0 +1,22 @@
mkdir $PREFIX/lib
mkdir $PREFIX/bin
mkdir $PREFIX/include
mkdir $PREFIX/include/slsDetectorPackage
#Shared and static libraries
cp build/bin/libSlsDetector.so $PREFIX/lib/.
cp build/bin/libSlsReceiver.so $PREFIX/lib/.
cp build/bin/libSlsSupport.so $PREFIX/lib/.
#Binaries
cp build/bin/sls_detector_acquire $PREFIX/bin/.
cp build/bin/sls_detector_get $PREFIX/bin/.
cp build/bin/sls_detector_put $PREFIX/bin/.
cp build/bin/sls_detector_help $PREFIX/bin/.
cp build/bin/slsReceiver $PREFIX/bin/.
cp build/bin/slsMultiReceiver $PREFIX/bin/.
#Which headers do we need for development??
cp build/install/include/* $PREFIX/include/slsDetectorPackage/
# cp include/some_lib.h $PREFIX/include/.

98
conda-recepie/meta.yaml Normal file
View File

@ -0,0 +1,98 @@
package:
name: sls_detector_software
version: "refactor"
source:
- path: ..
build:
number: 0
rpaths:
- lib/
requirements:
build:
- {{ compiler('c') }}
- {{compiler('cxx')}}
- cmake
- qwt 6.*
- qt=4.8.7=7
- zeromq=4.2.5=hfc679d8_5
- pyzmq
- xorg-libx11
- xorg-libice
- xorg-libxext
- xorg-libsm
- xorg-libxau
- xorg-libxrender
- xorg-libxfixes
- {{ cdt('mesa-libgl-devel') }} # [linux]
- {{ cdt('mesa-libegl-devel') }} # [linux]
- {{ cdt('mesa-dri-drivers') }} # [linux]
- {{ cdt('libselinux') }} # [linux]
- {{ cdt('libxdamage') }} # [linux]
- {{ cdt('libxxf86vm') }} # [linux]
host:
- libstdcxx-ng
- libgcc-ng
- libpng >=1.6.32,<1.6.35
- xorg-libx11
- xorg-libice
- xorg-libxext
- xorg-libsm
- xorg-libxau
- xorg-libxrender
- xorg-libxfixes
run:
- libstdcxx-ng
- libgcc-ng
outputs:
- name: sls_detector_lib
version: "refactor"
script: copy_lib.sh
requirements:
build:
- {{ compiler('c') }}
- {{compiler('cxx')}}
# - name: sls_detector
# version: "refactor"
# script: copy_lib.sh
# requirements:
# build:
# - {{ compiler('c') }}
# - {{compiler('cxx')}}
# - name: sls_detector_gui
# version: "refactor"
# script: copy_gui.sh
# requirements:
# build:
# - {{ compiler('c') }}
# - {{compiler('cxx')}}
# - cmake
# - qwt 6.*
# - qt=4.8.7=7
# - zeromq=4.2.5=hfc679d8_5
# - pyzmq
# - xorg-libx11
# - xorg-libice
# - xorg-libxext
# - xorg-libsm
# - xorg-libxau
# - xorg-libxrender
# - xorg-libxfixes
# - {{ cdt('mesa-libgl-devel') }} # [linux]
# - {{ cdt('mesa-libegl-devel') }} # [linux]
# - {{ cdt('mesa-dri-drivers') }} # [linux]
# - {{ cdt('libselinux') }} # [linux]
# - {{ cdt('libxdamage') }} # [linux]
# - {{ cdt('libxxf86vm') }} # [linux]
# run:
# - sls_detector_lib=refactor
# - qwt 6.*
# - qt=4.8.7=7

View File

@ -0,0 +1,57 @@
detsizechan 2560 1
hostname bchip074+bchip075+
0:extsig:0 trigger_in_rising_edge
0:rx_tcpport 1954
0:rx_udpport 50001
0:vhighvoltage 0
1:extsig:0 trigger_in_rising_edge
1:rx_tcpport 1955
1:rx_udpport 50002
1:vhighvoltage 0
##############################################################################
#########
######### Uncomment this part to use the gotthard25umZmq process
#########
##############################################################################
# #replace my_receiver_hostname with the hostname of IP of the machine where the receiver runs
#0:rx_zmqip my_receiver_hostname
#0:rx_zmqport 30003
# #replace my_client_hostname with the hostname of IP of the machine where the client/GUI or softIOC runs
#0:zmqip my_client_hostname
#0:zmqport 40003
# #replace my_receiver_hostname with the hostname of IP of the machine where the receiver runs
#1:rx_zmqip my_receiver_hostname
#1:rx_zmqport 30004
# #replace my_client_hostname with the hostname of IP of the machine where the client/GUI or softIOC runs
#1:zmqip my_client_hostname
#1:zmqport 40004
##############################################################################
#########
######### until here
#########
##############################################################################
r_readfreq 1
rx_datastream 1
#replace my_receiver_hostname with the hostname of 1Gb IP of the machine where the receiver runs
rx_hostname my_receiver_hostname
rx_datastream 1
outdir /tmp/
settings veryhighgain
exptime 0.000005
period 0.0001
vhighvoltage 90

View File

@ -0,0 +1,13 @@
Turn on the two receivers:
slsReceiver -t1954 &
slsReceiver -t1955 &
Switch on the photon conversion on the receiver machine (replace my_receiver_hostname):
gotthard25umZmq my_receiver_hostname 30003 my_receiver_hostname 40003 &
Run the configuration file:
sls_detector_put config bchip2modules.config
Start your measurements using the command line, the slsDetectorGui or the EPICS driver

View File

@ -0,0 +1,491 @@
hostname bchip085+
patword 0000 0000000000000000
patword 0001 0000000000000000
patword 0002 0008000900080000
patword 0003 0008000900080000
patword 0004 0008000900080000
patword 0005 0008000900080000
patword 0006 0008000900080000
patword 0007 0008000900080000
patword 0008 0008000900080000
patword 0009 0008000900080000
patword 000a 0008000900080000
patword 000b 0008000900080000
patword 000c 0008000900080000
patword 000d 0008000900080000
patword 000e 0008000900080000
patword 000f 0008000900080000
patword 0010 0008000900080000
patword 0011 0008000900080000
patword 0012 0008000900080000
patword 0013 0008000900080000
patword 0014 0008000900080000
patword 0015 0008000900080000
patword 0016 0008400900080020
patword 0017 0008400900080020
patword 0018 0008599f0418503a
patword 0019 0008599f0418503a
patword 001a 0108599f0418503a
patword 001b 0108599f0418503a
patword 001c 0108599f0418503a
patword 001d 0108599f0418503a
patword 001e 0108599f0418503a
patword 001f 0108599f0418503a
patword 0020 0108599f0418503a
patword 0021 0108599f0418503a
patword 0022 0108599f0418503a
patword 0023 0108599f0418503a
patword 0024 0108599f0418503a
patword 0025 0108599f0418503a
patword 0026 0108599f0418503a
patword 0027 0108599f0418503a
patword 0028 0108599f0418503a
patword 0029 0108599f0418503a
patword 002a 0108599f0418503a
patword 002b 0108599f0418503a
patword 002c 0108599f0418503a
patword 002d 0108599f0418503a
patword 002e 0108599f0418503a
patword 002f 0108599f0418503a
patword 0030 0108599f0418503a
patword 0031 0108599f0418503a
patword 0032 0108599f0418503a
patword 0033 0108599f0418503a
patword 0034 0108599f0418503a
patword 0035 0108599f0418503a
patword 0036 0108599f0418503a
patword 0037 0108599f0418503a
patword 0038 0108599f0418503a
patword 0039 0108599f0418503a
patword 003a 0108599f0418503a
patword 003b 0108599f0418503a
patword 003c 0108599f0418503a
patword 003d 0108599f0418503a
patword 003e 0108599f0418503a
patword 003f 0108599f0418503a
patword 0040 0108599f0418503a
patword 0041 0108599f0418503a
patword 0042 0108599f0418503a
patword 0043 0108599f0418503a
patword 0044 0108599f0418503a
patword 0045 0108599f0418503a
patword 0046 0108599f0418503a
patword 0047 0108599f0418503a
patword 0048 0108599f0418503a
patword 0049 0108599f0418503a
patword 004a 0108599f0418503a
patword 004b 0108599f0418503a
patword 004c 0108599f0418503a
patword 004d 0108599f0418503a
patword 004e 0108599f0418503a
patword 004f 0108599f0418503a
patword 0050 0108599f0418503a
patword 0051 0108599f0418503a
patword 0052 0108599f0418503a
patword 0053 0108599f0418503a
patword 0054 0108599f0418503a
patword 0055 0108599f0418503a
patword 0056 0108599f0418503a
patword 0057 0108599f0418503a
patword 0058 0108599f0418503a
patword 0059 0108599f0418503a
patword 005a 0108599f0418503a
patword 005b 0108599f0418503a
patword 005c 0108599f0418503a
patword 005d 0108599f0418503a
patword 005e 0108599f0418503a
patword 005f 0108599f0418503a
patword 0060 0108599f0418503a
patword 0061 0108599f0418503a
patword 0062 0108599f0418503a
patword 0063 0108599f0418503a
patword 0064 0108599f0418503a
patword 0065 0108599f0418503a
patword 0066 0108599f0418503a
patword 0067 0108599f0418503a
patword 0068 0108599f0418503a
patword 0069 0108599f0418503a
patword 006a 0108599f0418503a
patword 006b 0108599f0418503a
patword 006c 0108599f0418503a
patword 006d 0108599f0418503a
patword 006e 0108599f0418503a
patword 006f 0108599f0418503a
patword 0070 0108599f0418503a
patword 0071 0108599f0418503a
patword 0072 0108599f0418503a
patword 0073 0108599f0418503a
patword 0074 0108599f0418503a
patword 0075 0108599f0418503a
patword 0076 0108599f0418503a
patword 0077 0108599f0418503a
patword 0078 0108599f0418503a
patword 0079 0108599f0418503a
patword 007a 0108599f0418503a
patword 007b 0108599f0418503a
patword 007c 0108599f0418503a
patword 007d 0108599f0418503a
patword 007e 010859960418503a
patword 007f 010859960418503a
patword 0080 010859960418503a
patword 0081 010859960418503a
patword 0082 010859960418503a
patword 0083 010859960418503a
patword 0084 010859960418503a
patword 0085 010859960418503a
patword 0086 010859960418503a
patword 0087 010859960418503a
patword 0088 010859960418503a
patword 0089 010859960418503a
patword 008a 010859960418503a
patword 008b 010859960418503a
patword 008c 010859960418503a
patword 008d 010859960418503a
patword 008e 010859960418503a
patword 008f 010859960418503a
patword 0090 010859960418503a
patword 0091 010859960418503a
patword 0092 010819960418501a
patword 0093 010819960418501a
patword 0094 010819960418501a
patword 0095 010819960418501a
patword 0096 030819960418501a
patword 0097 030819960418501a
patword 0098 030819960418501a
patword 0099 030819960418501a
patword 009a 030819960418501a
patword 009b 030819960418501a
patword 009c 030819960418501a
patword 009d 030819960418501a
patword 009e 030819960418501a
patword 009f 030819960418501a
patword 00a0 030819960418501a
patword 00a1 030819960418501a
patword 00a2 030819960418501a
patword 00a3 030819960418501a
patword 00a4 030819960418501a
patword 00a5 030819960418501a
patword 00a6 030819960418501a
patword 00a7 030819960418501a
patword 00a8 030819960418501a
patword 00a9 030819960418501a
patword 00aa 030819960418501a
patword 00ab 030819960418501a
patword 00ac 030819960008501a
patword 00ad 030819960008501a
patword 00ae 030819960008501a
patword 00af 030819960008501a
patword 00b0 030819960008501a
patword 00b1 030819960008501a
patword 00b2 030819960008501a
patword 00b3 030819960008501a
patword 00b4 030819960008501a
patword 00b5 030819960008501a
patword 00b6 030819960008501a
patword 00b7 030819960008501a
patword 00b8 030819960008501a
patword 00b9 030819960008501a
patword 00ba 030819960008501a
patword 00bb 030819960008501a
patword 00bc 030819960008501a
patword 00bd 030819960008501a
patword 00be 030819960008501a
patword 00bf 030819960008501a
patword 00c0 0308199f0008501a
patword 00c1 0308199f0008501a
patword 00c2 0308199f0008501a
patword 00c3 0308199f0008501a
patword 00c4 0308199f0008501a
patword 00c5 0308199f0008501a
patword 00c6 0308199f0008501a
patword 00c7 0308199f0008501a
patword 00c8 0308199f0008501a
patword 00c9 0308199f0008501a
patword 00ca 0308199f0008501a
patword 00cb 0308199f0008501a
patword 00cc 0308199f0008501a
patword 00cd 0308199f0008501a
patword 00ce 0308199f0008501a
patword 00cf 0308199f0008501a
patword 00d0 0308199f0008501a
patword 00d1 0308199f0008501a
patword 00d2 0308199f0008501a
patword 00d3 0308199f0008501a
patword 00d4 0308599f0008503a
patword 00d5 0308599f0008503a
patword 00d6 030c599f000850ba
patword 00d7 030c599f000850ba
patword 00d8 030c599f000850ba
patword 00d9 030c599f000850ba
patword 00da 030c599f000850ba
patword 00db 030c599f000850ba
patword 00dc 030c599f000850ba
patword 00dd 030c599f000850ba
patword 00de 030c599f000850ba
patword 00df 030c599f000850ba
patword 00e0 030c599f000850ba
patword 00e1 030c599f000850ba
patword 00e2 030c599f000850ba
patword 00e3 030c599f000850ba
patword 00e4 030c599f000850ba
patword 00e5 030c599f000850ba
patword 00e6 030c599f000850ba
patword 00e7 030c599f000850ba
patword 00e8 030c599f000850ba
patword 00e9 030c599f000850ba
patword 00ea 030c799f010858ba
patword 00eb 030c799f010858ba
patword 00ec 030c599f000850ba
patword 00ed 030c599f000850ba
patword 00ee 030c599f000850ba
patword 00ef 030c599f000850ba
patword 00f0 030c599f000850ba
patword 00f1 030c599f000850ba
patword 00f2 030c599f000850ba
patword 00f3 030c599f000850ba
patword 00f4 030c599f000850ba
patword 00f5 030c599f000850ba
patword 00f6 030c599f000850ba
patword 00f7 030c599f000850ba
patword 00f8 030c599f000850ba
patword 00f9 030c599f000850ba
patword 00fa 030c599f000850ba
patword 00fb 030c599f000850ba
patword 00fc 030c599f000850ba
patword 00fd 030c599f000850ba
patword 00fe 030c599f000850ba
patword 00ff 030c599f000850ba
patword 0100 030c599f000850ba
patword 0101 030c599f000850ba
patword 0102 030c599f400850ba
patword 0103 030c599f400850ba
patword 0104 030c599f600850ba
patword 0105 030c599f400850ba
patword 0106 030c599f400850ba
patword 0107 030c599f400850ba
patword 0108 870c599f682e50ba
patword 0109 870c599f482850ba
patword 010a 870c599f000e50ba
patword 010b 870c599f000850ba
patword 010c 870c599f000e50ba
patword 010d 870c599f000850ba
patword 010e 870c599f000e50ba
patword 010f 870c599f000850ba
patword 0110 870c599f000e50ba
patword 0111 870c599f000850ba
patword 0112 870c599f000e50ba
patword 0113 870c599f000850ba
patword 0114 870c599f000e50ba
patword 0115 870c599f000850ba
patword 0116 870c599f000e50ba
patword 0117 870c599f000850ba
patword 0118 870c599f000e50ba
patword 0119 870c599f000850ba
patword 011a 870c599f000e50ba
patword 011b 870c599f000850ba
patword 011c 870c599f000e50ba
patword 011d 870c599f000850ba
patword 011e 870c599f000e50ba
patword 011f 870c599f000850ba
patword 0120 870c599f000e50ba
patword 0121 870c599f000850ba
patword 0122 870c599f200e50ba
patword 0123 870c599f000850ba
patword 0124 870c599f000e50ba
patword 0125 870c599f000850ba
patword 0126 870c599f000e50ba
patword 0127 870c599f000850ba
patword 0128 870c599f000e50ba
patword 0129 870c599f000850ba
patword 012a 870c599f000e50ba
patword 012b 870c599f000850ba
patword 012c 870c599f000e50ba
patword 012d 870c599f000850ba
patword 012e 870c599f000e50ba
patword 012f 870c599f000850ba
patword 0130 870c599f000e50ba
patword 0131 870c599f000850ba
patword 0132 870c599f000e50ba
patword 0133 870c599f000850ba
patword 0134 870c599f000e50ba
patword 0135 870c599f000850ba
patword 0136 870c599f000e50ba
patword 0137 870c599f000850ba
patword 0138 870c599f000e50ba
patword 0139 870c599f000850ba
patword 013a 870c599f282e50ba
patword 013b 870c599f082850ba
patword 013c 870c599f000e50ba
patword 013d 870c599f000850ba
patword 013e 870c599f000e50ba
patword 013f 870c599f000850ba
patword 0140 870c599f000e50ba
patword 0141 870c599f000850ba
patword 0142 870c599f000e50ba
patword 0143 870c599f000850ba
patword 0144 870c599f000e50ba
patword 0145 870c599f000850ba
patword 0146 870c599f000e50ba
patword 0147 870c599f000850ba
patword 0148 870c599f000e50ba
patword 0149 870c599f000850ba
patword 014a 870c599f000e50ba
patword 014b 870c599f000850ba
patword 014c 870c599f000e50ba
patword 014d 870c599f000850ba
patword 014e 870c599f000e50ba
patword 014f 870c599f000850ba
patword 0150 870c599f000e50ba
patword 0151 870c599f000850ba
patword 0152 870c599f000e50ba
patword 0153 870c599f000850ba
patword 0154 870c599f200e50ba
patword 0155 870c599f000850ba
patword 0156 870c599f000e50ba
patword 0157 870c599f000850ba
patword 0158 870c599f000e50ba
patword 0159 870c599f000850ba
patword 015a 870c599f000e50ba
patword 015b 870c599f000850ba
patword 015c 870c599f000e50ba
patword 015d 870c599f000850ba
patword 015e 870c599f000e50ba
patword 015f 870c599f000850ba
patword 0160 870c599f000e50ba
patword 0161 870c599f000850ba
patword 0162 870c599f000e50ba
patword 0163 870c599f000850ba
patword 0164 870c599f000e50ba
patword 0165 870c599f000850ba
patword 0166 870c599f000e50ba
patword 0167 870c599f000850ba
patword 0168 870c599f000e50ba
patword 0169 870c599f000850ba
patword 016a 870c599f000e50ba
patword 016b 870c599f000850ba
patword 016c 070c599f000850ba
patword 016d 070c599f000850ba
patword 016e 000c599f000850ba
patword 016f 000c599f000850ba
patword 0170 0008599f200e503a
patword 0171 0008599f0008503a
patword 0172 0008599f200e503a
patword 0173 0008599f0008503a
patword 0174 0008599f0008503a
patword 0175 0008599f0008503a
patword 0176 0008599f0008503a
patword 0177 0008599f0008503a
patword 0178 0008599f0008503a
patword 0179 0008599f0008503a
patword 017a 0008599f0008503a
patword 017b 0008599f0008503a
patword 017c 0008599f0008503a
patword 017d 0008599f0008503a
patword 017e 0008599f0008503a
patword 017f 0008599f0008503a
patword 0180 0008599f0008503a
patword 0181 0008599f0008503a
patword 0182 0008599f0008503a
patword 0183 0008599f0008503a
patword 0184 0008599f0008503a
patword 0185 0008599f0008503a
patword 0186 0008599f0008503a
patword 0187 0008599f0008503a
patword 0188 0008599f0008503a
patword 0189 0008599f0008503a
patword 018a 0008599f0008503a
patword 018b 0008599f0008503a
patword 018c 0008599f0008503a
patword 018d 0008599f0008503a
patioctrl 8f0effff6dbffdbf
patclkctrl 0000000000000000
patlimits 0000 018c
patloop0 013a 016b
patnloop0 199
patloop1 0400 0400
patnloop1 0
patloop2 0400 0400
patnloop2 0
patwait0 00aa
patwaittime0 40000
patwait1 0400
patwaittime1 0
patwait2 0400
patwaittime2 0
####mcp2011
#0:rx_udpip 10.1.1.102
#0:detectorip 10.1.1.19
#0:rx_udpport 32410
####gui listening to
#zmqip 129.129.202.131
#zmqport 30001
####data streaming out of
#rx_zmqip 10.1.2.103
#rx_zmqport 30003
#0:rx_hostname mpc2011
####mx-test-1
0:rx_udpip 10.1.1.100
0:detectorip 10.1.1.19
0:rx_udpport 32410
####gui listening to (on receiver pc)
zmqip 129.129.202.92
zmqport 30001
####data streaming out of
rx_zmqip 10.1.1.100
rx_zmqport 30003
0:rx_hostname pcmoench01
#turn on datastream from commandline
rx_datastream 1
r_readfreq 1
#0:configuremac -1
rx_datastream 1
r_readfreq 1
dac:6 800
dac:0 1300
dac:4 1428
dac:1 1000
dac:7 900
dac:3 680
dac:2 1400
dac:5 1200
adcinvert 4a342593
samples 5000
adcphase 90
adcpipeline 15
adcreg 14 40
powerchip 1
vhighvoltage 90
period 0.005
frames 100
period 0.1
outdir /scratch/
enablefwrite 0

View File

@ -0,0 +1,39 @@
MESSAGE( STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR} )
MESSAGE( STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR} )
include_directories(
${PROJECT_SOURCE_DIR}/catch
)
if(SLS_USE_TESTS)
set(TEST_SOURCES
src/test-slsDetector.cpp
src/test.cpp
)
add_executable(detector_test ${TEST_SOURCES})
target_link_libraries(detector_test
slsDetectorShared
slsSupportLib
pthread
rt
)
set_target_properties(detector_test PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
add_executable(a src/a.cpp)
target_link_libraries(a
slsDetectorShared
slsSupportLib
pthread
rt
)
set_target_properties(a PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
endif()

View File

@ -0,0 +1,94 @@
#include "catch.hpp"
#include "ClientSocket.h"
#include "Timer.h"
#include "logger.h"
#include "slsDetector.h"
#include "sls_detector_defs.h"
#include "sls_detector_exceptions.h"
#include "sls_detector_funcs.h"
#include <iostream>
#include <vector>
#define VERBOSE
using sls::RuntimeError;
using sls::SharedMemoryError;
using sls::SocketError;
using sls::DetectorError;
int main() {
const std::string hostname = "beb083";
auto type = slsDetector::getTypeFromDetector(hostname);
slsDetector d(type);
d.setHostname(hostname);
d.setOnline(true);
std::cout << "hostname: " << d.getHostname() << '\n';
d.setThresholdTemperature(50);
// try{
// d.setThresholdTemperature(50);
// }catch(const DetectorError &e){
// std::cout << "Caught: " << e.what() << '\n';
// }
// std::cout << "hostname: " << d.getHostname() << '\n';
// std::cout << "exptime: " << d.setDAC(-1, slsDetectorDefs::E_Vrf, 0) << '\n';
// slsDetector d2(type);
// std::cout << "Online: " << d2.getOnlineFlag() << '\n';
// d2.setHostname("beb55555");
// d2.setOnline(true);
// std::cout << "Online: " << d2.getOnlineFlag() << '\n';
// std::cout << "hostname: " << d2.getHostname() << '\n';
// std::cout << "port: " << d.getControlPort() << '\n';
// d.setOnline(true);
// d.setReceiverOnline(true);
// std::cout << "reciver version: " << std::hex << d.getReceiverVersion() << '\n';
// // std::cout << "version: " << d.getId(slsDetectorDefs::CLIENT_RECEIVER_API_VERSION) << '\n';
// d.freeSharedMemory();
// //Catch exception
// try {
// throw RuntimeError("something went wrong");
// } catch (RuntimeError &e) {
// std::cout << "Caught RuntimeError with message : " << e.what() << '\n';
// }
// //Catch base class
// try {
// throw SharedMemoryError("Could not create shared memory");
// } catch (RuntimeError &e) {
// std::cout << "Caught: " << e.what() << '\n';
// }
// //Catch base class after looking for something else
// try {
// throw SharedMemoryError("Could not create shared memory");
// } catch (SocketError &e) {
// std::cout << "Caught Socket error: " << e.what() << '\n';
// } catch (RuntimeError &e) {
// std::cout << "Caught base class: " << e.what() << '\n';
// }
// //Catch any after looking for something else
// try {
// throw SharedMemoryError("Could not create shared memory");
// } catch (SocketError &e) {
// std::cout << "Caught Socket error: " << e.what() << '\n';
// } catch (...) {
// std::cout << "Caught Something else probably should have let me crash\n";
// }
// throw RuntimeError("This one we missed");
return 0;
}

View File

@ -0,0 +1,11 @@
// #include "catch.hpp"
// #include "multiSlsDetector.h"
// #include <iostream>
// TEST_CASE("Initialize a detector") {
// multiSlsDetector det(0, true, true);
// std::cout << "Size: " << det.getNumberOfDetectors() << std::endl;
// std::cout << "Hostname: " << det.getHostname() << std::endl;
// REQUIRE(false);
// }

View File

@ -0,0 +1,199 @@
#include "catch.hpp"
#include "ClientSocket.h"
#include "logger.h"
#include "slsDetector.h"
#include "sls_detector_defs.h"
#include "Timer.h"
#include "sls_detector_funcs.h"
#include <iostream>
#include <vector>
#define VERBOSE
auto type_enum = slsDetectorDefs::detectorType::EIGER;
const std::string hostname = "beb083";
const std::string type_string = "Eiger";
const std::string my_ip = "129.129.205.242";
TEST_CASE("single EIGER detector no receiver basic set and get") {
//TODO! this test should take command line arguments for config
//Read type by connecting to the detector
auto type = slsDetector::getTypeFromDetector(hostname);
CHECK(type == type_enum);
//Create slsDetector of said type and set hostname and detector online
slsDetector d(type);
CHECK(d.getDetectorTypeAsEnum() == type);
CHECK(d.getDetectorTypeAsString() == type_string);
d.setHostname(hostname);
CHECK(d.getHostname() == hostname);
d.setOnline(true);
CHECK(d.getOnlineFlag() == true);
CHECK(d.getReceiverOnline() == false);
CHECK(d.checkDetectorVersionCompatibility() == slsDetectorDefs::OK);
//Setting and reading exposure time
auto t = 1000000000;
d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME, t);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) == t);
//size of an eiger half module with and without gap pixels
CHECK(d.getTotalNumberOfChannels() == 256 * 256 * 4);
CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::X) == 1024);
CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::Y) == 256);
// CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::dimension::X) == 1024);
CHECK(d.getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::dimension::Y) == 256);
// CHECK(d.getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getNChans() == 256 * 256);
CHECK(d.getNChans(slsDetectorDefs::dimension::X) == 256);
CHECK(d.getNChans(slsDetectorDefs::dimension::Y) == 256);
// CHECK(d.getNChans(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getNChips() == 4);
CHECK(d.getNChips(slsDetectorDefs::dimension::X) == 4);
CHECK(d.getNChips(slsDetectorDefs::dimension::Y) == 1);
// CHECK(d.getNChips(slsDetectorDefs::dimension::Z) == 1);
d.freeSharedMemory();
}
TEST_CASE("Set control port then create a new object with this control port") {
/*
TODO!
Standard port but should not be hardcoded
Is this the best way to initialize the detectors
Using braces to make the object go out of scope
*/
int old_cport = DEFAULT_PORTNO;
int old_sport = DEFAULT_PORTNO + 1;
int new_cport = 1993;
int new_sport = 2000;
{
auto type = slsDetector::getTypeFromDetector(hostname);
CHECK(type == type_enum);
slsDetector d(type);
d.setHostname(hostname);
d.setOnline(true);
CHECK(d.getControlPort() == old_cport);
d.setControlPort(new_cport);
CHECK(d.getStopPort() == old_sport);
d.setStopPort(new_sport);
d.freeSharedMemory();
}
{
auto type = slsDetector::getTypeFromDetector(hostname, new_cport);
CHECK(type == type_enum);
slsDetector d(type);
d.setHostname(hostname);
d.setControlPort(new_cport);
d.setStopPort(new_sport);
CHECK(d.getControlPort() == new_cport);
CHECK(d.getStopPort() == new_sport);
d.setOnline(true);
//Reset standard ports
d.setControlPort(old_cport);
d.setStopPort(old_sport);
d.freeSharedMemory();
}
auto type = slsDetector::getTypeFromDetector(hostname);
CHECK(type == type_enum);
slsDetector d(type);
d.setHostname(hostname);
d.setOnline(true);
CHECK(d.getStopPort() == DEFAULT_PORTNO + 1);
}
TEST_CASE("Locking mechanism and last ip") {
auto type = slsDetector::getTypeFromDetector(hostname);
slsDetector d(type);
d.setHostname(hostname);
d.setOnline(true);
//Check that detector server is unlocked then lock
CHECK(d.lockServer() == 0);
d.lockServer(1);
CHECK(d.lockServer() == 1);
//Can we do things while it is locked
auto t = 1300000000;
d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME, t);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) == t);
//unlock again
d.lockServer(0);
CHECK(d.lockServer() == 0);
CHECK(d.getLastClientIP() == my_ip);
}
TEST_CASE("Excersise all possible set timer functions") {
// FRAME_NUMBER, /**< number of real time frames: total number of acquisitions is number or frames*number of cycles */
// ACQUISITION_TIME, /**< exposure time */
// FRAME_PERIOD, /**< period between exposures */
// DELAY_AFTER_TRIGGER, /**< delay between trigger and start of exposure or readout (in triggered mode) */
// GATES_NUMBER, /**< number of gates per frame (in gated mode) */
// CYCLES_NUMBER, /**< number of cycles: total number of acquisitions is number or frames*number of cycles */
// ACTUAL_TIME, /**< Actual time of the detector's internal timer */
// MEASUREMENT_TIME, /**< Time of the measurement from the detector (fifo) */
// PROGRESS, /**< fraction of measurement elapsed - only get! */
// MEASUREMENTS_NUMBER,
// FRAMES_FROM_START,
// FRAMES_FROM_START_PG,
// SAMPLES,
// SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */
// STORAGE_CELL_NUMBER, /**<number of storage cells */
// SUBFRAME_DEADTIME, /**< subframe deadtime */
// MEASURED_PERIOD, /**< measured period */
// MEASURED_SUBPERIOD, /**< measured subperiod */
// MAX_TIMERS
auto type = slsDetector::getTypeFromDetector(hostname);
slsDetector d(type);
d.setHostname(hostname);
d.setOnline(true);
//Number of frames
auto frames = 10;
d.setTimer(slsDetectorDefs::timerIndex::FRAME_NUMBER, frames);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::FRAME_NUMBER) == frames);
auto t = 10000000;
d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME, t);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) == t);
auto period = 1000000000;
d.setTimer(slsDetectorDefs::timerIndex::FRAME_PERIOD, period);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::FRAME_PERIOD) == period);
// not implemented for EIGER
// auto delay = 10000;
// d.setTimer(slsDetectorDefs::timerIndex::DELAY_AFTER_TRIGGER, delay);
// CHECK(d.setTimer(slsDetectorDefs::timerIndex::DELAY_AFTER_TRIGGER) == delay);
// auto gates = 1;
// d.setTimer(slsDetectorDefs::timerIndex::GATES_NUMBER, gates);
// CHECK(d.setTimer(slsDetectorDefs::timerIndex::GATES_NUMBER) == gates);
auto cycles = 2;
d.setTimer(slsDetectorDefs::timerIndex::CYCLES_NUMBER, cycles);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::CYCLES_NUMBER) == cycles);
auto subtime = 200;
d.setTimer(slsDetectorDefs::timerIndex::SUBFRAME_ACQUISITION_TIME, subtime);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::SUBFRAME_ACQUISITION_TIME) == subtime);
}
// TEST_CASE()

View File

@ -0,0 +1,3 @@
// tests-main.cpp
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

View File

@ -3,8 +3,8 @@ set(SOURCES
)
include_directories(
../../slsSupportLib/include
../../slsReceiverSoftware/include
../../slsDetectorSoftware/slsDetectorAnalysis
../../build/bin
../../slsdetectorSoftware/slsDetector
)
@ -16,15 +16,12 @@ add_executable(slsMultiReceiver
target_link_libraries(slsMultiReceiver
slsReceiverShared
pthread
zmq
${ZeroMQ_LIBRARIES}
rt
${HDF5_LIBRARIES}
)
if (HDF5_FOUND)
target_link_libraries(slsMultiReceiver
${HDF5_LIBRARIES}
)
target_link_libraries(slsMultiReceiver ${HDF5_LIBRARIES})
endif ()

View File

@ -1,9 +1,9 @@
PKGDIR = ../..
LIBDIR = $(PKGDIR)/build/bin
INCLUDES = -I . -I$(PKGDIR)/slsReceiverSoftware/include -I$(PKGDIR)/slsDetectorSoftware/slsDetectorAnalysis -I$(LIBDIR) -I$(PKGDIR)/slsDetectorSoftware/slsDetector
LIBDIR = $(PKGDIR)/bin
INCLUDES = -I . -I$(PKGDIR)/slsSupportLib/include -I$(LIBDIR) -I$(PKGDIR)/slsDetectorSoftware/slsDetector -I$(PKGDIR)/slsReceiversoftware/include
SRC_DET = mainClient.cpp
SRC_REC = mainReceiver.cpp
ZMQLIBDIR = $(PKGDIR)/slsReceiverSoftware/include
ZMQLIBDIR = $(PKGDIR)/slsSupportLib/include
LDFLAG_DET = -I. -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsDetector -L/usr/lib64/ -pthread -lrt -L$(ZMQLIBDIR) -Wl,-rpath=$(ZMQLIBDIR) -lzmq
LDFLAG_REC = -I. -L$(LIBDIR) -Wl,-rpath=$(LIBDIR) -lSlsReceiver -L/usr/lib64/ -pthread -lrt -L$(ZMQLIBDIR) -Wl,-rpath=$(ZMQLIBDIR) -lzmq
DESTDIR ?= ../docs

View File

@ -16,7 +16,7 @@ It is linked in manual/manual-api from slsReceiverSoftware/include ]
*/
#include "sls_receiver_defs.h"
#include "sls_detector_defs.h"
#include "slsReceiverUsers.h"
#include <iostream>
@ -96,20 +96,20 @@ void AcquisitionFinished(uint64_t frames, void*p){
* @param p pointer to object
*/
void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata;
slsReceiverDefs::sls_detector_header detectorHeader = header->detHeader;
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata;
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row,
"#### %d GetData: ####\n"
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu"
"\t\ttimestamp: %llu\t\tmodId: %u\t\t"
"frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu"
"\t\ttimestamp: %lu\t\tmodId: %u\t\t"
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
//"\t\tpacketsMask:%s"
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId,
(long long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
detectorHeader.row, (long unsigned int)detectorHeader.frameNumber,
detectorHeader.expLength, detectorHeader.packetNumber, (long unsigned int)detectorHeader.bunchId,
(long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
detectorHeader.debug, detectorHeader.roundRNumber,
detectorHeader.detType, detectorHeader.version,
@ -130,8 +130,8 @@ void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
* @param p pointer to object
*/
void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){
slsReceiverDefs::sls_receiver_header* header = (slsReceiverDefs::sls_receiver_header*)metadata;
slsReceiverDefs::sls_detector_header detectorHeader = header->detHeader;
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata;
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row,
"#### %d GetData: ####\n"
@ -187,7 +187,7 @@ int main(int argc, char *argv[]) {
sa.sa_flags=0; // no flags
sa.sa_handler=sigInterruptHandler; // handler function
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
if (sigaction(SIGINT, &sa, NULL) == -1) {
if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n");
}
@ -197,7 +197,7 @@ int main(int argc, char *argv[]) {
asa.sa_flags=0; // no flags
asa.sa_handler=SIG_IGN; // handler function
sigemptyset(&asa.sa_mask); // dont block additional signals during invocation of handler
if (sigaction(SIGPIPE, &asa, NULL) == -1) {
if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGPIPE\n");
}
@ -221,10 +221,10 @@ int main(int argc, char *argv[]) {
char temp[10];
sprintf(temp,"%d",startTCPPort + i);
char* args[] = {(char*)"ignored", (char*)"--rx_tcpport", temp};
int ret = slsReceiverDefs::OK;
int ret = slsDetectorDefs::OK;
/** - create slsReceiverUsers object with appropriate arguments */
slsReceiverUsers *receiver = new slsReceiverUsers(3, args, ret);
if(ret==slsReceiverDefs::FAIL){
if(ret==slsDetectorDefs::FAIL){
delete receiver;
exit(EXIT_FAILURE);
}
@ -236,22 +236,22 @@ int main(int argc, char *argv[]) {
/** - Call back for start acquisition */
cprintf(BLUE, "Registering StartAcq()\n");
receiver->registerCallBackStartAcquisition(StartAcq, NULL);
receiver->registerCallBackStartAcquisition(StartAcq, nullptr);
/** - Call back for acquisition finished */
cprintf(BLUE, "Registering AcquisitionFinished()\n");
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, NULL);
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, nullptr);
/* - Call back for raw data */
cprintf(BLUE, "Registering GetData() \n");
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,NULL);
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,NULL);
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,nullptr);
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,nullptr);
}
/** - start tcp server thread */
if (receiver->start() == slsReceiverDefs::FAIL){
if (receiver->start() == slsDetectorDefs::FAIL){
delete receiver;
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
exit(EXIT_FAILURE);
@ -272,7 +272,7 @@ int main(int argc, char *argv[]) {
sa.sa_flags=0; // no flags
sa.sa_handler=SIG_IGN; // handler function
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
if (sigaction(SIGINT, &sa, NULL) == -1) {
if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n");
}
@ -283,7 +283,7 @@ int main(int argc, char *argv[]) {
/** - Parent process waits for all child processes to exit */
for(;;) {
pid_t childPid = waitpid (-1, NULL, 0);
pid_t childPid = waitpid (-1, nullptr, 0);
// no child closed
if (childPid == -1) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -24,7 +24,7 @@ Figure ~\ref{boards} show the readout board basic components on an Eiger half mo
\begin{center}
\includegraphics[width=1\textwidth]{Boards}
\end{center}
\caption{Picture with most relevant components of the EIGER readout system. The readout system starts with the Front End Boards (FEB) which performs data descrambling (also converts the packets from 12 $\to$ 16 bits) and rate correction. The BackEndBoard (BEB) has 2x2GB DDR2 memories and can perform data buffering (storing images on board) and data summation (16 bit $\to$ 32 bits). The controls to the detector are passed through the 1Gb, while in most installations, the data are sent out through the 10GB ethernet connection.}
\caption{Picture with most relevant components of the EIGER readout system. The readout system starts with the Front End Boards (FEB) which performs data descrambling (also converts the packets from 12 $\to$ 16 bits) and rate correction. The BackEndBoard (BEB) has 2x2GB DDR2 memories and can perform data buffering (storing images on board) and data summation (16 bit $\to$ 32 bits). The controls to the detector are passed through the 1Gb, while in most installations, the data are sent out through the 10~GB ethernet connection.}
\label{boards}
\end{figure}
@ -64,7 +64,8 @@ The directory contains some executables that are needed to make your detector to
\begin{verbatim}
./on #to switch modules on
./off #to switch modules off
./hvget #gets the current HV value
./state #tells you if is ON or OFF
cat /var/log/pcu.log #displays the log if there are problem
./waterflow #returns the current waterflow returned by the flowmeter
./temp #returns the water temperature returned by the flowmeter
\end{verbatim}
@ -155,6 +156,14 @@ outdir /sls/X12SA/data/x12saop/Data10/Eiger0.5M
threaded 1
\end{verbatim}
The geometry on af an EIGER module, showing the quadrants corresponding to the udp ports and the 2 receivers is shown in figure~\ref{fig:eigerports}.
\begin{figure}[t]
\begin{center}
\includegraphics[width=0.9\textwidth]{Eiger-Chips}
\end{center}
\caption{Geometry of UDP ports and receivers in a singel module.}
\label{fig:eigerports}
\end{figure}
In the case you are developing your own receiver, then you need to remove the 1Gb receiver hostname {\tt{rx\_hostname}} and substitute it with the mac address of the device:
\begin{verbatim}
@ -162,7 +171,6 @@ configuremac 0
rx_udpmac xx:xx:...
\end{verbatim}
One can configure all the detector settings in a parameter file {\tt{setup.det}}, which is loaded by doing:
\begin{verbatim}
sls_detector_put 0-parameters setup.det
@ -218,6 +226,7 @@ We have added a special command, {\tt{thresholdnotb}}, which allows to scan the
\begin{verbatim}
sls_detector_put 0-thresholdnotb energy_in_eV
\end{verbatim}
See section~\ref{sec:fastthresholdscan}.
\section{Standard acquisition}
@ -560,12 +569,23 @@ Here are the implemented options so far:
\item {\tt{auto}} is the software controlled acquisition (does not use triggers), where {\tt{exptime}} and {\tt{period}} have to be set. Set number of cycles (i.e. triggers) to 1 using {\tt{cycles}}. Set number of frames using {\tt{frames}}.
\item {\tt{trigger}} 1 frame taken for 1 trigger. Your {\tt{frames}} needs to be 1 always, {\tt{cycles}} can be changed and defines how many triggers are considered. {\tt{exptime}} needs to be set. In the GUI this is called trigger exposure series.
\item {\tt{burst\_trigger}} gets only 1 trigger, but allows to take many frames. With {\tt{frames}} one can change the number of frames. {\tt{cycles}} needs to be 1. {\tt{exptime}} and {\tt{period}} have to be set. In the gui it is called trigger readout.
\item{\tt{gating}} allows to get a frame only when the trigger pulse is gating. Note that in this case the exp time and period only depend on the gating signal. {\tt{cycles}} allows to select how many gates to consider. Set number of frames to 1 using {\tt{frames}}.
\item{\tt{gating}} allows to get a frame only when the trigger pulse is gating. Note that in this case the exp time and period only depend on the gating signal. {\tt{cycles}} allows to select how many gates to consider. Set number of frames to 1 using {\tt{frames}}. ATTENTION: if you are in 16 bit mode and you are applying online rate corrections, as now the exptime is generated by the trigger, you might not have correct rate corrections. If you know what the exposure time is in the gating signal, then you can set the {\tt{exptime}} once and the rate corrections will be correct. If the exposure time is unknow, it is recommended that you switch off the rate corrections. In 32 bit mode, it does not matter as the rate corrections depends on the {\tt{subexptime}} which is software set independently from the gate exptime.
\end{itemize}
Hardware-wise, the ENABLE OUT signal outputs when the chips are really acquiring. This means that the single subframes will be output in 32 bit mode. The TRIGGER OUT outputs the sum-up-signal at the moment (which is useless). This will be changed in the future to output the envelop of the enable signal.
We are planning to change some functionality, i.e. unify the {\tt{trigger}} and {\tt{burst}} trigger modes and make both {\tt{frames}} and {\tt{cycles}} configurable at the same time.
We are planning to change some functionality, i.e. unify the {\tt{trigger}} and {\tt{burst\_trigger}} trigger modes and make both {\tt{frames}} and {\tt{cycles}} configurable at the same time.
There is the possibility to use {\tt{timing trigger/burst\_trigger}} and send software single commands to fake the trigger. This is done with:
\begin{verbatim}
sls_detector_put 0-timing [trigger/burst_trigger]
sls_detector_put 0-frames x
sls_detector_put 0-cycles y
sls_detector_status trigger
\end{verbatim}
Note that this functionality is very (!) useful if you need to do something between and acquisition and the next. This can be used to do a fast threshold scan for example. See section~\ref{sec:fastthresholdscan}.
\section{Autosumming and rate corrections} \label{advanced}
@ -699,7 +719,7 @@ To activate back a module, do:
\end{verbatim}
\end{itemize}
\subsection{Setting up 10Gb correctly: experience so far}\label{10g}
\section{Setting up the PC settings for 10Gb}\label{10g}
For configuring well the 10Gb card not to loose packets,
\begin{itemize}
@ -721,13 +741,54 @@ Very important is to activate the flow control in 10Gb (in 1Gb it is on by defau
\begin{verbatim}
./sls_detector_put flowcontrol_10g 1
\end{verbatim}
Set the transmission delays as explained in the manual.
You ned to check that flow control is setup on the reeceiving interfaces. Check with:
\begin{verbatim}
ethtool -a eth1
\end{verbatim}
.RX should be ON. Set the transmission delays as explained in the manual if necessary. These transmission delays should help matching teh writing speed performance of your disk. You can check how fast you are writing using the {\tt{dstat}} command.
Now setup the computer server propery:
Check the size of:
\begin{verbatim}
sysctl -a | grep backlog
sysctl -a | grep rmem
\end{verbatim}
Set it correctly with:
\begin{verbatim}
sysctl net.core.netdev_max_backlog=250000
sysctl net.core.rmem_default=$((100*1024*1024))
\end{verbatim}
Last, you can disable power saving in teh CPU frequency:
\begin{verbatim}
cpupower frequency-info
cpupower frequency-set -g performance
\end{verbatim}
It can help to increase the fifo size of the receiver to {\tt{rx\_fifodepth}} to 1000 images
\begin{verbatim}
./sls_detector_put rx_fifodepth 1000
\end{verbatim}
One needs to keep into account that in 16 bit mode for 1 image we expect each slsReceiver to allocate 0.5MB. So for 1000 images, we expect 500MB memory for each receiver. This can be monitored in Linux with "top" or "free -m".
One needs to keep into account that in 16 bit mode for 1 image we expect each slsReceiver to allocate 0.5MB. So for 1000 images, we expect 500MB memory for each receiver. This can be monitored in Linux with "top" or "free -m". To receive the max number of images possible on the detector, a minimum of 8~GB of memories are required.
Last, it is very important that not too many files are created. There is high possibility to loose packets in the time to close and open files for the writer. IN 3.1.x, the default number of images written per file, in Eiger is 2000. This is defined by the line:
\begin{verbatim}
#define EIGER_MAX_FRAMES_PER_FILE 2000
\end{verbatim}
in {\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}. In 4.0.x, this is interactively defined using the command: {\tt{r\_framesperfile}}. By default it is 10000.
If you do not have a large disk, you can write to memory if your pc is not fast enough:
\begin{verbatim}
mount -t tmpfs none /ramdisk_folder
\end{verbatim}
or
\begin{verbatim}
mount -t tmpfs none /mnt/ramdisk -o size=10G
\end{verbatim}
check how many GB memory you can allocate, to avoid swapping otherwise
\section{Offline processing and monitoring}
@ -807,6 +868,11 @@ Checkout the {\tt{developer}} branch if in a 3.1.X release or the {\tt{v4.0.0}}
Three possible conversions are possible: into \textbf{cbf}, \textbf{hdf5} and \textbf{root} format. The detector writes 4 raw files per receiver. An offline image reconstruction executable has been written to collate the possible files together and produce output files. By default an interpolation between the values of the large pixels is performed. Gap pixels between modules are also inserted.
Note that the number of images per file is hardcoded and needs to match whatever you are using in {\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}:
\begin{verbatim}
#define EIGER_MAX_FRAMES_PER_FILE 2000
\end{verbatim}
The default is 2000.
\subsubsection{cbf}
The cbf executable executable uses the CBFlib-0.9.5 library (downloaded from the web as it download some architecture dependent packages at installation).Edit the Makefile to correclty point at it.\\
@ -820,7 +886,7 @@ eg.
{\tt{cbfMaker /scratch/run\_63\_d1\_f000000000000\_3.raw}}\\
To use it any geometry:\\
{\tt{cbfMaker [filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
{\tt{cbfMaker [filename] [outdir, def=same as filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
eg.
{\tt cbfMaker /scratch/run\_63\_d0\_f000000000000\_3.raw 3072 512 1 2 ``Eiger'' 0}.\\
@ -876,7 +942,7 @@ are not commented out. All other options need to be commented out. Copile the co
make hdf5Maker; make hdf5MakerOMNY;
\end{verbatim}
If you are at cSAXS. all images collected will be written in a single file. If you are not at CSAXS, most likely you want to have all the images written in a single raw file into an HDF5 file. The multiple HDF5 files are then linked in a master file, with many subdatasets (can be read by albula) or by a virtual file with a single dataset. If you want a mster o virtual file, uncomment this option:
If you are at cSAXS. all images collected will be written in a single file. If you are not at CSAXS, most likely you want to have all the images written in a single raw file into an HDF5 file. The multiple HDF5 files are then linked in a master file, with many subdatasets (can be read by albula) or by a virtual file with a single dataset. If you want a master o virtual file, uncomment this option:
\begin{verbatim}
#define MASTERVIRTUAL
\end{verbatim}
@ -898,7 +964,7 @@ The data will be written as TH2D in root format. Edit the {\tt{Makefile}} to poi
\begin{verbatim}
make image
\end{verbatim}
There is no program other executable that alredy keeps into account the geometry for it.
There is no program other executable that already keeps into account the geometry for it.
To use it any geometry:\\
{\tt{image [filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
eg.
@ -966,9 +1032,9 @@ ssh root@$i sync; done
\section{Loading firmware bitfiles}
\textbf{As a new procedure, the first thing to do is to kill the server on the boards, copy the new one there without starting it.} Note taht failure to do this step before may cause the linux on the baords to crash and not being able to ping it (this if the registers between the old and new firmware change).
\textbf{As a new procedure, the first thing to do is to kill the server on the boards, copy the new one there without starting it.} Note that failure to do this step before may cause the linux on the boards to crash and not being able to ping it (this if the registers between the old and new firmware change).
This is teh procedure from a terminal;
This is the procedure from a terminal;
\begin{verbatim}
for i in beb111 beb070;
do ssh root@$i killall eigerDetectorServer;
@ -1046,6 +1112,40 @@ To load the special noise file look at {\tt{settingsdir/eiger/standard/eigernois
\begin{verbatim}
sls_detector_put trimbits ../settingsdir/eiger/standard/eigernoise
\end{verbatim}
To exit from this pattern noise, just set the threshold to something known.
\begin{verbatim}
\item sls_detector_put threshold 50000 standard
\end{verbatim}
where 5000 would be a value in eV and {/tt{standard}} is important in this case.
\section{(Fast) threshold scans during beam operation}\label{sec:fastthresholdscan}
Occasionally you might need to do threshold scans during your data taking (for example for Laue experiments or to get any spectral information). Setting the threshold in this case would be not optimal as you would change trimbits at every energy and this could give you a ``step'' behaviour. What you could do is to use the
\begin{verbatim}
\item sls_detector_put thresholdnotb 50000
\end{verbatim}
which set the threshold to an energy but does not change trimbits. We suggest that before using this function you load the {\tt{threshold}} at an energy in the middle of your scan range and then change {\tt{thresholdnotb}}.
We have also been requested if we could speed up the threshold scan. At the moment no specific function has been integrated in firmware, but one could use the software trigger option to perform what you need:
\begin{verbatim}
./sls_detector_put exptime 0.01
./sls_detector_put timing trigger
./sls_detector_put enablefwrite 0
./sls_detector_put resetframescaught 0
./sls_detector_put index 0
./sls_detector_put cycles 21
./sls_detector_put receiver start
./sls_detector_put status start
for i in $(seq 0 20);
do
#./sls_detector_put thresholdnotb 5000 ##this is still too slow as it loads the module
./sls_detector_put 0:vrf 3199 #need to know the appropriate vrf at every energy
./sls_detector_put 1:vrf 3199 #need to know the appropriate vrf at every energy
./sls_detector_put status trigger
#sleep 0.005
done
./sls_detector_put receiver stop
./sls_detector_put resetframescaught 0
./sls_detector_put timing auto
\end{verbatim}
\section{Troubleshooting}
\subsection{Cannot successfully finish an acquisition}
@ -1167,6 +1267,13 @@ If you see strange lines in vertical occurring at period patterns, it is a memor
\subsection{ssh to the boards takes long}
Depending on your network setup, to speed up the ssh to the boards from a pc with internal dhcp server running: \textbf{iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE; echo "1" > /proc/sys/net/ipv4/ip\_forward}, where eth1 has to be the 1Gb network device on the pc
\subsection{Generate keys on the boards not to have to type the password}
\begin{verbatim}
export AFSDIRS64=/afs/psi.ch/intranet/Controls/Software/Trolltech/SL6-x86_64
ssh-copy-id -i /afs/psi.ch/user/t/tinti_g/.ssh/id_rsa.pub root@beb100
ssh-keygen
\end{verbatim}
\subsection{Check firmware version installed on BEB}
You can either ask in the client as described in section~\ref{api}, or login to the boards directly. Follow some steps described in Section~\ref{server}.
\begin{verbatim}
@ -1190,6 +1297,13 @@ Scroll up in the terminal till you find:\\
*************** MASTER/SLAVE ***************\\
*************** NORMAL/SPECIAL ***************\\
There is also an easier way, that is that only the master module will return the real value of the HV. If you have more than 1 detector system, then you will have more than 1 physical master, as the HV needs to be applied to all the systems.
\begin{verbatim}
for i in $(seq 0 36); do sls_detector_put $i:vhighvoltage; done
\end{verbatim}
Only the master will return to you a sensible number (150 normally). the others will return -999.
\subsection{'Cannot connect to socket'}
This error is typically due to the detector server not running. For why, see section~\ref{servernot}.
@ -1207,10 +1321,10 @@ If you see the client returning the following error message:\\
\end{verbatim}
\subsection{There is noise running the detector in 32-bit}
If you are running the detector in 32-bit (autosumming), there might be some noise, particularly at lower thereshold energies. This is due to the fact that the analog part of the chips require some latency time to settle which is larger than the readout time. It is possible to run the detector only in {\tt{parallel}} or {\tt{nonparallel}} mode, respectively with readout times between frames of 12~$\mu$s and 504~$\mu$s. If you switch {\tt{flags}} to non {\tt{nonparallel}} mode you will give enough time for the signals to settle. From release 4.0.0, there is a configurable delay that can be set through the {\tt{subdeadtime}} variable, such that you can remain with the {\tt{parallel}} flag, but can obtain a configurable dead time between frames. Ask the SLS detector group for an appropriate dead time for your detector, but typically a dead time of 20-50~$\mu$s should be enough. Note that this {\tt{subdeadtime}} need to include the 12~$\mu$s minimum readout time, so it has to be larger than 12~$\mu$s to do anything.
If you are running the detector in 32-bit (autosumming), there might be some noise, particularly at lower threshold energies. This is due to the fact that the analog part of the chips require some latency time to settle which is larger than the readout time. It is possible to run the detector only in {\tt{parallel}} or {\tt{nonparallel}} mode, respectively with readout times between frames of 12~$\mu$s and 504~$\mu$s. If you switch {\tt{flags}} to non {\tt{nonparallel}} mode you will give enough time for the signals to settle. From release 4.0.0, there is a configurable delay that can be set through the {\tt{subdeadtime}} variable, such that you can remain with the {\tt{parallel}} flag, but can obtain a configurable dead time between frames. Ask the SLS detector group for an appropriate dead time for your detector, but typically a dead time of 20-50~$\mu$s should be enough. Note that this {\tt{subdeadtime}} need to include the 12~$\mu$s minimum readout time, so it has to be larger than 12~$\mu$s to do anything.
\subsection{There is noise running the detector at high frame rate(4,8,16 bit)}
If are running in {\tt{parallel}} mode, in particular at low thereshold energies, you might encounter some noise. The reason is that the analog part of the chips require some latency time to settle which is larger than the readout time.
If are running in {\tt{parallel}} mode, in particular at low threshold energies, you might encounter some noise. The reason is that the analog part of the chips require some latency time to settle which is larger than the readout time.
\begin{enumerate}
\item You can lower the frame rate and relax requirements on period:
At low frame rate, you normally leave enough time between the end of the acquisition and the starting of the next, so you should not see this effect. In any case setting a {\tt{period}}={\tt{exptime}}+readout time from Table~\ref{tchipro} +extra 20$\mu$s cures the problem. The 20$\mu$s could also be 10~$\mu$s, they are very hardware dependent.

View File

@ -369,7 +369,7 @@ source directory.
$ cd ..
$ mkdir slsDetectorPackage-build
$ cd slsDetectorPackage-build
$ cmake ../slsDetectorPackage -DCMAKE_BUILD_TYPE=Debug -DUSE_HDF5=OFF
$ cmake ../slsDetectorPackage -DCMAKE_BUILD_TYPE=Debug -DSLS_USE_HDF5=OFF
$ make
\end{verbatim}
@ -377,7 +377,7 @@ Use the following as an example to compile statically and using specific hdf5
folder
\begin{verbatim}
$ HDF5_ROOT=/opt/hdf5v1.10.0 cmake ../slsDetectorPackage
-DCMAKE_BUILD_TYPE=Debug -DUSE_HDF5=ON
-DCMAKE_BUILD_TYPE=Debug -DSLS_USE_HDF5=ON
\end{verbatim}
After compiling, the libraries and executables will be found at `bin` directory

39
python/CMakeLists.txt Normal file
View File

@ -0,0 +1,39 @@
add_subdirectory(pybind11)
pybind11_add_module(_sls_detector src/main.cpp)
target_link_libraries(_sls_detector PUBLIC
slsDetectorShared
slsReceiverShared
slsSupportLib )
set_target_properties(_sls_detector PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
#Copy Python code
set( PYTHON_FILES
__init__.py
adcs.py
dacs.py
decorators.py
detector_property.py
detector.py
eiger.py
errors.py
experimental.py
jungfrau_ctb.py
jungfrau.py
registers.py
utils.py
)
foreach(FILE ${PYTHON_FILES})
configure_file( sls_detector/${FILE}
${CMAKE_BINARY_DIR}/bin/sls_detector/${FILE} )
endforeach(FILE ${PYTHON_FILES})
configure_file( scripts/basic.py
${CMAKE_BINARY_DIR}/basic.py )

674
python/LICENSE Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

63
python/README.md Normal file
View File

@ -0,0 +1,63 @@
# sls_detector: Python interface to slsDetectorPackage
Python interface to the Sls Detector Software.
### Documentation ###
Sphinx built documentation is available here:
[https://slsdetectorgroup.github.io/sls_detector/](https://slsdetectorgroup.github.io/sls_detector/)
### Install using conda ###
Binaries are available using conda. This installs both the detector software and the Python
interface.
```bash
#Add conda channels
conda config --add channels conda-forge
conda config --add channels slsdetectorgroup
#Install latest version
conda install sls_detector
#Install specific version
conda install sls_detector=3.0.1
#Scientific Linux 6 version (GLIBC2.12)
conda install sls_detector=SL6_3.0.1
```
### Building using conda-build ###
Needs [sls_detector_software](https://github.com/slsdetectorgroup/sls_detector_software) installed.
```bash
#Clone source code
git clone https://github.com/slsdetectorgroup/sls_detector.git
#Checkout the branch needed
git checkout 3.0.1
#Build and install the local version
conda-build sls_detector
conda install --use-local sls_detector
```
### Developer build ###
IF you if you are developing and are making constant changes to the code it's a bit cumbersome
to build with conda and install. Then an easier way is to build the C/C++ parts in the package
directory and temporary add this to the path
```bash
#in path/to/sls_detector
python setup.py build_ext --inplace
```
Then in your Python script
```python
import sys
sys.path.append('/path/to/sls_detector')
from sls_detector import Detector
```

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
${PYTHON} setup.py install # Python command to install the script

View File

@ -0,0 +1,43 @@
package:
name: sls_detector
version: refactor
build:
number: 0
source:
path: ..
requirements:
build:
- {{ compiler('c') }}
- {{ compiler('cxx') }}
- cmake
- python {{ python }}
- libpng >=1.6.32,<1.6.35
- setuptools
- sls_detector_lib refactor
- pyzmq
- pybind11 2.2
host:
- python
- pybind11 2.2
run:
- python
- numpy
- sls_detector_lib refactor
- pyzmq
- libstdcxx-ng
- libgcc-ng
test:
imports:
- sls_detector
about:
summary: "Interacting with detectors"

1
python/pybind11 Submodule

Submodule python/pybind11 added at a23996fce3

5
python/scripts/basic.py Normal file
View File

@ -0,0 +1,5 @@
from sls_detector import Eiger
from sls_detector import ExperimentalDetector
d = Eiger()
e = ExperimentalDetector()

125
python/setup.py Normal file
View File

@ -0,0 +1,125 @@
"""
Setup file for sls_detector
Build upon the pybind11 example found here: https://github.com/pybind/python_example
"""
from setuptools import setup, Extension, find_packages
from setuptools.command.build_ext import build_ext
import sys
import setuptools
import os
__version__ = 'refactor'
def get_conda_path():
"""
Keep this a function if we need some fancier logic later
"""
print('Prefix: ', os.environ['CONDA_PREFIX'])
return os.environ['CONDA_PREFIX']
class get_pybind_include(object):
"""Helper class to determine the pybind11 include path
The purpose of this class is to postpone importing pybind11
until it is actually installed, so that the ``get_include()``
method can be invoked. """
def __init__(self, user=False):
self.user = user
def __str__(self):
import pybind11
return pybind11.get_include(self.user)
ext_modules = [
Extension(
'_sls_detector',
['src/main.cpp'],
include_dirs=[
# Path to pybind11 headers
get_pybind_include(),
get_pybind_include(user=True),
os.path.join(get_conda_path(), 'include/slsDetectorPackage'),
],
libraries=['SlsDetector', 'SlsReceiver', 'zmq'],
library_dirs=[
os.path.join(get_conda_path(), 'lib'),
os.path.join(get_conda_path(), 'bin'),
],
language='c++'
),
]
# As of Python 3.6, CCompiler has a `has_flag` method.
# cf http://bugs.python.org/issue26689
def has_flag(compiler, flagname):
"""Return a boolean indicating whether a flag name is supported on
the specified compiler.
"""
import tempfile
with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f:
f.write('int main (int argc, char **argv) { return 0; }')
try:
compiler.compile([f.name], extra_postargs=[flagname])
except setuptools.distutils.errors.CompileError:
return False
return True
def cpp_flag(compiler):
"""Return the -std=c++[11/14] compiler flag.
The c++14 is prefered over c++11 (when it is available).
"""
if has_flag(compiler, '-std=c++14'):
return '-std=c++14'
elif has_flag(compiler, '-std=c++11'):
return '-std=c++11'
else:
raise RuntimeError('Unsupported compiler -- at least C++11 support '
'is needed!')
class BuildExt(build_ext):
"""A custom build extension for adding compiler-specific options."""
c_opts = {
'msvc': ['/EHsc'],
'unix': [],
}
if sys.platform == 'darwin':
c_opts['unix'] += ['-stdlib=libc++', '-mmacosx-version-min=10.7']
def build_extensions(self):
ct = self.compiler.compiler_type
opts = self.c_opts.get(ct, [])
if ct == 'unix':
opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version())
opts.append(cpp_flag(self.compiler))
if has_flag(self.compiler, '-fvisibility=hidden'):
opts.append('-fvisibility=hidden')
elif ct == 'msvc':
opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version())
for ext in self.extensions:
ext.extra_compile_args = opts
build_ext.build_extensions(self)
setup(
name='sls_detector',
version=__version__,
author='Erik Frojdh',
author_email='erik.frojdh@psi.ch',
url='https://github.com/slsdetectorgroup/sls_detector',
description='Detector API for SLS Detector Group detectors',
long_description='',
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
ext_modules=ext_modules,
install_requires=['pybind11>=2.2'],
cmdclass={'build_ext': BuildExt},
zip_safe=False,
)

View File

@ -0,0 +1,17 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 14 16:49:07 2017
@author: l_frojdh
"""
fw_version = 23
detector_type = 'Eiger'
known_hostnames = ['beb083', 'beb098']
image_size = (512,1024) #rows, cols
module_geometry = (1,2) #horizontal, vertical
#Remember to change these in the settings file as well!
settings_path = '/home/l_frojdh/slsDetectorPackage/settingsdir/eiger'
file_path = '/home/l_frojdh/out'

View File

@ -0,0 +1,27 @@
import pytest
from sls_detector import Detector
@pytest.fixture
def detector():
from sls_detector import Detector
return Detector()
@pytest.fixture
def eiger():
from sls_detector import Eiger
d = Eiger()
d.n_frames = 1
d.exposure_time = 1
d.file_write = False
return d
@pytest.fixture
def jungfrau():
from sls_detector import Jungfrau
return Jungfrau()
detector_type = Detector().detector_type
eigertest = pytest.mark.skipif(detector_type != 'Eiger', reason = 'Only valid for Eiger')
jungfrautest = pytest.mark.skipif(detector_type != 'Jungfrau', reason = 'Only valid for Jungfrau')

View File

@ -0,0 +1,33 @@
detsizechan 1024 512
#hostname for top+bottom+
hostname beb083+beb098+
#top
0:rx_tcpport 1954
0:lock 0
0:rx_udpport 50010
0:rx_udpport2 50011
0:rx_hostname mpc2048
0:flippeddatax 0
#bottom
1:rx_tcpport 1955
1:lock 0
1:rx_udpport 50004
1:rx_udpport2 50005
1:rx_hostname mpc2048
1:flippeddatax 1
settingsdir /home/l_frojdh/slsDetectorPackage/settingsdir/eiger
outdir /home/l_frojdh/out
vthreshold 1500
vtr 4000
dr 32
threaded 1
tengiga 0
vhighvoltage 150
iodelay 660
#gappixels 1

View File

@ -0,0 +1,2 @@
vrf 3000
vthreshold 1800

View File

@ -0,0 +1,44 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Testing setting dynamic range for Eiger.
If the detector is not Eiger the tests are skipped
"""
import pytest
import config_test
from fixtures import detector, eiger, jungfrau, eigertest, jungfrautest
from sls_detector.errors import DetectorValueError
@eigertest
def test_set_dynamic_range_and_make_acq(eiger):
eiger.exposure_time = 0.5
eiger.n_frames = 2
for dr in [4, 8, 16, 32]:
eiger.dynamic_range = dr
assert eiger.dynamic_range == dr
eiger.acq()
assert eiger.frames_caught == 2
@eigertest
def test_set_dynamic_range_raises(eiger):
with pytest.raises(DetectorValueError):
eiger.dynamic_range = 1
with pytest.raises(DetectorValueError):
eiger.dynamic_range = 75
with pytest.raises(DetectorValueError):
eiger.dynamic_range = -3
with pytest.raises(DetectorValueError):
eiger.dynamic_range = 12
@eigertest
def test_set_dynamic_range_reduces_speed(eiger):
eiger.readout_clock = 'Full Speed'
eiger.dynamic_range = 32
assert eiger.dynamic_range == 32
assert eiger.readout_clock == 'Quarter Speed'
eiger.dynamic_range = 16
assert eiger.dynamic_range == 16
assert eiger.readout_clock == 'Half Speed'

View File

@ -0,0 +1,119 @@
import pytest
import config_test
import time
from sls_detector.errors import DetectorValueError
from fixtures import eiger, eigertest
@eigertest
def test_set_matrix_reset(eiger):
eiger.eiger_matrix_reset = False
assert eiger.eiger_matrix_reset == False
eiger.eiger_matrix_reset = True
assert eiger.eiger_matrix_reset == True
@eigertest
def test_set_tx_delay_left_single(eiger):
eiger.tx_delay.left[0] = 130
assert eiger.tx_delay.left[0] == 130
eiger.tx_delay.left[1] = 150
assert eiger.tx_delay.left[1] == 150
eiger.tx_delay.left[0] = 0
eiger.tx_delay.left[1] = 0
assert eiger.tx_delay.left[0] == 0
assert eiger.tx_delay.left[1] == 0
@eigertest
def test_set_tx_delay_right_single(eiger):
eiger.tx_delay.right[0] = 130
assert eiger.tx_delay.right[0] == 130
eiger.tx_delay.right[1] = 150
assert eiger.tx_delay.right[1] == 150
eiger.tx_delay.right[0] = 0
eiger.tx_delay.right[1] = 0
assert eiger.tx_delay.right[0] == 0
assert eiger.tx_delay.right[1] == 0
@eigertest
def test_set_tx_delay_frame_single(eiger):
eiger.tx_delay.frame[0] = 500
eiger.tx_delay.frame[1] = 600
assert eiger.tx_delay.frame[0] == 500
assert eiger.tx_delay.frame[1] == 600
eiger.tx_delay.frame[0] = 0
eiger.tx_delay.frame[1] = 0
assert eiger.tx_delay.frame[0] == 0
assert eiger.tx_delay.frame[1] == 0
@eigertest
def test_tx_delay_from_list(eiger):
eiger.tx_delay.left = [123,456]
assert eiger.tx_delay.left[:] == [123,456]
eiger.tx_delay.right = [789,100]
assert eiger.tx_delay.right[:] == [789,100]
eiger.tx_delay.frame = [1000,90000]
assert eiger.tx_delay.frame[:] == [1000,90000]
eiger.tx_delay.left = [0, 0]
eiger.tx_delay.right = [0, 0]
eiger.tx_delay.frame = [0, 0]
assert eiger.tx_delay.left[:] == [0, 0]
assert eiger.tx_delay.right[:] == [0, 0]
assert eiger.tx_delay.frame[:] == [0, 0]
@eigertest
def test_acitve(eiger):
eiger.file_write = False
eiger.reset_frames_caught()
eiger.active[1] = False
eiger.acq()
assert eiger._api.getFramesCaughtByReceiver(1) == 0
assert eiger._api.getFramesCaughtByReceiver(0) == 1
eiger.active = True
time.sleep(0.5)
eiger.acq()
assert eiger.frames_caught == 1
@eigertest
def test_set_default_settings(eiger):
eiger.default_settings()
assert eiger.n_frames == 1
assert eiger.exposure_time == 1
assert eiger.period == 0
assert eiger.n_cycles == 1
assert eiger.dynamic_range == 16
@eigertest
def test_flowcontrol10g(eiger):
eiger.flowcontrol_10g = True
assert eiger.flowcontrol_10g == True
eiger.flowcontrol_10g = False
assert eiger.flowcontrol_10g == False
@eigertest
def test_read_vcmp(eiger):
eiger.vthreshold = 1500
assert eiger.vcmp[:] == [1500]*4*eiger.n_modules
@eigertest
def test_set_vcmp(eiger):
eiger.vcmp = [1000,1100,1200,1300,1400,1500,1600,1700]
assert eiger.vcmp[:] == [1000,1100,1200,1300,1400,1500,1600,1700]
eiger.vthreshold = 1500
#Disabled only works with receiver on the same pc
# @eigertest
# def test_setup500k():
# from sls_detector import Eiger, free_shared_memory
# free_shared_memory()
# d = Eiger()
# d.setup500k(config_test.known_hostnames)
# d.acq()
# assert d.rx_tcpport == [1954,1955]
# assert d.frames_caught == 1
# #could assert more setting but if the frame is caught it worked...

View File

@ -0,0 +1,129 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Tests specific for the firmware.
Check that register values are correct after starting an exposure
0x4 exposure time
0x5 period
0x6 sub exposure time
"""
import pytest
import config_test
from fixtures import detector, eiger, jungfrau, eigertest, jungfrautest
from sls_detector.errors import DetectorValueError
from sls_detector.utils import eiger_register_to_time
# testdata_exptimes = [0.001, 0.002, 0.0236]
@eigertest
def test_short_exposure_time(eiger):
t = 1.23
eiger.exposure_time = t
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
#Register 0x4 holds exposure time
reg = eiger.register[0x4]
assert pytest.approx(t, 1e-9) == eiger_register_to_time(reg)
@eigertest
def test_short_minimal_exposure_time(eiger):
t = 1e-8
eiger.exposure_time = t
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
#Register 0x4 holds exposure time
reg = eiger.register[0x4]
assert pytest.approx(t, 1e-9) == eiger_register_to_time(reg)
@eigertest
def test_long_exposure_time(eiger):
t = 623
eiger.exposure_time = t
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
# Register 0x4 holds exposure time
reg = eiger.register[0x4]
assert pytest.approx(t, 1e-9) == eiger_register_to_time(reg)
@eigertest
def test_short_period(eiger):
t = 0.1
eiger.exposure_time = 0.001
eiger.period = t
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
# Register 0x5 holds period
reg = eiger.register[0x5]
assert pytest.approx(t, 1e-9) == eiger_register_to_time(reg)
@eigertest
def test_long_period(eiger):
t = 8900
eiger.exposure_time = 0.001
eiger.period = t
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
# Register 0x5 holds period
reg = eiger.register[0x5]
assert pytest.approx(t, 1e-9) == eiger_register_to_time(reg)
@eigertest
def test_zero_period_with_acq(eiger):
t = 0
eiger.exposure_time = 0.001
eiger.period = t
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
# Register 0x5 holds period
reg = eiger.register[0x5]
assert pytest.approx(t, 1e-9) == eiger_register_to_time(reg)
testdata_times = [0.001, 0.002, 0.0236]
@eigertest
@pytest.mark.parametrize("t", testdata_times)
def test_subexptime(eiger,t):
eiger.sub_exposure_time = t
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
# Register 0x6 holds sub exposure time
# time is stored straight as n clocks
reg = eiger.register[0x6]
assert pytest.approx(t, 1e-9) == reg/100e6
@eigertest
@pytest.mark.parametrize("t", testdata_times)
def test_subdeadtime(eiger, t):
eiger.sub_deadtime = t
eiger.sub_exposure_time = 1
eiger.sub_exposure_time = 0.001
eiger.file_write = False
eiger.start_detector()
eiger.stop_detector()
# Register 0x7 holds sub period
# time is stored straight as n clocks
# exptime+deadtime
reg = eiger.register[0x7]
assert pytest.approx(t, 1e-7) == (reg/100e6-0.001)

View File

@ -0,0 +1,187 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
General tests for the Detector class. Should not depend on the connected detector. Aim is to have tests working
for both Jungfrau and Eiger.
NOTE! Uses hostnames from config_test
"""
import pytest
import config_test
from fixtures import detector
from sls_detector.errors import DetectorValueError, DetectorError
def test_error_handling(detector):
with pytest.raises(DetectorError):
detector._provoke_error()
def test_not_busy(detector):
"""Test that the detector is not busy from the start"""
assert detector.busy == False
def test_reset_frames_caught(detector):
detector.file_write = False
detector.acq()
assert detector.frames_caught == 1
detector.reset_frames_caught()
assert detector.frames_caught == 0
def test_set_busy_true_then_false(detector):
"""Test both cases of assignment"""
detector.busy = True
assert detector.busy == True
detector.busy = False
assert detector.busy == False
def test_set_readout_speed(detector):
for s in ['Full Speed', 'Half Speed', 'Quarter Speed', 'Super Slow Speed']:
detector.readout_clock = s
assert detector.readout_clock == s
def test_wrong_speed_raises_error(detector):
with pytest.raises(KeyError):
detector.readout_clock = 'Something strange'
def test_readout_clock_remains(detector):
s = detector.readout_clock
try:
detector.readout_clock = 'This does not exists'
except KeyError:
pass
assert detector.readout_clock == s
def test_len_method(detector):
"""to test this we need to know the length, this we get from the configuration of hostnames"""
assert len(detector) == len(config_test.known_hostnames)
def test_setting_n_cycles_to_zero_gives_error(detector):
with pytest.raises(DetectorValueError):
detector.n_cycles = 0
def test_setting_n_cycles_to_negative_gives_error(detector):
with pytest.raises(DetectorValueError):
detector.n_cycles = -50
def test_set_cycles_frome_one_to_ten(detector):
for i in range(1,11):
detector.n_cycles = i
assert detector.n_cycles == i
detector.n_cycles = 1
assert detector.n_cycles == 1
def test_get_detector_type(detector):
assert detector.detector_type == config_test.detector_type
def test_set_file_index(detector):
detector.file_index = 5
assert detector.file_index == 5
def test_negative_file_index_raises(detector):
with pytest.raises(ValueError):
detector.file_index = -8
def test_setting_file_name(detector):
fname = 'hej'
detector.file_name = fname
assert detector.file_name == fname
def test_set_file_write(detector):
detector.file_write = True
assert detector.file_write == True
detector.file_write = False
assert detector.file_write == False
def test_set_high_voltage(detector):
detector.high_voltage = 55
assert detector.high_voltage == 55
def test_negative_voltage_raises(detector):
with pytest.raises(DetectorValueError):
detector.high_voltage = -5
def test_high_voltage_raises_on_to_high(detector):
with pytest.raises(DetectorValueError):
detector.high_voltage = 500
def test_get_image_size(detector):
"""Compares with the size in the config file"""
assert detector.image_size.rows == config_test.image_size[0]
assert detector.image_size.cols == config_test.image_size[1]
def test_get_module_geometry(detector):
"""Compares with the size in the config file"""
assert detector.module_geometry.horizontal == config_test.module_geometry[0]
assert detector.module_geometry.vertical == config_test.module_geometry[1]
def test_set_nframes(detector):
detector.n_frames = 5
assert detector.n_frames == 5
detector.n_frames = 1
assert detector.n_frames == 1
def test_set_n_measurements(detector):
detector.n_measurements = 7
assert detector.n_measurements == 7
detector.n_measurements = 1
assert detector.n_measurements == 1
def test_negative_nframes_raises(detector):
with pytest.raises(DetectorValueError):
detector.n_frames = -2
def test_nmodules(detector):
"""Assume that the number of modules should be the same as the number of hostnames"""
assert detector.n_modules == len(config_test.known_hostnames)
def test_is_detector_online(detector):
assert detector.online == True
def test_set_online(detector):
detector.online = False
assert detector.online == False
detector.online = True
assert detector.online == True
def test_receiver_is_online(detector):
assert detector.receiver_online == True
def test_set_receiver_online(detector):
detector.receiver_online = False
assert detector.receiver_online == False
detector.receiver_online = True
assert detector.receiver_online == True
def test_set_receiver_online_raises_on_non_bool(detector):
with pytest.raises(TypeError):
detector.receiver_online = 'probably not this'
def test_set_period(detector):
detector.period = 5.123
assert detector.period == 5.123
detector.period = 0
assert detector.period == 0
def test_set_timing_mode(detector):
detector.timing_mode = 'trigger'
assert detector.timing_mode == 'trigger'
detector.timing_mode = 'auto'
assert detector.timing_mode == 'auto'

View File

@ -0,0 +1,38 @@
import pytest
import config_test
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
from sls_detector.detector import element_if_equal
from sls_detector.errors import DetectorValueError
from fixtures import eiger, eigertest
@eigertest
def test_load_config_file_eiger(eiger):
"""Load a settings file and assert all settings"""
eiger.load_config(os.path.join(dir_path, 'test.config'))
assert eiger.rx_tcpport == [1954, 1955]
assert eiger.lock == False
assert eiger.rx_udpport == [50010, 50011, 50004, 50005]
assert eiger.rx_hostname == 'mpc2048'
assert eiger.flipped_data_x[:] == [False, True]
assert eiger.settings_path == config_test.settings_path
assert eiger.file_path == config_test.file_path
assert eiger.vthreshold == 1500
assert element_if_equal(eiger.dacs.vtr[:]) == 4000
assert eiger.dynamic_range == 32
assert eiger.tengiga == False
assert eiger.high_voltage == 150
assert element_if_equal(eiger.dacs.iodelay[:]) == 660
@eigertest
def test_load_parameters_file_eiger(eiger):
"""Load a parametes file and assert the settings in the file"""
eiger.load_parameters(os.path.join(dir_path, 'test.par'))
assert element_if_equal(eiger.dacs.vrf[:]) == 3000
assert eiger.vthreshold == 1800

View File

@ -0,0 +1,81 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Tests for network related functions of the detector
"""
import pytest
import config_test
from fixtures import eiger, eigertest, detector
# def test_last_client(detector):
# import socket
# # We probably should check for multiple ip's
# myip = socket.gethostbyname_ex(socket.gethostname())[-1][0]
# assert detector.last_client_ip == myip
def test_get_hostname(detector):
for detector_host, config_host in zip(detector.hostname, config_test.known_hostnames):
assert detector_host == config_host
def test_hostname_has_same_length_as_n_modules(detector):
assert len(detector.hostname) == detector.n_modules
# # def test_get_receiver_hostname(detector):
# # """Assume that the receiver are on the local computer"""
# # import socket
# # host = socket.gethostname().split('.')[0]
# # assert detector.rx_hostname == host
# def test_set_receiver_hostname(detector):
# import socket
# host = socket.gethostname().split('.')[0]
# phony_host = 'madeup'
# detector.rx_hostname = phony_host
# assert detector.rx_hostname == phony_host
# detector.rx_hostname = host
# assert detector.rx_hostname == host
@eigertest
def test_set_rx_zmqport_single_value(eiger):
eiger.rx_zmqport = 35000
assert eiger.rx_zmqport == [35000, 35001, 35002, 35003]
@eigertest
def test_set_rx_zmqport_list(eiger):
eiger.rx_zmqport = [37000, 38000]
assert eiger.rx_zmqport == [37000, 37001, 38000, 38001]
@eigertest
def test_set_rx_updport(eiger):
ports = [60010,60011,60012,60013]
eiger.rx_udpport = ports
assert eiger.rx_udpport == ports
eiger.acq()
assert eiger.frames_caught == 1
@eigertest
def test_rx_tcpport(eiger):
ports = eiger.rx_tcpport
eiger.rx_tcpport = [2000,2001]
assert eiger.rx_tcpport == [2000,2001]
eiger.rx_tcpport = ports
assert eiger.rx_tcpport == ports
eiger.acq()
assert eiger.frames_caught == 1
# @eigertest
# @pytest.mark.new
# def test_enable_disable_tengiga(eiger):
# """
# This test does not check for dat on the 10Gbit link, only the set and get functions
# """
# eiger.tengiga = True
# assert eiger.tengiga == True
# eiger.tengiga = False
# assert eiger.tengiga == False
#TODO! Add test for Jungfrau

View File

@ -0,0 +1,54 @@
import pytest
import config_test
from fixtures import detector, eiger, jungfrau, eigertest, jungfrautest
from sls_detector.errors import DetectorValueError
@eigertest
@pytest.mark.local
def test_set_path(eiger, tmpdir):
import os
path = os.path.join(tmpdir.dirname, tmpdir.basename)
eiger.file_path = path
assert eiger.file_path == path
@eigertest
@pytest.mark.local
def test_set_path_and_write_files(eiger, tmpdir):
import os
prefix = 'testprefix'
path = os.path.join(tmpdir.dirname, tmpdir.basename)
eiger.file_path = path
eiger.file_write = True
eiger.exposure_time = 0.1
eiger.n_frames = 1
eiger.timing_mode = 'auto'
eiger.file_name = prefix
eiger.file_index = 0
eiger.acq()
files = [f.basename for f in tmpdir.listdir()]
assert len(files) == 5
assert (prefix+'_d0_0.raw' in files) == True
assert (prefix+'_d1_0.raw' in files) == True
assert (prefix+'_d2_0.raw' in files) == True
assert (prefix+'_d3_0.raw' in files) == True
def test_set_discard_policy(detector):
detector.frame_discard_policy = 'nodiscard'
assert detector.frame_discard_policy == 'nodiscard'
detector.frame_discard_policy = 'discardpartial'
assert detector.frame_discard_policy == 'discardpartial'
detector.frame_discard_policy = 'discardempty'
assert detector.frame_discard_policy == 'discardempty'
def test_set_discard_policy_raises(detector):
with pytest.raises(ValueError):
detector.frame_discard_policy = 'adjfvadksvsj'
def test_set_frames_perfile(detector):
detector.frames_per_file = 5000
assert detector.frames_per_file == 5000

View File

@ -0,0 +1,47 @@
import pytest
import config_test
import time
from sls_detector.errors import DetectorValueError
import os
from fixtures import eiger, eigertest
testdata_th = [0,333,500,1750,2000]
@eigertest
@pytest.mark.parametrize("th", testdata_th)
def test_set_vthreshold(eiger, th):
eiger.vthreshold = th
assert eiger.vthreshold == th
@eigertest
def test_vthreshold_with_different_vcmp(eiger):
#When vcmp is different for the chip vthreshold should return -1
eiger.vthreshold = 1500
eiger.dacs.vcmp_ll = 1400
assert eiger.vthreshold == -1
@eigertest
def test_set_settingsdir(eiger):
path = os.path.dirname( os.path.realpath(__file__) )
path = os.path.join(path, 'settingsdir')
eiger.settings_path = path
assert eiger.settings_path == path
@eigertest
def test_set_trimmed_energies(eiger):
en = [5000,6000,7000]
eiger.trimmed_energies = en
assert eiger.trimmed_energies == en
#TODO! add checks for vcmp as well and improve naming
#TODO! remove dependency on beb number
testdata_en = [(5000, 500),(5500,750),(6000,1000),(6200,1100),(7000,1500)]
@eigertest
@pytest.mark.parametrize('val', testdata_en)
def test_set_energy_threshold(eiger, val):
eiger.settings = 'standard'
eiger.threshold = val[0]
assert eiger.threshold == val[0]
assert eiger.dacs.vrf[0] == val[1]

View File

@ -0,0 +1,136 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Tests regarding exposure time and period of the detector
Set and get test as well as test for duration and on detector
measurement of the time.
"""
import pytest
import config_test
from fixtures import detector, eiger, jungfrau, eigertest, jungfrautest
from sls_detector.errors import DetectorValueError, DetectorError
import time
testdata_times = [1e-8, 0.001, 0.5, 3.125, 5.0, 600, 784]
@pytest.mark.parametrize("t", testdata_times)
def test_set_and_get_exposure_time(eiger, t):
"""
Test that the exposure time we set in the detector
is the same as the one read back
"""
eiger.exposure_time = t
assert eiger.exposure_time == t
def test_negative_exposure_time_raises_error(eiger):
with pytest.raises(DetectorValueError):
eiger.exposure_time = -15
testdata_times = [0.001, 0.0025, 0.005, 5]
@pytest.mark.parametrize("t", testdata_times)
def test_set_subexptime(eiger, t):
eiger.sub_exposure_time = t
assert eiger.sub_exposure_time == t
testdata_times = [-5,6,7,50]
@pytest.mark.parametrize("t", testdata_times)
def test_set_subextime_too_large_or_neg(eiger, t):
with pytest.raises((DetectorError, DetectorValueError)):
eiger.sub_exposure_time = t
testdata_times = [0.2, 0.5, 1, 2, 5, 7]
@pytest.mark.slow
@pytest.mark.parametrize("t", testdata_times)
def test_measure_exposure_time_from_python(eiger, t):
"""
The main idea with this test is to make sure the overhead of a
single acq is less than tol[s]. This test also catches stupid bugs
that would for example not change the exposure time or make acquire
not blocking.
"""
tol = 0.5
eiger.dynamic_range = 16
eiger.file_write = False
eiger.n_frames = 1
eiger.exposure_time = t
assert eiger.exposure_time == t
t0 = time.time()
eiger.acq()
duration = time.time()-t0
assert duration < (t+tol)
testdata_times = [0.5, 1, 3, 5]
@pytest.mark.slow
@pytest.mark.parametrize("t", testdata_times)
def test_measure_period_from_python_and_detector(eiger, t):
tol = 0.5
nframes = 5
eiger.dynamic_range = 16
eiger.file_write = False
eiger.n_frames = nframes
eiger.exposure_time = 0.001
eiger.period = t
t0 = time.time()
eiger.acq()
duration = time.time()-t0
assert duration < t*(nframes-1)+tol
for mp in eiger.measured_period:
assert pytest.approx(mp, 1e-5) == t
testdata_times = [0.001, 0.002, 0.003, 0.005, 0.01]
@pytest.mark.parametrize("t", testdata_times)
def test_measure_subperiod_nonparallel(eiger, t):
readout_time = 500e-6
eiger.dynamic_range = 32
eiger.file_write = False
eiger.flags = 'nonparallel'
eiger.n_frames = 1
eiger.period = 0
eiger.exposure_time = 0.5
eiger.sub_exposure_time = t
eiger.sub_deadtime = 0
eiger.acq()
for mp in eiger.measured_subperiod:
assert pytest.approx(mp, abs=1e-5) == t+readout_time
@pytest.mark.parametrize("t", testdata_times)
def test_measure_subperiod_parallel(eiger, t):
readout_time = 12e-6
eiger.dynamic_range = 32
eiger.file_write = False
eiger.flags = 'parallel'
eiger.n_frames = 1
eiger.period = 0
eiger.exposure_time = 0.5
eiger.sub_exposure_time = t
eiger.sub_deadtime = 0
eiger.acq()
for mp in eiger.measured_subperiod:
assert pytest.approx(mp, abs=1e-5) == t+readout_time
@pytest.mark.parametrize("t", testdata_times)
def test_measure_subperiod_parallel_when_changing_deadtime(eiger, t):
readout_time = 12e-6
exposure_time = 0.001
eiger.dynamic_range = 32
eiger.file_write = False
eiger.flags = 'parallel'
eiger.n_frames = 1
eiger.period = 0
eiger.exposure_time = 0.5
eiger.sub_exposure_time = exposure_time
eiger.sub_deadtime = t
eiger.acq()
for mp in eiger.measured_subperiod:
assert pytest.approx(mp, abs=1e-5) == t+exposure_time

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Tests for trimbit and dac related functions
"""
import pytest
import config_test
from fixtures import detector, eiger, jungfrau, eigertest, jungfrautest
from sls_detector.errors import DetectorValueError
@eigertest
def test_set_trimbits(eiger):
"""Limited values due to time"""
for i in [17, 32, 60]:
print(i)
eiger.trimbits = i
assert eiger.trimbits == i
@eigertest
def test_set_trimbits_raises_on_too_big(eiger):
with pytest.raises(DetectorValueError):
eiger.trimbits = 75
@eigertest
def test_set_trimbits_raises_on_negative(eiger):
with pytest.raises(DetectorValueError):
eiger.trimbits = -5
# @jungfrautest
# def test_jungfrau(jungfrau):
# """Example of a test that is not run with Eiger connected"""
# pass

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Tests for hostname related functions of the detector
"""
import pytest
import config_test
from fixtures import detector, eiger, jungfrau, eigertest, jungfrautest
from sls_detector.errors import DetectorValueError
def test_firmware_version(detector):
assert detector.firmware_version == config_test.fw_version

View File

@ -0,0 +1,42 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue May 22 14:13:48 2018
@author: l_frojdh
"""
import os
from sls_detector_tools.io import write_trimbit_file
from sls_detector_tools import mask
energy = [5000, 6000, 7000]
vrf = [500, 1000, 1500]
for i,e in enumerate(energy):
dacs = np.array( [[ 0., 0.], #vsvp
[4000., 4000.], #vtr
[vrf[i], vrf[i]], #vrf
[1400., 1400.], #vrs
[4000., 4000.], #vsvn
[2556., 2556.], #vtgstv
[1400., 1400.], #vcmp_ll
[1500., 1500.], #vcmp_lr
[4000., 4000.], #vcall
[1500., 1500.], #vcmp_rl
[1100., 1100.], #rxb_rb
[1100., 1100.], #rxb_lb
[1500., 1500.], #vcmp_rr
[1500., 1500.], #vcp
[2000., 2000.], #vcn
[1550., 1550.], #vis
[ 660., 660.], #iodelay
[ 0., 0.], #tau
])
tb = np.zeros((256,1024))
for beb in [83,98]:
write_trimbit_file(f'settingsdir/standard/{e}eV/noise.sn{beb:03d}', tb, dacs[:,0])
#print(os.getcwd())
#print( os.path.realpath(__file__))

View File

@ -0,0 +1,17 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 14 16:49:07 2017
@author: l_frojdh
"""
fw_version = 0x180220
detector_type = 'Jungfrau'
known_hostnames = ['bchip038']
image_size = (512,1024) #rows, cols
module_geometry = (1,1) #horizontal, vertical
#Remember to change these in the settings file as well!
settings_path = '/home/l_lopez/projects/slsDetectorPackage/settingsdir/jungfrau'
file_path = '/home/l_lopez/out'

View File

@ -0,0 +1,23 @@
import pytest
from sls_detector import Detector
@pytest.fixture
def detector():
from sls_detector import Detector
return Detector()
@pytest.fixture
def eiger():
from sls_detector import Eiger
return Eiger()
@pytest.fixture
def jungfrau():
from sls_detector import Jungfrau
return Jungfrau()
detector_type = Detector().detector_type
eigertest = pytest.mark.skipif(detector_type != 'Eiger', reason = 'Only valid for Eiger')
jungfrautest = pytest.mark.skipif(detector_type != 'Jungfrau', reason = 'Only valid for Jungfrau')

View File

@ -0,0 +1,17 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
General tests for the Jungfrau detector.
NOTE! Uses hostnames from config_test
"""
import pytest
import config_test
import tests
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
pytest.main(['-x', '-s', os.path.join(dir_path, 'tests/test_load_config.py')]) #Test 1
pytest.main(['-x', '-s', os.path.join(dir_path, 'tests/test_overtemperature.py')]) #Test 2

View File

@ -0,0 +1,21 @@
detsizechan 1024 512
settingsdir /home/l_lopez/projects/slsDetectorPackage/settingsdir/jungfrau
caldir /home/l_lopez/projects/slsDetectorPackage/settingsdir/jungfrau
lock 0
hostname bchip094+
rx_udpport 1754
rx_udpip 10.1.1.107
rx_udpmac 90:E2:BA:9A:4F:D4
detectorip 10.1.1.9
detectormac 00:aa:bb:cc:dd:ee
configuremac 0
powerchip 1
timing auto
outdir /home/l_lopez/out
threaded 1
high

View File

@ -0,0 +1 @@
vhighvoltage 200

View File

@ -0,0 +1,43 @@
import pytest
import config_test
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
from fixtures import jungfrau, jungfrautest
def load_config_file_jungfrau_test(jungfrau):
"""Load a settings file and assert all settings"""
print('\tStarting load_config_file_jungfrau_test test case')
jungfrau.free_shared_memory
jungfrau.load_config(os.path.join(dir_path, 'test.config'))
assert jungfrau.lock == False
assert jungfrau.rx_udpport == ['1754']
assert jungfrau.hostname == ['bchip094']
assert jungfrau.firmware_version == config_test.fw_version
print('\tFinished load_config_file_jungfrau_test test case')
def load_parameters_file_jungfrau_test(jungfrau):
"""Load a parametes file and assert the settings in the file"""
print('\tStarting load_parameters_file_jungfrau_test test case')
jungfrau.load_parameters(os.path.join(dir_path, 'test.par'))
assert jungfrau.high_voltage == 200
print('\tFinished load_parameters_file_jungfrau_test test case')
@jungfrautest
def test_main(jungfrau):
print('\nTesting configuration file loading')
load_config_file_jungfrau_test(jungfrau)
load_parameters_file_jungfrau_test(jungfrau)
print('Tested configuration file loading')

View File

@ -0,0 +1,68 @@
import pytest
import config_test
import time
from fixtures import jungfrau, jungfrautest
def powerchip_test(jungfrau, control):
"""
Test the main overtemperature protection control
"""
#Set test initial conditions
print('\tStarting powerchip_test test case')
jungfrau.power_chip = False
jungfrau.temperature_control = control
assert jungfrau.power_chip == False
jungfrau.temperature_threshold = 35
jungfrau.power_chip = True
if jungfrau.temperature_control is True:
if jungfrau.temperature_event is True:
assert jungfrau.power_chip == False
jungfrau.power_chip = True
assert jungfrau.power_chip == False
jungfrau.temperature_control = False
assert jungfrau.power_chip == True
jungfrau.temperature_control = True
jungfrau.temperature_threshold = 50
assert jungfrau.power_chip == False
print('\t\tWaiting to cool down the board. This may take a while...')
while jungfrau.temperature_threshold < jungfrau.temp.fpga[0]:
time.sleep(5)
print('\t\tJungfrau MCB temperature: {0:.2f} °C'.format(jungfrau.temp.fpga[0]))
#Leave enough time to let the board cool down a bit more
time.sleep(30)
jungfrau.reset_temperature_event()
assert jungfrau.temperature_event == False
assert jungfrau.power_chip == True
else:
assert jungfrau.power_chip == True
else:
print('\t\tWaiting to warm up the board. This may take a while...')
while jungfrau.temperature_threshold > jungfrau.temp.fpga[0]:
time.sleep(5)
print('\t\tJungfrau MCB temperature: {0:.2f} °C'.format(jungfrau.temp.fpga[0]))
assert jungfrau.temperature_event == False
assert jungfrau.power_chip == True
print('\tFinished powerchip_test test case')
#@jungfrautest
def test_main(jungfrau):
print('\nTesting overtemperature protection control')
powerchip_test(jungfrau, False)
powerchip_test(jungfrau, True)
print('Tested overtemperature protection control')

View File

@ -0,0 +1,6 @@
from .detector import Detector, DetectorError, free_shared_memory
from .eiger import Eiger
from .experimental import ExperimentalDetector
from .jungfrau import Jungfrau
from .jungfrau_ctb import JungfrauCTB
from _sls_detector import DetectorApi

View File

@ -0,0 +1,40 @@
from functools import partial
class Adc:
def __init__(self, name, detector):
self.name = name
self._detector = detector
self.get_nmod = self._detector._api.getNumberOfDetectors
# Bind functions to get and set the dac
self.get = partial(self._detector._api.getAdc, self.name)
def __getitem__(self, key):
"""
Get dacs either by slice, key or list
"""
if key == slice(None, None, None):
return [self.get(i) / 1000 for i in range(self.get_nmod())]
elif isinstance(key, Iterable):
return [self.get(k) / 1000 for k in key]
else:
return self.get(key) / 1000
def __repr__(self):
"""String representation for a single adc in all modules"""
degree_sign = u'\N{DEGREE SIGN}'
r_str = ['{:14s}: '.format(self.name)]
r_str += ['{:6.2f}{:s}C, '.format(self.get(i)/1000, degree_sign) for i in range(self.get_nmod())]
return ''.join(r_str).strip(', ')
class DetectorAdcs:
"""
Interface to the ADCs on the readout board
"""
def __iter__(self):
for attr, value in self.__dict__.items():
yield value
def __repr__(self):
return '\n'.join([str(t) for t in self])

125
python/sls_detector/dacs.py Normal file
View File

@ -0,0 +1,125 @@
from .detector_property import DetectorProperty
from functools import partial
import numpy as np
class Dac(DetectorProperty):
"""
This class represents a dac on the detector. One instance handles all
dacs with the same name for a multi detector instance.
.. note ::
This class is used to build up DetectorDacs and is in general
not directly accessed to the user.
"""
def __init__(self, name, low, high, default, detector):
super().__init__(partial(detector._api.getDac, name),
partial(detector._api.setDac, name),
detector._api.getNumberOfDetectors,
name)
self.min_value = low
self.max_value = high
self.default = default
def __repr__(self):
"""String representation for a single dac in all modules"""
r_str = ['{:10s}: '.format(self.__name__)]
r_str += ['{:5d}, '.format(self.get(i)) for i in range(self.get_nmod())]
return ''.join(r_str).strip(', ')
class DetectorDacs:
_dacs = [('vsvp', 0, 4000, 0),
('vtr', 0, 4000, 2500),
('vrf', 0, 4000, 3300),
('vrs', 0, 4000, 1400),
('vsvn', 0, 4000, 4000),
('vtgstv', 0, 4000, 2556),
('vcmp_ll', 0, 4000, 1500),
('vcmp_lr', 0, 4000, 1500),
('vcall', 0, 4000, 4000),
('vcmp_rl', 0, 4000, 1500),
('rxb_rb', 0, 4000, 1100),
('rxb_lb', 0, 4000, 1100),
('vcmp_rr', 0, 4000, 1500),
('vcp', 0, 4000, 200),
('vcn', 0, 4000, 2000),
('vis', 0, 4000, 1550),
('iodelay', 0, 4000, 660)]
_dacnames = [_d[0] for _d in _dacs]
def __init__(self, detector):
# We need to at least initially know which detector we are connected to
self._detector = detector
# Index to support iteration
self._current = 0
# Populate the dacs
for _d in self._dacs:
setattr(self, '_'+_d[0], Dac(*_d, detector))
def __getattr__(self, name):
return self.__getattribute__('_' + name)
def __setattr__(self, name, value):
if name in self._dacnames:
return self.__getattribute__('_' + name).__setitem__(slice(None, None, None), value)
else:
super().__setattr__(name, value)
def __next__(self):
if self._current >= len(self._dacs):
self._current = 0
raise StopIteration
else:
self._current += 1
return self.__getattr__(self._dacnames[self._current-1])
def __iter__(self):
return self
def __repr__(self):
r_str = ['========== DACS =========']
r_str += [repr(dac) for dac in self]
return '\n'.join(r_str)
def get_asarray(self):
"""
Read the dacs into a numpy array with dimensions [ndacs, nmodules]
"""
dac_array = np.zeros((len(self._dacs), self._detector.n_modules))
for i, _d in enumerate(self):
dac_array[i,:] = _d[:]
return dac_array
def set_from_array(self, dac_array):
"""
Set the dacs from an numpy array with dac values. [ndacs, nmodules]
"""
dac_array = dac_array.astype(np.int)
for i, _d in enumerate(self):
_d[:] = dac_array[i]
def set_default(self):
"""
Set all dacs to their default values
"""
for _d in self:
_d[:] = _d.default
def update_nmod(self):
"""
Update the cached value of nmod, needs to be run after adding or
removing detectors
"""
for _d in self:
_d._n_modules = self._detector.n_modules

View File

@ -0,0 +1,55 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Function decorators for the sls_detector.
"""
from .errors import DetectorError
import functools
def error_handling(func):
"""
Check for errors registered by the slsDetectorSoftware
"""
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
# remove any previous errors
self._api.clearErrorMask()
# call function
result = func(self, *args, **kwargs)
# check for new errors
m = self.error_mask
if m != 0:
msg = self.error_message
self._api.clearErrorMask()
raise DetectorError(msg)
return result
return wrapper
def property_error_handling(func):
"""
Check for errors registered by the slsDetectorSoftware
"""
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
# remove any previous errors
self._detector._api.clearErrorMask()
# call function
result = func(self, *args, **kwargs)
# check for new errors
m = self._detector.error_mask
if m != 0:
msg = self._detector.error_message
self._detector._api.clearErrorMask()
raise DetectorError(msg)
return result
return wrapper

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
from collections.abc import Iterable
import numpy as np
class DetectorProperty:
"""
Base class for a detector property that should be accessed by name and index
TODO! Calls are not in parallel and exposes object that can be passes around
"""
def __init__(self, get_func, set_func, nmod_func, name):
self.get = get_func
self.set = set_func
self.get_nmod = nmod_func
self.__name__ = name
def __getitem__(self, key):
if key == slice(None, None, None):
return [self.get(i) for i in range(self.get_nmod())]
elif isinstance(key, Iterable):
return [self.get(k) for k in key]
else:
return self.get(key)
def __setitem__(self, key, value):
#operate on all values
if key == slice(None, None, None):
if isinstance(value, (np.integer, int)):
for i in range(self.get_nmod()):
self.set(i, value)
elif isinstance(value, Iterable):
for i in range(self.get_nmod()):
self.set(i, value[i])
else:
raise ValueError('Value should be int or np.integer not', type(value))
#Iterate over some
elif isinstance(key, Iterable):
if isinstance(value, Iterable):
for k,v in zip(key, value):
self.set(k,v)
elif isinstance(value, int):
for k in key:
self.set(k, value)
#Set single value
elif isinstance(key, int):
self.set(key, value)
def __repr__(self):
s = ', '.join(str(v) for v in self[:])
return '{}: [{}]'.format(self.__name__, s)

View File

@ -0,0 +1,618 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 6 11:51:18 2017
@author: l_frojdh
"""
import socket
from collections.abc import Iterable
from collections import namedtuple
from functools import partial
from .adcs import Adc, DetectorAdcs
from .dacs import DetectorDacs
from .decorators import error_handling
from .detector import Detector
from .detector_property import DetectorProperty
from .utils import element_if_equal
from sls_detector.errors import DetectorValueError, DetectorError
class EigerVcmp:
"""
Convenience class to be able to loop over vcmp for Eiger
.. todo::
Support single assignment and perhaps unify with Dac class
"""
def __init__(self, detector):
_names = ['vcmp_ll',
'vcmp_lr',
'vcmp_rl',
'vcmp_rr']
self.set = []
self.get = []
for i in range(detector.n_modules):
if i % 2 == 0:
name = _names
else:
name = _names[::-1]
for n in name:
self.set.append(partial(detector._api.setDac, n, i))
self.get.append(partial(detector._api.getDac, n, i))
def __getitem__(self, key):
if key == slice(None, None, None):
return [_d() for _d in self.get]
return self.get[key]()
def __setitem__(self, i, value):
self.set[i](value)
def __repr__(self):
return 'vcmp: '+ str(self[:])
class EigerDacs(DetectorDacs):
_dacs = [('vsvp', 0, 4000, 0),
('vtr', 0, 4000, 2500),
('vrf', 0, 4000, 3300),
('vrs', 0, 4000, 1400),
('vsvn', 0, 4000, 4000),
('vtgstv', 0, 4000, 2556),
('vcmp_ll', 0, 4000, 1500),
('vcmp_lr', 0, 4000, 1500),
('vcall', 0, 4000, 4000),
('vcmp_rl', 0, 4000, 1500),
('rxb_rb', 0, 4000, 1100),
('rxb_lb', 0, 4000, 1100),
('vcmp_rr', 0, 4000, 1500),
('vcp', 0, 4000, 200),
('vcn', 0, 4000, 2000),
('vis', 0, 4000, 1550),
('iodelay', 0, 4000, 660)]
_dacnames = [_d[0] for _d in _dacs]
# noinspection PyProtectedMember
class DetectorDelays:
_delaynames = ['frame', 'left', 'right']
def __init__(self, detector):
# We need to at least initially know which detector we are connected to
self._detector = detector
setattr(self, '_frame', DetectorProperty(detector._api.getDelayFrame,
detector._api.setDelayFrame,
detector._api.getNumberOfDetectors,
'frame'))
setattr(self, '_left', DetectorProperty(detector._api.getDelayLeft,
detector._api.setDelayLeft,
detector._api.getNumberOfDetectors,
'left'))
setattr(self, '_right', DetectorProperty(detector._api.getDelayRight,
detector._api.setDelayRight,
detector._api.getNumberOfDetectors,
'right'))
# Index to support iteration
self._current = 0
def __getattr__(self, name):
return self.__getattribute__('_' + name)
def __setattr__(self, name, value):
if name in self._delaynames:
return self.__getattribute__('_' + name).__setitem__(slice(None, None, None), value)
else:
super().__setattr__(name, value)
def __next__(self):
if self._current >= len(self._delaynames):
self._current = 0
raise StopIteration
else:
self._current += 1
return self.__getattr__(self._delaynames[self._current-1])
def __iter__(self):
return self
def __repr__(self):
hn = self._detector.hostname
r_str = ['Transmission delay [ns]\n'
'{:11s}{:>8s}{:>8s}{:>8s}'.format('', 'left', 'right', 'frame')]
for i in range(self._detector.n_modules):
r_str.append('{:2d}:{:8s}{:>8d}{:>8d}{:>8d}'.format(i, hn[i], self.left[i], self.right[i], self.frame[i]))
return '\n'.join(r_str)
class Eiger(Detector):
"""
Subclassing Detector to set up correct dacs and detector specific
functions.
"""
_detector_dynamic_range = [4, 8, 16, 32]
_settings = ['standard', 'highgain', 'lowgain', 'veryhighgain', 'verylowgain']
"""available settings for Eiger, note almost always standard"""
def __init__(self, id=0):
super().__init__(id)
self._active = DetectorProperty(self._api.getActive,
self._api.setActive,
self._api.getNumberOfDetectors,
'active')
self._vcmp = EigerVcmp(self)
self._dacs = EigerDacs(self)
self._trimbit_limits = namedtuple('trimbit_limits', ['min', 'max'])(0, 63)
self._delay = DetectorDelays(self)
# Eiger specific adcs
self._temp = DetectorAdcs()
self._temp.fpga = Adc('temp_fpga', self)
self._temp.fpgaext = Adc('temp_fpgaext', self)
self._temp.t10ge = Adc('temp_10ge', self)
self._temp.dcdc = Adc('temp_dcdc', self)
self._temp.sodl = Adc('temp_sodl', self)
self._temp.sodr = Adc('temp_sodr', self)
self._temp.fpgafl = Adc('temp_fpgafl', self)
self._temp.fpgafr = Adc('temp_fpgafr', self)
@property
@error_handling
def active(self):
"""
Is the detector active? Can be used to enable or disable a detector
module
Examples
----------
::
d.active
>> active: [True, True]
d.active[1] = False
>> active: [True, False]
"""
return self._active
@active.setter
@error_handling
def active(self, value):
self._active[:] = value
@property
def measured_period(self):
return self._api.getMeasuredPeriod()
@property
def measured_subperiod(self):
return self._api.getMeasuredSubPeriod()
@property
@error_handling
def add_gappixels(self):
"""Enable or disable the (virual) pixels between ASICs
Examples
----------
::
d.add_gappixels = True
d.add_gappixels
>> True
"""
return self._api.getGapPixels()
@add_gappixels.setter
@error_handling
def add_gappixels(self, value):
self._api.setGapPixels(value)
@property
def dacs(self):
"""
An instance of DetectorDacs used for accessing the dacs of a single
or multi detector.
Examples
---------
::
d = Eiger()
#Set all vrf to 1500
d.dacs.vrf = 1500
#Check vrf
d.dacs.vrf
>> vrf : 1500, 1500
#Set a single vtr
d.dacs.vtr[0] = 1800
#Set vrf with multiple values
d.dacs.vrf = [3500,3700]
d.dacs.vrf
>> vrf : 3500, 3700
#read into a variable
var = d.dacs.vrf[:]
#set multiple with multiple values, mostly used for large systems
d.dacs.vcall[0,1] = [3500,3600]
d.dacs.vcall
>> vcall : 3500, 3600
d.dacs
>>
========== DACS =========
vsvp : 0, 0
vtr : 4000, 4000
vrf : 1900, 1900
vrs : 1400, 1400
vsvn : 4000, 4000
vtgstv : 2556, 2556
vcmp_ll : 1500, 1500
vcmp_lr : 1500, 1500
vcall : 4000, 4000
vcmp_rl : 1500, 1500
rxb_rb : 1100, 1100
rxb_lb : 1100, 1100
vcmp_rr : 1500, 1500
vcp : 1500, 1500
vcn : 2000, 2000
vis : 1550, 1550
iodelay : 660, 660
"""
return self._dacs
@property
@error_handling
def tx_delay(self):
"""
Transmission delay of the modules to allow running the detector
in a network not supporting the full speed of the detector.
::
d.tx_delay
>>
Transmission delay [ns]
left right frame
0:beb048 0 15000 0
1:beb049 100 190000 100
d.tx_delay.left = [2000,5000]
"""
return self._delay
def default_settings(self):
"""
reset the detector to some type of standard settings
mostly used when testing
"""
self.n_frames = 1
self.exposure_time = 1
self.period = 0
self.n_cycles = 1
self.n_measurements = 1
self.dynamic_range = 16
@property
@error_handling
def eiger_matrix_reset(self):
"""
Matrix reset bit for Eiger.
:py:obj:`True` : Normal operation, the matrix is reset before each acq.
:py:obj:`False` : Matrix reset disabled. Used to not reset before
reading out analog test pulses.
"""
return self._api.getCounterBit()
@eiger_matrix_reset.setter
@error_handling
def eiger_matrix_reset(self, value):
self._api.setCounterBit(value)
@property
@error_handling
def flowcontrol_10g(self):
"""
:py:obj:`True` - Flow control enabled :py:obj:`False` flow control disabled.
Sets for all moduels, if for some reason access to a single module is needed
this can be done trough the C++ API.
"""
fc = self._api.getNetworkParameter('flow_control_10g')
return element_if_equal([bool(int(e)) for e in fc])
@flowcontrol_10g.setter
@error_handling
def flowcontrol_10g(self, value):
if value is True:
v = '1'
else:
v = '0'
self._api.setNetworkParameter('flow_control_10g', v, -1)
@error_handling
def pulse_all_pixels(self, n):
"""
Pulse each pixel of the chip **n** times using the analog test pulses.
The pulse height is set using d.dacs.vcall with 4000 being 0 and 0 being
the highest pulse.
::
#Pulse all pixels ten times
d.pulse_all_pixels(10)
#Avoid resetting before acq
d.eiger_matrix_reset = False
d.acq() #take frame
#Restore normal behaviour
d.eiger_matrix_reset = True
"""
self._api.pulseAllPixels(n)
@error_handling
def pulse_diagonal(self, n):
"""
Pulse pixels in super colums in a diagonal fashion. Used for calibration
of vcall. Saves time compared to pulsing all pixels.
"""
self._api.pulseDiagonal(n)
@error_handling
def pulse_chip(self, n):
"""
Advance the counter by toggling enable. Gives 2*n+2 int the counter
"""
n = int(n)
if n >= -1:
self._api.pulseChip(n)
else:
raise ValueError('n must be equal or larger than -1')
@property
def vcmp(self):
"""
Convenience function to get and set the individual vcmp of chips
Used mainly in the calibration code.
Examples
---------
::
#Reading
d.vcmp[:]
>> [500, 500, 500, 500, 500, 500, 500, 500]
#Setting
d.vcmp = [500, 500, 500, 500, 500, 500, 500, 500]
"""
return self._vcmp
@vcmp.setter
@error_handling
def vcmp(self, values):
if len(values) == len(self._vcmp.set):
for i, v in enumerate(values):
self._vcmp.set[i](v)
else:
raise ValueError('vcmp only compatible with setting all')
@property
@error_handling
def rx_udpport(self):
"""
UDP port for the receiver. Each module has two ports referred to
as rx_udpport and rx_udpport2 in the command line interface
here they are grouped for each detector
::
[0:rx_udpport, 0:rx_udpport2, 1:rx_udpport ...]
Examples
-----------
::
d.rx_udpport
>> [50010, 50011, 50004, 50005]
d.rx_udpport = [50010, 50011, 50012, 50013]
"""
p0 = self._api.getReceiverUDPPort()
p1 = self._api.getReceiverUDPPort2()
return [int(val) for pair in zip(p0, p1) for val in pair]
@rx_udpport.setter
@error_handling
def rx_udpport(self, ports):
"""Requires iterating over elements two and two for setting ports"""
a = iter(ports)
for i, p in enumerate(zip(a, a)):
self._api.setReceiverUDPPort(p[0], i)
self._api.setReceiverUDPPort2(p[1], i)
@property
@error_handling
def rx_zmqport(self):
"""
Return the receiver zmq ports. Note that Eiger has two ports per receiver!
::
detector.rx_zmqport
>> [30001, 30002, 30003, 30004]
"""
_s = self._api.getReceiverStreamingPort()
if _s == '':
return []
else:
return [int(_p) + i for _p in _s for i in range(2)]
@rx_zmqport.setter
@error_handling
def rx_zmqport(self, port):
if isinstance(port, Iterable):
for i, p in enumerate(port):
self._api.setReceiverStreamingPort(p, i)
else:
self._api.setReceiverStreamingPort(port, -1)
@property
@error_handling
def sub_exposure_time(self):
"""
Sub frame exposure time in *seconds* for Eiger in 32bit autosumming mode
::
d.sub_exposure_time
>> 0.0023
d.sub_exposure_time = 0.002
"""
return self._api.getSubExposureTime() / 1e9
@sub_exposure_time.setter
@error_handling
def sub_exposure_time(self, t):
#TODO! checking here or in the detector?
ns_time = int(t * 1e9)
if ns_time > 0:
self._api.setSubExposureTime(ns_time)
else:
raise DetectorValueError('Sub exposure time must be larger than 0')
@property
@error_handling
def sub_deadtime(self):
"""
Deadtime between subexposures. Used to mimize noise by delaying the start of the next
subexposure.
"""
return self._api.getSubExposureDeadTime() / 1e9
@sub_deadtime.setter
@error_handling
def sub_deadtime(self, t):
ns_time = int(t * 1e9)
if ns_time >= 0:
self._api.setSubExposureDeadTime(ns_time)
else:
raise ValueError('Sub deadtime time must be larger or equal to 0')
@property
def temp(self):
"""
An instance of DetectorAdcs used to read the temperature
of different components
Examples
-----------
::
detector.temp
>>
temp_fpga : 36.90°C, 45.60°C
temp_fpgaext : 31.50°C, 32.50°C
temp_10ge : 0.00°C, 0.00°C
temp_dcdc : 36.00°C, 36.00°C
temp_sodl : 33.00°C, 34.50°C
temp_sodr : 33.50°C, 34.00°C
temp_fpgafl : 33.81°C, 30.93°C
temp_fpgafr : 27.88°C, 29.15°C
a = detector.temp.fpga[:]
a
>> [36.568, 45.542]
"""
return self._temp
@property
@error_handling
def tengiga(self):
"""Enable 10Gbit/s data output
Examples
----------
::
d.tengiga
>> False
d.tengiga = True
"""
return self._api.getTenGigabitEthernet()
@tengiga.setter
@error_handling
def tengiga(self, value):
self._api.setTenGigabitEthernet(value)
def set_delays(self, delta):
self.tx_delay.left = [delta*(i*2) for i in range(self.n_modules)]
self.tx_delay.right = [delta*(i*2+1) for i in range(self.n_modules)]
def setup500k(self, hostnames):
"""
Setup the Eiger detector to run on the local machine
"""
self.hostname = hostnames
self.file_write = False
self.image_size = (512, 1024)
self.rx_tcpport = [1954, 1955]
self.rx_udpport = [50010, 50011, 50004, 50005]
self.rx_hostname = socket.gethostname().split('.')[0]
self.rx_datastream = False
self.file_write = False
self.online = True
self.receiver_online = True

View File

@ -0,0 +1,25 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 14 17:13:55 2017
@author: l_frojdh
"""
class DetectorError(Exception):
"""
This error should be used when something fails
on the detector side
"""
pass
class DetectorSettingDoesNotExist(Exception):
"""This error should be used when the setting does not exist"""
pass
class DetectorValueError(Exception):
"""This error should be used when the set value is outside the allowed range"""
pass

View File

@ -0,0 +1,16 @@
from _sls_detector import multiDetectorApi
class ExperimentalDetector(multiDetectorApi):
def __init__(self):
super().__init__(0)
@property
def rx_udpip(self):
return self._getReceiverUDPIP(-1)
@rx_udpip.setter
def rx_udpip(self, ip):
self._setReceiverUDPIP(ip, -1)

View File

@ -0,0 +1,275 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Jungfrau detector class and support functions.
Inherits from Detector.
"""
from .adcs import Adc, DetectorAdcs
from .decorators import error_handling
from .detector import Detector
from .dacs import DetectorDacs
from .utils import element_if_equal
class JungfrauDacs(DetectorDacs):
_dacs = [('vb_comp', 0, 4000, 1220),
('vdd_prot', 0, 4000, 3000),
('vin_com', 0, 4000, 1053),
('vref_prech', 0, 4000, 1450),
('vb_pixbuff', 0, 4000, 750),
('vb_ds', 0, 4000, 1000),
('vref_ds', 0, 4000, 480),
('vref_comp', 0, 4000, 420),
]
_dacnames = [_d[0] for _d in _dacs]
class Jungfrau(Detector):
"""
Class used to control a Jungfrau detector. Inherits from the Detector class but a specialized
class is needed to provide the correct dacs and unique functions.
"""
_detector_dynamic_range = [4, 8, 16, 32]
_settings = ['dynamichg0',
'dynamicgain',
'fixgain1',
'fixgain2',
'forceswitchg1',
'forceswitchg2']
"""Available settings for Jungfrau"""
def __init__(self, multi_id=0):
#Init on base calss
super().__init__(multi_id)
self._dacs = JungfrauDacs(self)
#Jungfrau specific temps, this can be reduced to a single value?
self._temp = DetectorAdcs()
self._temp.fpga = Adc('temp_fpga', self)
# self._register = Register(self)
@property
def dacs(self):
"""
An instance of DetectorDacs used for accessing the dacs of a single
or multi detector.
Examples
---------
::
#Jungfrau
"""
return self._dacs
@property
@error_handling
def power_chip(self):
"""Power on or off the ASICs, True for on False for off"""
return self._api.isChipPowered()
@power_chip.setter
@error_handling
def power_chip(self, value):
self._api.powerChip(value)
@property
@error_handling
def delay(self):
"""Delay after trigger [s]"""
return self._api.getDelay()/1e9
@delay.setter
@error_handling
def delay(self, t):
ns_time = int(t * 1e9)
self._api.setDelay(ns_time)
@property
@error_handling
def n_gates(self):
return self._api.getNumberOfGates()
@n_gates.setter
@error_handling
def n_gates(self, n):
self._api.setNumberOfGates(n)
@property
@error_handling
def n_probes(self):
return self._api.getNumberOfProbes()
@n_probes.setter
@error_handling
def n_probes(self, n):
self._api.setNumberOfProbes(n)
@property
@error_handling
def storagecell_start(self):
"""
First storage cell
"""
return self._api.getStoragecellStart()
@storagecell_start.setter
@error_handling
def storagecell_start(self, value):
self._api.setStoragecellStart(value)
@property
@error_handling
def n_storagecells(self):
"""
number of storage cells used for the measurements
"""
return self._api.getNumberOfStorageCells()
@n_storagecells.setter
@error_handling
def n_storagecells(self, value):
self._api.setNumberOfStorageCells(value)
@property
def temp(self):
"""
An instance of DetectorAdcs used to read the temperature
of different components
Examples
-----------
::
detector.temp
>>
temp_fpga : 36.90°C, 45.60°C
a = detector.temp.fpga[:]
a
>> [36.568, 45.542]
"""
return self._temp
@property
def temperature_threshold(self):
"""Threshold for switching of chips"""
return self._api.getThresholdTemperature()
@temperature_threshold.setter
def temperature_threshold(self, t):
self._api.setThresholdTemperature(t)
@property
def temperature_control(self):
"""
Monitor the temperature of the detector and switch off chips if temperature_threshold is
crossed
Examples
---------
::
#activate
detector.temperature_control = True
#deactivate
detector.temperature_control = False
"""
return self._api.getTemperatureControl()
@temperature_control.setter
def temperature_control(self, v):
self._api.setTemperatureControl(v)
@property
def temperature_event(self):
"""Have the temperature threshold been crossed?
Returns
---------
:py:obj:`True` if the threshold have been crossed and temperature_control is active
otherwise :py:obj:`False`
"""
return self._api.getTemperatureEvent()
def reset_temperature_event(self):
"""Reset the temperature_event. After reset temperature_event is False"""
self._api.resetTemperatureEvent()
@property
@error_handling
def rx_udpport(self):
"""
UDP port for the receiver. Each module have one port.
Note! Eiger has two ports
::
[0:rx_udpport]
Examples
-----------
::
d.rx_udpport
>> [50010]
d.rx_udpport = [50010]
"""
return self._api.getNetworkParameter('rx_udpport')
@rx_udpport.setter
@error_handling
def rx_udpport(self, ports):
"""Requires iterating over elements two and two for setting ports"""
for i, p in enumerate(ports):
self._api.setNetworkParameter('rx_udpport', str(p), i)
@property
def detector_mac(self):
s = self._api.getNetworkParameter('detectormac')
return element_if_equal(s)
@detector_mac.setter
def detector_mac(self, mac):
if isinstance(mac, list):
for i, m in enumerate(mac):
self._api.setNetworkParameter('detectormac', m, i)
else:
self._api.setNetworkParameter('detectormac', mac, -1)
@property
@error_handling
def detector_ip(self):
s = self._api.getNetworkParameter('detectorip')
return element_if_equal(s)
@detector_ip.setter
def detector_ip(self, ip):
if isinstance(ip, list):
for i, addr in enumerate(ip):
self._api.setNetworkParameter('detectorip', addr, i)
else:
self._api.setNetworkParameter('detectorip', ip, -1)

View File

@ -0,0 +1,181 @@
from functools import partial
from collections.abc import Iterable
from collections import namedtuple
import socket
from .detector import Detector
from .utils import element_if_equal
from .adcs import DetectorAdcs, Adc
from .dacs import DetectorDacs
from .detector_property import DetectorProperty
from .decorators import error_handling
from .registers import Register, Adc_register
class JungfrauCTBDacs(DetectorDacs):
_dacs = [('dac0', 0, 4000, 1400),
('dac1', 0, 4000, 1200),
('dac2', 0, 4000, 900),
('dac3', 0, 4000, 1050),
('dac4', 0, 4000, 1400),
('dac5', 0, 4000, 655),
('dac6', 0, 4000, 2000),
('dac7', 0, 4000, 1400),
('dac8', 0, 4000, 850),
('dac9', 0, 4000, 2000),
('dac10', 0, 4000, 2294),
('dac11', 0, 4000, 983),
('dac12', 0, 4000, 1475),
('dac13', 0, 4000, 1200),
('dac14', 0, 4000, 1600),
('dac15', 0, 4000, 1455),
('dac16', 0, 4000, 0),
('dac17', 0, 4000, 1000),
]
_dacnames = [_d[0] for _d in _dacs]
class JungfrauCTB(Detector):
def __init__(self, id = 0):
super().__init__(id)
self._dacs = JungfrauCTBDacs(self)
self._register = Register(self)
self._adc_register = Adc_register(self)
@property
def v_a(self):
return self._api.getDac_mV('v_a', -1)
@v_a.setter
def v_a(self, value):
self._api.setDac_mV('v_a', -1, value)
@property
def v_b(self):
return self._api.getDac_mV('v_b', -1)
@v_b.setter
def v_b(self, value):
self._api.setDac_mV('v_b', -1, value)
@property
def v_c(self):
return self._api.getDac_mV('v_c', -1)
@v_c.setter
def v_c(self, value):
self._api.setDac_mV('v_c', -1, value)
@property
def v_d(self):
return self._api.getDac_mV('v_d', -1)
@v_d.setter
def v_d(self, value):
self._api.setDac_mV('v_d', -1, value)
@property
def v_io(self):
return self._api.getDac_mV('v_io', -1)
@v_io.setter
def v_io(self, value):
self._api.setDac_mV('v_io', -1, value)
@property
def v_limit(self):
return self._api.getDac_mV('v_limit', -1)
@v_limit.setter
def v_limit(self, value):
self._api.setDac_mV('v_limit', -1, value)
@property
def adc_register(self):
return self._adc_register
# @property
# def register(self):
# return self._register
def adcOFF(self):
"""Switch off the ADC"""
self.adc_register[0x8] = 1
@property
def dacs(self):
"""
An instance of DetectorDacs used for accessing the dacs of a single
or multi detector.
Examples
---------
::
#JungfrauCTB
"""
return self._dacs
@property
def dbitpipeline(self):
return self._api.getDbitPipeline()
@dbitpipeline.setter
def dbitpipeline(self, value):
self._api.setDbitPipeline(value)
@property
def dbitphase(self):
return self._api.getDbitPhase()
@dbitphase.setter
def dbitphase(self, value):
self._api.setDbitPhase(value)
@property
def dbitclock(self):
return self._api.getDbitClock()
@dbitclock.setter
def dbitclock(self, value):
self._api.setDbitClock(value)
@property
def samples(self):
return self._api.getJCTBSamples()
@samples.setter
def samples(self, value):
self._api.setJCTBSamples(value)
@property
@error_handling
def readout_clock(self):
"""
Speed of the readout clock relative to the full speed
Examples
---------
::
"""
return self._api.getReadoutClockSpeed()
@readout_clock.setter
@error_handling
def readout_clock(self, value):
self._api.setReadoutClockSpeed(value)

View File

@ -0,0 +1,18 @@
from .decorators import error_handling, property_error_handling
class Register:
def __init__(self, detector):
self._detector = detector
@property_error_handling
def __getitem__(self, key):
return self._detector._api.readRegister(key)
def __setitem__(self, key, value):
self._detector._api.writeRegister(key, value)
class Adc_register:
def __init__(self, detector):
self._detector = detector
def __setitem__(self, key, value):
self._detector._api.writeAdcRegister(key, value)

View File

@ -0,0 +1,32 @@
"""
Utility functions that are useful for testing and troubleshooting
but not directly used in controlling the detector
"""
def all_equal(mylist):
"""If all elements are equal return true otherwise false"""
return all(x == mylist[0] for x in mylist)
def element_if_equal(mylist):
"""If all elements are equal return only one element"""
if all_equal(mylist):
if len(mylist) == 0:
return None
else:
return mylist[0]
else:
return mylist
def eiger_register_to_time(register):
"""
Decode register value and return time in s. Values are stored in
a 32bit register with bits 2->0 containing the exponent and bits
31->3 containing the significand (int value)
"""
clocks = register >> 3
exponent = register & 0b111
return clocks*10**exponent / 100e6

20
python/sphinx/Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python -msphinx
SPHINXPROJ = sls_detector_tools
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@ -0,0 +1,134 @@
Code quality
=============================
For usability and reliability of the software the code needs to be high quality. For this
project it means meeting the four criteria described below. Any addition should pass all of
them.
--------------------------------
Look, read and feel like Python
--------------------------------
When using classes and functions from the
package it should feel like you are using Python tools and be forces
to write C++ style code with Python syntax.
::
with xray_box.shutter_open():
for th in threshold:
d.vthreshold = th
d.acq()
should be preferred over
::
N = len(threshold)
xray_box.open_shutter()
for i in range(N):
d.dacs.set_dac('vthreshold', threshold[i])
d.acq()
xray_box.close_shutter()
even if the difference might seem small.
--------------------
Have documentation
--------------------
Classes and functions should be documented with doc-strings
in the source code. Preferably with examples. The syntax to be used
is numpy-sphinx.
::
def function(arg):
"""
This is a function that does something
Parameters
----------
arg: int
An argument
Returns
--------
value: double
Returns a value
"""
return np.sin(arg+np.pi)
---------------------------------
Pass static analysis with pylint
---------------------------------
Yes, anything less than 9/10 just means that you are lazy. If
there is a good reason why to diverge, then we can always
add an exception.
Currently the following additions are made:
* good-names: x, y, ax, im etc.
* function arguments 10
* Whitelist: numpy, _sls
-----------------------
Tested code
-----------------------
Last but not least... *actually last just because of the long list included.*
All code that goes in should have adequate tests. If a new function does not
have a minimum of one test it does not get added.
**Unit-tests with pytest and mocker**
::
----------- coverage: platform linux, python 3.6.4-final-0 -----------
Name Stmts Miss Cover
------------------------------------------------
sls_detector/__init__.py 4 0 100%
sls_detector/decorators.py 14 3 79%
sls_detector/detector.py 461 115 75%
sls_detector/eiger.py 150 64 57%
sls_detector/errors.py 7 0 100%
sls_detector/jungfrau.py 59 26 56%
------------------------------------------------
TOTAL 695 208 70%
========= 78 passed in 0.60 seconds =========
**Simple integration tests**
These tests require a detector connected. Performs simple tasks like setting
exposure time and reading back to double check the value
::
----------- coverage: platform linux, python 3.6.4-final-0 -----------
Name Stmts Miss Cover
------------------------------------------------
sls_detector/__init__.py 4 0 100%
sls_detector/decorators.py 14 0 100%
sls_detector/detector.py 461 103 78%
sls_detector/eiger.py 150 20 87%
sls_detector/errors.py 7 0 100%
sls_detector/jungfrau.py 59 26 56%
------------------------------------------------
TOTAL 695 149 79%
========= 67 passed, 1 skipped in 16.66 seconds =========
**Complex integration test**
Typical measurements. Might require X-rays. Tests are usually evaluated from
plots

View File

@ -0,0 +1,370 @@
Command line to Python
=========================
If you are already familiar with the command line interface to the
slsDetectorSoftware here is a quick reference translating to Python commands
.. note ::
Commands labeled Mythen only or Gotthard only are currently not implemented in the
Python class. If you need this functionallity please contact the SLS Detector Group
.. py:currentmodule:: sls_detector
.. |ro| replace:: *(read only)*
.. |free| replace:: :py:func:`Detector.free_shared_memory`
.. |sub| replace:: :py:attr:`Detector.sub_exposure_time`
.. |mg| replace:: Mythen and Gotthard only
.. |g| replace:: Gotthard only
.. |m| replace:: Mythen only
.. |msp| replace:: :py:attr:`Detector.measured_subperiod`
.. |new_chiptest| replace:: New chip test board only
.. |chiptest| replace:: Chip test board only
.. |dr| replace:: :py:attr:`Detector.dynamic_range`
.. |j| replace:: Jungfrau only
.. |te| replace:: :py:attr:`Detector.trimmed_energies`
.. |temp_fpgaext| replace:: :py:attr:`Detector.temp`.fpgaext
.. |epa| replace:: :py:func:`Eiger.pulse_all_pixels`
.. |rfc| replace:: :py:func:`Detector.reset_frames_caught`
.. |rfi| replace:: :py:attr:`Detector.receiver_frame_index`
.. |ron| replace:: :py:attr:`Detector.receiver_online`
.. |flipy| replace:: :py:attr:`Detector.flipped_data_y`
.. |flipx| replace:: :py:attr:`Detector.flipped_data_x`
.. |adcr| replace:: :py:func:`DetectorApi.writeAdcRegister`
.. |sb| replace:: :py:func:`DetectorApi.setBitInRegister`
.. |cb| replace:: :py:func:`DetectorApi.clearBitInRegister`
.. |tempth| replace:: :py:attr:`Jungfrau.temperature_threshold`
.. |tempev| replace:: :py:attr:`Jungfrau.temperature_event`
.. |tempco| replace:: :py:attr:`Jungfrau.temperature_control`
.. |depr| replace:: *Deprecated/Internal*
.. |nimp| replace:: *Not implemented*
.. |rudp| replace:: :py:attr:`Detector.rx_realudpsocksize`
.. |lci| replace:: :py:attr:`Detector.last_client_ip`
.. |rlci| replace:: :py:attr:`Detector.receiver_last_client_ip`
.. |fdp| replace:: :py:attr:`Detector.frame_discard_policy`
.. |apic| replace:: :py:attr:`Detector.api_compatibility`
------------------------
Commands
------------------------
===================== ===================================== ================== =========
Command Python Implementation Tests
===================== ===================================== ================== =========
sls_detector_acquire :py:func:`Detector.acq` OK OK
test |depr| \- \-
help help(Detector.acq) \- \-
exitserver |depr| \- \-
exitreceiver |depr| \- \-
flippeddatay |flipy| OK \-
digitest |depr| \- \-
bustest |depr| \- \-
digibittest Which detector? \- \-
reg :py:attr:`Detector.register` OK \-
adcreg |adcr| OK \-
setbit |sb| OK \-
clearbit |cb| OK \-
getbit |nimp| \- \-
r_compression Not implemented in receiver \- \-
acquire :py:func:`Detector.acq` OK \-
busy :py:attr:`Detector.busy` OK Partial
status :py:attr:`Detector.status` OK |ro| \-
status start :py:func:`Detector.start_detector` OK \-
status stop :py:func:`Detector.stop_detector` OK \-
data |depr| \- \-
frame |depr| \- \-
readctr |g| \- \-
resetctr |g| \- \-
resmat :py:attr:`Eiger.eiger_matrix_reset` OK OK
free |free| OK \-
hostname :py:attr:`Detector.hostname` OK OK
add |nimp| \- \-
replace |nimp| \- \-
user |nimp| \- \-
master |nimp| \- \-
sync Which detector? \- \-
online :py:attr:`Detector.online` OK \-
checkonline |nimp| \- \-
activate :py:attr:`Eiger.active` \- \-
nmod :py:attr:`Detector.n_modules` OK \-
maxmod |depr| \- \-
dr |dr| OK OK
roi |g| \- \-
detsizechan :py:attr:`Detector.image_size` OK \-
roimask |nimp| \- \-
flippeddatax |flipx| OK \-
tengiga :py:attr:`Eiger.tengiga` OK \-
gappixels :py:attr:`Eiger.add_gappixels` OK \-
flags :py:attr:`Detector.flags` OK \-
extsig |mg| \- \-
programfpga |j| \- \-
resetfpga |j| \- \-
powerchip :py:attr:`Jungfrau.powerchip` \- \-
led |nimp| \- \-
auto_comp_disable |j| \- \-
pulse Used in |epa| OK \-
pulsenmove Used in |epa| OK \-
pulsechip :py:func:`Eiger.pulse_chip` OK \-
checkdetversion |apic| \- \-
checkrecversion |apic| \- \-
moduleversion |m| \- \-
detectornumber :py:attr:`Detector.detector_number` OK \-
modulenumber |m| \- \-
detectorversion :py:attr:`Detector.firmware_version` OK OK
softwareversion :py:attr:`Detector.server_version` \- \-
thisversion :py:attr:`Detector.client_version` Reads date \-
receiverversion :py:attr:`Detector.receiver_version` Reads date \-
timing :py:attr:`Detector.timing_mode` OK \-
exptime :py:attr:`Detector.exposure_time` OK OK
subexptime |sub| OK OK
period :py:attr:`Detector.period` OK OK
subdeadtime :py:attr:`Eiger.sub_deadtime` OK OK
delay :py:attr:`Jungfrau.delay` OK \-
gates :py:attr:`Jungfrau.n_gates` OK \-
frames :py:attr:`Detector.n_frames` OK OK
cycles :py:attr:`Detector.n_cycles` OK \-
probes :py:attr:`Jungfrau.n_probes` OK \-
measurements :py:attr:`Detector.n_measurements` OK \-
samples Chip test board only (new?) \- \-
storagecells :py:attr:`Jungfrau.n_storagecells` OK \-
storagecell_start :py:attr:`Jungfrau.storagecell_start` OK \-
exptimel |mg| \- \-
periodl |mg| \- \-
delayl |mg| \- \-
gatesl |mg| \- \-
framesl |mg| \- \-
cyclesl |mg| \- \-
probesl |mg| \- \-
now |nimp| \- \-
timestamp |m| \- \-
nframes |nimp| \- \-
measuredperiod :py:attr:`Detector.measured_period` OK \-
measuredsubperiod |msp| \- \-
clkdivider :py:attr:`Detector.readout_clock` OK OK
setlength |m| \- \-
waitstates |m| \- \-
totdivider |m| \- \-
totdutycycle |m| \- \-
phasestep |g| \- \-
oversampling |new_chiptest| \- \-
adcclk |new_chiptest| \- \-
adcphase |new_chiptest| \- \-
adcpipeline |new_chiptest| \- \-
dbitclk |new_chiptest| \- \-
dbitphase |new_chiptest| \- \-
dbitpipeline |new_chiptest| \- \-
config :py:func:`Detector.load_config` OK \-
rx_printconfig |nimp| \- \-
parameters :py:func:`Detector.load_parameters` OK \-
setup |nimp| \- \-
flatfield |nimp| \- \-
ffdir |nimp| \- \-
ratecorr :py:attr:`Detector.rate_correction` OK \-
badchannels |nimp| \- \-
angconv |m| \- \-
globaloff |nimp| \- \-
fineoff |nimp| \- \-
binsize |nimp| \- \-
angdir |nimp| \- \-
moveflag |nimp| \- \-
samplex |nimp| \- \-
sampley |nimp| \- \-
threaded :py:attr:`Detector.threaded` OK \-
darkimage |nimp| \- \-
gainimage |nimp| \- \-
settingsdir :py:attr:`Detector.settings_path` OK \-
trimdir |nimp| \- \-
caldir |nimp| \- \-
trimen :py:attr:`Detector.trimmed_energies` OK \-
settings :py:attr:`Detector.settings` OK \-
threshold :py:attr:`Detector.threshold` OK \-
thresholdnotb |nimp| \- \-
trimbits :py:func:`Detector.load_trimbits` OK \-
trim |nimp| \- \-
trimval :py:attr:`Detector.trimbits` OK OK
pedestal |nimp| \- \-
vthreshold :py:attr:`Detector.vthreshold` OK \-
vcalibration |nimp| \- \-
vtrimbit |nimp| \- \-
vpreamp |nimp| \- \-
vshaper1 |nimp| \- \-
vshaper2 |nimp| \- \-
vhighvoltage :py:attr:`Detector.high_voltage` OK \-
vapower |nimp| \- \-
vddpower |nimp| \- \-
vshpower |nimp| \- \-
viopower |nimp| \- \-
vref_ds :py:attr:`Jungfrau.dacs.vref_ds` OK \-
vcascn_pb |nimp| \- \-
vcascp_pb |nimp| \- \-
vout_cm |nimp| \- \-
vcasc_out |nimp| \- \-
vin_cm |nimp| \- \-
vref_comp |nimp| \- \-
ib_test_c |nimp| \- \-
dac0 |nimp| \- \-
dac1 |nimp| \- \-
dac2 |nimp| \- \-
dac3 |nimp| \- \-
dac4 |nimp| \- \-
dac5 |nimp| \- \-
dac6 |nimp| \- \-
dac7 |nimp| \- \-
vsvp :py:attr:`Eiger.dacs.vsvp` OK \-
vsvn :py:attr:`Eiger.dacs.vsvn` OK \-
vtr :py:attr:`Eiger.dacs.vtr` OK \-
vrf :py:attr:`Eiger.dacs.vrf` OK \-
vrs :py:attr:`Eiger.dacs.vrs` OK \-
vtgstv :py:attr:`Eiger.dacs.vtgstv` OK \-
vcmp_ll :py:attr:`Eiger.dacs.vcmp_ll` OK \-
vcmp_ll :py:attr:`Eiger.dacs.vcmp_ll` OK \-
vcall :py:attr:`Eiger.dacs.vcall` OK \-
vcmp_rl :py:attr:`Eiger.dacs.vcmp_rl` OK \-
vcmp_rr :py:attr:`Eiger.dacs.vcmp_rr` OK \-
rxb_rb :py:attr:`Eiger.dacs.rxb_rb` OK \-
rxb_lb :py:attr:`Eiger.dacs.rxb_lb` OK \-
vcp :py:attr:`Eiger.dacs.vcp` OK \-
vcn :py:attr:`Eiger.dacs.vcn` OK \-
vis :py:attr:`Eiger.dacs.vis` OK \-
iodelay :py:attr:`Eiger.dacs.iodelay` OK \-
dac |nimp| \- \-
adcvpp |nimp| \- \-
v_a |nimp| \- \-
v_b |nimp| \- \-
v_c |nimp| \- \-
v_d |nimp| \- \-
v_io |nimp| \- \-
v_chip |nimp| \- \-
v_limit |nimp| \- \-
vIpre |nimp| \- \-
VcdSh |nimp| \- \-
Vth1 |nimp| \- \-
Vth2 |nimp| \- \-
Vth3 |nimp| \- \-
VPL |nimp| \- \-
Vtrim |nimp| \- \-
vIbias |nimp| \- \-
vIinSh |nimp| \- \-
cas |nimp| \- \-
casSh |nimp| \- \-
vIbiasSh |nimp| \- \-
vIcin |nimp| \- \-
vIpreOut |nimp| \- \-
temp_adc |nimp| \- \-
temp_fpga :py:attr:`Detector.temp`.fpga OK \-
temp_fpgaext |temp_fpgaext| OK \-
temp_10ge :py:attr:`Detector.temp`.t10ge OK \-
temp_dcdc :py:attr:`Detector.temp`.dcdc OK \-
temp_sodl :py:attr:`Detector.temp`.sodl OK \-
temp_sodr :py:attr:`Detector.temp`.sodr OK \-
adc |nimp| \- \-
temp_fpgafl :py:attr:`Detector.temp`.fpgafl OK \-
temp_fpgafr :py:attr:`Detector.temp`.fpgafr OK \-
i_a |nimp| \- \-
i_b |nimp| \- \-
i_c |nimp| \- \-
i_d |nimp| \- \-
i_io |nimp| \- \-
vm_a |nimp| \- \-
vm_b |nimp| \- \-
vm_c |nimp| \- \-
vm_d |nimp| \- \-
vm_io |nimp| \- \-
temp_threshold |tempth| \- \-
temp_control |tempco| \- \-
temp_event |tempev| \- \-
outdir :py:attr:`Detector.file_path` OK OK
fname :py:attr:`Detector.file_name` OK OK
index :py:attr:`Detector.file_index` OK OK
enablefwrite :py:attr:`Detector.file_write` OK OK
overwrite :py:attr:`Detector.file_overwrite` OK \-
currentfname |nimp| \- \-
fileformat :py:attr:`Detector.file_format` OK \-
positions |depr| \- \-
startscript |depr| \- \-
startscriptpar |depr| \- \-
stopscript |depr| \- \-
stopscriptpar |depr| \- \-
scriptbefore |depr| \- \-
scriptbeforepar |depr| \- \-
scriptafter |depr| \- \-
scriptafterpar |depr| \- \-
headerafter |depr| \- \-
headerbefore |depr| \- \-
headerbeforepar |depr| \- \-
headerafterpar |depr| \- \-
encallog |depr| \- \-
angcallog |depr| \- \-
scan0script |depr| \- \-
scan0par |depr| \- \-
scan0prec |depr| \- \-
scan0steps |depr| \- \-
scan0range |depr| \- \-
scan1script |depr| \- \-
scan1par |depr| \- \-
scan1prec |depr| \- \-
scan1steps |depr| \- \-
scan1range |depr| \- \-
rx_hostname :py:attr:`Detector.rx_hostname` OK \-
rx_udpip :py:attr:`Detector.rx_udpip` OK \-
rx_udpmac :py:attr:`Detector.rx_udpmac` OK \-
rx_udpport :py:attr:`Detector.rx_udpport` OK \-
rx_udpport2 :py:attr:`Detector.rx_udpport` OK \-
rx_udpsocksize :py:attr:`Detector.rx_udpsocksize` OK \-
rx_realudpsocksize |rudp| OK
detectormac :py:attr:`Detector.detector_mac` OK \-
detectorip :py:attr:`Detector.detector_ip` OK \-
txndelay_left :py:attr:`Eiger.delay`.left OK \-
txndelay_right :py:attr:`Eiger.delay`.right OK \-
txndelay_frame :py:attr:`Eiger.delay`.frame OK \-
flowcontrol_10g :py:attr:`Eiger.flowcontrol_10g` OK \-
zmqport :py:attr:`Detector.client_zmqport` Read \-
rx_zmqport :py:attr:`Detector.rx_zmqport` Read \-
rx_datastream :py:attr:`Detector.rx_datastream` OK \-
zmqip :py:attr:`Detector.client_zmqip` OK \-
rx_zmqip :py:attr:`Detector.rx_zmqip` Read \-
rx_jsonaddheader :py:attr:`Detector.rx_jsonaddheader` OK \-
configuremac :py:attr:`Detector.config_network` OK \-
rx_tcpport :py:attr:`Detector.rx_tcpport`
port |nimp| \- \-
stopport |nimp| \- \-
lock :py:attr:`Detector.lock` OK \-
lastclient :py:attr:`Detector.last_client_ip` OK \-
receiver start :py:func:`Detector.start_receiver` OK \-
receiver stop :py:func:`Detector.stop_receiver` \- \-
r_online |ron| OK \-
r_checkonline |nimp| \- \-
framescaught :py:attr:`Detector.frames_caught` OK \-
resetframescaught |rfc| OK \-
frameindex |rfi| OK \-
r_lock :py:attr:`Detector.lock_receiver` OK \-
r_lastclient |rlci| OK \-
r_readfreq |nimp| \- \-
rx_fifodepth :py:attr:`Detector.rx_fifodepth` OK \-
r_silent |nimp| \- \-
r_framesperfile :py:attr:`Detector.n_frames_per_file` OK \-
r_discardpolicy |fdp| OK \-
r_padding :py:attr:`Detector.file_padding` OK \-
adcinvert |chiptest| \- \-
adcdisable |chiptest| \- \-
pattern |chiptest| \- \-
patword |chiptest| \- \-
patioctrl |chiptest| \- \-
patclkctrl |chiptest| \- \-
patlimits |chiptest| \- \-
patloop0 |chiptest| \- \-
patnloop0 |chiptest| \- \-
patwait0 |chiptest| \- \-
patwaittime0 |chiptest| \- \-
patloop1 |chiptest| \- \-
patnloop1 |chiptest| \- \-
patwait1 |chiptest| \- \-
patwaittime1 |chiptest| \- \-
patloop2 |chiptest| \- \-
patnloop2 |chiptest| \- \-
patwait2 |chiptest| \- \-
patwaittime2 |chiptest| \- \-
dut_clk |chiptest| \- \-
===================== ===================================== ================== =========

178
python/sphinx/conf.py Normal file
View File

@ -0,0 +1,178 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# sls_detector_tools documentation build configuration file, created by
# sphinx-quickstart on Wed Nov 1 10:17:29 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.coverage',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx.ext.todo',
'sphinx.ext.autosummary']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'sls_detector'
copyright = '2019, Sls Detector Group'
author = 'Erik Frojdh'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '4.0.1'
# The full version, including alpha/beta/rc tags.
release = '4.0.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
'about.html',
'navigation.html',
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
'donate.html',
]
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'sls_detector_doc'
napoleon_use_ivar = True
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'sls_detector.tex', 'sls_detector Documentation',
'Erik Frojdh', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'sls_detector_tools', 'sls_detector_tools Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'py_sls', 'py_sls Documentation',
author, 'py_sls', 'One line description of project.',
'Miscellaneous'),
]

12
python/sphinx/cpp_api.rst Normal file
View File

@ -0,0 +1,12 @@
C++ API
=====================================================
.. py:currentmodule:: _sls_detector
.. autoclass:: DetectorApi
:members:
:undoc-members:

View File

@ -0,0 +1,67 @@
Error handling
=========================
Check input in Python
----------------------
As far as possible we try to check the input on the Python side
before calling the slsDeteectorsSoftware. Errors should not pass
silently but raise an exception
::
#Trimbit range for Eiger is 0-63
detector.trimbits = 98
(...)
ValueError: Trimbit setting 98 is outside of range:0-63
Errors in slsDetectorsSoftware
-------------------------------
The slsDetectorsSoftware uses a mask to record errors from the different
detectors. If an error is found we raise a RuntimeError at the end of the
call using the error message from slsDetectorsSoftware
.. todo ::
Implement this for all functions
::
detector.settings = 'bananas'
(...)
RuntimeError: Detector 0:
Could not set settings.
Detector 1:
Could not set settings.
Detector 2:
Could not set settings.
Using decorators
-------------------
Using decorators we can reset the error mask before the command and then
check it after the command
.. code-block:: python
#add decorator to check the error mask
@error_handling
def some_function():
a = 1+1
return a
Communication with the detector is usually the biggest overhead so
this does not impact performance.
::
%timeit d.exposure_time
>> 1.52 ms ± 5.42 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit d.decorated_exposure_time
>> 1.53 ms ± 3.18 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Some files were not shown because too many files have changed in this diff Show More