Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into dev/ctb/display_counter_images

This commit is contained in:
2026-05-27 17:15:07 +02:00
42 changed files with 238 additions and 1238 deletions
+4 -4
View File
@@ -35,7 +35,7 @@ jobs:
shell: "bash -l {0}"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Fetch all history for proper git operations
token: ${{ secrets.GITHUB_TOKEN }} # Use the default token
@@ -58,13 +58,13 @@ jobs:
version: 1.0
- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: 3.12
cache: 'pip'
- name: Install Python Packages
run: pip install sphinx sphinx_rtd_theme breathe pyyaml jinja2
run: pip install sphinx sphinx_rtd_theme breathe pyyaml jinja2 numpy
- name: Build Documentation
@@ -84,7 +84,7 @@ jobs:
--date "$(date +'%d.%m.%Y')"
- name: Checkout gh-pages
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: gh-pages
path: gh-pages
+5 -5
View File
@@ -20,12 +20,12 @@ jobs:
os: [ubuntu-latest,]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Build wheels
run: pipx run cibuildwheel==3.2.1
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
@@ -34,12 +34,12 @@ jobs:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Build sdist
run: pipx run build --sdist
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: cibw-sdist
path: dist/*.tar.gz
@@ -54,7 +54,7 @@ jobs:
# or, alternatively, upload to PyPI on every tag starting with 'v' (remove on: release above to use this)
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
with:
# unpacks all CIBW artifacts into dist/
pattern: cibw-*
+2 -2
View File
@@ -14,8 +14,8 @@ jobs:
runs-on: ubuntu-latest
name: Configure and build using cmake
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.12
cache: 'pip'
+4 -4
View File
@@ -21,10 +21,10 @@ jobs:
shell: "bash -l {0}"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Get conda
uses: conda-incubator/setup-miniconda@v3.0.4
uses: conda-incubator/setup-miniconda@v4
with:
python-version: ${{ matrix.python-version }}
channels: conda-forge
@@ -38,10 +38,10 @@ jobs:
- name: Build
env:
CONDA_TOKEN: ${{ secrets.CONDA_TOKEN }}
run: conda build conda-recipes/main-library --user slsdetectorgroup --token ${CONDA_TOKEN} --output-folder build_output
run: conda-build conda-recipes/main-library --user slsdetectorgroup --token ${CONDA_TOKEN} --output-folder build_output
- name: Upload all Conda to github as artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: conda-packages
path: build_output/** # Uploads all packages
+4 -4
View File
@@ -21,10 +21,10 @@ jobs:
shell: "bash -l {0}"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Get conda
uses: conda-incubator/setup-miniconda@v3.0.4
uses: conda-incubator/setup-miniconda@v4
with:
python-version: ${{ matrix.python-version }}
channels: conda-forge
@@ -38,10 +38,10 @@ jobs:
- name: Build
env:
CONDA_TOKEN: ${{ secrets.CONDA_TOKEN }}
run: conda build conda-recipes/python-client --user slsdetectorgroup --token ${CONDA_TOKEN} --output-folder build_output
run: conda-build conda-recipes/python-client --user slsdetectorgroup --token ${CONDA_TOKEN} --output-folder build_output
- name: Upload all Conda packages
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: conda-packages
path: build_output/** # Uploads all packages
+4 -4
View File
@@ -18,10 +18,10 @@ jobs:
shell: "bash -l {0}"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Get conda
uses: conda-incubator/setup-miniconda@v3.0.4
uses: conda-incubator/setup-miniconda@v4
with:
python-version: ${{ matrix.python-version }}
channels: conda-forge
@@ -33,10 +33,10 @@ jobs:
run: conda config --set anaconda_upload no
- name: Build
run: conda build conda-recipes/main-library --output-folder build_output
run: conda-build conda-recipes/main-library --output-folder build_output
- name: Upload all Conda packages
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: conda-packages
path: build_output/** # Uploads all packages
+4 -4
View File
@@ -18,10 +18,10 @@ jobs:
shell: "bash -l {0}"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Get conda
uses: conda-incubator/setup-miniconda@v3.0.4
uses: conda-incubator/setup-miniconda@v4
with:
python-version: ${{ matrix.python-version }}
channels: conda-forge
@@ -33,10 +33,10 @@ jobs:
run: conda config --set anaconda_upload no
- name: Build
run: conda build conda-recipes/python-client --output-folder build_output
run: conda-build conda-recipes/python-client --output-folder build_output
- name: Upload all Conda packages
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: conda-packages
path: build_output/** # Uploads all packages
+1 -12
View File
@@ -209,22 +209,11 @@ else()
URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/fmt/fmt-12.1.0.tar.gz
# Compute hash: md5sum fmt-12.1.0.tar.gz
URL_HASH MD5=92eb6f492e4838e5f024ce5207beafc7)
set(FMT_INSTALL ON CACHE BOOL "")
FetchContent_MakeAvailable(fmt)
set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()
# Export fmt
if(SLS_MASTER_PROJECT)
install(TARGETS fmt
EXPORT ${TARGETS_EXPORT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()
option(SLS_USE_HDF5 "HDF5 File format" OFF)
option(SLS_BUILD_SHARED_LIBRARIES "Build shared libaries" OFF)
option(SLS_USE_TEXTCLIENT "Text Client" ON)
+21
View File
@@ -41,6 +41,27 @@ Detector.pattern (python) accepts also a pattern object, not only a pattern file
added patternstart to python (ctb, xilinx_ctb , mythen3), only the detector class api was exposed (startPattern())
can build virtual servers on mac OS
documentation for all branches and developer now online and build and pushed automatically
gui: mouse zooms not reset at start of acquisition
m3: fixed patwaittime in intervals, which is hardly used. patwaittime in clocks stays the same and working.
m3: getPatternFileName typo fixed
libfmt added to dependency
python dacs=> using deprecated np.int. dacs return float (default dtype of numpy)
=> changed to np.int32 (meant for v10.0.1)
support for building rpms
removed unused function readDataFile/writeDataFile from file_utils.h
2 On-board Detector Server Compatibility
==========================================
+1 -1
View File
@@ -6,7 +6,7 @@ mkdir -p $PREFIX/bin
mkdir -p $PREFIX/include/sls
#Shared and static libraries
cp build/install/lib/* $PREFIX/lib/
cp -r build/install/lib/* $PREFIX/lib/
#Binaries
cp build/install/bin/sls_detector_acquire $PREFIX/bin/.
+5 -2
View File
@@ -36,6 +36,7 @@ set(SPHINX_SOURCE_FILES
src/consuming.rst
src/dependencies.rst
src/detector.rst
src/pyctb.rst
src/index.rst
src/installation.rst
src/pydetector.rst
@@ -72,6 +73,8 @@ set(SPHINX_SOURCE_FILES
src/softwarearchitecture.rst
src/configcommands.rst
src/Versioning.rst
src/Testing.rst
src/pypower.rst
)
foreach(filename ${SPHINX_SOURCE_FILES})
@@ -105,7 +108,7 @@ add_custom_target(docs
gendoc
COMMAND python gen_server_doc.py
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
COMMAND ${SPHINX_EXECUTABLE} -a -b html
COMMAND ${SPHINX_EXECUTABLE} -W -a -b html
-Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml
-c "${SPHINX_BUILD}"
${SPHINX_BUILD}/src
@@ -113,7 +116,7 @@ add_custom_target(docs
COMMENT "Generating documentation with Sphinx")
add_custom_target(rst
COMMAND ${SPHINX_EXECUTABLE} -a -b html
COMMAND ${SPHINX_EXECUTABLE} -W -a -b html
-Dbreathe_projects.slsDetectorPackage=${CMAKE_CURRENT_BINARY_DIR}/xml
-c "${SPHINX_BUILD}"
${SPHINX_BUILD}/src
+2
View File
@@ -48,6 +48,8 @@ templates_path = ['_templates']
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
suppress_warnings = ["duplicate_declaration.cpp",]
# -- Options for HTML output -------------------------------------------------
+3
View File
@@ -67,12 +67,14 @@ This runs all tests marked with the tag ``[.detectorintegration]`` for all detec
If you want to run them for a specific virtual detector or a specific test use the following command:
.. code-block:: console
cd build
python bin/test_simulators.py --servers jungfrau --test "[dacs]"
You can exclude specific tests by adding the option ``~[<disable_test_name>]``. Again, we assume that this marker is added to the tests that you want to exclude.
.. code-block:: console
cd build
python bin/test_simulators.py --servers eiger jungfrau moench --test "[detectorintegration]~[disable_check_data_file]"
@@ -98,6 +100,7 @@ If a test requires a detector mark them with the pytest marker ``@pytest.mark.de
To run only tests requiring virtual detectors use the following command:
.. code-block:: console
#in build
python -m pytest -m detectorintegration ../python/tests/
+3 -3
View File
@@ -53,9 +53,9 @@ To build the python module the following dependencies are needed:
Refer :ref:`pybind11 notes. <pybind for different slsDetectorPackage versions>`
-------------------------------
------------------------------------
Dependencies to build documentation
-------------------------------
------------------------------------
To build this documentation that you are reading now the following dependencies are needed:
@@ -76,7 +76,7 @@ To build the GUI the following dependencies are needed:
Qwt is bundled in libs. One does not need to pre-install it on the system.
------------------------------------------------------
-----------------------------------------------------
Dependencies to build Moench and Jungfrau executables
-----------------------------------------------------
+4 -1
View File
@@ -45,13 +45,16 @@ int main() {
for (const auto &cmd : commands) {
std::ostringstream os;
std::cout << cmd << '\n';
caller.call(cmd, {}, -1, slsDetectorDefs::HELP_ACTION, os);
auto tmp = os.str().erase(0, cmd.size());
auto usage = tmp.substr(0, tmp.find_first_of('\n'));
tmp.erase(0, usage.size());
auto help = replace_all(tmp, "\n\t", "\n\t\t| ");
if (help.back() != '\n') {
help.push_back('\n');
}
fs << '\t' << cmd << usage << help << "\n";
}
+2
View File
@@ -48,7 +48,9 @@ slsDetectorPackage
pygettingstarted
pydetector
pyctb
pyenums
pypower
pyexamples
pyPatternGenerator
pattern
+15
View File
@@ -0,0 +1,15 @@
Ctb
=====================================================
.. py:currentmodule:: slsdet
.. autoclass:: Ctb
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
+12
View File
@@ -0,0 +1,12 @@
Power Supply
===============
Helper class to control power supplies on the Chip Test Board (CTB, Xilinx CTB).
.. py:currentmodule:: slsdet
.. autoclass:: Power
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
-110
View File
@@ -1,110 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int iarg;
char fname[10000];
uint64_t word;
int val[64];
int bit[64];
FILE *fdin;
int nb = 2;
int off = 0;
int ioff = 0;
int dr = 24;
int idr = 0;
int ib = 0;
int iw = 0;
bit[0] = 19;
bit[1] = 8;
// for (iarg=0; iarg<argc; iarg++) printf("%d %s\n",iarg, argv[iarg]);
if (argc < 2)
printf("Error: usage is %s fname [dr off b0 b1 bn]\n");
if (argc > 2)
dr = atoi(argv[2]);
if (argc > 3)
off = atoi(argv[3]);
if (argc > 4) {
for (ib = 0; ib < 64; ib++) {
if (argc > 4 + ib) {
bit[ib] = atoi(argv[4 + ib]);
nb++;
}
}
}
idr = 0;
for (ib = 0; ib < nb; ib++) {
val[ib] = 0;
}
fdin = fopen(argv[1], "rb");
if (fdin == NULL) {
printf("Cannot open input file %s for reading\n", argv[1]);
return 200;
}
while (fread((void *)&word, 8, 1, fdin)) {
// printf("%llx\n",word);
if (ioff < off)
ioff++;
else {
for (ib = 0; ib < nb; ib++) {
if (word & (1 << bit[ib]))
val[ib] |= (1 << idr);
}
idr++;
if (idr == dr) {
idr = 0;
fprintf(stdout, "%d\t", iw++);
for (ib = 0; ib < nb; ib++) {
#ifdef HEX
fprintf(stdout, "%08llx\t", val[ib]);
#else
fprintf(stdout, "%lld\t", val[ib]);
#endif
val[ib] = 0;
}
fprintf(stdout, "\n");
}
}
}
if (idr != 0) {
fprintf(stdout, "%d\t", iw++);
for (ib = 0; ib < nb; ib++) {
#ifdef HEX
fprintf(stdout, "%08llx\t", val[ib]);
#else
fprintf(stdout, "%lld\t", val[ib]);
#endif
val[ib] = 0;
}
fprintf(stdout, "\n");
}
fclose(fdin);
return 0;
}
@@ -1,4 +0,0 @@
BIT0 output0 1
BIT1 output1 1
BIT2 output2 1
BIT3 output3 1
@@ -1,97 +0,0 @@
//define signals and directions (Input, outputs, clocks)
#define output0 0
setoutput(output0);
#define output1 1
setoutput(output1);
#define output2 2
setoutput(output2);
#define output3 3
setoutput(output3);
#define input0 4
setinput(input0);
#define input1 5
setinput(input1);
#define input2 6
setinput(input2);
#define input3 7
setinput(input3);
#define PW pw()
#define SB(x) setbit(x)
#define CB(x) clearbit(x)
#define CLOCK clearbit(CLKBIT); pw();setbit(CLKBIT);pw()
#define LCLOCK clearbit(CLKBIT); pw();setbit(CLKBIT);pw();clearbit(CLKBIT); pw()
#define CLOCKS(x) for (i=0;i<x;i++) {clearbit(CLKBIT);pw(); setbit(CLKBIT); pw();}
#define STOP setstop();
#define START setstart();
#define REPEAT(x) for (i=0;i<(x);i++) {pw();}
#define DOFOR(x) for (j=0;j<(x);j++) {
// }
#define INST0 CB(output3);CB(output2);CB(output1);CB(output0);PW;
#define INST1 CB(output3);CB(output2);CB(output1);SB(output0);PW;
#define INST2 CB(output3);CB(output2);SB(output1);CB(output0);PW;
#define INST3 CB(output3);CB(output2);SB(output1);SB(output0);PW;
#define INST4 CB(output3);SB(output2);CB(output1);CB(output0);PW;
#define INST5 CB(output3);SB(output2);CB(output1);SB(output0);PW;
#define INST6 CB(output3);SB(output2);SB(output1);CB(output0);PW;
#define INST7 CB(output3);SB(output2);SB(output1);SB(output0);PW;
#define INST8 SB(output3);CB(output2);CB(output1);CB(output0);PW;
#define INST9 SB(output3);CB(output2);CB(output1);SB(output0);PW;
#define INST10 SB(output3);CB(output2);SB(output1);CB(output0);PW;
#define INST11 SB(output3);CB(output2);SB(output1);SB(output0);PW;
#define INST12 SB(output3);SB(output2);CB(output1);CB(output0);PW;
START;
INST0;
setwaitpoint(0);
setwaittime(0,5);
INST1;
setstartloop(5);
setnloop(5,2);
INST2;
setstartloop(0);
setnloop(0,2);
INST3;
INST4;
setstoploop(0);
setstoploop(5);
INST5;
INST6;
setwaitpoint(4);
setwaittime(1,0);
INST7;
INST8;
setstartloop(2);
setnloop(2,0);
INST9;
INST10;
setstoploop(2);
INST11;
STOP;
INST12;
@@ -1,25 +0,0 @@
patword 0x0000 0x0000000000000000
patword 0x0001 0x0000000000000001
patword 0x0002 0x0000000000000002
patword 0x0003 0x0000000000000003
patword 0x0004 0x0000000000000004
patword 0x0005 0x0000000000000005
patword 0x0006 0x0000000000000006
patword 0x0007 0x0000000000000007
patword 0x0008 0x0000000000000008
patword 0x0009 0x0000000000000009
patword 0x000a 0x000000000000000a
patword 0x000b 0x000000000000000b
patword 0x000c 0x000000000000000c
patlimits 0x0000 0x000c
patioctrl 0x000000000000000f
patloop 0 0x0003 0x0005
patnloop 0 2
patloop 2 0x0009 0x000b
patnloop 2 0
patloop 5 0x0002 0x0005
patnloop 5 2
patwait 0 0x0001
patwaittime 0 5
patwait 4 0x0007
patwaittime 4 0
Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 KiB

-34
View File
@@ -1,34 +0,0 @@
# SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package
if [ "$#" -eq 0 ]; then
echo "Wrong number of arguments: usage should be $0 patname"
exit 1
fi
infile=$1
outfile=$infile"at"
outfilebin=$infile"bin"
if [ "$#" -ge 2 ]; then
outfile=$2
fi
exe=$infile"exe"
if [ "$#" -ge 4 ]; then
exe=$4
fi
if [ "$#" -ge 3 ]; then
outfilebin=$3
fi
if [ -f "$infile" ]
then
dir=$(dirname $infile)
gcc -DINFILE="\"$infile\"" -DOUTFILE="\"$outfile\"" -DOUTFILEBIN="\"$outfilebin\"" -o $exe generator.c -I$dir;
echo compiling
echo gcc -DINFILE="\"$infile\"" -DOUTFILE="\"$outfile\"" -DOUTFILEBIN="\"$outfilebin\"" -o $exe generator.c -I$dir;
$exe ;
echo cleaning
rm $exe
echo done
else
echo "$infile not found."
fi
-183
View File
@@ -1,183 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
/****************************************************************************
usage to generate a patter test.pat from test.p
gcc -DINFILE="\"test.p\"" -DOUTFILE="\"test.pat\"" -o test.exe generator.c ;
./test.exe ; rm test.exe
*************************************************************************/
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
#define MAXLOOPS 6
#define MAXTIMERS 6
#define MAXWORDS 8191
uint64_t pat = 0;
uint64_t iopat = 0;
uint64_t clkpat = 0;
unsigned iaddr = 0;
unsigned waitaddr[MAXTIMERS] = {MAXWORDS, MAXWORDS, MAXWORDS,
MAXWORDS, MAXWORDS, MAXWORDS};
unsigned startloopaddr[MAXLOOPS] = {MAXWORDS, MAXWORDS, MAXWORDS,
MAXWORDS, MAXWORDS, MAXWORDS};
unsigned stoploopaddr[MAXLOOPS] = {MAXWORDS, MAXWORDS, MAXWORDS,
MAXWORDS, MAXWORDS, MAXWORDS};
unsigned start = 0, stop = 0;
uint64_t waittime[MAXTIMERS] = {0, 0, 0, 0, 0, 0};
unsigned nloop[MAXLOOPS] = {0, 0, 0, 0, 0, 0};
char infile[10000], outfile[10000];
FILE *fd, *fd1;
uint64_t PAT[MAXWORDS];
int iopat_enable = 0;
int i, ii, iii, j, jj, jjj, pixx, pixy, memx, memy, muxout, memclk, colclk,
rowclk, muxclk, memcol, memrow, loopcounter;
void setstart() { start = iaddr; }
void setstop() { stop = iaddr; }
void setinput(int bit) {
uint64_t mask = 1;
mask = mask << bit;
iopat &= ~mask;
iopat_enable = 1;
}
void setoutput(int bit) {
uint64_t mask = 1;
mask = mask << bit;
iopat |= mask;
iopat_enable = 1;
}
void clearbit(int bit) {
uint64_t mask = 1;
mask = mask << bit;
pat &= ~mask;
}
void setbit(int bit) {
uint64_t mask = 1;
mask = mask << bit;
pat |= mask;
}
int checkbit(int bit) {
uint64_t mask = 1;
mask = mask << bit;
return (pat & mask) >> bit;
}
void setstartloop(int iloop) {
if (iloop >= 0 && iloop < MAXLOOPS) {
startloopaddr[iloop] = iaddr;
}
}
void setstoploop(int iloop) {
if (iloop >= 0 && iloop < MAXLOOPS) {
stoploopaddr[iloop] = iaddr;
}
}
void setnloop(int iloop, int n) {
if (iloop >= 0 && iloop < MAXLOOPS) {
nloop[iloop] = n;
}
}
void setwaitpoint(int iloop) {
if (iloop >= 0 && iloop < MAXTIMERS) {
waitaddr[iloop] = iaddr;
}
}
void setwaittime(int iloop, uint64_t t) {
if (iloop >= 0 && iloop < MAXTIMERS) {
waittime[iloop] = t;
}
}
void pw() {
if (iaddr < MAXWORDS) {
PAT[iaddr] = pat;
}
fprintf(fd, "patword 0x%04x 0x%016llx\n", iaddr, pat);
iaddr++;
if (iaddr >= MAXWORDS) {
printf("ERROR: too many word in the pattern (%d instead of %d)!", iaddr,
MAXWORDS);
}
}
int parseCommand(int clk, int cmdbit, int cmd, int length) {
int ibit;
clearbit(clk);
for (ibit = 0; ibit < length; ibit++) {
if (cmd & (1 >> ibit)) {
setbit(cmdbit);
} else {
clearbit(cmdbit);
}
pw();
/******/
setbit(clk);
pw();
/******/
}
};
int main() {
int iloop = 0;
fd = fopen(OUTFILE, "w");
#include INFILE
fprintf(fd, "patlimits 0x%04x 0x%04x\n", start, stop);
if (iopat_enable == 1) {
fprintf(fd, "patioctrl 0x%016llx\n", iopat);
}
for (iloop = 0; iloop < MAXLOOPS; iloop++) {
if ((startloopaddr[iloop] != MAXWORDS) &&
(stoploopaddr[iloop] != MAXWORDS)) {
fprintf(fd, "patloop %d 0x%04x 0x%04x\n", iloop,
startloopaddr[iloop], stoploopaddr[iloop]);
if (stoploopaddr[iloop] <= startloopaddr[iloop]) {
nloop[iloop] = 0;
}
fprintf(fd, "patnloop %d %u\n", iloop, nloop[iloop]);
}
}
for (iloop = 0; iloop < MAXTIMERS; iloop++) {
if (waitaddr[iloop] != MAXWORDS) {
fprintf(fd, "patwait %d 0x%04x\n", iloop, waitaddr[iloop]);
fprintf(fd, "patwaittime %d %llu\n", iloop, waittime[iloop]);
}
}
fclose(fd);
fd1 = fopen(OUTFILEBIN, "w");
fwrite(PAT, sizeof(uint64_t), iaddr, fd1);
fclose(fd1);
return 0;
}
-610
View File
@@ -1,610 +0,0 @@
#!/usr/bin/env python3
"""
Created on Wed May 24 09:44:53 2017
Plot the pattern for New Chip Test Box (.pat)
Changes:
- 2017-11-21 Adapt it to python-3
- 2017-09-25 All can be plotted
- 2017-09-22 Can be plotted but the loop and wait not work yet
@author: zhang_j1
"""
import matplotlib.pyplot as plt
from numpy import *
from matplotlib.pyplot import *
from matplotlib.patches import Rectangle
import os
import argparse
###############################################################################
# COLORS AND LINE STYLES
# alternating colors of the plots (2 needed)
colors_plot = ['tab:blue', 'tab:orange']
# Wait colors and line styles (6 needed from 0 to 5)
colors_wait = ['b', 'g', 'r', 'c', 'm', 'y']
linestyles_wait = ['--', '--', '--', '--', '--', '--']
alpha_wait = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5]
alpha_wait_rect = [0.2, 0.2, 0.2, 0.2, 0.2, 0.2]
# Loop colors and line styles (6 needed from 0 to 5)
colors_loop = ['tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:grey']
linestyles_loop = ['-.', '-.', '-.', '-.', '-.', '-.']
alpha_loop = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5]
alpha_loop_rect = [0.2, 0.2, 0.2, 0.2, 0.2, 0.2]
# Display the count of clocks
clock_vertical_lines_spacing = 1
show_clocks_number = True
###############################################################################
# Define a hex to binary function
# global definition
# base = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F]
base = [str(x) for x in range(10)] + [chr(x) for x in range(ord('A'), ord('A')+6)]
# dec2bin
def dec2bin(string_num):
num = int(string_num)
mid = []
while True:
if num == 0:
break
num, rem = divmod(num, 2)
mid.append(base[rem])
return ''.join([str(x) for x in mid[::-1]])
# dec2binary: better than dec2bin
def dec2binary(dec_num, width=None):
return binary_repr(int(dec_num), width=width)
# hex2dec
def hex2dec(string_num):
return str(int(string_num.upper(), 16))
# hex2bin
def hex2bin(string_num):
return dec2bin(hex2dec(string_num.upper()))
# hex2bin
def hex2binary(string_num, width=None):
return dec2binary(hex2dec(string_num.upper()), width=width)
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--directory', required = True, help = "Working directory where the pattern is located")
parser.add_argument('-p', '--pattern', required = True, help = "Pattern name")
parser.add_argument('-a', '--alias', help = "Alias name")
parser.add_argument('-v', '--verbose', action='store_true')
args = parser.parse_args()
Folder = args.directory
File_pat = args.pattern
File_alias = args.alias
verbose = args.verbose
# Look at the alias file and generate the lookup table for pin names
# Create a 64 bit look up table
table = []
for i in range(64):
# for special bit
if i+1 == 59:
table.append([str(i+1), "external_trigger"])
elif i+1 == 63:
table.append([str(i+1), "adc_enable"])
elif i+1 == 62:
table.append([str(i+1), "dbit_enable"])
else:
table.append([str(i+1), ""])
# Loop all lines
try:
with open(Folder + "/" + File_alias + ".alias") as f:
lines = f.readlines()
f.close()
nlines = len(lines)
except:
nlines = 0
if nlines > 0:
for i in range(nlines):
# whether the line is bit definition
if lines[i][0:3] == "BIT":
# split words
words = lines[i].split()
bit_num = int(words[0][3:])
table[bit_num][0] = words[0][3:]
table[bit_num][1] = words[1]
else:
for i in range(64):
table[i][0] = i
table[i][1] = f'BIT#{i}'
if verbose:
print(table)
# Load the pattern and get all lines
# Loop all lines
if os.path.exists(Folder + "/" + File_pat + ".pat"):
with open(Folder + "/" + File_pat + ".pat") as f_pat:
lines_pat = f_pat.readlines()
elif os.path.exists(Folder + "/" + File_pat + ".pyat"):
with open(Folder + "/" + File_pat + ".pyat") as f_pat:
lines_pat = f_pat.readlines()
else:
print("No file found - Check it")
exit()
f_pat.close()
# number of lines for pattern file
nlines_pat = len(lines_pat)
# a counter
cnt = 0
if verbose:
print("The total number of lines of pattern:", nlines_pat)
# Loop all lines of pattern
waittime0 = None
waittime1 = None
waittime2 = None
waittime3 = None
waittime4 = None
waittime5 = None
nloop0 = None
nloop1 = None
nloop2 = None
nloop3 = None
nloop4 = None
nloop5 = None
for k in range(nlines_pat):
# content of line
words_line = lines_pat[k].split()
if words_line[0] == "patword":
# print words_line from b0 to b63
bits = hex2binary(words_line[-1], 64)[::-1]
if verbose:
print("The bits for line-", k+1, "is:", bits)
# convert string bits to decimal array
num_bits = array(list(map(str, bits)), dtype="uint16")
if cnt == 0:
mat_pat = num_bits
else:
# add bits to matrix
mat_pat = concatenate((mat_pat, num_bits), axis=0)
cnt = cnt + 1
# print("The matrix of pattern:", mat_pat.reshape(int(cnt), int(len(num_bits))))
# Look at the io: 0 for sending to ASIC, 1 for reading from ASIC
if words_line[0] == "patioctrl":
# print words_line
if verbose:
print(words_line[-1])
bits = hex2binary(words_line[-1], 64)[::-1]
if verbose:
print(bits)
# convert string bits to decimal array
out_bits = array(list(map(str, bits)), dtype="uint16")
if verbose:
print(words_line)
# Deal with waiting point
# ====== WAIT ======
if words_line[0] == "patwait" and words_line[1] == "0":
wait0 = int(hex2dec(words_line[2]))
if verbose:
print("wait 0 at:", wait0)
if words_line[0] == "patwaittime" and words_line[1] == "0":
waittime0 = int(words_line[2])
if verbose:
print("wait 0 for:", waittime0)
if words_line[0] == "patwait" and words_line[1] == "1":
wait1 = int(hex2dec(words_line[2]))
if verbose:
print("wait 1 at:", wait1)
if words_line[0] == "patwaittime" and words_line[1] == "1":
waittime1 = int(words_line[2])
if verbose:
print("wait 1 for:", waittime1)
if words_line[0] == "patwait" and words_line[1] == "2":
wait2 = int(hex2dec(words_line[2]))
if verbose:
print("wait 2 at:", wait2)
if words_line[0] == "patwaittime" and words_line[1] == "2":
waittime2 = int(words_line[2])
if verbose:
print("wait 2 for:", waittime2)
if words_line[0] == "patwait" and words_line[1] == "3":
wait3 = int(hex2dec(words_line[2]))
if verbose:
print("wait 0 at:", wait3)
if words_line[0] == "patwaittime" and words_line[1] == "3":
waittime3 = int(words_line[2])
if verbose:
print("wait 0 for:", waittime3)
if words_line[0] == "patwait" and words_line[1] == "4":
wait4 = int(hex2dec(words_line[2]))
if verbose:
print("wait 1 at:", wait4)
if words_line[0] == "patwaittime" and words_line[1] == "4":
waittime4 = int(words_line[2])
if verbose:
print("wait 1 for:", waittime4)
if words_line[0] == "patwait" and words_line[1] == "5":
wait5 = int(hex2dec(words_line[2]))
if verbose:
print("wait 2 at:", wait5)
if words_line[0] == "patwaittime" and words_line[1] == "5":
waittime5 = int(words_line[2])
if verbose:
print("wait 2 for:", waittime5)
# ====== LOOPS ======
if words_line[0] == "patloop" and words_line[1] == "0":
loop0_start = int(hex2dec(words_line[2]))
loop0_end = int(hex2dec(words_line[3]))
if verbose:
print("loop 0 start:", loop0_start, ", end:", loop0_end)
if words_line[0] == "patnloop" and words_line[1] == "0":
nloop0 = int(words_line[2])
if verbose:
print("loop 0 times:", nloop0)
if words_line[0] == "patloop" and words_line[1] == "1":
loop1_start = int(hex2dec(words_line[2]))
loop1_end = int(hex2dec(words_line[3]))
if verbose:
print("loop 1 start:", loop1_start, ", end:", loop1_end)
if words_line[0] == "patnloop" and words_line[1] == "1":
nloop1 = int(words_line[2])
if verbose:
print("loop 1 times:", nloop1)
if words_line[0] == "patloop" and words_line[1] == "2":
loop2_start = int(hex2dec(words_line[2]))
loop2_end = int(hex2dec(words_line[3]))
if verbose:
print("loop 2 start:", loop2_start, ", end:", loop2_end)
if words_line[0] == "patnloop" and words_line[1] == "2":
nloop2 = int(words_line[2])
if verbose:
print("loop 2 times:", nloop2)
if words_line[0] == "patloop" and words_line[1] == "3":
loop3_start = int(hex2dec(words_line[2]))
loop3_end = int(hex2dec(words_line[3]))
if verbose:
print("loop 3 start:", loop3_start, ", end:", loop3_end)
if words_line[0] == "patnloop" and words_line[1] == "3":
nloop3 = int(words_line[2])
if verbose:
print("loop 3 times:", nloop3)
if words_line[0] == "patloop" and words_line[1] == "4":
loop4_start = int(hex2dec(words_line[2]))
loop4_end = int(hex2dec(words_line[3]))
if verbose:
print("loop 4 start:", loop4_start, ", end:", loop4_end)
if words_line[0] == "patnloop" and words_line[1] == "4":
nloop4 = int(words_line[2])
if verbose:
print("loop 4 times:", nloop4)
if words_line[0] == "patloop" and words_line[1] == "5":
loop5_start = int(hex2dec(words_line[2]))
loop5_end = int(hex2dec(words_line[3]))
if verbose:
print("loop 5 start:", loop5_start, ", end:", loop5_end)
if words_line[0] == "patnloop" and words_line[1] == "5":
nloop5 = int(words_line[2])
if verbose:
print("loop 5 times:", nloop5)
# print(out_bits)
# internal counter
avail_index = []
avail_name = []
# Remove non-used bits
for i in range(64):
# if out_bits[0][i] == 1:
if out_bits[i] == 1:
avail_index.append(i)
avail_name.append(table[i][1])
if verbose:
print(avail_index)
print(avail_name)
# number of effective used bits
nbiteff = len(avail_name)
# subMat = mat_ext[:,index]
# print(mat_pat.shape)
subMat = mat_pat.reshape(int(cnt), int(len(num_bits)))[0:, avail_index]
# subMat = mat_pat[avail_index]
timing = linspace(0, subMat.shape[0]-1, subMat.shape[0])
rcParams['figure.figsize'] = 15, 5
# ============= PLOTTING =============
rcParams["font.weight"] = "bold"
rcParams["axes.labelweight"] = "bold"
fig2, axs2 = subplots(nbiteff, sharex='all')
subplots_adjust(wspace=0, hspace=0)
# axs2[nbiteff - 1].set(xlabel='Timing [clk]')
for idx, i in enumerate(range(nbiteff)):
axs2[idx].plot(subMat.T[i], "-", drawstyle="steps-post", linewidth=2.0, color=colors_plot[idx % 2])
x_additional = range(len(subMat.T[i]) - 1, len(subMat.T[i]) + 2)
additional_stuff = [subMat.T[i][-1]] * 3
axs2[idx].plot(x_additional, additional_stuff,
"--", drawstyle="steps-post", linewidth=2.0, color=colors_plot[idx % 2], alpha=0.5)
axs2[idx].yaxis.set_ticks([0.5], minor=False)
axs2[idx].xaxis.set_ticks(arange(0, len(subMat.T[i]) + 10, clock_vertical_lines_spacing))
axs2[idx].yaxis.set_ticklabels([avail_name[i]])
axs2[idx].get_yticklabels()[0].set_color(colors_plot[idx % 2])
axs2[idx].grid(1, 'both', 'both', alpha=0.5)
axs2[idx].yaxis.grid(which="both", color=colors_plot[idx % 2], alpha=0.2)
if idx != nbiteff - 1:
if not show_clocks_number:
axs2[idx].xaxis.set_ticklabels([])
axs2[idx].set(xlabel=' ', ylim=(-0.2, 1.2))
else:
axs2[idx].set(xlabel='Timing [clk]', ylim=(-0.2, 1.2))
# axs2[idx].set_xlim(left=0)
axs2[idx].set_xlim(left=0, right=len(subMat.T[i]) + 1)
axs2[idx].spines['top'].set_visible(False)
axs2[idx].spines['right'].set_alpha(0.2)
axs2[idx].spines['right'].set_visible(True)
axs2[idx].spines['bottom'].set_visible(False)
axs2[idx].spines['left'].set_visible(False)
# =====================================================================================================
# Plot the wait lines
# Wait 0
if waittime0 is not None:
if waittime0 == 0:
axs2[idx].plot([wait0, wait0], [-10, 10],
linestyle=linestyles_wait[0], color=colors_wait[0], alpha=alpha_wait[0], linewidth=2.0)
axs2[idx].plot([wait0 + 1, wait0 + 1], [-10, 10],
linestyle=linestyles_wait[0], color=colors_wait[0], linewidth=2.0, alpha=alpha_wait[0])
axs2[idx].add_patch(Rectangle((wait0, -10), 1, 20,
label="wait 0: skipped" if idx == 0 else "",
facecolor=colors_wait[0], alpha=alpha_wait_rect[0], hatch='\\\\'))
else:
axs2[idx].plot([wait0, wait0], [-10, 10],
linestyle=linestyles_wait[0], color=colors_wait[0],
label="wait 0: " + str(waittime0) + " clk" if idx == 0 else "",
linewidth=2.0, alpha=alpha_wait[0])
# Wait 1
if waittime1 is not None:
if waittime1 == 0:
axs2[idx].plot([wait1, wait1], [-10, 10],
linestyle=linestyles_wait[1], color=colors_wait[1], alpha=alpha_wait[1], linewidth=2.0)
axs2[idx].plot([wait1 + 1, wait1 + 1], [-10, 10],
linestyle=linestyles_wait[1], color=colors_wait[1], linewidth=2.0, alpha=alpha_wait[1])
axs2[idx].add_patch(Rectangle((wait1, -10), 1, 20,
label="wait 1: skipped" if idx == 0 else "",
facecolor=colors_wait[1], alpha=alpha_wait_rect[1], hatch='\\\\'))
else:
axs2[idx].plot([wait1, wait1], [-10, 10],
linestyle=linestyles_wait[1], color=colors_wait[1],
label="wait 1: " + str(waittime1) + " clk" if idx == 0 else "",
linewidth=2.0, alpha=alpha_wait[1])
# Wait 2
if waittime2 is not None:
if waittime2 == 0:
axs2[idx].plot([wait2, wait2], [-10, 10],
linestyle=linestyles_wait[2], color=colors_wait[2], alpha=alpha_wait[2], linewidth=2.0)
axs2[idx].plot([wait2 + 1, wait2 + 1], [-10, 10],
linestyle=linestyles_wait[2], color=colors_wait[2], linewidth=2.0, alpha=alpha_wait[2])
axs2[idx].add_patch(Rectangle((wait2, -10), 1, 20,
label="wait 2: skipped" if idx == 0 else "",
facecolor=colors_wait[2], alpha=alpha_wait_rect[2], hatch='\\\\'))
else:
axs2[idx].plot([wait2, wait2], [-10, 10],
linestyle=linestyles_wait[2], color=colors_wait[2],
label="wait 2: " + str(waittime2) + " clk" if idx == 0 else "",
linewidth=2.0, alpha=alpha_wait[2])
# Wait 3
if waittime3 is not None:
if waittime3 == 0:
axs2[idx].plot([wait3, wait3], [-10, 10],
linestyle=linestyles_wait[3], color=colors_wait[3], alpha=alpha_wait[3], linewidth=2.0)
axs2[idx].plot([wait3 + 1, wait3 + 1], [-10, 10],
linestyle=linestyles_wait[3], color=colors_wait[3], linewidth=2.0, alpha=alpha_wait[3])
axs2[idx].add_patch(Rectangle((wait3, -10), 1, 20,
label="wait 3: skipped" if idx == 0 else "",
facecolor=colors_wait[3], alpha=alpha_wait_rect[3], hatch='\\\\'))
else:
axs2[idx].plot([wait3, wait3], [-10, 10],
linestyle=linestyles_wait[3], color=colors_wait[3],
label="wait 3: " + str(waittime3) + " clk" if idx == 0 else "",
linewidth=2.0, alpha=alpha_wait[3])
# Wait 4
if waittime4 is not None:
if waittime4 == 0:
axs2[idx].plot([wait4, wait4], [-10, 10],
linestyle=linestyles_wait[4], color=colors_wait[4], alpha=alpha_wait[4], linewidth=2.0)
axs2[idx].plot([wait4 + 1, wait4 + 1], [-10, 10],
linestyle=linestyles_wait[4], color=colors_wait[4], linewidth=2.0, alpha=alpha_wait[4])
axs2[idx].add_patch(Rectangle((wait4, -10), 1, 20,
label="wait 4: skipped" if idx == 0 else "",
facecolor=colors_wait[4], alpha=alpha_wait_rect[4], hatch='\\\\'))
else:
axs2[idx].plot([wait4, wait4], [-10, 10],
linestyle=linestyles_wait[4], color=colors_wait[4],
label="wait 4: " + str(waittime4) + " clk" if idx == 0 else "",
linewidth=2.0, alpha=alpha_wait[4])
# Wait 5
if waittime5 is not None:
if waittime5 == 0:
axs2[idx].plot([wait5, wait5], [-10, 10],
linestyle=linestyles_wait[5], color=colors_wait[5], alpha=alpha_wait[5], linewidth=2.0)
axs2[idx].plot([wait5 + 1, wait5 + 1], [-10, 10],
linestyle=linestyles_wait[5], color=colors_wait[5], linewidth=2.0, alpha=alpha_wait[5])
axs2[idx].add_patch(Rectangle((wait5, -10), 1, 20,
label="wait 5: skipped" if idx == 0 else "",
facecolor=colors_wait[5], alpha=alpha_wait_rect[5], hatch='\\\\'))
else:
axs2[idx].plot([wait5, wait5], [-10, 10],
linestyle=linestyles_wait[5], color=colors_wait[5],
label="wait 5: " + str(waittime5) + " clk" if idx == 0 else "",
linewidth=2.0, alpha=alpha_wait[5])
# =====================================================================================================
# Plot the loop lines
# Loop 0
if nloop0 is not None:
if nloop0 == 0:
axs2[idx].plot([loop0_start, loop0_start], [-10, 10],
linestyle=linestyles_loop[0], color=colors_loop[0],
alpha=alpha_loop[0], linewidth=2.0)
axs2[idx].plot([loop0_end + 1, loop0_end + 1], [-10, 10],
linestyle=linestyles_loop[0], color=colors_loop[0], alpha=alpha_loop[0], linewidth=2.0)
axs2[idx].add_patch(Rectangle((loop0_start, -10), loop0_end + 1 - loop0_start, 20,
label="loop 0: skipped" if idx == 0 else "",
facecolor=colors_loop[0], alpha=alpha_loop_rect[0], hatch='//'))
else:
axs2[idx].plot([loop0_start, loop0_start], [-10, 10],
linestyle=linestyles_loop[0], color=colors_loop[0], alpha=alpha_loop[0],
label="loop 0: " + str(nloop0) + " times" if idx == 0 else "", linewidth=2.0)
axs2[idx].plot([loop0_end, loop0_end], [-10, 10],
linestyle=linestyles_loop[0], color=colors_loop[0], alpha=alpha_loop[0], linewidth=2.0)
# Loop 1
if nloop1 is not None:
if nloop1 == 0:
axs2[idx].plot([loop1_start, loop1_start], [-10, 10],
linestyle=linestyles_loop[1], color=colors_loop[1],
alpha=alpha_loop[1], linewidth=2.0)
axs2[idx].plot([loop1_end + 1, loop1_end + 1], [-10, 10],
linestyle=linestyles_loop[1], color=colors_loop[1], alpha=alpha_loop[1], linewidth=2.0)
axs2[idx].add_patch(Rectangle((loop1_start, -10), loop1_end + 1 - loop1_start, 20,
label="loop 1: skipped" if idx == 0 else "",
facecolor=colors_loop[1], alpha=alpha_loop_rect[1], hatch='//'))
else:
axs2[idx].plot([loop1_start, loop1_start], [-10, 10],
linestyle=linestyles_loop[1], color=colors_loop[1], alpha=alpha_loop[1],
label="loop 1: " + str(nloop1) + " times" if idx == 0 else "", linewidth=2.0)
axs2[idx].plot([loop1_end, loop1_end], [-10, 10],
linestyle=linestyles_loop[1], color=colors_loop[1], alpha=alpha_loop[1], linewidth=2.0)
# Loop 2
if nloop2 is not None:
if nloop2 == 0:
axs2[idx].plot([loop2_start, loop2_start], [-10, 10],
linestyle=linestyles_loop[2], color=colors_loop[2],
alpha=alpha_loop[2], linewidth=2.0)
axs2[idx].plot([loop2_end + 1, loop2_end + 1], [-10, 10],
linestyle=linestyles_loop[2], color=colors_loop[2], alpha=alpha_loop[2], linewidth=2.0)
axs2[idx].add_patch(Rectangle((loop2_start, -10), loop2_end + 1 - loop2_start, 20,
label="loop 2: skipped" if idx == 0 else "",
facecolor=colors_loop[2], alpha=alpha_loop_rect[2], hatch='//'))
else:
axs2[idx].plot([loop2_start, loop2_start], [-10, 10],
linestyle=linestyles_loop[2], color=colors_loop[2], alpha=alpha_loop[2],
label="loop 2: " + str(nloop2) + " times" if idx == 0 else "", linewidth=2.0)
axs2[idx].plot([loop2_end, loop2_end], [-10, 10],
linestyle=linestyles_loop[2], color=colors_loop[2], alpha=alpha_loop[2], linewidth=2.0)
# Loop 3
if nloop3 is not None:
if nloop3 == 0:
axs2[idx].plot([loop3_start, loop3_start], [-10, 10],
linestyle=linestyles_loop[3], color=colors_loop[3],
alpha=alpha_loop[3], linewidth=2.0)
axs2[idx].plot([loop3_end + 1, loop3_end + 1], [-10, 10],
linestyle=linestyles_loop[3], color=colors_loop[3], alpha=alpha_loop[3], linewidth=2.0)
axs2[idx].add_patch(Rectangle((loop3_start, -10), loop3_end + 1 - loop3_start, 20,
label="loop 3: skipped" if idx == 0 else "",
facecolor=colors_loop[3], alpha=alpha_loop_rect[3], hatch='//'))
else:
axs2[idx].plot([loop3_start, loop3_start], [-10, 10],
linestyle=linestyles_loop[3], color=colors_loop[3], alpha=alpha_loop[3],
label="loop 3: " + str(nloop3) + " times" if idx == 0 else "", linewidth=2.0)
axs2[idx].plot([loop3_end, loop3_end], [-10, 10],
linestyle=linestyles_loop[3], color=colors_loop[3], alpha=alpha_loop[3], linewidth=2.0)
# Loop 4
if nloop4 is not None:
if nloop4 == 0:
axs2[idx].plot([loop4_start, loop4_start], [-10, 10],
linestyle=linestyles_loop[4], color=colors_loop[4],
alpha=alpha_loop[4], linewidth=2.0)
axs2[idx].plot([loop4_end + 1, loop4_end + 1], [-10, 10],
linestyle=linestyles_loop[4], color=colors_loop[4], alpha=alpha_loop[4], linewidth=2.0)
axs2[idx].add_patch(Rectangle((loop4_start, -10), loop4_end + 1 - loop4_start, 20,
label="loop 4: skipped" if idx == 0 else "",
facecolor=colors_loop[4], alpha=alpha_loop_rect[4], hatch='//'))
else:
axs2[idx].plot([loop4_start, loop4_start], [-10, 10],
linestyle=linestyles_loop[4], color=colors_loop[4], alpha=alpha_loop[4],
label="loop 4: " + str(nloop4) + " times" if idx == 0 else "", linewidth=2.0)
axs2[idx].plot([loop4_end, loop4_end], [-10, 10],
linestyle=linestyles_loop[4], color=colors_loop[4], alpha=alpha_loop[4], linewidth=2.0)
# Loop 5
if nloop5 is not None:
if nloop5 == 0:
axs2[idx].plot([loop5_start, loop5_start], [-10, 10],
linestyle=linestyles_loop[5], color=colors_loop[5],
alpha=alpha_loop[5], linewidth=2.0)
axs2[idx].plot([loop5_end + 1, loop5_end + 1], [-10, 10],
linestyle=linestyles_loop[5], color=colors_loop[5], alpha=alpha_loop[5], linewidth=2.0)
axs2[idx].add_patch(Rectangle((loop5_start, -10), loop5_end + 1 - loop5_start, 20,
label="loop 5: skipped" if idx == 0 else "",
facecolor=colors_loop[5], alpha=alpha_loop_rect[5], hatch='//'))
else:
axs2[idx].plot([loop5_start, loop5_start], [-10, 10],
linestyle=linestyles_loop[5], color=colors_loop[5], alpha=alpha_loop[5],
label="loop 5: " + str(nloop5) + " times" if idx == 0 else "", linewidth=2.0)
axs2[idx].plot([loop5_end, loop5_end], [-10, 10],
linestyle=linestyles_loop[5], color=colors_loop[5], alpha=alpha_loop[5], linewidth=2.0)
n_cols = count_nonzero([waittime0 != 0, waittime1 != 0, waittime2 != 0, waittime3 != 0, waittime4 != 0, waittime5 != 0,
nloop0 != 0, nloop1 != 0, nloop2 != 0, nloop3 != 0, nloop4 != 0, nloop5 != 0])
if n_cols > 0:
fig2.legend(loc="upper center", ncol=n_cols)
# manager = get_current_fig_manager()
# manager.window.showMaximized()
figure = plt.gcf() # get current figure
figure.set_size_inches(20, 10)
# when saving, specify the DPI
# tight_layout()
plt.savefig(Folder+"/"+File_pat+".png", dpi=300)
# Remove the white space around the plot -- only works on Unix (ImageMagick command)
os.system(f'mogrify -trim {Folder}/{File_pat}.png')
show()
+24
View File
@@ -27,10 +27,34 @@ class Ctb(Detector):
@property
def powers(self):
"""
[Chiptestboard][Xilinx CTB] Power names and values of all power supplies.
Example
-----------
>>> # print all powers with DAC and info if enabled
>>> d.powers
>>> # set DAC or enables for power supply VA
>>> d.powers.VA = 1200
>>> # enable or disable power subbly VA
>>> d.powers.VA.enable()
>>> d.powers.VA.disable()
>>> # get dac value of power supply VA
>>> d.powers.VA.dac
>>> # check if power supply VA is enabled
>>> d.powers.VA.enabled
>>> # print both enabled and dac value of power supply VA
>>> d.powers.VA
"""
return self._powers
@property
def powerlist(self):
"""
List of power supply names on the Chip Test Board.
:setter: List of custom power supply names to set.
"""
return self.getPowerNames()
@powerlist.setter
+20 -12
View File
@@ -827,16 +827,21 @@ class Detector(CppDetectorApi):
@property
@element
def txdelay(self):
"""
r"""
[Eiger][Jungfrau][Moench][Mythen3] Set transmission delay for all modules in the detector using the step size provided.
Note
----
Sets up the following for every module:\n
\t\t[Eiger] txdelay_left to (2 * mod_index * n_delay), \n
\t\t[Eiger] txdelay_right to ((2 * mod_index + 1) * n_delay) and \n
\t\t[Eiger] txdelay_frame to (2 *num_modules * n_delay) \n
\t\t[Jungfrau][Moench][Mythen3] txdelay_frame to (num_modules * n_delay)\n\n
Sets up the following for every module:
[Eiger] txdelay_left to (2 \* mod_index \* n_delay),
[Eiger] txdelay_right to ((2 \* mod_index + 1) \* n_delay) and
[Eiger] txdelay_frame to (2 \* num_modules \* n_delay)
[Jungfrau][Moench][Mythen3] txdelay_frame to (num_modules \* n_delay)
Please refer txdelay_left, txdelay_right and txdelay_frame for details.
"""
return self.getTransmissionDelay()
@@ -1313,10 +1318,10 @@ class Detector(CppDetectorApi):
@property
def zmqhwm(self):
"""
Client's zmq receive high water mark. Default is the zmq library's default (1000), can also be set here using -1.
This is a high number and can be set to 2 for gui purposes.
Client's zmq receive high water mark. Default is the zmq library's default (1000), can also be set here using -1.
This is a high number and can be set to 2 for gui purposes.
One must also set the receiver's send high water mark to similar value. Final effect is sum of them.
Setting it via command line is useful only before zmq enabled (before opening gui).
Setting it via command line is useful only before zmq enabled (before opening gui).
"""
return self.getClientZmqHwm()
@@ -2312,13 +2317,16 @@ class Detector(CppDetectorApi):
@property
@element
def threshold(self):
"""[Eiger][Mythen3] Threshold in eV
"""
[Eiger][Mythen3] Threshold in eV
Note
----
To change settings as well or set threshold without trimbits, use setThresholdEnergy.
To change settings as well or set threshold without trimbits,
use setThresholdEnergy.
:setter: It loads trim files from settingspath.\n [Mythen3] An energy of -1 will pick up values from detector.
:setter: It loads trim files from settingspath.\n
[Mythen3] An energy of -1 will pick up values from detector.
"""
if self.type == detectorType.MYTHEN3:
+12
View File
@@ -27,6 +27,12 @@ void init_enums(py::module &m) {
.value("GOTTHARD2", slsDetectorDefs::detectorType::GOTTHARD2)
.value("XILINX_CHIPTESTBOARD",
slsDetectorDefs::detectorType::XILINX_CHIPTESTBOARD)
.value("MATTERHORN", slsDetectorDefs::detectorType::MATTERHORN)
.export_values();
py::enum_<slsDetectorDefs::ReturnCode>(Defs, "ReturnCode")
.value("OK", slsDetectorDefs::ReturnCode::OK)
.value("FAIL", slsDetectorDefs::ReturnCode::FAIL)
.export_values();
py::enum_<slsDetectorDefs::boolFormat>(Defs, "boolFormat")
@@ -50,6 +56,12 @@ void init_enums(py::module &m) {
.value("Y", slsDetectorDefs::dimension::Y)
.export_values();
py::enum_<slsDetectorDefs::FrequencyUnit>(Defs, "FrequencyUnit")
.value("Hz", slsDetectorDefs::FrequencyUnit::Hz)
.value("kHz", slsDetectorDefs::FrequencyUnit::kHz)
.value("MHz", slsDetectorDefs::FrequencyUnit::MHz)
.export_values();
py::enum_<slsDetectorDefs::frameDiscardPolicy>(Defs, "frameDiscardPolicy")
.value("NO_DISCARD", slsDetectorDefs::frameDiscardPolicy::NO_DISCARD)
.value("DISCARD_EMPTY_FRAMES",
-5
View File
@@ -620,11 +620,6 @@ void qDrawPlot::StartAcquisition() {
"qDrawPlot::StartAcquisition");
}
// refixing all the zooming
{
std::lock_guard<std::mutex> lock(mPlots);
xyRangeChanged = true;
}
QtConcurrent::run(this, &qDrawPlot::AcquireThread);
@@ -11,7 +11,15 @@
#include <unistd.h>
// gettid added in glibc 2.30
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
#if defined(__APPLE__)
#include <cstdint>
#include <pthread.h>
static inline uint64_t gettid() {
uint64_t tid = 0;
pthread_threadid_np(nullptr, &tid);
return tid;
}
#elif __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
#endif
@@ -11,8 +11,10 @@
#include <stdlib.h>
#include <fcntl.h>
#ifndef __APPLE__
#include <linux/spi/spidev.h>
#include <linux/types.h>
#endif
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
@@ -11,6 +11,12 @@
#include <sys/stat.h> // stat
#include <sys/utsname.h> // uname
#include <unistd.h> // readlink
#ifdef __APPLE__
#include <limits.h> // PATH_MAX
#include <mach-o/dyld.h> // _NSGetExecutablePath
#include <stdint.h> // uint32_t
#include <stdlib.h> // realpath
#endif
extern int executeCommand(char *command, char *result, enum TLogLevel level);
@@ -58,12 +64,33 @@ int getAbsPath(char *buf, size_t bufSize, char *fname) {
// get path of current binary
char path[bufSize];
memset(path, 0, bufSize);
#ifdef __APPLE__
// macOS has no /proc; use _NSGetExecutablePath and canonicalize with
// realpath (the path returned may contain ".." or symlinks).
char raw[PATH_MAX];
uint32_t rawSize = sizeof(raw);
if (_NSGetExecutablePath(raw, &rawSize) != 0) {
LOG(logWARNING,
("Could not get current binary path for %s (buffer too small)\n",
fname));
return FAIL;
}
char resolved[PATH_MAX];
const char *src = realpath(raw, resolved) != NULL ? resolved : raw;
if (strlen(src) >= bufSize) {
LOG(logWARNING,
("Current binary path too long for buffer (%s)\n", fname));
return FAIL;
}
strcpy(path, src);
#else
ssize_t len = readlink("/proc/self/exe", path, bufSize - 1);
if (len < 0) {
LOG(logWARNING, ("Could not readlink current binary for %s\n", fname));
return FAIL;
}
path[len] = '\0';
#endif
// get dir path and attach file name
char *dir = dirname(path);
@@ -8,7 +8,9 @@
#include <string.h>
#include <sys/stat.h>
#ifndef __APPLE__
#include <sys/sysinfo.h>
#endif
#include <unistd.h> // usleep
/* global variables */
@@ -309,6 +311,7 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd,
}
// check available memory to copy program
#ifndef __APPLE__
{
struct sysinfo info;
sysinfo(&info);
@@ -322,6 +325,7 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd,
return FAIL;
}
}
#endif
// open file to copy program
*fd = fopen(TEMP_PROG_FILE_NAME, "w");
@@ -20,10 +20,24 @@
#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
#ifndef __APPLE__
#include <sys/sysinfo.h>
#endif
#include <unistd.h>
#ifdef __APPLE__
// spidev is Linux-only; provide a minimal stub so virtual builds compile.
// The real ioctl(SPI_IOC_MESSAGE(...)) calls are guarded by detector
// macros (XILINX_CHIPTESTBOARDD) that are never set on macOS.
struct spi_ioc_transfer {
unsigned long tx_buf;
unsigned long rx_buf;
unsigned int len;
unsigned char cs_change;
};
#else
#include <linux/spi/spidev.h>
#endif
// defined in the detector specific Makefile
#ifdef EIGERD
@@ -127,6 +141,10 @@ int sendError(int file_des) {
}
void setMemoryAllocationErrorMessage() {
#ifdef __APPLE__
sprintf(mess, "Memory allocation error (%s). Please reboot",
getFunctionNameFromEnum((enum detFuncs)fnum));
#else
struct sysinfo info;
sysinfo(&info);
sprintf(
@@ -134,6 +152,7 @@ void setMemoryAllocationErrorMessage() {
"Memory allocation error (%s). Available space: %d MB. Please reboot",
getFunctionNameFromEnum((enum detFuncs)fnum),
(int)(info.freeram / (1024 * 1024)));
#endif
#ifdef EIGERD
strcat(mess, ".\n");
#else
@@ -9784,12 +9803,17 @@ void receive_program_default(int file_des, enum PROGRAM_INDEX index,
if (ret == OK) {
src = malloc(filesize);
if (src == NULL) {
#ifdef __APPLE__
sprintf(mess, "Could not %s. Memory allocation failure.\n",
functionType);
#else
struct sysinfo info;
sysinfo(&info);
sprintf(mess,
"Could not %s. Memory allocation failure. Free "
"space: %d MB\n",
functionType, (int)(info.freeram / (1024 * 1024)));
#endif
LOG(logERROR, (mess));
ret = FAIL;
}
@@ -25,6 +25,8 @@ struct UDPInfo {
uint32_t dstip{};
};
using ReturnCode = slsDetectorDefs::ReturnCode;
template <typename DerivedDetectorServer> class DetectorServer {
public:
@@ -19,8 +19,8 @@ class TCPInterface {
public:
~TCPInterface();
TCPInterface(std::function<ReturnCode(const detFuncs &, ServerInterface &)>
&processFunction_,
TCPInterface(std::function<slsDetectorDefs::ReturnCode(
const detFuncs &, ServerInterface &)> &processFunction_,
const uint16_t portNumber = DEFAULT_TCP_CNTRL_PORTNO);
/// @brief creates tcp thread
@@ -40,11 +40,12 @@ class TCPInterface {
* @param function_id The ID of the function recived by the server and to
* be executed
*/
ReturnCode processReceivedData(const detFuncs function_id,
ServerInterface &socket);
slsDetectorDefs::ReturnCode processReceivedData(const detFuncs function_id,
ServerInterface &socket);
/// @brief map of function IDs and corresponding functions
std::function<ReturnCode(const detFuncs &, ServerInterface &)>
std::function<slsDetectorDefs::ReturnCode(const detFuncs &,
ServerInterface &)>
processFunction;
/// @brief TCP/IP port number for the detector server
@@ -8,8 +8,8 @@
namespace sls {
TCPInterface::TCPInterface(
std::function<ReturnCode(const detFuncs &, ServerInterface &)>
&processFunction_,
std::function<slsDetectorDefs::ReturnCode(
const detFuncs &, ServerInterface &)> &processFunction_,
const uint16_t portNumber_)
: processFunction(processFunction_), portNumber(portNumber_),
server(portNumber_) {
@@ -53,7 +53,7 @@ void TCPInterface::startTCPServerClientConnection() {
auto returncode = processReceivedData(
static_cast<detFuncs>(function_id), socket);
if (returncode == FAIL) {
if (returncode == slsDetectorDefs::ReturnCode::FAIL) {
throw RuntimeError(fmt::format(
"Error processing command with fnum: {}",
getFunctionNameFromEnum((enum detFuncs)function_id)));
@@ -76,14 +76,16 @@ void TCPInterface::startTCPServerClientConnection() {
LOG(logINFOBLUE) << "Exiting TCP Server";
}
ReturnCode TCPInterface::processReceivedData(const detFuncs function_id,
ServerInterface &socket) {
slsDetectorDefs::ReturnCode
TCPInterface::processReceivedData(const detFuncs function_id,
ServerInterface &socket) {
LOG(logDEBUG1) << "calling function fnum: " << function_id << " ("
<< getFunctionNameFromEnum((enum detFuncs)function_id)
<< ")";
ReturnCode returncode = processFunction(function_id, socket);
slsDetectorDefs::ReturnCode returncode =
processFunction(function_id, socket);
LOG(logDEBUG1) << "Function "
<< getFunctionNameFromEnum((enum detFuncs)function_id)
+3 -2
View File
@@ -1586,7 +1586,7 @@ std::string Caller::define_bit(int action) {
std::string Caller::definelist_reg(int action) {
std::ostringstream os;
if (action == defs::HELP_ACTION) {
os << "List of user-defined register definitions in shared memory."
os << "\n\t List of user-defined register definitions in shared memory."
<< '\n';
} else if (action == defs::PUT_ACTION) {
throw RuntimeError("cannot put");
@@ -1605,7 +1605,8 @@ std::string Caller::definelist_reg(int action) {
std::string Caller::definelist_bit(int action) {
std::ostringstream os;
if (action == defs::HELP_ACTION) {
os << "List of user-defined bit definitions in shared memory." << '\n';
os << "\n\t List of user-defined bit definitions in shared memory."
<< '\n';
} else if (action == defs::PUT_ACTION) {
throw RuntimeError("cannot put");
} else if (action == defs::GET_ACTION) {
-27
View File
@@ -11,37 +11,10 @@
namespace sls {
/**
* @param data array of data values
* @param nch number of channels
* @param offset start channel value
*/
int readDataFile(std::ifstream &infile, short int *data, int nch,
int offset = 0);
/**
* @param data array of data value
* @param nch number of channels
*/
int readDataFile(std::string fname, short int *data, int nch);
std::vector<char> readBinaryFile(const std::string &fname,
const std::string &errorPrefix);
/**
* @param nch number of channels
* @param data array of data values
* @param offset start channel number
*/
int writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset = 0);
/**
* @param nch number of channels
* @param data array of data values
*/
int writeDataFile(std::string fname, int nch, short int *data);
// mkdir -p path implemented by recursive calls
void mkdir_p(const std::string &path, std::string dir = "");
@@ -89,9 +89,6 @@
// NOLINTEND(cppcoreguidelines-macro-usage)
#ifdef __cplusplus
// TODO: why are all these defs inside a class? - why not static
enum ReturnCode { OK = 0, FAIL = 1 };
class slsDetectorDefs {
public:
#endif
@@ -111,8 +108,7 @@ class slsDetectorDefs {
// slsDetectorDefs instead of grouped in a class
};
/** return values */
enum { OK, FAIL };
enum ReturnCode { OK, FAIL };
enum boolFormat { TrueFalse, OnOff, OneZero };
-66
View File
@@ -22,48 +22,6 @@
namespace sls {
int readDataFile(std::ifstream &infile, short int *data, int nch, int offset) {
int ichan, iline = 0;
short int idata;
int interrupt = 0;
std::string str;
while (infile.good() and interrupt == 0) {
getline(infile, str);
std::istringstream ssstr(str);
ssstr >> ichan >> idata;
if (ssstr.fail() || ssstr.bad()) {
interrupt = 1;
break;
}
if (iline < nch) {
if (ichan >= offset) {
data[iline] = idata;
iline++;
}
} else {
interrupt = 1;
break;
}
return iline;
};
return iline;
}
int readDataFile(std::string fname, short int *data, int nch) {
std::ifstream infile;
int iline = 0;
std::string str;
infile.open(fname.c_str(), std::ios_base::in);
if (infile.is_open()) {
iline = readDataFile(infile, data, nch, 0);
infile.close();
} else {
LOG(logERROR) << "Could not read file " << fname;
return -1;
}
return iline;
}
std::vector<char> readBinaryFile(const std::string &fname,
const std::string &errorPrefix) {
// check if it exists
@@ -96,30 +54,6 @@ std::vector<char> readBinaryFile(const std::string &fname,
return buffer;
}
int writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset) {
if (data == nullptr)
return slsDetectorDefs::FAIL;
for (int ichan = 0; ichan < nch; ichan++)
outfile << ichan + offset << " " << *(data + ichan) << std::endl;
return slsDetectorDefs::OK;
}
int writeDataFile(std::string fname, int nch, short int *data) {
std::ofstream outfile;
if (data == nullptr)
return slsDetectorDefs::FAIL;
outfile.open(fname.c_str(), std::ios_base::out);
if (outfile.is_open()) {
writeDataFile(outfile, nch, data, 0);
outfile.close();
return slsDetectorDefs::OK;
} else {
LOG(logERROR) << "Could not open file " << fname << "for writing";
return slsDetectorDefs::FAIL;
}
}
void mkdir_p(const std::string &path, std::string dir) {
if (path.length() == 0)
return;