Compare commits

..

80 Commits

Author SHA1 Message Date
a86fd00e59 Merge branch 'main' into 8.0.0.rc 2023-11-13 16:38:25 +01:00
24894667b7 release fw for ctb 2023-11-13 16:03:52 +01:00
4b414bfddb release notes 2023-11-12 15:39:58 +01:00
15d357d9ab release notes 2023-11-12 15:32:28 +01:00
f95de054f9 formatting 2023-11-12 15:29:34 +01:00
0aef8113dd documentation and examples 2023-11-12 15:11:36 +01:00
9785a41048 Merge branch '8.0.0.rc' of github.com:slsdetectorgroup/slsDetectorPackage into 8.0.0.rc 2023-11-10 17:29:47 +01:00
417e1a88a5 fixed doc 2023-11-10 17:29:35 +01:00
9c0dd0385d updating docs 2023-11-10 16:02:21 +01:00
5ab64efe3e added python 3.12 to the conda build variants 2023-11-10 14:18:38 +01:00
8f77e4d4fe added python 3.12 to the conda build variants 2023-11-10 14:17:40 +01:00
41c5b75b10 trigger signal issues handled at acquire (#862)
* if blocking and handling sync, only master gets blocking acq, slaves get non blocking as they are first and so dont get status or error caught when slaves dont get trigger (due to not connected etc) and acq returns with slaves still in waiting status. so check status of all in blocking acq

* for all dets with sync, ensure atleast one master when starting acq

* docs updated about sync
2023-11-10 11:24:18 +01:00
bfe53c6693 udpated release notes 2023-11-09 15:10:17 +01:00
f7997dd09a 8.0.0.rc: fix server logic in checking detector idle (#860)
* fix buggy logic in checking detector idle and an argument check
2023-11-09 15:07:03 +01:00
c64e87a2b6 7.0.3.rc: fix server logic in checking detector idle (#859)
* fix buggy logic in checking detector idle and an argument check
2023-11-09 14:21:11 +01:00
5eeb8e29c1 project version change 2023-11-08 17:31:29 +01:00
09697fa325 updated release notes 2023-11-08 17:30:07 +01:00
90b4daef39 updated release notes 2023-11-08 17:28:48 +01:00
2082f1eee7 updated release notes 2023-11-08 17:28:17 +01:00
d3a636b563 updated release notes 2023-11-08 17:24:56 +01:00
50b9b6ca39 update release notes 2023-11-08 14:14:04 +01:00
e86b57cdfc versioning, format, release notes, update test simulator (no need for psutil) 2023-11-08 12:12:17 +01:00
14e11e8b5b formatting and versioning 2023-11-08 11:43:09 +01:00
beafe86554 execute command inside server fixed (from fix simulator tests and exec command PR) (#856) 2023-11-08 09:26:00 +01:00
af3dc1e7f4 7.0.3.rc: execute command inside server fixed (from fix simulator tests and exec command PR) (#855)
* execute command inside server fixed (from fix simulator tests and exec command PR)
2023-11-08 09:25:52 +01:00
573177203b formatting 2023-11-07 14:51:15 +01:00
a3ca9ebce5 updating release notes 2023-11-07 14:35:42 +01:00
8174fc9691 Update RELEASE.txt 2023-11-07 12:34:10 +01:00
d6eac6da71 updated release notes 2023-11-07 11:22:09 +01:00
56c7ae4852 8.0.0.rc: fix py virtual test (#841)
* fix virtual test when it fails

* catching errors in tests and removing sigchild ignore so servers (process in background) executing commands will not fail (pclose no child processes, if sigchld is ignored) fixed

* uncommented python loading config

* somehow killal slsReciever in second detector test fails even though no receiver running

* fixing script for virtual simlator test:fixed issue with check if process running, fixed moench tests
2023-11-07 09:30:24 +01:00
9b9b09ceaf 703rc/tests/fix execute command (#842)
* fix execute command
* fix for tests for ctb
2023-11-07 09:29:48 +01:00
cfebaee2a5 handling inconsistent fnums to be -1 in gui, so when one sets 0 (change of value) will also give an exception (#853) 2023-11-06 16:11:40 +01:00
4613c54f57 handling inconsistent fnums to be -1 in gui, so when one sets 0 (change of value) will also give an exception (#852) 2023-11-06 16:11:25 +01:00
51f9d6f011 8.0.0rc: : gui acq finished callback for different status (#851)
* fix acquisition finished status to have different status for different modules, but does not have to be error. for eg. jf sync fw (2.4.1 gives idle for master and stopped for slaves when stopping acquiistion)
2023-11-06 16:08:23 +01:00
58ac7ac280 7.0.3.rc: gui acq finished callback for different status (#847)
* fix acquisition finished status to have different status for different modules, but does not have to be error. for eg. jf sync fw (2.4.1 gives idle for master and stopped for slaves when stopping acquiistion)
2023-11-06 16:07:38 +01:00
82edfa75d3 7.0.3.rc: process the raw data files as a list (#848)
* Added file list option for moenchRawDataProcess
2023-11-03 12:10:20 +01:00
35ed926047 formatting 2023-10-25 09:36:51 +02:00
4023ed0775 updated versioning 2023-10-25 09:36:04 +02:00
b6ef3bc39e updated release notest 2023-10-25 09:15:10 +02:00
2035666792 versioning and binaries updated 2023-10-25 08:43:23 +02:00
1ff4d806e7 minor 2023-10-25 08:25:02 +02:00
3861379653 updated release notes 2023-10-24 17:39:47 +02:00
91140bbb71 formatting 2023-10-24 11:17:18 +02:00
a5632fcbea fix warning for prev_val (variable size array) in tests (#837) 2023-10-23 15:55:13 +02:00
d44329117d fix warning for prev_val (variable size array) in tests (#836) 2023-10-23 15:52:59 +02:00
4a454aa698 tests for jf (#835) 2023-10-19 16:55:29 +02:00
0e43072db8 eiger required fw version to 32: fix for blocking trigger in quad (#833) 2023-10-18 17:04:26 +02:00
6c67025ea8 7.0.3.rc eiger: fw version to 32 (quad blocking trigger) (#832)
* eiger required fw version to 32: fix for blocking trigger in quad
2023-10-18 16:51:17 +02:00
e5ee27dbfa 8.0.0.rc jf: reconfigure chip when touching electron collection mode bit (#830)
* jf: if bit 14 in reg 0x5d (electron mode collection bit) is changed, configure chip if v1.1 and powered on. so touch writeregister (setbit/clearbit also calls write register in the end). replace when electroncollectionmode command introduced
2023-10-18 10:49:44 +02:00
601249cc71 8.0.0.rc jf: change status reg bits (#828)
* rewrite of status reg bits, waiting state includes both wati for trigger and start frame, blocking trigger only waits if its not in waiting for trigger and run busy enabled, error state connected in firmware
2023-10-18 10:36:56 +02:00
ff60b8c379 8.0.0.rc: jf sync: stopping master gives idle (#823)
* jf sync mode master could return idle when stopped and so not all modules return the same value and must check for 'stopped or idle', Also must throw if any of the module gives an error

* added contains_only to sls::Result (#827)

* added variadic template for checking if a result contains only specified values

* fix for gcc4.8

* renamed to Result::contains_only

* stop on only the positions

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@gmail.com>
2023-10-13 15:25:19 +02:00
37ce3d6f59 7.0.3.rc: jf sync: stopping master gives idle (#822)
* jf sync mode master could return idle when stopped and so not all modules return the same value and must check for 'stopped or idle', Also must throw if any of the module gives an error ( not jungfrau, but eiger could)

* added contains_only to sls::Result (#827)

* added variadic template for checking if a result contains only specified values

* fix for gcc4.8

* renamed to Result::contains_only

* stop on only the positions

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@gmail.com>
2023-10-13 12:27:43 +02:00
bf26533fd8 8.0.0.rc: jf fix pedestal (#820)
* jf pedestal fix: touch enable bit last
2023-10-05 10:28:51 +02:00
7106273521 update 2d gain plot (if no x and ymin/max changes or window resizing): setFixedWidth was updating for window resize, updated virtual servers for g2 and jungfrau to keep changing gain and data for every frame (#817) 2023-10-03 17:22:14 +02:00
1484d038de 7.03.rc: update 2d gain plot color map (if no x and ymin/max changes or window resizing): setFixedWidth was updating for window resize, updated virtual servers for g2 and jungfrau to keep changing gain and data for every frame. the data value (#818) 2023-10-03 17:22:03 +02:00
fb0090c79e removing the misleading word 'Simulating' when programmig fpga (#814) 2023-09-28 16:20:59 +02:00
adc68cd519 formatting 2023-09-28 15:51:40 +02:00
1566eef247 703rc/fix numeric limits (#812)
* fixed compilation for fedora for numeric_limits

* formatting
2023-09-28 10:49:02 +02:00
e7cd90db78 fixed crashing of moench03RawDataProcess when nframes>0 (#810) 2023-09-27 09:22:40 +02:00
45414149fe binaries in for the previous PR 2023-09-22 15:59:35 +02:00
48759f440e 703rc/fix port size (#802)
* validate port numbers in client

* validate port numbers created at virtual servers and receiver process as tcp ports
2023-09-18 08:59:53 +02:00
b367b7e431 fixed some interpolation issues (#796) 2023-08-28 13:38:19 +02:00
f0b2a6f6f9 update release notes 2023-08-25 14:02:50 +02:00
f761046bfc updated docs and versions 2023-07-12 16:50:13 +02:00
1a859b83db formatting 2023-07-12 16:06:31 +02:00
70bfc875a6 updating release notes 2023-07-11 17:02:27 +02:00
c0755308a4 updating release notes 2023-07-11 17:01:14 +02:00
ab5509e10c updating release notes 2023-07-11 17:00:42 +02:00
004cb26646 updated firmware versions for 7.0.2 2023-07-10 12:21:19 +02:00
a4f47a5945 synced master status running when setting to slave (#747)
* jf: unsync before setting master/slave and then sync (if it was set) to overcome master going into running state when making it a slave and synced

* add tests for this condition

* updated release notes, updated min fw version requirement for v1.0 boards
2023-05-25 11:04:05 +02:00
312f3f473d fix that only master starts second and not all (for start acq), typo with pos and masters list (#743) 2023-05-11 10:20:17 +02:00
5871086cd6 formatting 2023-05-08 17:04:04 +02:00
6a0fe823b3 enable fix g0 when in expert mode (when gain mode enabled and not just visible) (#736) 2023-05-08 14:20:21 +02:00
5912aae53e Rx roi zmq (#726)
adding rx_roi also in the zmq header for external guis to put the "yellow box".. sending full roi instead of -1, and sending for each zmq port. "(multiple yellow boxes)".
2023-05-08 12:23:05 +02:00
8833ccf5cc 7.0.2.rc (#721)
* row and column for jungfrau mixed up

* multi module jungfrau sync must do slaves first then master for start acquisition and send software trigger, and master first and then slaves for stopacquisition

* non blocking to slaves first and only then blocking/nonblocking to the master for sending software trigger(jungfrau multi mod sync)

* fixed get/set timing jungfrau when sync enabled, getsync during blocking acquire (for trigger or stop) will get stuck as it should ask the stop server

* switching between 1 and 2 interfaces did not set gui/client zmq port properly. Resulted in dummy streaming forever. fixed

* formatting, refactoring: const & for positions, multi mod M3 stop first master first

* adding missing cstdint for gcc 13

* Refactoring handle sync out, handling synchronization also for softwaretrigger for m3, for start/sync/stop for g2/g1

---------

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
2023-05-08 12:11:19 +02:00
77c558a7be formatting 2023-03-24 12:54:55 +01:00
378fc301b8 updating client version, release version and project_version in CMakeLists.txt 2023-03-23 15:43:17 +01:00
87d6e16090 7.0.1 fix det server version (#702)
* check server version before initial checks, catch old server version exception, get old server version as 64 bit and print it along with exception
2023-03-23 15:37:01 +01:00
2ef021041c rx_arping sigchld (#701)
* rx_arping pclose gave -1 due to sigchld being ignored, fixed with sig handler doing a wait
2023-03-23 13:58:40 +01:00
574127b5ac fix hdf5 compilation using det spec fields in header (#700)
* fix hdf5 compilation using det spec fields in header
2023-03-23 12:30:38 +01:00
158 changed files with 10364 additions and 186147 deletions

View File

@ -17,7 +17,7 @@ jobs:
- uses: actions/checkout@v3
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev
packages: libzmq3-dev libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev
version: 1.0
- name: Configure CMake

View File

@ -1 +0,0 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file

View File

@ -2,7 +2,7 @@
# Copyright (C) 2021 Contributors to the SLS Detector Package
cmake_minimum_required(VERSION 3.14)
project(slsDetectorPackage)
set(PROJECT_VERSION 7.0.0)
set(PROJECT_VERSION 8.0.0)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
@ -33,7 +33,7 @@ else()
# Standard behaviour use libzmq included in this repo (libs/libzmq)
FetchContent_Declare(
libzmq
URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-4.3.4.tar.gz
URL ${CMAKE_SOURCE_DIR}/libs/libzmq/libzmq-4.3.4.tar.gz
URL_HASH MD5=cc20b769ac10afa352e5ed2769bb23b3
)
endif()
@ -232,8 +232,6 @@ if (NOT TARGET slsProjectCSettings)
-Wredundant-decls
-Wdouble-promotion
-Werror=return-type
-Wno-format-overflow
-Wno-format-truncation
)
sls_disable_c_warning("-Wstringop-truncation")
endif()
@ -246,7 +244,6 @@ if(SLS_USE_SANITIZER)
# target_link_libraries(slsProjectOptions INTERFACE -fsanitize=thread)
endif()
if(SLS_TUNE_LOCAL)
target_compile_options(slsProjectOptions INTERFACE -mtune=native -march=native)
endif()

View File

@ -1,36 +1,264 @@
SLS Detector Package Major Release 7.x.x released on xx.xx.2023
SLS Detector Package Major Release 8.0.0 released on 13.11.2023
===============================================================
This document describes the differences between v7.x.x and v7.0.2
This document describes the differences between v8.0.0 and v7.0.3
CONTENTS
--------
1 New, Changed or Resolved Features
1.1 Compilation
1.2 Callback
1.3 Python
1.4 Client
1.5 Detector Server
1.6 Simulator
1.7 Receiver
1.8 Gui
2 On-board Detector Server Compatibility
3 Firmware Requirements
4 Kernel Requirements
5 Download, Documentation & Support
1 Compilation Changes
2 New or Changed Features
2.1 Breaking API
2.2 Resolved or Changed Features
2.3 New Features
3 On-board Detector Server Compatibility
4 Firmware Requirements
5 Kernel Requirements
6 Download, Documentation & Support
1 New, Changed or Resolved Features
2 Compilation Changes
=====================
* Minimum CMake version changed from 3.12 to 3.14
* Internal zmq lib
Building zmq from tar file in repo (libs/libzmq/libzmq-4.3.4.tar.gz),
but added option (SLS_FETCH_ZMQ_FROM_GITHUB) to pull zmq version (v4.3.4)
from github (https://github.com/zeromq/libzmq.git)
* Internal pybind11 lib
Building pybind11 from tar file in repo (libs/pybind11/v2.11.0.tar.gz),
but added option (SLS_FETCH_PYBIND11_FROM_GITHUB) to pull pybind11 version
(v2.11.0) from github (https://github.com/pybind/pybind11)
2 New, Changed or Resolved Features
=====================================
- moench being made compatible with jungfrau 2.0 boards (jungfrau structure, away from ctb)
- eiger febl and feb in versions
- fix ctb slow adcs
2.1 Breaking API
==================
Firmware
--------
* [Jungfrau] Status register and Sync mode fix
The regiser bit definition changed and fixes for stable control in sync mode.
Effect: Master and slaves give same status (previously master is sometimes 'idle' when acquisition is stopped), same #frames left and #nextframenumber.
Also ERROR status connected, but never noticed to occur.
For user, everything is transparent unless one touches status register
using advanced commands.
* [Moench] Status: Development mode
Moench is now being made compatible with Jungfrau v2.0 readout boards.
Hence, firmware and software is in development mode.
7.x.x will continue to have fixes for Moench until this version is deployed.
* [Ctb] Fixes and features described later on.
Client
======
* Datatype change of port numbers from int to uint16_t
API: setVirtualDetectorServers,
get/setRxPort, get/setControlPort, get/setStopPort,
get/setDestinationUDPPort(2), get/setRxZmqPort, get/setClientZmqPort
* [Eiger] versions, hardware version, febl/r firmware version
Versions command modified to give more info about hardware version ['fx30', 'fx70'] and Febl/r firmware versions.
Command line: versions (output modified), hardwareversion (added for Eiger)
API added for Eiger: getHardwareVersion, getFrontEndFirmwareVersion
Enums added: fpgaPosition {FRONT_LEFT, FRONT_RIGHT}
* [Ctb] Voltage->Power name change
Command line: voltagelist ->powerlist
API: get/setVoltage -> get/setPower, get/setVoltageList -> get/setPowerList,
getMeasuredVoltage -> getMeasuredPower
2.2 Resolved or Changed Features
================================
Detector Server
---------------
* Set bit and clear bit validation
Previously, validation expected all the other bits in the register to
not change. Now, it only validates the selected bit.
* [Jungfrau] Electron collection mode (bit 14 of 0x5D register)
Affected Command line: setbit, clearbit, reg
Affected API: setBit, clearBit, writeRegister
Electron collection mode and requires chip reconfiguration.
Temporary fix added that touching this bit will reconfigure chip if chip
is v1.1 and powered on. Permanent fix by introducing a command for the
same in future release.
* [Ctb] Fixes
- Patioctrl, patsetbit, patbitmask
MSB (64 bit unsigned) could not be set as a value of -1 was interpreted
as a 'get'. Fixed in server.
- Allow dac tristate when v_limit is set. Fixed.
- Changing fw bit from disable analog to enable analog
- Allow adc enable for 1 GbE and 10GbE to be 0.
- Slow ADCs previously misread (a high 5k+ value). Firmware updated
and software adjusted now.
- Allow non blocking acquire for 1GbE. Added Transmitting status when it
might still be reading from fifo.
- Clean memory before reading from fifo in 1GbE mode. Read fifo then
RD strobe (corresponding firmware fix) fixes number of reads, but
increases all pipelines by 1.
- Fixed pattern viewer (auto legend buf without wait and loop), allow
pyat files. (/patterngenerator)
Simulator
---------
* Unique TCP port for multiple simulators
Checks include unique TCP port-hostname combo.
Receiver
--------
* Unique TCP port for multiple receivers
7.x.x already has automatically increasing TCP ports in shared memory
for multiple receivers. Now, checks include unique TCP port-hostname
combo.
* [Ctb] Fixes
- Readout mode updated
'rx_hostname' should configure the receiver with parameters from detector,
but readout mode in receiver always configured at start up to Analog only.
Fixed.
- Incorrect image size in zmq header, which happens when dbit list is
less than 64 bits. Fixed.
- Rearranging digital data when dbit list less than 64 bits fixed.
Client
------
* [Jungfrau][Mythen3][Gotthard2] Sync mode should have at least one master
Multi module synced detectors should have at least one master when
starting acquisition, else it will throw. Once master is done acquiring
(blocking mode), status of all modules checked to ensure none of the
slaves in waiting due to hardware issues such as cabling.
2.3 New Features
================
Client
------
* [Jungfrau] Pedestal mode
Command line: pedestalmode
API: get/setPedestalMode
Example:
pedestalmode 0 # turns off pedestal mode
pedestalmode 50 10 # turns on pedestal mode (50 pedestal frames, 10 loops)
In pedestal mode, number of frames/triggers
is overwritten by '#pedestal_frames x #pedestal_loops x 2'.
In auto timing mode or trigger mode with #frames > 1, #frames is overwritten
with #triggers is 1. Otherwise, #triggers is overwritten with #frames is 1.
In pedestal mode, one cannot set #frames, #triggers or timing mode (exception).
Disabling pedestal mode will set back to normal mode with normal previous
values of #frames and #triggers.
* Source UDP IP: Auto
Command line: udp_srcip, udp_srcip2
API: get/setSourceUDPIP(2)
Allow 'auto' for udp_srcip to pick up IP from detector hostname. Not allowed
for Gotthard1.
* Custom row and column for detector UDP header
Command line: row, column
API: get/setRow, get/setColumn
By default, row and column of module is determined in a pre-determined
manner or by custom detector size (Command line: detsize).
This is useful if user accesses row and column in multi- detector UDP header
or for the GUI to rearrange for complete image.
Option now added to set custom row and column.
* [Ctb] Features
- List for ADC, signal, power, slowadc
Also allow their list to set names and to obtain their indices and values.
Command line: dacname, dacindex,
adclist, adcname, adcindex,
signallist, signalname,signalindex,
powerlist, powername, powerindex, powervalues,
slowadclist, slowadcname, slowadcindex, slowadcvalues
API: get/setDacName, getDacIndex,
get/setAdcNames, getAdcIndex, get/setAdcName,
get/setSignalNames, getSignalIndex, get/setSignalName,
get/setPowerNames, getPowerIndex, get/setPowerName, getPowerList,
get/setSlowADCNames, getSlowADCIndex, get/setSlowADCName, getSlowADCList
- Added more modes for transceiver in read out mode.
Allow to set number of samples and enable mask for transceiver.
Command line: romode (more modes: 'transceiver', 'digital_transceiver'),
tsamples, transceiverenable
API: get/setTransceiverEnableMask, get/setNumberOfTransceiverSamples,
get/setReadoutMode (more enums: TRANSCEIVER_ONLY, DIGITAL_AND_TRANSCEIVER)
- Command to get file name with path of last pattern uploaded.
Command line: patfname
API: getPatterFileName
* Automatic test script for all virtual simulators added.
@ -38,13 +266,13 @@ This document describes the differences between v7.x.x and v7.0.2
==========================================
Eiger 7.0.0
Jungfrau 7.0.2
Mythen3 7.0.0
Gotthard2 7.0.0
Gotthard 7.0.0
Moench 7.0.0
Ctb 7.0.0
Eiger 8.0.0
Jungfrau 8.0.0
Mythen3 8.0.0
Gotthard2 8.0.0
Gotthard 8.0.0
Moench 8.0.0
Ctb 8.0.0
On-board Detector Server Upgrade
@ -65,21 +293,21 @@ This document describes the differences between v7.x.x and v7.0.2
========================
Eiger 20.02.2023 (v31)
Eiger 02.10.2023 (v32) (updated in 7.0.3)
Jungfrau 04.11.2022 (v1.4, HW v1.0)
03.11.2022 (v2.4, HW v2.0)
Jungfrau 20.09.2023 (v1.5, HW v1.0) (updated in 8.0.0)
21.09.2023 (v2.5, HW v2.0) (updated in 8.0.0)
Mythen3 24.01.2023 (v1.4)
Mythen3 24.01.2023 (v1.4) (updated in 7.0.0)
Gotthard2 23.11.2022 (v0.3)
Gotthard2 23.11.2022 (v0.3) (updated in 7.0.0)
Gotthard 08.02.2018 (50um and 25um Master)
09.02.2018 (25 um Slave)
Moench 05.12.2022 (v0.3)
Moench 10.07.2023 (v0.3.2) (updated in 8.0.0, under development)
Ctb 03.04.2023 (v1.2?)
Ctb 28.08.2023 (v1.2) (updated in 8.0.0)
Detector Upgrade

View File

@ -1 +0,0 @@
slsDetectorSoftware/generator/autocomplete/bash_autocomplete.sh

View File

@ -18,6 +18,7 @@ requirements:
- {{compiler('cxx')}}
- cmake
- qt 5.*
- zeromq
- xorg-libx11
- xorg-libice
- xorg-libxext
@ -36,6 +37,7 @@ requirements:
host:
- libstdcxx-ng
- libgcc-ng
- zeromq
- xorg-libx11
- xorg-libice
- xorg-libxext
@ -46,6 +48,7 @@ requirements:
- expat
run:
- zeromq
- libstdcxx-ng
- libgcc-ng
@ -60,11 +63,15 @@ outputs:
- {{compiler('cxx')}}
- libstdcxx-ng
- libgcc-ng
- zeromq
host:
- zeromq
run:
- libstdcxx-ng
- libgcc-ng
- zeromq
- name: slsdet
@ -77,12 +84,10 @@ outputs:
- {{compiler('cxx')}}
- {{ pin_subpackage('slsdetlib', exact=True) }}
- setuptools
- pybind11=2.11
host:
- python
- {{ pin_subpackage('slsdetlib', exact=True) }}
- pybind11=2.11
run:

View File

@ -1,22 +0,0 @@
numfiles 1
nthreads 5,
fifosize 5000
nsigma 5
gainfile none
detectorMode counting
threshold 0
pedestalfile none
nframes 0
xMin 0
xMax 400
yMin 0
yMax 400
outdir ./
indir ./
flist none
fformat none
runmin 0
runmax -1
readnrows 400
eMin 0
eMax 16000

View File

@ -1,16 +0,0 @@
numinterfaces 1
rx_zmqip 10.1.2.102
rx_zmqport 1978
zmqip 129.129.202.57
zmqport 1979
nthreads 6
fifosize 5000
nsigma 5
gainfile none
nbinsx 5
nbinsy 5
etafile none
etabinsx 1000
etabinsy 1000
etamin -1
etamax 2

View File

@ -3,10 +3,3 @@ slsDetectorPackage/7.0.1_rh7 stable cmake/3.15.5 zeromq/4.3.4 Qt/5.12.10
slsDetectorPackage/7.0.1_rh8 stable cmake/3.15.5 zeromq/4.3.4 Qt/5.12.10
slsDetectorPackage/7.0.2_rh7 stable cmake/3.15.5 zeromq/4.3.4 Qt/5.12.10
slsDetectorPackage/7.0.2_rh8 stable cmake/3.15.5 zeromq/4.3.4 Qt/5.12.10
slsDetectorPackage/7.0.3_rh7 stable cmake/3.15.5 zeromq/4.3.4 Qt/5.12.10
slsDetectorPackage/7.0.3_rh8 stable cmake/3.15.5 zeromq/4.3.4 Qt/5.12.10
slsDetectorPackage/8.0.0_rh7 stable cmake/3.15.5 Qt/5.12.10
slsDetectorPackage/8.0.0_rh8 stable cmake/3.15.5 Qt/5.12.10
slsDetectorPackage/8.0.1_rh7 stable cmake/3.15.5 Qt/5.12.10
slsDetectorPackage/8.0.1_rh8 stable cmake/3.15.5 Qt/5.12.10

View File

@ -7,6 +7,7 @@ Build upon the pybind11 example found here: https://github.com/pybind/python_exa
import os
import sys
sys.path.append('../libs/pybind')
from setuptools import setup, find_packages
from pybind11.setup_helpers import Pybind11Extension, build_ext
@ -40,10 +41,11 @@ ext_modules = [
,
include_dirs=[
os.path.join('../libs/pybind/include'),
os.path.join(get_conda_path(), 'include'),
],
libraries=['SlsDetector', 'SlsSupport', 'SlsReceiver'],
libraries=['SlsDetector', 'SlsSupport', 'SlsReceiver', 'zmq'],
library_dirs=[
os.path.join(get_conda_path(), 'lib'),
],

View File

@ -232,7 +232,7 @@ class Detector(CppDetectorApi):
@element
def hardwareversion(self):
"""
Hardware version of detector. \n
[Jungfrau][Moench][Gotthard2][Myhten3][Gotthard][Ctb] Hardware version of detector. \n
[Eiger] Hardware version of front FPGA on detector.
"""
return self.getHardwareVersion()
@ -308,7 +308,7 @@ class Detector(CppDetectorApi):
-----
[Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n
[Mythen3] Options: 8, 16, 32 \n
[Jungfrau][Moench][Gotthard][Ctb][Mythen3][Gotthard2][Xilinx Ctb] 16
[Jungfrau][Moench][Gotthard][Ctb][Mythen3][Gotthard2] 16
"""
return self.getDynamicRange()
@ -400,7 +400,7 @@ class Detector(CppDetectorApi):
@element
def framesl(self):
"""
[Gotthard][Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx CTB] Number of frames left in acquisition.\n
[Gotthard][Jungfrau][Moench][Mythen3][Gotthard2][CTB] Number of frames left in acquisition.\n
Note
----
@ -414,7 +414,7 @@ class Detector(CppDetectorApi):
@element
def framecounter(self):
"""
[Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx Ctb] Number of frames from start run control.
[Jungfrau][Moench][Mythen3][Gotthard2][CTB] Number of frames from start run control.
Note
-----
@ -443,13 +443,12 @@ class Detector(CppDetectorApi):
@element
def powerchip(self):
"""
[Jungfrau][Moench][Mythen3][Gotthard2][Xilinx Ctb] Power the chip.
[Jungfrau][Moench][Mythen3][Gotthard2] Power the chip.
Note
----
[Jungfrau][Moench] Default is disabled. Get will return power status. Can be off if temperature event occured (temperature over temp_threshold with temp_control enabled. Will configure chip (only chip v1.1).\n
[Mythen3][Gotthard2] Default is 1. If module not connected or wrong module, powerchip will fail.
[Xilinx Ctb] Default is 0. Also configures the chip if powered on.
"""
return self.getPowerChip()
@ -457,16 +456,6 @@ class Detector(CppDetectorApi):
def powerchip(self, value):
ut.set_using_dict(self.setPowerChip, value)
def configtransceiver(self):
"""
[Xilinx Ctb] Waits for transceiver to be aligned.
Note
----
Chip had to be configured (powered on) before this.
"""
self.configureTransceiver()
@property
@element
def triggers(self):
@ -631,7 +620,7 @@ class Detector(CppDetectorApi):
@element
def periodl(self):
"""
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Period left for current frame.
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2] Period left for current frame.
Note
-----
@ -653,7 +642,7 @@ class Detector(CppDetectorApi):
@element
def delay(self):
"""
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Delay after trigger, accepts either a value in seconds, DurationWrapper or datetime.timedelta
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2] Delay after trigger, accepts either a value in seconds, DurationWrapper or datetime.timedelta
:getter: always returns in seconds. To get in DurationWrapper, use getDelayAfterTrigger
@ -695,7 +684,7 @@ class Detector(CppDetectorApi):
@element
def delayl(self):
"""
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2][Xilinx Ctb] Delay left after trigger during acquisition, accepts either a value in seconds, datetime.timedelta or DurationWrapper
[Gotthard][Jungfrau][Moench][CTB][Mythen3][Gotthard2] Delay left after trigger during acquisition, accepts either a value in seconds, datetime.timedelta or DurationWrapper
Note
-----
@ -743,7 +732,7 @@ class Detector(CppDetectorApi):
@property
@element
def nextframenumber(self):
"""[Eiger][Jungfrau][Moench][CTB][Xilinx CTB] Next frame number. Stopping acquisition might result in different frame numbers for different modules. """
"""[Eiger][Jungfrau][Moench][CTB] Next frame number. Stopping acquisition might result in different frame numbers for different modules. """
return self.getNextFrameNumber()
@nextframenumber.setter
@ -1962,7 +1951,7 @@ class Detector(CppDetectorApi):
@element
def triggersl(self):
"""
[Gotthard][Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx CTB] Number of triggers left in acquisition.\n
[Gotthard][Jungfrau][Moench][Mythen3][Gotthard2][CTB] Number of triggers left in acquisition.\n
Note
----
@ -1975,7 +1964,7 @@ class Detector(CppDetectorApi):
@property
@element
def frametime(self):
"""[Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx Ctb] Timestamp at a frame start.
"""[Jungfrau][Moench][Mythen3][Gotthard2][CTB] Timestamp at a frame start.
Note
----
@ -2191,7 +2180,7 @@ class Detector(CppDetectorApi):
Note
-----
Default: AUTO_TIMING \n
[Jungfrau][Moench][Gotthard][Ctb][Gotthard2][Xilinx Ctb] AUTO_TIMING, TRIGGER_EXPOSURE \n
[Jungfrau][Moench][Gotthard][Ctb][Gotthard2] AUTO_TIMING, TRIGGER_EXPOSURE \n
[Mythen3] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, TRIGGER_GATED \n
[Eiger] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, BURST_TRIGGER
"""
@ -2613,7 +2602,7 @@ class Detector(CppDetectorApi):
@property
@element
def runtime(self):
"""[Jungfrau][Moench][Mythen3][Gotthard2][CTB][Xilinx Ctb] Time from detector start up.
"""[Jungfrau][Moench][Mythen3][Gotthard2][CTB] Time from detector start up.
Note
-----
@ -3248,7 +3237,7 @@ class Detector(CppDetectorApi):
@property
@element
def transceiverenable(self):
"""[CTB][Xilinx CTB] Transceiver Enable Mask. Enable for each 4 transceiver channel."""
"""[Ctb] Transceiver Enable Mask. Enable for each 4 transceiver channel."""
return self.getTransceiverEnableMask()
@transceiverenable.setter
@ -3287,10 +3276,8 @@ class Detector(CppDetectorApi):
Note
------
[CTB] Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL, TRANSCEIVER_ONLY, DIGITAL_AND_TRANSCEIVER
[CTB] Default: ANALOG_ONLY
[Xilinx CTB] Options: TRANSCEIVER_ONLY
[Xilinx CTB] Default: TRANSCEIVER_ONLY
Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL, TRANSCEIVER_ONLY, DIGITAL_AND_TRANSCEIVER
Default: ANALOG_ONLY
Example
--------
@ -3327,7 +3314,7 @@ class Detector(CppDetectorApi):
@property
@element
def tsamples(self):
"""[CTB][Xilinx CTB] Number of transceiver samples expected. """
"""[CTB] Number of transceiver samples expected. """
return self.getNumberOfTransceiverSamples()
@tsamples.setter
@ -3490,7 +3477,7 @@ class Detector(CppDetectorApi):
@property
def pattern(self):
"""[Mythen3][Ctb][Xilinx Ctb] Loads ASCII pattern file directly to server (instead of executing line by line).
"""[Mythen3][Ctb] Loads ASCII pattern file directly to server (instead of executing line by line).
:getter: Not Implemented
@ -3508,7 +3495,7 @@ class Detector(CppDetectorApi):
@property
def patfname(self):
"""
[Ctb][Mythen3][Xilinx Ctb] Gets the pattern file name including path of the last pattern uploaded. Returns an empty if nothing was uploaded or via a server default
[Ctb][Mythen3] Gets the pattern file name including path of the last pattern uploaded. Returns an empty if nothing was uploaded or via a server default
file
"""
return self.getPatterFileName()
@ -3533,7 +3520,7 @@ class Detector(CppDetectorApi):
@property
@element
def patlimits(self):
"""[Ctb][Mythen3][Xilinx Ctb] Limits (start and stop address) of complete pattern.
"""[Ctb][Mythen3] Limits (start and stop address) of complete pattern.
Example
---------
@ -3553,7 +3540,7 @@ class Detector(CppDetectorApi):
@property
@element
def patsetbit(self):
"""[Ctb][Mythen3][Xilinx Ctb] Sets the mask applied to every pattern to the selected bits.
"""[Ctb][Mythen3] Sets the mask applied to every pattern to the selected bits.
Example
--------
@ -3570,7 +3557,7 @@ class Detector(CppDetectorApi):
@property
@element
def patmask(self):
"""[Ctb][Mythen3][Xilinx Ctb] Selects the bits that will have a pattern mask applied to the selected patmask for every pattern.
"""[Ctb][Mythen3] Selects the bits that will have a pattern mask applied to the selected patmask for every pattern.
Example
--------
@ -3588,7 +3575,7 @@ class Detector(CppDetectorApi):
# @element
def patwait(self):
"""
[Ctb][Mythen3][Xilinx Ctb] Wait address of loop level provided.
[Ctb][Mythen3] Wait address of loop level provided.
Example
-------
@ -3605,7 +3592,7 @@ class Detector(CppDetectorApi):
@property
@element
def patwait0(self):
"""[Ctb][Mythen3][Xilinx Ctb] Wait 0 address.
"""[Ctb][Mythen3] Wait 0 address.
Example
--------
@ -3625,7 +3612,7 @@ class Detector(CppDetectorApi):
@property
@element
def patwait1(self):
"""[Ctb][Mythen3][Xilinx Ctb] Wait 1 address.
"""[Ctb][Mythen3] Wait 1 address.
Example
--------
@ -3645,7 +3632,7 @@ class Detector(CppDetectorApi):
@property
@element
def patwait2(self):
"""[Ctb][Mythen3][Xilinx Ctb] Wait 2 address.
"""[Ctb][Mythen3] Wait 2 address.
Example
--------
@ -3665,7 +3652,7 @@ class Detector(CppDetectorApi):
@property
def patwaittime(self):
"""
[Ctb][Mythen3][Xilinx Ctb] Wait time in clock cycles of loop level provided.
[Ctb][Mythen3] Wait time in clock cycles of loop level provided.
Example
-------
@ -3682,7 +3669,7 @@ class Detector(CppDetectorApi):
@property
@element
def patwaittime0(self):
"""[Ctb][Mythen3][Xilinx Ctb] Wait 0 time in clock cycles."""
"""[Ctb][Mythen3] Wait 0 time in clock cycles."""
return self.getPatternWaitTime(0)
@patwaittime0.setter
@ -3693,7 +3680,7 @@ class Detector(CppDetectorApi):
@property
@element
def patwaittime1(self):
"""[Ctb][Mythen3][Xilinx Ctb] Wait 1 time in clock cycles."""
"""[Ctb][Mythen3] Wait 1 time in clock cycles."""
return self.getPatternWaitTime(1)
@patwaittime1.setter
@ -3704,7 +3691,7 @@ class Detector(CppDetectorApi):
@property
@element
def patwaittime2(self):
"""[Ctb][Mythen3][Xilinx Ctb] Wait 2 time in clock cycles."""
"""[Ctb][Mythen3] Wait 2 time in clock cycles."""
return self.getPatternWaitTime(2)
@patwaittime2.setter
@ -3716,7 +3703,7 @@ class Detector(CppDetectorApi):
@property
def patloop(self):
"""
[Ctb][Mythen3][Xilinx Ctb] Limits (start and stop address) of the loop provided.
[Ctb][Mythen3] Limits (start and stop address) of the loop provided.
Example
-------
@ -3733,7 +3720,7 @@ class Detector(CppDetectorApi):
@property
@element
def patloop0(self):
"""[Ctb][Mythen3][Xilinx Ctb] Limits (start and stop address) of loop 0.
"""[Ctb][Mythen3] Limits (start and stop address) of loop 0.
Example
---------
@ -3753,7 +3740,7 @@ class Detector(CppDetectorApi):
@property
@element
def patloop1(self):
"""[Ctb][Mythen3][Xilinx Ctb] Limits (start and stop address) of loop 1.
"""[Ctb][Mythen3] Limits (start and stop address) of loop 1.
Example
---------
@ -3774,7 +3761,7 @@ class Detector(CppDetectorApi):
@property
@element
def patloop2(self):
"""[Ctb][Mythen3][Xilinx Ctb] Limits (start and stop address) of loop 2.
"""[Ctb][Mythen3] Limits (start and stop address) of loop 2.
Example
---------
@ -3796,7 +3783,7 @@ class Detector(CppDetectorApi):
@property
def patnloop(self):
"""
[Ctb][Mythen3][Xilinx Ctb] Number of cycles of the loop provided.
[Ctb][Mythen3] Number of cycles of the loop provided.
Example
-------
@ -3813,7 +3800,7 @@ class Detector(CppDetectorApi):
@property
@element
def patnloop0(self):
"""[Ctb][Mythen3][Xilinx Ctb] Number of cycles of loop 0."""
"""[Ctb][Mythen3] Number of cycles of loop 0."""
return self.getPatternLoopCycles(0)
@patnloop0.setter
@ -3824,7 +3811,7 @@ class Detector(CppDetectorApi):
@property
@element
def patnloop1(self):
"""[Ctb][Mythen3][Xilinx Ctb] Number of cycles of loop 1."""
"""[Ctb][Mythen3] Number of cycles of loop 1."""
return self.getPatternLoopCycles(1)
@patnloop1.setter
@ -3835,7 +3822,7 @@ class Detector(CppDetectorApi):
@property
@element
def patnloop2(self):
"""[Ctb][Mythen3][Xilinx Ctb] Number of cycles of loop 2."""
"""[Ctb][Mythen3] Number of cycles of loop 2."""
return self.getPatternLoopCycles(2)
@patnloop2.setter
@ -3846,7 +3833,7 @@ class Detector(CppDetectorApi):
@property
@element
def v_a(self):
"""[Ctb][Xilinx Ctb] Power supply a in mV."""
"""[Ctb] Power supply a in mV."""
return self.getPower(dacIndex.V_POWER_A)
@v_a.setter
@ -3857,7 +3844,7 @@ class Detector(CppDetectorApi):
@property
@element
def v_b(self):
"""[Ctb][Xilinx Ctb] Power supply b in mV."""
"""[Ctb] Power supply b in mV."""
return self.getPower(dacIndex.V_POWER_B)
@v_b.setter
@ -3868,7 +3855,7 @@ class Detector(CppDetectorApi):
@property
@element
def v_c(self):
"""[Ctb][Xilinx Ctb] Power supply c in mV."""
"""[Ctb] Power supply c in mV."""
return self.getPower(dacIndex.V_POWER_C)
@v_c.setter
@ -3879,7 +3866,7 @@ class Detector(CppDetectorApi):
@property
@element
def v_d(self):
"""[Ctb][Xilinx Ctb] Power supply d in mV."""
"""[Ctb] Power supply d in mV."""
return self.getPower(dacIndex.V_POWER_D)
@v_d.setter
@ -3890,7 +3877,7 @@ class Detector(CppDetectorApi):
@property
@element
def v_io(self):
"""[Ctb][Xilinx Ctb] Power supply io in mV. Minimum 1200 mV.
"""[Ctb] Power supply io in mV. Minimum 1200 mV.
Note
----
@ -3906,7 +3893,7 @@ class Detector(CppDetectorApi):
@property
@element
def v_limit(self):
"""[Ctb][Xilinx Ctb] Soft limit for power supplies (ctb only) and DACS in mV."""
"""[Ctb] Soft limit for power supplies (ctb only) and DACS in mV."""
return self.getPower(dacIndex.V_LIMIT)
@v_limit.setter

View File

@ -1778,10 +1778,6 @@ void init_det(py::module &m) {
(std::string(Detector::*)(const defs::dacIndex) const) &
Detector::getSlowADCName,
py::arg());
CppDetectorApi.def("configureTransceiver",
(void (Detector::*)(sls::Positions)) &
Detector::configureTransceiver,
py::arg() = Positions{});
CppDetectorApi.def(
"getPatterFileName",
(Result<std::string>(Detector::*)(sls::Positions) const) &

View File

@ -25,8 +25,6 @@ void init_enums(py::module &m) {
.value("MOENCH", slsDetectorDefs::detectorType::MOENCH)
.value("MYTHEN3", slsDetectorDefs::detectorType::MYTHEN3)
.value("GOTTHARD2", slsDetectorDefs::detectorType::GOTTHARD2)
.value("XILINX_CHIPTESTBOARD",
slsDetectorDefs::detectorType::XILINX_CHIPTESTBOARD)
.export_values();
py::enum_<slsDetectorDefs::runStatus>(Defs, "runStatus")

View File

@ -1 +0,0 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer

View File

@ -0,0 +1 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv8.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer

View File

@ -0,0 +1 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv8.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv8.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv8.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer

View File

@ -0,0 +1 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv8.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer

View File

@ -0,0 +1 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv8.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer

View File

@ -0,0 +1 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv8.0.0

View File

@ -1,240 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#ifndef MOENCH03v2DATA_H
#define MOENCH03v2DATA_H
//#define MYROOT
#ifndef MYROOT
#include "sls/sls_detector_defs.h"
#endif
#ifdef MYROOT
typedef struct {
uint64_t frameNumber;
uint32_t expLength;
uint32_t packetNumber;
uint64_t bunchId;
uint64_t timestamp;
uint16_t modId;
uint16_t row;
uint16_t column;
uint16_t reserved;
uint32_t debug;
uint16_t roundRNumber;
uint8_t detType;
uint8_t version;
} sls_detector_header;
#define MAX_NUM_PACKETS 512
// using sls_bitset = std::bitset<MAX_NUM_PACKETS>;
// using bitset_storage = uint8_t[MAX_NUM_PACKETS / 8];
struct sls_receiver_header {
sls_detector_header detHeader; /**< is the detector header */
uint8_t packetsMask[64]; /**< is the packets caught bit mask */
};
#endif
#include "slsDetectorData.h"
#ifdef RAWDATA
#define DATA_OFFSET sizeof(header)
#endif
#ifndef RAWDATA
#define DATA_OFFSET 0
#endif
class moench03v2Data : public slsDetectorData<uint16_t> {
private:
int iframe;
const int nRows;
double ghost[200][25];
// Single point of definition if we need to customize
#ifndef MYROOT
using header = sls::defs::sls_receiver_header;
#endif
#ifdef MYROOT
sls_receiver_header header;
#endif
public:
/**
Implements the slsReceiverData structure for the moench02 prototype read
out by a module i.e. using the slsReceiver (160x160 pixels, 40 packets
1286 large etc.) \param c crosstalk parameter for the output buffer
*/
moench03v2Data(int nrows = 200)
: slsDetectorData<uint16_t>(400, nrows*2,2* 400*nrows*2 + DATA_OFFSET),
nRows(nrows) {
std::cout << "MOENCH width new firmware " << dataSize << std::endl;
int off=DATA_OFFSET;
for (int ix = 0; ix < 400; ix++) {
for (int iy = 0; iy < nRows*2; iy++) {
dataMap[iy][ix]=off+2*(iy*400+ix);
}
}
iframe = 0;
// cout << "data struct created" << endl;
};
/**
Returns the value of the selected channel for the given dataset as
double. \param data pointer to the dataset (including headers etc) \param
ix pixel number in the x direction \param iy pixel number in the y
direction \returns data for the selected channel, with inversion if
required as double
*/
double getValue(char *data, int ix, int iy = 0) override {
uint16_t val = getChannel(data, ix, iy) & 0x3fff;
return val;
};
virtual void calcGhost(char *data, int ix, int iy) {
double val = 0;
/* for (int ix=0; ix<25; ix++){ */
/* for (int iy=0; iy<200; iy++) { */
val = 0;
// cout << "** ";
for (int isc = 0; isc < 16; isc++) {
// for (int ii=0; ii<2; ii++) {
val += getChannel(data, ix + 25 * isc, iy);
// cout << "(" << isc << "," << val << " " ;
val += getChannel(data, ix + 25 * isc, 399 - iy);
// cout << val << " " ;
// }
}
ghost[iy][ix] = val; //-6224;
// cout << " --"<< endl;
/* } */
/* } */
// cout << "*" << endl;
}
virtual void calcGhost(char *data) {
for (int ix = 0; ix < 25; ix++) {
for (int iy = 0; iy < 200; iy++) {
calcGhost(data, ix, iy);
}
}
// cout << "*" << endl;
}
double getGhost(int ix, int iy) {
if (iy < 200)
return ghost[iy][ix % 25];
if (iy < 400)
return ghost[399 - iy][ix % 25];
return 0;
};
/**
Returns the frame number for the given dataset. Purely virtual func.
\param buff pointer to the dataset
\returns frame number
*/
int getFrameNumber(char *buff) {
#ifdef RAWDATA
return ((sls::defs::sls_receiver_header *)buff)->detHeader.frameNumber;
#endif
#ifndef RAWDATA
return 1;
#endif
}
/**
Returns the packet number for the given dataset. purely virtual func
\param buff pointer to the dataset
\returns packet number number
*/
int getPacketNumber(char *buff) {
#ifdef RAWDATA
return ((sls::defs::sls_receiver_header *)buff)->detHeader.packetNumber;
#endif
#ifndef RAWDATA
return 0;
#endif
}
char *readNextFrame(std::ifstream &filebin) override {
int ff = -1, np = -1;
return readNextFrame(filebin, ff, np);
}
// not present in base class
virtual char *readNextFrame(std::ifstream &filebin, int &ff) {
int np = -1;
return readNextFrame(filebin, ff, np);
};
// not present in base class
virtual char *readNextFrame(std::ifstream &filebin, int &ff, int &np) {
char *data = new char[dataSize];
char *d = readNextFrame(filebin, ff, np, data);
if (d == NULL) {
delete[] data;
data = NULL;
}
return data;
}
// not present in base class
virtual char *readNextFrame(std::ifstream &filebin, int &ff, int &np,
char *data) {
np = 0;
if (filebin.is_open()) {
if (filebin.read(data, dataSize)) {
ff = getFrameNumber(data);
np = getPacketNumber(data);
// std::cout << "**" << ff << " " << dataSize << " " << ff << " " << np << std::endl;
return data;
}
}
std::cout << "**" << ff << " " << dataSize << " " << ff << " " << np << std::endl;
return nullptr;
}
/**
Loops over a memory slot until a complete frame is found (i.e. all
packets 0 to nPackets, same frame number). purely virtual func \param
data pointer to the memory to be analyzed \param ndata reference to the
amount of data found for the frame, in case the frame is incomplete at
the end of the memory slot \param dsize size of the memory slot to be
analyzed \returns pointer to the beginning of the last good frame (might
be incomplete if ndata smaller than dataSize), or NULL if no frame is
found
*/
char *findNextFrame(char *data, int &ndata, int dsize) override {
if (dsize < dataSize)
ndata = dsize;
else
ndata = dataSize;
return data;
}
// int getPacketNumber(int x, int y) {return dataMap[y][x]/packetSize;};
};
#endif

View File

@ -1,240 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#ifndef MOENCH03v2DATA_H
#define MOENCH03v2DATA_H
//#define MYROOT
#ifndef MYROOT
#include "sls/sls_detector_defs.h"
#endif
#ifdef MYROOT
typedef struct {
uint64_t frameNumber;
uint32_t expLength;
uint32_t packetNumber;
uint64_t bunchId;
uint64_t timestamp;
uint16_t modId;
uint16_t row;
uint16_t column;
uint16_t reserved;
uint32_t debug;
uint16_t roundRNumber;
uint8_t detType;
uint8_t version;
} sls_detector_header;
#define MAX_NUM_PACKETS 512
// using sls_bitset = std::bitset<MAX_NUM_PACKETS>;
// using bitset_storage = uint8_t[MAX_NUM_PACKETS / 8];
struct sls_receiver_header {
sls_detector_header detHeader; /**< is the detector header */
uint8_t packetsMask[64]; /**< is the packets caught bit mask */
};
#endif
#include "slsDetectorData.h"
#ifdef RAWDATA
#define DATA_OFFSET sizeof(header)
#endif
#ifndef RAWDATA
#define DATA_OFFSET 0
#endif
class moench03v2Data : public slsDetectorData<uint16_t> {
private:
int iframe;
const int nRows;
double ghost[200][25];
// Single point of definition if we need to customize
#ifndef MYROOT
using header = sls::defs::sls_receiver_header;
#endif
#ifdef MYROOT
sls_receiver_header header;
#endif
public:
/**
Implements the slsReceiverData structure for the moench02 prototype read
out by a module i.e. using the slsReceiver (160x160 pixels, 40 packets
1286 large etc.) \param c crosstalk parameter for the output buffer
*/
moench03v2Data(int nrows = 200)
: slsDetectorData<uint16_t>(400, nrows*2,2* 400*nrows*2 + DATA_OFFSET),
nRows(nrows) {
std::cout << "MOENCH width new firmware " << dataSize << std::endl;
int off=DATA_OFFSET;
for (int ix = 0; ix < 400; ix++) {
for (int iy = 0; iy < nRows*2; iy++) {
dataMap[iy][ix]=off+2*(iy*400+ix);
}
}
iframe = 0;
// cout << "data struct created" << endl;
};
/**
Returns the value of the selected channel for the given dataset as
double. \param data pointer to the dataset (including headers etc) \param
ix pixel number in the x direction \param iy pixel number in the y
direction \returns data for the selected channel, with inversion if
required as double
*/
double getValue(char *data, int ix, int iy = 0) override {
uint16_t val = getChannel(data, ix, iy) & 0x3fff;
return val;
};
virtual void calcGhost(char *data, int ix, int iy) {
double val = 0;
/* for (int ix=0; ix<25; ix++){ */
/* for (int iy=0; iy<200; iy++) { */
val = 0;
// cout << "** ";
for (int isc = 0; isc < 16; isc++) {
// for (int ii=0; ii<2; ii++) {
val += getChannel(data, ix + 25 * isc, iy);
// cout << "(" << isc << "," << val << " " ;
val += getChannel(data, ix + 25 * isc, 399 - iy);
// cout << val << " " ;
// }
}
ghost[iy][ix] = val; //-6224;
// cout << " --"<< endl;
/* } */
/* } */
// cout << "*" << endl;
}
virtual void calcGhost(char *data) {
for (int ix = 0; ix < 25; ix++) {
for (int iy = 0; iy < 200; iy++) {
calcGhost(data, ix, iy);
}
}
// cout << "*" << endl;
}
double getGhost(int ix, int iy) {
if (iy < 200)
return ghost[iy][ix % 25];
if (iy < 400)
return ghost[399 - iy][ix % 25];
return 0;
};
/**
Returns the frame number for the given dataset. Purely virtual func.
\param buff pointer to the dataset
\returns frame number
*/
int getFrameNumber(char *buff) {
#ifdef RAWDATA
return ((sls::defs::sls_receiver_header *)buff)->detHeader.frameNumber;
#endif
#ifndef RAWDATA
return 1;
#endif
}
/**
Returns the packet number for the given dataset. purely virtual func
\param buff pointer to the dataset
\returns packet number number
*/
int getPacketNumber(char *buff) {
#ifdef RAWDATA
return ((sls::defs::sls_receiver_header *)buff)->detHeader.packetNumber;
#endif
#ifndef RAWDATA
return 0;
#endif
}
char *readNextFrame(std::ifstream &filebin) override {
int ff = -1, np = -1;
return readNextFrame(filebin, ff, np);
}
// not present in base class
virtual char *readNextFrame(std::ifstream &filebin, int &ff) {
int np = -1;
return readNextFrame(filebin, ff, np);
};
// not present in base class
virtual char *readNextFrame(std::ifstream &filebin, int &ff, int &np) {
char *data = new char[dataSize];
char *d = readNextFrame(filebin, ff, np, data);
if (d == NULL) {
delete[] data;
data = NULL;
}
return data;
}
// not present in base class
virtual char *readNextFrame(std::ifstream &filebin, int &ff, int &np,
char *data) {
np = 0;
if (filebin.is_open()) {
if (filebin.read(data, dataSize)) {
ff = getFrameNumber(data);
np = getPacketNumber(data);
std::cout << "**" << ff << " " << dataSize << " " << ff << " " << np << std::endl;
return data;
}
}
std::cout << "**" << ff << " " << dataSize << " " << ff << " " << np << std::endl;
return nullptr;
}
/**
Loops over a memory slot until a complete frame is found (i.e. all
packets 0 to nPackets, same frame number). purely virtual func \param
data pointer to the memory to be analyzed \param ndata reference to the
amount of data found for the frame, in case the frame is incomplete at
the end of the memory slot \param dsize size of the memory slot to be
analyzed \returns pointer to the beginning of the last good frame (might
be incomplete if ndata smaller than dataSize), or NULL if no frame is
found
*/
char *findNextFrame(char *data, int &ndata, int dsize) override {
if (dsize < dataSize)
ndata = dsize;
else
ndata = dataSize;
return data;
}
// int getPacketNumber(int x, int y) {return dataMap[y][x]/packetSize;};
};
#endif

View File

@ -33,7 +33,7 @@ int main(int argc, char *argv[]) {
#ifndef FF
if (argc < 9) {
cout << "Wrong usage! Should be: " << argv[0]
<< " infile etafile outfile runmin runmax ns [cmin cmax xmin xmax ymin ymax]" << endl;
<< " infile etafile outfile runmin runmax ns cmin cmax" << endl;
return 1;
}
#endif
@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
#ifdef FF
if (argc < 7) {
cout << "Wrong usage! Should be: " << argv[0]
<< " infile etafile runmin runmax [cmin cmax xmin xmax ymin ymax]" << endl;
<< " infile etafile runmin runmax cmin cmax" << endl;
return 1;
}
#endif
@ -65,30 +65,13 @@ int main(int argc, char *argv[]) {
nsubpix = atoi(argv[iarg++]);
cout << "Subpix: " << nsubpix << endl;
#endif
float cmin = 0;
float cmax=1000000;
if (argc>iarg)
cmin=atof(argv[iarg++]);
if (argc>iarg)
cmax= atof(argv[iarg++]);
float cmin = atof(argv[iarg++]);
float cmax = atof(argv[iarg++]);
cout << "Energy min: " << cmin << endl;
cout << "Energy max: " << cmax << endl;
int xmin=0, xmax=NC, ymin=0, ymax=NR;
if (argc>iarg)
xmin=atof(argv[iarg++]);
if (argc>iarg)
xmax= atof(argv[iarg++]);
if (argc>iarg)
ymin=atof(argv[iarg++]);
if (argc>iarg)
ymax= atof(argv[iarg++]);
// int etabins=500;
int etabins = 1000; // nsubpix*2*100;
double etamin = -0.25, etamax = 1.25;
double etamin = -1, etamax = 2;
// double etamin=-0.1, etamax=1.1;
// double eta3min = -2, eta3max = 2;
double sum, totquad;
@ -97,7 +80,7 @@ int main(int argc, char *argv[]) {
// double eta3x, eta3y, int3_x, int3_y, noint_x, noint_y;
int ix, iy, isx, isy;
int nframes = 0, lastframe = -1, iframe, nphFrame;
int nframes = 0, lastframe = -1;
//double d_x, d_y, res = 5, xx, yy;
int nph = 0, totph = 0;
//badph = 0,
@ -115,7 +98,7 @@ int main(int argc, char *argv[]) {
// int nSubPixels = nsubpix;
#ifndef NOINTERPOLATION
eta2InterpolationPosXY *interp =
new eta2InterpolationPosXY(NC, NR, nsubpix, nsubpix, etabins, etabins, etamin, etamax);
new eta2InterpolationPosXY(NC, NR, nsubpix, nsubpix,etabins,etabins, etamin, etamax);
// eta2InterpolationCleverAdaptiveBins *interp=new
// eta2InterpolationCleverAdaptiveBins(NC, NR, nsubpix, etabins, etamin,
// etamax);
@ -124,8 +107,8 @@ int main(int argc, char *argv[]) {
noInterpolation *interp = new noInterpolation(NC, NR, nsubpix);
#endif
int quad;
#ifndef FF
int quad;
#ifndef NOINTERPOLATION
char fname[10000];
int ok;
@ -159,26 +142,19 @@ int main(int argc, char *argv[]) {
#endif
int irun;
for (irun = runmin; irun <= runmax; irun++) {
for (irun = runmin; irun < runmax; irun++) {
sprintf(infname, argv[1], irun);
#ifndef FF
sprintf(outfname, argv[3], irun);
#endif
f = fopen(infname, "r");
if (f) {
cout << infname << endl;
nframes = 0;
//f0 = -1;
//iff=0;
while (fread((void*)&iframe, 1, sizeof(int), f)) {
//n=0;
if (fread((void*)&nphFrame, 1, sizeof(int), f)) {
for (int iph=0; iph<nphFrame; iph++) {
//while (cl.read(f)) {
if (cl.read(f)) {
while (cl.read(f)) {
totph++;
if (lastframe != cl.iframe) {
lastframe = cl.iframe;
@ -189,28 +165,18 @@ int main(int argc, char *argv[]) {
nframes++;
}
// quad=interp->calcQuad(cl.get_cluster(), sum, totquad, sDum);
// #ifndef FF
// quad = interp->calcEta(cl.get_cluster(), etax, etay, sum,
// totquad, sDum);
// #endif
// #ifdef FF
#ifndef FF
quad = interp->calcEta(cl.get_cluster(), etax, etay, sum,
totquad, sDum);
/* cl.print();
cout << "(" << etax <<","<< etay <<")"<< quad<< endl;
*/
//#endif
#endif
#ifdef FF
interp->calcEta(cl.get_cluster(), etax, etay, sum,
totquad, sDum);
#endif
if (totquad > cmin && cl.x >= xmin && cl.x <= xmax &&
cl.y >= ymin && cl.y <= ymax &&
totquad < cmax) {
// if (sum > cmin && totquad / sum > 0.8 && totquad / sum < 1.2 &&
// sum < cmax) {
nph++;
if (sum > cmin && totquad / sum > 0.8 && totquad / sum < 1.2 &&
sum < cmax) {
nph++;
// if (sum>200 && sum<580) {
// interp->getInterpolatedPosition(cl.x,cl.y,
// totquad,quad,cl.get_cluster(),int_x, int_y);
@ -261,12 +227,9 @@ int main(int argc, char *argv[]) {
#ifdef FF
interp->writeFlatField(outfname);
#endif
}
}
}
}
}
}
}
fclose(f);
#ifdef FF

View File

@ -13,7 +13,7 @@
#ifndef MOENCH04
#ifndef RECT
#include "moench03v2Data.h"
#include "moench03T1ReceiverDataNew.h"
#endif
#endif
@ -41,148 +41,34 @@ using namespace std;
int main(int argc, char *argv[]) {
std::map<std::string, std::string> args = {
{"numfiles","1"},
{"nthreads","5"},
{"fifosize","5000"},
{"nsigma","5"},
{"gainfile","none"},
{"detectorMode","counting"},
{"threshold","0"},
{"pedestalfile","none"},
{"nframes","0"},
{"xMin","0"},
{"xMax","400"},
{"yMin","0"},
{"yMax","400"},
{"eMin","0"},
{"eMax","16000"},
{"outdir","./"},
{"indir","./"},
{"flist","none"},
{"fformat","none"},
{"runmin","0"},
{"runmax","-1"},
{"readnrows","400"}
};
//float *gm;
int ff, np;
// cout << " data size is " << dsize;
ifstream filebin;
if (argc < 4) {
std::string name, value,sline;
int ic=0;
ifstream flist;
flist.open (argv[1], std::ifstream::in);
if (flist.is_open()) {
cout << "Using config file " <<argv[1] << endl;
while (std::getline(flist,sline)){
if (sline.at(0)!='#') {
ic=sline.find(' ');
name = sline.substr(0,ic);
value = sline.substr(ic+1,sline.size()-ic);
args[name]=value;
}
}
flist.close();
} else {
if (argc < 4) {
cout << "Usage is " << argv[0]
<< "indir outdir fname(no extension) [runmin] [runmax] [pedfile (raw or tiff)] [threshold] "
"[nframes] [xmin xmax ymin ymax] [gainmap]"
"[nframes] [xmin xmax ymin ymax] [gainmap]"
<< endl;
cout << "threshold <0 means analog; threshold=0 means cluster finder; "
"threshold>0 means photon counting"
"threshold>0 means photon counting"
<< endl;
cout << "nframes <0 means sum everything; nframes=0 means one file per "
"run; nframes>0 means one file every nframes"
"run; nframes>0 means one file every nframes"
<< endl;
return EXIT_FAILURE;
}
} else {
args["indir"]=argv[1];
args["outdir"]=argv[1];
args["fformat"]=argv[3];
if (argc >= 5) {
args["runmin"] = argv[4];
}
args["runmax"] = args["runmin"];
if (argc >= 6) {
args["runmax"] = argv[5];
}
if (argc >= 7) {
args["pedestalfile"] = argv[6];
}
if (argc >= 8) {
args["threshold"] = argv[7];
}
if (argc >= 9) {
args["nframes"] = argv[8];
}
if (argc >= 13) {
args["xMin"] = argv[9];
args["xMax"] = argv[10];
args["yMin"] = argv[11];
args["yMax"] = argv[12];
}
if (argc > 13) {
args["gainfile"] = argv[13];
}
if (atof(args["threshold"].c_str())<0) {
args["detectorMode"]="analog";
}
return 1;
}
for (auto const& x : args)
{
std::cout << x.first // string (key)
<< ':'
<< x.second // string's value
<< std::endl;
}
string indir=args["indir"];
string outdir = args["outdir"];
string fformat= args["fformat"];
int runmin = atoi(args["runmin"].c_str());
int runmax = atoi(args["runmin"].c_str());
string pedfile =args["pedestalfile"];
double thr = atof(args["threshold"].c_str());
double thr1 = 1;
int nframes = atoi(args["nframes"].c_str());
int xmin = atoi(args["xMin"].c_str()), xmax = atoi(args["xMax"].c_str()), ymin = atoi(args["yMin"].c_str()), ymax = atoi(args["yMax"].c_str());
string gainfname=args["gainfile"];
int fifosize = atoi(args["fifosize"].c_str());
int nthreads = atoi(args["nthreads"].c_str());
int nsigma = atoi(args["nsigma"].c_str());
int nrows = atoi(args["readnrows"].c_str());
float eMin = atof(args["eMin"].c_str());
float eMax = atof(args["eMax"].c_str());
int fifosize = 1000;
int nthreads = 10;
int csize = 3;
int nped = 1000;
int nsigma = 5;
int nped = 10000;
int cf = 0;
int numberOfPackets=nrows/8;
int numberOfPackets=40;
#ifdef RECT
cout << "Should be rectangular but now it will crash! No data structure defined!" << endl;
#endif
#ifndef MOENCH04
moench03v2Data *decoder = new moench03v2Data(100);
moench03T1ReceiverDataNew *decoder = new moench03T1ReceiverDataNew();
cout << "MOENCH03!" << endl;
#endif
@ -191,7 +77,7 @@ int main(int argc, char *argv[]) {
moench04CtbZmq10GbData *decoder = new moench04CtbZmq10GbData(5000,0);
cout << "MOENCH04!" << endl;
#endif
#ifdef MOENCH04_DGS
moench04CtbZmq10GbData *decoder = new moench04CtbZmq10GbData(5000,5000);
cout << "MOENCH04 DGS!" << endl;
@ -200,11 +86,63 @@ int main(int argc, char *argv[]) {
#endif
//Read detector size from decoder
int nx , ny;
decoder->getDetectorSize(nx, ny);
//Read detector size from decoder
//float *gm;
int ff, np;
// cout << " data size is " << dsize;
ifstream filebin;
char *indir = argv[1];
char *outdir = argv[2];
char *fformat = argv[3];
int runmin = 0;
// cout << "argc is " << argc << endl;
if (argc >= 5) {
runmin = atoi(argv[4]);
}
int runmax = runmin;
if (argc >= 6) {
runmax = atoi(argv[5]);
}
char *pedfile = NULL;
if (argc >= 7) {
pedfile = argv[6];
}
double thr = 0;
double thr1 = 1;
if (argc >= 8) {
thr = atof(argv[7]);
}
int nframes = 0;
if (argc >= 9) {
nframes = atoi(argv[8]);
}
int xmin = 0, xmax = nx, ymin = 0, ymax = ny;
if (argc >= 13) {
xmin = atoi(argv[9]);
xmax = atoi(argv[10]);
ymin = atoi(argv[11]);
ymax = atoi(argv[12]);
}
char *gainfname = NULL;
if (argc > 13) {
gainfname = argv[13];
cout << "Gain map file name is: " << gainfname << endl;
}
char ffname[10000];
char fname[10000];
char imgfname[10000];
@ -213,6 +151,17 @@ int main(int argc, char *argv[]) {
std::time_t end_time;
FILE *of = NULL;
cout << "input directory is " << indir << endl;
cout << "output directory is " << outdir << endl;
cout << "input file is " << fformat << endl;
cout << "runmin is " << runmin << endl;
cout << "runmax is " << runmax << endl;
if (pedfile)
cout << "pedestal file is " << pedfile << endl;
if (thr > 0)
cout << "threshold is " << thr << endl;
cout << "Nframes is " << nframes << endl;
uint32_t nnx, nny;
@ -233,62 +182,50 @@ int main(int argc, char *argv[]) {
singlePhotonDetector *filter = new singlePhotonDetector(
decoder, csize, nsigma, 1, cm, nped, 200, -1, -1, gainmap, gs);
//if (gainfname) {
if (gainfname) {
if (filter->readGainMap(gainfname.c_str()))
if (filter->readGainMap(gainfname))
cout << "using gain map " << gainfname << endl;
else
cout << "Could not open gain map " << gainfname << endl;
// } else
thr = 0.15 * thr;
} else
thr = 0.15 * thr;
filter->newDataSet();
//int dsize = decoder->getDataSize();
if (thr > 0) {
cout << "threshold is " << thr << endl;
filter->setThreshold(thr);
cf = 0;
cout << "threshold is " << thr << endl;
filter->setThreshold(thr);
cf = 0;
} else
cf = 1;
cf = 1;
filter->setROI(xmin, xmax, ymin, ymax);
filter->setEnergyRange(eMin, eMax);
std::time(&end_time);
cout << std::ctime(&end_time) << endl;
char *buff;
// multiThreadedAnalogDetector *mt=new
// multiThreadedAnalogDetector(filter,nthreads,fifosize);
multiThreadedCountingDetector *mt =
new multiThreadedCountingDetector(filter, nthreads, fifosize);
if (args["detectorMode"]=="counting") {
mt->setDetectorMode(ePhotonCounting);
if (thr > 0) {
#ifndef ANALOG
mt->setDetectorMode(ePhotonCounting);
cout << "Counting!" << endl;
if (thr > 0) {
cf = 0;
}
} else {
mt->setDetectorMode(eAnalog);
cf = 0;
}
// #ifndef ANALOG
// mt->setDetectorMode(ePhotonCounting);
// cout << "Counting!" << endl;
// if (thr > 0) {
// cf = 0;
// }
// #endif
// //{
// #ifdef ANALOG
// mt->setDetectorMode(eAnalog);
// cout << "Analog!" << endl;
// cf = 0;
// // thr1=thr;
// #endif
// // }
#endif
//{
#ifdef ANALOG
mt->setDetectorMode(eAnalog);
cout << "Analog!" << endl;
cf = 0;
// thr1=thr;
#endif
// }
mt->StartThreads();
mt->popFree(buff);
@ -299,122 +236,84 @@ int main(int argc, char *argv[]) {
char froot[1000];
double *ped=new double[nx * ny];//, *ped1;
int pos,pos1;
//return 0;
if (pedfile.find(".raw") != std::string::npos) {
pos1=pedfile.rfind("/");
strcpy(froot,pedfile.substr(pos1).c_str());
pos=string(froot).find(".raw");
froot[pos]='\0';
}
cout << "PEDESTAL " << endl;
if (pedfile.find(".tif") == std::string::npos) {
sprintf(fname, "%s", pedfile.c_str());
if (pedfile) {
if (string(pedfile).find(".raw") != std::string::npos) {
pos1=string(pedfile).rfind("/");
strcpy(froot,pedfile+pos1);
pos=string(froot).find(".raw");
froot[pos]='\0';
}
cout << "PEDESTAL " << endl;
if (string(pedfile).find(".tif") == std::string::npos) {
sprintf(fname, "%s", pedfile);
cout << fname << endl;
std::time(&end_time);
//cout << "aaa" << std::ctime(&end_time) << endl;
mt->setFrameMode(ePedestal);
// sprintf(fn,fformat,irun);
filebin.open((const char *)(fname), ios::in | ios::binary);
// //open file
if (filebin.is_open()) {
ff = -1;
ff = -1;
while (decoder->readNextFrame(filebin, ff, np, buff)) {
if (np == numberOfPackets) {
mt->pushData(buff);
if (np == numberOfPackets) {
mt->pushData(buff);
mt->nextThread();
mt->popFree(buff);
ifr++;
if (ifr % 100 == 0)
cout << ifr << " " << ff << " " << np << endl;
// break;
} else {
cout << ifr << " " << ff << " " << np << endl;
break;
}
if (ifr % 100 == 0)
cout << ifr << " " << ff << " " << np << endl;
} else
cout << ifr << " " << ff << " " << np << endl;
ff = -1;
}
filebin.close();
while (mt->isBusy()) {
;
}
;
}
sprintf(imgfname, "%s/%s_ped.tiff", outdir.c_str(),froot);
sprintf(imgfname, "%s/%s_ped.tiff", outdir,froot);
mt->writePedestal(imgfname);
sprintf(imgfname, "%s/%s_var.tiff", outdir.c_str(),froot);
sprintf(imgfname, "%s/%s_var.tiff", outdir,froot);
mt->writePedestalRMS(imgfname);
} else
cout << "Could not open pedestal file " << fname
<< " for reading " << endl;
} else {
float *pp = ReadFromTiff(pedfile.c_str(), nny, nnx);
if (pp && (int)nnx == nx && (int)nny == ny) {
for (int i = 0; i < nx * ny; i++) {
ped[i] = pp[i];
}
delete[] pp;
mt->setPedestal(ped);
cout << "Pedestal set from tiff file " << pedfile << endl;
} else {
cout << "Could not open pedestal tiff file " << pedfile
cout << "Could not open pedestal file " << fname
<< " for reading " << endl;
}
} else {
float *pp = ReadFromTiff(pedfile, nny, nnx);
if (pp && (int)nnx == nx && (int)nny == ny) {
for (int i = 0; i < nx * ny; i++) {
ped[i] = pp[i];
}
delete[] pp;
mt->setPedestal(ped);
cout << "Pedestal set from tiff file " << pedfile << endl;
} else {
cout << "Could not open pedestal tiff file " << pedfile
<< " for reading " << endl;
}
}
std::time(&end_time);
cout << std::ctime(&end_time) << endl;
}
std::time(&end_time);
cout << std::ctime(&end_time) << endl;
ifr = 0;
int ifile = 0;
mt->setFrameMode(eFrame);
//t filelist=0;
ifstream flist;
flist.open (args["flist"].c_str(), std::ifstream::in);
if (flist.is_open()) {
cout << "Using file list" << endl;
runmin=0;
runmax=0;
while (flist.getline(ffname,10000)){
cout << ffname << endl;
runmax++;
}
runmax--;
flist.close();
cout << "Found " << runmax << " files " << endl;
flist.open (fformat, std::ifstream::in);
}
for (int irun = runmin; irun <= runmax; irun++) {
cout << "DATA ";
// sprintf(fn,fformat,irun);
// sprintf(ffname, "%s/%s.raw", indir, fformat);
// sprintf(fname, (const char*)ffname, irun);
// sprintf(ffname, "%s/%s.tiff", outdir, fformat);
// sprintf(imgfname, (const char*)ffname, irun);
// sprintf(ffname, "%s/%s.clust", outdir, fformat);
// sprintf(cfname, (const char*)ffname, irun);
if (flist.is_open()) {
flist.getline(ffname,10000);
cout << "file list " << ffname << endl;
} else {
//sprintf(ffname,(const char*)fformat,irun);
sprintf(ffname,args["fformat"].c_str(),irun);
cout << "loop " << ffname << endl;
}
cout << "ffname "<< ffname << endl;
sprintf(fname, "%s/%s.raw",indir.c_str(),ffname);
sprintf(imgfname, "%s/%s.tiff",outdir.c_str(),ffname);
sprintf(cfname, "%s/%s.clust",outdir.c_str(),ffname);
sprintf(ffname, "%s/%s.raw", indir, fformat);
sprintf(fname, (const char*)ffname, irun);
sprintf(ffname, "%s/%s.tiff", outdir, fformat);
sprintf(imgfname, (const char*)ffname, irun);
sprintf(ffname, "%s/%s.clust", outdir, fformat);
sprintf(cfname, (const char*)ffname, irun);
cout << fname << " ";
cout << imgfname << endl;
std::time(&end_time);
@ -424,7 +323,7 @@ int main(int argc, char *argv[]) {
// //open file
ifile = 0;
if (filebin.is_open()) {
if (cf != 0) { // cluster finder
if (thr <= 0 && cf != 0) { // cluster finder
if (of == NULL) {
of = fopen(cfname, "w");
if (of) {
@ -442,8 +341,7 @@ int main(int argc, char *argv[]) {
ff = -1;
ifr = 0;
while (decoder->readNextFrame(filebin, ff, np, buff)) {
if (np == numberOfPackets) {
if (np == numberOfPackets) {
// //push
mt->pushData(buff);
// // //pop
@ -452,27 +350,21 @@ int main(int argc, char *argv[]) {
ifr++;
if (ifr % 100 == 0)
cout << ifr << " " << ff << " " << np << endl;
//break;
cout << ifr << " " << ff << endl;
if (nframes > 0) {
if (ifr % nframes == 0) {
// sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat,
// ifile);
// sprintf(imgfname, (const char*)ffname, irun);
sprintf(imgfname, "%s/%s_f%05d.tiff",outdir.c_str(),ffname,ifile);
while (mt->isBusy())
;
sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat,
ifile);
sprintf(imgfname, (const char*)ffname, irun);
mt->writeImage(imgfname, thr1);
mt->clearImage();
ifile++;
}
}
} else {
cout << "bp " << ifr << " " << ff << " " << np << endl;
//break;
}
} else {
cout << "bp " << ifr << " " << ff << " " << np << endl;
//break;
}
ff = -1;
}
cout << "--" << endl;
@ -482,17 +374,13 @@ int main(int argc, char *argv[]) {
}
if (nframes >= 0) {
if (nframes > 0) {
sprintf(imgfname, "%s/%s_f%05d.tiff",outdir.c_str(),ffname,ifile);
// sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat, ifile);
//sprintf(imgfname, (const char*)ffname, irun);
sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat, ifile);
sprintf(imgfname, (const char*)ffname, irun);
} else {
sprintf(imgfname, "%s/%s.tiff",outdir.c_str(),ffname);
// sprintf(ffname, "%s/%s.tiff", outdir, fformat);
// sprintf(imgfname, (const char*)ffname, irun);
sprintf(ffname, "%s/%s.tiff", outdir, fformat);
sprintf(imgfname, (const char*)ffname, irun);
}
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
while (mt->isBusy())
;
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
mt->writeImage(imgfname, thr1);
mt->clearImage();
if (of) {
@ -507,16 +395,11 @@ int main(int argc, char *argv[]) {
cout << "Could not open " << fname << " for reading " << endl;
}
if (nframes < 0) {
//sprintf(ffname, "%s/%s.tiff", outdir, fformat);
// strcpy(imgfname, ffname);
sprintf(imgfname, "%s/%s_tot.tiff",outdir.c_str(),ffname);
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
while (mt->isBusy())
;
mt->writeImage(imgfname, thr1);
}
if (flist.is_open()) {
flist.close();
sprintf(ffname, "%s/%s.tiff", outdir, fformat);
strcpy(imgfname, ffname);
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
mt->writeImage(imgfname, thr1);
}
return 0;
}

View File

@ -13,8 +13,7 @@
#include "sls/sls_detector_defs.h"
#ifndef MOENCH04
//#ifndef RECT
#include "moench03v2Data.h"
//#include "moench03T1ZmqDataNew.h"
#include "moench03T1ZmqDataNew.h"
//#endif
//#ifdef RECT
//#include "moench03T1ZmqDataNewRect.h"
@ -32,7 +31,6 @@
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <rapidjson/document.h> //json header in zmq stream
@ -65,48 +63,36 @@ int main(int argc, char *argv[]) {
* trial.o [socket ip] [starting port number] [send_socket ip] [send port
* number]
*
*/
std::map<std::string, std::string> args = {
{"numinterfaces","1"},
{"rx_zmqip","10.1.2.102"},
{"rx_zmqport","7770"},
{"zmqip","129.129.202.153"},
{"zmqport","7780"},
{"nthreads","5"},
{"fifosize","5000"},
{"nsigma","5"},
{"gainfile","none"},
{"nbinsx","5"},
{"nbinsy","5"},
{"etafile","none"},
{"etabinsx","1000"},
{"etamin","-1"},
{"etamax","2"} };
FILE *of = NULL;
*/
FILE *of = NULL;
int fifosize = 5000;
int etabins = 1000, etabinsy = 1000; // nsubpix*2*100;
double etamin = -1, etamax = 2;
int nSubPixelsX = 2;
int emin, emax;
int nSubPixelsY = 2;
int nthreads = 5;
int fifosize = 5000;
uint32_t nSigma = 5;
string etafname;// = NULL;
string gainfname;// = NULL;
// help
if (argc < 3) {
cprintf(RED, "Help: ./trial [receive socket ip] [receive starting port "
"number] [send_socket ip] [send starting port number] "
"[nthreads] [nsubpix] [gainmap] [etafile]\n");
return EXIT_FAILURE;
}
// receive parameters
bool send = false;
char *socketip = argv[1];
uint32_t portnum = atoi(argv[2]);
// send parameters if any
string socketip2;// = 0;
uint32_t portnum2 = 0;
string socketip;// = 0;
uint32_t portnum = 0;
char *socketip2 = 0;
uint32_t portnum2 = 0;
sls::zmqHeader zHeader, outHeader;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
outHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
uint32_t nSigma = 5;
int ok;
@ -116,85 +102,48 @@ int main(int argc, char *argv[]) {
// time_t begin,end,finished;
int rms = 0;
send = true;
// help
if (argc < 5) {
std::string name, value,sline;
int ic=0;
ifstream flist;
flist.open (argv[1], std::ifstream::in);
if (flist.is_open()) {
cout << "Using config file " <<argv[1] << endl;
while (std::getline(flist,sline)){
if (sline.at(0)!='#') {
ic=sline.find(' ');
name = sline.substr(0,ic);
value = sline.substr(ic+1,sline.size()-ic);
args[name]=value;
}
if (argc > 4) {
socketip2 = argv[3];
portnum2 = atoi(argv[4]);
if (portnum2 > 0)
send = true;
}
cout << "\nrx socket ip : " << socketip << "\nrx port num : " << portnum;
if (send) {
cout << "\ntx socket ip : " << socketip2
<< "\ntx port num : " << portnum2;
}
int nthreads = 5;
if (argc > 5)
nthreads = atoi(argv[5]);
}
flist.close();
} else {
cprintf(RED, "Arguments are either: \n [config file] \n or the following list (deprecated): [receive socket ip] [receive starting port "
"number] [send_socket ip] [send starting port number] "
"[nthreads] [nsubpix] [gainmap] [etafile]\n");
return EXIT_FAILURE;
}
} else {
args["rx_zmqip"]=argv[1];
args["rx_zmqport"]=argv[2];
args["zmqip"]=argv[3];
args["zmqport"]=argv[4];
if (argc > 5)
args["nthreads"] = argv[5];
if (argc > 6) {
args["nbinsx"]=argv[6];
args["nbinsy"]=argv[6];
}
if (argc > 7) {
args["gainfile"]=argv[7];
}
if (argc > 8) {
args["etafilefile"]=argv[8];
}
cout << "Number of threads is: " << nthreads << endl;
if (argc > 6) {
nSubPixelsX = atoi(argv[6]);
nSubPixelsY = nSubPixelsX;
#ifdef RECT
nSubPixelsX = 2;
#endif
}
cout << "Number of subpixels is: " << nSubPixelsX << " " << nSubPixelsY
<< endl;
char *gainfname = NULL;
if (argc > 7) {
gainfname = argv[7];
cout << "Gain map file name is: " << gainfname << endl;
}
for (auto const& x : args)
{
std::cout << x.first // string (key)
<< ':'
<< x.second // string's value
<< std::endl;
}
socketip = args["rx_zmqip"];
portnum = atoi(args["rx_zmqport"].c_str());
socketip2 = args["zmqip"];
portnum2 = atoi(args["zmqport"].c_str());
nthreads = atoi(args["nthreads"].c_str());
nSubPixelsX =atoi(args["nbinsx"].c_str());
nSubPixelsY =atoi(args["nbinsy"].c_str());
gainfname = args["gainfile"];
etafname = args["etafilefile"];
if (atoi(args["nuninterfaces"].c_str())>1){
cprintf(RED, "Sorry, at the moment only a single interface is supported instead of %d\n",atoi(args["nuninterfaces"].c_str()));
return EXIT_FAILURE;
char *etafname = NULL;
if (argc > 8) {
etafname = argv[8];
cout << "Eta file name is: " << etafname << endl;
}
// slsDetectorData *det=new moench03T1ZmqDataNew();
#ifndef MOENCH04
cout << "This is a Moench03 v2" << endl;
//moench03T1ZmqDataNew *det = new moench03T1ZmqDataNew();
moench03v2Data *det = new moench03v2Data();
cout << "MOENCH03!" << endl;
cout << "This is a Moench03" << endl;
moench03T1ZmqDataNew *det = new moench03T1ZmqDataNew();
#endif
#ifdef MOENCH04
cout << "This is a Moench04" << endl;
@ -228,8 +177,8 @@ int main(int argc, char *argv[]) {
double *gmap = NULL;
uint32_t nnnx, nnny;
//if (gainfname) {
gm = ReadFromTiff(gainfname.c_str(), nnny, nnnx);
if (gainfname) {
gm = ReadFromTiff(gainfname, nnny, nnnx);
if (gm && nnnx == (uint)npx && nnny == (uint)npy) {
gmap = new double[npx * npy];
for (int i = 0; i < npx * npy; i++) {
@ -238,7 +187,7 @@ int main(int argc, char *argv[]) {
delete[] gm;
} else
cout << "Could not open gain map " << gainfname << endl;
//}
}
// analogDetector<uint16_t> *filter=new
// analogDetector<uint16_t>(det,1,NULL,1000);
@ -256,8 +205,8 @@ int main(int argc, char *argv[]) {
eta2InterpolationPosXY *interp = new eta2InterpolationPosXY(
npx, npy, nSubPixelsX, nSubPixelsY, etabins, etabinsy, etamin, etamax);
//if (etafname)
interp->readFlatField(etafname.c_str());
if (etafname)
interp->readFlatField(etafname);
interpolatingDetector *filter = new interpolatingDetector(
det, interp, nSigma, 1, cm, 1000, 10, -1, -1, gainmap, gs);
@ -277,13 +226,13 @@ int main(int argc, char *argv[]) {
try {
#endif
zmqsocket = new sls::ZmqSocket(socketip.c_str(), portnum);
zmqsocket = new sls::ZmqSocket(socketip, portnum);
#ifdef NEWZMQ
} catch (...) {
cprintf(RED,
"Error: Could not create Zmq socket on port %d with ip %s\n",
portnum, socketip.c_str());
portnum, socketip);
delete zmqsocket;
return EXIT_FAILURE;
}
@ -293,7 +242,7 @@ int main(int argc, char *argv[]) {
if (zmqsocket->IsError()) {
cprintf(RED,
"Error: Could not create Zmq socket on port %d with ip %s\n",
portnum, socketip.c_str());
portnum, socketip);
delete zmqsocket;
return EXIT_FAILURE;
}
@ -314,14 +263,14 @@ int main(int argc, char *argv[]) {
// receive socket
try {
#endif
zmqsocket2 = new sls::ZmqSocket(portnum2, socketip2.c_str());
zmqsocket2 = new sls::ZmqSocket(portnum2, socketip2);
#ifdef NEWZMQ
} catch (...) {
cprintf(RED,
"Error: Could not create Zmq socket server on port %d and "
"ip %s\n",
portnum2, socketip2.c_str());
portnum2, socketip2);
// delete zmqsocket2;
// zmqsocket2=NULL;
// delete zmqsocket;
@ -335,7 +284,7 @@ int main(int argc, char *argv[]) {
cprintf(RED,
"AAA Error: Could not create Zmq socket server on port %d "
"and ip %s\n",
portnum2, socketip2.c_str());
portnum2, socketip2);
// delete zmqsocket2;
// delete zmqsocket;
// return EXIT_FAILURE;
@ -773,25 +722,6 @@ int main(int argc, char *argv[]) {
cprintf(MAGENTA, "%d %d %d %d\n", xmin, xmax, ymin, ymax);
mt->setROI(xmin, xmax, ymin, ymax);
if (addJsonHeader.find("xMin") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("xMin")) >> xmin;
}
if (addJsonHeader.find("yMin") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("yMin")) >> ymin;
}
if (addJsonHeader.find("xMax") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("xMax")) >> xmax;
}
if (addJsonHeader.find("yMax") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("yMax")) >> ymax;
}
if (addJsonHeader.find("dynamicRange") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("dynamicRange")) >> dr;
dr = 32;
@ -891,7 +821,7 @@ int main(int argc, char *argv[]) {
// cout << acqIndex << " " << frameIndex << " " << subFrameIndex << "
// "<< detSpec1 << " " << timestamp << " " << packetNumber << endl;
// cprintf(GREEN, "frame\n");
if (packetNumber <= 50) {
if (packetNumber >= 40) {
//*((int*)buff)=frameIndex;
if (insubframe == 0)
f0 = frameIndex;

View File

@ -11,7 +11,6 @@ install(TARGETS slsProjectCSettings
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
add_subdirectory(ctbDetectorServer)
add_subdirectory(xilinx_ctbDetectorServer)
add_subdirectory(eigerDetectorServer)
add_subdirectory(gotthardDetectorServer)
add_subdirectory(jungfrauDetectorServer)

View File

@ -8,8 +8,7 @@ det_list=("ctbDetectorServer
gotthard2DetectorServer
jungfrauDetectorServer
mythen3DetectorServer
moenchDetectorServer
xilinx_ctbDetectorServer"
moenchDetectorServer"
)
usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"

View File

@ -9,7 +9,6 @@ det_list=("ctbDetectorServer"
"jungfrauDetectorServer"
"mythen3DetectorServer"
"moenchDetectorServer"
"xilinx_ctbDetectorServer"
)
usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"

View File

@ -37,7 +37,8 @@ target_compile_definitions(ctbDetectorServer_virtual
)
target_link_libraries(ctbDetectorServer_virtual
PUBLIC pthread rt m slsProjectCSettings
PUBLIC pthread rt slsProjectCSettings
m
)
set_target_properties(ctbDetectorServer_virtual PROPERTIES

View File

@ -55,9 +55,7 @@
#define DEFAULT_SYNC_CLK (40) // 20
#define DEFAULT_DBIT_CLK (200)
#define DEFAULT_TRANSCEIVER_MASK (0x3)
#define MAX_TRANSCEIVER_MASK (0xF)
#define MAX_TRANSCEIVER_SAMPLES (0xFFFF)
#define MAX_TRANSCEIVER_MASK (0xF)
#define UDP_HEADER_MAX_FRAME_VALUE (0xFFFFFFFFFFFF)

View File

@ -471,8 +471,7 @@ void setupDetector() {
// hv
DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME);
// dacs
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC, 1,
0, "");
LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC);
// on chip dacs
ASIC_Driver_SetDefines(ONCHIP_DAC_DRIVER_FILE_NAME);
setTimingSource(DEFAULT_TIMING_SOURCE);

View File

@ -35,7 +35,6 @@
#define TEMPERATURE_FILE_NAME ("/sys/class/hwmon/hwmon0/temp1_input")
#endif
#define CONFIG_FILE ("config_gotthard2.txt")
#define DAC_MIN_MV (0)
#define DAC_MAX_MV (2048)
#define ONCHIP_DAC_MAX_VAL (0x3FF)
#define ADU_MAX_VAL (0xFFF)

View File

@ -90,7 +90,6 @@ void basictests() {
"Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage));
initError = FAIL;
return;
}
#ifndef VIRTUAL
// does check only if flag is 0 (by default), set by command line

View File

@ -88,7 +88,6 @@ void basictests() {
"Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage));
initError = FAIL;
return;
}
#ifndef VIRTUAL
// does check only if flag is 0 (by default), set by command line

View File

@ -82,7 +82,6 @@ void basictests() {
"Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL;
return;
}
#ifndef VIRTUAL
// does check only if flag is 0 (by default), set by command line
@ -482,6 +481,7 @@ void setupDetector() {
return;
}
setReadoutSpeed(DEFAULT_SPEED);
cleanFifos();
resetCore();
@ -495,7 +495,6 @@ void setupDetector() {
initReadoutConfiguration();
// Initialization of acquistion parameters
setReadoutSpeed(DEFAULT_SPEED);
setSettings(DEFAULT_SETTINGS);
setNumFrames(DEFAULT_NUM_FRAMES);
setNumTriggers(DEFAULT_NUM_CYCLES);
@ -700,12 +699,14 @@ int setExpTime(int64_t val) {
}
LOG(logINFO, ("Setting exptime %lld ns\n", (long long int)val));
val *= (1E-3 * CLK_RUN);
val -= ACQ_TIME_MIN_CLOCK;
if (val < 0) {
val = 0;
}
set64BitReg(val, SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG);
// validate for tolerance
val += ACQ_TIME_MIN_CLOCK;
int64_t retval = getExpTime();
val /= (1E-3 * CLK_RUN);
if (val != retval) {
@ -715,7 +716,8 @@ int setExpTime(int64_t val) {
}
int64_t getExpTime() {
return get64BitReg(SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) /
return (get64BitReg(SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) +
ACQ_TIME_MIN_CLOCK) /
(1E-3 * CLK_RUN);
}

View File

@ -5,7 +5,7 @@
#include "sls/sls_detector_defs.h"
#define REQRD_FRMWRE_VRSN_BOARD2 0x444445 // 1.0 pcb (version = 010)
#define REQRD_FRMWRE_VRSN 0x231026 // 2.0 pcb (version = 011)
#define REQRD_FRMWRE_VRSN 0x230710 // 2.0 pcb (version = 011)
#define NUM_HARDWARE_VERSIONS (2)
#define HARDWARE_VERSION_NUMBERS \
@ -58,10 +58,11 @@
/* Defines in the Firmware */
#define MAX_TIMESLOT_VAL (0x1F)
#define MAX_THRESHOLD_TEMP_VAL (127999) // millidegrees
#define ACQ_TIME_MIN_CLOCK (2)
#define ASIC_FILTER_MAX_RES_VALUE (1)
#define MAX_SELECT_CHIP10_VAL (63)
#define MAX_PHASE_SHIFTS (200)
#define MAX_PHASE_SHIFTS (240)
#define BIT16_MASK (0xFFFF)
#define ADC_DECMT_QUARTER_SPEED (0x3)

View File

@ -92,7 +92,6 @@ void basictests() {
"Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage));
initError = FAIL;
return;
}
#ifndef VIRTUAL
// does check only if flag is 0 (by default), set by command line
@ -483,8 +482,7 @@ void setupDetector() {
// hv
DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME);
// dac
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC, 1,
0, "");
LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC);
resetCore();
resetPeripheral();

View File

@ -34,7 +34,6 @@
#else
#define TEMPERATURE_FILE_NAME ("/sys/class/hwmon/hwmon0/temp1_input")
#endif
#define DAC_MIN_MV (0)
#define DAC_MAX_MV (2048)
#define TYPE_MYTHEN3_MODULE_VAL (93)
#define TYPE_TOLERANCE (5)

View File

@ -4,11 +4,18 @@
#include <inttypes.h>
void LTC2620_D_SetDefines(int hardMinV, int hardMaxV, char *driverfname,
int numdacs, int numdevices, int startingDeviceIndex,
char *powerdownDriverfname);
/**
* Set Defines
* @param hardMaxV maximum hardware limit
* @param driverfname driver file name
* @param numdacs number of dacs
*/
void LTC2620_D_SetDefines(int hardMaxV, char *driverfname, int numdacs);
/**
* Get max number of steps
*/
int LTC2620_D_GetMaxNumSteps();
int LTC2620_D_GetPowerDownValue();
/**
* Convert voltage to dac units

View File

@ -1,15 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include <inttypes.h>
#include <sys/types.h>
void bus_w(u_int32_t offset, u_int32_t data);
u_int32_t bus_r(u_int32_t offset);
uint64_t getU64BitReg(int aLSB, int aMSB);
void setU64BitReg(uint64_t value, int aLSB, int aMSB);
u_int32_t readRegister(u_int32_t offset);
u_int32_t writeRegister(u_int32_t offset, u_int32_t data);
int mapCSP0(void);
u_int32_t *Arm_getUDPBaseAddress();

View File

@ -6,12 +6,10 @@
#include "clogger.h"
void initializePatternAddresses();
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
#ifdef CHIPTESTBOARDD
#ifdef VIRTUAL
void initializePatternWord();
#endif
#endif
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
uint64_t validate_readPatternIOControl();
int validate_writePatternIOControl(char *message, uint64_t arg);
void writePatternIOControl(uint64_t word);

View File

@ -1,12 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include <sys/types.h>
int resetFPGA(char *mess);
int loadDeviceTree(char *mess, int *adcDeviceIndex, int *dacDeviceIndex);
int checksBeforeCreatingDeviceTree(char *mess);
int createDeviceTree(char *mess);
int verifyDeviceTree(char *mess, int *adcDeviceIndex, int *dacDeviceIndex);

View File

@ -25,11 +25,6 @@
#include "blackfin.h"
#endif
#ifdef ARMPROCESSOR
#include "arm64.h"
#include "programViaArm.h"
#endif
#ifdef MYTHEN3D
#include "mythen3.h"
#endif
@ -66,15 +61,12 @@ typedef struct udpStruct_s {
int isInitCheckDone();
int getInitResult(char **mess);
void basictests();
#if !defined(EIGERD)
#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(MOENCHD) || \
defined(CHIPTESTBOARDD) || defined(MYTHEN3D) || defined(GOTTHARD2D)
int checkType();
int testFpga();
#ifdef XILINX_CHIPTESTBOARDD
int testFixedFPGAPattern();
#else
int testBus();
#endif
#endif
#if defined(GOTTHARDD) || \
((defined(EIGERD) || defined(JUNGFRAUD) || defined(MOENCHD)) && \
@ -94,10 +86,8 @@ void getHardwareVersion(char *version);
#ifdef EIGERD
int getHardwareVersionNumber();
#else
#ifndef XILINX_CHIPTESTBOARDD
u_int16_t getHardwareVersionNumber();
#endif
#endif
#if defined(JUNGFRAUD) || defined(MOENCHD) || defined(CHIPTESTBOARDD)
u_int16_t getHardwareSerialNumber();
#endif
@ -121,6 +111,7 @@ int updateModuleId();
void setModuleId(int modid);
#endif
#endif
u_int64_t getDetectorMAC();
u_int32_t getDetectorIP();
@ -145,7 +136,7 @@ int updateDatabytesandAllocateRAM();
void updateDataBytes();
#endif
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
#ifndef CHIPTESTBOARDD
int resetToDefaultDacs(int hardReset);
int getDefaultDac(enum DACINDEX index, enum detectorSettings sett, int *retval);
int setDefaultDac(enum DACINDEX index, enum detectorSettings sett, int value);
@ -181,22 +172,6 @@ uint32_t readRegister16And32(uint32_t offset);
#endif
// firmware functions (resets)
#if defined(XILINX_CHIPTESTBOARDD)
void cleanFifos();
void resetFlow();
int waitTranseiverReset(char *mess);
#ifdef VIRTUAL
void setTransceiverAlignment(int align);
#endif
int isTransceiverAligned();
int waitTransceiverAligned(char *mess);
int configureTransceiver(char *mess);
int isChipConfigured();
int powerChip(int on, char *mess);
int getPowerChip();
int configureChip(char *mess);
void startPeriphery();
#endif
#if defined(JUNGFRAUD) || defined(MOENCHD) || defined(CHIPTESTBOARDD) || \
defined(MYTHEN3D) || defined(GOTTHARD2D)
void cleanFifos();
@ -236,12 +211,6 @@ uint32_t getTransceiverEnableMask();
void setADCInvertRegister(uint32_t val);
uint32_t getADCInvertRegister();
#endif
#ifdef XILINX_CHIPTESTBOARDD
void setADCEnableMask_10G(uint32_t mask);
uint32_t getADCEnableMask_10G();
int setTransceiverEnableMask(uint32_t mask);
uint32_t getTransceiverEnableMask();
#endif
#if defined(CHIPTESTBOARDD)
int setExternalSamplingSource(int val);
int setExternalSampling(int val);
@ -257,7 +226,7 @@ int getParallelMode();
int setOverFlowMode(int mode);
int getOverFlowMode();
#endif
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
#ifdef CHIPTESTBOARDD
int setReadoutMode(enum readoutMode mode);
int getReadoutMode();
#endif
@ -268,7 +237,7 @@ int selectStoragecellStart(int pos);
int getMaxStoragecellStart();
#endif
#if defined(JUNGFRAUD) || defined(MOENCHD) || defined(EIGERD) || \
defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
defined(CHIPTESTBOARDD)
int setNextFrameNumber(uint64_t value);
int getNextFrameNumber(uint64_t *value);
#endif
@ -313,9 +282,11 @@ int getNumAdditionalStorageCells();
int setStorageCellDelay(int64_t val);
int64_t getStorageCellDelay();
#endif
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
#if defined(CHIPTESTBOARDD)
int setNumAnalogSamples(int val);
int getNumAnalogSamples();
#endif
#ifdef CHIPTESTBOARDD
int setNumDigitalSamples(int val);
int getNumDigitalSamples();
int setNumTransceiverSamples(int val);
@ -328,15 +299,12 @@ uint32_t getCounterMask();
void updatePacketizing();
#endif
#ifndef EIGERD
int64_t getNumFramesLeft();
int64_t getNumTriggersLeft();
#endif
#if defined(JUNGFRAUD) || defined(MOENCHD) || defined(GOTTHARDD) || \
defined(CHIPTESTBOARDD) || defined(MYTHEN3D) || defined(GOTTHARD2D) || \
defined(XILINX_CHIPTESTBOARDD)
defined(CHIPTESTBOARDD) || defined(MYTHEN3D) || defined(GOTTHARD2D)
int setDelayAfterTrigger(int64_t val);
int64_t getDelayAfterTrigger();
int64_t getNumFramesLeft();
int64_t getNumTriggersLeft();
int64_t getDelayAfterTriggerLeft();
int64_t getPeriodLeft();
#endif
@ -347,7 +315,7 @@ int64_t getNumBurstsLeft();
int64_t getExpTimeLeft();
#endif
#if defined(JUNGFRAUD) || defined(MOENCHD) || defined(CHIPTESTBOARDD) || \
defined(MYTHEN3D) || defined(GOTTHARD2D) || defined(XILINX_CHIPTESTBOARDD)
defined(MYTHEN3D) || defined(GOTTHARD2D)
int64_t getFramesFromStart();
int64_t getActualTime();
int64_t getMeasurementTime();
@ -369,12 +337,10 @@ int setTrimbits(int *trimbits);
int setAllTrimbits(int val);
int getAllTrimbits();
#endif
#ifndef XILINX_CHIPTESTBOARDD
#ifndef CHIPTESTBOARDD
enum detectorSettings setSettings(enum detectorSettings sett);
#endif
enum detectorSettings getSettings();
#endif
#if defined(JUNGFRAUD)
enum gainMode getGainMode();
void setGainMode(enum gainMode mode);
@ -404,7 +370,7 @@ void setDAC(enum DACINDEX ind, int val, int mV);
#endif
int getDAC(enum DACINDEX ind, int mV);
int getMaxDacSteps();
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
#if defined(CHIPTESTBOARDD)
int dacToVoltage(int dac);
int checkVLimitCompliant(int mV);
int checkVLimitDacCompliant(int dac);
@ -423,12 +389,9 @@ int isPowerValid(enum DACINDEX ind, int val);
int getPower();
void setPower(enum DACINDEX ind, int val);
void powerOff();
#elif XILINX_CHIPTESTBOARDD
int getPower();
void setPower(enum DACINDEX ind, int val);
#endif
#if defined(MYTHEN3D) || defined(GOTTHARD2D) || defined(XILINX_CHIPTESTBOARDD)
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
int getADC(enum ADCINDEX ind, int *value);
#else
int getADC(enum ADCINDEX ind);
@ -437,12 +400,8 @@ int getADC(enum ADCINDEX ind);
int getSlowADC(int ichan);
int getSlowADCTemperature();
#endif
#ifdef XILINX_CHIPTESTBOARDD
int getSlowADC(int ichan, int *retval);
int getTemperature(int *retval);
#else
int setHighVoltage(int val);
#endif
// parameters - timing, extsig
#if defined(EIGERD) || defined(GOTTHARD2D) || defined(JUNGFRAUD) || \
@ -512,8 +471,7 @@ void setupHeader(int iRxEntry, enum interfaceType type, uint32_t destip,
uint32_t sourceip, uint16_t sourceport);
#endif
#if defined(JUNGFRAUD) || defined(MOENCHD) || defined(GOTTHARD2D) || \
defined(MYTHEN3D) || defined(CHIPTESTBOARDD) || \
defined(XILINX_CHIPTESTBOARDD)
defined(MYTHEN3D) || defined(CHIPTESTBOARDD)
void calcChecksum(udp_header *udp);
#endif
#ifdef GOTTHARDD
@ -721,14 +679,13 @@ int startStateMachine();
void *start_timer(void *arg);
#endif
int stopStateMachine();
#if defined(MYTHEN3D) || defined(XILINX_CHIPTESTBOARDD)
#ifdef MYTHEN3D
int softwareTrigger();
#endif
#if defined(EIGERD) || defined(JUNGFRAUD) || defined(MOENCHD)
int softwareTrigger(int block);
#endif
#if defined(EIGERD) || defined(MYTHEN3D) || defined(CHIPTESTBOARDD) || \
defined(XILINX_CHIPTESTBOARDD)
#if defined(EIGERD) || defined(MYTHEN3D) || defined(CHIPTESTBOARDD)
int startReadOut();
#endif
enum runStatus getRunStatus();
@ -748,8 +705,7 @@ int readFrameFromFifo();
#endif
#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(MOENCHD) || \
defined(CHIPTESTBOARDD) || defined(MYTHEN3D) || defined(GOTTHARD2D) || \
defined(XILINX_CHIPTESTBOARDD)
defined(CHIPTESTBOARDD) || defined(MYTHEN3D) || defined(GOTTHARD2D)
u_int32_t runBusy();
#endif
@ -760,9 +716,9 @@ u_int32_t runState(enum TLogLevel lev);
// common
int calculateDataBytes();
int getTotalNumberOfChannels();
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
#if defined(CHIPTESTBOARDD)
void getNumberOfChannels(int *nchanx, int *nchany);
#endif
int getNumberOfChips();
int getNumberOfDACs();
int getNumberOfChannelsPerChip();
int getNumberOfChannelsPerChip();

View File

@ -329,4 +329,3 @@ int getColumn();
int setColumn(int);
int get_pedestal_mode(int);
int set_pedestal_mode(int);
int config_transceiver(int);

View File

@ -13,54 +13,35 @@
#define LTC2620_D_MAX_STEPS (LTC2620_D_MAX_DAC_VAL + 1)
// defines from the fpga
int LTC2620_D_HardMinVoltage = 0;
int LTC2620_D_HardMaxVoltage = 0;
char LTC2620_D_DriverFileName[MAX_STR_LENGTH];
char LTC2620_D_PowerDownDriverFileName[MAX_STR_LENGTH];
int LTC2620_D_NumDacs = 0;
int LTC2620_D_NumDevices = 0;
int LTC2620_D_NumChannelsPerDevice = 0;
int LTC2620_D_DacDriverStartingDeviceIndex = 0;
void LTC2620_D_SetDefines(int hardMinV, int hardMaxV, char *driverfname,
int numdacs, int numdevices, int startingDeviceIndex,
char *powerdownDriverfname) {
void LTC2620_D_SetDefines(int hardMaxV, char *driverfname, int numdacs) {
LOG(logINFOBLUE,
("Configuring DACs (LTC2620) to %s\n\t (numdacs:%d, hard min:%d, hard "
"max: %dmV, idev:%d)\n",
driverfname, numdacs, hardMinV, hardMaxV, startingDeviceIndex));
LTC2620_D_HardMinVoltage = hardMinV;
("Configuring DACs (LTC2620) to %s (numdacs:%d, hard max: %dmV)\n",
driverfname, numdacs, hardMaxV));
LTC2620_D_HardMaxVoltage = hardMaxV;
memset(LTC2620_D_DriverFileName, 0, MAX_STR_LENGTH);
strcpy(LTC2620_D_DriverFileName, driverfname);
memset(LTC2620_D_PowerDownDriverFileName, 0, MAX_STR_LENGTH);
strcpy(LTC2620_D_PowerDownDriverFileName, powerdownDriverfname);
LTC2620_D_NumDacs = numdacs;
LTC2620_D_NumDevices = numdevices;
LTC2620_D_NumChannelsPerDevice = LTC2620_D_NumDacs / LTC2620_D_NumDevices;
LTC2620_D_DacDriverStartingDeviceIndex = startingDeviceIndex;
}
int LTC2620_D_GetMaxNumSteps() { return LTC2620_D_MAX_STEPS; }
int LTC2620_D_GetPowerDownValue() { return LTC2620_D_PWR_DOWN_VAL; }
int LTC2620_D_VoltageToDac(int voltage, int *dacval) {
return ConvertToDifferentRange(LTC2620_D_HardMinVoltage,
LTC2620_D_HardMaxVoltage, 0,
return ConvertToDifferentRange(0, LTC2620_D_HardMaxVoltage, 0,
LTC2620_D_MAX_DAC_VAL, voltage, dacval);
}
int LTC2620_D_DacToVoltage(int dacval, int *voltage) {
return ConvertToDifferentRange(0, LTC2620_D_MAX_DAC_VAL,
LTC2620_D_HardMinVoltage,
return ConvertToDifferentRange(0, LTC2620_D_MAX_DAC_VAL, 0,
LTC2620_D_HardMaxVoltage, dacval, voltage);
}
int LTC2620_D_SetDACValue(int dacnum, int val, int mV, char *dacname,
int *dacval) {
LOG(logDEBUG1, ("dacnum:%d, val:%d, ismV:%d\n", dacnum, val, mV));
// validate index
if (dacnum < 0 || dacnum >= LTC2620_D_NumDacs) {
LOG(logERROR, ("Dac index %d is out of bounds (0 to %d)\n", dacnum,
@ -68,90 +49,53 @@ int LTC2620_D_SetDACValue(int dacnum, int val, int mV, char *dacname,
return FAIL;
}
// validate set
// get
if (val < 0 && val != LTC2620_D_PWR_DOWN_VAL)
return FAIL;
int ret = OK;
// convert to dac or get mV value
*dacval = val;
#ifndef VIRTUAL
char fnameFormat[MAX_STR_LENGTH];
memset(fnameFormat, 0, MAX_STR_LENGTH);
strcpy(fnameFormat, LTC2620_D_DriverFileName);
#endif
// power down dac (different file name)
if (val == LTC2620_D_PWR_DOWN_VAL) {
#if defined(XILINX_CHIPTESTBOARDD) && !defined(VIRTUAL)
LOG(logINFO, ("Powering down DAC %2d [%-6s] \n", dacnum, dacname));
strcpy(fnameFormat, LTC2620_D_PowerDownDriverFileName);
#endif
int dacmV = val;
int ret = OK;
if (mV) {
ret = LTC2620_D_VoltageToDac(val, dacval);
} else if (val >= 0) {
// do not convert power down dac val
ret = LTC2620_D_DacToVoltage(val, &dacmV);
}
// proper value to set
else {
// convert to dac or get mV value
int dacmV = val;
if (mV) {
ret = LTC2620_D_VoltageToDac(val, dacval);
} else if (val >= 0) {
// do not convert power down dac val
ret = LTC2620_D_DacToVoltage(val, &dacmV);
}
// conversion out of bounds
if (ret == FAIL) {
LOG(logERROR, ("Setting Dac %d %s is out of bounds\n", dacnum,
(mV ? "mV" : "dac units")));
return FAIL;
}
// print and set
#ifdef XILINX_CHIPTESTBOARDD
if (*dacval >= 0) {
LOG(logINFO, ("Setting DAC %2d [%-6s] : %d dac (%d mV)\n", dacnum,
dacname, *dacval, dacmV));
}
#else
if ((*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) {
LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n", dacnum,
dacname, *dacval, dacmV));
}
#endif
}
// set in file
#ifndef VIRTUAL
char fname[MAX_STR_LENGTH];
memset(fname, 0, MAX_STR_LENGTH);
#ifdef XILINX_CHIPTESTBOARDD
int idev = LTC2620_D_DacDriverStartingDeviceIndex +
(dacnum / LTC2620_D_NumChannelsPerDevice);
int idac = dacnum % LTC2620_D_NumChannelsPerDevice;
sprintf(fname, fnameFormat, idev, idac);
#else
sprintf(fname, "%s%d", fnameFormat, dacnum);
#endif
LOG(logDEBUG1, ("fname %s\n", fname));
// open file
FILE *fd = fopen(fname, "w");
if (fd == NULL) {
LOG(logERROR, ("Could not open file %s for writing to set dac %d\n",
fname, dacnum));
// conversion out of bounds
if (ret == FAIL) {
LOG(logERROR, ("Setting Dac %d %s is out of bounds\n", dacnum,
(mV ? "mV" : "dac units")));
return FAIL;
}
// convert to string, add 0 and write to file
#ifdef XILINX_CHIPTESTBOARDD
// not changing *dacval from -100 (cant write -100 to file: invalid arg)
int writeValue = *dacval;
if (writeValue == LTC2620_D_PWR_DOWN_VAL)
writeValue = 1;
fprintf(fd, "%d\n", writeValue);
#else
fprintf(fd, "%d\n", *dacval);
#endif
fclose(fd);
// set
if ((*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) {
LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n", dacnum,
dacname, *dacval, dacmV));
#ifndef VIRTUAL
char fname[MAX_STR_LENGTH];
strcpy(fname, LTC2620_D_DriverFileName);
char temp[20];
memset(temp, 0, sizeof(temp));
sprintf(temp, "%d", dacnum);
strcat(fname, temp);
LOG(logDEBUG1, ("fname %s\n", fname));
// open file
FILE *fd = fopen(fname, "w");
if (fd == NULL) {
LOG(logERROR, ("Could not open file %s for writing to set dac %d\n",
fname, dacnum));
return FAIL;
}
// convert to string, add 0 and write to file
fprintf(fd, "%d\n", *dacval);
fclose(fd);
#endif
}
return OK;
}

View File

@ -1,94 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "arm64.h"
#include "RegisterDefs.h"
#include "clogger.h"
#include "common.h"
#include "sls/ansi.h"
#include "sls/sls_detector_defs.h"
#include <fcntl.h> // open
#include <sys/mman.h> // mmap
/* global variables */
#define CSP0 (0xB0080000)
#define CSP1 (0xB0050000) // udp
#define MEM_SIZE (0x10000)
//#define MEM_SIZE_CSP0 (4096)
//#define MEM_SIZE_CSP1 (2 * 4096)
u_int32_t *csp0base = 0;
u_int32_t *csp1base = 0;
void bus_w(u_int32_t offset, u_int32_t data) {
volatile u_int32_t *ptr1;
ptr1 = (u_int32_t *)(csp0base + offset / (sizeof(u_int32_t)));
*ptr1 = data;
}
u_int32_t bus_r(u_int32_t offset) {
volatile u_int32_t *ptr1;
ptr1 = (u_int32_t *)(csp0base + offset / (sizeof(u_int32_t)));
return *ptr1;
}
uint64_t getU64BitReg(int aLSB, int aMSB) {
uint64_t retval = bus_r(aMSB);
retval = (retval << 32) | bus_r(aLSB);
return retval;
}
void setU64BitReg(uint64_t value, int aLSB, int aMSB) {
bus_w(aLSB, value & (0xffffffff));
bus_w(aMSB, (value >> 32) & (0xffffffff));
}
u_int32_t readRegister(u_int32_t offset) { return bus_r(offset); }
u_int32_t writeRegister(u_int32_t offset, u_int32_t data) {
bus_w(offset, data);
return readRegister(offset);
}
int mapCSP0(void) {
u_int32_t csps[2] = {CSP0, CSP1};
u_int32_t **cspbases[2] = {&csp0base, &csp1base};
char names[2][10] = {"csp0base", "csp1base"};
for (int i = 0; i < 2; ++i) {
// if not mapped
if (*cspbases[i] == 0) {
LOG(logINFO, ("Mapping memory for %s\n", names[i]));
#ifdef VIRTUAL
*cspbases[i] = malloc(MEM_SIZE);
if (*cspbases[i] == NULL) {
LOG(logERROR,
("Could not allocate virtual memory for %s.\n", names[i]));
return FAIL;
}
LOG(logINFO, ("memory allocated for %s\n", names[i]));
#else
int fd = open("/dev/mem", O_RDWR | O_SYNC, 0);
if (fd == -1) {
LOG(logERROR, ("Can't find /dev/mem for %s\n", names[i]));
return FAIL;
}
LOG(logDEBUG1,
("/dev/mem opened for %s, (CSP:0x%x)\n", names[i], csps[i]));
*cspbases[i] =
(u_int32_t *)mmap(0, MEM_SIZE, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, fd, csps[i]);
if (*cspbases[i] == MAP_FAILED) {
LOG(logERROR, ("Can't map memmory area for %s\n", names[i]));
return FAIL;
}
#endif
LOG(logINFO, ("%s mapped from %p to %p,(CSP:0x%x) \n", names[i],
*cspbases[i], *cspbases[i] + MEM_SIZE, csps[i]));
// LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG)));
} else
LOG(logINFO, ("Memory %s already mapped before\n", names[i]));
}
return OK;
}
u_int32_t *Arm_getUDPBaseAddress() { return csp1base; }

View File

@ -114,11 +114,6 @@ int getTimeFromString(char *buf, time_t *result) {
t.tm_mday, t.tm_mon, t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec));
*result = mktime(&t);
/* Do not check as it fails with nios
if (*result == (time_t)-1) {
LOG(logERROR, ("Could not convert time structure to time_t\n"));
return FAIL;
}*/
return OK;
}
@ -148,25 +143,14 @@ int validateKernelVersion(char *expectedVersion) {
#ifdef VIRTUAL
strcpy(currentVersion, expectedVersion);
#else
#ifndef ARMPROCESSOR
// remove first word (#version number)
const char *ptr = strstr(version, " ");
const char *ptr = strchr(version, ' ');
if (ptr == NULL) {
LOG(logERROR, ("Could not parse kernel version\n"));
return FAIL;
}
strcpy(currentVersion, ptr + 1);
#else
// remove first two words (#version number and SMP)
const char *ptr = strstr(version, "SMP ");
if (ptr == NULL) {
LOG(logERROR, ("Could not parse kernel version\n"));
return FAIL;
}
strcpy(currentVersion, ptr + 4);
strcpy(currentVersion, version + (ptr - version + 1));
#endif
#endif
currentVersion[sizeof(currentVersion) - 1] = '\0';
// convert kernel date string into time
time_t kernelDate;
@ -175,7 +159,6 @@ int validateKernelVersion(char *expectedVersion) {
("Could not parse retrieved kernel date, %s\n", currentVersion));
return FAIL;
}
LOG(logDEBUG, ("Kernel Date: [%s]\n", ctime(&kernelDate)));
// convert expected date into time
time_t expDate;
@ -184,12 +167,11 @@ int validateKernelVersion(char *expectedVersion) {
("Could not parse expected kernel date, %s\n", expectedVersion));
return FAIL;
}
LOG(logDEBUG, ("Expected Date: [%s]\n", ctime(&expDate)));
// compare if kernel time is older than expected time
if (kernelDate < expDate) {
LOG(logERROR, ("Kernel Version Incompatible (too old)!\nExpected: '%s'"
"\nGot : '%s'\n",
LOG(logERROR, ("Kernel Version Incompatible (too old)! Expected: [%s], "
"Got [%s]\n",
expectedVersion, currentVersion));
return FAIL;
}
@ -752,17 +734,13 @@ int readADCFromFile(char *fname, int *value) {
*value = -1;
if (sscanf(line, "%d", value) != 1) {
#ifdef XILINX_CHIPTESTBOARDD
LOG(logERROR, ("Could not scan adc from %s\n", line));
#else
LOG(logERROR, ("Could not scan temperature from %s\n", line));
#endif
return FAIL;
}
#ifdef EIGERD
*value /= 10;
#elif !defined(XILINX_CHIPTESTBOARDD)
#else
LOG(logINFO, ("Temperature: %.2f °C\n", (double)(*value) / 1000.00));
#endif

View File

@ -13,7 +13,7 @@
extern enum TLogLevel trimmingPrint;
#endif
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
#ifdef CHIPTESTBOARDD
#ifdef VIRTUAL
uint64_t virtual_pattern[MAX_PATTERN_LENGTH];
#endif
@ -21,8 +21,8 @@ uint64_t virtual_pattern[MAX_PATTERN_LENGTH];
extern void bus_w(u_int32_t offset, u_int32_t data);
extern u_int32_t bus_r(u_int32_t offset);
// extern int64_t get64BitReg(int aLSB, int aMSB); TODO for all servers (only
// uint64_t) extern int64_t set64BitReg(int64_t value, int aLSB, int aMSB);
extern int64_t get64BitReg(int aLSB, int aMSB);
extern int64_t set64BitReg(int64_t value, int aLSB, int aMSB);
extern uint64_t getU64BitReg(int aLSB, int aMSB);
extern void setU64BitReg(uint64_t value, int aLSB, int aMSB);
@ -44,34 +44,18 @@ void initializePatternAddresses() {
}
}
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
#ifdef CHIPTESTBOARDD
#ifdef VIRTUAL
void initializePatternWord() {
memset(virtual_pattern, 0, sizeof(virtual_pattern));
}
#endif
#endif
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
uint64_t validate_readPatternIOControl() {
#if defined(CHIPTESTBOARDD)
return getU64BitReg(PATTERN_IO_CNTRL_LSB_REG, PATTERN_IO_CNTRL_MSB_REG);
#elif defined(XILINX_CHIPTESTBOARDD)
return (uint64_t)(bus_r(PINIOCTRLREG));
#endif
}
int validate_writePatternIOControl(char *message, uint64_t arg) {
// validate input
#ifdef XILINX_CHIPTESTBOARDD
if (arg > BIT32_MSK) {
strcpy(message, "Could not set pattern IO Control. Must be 32 bit for "
"this detector\n");
LOG(logERROR, (message));
return FAIL;
}
#endif
writePatternIOControl(arg);
// validate result
@ -91,15 +75,9 @@ int validate_writePatternIOControl(char *message, uint64_t arg) {
}
void writePatternIOControl(uint64_t word) {
#ifdef CHIPTESTBOARDD
LOG(logINFO,
("Setting Pattern I/O Control: 0x%llx\n", (long long int)word));
setU64BitReg(word, PATTERN_IO_CNTRL_LSB_REG, PATTERN_IO_CNTRL_MSB_REG);
#elif defined(XILINX_CHIPTESTBOARDD)
uint32_t val = (uint32_t)word;
LOG(logINFO, ("Setting Pattern I/O Control: 0x%x\n", val));
bus_w(PINIOCTRLREG, val);
#endif
}
#endif
@ -123,7 +101,7 @@ uint64_t readPatternWord(int addr) {
// the first word in RAM as base plus the offset of the word to write (addr)
uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr * REG_OFFSET * 2;
uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2;
return getU64BitReg(reg_lsb, reg_msb);
return get64BitReg(reg_lsb, reg_msb);
#else
LOG(logDEBUG1, (" Reading (Executing) Pattern Word (addr:0x%x)\n", addr));
uint32_t reg = PATTERN_CNTRL_REG;
@ -140,7 +118,7 @@ uint64_t readPatternWord(int addr) {
// read value
#ifndef VIRTUAL
return getU64BitReg(PATTERN_OUT_LSB_REG, PATTERN_OUT_MSB_REG);
return get64BitReg(PATTERN_OUT_LSB_REG, PATTERN_OUT_MSB_REG);
#else
return virtual_pattern[addr];
#endif
@ -182,7 +160,7 @@ void writePatternWord(int addr, uint64_t word) {
uint32_t reg = PATTERN_CNTRL_REG;
// write word
setU64BitReg(word, PATTERN_IN_LSB_REG, PATTERN_IN_MSB_REG);
set64BitReg(word, PATTERN_IN_LSB_REG, PATTERN_IN_MSB_REG);
// overwrite with only addr
bus_w(reg, ((addr << PATTERN_CNTRL_ADDR_OFST) & PATTERN_CNTRL_ADDR_MSK));
@ -200,7 +178,7 @@ void writePatternWord(int addr, uint64_t word) {
// the first word in RAM as base plus the offset of the word to write (addr)
uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr * REG_OFFSET * 2;
uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2;
setU64BitReg(word, reg_lsb, reg_msb);
set64BitReg(word, reg_lsb, reg_msb);
#endif
}
@ -333,24 +311,24 @@ int validate_getPatternWaitTime(char *message, int level, uint64_t *waittime) {
uint64_t getPatternWaitTime(int level) {
switch (level) {
case 0:
return getU64BitReg(PATTERN_WAIT_TIMER_0_LSB_REG,
PATTERN_WAIT_TIMER_0_MSB_REG);
return get64BitReg(PATTERN_WAIT_TIMER_0_LSB_REG,
PATTERN_WAIT_TIMER_0_MSB_REG);
case 1:
return getU64BitReg(PATTERN_WAIT_TIMER_1_LSB_REG,
PATTERN_WAIT_TIMER_1_MSB_REG);
return get64BitReg(PATTERN_WAIT_TIMER_1_LSB_REG,
PATTERN_WAIT_TIMER_1_MSB_REG);
case 2:
return getU64BitReg(PATTERN_WAIT_TIMER_2_LSB_REG,
PATTERN_WAIT_TIMER_2_MSB_REG);
return get64BitReg(PATTERN_WAIT_TIMER_2_LSB_REG,
PATTERN_WAIT_TIMER_2_MSB_REG);
#ifndef MYTHEN3D
case 3:
return getU64BitReg(PATTERN_WAIT_TIMER_3_LSB_REG,
PATTERN_WAIT_TIMER_3_MSB_REG);
return get64BitReg(PATTERN_WAIT_TIMER_3_LSB_REG,
PATTERN_WAIT_TIMER_3_MSB_REG);
case 4:
return getU64BitReg(PATTERN_WAIT_TIMER_4_LSB_REG,
PATTERN_WAIT_TIMER_4_MSB_REG);
return get64BitReg(PATTERN_WAIT_TIMER_4_LSB_REG,
PATTERN_WAIT_TIMER_4_MSB_REG);
case 5:
return getU64BitReg(PATTERN_WAIT_TIMER_5_LSB_REG,
PATTERN_WAIT_TIMER_5_MSB_REG);
return get64BitReg(PATTERN_WAIT_TIMER_5_LSB_REG,
PATTERN_WAIT_TIMER_5_MSB_REG);
#endif
default:
return -1;
@ -391,29 +369,29 @@ void setPatternWaitTime(int level, uint64_t t) {
(long long int)t));
switch (level) {
case 0:
setU64BitReg(t, PATTERN_WAIT_TIMER_0_LSB_REG,
PATTERN_WAIT_TIMER_0_MSB_REG);
set64BitReg(t, PATTERN_WAIT_TIMER_0_LSB_REG,
PATTERN_WAIT_TIMER_0_MSB_REG);
break;
case 1:
setU64BitReg(t, PATTERN_WAIT_TIMER_1_LSB_REG,
PATTERN_WAIT_TIMER_1_MSB_REG);
set64BitReg(t, PATTERN_WAIT_TIMER_1_LSB_REG,
PATTERN_WAIT_TIMER_1_MSB_REG);
break;
case 2:
setU64BitReg(t, PATTERN_WAIT_TIMER_2_LSB_REG,
PATTERN_WAIT_TIMER_2_MSB_REG);
set64BitReg(t, PATTERN_WAIT_TIMER_2_LSB_REG,
PATTERN_WAIT_TIMER_2_MSB_REG);
break;
#ifndef MYTHEN3D
case 3:
setU64BitReg(t, PATTERN_WAIT_TIMER_3_LSB_REG,
PATTERN_WAIT_TIMER_3_MSB_REG);
set64BitReg(t, PATTERN_WAIT_TIMER_3_LSB_REG,
PATTERN_WAIT_TIMER_3_MSB_REG);
break;
case 4:
setU64BitReg(t, PATTERN_WAIT_TIMER_4_LSB_REG,
PATTERN_WAIT_TIMER_4_MSB_REG);
set64BitReg(t, PATTERN_WAIT_TIMER_4_LSB_REG,
PATTERN_WAIT_TIMER_4_MSB_REG);
break;
case 5:
setU64BitReg(t, PATTERN_WAIT_TIMER_5_LSB_REG,
PATTERN_WAIT_TIMER_5_MSB_REG);
set64BitReg(t, PATTERN_WAIT_TIMER_5_LSB_REG,
PATTERN_WAIT_TIMER_5_MSB_REG);
break;
#endif
default:
@ -797,7 +775,7 @@ int loadPattern(char *message, enum TLogLevel printLevel,
}
}
// iocontrol
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO
#ifndef MYTHEN3D
if (ret == OK) {
ret = validate_writePatternIOControl(message, pat->ioctrl);
}
@ -857,7 +835,7 @@ int getPattern(char *message, patternParameters *pat) {
pat->word[i] = retval64;
}
// iocontrol
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO
#ifndef MYTHEN3D
if (ret == OK) {
validate_readPatternIOControl();
}
@ -978,7 +956,7 @@ int loadPatternFile(char *patFname, char *errMessage) {
uint64_t word = 0;
// cannot scan values
#if defined(VIRTUAL) || defined(XILINX_CHIPTESTBOARDD)
#ifdef VIRTUAL
if (sscanf(line, "%s 0x%x 0x%lx", command, &addr, &word) != 3) {
#else
if (sscanf(line, "%s 0x%x 0x%llx", command, &addr, &word) != 3) {
@ -993,7 +971,7 @@ int loadPatternFile(char *patFname, char *errMessage) {
}
// patioctrl
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO
#ifndef MYTHEN3D
if (!strncmp(line, "patioctrl", strlen("patioctrl"))) {
uint64_t arg = 0;
@ -1085,7 +1063,7 @@ int loadPatternFile(char *patFname, char *errMessage) {
uint64_t waittime = 0;
// cannot scan values
#if defined(VIRTUAL) || defined(XILINX_CHIPTESTBOARDD)
#ifdef VIRTUAL
if (sscanf(line, "%s %d %ld", command, &level, &waittime) != 3) {
#else
if (sscanf(line, "%s %d %lld", command, &level, &waittime) != 3) {

View File

@ -1,196 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "programViaArm.h"
#include "clogger.h"
#include "sls/sls_detector_defs.h"
#include <string.h> //memset
#include <unistd.h> // access
#define CMD_ARM_LOAD_BIT_FILE \
"~/fpgautil/fpgautil -b /root/apps/xilinx-ctb/XilinxCTB.bit -f Full"
#define CMD_ARM_DEVICE_TREE_API_FOLDER \
"/sys/kernel/config/device-tree/overlays/spidr"
#define CMD_ARM_DEVICE_TREE_OVERLAY_FILE "/root/apps/xilinx-ctb/pl.dtbo"
#define CMD_ARM_LOAD_DEVICE_TREE_FORMAT "cat %s > %s/dtbo"
#define CMD_ARM_DEVICE_TREE_DST "/sys/bus/iio/devices/iio:device"
#define CMD_ARM_DEVICE_NAME "xilinx-ams", "ad7689", "dac@0", "dac@1", "dac@2"
#define TIME_LOAD_DEVICE_TREE_MS (500)
extern int executeCommand(char *command, char *result, enum TLogLevel level);
int resetFPGA(char *mess) {
LOG(logINFOBLUE, ("Reseting FPGA...\n"));
#ifndef VIRTUAL
char retvals[MAX_STR_LENGTH] = {0};
if (executeCommand(CMD_ARM_LOAD_BIT_FILE, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not reset fpga. Command to load bit file failed (%s)\n",
retvals);
LOG(logERROR, (mess));
return FAIL;
}
#endif
LOG(logINFOBLUE, ("FPGA reset successfully\n"))
return OK;
}
int loadDeviceTree(char *mess, int *adcDeviceIndex, int *dacDeviceIndex) {
if (verifyDeviceTree(mess, adcDeviceIndex, dacDeviceIndex) == OK)
return OK;
if (checksBeforeCreatingDeviceTree(mess) == FAIL)
return FAIL;
if (createDeviceTree(mess) == FAIL)
return FAIL;
if (verifyDeviceTree(mess, adcDeviceIndex, dacDeviceIndex) == FAIL) {
LOG(logERROR, ("Device tree loading failed at verification\n"));
return FAIL;
}
LOG(logINFOBLUE, ("Device tree loaded successfully\n"))
return OK;
}
int checksBeforeCreatingDeviceTree(char *mess) {
// check if device tree overlay file exists
if (access(CMD_ARM_DEVICE_TREE_OVERLAY_FILE, F_OK) != 0) {
snprintf(mess, MAX_STR_LENGTH,
"Device tree overlay file (%s) does not exist\n",
CMD_ARM_DEVICE_TREE_OVERLAY_FILE);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tDevice tree overlay file exists (%s)\n",
CMD_ARM_DEVICE_TREE_OVERLAY_FILE));
// check if device tree folder exists. If it does, remove it
if (access(CMD_ARM_DEVICE_TREE_API_FOLDER, F_OK) == 0) {
// remove it
char cmd[MAX_STR_LENGTH] = {0};
memset(cmd, 0, MAX_STR_LENGTH);
sprintf(cmd, "rmdir %s", CMD_ARM_DEVICE_TREE_API_FOLDER);
char retvals[MAX_STR_LENGTH] = {0};
memset(retvals, 0, MAX_STR_LENGTH);
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not unload device tree overlay api with %s (%s)\n",
cmd, retvals);
LOG(logWARNING, (mess));
return FAIL;
}
LOG(logINFO, ("\tUnloaded existing device tree overlay api (%s)\n",
CMD_ARM_DEVICE_TREE_API_FOLDER));
} else {
LOG(logINFO, ("\tNo existing device tree overlay api found(%s)\n",
CMD_ARM_DEVICE_TREE_API_FOLDER));
}
// create device tree overlay folder
{
char cmd[MAX_STR_LENGTH] = {0};
memset(cmd, 0, MAX_STR_LENGTH);
sprintf(cmd, "mkdir %s", CMD_ARM_DEVICE_TREE_API_FOLDER);
char retvals[MAX_STR_LENGTH] = {0};
memset(retvals, 0, MAX_STR_LENGTH);
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not create device tree overlay api with %s (%s)\n",
cmd, retvals);
LOG(logWARNING, (mess));
return FAIL;
}
LOG(logINFO, ("\tDevice tree overlay api created (%s)\n",
CMD_ARM_DEVICE_TREE_API_FOLDER));
}
return OK;
}
int createDeviceTree(char *mess) {
char cmd[MAX_STR_LENGTH] = {0};
memset(cmd, 0, MAX_STR_LENGTH);
sprintf(cmd, CMD_ARM_LOAD_DEVICE_TREE_FORMAT,
CMD_ARM_DEVICE_TREE_OVERLAY_FILE, CMD_ARM_DEVICE_TREE_API_FOLDER);
char retvals[MAX_STR_LENGTH] = {0};
memset(retvals, 0, MAX_STR_LENGTH);
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not load device tree overlay with %s (%s)\n", cmd,
retvals);
LOG(logWARNING, (mess));
return FAIL;
}
LOG(logINFO, ("\tDevice tree overlay created (cmd: %s)\n", cmd));
usleep(TIME_LOAD_DEVICE_TREE_MS * 1000);
return OK;
}
int verifyDeviceTree(char *mess, int *adcDeviceIndex, int *dacDeviceIndex) {
LOG(logINFOBLUE, ("Verifying Device Tree...\n"));
*adcDeviceIndex = 1;
*dacDeviceIndex = 2;
#ifndef VIRTUAL
// check if iio:device0-4 exists in device tree destination
int hardcodedDeviceIndex = 0;
for (int i = 0; i != 5; ++i) {
char deviceName[MAX_STR_LENGTH] = {0};
memset(deviceName, 0, MAX_STR_LENGTH);
sprintf(deviceName, "%s%d/name", CMD_ARM_DEVICE_TREE_DST, i);
// check if device exist
if (access(deviceName, F_OK) != 0) {
snprintf(mess, MAX_STR_LENGTH,
"Could not verify device tree. Device %s does not exist\n",
deviceName);
LOG(logWARNING, (mess));
return FAIL;
}
// find name
char cmd[MAX_STR_LENGTH] = {0};
memset(cmd, 0, MAX_STR_LENGTH);
sprintf(cmd, "cat %s", deviceName);
char retvals[MAX_STR_LENGTH] = {0};
memset(retvals, 0, MAX_STR_LENGTH);
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not retrieve device name from device %s (%s)\n",
deviceName, retvals);
LOG(logWARNING, (mess));
return FAIL;
}
// verify name
char *deviceNames[] = {CMD_ARM_DEVICE_NAME};
if (strstr(retvals, deviceNames[hardcodedDeviceIndex]) == NULL) {
// dacs got loaded first
if (i == 1 &&
strstr(retvals, deviceNames[hardcodedDeviceIndex + 1]) !=
NULL) {
++hardcodedDeviceIndex;
*adcDeviceIndex = 4;
*dacDeviceIndex = 1;
} else {
snprintf(
mess, MAX_STR_LENGTH,
"Could not verify device tree. Device %s expected %s but "
"got %s\n",
deviceName, deviceNames[i], retvals);
LOG(logWARNING, (mess));
return FAIL;
}
}
++hardcodedDeviceIndex;
// in case dacs were loaded first
if (hardcodedDeviceIndex == 5)
hardcodedDeviceIndex = 1;
}
#endif
LOG(logINFOBLUE, ("Device tree verified successfully [temp: 0, adc:%d, "
"dac:%d, %d, %d]\n",
*adcDeviceIndex, *dacDeviceIndex, *dacDeviceIndex + 1,
*dacDeviceIndex + 2));
return OK;
}

View File

@ -79,7 +79,7 @@ int main(int argc, char *argv[]) {
"\t-v, --version : Software version\n"
"\t-p, --port <port> : TCP communication port with client. "
"\n"
"\t-g, --nomodule : [Mythen3][Gotthard2][Xilinx Ctb] \n"
"\t-g, --nomodule : [Mythen3][Gotthard2] \n"
"\t Generic or No Module mode. Skips "
"detector type checks. \n"
"\t-f, --phaseshift <value> : [Gotthard] only. Sets phase shift. \n"

View File

@ -1,42 +0,0 @@
# SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package
add_executable(xilinx_ctbDetectorServer_virtual
slsDetectorFunctionList.c
../slsDetectorServer/src/slsDetectorServer.c
../slsDetectorServer/src/slsDetectorServer_funcs.c
../slsDetectorServer/src/communication_funcs.c
../slsDetectorServer/src/arm64.c
../slsDetectorServer/src/common.c
../slsDetectorServer/src/sharedMemory.c
../slsDetectorServer/src/loadPattern.c
../slsDetectorServer/src/programViaArm.c
../slsDetectorServer/src/communication_funcs_UDP.c
../../slsSupportLib/src/md5.c
../slsDetectorServer/src/LTC2620_Driver.c
)
include_directories(
../slsDetectorServer/include
../../slsSupportLib/include
../../slsDetectorSoftware/include/sls/
)
target_include_directories(xilinx_ctbDetectorServer_virtual
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
)
target_compile_definitions(xilinx_ctbDetectorServer_virtual
PUBLIC XILINX_CHIPTESTBOARDD ARMPROCESSOR VIRTUAL STOP_SERVER
)
target_link_libraries(xilinx_ctbDetectorServer_virtual
PUBLIC pthread rt m slsProjectCSettings
)
set_target_properties(xilinx_ctbDetectorServer_virtual PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
install(TARGETS xilinx_ctbDetectorServer_virtual
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

View File

@ -1,47 +0,0 @@
# SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package
current_dir = $(shell pwd)
main_inc = ../slsDetectorServer/include/
main_src = ../slsDetectorServer/src/
support_lib = ../../slsSupportLib/include/
det_lib = ../../slsDetectorSoftware/include/sls/
md5_dir = ../../slsSupportLib/src/
CROSS = aarch64-none-linux-gnu-
CC = $(CROSS)gcc
#TODO: allow these warnings and fix code
CFLAGS += -Wall -std=gnu99 -Wno-format-overflow -Wno-format-truncation -DXILINX_CHIPTESTBOARDD -DARMPROCESSOR -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE
#CFLAGS += -Wall -std=gnu99 -DXILINX_CHIPTESTBOARDD -DARMPROCESSOR -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(det_lib) -I$(current_dir) #-DDEBUG1 #-DVERBOSEI #-DVERBOSE
LDLIBS += -lm -lrt -pthread
PROGS = xilinx_ctbDetectorServer
DESTDIR ?= bin
INSTMODE = 0777
SRCS = slsDetectorFunctionList.c
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)arm64.c $(main_src)common.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c $(main_src)programViaArm.c $(main_src)LTC2620_Driver.c
OBJS = $(SRCS:.c=.o)
all: clean $(PROGS)
version: clean versioning $(PROGS)
boot: $(OBJS)
version_branch=$(API_BRANCH)
version_name=APIXILINXCTB
version_path=slsDetectorServers/xilinx_ctbDetectorServer
versioning:
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
$(PROGS): $(OBJS)
# echo $(OBJS)
mkdir -p $(DESTDIR)
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
mv $(PROGS) $(DESTDIR)
rm $(main_src)*.o $(md5_dir)*.o
clean:
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o

File diff suppressed because it is too large Load Diff

View File

@ -1,145 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "RegisterDefs.h"
#include "sls/sls_detector_defs.h"
#define REQRD_FRMWRE_VRSN (0x230710)
#define KERNEL_DATE_VRSN "Wed Nov 29 17:32:14 CET 2023"
#define LINKED_SERVER_NAME "xilinx_ctbDetectorServer"
#define CTRL_SRVR_INIT_TIME_US (2 * 1000 * 1000)
/* Hardware Definitions */
#define NCHAN (40)
#define NCHAN_ANALOG (32)
#define NCHAN_DIGITAL (64)
#define NCHAN_TRANSCEIVER (4)
#define NBITS_PER_TRANSCEIVER (64)
#define NCHIP (1)
#define NDAC (24)
#define NPWR (6)
#define NDAC_ONLY (NDAC - NPWR)
#define DYNAMIC_RANGE (16)
#define NUM_BYTES_PER_PIXEL (DYNAMIC_RANGE / 8)
#define DAC_DRIVER_NUM_DEVICES (3)
#define DAC_DRIVER_FILE_NAME \
("/sys/bus/iio/devices/iio:device%d/out_voltage%d_raw")
#define DAC_POWERDOWN_DRIVER_FILE_NAME \
("/sys/bus/iio/devices/iio:device%d/out_voltage%d_powerdown")
#define SLOWADC_DRIVER_FILE_NAME \
("/sys/bus/iio/devices/iio:device%d/in_voltage%d_raw")
//#define SLOWDAC_CONVERTION_FACTOR_TO_UV (62.500953)
#define TEMP_DRIVER_FILE_NAME \
("/sys/bus/iio/devices/iio:device0/in_temp7_input")
/** Default Parameters */
#define DEFAULT_NUM_FRAMES (1)
#define DEFAULT_NUM_CYCLES (1)
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
#define DEFAULT_EXPTIME (0)
#define DEFAULT_PERIOD (300 * 1000) // 300us
#define DEFAULT_READOUT_MODE (TRANSCEIVER_ONLY)
#define DEFAULT_READOUT_MODE_STR "transceiver_only"
#define DEFAULT_TRANSCEIVER_MASK (0x3) // TODO: check
#define DEFAULT_NUM_ASAMPLES (1)
#define DEFAULT_NUM_DSAMPLES (1)
#define DEFAULT_NUM_TSAMPLES (200)
#define DEFAULT_STARTING_FRAME_NUMBER (1)
#define DEFAULT_VLIMIT (-100)
#define DEFAULT_DELAY (0)
#define MAX_TRANSCEIVER_MASK (0xF)
#define MAX_TRANSCEIVER_SAMPLES (0x1FFF)
#define MAX_ANALOG_SAMPLES (0x3FFF)
#define MAX_DIGITAL_SAMPLES (0x3FFF)
#define DAC_MIN_MV (0)
#define DAC_MAX_MV (2500)
#define TICK_CLK (20) // MHz (trig_timeFromStart, frametime, timeFromStart)
#define RUN_CLK \
(100) // MHz (framesFromStart, c_swTrigger, run, waitForTrigger, starting,
// acquiring, waitForPeriod, internalStop, c_framesFromSTart_reset,
// s_start, c_stop, triggerEnable, period, frames, cycles, delay)
/* Defines in the Firmware */
#define WAIT_TIME_PATTERN_READ (10)
#define WAIT_TIME_OUT_0US_TIMES (35000) // 2s
#define BIT32_MSK (0xFFFFFFFF)
#define BIT16_MASK (0xFFFF)
#define MAX_DATA_SIZE_IN_PACKET (8144)
/* Enum Definitions */
enum ADCINDEX {
S_ADC0,
S_ADC1,
S_ADC2,
S_ADC3,
S_ADC4,
S_ADC5,
S_ADC6,
S_ADC7,
TEMP_FPGA
};
enum DACINDEX {
D0,
D1,
D2,
D3,
D4,
D5,
D6,
D7,
D8,
D9,
D10,
D11,
D12,
D13,
D14,
D15,
D16,
D17,
D_PWR_D,
D_PWR_EMPTY,
D_PWR_IO,
D_PWR_A,
D_PWR_B,
D_PWR_C
};
/* Struct Definitions */
typedef struct udp_header_struct {
uint32_t udp_destmac_msb;
uint16_t udp_srcmac_msb;
uint16_t udp_destmac_lsb;
uint32_t udp_srcmac_lsb;
uint8_t ip_tos;
uint8_t ip_ihl : 4, ip_ver : 4;
uint16_t udp_ethertype;
uint16_t ip_identification;
uint16_t ip_totallength;
uint8_t ip_protocol;
uint8_t ip_ttl;
uint16_t ip_fragmentoffset : 13, ip_flags : 3;
uint16_t ip_srcip_msb;
uint16_t ip_checksum;
uint16_t ip_destip_msb;
uint16_t ip_srcip_lsb;
uint16_t udp_srcport;
uint16_t ip_destip_lsb;
uint16_t udp_checksum;
uint16_t udp_destport;
} udp_header;
#define IP_HEADER_SIZE (20)
#define UDP_IP_HEADER_LENGTH_BYTES (28)

View File

@ -4,13 +4,10 @@ set(SOURCES
src/DetectorImpl.cpp
src/Module.cpp
src/Detector.cpp
src/HelpDacs.cpp
src/CmdProxy.cpp
src/CmdParser.cpp
src/Pattern.cpp
src/CtbConfig.cpp
src/Caller.cpp
src/CallerSpecial.cpp
src/inferAction.cpp
)
add_library(slsDetectorObject OBJECT
@ -79,30 +76,26 @@ endif()
if(SLS_USE_TEXTCLIENT)
set(det_bin_names "sls_detector_put"
# Loop over list to generate command line binaries
set(bin_names "sls_detector_put"
"sls_detector_get"
"sls_detector_acquire"
"sls_detector_help"
"sls_detector"
)
set(det_cmd_name "PUT" "GET" "READOUT" "HELP" "INFER")
list(LENGTH det_bin_names len1)
"sls_detector_help")
set(cmd_name "PUT" "GET" "READOUT" "HELP")
list(LENGTH bin_names len1)
math(EXPR len2 "${len1} - 1")
foreach(val RANGE ${len2})
list(GET det_bin_names ${val} val1)
list(GET det_cmd_name ${val} val2)
list(GET bin_names ${val} val1)
list(GET cmd_name ${val} val2)
message(STATUS "${val1} ${val2}")
add_executable(${val1} src/CmdApp.cpp)
add_executable(${val1} src/CmdLineApp.cpp)
target_link_libraries(${val1}
slsDetectorStatic
pthread
rt
slsDetectorStatic
pthread
rt
)
SET_SOURCE_FILES_PROPERTIES( src/Caller.cpp PROPERTIES COMPILE_FLAGS "-Wno-unused-variable -Wno-unused-but-set-variable")
set_target_properties(${val1} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
COMPILE_DEFINITIONS ${val2}=1
@ -111,8 +104,7 @@ if(SLS_USE_TEXTCLIENT)
set_property(TARGET ${val1} PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif()
endforeach()
install(TARGETS ${det_bin_names} DESTINATION bin)
install(TARGETS ${bin_names} DESTINATION bin)
endif(SLS_USE_TEXTCLIENT)

View File

@ -1,10 +0,0 @@
#include "Caller.h"
#include "sls/logger.h"
#include "sls/string_utils.h"
#include <iostream>
namespace sls {
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE
}

View File

@ -1,88 +0,0 @@
// This file is used as input to generate the caller class
#include "CmdParser.h"
#include "HelpDacs.h"
#include "sls/Detector.h"
#include <iostream>
#include <string>
#include <vector>
namespace sls {
class Caller {
public:
Caller(Detector *ptr) : det(ptr) {}
void call(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action, std::ostream &os = std::cout, int receiver_id = -1);
IpAddr getDstIpFromAuto();
IpAddr getSrcIpFromAuto();
UdpDestination getUdpEntry();
void GetLevelAndUpdateArgIndex(int action,
std::string levelSeparatedCommand,
int &level, int &iArg, size_t nGetArgs,
size_t nPutArgs);
void WrongNumberOfParameters(size_t expected);
template <typename V> std::string OutStringHex(const V &value) {
if (value.equal())
return ToStringHex(value.front());
return ToStringHex(value);
}
template <typename V> std::string OutStringHex(const V &value, int width) {
if (value.equal())
return ToStringHex(value.front(), width);
return ToStringHex(value, width);
}
template <typename V> std::string OutString(const Result<V> &value) {
if (value.equal())
return ToString(value.front());
return ToString(value);
}
template <typename V> std::string OutString(const V &value) {
return ToString(value);
}
template <typename V>
std::string OutString(const V &value, const std::string &unit) {
if (value.equal())
return ToString(value.front(), unit);
return ToString(value, unit);
}
std::vector<std::string> getAllCommands();
std::string list(int action);
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (1)
std::vector<std::string> args;
std::string cmd;
Detector *det;
int det_id{-1};
int rx_id{-1};
private:
bool ReplaceIfDepreciated(std::string &command);
using FunctionMap = std::map<std::string, std::string (Caller::*)(int)>;
using StringMap = std::map<std::string, std::string>;
Detector *ptr; // pointer to the detector that executes the command
FunctionMap functions{
{"list", &Caller::list},
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (2)
};
StringMap depreciated_functions{
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (3)
};
};
} // namespace sls

View File

@ -1,236 +0,0 @@
import argparse
import json
from pathlib import Path
# command to generate the ast
# clang version: 14.0.0-1ubuntu1.1
# clang++ -Xclang -ast-dump=json -Xclang -ast-dump-filter -Xclang StringTo -c ToString.cpp -I ../include/ -std=gnu++11
#
import yaml
AUTOCOMPLETE_PATH = Path(__file__).parent
DUMP_PATH = AUTOCOMPLETE_PATH / 'dump.json'
FIXED_PATH = AUTOCOMPLETE_PATH / 'fixed.json'
type_values = {
'special::mv': ["mv", "mV"],
"special::deg": ["deg"],
"special::time_unit": ["s", "ms", "us", "ns"],
"special::hard": ["hard"],
"special::force-delete-normal-file": ["--force-delete-normal-file"],
"special::currentSourceFix": ["fix", "nofix"],
"special::currentSourceLow": ["normal", "low"],
"special::path": [],
"special::pedestal_parameters" : ["", "0"]
}
def get_types(arg_types):
ret = set()
for arg_type in arg_types:
if type_info(arg_type) == 'base':
if arg_type == 'bool':
ret = ret.union(["0", "1"])
else:
tmp = [not_list for not_list in type_values[arg_type] if not isinstance(not_list, list)]
ret = ret.union(tmp)
#Intercept the options and in case detector specific options appear replace the
#list of options with a command line call that fetches them
#TODO! Rename sls_detector_get
if "defs::dacIndex" in arg_types:
return "`sls_detector_get daclist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
elif "defs::detectorSettings" in arg_types:
return "`sls_detector_get settingslist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
elif "defs::timingMode" in arg_types:
return "`sls_detector_get timinglist | sed -e 's/.*\[\(.*\)\].*/\\1/' | sed 's/,//g'`"
return ret
def type_info(type_name):
if type_name.startswith('defs::') or type_name.startswith('slsDetectorDefs::'):
return 'enum'
if type_name.startswith('special::'):
return 'special'
return 'base'
def get_enum(function):
return function['type']['qualType'].split(' ')[0]
def get_literal(ifstmt):
stringliteral = []
expression = ifstmt['inner'][0]
if expression['kind'] == 'BinaryOperator':
if expression['opcode'] == '!=':
return None, None
for cxxOperatorCall in expression['inner']:
if cxxOperatorCall['kind'] == 'CXXOperatorCallExpr':
implicitCastExpr = cxxOperatorCall['inner'][2]
stringliteral.append(implicitCastExpr['inner'][0]['value'][1:-1])
else:
cxxOperatorCall = expression
implicitCastExpr = cxxOperatorCall['inner'][2]
stringliteral = implicitCastExpr['inner'][0]['value'][1:-1]
retstmt = get_object_by_kind(ifstmt['inner'], 'ReturnStmt')
declrefexpt = get_object_by_kind(retstmt['inner'], 'DeclRefExpr')
enum_val = declrefexpt["referencedDecl"]["name"]
return enum_val, stringliteral
def get_object_by_kind(inner, kind, position=1):
for obj in inner:
if obj['kind'] == kind:
position -= 1
if position == 0:
return obj
return None
def generate_type_values():
functions = json.loads(FIXED_PATH.read_text())
for function in functions:
if function['kind'] != 'FunctionDecl' or function['name'] != 'StringTo':
continue
enum = get_enum(function)
if not enum.startswith('defs::'):
continue
# if enum != 'defs::dacIndex':
# continue
if not function['loc']['file'].endswith('ToString.cpp'):
continue
compound_stmt = get_object_by_kind(function['inner'], 'CompoundStmt')
for ifstmt in compound_stmt['inner']:
if ifstmt['kind'] != 'IfStmt':
continue
enum_val, stringliteral = get_literal(ifstmt)
if enum_val is None:
continue
if enum not in type_values or type_values[enum] is None:
type_values[enum] = []
type_values[enum].append(stringliteral)
items = list(type_values.items())
for key, val in items:
if key.startswith('defs::'):
new_key = key.split('::')[1]
new_key = 'slsDetectorDefs::' + new_key
type_values[new_key] = val
elif key.startswith('slsDetectorDefs::'):
new_key = key.split('::')[1]
new_key = 'defs::' + new_key
type_values[new_key] = val
return json.dumps(type_values, indent=2)
def fix_json():
with DUMP_PATH.open('r') as f:
tmp = '[\n'
for line in f.read().split('\n'):
if line.startswith('}'):
tmp += line + ',\n'
else:
tmp += line + '\n'
tmp = tmp[:-3] + '\n]'
with FIXED_PATH.open('w') as f:
f.write(tmp)
def generate_bash_autocomplete(output_path=Path(__file__).parent / 'bash_autocomplete.sh', input_path=Path(__file__).parent / 'bash_autocomplete.in.sh'):
generate_type_values()
output_file = output_path.open('w')
template_file = input_path.open('r')
def writeline(line):
output_file.write(line + '\n')
class if_block:
def __init__(self, condition):
self.condition = condition
def __enter__(self):
output_file.write('if [[ ' + self.condition + ' ]]; then\n')
def __exit__(self, type, value, traceback):
output_file.write('fi\n')
class function:
def __init__(self, name):
self.name = name
def __enter__(self):
output_file.write(self.name + '() {\n')
def __exit__(self, type, value, traceback):
output_file.write('}\n')
command_path = Path(__file__).parent.parent / 'extended_commands.yaml'
commands = yaml.unsafe_load(command_path.open('r'))
for line in template_file:
if '-- THIS LINE WILL BE REPLACED WITH GENERATED CODE --' not in line:
output_file.write(line)
continue
writeline(f'local SLS_COMMANDS=" {" ".join(commands.keys())} "')
# generate functions
for command_name, command in commands.items():
# added for debugging
if command_name == 'xxxexptime':
continue
with function('__' + command_name):
writeline('FCN_RETURN=""')
actions = ['GET', 'PUT']
for action in actions:
if action in command['actions'] and 'args' in command['actions'][action]:
args = command['actions'][action]['args']
possible_argc = {}
for arg in args:
if arg['argc'] == 0:
pass
for i in range(arg['argc']):
if i + 1 not in possible_argc:
possible_argc[i + 1] = []
possible_argc[i + 1].append(arg['arg_types'][i])
if possible_argc:
with if_block(f'${{IS_GET}} -eq {"1" if action == "GET" else "0"}'):
for argc in possible_argc:
with if_block(f'"${{cword}}" == "{argc + 1}"'):
if "defs::detectorSettings" in possible_argc[argc]:
print(argc, command_name, possible_argc[argc])
choices = get_types(possible_argc[argc])
#check if we got choices back or a bash command
if isinstance(choices, (list,set)):
writeline(f'FCN_RETURN="{" ".join(sorted(choices))}"')
else:
writeline(f'FCN_RETURN="{choices}"')
if 'special::path' in possible_argc[argc]:
writeline('IS_PATH=1')
writeline('return 0')
output_file.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='use parsed c++ code to generate autocomplete snippets')
parser.add_argument('-f', '--fix', action='store_true', help='fix the parsed ast to make it loadable')
# parser.add_argument('-p', '--path', type=str, help='output path to the fixed ast', default='ast.json')
args = parser.parse_known_args()
if args[0].fix:
fix_json()
ret = generate_type_values()
print(ret)

View File

@ -1,167 +0,0 @@
# GENERATED FILE - DO NOT EDIT
# ANY CHANGES TO THIS FILE WILL BE OVERWRITTEN
_sd() {
# Taken from https://github.com/scop/bash-completion/blob/15b74b1050333f425877a7cbd99af2998b95c476/bash_completion#L770C12-L770C12
# Reassemble command line words, excluding specified characters from the
# list of word completion separators (COMP_WORDBREAKS).
# @param $1 chars Characters out of $COMP_WORDBREAKS which should
# NOT be considered word breaks. This is useful for things like scp where
# we want to return host:path and not only path, so we would pass the
# colon (:) as $1 here.
# @param $2 words Name of variable to return words to
# @param $3 cword Name of variable to return cword to
#
_comp__reassemble_words()
{
local exclude="" i j line ref
# Exclude word separator characters?
if [[ $1 ]]; then
# Yes, exclude word separator characters;
# Exclude only those characters, which were really included
exclude="[${1//[^$COMP_WORDBREAKS]/}]"
fi
# Default to cword unchanged
printf -v "$3" %s "$COMP_CWORD"
# Are characters excluded which were former included?
if [[ $exclude ]]; then
# Yes, list of word completion separators has shrunk;
line=$COMP_LINE
# Re-assemble words to complete
for ((i = 0, j = 0; i < ${#COMP_WORDS[@]}; i++, j++)); do
# Is current word not word 0 (the command itself) and is word not
# empty and is word made up of just word separator characters to
# be excluded and is current word not preceded by whitespace in
# original line?
while [[ $i -gt 0 && ${COMP_WORDS[i]} == +($exclude) ]]; do
# Is word separator not preceded by whitespace in original line
# and are we not going to append to word 0 (the command
# itself), then append to current word.
[[ $line != [[:blank:]]* ]] && ((j >= 2)) && ((j--))
# Append word separator to current or new word
ref="$2[$j]"
printf -v "$ref" %s "${!ref-}${COMP_WORDS[i]}"
# Indicate new cword
((i == COMP_CWORD)) && printf -v "$3" %s "$j"
# Remove optional whitespace + word separator from line copy
line=${line#*"${COMP_WORDS[i]}"}
# Indicate next word if available, else end *both* while and
# for loop
if ((i < ${#COMP_WORDS[@]} - 1)); then
((i++))
else
break 2
fi
# Start new word if word separator in original line is
# followed by whitespace.
[[ $line == [[:blank:]]* ]] && ((j++))
done
# Append word to current word
ref="$2[$j]"
printf -v "$ref" %s "${!ref-}${COMP_WORDS[i]}"
# Remove optional whitespace + word from line copy
line=${line#*"${COMP_WORDS[i]}"}
# Indicate new cword
((i == COMP_CWORD)) && printf -v "$3" %s "$j"
done
((i == COMP_CWORD)) && printf -v "$3" %s "$j"
else
# No, list of word completions separators hasn't changed;
for i in "${!COMP_WORDS[@]}"; do
printf -v "$2[i]" %s "${COMP_WORDS[i]}"
done
fi
}
local FCN_RETURN=""
local IS_PATH=0
# -- THIS LINE WILL BE REPLACED WITH GENERATED CODE --
COMPREPLY=()
local OPTIONS_NEW=""
# check if bash or zsh
# _get_comp_words_by_ref is a bash built-in function, we check if it exists
declare -Ff _get_comp_words_by_ref > /dev/null && IS_BASH=1 || IS_BASH=0
# bash interprets the colon character : as a special character and splits the argument in two
# different than what zsh does
# https://stackoverflow.com/a/3224910
# https://stackoverflow.com/a/12495727
local cur
local cword words=()
_comp__reassemble_words ":" words cword
cur=${words[cword]}
# check the action (get or put)
case "${words[0]}" in
"sls_detector_get" | "g" | "detg")
local IS_GET=1
;;
*)
local IS_GET=0
;;
esac
# if no command is written, autocomplete with the commands
if [[ ${cword} -eq 1 ]]; then
# local SLS_COMMANDS="trimbits exptime"
local SLS_COMMANDS_NEW=""
case "$cur" in
[0-9]*:*)
local suggestions=($(compgen -W "${SLS_COMMANDS}" -- "${cur#*:}"))
COMPREPLY=( ${suggestions[*]} )
;;
[0-9]*)
COMPREPLY=()
;;
*)
COMPREPLY=( $( compgen -W "$SLS_COMMANDS -h" -- "$cur" ) );;
esac
return 0
fi
if [[ ${cword} -eq 2 ]] && [[ ${words[1]} == "-h" ]]; then
COMPREPLY=( $( compgen -W "$SLS_COMMANDS" -- "$cur" ) )
return 0
fi
# if a command is written, autocomplete with the options
# call the function for the command
if [[ "$SLS_COMMANDS" == *"${words[1]##*:}"* ]]; then
__"${words[1]##*:}"
fi
# if IS_PATH is activated, autocomplete with the path
if [[ ${IS_PATH} -eq 1 ]]; then
COMPREPLY=($(compgen -f -- "${cur}"))
return 0
fi
# autocomplete with the options
COMPREPLY=($(compgen -W "${FCN_RETURN}" -- "${cur}"))
}
complete -F _sd -o filenames sls_detector_get
complete -F _sd -o filenames g
complete -F _sd -o filenames detg
complete -F _sd -o filenames sls_detector_put
complete -F _sd -o filenames p
complete -F _sd -o filenames detp
complete -F _sd -o filenames sls_detector
complete -F _sd -o filenames det

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,177 +0,0 @@
#### simpler version of autocomplete.sh to understand the logic
#### each command has its own function when called it will produce the possible values for autocompletion
_sd() {
# Reassemble command line words, excluding specified characters from the
# list of word completion separators (COMP_WORDBREAKS).
# @param $1 chars Characters out of $COMP_WORDBREAKS which should
# NOT be considered word breaks. This is useful for things like scp where
# we want to return host:path and not only path, so we would pass the
# colon (:) as $1 here.
# @param $2 words Name of variable to return words to
# @param $3 cword Name of variable to return cword to
#
_comp__reassemble_words()
{
local exclude="" i j line ref
# Exclude word separator characters?
if [[ $1 ]]; then
# Yes, exclude word separator characters;
# Exclude only those characters, which were really included
exclude="[${1//[^$COMP_WORDBREAKS]/}]"
fi
# Default to cword unchanged
printf -v "$3" %s "$COMP_CWORD"
# Are characters excluded which were former included?
if [[ $exclude ]]; then
# Yes, list of word completion separators has shrunk;
line=$COMP_LINE
# Re-assemble words to complete
for ((i = 0, j = 0; i < ${#COMP_WORDS[@]}; i++, j++)); do
# Is current word not word 0 (the command itself) and is word not
# empty and is word made up of just word separator characters to
# be excluded and is current word not preceded by whitespace in
# original line?
while [[ $i -gt 0 && ${COMP_WORDS[i]} == +($exclude) ]]; do
# Is word separator not preceded by whitespace in original line
# and are we not going to append to word 0 (the command
# itself), then append to current word.
[[ $line != [[:blank:]]* ]] && ((j >= 2)) && ((j--))
# Append word separator to current or new word
ref="$2[$j]"
printf -v "$ref" %s "${!ref-}${COMP_WORDS[i]}"
# Indicate new cword
((i == COMP_CWORD)) && printf -v "$3" %s "$j"
# Remove optional whitespace + word separator from line copy
line=${line#*"${COMP_WORDS[i]}"}
# Indicate next word if available, else end *both* while and
# for loop
if ((i < ${#COMP_WORDS[@]} - 1)); then
((i++))
else
break 2
fi
# Start new word if word separator in original line is
# followed by whitespace.
[[ $line == [[:blank:]]* ]] && ((j++))
done
# Append word to current word
ref="$2[$j]"
printf -v "$ref" %s "${!ref-}${COMP_WORDS[i]}"
# Remove optional whitespace + word from line copy
line=${line#*"${COMP_WORDS[i]}"}
# Indicate new cword
((i == COMP_CWORD)) && printf -v "$3" %s "$j"
done
((i == COMP_CWORD)) && printf -v "$3" %s "$j"
else
# No, list of word completions separators hasn't changed;
for i in "${!COMP_WORDS[@]}"; do
printf -v "$2[i]" %s "${COMP_WORDS[i]}"
done
fi
}
__exptime(){
if [ "${IS_GET}" == "1" ]; then
if [ "${cword}" == "2" ]; then
FCN_RETURN="s ms us ns"
fi
else
if [ "${cword}" == "2" ]; then
FCN_RETURN=""
fi
if [ "${cword}" == "3" ]; then
FCN_RETURN="s ms us ns"
fi
fi
}
# trimbits will activate IS_PATH and signal that its input is a path
__trimbits(){
if [ "${IS_GET}" == "1" ]; then
if [ "${cword}" == "2" ]; then
FCN_RETURN=""
IS_PATH=1
fi
else
if [ "${cword}" == "2" ]; then
FCN_RETURN=""
IS_PATH=1
fi
fi
}
local cword words=()
_comp__reassemble_words ":" words cword
local FCN_RETURN=""
local IS_PATH=0
COMPREPLY=()
local OPTIONS_NEW=""
# _get_comp_words_by_ref -n : cur
local cur=${words[cword]}
# check the action (get or put)
if [ "${words[0]}" == "sls_detector_get" ]; then
local IS_GET=1
else
local IS_GET=0
fi
# if no command is written, autocomplete with the commands
if [[ ${cword} -eq 1 ]]; then
local SLS_COMMANDS="trimbits exptime"
local SLS_COMMANDS_NEW=""
case "$cur" in
[0-9]*:*)
local suggestions=($(compgen -W "${SLS_COMMANDS}" -- "${cur#*:}"))
COMPREPLY=( ${suggestions[*]} )
;;
[0-9]*)
COMPREPLY=()
;;
*)
COMPREPLY=( $( compgen -W "$SLS_COMMANDS -h" -- "$cur" ) );;
esac
return 0
fi
# if a command is written, autocomplete with the options
# call the function for the command
__"${words[1]##*:}"
# if IS_PATH is activated, autocomplete with the path
if [[ ${IS_PATH} -eq 1 ]]; then
COMPREPLY=($(compgen -f -- "${cur}"))
return 0
fi
# autocomplete with the options
COMPREPLY=($(compgen -W "${FCN_RETURN}" -- "${cur}"))
}
complete -F _sd -o filenames sls_detector_put
complete -F _sd -o filenames sls_detector_get
complete -F _sd -o filenames g
complete -F _sd -o filenames p
complete -F _sd -o filenames detg
complete -F _sd -o filenames detp
complete -F _sd -o filenames sls_detector
complete -F _sd -o filenames det

View File

@ -1,77 +0,0 @@
# GENERATED FILE - DO NOT EDIT
# ANY CHANGES TO THIS FILE WILL BE OVERWRITTEN
_sd() {
# -- THIS LINE WILL BE REPLACED WITH GENERATED CODE --
local FCN_RETURN=""
local IS_PATH=0
COMPREPLY=()
local OPTIONS_NEW=""
words=("${COMP_WORDS[@]}")
cword=$COMP_CWORD
local cur=${words[cword]}
# check the action (get or put)
case "${words[0]}" in
"sls_detector_get" | "g" | "detg")
local IS_GET=1
;;
*)
local IS_GET=0
;;
esac
# if no command is written, autocomplete with the commands
if [[ ${cword} -eq 1 ]]; then
case "$cur" in
[0-9]*)
for i in $SLS_COMMANDS; do
SLS_COMMANDS_NEW="${SLS_COMMANDS_NEW} ${cur%%:*}:$i"
done
COMPREPLY=( $( compgen -W "${SLS_COMMANDS_NEW}" -- "$cur" ) );;
*)
COMPREPLY=( $( compgen -W "$SLS_COMMANDS -h" -- "$cur" ) );;
esac
return 0
fi
if [[ ${cword} -eq 2 ]] && [[ ${words[1]} == "-h" ]]; then
COMPREPLY=( $( compgen -W "$SLS_COMMANDS" -- "$cur" ) )
return 0
fi
# if a command is written, autocomplete with the options
# call the function for the command
if [[ "$SLS_COMMANDS" == *"${words[1]##*:}"* ]]; then
__"${words[1]##*:}"
fi
# if IS_PATH is activated, autocomplete with the path
if [[ ${IS_PATH} -eq 1 ]]; then
COMPREPLY=($(compgen -f -- "${cur}"))
return 0
fi
# autocomplete with the options
COMPREPLY=($(compgen -W "${FCN_RETURN}" -- "${cur}"))
}
complete -F _sd -o filenames sls_detector_get
complete -F _sd -o filenames g
complete -F _sd -o filenames detg
complete -F _sd -o filenames sls_detector_put
complete -F _sd -o filenames p
complete -F _sd -o filenames detp
complete -F _sd -o filenames sls_detector
complete -F _sd -o filenames det

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,379 +0,0 @@
import copy
import logging
import yaml
from pathlib import Path
class CommandParser:
def __init__(
self,
commands_file: Path = Path(__file__).parent.parent / 'commands.yaml',
output_file: Path = Path(__file__).parent.parent / 'extended_commands.yaml'
):
self.output_file = output_file
self.commands_file = commands_file
self.fp = self.commands_file.open('r')
self.simple_commands = yaml.unsafe_load(self.fp)
self.extended_commands = {}
self.argc_set = set()
self.logger = logging.getLogger('command_parser')
self.__current_action: str = ''
FORMAT = '[%(levelname)s] %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)
self.propagate_config = {
'require_det_id': False,
'convert_det_id': True,
'input': [],
'input_types': [],
'function': '',
'output': [],
'cast_input': [],
'check_det_id': False,
'arg_types': [],
# 'store_result_in_t': False, # always true in GET action
}
self.default_config = {
'infer_action': True,
'help': '',
'actions': {}
}
def _verify_argument(self, arg, infer_action, command_name, action):
if arg['function'] == '' and 'ctb_output_list' not in arg:
special_exception_message_list = ["Cannot put", "Cannot get"]
if 'exceptions' in arg and arg['exceptions'][0]['condition'] == 'true' and any(ele in arg['exceptions'][0]['message'] for ele in special_exception_message_list):
self.logger.warning(f"{command_name} has a special exception message for {action}.")
else:
self.logger.warning(f"{command_name} [{action}] does not have a function")
if len(arg['input_types']) != len(arg['input']):
raise ValueError(f'Argument {arg} does not have the correct number of inputs')
if 'separate_time_units' in arg:
if arg['separate_time_units']['input'] == "":
raise ValueError(f'Argument {arg} does not have the correct number of inputs for separate_time_units')
if len(arg['separate_time_units']['output']) != 2:
raise ValueError(f'Argument {arg} does not have the correct number of outputs for separate_time_units')
if 'convert_to_time' in arg:
if len(arg['convert_to_time']['input']) != 2:
raise ValueError(f'Argument {arg} does not have the correct number of inputs for convert_to_time')
if len(arg['convert_to_time']['output']) == "":
raise ValueError(f'Argument {arg} does not have the correct number of outputs for convert_to_time')
# if infer_action:
# if arg['argc'] in self.argc_set:
# raise ValueError(f'Argument {arg} has a duplicate argc')
# self.argc_set.add(arg['argc'])
def verify_format(self):
# todo verify detectors
# todo verify circular inheritance
# todo verify child commands (those that inherit)
# todo verify that there is no wrongly typed parameters
# todo verify that the same number of input_types and input are given
# todo verify that each argument has argc (error can happen when inheriting)
for command_name, command in self.simple_commands.items():
if 'inherit_actions' in command or 'template' in command and command[
'template'] or 'is_description' in command and command['is_description']:
continue
self.argc_set = set()
if 'infer_action' not in command:
command['infer_action'] = True
if 'actions' not in command:
raise ValueError(f'Command {command_name} does not have any actions')
for action, action_params in command['actions'].items():
if 'argc' in action_params:
if 'args' in action_params:
raise ValueError(f'Action {action} has both argc and args')
arg = {**self.propagate_config, **action_params}
self._verify_argument(arg, command['infer_action'], command_name, action)
elif 'args' in action_params:
if type(action_params['args']) is not list:
raise ValueError(f'Action {action} args is not a list')
if len(action_params['args']) == 0:
raise ValueError(f'Action {action} args is empty')
action_args = {**self.propagate_config, **action_params}
del action_args['args']
for arg in action_params['args']:
arg = {**action_args, **arg}
self._verify_argument(arg, command['infer_action'], command_name, action)
self.logger.info('Commands file is valid ✅️')
return True
def _parse_inherited_command(self, parent, command, simple_parent):
"""
parse a command that inherits from parent command
:param parent: parsed parent command
:param command: the current command
:param simple_parent: unparsed parent command
:return: parsed command
"""
# deepcopy parent and command to avoid modifying the originals
command = copy.deepcopy(command)
config = copy.deepcopy(parent)
# add help
if 'help' in command:
config['help'] = command['help']
if 'actions' not in command:
return config
for action, command_params in command['actions'].items():
self.__current_action = action
if action not in config['actions']:
# todo: handle this case
pass
parent_params = config['actions'][action]
if 'args' in command_params:
# child has args => inherit action level params from parent + override with child args + use child's
# action level params
context = {**self.propagate_config, **simple_parent['actions'][action], **command_params}
config['actions'][action]['args'] = self.parse_action(context, command_params['args'])
elif 'argc' in command_params:
# child has action level args (argc)
context = {**self.propagate_config, **simple_parent['actions'][action], **command_params}
config['actions'][action]['args'] = self.parse_action(context, [])
else:
# child does not have args => use parent's action level params + override with child's action level
if 'args' in parent_params:
config['actions'][action]['args'] = self.parse_action({}, parent_params['args'], command_params)
if 'detectors' in command_params:
if command_params['detectors'] is None:
# if child has an empty detector section, then delete the parent's detector section
del config['actions'][action]['detectors']
continue
for detector_name, detector_params in command_params['detectors'].items():
if 'detectors' not in config['actions'][action]:
config['actions'][action]['detectors'] = {}
config_detector = config['actions'][action]['detectors']
if 'detectors' not in parent_params or detector_name not in parent_params['detectors']:
if 'args' in detector_params:
# if child has detector args and parent does not have detectors
# => use child's detector args
context = {**self.propagate_config, **simple_parent['actions'][action], **detector_params}
config_detector[detector_name] = self.parse_action(context, detector_params['args'])
elif 'args' in parent_params:
# if child does not have detector args and parent does not have detectors
# => use the child's action args
context = {**self.propagate_config, **simple_parent['actions'][action]}
config_detector[detector_name] = self.parse_action(context,
config['actions'][action]['args'],
detector_params)
elif detector_name in parent_params['detectors']:
if 'args' in detector_params:
# child and parent have the same detector and child has detector args
# => use child's detector args
context = {
**self.propagate_config,
**simple_parent['actions'][action],
**simple_parent['actions'][action]['detectors'][detector_name],
}
config_detector[detector_name] = self.parse_action(context, detector_params['args'])
else:
# child and parent have the same detector and child does not have detector args
# => use parent's detector args
priority_context = {**command_params, **detector_params}
config_detector[detector_name] = self.parse_action(
{},
parent_params['detectors'][detector_name],
priority_context
)
else:
pass
return config
def _parse_command(self, command):
"""
logic function for parse_command.
This function is recursive
:return: parsed command
"""
config = self.default_config.copy()
config.update(command)
config['actions'] = {}
# check if command inherits from another command
if 'inherit_actions' in command:
if command['inherit_actions'] in self.extended_commands:
# if parent command has already been parsed, use that
parent = self.extended_commands[command['inherit_actions']]
else:
# if parent command has not been parsed, parse it
parent = self.parse_command(command['inherit_actions'])
# parse the current command and merge it with the parent command
config = self._parse_inherited_command(parent, command, self.simple_commands[command['inherit_actions']])
return config
if 'actions' not in command:
return config
for action, action_params in command['actions'].items():
self.__current_action = action
config['actions'][action] = {}
config_action = config['actions'][action]
# the context in the current command and the current action
action_context = {**self.propagate_config, **action_params}
if 'args' not in action_params:
# parse the action with the action context
if action_params.keys() != {'detectors'}:
config_action['args'] = self.parse_action(action_context, [])
else:
config_action['args'] = self.parse_action(action_context, action_params['args'])
# check if the action has detectors
if 'detectors' in action_params:
config_action['detectors'] = {}
for detector_name, detector_params in action_params['detectors'].items():
# get the context for the detector and merge it with the action context
detector_context = {**action_context, **detector_params}
# if the detector does not have args, then use the action args
# otherwise, use the detector args and override the action args
tmp_args = []
if 'args' not in detector_params:
if 'args' in config_action:
tmp_args = config_action['args']
else:
tmp_args = detector_params['args']
detector_params['args'] = tmp_args
# parse the action with the detector context
config_action['detectors'][detector_name] = self.parse_action(detector_context,
tmp_args,
detector_params)
return config
def sanitize_argument(func):
def f(self, action_context, args_old, priority_context={}):
args = func(self, action_context, args_old, priority_context)
for i, arg in enumerate(args):
if 'args' in arg:
del arg['args']
if 'detectors' in arg:
del arg['detectors']
if not arg['cast_input']:
# if the cast_input is empty, then set it to False
arg['cast_input'] = [False] * len(arg['input'])
elif len(arg['cast_input']) != len(arg['input']):
# if the cast_input is not the same length as the input, then set it to False
arg['cast_input'] = [False] * len(arg['input'])
self.logger.warning(f'cast_input for {arg["function"]} '
f'with argc: {arg["argc"]} has different length than input')
if 'store_result_in_t' not in arg:
if self.__current_action == 'GET':
arg['store_result_in_t'] = True
else:
arg['store_result_in_t'] = False
return args
return f
@sanitize_argument
def parse_action(self, action_context, args, priority_context={}):
"""
parse an action
:param action_context: context of the action
:param args: arguments to be used in the action
:param priority_context: context that should override the arguments params
:return: parsed action
"""
def add_cast_input(argument):
return argument
# deepcopy action_context to avoid modifying the original
action_context = {**self.propagate_config, **copy.deepcopy(action_context)}
priority_context = copy.deepcopy(priority_context)
if 'detectors' in action_context:
del action_context['detectors']
if 'detectors' in priority_context:
del priority_context['detectors']
if args == []:
# if there are no arguments, then the action has only one argument
context = {**action_context, **priority_context}
return [add_cast_input(context)]
ret_args = []
if 'args' in action_context:
del action_context['args']
if 'args' in priority_context:
del priority_context['args']
# if there are arguments, then merge them with the action context and priority context
for arg in args:
arg = {**action_context, **arg, **priority_context}
ret_args.append(add_cast_input(arg))
return ret_args
def parse_command(self, command_name):
"""
parse a single command
This function is recursive
:param command_name: name of the command to parse
:return: the parsed command
"""
command = self.simple_commands[command_name]
parsed_command = self._parse_command(command)
if 'function_alias' not in command:
if 'command_name' in command:
parsed_command['function_alias'] = command['command_name']
else:
parsed_command['function_alias'] = command_name
if 'command_name' not in command:
parsed_command['command_name'] = command_name
if 'template' in command and command['template']:
return parsed_command
self.extended_commands[command_name] = parsed_command
return self.extended_commands[command_name]
def parse_all_commands(self):
"""
iterate over all commands in yaml file and parse them
:return: None
"""
for command_name in self.simple_commands:
# todo remove this (added for debugging)
if command_name != 'xtiming':
self.parse_command(command_name)
# post-process the parsed commands
self.post_process_all_commands()
yaml.Dumper.ignore_aliases = lambda *args: True
self.logger.info(f'parsed {len(self.extended_commands)} commands')
yaml.dump(self.extended_commands, self.output_file.open('w'), default_flow_style=False)
def post_process_all_commands(self):
for command_name, command in self.extended_commands.items():
if 'is_description' in command and command['is_description']:
continue
for action_name, action, in command['actions'].items():
for arg in action['args']:
if arg['argc'] == 0:
arg['arg_types'] = []
continue
if arg['argc'] == -1:
pass
if arg['arg_types'] == []:
arg['arg_types'] = arg['input_types']
# command_parser = CommandParser(Path(
# '/afs/psi.ch/user/b/braham_b/github/slsDetectorPackage/slsDetectorSoftware/generator/tests/command_parser/data/detectors.yaml'))
command_parser = CommandParser()
if __name__ == '__main__':
command_parser.verify_format()
command_parser.parse_all_commands()

View File

@ -1,282 +0,0 @@
class CodeGenerator:
def __init__(self):
self.file = None
self.actions_dict = {
'GET': 'slsDetectorDefs::GET_ACTION',
'PUT': 'slsDetectorDefs::PUT_ACTION',
'READOUT': 'slsDetectorDefs::READOUT_ACTION',
'HELP': 'slsDetectorDefs::HELP_ACTION',
}
self.template_file = None
def open(self, path):
self.file = path.open('w')
def close(self):
self.file.close()
self.file = None
def write_line(self, line):
self.file.write(line + '\n')
def write(self, text):
self.file.write(text)
def write_opening(self, path):
"""Write the opening file for the caller.cpp file"""
self.template_file = path.open('r')
for line in self.template_file:
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE" in line:
return
self.file.write(line)
def write_closing(self):
"""Write the closing file for the caller.cpp file"""
for line in self.template_file.readlines():
self.file.write(line)
self.template_file.close()
def write_header(self, in_path, out_path, commands, deprecated_commands):
"""Write the header file for the caller.h file"""
with out_path.open('w') as fp:
with in_path.open('r') as fp2:
for line in fp2:
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (1)" in line:
for command_name, command in commands.items():
if 'duplicate_function' in command and command['duplicate_function']:
continue
fp.write(f'std::string {command["function_alias"]}(int action);\n')
continue
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (2)" in line:
map_string = ''
for command_name, command in commands.items():
map_string += f'{{"{command_name}", &Caller::{command["function_alias"]}}},'
fp.write(map_string[:-1] + '\n')
continue
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (3)" in line:
for key, value in deprecated_commands.items():
fp.write(f'{{"{key}", "{value}"}},\n')
continue
fp.write(line)
def write_infer_header(self, in_path, out_path, commands):
"""Write the header file for the inferAction.h file"""
with out_path.open('w+') as fp:
with in_path.open('r') as fp2:
for line in fp2:
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (1) - DO NOT REMOVE" in line:
for command_name, command in commands.items():
if 'duplicate_function' in command and command['duplicate_function']:
continue
fp.write(f'int {command["function_alias"]}();\n')
continue
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (2) - DO NOT REMOVE" in line:
map_string = ''
for command_name, command in commands.items():
map_string += f'{{"{command_name}", &InferAction::{command["function_alias"]}}},'
fp.write(map_string[:-1] + '\n')
continue
fp.write(line)
def write_infer_cpp(self, in_path, out_path, commands, non_dist, type_dist):
"""Write the source file for the inferAction.cpp file"""
with in_path.open('r') as fp2:
for line in fp2:
if "THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (1) - DO NOT REMOVE" in line:
for command_name, command in commands.items():
if 'duplicate_function' in command and command['duplicate_function']:
continue
with function('int', f"InferAction::{command['function_alias']}", []) as f:
if (command_name, -1) in non_dist| type_dist:
self.write_line(
f'throw RuntimeError("sls_detector is disabled for command: {command_name}. Use sls_detector_get or sls_detector_put");')
elif not command['infer_action']:
self.write_line('throw RuntimeError("infer_action is disabled");')
else:
checked_argcs = set()
for action, action_params in command['actions'].items():
for arg in action_params['args']:
if arg['argc'] in checked_argcs:
continue
checked_argcs.add(arg['argc'])
with if_block(f'args.size() == {arg["argc"]}'):
# check if this argc is not distinguishable
if (command_name, arg["argc"]) in non_dist | type_dist:
self.write_line(
f'throw RuntimeError("sls_detector is disabled for command: {command_name} with number of arguments {arg["argc"]}. Use sls_detector_get or sls_detector_put");')
else:
self.write_line(f'return {self.actions_dict[action]};')
with else_block():
self.write_line(
'throw RuntimeError("Could not infer action: Wrong number of arguments");')
continue
self.write_line(line)
def write_check_arg(self):
pass
def write_arg(self, args, action, command_name):
for arg in args:
if arg['argc'] != -1:
if_block(f'args.size() == {arg["argc"]}',).__enter__()
if 'pattern_command' in arg and arg['pattern_command']:
self.write_line(f'int level = -1, iArg = 0, '
f'nGetArgs = {arg["pattern_command"]["nGetArgs"]},'
f' nPutArgs = {arg["pattern_command"]["nPutArgs"]};\nGetLevelAndUpdateArgIndex(action, '
f'"{arg["pattern_command"]["command_name"]}", level, iArg, nGetArgs,nPutArgs);'
)
if 'extra_variables' in arg:
for var in arg['extra_variables']:
codegen.write_line(f'{var["type"]} {var["name"]} = {var["value"]};')
if 'separate_time_units' in arg and arg['separate_time_units']:
self.write_line(f'std::string tmp_time({arg["separate_time_units"]["input"]});')
self.write_line(f'std::string {arg["separate_time_units"]["output"][1]}'
f' = RemoveUnit(tmp_time);')
self.write_line(f'auto {arg["separate_time_units"]["output"][0]} = '
f'StringTo < time::ns > (tmp_time,'
f' {arg["separate_time_units"]["output"][1]});')
if 'convert_to_time' in arg and arg['convert_to_time']:
self.write_line(f'auto {arg["convert_to_time"]["output"]} = '
f'StringTo < time::ns > ({", ".join(arg["convert_to_time"]["input"])});')
input_arguments = []
if 'exceptions' in arg:
for exception in arg['exceptions']:
self.write_line(f'if ({exception["condition"]}) {{ throw RuntimeError({exception["message"]}); }}')
if 'check_det_id' in arg and arg['check_det_id']:
self.write_line(
f'if (det_id != -1) {{ throw RuntimeError("Cannot execute {command_name} at module level"); }} '
)
# only used for 3 commands :(
if 'ctb_output_list' in arg:
self.write_line(f"""
std::string suffix = " {arg['ctb_output_list']['suffix']}";
auto t = det->{arg['ctb_output_list']['GETFCNLIST']}();""")
if arg['ctb_output_list']['GETFCNNAME'] != '':
self.write_line(f"""
auto names = det->{arg['ctb_output_list']['GETFCNNAME']}();
auto name_it = names.begin();""")
self.write_line("os << '[';")
with if_block(f't.size() > 0'):
self.write_line(f"""
auto it = t.cbegin();
os << ToString({arg['ctb_output_list']['printable_name']}) << ' ';
os << OutString(det->{arg['ctb_output_list']['GETFCN']}(*it++, std::vector<int>{{det_id}}))<< suffix;
while (it != t.cend()) {{
os << ", " << ToString({arg['ctb_output_list']['printable_name']}) << ' ';
os << OutString(det->{arg['ctb_output_list']['GETFCN']}(*it++, std::vector<int>{{det_id}}))<< suffix;
}}
""")
self.write_line('os << "]\\n";')
if arg['argc'] != -1:
if_block().__exit__()
return
for i in range(len(arg['input'])):
if arg['cast_input'][i]:
self.write_line(
f'auto arg{i} = StringTo<{arg["input_types"][i]}>({arg["input"][i]});')
input_arguments.append(f'arg{i}')
else:
input_arguments.append(arg["input"][i])
if 'require_det_id' in arg and arg['require_det_id']:
if 'convert_det_id' in arg and arg['convert_det_id']:
input_arguments.append("std::vector<int>{ det_id }")
else:
input_arguments.append("det_id")
input_arguments = ", ".join(input_arguments)
# call function
if arg["function"]:
if arg['store_result_in_t']:
self.write_line(f'auto t = det->{arg["function"]}({input_arguments});')
else:
self.write_line(f'det->{arg["function"]}({input_arguments});')
else:
pass #We have no function so skip block
output_args = []
for output in arg['output']:
output_args.append(output)
if len(output_args) > 0:
self.write_line(f"os << {'<< '.join(output_args)} << '\\n';")
if arg['argc'] != -1:
if_block().__exit__()
class if_block:
def __init__(self, condition="", elseif=False):
self.condition = condition
self.elseif = elseif
self.block = False
def __enter__(self):
if self.elseif:
codegen.write_line('else if (' + self.condition + ') {')
else:
codegen.write_line('if (' + self.condition + ') {')
if self.block:
codegen.write_line('{\n')
def __exit__(self, *args):
codegen.write_line('}')
if self.block:
codegen.write_line('}')
codegen.write_line('')
class else_block:
def __init__(self):
pass
def __enter__(self):
codegen.write_line('else {')
codegen.write_line('')
def __exit__(self, *args):
codegen.write_line('}')
codegen.write_line('')
class for_block:
def __init__(self, condition):
self.condition = condition
def __enter__(self):
codegen.write_line('for (' + self.condition + ') {')
codegen.write_line('')
def __exit__(self, *args):
codegen.write_line('}')
codegen.write_line('')
class function:
def __init__(self, return_type, name, args: list[tuple[str, str]]):
self.name = name
self.args = args
self.return_type = return_type
def __enter__(self):
s = ""
for arg in self.args:
arg_type, arg_name = arg
s += arg_type + ' ' + arg_name + ', '
s = s[:-2]
codegen.write_line(self.return_type + ' ' + self.name +
f'({s}) {{')
codegen.write_line('')
return self
def __exit__(self, *args):
codegen.write_line('}')
codegen.write_line('')
codegen = CodeGenerator()

View File

@ -1,176 +0,0 @@
#configuration
detectorversion: firmwareversion
softwareversion: detectorserverversion
receiverversion: rx_version
detectornumber: serialnumber
thisversion: clientversion
detsizechan: detsize
trimdir: settingspath
settingsdir: settingspath
flippeddatax: fliprows
#acquisition parameters
cycles: triggers
cyclesl: triggersl
clkdivider: readoutspeed
speed: readoutspeed
vhighvoltage: highvoltage
digitest: imagetest
filter: filterresistor
readnlines: readnrows
# temperature
# super old dacs
vtr: vtrim
vrf: vrpreamp
vrs: vrshaper
vcall: vcal
vis: vishaper
vshaper: vrshaper
vpreamp: vrpreamp
vshaperneg: vrshaper_n
viinsh: vishaper
vpl: vcal_n
vph: vcal_p
# dacs
vthreshold: dac
vsvp: dac
vsvn: dac
vtrim: dac
vrpreamp: dac
vrshaper: dac
vtgstv: dac
vcmp_ll: dac
vcmp_lr: dac
vcal: dac
vcmp_rl: dac
vcmp_rr: dac
rxb_rb: dac
rxb_lb: dac
vcp: dac
vcn: dac
vishaper: dac
iodelay: dac
vref_ds: dac
vcascn_pb: dac
vcascp_pb: dac
vout_cm: dac
vcasc_out: dac
vin_cm: dac
vref_comp: dac
ib_test_c: dac
vrshaper_n: dac
vipre: dac
vdcsh: dac
vth1: dac
vth2: dac
vth3: dac
vcal_n: dac
vcal_p: dac
vcassh: dac
vcas: dac
vicin: dac
vipre_out: dac
vref_h_adc: dac
vb_comp_fe: dac
vb_comp_adc: dac
vcom_cds: dac
vref_rstore: dac
vb_opa_1st: dac
vref_comp_fe: dac
vcom_adc1: dac
vref_prech: dac
vref_l_adc: dac
vref_cds: dac
vb_cs: dac
vb_opa_fd: dac
vcom_adc2: dac
vb_ds: dac
vb_comp: dac
vb_pixbuf: dac
vin_com: dac
vdd_prot: dac
vbp_colbuf: dac
vb_sda: dac
vcasc_sfp: dac
vipre_cds: dac
ibias_sfp: dac
defaultdacs: resetdacs
#acquisition
busy: clearbusy
receiver: rx_status
framescaught: rx_framescaught
startingfnum: nextframenumber
#Network Configuration (Detector<->Receiver)
detectorip: udp_srcip
detectorip2: udp_srcip2
detectormac: udp_srcmac
detectormac2: udp_srcmac2
rx_udpip: udp_dstip
rx_udpip2: udp_dstip2
rx_udpmac: udp_dstmac
rx_udpmac2: udp_dstmac2
rx_udpport: udp_dstport
rx_udpport2: udp_dstport2
flowcontrol_10g: flowcontrol10g
txndelay_frame: txdelay_frame
txndelay_left: txdelay_left
txndelay_right: txdelay_right
#Receiver Config
r_silent: rx_silent
r_discardpolicy: rx_discardpolicy
r_padding: rx_padding
r_lock: rx_lock
r_lastclient: rx_lastclient
#File
fileformat: fformat
outdir: fpath
index: findex
enablefwrite: fwrite
masterfile: fmaster
overwrite: foverwrite
r_framesperfile: rx_framesperfile
#ZMQ Streaming Parameters (Receiver<->Client)
r_readfreq: rx_zmqfreq
rx_readfreq: rx_zmqfreq
rx_datastream: rx_zmqstream
#Eiger Specific
resmat: partialreset
#Jungfrau Specific
storagecells: extrastoragecells
auto_comp_disable: autocompdisable
comp_disable_time: compdisabletime
#Gotthard Specific
#Gotthard2 Specific
#Mythen3 Specific
#CTB Specific
adc: slowadc
flags: romode
i_a: im_a
i_b: im_b
i_c: im_c
i_d: im_d
i_io: im_io
#Pattern
#Moench
#Advanced
copydetectorserver: updatedetectorserver
#Insignificant
nframes: framecounter
now: runtime
timestamp: frametime
frameindex: rx_frameindex

File diff suppressed because it is too large Load Diff

View File

@ -1,276 +0,0 @@
import argparse
import os
import subprocess
from pathlib import Path
import yaml
from autocomplete.autocomplete import type_info
from cpp_codegen.codegen import codegen, if_block, for_block, function, else_block
from infer_action.check_infer import check_infer
from autocomplete.autocomplete import type_values
GEN_PATH = Path(__file__).parent
COMMANDS_PATH = GEN_PATH / 'extended_commands.yaml'
DEPRECATED_COMMANDS_PATH = GEN_PATH / 'deprecated_commands.yaml'
CPP_INPUT_PATH = GEN_PATH / 'Caller.in.cpp'
HEADER_INPUT_PATH = GEN_PATH / 'Caller.in.h'
CPP_OUTPUT_PATH = GEN_PATH.parent / 'src' / 'Caller.cpp'
HEADER_OUTPUT_PATH = GEN_PATH.parent / 'src' / 'Caller.h'
INFER_HEADER_INPUT_PATH = GEN_PATH / 'inferAction.in.h'
INFER_CPP_INPUT_PATH = GEN_PATH / 'inferAction.in.cpp'
INFER_HEADER_OUTPUT_PATH = GEN_PATH.parent / 'src' / 'inferAction.h'
INFER_CPP_OUTPUT_PATH = GEN_PATH.parent / 'src' / 'inferAction.cpp'
def generate(
commands_path=COMMANDS_PATH,
cpp_input_path=CPP_INPUT_PATH,
header_input_path=HEADER_INPUT_PATH,
cpp_output_path=CPP_OUTPUT_PATH,
header_output_path=HEADER_OUTPUT_PATH,
infer_header_input_path=INFER_HEADER_INPUT_PATH,
infer_cpp_input_path=INFER_CPP_INPUT_PATH,
infer_header_output_path=INFER_HEADER_OUTPUT_PATH,
infer_cpp_output_path=INFER_CPP_OUTPUT_PATH,
):
commands_config = yaml.unsafe_load(commands_path.open('r'))
deprecated_commands_config = yaml.unsafe_load(DEPRECATED_COMMANDS_PATH.open('r'))
type_dist, non_dist = check_infer(commands=commands_config)
codegen.open(cpp_output_path)
# write call function
codegen.write_opening(cpp_input_path)
# iterate over the commands and generate code for each
print(f"[X] found {len(commands_config)} commands")
print('[*] generating code for commands')
for command_name, command in commands_config.items():
if 'is_description' in command and command['is_description']:
continue
with function('std::string', 'Caller::' + command['function_alias'], [('int', 'action')]) as fn:
codegen.write_line('std::ostringstream os;')
# print help
codegen.write_line('// print help')
with if_block('action == slsDetectorDefs::HELP_ACTION'):
if command["help"].startswith('code:'):
codegen.write_line(command["help"].strip('code:'))
else:
codegen.write_line(f'os << "Command: {command_name}" << std::endl;')
codegen.write_line(f'os << R"V0G0N({command["help"]} )V0G0N" << std::endl;')
codegen.write_line('return os.str();')
# check if action and arguments are valid
codegen.write_line('// check if action and arguments are valid')
first = True
for action, action_params in command['actions'].items():
with if_block(f'action == {codegen.actions_dict[action]}', elseif=not first):
check_argc = True
for arg in action_params['args']:
if arg['argc'] == -1:
check_argc = False
break
# check number of arguments
condition = "1" if check_argc else "0"
if check_argc:
for arg in action_params['args']:
condition += f' && args.size() != {arg["argc"]}'
with if_block(condition):
codegen.write_line(f'throw RuntimeError("Wrong number of arguments for action {action}");')
for arg in action_params['args']:
if not check_argc:
continue
with if_block(f'args.size() == {arg["argc"]}'):
# check argument types
if 'extra_variables' in arg:
for var in arg['extra_variables']:
codegen.write_line(f'{var["type"]} {var["name"]} = {var["value"]};')
if 'separate_time_units' in arg and arg['separate_time_units']:
codegen.write_line(f'try {{')
# TODO: refactor this repeating code
codegen.write_line(f'std::string tmp_time({arg["separate_time_units"]["input"]});')
codegen.write_line(f'std::string {arg["separate_time_units"]["output"][1]}'
f' = RemoveUnit(tmp_time);')
codegen.write_line(f'auto {arg["separate_time_units"]["output"][0]} = '
f'StringTo < time::ns > (tmp_time,'
f' {arg["separate_time_units"]["output"][1]});')
codegen.write_line(
f'}} catch (...) {{ throw RuntimeError("Could not convert argument to time::ns");}}')
elif 'convert_to_time' in arg and arg['convert_to_time']:
codegen.write_line(f'try {{')
codegen.write_line(
f'StringTo < time::ns > ({", ".join(arg["convert_to_time"]["input"])});')
codegen.write_line(
f'}} catch (...) {{ throw RuntimeError("Could not convert arguments to time::ns");}}')
for i in range(len(arg['input'])):
if not arg['cast_input'][i]:
continue
codegen.write_line(f'try {{')
codegen.write_line(f'StringTo<{arg["input_types"][i]}>({arg["input"][i]});')
codegen.write_line(f'}} catch (...) {{')
codegen.write_line(
f' throw RuntimeError("Could not convert argument {i} to {arg["input_types"][i]}");')
codegen.write_line(f'}}')
first = False
with else_block():
codegen.write_line(
f'throw RuntimeError("INTERNAL ERROR: Invalid action: supported actions are {list(command["actions"].keys())}");')
# generate code for each action
codegen.write_line('// generate code for each action')
for action, action_params in command['actions'].items():
if 'detectors' in action_params:
codegen.write_line('auto detector_type = det->getDetectorType().squash();')
with if_block(f'action == {codegen.actions_dict[action]}'):
if 'detectors' in action_params:
first = True
for detector, detector_params in action_params['detectors'].items():
with if_block(f'detector_type == defs::{detector}', elseif=not first):
codegen.write_arg(detector_params, action, command_name)
else_block().__enter__()
if not action_params:
codegen.write_line(f'throw RuntimeError("detector not supported for action: {action}");')
else:
tmp_args = []
if 'args' in action_params:
tmp_args = action_params['args']
codegen.write_arg(tmp_args, action, command_name)
if 'detectors' in action_params:
else_block().__exit__()
codegen.write_line('return os.str();')
# close sls namespace
codegen.write_closing()
codegen.close()
print('[X] .cpp code generated')
deprecated_commands = []
codegen.write_header(header_input_path, header_output_path, commands_config, deprecated_commands_config)
print('[X] header code generated')
codegen.write_infer_header(infer_header_input_path, infer_header_output_path, commands_config) #TODO: add deprecated commands
print('[X] infer header code generated')
codegen.open(infer_cpp_output_path)
codegen.write_infer_cpp(infer_cpp_input_path, infer_cpp_output_path, commands_config, non_dist, type_dist)
codegen.close()
print('[X] infer cpp code generated')
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='generate c++ code for cli commands from the commands.yaml file',
)
parser.add_argument('-f', '--format', action='store_true', default=False, dest='format',
help='format header and cpp file using clang-format')
parser.add_argument('-p', '--parse', action='store_true', default=False, dest='parse',
help='parse the commands.yaml file into extended_commands.yaml')
parser.add_argument('-c', '--check', action='store_true', default=False, dest='check',
help='check missing commands')
parser.add_argument('-g', '--generate', action='store_true', default=False, dest='generate', help='generate code (C++ or bash if -a is used)')
parser.add_argument('-a', '--autocomplete', action='store_true', default=False, dest='autocomplete',
help='print bash autocomplete values')
cli_args = parser.parse_args()
if cli_args.autocomplete:
from autocomplete.autocomplete import generate_type_values, generate_bash_autocomplete
if cli_args.generate:
generate_bash_autocomplete()
print('[X] bash autocomplete generated')
generate_bash_autocomplete(
output_path=Path(__file__).parent / 'autocomplete' / 'zsh_autocomplete.sh',
input_path=Path(__file__).parent / 'autocomplete' / 'zsh_autocomplete.in.sh'
)
print('[X] zsh autocomplete generated')
exit(0)
else:
ret = generate_type_values()
print(ret)
exit(0)
if cli_args.check:
from commands_parser.commands_parser import command_parser
commands_config = yaml.unsafe_load(COMMANDS_PATH.open('r'))
# infer action based on number of arguments and types
type_dist, non_dist = check_infer(commands=commands_config)
command_parser.verify_format()
command_parser.parse_all_commands()
# generate list of commands found in sls_detector_get
glist_path = GEN_PATH / 'glist'
ret = subprocess.run([f"sls_detector_get list | tail -n +2 | sort > {glist_path.absolute()}"], shell=True,
capture_output=True, check=True)
if ret.stderr != b'':
print('[!] glist generation failed and glist not found')
exit(1)
if not COMMANDS_PATH.exists():
print('[!] extended_commands.yaml not found')
exit(1)
detglist = set(command['command_name'] for __, command in commands_config.items())
detglist.add('free')
detglist.add('list')
g_path = GEN_PATH / 'glist'
if not g_path.exists():
print('[!] glist not found')
exit(1)
glist = set(g_path.read_text().split('\n'))
if "" in glist:
glist.remove("")
if "" in detglist:
detglist.remove("")
not_found = set()
for command in glist:
if command not in detglist:
not_found.add(command)
print()
if len(not_found) > 0:
print(f'[!] found {len(not_found)} missing')
print(f"not_found: {not_found}")
else:
print(f'[X] found no missing commands')
for command in detglist:
if command not in glist:
print(f'[!] command {command} found in commands.yaml but not found in g list')
exit(0)
if cli_args.parse:
from commands_parser.commands_parser import command_parser
command_parser.verify_format()
command_parser.parse_all_commands()
if cli_args.generate:
generate()
if cli_args.format:
files = [CPP_OUTPUT_PATH, HEADER_OUTPUT_PATH, INFER_HEADER_OUTPUT_PATH, INFER_CPP_OUTPUT_PATH]
for file in files:
os.system(f'clang-format -i {file.absolute()}')
#os.system(f'clang-format -i --style="{{Standard: C++11}}" {file.absolute()}')
print('[X] code formatted')

View File

@ -1,20 +0,0 @@
#include "inferAction.h"
#include "sls/sls_detector_defs.h"
namespace sls {
int InferAction::infer(sls::CmdParser &parser, std::ostream &os) {
args = parser.arguments();
cmd = parser.command();
auto it = functions.find(parser.command());
if (it != functions.end()) {
return ((*this).*(it->second))();
} else {
throw RuntimeError(
"sls_detector not implemented for command: " + parser.command() +
". Use sls_detector_get or sls_detector_put.");
}
}
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (1) - DO NOT REMOVE
} // namespace sls

View File

@ -1,30 +0,0 @@
#include "CmdParser.h"
#include <iostream>
#include <map>
#include <vector>
namespace sls {
class InferAction {
public:
InferAction() {}
int infer(sls::CmdParser &parser, std::ostream &os = std::cout);
std::vector<std::string> args;
std::string cmd;
// generated functions
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (1) - DO NOT REMOVE
// int frames();
private:
using FunctionMap = std::map<std::string, int (InferAction::*)()>;
FunctionMap functions{
// generated functions
// THIS COMMENT TO BE REPLACED BY THE ACTUAL CODE (2) - DO NOT REMOVE
// {"frames",&InferAction::frames}
};
};
} // namespace sls

View File

@ -1,64 +0,0 @@
from pathlib import Path
import argparse
import yaml
def check_infer(EXTENDED_COMMANDS_PATH=Path(__file__).parent.parent / "extended_commands.yaml", commands=None):
if commands is None:
# load yaml file
with EXTENDED_COMMANDS_PATH.open('r') as f:
commands = yaml.safe_load(f)
type_distinguishable = {}
non_distinguishable = {}
for command_name, command in commands.items():
# todo: remove this (added for debug)
# if command_name != 'badchannels':
# continue
if len(command["actions"]) == 1:
action = list(command["actions"].items())[0][1]
for arg in action['args']:
if arg['argc'] == -1:
non_distinguishable[(command_name, arg['argc'])] = ([], arg['arg_types'])
continue
get_argcs = {}
get_args = command['actions']['GET']['args']
for arg in get_args:
if arg['argc'] != -1:
get_argcs[arg["argc"]] = arg['arg_types']
else:
non_distinguishable[(command_name, arg['argc'])] = ([], arg['arg_types'])
put_args = command['actions']['PUT']['args']
for arg in put_args:
if arg['argc'] == -1:
non_distinguishable[(command_name, arg['argc'])] = ([], arg['arg_types'])
elif arg['argc'] in get_argcs:
if arg['arg_types'] != get_argcs[arg['argc']]:
type_distinguishable[(command_name, arg['argc'])] = (get_argcs[arg['argc']], arg['arg_types'])
else:
non_distinguishable[(command_name, arg['argc'])] = (get_argcs[arg['argc']], arg['arg_types'])
return type_distinguishable, non_distinguishable
if __name__ == "__main__":
argparse = argparse.ArgumentParser()
argparse.add_argument("--print", choices=['all', 'type', 'impossible'], default="all", help="command name")
args = argparse.parse_args()
type_distinguishable, non_distinguishable = check_infer()
if args.print == 'type' or args.print == 'all':
print("type distinguishable:")
print("command_name: argc get_arg_type put_arg_type\n")
for (command_name, argc), (get_arg_types, put_arg_types) in type_distinguishable.items():
print(f"{command_name}: {argc} {get_arg_types} {put_arg_types}")
if args.print == 'impossible' or args.print == 'all':
print("\n\nimpossible to distinguish:")
print("command_name: argc get_arg_type put_arg_type")
for (command_name, argc), (get_arg_types, put_arg_types) in non_distinguishable.items():
print(f"{command_name}: {argc} {get_arg_types} {put_arg_types}")

View File

@ -1,288 +0,0 @@
# Generator
used to generate C++ cli commands. and bash autocompletion scripts.
## Autocomplete
### Overview
Looks through the `dump.json` file for the different values of an enum and stores them in the dictionary `type_values`.
```sh
# To print the different values for enums
python gen_commands.py -a
```
also the autocomplete.py generates shell autocompletion scripts for both bash and zsh. It uses the template file `bash_autocomplete.in.sh` and adds the necessary code in an output file `bash_autocomplete.sh` (same for zsh).
To use the bash autocompletion the `bash_autocomplete.sh` must be sourced.
```sh
source bash_autocomplete.sh
# g <Tab><Tab> will give the list of all commands
# p 0:<Tab><Tab> will also give the list of all commands
# g exp<Tab> will autocomplete to g exptime
# g exptime <Tab><Tab> will return "s ms us ns"
# p timing <Tab><Tab> will return "auto,burst_trigger,gating..."
```
**Note:**
The dump.json is the AST of the file `slsDetectorPackage/slsSupportLib/src/ToString.cpp`.
```sh
# to generate the dump.json file
cd slsSupportLib/src/ToString.cpp
clang++ -Xclang -ast-dump=json -Xclang -ast-dump-filter -Xclang StringTo -c ToString.cpp -I ../include/ -std=gnu++11
# clang version used: 14.0.0-1ubuntu1.1
```
the `dump.json` file produced by clang is not a correct json file because we used the `-ast-dump-filter`. autocomplete.py can be used to fix the format of `dump.json` and produce a new file called `fixed.json` that is json format.
```
# to convert dump.json into correct json format.
python autocomplete.py -f # produces the file fixed.json
```
### Code components
- `type_values` is a dictionary that contains the different values for commands args. It is populated with enum values that stard with defs:: or slsDetectorDefs:: (eg. defs::burstMode). Also it contains values added manually such as "mv,mV" and those start with special::
- `generate_type_values` parses the AST file to find the part that contains if statements. and extracts the different possible values for an enum.
- `generate_bash_autocomplete` generates autocompletion scripts for bash or zsh. the difference between zsh and bash scripts can be found in the template files. (bash handles 0:<Tab><Tab> completion differently than zsh more details can be found in the comments of the template files )
- `fix_json` fixes the file 'autocomplete/dump.json' and outputs a new corrected file in 'autocomplete/fixed.json'
## Command Parser
Definitely the most important component of all the generator module.
command_parser exist to keep the commands.yaml file concise and easy to read and produce a complete version of the commands.yaml for the code generator to work on.
The goal is that the code generator works on a version of commands.yaml that is easy to iterate over and generate code.
```
# complete version
some_command:
help: "do this"
infer_action: true
actions:
GET:
args:
- argc: 0
function: "getCommand"
...
- argc: 1
function: "getCommand"
...
detectors:
MYTHEN3:
- argc: 0
function: "getCommandMythen"
...
PUT:
args:
- argc: 2
function: "setCommand"
...
- argc: 3
function: "setCommand"
...
```
the complete vesion can only have `args` or `detectors` field inside an action (GET or PUT). **Each element in the args array have a different argc**. and in each element in the args array we can find all the information needed to generate the code for that one argc case. for example in the code `if(action == 'GET')` and `if (args.size() == 1)` then we can generate the code for that one case independetly.
commands.yaml has a lot on ~inheritance~. examples show best what it is:
> fields insides an action will be passed to args and detectors
> the extended args for default actions will be used for detectors
> any field can be overriden
```
resetdacs:
help: "[(optional) hard] ..."
actions:
PUT:
function: resetToDefaultDacs
require_det_id: true
output: [ '"successful"' ]
input_types: [ bool ]
args:
- argc: 1
arg_types: [ special::hard ]
input: [ '"1"' ]
- argc: 0
input: [ '"0"' ]
# this will be converted to
resetdacs:
actions:
PUT:
args:
- arg_types:
- special::hard
argc: 1
cast_input:
- false
check_det_id: false
convert_det_id: true
function: resetToDefaultDacs
input:
- '"1"'
input_types:
- bool
output:
- '"successful"'
require_det_id: true
store_result_in_t: false
- arg_types: []
argc: 0
cast_input:
- false
check_det_id: false
convert_det_id: true
function: resetToDefaultDacs
input:
- '"0"'
input_types:
- bool
output:
- '"successful"'
require_det_id: true
store_result_in_t: false
command_name: resetdacs
function_alias: resetdacs
help: "[(optional) hard] ..."
infer_action: true
```
command_parser does not have a specific schema for the commands.yaml this is by design so it can be very extensible and future-proof. This also can have problems when there is typos (writing intput instead of input...)
command_parser first verifies the commands.yaml and checks if there's some obvious problems in it.
templates found in commands.yaml were taken from the CmdProxy code they were added for debugging purposes when writing the generator.
tricky things:
--
- if input array has n elements and cast_input array is empty. command_parser will fill it with n false values.
- store_result_in_t will be added by default as true to GET action. but as false to PUT action. (unless it is written in the action)
- infer_action by default is true
- commands that have is_description true won't be verified
- function_alias is the name of the function in the c++ code. by default it is the command name. errors came up with the command virtual as virtual is a reserved keyword in c++
- command_name is the string of the command that will be typed in cli. (frames, exptime, ...). by default it is the command name. pattern is a special keyword in yaml. problems came up with the command pattern
- arg_types is by default input_types unless otherwise specified
- when the parent has specific detector behaviour and the child does not. writing an empty detector section in the action would not inherit any detector specific fields (check exptime1)
- commands can inherit other commands (check exptime1 and exptime2)
- argc: -1 means that the command has an unknown number of arguments
### Code Walkthrough
the code is well commented it is well explained in the script
### Tests
tests for command_parser can be found in `generator/tests/command_parser/`
```
pip install -r requirements.txt
python -m pytests
```
verification is not well tested
## codegen
Now for C++ code generation. After parsing the commands.yaml file and producing the extended_commands.yaml `gen_commands.py` will iterate over the commands and generate `Caller.h`, `Caller.cpp`, `inferAction.cpp` and `inferAction.h` .
### infer action
the generated code will produce 5 new targets: "sls_detector_get sls_detector_put sls_detector_acquire sls_detector_help sls_detector"
`sls_detector_get` will set the action as GET
`sls_detector_put` will the action as PUT
`sls_detector` will guess the action depending on the number of arguments
the codegen module will generate a function for every command that will return the action based on the number of arguments
```cpp
int InferAction::activate() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
} else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
```
the `inferAction` class will be called from `CmdApp.cpp` to infer the action and the command function will be called with the appropriate action.
some commands have the same number of argument count for both get and put. These commands can be found using the the `check_infer.py` script. in the generated code it will say that "sls_detector is disabled"
```bash
# to see these commands
python infer_action/check_infer.py
```
### Caller.cpp code
in this level we only use the extended_commands.yaml file.
the `generate()` function in `gen_commands.py` will iterate over all of the commands and :
- write the function signature
- write the help
- write c++ code to check the inputs: check argument count and check if we are able to convert the arguments into the required types
- iterate over actions and arguments
- iterate over the detectors and write code for each one of them (if mythen3 ... if eiger ... else default code... ) and call `codegen.write_arg()` to write the argument for a single argument
codegen.write_arg()
-
write_arg in codegen reads the argument fields and generate c++ code accordingly.
## fields explanations
- arg_types:[array of types] it is only used for autocompletion no C++ code is dependent on it
- is_description:[boolean] same as above
- template:[boolean] only used in commands.yaml and it won't present in extended_commands.yaml. it is inspired by the CmdProxy.h code
- help:[string] command help
- input:[array of variable names] the input arguments that will be passed to the function
- input_types:[array of types] the types of the input arguments given to the function
- cast_input:[array of boolean] if true it will cast the corresponding input to the type in input_types
- output:[array] outputs that will be printed (eg. ["123", "'a'"] will be os<<123<<'a')
- function: the function that will be called
- function_alias: the name of the function in the c++ code (more on it in tricky things)
- command_name: the string of the command that will be typed in cli. (more on it in tricky things)
- require_det_id: if true it will require a detector id to be passed as the last argument
- check_det_id: if true it will check the detector id and throw an error if it is not valid
- convert_det_id: if true it will convert the detector id to the correct type `std::vector<int>{ det_id }`
- store_result_in_t: if true it will store the result of the function in the variable t (more on it in tricky things)
- infer_action: if true it will infer the action (only if sls_detector is used)
- detectors: the detectors that have specific behaviour
- args: the arguments of the command
- argc: the number of arguments
- extra_variables[array]: each element takes three parameters: value, name, type and creates that variable in the beginning of the argument code
- exceptions[array]: each element takes two parameters: condition, message
- pattern_command: takes three arguments: nGetArgs, nPutArgs and command_name and it will write this code
```cpp
int level = -1, iArg = 0, nGetArgs = $nGetArgs$, nPutArgs = $nPutArgs$;
GetLevelAndUpdateArgIndex(action, $command_name$, level, iArg, nGetArgs,nPutArgs);
```
- separate_time_units: takes three parameters: input, output[0], output[1] each one is a variable name
```cpp
std::string tmp_time($input$);
std::string $output[1]$ = RemoveUnit(tmp_time);
auto $output[0]$ = StringTo<time::ns>(tmp_time, $output[1]$);
```
- convert_to_time: takes three parameters: input[0], input[1], output
```cpp
auto output = StringTo<time::ns>(input[0], input[1]);
```
- ctb_output_list: **maybe it should be removed?** takes 5 parameters: GETFCNLIST, GETFCNNAME, GETFCN, suffix, printable_name

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