Compare commits

..

12 Commits

Author SHA1 Message Date
f377e1aae2 fill value in hdf5 according to actual datatype of dataset 2024-08-08 17:38:50 +02:00
8d185988c1 8.0.2.rc: m3 clkdiv0 20 (#923)
* m3: clk 0 changed from 10 to 20 (100MHz to 50MHz)

* g2: startup clk div back to 10 as in firmware but setting in software startup to 20
2024-07-25 17:17:20 +02:00
61e9437842 fix to rapidjson for build with gcc 14 (#928) 2024-07-25 17:15:03 +02:00
2d177924eb 8.0.2.rc: client: blocking acquire stop with slave temporarily in waiting (#925)
* client: stopping a blocking acquire of multi modules checks status to catch slaves that might still be in waiting. Problem is (gotthard2 25um at least) slave is in waiting only temporarily before going go idle/stopped. So a 50ms sleep is necessary ot not throw an unnecessary error

* client: when stopping blocking acquire, wait up to 1s in 50ms increments for slave to stop waiting temporarily
2024-07-16 15:43:14 +02:00
4eb8e52360 client bug fix: m3 multi module bad channel file throws bad allocation when modules skipped, needed to add vectors in 2d vector of bad channel list (#919) 2024-07-16 11:58:39 +02:00
2c278b1933 moench server: changed default values of adcphase for full speed from 300 to 150 and dac vipre_cds from 800 to 1280 (#921) 2024-07-15 12:31:27 +02:00
e4c52bde1d moench: min exptime and also a firmware update required (#911) 2024-02-07 10:22:46 +01:00
6251dc1b71 Protect from getenv("HOME") returning nullptr (#907)
* Protect from getenv("HOME") returning nullptr (e.g., in case running in systemd)

* Write proper warning in Module.cpp
2024-02-07 09:35:50 +01:00
aa173d3a87 802/moench default speed (#910)
* moench:change default speed to half speed
2024-02-06 12:10:42 +01:00
62c428320f moench server name and version renaming 2024-02-06 11:45:55 +01:00
70f467a3cd moench: changed max shifts of adc clk from 240 to 200 (#909) 2024-02-06 11:34:17 +01:00
97f0c1fe46 8.0.1.rc (#891)
* forward declare zmq_msg_t and moved include

* removed zmq as dependency for slsdet (#870)

* Fixed path when building as submodule

* new moench data structure for offline processing

* meonch raw data and zmq process files updated to 7.0.3 version

* implemented config file for Zmq file

* raw data and zmq work with config file, but only with one file/interface

* zmq config change

* added config examples for zmq and rawdata

* update release notes, release versions

---------

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
Co-authored-by: froejdh_e <erik.frojdh@psi.ch>
Co-authored-by: Anna Bergamaschi <anna.bergamaschi@psi.ch>
Co-authored-by: anberga <34126852+anberga@users.noreply.github.com>
2024-01-16 15:31:25 +01:00
31 changed files with 1089 additions and 547 deletions

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 8.0.0)
set(PROJECT_VERSION 8.0.1)
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_SOURCE_DIR}/libs/libzmq/libzmq-4.3.4.tar.gz
URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-4.3.4.tar.gz
URL_HASH MD5=cc20b769ac10afa352e5ed2769bb23b3
)
endif()

View File

@ -1,265 +1,43 @@
SLS Detector Package Major Release 8.0.0 released on 13.11.2023
SLS Detector Package Major Release 8.0.1 released on 16.01.2024
===============================================================
This document describes the differences between v8.0.0 and v7.0.3
This document describes the differences between v8.0.1 and v8.0.0
CONTENTS
--------
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 Resolved Issues
2 On-board Detector Server Compatibility
3 Firmware Requirements
4 Kernel Requirements
5 Download, Documentation & Support
2 Compilation Changes
=====================
1 Resolved Issues
=================
* Minimum CMake version changed from 3.12 to 3.14
Compilation
-----------
* 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)
* Fixed compilation error when building without zmq-devel installed
and removed dependency on zeromq in conda build.
* 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)
* Fixed libzmq compilation error to build the package as a submodule.
Calibration
-----------
2 New, Changed or Resolved Features
=====================================
* [Moench] Fixed Moench calibration
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.
2 On-board Detector Server Compatibility

View File

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

22
examples/rawdata.config Normal file
View File

@ -0,0 +1,22 @@
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

16
examples/zmq.config Normal file
View File

@ -0,0 +1,16 @@
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

@ -316,7 +316,8 @@ struct GenericStringRef {
GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; }
// Removed to fix failing build in GCC 14
// GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; }
//! implicit conversion to plain CharType pointer
operator const Ch *() const { return s; }

View File

@ -7,7 +7,6 @@ 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
@ -41,11 +40,10 @@ ext_modules = [
,
include_dirs=[
os.path.join('../libs/pybind/include'),
os.path.join(get_conda_path(), 'include'),
],
libraries=['SlsDetector', 'SlsSupport', 'SlsReceiver', 'zmq'],
libraries=['SlsDetector', 'SlsSupport', 'SlsReceiver'],
library_dirs=[
os.path.join(get_conda_path(), 'lib'),
],

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,240 @@
// 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

@ -0,0 +1,240 @@
// 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" << endl;
<< " infile etafile outfile runmin runmax ns [cmin cmax xmin xmax ymin ymax]" << 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" << endl;
<< " infile etafile runmin runmax [cmin cmax xmin xmax ymin ymax]" << endl;
return 1;
}
#endif
@ -65,13 +65,30 @@ int main(int argc, char *argv[]) {
nsubpix = atoi(argv[iarg++]);
cout << "Subpix: " << nsubpix << endl;
#endif
float cmin = atof(argv[iarg++]);
float cmax = atof(argv[iarg++]);
float cmin = 0;
float cmax=1000000;
if (argc>iarg)
cmin=atof(argv[iarg++]);
if (argc>iarg)
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 = -1, etamax = 2;
double etamin = -0.25, etamax = 1.25;
// double etamin=-0.1, etamax=1.1;
// double eta3min = -2, eta3max = 2;
double sum, totquad;
@ -80,7 +97,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;
int nframes = 0, lastframe = -1, iframe, nphFrame;
//double d_x, d_y, res = 5, xx, yy;
int nph = 0, totph = 0;
//badph = 0,
@ -98,7 +115,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);
@ -107,8 +124,8 @@ int main(int argc, char *argv[]) {
noInterpolation *interp = new noInterpolation(NC, NR, nsubpix);
#endif
#ifndef FF
int quad;
#ifndef FF
#ifndef NOINTERPOLATION
char fname[10000];
int ok;
@ -142,19 +159,26 @@ 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;
while (cl.read(f)) {
//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)) {
totph++;
if (lastframe != cl.iframe) {
lastframe = cl.iframe;
@ -165,18 +189,28 @@ int main(int argc, char *argv[]) {
nframes++;
}
// quad=interp->calcQuad(cl.get_cluster(), sum, totquad, sDum);
#ifndef FF
// #ifndef FF
// quad = interp->calcEta(cl.get_cluster(), etax, etay, sum,
// totquad, sDum);
// #endif
// #ifdef FF
quad = interp->calcEta(cl.get_cluster(), etax, etay, sum,
totquad, sDum);
#endif
#ifdef FF
interp->calcEta(cl.get_cluster(), etax, etay, sum,
totquad, sDum);
#endif
if (sum > cmin && totquad / sum > 0.8 && totquad / sum < 1.2 &&
sum < cmax) {
nph++;
/* cl.print();
cout << "(" << etax <<","<< etay <<")"<< quad<< endl;
*/
//#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>200 && sum<580) {
// interp->getInterpolatedPosition(cl.x,cl.y,
// totquad,quad,cl.get_cluster(),int_x, int_y);
@ -227,9 +261,12 @@ 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 "moench03T1ReceiverDataNew.h"
#include "moench03v2Data.h"
#endif
#endif
@ -41,34 +41,147 @@ using namespace std;
int main(int argc, char *argv[]) {
if (argc < 4) {
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 {
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 1;
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";
}
}
int fifosize = 1000;
int nthreads = 10;
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 csize = 3;
int nsigma = 5;
int nped = 10000;
int nped = 1000;
int cf = 0;
int numberOfPackets=40;
int numberOfPackets=nrows/8;
#ifdef RECT
cout << "Should be rectangular but now it will crash! No data structure defined!" << endl;
#endif
#ifndef MOENCH04
moench03T1ReceiverDataNew *decoder = new moench03T1ReceiverDataNew();
moench03v2Data *decoder = new moench03v2Data(100);
cout << "MOENCH03!" << endl;
#endif
@ -86,62 +199,10 @@ int main(int argc, char *argv[]) {
#endif
//Read detector size from decoder
int nx , ny;
decoder->getDetectorSize(nx, ny);
//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;
}
//Read detector size from decoder
char ffname[10000];
char fname[10000];
@ -151,17 +212,6 @@ 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;
@ -182,26 +232,26 @@ 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))
if (filter->readGainMap(gainfname.c_str()))
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;
@ -211,21 +261,33 @@ int main(int argc, char *argv[]) {
// multiThreadedAnalogDetector(filter,nthreads,fifosize);
multiThreadedCountingDetector *mt =
new multiThreadedCountingDetector(filter, nthreads, fifosize);
#ifndef ANALOG
mt->setDetectorMode(ePhotonCounting);
cout << "Counting!" << endl;
if (thr > 0) {
if (args["detectorMode"]=="counting") {
mt->setDetectorMode(ePhotonCounting);
if (thr > 0) {
cf = 0;
}
} else {
mt->setDetectorMode(eAnalog);
cf = 0;
}
#endif
//{
#ifdef ANALOG
mt->setDetectorMode(eAnalog);
cout << "Analog!" << endl;
cf = 0;
// thr1=thr;
#endif
// }
// #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
// // }
mt->StartThreads();
mt->popFree(buff);
@ -236,18 +298,17 @@ 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';
}
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 << "PEDESTAL " << endl;
if (pedfile.find(".tif") == std::string::npos) {
sprintf(fname, "%s", pedfile.c_str());
cout << fname << endl;
std::time(&end_time);
//cout << "aaa" << std::ctime(&end_time) << endl;
@ -257,63 +318,97 @@ int main(int argc, char *argv[]) {
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;
} else
cout << ifr << " " << ff << " " << np << endl;
if (ifr % 100 == 0)
cout << ifr << " " << ff << " " << np << endl;
// break;
} else {
cout << ifr << " " << ff << " " << np << endl;
break;
}
ff = -1;
}
filebin.close();
while (mt->isBusy()) {
;
;
}
sprintf(imgfname, "%s/%s_ped.tiff", outdir,froot);
sprintf(imgfname, "%s/%s_ped.tiff", outdir.c_str(),froot);
mt->writePedestal(imgfname);
sprintf(imgfname, "%s/%s_var.tiff", outdir,froot);
sprintf(imgfname, "%s/%s_var.tiff", outdir.c_str(),froot);
mt->writePedestalRMS(imgfname);
} else
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++) {
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
}
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);
// 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);
cout << fname << " ";
cout << imgfname << endl;
std::time(&end_time);
@ -323,7 +418,7 @@ int main(int argc, char *argv[]) {
// //open file
ifile = 0;
if (filebin.is_open()) {
if (thr <= 0 && cf != 0) { // cluster finder
if (cf != 0) { // cluster finder
if (of == NULL) {
of = fopen(cfname, "w");
if (of) {
@ -341,7 +436,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
@ -350,21 +445,26 @@ int main(int argc, char *argv[]) {
ifr++;
if (ifr % 100 == 0)
cout << ifr << " " << ff << endl;
cout << ifr << " " << ff << " " << np << endl;
//break;
if (nframes > 0) {
if (ifr % nframes == 0) {
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);
sprintf(imgfname, "%s/%s_f%05d.tiff",outdir.c_str(),ffname,ifile);
while (mt->isBusy())
;
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;
@ -374,13 +474,17 @@ int main(int argc, char *argv[]) {
}
if (nframes >= 0) {
if (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);
// sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat, ifile);
//sprintf(imgfname, (const char*)ffname, irun);
} else {
sprintf(ffname, "%s/%s.tiff", outdir, fformat);
sprintf(imgfname, (const char*)ffname, irun);
sprintf(imgfname, "%s/%s.tiff",outdir.c_str(),ffname);
// sprintf(ffname, "%s/%s.tiff", outdir, fformat);
// sprintf(imgfname, (const char*)ffname, irun);
}
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
while (mt->isBusy())
;
mt->writeImage(imgfname, thr1);
mt->clearImage();
if (of) {
@ -395,11 +499,16 @@ 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);
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
mt->writeImage(imgfname, thr1);
//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();
}
return 0;
}

View File

@ -13,7 +13,8 @@
#include "sls/sls_detector_defs.h"
#ifndef MOENCH04
//#ifndef RECT
#include "moench03T1ZmqDataNew.h"
#include "moench03v2Data.h"
//#include "moench03T1ZmqDataNew.h"
//#endif
//#ifdef RECT
//#include "moench03T1ZmqDataNewRect.h"
@ -31,6 +32,7 @@
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <rapidjson/document.h> //json header in zmq stream
@ -64,35 +66,47 @@ int main(int argc, char *argv[]) {
* number]
*
*/
FILE *of = NULL;
int fifosize = 5000;
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;
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;
// 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;
}
string etafname;// = NULL;
string gainfname;// = NULL;
// receive parameters
bool send = false;
char *socketip = argv[1];
uint32_t portnum = atoi(argv[2]);
// send parameters if any
char *socketip2 = 0;
string socketip2;// = 0;
uint32_t portnum2 = 0;
string socketip;// = 0;
uint32_t portnum = 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;
@ -102,48 +116,85 @@ int main(int argc, char *argv[]) {
// time_t begin,end,finished;
int rms = 0;
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]);
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;
}
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;
}
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];
}
char *gainfname = NULL;
if (argc > 7) {
gainfname = argv[7];
cout << "Gain map file name is: " << gainfname << endl;
}
char *etafname = NULL;
if (argc > 8) {
etafname = argv[8];
cout << "Eta file name is: " << etafname << 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;
}
// slsDetectorData *det=new moench03T1ZmqDataNew();
#ifndef MOENCH04
cout << "This is a Moench03" << endl;
moench03T1ZmqDataNew *det = new moench03T1ZmqDataNew();
cout << "This is a Moench03 v2" << endl;
//moench03T1ZmqDataNew *det = new moench03T1ZmqDataNew();
moench03v2Data *det = new moench03v2Data();
cout << "MOENCH03!" << endl;
#endif
#ifdef MOENCH04
cout << "This is a Moench04" << endl;
@ -177,8 +228,8 @@ int main(int argc, char *argv[]) {
double *gmap = NULL;
uint32_t nnnx, nnny;
if (gainfname) {
gm = ReadFromTiff(gainfname, nnny, nnnx);
//if (gainfname) {
gm = ReadFromTiff(gainfname.c_str(), nnny, nnnx);
if (gm && nnnx == (uint)npx && nnny == (uint)npy) {
gmap = new double[npx * npy];
for (int i = 0; i < npx * npy; i++) {
@ -187,7 +238,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);
@ -205,8 +256,8 @@ int main(int argc, char *argv[]) {
eta2InterpolationPosXY *interp = new eta2InterpolationPosXY(
npx, npy, nSubPixelsX, nSubPixelsY, etabins, etabinsy, etamin, etamax);
if (etafname)
interp->readFlatField(etafname);
//if (etafname)
interp->readFlatField(etafname.c_str());
interpolatingDetector *filter = new interpolatingDetector(
det, interp, nSigma, 1, cm, 1000, 10, -1, -1, gainmap, gs);
@ -226,13 +277,13 @@ int main(int argc, char *argv[]) {
try {
#endif
zmqsocket = new sls::ZmqSocket(socketip, portnum);
zmqsocket = new sls::ZmqSocket(socketip.c_str(), portnum);
#ifdef NEWZMQ
} catch (...) {
cprintf(RED,
"Error: Could not create Zmq socket on port %d with ip %s\n",
portnum, socketip);
portnum, socketip.c_str());
delete zmqsocket;
return EXIT_FAILURE;
}
@ -242,7 +293,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);
portnum, socketip.c_str());
delete zmqsocket;
return EXIT_FAILURE;
}
@ -263,14 +314,14 @@ int main(int argc, char *argv[]) {
// receive socket
try {
#endif
zmqsocket2 = new sls::ZmqSocket(portnum2, socketip2);
zmqsocket2 = new sls::ZmqSocket(portnum2, socketip2.c_str());
#ifdef NEWZMQ
} catch (...) {
cprintf(RED,
"Error: Could not create Zmq socket server on port %d and "
"ip %s\n",
portnum2, socketip2);
portnum2, socketip2.c_str());
// delete zmqsocket2;
// zmqsocket2=NULL;
// delete zmqsocket;
@ -284,7 +335,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);
portnum2, socketip2.c_str());
// delete zmqsocket2;
// delete zmqsocket;
// return EXIT_FAILURE;
@ -722,6 +773,25 @@ 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;
@ -821,7 +891,7 @@ int main(int argc, char *argv[]) {
// cout << acqIndex << " " << frameIndex << " " << subFrameIndex << "
// "<< detSpec1 << " " << timestamp << " " << packetNumber << endl;
// cprintf(GREEN, "frame\n");
if (packetNumber >= 40) {
if (packetNumber <= 50) {
//*((int*)buff)=frameIndex;
if (insubframe == 0)
f0 = frameIndex;

View File

@ -481,7 +481,6 @@ void setupDetector() {
return;
}
setReadoutSpeed(DEFAULT_SPEED);
cleanFifos();
resetCore();
@ -495,6 +494,7 @@ void setupDetector() {
initReadoutConfiguration();
// Initialization of acquistion parameters
setReadoutSpeed(DEFAULT_SPEED);
setSettings(DEFAULT_SETTINGS);
setNumFrames(DEFAULT_NUM_FRAMES);
setNumTriggers(DEFAULT_NUM_CYCLES);
@ -699,14 +699,12 @@ 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) {
@ -716,8 +714,7 @@ int setExpTime(int64_t val) {
}
int64_t getExpTime() {
return (get64BitReg(SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) +
ACQ_TIME_MIN_CLOCK) /
return get64BitReg(SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) /
(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 0x230710 // 2.0 pcb (version = 011)
#define REQRD_FRMWRE_VRSN 0x231026 // 2.0 pcb (version = 011)
#define NUM_HARDWARE_VERSIONS (2)
#define HARDWARE_VERSION_NUMBERS \
@ -58,11 +58,10 @@
/* 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 (240)
#define MAX_PHASE_SHIFTS (200)
#define BIT16_MASK (0xFFFF)
#define ADC_DECMT_QUARTER_SPEED (0x3)
@ -71,7 +70,7 @@
#define ADC_PHASE_DEG_QUARTER_SPEED (0)
#define ADC_PHASE_DEG_HALF_SPEED (0)
#define ADC_PHASE_DEG_FULL_SPEED (300)
#define ADC_PHASE_DEG_FULL_SPEED (150)
#define ADC_OFST_QUARTER_SPEED (0x12)
#define ADC_OFST_HALF_SPEED (0x12)
@ -134,7 +133,7 @@ enum DACINDEX {
680, /* MO_VB_SDA */ \
1428, /* MO_VCASC_SFP */ \
1200, /* MO_VOUT_CM */ \
800, /* MO_VIPRE_CDS */ \
1280, /* MO_VIPRE_CDS */ \
900 /* MO_IBIAS_SFP */ \
};

View File

@ -479,6 +479,11 @@ void setupDetector() {
READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ);
ALTERA_PLL_C10_ResetPLL(READOUT_PLL);
ALTERA_PLL_C10_ResetPLL(SYSTEM_PLL);
// change startup clock divider in software
// because firmware only sets max clock divider
setClockDividerWithTimeUpdateOption(READOUT_C0, DEFAULT_READOUT_C0_STARTUP,
0);
// hv
DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME);
// dac
@ -2331,6 +2336,7 @@ int setClockDividerWithTimeUpdateOption(enum CLKINDEX ind, int val,
return FAIL;
}
if (val < 2 || val > getMaxClockDivider()) {
LOG(logERROR, ("Invalid clock divider %d\n", val));
return FAIL;
}
char *clock_names[] = {CLK_NAMES};

View File

@ -64,6 +64,8 @@
#define DEFAULT_SYSTEM_C2 (5) //(200000000) // smp_clk, 200 MHz const
#define DEFAULT_TRIMMING_RUN_CLKDIV (40) // (25000000) // 25 MHz
#define DEFAULT_READOUT_C0_STARTUP (20) //(50000000) // rdo_clk, 50 MHz
#define DEFAULT_ASIC_LATCHING_NUM_PULSES (10)
#define DEFAULT_MSTR_OTPT_P1_NUM_PULSES (20)
#define DEFAULT_ADIF_PIPELINE_VAL (8)

View File

@ -2533,7 +2533,7 @@ int set_exptime(int file_des) {
if (gateIndex != -1) {
ret = FAIL;
sprintf(mess,
"Could not get exposure time. Gate index not implemented "
"Could not set exposure time. Gate index not implemented "
"for this detector\n");
LOG(logERROR, (mess));
} else {

View File

@ -742,9 +742,8 @@ void DetectorImpl::readFrameFromReceiver() {
}
}
LOG(logDEBUG) << "Call Back Info:"
<< "\n\t nDetPixelsX: " << nDetPixelsX
<< "\n\t nDetPixelsY: " << nDetPixelsY
LOG(logDEBUG) << "Call Back Info:" << "\n\t nDetPixelsX: "
<< nDetPixelsX << "\n\t nDetPixelsY: " << nDetPixelsY
<< "\n\t databytes: " << multisize
<< "\n\t dynamicRange: " << dynamicRange;
@ -762,8 +761,8 @@ void DetectorImpl::readFrameFromReceiver() {
callbackImage = multigappixels;
imagesize = n;
}
LOG(logDEBUG) << "Image Info:"
<< "\n\tnDetActualPixelsX: " << nDetActualPixelsX
LOG(logDEBUG) << "Image Info:" << "\n\tnDetActualPixelsX: "
<< nDetActualPixelsX
<< "\n\tnDetActualPixelsY: " << nDetActualPixelsY
<< "\n\timagesize: " << imagesize
<< "\n\tdynamicRange: " << dynamicRange;
@ -798,8 +797,7 @@ void DetectorImpl::readFrameFromReceiver() {
int DetectorImpl::insertGapPixels(char *image, char *&gpImage, bool quadEnable,
int dr, int &nPixelsx, int &nPixelsy) {
LOG(logDEBUG) << "Insert Gap pixels:"
<< "\n\t nPixelsx: " << nPixelsx
LOG(logDEBUG) << "Insert Gap pixels:" << "\n\t nPixelsx: " << nPixelsx
<< "\n\t nPixelsy: " << nPixelsy
<< "\n\t quadEnable: " << quadEnable << "\n\t dr: " << dr;
@ -884,12 +882,10 @@ int DetectorImpl::insertGapPixels(char *image, char *&gpImage, bool quadEnable,
<< "nMod1Pixelsy: " << nMod1Pixelsy << "\n\t"
<< "nMod1GapPixelsx: " << nMod1GapPixelsx << "\n\t"
<< "nMod1GapPixelsy: " << nMod1GapPixelsy << "\n\t"
<< "nChipy: " << nChipy << "\n\t"
<< "nChipx: " << nChipx << "\n\t"
<< "nModx: " << nModx << "\n\t"
<< "nMody: " << nMody << "\n\t"
<< "nTotx: " << nTotx << "\n\t"
<< "nToty: " << nToty << "\n\t"
<< "nChipy: " << nChipy << "\n\t" << "nChipx: " << nChipx
<< "\n\t" << "nModx: " << nModx << "\n\t"
<< "nMody: " << nMody << "\n\t" << "nTotx: " << nTotx
<< "\n\t" << "nToty: " << nToty << "\n\t"
<< "bytesPerPixel: " << bytesPerPixel << "\n\t"
<< "imagesize: " << imagesize << "\n\t"
<< "nChipBytesx: " << nChipBytesx << "\n\t"
@ -1321,6 +1317,11 @@ void DetectorImpl::startAcquisition(const bool blocking, Positions pos) {
// ensure all status normal (slaves not blocking)
// to catch those slaves that are still 'waiting'
auto status = Parallel(&Module::getRunStatus, pos);
// if any slave still waiting, wait up to 1s
for (int i = 0; i != 20 && status.any(WAITING); ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
status = Parallel(&Module::getRunStatus, pos);
}
if (!status.contains_only(IDLE, STOPPED, RUN_FINISHED)) {
throw RuntimeError("Acquisition not successful. "
"Unexpected detector status");
@ -1977,7 +1978,7 @@ void DetectorImpl::setBadChannels(const std::vector<int> list, Positions pos) {
// update to multi values if multi modules
if (isAllPositions(pos)) {
std::vector<std::vector<int>> badchannels;
std::vector<std::vector<int>> badchannels(modules.size());
int nchan = modules[0]->getNumberOfChannels().x;
if (shm()->detType == MYTHEN3) {
// assuming single counter
@ -1996,16 +1997,9 @@ void DetectorImpl::setBadChannels(const std::vector<int> list, Positions pos) {
std::to_string(badchannel) +
" out of bounds.");
}
if (badchannels.size() != imod + 1) {
badchannels.push_back(std::vector<int>{});
}
badchannels[imod].push_back(ch);
}
for (size_t imod = 0; imod != modules.size(); ++imod) {
// add empty vector if no bad channels in this module
if (badchannels.size() != imod + 1) {
badchannels.push_back(std::vector<int>{});
}
Parallel(&Module::setBadChannels, {static_cast<int>(imod)},
badchannels[imod]);
}

View File

@ -3332,7 +3332,13 @@ void Module::initializeModuleStructure(detectorType type) {
shm()->numberOfModule.y = 0;
shm()->controlPort = DEFAULT_TCP_CNTRL_PORTNO;
shm()->stopPort = DEFAULT_TCP_STOP_PORTNO;
strcpy_safe(shm()->settingsDir, getenv("HOME"));
char *home_directory = getenv("HOME");
if (home_directory != nullptr)
strcpy_safe(shm()->settingsDir, home_directory);
else {
strcpy_safe(shm()->settingsDir, "");
LOG(logWARNING) << "HOME directory not set";
}
strcpy_safe(shm()->rxHostname, "none");
shm()->rxTCPPort = DEFAULT_TCP_RX_PORTNO + moduleIndex;
shm()->useReceiverFlag = false;

View File

@ -215,12 +215,42 @@ std::string CreateVirtualHDF5File(
// property list
H5::DSetCreatPropList plist;
int fill_value = -1;
plist.setFillValue(dataType, &fill_value);
uint8_t u8 = -1;
uint16_t u16 = -1;
uint32_t u32 = -1;
uint64_t u64 = -1;
void* fill_value;
if (dataType == H5::PredType::STD_U8LE) {
fill_value = &u8;
} else if (dataType == H5::PredType::STD_U16LE) {
fill_value = &u16;
} else if (dataType == H5::PredType::STD_U32LE) {
fill_value = &u32;
} else if (dataType == H5::PredType::STD_U64LE) {
fill_value = &u64;
} else {
throw RuntimeError("Unsupported data type for virtual HDF5 file");
}
plist.setFillValue(dataType, fill_value);
//uint64_t fill_value = -1;
//plist.setFillValue(dataType, &fill_value);
std::vector<H5::DSetCreatPropList> plistPara(paraSize);
// ignoring last fill (string)
for (unsigned int i = 0; i != plistPara.size() - 1; ++i) {
plistPara[i].setFillValue(parameterDataTypes[i], &fill_value);
if (parameterDataTypes[i] == H5::PredType::STD_U8LE) {
fill_value = &u8;
} else if (parameterDataTypes[i] == H5::PredType::STD_U16LE) {
fill_value = &u16;
} else if (parameterDataTypes[i] == H5::PredType::STD_U32LE) {
fill_value = &u32;
} else if (parameterDataTypes[i] == H5::PredType::STD_U64LE) {
fill_value = &u64;
} else {
throw RuntimeError("Unsupported data type for virtual HDF5 file");
}
plistPara[i].setFillValue(parameterDataTypes[i], fill_value);
}
// hyperslab (files)

View File

@ -24,8 +24,9 @@
#include <rapidjson/document.h> //json header in zmq stream
#pragma GCC diagnostic pop
#include <zmq.h>
//#include <zmq.h>
class zmq_msg_t;
namespace sls {
#define MAX_STR_LENGTH 1000

View File

@ -20,6 +20,7 @@ Still this is better than strcpy and a buffer overflow...
*/
template <size_t array_size>
void strcpy_safe(char (&destination)[array_size], const char *source) {
assert(source != nullptr);
assert(array_size > strlen(source));
strncpy(destination, source, array_size - 1);
destination[array_size - 1] = '\0';

View File

@ -1,13 +1,13 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
/** API versions */
#define RELEASE "8.0.0"
#define APILIB "8.0.0 0x231108"
#define RELEASE "8.0.1"
#define APIRECEIVER "8.0.0 0x231108"
#define APICTB "8.0.0 0x231109"
#define APIGOTTHARD "8.0.0 0x231109"
#define APIGOTTHARD2 "8.0.0 0x231109"
#define APIJUNGFRAU "8.0.0 0x231109"
#define APIMYTHEN3 "8.0.0 0x231109"
#define APIMOENCH "8.0.0 0x231109"
#define APIEIGER "8.0.0 0x231109"
#define APILIB "8.0.1 0x240112"
#define APIMOENCH "8.0.2 0x240703"
#define APIMYTHEN3 "8.0.2 0x240715"

View File

@ -10,7 +10,7 @@
#include <string.h>
#include <thread>
#include <vector>
#include <zmq.h>
namespace sls {
using namespace rapidjson;