mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-14 13:57:13 +02:00
Compare commits
653 Commits
2020.06.08
...
5.0.0-rc1
Author | SHA1 | Date | |
---|---|---|---|
ae58e9f0f4 | |||
603ddb0d75 | |||
c0be5ab8cb | |||
30f4c80031 | |||
d25da43851 | |||
ec2d6c597f | |||
fe81963873 | |||
f950e32893 | |||
aa3af2f0ce | |||
e4615a11bb | |||
c01ce3d514 | |||
99642dad69 | |||
2c1fddee84 | |||
c862f1df81 | |||
671a2724ac | |||
9c5d8cfcd7 | |||
8483e05f4c | |||
d96352f2ae | |||
0f65633ea3 | |||
18d5c5e26d | |||
3f19f29c9e | |||
101f029eef | |||
97fea10ee2 | |||
d3fbfebeb7 | |||
50fd9276ce | |||
1f31dd667b | |||
18cd363f8f | |||
0b0f5c94d5 | |||
23720e3c63 | |||
3432343adb | |||
d06e0d1e7f | |||
750adffe6a | |||
0b02fabaf8 | |||
4aa33b5d7f | |||
40a1d27e3a | |||
b23410bc5e | |||
b6d5efd441 | |||
79a03c6c92 | |||
330df3463a | |||
11754fbb5e | |||
e786b9f037 | |||
bd4299fd15 | |||
a4bdffd0b9 | |||
bb575c6017 | |||
65da9e701b | |||
804ad0997c | |||
2fc0768ad1 | |||
ca0192e27e | |||
4ad486fda0 | |||
cf8581caaa | |||
a8cc47d25c | |||
d50c40e2ad | |||
f6a442fd10 | |||
f5b8681811 | |||
54ca9f7ebb | |||
9920987b4d | |||
569c014d3c | |||
608b71d5ea | |||
c83daab56d | |||
d65030f5ca | |||
c3366a6748 | |||
7c21aa96a9 | |||
d028a120bb | |||
f6dd02acc2 | |||
0906efaf31 | |||
8ef79ce173 | |||
539c0c295b | |||
e91420bd16 | |||
515a0c05b9 | |||
46b75c1429 | |||
092b3fa8b9 | |||
a7e24717a9 | |||
e01e41926c | |||
44a8ce864b | |||
e18f10051e | |||
d9bb028da2 | |||
6d01348bf4 | |||
e8cd75a6ac | |||
d945f39142 | |||
ac1e9569b5 | |||
ea1b41c84a | |||
b0dd82c667 | |||
bf69951456 | |||
2d2e80469c | |||
5d648443fa | |||
1fb7352378 | |||
511c206787 | |||
74edb6a1c1 | |||
3376f7fa37 | |||
bfe36085f2 | |||
f061d2273a | |||
b12ae5d929 | |||
2285061623 | |||
e10ebe33d7 | |||
01921bc016 | |||
aa10c4665f | |||
f644cba244 | |||
884da7197e | |||
8ae0659478 | |||
ad95f729dc | |||
3b071cc43f | |||
2805359cd0 | |||
1515b79c97 | |||
2ab4bb1c04 | |||
5214c0f1a4 | |||
60bc3a8fa7 | |||
00f780665f | |||
ab738790e0 | |||
d4cff5b99c | |||
84f49a9b27 | |||
a4926e6ae1 | |||
cf8785ad2e | |||
be8284f5c2 | |||
3fd32b2c9c | |||
d70090967d | |||
88fe306902 | |||
d931416def | |||
6cfaa92b61 | |||
c94dfde17c | |||
b879a377ba | |||
d420451751 | |||
2bc33ad34a | |||
cb23e827bf | |||
a0f915316e | |||
2733bc5320 | |||
3b82e9fcc1 | |||
a95d8f664a | |||
11e7d89da3 | |||
34043c358f | |||
da9c7c354e | |||
4d499e231d | |||
0a7809286b | |||
00abb5e14b | |||
22c2bb0258 | |||
9d1cd09fd4 | |||
80b053eb10 | |||
3cd4f3897b | |||
d011186b9a | |||
669c14d6d5 | |||
ecabc94ade | |||
c58a2d957d | |||
1b214778a5 | |||
d5f6cbc075 | |||
52303daffd | |||
02d4769f6a | |||
a9d1a78662 | |||
3cf2160a2d | |||
4917812bb0 | |||
a0f9c6fe8c | |||
82e978e901 | |||
04bf2aca6d | |||
8bdfe7527f | |||
b33fdf4462 | |||
70386633f6 | |||
6c8443f09e | |||
bf52ec10da | |||
bdac4d133e | |||
e8156d412e | |||
97687f0f6d | |||
bfbfe204f4 | |||
67d57eb5cd | |||
f940c09290 | |||
30293b1d36 | |||
8e09b50c5e | |||
87bad38f80 | |||
67f1f9924a | |||
e1e04ee755 | |||
6e06d4307d | |||
20a959bf61 | |||
8e49a114db | |||
aecde086a0 | |||
311cebcd00 | |||
8496f5715f | |||
f26d8e514b | |||
0b9ff70244 | |||
e82e531fb1 | |||
503f83e8e3 | |||
1a90c58d9e | |||
c467bd677e | |||
f280d033b9 | |||
c9cf845c9a | |||
63bbbfb438 | |||
5540f16116 | |||
a77833b4c7 | |||
9ee67f2cfa | |||
cf3758f155 | |||
b20720686e | |||
1edb1e8816 | |||
30e06c6386 | |||
ea601fe1f7 | |||
f0c576c779 | |||
fb8842e048 | |||
5b182469a1 | |||
a1b88d3a62 | |||
514346c3ba | |||
9218ef5a95 | |||
b124cea67b | |||
497eff6f04 | |||
92635c5bd3 | |||
a00231dab6 | |||
35c7e46d60 | |||
47da2540af | |||
891b8dbd2c | |||
89f0479318 | |||
7048a75808 | |||
a081fbbdaa | |||
22f14cacb0 | |||
6b7dee2631 | |||
6d1856daa2 | |||
7bb9696151 | |||
44335f9cf4 | |||
d62d5ef804 | |||
dbaab61ea2 | |||
180c7b7191 | |||
050f0ff8a0 | |||
658a804cca | |||
73530ddd6f | |||
abe34d573c | |||
05d5652532 | |||
38e0351068 | |||
e192cad1f2 | |||
b8350b070e | |||
3ddeea3c2b | |||
42b5ff3a62 | |||
00978a52c8 | |||
8400c686b5 | |||
adb6171e35 | |||
973b8f7106 | |||
2f81c233f5 | |||
e4274e3f95 | |||
b92f9af025 | |||
7ca1609c58 | |||
4cd81437ab | |||
7e202b6c26 | |||
e0df9fcd99 | |||
30307220e3 | |||
6a74851e0c | |||
ac30717083 | |||
bfed02b41e | |||
b5669dc921 | |||
97ee2d269d | |||
bc5cc3fa29 | |||
abd2808924 | |||
786b14e88b | |||
f19799343e | |||
2e4783f296 | |||
3954913661 | |||
7eafceb0f9 | |||
a1e06ca7a9 | |||
27c1916d63 | |||
64075c0e75 | |||
9505c51404 | |||
6d8168722a | |||
f9261c0f32 | |||
d44388a44e | |||
6a18a214ba | |||
83baf18490 | |||
ddf2085b4b | |||
508ec150f5 | |||
5eda75ebdd | |||
0253933271 | |||
0f80079d16 | |||
fd601128b7 | |||
bc09b8bfb9 | |||
e85326d415 | |||
396685e6a9 | |||
cf6a48d7a9 | |||
4f45110cda | |||
3aa75ce167 | |||
5b364b9ad8 | |||
550ab51f34 | |||
e782fcce62 | |||
a2ec86006d | |||
6399d1bdfb | |||
6cd8bbcb12 | |||
678967bfe1 | |||
ffd694eda1 | |||
ab2f929e83 | |||
4540eddd68 | |||
534c7105f4 | |||
c8a39d1d9e | |||
bd6d212f99 | |||
c4f0052ac9 | |||
5bfbc83a04 | |||
429eb8da53 | |||
f6cde374c4 | |||
1f811dfabd | |||
8ef6f32be6 | |||
a7cc2b38d8 | |||
9b26f5a6c8 | |||
c4fde7f7bc | |||
5f23a664fa | |||
209c97f44c | |||
d631fda2c7 | |||
caff89a040 | |||
42067b3de3 | |||
a287ce46b1 | |||
7212a0d433 | |||
9bae97ec4c | |||
096b0c424d | |||
39c2ab4743 | |||
57e0fd805e | |||
071a1c9f98 | |||
0cb418a89b | |||
4e9c99d65d | |||
dd918fb326 | |||
7ea86dec43 | |||
eeb386fef5 | |||
afabc9a503 | |||
1d8f9a5aed | |||
d4e11e56ea | |||
de69e666a9 | |||
28ffad223d | |||
f0d0e9ab1f | |||
854d8d4ae2 | |||
16af67924e | |||
d822600c68 | |||
816e5200b2 | |||
9c58b4802c | |||
0c7759d7e4 | |||
690947ec3a | |||
45182283d1 | |||
03ac0910cd | |||
b6c94b2ab4 | |||
336dfcae60 | |||
d47f0feb17 | |||
784628589e | |||
21995b3d4a | |||
27b2a607c8 | |||
8e2bd17704 | |||
0e011a77b5 | |||
d56b2134ef | |||
8af1183220 | |||
78fdf5b60a | |||
132043a70d | |||
b51290d0fe | |||
0369413201 | |||
04d6644753 | |||
949c6a81ce | |||
aa0c36713c | |||
4aee113dda | |||
6c3f0d18ec | |||
7b6f4d0b5b | |||
6db5954d21 | |||
69d9680034 | |||
bbf8ab4b88 | |||
79f010a438 | |||
ab05da4d0e | |||
6e67ff9f90 | |||
321ed13659 | |||
de39310a9c | |||
e1de2f72ba | |||
f6172f9b9e | |||
5616d4aeeb | |||
857aa47ee7 | |||
bb3951c201 | |||
380b062216 | |||
a70d4e1e5d | |||
3301a80d99 | |||
ce25b3018c | |||
d25f9093d5 | |||
d24edd52e1 | |||
7b1ede32b1 | |||
4174d193b4 | |||
0514f00552 | |||
8631f5e2b0 | |||
540a203139 | |||
57c3cb0849 | |||
e82bcafb76 | |||
3cdf98b230 | |||
acc43842eb | |||
63a5b4d61f | |||
3083260b28 | |||
6e4b7f5bd7 | |||
ddd562f8b5 | |||
e2f1fd076a | |||
6a084e99b4 | |||
885b22eca8 | |||
bea4ba131a | |||
09fa8a3ba5 | |||
874092a9d0 | |||
5c4d355d57 | |||
4702a76235 | |||
fd503e84af | |||
1211d02428 | |||
ec27d35d6d | |||
ea2e7839d0 | |||
d5b893e452 | |||
68c0f76bd9 | |||
4eaa9588ba | |||
459a715b9c | |||
40d0430f2e | |||
0cb38a9c51 | |||
caef8c111c | |||
02d5cf14e4 | |||
bd221fefe5 | |||
c683f62452 | |||
1177e54602 | |||
85c958facf | |||
87c33c8e81 | |||
7492f7dbfa | |||
c2b586a333 | |||
d31839e80e | |||
b47f751d66 | |||
aa52028690 | |||
6f5635a402 | |||
5b9c7c4105 | |||
98ffe350f3 | |||
7dfeb987db | |||
7899c5faef | |||
17fb497774 | |||
e9c03c6eaf | |||
f497177022 | |||
984b43545e | |||
327218cb2b | |||
cdfd3934ee | |||
4cebefbc55 | |||
24c4cd8d84 | |||
f358492e09 | |||
86d3fc7e55 | |||
89da671ae2 | |||
24e44d56fe | |||
b13d04dd89 | |||
d19530b3d4 | |||
5ba3a414d6 | |||
54ad92a2bf | |||
74a7ca9b71 | |||
6846939f92 | |||
99ec7f0046 | |||
df3ae7f409 | |||
410f38c804 | |||
91652df5b1 | |||
02bda7c533 | |||
9204a56ff7 | |||
3ec637601d | |||
dc33f1a5da | |||
879b2c8864 | |||
b1a4723028 | |||
bad7fd3906 | |||
21c8b77e2c | |||
097acf8086 | |||
799f540d71 | |||
a412b465c6 | |||
bb2f70beb5 | |||
096e94562a | |||
9063a8d4ed | |||
b1d3cbb25e | |||
1fefc001f9 | |||
e8556abbe7 | |||
f8da057735 | |||
df0b52604f | |||
f792d59682 | |||
98d061a032 | |||
2bb9629f14 | |||
cf2e1c1dfc | |||
cb54bf6225 | |||
3b0f68c3c4 | |||
5faf3c7336 | |||
3ddb264875 | |||
1fb19aeae2 | |||
ad297e9c51 | |||
beb6afe101 | |||
78a6896ae9 | |||
9ea8882c05 | |||
4cf5e81971 | |||
2fa5e7d00c | |||
af17fb9f61 | |||
07869134d6 | |||
8b9a69e1f1 | |||
023924c4cc | |||
01d00164e5 | |||
e6c8ba0e88 | |||
37fc69b297 | |||
e1e265bd49 | |||
b46809e1c0 | |||
396d82bd62 | |||
e7ff96fe8d | |||
07a292af95 | |||
e4433a99a5 | |||
28fb1023fa | |||
c4374e623e | |||
da2f12072f | |||
918da2402f | |||
94e9591974 | |||
a76ed6d8db | |||
b7cb341ee3 | |||
546bef5e5a | |||
97ddfed819 | |||
2d68b61f00 | |||
3bdf02a23c | |||
f70d28b175 | |||
d076fda59a | |||
a3062a5e00 | |||
c6921bf954 | |||
ae9499047b | |||
8dd9bb6ea3 | |||
9a284f75c3 | |||
3e87cfa5c1 | |||
6136eabee2 | |||
67bb0dff1a | |||
ca298580f3 | |||
d7f490701b | |||
7752b86d97 | |||
35dbc3813d | |||
a096434864 | |||
ab4d89aa70 | |||
c67b7aab4d | |||
293fda0c7a | |||
bef35eb3d6 | |||
eea013d492 | |||
890a641304 | |||
1e0160d655 | |||
42b7f6fa7c | |||
4a1943216b | |||
a23504c9c4 | |||
4db3473e32 | |||
8c1c696f64 | |||
39bbc5c688 | |||
28b3fb4101 | |||
05059c1176 | |||
95089b5faa | |||
7c48ef8931 | |||
0dc062e6d3 | |||
9b1b878f95 | |||
e23a8e7da2 | |||
a228ae0773 | |||
9787c6a385 | |||
4d1fad04c3 | |||
c5a9ff3024 | |||
25ec47dfff | |||
93c5505285 | |||
a656668d73 | |||
3156e6f50e | |||
f224b7dadf | |||
ccf54f29b6 | |||
ef564e382c | |||
e571f7bb3e | |||
aacc61b058 | |||
7d128585e1 | |||
279986d77c | |||
ff729fb43f | |||
488e0230ba | |||
c04793a9d7 | |||
f1cbf49449 | |||
285ef30439 | |||
75e9d63341 | |||
21a79752e2 | |||
5780cabe8d | |||
cec26f81e1 | |||
0c045f0faa | |||
19e40cf0e6 | |||
902366fede | |||
ee67c28711 | |||
cfe9a431f9 | |||
524c86de49 | |||
05ef55b258 | |||
bcd217b6fe | |||
4ca46e4123 | |||
7333909f6b | |||
ba7f54744b | |||
cd677e4d97 | |||
4240ea57d4 | |||
692ade6c17 | |||
4cbe354396 | |||
39d5a7db26 | |||
ae88af2a72 | |||
f592d21570 | |||
35f95e603e | |||
5c42792580 | |||
301073e60b | |||
159b0a0367 | |||
f6911c4238 | |||
1d53dc65cd | |||
9d3bbc0a68 | |||
801f2c4559 | |||
da2ce03e1d | |||
f366e9ae6f | |||
5bf6b7a338 | |||
991acc7c07 | |||
b40e481da9 | |||
12b40a44a2 | |||
f14c2d06a5 | |||
0cc547c2de | |||
489fccb25c | |||
7c23f1e42c | |||
f66345d128 | |||
e7da4ae862 | |||
8adddfb083 | |||
7cc05ead89 | |||
ebc164aaa6 | |||
a57f7943ee | |||
db8616fcb3 | |||
55af974c4e | |||
1f3fd010a7 | |||
cf9ec3de0d | |||
b5781e1f9b | |||
e09fc8cd2b | |||
48b8116849 | |||
f5759921d2 | |||
b5b50a2061 | |||
a7d2a89c50 | |||
e80bc905d6 | |||
c6b664b25b | |||
f078e6147d | |||
7609a2bda4 | |||
d5ae9a22f4 | |||
ffb1a59df0 | |||
889e926479 | |||
19bd39eece | |||
f28b41b130 | |||
9a80975929 | |||
efc247f46f | |||
c0e8e44b41 | |||
82a6383466 | |||
0289f22a0d | |||
6a919ece02 | |||
d0baa4c7b9 | |||
6dccf48759 | |||
b128837538 | |||
3c46204b14 | |||
807a588c4b | |||
fb5b2133f5 | |||
6f2413fd5d | |||
5412569e77 | |||
0375e80b42 | |||
569d0464e7 | |||
cc8549e6cb | |||
bcb5b8047b | |||
8c9341836b | |||
ad36ee2ba2 | |||
afa71895e7 | |||
62449b81ad | |||
6794d58db1 | |||
3775ff302e | |||
e76da84c9f | |||
24af0ee578 | |||
e0b86799ae | |||
5a7451e29e | |||
e0c056be09 | |||
cf0681a23c | |||
24168d5e32 | |||
7c2949f372 | |||
5a7eeb3d76 | |||
64a94b962a | |||
ab72d342c9 | |||
200186ddde | |||
7388bb4aa7 | |||
9c26cd5552 | |||
5f91198328 | |||
265e96d675 | |||
f5160b0978 | |||
2a2bb5f63a | |||
e306c39e1d |
42
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
42
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: New Bug Report
|
||||||
|
labels: action - Bug, priority - Unclassified, status - Pending
|
||||||
|
template: bug_report.md
|
||||||
|
---
|
||||||
|
<!-- Preview changes before submitting -->
|
||||||
|
<!-- Please fill out everything with an *, as this report will be discarded otherwise -->
|
||||||
|
<!-- This is a comment, the syntax is a bit different from c++ or bash -->
|
||||||
|
|
||||||
|
##### *Distribution:
|
||||||
|
<!-- RHEL7, RHEL6, Fedora, etc -->
|
||||||
|
|
||||||
|
|
||||||
|
##### *Detector type:
|
||||||
|
<!-- If applicable, Eiger, Jungfrau, Mythen3, Gotthard2, Gotthard, Moench, ChipTestBoard -->
|
||||||
|
|
||||||
|
##### *Software Package Version:
|
||||||
|
<!-- developer, 4.2.0, 4.1.1, etc -->
|
||||||
|
|
||||||
|
##### Priority:
|
||||||
|
<!-- Super Low, Low, Medium, High, Super High -->
|
||||||
|
|
||||||
|
##### *Describe the bug
|
||||||
|
<!-- A clear and concise description of what the bug is -->
|
||||||
|
|
||||||
|
##### Expected behavior
|
||||||
|
<!-- A clear and concise description of what you expected to happen. -->
|
||||||
|
|
||||||
|
##### To Reproduce
|
||||||
|
<!-- Steps to reproduce the behavior: -->
|
||||||
|
<!-- 1. Go to '...' -->
|
||||||
|
<!-- 2. Click on '....' -->
|
||||||
|
<!-- 3. Scroll down to '....' -->
|
||||||
|
<!-- 4. See error -->
|
||||||
|
|
||||||
|
##### Screenshots
|
||||||
|
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||||
|
|
||||||
|
##### Additional context
|
||||||
|
<!-- Add any other context about the problem here. -->
|
28
.github/ISSUE_TEMPLATE/change_request.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/change_request.md
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: Change Request
|
||||||
|
about: Suggest a change to an existing feature
|
||||||
|
title: New Change Request
|
||||||
|
labels: action - Change, priority - Unclassified, status - Pending
|
||||||
|
template: change_request.md
|
||||||
|
---
|
||||||
|
<!-- Preview changes before submitting -->
|
||||||
|
<!-- Please fill out everything with an *, as this report will be discarded otherwise -->
|
||||||
|
<!-- This is a comment, the syntax is a bit different from c++ or bash -->
|
||||||
|
|
||||||
|
##### *Detector type:
|
||||||
|
<!-- If applicable, Eiger, Jungfrau, Mythen3, Gotthard2, Gotthard, Moench, ChipTestBoard -->
|
||||||
|
|
||||||
|
##### *Software Package Version:
|
||||||
|
<!-- developer, 4.2.0, 4.1.1, etc -->
|
||||||
|
|
||||||
|
##### Priority:
|
||||||
|
<!-- Super Low, Low, Medium, High, Super High -->
|
||||||
|
|
||||||
|
##### *State the change request:
|
||||||
|
<!-- A clear and concise description of what the change is to an existing feature -->
|
||||||
|
|
||||||
|
##### Is your change request related to a problem. Please describe:
|
||||||
|
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
||||||
|
|
||||||
|
##### Additional context:
|
||||||
|
<!-- Add any other context about the feature here -->
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
34
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
34
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
name: Feature Request
|
||||||
|
about: Suggest a feature, documentation or submit a question
|
||||||
|
title: New Feature Request
|
||||||
|
labels: action - Enhancement, priority - Unclassified, status - Pending
|
||||||
|
template: feature_request.md
|
||||||
|
---
|
||||||
|
<!-- Preview changes before submitting -->
|
||||||
|
<!-- Please fill out everything with an *, as this report will be discarded otherwise -->
|
||||||
|
<!-- This is a comment, the syntax is a bit different from c++ or bash -->
|
||||||
|
|
||||||
|
##### *Detector type:
|
||||||
|
<!-- If applicable, Eiger, Jungfrau, Mythen3, Gotthard2, Gotthard, Moench, ChipTestBoard -->
|
||||||
|
|
||||||
|
##### *Software Package Version:
|
||||||
|
<!-- developer, 4.2.0, 4.1.1, etc -->
|
||||||
|
|
||||||
|
##### Priority:
|
||||||
|
<!-- Super Low, Low, Medium, High, Super High -->
|
||||||
|
|
||||||
|
##### *State the feature:
|
||||||
|
<!-- A clear and concise description of what the feature is -->
|
||||||
|
|
||||||
|
##### Is your feature request related to a problem. Please describe:
|
||||||
|
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
||||||
|
|
||||||
|
##### Describe the solution you'd like:
|
||||||
|
<!-- A clear and concise description of what you want to happen -->
|
||||||
|
|
||||||
|
##### Describe alternatives you've considered:
|
||||||
|
<!-- A clear and concise description of any alternative solutions or features you've considered -->
|
||||||
|
|
||||||
|
##### Additional context:
|
||||||
|
<!-- Add any other context about the feature here -->
|
@ -46,6 +46,7 @@ option(SLS_BUILD_DOCS "docs" OFF)
|
|||||||
option(SLS_BUILD_EXAMPLES "examples" OFF)
|
option(SLS_BUILD_EXAMPLES "examples" OFF)
|
||||||
option(SLS_TUNE_LOCAL "tune to local machine" OFF)
|
option(SLS_TUNE_LOCAL "tune to local machine" OFF)
|
||||||
option(SLS_DEVEL_HEADERS "install headers for devel" OFF)
|
option(SLS_DEVEL_HEADERS "install headers for devel" OFF)
|
||||||
|
option(SLS_USE_MOENCH "compile zmq and post processing for Moench" OFF)
|
||||||
|
|
||||||
# set(ClangFormat_BIN_NAME clang-format)
|
# set(ClangFormat_BIN_NAME clang-format)
|
||||||
set(ClangFormat_EXCLUDE_PATTERNS "build/"
|
set(ClangFormat_EXCLUDE_PATTERNS "build/"
|
||||||
@ -62,17 +63,18 @@ find_package(ClangFormat)
|
|||||||
check_ipo_supported(RESULT SLS_LTO_AVAILABLE)
|
check_ipo_supported(RESULT SLS_LTO_AVAILABLE)
|
||||||
|
|
||||||
|
|
||||||
# Use ld.gold if it is available and isn't disabled explicitly
|
# # Use ld.gold if it is available and isn't disabled explicitly
|
||||||
option(SLS_USE_LD_GOLD "Use GNU gold linker" ON)
|
# option(SLS_USE_LD_GOLD "Use GNU gold linker" ON)
|
||||||
if (SLS_USE_LD_GOLD)
|
# if (SLS_USE_LD_GOLD)
|
||||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
# execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
if ("${LD_VERSION}" MATCHES "GNU gold")
|
# if ("${LD_VERSION}" MATCHES "GNU gold")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold")
|
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||||
else ()
|
# set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||||
message(WARNING "GNU gold linker isn't available, using the default system linker.")
|
# else ()
|
||||||
endif ()
|
# message(WARNING "GNU gold linker isn't available, using the default system linker.")
|
||||||
endif ()
|
# endif ()
|
||||||
|
# endif ()
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
@ -96,6 +98,7 @@ target_compile_options(slsProjectWarnings INTERFACE
|
|||||||
-Wformat=2
|
-Wformat=2
|
||||||
-Wredundant-decls
|
-Wredundant-decls
|
||||||
# -Wconversion
|
# -Wconversion
|
||||||
|
-Wvla
|
||||||
-Wdouble-promotion
|
-Wdouble-promotion
|
||||||
-Werror=return-type
|
-Werror=return-type
|
||||||
|
|
||||||
@ -229,11 +232,16 @@ if(SLS_BUILD_DOCS)
|
|||||||
add_subdirectory(docs)
|
add_subdirectory(docs)
|
||||||
endif(SLS_BUILD_DOCS)
|
endif(SLS_BUILD_DOCS)
|
||||||
|
|
||||||
|
|
||||||
|
if(SLS_USE_MOENCH)
|
||||||
|
add_subdirectory(slsDetectorCalibration/moenchExecutables)
|
||||||
|
endif(SLS_USE_MOENCH)
|
||||||
|
|
||||||
if(SLS_MASTER_PROJECT)
|
if(SLS_MASTER_PROJECT)
|
||||||
# Set install dir CMake packages
|
# Set install dir CMake packages
|
||||||
set(CMAKE_INSTALL_DIR "share/cmake/${PROJECT_NAME}")
|
set(CMAKE_INSTALL_DIR "share/cmake/${PROJECT_NAME}")
|
||||||
# Set the list of exported targets
|
# Set the list of exported targets
|
||||||
set(PROJECT_LIBRARIES slsSupportLib slsDetectorShared slsReceiverShared)
|
set(PROJECT_LIBRARIES slsSupportShared slsDetectorShared slsReceiverShared)
|
||||||
# Generate and install package config file and version
|
# Generate and install package config file and version
|
||||||
include(cmake/package_config.cmake)
|
include(cmake/package_config.cmake)
|
||||||
endif()
|
endif()
|
||||||
|
116
RELEASE.txt
116
RELEASE.txt
@ -1,2 +1,114 @@
|
|||||||
Draft
|
SLS Detector Package 5.0.0-rc1 released on 25.09.2020 (Release Candidate 1)
|
||||||
- dr 4, 8, 16 in eiger -> speed 0, 32 stays same (speed 1)
|
===========================================================================
|
||||||
|
|
||||||
|
CONTENTS
|
||||||
|
--------
|
||||||
|
1. Firmware Requirements
|
||||||
|
2. Download, Documentation & Support
|
||||||
|
|
||||||
|
|
||||||
|
1. Firmware Requirements
|
||||||
|
========================
|
||||||
|
|
||||||
|
Eiger
|
||||||
|
=====
|
||||||
|
Minimum compatible version : 27
|
||||||
|
Latest compatible version : 27
|
||||||
|
|
||||||
|
Jungfrau
|
||||||
|
========
|
||||||
|
Minimum compatible version (PCB v1.0) : 24.07.2020 (v0.8)
|
||||||
|
Latest compatible version (PCB v1.0) : 24.07.2020 (v0.8)
|
||||||
|
Minimum compatible version (PCB v2.0) : 21.07.2020 (v2.1)
|
||||||
|
Latest compatible version (PCB v2.0) : 21.07.2020 (v2.1)
|
||||||
|
|
||||||
|
Gotthard
|
||||||
|
========
|
||||||
|
Minimum compatible version : 11.01.2013
|
||||||
|
Latest compatible version : 08.02.2018 (50um and 25um Master)
|
||||||
|
09.02.2018 (25 um Slave)
|
||||||
|
|
||||||
|
Mythen3
|
||||||
|
=======
|
||||||
|
Minimum compatible version : 25.09.2020
|
||||||
|
Latest compatible version : 25.09.2020
|
||||||
|
|
||||||
|
Gotthard2
|
||||||
|
=========
|
||||||
|
Minimum compatible version : 25.09.2020
|
||||||
|
Latest compatible version : 25.09.2020
|
||||||
|
|
||||||
|
Moench
|
||||||
|
======
|
||||||
|
Minimum compatible version : 02.03.2020
|
||||||
|
Latest compatible version : 02.03.2020
|
||||||
|
|
||||||
|
Ctb
|
||||||
|
===
|
||||||
|
Minimum compatible version : 27.11.2019
|
||||||
|
Latest compatible version : 27.11.2019
|
||||||
|
|
||||||
|
|
||||||
|
Detector Upgrade
|
||||||
|
================
|
||||||
|
Eiger Remotely via bit files
|
||||||
|
Jungfrau Remotely using sls_detector_put programfpga <pof>
|
||||||
|
Gotthard Cannot be upgraded remotely. Requires programming via USB blaster
|
||||||
|
Mythen3 Remotely using sls_detector_put programfpga <rbf>
|
||||||
|
Gotthard2 Remotely using sls_detector_put programfpga <rbf>
|
||||||
|
Moench Remotely using sls_detector_put programfpga <pof>
|
||||||
|
Ctb Remotely using sls_detector_put programfpga <pof>
|
||||||
|
|
||||||
|
Instructions available at
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/firmware.html
|
||||||
|
|
||||||
|
Please refer to the link below for more details on the firmware versions.
|
||||||
|
https://www.psi.ch/en/detectors/firmware
|
||||||
|
|
||||||
|
|
||||||
|
2. Download, Documentation & Support
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Download
|
||||||
|
--------
|
||||||
|
|
||||||
|
The Source Code (Default C++ API):
|
||||||
|
https://github.com/slsdetectorgroup/slsDetectorPackage
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Installation:
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/installation.html#
|
||||||
|
|
||||||
|
Consuming slsDetectorPackage:
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/consuming.html
|
||||||
|
|
||||||
|
Command Line Documentation:
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/commandline.html
|
||||||
|
|
||||||
|
C++ API Documentation:
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/detector.html
|
||||||
|
|
||||||
|
C++ API Example:
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/examples.html#
|
||||||
|
|
||||||
|
Python API Documentation:
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/pygettingstarted.html
|
||||||
|
|
||||||
|
Python API Example:
|
||||||
|
https://slsdetectorgroup.github.io/devdoc/pyexamples.html
|
||||||
|
|
||||||
|
TroubleShooting:
|
||||||
|
https://www.psi.ch/en/detectors/troubleshooting
|
||||||
|
|
||||||
|
Further Documentation:
|
||||||
|
https://www.psi.ch/en/detectors/users-support
|
||||||
|
|
||||||
|
|
||||||
|
Support
|
||||||
|
-------
|
||||||
|
|
||||||
|
dhanya.thattil@psi.ch
|
||||||
|
erik.frojdh@psi.ch
|
||||||
|
anna.bergamaschi@psi.ch
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#Look for an executable called sphinx-build
|
#Look for an executable called sphinx-build
|
||||||
find_program(SPHINX_EXECUTABLE
|
find_program(SPHINX_EXECUTABLE
|
||||||
NAMES sphinx-build
|
NAMES sphinx-build sphinx-build-3.6
|
||||||
DOC "Path to sphinx-build executable")
|
DOC "Path to sphinx-build executable")
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
|
56
cmk.sh
56
cmk.sh
@ -12,6 +12,8 @@ TESTS=0
|
|||||||
SIMULATOR=0
|
SIMULATOR=0
|
||||||
CTBGUI=0
|
CTBGUI=0
|
||||||
MANUALS=0
|
MANUALS=0
|
||||||
|
MANUALS_ONLY_RST=0
|
||||||
|
MOENCHZMQ=0
|
||||||
|
|
||||||
|
|
||||||
CLEAN=0
|
CLEAN=0
|
||||||
@ -20,7 +22,7 @@ CMAKE_PRE=""
|
|||||||
CMAKE_POST=""
|
CMAKE_POST=""
|
||||||
|
|
||||||
usage() { echo -e "
|
usage() { echo -e "
|
||||||
Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [s] [u] [i] [m] [-h] [-d <HDF5 directory>] [-j] <Number of threads>
|
Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [s] [u] [i] [m] [n] [-h] [z] [-d <HDF5 directory>] [-j] <Number of threads>
|
||||||
-[no option]: only make
|
-[no option]: only make
|
||||||
-c: Clean
|
-c: Clean
|
||||||
-b: Builds/Rebuilds CMake files normal mode
|
-b: Builds/Rebuilds CMake files normal mode
|
||||||
@ -36,6 +38,8 @@ Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [s] [u] [i] [m] [-h] [-d <HDF5 director
|
|||||||
-e: Debug mode
|
-e: Debug mode
|
||||||
-i: Builds tests
|
-i: Builds tests
|
||||||
-m: Manuals
|
-m: Manuals
|
||||||
|
-n: Manuals without compiling doxygen (only rst)
|
||||||
|
-z: Moench zmq processor
|
||||||
|
|
||||||
Rebuild when you switch to a new build and compile in parallel:
|
Rebuild when you switch to a new build and compile in parallel:
|
||||||
./cmk.sh -bj5
|
./cmk.sh -bj5
|
||||||
@ -71,7 +75,7 @@ For rebuilding only certain sections
|
|||||||
|
|
||||||
" ; exit 1; }
|
" ; exit 1; }
|
||||||
|
|
||||||
while getopts ":bpchd:j:trgeisum" opt ; do
|
while getopts ":bpchd:j:trgeisumnz" opt ; do
|
||||||
case $opt in
|
case $opt in
|
||||||
b)
|
b)
|
||||||
echo "Building of CMake files Required"
|
echo "Building of CMake files Required"
|
||||||
@ -130,6 +134,14 @@ while getopts ":bpchd:j:trgeisum" opt ; do
|
|||||||
echo "Compiling Manuals"
|
echo "Compiling Manuals"
|
||||||
MANUALS=1
|
MANUALS=1
|
||||||
;;
|
;;
|
||||||
|
n)
|
||||||
|
echo "Compiling Manuals (Only RST)"
|
||||||
|
MANUALS_ONLY_RST=1
|
||||||
|
;;
|
||||||
|
z)
|
||||||
|
echo "Compiling Moench Zmq Processor"
|
||||||
|
MOENCHZMQ=1
|
||||||
|
;;
|
||||||
u)
|
u)
|
||||||
echo "Compiling Options: Chip Test Gui"
|
echo "Compiling Options: Chip Test Gui"
|
||||||
CTBGUI=1
|
CTBGUI=1
|
||||||
@ -210,6 +222,12 @@ if [ $MANUALS -eq 1 ]; then
|
|||||||
echo "Manuals Option enabled"
|
echo "Manuals Option enabled"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#Moench zmq processor
|
||||||
|
if [ $MOENCHZMQ -eq 1 ]; then
|
||||||
|
CMAKE_POST+=" -DSLS_USE_MOENCH=ON "
|
||||||
|
echo "Moench Zmq Processor Option enabled"
|
||||||
|
fi
|
||||||
|
|
||||||
#Chip Test Gui
|
#Chip Test Gui
|
||||||
if [ $CTBGUI -eq 1 ]; then
|
if [ $CTBGUI -eq 1 ]; then
|
||||||
CMAKE_POST+=" -DSLS_USE_CTBGUI=ON "
|
CMAKE_POST+=" -DSLS_USE_CTBGUI=ON "
|
||||||
@ -256,16 +274,36 @@ fi
|
|||||||
|
|
||||||
#make
|
#make
|
||||||
if [ $COMPILERTHREADS -gt 0 ]; then
|
if [ $COMPILERTHREADS -gt 0 ]; then
|
||||||
BUILDCOMMAND="make -j$COMPILERTHREADS"
|
if [ $MANUALS -eq 0 ] && [ $MANUALS_ONLY_RST -eq 0 ]; then
|
||||||
echo $BUILDCOMMAND
|
BUILDCOMMAND="make -j$COMPILERTHREADS"
|
||||||
eval $BUILDCOMMAND
|
echo $BUILDCOMMAND
|
||||||
|
eval $BUILDCOMMAND
|
||||||
|
else
|
||||||
|
if [ $MANUALS -eq 1 ]; then
|
||||||
|
BUILDCOMMAND="make docs -j$COMPILERTHREADS"
|
||||||
|
echo $BUILDCOMMAND
|
||||||
|
eval $BUILDCOMMAND
|
||||||
|
else
|
||||||
|
BUILDCOMMAND="make rst -j$COMPILERTHREADS"
|
||||||
|
echo $BUILDCOMMAND
|
||||||
|
eval $BUILDCOMMAND
|
||||||
|
fi
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
make
|
if [ $MANUALS -eq 0 ] && [ $MANUALS_ONLY_RST -eq 0 ]; then
|
||||||
|
echo "make"
|
||||||
|
make
|
||||||
|
else
|
||||||
|
if [ $MANUALS -eq 1 ]; then
|
||||||
|
echo "make docs"
|
||||||
|
make docs
|
||||||
|
else
|
||||||
|
echo "make rst"
|
||||||
|
make rst
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $MANUALS -eq 1 ]; then
|
|
||||||
make docs
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ requirements:
|
|||||||
- {{ cdt('libselinux') }} # [linux]
|
- {{ cdt('libselinux') }} # [linux]
|
||||||
- {{ cdt('libxdamage') }} # [linux]
|
- {{ cdt('libxdamage') }} # [linux]
|
||||||
- {{ cdt('libxxf86vm') }} # [linux]
|
- {{ cdt('libxxf86vm') }} # [linux]
|
||||||
|
- expat
|
||||||
|
|
||||||
host:
|
host:
|
||||||
- libstdcxx-ng
|
- libstdcxx-ng
|
||||||
@ -45,6 +46,7 @@ requirements:
|
|||||||
- xorg-libxau
|
- xorg-libxau
|
||||||
- xorg-libxrender
|
- xorg-libxrender
|
||||||
- xorg-libxfixes
|
- xorg-libxfixes
|
||||||
|
- expat
|
||||||
|
|
||||||
run:
|
run:
|
||||||
- zeromq
|
- zeromq
|
||||||
@ -96,3 +98,4 @@ outputs:
|
|||||||
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
- {{ pin_subpackage('slsdetlib', exact=True) }}
|
||||||
- qwt 6.*
|
- qwt 6.*
|
||||||
- qt 4.8.*
|
- qt 4.8.*
|
||||||
|
- expat
|
||||||
|
@ -59,14 +59,13 @@ set( HEADERS
|
|||||||
#set(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
#set(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
# ROOT dictionary generation
|
# ROOT dictionary generation
|
||||||
include("${ROOT_DIR}/modules/RootNewMacros.cmake")
|
include("${ROOT_DIR}/RootMacros.cmake")
|
||||||
root_generate_dictionary(ctbDict ${HEADERS} LINKDEF ctbLinkDef.h)
|
root_generate_dictionary(ctbDict ${HEADERS} LINKDEF ctbLinkDef.h)
|
||||||
add_library(ctbRootLib SHARED ctbDict.cxx)
|
add_library(ctbRootLib SHARED ctbDict.cxx)
|
||||||
target_include_directories(ctbRootLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(ctbRootLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
target_link_libraries(ctbRootLib PUBLIC
|
target_link_libraries(ctbRootLib PUBLIC
|
||||||
ROOT::Core
|
ROOT::Core
|
||||||
slsDetectorShared
|
slsDetectorShared
|
||||||
slsSupportLib
|
|
||||||
${ROOT_LIBRARIES}
|
${ROOT_LIBRARIES}
|
||||||
${ROOT_EXE_LINKER_FLAGS}
|
${ROOT_EXE_LINKER_FLAGS}
|
||||||
)
|
)
|
||||||
@ -78,7 +77,6 @@ set_target_properties(
|
|||||||
|
|
||||||
target_link_libraries(ctbGui PUBLIC
|
target_link_libraries(ctbGui PUBLIC
|
||||||
slsDetectorShared
|
slsDetectorShared
|
||||||
slsSupportLib
|
|
||||||
ctbRootLib
|
ctbRootLib
|
||||||
${TIFF_LIBRARIES}
|
${TIFF_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@ -38,11 +38,15 @@ set(SPHINX_SOURCE_FILES
|
|||||||
src/pydetector.rst
|
src/pydetector.rst
|
||||||
src/pyenums.rst
|
src/pyenums.rst
|
||||||
src/pyexamples.rst
|
src/pyexamples.rst
|
||||||
|
src/servers.rst
|
||||||
src/receiver.rst
|
src/receiver.rst
|
||||||
src/result.rst
|
src/result.rst
|
||||||
src/type_traits.rst
|
src/type_traits.rst
|
||||||
src/ToString.rst
|
src/ToString.rst
|
||||||
src/examples.rst
|
src/examples.rst
|
||||||
|
src/pygettingstarted.rst
|
||||||
|
src/firmware.rst
|
||||||
|
src/serverupgrade.rst
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -56,8 +60,21 @@ configure_file(
|
|||||||
"${SPHINX_BUILD}/conf.py"
|
"${SPHINX_BUILD}/conf.py"
|
||||||
@ONLY)
|
@ONLY)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/gen_server_doc.py.in"
|
||||||
|
"${SPHINX_BUILD}/gen_server_doc.py"
|
||||||
|
@ONLY)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/static/extra.css"
|
||||||
|
"${SPHINX_BUILD}/static/css/extra.css"
|
||||||
|
@ONLY)
|
||||||
|
|
||||||
|
add_custom_target(server_rst python gen_server_doc.py)
|
||||||
|
|
||||||
add_custom_target(docs
|
add_custom_target(docs
|
||||||
gendoc
|
gendoc
|
||||||
|
COMMAND python gen_server_doc.py
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||||
COMMAND ${SPHINX_EXECUTABLE} -a -b html
|
COMMAND ${SPHINX_EXECUTABLE} -a -b html
|
||||||
-Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml
|
-Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml
|
||||||
@ -66,4 +83,11 @@ add_custom_target(docs
|
|||||||
${SPHINX_BUILD}/html
|
${SPHINX_BUILD}/html
|
||||||
COMMENT "Generating documentation with Sphinx")
|
COMMENT "Generating documentation with Sphinx")
|
||||||
|
|
||||||
|
add_custom_target(rst
|
||||||
|
COMMAND ${SPHINX_EXECUTABLE} -a -b html
|
||||||
|
-Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml
|
||||||
|
-c "${SPHINX_BUILD}"
|
||||||
|
${SPHINX_BUILD}/src
|
||||||
|
${SPHINX_BUILD}/html
|
||||||
|
COMMENT "Generating documentation with Sphinx")
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ print(sys.path)
|
|||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
project = 'slsDetectorPackage'
|
project = 'slsDetectorPackage'
|
||||||
copyright = '2019, PSD Detector Group'
|
copyright = '2020, PSD Detector Group'
|
||||||
author = 'PSD Detector Group'
|
author = 'PSD Detector Group'
|
||||||
version = '@PROJECT_VERSION@'
|
version = '@PROJECT_VERSION@'
|
||||||
|
|
||||||
@ -59,4 +59,8 @@ html_theme = "sphinx_rtd_theme"
|
|||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# 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,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
#html_static_path = ['_static']
|
html_static_path = ['static']
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_stylesheet('css/extra.css') # may also be an URL
|
86
docs/gen_server_doc.py.in
Normal file
86
docs/gen_server_doc.py.in
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
def remove_comments(text):
|
||||||
|
def replacer(match):
|
||||||
|
s = match.group(0)
|
||||||
|
if s.startswith('/'):
|
||||||
|
return " " # note: a space and not an empty string
|
||||||
|
else:
|
||||||
|
return s
|
||||||
|
pattern = re.compile(
|
||||||
|
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
|
||||||
|
re.DOTALL | re.MULTILINE
|
||||||
|
)
|
||||||
|
return re.sub(pattern, replacer, text)
|
||||||
|
|
||||||
|
|
||||||
|
# @CMAKE_CURRENT_BINARY_DIR@
|
||||||
|
|
||||||
|
print('\n\n\n\n SERVER CSV')
|
||||||
|
|
||||||
|
src = Path('@CMAKE_SOURCE_DIR@')/'slsDetectorServers/'
|
||||||
|
detectors = ['Mythen3', 'Gotthard2', 'Eiger',
|
||||||
|
'Jungfrau', 'Moench', 'Gotthard', 'Ctb']
|
||||||
|
|
||||||
|
|
||||||
|
for det in detectors:
|
||||||
|
print(det)
|
||||||
|
in_fname = src/f'{det.lower()}DetectorServer/slsDetectorServer_defs.h'
|
||||||
|
#print(f'Reading: {in_fname}')
|
||||||
|
with open(in_fname) as f:
|
||||||
|
lines = f.read().replace('\\\n', '')
|
||||||
|
lines = lines.splitlines(keepends = True)
|
||||||
|
|
||||||
|
lines = [l.strip('#define').strip(' ') for l in lines if l.startswith('#define')]
|
||||||
|
output = []
|
||||||
|
signals = []
|
||||||
|
fields = ['Name,', 'Value', 'Comment']
|
||||||
|
excluded = ['DAC_NAMES', 'DEFAULT_DAC_VALS', 'CLK_NAMES', 'ONCHIP_DAC_NAMES']
|
||||||
|
header = f'{fields[0]:35}{fields[1]:35}\n'
|
||||||
|
output.append(header)
|
||||||
|
signals.append(header)
|
||||||
|
dac_names = []
|
||||||
|
dac_values = []
|
||||||
|
for line in lines:
|
||||||
|
name, *parts = line.split()
|
||||||
|
arg = ' '.join(parts)
|
||||||
|
value, *comments = arg.split('//')
|
||||||
|
value = value.strip('() ')
|
||||||
|
# value = value.replace(', ', ' ')
|
||||||
|
value = value.replace('\"', '')
|
||||||
|
if name not in excluded:
|
||||||
|
name += ','
|
||||||
|
if name.startswith('SIGNAL_'):
|
||||||
|
signals.append(f'{name:35}{value}\n')
|
||||||
|
else:
|
||||||
|
output.append(f'{name:35}\"{value}\"\n')
|
||||||
|
elif name == 'DAC_NAMES':
|
||||||
|
dac_names = [v.strip(', ') for v in value.split()]
|
||||||
|
dac_names = [n+',' for n in dac_names]
|
||||||
|
elif name == 'DEFAULT_DAC_VALS':
|
||||||
|
dac_values = remove_comments(value).strip('{}; ')
|
||||||
|
dac_values = dac_values.replace(',', '').split()
|
||||||
|
dac_values = [v.strip('') for v in dac_values]
|
||||||
|
|
||||||
|
print(f"dac_names: {len(dac_names)}, dac_values={len(dac_values)}")
|
||||||
|
if len(dac_values) == 0:
|
||||||
|
dac_values = ['N/A']*len(dac_names)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rstpath = Path('@CMAKE_SOURCE_DIR@')/'docs/src/'
|
||||||
|
|
||||||
|
out_fname = Path.cwd()/f'src/{det.lower()}.csv'
|
||||||
|
out_dac_fname = Path.cwd()/f'src/{det.lower()}-dacs.csv'
|
||||||
|
#print(f'Writing: {out_fname}')
|
||||||
|
with open(out_fname, 'w') as f:
|
||||||
|
f.writelines(output)
|
||||||
|
|
||||||
|
output = [f'{n:35}{v}\n' for n,v in zip(dac_names, dac_values)]
|
||||||
|
output.insert(0, header)
|
||||||
|
|
||||||
|
with open(out_dac_fname, 'w') as f:
|
||||||
|
f.writelines(output)
|
||||||
|
|
||||||
|
print('END\n\n\n\n')
|
@ -4,12 +4,28 @@ Command line interface
|
|||||||
Usage
|
Usage
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Commands can be uses either with sls_detector_get or sls_detector_put
|
Commands can be used either with sls_detector_get or sls_detector_put
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
sls_detector_get vrf
|
sls_detector_get vrf
|
||||||
|
|
||||||
|
Help
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
# get list of commands
|
||||||
|
sls_detector_get list
|
||||||
|
|
||||||
|
# search for a particular command using a word
|
||||||
|
sls_detector_get list | grep adc
|
||||||
|
|
||||||
|
# get help for a particular command
|
||||||
|
sls_detector_get -h fpath
|
||||||
|
sls_detector_help fpath
|
||||||
|
|
||||||
|
|
||||||
Commands
|
Commands
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ The documentation that you are reading now is built with
|
|||||||
|
|
||||||
* Doxygen (to extract C++ classes etc.)
|
* Doxygen (to extract C++ classes etc.)
|
||||||
* Breathe (Sphinx plugin to handle doxygen xml)
|
* Breathe (Sphinx plugin to handle doxygen xml)
|
||||||
* Sphinx
|
* Sphinx with sphinx_rtd_theme
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
Packaged in libs/
|
Packaged in libs/
|
||||||
|
357
docs/src/firmware.rst
Normal file
357
docs/src/firmware.rst
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
Firmware Upgrade
|
||||||
|
=================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Eiger
|
||||||
|
-------------
|
||||||
|
.. note ::
|
||||||
|
| Eiger firmware can be upgraded remotely.
|
||||||
|
| The programming executable (bcp) and corresponding bit files are provided by the SLS Detector group.
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Release candidate 5.0.0-rc1**
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Minimum compatible version : 27
|
||||||
|
Latest compatible version : 27
|
||||||
|
|
||||||
|
`Older versions <https://www.psi.ch/en/detectors/latest-installation>`_
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade
|
||||||
|
^^^^^^^^
|
||||||
|
#. Tftp must be already installed on your pc to use the bcp executable.
|
||||||
|
|
||||||
|
#. Kill the on-board servers and copy new servers to the board.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# Option 1: from detector console
|
||||||
|
# kill old server
|
||||||
|
ssh root@bebxxx
|
||||||
|
killall eigerDetectorServer
|
||||||
|
|
||||||
|
# copy new server
|
||||||
|
cd executables
|
||||||
|
scp user@pc:/path/eigerDetectorServerxxx .
|
||||||
|
chmod 777 eigerDetectorServerxxx
|
||||||
|
ln -sf eigerDetectorServerxxx eigerDetectorServer
|
||||||
|
sync
|
||||||
|
|
||||||
|
# Options 2: from client console for multiple modules
|
||||||
|
for i in bebxxx bebyyy;
|
||||||
|
do ssh root@$i killall eigerDetectorServer;
|
||||||
|
scp eigerDetectorServerxxx root@$i:~/executables/eigerDetectorServer;
|
||||||
|
ssh root@$i sync; done
|
||||||
|
|
||||||
|
|
||||||
|
* This is crucial when registers between firmwares change. Failure to do so will result in linux on boards to crash and boards can't be pinged anymore.
|
||||||
|
|
||||||
|
#. Bring the board into programmable mode using either of the 2 ways. Both methods result in only the central LED blinking.
|
||||||
|
|
||||||
|
* **Manual:**
|
||||||
|
|
||||||
|
Do a hard reset for each half module on back panel boards, between the LEDs, closer to each of the 1G ethernet connectors. Push until all LEDs start to blink.
|
||||||
|
|
||||||
|
* Software:
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
ssh root@bebxxx
|
||||||
|
cd executables
|
||||||
|
./boot_recovery
|
||||||
|
|
||||||
|
#. Start a terminal for each half module and run the following to see progress.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
nc -p 3000 -u bebxxx 3000
|
||||||
|
# Press enter twice to see prompt with board name.
|
||||||
|
> bebxxx
|
||||||
|
# After each bcp command, wait for this terminal to print "Success".
|
||||||
|
|
||||||
|
|
||||||
|
#. In another terminal, run the following to update firmware. Please update bit files with great caution as it could make your board inaccessible, if done incorrectly.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
#update back end fpga
|
||||||
|
bcp download.bit bebxxx:/fw0
|
||||||
|
|
||||||
|
#update front left fpga
|
||||||
|
bcp download.bit bebxxx:/febl
|
||||||
|
|
||||||
|
#update front right fpga
|
||||||
|
bcp download.bit bebxxx:/febr
|
||||||
|
|
||||||
|
#update kernel (only if required by the SLS Detector Group)
|
||||||
|
bcp download.bit bebxxx:/kernel
|
||||||
|
|
||||||
|
#. Reboot the detector.
|
||||||
|
|
||||||
|
Jungfrau
|
||||||
|
-------------
|
||||||
|
.. note ::
|
||||||
|
| Jungfrau firmware can be upgraded remotely.
|
||||||
|
| The corresponding programming file (pof) is provided by the SLS Detector group.
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Release candidate 5.0.0-rc1**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# PCB v1.0
|
||||||
|
Minimum compatible version : 24.07.2020 (v0.8)
|
||||||
|
Latest compatible version : 24.07.2020 (v0.8)
|
||||||
|
# PCB v2.0
|
||||||
|
Minimum compatible version : 21.07.2020 (v2.1)
|
||||||
|
Latest compatible version : 21.07.2020 (v2.1)
|
||||||
|
|
||||||
|
`Older versions <https://www.psi.ch/en/detectors/latest-installation>`_
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade (from v4.x.x)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
#. Tftp must be installed on pc.
|
||||||
|
|
||||||
|
#. Update client package to the latest (5.0.0-rc1).
|
||||||
|
|
||||||
|
#. Disable server respawning or kill old server
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# Option 1: if respawning enabled
|
||||||
|
telnet bchipxxx
|
||||||
|
# edit /etc/inittab
|
||||||
|
# comment out line #ttyS0::respawn:/jungfrauDetectorServervxxx
|
||||||
|
reboot
|
||||||
|
# ensure servers did not start up after reboot
|
||||||
|
telnet bchipxxx
|
||||||
|
ps
|
||||||
|
|
||||||
|
# Option 2: if respawning already disabled
|
||||||
|
telnet bchipxxx
|
||||||
|
killall jungfrauDetectorServerv*
|
||||||
|
|
||||||
|
#. Copy new server and start in update mode
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
tftp pcxxx -r jungfrauDetectorServervxxx -g
|
||||||
|
chmod 777 jungfrauDetectorServervxxx
|
||||||
|
./jungfrauDetectorServervxxx -u
|
||||||
|
|
||||||
|
#. Program fpga from the client console
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
sls_detector_get free
|
||||||
|
# Crucial that the next command executes without any errors
|
||||||
|
sls_detector_put hostname bchipxxx
|
||||||
|
sls_detector_put programfpga xxx.pof
|
||||||
|
|
||||||
|
#. After programming, kill update server using Ctrl + C.
|
||||||
|
|
||||||
|
#. Enable server respawning if needed
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
telnet bchipxxx
|
||||||
|
# edit /etc/inittab
|
||||||
|
# uncomment out line #ttyS0::respawn:/jungfrauDetectorServervxxx
|
||||||
|
# ensure the line has the new server name
|
||||||
|
reboot
|
||||||
|
# ensure both servers are running using ps
|
||||||
|
jungfrauDetectorServervxxx
|
||||||
|
jungfrauDetectorServervxxx --stop-server 1953
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade (from v5.0.0-rc1)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
#. Program from console
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies server from tftp folder of pc, programs fpga,
|
||||||
|
# removes old server from respawn, sets up new server to respawn
|
||||||
|
# and reboots
|
||||||
|
sls_detector_put update jungfrauDetectorServervxxx pcxxx xx.pof
|
||||||
|
|
||||||
|
# Or only program firmware
|
||||||
|
sls_detector_put programfpga xxx.pof
|
||||||
|
|
||||||
|
|
||||||
|
Gotthard
|
||||||
|
---------
|
||||||
|
|
||||||
|
.. warning ::
|
||||||
|
| Gotthard firmware cannot be upgraded remotely and requires the use of USB-Blaster.
|
||||||
|
| It is generally updated by the SLS Detector group.
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Release candidate 5.0.0-rc1**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Minimum compatible version : 11.01.2013
|
||||||
|
Latest compatible version : 08.02.2018 (50um and 25um Master)
|
||||||
|
09.02.2018 (25 um Slave)
|
||||||
|
|
||||||
|
`Older versions <https://www.psi.ch/en/detectors/latest-installation>`_
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
#. Download `Altera Quartus software or Quartus programmer <https://fpgasoftware.intel.com/20.1/?edition=standard&platform=linux&product=qprogrammer#tabs-4>`_.
|
||||||
|
|
||||||
|
|
||||||
|
#. Start Quartus programmer, click on Hardware Setup. In the "Currently selected hardware" window, select USB-Blaster.
|
||||||
|
|
||||||
|
#. In the Mode combo box, select "Active Serial Programming".
|
||||||
|
|
||||||
|
#. Plug the end of your USB-Blaster with the adaptor provided to the connector 'AS config' on the Gotthard board.
|
||||||
|
|
||||||
|
#. Click on 'Add file'. Select programming (pof) file provided by the SLS Detector group.
|
||||||
|
|
||||||
|
#. Check "Program/Configure" and "Verify". Push the start button. Wait until the programming process is finished.
|
||||||
|
|
||||||
|
#. In case of error messages, check the polarity of cable (that pin1 corresponds) and that the correct programming connector is selected.
|
||||||
|
|
||||||
|
#. Reboot the detector.
|
||||||
|
|
||||||
|
|
||||||
|
Mythen3
|
||||||
|
-------
|
||||||
|
.. note ::
|
||||||
|
| Mythen3 firmware can be upgraded remotely.
|
||||||
|
| The corresponding programming file (rbf) is provided by the SLS Detector group.
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Release candidate 5.0.0-rc1**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Minimum compatible version : 25.09.2020
|
||||||
|
Latest compatible version : 25.09.2020
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade (from v5.0.0-rc1)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
#. Program from console
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies server from tftp folder of pc, programs fpga,
|
||||||
|
# and reboots (new server not respawned currently)
|
||||||
|
sls_detector_put update mythen3DetectorServervxxx pcxxx xxx.rbf
|
||||||
|
|
||||||
|
# Or only program firmware
|
||||||
|
sls_detector_put programfpga xxx.rbf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Gotthard2
|
||||||
|
----------
|
||||||
|
.. note ::
|
||||||
|
| Gotthard2 firmware can be upgraded remotely.
|
||||||
|
| The corresponding programming file (rbf) is provided by the SLS Detector group.
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Release candidate 5.0.0-rc1**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Minimum compatible version : 25.09.2020
|
||||||
|
Latest compatible version : 25.09.2020
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade (from v5.0.0-rc1)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
#. Program from console
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies server from tftp folder of pc, programs fpga,
|
||||||
|
# and reboots (new server not respawned currently)
|
||||||
|
sls_detector_put update gotthard2DetectorServervxxx pcxxx xxx.rbf
|
||||||
|
|
||||||
|
# Or only program firmware
|
||||||
|
sls_detector_put programfpga xxx.rbf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Moench
|
||||||
|
------
|
||||||
|
.. note ::
|
||||||
|
| Moench firmware can be upgraded remotely.
|
||||||
|
| The corresponding programming file (pof) is provided by the SLS Detector group.
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Release candidate 5.0.0-rc1**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Minimum compatible version : 02.03.2020
|
||||||
|
Latest compatible version : 02.03.2020
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade (from v5.0.0-rc1)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
#. Program from console
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies server from tftp folder of pc, programs fpga,
|
||||||
|
# removes old server from respawn, sets up new server to respawn
|
||||||
|
# and reboots
|
||||||
|
sls_detector_put update moenchDetectorServervxxx pcxxx xx.pof
|
||||||
|
|
||||||
|
# Or only program firmware
|
||||||
|
sls_detector_put programfpga xxx.pof
|
||||||
|
|
||||||
|
Ctb
|
||||||
|
---
|
||||||
|
.. note ::
|
||||||
|
| Ctb firmware can be upgraded remotely.
|
||||||
|
| The corresponding programming file (pof) is provided by the SLS Detector group.
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Release candidate 5.0.0-rc1**
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Minimum compatible version : 27.11.2019
|
||||||
|
Latest compatible version : 27.11.2019
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade (from v5.0.0-rc1)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
#. Program from console
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies server from tftp folder of pc, programs fpga,
|
||||||
|
# removes old server from respawn, sets up new server to respawn
|
||||||
|
# and reboots
|
||||||
|
sls_detector_put update ctbDetectorServervxxx pcxxx xx.pof
|
||||||
|
|
||||||
|
# Or only program firmware
|
||||||
|
sls_detector_put programfpga xxx.pof
|
@ -48,7 +48,7 @@ int main() {
|
|||||||
auto tmp = os.str().erase(0, cmd.size());
|
auto tmp = os.str().erase(0, cmd.size());
|
||||||
auto usage = tmp.substr(0, tmp.find_first_of('\n'));
|
auto usage = tmp.substr(0, tmp.find_first_of('\n'));
|
||||||
tmp.erase(0, usage.size());
|
tmp.erase(0, usage.size());
|
||||||
auto help = replace_all(tmp, "\n\t", "\n\t\t");
|
auto help = replace_all(tmp, "\n\t", "\n\t\t| ");
|
||||||
fs << '\t' << cmd << usage << help << "\n";
|
fs << '\t' << cmd << usage << help << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ Welcome to slsDetectorPackage's documentation!
|
|||||||
:caption: Python API
|
:caption: Python API
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
pygettingstarted
|
||||||
pydetector
|
pydetector
|
||||||
pyenums
|
pyenums
|
||||||
pyexamples
|
pyexamples
|
||||||
@ -49,6 +50,17 @@ Welcome to slsDetectorPackage's documentation!
|
|||||||
type_traits
|
type_traits
|
||||||
ToString
|
ToString
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Servers
|
||||||
|
|
||||||
|
servers
|
||||||
|
serverupgrade
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Firmware
|
||||||
|
|
||||||
|
firmware
|
||||||
|
|
||||||
.. Indices and tables
|
.. Indices and tables
|
||||||
.. ==================
|
.. ==================
|
||||||
|
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
|
|
||||||
Installation
|
|
||||||
==============================================
|
|
||||||
|
|
||||||
Build from source using CMake
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
.. note ::
|
.. note ::
|
||||||
|
|
||||||
@ -13,17 +9,74 @@ Build from source using CMake
|
|||||||
without being communicated. If absolute stability of the API is needed please
|
without being communicated. If absolute stability of the API is needed please
|
||||||
use one of the release versions.
|
use one of the release versions.
|
||||||
|
|
||||||
|
.. warning ::
|
||||||
|
|
||||||
|
Before building from source make sure that you have the
|
||||||
|
:doc:`dependencies <../dependencies>` installed. If installing using conda, conda will
|
||||||
|
manage the dependencies.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
Build from source using CMake
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
Note that on some systems, for example RH7, cmake v3+ is available under the cmake3 alias.
|
||||||
|
It is also required to clone with the option --recursive to get the git submodules used
|
||||||
|
in the package.
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
git clone https://github.com/slsdetectorgroup/slsDetectorPackage.git
|
git clone --recursive https://github.com/slsdetectorgroup/slsDetectorPackage.git
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake ../slsDetectorPackage -DCMAKE_INSTALL_PREFIX=/your/install/path
|
cmake ../slsDetectorPackage -DCMAKE_INSTALL_PREFIX=/your/install/path
|
||||||
make -j12
|
make -j12 #or whatever number of cores you are using to build
|
||||||
make install
|
make install
|
||||||
|
|
||||||
|
The easiest way to configure options is to use the ccmake utility.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
#from the build directory
|
||||||
|
ccmake .
|
||||||
|
|
||||||
|
|
||||||
|
Build using cmk.sh script
|
||||||
|
-------------------------
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# new build and make with 9 parallel threads
|
||||||
|
./cmk.sh -cbj9
|
||||||
|
|
||||||
|
# build with python
|
||||||
|
./cmk.sh -bpj9
|
||||||
|
|
||||||
|
# build with GUI
|
||||||
|
./cmk.sh -bgj9
|
||||||
|
|
||||||
|
# build with hdf5
|
||||||
|
./cmk.sh -hj9 -d [path of hdf5 dir]
|
||||||
|
|
||||||
|
# get all options
|
||||||
|
./cmk.sh -?
|
||||||
|
|
||||||
|
|
||||||
Install binaries using conda
|
Install binaries using conda
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
Conda is not only useful to manage python environments but can also
|
||||||
|
be used as a user space package manager.
|
||||||
|
|
||||||
|
We have three different packages available:
|
||||||
|
|
||||||
|
* **slsdetlib**, shared libraries and command line utilities
|
||||||
|
* **slsdetgui**, GUI
|
||||||
|
* **slsdet**, Python bindings
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
#Add channels for dependencies and our library
|
#Add channels for dependencies and our library
|
||||||
@ -32,14 +85,19 @@ Install binaries using conda
|
|||||||
conda config --set channel_priority strict
|
conda config --set channel_priority strict
|
||||||
|
|
||||||
#cerate an environment with our library, then activate
|
#cerate an environment with our library, then activate
|
||||||
conda create -n myenv slsdetlib=2020.03.18.dev2
|
conda create -n myenv slsdetlib=2020.07.23.dev0
|
||||||
codna activate myenv
|
conda activate myenv
|
||||||
|
|
||||||
#ready to use
|
#ready to use
|
||||||
sls_detector_get exptime
|
sls_detector_get exptime
|
||||||
etc ...
|
etc ...
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
#List available versions
|
||||||
|
conda search slsdet
|
||||||
|
|
||||||
|
|
||||||
Build from source on old distributions
|
Build from source on old distributions
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
@ -66,4 +124,11 @@ is to use conda
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
conda create -n myenv python sphinx sphinx_rtd_theme
|
conda create -n myenv python sphinx sphinx_rtd_theme
|
||||||
|
|
||||||
|
Then enable the option SLS_BUILD_DOCS to create the targets
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
make docs # generate API docs and build Sphinx RST
|
||||||
|
make rst # rst only, saves time in case the API did not change
|
@ -6,4 +6,5 @@ Detector
|
|||||||
.. autoclass:: Detector
|
.. autoclass:: Detector
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
:inherited-members:
|
@ -4,9 +4,80 @@ Enums
|
|||||||
These enums are defined in slsDetectorDefs in the C++ package and
|
These enums are defined in slsDetectorDefs in the C++ package and
|
||||||
exposed to Python through pybind11.
|
exposed to Python through pybind11.
|
||||||
|
|
||||||
.. py:currentmodule:: sls_detector
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Most settings are represented as enums that can be
|
||||||
|
# explicitly imported
|
||||||
|
|
||||||
|
from slsdet import Detector, fileFormat
|
||||||
|
d = Detector()
|
||||||
|
d.fformat = fileFormat.BINARY
|
||||||
|
|
||||||
|
# Altough not recommended for convenience all enums
|
||||||
|
# and some other things can be impored using *
|
||||||
|
|
||||||
|
from slsdet import *
|
||||||
|
d.speed = speedLevel.FULL_SPEED
|
||||||
|
|
||||||
|
# To list the available enums, use dir()
|
||||||
|
|
||||||
|
import slsdet.enums
|
||||||
|
for enum in dir(slsdet.enums):
|
||||||
|
# filter out special memebers
|
||||||
|
if not enum.startswith('_'):
|
||||||
|
print(enum)
|
||||||
|
|
||||||
|
|
||||||
|
.. py:currentmodule:: slsdet
|
||||||
|
|
||||||
.. autoclass:: runStatus
|
.. autoclass:: runStatus
|
||||||
:members:
|
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
|
||||||
|
.. autoclass:: detectorType
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: frameDiscardPolicy
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: fileFormat
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: dimension
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: externalSignalFlag
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: timingMode
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: dacIndex
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: detectorSettings
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: clockIndex
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: speedLevel
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: readoutMode
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: masterFlags
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: frameModeType
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: detectorModeType
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: burstMode
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: timingSourceType
|
||||||
|
:undoc-members:
|
@ -1,7 +1,73 @@
|
|||||||
Examples
|
Examples
|
||||||
================
|
================
|
||||||
|
|
||||||
Some short hints on how to use the detector
|
Some short examples on how to use slsdet. If something is missing don't hesitate to
|
||||||
|
open an issue in our our `github repo
|
||||||
|
<https://github.com/slsdetectorgroup/slsDetectorPackage>`_.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
Setting exposure time
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Setting and reading back exposure time can be done either using a Python datetime.timedelta
|
||||||
|
or by setting the time in seconds.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Set exposure time to 1.2 seconds
|
||||||
|
>>> d.exptime = 1.2
|
||||||
|
|
||||||
|
# Setting exposure time using timedelta
|
||||||
|
import datetime as dt
|
||||||
|
>>> d.exptime = dt.timedelta(seconds = 1.2)
|
||||||
|
|
||||||
|
# With timedelta any arbitrary combination of units can be used
|
||||||
|
>>> t = dt.timedelta(microseconds = 100, seconds = 5.3, minutes = .3)
|
||||||
|
|
||||||
|
# To set exposure time for individual detector one have to resort
|
||||||
|
# to the C++ style API.
|
||||||
|
# Sets exposure time to 1.2 seconds for module 0, 6 and 12
|
||||||
|
>>> d.setExptime(1.2, [0, 6, 12])
|
||||||
|
>>> d.setExptime(dt.timedelta(seconds = 1.2), [0, 6, 12])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
Converting numbers to hex
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Python support entering numbers in format by using the 0x prefix. However, when reading
|
||||||
|
back you will get a normal integer. This can then be converted to a hex string representation
|
||||||
|
using the built in hex() function.
|
||||||
|
|
||||||
|
.. code-block :: python
|
||||||
|
|
||||||
|
from slsdet import Detector
|
||||||
|
>>> d = Detector()
|
||||||
|
>>> d.patwait0 = 0xaa
|
||||||
|
>>> d.patwait0
|
||||||
|
170
|
||||||
|
|
||||||
|
# Convert to string
|
||||||
|
>>> hex(d.patwait0)
|
||||||
|
'0xaa'
|
||||||
|
|
||||||
|
For multiple values one can use a list comprehension to loop over the values.
|
||||||
|
|
||||||
|
.. code-block :: python
|
||||||
|
|
||||||
|
>>> values = [1,2,3,4,5]
|
||||||
|
>>> [(v) for v in values]
|
||||||
|
['0x1', '0x2', '0x3', '0x4', '0x5']
|
||||||
|
|
||||||
|
# or to a single string by passing the list to .join
|
||||||
|
>>> ', '.join([hex(v) for v in values])
|
||||||
|
'0x1, 0x2, 0x3, 0x4, 0x5'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
Simple threshold scan
|
Simple threshold scan
|
||||||
@ -74,37 +140,39 @@ But lets start looking at the at the manual way:
|
|||||||
::
|
::
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from sls_detector import Eiger
|
from slsdet import Detector, runStatus
|
||||||
d = Eiger()
|
|
||||||
|
|
||||||
n = 10
|
|
||||||
t = 1
|
|
||||||
|
|
||||||
d.exposure_time = t
|
n_frames = 10
|
||||||
d.n_frames = n
|
t_exp = 1
|
||||||
d.reset_frames_caught()
|
|
||||||
|
|
||||||
#Start the measurement
|
# Set exposure time and number of frames
|
||||||
|
d = Detector()
|
||||||
|
d.exptime = t_exp
|
||||||
|
d.frames = n_frames
|
||||||
|
|
||||||
|
# Start the measurement
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
d.start_receiver()
|
d.startDetector()
|
||||||
d.start_detector()
|
d.startReceiver()
|
||||||
|
|
||||||
#Wait for the detector to be ready or do other important stuff
|
# Wait for the detector to be ready or do other important stuff
|
||||||
time.sleep(t*n)
|
time.sleep(t_exp * n_frames)
|
||||||
|
|
||||||
#check if the detector is ready otherwise wait a bit longer
|
# check if the detector is ready otherwise wait a bit longer
|
||||||
while d.status != 'idle':
|
while d.status != runStatus.IDLE:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
#Stop the receiver after we got the frames
|
# Stop the receiver after we got the frames
|
||||||
#Detector is already idle so we don't need to stop it
|
# Detector is already idle so we don't need to stop it
|
||||||
d.stop_receiver()
|
d.stopReceiver()
|
||||||
|
|
||||||
|
lost = d.rx_framescaught - n_frames
|
||||||
|
print(
|
||||||
|
f"{n_frames} frames of {t_exp}s took {time.time()-t0:{.3}}s with {lost} frames lost "
|
||||||
|
)
|
||||||
|
|
||||||
lost = d.frames_caught - n
|
|
||||||
print(f'{n} frames of {t}s took {time.time()-t0:{.3}}s with {lost} frames lost ')
|
|
||||||
|
|
||||||
#Reset to not interfere with a potential next measurement
|
|
||||||
d.reset_frames_caught()
|
|
||||||
|
|
||||||
Instead launching d.acq() from a different process is a bit easier since the control of receiver and detector
|
Instead launching d.acq() from a different process is a bit easier since the control of receiver and detector
|
||||||
is handled in the acq call. However, you need to join the process used otherwise a lot of zombie processes would
|
is handled in the acq call. However, you need to join the process used otherwise a lot of zombie processes would
|
||||||
@ -114,30 +182,104 @@ hang around until the main process exits.
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
from sls_detector import Eiger
|
from slsdet import Detector, runStatus
|
||||||
|
|
||||||
def acquire():
|
|
||||||
"""
|
|
||||||
Create a new Eiger object that still referes to the same actual detector
|
|
||||||
and same shared memory. Then launch acq.
|
|
||||||
"""
|
|
||||||
detector = Eiger()
|
|
||||||
detector.acq()
|
|
||||||
|
|
||||||
#This is the detector we use throughout the session
|
d = Detector()
|
||||||
d = Eiger()
|
|
||||||
|
|
||||||
#Process to run acquire
|
#Create a separate process to run acquire in
|
||||||
p = Process(target=acquire)
|
p = Process(target=d.acquire)
|
||||||
|
|
||||||
#Start the thread and short sleep to allow the acq to start
|
#Start the thread and short sleep to allow the acq to start
|
||||||
p.start()
|
p.start()
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
#Do some other work
|
#Do some other work
|
||||||
while d.busy is True:
|
while d.status != runStatus.IDLE:
|
||||||
print(d.busy)
|
print("Working")
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
#Join the process
|
#Join the process
|
||||||
p.join()
|
p.join()
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
Setting and getting times
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
import datetime as dt
|
||||||
|
from slsdet import Detector
|
||||||
|
from slsdet.utils import element_if_equal
|
||||||
|
|
||||||
|
d = Detector()
|
||||||
|
|
||||||
|
# The simplest way is to set the exposure time in
|
||||||
|
# seconds by using the exptime property
|
||||||
|
# This sets the exposure time for all modules
|
||||||
|
d.exptime = 0.5
|
||||||
|
|
||||||
|
# exptime also accepts a python datetime.timedelta
|
||||||
|
# which can be used to set the time in almost any unit
|
||||||
|
t = dt.timedelta(milliseconds = 2.3)
|
||||||
|
d.exptime = t
|
||||||
|
|
||||||
|
# or combination of units
|
||||||
|
t = dt.timedelta(minutes = 3, seconds = 1.23)
|
||||||
|
d.exptime = t
|
||||||
|
|
||||||
|
# exptime however always returns the time in seconds
|
||||||
|
>>> d.exptime
|
||||||
|
181.23
|
||||||
|
|
||||||
|
# To get back the exposure time for each module
|
||||||
|
# it's possible to use getExptime, this also returns
|
||||||
|
# the values as datetime.timedelta
|
||||||
|
|
||||||
|
>>> d.getExptime()
|
||||||
|
[datetime.timedelta(seconds=181, microseconds=230000), datetime.timedelta(seconds=181, microseconds=230000)]
|
||||||
|
|
||||||
|
# In case the values are the same it's possible to use the
|
||||||
|
# element_if_equal function to reduce the values to a single
|
||||||
|
# value
|
||||||
|
|
||||||
|
>>> t = d.getExptime()
|
||||||
|
>>> element_if_equal(t)
|
||||||
|
datetime.timedelta(seconds=1)
|
||||||
|
|
||||||
|
--------------
|
||||||
|
Reading dacs
|
||||||
|
--------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from slsdet import Detector, Eiger, dacIndex
|
||||||
|
|
||||||
|
#using the specialized class
|
||||||
|
e = Eiger()
|
||||||
|
>>> e.dacs
|
||||||
|
========== DACS =========
|
||||||
|
vsvp : 0 0
|
||||||
|
vtrim : 2480 2480
|
||||||
|
vrpreamp : 3300 3300
|
||||||
|
vrshaper : 1400 1400
|
||||||
|
vsvn : 4000 4000
|
||||||
|
vtgstv : 2556 2556
|
||||||
|
vcmp_ll : 1000 1000
|
||||||
|
vcmp_lr : 1000 1000
|
||||||
|
vcal : 0 0
|
||||||
|
vcmp_rl : 1000 1000
|
||||||
|
rxb_rb : 1100 1100
|
||||||
|
rxb_lb : 1100 1100
|
||||||
|
vcmp_rr : 1000 1000
|
||||||
|
vcp : 1000 1000
|
||||||
|
vcn : 2000 2000
|
||||||
|
vishaper : 1550 1550
|
||||||
|
iodelay : 650 650
|
||||||
|
|
||||||
|
# or using the general class and the list
|
||||||
|
d = Detector()
|
||||||
|
for dac in d.daclist:
|
||||||
|
r = d.getDAC(dac, False)
|
||||||
|
print(f'{dac.name:10s} {r}')
|
||||||
|
228
docs/src/pygettingstarted.rst
Normal file
228
docs/src/pygettingstarted.rst
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
Getting Started
|
||||||
|
==================
|
||||||
|
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
Which Python?
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
We require at lest Python 3.6 and strongly recommended that you don't use the system
|
||||||
|
Python installation. The examples in this documentation uses `conda
|
||||||
|
<https://docs.conda.io/en/latest/miniconda.html>`_ since it provides good support
|
||||||
|
also for non Python packages but there are also other alternatives like, pyenv.
|
||||||
|
|
||||||
|
Using something like conda also allows you to quickly switch beteen different Python
|
||||||
|
environments.
|
||||||
|
|
||||||
|
.. warning ::
|
||||||
|
|
||||||
|
If you use conda avoid also installing packages with pip.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
PYTHONPATH
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
If you install slsdet using conda everything is set up and you can
|
||||||
|
directly start using the Python bindings. However, if you build
|
||||||
|
from source you need to tell Python where to find slsdet. This
|
||||||
|
is be done by adding your build/bin directory to PYTHONPATH.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
export PYTHONPATH = /path/to/your/build/bin:$PYTHONPATH
|
||||||
|
|
||||||
|
.. note ::
|
||||||
|
|
||||||
|
Don't forget to compile with the option SLS_USE_PYTHON=ON to enable
|
||||||
|
the Python bindings or if you use the cmk.sh script -p.
|
||||||
|
|
||||||
|
--------------------------------------
|
||||||
|
Which detector class should I use?
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
We provide a generic class called Detector and detector specific
|
||||||
|
versions like, Eiger, Jungfrau etc. The most or all functionality
|
||||||
|
is there in the base class except the convenient access to dacs
|
||||||
|
and temperatures.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from slsdet import Detector, Eiger
|
||||||
|
|
||||||
|
d = Detector()
|
||||||
|
e = Eiger()
|
||||||
|
|
||||||
|
# Both classes can be used to control an Eiger detector
|
||||||
|
d.exptime = 0.5
|
||||||
|
e.period = 1
|
||||||
|
|
||||||
|
# But Eiger gives a simpler interface to the dacs
|
||||||
|
>>> e.dacs
|
||||||
|
========== DACS =========
|
||||||
|
vsvp : 0
|
||||||
|
vtrim : 2480
|
||||||
|
vrpreamp : 3300
|
||||||
|
vrshaper : 1400
|
||||||
|
vsvn : 4000
|
||||||
|
vtgstv : 2556
|
||||||
|
vcmp_ll : 1000
|
||||||
|
vcmp_lr : 1000
|
||||||
|
vcal : 0
|
||||||
|
vcmp_rl : 1000
|
||||||
|
rxb_rb : 1100
|
||||||
|
rxb_lb : 1100
|
||||||
|
vcmp_rr : 1000
|
||||||
|
vcp : 1000
|
||||||
|
vcn : 2000
|
||||||
|
vishaper : 1550
|
||||||
|
iodelay : 650
|
||||||
|
|
||||||
|
|
||||||
|
.. note ::
|
||||||
|
|
||||||
|
Depending on user feedback we might move some detector specific
|
||||||
|
functionality to the specialized classes.
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
Hey, there seems to be two APIs?
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
To make the Python API approachable, both if you come from the command line
|
||||||
|
or are using the C++ API, we provide two interfaces to the detector.
|
||||||
|
One is property based and tries to stay as close to the command line syntax
|
||||||
|
as is possible, and the other one directly maps the C++ API found in Detector.h.
|
||||||
|
There is also an underlying design reason for the two APIs since we auto
|
||||||
|
generate the bindings to the C++ code using a mix of pybind11 and clang-tools.
|
||||||
|
The property based API covers most of the functionality but in some cases
|
||||||
|
you have to reach for the C++ like interface.
|
||||||
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
d = Detector()
|
||||||
|
|
||||||
|
# C++ like API
|
||||||
|
d.setExptime(0.1)
|
||||||
|
|
||||||
|
# or a bit more pythonic
|
||||||
|
d.exptime = 0.1
|
||||||
|
|
||||||
|
The c++ style API offers more control over access to individual modules
|
||||||
|
in a large detector.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Set exposure time for module 1, 5 and 7
|
||||||
|
d.setExptime(0.1, [1,5,7])
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
Finding functions
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
To find out which properties and methods that a Python object have you
|
||||||
|
can use dir()
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
>>> from slsdet import Detector
|
||||||
|
>>> d = Detector()
|
||||||
|
>>> dir(d)
|
||||||
|
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
|
||||||
|
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
|
||||||
|
'__hash__', '__init__', '__init_subclass__', '__le__', '__len__',
|
||||||
|
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
|
||||||
|
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
|
||||||
|
'__str__', '__subclasshook__', '_adc_register', '_frozen',
|
||||||
|
'_register', 'acquire', 'adcclk', 'adcphase', 'adcpipeline',
|
||||||
|
'adcreg', 'asamples', 'auto_comp_disable', 'clearAcquiringFlag',
|
||||||
|
'clearBit', 'clearROI', 'client_version', 'config', 'copyDetectorServer',
|
||||||
|
'counters', 'daclist', 'dacvalues', 'dbitclk', 'dbitphase' ...
|
||||||
|
|
||||||
|
Since the list for Detector is rather long it's an good idea to filter it.
|
||||||
|
The following example gives you properties and methods containing time in
|
||||||
|
their name.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
>>> [item for item in dir(d) if 'time' in item]
|
||||||
|
['exptime', 'getExptime', 'getExptimeForAllGates', 'getExptimeLeft',
|
||||||
|
'getSubExptime', 'patwaittime0', 'patwaittime1', 'patwaittime2',
|
||||||
|
'setExptime', 'setSubExptime', 'subdeadtime', 'subexptime']
|
||||||
|
|
||||||
|
The above method works on any Python object but for convenience we also
|
||||||
|
included two functions to find names. View prints the names one per line
|
||||||
|
while find returns a list of names.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from slsdet.lookup import view, find
|
||||||
|
|
||||||
|
>>> view('exptime')
|
||||||
|
exptime
|
||||||
|
getExptime
|
||||||
|
getExptimeForAllGates
|
||||||
|
getExptimeLeft
|
||||||
|
getSubExptime
|
||||||
|
setExptime
|
||||||
|
setSubExptime
|
||||||
|
subexptime
|
||||||
|
|
||||||
|
>>> find('exptime')
|
||||||
|
['exptime', 'getExptime', 'getExptimeForAllGates', 'getExptimeLeft',
|
||||||
|
'getSubExptime', 'setExptime', 'setSubExptime', 'subexptime']
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
Finding out what the function does
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
To access the documentation of a function directly from the Python prompt use help().
|
||||||
|
|
||||||
|
.. code-block :: python
|
||||||
|
|
||||||
|
>>> help(Detector.period)
|
||||||
|
Help on property:
|
||||||
|
|
||||||
|
Period between frames, accepts either a value in seconds or datetime.timedelta
|
||||||
|
|
||||||
|
Note
|
||||||
|
-----
|
||||||
|
:getter: always returns in seconds. To get in datetime.delta, use getPeriod
|
||||||
|
|
||||||
|
Examples
|
||||||
|
-----------
|
||||||
|
>>> d.period = 1.05
|
||||||
|
>>> d.period = datetime.timedelta(minutes = 3, seconds = 1.23)
|
||||||
|
>>> d.period
|
||||||
|
181.23
|
||||||
|
>>> d.getPeriod()
|
||||||
|
[datetime.timedelta(seconds=181, microseconds=230000)]
|
||||||
|
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
Where are the ENUMs?
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
To set some of the detector settings like file format you have
|
||||||
|
to pass in an enum.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
>>> d.setFileFormat(fileFormat.BINARY)
|
||||||
|
|
||||||
|
The enums can be found in slsdet.enums
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
import slsdet
|
||||||
|
>>> [e for e in dir(slsdet.enums) if not e.startswith('_')]
|
||||||
|
['burstMode', 'clockIndex', 'dacIndex', 'detectorModeType',
|
||||||
|
'detectorSettings', 'detectorType', 'dimension', 'externalSignalFlag',
|
||||||
|
'fileFormat', 'frameDiscardPolicy', 'frameModeType', 'masterFlags',
|
||||||
|
'readoutMode', 'runStatus', 'speedLevel', 'timingMode',
|
||||||
|
'timingSourceType']
|
||||||
|
|
||||||
|
# Even though importing using * is not recommended one could
|
||||||
|
# get all the enums like this:
|
||||||
|
>>> from slsdet.enums import *
|
@ -1,6 +1,6 @@
|
|||||||
Receiver
|
Receiver
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
.. doxygenclass:: slsReceiver
|
.. doxygenclass:: Receiver
|
||||||
:members:
|
:members:
|
||||||
.. :undoc-members:
|
.. :undoc-members:
|
108
docs/src/servers.rst
Normal file
108
docs/src/servers.rst
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
Default values
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
Some general intro
|
||||||
|
|
||||||
|
Mythen3
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. csv-table:: Default values
|
||||||
|
:file: mythen3.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
DACS
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. csv-table:: Mythen3 DACS
|
||||||
|
:file: mythen3-dacs.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
Gotthard2
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. csv-table:: Default values
|
||||||
|
:file: gotthard2.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
DACS
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. csv-table:: Gotthard 2 DACS
|
||||||
|
:file: gotthard2-dacs.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
Moench
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. csv-table:: Default values
|
||||||
|
:file: moench.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
DACS
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. csv-table:: Moench DACS
|
||||||
|
:file: moench-dacs.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
Ctb
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. csv-table:: Default values
|
||||||
|
:file: ctb.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
Eiger
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. csv-table:: Default values
|
||||||
|
:file: eiger.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
DACS
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. csv-table:: Eiger DACS
|
||||||
|
:file: eiger-dacs.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
Jungfrau
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. csv-table:: Default values
|
||||||
|
:file: jungfrau.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
DACS
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. csv-table:: Jungfrau DACS
|
||||||
|
:file: jungfrau-dacs.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
Gotthard
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. csv-table:: Default values
|
||||||
|
:file: gotthard.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
DACS
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. csv-table:: Gotthard DACS
|
||||||
|
:file: gotthard-dacs.csv
|
||||||
|
:widths: 35, 35
|
||||||
|
:header-rows: 1
|
88
docs/src/serverupgrade.rst
Normal file
88
docs/src/serverupgrade.rst
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
Server Upgrade
|
||||||
|
=================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Eiger
|
||||||
|
-------------
|
||||||
|
|
||||||
|
#. Kill old server and copy new server
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# Option 1: from detector console
|
||||||
|
# kill old server
|
||||||
|
ssh root@bebxxx
|
||||||
|
killall eigerDetectorServer
|
||||||
|
|
||||||
|
# copy new server
|
||||||
|
cd executables
|
||||||
|
scp user@pc:/path/eigerDetectorServerxxx .
|
||||||
|
chmod 777 eigerDetectorServerxxx
|
||||||
|
ln -sf eigerDetectorServerxxx eigerDetectorServer
|
||||||
|
sync
|
||||||
|
|
||||||
|
# Options 2: from client console for multiple modules
|
||||||
|
for i in bebxxx bebyyy;
|
||||||
|
do ssh root@$i killall eigerDetectorServer;
|
||||||
|
scp eigerDetectorServerxxx root@$i:~/executables/eigerDetectorServer;
|
||||||
|
ssh root@$i sync; done
|
||||||
|
|
||||||
|
|
||||||
|
#. Reboot the detector.
|
||||||
|
|
||||||
|
|
||||||
|
Jungfrau
|
||||||
|
-------------
|
||||||
|
|
||||||
|
#. Program from console (only from 5.0.0-rc1)
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies new server from pc tftp folder, respawns and reboots
|
||||||
|
sls_detector_put copydetectorserver jungfrauDetectorServerxxx pcxxx
|
||||||
|
|
||||||
|
|
||||||
|
Gotthard
|
||||||
|
---------
|
||||||
|
#. Program from console (only from 5.0.0-rc1)
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies new server from pc tftp folder, respawns and reboots
|
||||||
|
sls_detector_put copydetectorserver gotthardDetectorServerxxx pcxxx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mythen3
|
||||||
|
-------
|
||||||
|
|
||||||
|
#. Program from console (only from 5.0.0-rc1)
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies new server from pc tftp folder and reboots (does not respawn)
|
||||||
|
sls_detector_put copydetectorserver mythen3DetectorServerxxx pcxxx
|
||||||
|
|
||||||
|
|
||||||
|
Gotthard2
|
||||||
|
----------
|
||||||
|
#. Program from console (only from 5.0.0-rc1)
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies new server from pc tftp folder and reboots (does not respawn)
|
||||||
|
sls_detector_put copydetectorserver gotthard2DetectorServerxxx pcxxx
|
||||||
|
|
||||||
|
|
||||||
|
Moench
|
||||||
|
------
|
||||||
|
#. Program from console (only from 5.0.0-rc1)
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies new server from pc tftp folder, respawns and reboots
|
||||||
|
sls_detector_put copydetectorserver moenchDetectorServerxxx pcxxx
|
||||||
|
|
||||||
|
|
||||||
|
Ctb
|
||||||
|
---
|
||||||
|
#. Program from console (only from 5.0.0-rc1)
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# copies new server from pc tftp folder, respawns and reboots
|
||||||
|
sls_detector_put copydetectorserver ctbDetectorServerxxx pcxxx
|
4
docs/static/extra.css
vendored
Normal file
4
docs/static/extra.css
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/* override table no-wrap */
|
||||||
|
.wy-table-responsive table td, .wy-table-responsive table th {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
@ -12,7 +12,7 @@ hostname bchip007
|
|||||||
0:rx_udpip 129.129.202.98
|
0:rx_udpip 129.129.202.98
|
||||||
0:rx_hostname pc6898
|
0:rx_hostname pc6898
|
||||||
0:outdir /bigRAID/datadir_gotthard/rec_test_data
|
0:outdir /bigRAID/datadir_gotthard/rec_test_data
|
||||||
0:vhighvoltage 120
|
0:highvoltage 120
|
||||||
master -1
|
master -1
|
||||||
sync none
|
sync none
|
||||||
outdir /bigRAID/datadir_gotthard/rec_test_data
|
outdir /bigRAID/datadir_gotthard/rec_test_data
|
||||||
|
129
examples/gotthard2_veto_file.txt
Normal file
129
examples/gotthard2_veto_file.txt
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#Gain index ADU value (12 bit)
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
||||||
|
1 3655
|
@ -1,132 +1,129 @@
|
|||||||
#G1 Energy #G2 Energy
|
#G0 pedestal G1 pedestal G2 pedestal G0 gain G1 gain G2 gain #G1 Energy #G2 Energy
|
||||||
300 7000
|
100 100 100 10 1 0.1 300 7000
|
||||||
|
100 100 100 10 1 0.1 300 7000
|
||||||
#G0 pedestal G1 pedestal G2 pedestal G0 gain G1 gain G2 gain (for every channel) ADU
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
100 100 100 10 1 0.1 300 7000
|
||||||
100 100 100 10 1 0.1
|
|
||||||
100 100 100 10 1 0.1
|
|
||||||
100 100 100 10 1 0.1
|
|
||||||
|
@ -6,12 +6,12 @@ hostname bchip074+bchip075+
|
|||||||
0:extsig:0 trigger_in_rising_edge
|
0:extsig:0 trigger_in_rising_edge
|
||||||
0:rx_tcpport 1954
|
0:rx_tcpport 1954
|
||||||
0:rx_udpport 50001
|
0:rx_udpport 50001
|
||||||
0:vhighvoltage 0
|
0:highvoltage 0
|
||||||
|
|
||||||
1:extsig:0 trigger_in_rising_edge
|
1:extsig:0 trigger_in_rising_edge
|
||||||
1:rx_tcpport 1955
|
1:rx_tcpport 1955
|
||||||
1:rx_udpport 50002
|
1:rx_udpport 50002
|
||||||
1:vhighvoltage 0
|
1:highvoltage 0
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#########
|
#########
|
||||||
@ -41,11 +41,11 @@ hostname bchip074+bchip075+
|
|||||||
|
|
||||||
|
|
||||||
r_readfreq 1
|
r_readfreq 1
|
||||||
rx_datastream 1
|
rx_zmqstream 1
|
||||||
|
|
||||||
#replace my_receiver_hostname with the hostname of 1Gb IP of the machine where the receiver runs
|
#replace my_receiver_hostname with the hostname of 1Gb IP of the machine where the receiver runs
|
||||||
rx_hostname my_receiver_hostname
|
rx_hostname my_receiver_hostname
|
||||||
rx_datastream 1
|
rx_zmqstream 1
|
||||||
outdir /tmp/
|
outdir /tmp/
|
||||||
|
|
||||||
|
|
||||||
@ -53,5 +53,5 @@ settings veryhighgain
|
|||||||
exptime 0.000005
|
exptime 0.000005
|
||||||
period 0.0001
|
period 0.0001
|
||||||
|
|
||||||
vhighvoltage 90
|
highvoltage 90
|
||||||
|
|
||||||
|
@ -459,8 +459,8 @@ rx_hostname mpc2011
|
|||||||
|
|
||||||
tengiga 1
|
tengiga 1
|
||||||
|
|
||||||
rx_datastream 1
|
rx_zmqstream 1
|
||||||
rx_readfreq 1
|
rx_zmqfreq 1
|
||||||
|
|
||||||
|
|
||||||
dac 6 800
|
dac 6 800
|
||||||
@ -498,4 +498,4 @@ rx_jsonpara detectorMode analog
|
|||||||
|
|
||||||
reg 0x5e 0x00010000
|
reg 0x5e 0x00010000
|
||||||
#powerchip 1
|
#powerchip 1
|
||||||
vhighvoltage 90
|
highvoltage 90
|
||||||
|
@ -6,7 +6,7 @@ hostname localhost
|
|||||||
rx_hostname localhost
|
rx_hostname localhost
|
||||||
|
|
||||||
#powerchip 1
|
#powerchip 1
|
||||||
#vhighvoltage 200
|
#highvoltage 200
|
||||||
|
|
||||||
#extsig:0 trigger_in_rising_edge
|
#extsig:0 trigger_in_rising_edge
|
||||||
#timing trigger
|
#timing trigger
|
||||||
|
@ -17,7 +17,7 @@ hostname bchip048+bchip052+
|
|||||||
rx_hostname pcmoench01
|
rx_hostname pcmoench01
|
||||||
|
|
||||||
powerchip 1
|
powerchip 1
|
||||||
vhighvoltage 200
|
highvoltage 200
|
||||||
#extsig:0 trigger_in_rising_edge
|
#extsig:0 trigger_in_rising_edge
|
||||||
#timing trigger
|
#timing trigger
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ zmqport 50001
|
|||||||
|
|
||||||
|
|
||||||
tengiga 1
|
tengiga 1
|
||||||
rx_datastream 1
|
rx_zmqstream 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ period 0.0006
|
|||||||
############################################
|
############################################
|
||||||
fpath /mnt/moench_data/scratch/
|
fpath /mnt/moench_data/scratch/
|
||||||
fwrite 0
|
fwrite 0
|
||||||
rx_datastream 1
|
rx_zmqstream 1
|
||||||
|
|
||||||
rx_jsonpara frameMode frame
|
rx_jsonpara frameMode frame
|
||||||
rx_jsonpara detectorMode counting
|
rx_jsonpara detectorMode counting
|
||||||
@ -56,7 +56,7 @@ rx_discardpolicy discardpartial
|
|||||||
adcpipeline 15
|
adcpipeline 15
|
||||||
|
|
||||||
powerchip 1
|
powerchip 1
|
||||||
vhighvoltage 90
|
highvoltage 90
|
||||||
|
|
||||||
#adcreg 0x14 0x40
|
#adcreg 0x14 0x40
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ hostname bchip007+bchip009+
|
|||||||
0:rx_udpip 10.1.1.1
|
0:rx_udpip 10.1.1.1
|
||||||
0:rx_hostname 129.129.202.134
|
0:rx_hostname 129.129.202.134
|
||||||
0:outdir /data/speedt
|
0:outdir /data/speedt
|
||||||
0:vhighvoltage 120
|
0:highvoltage 120
|
||||||
|
|
||||||
|
|
||||||
#1:hostname bchip009
|
#1:hostname bchip009
|
||||||
@ -37,7 +37,7 @@ hostname bchip007+bchip009+
|
|||||||
1:rx_udpip 10.1.2.1
|
1:rx_udpip 10.1.2.1
|
||||||
1:rx_hostname 129.129.202.134
|
1:rx_hostname 129.129.202.134
|
||||||
1:outdir /data/speedt
|
1:outdir /data/speedt
|
||||||
1:vhighvoltage 120
|
1:highvoltage 120
|
||||||
|
|
||||||
|
|
||||||
master -1
|
master -1
|
||||||
|
@ -99,7 +99,7 @@ If one desires to set the zmqport manually, he offset has to be taken into accou
|
|||||||
|
|
||||||
{\tt{slsMultiReceiver}} uses two or more receivers in one single terminal: {\tt{./slsMultiReceiver startTCPPort numReceivers withCallback}}, where startTCPPort assumes the other ports are consecutively increased.
|
{\tt{slsMultiReceiver}} uses two or more receivers in one single terminal: {\tt{./slsMultiReceiver startTCPPort numReceivers withCallback}}, where startTCPPort assumes the other ports are consecutively increased.
|
||||||
|
|
||||||
The command {\tt{r\_framesperfile}} sets the number of frames written in the same file. By default now it is 10000. It can be changes. It needs to be lowered particularly if one wants to parallelize the following conversion of the files.
|
The command {\tt{r\_framesperfile}} (\tt{\textcolor{red}{rx\_framesperfile}}) sets the number of frames written in the same file. By default now it is 10000. It can be changes. It needs to be lowered particularly if one wants to parallelize the following conversion of the files.
|
||||||
|
|
||||||
|
|
||||||
\subsection{Mandatory setup - Client}
|
\subsection{Mandatory setup - Client}
|
||||||
@ -122,7 +122,23 @@ To do that:
|
|||||||
sls_detector_put 0-config mydetector.config
|
sls_detector_put 0-config mydetector.config
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
In the config file, if client, receiver and detector are using \textbf{1GbE} the following lines are mandatory (see slsDetectorsPackage/examples/eiger\_1Gb.config):
|
In the config file, if client, receiver and detector are using \textbf{1GbE} the following lines are mandatory (see slsDetectorsPackage/examples/eiger\_1Gb.config). It has been adapted to the the new 5.0 major release change:
|
||||||
|
\begin{verbatim}
|
||||||
|
detsize 1024 512 #detector geometry, long side of the module first
|
||||||
|
hostname beb059+beb058+ #1Gb detector hostname for controls
|
||||||
|
#1Gb receiver pc hostname to be inserted immediately and tcp\_ports to be stated immediately
|
||||||
|
rx_hostname x12sa-vcons:1991+pc1875:1992+
|
||||||
|
0:udp_dstport 50011 #udp port first quadrant, first halfmodule
|
||||||
|
0:udp_dstport2 50012 #udp port second quadrant, first halfmodule
|
||||||
|
1:udp_dstport 50013 #udp port first quadrant, second halfmodule
|
||||||
|
1:udp_dstport2 50014 #udp port second quadrant, second halfmodule
|
||||||
|
0:udp_srcip 129.129.202.237
|
||||||
|
0:udp_dstip auto
|
||||||
|
1:udp_srcip 129.129.202.236
|
||||||
|
1:udp_dstip auto
|
||||||
|
fpath /sls/X12SA/data/x12saop/Data10/Eiger0.5M
|
||||||
|
\end{verbatim}
|
||||||
|
In the old 3.x and 4.x release it was:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
detsizechan 1024 512 #detector geometry, long side of the module first
|
detsizechan 1024 512 #detector geometry, long side of the module first
|
||||||
hostname beb059+beb058+ #1Gb detector hostname for controls
|
hostname beb059+beb058+ #1Gb detector hostname for controls
|
||||||
@ -138,21 +154,39 @@ threaded 1
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
In the config file, if client, receiver and detector commands are on 1Gb, but detector data to receiver are sent using \textbf{10GbE} the following lines are mandatory (see slsDetectorsPackage/examples/eiger\_10Gb.config):
|
In the config file, if client, receiver and detector commands are on 1Gb, but detector data to receiver are sent using \textbf{10GbE} the following lines are mandatory (see slsDetectorsPackage/examples/eiger\_10Gb.config):
|
||||||
|
It has been adapted to the the new 5.0 major release change:
|
||||||
|
\begin{verbatim}
|
||||||
|
detsize 1024 512
|
||||||
|
hostname beb059+beb058+
|
||||||
|
rx_hostname pc1875:1955+pc1875:1956+
|
||||||
|
0:udp_dstport 50011
|
||||||
|
0:udp_dstport2 50012
|
||||||
|
0:udp_dstip 10.0.30.210
|
||||||
|
0:udp_srcip 10.0.30.100
|
||||||
|
1:flippeddatax 1
|
||||||
|
1:udp_dstport 50013
|
||||||
|
1:udp_dstport2 50014
|
||||||
|
1:udp_dstip 0.0.40.210
|
||||||
|
1:udp_srcip 10.0.40.101
|
||||||
|
fpath /sls/X12SA/data/x12saop/Data10/Eiger0.5M
|
||||||
|
\end{verbatim}
|
||||||
|
In the old 3.x and 4.x release it was:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
detsizechan 1024 512 #detector geometry, long side of the module first
|
detsizechan 1024 512 #detector geometry, long side of the module first
|
||||||
hostname beb059+beb058+ #1Gb detector hostname for controls
|
hostname beb059+beb058+ #1Gb detector hostname for controls
|
||||||
0:rx_tcpport 1991 #tcpport for the first halfmodule
|
0:rx_tcpport 1955 #tcpport for the first halfmodule
|
||||||
0:rx_udpport 50011 #udp port first quadrant, first halfmodule
|
0:rx_udpport 50011 #udp port first quadrant, first halfmodule
|
||||||
0:rx_udpport2 50012 #udp port second quadrant, first halfmodule
|
0:rx_udpport2 50012 #udp port second quadrant, first halfmodule
|
||||||
0:rx_udpip 10.0.30.210 #udp IP of the receiver over 10Gb
|
0:rx_udpip 10.0.30.210 #udp IP of the receiver over 10Gb
|
||||||
0:detectorip 10.0.30.100 #first half module 10 Gb IP
|
0:detectorip 10.0.30.100 #first half module 10 Gb IP
|
||||||
1:rx_tcpport 1992 #tcpport for the second halfmodule
|
1:flippeddatax 1
|
||||||
|
1:rx_tcpport 1956 #tcpport for the second halfmodule
|
||||||
1:rx_udpport 50013 #udp port first quadrant, second halfmodule
|
1:rx_udpport 50013 #udp port first quadrant, second halfmodule
|
||||||
1:rx_udpport2 50014 #udp port second quadrant, second halfmodule
|
1:rx_udpport2 50014 #udp port second quadrant, second halfmodule
|
||||||
1:rx_udpip 10.0.40.210 #udp IP of the receiver over 10Gb,
|
1:rx_udpip 10.0.40.210 #udp IP of the receiver over 10Gb,
|
||||||
can be the same or different from 0:rx_udpip
|
can be the same or different from 0:rx_udpip
|
||||||
1:detectorip 10.0.40.101 #second half module 10 Gb IP
|
1:detectorip 10.0.40.101 #second half module 10 Gb IP
|
||||||
rx_hostname x12sa-vcons #1Gb receiver pc hostname
|
rx_hostname pc1875 #1Gb receiver pc hostname
|
||||||
outdir /sls/X12SA/data/x12saop/Data10/Eiger0.5M
|
outdir /sls/X12SA/data/x12saop/Data10/Eiger0.5M
|
||||||
threaded 1
|
threaded 1
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
@ -172,24 +206,25 @@ configuremac 0
|
|||||||
rx_udpmac xx:xx:...
|
rx_udpmac xx:xx:...
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
Now we will give general communication commands. Commands with a diffent name in the \textcolor{red}{5.x} realease will be highlighted in \textcolor{red}{red}.
|
||||||
|
|
||||||
One can configure all the detector settings in a parameter file {\tt{setup.det}}, which is loaded by doing:
|
One can configure all the detector settings in a parameter file {\tt{setup.det}}, which is loaded by doing:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
sls_detector_put 0-parameters setup.det
|
sls_detector_put 0-parameters setup.det
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
Note that the parameter file for any realease before 4.1.1 has not the possibility to understand parameters to be set differently for different half modules, i.e. {\tt{0:txndelay\_left xxxxx},\tt{1:txndelay\_left yyyyy}}.
|
Note that the parameter file for any realease before 4.1.1 has not the possibility to understand parameters to be set differently for different half modules, i.e. {\tt{0:txndelay\_left xxxxx},\tt{1:txndelay\_left yyyyy}}.
|
||||||
|
|
||||||
In the case of \E, the proper bias voltage of the sensor has to be setup, i.e. the {\tt{setup.det}} file needs to contain the line {\tt{vhighvoltage 150}}. Other detector functionality, which are rarely changed can be setup here.
|
In the case of \E, the proper bias voltage of the sensor has to be setup, i.e. the {\tt{setup.det}} file needs to contain the line {\tt{highvoltage 150}}. Other detector functionality, which are rarely changed can be setup here.
|
||||||
Other important settings that are configured in the {\tt{setup.det}} file are:
|
Other important settings that are configured in the {\tt{setup.det}} file are:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item {\tt{tengiga 0/1}}, which sets whether the detector is enabled to send data through the 1~or the 10~Gb Ethernet.
|
\item {\tt{tengiga 0/1}}, which sets whether the detector is enabled to send data through the 1~or the 10~Gb Ethernet.
|
||||||
\item {\tt{flags parallel/nonparallel}}, which sets whether the detector is set in parallel acquisition and readout or in sequential mode. This changes the readout time of the chip and affects the frame rate capability (faster is {\tt{parallel}}, with higher noise but needed when the frame rate is $>2$~kHz.
|
\item {\tt{flags parallel/nonparallel}} or {\tt{\textcolor{red}{parallel 1/0}}}, which sets whether the detector is set in parallel acquisition and readout or in sequential mode. This changes the readout time of the chip and affects the frame rate capability (faster is {\tt{parallel}}).
|
||||||
\item {\tt{dr 32/16/8/4}} sets the detector in autosumming mode (32 bit counter or not autosumming, 12 bit out of the chip). This is strictly connected to what is required for the readout clock of chip. See next point.
|
\item {\tt{dr 32/16/8/4}} sets the detector in autosumming mode (32 bit counter or not autosumming, 12 bit out of the chip). This is strictly connected to what is required for the readout clock of chip. See next point.
|
||||||
\item {\tt{clkdivider 0/1/2}}. Changes the readout clock: 200, 100, 50~MHz (also referred to as full, half, quarter speed). Note that autosumming mode ({\tt{dr 32}} only works at {clkdivider 2}=quarter speed). By selecting Refer to readout timing specifications in~section\ref{timing} for how to set the detector.
|
\item {\tt{clkdivider 0/1/2}} or {\tt{\textcolor{red}{speed full\_speed/half\_speed/quart\_speed}}}. Changes the readout clock: 200, 100, 50~MHz (also referred to as full, half, quarter speed). Note that autosumming mode ({\tt{dr 32}} only works at \tt{clkdivider 2}=\tt{quart\_speed}). By selecting Refer to readout timing specifications in~section\ref{timing} for how to set the detector.
|
||||||
\item {\tt{flags continuous/storeinram}}. Allows to take frame continuously or storing them on memory. Users should use the {\tt{continuous}} flags. Enabling the {\tt{stroreinram}} flag makes the data to be sent out all at the end of the acquisition. Refer to readout timing specifications in section~\ref{timing} for how to set the detector. Examples will be given in section~\ref{}.
|
\item {\tt{flags continuous/storeinram}}. Allows to take frame continuously or storing them on memory. Users should use the {\tt{continuous}} flags. Enabling the {\tt{stroreinram}} flag makes the data to be sent out all at the end of the acquisition. Refer to readout timing specifications in section~\ref{timing} for how to set the detector. Examples will be given in section~\ref{}.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
One should notice that, by default, by choosing the option {\tt{dr 32}}, then the software automatically sets the detector to {\tt{clkdivider 2}}. By choosing the option {\tt{dr 16}}, the software automatically sets the detector to {\tt{clkdivider 1}}. One needs to choose {\tt{clkdivider 0}} after setting the {\tt{dr 16}} option to have the fastest frame rate.
|
One should notice that, by default, by choosing the option {\tt{dr 32}}, then the software automatically sets the detector to {\tt{clkdivider 2}} ({\tt{\textcolor{red}{quart\_speed}}}). By choosing the option {\tt{dr 16}}, the software automatically sets the detector to {\tt{clkdivider 1}} ({\tt{\textcolor{red}{speed quart\_speed}}}). From release 5.x,
|
||||||
We would recommend expert users (beamline people) to write their parameters file for the users.
|
|
||||||
|
|
||||||
\section{API versioning} \label{api}
|
\section{API versioning} \label{api}
|
||||||
The eigerDetectorServer running on the boards has a versioning API scheme that will make it crash if used with a wrong firmware.
|
The eigerDetectorServer running on the boards has a versioning API scheme that will make it crash if used with a wrong firmware.
|
||||||
@ -210,10 +245,18 @@ Killing and starting the server on the boards allows you to check the firmware v
|
|||||||
|
|
||||||
\section{Setting up the threshold}
|
\section{Setting up the threshold}
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
|
sls_detector_put 0-settingsdir /path
|
||||||
sls_detector_put 0-trimen N xxxx yyyy zzzz
|
sls_detector_put 0-trimen N xxxx yyyy zzzz
|
||||||
sls_detector_put 0-settings standard
|
sls_detector_put 0-settings standard
|
||||||
sls_detector_put 0-threshold energy_in_eV standard
|
sls_detector_put 0-threshold energy_in_eV standard
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
or in \textcolor{red}{5.x}:
|
||||||
|
\begin{verbatim}
|
||||||
|
sls_detector_put 0-settingspath /path}
|
||||||
|
sls_detector_put 0-trimen N xxxx yyyy zzzz}
|
||||||
|
sls_detector_put 0-threshold energy_in_eV standard
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
The first line requires to specify how many ({\tt{N}}) and at which energies in eV {\{tt{xxxx}}, {\tt{yyyy}}, {\tt{zzzz}} and so on) trimmed files were generated (to allow for an interpolation). This line should normally be included into the {\tt{mydetector.config}} file and should be set for you by one of the detector group.
|
The first line requires to specify how many ({\tt{N}}) and at which energies in eV {\{tt{xxxx}}, {\tt{yyyy}}, {\tt{zzzz}} and so on) trimmed files were generated (to allow for an interpolation). This line should normally be included into the {\tt{mydetector.config}} file and should be set for you by one of the detector group.
|
||||||
NORMALLY, in this new calibration scheme, only {\tt{settings standard}} will be provided to you, unless specific cases to be discussed.
|
NORMALLY, in this new calibration scheme, only {\tt{settings standard}} will be provided to you, unless specific cases to be discussed.
|
||||||
The threshold at 6000 eV , for example would be set as:{\tt{sls\_detector\_put 0-threshold 6000 standard}}.
|
The threshold at 6000 eV , for example would be set as:{\tt{sls\_detector\_put 0-threshold 6000 standard}}.
|
||||||
@ -244,11 +287,11 @@ In this acquisition 10 consecutive 1~s frames will be acquired. Note that {\tt{p
|
|||||||
|
|
||||||
You need to setup where the files will be written to
|
You need to setup where the files will be written to
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
sls_detector_put 0-outdir /scratch
|
sls_detector_put 0-outdir /scratch (\textcolor{red}{0-fpath})
|
||||||
sls_detector_put 0-fname run
|
sls_detector_put 0-fname run
|
||||||
sls_detector_put 0-index 0
|
sls_detector_put 0-index 0 (\textcolor{red}{0-findex})
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
this way your files will all be named /scratch/run\_dj\_i.raw where $j$ is relative to each specific half module, $i$ in the {\tt{index}} starts from 0 when starting the detector the first time and is automatically incremented. The next acquisition {\tt{index}} will be 1. One can reset the {\tt{index}} to what wished.
|
this way your files will all be named /scratch/run\_dj\_i.raw where $j$ is relative to each specific half module, $i$ in the {\tt{index}} starts from 0 when starting the detector the first time and is automatically incremented. The next acquisition {\tt{index}} will be 1. One can reset the {\tt{index}} (\tt{\textcolor{red}{findex}}) to what wished.
|
||||||
|
|
||||||
To acquire simply type:
|
To acquire simply type:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@ -267,12 +310,13 @@ sls_detector_get receiver
|
|||||||
|
|
||||||
There is a more complex way of performing an acquisition, that is useful for debugging and in case one wants a non blocking behavior:
|
There is a more complex way of performing an acquisition, that is useful for debugging and in case one wants a non blocking behavior:
|
||||||
|
|
||||||
You can then reset to zero the number of frames caught, then start the receiver and the detector:
|
You can then reset to zero the number of frames caught (in releases<5.0), then start the receiver and the detector:
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item {\tt{sls\_detector\_put 0-resetframescaught 0}}
|
\item {\tt{sls\_detector\_put 0-resetframescaught 0}}
|
||||||
\item {\tt{sls\_detector\_put 0-receiver start}}
|
\item {\tt{sls\_detector\_put 0-receiver start}}
|
||||||
\item {\tt{sls\_detector\_put 0-status start}}
|
\item {\tt{sls\_detector\_put 0-status start}}
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
In release \textcolor{red}{5.0} it is not needed to reset the frames caughts.
|
||||||
|
|
||||||
You can poll the detector status using:
|
You can poll the detector status using:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@ -347,8 +391,11 @@ col : 257 pixels
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
\section{Readout timing- maximum frame rate}\label{timing}
|
\section{Readout timing- maximum frame rate}\label{timing}
|
||||||
IMPORTANT: to have faster readout and smaller dead time, one can configure {\tt{clkdivider}}, i.e. the speed at which the data are read, i.e. 200/100/50~MHz for {\tt{clkdivider 0/1/2}} and the dead time between frames through {\tt{flags parallel}}, i.e. acquire and read at the same time or acquire and then read out.
|
IMPORTANT: to have faster readout and smaller dead time, one can configure {\tt{clkdivider}}, i.e. the {\tt{textcolor}{red}{speed} at which the data are read, i.e. 200/100/50~MHz for {\tt{clkdivider 0/1/2}} ({\tt{
|
||||||
The configuration of this timing variables allows to achieve different frame rates. NOTE THAT IN EIGER, WHATEVER YOU DO, THE FRAME RATE LIMITATIONS COME FROM THE NETWORK BOTTLENECK AS THE HARDWARE GOES FASTER THAN THE DATA OUT.
|
\textcolor{red}{speed full\_speed/half\_speed/quart\_speed}}) and the dead time between frames through {\tt{flags parallel}} or {\tt{\textcolor{red}{parallel 1}}}, i.e. acquire and read at the same time or acquire and then read out.
|
||||||
|
The configuration of this timing variables allows to achieve different frame rates. NOTE THAT IN EIGER, WHATEVER YOU DO, THE FRAME RATE LIMITATIONS COME FROM THE NETWORK BOTTLENECK AS THE HARDWARE GOES FASTER THAN THE DATA OUT. WE recconmmend using the detector in \tt{dr 4/8/16}, \tt{\textcolor{red}{speed full\_speed}}, \tt{parallel 1} or \tt{dr 32}, \tt{\textcolor{red}{speed quart\_speed}}, \tt{parallel 1. All those options are now the defaults options starting from version 5.x.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from the boards (independent on how the chip is set), the continuous frame rates are listed in table~\ref{tcont}. The time to send out the frame out of the board
|
In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from the boards (independent on how the chip is set), the continuous frame rates are listed in table~\ref{tcont}. The time to send out the frame out of the board
|
||||||
\begin{table}
|
\begin{table}
|
||||||
@ -360,16 +407,16 @@ In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from
|
|||||||
\hline
|
\hline
|
||||||
1 & 32 & \textbf{128} & 7820 & \\
|
1 & 32 & \textbf{128} & 7820 & \\
|
||||||
\hline
|
\hline
|
||||||
10 & 4 & \textbf{10240} & 98 & 105/128\\
|
10 & 4 & \textbf{7813} & 98 & 105/128\\
|
||||||
\hline
|
\hline
|
||||||
10 & 8 & \textbf{5120} & 196 & 210/250\\
|
10 & 8 & \textbf{4000} & 196 & 210/250\\
|
||||||
\hline
|
\hline
|
||||||
10 & 16 & \textbf{2560} & 391 & 420/490\\
|
10 & 16 & \textbf{2000} & 391 & 420/490\\
|
||||||
\hline
|
\hline
|
||||||
10 & 32 & \textbf{1280} & 782 & 840/977\\
|
10 & 32 & \textbf{1023} & 782 & 840/977\\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\caption{Frame rate limits for the CONTINUOS streaming out of images, i.e. the data rate out is just below 1Gb/s or 10Gb/s. 1280~Hz for 32-bit, 10GbE is obtained from the 10GbE limitation. The maximum achievable frame rate is 977~Hz.}
|
\caption{Frame rate limits for the CONTINUOS streaming out of images, i.e. the data rate out is just below 1Gb/s or 10Gb/s. 1023~Hz for 32-bit, 10GbE is obtained from the 10GbE limitation. The maximum achievable frame rate is 977~Hz.}
|
||||||
\label{tcont}\end{table}
|
\label{tcont}\end{table}
|
||||||
Note that in the {\tt{continuous}} flag mode, some buffering is still done on the memories, so a higher frame rate than the proper real continuous one can be achieved. Still, this extra buffering is possible till the memories are not saturated. The number of images that can be stored on the DDR2 on board memories are listed in table~\ref{timgs}.
|
Note that in the {\tt{continuous}} flag mode, some buffering is still done on the memories, so a higher frame rate than the proper real continuous one can be achieved. Still, this extra buffering is possible till the memories are not saturated. The number of images that can be stored on the DDR2 on board memories are listed in table~\ref{timgs}.
|
||||||
\begin{table}
|
\begin{table}
|
||||||
@ -384,11 +431,11 @@ dynamic range & images\\
|
|||||||
16 & 7600\\
|
16 & 7600\\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\caption{Amount of images that can be stored on board. As while we store them, we start to send them out, the effective number of images could be larger than this, but it will depend on the network setup (how fats you stream out images).}
|
\caption{Amount of images that can be stored on board. As while we store them, we start to send them out, the effective number of images could be larger than this, but it will depend on the network setup (how fast you stream out images).}
|
||||||
\label{timgs}
|
\label{timgs}
|
||||||
\end{table}
|
\end{table}
|
||||||
|
|
||||||
The maximum frame rate achievable with 10~GbE, {\tt{dr 16}}, {\tt{flags continuous}}, {\tt{flags parallel}},{\tt{clkdivider 0}}, \textbf{6.1~kHz}. This is currently limited by the connection between the Front End Board and the Backend board. We expect the 32 bit mode limit, internally, to be \textbf{2~kHz} ({\tt{clkdivider 2}}).
|
The maximum frame rate achievable with 10~GbE, {\tt{dr 16}}, {\tt{flags continuous}}, {\tt{flags parallel}} ({\tt{\textcolor{red}{parallel 1}}}),{\tt{clkdivider 0}} ({\tt{\textcolor{red}{speed full\_speed}}}), \textbf{6.1~kHz}. This is currently limited by the connection between the Front End Board and the Backend board. We expect the 32 bit mode limit, internally, to be \textbf{2~kHz} ({\tt{clkdivider 2}}).
|
||||||
In dynamic range {\tt{dr 8}} the frame rate is \textbf{11~kHz} and for{\tt{dr 4}} is \textbf{22~kHz}. For 4 and 8 bit mode the frame rate are directly limited by the speed of the detector chip and not by the readout boards.
|
In dynamic range {\tt{dr 8}} the frame rate is \textbf{11~kHz} and for{\tt{dr 4}} is \textbf{22~kHz}. For 4 and 8 bit mode the frame rate are directly limited by the speed of the detector chip and not by the readout boards.
|
||||||
|
|
||||||
\subsection{Minimum time between frames and Maximum frame rate}
|
\subsection{Minimum time between frames and Maximum frame rate}
|
||||||
@ -459,6 +506,23 @@ where the 'minimum time between frames' and the minimum period will be discussed
|
|||||||
|
|
||||||
\textbf{From software version 4.0.0, there is a very useful function {\tt{sls\_detector\_get measuredperiod}} which return the measured period AFTER the acquisition. This is important to check that the settings to obtain the targeted frame rate was correct.}
|
\textbf{From software version 4.0.0, there is a very useful function {\tt{sls\_detector\_get measuredperiod}} which return the measured period AFTER the acquisition. This is important to check that the settings to obtain the targeted frame rate was correct.}
|
||||||
|
|
||||||
|
In release \textcolor{red}{5.0} in 4-bit modes one can set a sort of ROI in the detector such to read half of the module (the central part) or a quarter of it with almost double or four times the frame rate. By default the \tt{\textcolor{red}{readnlines}} is set to \tt{256} meaning the whole chip. With \tt{\textcolor{red}{readnlines 128}} or \tt{\textcolor{red}{readnlines 64}} one sets to read half/quarter rows from the chip. In table~\ref{table:hfrpartial} the maximum frame rates, exposure time and period for the partial readout.\\
|
||||||
|
|
||||||
|
|
||||||
|
\begin{tabular}{|c|c|c|c|c|c|c|}
|
||||||
|
\hline
|
||||||
|
readnlines & \# pixels & Active area (cm$^2$) & Max frame rate (kHz) & Period ($\mu$s) & Dead time ($\mu$s) & \# buffered images\\
|
||||||
|
\hline
|
||||||
|
256 &1024 $\times$ 512 & 8 $\times$ 3.8 & 22.7 & 44.0 &4.1 & 30k\\
|
||||||
|
\hline
|
||||||
|
128 &1024 $\times$ 256 & 8 $\times$ 1.9 & 42.1 & 23.7 &4.2 & 60k\\
|
||||||
|
\hline
|
||||||
|
64 & 1024 $\times$ 128 & 8 $\times$ 0.95 & 73.5 & 13.6 &4.2 & 120k\\
|
||||||
|
\hline
|
||||||
|
\end{tabular}
|
||||||
|
\label{table:hfrpartial}
|
||||||
|
|
||||||
|
|
||||||
\textbf{If you run too fast, the detector could become noisier (see problem shooting), it is important to match the detector settings to your frame rate. This can be done having more parameters files and load the one suitable with your experiment.} We experienced that with low energy settings could not reach 6~kHz and no noise.
|
\textbf{If you run too fast, the detector could become noisier (see problem shooting), it is important to match the detector settings to your frame rate. This can be done having more parameters files and load the one suitable with your experiment.} We experienced that with low energy settings could not reach 6~kHz and no noise.
|
||||||
In 16 bit mode, it could make sense, in case of noise and low threshold to either reduce the frame rate:
|
In 16 bit mode, it could make sense, in case of noise and low threshold to either reduce the frame rate:
|
||||||
\begin{equation}
|
\begin{equation}
|
||||||
@ -579,10 +643,10 @@ The number of subframes composing a single 32bit acquisition can be calculated a
|
|||||||
\end{equation}
|
\end{equation}
|
||||||
This also means that {\tt{exptime}}$<${\tt{subexptime}} will be rounded to{\tt{subexptime}}. If you want shorter acquisitions, either reduce the {\tt{subexptime}} or switch two 16-bit mode (you can always sum offline if needed).
|
This also means that {\tt{exptime}}$<${\tt{subexptime}} will be rounded to{\tt{subexptime}}. If you want shorter acquisitions, either reduce the {\tt{subexptime}} or switch two 16-bit mode (you can always sum offline if needed).
|
||||||
|
|
||||||
From release 4.0.0, an extra {\tt{flag overflow/nooverflow}} is added, with {\tt{nooverflow}} default:
|
From release 4.0.0, an extra {\tt{flag overflow/nooverflow}} is added (\tt{\textcolor{red}{overflow 0/1}}), with {\tt{nooverflow}} (\tt{\textcolor{red}{overflow 0}}) default:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item {\tt{nooverflow}}: the internal 12-bit result is summed, even if there was saturation of the 12-bit counter (4095) in any of the subframes. Note that if there is saturation for every subframe, you might get as a result a value of the counter equal to (4095$\times$~number~of~subframes), which you need to correctly identify. On the other hand if the saturation occurred only one time, you will get something "close'' to the real number.
|
\item {\tt{nooverflow}} (\tt{\textcolor{red}{overflow 0}}): the internal 12-bit result is summed, even if there was saturation of the 12-bit counter (4095) in any of the subframes. Note that if there is saturation for every subframe, you might get as a result a value of the counter equal to (4095$\times$~number~of~subframes), which you need to correctly identify. On the other hand if the saturation occurred only one time, you will get something "close'' to the real number.
|
||||||
\item {\tt{overflow}}: In this case, even if a pixel saturate only 1 time in a subframe, you will be returned as a value of the counter for that pixel: $2^{32}-1$, i.e. 4294967295.
|
\item {\tt{overflow}} (\tt{\textcolor{red}{overflow 1}})): In this case, even if a pixel saturate only 1 time in a subframe, you will be returned as a value of the counter for that pixel: $2^{32}-1$, i.e. 4294967295.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
The UDP header will contain, after you receive the data, the effective number of subframe per image (see section~\ref{UDP}) as "SubFrame Num or Exp Time", i.e. the number of subframes recorded (32 bit eiger).
|
The UDP header will contain, after you receive the data, the effective number of subframe per image (see section~\ref{UDP}) as "SubFrame Num or Exp Time", i.e. the number of subframes recorded (32 bit eiger).
|
||||||
@ -610,17 +674,17 @@ The detector can be setup such to receive external triggers. Connect a LEMO sign
|
|||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
sls_detector_put 0-timing [auto/trigger/burst_trigger/gating]
|
sls_detector_put 0-timing [auto/trigger/burst_trigger/gating]
|
||||||
sls_detector_put 0-frames x
|
sls_detector_put 0-frames x
|
||||||
sls_detector_put 0-cycles y
|
sls_detector_put 0-cycles y (\textcolor{red}{triggers})
|
||||||
sls_detector_acquire 0-
|
sls_detector_acquire 0-
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
No timeout is expected between the start of the acquisition and the arrival of the first trigger.
|
No timeout is expected between the start of the acquisition and the arrival of the first trigger.
|
||||||
|
|
||||||
Here are the implemented options so far:
|
Here are the implemented options so far:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\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{auto}} is the software controlled acquisition (does not use triggers), where {\tt{exptime}} and {\tt{period}} have to be set. Set number of {\tt{cycles}} (\textcolor{red}{triggers}) to 1. 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{trigger}} 1 frame taken for 1 trigger. Your {\tt{frames}} needs to be 1 always, {\tt{cycles}} ({\tt{\textcolor{red}{triggers}}}) 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{burst\_trigger}} gets only 1 trigger, but allows to take many frames. With {\tt{frames}} one can change the number of frames. {\tt{cycles}} ({\tt{\textcolor{red}{triggers}}}) 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}}. IMPORTANT: Up to firmware 23, the last subframe is oblige to finish being taken, despite the gate signal going down. This will be configurable from later fw and software version. Also, in gating mode, due to timimg of the state machine, you need to leave 500~$\mu$s deadtime between the end on an acquisition and the next. This is as the state machine is unable to check for changes in the status in the first 500~$\mu$s. 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. 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.
|
\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}} (\tt{\textcolor{red}{triggers}}) allows to select how many gates to consider. Set number of frames to 1 using {\tt{frames}}. IMPORTANT: Up to firmware 23, the last subframe is oblige to finish being taken, despite the gate signal going down. This will be configurable from later fw and software version. Also, in gating mode, due to timimg of the state machine, you need to leave 500~$\mu$s deadtime between the end on an acquisition and the next. This is as the state machine is unable to check for changes in the status in the first 500~$\mu$s. 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. 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.
|
||||||
|
|
||||||
ATTENTION: From release 4.1.1 with the {\tt{trigger}} option it is possible to have software triggers as a debugging tool (instead of the hardware trigger signal. One should start the acquisition (with the blocking {\tt{sls\_detector\_acquire}} if wanted and with another client one can send the softare trigger {\tt{sls\_detector\_put status trigger}}. This option allows for example to perform a motor scan (moving a motor in between single images) and still writing all images to the same file.
|
ATTENTION: From release 4.1.1 with the {\tt{trigger}} option it is possible to have software triggers as a debugging tool (instead of the hardware trigger signal. One should start the acquisition (with the blocking {\tt{sls\_detector\_acquire}} if wanted and with another client one can send the softare trigger {\tt{sls\_detector\_put status trigger}}. This option allows for example to perform a motor scan (moving a motor in between single images) and still writing all images to the same file.
|
||||||
When using 32-bit mode, by default the acquisition ends the last complete subframe that was started when still the acquisition time was valid. This has been chosen as many people wants to know the exact acquisition time for when the detector was taking data and also, if {\tt{ratecorr}} are active, the last subframe will be correctly corrected, while otherwise it will be corrected with a wrong subdeadtime.
|
When using 32-bit mode, by default the acquisition ends the last complete subframe that was started when still the acquisition time was valid. This has been chosen as many people wants to know the exact acquisition time for when the detector was taking data and also, if {\tt{ratecorr}} are active, the last subframe will be correctly corrected, while otherwise it will be corrected with a wrong subdeadtime.
|
||||||
@ -630,13 +694,13 @@ However, from 4.1.0, in gating mode, an option to immediately terminate the subf
|
|||||||
|
|
||||||
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.
|
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}} 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}} (\tt{\textcolor{red}{triggers}}) 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:
|
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}
|
\begin{verbatim}
|
||||||
sls_detector_put 0-timing [trigger/burst_trigger]
|
sls_detector_put 0-timing [trigger/burst_trigger]
|
||||||
sls_detector_put 0-frames x
|
sls_detector_put 0-frames x
|
||||||
sls_detector_put 0-cycles y
|
sls_detector_put 0-cycles y (\textcolor{red}{triggers})
|
||||||
sls_detector_status trigger
|
sls_detector_status trigger
|
||||||
\end{verbatim}
|
\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}.
|
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}.
|
||||||
@ -716,8 +780,8 @@ If \textbf{dr} is 32 and \textbf{clkdivider} is not 2, whatever the detector get
|
|||||||
|
|
||||||
Here is a list of parameters that should be reset:
|
Here is a list of parameters that should be reset:
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item \textbf{resetframescaught} should be reset to zero after every acquisition taken with {\tt{receiver start}},{\tt{status start}},{\tt{receiver stop}}. If the acquisition is taken with {\tt{sls\_detector\_acquire}}, there is no need to reset this.
|
\item \textbf{resetframescaught} (only for releases < 5.x) should be reset to zero after every acquisition taken with {\tt{receiver start}},{\tt{status start}},{\tt{receiver stop}}. If the acquisition is taken with {\tt{sls\_detector\_acquire}}, there is no need to reset this.
|
||||||
\item After changing the {\tt{timing}} mode of the detector, one should reset to '1' the unused value, in that specific timing mode, between \textbf{frames} and \textbf{cycles}. See section~\ref{triggering} for how to use the timing. At the present moment the detector will acquire more frames than planned if the variable not used between \textbf{frames} and \textbf{cycles} is not reset. In future releases, the unused variable will be ignored. Still resetting is a good practice.
|
\item After changing the {\tt{timing}} mode of the detector, one should reset to '1' the unused value, in that specific timing mode, between \textbf{frames} and \textbf{cycles} (\tt{\textcolor{red}{triggers}}). See section~\ref{triggering} for how to use the timing. At the present moment the detector will acquire more frames than planned if the variable not used between \textbf{frames} and \textbf{cycles} (\tt{\textcolor{red}{trigger}}) is not reset. In future releases, the unused variable will be ignored. Still resetting is a good practice.
|
||||||
|
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
@ -746,7 +810,7 @@ Extremely advanced options allow to:
|
|||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Activate the flow control for 10~Gb/s~E (by default the 1~Gb/s~E is always active and cannot be switched off:
|
\item Activate the flow control for 10~Gb/s~E (by default the 1~Gb/s~E is always active and cannot be switched off:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
./sls_detector_put flowcontrol_10g 1
|
./sls_detector_put flowcontrol_10g 1 (\textcolor{red}{flowcontrol10g})
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
\item Delay the transmission of the left port. This delay option is useful in the case of many simultaneous receivers running, such that it reduces the throughput to the receivers all at the same time. To be used board by board (i.e {\tt{X:, Y:,etc..}} with different units:
|
\item Delay the transmission of the left port. This delay option is useful in the case of many simultaneous receivers running, such that it reduces the throughput to the receivers all at the same time. To be used board by board (i.e {\tt{X:, Y:,etc..}} with different units:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@ -839,7 +903,7 @@ NOTE THAT THIS SETTINGS WILL BE LOST IF YOU REBOOT THE COMPUTER.
|
|||||||
|
|
||||||
Very important is to activate the flow control in 10Gb (in 1Gb it is on by default and not configurable)
|
Very important is to activate the flow control in 10Gb (in 1Gb it is on by default and not configurable)
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
./sls_detector_put flowcontrol_10g 1
|
./sls_detector_put flowcontrol_10g 1 (\textcolor{red}{flowcontrol10g 1})
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
You ned to check that flow control is setup on the reeceiving interfaces. Check with:
|
You ned to check that flow control is setup on the reeceiving interfaces. Check with:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@ -1128,10 +1192,10 @@ In 500k--2M pixel systems there is a hardware temperature safety switch, which w
|
|||||||
|
|
||||||
The HV can also be set and read through the software:
|
The HV can also be set and read through the software:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
./sls_detector_put vhighvoltage 150
|
./sls_detector_put vhighvoltage 150 (\textcolor{red}{highvoltage})
|
||||||
./sls_detector_get vhighvoltage
|
./sls_detector_get vhighvoltage (\textcolor{red}{highvoltage})
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
Note that the get {\tt{vhighvoltage}} would return the measured HV from the master module only. If getting the vhighvoltage for individual halfmodules, only the master will have a value different from -999.
|
Note that the get {\tt{vhighvoltage}}(\tt{\textcolor{red}{highvoltage}}) would return the measured HV from the master module only. If getting the highvoltage for individual halfmodules, only the master will have a value different from -999.
|
||||||
|
|
||||||
\appendix
|
\appendix
|
||||||
|
|
||||||
@ -1213,13 +1277,21 @@ do the same for the other boards. You can program in parallel many boards, but y
|
|||||||
There are two ways to pulse the detector:
|
There are two ways to pulse the detector:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \textbf{Pulse digitally:} when you are interested to the output readout and do not care about the analog response from the pixels:
|
\item \textbf{Pulse digitally:} when you are interested to the output readout and do not care about the analog response from the pixels:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
sls_detector_put vthreshold 4000
|
sls_detector_put vthreshold 4000
|
||||||
sls_detector_put vtr 4000
|
sls_detector_put vtr 4000
|
||||||
sls_detector_put pulsechip N #to pulse N
|
sls_detector_put pulsechip N #to pulse N
|
||||||
sls_detector_put pulsechip -1 #to get out of testing mode
|
sls_detector_put pulsechip -1 #to get out of testing mode
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
Note that the answer will be $2 \cdot \textrm{{\tt{N}}} +2$ in this case.
|
Note that the answer will be $2 \cdot \textrm{{\tt{N}}} +2$ in this case.
|
||||||
|
Or in \textcolor{red}{5.x}:
|
||||||
|
\begin{verbatim}
|
||||||
|
sls_detector_put vthreshold 4000
|
||||||
|
sls_detector_put vtrim 4000
|
||||||
|
sls_detector_put pulsechip N #to pulse N
|
||||||
|
sls_detector_put pulsechip -1 #to get out of testing mode
|
||||||
|
\end{verbatim}
|
||||||
|
Note that the answer will be $2 \cdot \textrm{{\tt{N}}} +4$ in this case.
|
||||||
|
|
||||||
\item \textbf{Pulse analogically:} You want to really check the analogical part of the detector, not just the readout.
|
\item \textbf{Pulse analogically:} You want to really check the analogical part of the detector, not just the readout.
|
||||||
|
|
||||||
@ -1238,8 +1310,25 @@ sls_detector_put resmat 0
|
|||||||
sls_detector_acquire
|
sls_detector_acquire
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
You read {\tt{N}} in every pixel if you are setup correctly.
|
You read {\tt{N}} in every pixel if you are setup correctly.
|
||||||
|
or in realese \textcolor{red}{5.x}:
|
||||||
|
\begin{verbatim}
|
||||||
|
sls_detector_put vcal 3600
|
||||||
|
sls_detector_put vthreshold 1700
|
||||||
|
sls_detector_put vrpreamp 3100
|
||||||
|
for i in $(seq 0 7) ;
|
||||||
|
do px=$((-255+i));
|
||||||
|
sls_detector_put pulse 0 $px 0;
|
||||||
|
for j in $(seq 0 255) ; do
|
||||||
|
sls_detector_put pulsenmove 100 0 1;
|
||||||
|
done;
|
||||||
|
done;
|
||||||
|
sls_detector_put partialreset 1
|
||||||
|
\end{verbatim}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\section{Load a noise pattern with shape}
|
\section{Load a noise pattern with shape}
|
||||||
For debug purposes, we have created a noise pattern with a shape. If you reconstruct correctly your image, you should be able to read ".EIGER'' in the same direction for both the top and bottom in normal human readable orientation.
|
For debug purposes, we have created a noise pattern with a shape. If you reconstruct correctly your image, you should be able to read ".EIGER'' in the same direction for both the top and bottom in normal human readable orientation.
|
||||||
To load the special noise file look at {\tt{settingsdir/eiger/standard/eigernoise.sn0xx}} in the package.
|
To load the special noise file look at {\tt{settingsdir/eiger/standard/eigernoise.sn0xx}} in the package.
|
||||||
@ -1262,10 +1351,10 @@ We have also been requested if we could speed up the threshold scan. At the mome
|
|||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
./sls_detector_put exptime 0.01
|
./sls_detector_put exptime 0.01
|
||||||
./sls_detector_put timing trigger
|
./sls_detector_put timing trigger
|
||||||
./sls_detector_put enablefwrite 0
|
./sls_detector_put enablefwrite 0 (\textcolor{red}{fwrite} 0)
|
||||||
./sls_detector_put resetframescaught 0
|
./sls_detector_put resetframescaught 0 (\textcolor{red}{not needed anymore})
|
||||||
./sls_detector_put index 0
|
./sls_detector_put index 0 (\textcolor{red}{findex} 0)
|
||||||
./sls_detector_put cycles 21
|
./sls_detector_put cycles 21 (\textcolor{red}{triggers} 21)
|
||||||
./sls_detector_put receiver start
|
./sls_detector_put receiver start
|
||||||
./sls_detector_put status start
|
./sls_detector_put status start
|
||||||
for i in $(seq 0 20);
|
for i in $(seq 0 20);
|
||||||
@ -1383,7 +1472,7 @@ Environment variable SLSDETNAME can be set for using 2 different detectors from
|
|||||||
\subsection{Measure the HV}
|
\subsection{Measure the HV}
|
||||||
For every system:
|
For every system:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Software-wise measure it (now the software returns the measured value), with {\tt{sls\_detector\_get vhighvoltage}}. The returned value is the HV (for proper Eiger setting is approximately 150~V) if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
|
\item Software-wise measure it (now the software returns the measured value), with {\tt{sls\_detector\_get highvoltage}}. The returned value is the HV (for proper Eiger setting is approximately 150~V) if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:highvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
|
||||||
\item Hardware-wise (opening the detector) measure value of HV on C14 on the power distribution board. Check also that the small HV connector cable is really connected.
|
\item Hardware-wise (opening the detector) measure value of HV on C14 on the power distribution board. Check also that the small HV connector cable is really connected.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
@ -1434,7 +1523,7 @@ Scroll up in the terminal till you find:\\
|
|||||||
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.
|
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}
|
\begin{verbatim}
|
||||||
for i in $(seq 0 36); do sls_detector_put $i:vhighvoltage; done
|
for i in $(seq 0 36); do sls_detector_put $i:highvoltage; done
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
Only the master will return to you a sensible number (150 normally). the others will return -999.
|
Only the master will return to you a sensible number (150 normally). the others will return -999.
|
||||||
|
|
||||||
@ -1595,10 +1684,10 @@ ratecorr number
|
|||||||
where {\tt{number}} is a string that should be interpreted as a float in s. 0.000000 means correction off. Values above zero are the value of $\tau$ in ns.
|
where {\tt{number}} is a string that should be interpreted as a float in s. 0.000000 means correction off. Values above zero are the value of $\tau$ in ns.
|
||||||
|
|
||||||
\item \begin{verbatim}
|
\item \begin{verbatim}
|
||||||
sls_detector_get vhighvoltage
|
sls_detector_get highvoltage
|
||||||
vhighvoltage number
|
highvoltage number
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
|
where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:highvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
|
||||||
|
|
||||||
\item \begin{verbatim}
|
\item \begin{verbatim}
|
||||||
sls_detector_get busy
|
sls_detector_get busy
|
||||||
|
@ -142,7 +142,7 @@
|
|||||||
"vpreamp"; // sets/get vpreamp value (advanced! Mythen)
|
"vpreamp"; // sets/get vpreamp value (advanced! Mythen)
|
||||||
"vshaper1"; // sets/get vshaper1 value (advanced! Mythen)
|
"vshaper1"; // sets/get vshaper1 value (advanced! Mythen)
|
||||||
"vshaper2"; // sets/get vshaper2 value (advanced! Mythen)
|
"vshaper2"; // sets/get vshaper2 value (advanced! Mythen)
|
||||||
"vhighvoltage"; // sets/get vhighvoltage value (advanced! Chiptest board and Eiger)
|
"highvoltage"; // sets/get highvoltage value (advanced! Chiptest board and Eiger)
|
||||||
"vapower"; // sets/get vapower value (advanced! Chiptest board)
|
"vapower"; // sets/get vapower value (advanced! Chiptest board)
|
||||||
"vddpower"; // sets/get vddpower value (advanced! Chiptest board)
|
"vddpower"; // sets/get vddpower value (advanced! Chiptest board)
|
||||||
"vshpower"; // sets/get vshpower value (advanced! Chiptest board)
|
"vshpower"; // sets/get vshpower value (advanced! Chiptest board)
|
||||||
|
@ -335,7 +335,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
|
|||||||
\item[vpreamp n] Sets the DAC value of the preamp feedback to n.
|
\item[vpreamp n] Sets the DAC value of the preamp feedback to n.
|
||||||
\item[vshaper1 n] Sets the DAC value of the shaper1 feedback to n.
|
\item[vshaper1 n] Sets the DAC value of the shaper1 feedback to n.
|
||||||
\item[vshaper2 n] Sets the DAC value of the shaper2 feedback to n.
|
\item[vshaper2 n] Sets the DAC value of the shaper2 feedback to n.
|
||||||
\item[vhighvoltage n] Sets the DAC value of the high voltage to n (in V).
|
\item[highvoltage n] Sets the DAC value of the high voltage to n (in V).
|
||||||
\item[vapower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
\item[vapower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
||||||
\item[vddpower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
\item[vddpower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
||||||
\item[vshpower n] CHIPTEST BOARD ONLY - Sets the comparator power supply in dac units (0-1024).
|
\item[vshpower n] CHIPTEST BOARD ONLY - Sets the comparator power supply in dac units (0-1024).
|
||||||
@ -648,7 +648,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
|
|||||||
\item[vpreamp] Returns the DAC value of the preamp feedback to n.
|
\item[vpreamp] Returns the DAC value of the preamp feedback to n.
|
||||||
\item[vshaper1] Returns the DAC value of the shaper1 feedback to n.
|
\item[vshaper1] Returns the DAC value of the shaper1 feedback to n.
|
||||||
\item[vshaper2] Returns the DAC value of the shaper2 feedback to n.
|
\item[vshaper2] Returns the DAC value of the shaper2 feedback to n.
|
||||||
\item[vhighvoltage] Returns the DAC value of the high voltage to n.
|
\item[highvoltage] Returns the DAC value of the high voltage to n.
|
||||||
\item[vapower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
\item[vapower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
||||||
\item[vddpower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
\item[vddpower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
||||||
\item[vshpower] CHIPTEST BOARD ONLY - Returns the comparator power supply in dac units (0-1024).
|
\item[vshpower] CHIPTEST BOARD ONLY - Returns the comparator power supply in dac units (0-1024).
|
||||||
@ -714,7 +714,7 @@ One can configure all the detector settings in a parameter file {\tt{setup.det}}
|
|||||||
sls_detector_put parameters setup.det
|
sls_detector_put parameters setup.det
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
In the case of \E, the parameter file ({\tt{setup.det}} needs to setup the proper bias voltage of the sensor, i.e. needs to contain the line {\tt{vhighvoltage 150}}.
|
In the case of \E, the parameter file ({\tt{setup.det}} needs to setup the proper bias voltage of the sensor, i.e. needs to contain the line {\tt{highvoltage 150}}.
|
||||||
|
|
||||||
\subsection{Standard acquisition}
|
\subsection{Standard acquisition}
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
|
|||||||
\item[vpreamp n] Sets the DAC value of the preamp feedback to n.
|
\item[vpreamp n] Sets the DAC value of the preamp feedback to n.
|
||||||
\item[vshaper1 n] Sets the DAC value of the shaper1 feedback to n.
|
\item[vshaper1 n] Sets the DAC value of the shaper1 feedback to n.
|
||||||
\item[vshaper2 n] Sets the DAC value of the shaper2 feedback to n.
|
\item[vshaper2 n] Sets the DAC value of the shaper2 feedback to n.
|
||||||
\item[vhighvoltage n] CHIPTEST BOARD ONLY - Sets the DAC value of the high voltage to n.
|
\item[highvoltage n] CHIPTEST BOARD ONLY - Sets the DAC value of the high voltage to n.
|
||||||
\item[vapower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
\item[vapower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
||||||
\item[vddpower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
\item[vddpower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
|
||||||
\item[vshpower n] CHIPTEST BOARD ONLY - Sets the comparator power supply in dac units (0-1024).
|
\item[vshpower n] CHIPTEST BOARD ONLY - Sets the comparator power supply in dac units (0-1024).
|
||||||
@ -594,7 +594,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
|
|||||||
\item[vpreamp] Returns the DAC value of the preamp feedback to n.
|
\item[vpreamp] Returns the DAC value of the preamp feedback to n.
|
||||||
\item[vshaper1] Returns the DAC value of the shaper1 feedback to n.
|
\item[vshaper1] Returns the DAC value of the shaper1 feedback to n.
|
||||||
\item[vshaper2] Returns the DAC value of the shaper2 feedback to n.
|
\item[vshaper2] Returns the DAC value of the shaper2 feedback to n.
|
||||||
\item[vhighvoltage] CHIPTEST BOARD ONLY - Returns the DAC value of the high voltage to n.
|
\item[highvoltage] CHIPTEST BOARD ONLY - Returns the DAC value of the high voltage to n.
|
||||||
\item[vapower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
\item[vapower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
||||||
\item[vddpower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
\item[vddpower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
|
||||||
\item[vshpower] CHIPTEST BOARD ONLY - Returns the comparator power supply in dac units (0-1024).
|
\item[vshpower] CHIPTEST BOARD ONLY - Returns the comparator power supply in dac units (0-1024).
|
||||||
|
@ -11,7 +11,8 @@ pybind11_add_module(_slsdet
|
|||||||
target_link_libraries(_slsdet PUBLIC
|
target_link_libraries(_slsdet PUBLIC
|
||||||
slsDetectorShared
|
slsDetectorShared
|
||||||
slsReceiverShared
|
slsReceiverShared
|
||||||
slsSupportLib
|
slsSupportShared
|
||||||
|
${ZeroMQ_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -29,11 +30,17 @@ set( PYTHON_FILES
|
|||||||
detector_property.py
|
detector_property.py
|
||||||
detector.py
|
detector.py
|
||||||
eiger.py
|
eiger.py
|
||||||
|
enums.py
|
||||||
errors.py
|
errors.py
|
||||||
|
gotthard.py
|
||||||
|
gotthard2.py
|
||||||
|
moench.py
|
||||||
|
proxy.py
|
||||||
ctb.py
|
ctb.py
|
||||||
jungfrau.py
|
jungfrau.py
|
||||||
mythen3.py
|
mythen3.py
|
||||||
registers.py
|
registers.py
|
||||||
|
temperature.py
|
||||||
lookup.py
|
lookup.py
|
||||||
utils.py
|
utils.py
|
||||||
|
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
import pytest
|
|
||||||
import datetime as dt
|
|
||||||
from slsdet import Detector, timingMode, detectorType
|
|
||||||
|
|
||||||
not_eiger = pytest.mark.skipif(
|
|
||||||
Detector().type == detectorType.EIGER, reason="Does not work for eiger"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def det():
|
|
||||||
from slsdet import Detector
|
|
||||||
|
|
||||||
return Detector()
|
|
||||||
|
|
||||||
|
|
||||||
def test_frames(det):
|
|
||||||
for n in [1, 100, 3245, 10000]:
|
|
||||||
det.frames = n
|
|
||||||
assert det.frames == n
|
|
||||||
det.frames = 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_triggers(det):
|
|
||||||
for n in [1, 100, 3245, 10000]:
|
|
||||||
det.triggers = n
|
|
||||||
assert det.triggers == n
|
|
||||||
det.triggers = 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_exptime(det):
|
|
||||||
det.exptime = 1
|
|
||||||
assert det.exptime == 1
|
|
||||||
det.exptime = dt.timedelta(milliseconds=10)
|
|
||||||
assert det.exptime == 0.01
|
|
||||||
det.exptime = 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_period(det):
|
|
||||||
det.period = 3.2
|
|
||||||
assert det.period == 3.2
|
|
||||||
|
|
||||||
p = dt.timedelta(microseconds=1020)
|
|
||||||
det.period = p
|
|
||||||
assert det.period == 0.001020
|
|
||||||
r = det.getPeriod()
|
|
||||||
assert r[0] == p
|
|
||||||
det.period = 0
|
|
||||||
assert det.period == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_lock(det):
|
|
||||||
for l in [True, False]:
|
|
||||||
det.lock = l
|
|
||||||
assert det.lock == l
|
|
||||||
|
|
||||||
|
|
||||||
def test_timing(det):
|
|
||||||
# auto and trigger is available for all det
|
|
||||||
for m in [timingMode.TRIGGER_EXPOSURE, timingMode.AUTO_TIMING]:
|
|
||||||
det.timing = m
|
|
||||||
assert det.timing == m
|
|
||||||
|
|
||||||
@not_eiger
|
|
||||||
def test_delay(det):
|
|
||||||
det.delay = 1
|
|
||||||
assert det.delay == 1
|
|
||||||
|
|
||||||
t = dt.timedelta(microseconds=1)
|
|
||||||
det.delay = t
|
|
||||||
assert det.delay == t.total_seconds()
|
|
||||||
|
|
||||||
r = det.getDelayAfterTrigger()[0]
|
|
||||||
assert r == t
|
|
||||||
|
|
||||||
det.delay = 0
|
|
||||||
assert det.delay == 0
|
|
||||||
|
|
||||||
|
|
||||||
@not_eiger
|
|
||||||
def test_delayl(det):
|
|
||||||
assert det.delayl == 0
|
|
@ -1,89 +0,0 @@
|
|||||||
import pytest
|
|
||||||
import datetime as dt
|
|
||||||
from slsdet import Detector, detectorType
|
|
||||||
|
|
||||||
"""
|
|
||||||
These tests are designed to work the API and catch
|
|
||||||
any changes in behavior or naming. Tests are expected
|
|
||||||
to pass with a virtual detector or a real one
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def jf():
|
|
||||||
from slsdet import Jungfrau
|
|
||||||
return Jungfrau()
|
|
||||||
|
|
||||||
|
|
||||||
jungfrautest = pytest.mark.skipif(
|
|
||||||
Detector().type != detectorType.JUNGFRAU, reason="Only valid for Jungfrau"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_storagecells(jf):
|
|
||||||
for i in range(16):
|
|
||||||
jf.storagecells = i
|
|
||||||
assert jf.storagecells == i
|
|
||||||
jf.storagecells = 0 # default
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_storagecell_start(jf):
|
|
||||||
for i in range(16):
|
|
||||||
jf.storagecell_start = i
|
|
||||||
assert jf.storagecell_start == i
|
|
||||||
jf.storagecells = 15 # default
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_storagecell_delay(jf):
|
|
||||||
for t in [0.001, 0.0002, 0.0013]:
|
|
||||||
jf.storagecell_delay = t
|
|
||||||
assert jf.storagecell_delay == t
|
|
||||||
jf.storagecell_delay = 0 # default
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_temp_event(jf):
|
|
||||||
# hard to test with virtual server
|
|
||||||
assert jf.temp_event == 0
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_temp_threshold(jf):
|
|
||||||
for th in [0, 10, 43, 72]:
|
|
||||||
jf.temp_threshold = th
|
|
||||||
assert jf.temp_threshold == th
|
|
||||||
jf.temp_threshold = 0
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_auto_comp_disable(jf):
|
|
||||||
for v in [True, False]:
|
|
||||||
jf.auto_comp_disable = v
|
|
||||||
assert jf.auto_comp_disable == v
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_numinterfaces(jf):
|
|
||||||
for n in [2, 1]:
|
|
||||||
jf.numinterfaces = n
|
|
||||||
assert jf.numinterfaces == n
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_dr(jf):
|
|
||||||
assert jf.dr == 16
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_temp_control(jf):
|
|
||||||
for v in [True, False]:
|
|
||||||
jf.temp_control = v
|
|
||||||
assert jf.temp_control == v
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_startingfnum(jf):
|
|
||||||
for n in [10, 127, 43321, 1]:
|
|
||||||
jf.startingfnum = n
|
|
||||||
assert jf.startingfnum == n
|
|
||||||
|
|
||||||
@jungfrautest
|
|
||||||
def test_selinterface(jf):
|
|
||||||
for i in [1, 0]:
|
|
||||||
jf.selinterface = i
|
|
||||||
assert jf.selinterface == i
|
|
42
python/examples/exposure_time.py
Normal file
42
python/examples/exposure_time.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
"""
|
||||||
|
Example showing how to set and get exposure times
|
||||||
|
"""
|
||||||
|
|
||||||
|
import datetime as dt
|
||||||
|
from slsdet import Detector
|
||||||
|
from slsdet.utils import element_if_equal
|
||||||
|
|
||||||
|
d = Detector()
|
||||||
|
|
||||||
|
# The simplest way is to set the exposure time in
|
||||||
|
# seconds by using the exptime property
|
||||||
|
# This sets the exposure time for all modules
|
||||||
|
d.exptime = 0.5
|
||||||
|
|
||||||
|
# exptime also accepts a python datetime.timedelta
|
||||||
|
# which can be used to set the time in almost any unit
|
||||||
|
t = dt.timedelta(milliseconds = 2.3)
|
||||||
|
d.exptime = t
|
||||||
|
|
||||||
|
# or combination of units
|
||||||
|
t = dt.timedelta(minutes = 3, seconds = 1.23)
|
||||||
|
d.exptime = t
|
||||||
|
|
||||||
|
#exptime however always returns the time in seconds
|
||||||
|
# >>> d.exptime
|
||||||
|
# 181.23
|
||||||
|
|
||||||
|
# To get back the exposure time for each module
|
||||||
|
# it's possible to use getExptime, this also returns
|
||||||
|
# the values as datetime.timedelta
|
||||||
|
|
||||||
|
# >>> d.getExptime()
|
||||||
|
# [datetime.timedelta(seconds=181, microseconds=230000), datetime.timedelta(seconds=181, microseconds=230000)]
|
||||||
|
|
||||||
|
# In case the values are the same it's possible to use the
|
||||||
|
# element_if_equal function to reduce the values to a single
|
||||||
|
# value
|
||||||
|
|
||||||
|
# >>> t = d.getExptime()
|
||||||
|
# >>> element_if_equal(t)
|
||||||
|
# datetime.timedelta(seconds=1)
|
21
python/examples/non-blocking-acquire-process.py
Normal file
21
python/examples/non-blocking-acquire-process.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import time
|
||||||
|
from multiprocessing import Process
|
||||||
|
from slsdet import Detector, runStatus
|
||||||
|
|
||||||
|
|
||||||
|
d = Detector()
|
||||||
|
|
||||||
|
#Create a separate process to run acquire in
|
||||||
|
p = Process(target=d.acquire)
|
||||||
|
|
||||||
|
#Start the thread and short sleep to allow the acq to start
|
||||||
|
p.start()
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
#Do some other work
|
||||||
|
while d.status != runStatus.IDLE:
|
||||||
|
print("Working")
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
#Join the process
|
||||||
|
p.join()
|
33
python/examples/non-blocking-acquire.py
Normal file
33
python/examples/non-blocking-acquire.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import time
|
||||||
|
from slsdet import Detector, runStatus
|
||||||
|
|
||||||
|
|
||||||
|
n_frames = 10
|
||||||
|
t_exp = 1
|
||||||
|
|
||||||
|
# Set exposure time and number of frames
|
||||||
|
d = Detector()
|
||||||
|
d.exptime = t_exp
|
||||||
|
d.frames = n_frames
|
||||||
|
|
||||||
|
# Start the measurement
|
||||||
|
t0 = time.time()
|
||||||
|
d.startDetector()
|
||||||
|
d.startReceiver()
|
||||||
|
|
||||||
|
# Wait for the detector to be ready or do other important stuff
|
||||||
|
time.sleep(t_exp * n_frames)
|
||||||
|
|
||||||
|
# check if the detector is ready otherwise wait a bit longer
|
||||||
|
while d.status != runStatus.IDLE:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# Stop the receiver after we got the frames
|
||||||
|
# Detector is already idle so we don't need to stop it
|
||||||
|
d.stopReceiver()
|
||||||
|
|
||||||
|
lost = d.rx_framescaught - n_frames
|
||||||
|
print(
|
||||||
|
f"{n_frames} frames of {t_exp}s took {time.time()-t0:{.3}}s with {lost} frames lost "
|
||||||
|
)
|
||||||
|
|
32
python/examples/reading_dacs.py
Normal file
32
python/examples/reading_dacs.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from slsdet import Detector, Eiger, dacIndex
|
||||||
|
|
||||||
|
|
||||||
|
#using the specialized class
|
||||||
|
|
||||||
|
e = Eiger()
|
||||||
|
e.dacs
|
||||||
|
# >>> e.dacs
|
||||||
|
# ========== DACS =========
|
||||||
|
# vsvp : 0 0
|
||||||
|
# vtrim : 2480 2480
|
||||||
|
# vrpreamp : 3300 3300
|
||||||
|
# vrshaper : 1400 1400
|
||||||
|
# vsvn : 4000 4000
|
||||||
|
# vtgstv : 2556 2556
|
||||||
|
# vcmp_ll : 1000 1000
|
||||||
|
# vcmp_lr : 1000 1000
|
||||||
|
# vcal : 0 0
|
||||||
|
# vcmp_rl : 1000 1000
|
||||||
|
# rxb_rb : 1100 1100
|
||||||
|
# rxb_lb : 1100 1100
|
||||||
|
# vcmp_rr : 1000 1000
|
||||||
|
# vcp : 1000 1000
|
||||||
|
# vcn : 2000 2000
|
||||||
|
# vishaper : 1550 1550
|
||||||
|
# iodelay : 650 650
|
||||||
|
|
||||||
|
# or using the general class and the list
|
||||||
|
d = Detector()
|
||||||
|
for dac in d.daclist:
|
||||||
|
r = d.getDAC(dac, False)
|
||||||
|
print(f'{dac.name:10s} {r}')
|
45
python/examples/reading_temperature.py
Normal file
45
python/examples/reading_temperature.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from slsdet import Detector, Eiger, dacIndex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Using the general detector class and calling with an index
|
||||||
|
d = Detector()
|
||||||
|
fpga_temp = d.getTemperature(dacIndex.TEMPERATURE_FPGA)
|
||||||
|
print(f'fpga_temp: {fpga_temp}\n')
|
||||||
|
|
||||||
|
#Using the specialized detector class
|
||||||
|
e = Eiger()
|
||||||
|
print("All temperatures for Eiger\n")
|
||||||
|
print(e.temp)
|
||||||
|
# >>> e.temp
|
||||||
|
# temp_fpga : 54°C 60°C
|
||||||
|
# temp_fpgaext : 49°C 52°C
|
||||||
|
# temp_10ge : 47°C 45°C
|
||||||
|
# temp_dcdc : 52°C 53°C
|
||||||
|
# temp_sodl : 51°C 53°C
|
||||||
|
# temp_sodl : 51°C 51°C
|
||||||
|
# temp_fpgafl : 45°C 49°C
|
||||||
|
# temp_fpgafr : 39°C 42°C
|
||||||
|
|
||||||
|
# The temperatures can also be returned in a dictionary
|
||||||
|
t = e.temp.to_dict()
|
||||||
|
print(t)
|
||||||
|
# >>> e.temp.to_dict()
|
||||||
|
# {'fpga': array([55, 60]), 'fpgaext': array([49, 52]),
|
||||||
|
# 't10ge': array([47, 45]), 'dcdc': array([52, 53]),
|
||||||
|
# 'sodl': array([51, 53]), 'sodr': array([51, 51]), '
|
||||||
|
# temp_fpgafl': array([45, 49]),
|
||||||
|
# 'temp_fpgafr': array([39, 42])}
|
||||||
|
|
||||||
|
# or in a numpy array
|
||||||
|
t = e.temp.to_array()
|
||||||
|
print(t)
|
||||||
|
# >>> e.temp.to_array()
|
||||||
|
# array([[55, 60],
|
||||||
|
# [49, 52],
|
||||||
|
# [47, 45],
|
||||||
|
# [52, 53],
|
||||||
|
# [51, 53],
|
||||||
|
# [51, 51],
|
||||||
|
# [45, 49],
|
||||||
|
# [40, 43]])
|
8
python/examples/threshold_scan.py
Normal file
8
python/examples/threshold_scan.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from slsdet import Eiger
|
||||||
|
|
||||||
|
d = Eiger()
|
||||||
|
threshold = range(0, 2000, 200)
|
||||||
|
for th in threshold:
|
||||||
|
print(f'{th=}')
|
||||||
|
d.vthreshold = th
|
||||||
|
d.acquire()
|
20
python/examples/use_enum.py
Normal file
20
python/examples/use_enum.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Most settings are represented as enums that can be
|
||||||
|
# explicitly imported
|
||||||
|
|
||||||
|
from slsdet import Detector, fileFormat
|
||||||
|
d = Detector()
|
||||||
|
d.fformat = fileFormat.BINARY
|
||||||
|
|
||||||
|
# Altough not recommended for convenience all enums
|
||||||
|
# and some other things can be impored using *
|
||||||
|
|
||||||
|
from slsdet import *
|
||||||
|
d.speed = speedLevel.FULL_SPEED
|
||||||
|
|
||||||
|
# To list the available enums, use dir()
|
||||||
|
|
||||||
|
import slsdet.enums
|
||||||
|
for enum in dir(slsdet.enums):
|
||||||
|
# filter out special memebers
|
||||||
|
if not enum.startswith('_'):
|
||||||
|
print(enum)
|
@ -1,15 +1,20 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from pathlib import Path
|
||||||
sys.path.append(os.path.join(os.getcwd(), 'bin'))
|
sys.path.append(os.path.join(os.getcwd(), 'bin'))
|
||||||
|
|
||||||
from slsdet import Detector, Mythen3, Eiger, Jungfrau, DetectorDacs, Dac, Ctb
|
from slsdet import Detector, Mythen3, Eiger, Jungfrau, DetectorDacs, Dac, Ctb, Gotthard2, Moench
|
||||||
from slsdet import dacIndex, readoutMode
|
from slsdet import dacIndex, readoutMode
|
||||||
from slsdet.lookup import view, find
|
from slsdet.lookup import view, find
|
||||||
|
import slsdet
|
||||||
|
|
||||||
|
|
||||||
d = Detector()
|
d = Detector()
|
||||||
# e = Eiger()
|
e = Eiger()
|
||||||
c = Ctb()
|
c = Ctb()
|
||||||
|
g = Gotthard2()
|
||||||
# j = Jungfrau()
|
# j = Jungfrau()
|
||||||
# m = Mythen3()
|
# m = Mythen3()
|
||||||
|
m = Moench()
|
||||||
|
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
import locale
|
|
||||||
out = subprocess.run(['g', 'list'], stdout = subprocess.PIPE, encoding=locale.getpreferredencoding())
|
|
||||||
cmd = out.stdout.splitlines()
|
|
||||||
cmd.pop(0)
|
|
||||||
|
|
||||||
from slsdet import Detector, Eiger, Ctb
|
|
||||||
|
|
||||||
pycmd = dir(Detector)+dir(Eiger)+dir(Ctb)
|
|
||||||
|
|
||||||
#Add commands that we should not expect as direct commands in python
|
|
||||||
pycmd += ['vrf', 'vtr', 'vrs', 'vtgstv', 'vsvn', 'vtrim',
|
|
||||||
'vsvp', 'vth1', 'vth2', 'vth3', 'vshaper', 'vshaperneg', 'rxb_rb',
|
|
||||||
'rxb_lb', 'vref_prech', 'vref_rstore', 'vref_cds',
|
|
||||||
'vpreamp', 'vref_comp', 'vref_comp_fe vref_ds', 'vref_h_adc',
|
|
||||||
'vref_l_adc', 'iodelay', 'list', 'vref_ds', 'vis', 'vpl',
|
|
||||||
'vref_comp_fe', 'vph', 'vout_cm', 'vcp', 'vcn', 'vcmp_ll', 'vcmp_lr'
|
|
||||||
, 'vcmp_rl', 'vcmp_rr', 'daclist', 'dacvalues', 'vcal', 'vcas']
|
|
||||||
|
|
||||||
missing = []
|
|
||||||
for c in cmd:
|
|
||||||
if c not in pycmd:
|
|
||||||
print(c)
|
|
||||||
missing.append(c)
|
|
||||||
|
|
||||||
print(f'Missing: {len(missing)} commands')
|
|
143
python/scripts/compare_with_commandline.py
Normal file
143
python/scripts/compare_with_commandline.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import subprocess
|
||||||
|
import locale
|
||||||
|
out = subprocess.run(['g', 'list'], stdout = subprocess.PIPE, encoding=locale.getpreferredencoding())
|
||||||
|
cmd = out.stdout.splitlines()
|
||||||
|
cmd.pop(0)
|
||||||
|
|
||||||
|
from slsdet import Detector
|
||||||
|
|
||||||
|
pycmd = dir(Detector)
|
||||||
|
|
||||||
|
|
||||||
|
# dacs are in general not included in the python commands and we expect to
|
||||||
|
# set them from the specialized class or using an enum
|
||||||
|
dacs = [
|
||||||
|
'adcvpp',
|
||||||
|
'iodelay',
|
||||||
|
'list',
|
||||||
|
'rxb_lb',
|
||||||
|
'rxb_rb',
|
||||||
|
'v_chip',
|
||||||
|
'vb_comp',
|
||||||
|
'vb_comp_adc',
|
||||||
|
'vb_comp_fe',
|
||||||
|
'vb_cs',
|
||||||
|
'vb_ds',
|
||||||
|
'vb_opa_1st',
|
||||||
|
'vb_opa_fd',
|
||||||
|
'vb_pixbuf',
|
||||||
|
'vb_sda',
|
||||||
|
'vbp_colbuf',
|
||||||
|
'vcal',
|
||||||
|
'vcal_n',
|
||||||
|
'vcal_p',
|
||||||
|
'vipre_out',
|
||||||
|
'vcas',
|
||||||
|
'vcasc_out',
|
||||||
|
'vcasc_sfp',
|
||||||
|
'vcascn_pb',
|
||||||
|
'vcascp_pb',
|
||||||
|
'vcassh',
|
||||||
|
'vchip_comp_adc',
|
||||||
|
'vchip_comp_fe',
|
||||||
|
'vchip_cs',
|
||||||
|
'vchip_opa_1st',
|
||||||
|
'vchip_opa_fd',
|
||||||
|
'vchip_ref_comp_fe',
|
||||||
|
'vcmp_ll',
|
||||||
|
'vcmp_lr',
|
||||||
|
'vcmp_rl',
|
||||||
|
'vcmp_rr',
|
||||||
|
'vcn',
|
||||||
|
'vcom_adc1',
|
||||||
|
'vcom_adc2',
|
||||||
|
'vcom_cds',
|
||||||
|
'vcp',
|
||||||
|
'vdcsh',
|
||||||
|
'vdd_prot',
|
||||||
|
'vicin',
|
||||||
|
'vin_cm',
|
||||||
|
'vin_com',
|
||||||
|
'vipre',
|
||||||
|
'vipre_cds',
|
||||||
|
'vipre_out',
|
||||||
|
'vishaper',
|
||||||
|
'vout_cm',
|
||||||
|
'vref_cds',
|
||||||
|
'vref_comp',
|
||||||
|
'vref_comp_fe',
|
||||||
|
'vref_ds',
|
||||||
|
'vref_h_adc',
|
||||||
|
'vref_l_adc',
|
||||||
|
'vref_prech',
|
||||||
|
'vref_rstore',
|
||||||
|
'vrpreamp',
|
||||||
|
'vrshaper',
|
||||||
|
'vrshaper_n',
|
||||||
|
'vsvn',
|
||||||
|
'vsvp',
|
||||||
|
'vtgstv',
|
||||||
|
'vth1',
|
||||||
|
'vth2',
|
||||||
|
'vth3',
|
||||||
|
'vtrim',
|
||||||
|
'ib_test_c',
|
||||||
|
'ibias_sfp',
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
intentionally_missing = [
|
||||||
|
'activate', #use getActive and getRxPadDeactivatedMode syntax is not a good fit for python
|
||||||
|
'temp_10ge', #temperatures already available from enum or specialized class
|
||||||
|
'temp_adc',
|
||||||
|
'temp_dcdc',
|
||||||
|
'temp_fpga',
|
||||||
|
'temp_fpgaext',
|
||||||
|
'temp_fpgafl',
|
||||||
|
'temp_fpgafr',
|
||||||
|
'temp_slowadc',
|
||||||
|
'temp_sodl',
|
||||||
|
'temp_sodr',
|
||||||
|
'trigger', #use sendSoftwareTrigger
|
||||||
|
'update', #use updateServerAndFirmare
|
||||||
|
'udp_validate', #use validateUdpConfiguration
|
||||||
|
'udp_reconfigure', #use reconfigureUdpDestination
|
||||||
|
'pulse', # use pulseChip pulsePixel pulsePixelNmove
|
||||||
|
'pulsechip',
|
||||||
|
'pulsenmove',
|
||||||
|
'savepattern', #use savePattern()
|
||||||
|
'resetfpga', #use resetFPGA()
|
||||||
|
'rebootcontroller', #use rebootController()
|
||||||
|
'firmwaretest', #use executeFirmwareTest
|
||||||
|
'bustest', # executeBusTest
|
||||||
|
'programfpga', #programFPGA
|
||||||
|
'dac', #use setDAC or detector specific class
|
||||||
|
'clearroi', #clearROI
|
||||||
|
]
|
||||||
|
|
||||||
|
pycmd += intentionally_missing
|
||||||
|
pycmd += dacs
|
||||||
|
missing = []
|
||||||
|
for c in cmd:
|
||||||
|
if c not in pycmd:
|
||||||
|
print(c)
|
||||||
|
missing.append(c)
|
||||||
|
|
||||||
|
print(f'\nMissing: {len(missing)} commands')
|
||||||
|
print(f'Excluded: {len(dacs)} dacs')
|
||||||
|
print(f'Excluded: {len(intentionally_missing)} other commands')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
not_in_cmd = []
|
||||||
|
for c in pycmd:
|
||||||
|
if c.islower() and not c.startswith('_'):
|
||||||
|
if c not in cmd:
|
||||||
|
not_in_cmd.append(c)
|
||||||
|
print(f'\nCommands in Python and NOT in command line: {len(not_in_cmd)}')
|
||||||
|
for c in not_in_cmd:
|
||||||
|
print(c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# print(',\n'.join([f'\'{d}\'' for d in sorted(dacs)]))
|
@ -42,6 +42,7 @@ def extract_enums(lines):
|
|||||||
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
fields = [f.strip() for f in fields]
|
||||||
enums[enum_name] = fields
|
enums[enum_name] = fields
|
||||||
return enums
|
return enums
|
||||||
|
|
||||||
|
@ -60,6 +60,23 @@ def get_arguments(node):
|
|||||||
args = f", {args}"
|
args = f", {args}"
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
def get_arguments_with_default(node):
|
||||||
|
args = []
|
||||||
|
for arg in node.get_arguments():
|
||||||
|
tokens = [t.spelling for t in arg.get_tokens()]
|
||||||
|
print(tokens)
|
||||||
|
if '=' in tokens:
|
||||||
|
if arg.type.spelling == "sls::Positions": #TODO! automate
|
||||||
|
args.append("py::arg() = Positions{}")
|
||||||
|
else:
|
||||||
|
args.append('py::arg()' + ''.join(tokens[tokens.index('='):]))
|
||||||
|
else:
|
||||||
|
args.append('py::arg()')
|
||||||
|
args = ", ".join(args)
|
||||||
|
if args:
|
||||||
|
args = f", {args}"
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
def get_fdec(node):
|
def get_fdec(node):
|
||||||
args = [a.type.spelling for a in node.get_arguments()]
|
args = [a.type.spelling for a in node.get_arguments()]
|
||||||
@ -86,7 +103,8 @@ def visit(node):
|
|||||||
and child.access_specifier == cindex.AccessSpecifier.PUBLIC
|
and child.access_specifier == cindex.AccessSpecifier.PUBLIC
|
||||||
):
|
):
|
||||||
m.append(child)
|
m.append(child)
|
||||||
args = get_arguments(child)
|
# args = get_arguments(child)
|
||||||
|
args = get_arguments_with_default(child)
|
||||||
fs = get_fdec(child)
|
fs = get_fdec(child)
|
||||||
lines.append(
|
lines.append(
|
||||||
f'.def("{child.spelling}",{fs} &Detector::{child.spelling}{args})'
|
f'.def("{child.spelling}",{fs} &Detector::{child.spelling}{args})'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Setup file for sls_detector
|
Setup file for slsdet
|
||||||
Build upon the pybind11 example found here: https://github.com/pybind/python_example
|
Build upon the pybind11 example found here: https://github.com/pybind/python_example
|
||||||
"""
|
"""
|
||||||
from setuptools import setup, Extension, find_packages
|
from setuptools import setup, Extension, find_packages
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
#!/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'
|
|
@ -1,27 +0,0 @@
|
|||||||
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')
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,33 +0,0 @@
|
|||||||
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
|
|
@ -1,2 +0,0 @@
|
|||||||
vrf 3000
|
|
||||||
vthreshold 1800
|
|
@ -1,44 +0,0 @@
|
|||||||
#!/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'
|
|
@ -1,119 +0,0 @@
|
|||||||
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...
|
|
@ -1,129 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,187 +0,0 @@
|
|||||||
#!/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'
|
|
||||||
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
|
|
||||||
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
|
|
@ -1,81 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,54 +0,0 @@
|
|||||||
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
|
|
@ -1,47 +0,0 @@
|
|||||||
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]
|
|
@ -1,136 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,34 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,16 +0,0 @@
|
|||||||
#!/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
|
|
||||||
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
#!/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__))
|
|
@ -1,17 +0,0 @@
|
|||||||
#!/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'
|
|
@ -1,23 +0,0 @@
|
|||||||
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')
|
|
@ -1,17 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,21 +0,0 @@
|
|||||||
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
|
|
@ -1 +0,0 @@
|
|||||||
vhighvoltage 200
|
|
@ -1,43 +0,0 @@
|
|||||||
|
|
||||||
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')
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
|||||||
|
|
||||||
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')
|
|
@ -5,19 +5,16 @@ from .dacs import DetectorDacs, Dac
|
|||||||
from .detector import Detector
|
from .detector import Detector
|
||||||
from .jungfrau import Jungfrau
|
from .jungfrau import Jungfrau
|
||||||
from .mythen3 import Mythen3
|
from .mythen3 import Mythen3
|
||||||
# from .jungfrau_ctb import JungfrauCTB
|
from .gotthard2 import Gotthard2
|
||||||
# from _slsdet import DetectorApi
|
from .gotthard import Gotthard
|
||||||
|
from .moench import Moench
|
||||||
|
|
||||||
import _slsdet
|
import _slsdet
|
||||||
|
xy = _slsdet.xy
|
||||||
defs = _slsdet.slsDetectorDefs
|
defs = _slsdet.slsDetectorDefs
|
||||||
runStatus = _slsdet.slsDetectorDefs.runStatus
|
|
||||||
speedLevel = _slsdet.slsDetectorDefs.speedLevel
|
from .enums import *
|
||||||
timingMode = _slsdet.slsDetectorDefs.timingMode
|
|
||||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
|
||||||
detectorType = _slsdet.slsDetectorDefs.detectorType
|
|
||||||
detectorSettings = _slsdet.slsDetectorDefs.detectorSettings
|
|
||||||
readoutMode = _slsdet.slsDetectorDefs.readoutMode
|
|
||||||
|
|
||||||
IpAddr = _slsdet.IpAddr
|
IpAddr = _slsdet.IpAddr
|
||||||
MacAddr = _slsdet.MacAddr
|
MacAddr = _slsdet.MacAddr
|
||||||
|
@ -1,23 +1,33 @@
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
class Adc:
|
class Adc:
|
||||||
def __init__(self, name, detector):
|
def __init__(self, name, enum, detector):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.enum = enum
|
||||||
self._detector = detector
|
self._detector = detector
|
||||||
self.get_nmod = self._detector._api.getNumberOfDetectors
|
self.get_nmod = self._detector.size
|
||||||
# Bind functions to get and set the dac
|
# Bind functions to get and set the dac
|
||||||
self.get = partial(self._detector._api.getAdc, self.name)
|
self.get = partial(self._detector.getAdc, self.enum)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""
|
|
||||||
Get dacs either by slice, key or list
|
|
||||||
"""
|
|
||||||
if key == slice(None, None, None):
|
if key == slice(None, None, None):
|
||||||
return [self.get(i) / 1000 for i in range(self.get_nmod())]
|
return self.get()
|
||||||
elif isinstance(key, Iterable):
|
elif isinstance(key, Iterable):
|
||||||
return [self.get(k) / 1000 for k in key]
|
return self.get(list(key))
|
||||||
else:
|
else:
|
||||||
return self.get(key) / 1000
|
return self.get([key])[0] #No list for single value
|
||||||
|
|
||||||
|
|
||||||
|
# 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):
|
def __repr__(self):
|
||||||
"""String representation for a single adc in all modules"""
|
"""String representation for a single adc in all modules"""
|
||||||
|
@ -32,10 +32,9 @@ class Dac(DetectorProperty):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""String representation for a single dac in all modules"""
|
"""String representation for a single dac in all modules"""
|
||||||
dacstr = ''.join([f'{item:5d}' for item in self.get()])
|
dacstr = ''.join([f'{item:5d}' for item in self.get()])
|
||||||
return f'{self.__name__:10s}:{dacstr}'
|
return f'{self.__name__:15s}:{dacstr}'
|
||||||
|
|
||||||
|
|
||||||
# a = Dac('vrf', dacIndex.VRF, 0, 4000, 2500, d )
|
|
||||||
# @freeze
|
|
||||||
class DetectorDacs:
|
class DetectorDacs:
|
||||||
_dacs = []
|
_dacs = []
|
||||||
_dacnames = [_d[0] for _d in _dacs]
|
_dacnames = [_d[0] for _d in _dacs]
|
||||||
@ -93,6 +92,9 @@ class DetectorDacs:
|
|||||||
dac_array[i,:] = _d[:]
|
dac_array[i,:] = _d[:]
|
||||||
return dac_array
|
return dac_array
|
||||||
|
|
||||||
|
def to_array(self):
|
||||||
|
return self.get_asarray()
|
||||||
|
|
||||||
def set_from_array(self, dac_array):
|
def set_from_array(self, dac_array):
|
||||||
"""
|
"""
|
||||||
Set the dacs from an numpy array with dac values. [ndacs, nmodules]
|
Set the dacs from an numpy array with dac values. [ndacs, nmodules]
|
||||||
@ -101,6 +103,9 @@ class DetectorDacs:
|
|||||||
for i, _d in enumerate(self):
|
for i, _d in enumerate(self):
|
||||||
_d[:] = dac_array[i]
|
_d[:] = dac_array[i]
|
||||||
|
|
||||||
|
def from_array(self, dac_array):
|
||||||
|
self.set_from_array(dac_array)
|
||||||
|
|
||||||
def set_default(self):
|
def set_default(self):
|
||||||
"""
|
"""
|
||||||
Set all dacs to their default values
|
Set all dacs to their default values
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,22 +6,17 @@ Created on Wed Dec 6 11:51:18 2017
|
|||||||
@author: l_frojdh
|
@author: l_frojdh
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from .detector import Detector
|
from .detector import Detector
|
||||||
|
from .temperature import Temperature, DetectorTemperature
|
||||||
# from .adcs import Adc, DetectorAdcs
|
|
||||||
from .dacs import DetectorDacs
|
from .dacs import DetectorDacs
|
||||||
import _slsdet
|
import _slsdet
|
||||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||||
from .detector_property import DetectorProperty
|
from .detector_property import DetectorProperty
|
||||||
# from .utils import element_if_equal
|
|
||||||
# from sls_detector.errors import DetectorValueError, DetectorError
|
|
||||||
|
|
||||||
class EigerVcmp:
|
class EigerVcmp:
|
||||||
"""
|
"""
|
||||||
Convenience class to be able to loop over vcmp for Eiger
|
Convenience class to be able to loop over vcmp for Eiger
|
||||||
|
|
||||||
|
|
||||||
.. todo::
|
.. todo::
|
||||||
|
|
||||||
Support single assignment and perhaps unify with Dac class
|
Support single assignment and perhaps unify with Dac class
|
||||||
@ -60,77 +55,25 @@ class EigerDacs(DetectorDacs):
|
|||||||
"""
|
"""
|
||||||
Eiger specific dacs
|
Eiger specific dacs
|
||||||
"""
|
"""
|
||||||
_dacs = [('vsvp', dacIndex.SVP,0, 4000, 0),
|
_dacs = [('vsvp', dacIndex.VSVP,0, 4000, 0),
|
||||||
('vtr', dacIndex.VTR,0, 4000, 2500),
|
('vtrim', dacIndex.VTRIM,0, 4000, 2500),
|
||||||
('vrf', dacIndex.VRF,0, 4000, 3300),
|
('vrpreamp', dacIndex.VRPREAMP,0, 4000, 3300),
|
||||||
('vrs', dacIndex.VRS,0, 4000, 1400),
|
('vrshaper', dacIndex.VRSHAPER,0, 4000, 1400),
|
||||||
('vsvn', dacIndex.SVN,0, 4000, 4000),
|
('vsvn', dacIndex.VSVN,0, 4000, 4000),
|
||||||
('vtgstv', dacIndex.VTGSTV,0, 4000, 2556),
|
('vtgstv', dacIndex.VTGSTV,0, 4000, 2556),
|
||||||
('vcmp_ll', dacIndex.VCMP_LL,0, 4000, 1500),
|
('vcmp_ll', dacIndex.VCMP_LL,0, 4000, 1500),
|
||||||
('vcmp_lr', dacIndex.VCMP_LR,0, 4000, 1500),
|
('vcmp_lr', dacIndex.VCMP_LR,0, 4000, 1500),
|
||||||
('vcall', dacIndex.CAL,0, 4000, 4000),
|
('vcal', dacIndex.VCAL,0, 4000, 4000),
|
||||||
('vcmp_rl', dacIndex.VCMP_RL,0, 4000, 1500),
|
('vcmp_rl', dacIndex.VCMP_RL,0, 4000, 1500),
|
||||||
('rxb_rb', dacIndex.RXB_RB,0, 4000, 1100),
|
('rxb_rb', dacIndex.RXB_RB,0, 4000, 1100),
|
||||||
('rxb_lb', dacIndex.RXB_LB,0, 4000, 1100),
|
('rxb_lb', dacIndex.RXB_LB,0, 4000, 1100),
|
||||||
('vcmp_rr', dacIndex.VCMP_RR,0, 4000, 1500),
|
('vcmp_rr', dacIndex.VCMP_RR,0, 4000, 1500),
|
||||||
('vcp', dacIndex.VCP,0, 4000, 200),
|
('vcp', dacIndex.VCP,0, 4000, 200),
|
||||||
('vcn', dacIndex.VCN,0, 4000, 2000),
|
('vcn', dacIndex.VCN,0, 4000, 2000),
|
||||||
('vis', dacIndex.VIS,0, 4000, 1550),
|
('vishaper', dacIndex.VISHAPER,0, 4000, 1550),
|
||||||
('iodelay', dacIndex.IO_DELAY,0, 4000, 660)]
|
('iodelay', dacIndex.IO_DELAY,0, 4000, 660)]
|
||||||
_dacnames = [_d[0] for _d in _dacs]
|
_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)
|
|
||||||
|
|
||||||
from .detector import freeze
|
from .detector import freeze
|
||||||
|
|
||||||
@ -152,76 +95,18 @@ class Eiger(Detector):
|
|||||||
self._dacs = EigerDacs(self)
|
self._dacs = EigerDacs(self)
|
||||||
self._vcmp = EigerVcmp(self)
|
self._vcmp = EigerVcmp(self)
|
||||||
|
|
||||||
# self._active = DetectorProperty(self.getActive,
|
# Eiger specific adcs
|
||||||
# self.setActive,
|
self._temp = DetectorTemperature()
|
||||||
# self.size,
|
self._temp.fpga = Temperature('temp_fpga', dacIndex.TEMPERATURE_FPGA, self)
|
||||||
# 'active')
|
self._temp.fpgaext = Temperature('temp_fpgaext', dacIndex.TEMPERATURE_FPGAEXT, self)
|
||||||
|
self._temp.t10ge = Temperature('temp_10ge', dacIndex.TEMPERATURE_10GE, self)
|
||||||
|
self._temp.dcdc = Temperature('temp_dcdc', dacIndex.TEMPERATURE_DCDC, self)
|
||||||
|
self._temp.sodl = Temperature('temp_sodl', dacIndex.TEMPERATURE_SODL, self)
|
||||||
|
self._temp.sodr = Temperature('temp_sodl', dacIndex.TEMPERATURE_SODR, self)
|
||||||
|
self._temp.temp_fpgafl = Temperature('temp_fpgafl', dacIndex.TEMPERATURE_FPGA2, self)
|
||||||
|
self._temp.temp_fpgafr = Temperature('temp_fpgafr', dacIndex.TEMPERATURE_FPGA3, 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
|
|
||||||
# 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
|
|
||||||
# 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
|
|
||||||
# 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
|
|
||||||
# def add_gappixels(self, value):
|
|
||||||
# self._api.setGapPixels(value)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dacs(self):
|
def dacs(self):
|
||||||
@ -284,68 +169,6 @@ class Eiger(Detector):
|
|||||||
"""
|
"""
|
||||||
return self._dacs
|
return self._dacs
|
||||||
|
|
||||||
# @property
|
|
||||||
# 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 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)
|
|
||||||
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
|
|
||||||
# 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
|
@property
|
||||||
def vcmp(self):
|
def vcmp(self):
|
||||||
@ -437,40 +260,33 @@ class Eiger(Detector):
|
|||||||
# else:
|
# else:
|
||||||
# self._api.setReceiverStreamingPort(port, -1)
|
# self._api.setReceiverStreamingPort(port, -1)
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def temp(self):
|
def temp(self):
|
||||||
# """
|
"""
|
||||||
# An instance of DetectorAdcs used to read the temperature
|
An instance of DetectorAdcs used to read the temperature
|
||||||
# of different components
|
of different components
|
||||||
|
|
||||||
# Examples
|
Examples
|
||||||
# -----------
|
-----------
|
||||||
|
|
||||||
# ::
|
::
|
||||||
|
|
||||||
# detector.temp
|
detector.temp
|
||||||
# >>
|
>>
|
||||||
# temp_fpga : 36.90°C, 45.60°C
|
temp_fpga : 36.90°C, 45.60°C
|
||||||
# temp_fpgaext : 31.50°C, 32.50°C
|
temp_fpgaext : 31.50°C, 32.50°C
|
||||||
# temp_10ge : 0.00°C, 0.00°C
|
temp_10ge : 0.00°C, 0.00°C
|
||||||
# temp_dcdc : 36.00°C, 36.00°C
|
temp_dcdc : 36.00°C, 36.00°C
|
||||||
# temp_sodl : 33.00°C, 34.50°C
|
temp_sodl : 33.00°C, 34.50°C
|
||||||
# temp_sodr : 33.50°C, 34.00°C
|
temp_sodr : 33.50°C, 34.00°C
|
||||||
# temp_fpgafl : 33.81°C, 30.93°C
|
temp_fpgafl : 33.81°C, 30.93°C
|
||||||
# temp_fpgafr : 27.88°C, 29.15°C
|
temp_fpgafr : 27.88°C, 29.15°C
|
||||||
|
|
||||||
# a = detector.temp.fpga[:]
|
a = detector.temp.fpga[:]
|
||||||
# a
|
a
|
||||||
# >> [36.568, 45.542]
|
>> [36.568, 45.542]
|
||||||
|
|
||||||
|
|
||||||
# """
|
"""
|
||||||
# return self._temp
|
return self._temp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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)]
|
|
||||||
|
|
||||||
|
|
||||||
|
17
python/slsdet/enums.py
Normal file
17
python/slsdet/enums.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
import _slsdet
|
||||||
|
runStatus = _slsdet.slsDetectorDefs.runStatus
|
||||||
|
speedLevel = _slsdet.slsDetectorDefs.speedLevel
|
||||||
|
detectorType = _slsdet.slsDetectorDefs.detectorType
|
||||||
|
frameDiscardPolicy = _slsdet.slsDetectorDefs.frameDiscardPolicy
|
||||||
|
fileFormat = _slsdet.slsDetectorDefs.fileFormat
|
||||||
|
dimension = _slsdet.slsDetectorDefs.dimension
|
||||||
|
externalSignalFlag = _slsdet.slsDetectorDefs.externalSignalFlag
|
||||||
|
timingMode = _slsdet.slsDetectorDefs.timingMode
|
||||||
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||||
|
detectorSettings = _slsdet.slsDetectorDefs.detectorSettings
|
||||||
|
clockIndex = _slsdet.slsDetectorDefs.clockIndex
|
||||||
|
readoutMode = _slsdet.slsDetectorDefs.readoutMode
|
||||||
|
masterFlags = _slsdet.slsDetectorDefs.masterFlags
|
||||||
|
burstMode = _slsdet.slsDetectorDefs.burstMode
|
||||||
|
timingSourceType = _slsdet.slsDetectorDefs.timingSourceType
|
51
python/slsdet/gotthard.py
Normal file
51
python/slsdet/gotthard.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
This file contains the specialization for the Moench detector
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from .detector import Detector, freeze
|
||||||
|
from .dacs import DetectorDacs
|
||||||
|
import _slsdet
|
||||||
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||||
|
from .detector_property import DetectorProperty
|
||||||
|
|
||||||
|
# @freeze
|
||||||
|
|
||||||
|
# vref_ds, vcascn_pb, vcascp_pb, vout_cm, vcasc_out, vin_cm, vref_comp, ib_test_c
|
||||||
|
class GotthardDacs(DetectorDacs):
|
||||||
|
_dacs = [('vref_ds', dacIndex.VREF_DS, 0, 4000, 660),
|
||||||
|
('vcascn_pb', dacIndex.VCASCN_PB, 0, 4000, 650),
|
||||||
|
('vcascp_pb,', dacIndex.VCASCP_PB, 0, 4000, 1480),
|
||||||
|
('vout_cm', dacIndex.VOUT_CM, 0, 4000, 1520),
|
||||||
|
('vcasc_out', dacIndex.VCASC_OUT, 0, 4000, 1320),
|
||||||
|
('vin_cm', dacIndex.VIN_CM, 0, 4000, 1350),
|
||||||
|
('vref_comp', dacIndex.VREF_COMP, 0, 4000, 350),
|
||||||
|
('ib_test_c', dacIndex.IB_TESTC, 0, 4000, 2001),
|
||||||
|
]
|
||||||
|
_dacnames = [_d[0] for _d in _dacs]
|
||||||
|
|
||||||
|
#vthreshold??
|
||||||
|
|
||||||
|
|
||||||
|
@freeze
|
||||||
|
class Gotthard(Detector):
|
||||||
|
"""
|
||||||
|
Subclassing Detector to set up correct dacs and detector specific
|
||||||
|
functions.
|
||||||
|
"""
|
||||||
|
_detector_dynamic_range = [16]
|
||||||
|
|
||||||
|
|
||||||
|
_settings = ['standard', 'highgain', 'lowgain', 'veryhighgain', 'verylowgain']
|
||||||
|
"""available settings for Eiger, note almost always standard"""
|
||||||
|
|
||||||
|
def __init__(self, id=0):
|
||||||
|
super().__init__(id)
|
||||||
|
self._frozen = False
|
||||||
|
self._dacs = GotthardDacs(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dacs(self):
|
||||||
|
return self._dacs
|
61
python/slsdet/gotthard2.py
Normal file
61
python/slsdet/gotthard2.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
This file contains the specialization for the Jungfrau detector
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from .detector import Detector, freeze
|
||||||
|
|
||||||
|
# from .adcs import Adc, DetectorAdcs
|
||||||
|
from .dacs import DetectorDacs
|
||||||
|
import _slsdet
|
||||||
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||||
|
from .detector_property import DetectorProperty
|
||||||
|
|
||||||
|
|
||||||
|
# @freeze
|
||||||
|
class Gotthard2Dacs(DetectorDacs):
|
||||||
|
"""
|
||||||
|
Gotthard2 specific DACs
|
||||||
|
"""
|
||||||
|
_dacs = [('vref_h_adc', dacIndex.VREF_H_ADC, 0, 4000, 2116),
|
||||||
|
('vb_comp_fe', dacIndex.VB_COMP_FE, 0, 4000, 0),
|
||||||
|
('vb_comp_adc', dacIndex.VB_COMP_ADC, 0, 4000, 0),
|
||||||
|
('vcom_cds', dacIndex.VCOM_CDS, 0, 4000, 705),
|
||||||
|
('vref_rstore', dacIndex.VREF_RSTORE, 0, 4000, 205),
|
||||||
|
('vb_opa_1st', dacIndex.VB_OPA_1ST, 0, 4000, 0),
|
||||||
|
('vref_comp_fe', dacIndex.VREF_COMP_FE, 0, 4000, 0),
|
||||||
|
('vcom_adc1', dacIndex.VCOM_ADC1, 0, 4000, 705),
|
||||||
|
('vref_prech', dacIndex.VREF_PRECH, 0, 4000, 900),
|
||||||
|
('vref_l_adc', dacIndex.VREF_L_ADC, 0, 4000, 700),
|
||||||
|
('vref_cds', dacIndex.VREF_CDS, 0, 4000, 600),
|
||||||
|
('vb_cs', dacIndex.VB_CS, 0, 4000, 2799),
|
||||||
|
('vb_opa_fd', dacIndex.VB_OPA_FD, 0, 4000, 0),
|
||||||
|
('vcom_adc2', dacIndex.VCOM_ADC2, 0, 4000, 704),
|
||||||
|
]
|
||||||
|
_dacnames = [_d[0] for _d in _dacs]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@freeze
|
||||||
|
class Gotthard2(Detector):
|
||||||
|
"""
|
||||||
|
Subclassing Detector to set up correct dacs and detector specific
|
||||||
|
functions.
|
||||||
|
"""
|
||||||
|
_detector_dynamic_range = [16]
|
||||||
|
|
||||||
|
|
||||||
|
_settings = ['standard', 'highgain', 'lowgain', 'veryhighgain', 'verylowgain']
|
||||||
|
"""available settings for Eiger, note almost always standard"""
|
||||||
|
|
||||||
|
def __init__(self, id=0):
|
||||||
|
super().__init__(id)
|
||||||
|
self._frozen = False
|
||||||
|
self._dacs = Gotthard2Dacs(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dacs(self):
|
||||||
|
return self._dacs
|
52
python/slsdet/moench.py
Normal file
52
python/slsdet/moench.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
This file contains the specialization for the Moench detector
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from .detector import Detector, freeze
|
||||||
|
from .dacs import DetectorDacs
|
||||||
|
import _slsdet
|
||||||
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||||
|
from .detector_property import DetectorProperty
|
||||||
|
|
||||||
|
# @freeze
|
||||||
|
class MoenchDacs(DetectorDacs):
|
||||||
|
"""
|
||||||
|
Jungfrau specific DACs
|
||||||
|
"""
|
||||||
|
_dacs = [('vbp_colbuf', dacIndex.VBP_COLBUF, 0, 4000, 1300),
|
||||||
|
('vipre', dacIndex.VIPRE, 0, 4000, 1000),
|
||||||
|
('vin_cm,', dacIndex.VIN_CM, 0, 4000, 1400),
|
||||||
|
('vb_sda', dacIndex.VB_SDA, 0, 4000, 680),
|
||||||
|
('vcasc_sfp', dacIndex.VCASC_SFP, 0, 4000, 1428),
|
||||||
|
('vout_cm', dacIndex.VOUT_CM, 0, 4000, 1200),
|
||||||
|
('vipre_cds', dacIndex.VIPRE_CDS, 0, 4000, 800),
|
||||||
|
('ibias_sfp', dacIndex.IBIAS_SFP, 0, 4000, 900),
|
||||||
|
]
|
||||||
|
_dacnames = [_d[0] for _d in _dacs]
|
||||||
|
|
||||||
|
#vthreshold??
|
||||||
|
|
||||||
|
|
||||||
|
@freeze
|
||||||
|
class Moench(Detector):
|
||||||
|
"""
|
||||||
|
Subclassing Detector to set up correct dacs and detector specific
|
||||||
|
functions.
|
||||||
|
"""
|
||||||
|
_detector_dynamic_range = [16]
|
||||||
|
|
||||||
|
|
||||||
|
_settings = ['standard', 'highgain', 'lowgain', 'veryhighgain', 'verylowgain']
|
||||||
|
"""available settings for Eiger, note almost always standard"""
|
||||||
|
|
||||||
|
def __init__(self, id=0):
|
||||||
|
super().__init__(id)
|
||||||
|
self._frozen = False
|
||||||
|
self._dacs = MoenchDacs(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dacs(self):
|
||||||
|
return self._dacs
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
This file contains the specialization for the Jungfrau detector
|
This file contains the specialization for the Mythen3 detector
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@ -13,49 +13,32 @@ import _slsdet
|
|||||||
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
||||||
from .detector_property import DetectorProperty
|
from .detector_property import DetectorProperty
|
||||||
|
|
||||||
# vcassh 1200,
|
|
||||||
# vth2 2800,
|
|
||||||
# vshaper 1280,
|
|
||||||
# vshaperneg 2800,
|
|
||||||
# vipre_out 1220,
|
|
||||||
# vth3 2800,
|
|
||||||
# vth1 2800,
|
|
||||||
# vicin 1708,
|
|
||||||
# vcas 1800,
|
|
||||||
# vpreamp 1100,
|
|
||||||
# vpl 1100,
|
|
||||||
# vipre 2624,
|
|
||||||
# viinsh 1708,
|
|
||||||
# vph 1712,
|
|
||||||
# vtrim 2800,
|
|
||||||
# vdcsh 800
|
|
||||||
|
|
||||||
|
|
||||||
# @freeze
|
# @freeze
|
||||||
class Mythen3Dacs(DetectorDacs):
|
class Mythen3Dacs(DetectorDacs):
|
||||||
"""
|
"""
|
||||||
Jungfrau specific DACs
|
Jungfrau specific DACs
|
||||||
"""
|
"""
|
||||||
_dacs = [('vcassh', dacIndex.CASSH, 0, 4000, 1220),
|
_dacs = [('vcassh', dacIndex.VCASSH, 0, 4000, 1220),
|
||||||
('vth2', dacIndex.VTH2, 0, 4000, 2800),
|
('vth2', dacIndex.VTH2, 0, 4000, 2800),
|
||||||
('vshaper', dacIndex.SHAPER1, 0, 4000, 1280),
|
('vrshaper', dacIndex.VRSHAPER, 0, 4000, 1280),
|
||||||
('vshaperneg', dacIndex.SHAPER2, 0, 4000, 2800),
|
('vrshaper_n', dacIndex.VRSHAPER_N, 0, 4000, 2800),
|
||||||
('vipre_out', dacIndex.VIPRE_OUT, 0, 4000, 1220),
|
('vipre_out', dacIndex.VIPRE_OUT, 0, 4000, 1220),
|
||||||
('vth3', dacIndex.VTH3, 0, 4000, 2800),
|
('vth3', dacIndex.VTH3, 0, 4000, 2800),
|
||||||
('vth1', dacIndex.THRESHOLD, 0, 4000, 2800),
|
('vth1', dacIndex.VTH1, 0, 4000, 2800),
|
||||||
('vicin', dacIndex.VICIN, 0, 4000, 1708),
|
('vicin', dacIndex.VICIN, 0, 4000, 1708),
|
||||||
('vcas', dacIndex.CAS, 0, 4000, 1800),
|
('vcas', dacIndex.VCAS, 0, 4000, 1800),
|
||||||
('vpreamp', dacIndex.PREAMP, 0, 4000, 1100),
|
('vrpreamp', dacIndex.VRPREAMP, 0, 4000, 1100),
|
||||||
('vpl', dacIndex.VPL, 0, 4000, 1100),
|
('vcal_n', dacIndex.VCAL_N, 0, 4000, 1100),
|
||||||
('vipre', dacIndex.VIPRE, 0, 4000, 2624),
|
('vipre', dacIndex.VIPRE, 0, 4000, 2624),
|
||||||
('viinsh', dacIndex.VIINSH, 0, 4000, 1708),
|
('vishaper', dacIndex.VISHAPER, 0, 4000, 1708),
|
||||||
('vph', dacIndex.CALIBRATION_PULSE, 0, 4000, 1712),
|
('vcal_p', dacIndex.VCAL_P, 0, 4000, 1712),
|
||||||
('vtrim', dacIndex.TRIMBIT_SIZE, 0, 4000, 2800),
|
('vtrim', dacIndex.VTRIM, 0, 4000, 2800),
|
||||||
('vdcsh', dacIndex.VDCSH, 0, 4000, 800),
|
('vdcsh', dacIndex.VDCSH, 0, 4000, 800),
|
||||||
]
|
]
|
||||||
_dacnames = [_d[0] for _d in _dacs]
|
_dacnames = [_d[0] for _d in _dacs]
|
||||||
|
|
||||||
|
#vthreshold??
|
||||||
|
|
||||||
|
|
||||||
@freeze
|
@freeze
|
||||||
|
128
python/slsdet/proxy.py
Normal file
128
python/slsdet/proxy.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
from .utils import element_if_equal
|
||||||
|
from .enums import dacIndex
|
||||||
|
|
||||||
|
|
||||||
|
def set_proxy_using_dict(func, key, value):
|
||||||
|
if isinstance(value, dict) and all(isinstance(k, int) for k in value.keys()):
|
||||||
|
for dkey, dvalue in value.items():
|
||||||
|
func(key, dvalue, [dkey])
|
||||||
|
else:
|
||||||
|
func(key, value)
|
||||||
|
|
||||||
|
class JsonProxy:
|
||||||
|
"""
|
||||||
|
Proxy class to allow for intuitive setting and getting of rx_jsonpara
|
||||||
|
This class is returned by Detectr.rx_jsonpara
|
||||||
|
"""
|
||||||
|
def __init__(self, det):
|
||||||
|
self.det = det
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return element_if_equal(self.det.getAdditionalJsonParameter(key))
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self.det.setAdditionalJsonParameter(key, str(value))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
r = element_if_equal(self.det.getAdditionalJsonHeader())
|
||||||
|
if isinstance(r, list):
|
||||||
|
rstr = ''
|
||||||
|
for i, list_item in enumerate(r):
|
||||||
|
list_item = dict(list_item)
|
||||||
|
rstr += ''.join([f'{i}:{key}: {value}\n' for key, value in list_item.items()])
|
||||||
|
|
||||||
|
return rstr.strip('\n')
|
||||||
|
else:
|
||||||
|
r = dict(r)
|
||||||
|
return '\n'.join([f'{key}: {value}' for key, value in r.items()])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SlowAdcProxy:
|
||||||
|
"""
|
||||||
|
Proxy class to allow for more intuitive reading the slow ADCs
|
||||||
|
"""
|
||||||
|
def __init__(self, det):
|
||||||
|
self.det = det
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
dac_index = dacIndex(int(dacIndex.SLOW_ADC0)+key)
|
||||||
|
return element_if_equal(self.det.getSlowADC(dac_index))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
rstr = ''
|
||||||
|
for i in range(8):
|
||||||
|
r = element_if_equal(self.__getitem__(i))
|
||||||
|
if isinstance(r, list):
|
||||||
|
rstr += ' '.join(f'{item} uV' for item in r)
|
||||||
|
else:
|
||||||
|
rstr += f'{i}: {r} uV\n'
|
||||||
|
|
||||||
|
return rstr.strip('\n')
|
||||||
|
|
||||||
|
class ClkDivProxy:
|
||||||
|
"""
|
||||||
|
Proxy class to allow for more intuitive reading clockdivider
|
||||||
|
"""
|
||||||
|
def __init__(self, det):
|
||||||
|
self.det = det
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return element_if_equal(self.det.getClockDivider(key))
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
set_proxy_using_dict(self.det.setClockDivider, key, value)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
rstr = ''
|
||||||
|
for i in range(6):
|
||||||
|
r = element_if_equal(self.__getitem__(i))
|
||||||
|
if isinstance(r, list):
|
||||||
|
rstr += ' '.join(f'{item}' for item in r)
|
||||||
|
else:
|
||||||
|
rstr += f'{i}: {r}\n'
|
||||||
|
|
||||||
|
return rstr.strip('\n')
|
||||||
|
|
||||||
|
|
||||||
|
class MaxPhaseProxy:
|
||||||
|
"""
|
||||||
|
Proxy class to allow for more intuitive reading clockdivider
|
||||||
|
"""
|
||||||
|
def __init__(self, det):
|
||||||
|
self.det = det
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return element_if_equal(self.det.getMaxClockPhaseShift(key))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
rstr = ''
|
||||||
|
for i in range(5):
|
||||||
|
r = element_if_equal(self.__getitem__(i))
|
||||||
|
if isinstance(r, list):
|
||||||
|
rstr += ' '.join(f'{item}' for item in r)
|
||||||
|
else:
|
||||||
|
rstr += f'{i}: {r}\n'
|
||||||
|
|
||||||
|
return rstr.strip('\n')
|
||||||
|
|
||||||
|
class ClkFreqProxy:
|
||||||
|
"""
|
||||||
|
Proxy class to allow for more intuitive reading clockdivider
|
||||||
|
"""
|
||||||
|
def __init__(self, det):
|
||||||
|
self.det = det
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return element_if_equal(self.det.getClockFrequency(key))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
rstr = ''
|
||||||
|
for i in range(5):
|
||||||
|
r = element_if_equal(self.__getitem__(i))
|
||||||
|
if isinstance(r, list):
|
||||||
|
rstr += ' '.join(f'{item}' for item in r)
|
||||||
|
else:
|
||||||
|
rstr += f'{i}: {r}\n'
|
||||||
|
|
||||||
|
return rstr.strip('\n')
|
50
python/slsdet/temperature.py
Normal file
50
python/slsdet/temperature.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from functools import partial
|
||||||
|
from collections.abc import Iterable
|
||||||
|
import numpy as np
|
||||||
|
class Temperature:
|
||||||
|
degree_sign = u"\N{DEGREE SIGN}"
|
||||||
|
|
||||||
|
def __init__(self, name, enum, detector):
|
||||||
|
self.name = name
|
||||||
|
self.enum = enum
|
||||||
|
self._detector = detector
|
||||||
|
self.get_nmod = self._detector.size
|
||||||
|
# Bind functions to get and set the dac
|
||||||
|
self.get = partial(self._detector.getTemperature, self.enum)
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key == slice(None, None, None):
|
||||||
|
return self.get()
|
||||||
|
elif isinstance(key, Iterable):
|
||||||
|
return self.get(list(key))
|
||||||
|
else:
|
||||||
|
return self.get([key])[0] # No list for single value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""String representation for a single temperature in all modules"""
|
||||||
|
|
||||||
|
tempstr = ''.join([f'{item:5d}{self.degree_sign}C' for item in self.get()])
|
||||||
|
return f'{self.name:15s}:{tempstr}'
|
||||||
|
|
||||||
|
class DetectorTemperature:
|
||||||
|
"""
|
||||||
|
Interface to temperatures on the readout board
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
for attr, value in self.__dict__.items():
|
||||||
|
yield value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""String representation of all temps all mods"""
|
||||||
|
r_str = '\n'.join([repr(temp) for temp in self])
|
||||||
|
return r_str
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
"""Get temperatures as a dictionary with numpy arrays"""
|
||||||
|
return {attr:np.array(value.get()) for attr, value in self.__dict__.items()}
|
||||||
|
|
||||||
|
def to_array(self):
|
||||||
|
"""Get all temperatures as a numpy array"""
|
||||||
|
t = self.to_dict()
|
||||||
|
return np.vstack([value for key, value in t.items()])
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user