M3settings (#228)

* added temp m3 settings files

* renames settings noise to trim

* get threshold for M3

* some changes to compile on RH7 and in the server to load the default chip status register at startup

* Updated mythen3DeectorServer_developer executable with correct initialization at startup

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
Co-authored-by: Anna Bergamaschi <anna.bergamaschi@psi.ch>
This commit is contained in:
Dhanya Thattil 2021-01-14 12:34:13 +01:00 committed by GitHub
parent a62e068a9a
commit f9f50f1d84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 1715 additions and 8446 deletions

View File

@ -8,6 +8,7 @@ This document describes the differences between 5.1.0 and 5.x.x releases.
CONTENTS CONTENTS
-------- --------
1. Topics Concerning 1. Topics Concerning
2. New Features
2. Resolved Issues 2. Resolved Issues
3. Known Issues 3. Known Issues
4. Firmware Requirements 4. Firmware Requirements
@ -21,9 +22,19 @@ This document describes the differences between 5.1.0 and 5.x.x releases.
- potentital memory leak in receiver - potentital memory leak in receiver
- scanParameters in Python - scanParameters in Python
- cmk.sh refactored - cmk.sh refactored
- m3 settings and threshold
2. Resolved Issues 2. New Features
===============
Client
------
1. Aded settings and threshold features for Mythen3.
3. Resolved Issues
================== ==================
@ -33,32 +44,32 @@ This document describes the differences between 5.1.0 and 5.x.x releases.
1. Current code only calls Implementation::setDetectorType from constructor, 1. Current code only calls Implementation::setDetectorType from constructor,
but potential memory leak if called out of constructor context. Fixed. but potential memory leak if called out of constructor context. Fixed.
Cleint Client
------ ------
1. Fixed missing scanParameters class in Python 1. Fixed missing scanParameters class in Python
2. cmk.sh refactored to have better option handling. 2. cmk.sh refactored to have better option handling
3. Firmware Requirements 4. Firmware Requirements
======================== ========================
No updates from 5.0.0 No updates from 5.0.0
4. Known Issues 5. Known Issues
=============== ===============
No updates from 5.0.0 No updates from 5.0.0
5. Download, Documentation & Support 6. Download, Documentation & Support
==================================== ====================================
Download Download

@ -1 +1 @@
Subproject commit f1abf5d9159b805674197f6bc443592e631c9130 Subproject commit 4f72ef846fe8453596230ac285eeaa0ce3278bb4

View File

@ -1696,6 +1696,8 @@ class Detector(CppDetectorApi):
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. :setter: It loads trim files from settingspath.
""" """
if self.type == detectorType.MYTHEN3:
return self.getAllThresholdEnergy()
return self.getThresholdEnergy() return self.getThresholdEnergy()
@threshold.setter @threshold.setter

View File

@ -102,6 +102,34 @@ void init_det(py::module &m) {
(void (Detector::*)(defs::detectorSettings, sls::Positions)) & (void (Detector::*)(defs::detectorSettings, sls::Positions)) &
Detector::setSettings, Detector::setSettings,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("getThresholdEnergy",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getThresholdEnergy,
py::arg() = Positions{})
.def("getAllThresholdEnergy",
(Result<std::array<int, 3>>(Detector::*)(sls::Positions) const) &
Detector::getAllThresholdEnergy,
py::arg() = Positions{})
.def("setThresholdEnergy",
(void (Detector::*)(int, defs::detectorSettings, bool,
sls::Positions)) &
Detector::setThresholdEnergy,
py::arg(), py::arg() = defs::STANDARD, py::arg() = true,
py::arg() = Positions{})
.def("setThresholdEnergy",
(void (Detector::*)(std::array<int, 3>, defs::detectorSettings,
bool, sls::Positions)) &
Detector::setThresholdEnergy,
py::arg(), py::arg() = defs::STANDARD, py::arg() = true,
py::arg() = Positions{})
.def("getSettingsPath",
(Result<std::string>(Detector::*)(sls::Positions) const) &
Detector::getSettingsPath,
py::arg() = Positions{})
.def("setSettingsPath",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::setSettingsPath,
py::arg(), py::arg() = Positions{})
.def("loadTrimbits", .def("loadTrimbits",
(void (Detector::*)(const std::string &, sls::Positions)) & (void (Detector::*)(const std::string &, sls::Positions)) &
Detector::loadTrimbits, Detector::loadTrimbits,
@ -114,6 +142,14 @@ void init_det(py::module &m) {
(void (Detector::*)(int, sls::Positions)) & (void (Detector::*)(int, sls::Positions)) &
Detector::setAllTrimbits, Detector::setAllTrimbits,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("getTrimEnergies",
(Result<std::vector<int>>(Detector::*)(sls::Positions) const) &
Detector::getTrimEnergies,
py::arg() = Positions{})
.def("setTrimEnergies",
(void (Detector::*)(std::vector<int>, sls::Positions)) &
Detector::setTrimEnergies,
py::arg(), py::arg() = Positions{})
.def("getGapPixelsinCallback", .def("getGapPixelsinCallback",
(bool (Detector::*)() const) & Detector::getGapPixelsinCallback) (bool (Detector::*)() const) & Detector::getGapPixelsinCallback)
.def("setGapPixelsinCallback", .def("setGapPixelsinCallback",
@ -783,24 +819,6 @@ void init_det(py::module &m) {
(void (Detector::*)(sls::ns, sls::Positions)) & (void (Detector::*)(sls::ns, sls::Positions)) &
Detector::setSubDeadTime, Detector::setSubDeadTime,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("getThresholdEnergy",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getThresholdEnergy,
py::arg() = Positions{})
.def("setThresholdEnergy",
(void (Detector::*)(int, defs::detectorSettings, bool,
sls::Positions)) &
Detector::setThresholdEnergy,
py::arg(), py::arg() = defs::STANDARD, py::arg() = true,
py::arg() = Positions{})
.def("getSettingsPath",
(Result<std::string>(Detector::*)(sls::Positions) const) &
Detector::getSettingsPath,
py::arg() = Positions{})
.def("setSettingsPath",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::setSettingsPath,
py::arg(), py::arg() = Positions{})
.def("getOverFlowMode", .def("getOverFlowMode",
(Result<bool>(Detector::*)(sls::Positions) const) & (Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getOverFlowMode, Detector::getOverFlowMode,
@ -816,14 +834,6 @@ void init_det(py::module &m) {
.def("setBottom", .def("setBottom",
(void (Detector::*)(bool, sls::Positions)) & Detector::setBottom, (void (Detector::*)(bool, sls::Positions)) & Detector::setBottom,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("getTrimEnergies",
(Result<std::vector<int>>(Detector::*)(sls::Positions) const) &
Detector::getTrimEnergies,
py::arg() = Positions{})
.def("setTrimEnergies",
(void (Detector::*)(std::vector<int>, sls::Positions)) &
Detector::setTrimEnergies,
py::arg(), py::arg() = Positions{})
.def("getRateCorrection", .def("getRateCorrection",
(Result<sls::ns>(Detector::*)(sls::Positions) const) & (Result<sls::ns>(Detector::*)(sls::Positions) const) &
Detector::getRateCorrection, Detector::getRateCorrection,

View File

@ -1 +0,0 @@
800 10

View File

@ -1 +0,0 @@
829 9.3

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
800 10

View File

@ -1 +0,0 @@
804 15.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
800 10

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
817 11.6

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -32,17 +32,23 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="2"> <item row="1" column="4">
<widget class="QSpinBox" name="spinThreshold"> <widget class="QSpinBox" name="spinThreshold3">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>140</width>
<height>25</height> <height>25</height>
</size> </size>
</property> </property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking"> <property name="keyboardTracking">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -63,10 +69,69 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="2">
<spacer name="horizontalSpacer"> <widget class="QSpinBox" name="spinThreshold">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblDynamicRange">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Dynamic Range:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Fixed</enum> <enum>QSizePolicy::Fixed</enum>
@ -74,7 +139,7 @@
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>20</height> <height>190</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -86,10 +151,16 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>140</width>
<height>25</height> <height>25</height>
</size> </size>
</property> </property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<item> <item>
<property name="text"> <property name="text">
<string>1.67772e+07</string> <string>1.67772e+07</string>
@ -112,21 +183,102 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="0" column="3"> <item row="1" column="6">
<spacer name="horizontalSpacer_2"> <widget class="QPushButton" name="btnSetThreshold">
<property name="orientation"> <property name="enabled">
<enum>Qt::Horizontal</enum> <bool>true</bool>
</property> </property>
<property name="sizeType"> <property name="sizePolicy">
<enum>QSizePolicy::Expanding</enum> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="minimumSize">
<size> <size>
<width>20</width> <width>100</width>
<height>20</height> <height>30</height>
</size> </size>
</property> </property>
</spacer> <property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>Set</string>
</property>
<property name="icon">
<iconset resource="../include/icons.qrc">
<normaloff>:/icons/images/rightArrow.png</normaloff>:/icons/images/rightArrow.png</iconset>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblSettings">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Settings:</string>
</property>
</widget>
</item> </item>
<item row="0" column="2"> <item row="0" column="2">
<widget class="QComboBox" name="comboSettings"> <widget class="QComboBox" name="comboSettings">
@ -141,10 +293,16 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>140</width>
<height>25</height> <height>25</height>
</size> </size>
</property> </property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Settings of the detector. <string>Settings of the detector.
#settings#</string> #settings#</string>
@ -266,40 +424,10 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="0" column="1">
<widget class="QLabel" name="lblThreshold"> <spacer name="horizontalSpacer">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Threshold:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblDynamicRange">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Dynamic Range:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblSettings">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Settings:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Fixed</enum> <enum>QSizePolicy::Fixed</enum>
@ -307,7 +435,82 @@
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>190</height> <height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblThreshold">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Threshold:</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="spinThreshold2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="1" column="7">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -317,6 +520,9 @@
<tabstops> <tabstops>
<tabstop>comboSettings</tabstop> <tabstop>comboSettings</tabstop>
<tabstop>spinThreshold</tabstop> <tabstop>spinThreshold</tabstop>
<tabstop>spinThreshold2</tabstop>
<tabstop>spinThreshold3</tabstop>
<tabstop>btnSetThreshold</tabstop>
<tabstop>comboDynamicRange</tabstop> <tabstop>comboDynamicRange</tabstop>
</tabstops> </tabstops>
<resources> <resources>

View File

@ -14,6 +14,7 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject {
void SetSettings(int index); void SetSettings(int index);
void SetDynamicRange(int index); void SetDynamicRange(int index);
void SetThresholdEnergy(int index); void SetThresholdEnergy(int index);
void SetThresholdEnergies();
private: private:
void SetupWidgetWindow(); void SetupWidgetWindow();
@ -23,6 +24,7 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject {
void GetSettings(); void GetSettings();
void GetDynamicRange(); void GetDynamicRange();
void GetThresholdEnergy(); void GetThresholdEnergy();
void GetThresholdEnergies();
sls::Detector *det; sls::Detector *det;
enum { enum {

View File

@ -14,14 +14,24 @@ qTabSettings::~qTabSettings() {}
void qTabSettings::SetupWidgetWindow() { void qTabSettings::SetupWidgetWindow() {
spinThreshold2->hide();
spinThreshold3->hide();
btnSetThreshold->hide();
btnSetThreshold->setEnabled(false);
// enabling according to det type // enabling according to det type
slsDetectorDefs::detectorType detType = det->getDetectorType().squash(); slsDetectorDefs::detectorType detType = det->getDetectorType().squash();
if (detType == slsDetectorDefs::MYTHEN3) { if (detType == slsDetectorDefs::MYTHEN3) {
lblSettings->setEnabled(false);
comboSettings->setEnabled(false);
lblDynamicRange->setEnabled(true); lblDynamicRange->setEnabled(true);
comboDynamicRange->setEnabled(true); comboDynamicRange->setEnabled(true);
spinThreshold2->show();
spinThreshold3->show();
lblThreshold->setEnabled(true);
spinThreshold->setEnabled(true);
spinThreshold2->setEnabled(true);
spinThreshold3->setEnabled(true);
btnSetThreshold->setEnabled(true);
btnSetThreshold->show();
// disable dr // disable dr
QStandardItemModel *model = QStandardItemModel *model =
qobject_cast<QStandardItemModel *>(comboDynamicRange->model()); qobject_cast<QStandardItemModel *>(comboDynamicRange->model());
@ -34,7 +44,6 @@ void qTabSettings::SetupWidgetWindow() {
item = model->itemFromIndex(index); item = model->itemFromIndex(index);
item->setEnabled(false); item->setEnabled(false);
} }
} else if (detType == slsDetectorDefs::EIGER) { } else if (detType == slsDetectorDefs::EIGER) {
lblDynamicRange->setEnabled(true); lblDynamicRange->setEnabled(true);
comboDynamicRange->setEnabled(true); comboDynamicRange->setEnabled(true);
@ -48,6 +57,10 @@ void qTabSettings::SetupWidgetWindow() {
SetupDetectorSettings(); SetupDetectorSettings();
} }
spinThreshold->setValue(-1); spinThreshold->setValue(-1);
if (detType == slsDetectorDefs::MYTHEN3) {
spinThreshold2->setValue(-1);
spinThreshold3->setValue(-1);
}
Initialization(); Initialization();
// default for the disabled // default for the disabled
GetDynamicRange(); GetDynamicRange();
@ -104,6 +117,11 @@ void qTabSettings::SetupDetectorSettings() {
item[(int)G4_HIGHGAIN]->setEnabled(true); item[(int)G4_HIGHGAIN]->setEnabled(true);
item[(int)G4_LOWGAIN]->setEnabled(true); item[(int)G4_LOWGAIN]->setEnabled(true);
break; break;
case slsDetectorDefs::MYTHEN3:
item[(int)STANDARD]->setEnabled(true);
item[(int)FAST]->setEnabled(true);
item[(int)HIGHGAIN]->setEnabled(true);
break;
default: default:
LOG(logDEBUG) << "Unknown detector type. Exiting GUI."; LOG(logDEBUG) << "Unknown detector type. Exiting GUI.";
qDefs::Message(qDefs::CRITICAL, qDefs::Message(qDefs::CRITICAL,
@ -126,7 +144,13 @@ void qTabSettings::Initialization() {
SLOT(SetDynamicRange(int))); SLOT(SetDynamicRange(int)));
// Threshold // Threshold
if (spinThreshold->isEnabled()) // m3
if (btnSetThreshold->isEnabled()) {
connect(btnSetThreshold, SIGNAL(clicked()), this,
SLOT(SetThresholdEnergies()));
}
// eiger
else if (spinThreshold->isEnabled())
connect(spinThreshold, SIGNAL(valueChanged(int)), this, connect(spinThreshold, SIGNAL(valueChanged(int)), this,
SLOT(SetThresholdEnergy(int))); SLOT(SetThresholdEnergy(int)));
} }
@ -169,7 +193,7 @@ void qTabSettings::SetSettings(int index) {
CATCH_HANDLE("Could not set settings.", "qTabSettings::SetSettings", this, CATCH_HANDLE("Could not set settings.", "qTabSettings::SetSettings", this,
&qTabSettings::GetSettings) &qTabSettings::GetSettings)
// threshold // threshold
if (spinThreshold->isEnabled()) { if (det->getDetectorType().squash() == slsDetectorDefs::EIGER) {
SetThresholdEnergy(spinThreshold->value()); SetThresholdEnergy(spinThreshold->value());
} }
} }
@ -233,6 +257,23 @@ void qTabSettings::SetDynamicRange(int index) {
&qTabSettings::GetDynamicRange) &qTabSettings::GetDynamicRange)
} }
void qTabSettings::GetThresholdEnergies() {
LOG(logDEBUG) << "Getting theshold energies";
disconnect(btnSetThreshold, SIGNAL(clicked()), this,
SLOT(SetThresholdEnergies()));
try {
auto retval = det->getAllThresholdEnergy().tsquash(
"Inconsistent threhsold energies for all detectors.");
spinThreshold->setValue(retval[0]);
spinThreshold2->setValue(retval[1]);
spinThreshold3->setValue(retval[2]);
}
CATCH_DISPLAY("Could not get threshold energy.",
"qTabDataOutput::GetThresholdEnergies")
connect(btnSetThreshold, SIGNAL(clicked()), this,
SLOT(SetThresholdEnergies()));
}
void qTabSettings::GetThresholdEnergy() { void qTabSettings::GetThresholdEnergy() {
LOG(logDEBUG) << "Getting theshold energy"; LOG(logDEBUG) << "Getting theshold energy";
disconnect(spinThreshold, SIGNAL(valueChanged(int)), this, disconnect(spinThreshold, SIGNAL(valueChanged(int)), this,
@ -248,6 +289,23 @@ void qTabSettings::GetThresholdEnergy() {
SLOT(SetThresholdEnergy(int))); SLOT(SetThresholdEnergy(int)));
} }
void qTabSettings::SetThresholdEnergies() {
std::array<int, 3> eV = {spinThreshold->value(), spinThreshold2->value(),
spinThreshold3->value()};
slsDetectorDefs::detectorSettings sett =
static_cast<slsDetectorDefs::detectorSettings>(
comboSettings->currentIndex());
LOG(logINFO) << "Setting Threshold Energies to " << sls::ToString(eV)
<< " (eV)";
try {
det->setThresholdEnergy(eV, sett);
}
CATCH_DISPLAY("Could not get threshold energies.",
"qTabSettings::SetThresholdEnergies")
// set the right value anyway (due to tolerance)
GetThresholdEnergies();
}
void qTabSettings::SetThresholdEnergy(int index) { void qTabSettings::SetThresholdEnergy(int index) {
LOG(logINFO) << "Setting Threshold Energy to " << index << " eV"; LOG(logINFO) << "Setting Threshold Energy to " << index << " eV";
try { try {
@ -270,8 +328,14 @@ void qTabSettings::Refresh() {
GetDynamicRange(); GetDynamicRange();
} }
if (spinThreshold->isEnabled()) // m3
if (btnSetThreshold->isEnabled())
GetThresholdEnergies();
// eiger
else if (spinThreshold->isEnabled()) {
LOG(logINFOBLUE) << "calling it!";
GetThresholdEnergy(); GetThresholdEnergy();
}
LOG(logDEBUG) << "**Updated Settings Tab"; LOG(logDEBUG) << "**Updated Settings Tab";
} }

View File

@ -669,7 +669,9 @@ void allocateDetectorStructureMemory() {
(detectorModules)->reg = 0; (detectorModules)->reg = 0;
(detectorModules)->iodelay = 0; (detectorModules)->iodelay = 0;
(detectorModules)->tau = 0; (detectorModules)->tau = 0;
(detectorModules)->eV = 0; (detectorModules)->eV[0] = 0;
(detectorModules)->eV[1] = 0;
(detectorModules)->eV[2] = 0;
thisSettings = UNINITIALIZED; thisSettings = UNINITIALIZED;
// if trimval requested, should return -1 to acknowledge unknown // if trimval requested, should return -1 to acknowledge unknown
@ -1090,8 +1092,8 @@ int setModule(sls_detector_module myMod, char *mess) {
} }
// threshold // threshold
if (myMod.eV >= 0) if (myMod.eV[0] >= 0)
setThresholdEnergy(myMod.eV); setThresholdEnergy(myMod.eV[0]);
else { else {
// (loading a random trim file) (dont return fail) // (loading a random trim file) (dont return fail)
setSettings(UNDEFINED); setSettings(UNDEFINED);
@ -2554,8 +2556,8 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
destMod->iodelay = srcMod->iodelay; destMod->iodelay = srcMod->iodelay;
if (srcMod->tau >= 0) if (srcMod->tau >= 0)
destMod->tau = srcMod->tau; destMod->tau = srcMod->tau;
if (srcMod->eV >= 0) if (srcMod->eV[0] >= 0)
destMod->eV = srcMod->eV; destMod->eV[0] = srcMod->eV[0];
LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg)); LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg));
if (destMod->nchan != 0) { if (destMod->nchan != 0) {

View File

@ -19,6 +19,9 @@
#include <time.h> #include <time.h>
#endif #endif
/// NOT the right place to put it!
int setChipStatusRegister(int csr);
// Global variable from slsDetectorServer_funcs // Global variable from slsDetectorServer_funcs
extern int debugflag; extern int debugflag;
extern int updateFlag; extern int updateFlag;
@ -40,6 +43,7 @@ pthread_t pthread_virtual_tid;
int64_t virtual_currentFrameNumber = 2; int64_t virtual_currentFrameNumber = 2;
#endif #endif
enum detectorSettings thisSettings;
sls_detector_module *detectorModules = NULL; sls_detector_module *detectorModules = NULL;
int *detectorChans = NULL; int *detectorChans = NULL;
int *detectorDacs = NULL; int *detectorDacs = NULL;
@ -50,8 +54,10 @@ uint32_t clkDivider[NUM_CLOCKS] = {};
int highvoltage = 0; int highvoltage = 0;
int detPos[2] = {}; int detPos[2] = {};
int64_t exptimeReg[3] = {0, 0, 0}; int64_t exptimeReg[NCOUNTERS] = {0, 0, 0};
int64_t gateDelayReg[3] = {0, 0, 0}; int64_t gateDelayReg[NCOUNTERS] = {0, 0, 0};
int vthEnabledVals[NCOUNTERS] = {0, 0, 0};
int detID = 0;
int isInitCheckDone() { return initCheckDone; } int isInitCheckDone() { return initCheckDone; }
@ -264,12 +270,28 @@ u_int16_t getHardwareVersionNumber() {
MCB_SERIAL_NO_VRSN_OFST); MCB_SERIAL_NO_VRSN_OFST);
} }
u_int32_t getDetectorNumber() { void readDetectorNumber() {
#ifdef VIRTUAL #ifndef VIRTUAL
return 0; if (initError == FAIL) {
#endif return;
return bus_r(MCB_SERIAL_NO_REG);
} }
FILE *fd = fopen(ID_FILE, "r");
if (fd == NULL) {
sprintf(initErrorMessage, "No %s file found.\n", ID_FILE);
LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL;
return;
}
char output[255];
fgets(output, sizeof(output), fd);
sscanf(output, "%u", &detID);
if (isControlServer) {
LOG(logINFOBLUE, ("Detector ID: %u\n", detID));
}
#endif
}
u_int32_t getDetectorNumber() { return detID; }
u_int64_t getDetectorMAC() { u_int64_t getDetectorMAC() {
#ifdef VIRTUAL #ifdef VIRTUAL
@ -365,17 +387,19 @@ void allocateDetectorStructureMemory() {
(detectorModules)->reg = UNINITIALIZED; (detectorModules)->reg = UNINITIALIZED;
(detectorModules)->iodelay = 0; (detectorModules)->iodelay = 0;
(detectorModules)->tau = 0; (detectorModules)->tau = 0;
(detectorModules)->eV = 0; (detectorModules)->eV[0] = 0;
// thisSettings = UNINITIALIZED; (detectorModules)->eV[1] = 0;
(detectorModules)->eV[2] = 0;
thisSettings = UNINITIALIZED;
// initialize dacs // initialize dacs
for (int idac = 0; idac < (detectorModules)->ndac; ++idac) { for (int idac = 0; idac < (detectorModules)->ndac; ++idac) {
detectorDacs[idac] = 0; detectorDacs[idac] = 0;
} }
// if trimval requested, should return -1 to acknowledge unknown // trimbits start at 0 //TODO: restart server will not have 0 always
for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) { for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) {
*((detectorModules->chanregs) + ichan) = -1; *((detectorModules->chanregs) + ichan) = 0;
} }
} }
@ -439,7 +463,7 @@ void setupDetector() {
setTiming(DEFAULT_TIMING_MODE); setTiming(DEFAULT_TIMING_MODE);
setNumIntGates(DEFAULT_INTERNAL_GATES); setNumIntGates(DEFAULT_INTERNAL_GATES);
setNumGates(DEFAULT_EXTERNAL_GATES); setNumGates(DEFAULT_EXTERNAL_GATES);
for (int i = 0; i != 3; ++i) { for (int i = 0; i != NCOUNTERS; ++i) {
setExpTime(i, DEFAULT_GATE_WIDTH); setExpTime(i, DEFAULT_GATE_WIDTH);
setGateDelay(i, DEFAULT_GATE_DELAY); setGateDelay(i, DEFAULT_GATE_DELAY);
} }
@ -449,6 +473,11 @@ void setupDetector() {
#ifdef VIRTUAL #ifdef VIRTUAL
enableTenGigabitEthernet(0); enableTenGigabitEthernet(0);
#endif #endif
readDetectorNumber();
if (initError == FAIL) {
return;
}
setSettings(DEFAULT_SETTINGS);
// check module type attached if not in debug mode // check module type attached if not in debug mode
{ {
@ -484,8 +513,11 @@ void setupDetector() {
powerChip(1); powerChip(1);
if (initError != FAIL) { if (initError != FAIL) {
initError = loadDefaultPattern(DEFAULT_PATTERN_FILE, initErrorMessage); initError = setChipStatusRegister(CSR_default);
//loadDefaultPattern(DEFAULT_PATTERN_FILE, initErrorMessage);
//startStateMachine(); //this was missing in previous code! runs the default pattern
} }
setAllTrimbits(DEFAULT_TRIMBIT_VALUE);
} }
int setDefaultDacs() { int setDefaultDacs() {
@ -693,7 +725,7 @@ int getNumGates() { return bus_r(ASIC_EXP_EXT_GATE_NUMBER_REG); }
void updateGatePeriod() { void updateGatePeriod() {
uint64_t max = 0; uint64_t max = 0;
uint32_t countermask = getCounterMask(); uint32_t countermask = getCounterMask();
for (int i = 0; i != 3; ++i) { for (int i = 0; i != NCOUNTERS; ++i) {
// only if counter enabled // only if counter enabled
if (countermask & (1 << i)) { if (countermask & (1 << i)) {
uint64_t sum = getExpTime(i) + getGateDelay(i); uint64_t sum = getExpTime(i) + getGateDelay(i);
@ -880,6 +912,7 @@ void setCounterMask(uint32_t arg) {
if (arg == 0 || arg > MAX_COUNTER_MSK) { if (arg == 0 || arg > MAX_COUNTER_MSK) {
return; return;
} }
uint32_t oldmask = getCounterMask();
LOG(logINFO, ("Setting counter mask to 0x%x\n", arg)); LOG(logINFO, ("Setting counter mask to 0x%x\n", arg));
uint32_t addr = CONFIG_REG; uint32_t addr = CONFIG_REG;
bus_w(addr, bus_r(addr) & ~CONFIG_COUNTERS_ENA_MSK); bus_w(addr, bus_r(addr) & ~CONFIG_COUNTERS_ENA_MSK);
@ -889,12 +922,21 @@ void setCounterMask(uint32_t arg) {
updatePacketizing(); updatePacketizing();
LOG(logINFO, ("\tUpdating Exptime and Gate Delay\n")); LOG(logINFO, ("\tUpdating Exptime and Gate Delay\n"));
for (int i = 0; i < 3; ++i) { for (int i = 0; i < NCOUNTERS; ++i) {
uint64_t ns = exptimeReg[i] / (1E-9 * getFrequency(SYSTEM_C0)); uint64_t ns = exptimeReg[i] / (1E-9 * getFrequency(SYSTEM_C0));
setExpTime(i, ns); setExpTime(i, ns);
ns = gateDelayReg[i] / (1E-9 * getFrequency(SYSTEM_C0)); ns = gateDelayReg[i] / (1E-9 * getFrequency(SYSTEM_C0));
setGateDelay(i, ns); setGateDelay(i, ns);
} }
LOG(logINFO, ("\tUpdating Vth dacs\n"));
for (int i = 0; i < NCOUNTERS; ++i) {
// if change in enable
if ((arg & (1 << i)) ^ (oldmask & (1 << i))) {
// will disable if counter disabled
setDAC(VTH1, vthEnabledVals[i], 0);
}
}
} }
uint32_t getCounterMask() { uint32_t getCounterMask() {
@ -1014,24 +1056,28 @@ int setModule(sls_detector_module myMod, char *mess) {
LOG(logINFO, ("Setting module\n")); LOG(logINFO, ("Setting module\n"));
/* future implementation // settings
// settings (not yet implemented)
setSettings((enum detectorSettings)myMod.reg);
if (myMod.reg >= 0) { if (myMod.reg >= 0) {
setSettings((enum detectorSettings)myMod.reg);
if (getSettings() != (enum detectorSettings)myMod.reg) {
sprintf(
mess,
"Could not set module. Could not set settings to %d, read %d\n",
myMod.reg, (int)getSettings());
LOG(logERROR, (mess));
return FAIL;
}
detectorModules->reg = myMod.reg; detectorModules->reg = myMod.reg;
} }
// custom trimbit file
// threshold
if (myMod.eV >= 0)
setThresholdEnergy(myMod.eV);
else { else {
// (loading a random trim file) (dont return fail) // changed for setsettings (direct),
setSettings(UNDEFINED); // custom trimbit file (setmodule with myMod.reg as -1),
LOG(logERROR, // change of dac (direct)
("Settings has been changed to undefined (random trim for (int i = 0; i < NCOUNTERS; ++i) {
file)\n")); setThresholdEnergy(i, -1);
}
} }
*/
// dacs // dacs
for (int i = 0; i < NDAC; ++i) { for (int i = 0; i < NDAC; ++i) {
@ -1039,16 +1085,42 @@ int setModule(sls_detector_module myMod, char *mess) {
if (myMod.dacs[i] != -1) { if (myMod.dacs[i] != -1) {
setDAC((enum DACINDEX)i, myMod.dacs[i], 0); setDAC((enum DACINDEX)i, myMod.dacs[i], 0);
if (myMod.dacs[i] != detectorDacs[i]) { if (myMod.dacs[i] != detectorDacs[i]) {
sprintf(mess, "Could not set module. Could not set dac %d\n", // dont complain if that counter was disabled
i); if ((i == M_VTH1 || i == M_VTH2 || i == M_VTH3) &&
(detectorDacs[i] == DEFAULT_COUNTER_DISABLED_VTH_VAL)) {
continue;
}
sprintf(mess,
"Could not set module. Could not set dac %d, wrote %d, "
"read %d\n",
i, myMod.dacs[i], detectorDacs[i]);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
// setSettings(UNDEFINED);
// LOG(logERROR, ("Settings has been changed to undefined\n"));
return FAIL; return FAIL;
} }
} }
} }
// if settings given and cannot be validated (after setting dacs), return
// error
if (myMod.reg >= 0) {
if (getSettings() != (enum detectorSettings)myMod.reg) {
sprintf(
mess,
"Could not set module. The dacs in file do not correspond to "
"settings %d\n",
myMod.reg);
LOG(logERROR, (mess));
return FAIL;
}
}
// threshold
for (int i = 0; i < NCOUNTERS; ++i) {
if (myMod.eV[i] >= 0) {
setThresholdEnergy(i, myMod.eV[i]);
}
}
// trimbits // trimbits
if (myMod.nchan == 0) { if (myMod.nchan == 0) {
LOG(logINFO, ("Setting module without trimbits\n")); LOG(logINFO, ("Setting module without trimbits\n"));
@ -1057,9 +1129,6 @@ int setModule(sls_detector_module myMod, char *mess) {
if (setTrimbits(myMod.chanregs) == FAIL) { if (setTrimbits(myMod.chanregs) == FAIL) {
sprintf(mess, "Could not set module. Could not set trimbits\n"); sprintf(mess, "Could not set module. Could not set trimbits\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
// setSettings(UNDEFINED);
// LOG(logERROR, ("Settings has been changed to undefined (random "
// "trim file)\n"));
return FAIL; return FAIL;
} }
} }
@ -1239,6 +1308,7 @@ int setTrimbits(int *trimbits) {
} }
int setAllTrimbits(int val) { int setAllTrimbits(int val) {
LOG(logINFO, ("Setting all trimbits to %d\n", val));
int *trimbits = malloc(sizeof(int) * ((detectorModules)->nchan)); int *trimbits = malloc(sizeof(int) * ((detectorModules)->nchan));
for (int ichan = 0; ichan < ((detectorModules)->nchan); ++ichan) { for (int ichan = 0; ichan < ((detectorModules)->nchan); ++ichan) {
trimbits[ichan] = val; trimbits[ichan] = val;
@ -1248,11 +1318,14 @@ int setAllTrimbits(int val) {
free(trimbits); free(trimbits);
return FAIL; return FAIL;
} }
// setSettings(UNDEFINED);
// LOG(logERROR, ("Settings has been changed to undefined (random "
// "trim file)\n"));
LOG(logINFO, ("All trimbits have been set to %d\n", val)); LOG(logINFO, ("All trimbits have been set to %d\n", val));
free(trimbits); free(trimbits);
// changed for setsettings (direct),
// custom trimbit file (setmodule with myMod.reg as -1),
// change of dac (direct)
for (int i = 0; i < NCOUNTERS; ++i) {
setThresholdEnergy(i, -1);
}
return OK; return OK;
} }
@ -1270,6 +1343,73 @@ int getAllTrimbits() {
return value; return value;
} }
enum detectorSettings setSettings(enum detectorSettings sett) {
switch (sett) {
case STANDARD:
LOG(logINFOBLUE, ("Setting to standard settings\n"));
thisSettings = sett;
setDAC(M_VRPREAMP, DEFAULT_STANDARD_VRPREAMP, 0);
setDAC(M_VRSHAPER, DEFAULT_STANDARD_VRSHAPER, 0);
break;
case FAST:
LOG(logINFOBLUE, ("Setting to fast settings\n"));
thisSettings = sett;
setDAC(M_VRPREAMP, DEFAULT_FAST_VRPREAMP, 0);
setDAC(M_VRSHAPER, DEFAULT_FAST_VRSHAPER, 0);
break;
case HIGHGAIN:
LOG(logINFOBLUE, ("Setting to high gain settings\n"));
thisSettings = sett;
setDAC(M_VRPREAMP, DEFAULT_HIGHGAIN_VRPREAMP, 0);
setDAC(M_VRSHAPER, DEFAULT_HIGHGAIN_VRSHAPER, 0);
break;
default:
LOG(logERROR,
("Settings %d not defined for this detector\n", (int)sett));
return thisSettings;
}
LOG(logINFO, ("Settings: %d\n", thisSettings));
return thisSettings;
}
void validateSettings() {
if (detectorDacs[M_VRPREAMP] == DEFAULT_STANDARD_VRPREAMP &&
detectorDacs[M_VRSHAPER] == DEFAULT_STANDARD_VRSHAPER) {
if (thisSettings != STANDARD) {
thisSettings = STANDARD;
LOG(logINFOBLUE, ("Validated Settings changed to standard!\n"));
}
} else if (detectorDacs[M_VRPREAMP] == DEFAULT_FAST_VRPREAMP &&
detectorDacs[M_VRSHAPER] == DEFAULT_FAST_VRSHAPER) {
if (thisSettings != FAST) {
thisSettings = FAST;
LOG(logINFOBLUE, ("Validated Settings changed to fast!\n"));
}
} else if (detectorDacs[M_VRPREAMP] == DEFAULT_HIGHGAIN_VRPREAMP &&
detectorDacs[M_VRSHAPER] == DEFAULT_HIGHGAIN_VRSHAPER) {
if (thisSettings != HIGHGAIN) {
thisSettings = HIGHGAIN;
LOG(logINFOBLUE, ("Validated Settings changed to highgain!\n"));
}
} else {
thisSettings = UNDEFINED;
LOG(logWARNING,
("Settings set to undefined [vrpreamp: %d, vrshaper: %d]\n",
detectorDacs[M_VRPREAMP], detectorDacs[M_VRSHAPER]));
}
}
enum detectorSettings getSettings() { return thisSettings; }
int getThresholdEnergy(int counterIndex) {
return (detectorModules)->eV[counterIndex];
}
void setThresholdEnergy(int counterIndex, int eV) {
(detectorModules)->eV[counterIndex] = eV;
}
/* parameters - dac, hv */ /* parameters - dac, hv */
void setDAC(enum DACINDEX ind, int val, int mV) { void setDAC(enum DACINDEX ind, int val, int mV) {
if (val < 0) { if (val < 0) {
@ -1284,12 +1424,37 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
setDAC(M_VTH3, val, mV); setDAC(M_VTH3, val, mV);
return; return;
} }
char *dac_names[] = {DAC_NAMES}; char *dac_names[] = {DAC_NAMES};
// remember vthx values and set 2800 if counter disabled
uint32_t counters = getCounterMask();
int vthdacs[] = {M_VTH1, M_VTH2, M_VTH3};
for (int i = 0; i < NCOUNTERS; ++i) {
if (vthdacs[i] == (int)ind) {
// remember enabled values for vthx
if (val != DEFAULT_COUNTER_DISABLED_VTH_VAL) {
int vthval = val;
if (mV) {
if (LTC2620_D_VoltageToDac(val, &vthval) == FAIL) {
return;
}
}
vthEnabledVals[i] = vthval;
LOG(logINFO, ("Remembering %s [%d]\n", dac_names[ind], vthval));
}
// set vthx to disable val, if counter disabled
if (!(counters & (1 << i))) {
LOG(logINFO, ("Disabling %s\n", dac_names[ind]));
val = DEFAULT_COUNTER_DISABLED_VTH_VAL;
mV = 0;
}
}
}
LOG(logDEBUG1, ("Setting dac[%d - %s]: %d %s \n", (int)ind, dac_names[ind], LOG(logDEBUG1, ("Setting dac[%d - %s]: %d %s \n", (int)ind, dac_names[ind],
val, (mV ? "mV" : "dac units"))); val, (mV ? "mV" : "dac units")));
int dacval = val; int dacval = val;
#ifdef VIRTUAL #ifdef VIRTUAL
LOG(logINFO, ("Setting dac[%d - %s]: %d %s \n", (int)ind, dac_names[ind], LOG(logINFO, ("Setting dac[%d - %s]: %d %s \n", (int)ind, dac_names[ind],
val, (mV ? "mV" : "dac units"))); val, (mV ? "mV" : "dac units")));
@ -1306,11 +1471,14 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
detectorDacs[ind] = dacval; detectorDacs[ind] = dacval;
} }
#endif #endif
if (ind == M_VRPREAMP || ind == M_VRSHAPER) {
validateSettings();
}
} }
int getDAC(enum DACINDEX ind, int mV) { int getDAC(enum DACINDEX ind, int mV) {
if (ind == M_VTHRESHOLD) { if (ind == M_VTHRESHOLD) {
int ret[3] = {0}; int ret[NCOUNTERS] = {0};
ret[0] = getDAC(M_VTH1, mV); ret[0] = getDAC(M_VTH1, mV);
ret[1] = getDAC(M_VTH2, mV); ret[1] = getDAC(M_VTH2, mV);
ret[2] = getDAC(M_VTH3, mV); ret[2] = getDAC(M_VTH3, mV);
@ -1722,8 +1890,8 @@ uint64_t readPatternWord(int addr) {
LOG(logDEBUG1, (" Reading Pattern Word (addr:0x%x)\n", addr)); LOG(logDEBUG1, (" Reading Pattern Word (addr:0x%x)\n", addr));
uint32_t reg_lsb = uint32_t reg_lsb =
PATTERN_STEP0_LSB_REG + PATTERN_STEP0_LSB_REG +
addr * REG_OFFSET * 2; // the first word in RAM as base plus the offset addr * REG_OFFSET * 2; // the first word in RAM as base plus the
// of the word to write (addr) // offset of the word to write (addr)
uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2; uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2;
// read value // read value
@ -1753,8 +1921,8 @@ uint64_t writePatternWord(int addr, uint64_t word) {
// write word // write word
uint32_t reg_lsb = uint32_t reg_lsb =
PATTERN_STEP0_LSB_REG + PATTERN_STEP0_LSB_REG +
addr * REG_OFFSET * 2; // the first word in RAM as base plus the offset addr * REG_OFFSET * 2; // the first word in RAM as base plus the
// of the word to write (addr) // offset of the word to write (addr)
uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2; uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2;
set64BitReg(word, reg_lsb, reg_msb); set64BitReg(word, reg_lsb, reg_msb);
@ -2479,8 +2647,8 @@ enum runStatus getRunStatus() {
uint32_t deadtimeReg = bus_r(DEADTIME_CONFIG_REG); uint32_t deadtimeReg = bus_r(DEADTIME_CONFIG_REG);
if ((deadtimeReg & DEADTIME_EARLY_EXP_FIN_ERR_MSK) >> if ((deadtimeReg & DEADTIME_EARLY_EXP_FIN_ERR_MSK) >>
DEADTIME_EARLY_EXP_FIN_ERR_OFST) { DEADTIME_EARLY_EXP_FIN_ERR_OFST) {
LOG(logERROR, LOG(logERROR, ("Status: ERROR in Dead Time Reg (too short "
("Status: ERROR in Dead Time Reg (too short exptime) %08x\n", "exptime) %08x\n",
deadtimeReg)); deadtimeReg));
s = ERROR; s = ERROR;
} }
@ -2567,9 +2735,12 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
destMod->iodelay = srcMod->iodelay; destMod->iodelay = srcMod->iodelay;
if (srcMod->tau >= 0) if (srcMod->tau >= 0)
destMod->tau = srcMod->tau; destMod->tau = srcMod->tau;
if (srcMod->eV >= 0)
destMod->eV = srcMod->eV;
*/ */
for (int i = 0; i < NCOUNTERS; ++i) {
if (srcMod->eV[i] >= 0)
destMod->eV[i] = srcMod->eV[i];
}
LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg)); LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg));
if (destMod->nchan != 0) { if (destMod->nchan != 0) {
@ -2599,3 +2770,78 @@ int getTotalNumberOfChannels() {
int getNumberOfChips() { return NCHIP; } int getNumberOfChips() { return NCHIP; }
int getNumberOfDACs() { return NDAC; } int getNumberOfDACs() { return NDAC; }
int getNumberOfChannelsPerChip() { return NCHAN; } int getNumberOfChannelsPerChip() { return NCHAN; }
int setChipStatusRegister(int csr) {
int iaddr=0;
int nbits=18;
int error=0;
//int start=0, stop=MAX_PATTERN_LENGTH, loop=0;
int patword=0;
patword=setBit(SIGNAL_STATLOAD,patword);
for (int i=0; i<2; i++)
writePatternWord(iaddr++, patword);
patword=setBit(SIGNAL_resStorage,patword);
patword=setBit(SIGNAL_resCounter,patword);
for (int i=0; i<8; i++)
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_resStorage,patword);
patword=clearBit(SIGNAL_resCounter,patword);
for (int i=0; i<8; i++)
writePatternWord(iaddr++, patword);
//#This version of the serializer pushes in the MSB first (compatible with the CSR bit numbering)
for (int ib=nbits-1; ib>=0; ib--) {
if (csr&(1<<ib))
patword=setBit(SIGNAL_serialIN,patword);
else
patword=clearBit(SIGNAL_serialIN,patword);
for (int i=0; i<4; i++)
writePatternWord(iaddr++, patword);
patword=setBit(SIGNAL_CHSclk,patword);
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_CHSclk,patword);
writePatternWord(iaddr++, patword);
}
patword=clearBit(SIGNAL_serialIN,patword);
for (int i=0; i<2; i++)
writePatternWord(iaddr++, patword);
patword=setBit(SIGNAL_STO,patword);
for (int i=0; i<5; i++)
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_STO,patword);
for (int i=0; i<5; i++)
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_STATLOAD,patword);
for (int i=0; i<5; i++)
writePatternWord(iaddr++, patword);
if (iaddr >= MAX_PATTERN_LENGTH) {
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
iaddr, MAX_PATTERN_LENGTH));
error = 1;
}
// set pattern wait address
for (int i = 0; i <= 2; i++)
setPatternWaitAddress(i, MAX_PATTERN_LENGTH - 1);
// pattern loop
for (int i = 0; i <= 2; i++) {
int stop = MAX_PATTERN_LENGTH - 1, nloop = 0;
setPatternLoop(i, &stop, &stop, &nloop);
}
// pattern limits
{
int start = 0, nloop = 0;
setPatternLoop(-1, &start, &iaddr, &nloop);
}
// send pattern to the chips
startPattern();
if (error != 0) {
return FAIL;
}
return OK;
}

View File

@ -3,6 +3,7 @@
#define REQRD_FRMWRE_VRSN (0x200925) #define REQRD_FRMWRE_VRSN (0x200925)
#define KERNEL_DATE_VRSN "Wed May 20 13:58:38 CEST 2020" #define KERNEL_DATE_VRSN "Wed May 20 13:58:38 CEST 2020"
#define ID_FILE "detid_mythen3.txt"
#define CTRL_SRVR_INIT_TIME_US (300 * 1000) #define CTRL_SRVR_INIT_TIME_US (300 * 1000)
@ -37,6 +38,17 @@
#define DEFAULT_DELAY_AFTER_TRIGGER (0) #define DEFAULT_DELAY_AFTER_TRIGGER (0)
#define DEFAULT_HIGH_VOLTAGE (0) #define DEFAULT_HIGH_VOLTAGE (0)
#define DEFAULT_TIMING_MODE (AUTO_TIMING) #define DEFAULT_TIMING_MODE (AUTO_TIMING)
#define DEFAULT_SETTINGS (STANDARD)
#define DEFAULT_TRIMBIT_VALUE (0)
#define DEFAULT_COUNTER_DISABLED_VTH_VAL (2800)
#define DEFAULT_STANDARD_VRPREAMP (1100)
#define DEFAULT_FAST_VRPREAMP (300)
#define DEFAULT_HIGHGAIN_VRPREAMP (1300)
#define DEFAULT_STANDARD_VRSHAPER (1280)
#define DEFAULT_FAST_VRSHAPER (1500)
#define DEFAULT_HIGHGAIN_VRSHAPER (900)
#define DEFAULT_READOUT_C0 (10) //(100000000) // rdo_clk, 100 MHz #define DEFAULT_READOUT_C0 (10) //(100000000) // rdo_clk, 100 MHz
#define DEFAULT_READOUT_C1 (10) //(100000000) // smp sample clk (x2), 100 MHz #define DEFAULT_READOUT_C1 (10) //(100000000) // smp sample clk (x2), 100 MHz
#define DEFAULT_SYSTEM_C0 (10) //(100000000) // run_clk, 100 MHz #define DEFAULT_SYSTEM_C0 (10) //(100000000) // run_clk, 100 MHz
@ -174,3 +186,19 @@ typedef struct udp_header_struct {
#define SIGNAL_resCounter (23) #define SIGNAL_resCounter (23)
#define SIGNAL_CHSclk (24) #define SIGNAL_CHSclk (24)
#define SIGNAL_exposing (25) #define SIGNAL_exposing (25)
//CHIP STARTUS REGISTER BITS
#define CSR_spypads 0
#define CSR_invpol 4
#define CSR_dpulse 5
#define CSR_interp 6
#define CSR_C10pre 7 //#default
#define CSR_pumprobe 8
#define CSR_apulse 9
#define CSR_C15sh 10
#define CSR_C30sh 11 //#default
#define CSR_C50sh 12
#define CSR_C225ACsh 13 // Connects 225fF SHAPER AC cap (1: 225 to shaper, 225 to GND. 0: 450 to shaper)
#define CSR_C15pre 14
#define CSR_default (1<<CSR_C10pre )|(1<< CSR_C30sh)

View File

@ -87,7 +87,7 @@ u_int16_t getHardwareSerialNumber();
#ifdef JUNGFRAUD #ifdef JUNGFRAUD
int isHardwareVersion2(); int isHardwareVersion2();
#endif #endif
#ifdef EIGERD #if defined(EIGERD) || defined(MYTHEN3D)
void readDetectorNumber(); void readDetectorNumber();
#endif #endif
u_int32_t getDetectorNumber(); u_int32_t getDetectorNumber();
@ -291,19 +291,23 @@ int setTrimbits(int *trimbits);
int setAllTrimbits(int val); int setAllTrimbits(int val);
int getAllTrimbits(); int getAllTrimbits();
#endif #endif
#if (!defined(CHIPTESTBOARDD)) && (!defined(MYTHEN3D)) #ifndef CHIPTESTBOARDD
enum detectorSettings setSettings(enum detectorSettings sett); enum detectorSettings setSettings(enum detectorSettings sett);
#endif #endif
#if !defined(MYTHEN3D) #ifdef MYTHEN3D
enum detectorSettings getSettings(); void validateSettings();
#endif #endif
enum detectorSettings getSettings();
// parameters - threshold // parameters - threshold
#ifdef EIGERD #ifdef EIGERD
int getThresholdEnergy(); int getThresholdEnergy();
int setThresholdEnergy(int ev); int setThresholdEnergy(int ev);
#endif #endif
#ifdef MYTHEN3D
int getThresholdEnergy(int counterIndex);
void setThresholdEnergy(int counterIndex, int eV);
#endif
// parameters - dac, adc, hv // parameters - dac, adc, hv
#ifdef GOTTHARD2D #ifdef GOTTHARD2D

View File

@ -245,3 +245,4 @@ int set_default_dacs(int);
int is_virtual(int); int is_virtual(int);
int get_pattern(int); int get_pattern(int);
int load_default_pattern(int); int load_default_pattern(int);
int get_all_threshold_energy(int);

View File

@ -458,12 +458,12 @@ int receiveModule(int file_des, sls_detector_module *myMod) {
} }
ts += n; ts += n;
LOG(level, ("tau received. %d bytes. tau: %d\n", n, myMod->tau)); LOG(level, ("tau received. %d bytes. tau: %d\n", n, myMod->tau));
n = receiveData(file_des, &(myMod->eV), sizeof(myMod->eV), INT32); n = receiveData(file_des, myMod->eV, sizeof(myMod->eV), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("eV received. %d bytes. eV: %d\n", n, myMod->eV)); LOG(level, ("eV received. %d bytes. eV: %d\n", n, myMod->eV[0]));
// dacs // dacs
if (nDacs != (myMod->ndac)) { if (nDacs != (myMod->ndac)) {
LOG(logERROR, ("received wrong number of dacs. " LOG(logERROR, ("received wrong number of dacs. "

View File

@ -367,6 +367,7 @@ void function_table() {
flist[F_IS_VIRTUAL] = &is_virtual; flist[F_IS_VIRTUAL] = &is_virtual;
flist[F_GET_PATTERN] = &get_pattern; flist[F_GET_PATTERN] = &get_pattern;
flist[F_LOAD_DEFAULT_PATTERN] = &load_default_pattern; flist[F_LOAD_DEFAULT_PATTERN] = &load_default_pattern;
flist[F_GET_ALL_THRESHOLD_ENERGY] = &get_all_threshold_energy;
// check // check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -1238,6 +1239,16 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
} }
LOG(logDEBUG1, ("Dac (%d): %d %s\n\n", serverDacIndex, retval, LOG(logDEBUG1, ("Dac (%d): %d %s\n\n", serverDacIndex, retval,
(mV ? "mV" : "dac units"))); (mV ? "mV" : "dac units")));
#ifdef MYTHEN3D
// changed for setsettings (direct),
// custom trimbit file (setmodule with myMod.reg as -1),
// change of dac (direct)
if (val != GET_FLAG && ret == OK) {
for (int i = 0; i < NCOUNTERS; ++i) {
setThresholdEnergy(i, -1);
}
}
#endif
break; break;
} }
} }
@ -1513,7 +1524,7 @@ int set_module(int file_des) {
LOG(logDEBUG1, ("module register is %d, nchan %d, nchip %d, " LOG(logDEBUG1, ("module register is %d, nchan %d, nchip %d, "
"ndac %d, iodelay %d, tau %d, eV %d\n", "ndac %d, iodelay %d, tau %d, eV %d\n",
module.reg, module.nchan, module.nchip, module.ndac, module.reg, module.nchan, module.nchip, module.ndac,
module.iodelay, module.tau, module.eV)); module.iodelay, module.tau, module.eV[0]));
// should at least have a dac // should at least have a dac
if (ts <= (int)sizeof(sls_detector_module)) { if (ts <= (int)sizeof(sls_detector_module)) {
ret = FAIL; ret = FAIL;
@ -1540,6 +1551,10 @@ int set_module(int file_des) {
case LOWGAIN: case LOWGAIN:
case VERYHIGHGAIN: case VERYHIGHGAIN:
case VERYLOWGAIN: case VERYLOWGAIN:
#elif MYTHEN3D
case STANDARD:
case FAST:
case HIGHGAIN:
#elif JUNGFRAUD #elif JUNGFRAUD
case DYNAMICGAIN: case DYNAMICGAIN:
case DYNAMICHG0: case DYNAMICHG0:
@ -1561,11 +1576,9 @@ int set_module(int file_des) {
} }
ret = setModule(module, mess); ret = setModule(module, mess);
#ifndef MYTHEN3D
enum detectorSettings retval = getSettings(); enum detectorSettings retval = getSettings();
validate(module.reg, (int)retval, "set module (settings)", DEC); validate(module.reg, (int)retval, "set module (settings)", DEC);
LOG(logDEBUG1, ("Settings: %d\n", retval)); LOG(logDEBUG1, ("Settings: %d\n", retval));
#endif
} }
free(myChan); free(myChan);
free(myDac); free(myDac);
@ -1583,7 +1596,7 @@ int set_settings(int file_des) {
if (receiveData(file_des, &isett, sizeof(isett), INT32) < 0) if (receiveData(file_des, &isett, sizeof(isett), INT32) < 0)
return printSocketReadError(); return printSocketReadError();
#if defined(CHIPTESTBOARDD) || defined(MYTHEN3D) #ifdef CHIPTESTBOARDD
functionNotImplemented(); functionNotImplemented();
#else #else
LOG(logDEBUG1, ("Setting settings %d\n", isett)); LOG(logDEBUG1, ("Setting settings %d\n", isett));
@ -1620,13 +1633,17 @@ int set_settings(int file_des) {
case G2_LOWCAP_LOWGAIN: case G2_LOWCAP_LOWGAIN:
case G4_HIGHGAIN: case G4_HIGHGAIN:
case G4_LOWGAIN: case G4_LOWGAIN:
#elif MYTHEN3D
case STANDARD:
case FAST:
case HIGHGAIN:
#endif #endif
break; break;
default: default:
if (myDetectorType == EIGER) { if (myDetectorType == EIGER) {
ret = FAIL; ret = FAIL;
sprintf(mess, "Cannot set settings via SET_SETTINGS, use " sprintf(mess, "Cannot set settings via SET_SETTINGS, use "
"SET_MODULE (set threshold)\n"); "SET_MODULE\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else } else
modeNotImplemented("Settings Index", (int)isett); modeNotImplemented("Settings Index", (int)isett);
@ -1651,6 +1668,16 @@ int set_settings(int file_des) {
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} }
} }
#endif
#ifdef MYTHEN3D
// changed for setsettings (direct),
// custom trimbit file (setmodule with myMod.reg as -1),
// change of dac (direct)
if (ret == OK) {
for (int i = 0; i < NCOUNTERS; ++i) {
setThresholdEnergy(i, -1);
}
}
#endif #endif
} }
} }
@ -7101,14 +7128,19 @@ int get_receiver_parameters(int file_des) {
return printSocketReadError(); return printSocketReadError();
// threshold ev // threshold ev
{
int i32s[3] = {0, 0, 0};
#ifdef EIGERD #ifdef EIGERD
i32 = getThresholdEnergy(); i32s[0] = getThresholdEnergy();
#else #elif MYTHEN3D
i32 = 0; for (int i = 0; i < NCOUNTERS; ++i) {
i32s[i] = getThresholdEnergy(i);
}
#endif #endif
n += sendData(file_des, &i32, sizeof(i32), INT32); n += sendData(file_des, i32s, sizeof(i32s), INT32);
if (n < 0) if (n < 0)
return printSocketReadError(); return printSocketReadError();
}
// dynamic range // dynamic range
i32 = setDynamicRange(GET_FLAG); i32 = setDynamicRange(GET_FLAG);
@ -8315,3 +8347,21 @@ int load_default_pattern(int file_des) {
#endif #endif
return Server_SendResult(file_des, INT32, NULL, 0); return Server_SendResult(file_des, INT32, NULL, 0);
} }
int get_all_threshold_energy(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retvals[3] = {-1, -1, -1};
LOG(logDEBUG1, ("Getting all threshold energy\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
for (int i = 0; i < NCOUNTERS; ++i) {
retvals[i] = getThresholdEnergy(i);
LOG(logDEBUG, ("eV[%d]: %deV\n", i, retvals[i]));
}
#endif
return Server_SendResult(file_des, INT32, retvals, sizeof(retvals));
}

View File

@ -110,7 +110,7 @@ class Detector {
/** list of possible settings for this detector */ /** list of possible settings for this detector */
std::vector<defs::detectorSettings> getSettingsList() const; std::vector<defs::detectorSettings> getSettingsList() const;
/** [Jungfrau][Gotthard][Gotthard2] */ /** [Jungfrau][Gotthard][Gotthard2][Mythen3] */
Result<defs::detectorSettings> getSettings(Positions pos = {}) const; Result<defs::detectorSettings> getSettings(Positions pos = {}) const;
/** [Jungfrau] DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2, /** [Jungfrau] DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2,
@ -118,12 +118,34 @@ class Detector {
* LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN \n [Gotthard2] DYNAMICGAIN, * LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN \n [Gotthard2] DYNAMICGAIN,
* FIXGAIN1, FIXGAIN2 \n [Moench] G1_HIGHGAIN, G1_LOWGAIN, * FIXGAIN1, FIXGAIN2 \n [Moench] G1_HIGHGAIN, G1_LOWGAIN,
* G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN, G2_LOWCAP_HIGHGAIN, * G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN, G2_LOWCAP_HIGHGAIN,
* G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN \n [Eiger] Use threshold * G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN \n [Mythen3] STANDARD, FAST,
* command. Settings loaded from file found in * HIGHGAIN. Also changes vrshaper and vrpreamp \n [Eiger] Use threshold
* settingspath * command. Settings loaded from file found in settingspath
*/ */
void setSettings(defs::detectorSettings value, Positions pos = {}); void setSettings(defs::detectorSettings value, Positions pos = {});
/** [Eiger] */
Result<int> getThresholdEnergy(Positions pos = {}) const;
/** Mythen3] threshold energy for the three counters */
Result<std::array<int, 3>> getAllThresholdEnergy(Positions pos = {}) const;
/** [Eiger][Mythen3] It loads trim files from settingspath */
void setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
/** [Mythen3] It loads trim files from settingspath */
void setThresholdEnergy(std::array<int, 3> threshold_ev,
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
/** [Eiger][Mythen3] */
Result<std::string> getSettingsPath(Positions pos = {}) const;
/** [Eiger][Mythen3] Directory where settings files are loaded from/to */
void setSettingsPath(const std::string &value, Positions pos = {});
/** [Eiger][Mythen3] If no extension specified, serial number of each module /** [Eiger][Mythen3] If no extension specified, serial number of each module
* is attached. */ * is attached. */
void loadTrimbits(const std::string &fname, Positions pos = {}); void loadTrimbits(const std::string &fname, Positions pos = {});
@ -134,6 +156,13 @@ class Detector {
/**[Eiger][Mythen3] */ /**[Eiger][Mythen3] */
void setAllTrimbits(int value, Positions pos = {}); void setAllTrimbits(int value, Positions pos = {});
/**[Eiger][Mythen3] Returns energies in eV where the module is trimmed */
Result<std::vector<int>> getTrimEnergies(Positions pos = {}) const;
/** [Eiger][Mythen3] List of trim energies, where corresponding default trim
* files exist in corresponding trim folders */
void setTrimEnergies(std::vector<int> energies, Positions pos = {});
/**[Eiger][Jungfrau] */ /**[Eiger][Jungfrau] */
bool getGapPixelsinCallback() const; bool getGapPixelsinCallback() const;
@ -940,20 +969,6 @@ class Detector {
/** [Eiger] in 32 bit mode */ /** [Eiger] in 32 bit mode */
void setSubDeadTime(ns value, Positions pos = {}); void setSubDeadTime(ns value, Positions pos = {});
/** [Eiger] */
Result<int> getThresholdEnergy(Positions pos = {}) const;
/** [Eiger] It loads trim files from settingspath */
void setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
/** [Eiger] */
Result<std::string> getSettingsPath(Positions pos = {}) const;
/** [Eiger] Directory where settings files are loaded from/to */
void setSettingsPath(const std::string &value, Positions pos = {});
/** [Eiger] */ /** [Eiger] */
Result<bool> getOverFlowMode(Positions pos = {}) const; Result<bool> getOverFlowMode(Positions pos = {}) const;
@ -966,13 +981,6 @@ class Detector {
/** [Eiger] for client call back (gui) purposes to flip bottom image */ /** [Eiger] for client call back (gui) purposes to flip bottom image */
void setBottom(bool value, Positions pos = {}); void setBottom(bool value, Positions pos = {});
/**[Eiger] Returns energies in eV where the module is trimmed */
Result<std::vector<int>> getTrimEnergies(Positions pos = {}) const;
/** [Eiger] List of trim energies, where corresponding default trim files
* exist in corresponding trim folders */
void setTrimEnergies(std::vector<int> energies, Positions pos = {});
/** [Eiger] deadtime in ns, 0 = disabled */ /** [Eiger] deadtime in ns, 0 = disabled */
Result<ns> getRateCorrection(Positions pos = {}) const; Result<ns> getRateCorrection(Positions pos = {}) const;

View File

@ -356,6 +356,119 @@ std::string CmdProxy::DetectorSize(int action) {
return os.str(); return os.str();
} }
std::string CmdProxy::Threshold(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[eV] [(optinal settings)"
"\n\t[Eiger][Mythen3] Threshold in eV. It loads trim files from "
"settingspath.";
if (cmd == "thresholdnotb") {
os << "Trimbits are not loaded.";
}
os << "\n\nthreshold [eV1] [eV2] [eV3] [(optional settings)]"
"\n\t[Mythen3] Threshold in eV for each counter. It loads trim "
"files from "
"settingspath.";
if (cmd == "thresholdnotb") {
os << "Trimbits are not loaded.";
}
os << '\n';
} else if (action == defs::GET_ACTION) {
if (cmd == "thresholdnotb") {
throw sls::RuntimeError("cannot get");
}
if (!args.empty()) {
WrongNumberOfParameters(0);
}
defs::detectorType type = det->getDetectorType().squash();
if (type == defs::EIGER) {
auto t = det->getThresholdEnergy(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (type == defs::MYTHEN3) {
auto t = det->getAllThresholdEnergy(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else {
throw RuntimeError("Not implemented for this detector\n");
}
} else if (action == defs::PUT_ACTION) {
defs::detectorType type = det->getDetectorType().squash();
if (type == defs::EIGER && args.size() != 1 && args.size() != 2) {
WrongNumberOfParameters(1);
}
if (type == defs::MYTHEN3 && (args.size() < 1 || args.size() > 4)) {
WrongNumberOfParameters(1);
}
bool trimbits = (cmd == "thresholdnotb") ? false : true;
std::array<int, 3> energy = {StringTo<int>(args[0]), 0, 0};
energy[1] = energy[0];
energy[2] = energy[0];
defs::detectorSettings sett = defs::STANDARD;
// check if argument has settings or get it
if (args.size() == 2 || args.size() == 4) {
sett = StringTo<defs::detectorSettings>(args[args.size() - 1]);
} else {
sett = det->getSettings(std::vector<int>{det_id})
.tsquash("Inconsistent settings between detectors");
}
// get other threshold values
if (args.size() > 2) {
energy[1] = StringTo<int>(args[1]);
energy[2] = StringTo<int>(args[2]);
}
switch (type) {
case defs::EIGER:
det->setThresholdEnergy(energy[0], sett, trimbits,
std::vector<int>{det_id});
break;
case defs::MYTHEN3:
det->setThresholdEnergy(energy, sett, trimbits,
std::vector<int>{det_id});
break;
default:
throw RuntimeError("Not implemented for this detector\n");
}
os << ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::TrimEnergies(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[trim_ev1] [trim_Ev2 (optional)] [trim_ev3 (optional)] "
"...\n\t[Eiger][Mythen3] Number of trim energies and list of "
"trim "
"energies, where corresponding default trim files exist in "
"corresponding trim folders."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getTrimEnergies(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
std::vector<int> t(args.size());
if (!args.empty()) {
for (size_t i = 0; i < t.size(); ++i) {
t[i] = StringTo<int>(args[i]);
}
}
det->setTrimEnergies(t, std::vector<int>{det_id});
os << sls::ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::GapPixels(int action) { std::string CmdProxy::GapPixels(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
@ -1264,103 +1377,6 @@ std::string CmdProxy::ZMQHWM(int action) {
/* Eiger Specific */ /* Eiger Specific */
std::string CmdProxy::Threshold(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[eV] [(optinal settings) standard, lowgain, veryhighgain, "
"verylowgain]"
"\n\t[Eiger] Threshold in eV. It loads trim files from "
"settingspath."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getThresholdEnergy(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
auto t = det->getSettings(std::vector<int>{det_id})
.tsquash("Inconsistent settings between detectors");
det->setThresholdEnergy(StringTo<int>(args[0]), t, true,
std::vector<int>{det_id});
} else if (args.size() == 2) {
det->setThresholdEnergy(
StringTo<int>(args[0]),
sls::StringTo<slsDetectorDefs::detectorSettings>(args[1]), true,
{det_id});
} else {
WrongNumberOfParameters(1);
}
os << ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::ThresholdNoTb(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[eV] [(optional settings) standard, lowgain, veryhighgain, "
"verylowgain]"
"\n\t[Eiger] Threshold in eV set without setting trimbits"
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("cannot get");
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
auto t = det->getSettings(std::vector<int>{det_id})
.tsquash("Inconsistent settings between detectors");
det->setThresholdEnergy(StringTo<int>(args[0]), t, false,
std::vector<int>{det_id});
} else if (args.size() == 2) {
det->setThresholdEnergy(
StringTo<int>(args[0]),
sls::StringTo<slsDetectorDefs::detectorSettings>(args[1]),
false, std::vector<int>{det_id});
} else {
WrongNumberOfParameters(1);
}
os << ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::TrimEnergies(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[trim_ev1] [trim_Ev2 (optional)] [trim_ev3 (optional)] "
"...\n\t[Eiger] Number of trim energies and list of trim "
"energies, where corresponding default trim files exist in "
"corresponding trim folders."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getTrimEnergies(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
std::vector<int> t(args.size());
if (!args.empty()) {
for (size_t i = 0; i < t.size(); ++i) {
t[i] = StringTo<int>(args[i]);
}
}
det->setTrimEnergies(t, std::vector<int>{det_id});
os << sls::ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::RateCorrection(int action) { std::string CmdProxy::RateCorrection(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';

View File

@ -596,6 +596,8 @@ class CmdProxy {
{"detectornumber", "serialnumber"}, {"detectornumber", "serialnumber"},
{"thisversion", "clientversion"}, {"thisversion", "clientversion"},
{"detsizechan", "detsize"}, {"detsizechan", "detsize"},
{"trimdir", "settingspath"},
{"settingsdir", "settingspath"},
/* acquisition parameters */ /* acquisition parameters */
{"cycles", "triggers"}, {"cycles", "triggers"},
@ -724,8 +726,6 @@ class CmdProxy {
{"rx_datastream", "rx_zmqstream"}, {"rx_datastream", "rx_zmqstream"},
/* Eiger Specific */ /* Eiger Specific */
{"trimdir", "settingspath"},
{"settingsdir", "settingspath"},
{"resmat", "partialreset"}, {"resmat", "partialreset"},
/* Jungfrau Specific */ /* Jungfrau Specific */
@ -774,8 +774,12 @@ class CmdProxy {
{"detsize", &CmdProxy::DetectorSize}, {"detsize", &CmdProxy::DetectorSize},
{"settingslist", &CmdProxy::settingslist}, {"settingslist", &CmdProxy::settingslist},
{"settings", &CmdProxy::settings}, {"settings", &CmdProxy::settings},
{"threshold", &CmdProxy::Threshold},
{"thresholdnotb", &CmdProxy::Threshold},
{"settingspath", &CmdProxy::settingspath},
{"trimbits", &CmdProxy::trimbits}, {"trimbits", &CmdProxy::trimbits},
{"trimval", &CmdProxy::trimval}, {"trimval", &CmdProxy::trimval},
{"trimen", &CmdProxy::TrimEnergies},
{"gappixels", &CmdProxy::GapPixels}, {"gappixels", &CmdProxy::GapPixels},
/* acquisition parameters */ /* acquisition parameters */
@ -911,12 +915,8 @@ class CmdProxy {
/* Eiger Specific */ /* Eiger Specific */
{"subexptime", &CmdProxy::subexptime}, {"subexptime", &CmdProxy::subexptime},
{"subdeadtime", &CmdProxy::subdeadtime}, {"subdeadtime", &CmdProxy::subdeadtime},
{"threshold", &CmdProxy::Threshold},
{"thresholdnotb", &CmdProxy::ThresholdNoTb},
{"settingspath", &CmdProxy::settingspath},
{"overflow", &CmdProxy::overflow}, {"overflow", &CmdProxy::overflow},
{"flippeddatax", &CmdProxy::flippeddatax}, {"flippeddatax", &CmdProxy::flippeddatax},
{"trimen", &CmdProxy::TrimEnergies},
{"ratecorr", &CmdProxy::RateCorrection}, {"ratecorr", &CmdProxy::RateCorrection},
{"readnlines", &CmdProxy::readnlines}, {"readnlines", &CmdProxy::readnlines},
{"interruptsubframe", &CmdProxy::interruptsubframe}, {"interruptsubframe", &CmdProxy::interruptsubframe},
@ -1082,6 +1082,8 @@ class CmdProxy {
std::string PackageVersion(int action); std::string PackageVersion(int action);
std::string ClientVersion(int action); std::string ClientVersion(int action);
std::string DetectorSize(int action); std::string DetectorSize(int action);
std::string Threshold(int action);
std::string TrimEnergies(int action);
std::string GapPixels(int action); std::string GapPixels(int action);
/* acquisition parameters */ /* acquisition parameters */
std::string Acquire(int action); std::string Acquire(int action);
@ -1113,9 +1115,6 @@ class CmdProxy {
/* ZMQ Streaming Parameters (Receiver<->Client) */ /* ZMQ Streaming Parameters (Receiver<->Client) */
std::string ZMQHWM(int action); std::string ZMQHWM(int action);
/* Eiger Specific */ /* Eiger Specific */
std::string Threshold(int action);
std::string ThresholdNoTb(int action);
std::string TrimEnergies(int action);
std::string RateCorrection(int action); std::string RateCorrection(int action);
std::string Activate(int action); std::string Activate(int action);
std::string PulsePixel(int action); std::string PulsePixel(int action);
@ -1212,9 +1211,14 @@ class CmdProxy {
"\n\t[Gotthard2] - [dynamicgain | fixgain1 | fixgain2]" "\n\t[Gotthard2] - [dynamicgain | fixgain1 | fixgain2]"
"\n\t[Moench] - [g1_hg | g1_lg | g2_hc_hg | g2_hc_lg | " "\n\t[Moench] - [g1_hg | g1_lg | g2_hc_hg | g2_hc_lg | "
"g2_lc_hg | g2_lc_lg | g4_hg | g4_lg]" "g2_lc_hg | g2_lc_lg | g4_hg | g4_lg]"
"\n\t[Eiger] Use threshold or thresholdnotb. \n\t[Eiger] " "\n\t[Mythen3] - [standard | fast | highgain] Also changes vrshaper "
"settings loaded from file found in settingspath. \n\t[Gotthard] Also " "and vrpreamp. \n\t[Eiger] Use threshold or thresholdnotb. \n\t[Eiger] "
"loads default dacs on to the detector."); "threshold and settings loaded from file found in settingspath. "
"\n\t[Gotthard] Also loads default dacs on to the detector.");
STRING_COMMAND(settingspath, getSettingsPath, setSettingsPath,
"[path]\n\t[Eiger][Mythen3] Directory where settings files "
"are loaded from/to.");
EXECUTE_SET_COMMAND_1ARG( EXECUTE_SET_COMMAND_1ARG(
trimbits, loadTrimbits, trimbits, loadTrimbits,
@ -1776,10 +1780,6 @@ class CmdProxy {
"of EIGER subframes in 32 bit mode. Subperiod = subexptime + " "of EIGER subframes in 32 bit mode. Subperiod = subexptime + "
"subdeadtime."); "subdeadtime.");
STRING_COMMAND(
settingspath, getSettingsPath, setSettingsPath,
"[path]\n\t[Eiger] Directory where settings files are loaded from/to.");
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
overflow, getOverFlowMode, setOverFlowMode, StringTo<int>, overflow, getOverFlowMode, setOverFlowMode, StringTo<int>,
"[0, 1]\n\t[Eiger] Enable or disable show overflow flag in " "[0, 1]\n\t[Eiger] Enable or disable show overflow flag in "

View File

@ -171,8 +171,10 @@ std::vector<defs::detectorSettings> Detector::getSettingsList() const {
defs::G2_HIGHCAP_HIGHGAIN, defs::G2_HIGHCAP_LOWGAIN, defs::G2_HIGHCAP_HIGHGAIN, defs::G2_HIGHCAP_LOWGAIN,
defs::G2_LOWCAP_HIGHGAIN, defs::G2_LOWCAP_LOWGAIN, defs::G2_LOWCAP_HIGHGAIN, defs::G2_LOWCAP_LOWGAIN,
defs::G4_HIGHGAIN, defs::G4_LOWGAIN}; defs::G4_HIGHGAIN, defs::G4_LOWGAIN};
case defs::CHIPTESTBOARD:
case defs::MYTHEN3: case defs::MYTHEN3:
return std::vector<defs::detectorSettings>{defs::STANDARD, defs::FAST,
defs::HIGHGAIN};
case defs::CHIPTESTBOARD:
throw RuntimeError("Settings not implemented for this detector"); throw RuntimeError("Settings not implemented for this detector");
default: default:
throw RuntimeError("Unknown detector type"); throw RuntimeError("Unknown detector type");
@ -184,7 +186,71 @@ Result<defs::detectorSettings> Detector::getSettings(Positions pos) const {
} }
void Detector::setSettings(const defs::detectorSettings value, Positions pos) { void Detector::setSettings(const defs::detectorSettings value, Positions pos) {
if (value == defs::UNINITIALIZED || value == defs::UNDEFINED) {
throw RuntimeError(
"Cannot set settings with undefined or uninitialized settings.");
}
if (anyEqualTo<defs::detectorSettings>(getSettingsList(), value)) {
pimpl->Parallel(&Module::setSettings, pos, value); pimpl->Parallel(&Module::setSettings, pos, value);
} else {
throw RuntimeError("Unknown Settings " + ToString(value) +
" for this detector\n");
}
}
Result<int> Detector::getThresholdEnergy(Positions pos) const {
return pimpl->Parallel(&Module::getThresholdEnergy, pos);
}
Result<std::array<int, 3>>
Detector::getAllThresholdEnergy(Positions pos) const {
return pimpl->Parallel(&Module::getAllThresholdEnergy, pos);
}
void Detector::setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
defs::detectorType type = getDetectorType().squash();
if (type == defs::MYTHEN3) {
std::array<int, 3> energy = {threshold_ev, threshold_ev, threshold_ev};
setThresholdEnergy(energy, settings, trimbits, pos);
return;
}
if (type != defs::EIGER) {
throw RuntimeError(
"Set threshold energy not implemented for this detector");
}
if (anyEqualTo<defs::detectorSettings>(getSettingsList(), settings)) {
pimpl->Parallel(&Module::setThresholdEnergy, pos, threshold_ev,
settings, static_cast<int>(trimbits));
} else {
throw RuntimeError("Unknown Settings " + ToString(settings) +
" for this detector\n");
}
}
void Detector::setThresholdEnergy(std::array<int, 3> threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
if (getDetectorType().squash() != defs::MYTHEN3) {
throw RuntimeError("Set threshold energy for different counters not "
"implemented for this detector");
}
if (anyEqualTo<defs::detectorSettings>(getSettingsList(), settings)) {
pimpl->Parallel(&Module::setAllThresholdEnergy, pos, threshold_ev,
settings, static_cast<int>(trimbits));
} else {
throw RuntimeError("Unknown Settings " + ToString(settings) +
" for this detector\n");
}
}
Result<std::string> Detector::getSettingsPath(Positions pos) const {
return pimpl->Parallel(&Module::getSettingsDir, pos);
}
void Detector::setSettingsPath(const std::string &value, Positions pos) {
pimpl->Parallel(&Module::setSettingsDir, pos, value);
} }
void Detector::loadTrimbits(const std::string &fname, Positions pos) { void Detector::loadTrimbits(const std::string &fname, Positions pos) {
@ -199,6 +265,14 @@ void Detector::setAllTrimbits(int value, Positions pos) {
pimpl->Parallel(&Module::setAllTrimbits, pos, value); pimpl->Parallel(&Module::setAllTrimbits, pos, value);
} }
Result<std::vector<int>> Detector::getTrimEnergies(Positions pos) const {
return pimpl->Parallel(&Module::getTrimEn, pos);
}
void Detector::setTrimEnergies(std::vector<int> energies, Positions pos) {
pimpl->Parallel(&Module::setTrimEn, pos, energies);
}
bool Detector::getGapPixelsinCallback() const { bool Detector::getGapPixelsinCallback() const {
return pimpl->getGapPixelsinCallback(); return pimpl->getGapPixelsinCallback();
} }
@ -1158,25 +1232,6 @@ void Detector::setSubDeadTime(ns value, Positions pos) {
pimpl->Parallel(&Module::setSubDeadTime, pos, value.count()); pimpl->Parallel(&Module::setSubDeadTime, pos, value.count());
} }
Result<int> Detector::getThresholdEnergy(Positions pos) const {
return pimpl->Parallel(&Module::getThresholdEnergy, pos);
}
void Detector::setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
pimpl->Parallel(&Module::setThresholdEnergy, pos, threshold_ev, settings,
static_cast<int>(trimbits));
}
Result<std::string> Detector::getSettingsPath(Positions pos) const {
return pimpl->Parallel(&Module::getSettingsDir, pos);
}
void Detector::setSettingsPath(const std::string &value, Positions pos) {
pimpl->Parallel(&Module::setSettingsDir, pos, value);
}
Result<bool> Detector::getOverFlowMode(Positions pos) const { Result<bool> Detector::getOverFlowMode(Positions pos) const {
return pimpl->Parallel(&Module::getOverFlowMode, pos); return pimpl->Parallel(&Module::getOverFlowMode, pos);
} }
@ -1193,14 +1248,6 @@ void Detector::setBottom(bool value, Positions pos) {
pimpl->Parallel(&Module::setFlippedDataX, pos, value); pimpl->Parallel(&Module::setFlippedDataX, pos, value);
} }
Result<std::vector<int>> Detector::getTrimEnergies(Positions pos) const {
return pimpl->Parallel(&Module::getTrimEn, pos);
}
void Detector::setTrimEnergies(std::vector<int> energies, Positions pos) {
pimpl->Parallel(&Module::setTrimEn, pos, energies);
}
Result<ns> Detector::getRateCorrection(Positions pos) const { Result<ns> Detector::getRateCorrection(Positions pos) const {
return pimpl->Parallel(&Module::getRateCorrection, pos); return pimpl->Parallel(&Module::getRateCorrection, pos);
} }

View File

@ -2,6 +2,7 @@
#include "SharedMemory.h" #include "SharedMemory.h"
#include "sls/ClientSocket.h" #include "sls/ClientSocket.h"
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/bit_utils.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/file_utils.h" #include "sls/file_utils.h"
#include "sls/network_utils.h" #include "sls/network_utils.h"
@ -9,7 +10,6 @@
#include "sls/sls_detector_funcs.h" #include "sls/sls_detector_funcs.h"
#include "sls/string_utils.h" #include "sls/string_utils.h"
#include "sls/versionAPI.h" #include "sls/versionAPI.h"
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <bitset> #include <bitset>
@ -152,16 +152,237 @@ void Module::setSettings(detectorSettings isettings) {
sendToDetector<int>(F_SET_SETTINGS, isettings); sendToDetector<int>(F_SET_SETTINGS, isettings);
} }
int Module::getThresholdEnergy() const {
return sendToDetector<int>(F_GET_THRESHOLD_ENERGY);
}
std::array<int, 3> Module::getAllThresholdEnergy() const {
return sendToDetector<std::array<int, 3>>(F_GET_ALL_THRESHOLD_ENERGY);
}
void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits) {
// verify e_eV exists in trimEneregies[]
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
(e_eV > shm()->trimEnergies.back())) {
throw RuntimeError("This energy " + std::to_string(e_eV) +
" not defined for this module!");
}
bool interpolate =
std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(),
[e_eV](const int &e) { return e != e_eV; });
sls_detector_module myMod{shm()->myDetectorType};
if (!interpolate) {
std::string settingsfname = getTrimbitFilename(isettings, e_eV);
LOG(logDEBUG1) << "Settings File is " << settingsfname;
myMod = readSettingsFile(settingsfname, trimbits);
} else {
// find the trim values
int trim1 = -1, trim2 = -1;
for (size_t i = 0; i < shm()->trimEnergies.size(); ++i) {
if (e_eV < shm()->trimEnergies[i]) {
trim2 = shm()->trimEnergies[i];
trim1 = shm()->trimEnergies[i - 1];
break;
}
}
std::string settingsfname1 = getTrimbitFilename(isettings, trim1);
std::string settingsfname2 = getTrimbitFilename(isettings, trim2);
LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and "
<< settingsfname2;
auto myMod1 = readSettingsFile(settingsfname1, trimbits);
auto myMod2 = readSettingsFile(settingsfname2, trimbits);
if (myMod1.iodelay != myMod2.iodelay) {
throw RuntimeError("setThresholdEnergyAndSettings: Iodelays do not "
"match between files");
}
myMod = interpolateTrim(&myMod1, &myMod2, e_eV, trim1, trim2, trimbits);
myMod.iodelay = myMod1.iodelay;
myMod.tau =
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
}
myMod.reg = isettings;
myMod.eV[0] = e_eV;
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
}
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_THRESHOLD, e_eV, nullptr);
}
}
void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
detectorSettings isettings, bool trimbits) {
if (shm()->trimEnergies.empty()) {
throw RuntimeError(
"Trim energies have not been defined for this module yet!");
}
auto counters = getSetBits(getCounterMask());
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
std::vector<sls_detector_module> myMods{shm()->myDetectorType};
std::vector<int> energy(e_eV.begin(), e_eV.end());
// if all energies are same
if (allEqualTo(energy, energy[0])) {
energy.resize(1);
}
myMods.resize(energy.size());
// for each threshold
for (size_t i = 0; i < energy.size(); ++i) {
// don't interpolate
if (shm()->trimEnergies.anyEqualTo(energy[i])) {
std::string settingsfname =
getTrimbitFilename(isettings, energy[i]);
LOG(logDEBUG1) << "Settings File is " << settingsfname;
myMods[i] = readSettingsFile(settingsfname, trimbits);
}
// interpolate
else {
if (shm()->trimEnergies.size() < 2) {
throw RuntimeError(
"Cannot interpolate with less than 2 trim energies");
}
// find the trim values
int trim1 = -1, trim2 = -1;
if (energy[i] < shm()->trimEnergies[0]) {
trim1 = shm()->trimEnergies[0];
trim2 = shm()->trimEnergies[1];
} else if (energy[i] >
shm()->trimEnergies[shm()->trimEnergies.size() - 1]) {
trim1 = shm()->trimEnergies[shm()->trimEnergies.size() - 2];
trim2 = shm()->trimEnergies[shm()->trimEnergies.size() - 1];
} else {
for (size_t j = 0; j < shm()->trimEnergies.size(); ++j) {
// std::cout << "checking " << energy[i] << " and "
// << shm()->trimEnergies[j] << std::endl;
if (energy[i] < shm()->trimEnergies[j]) {
trim1 = shm()->trimEnergies[j - 1];
trim2 = shm()->trimEnergies[j];
break;
}
}
}
LOG(logINFO) << "e_eV:" << energy[i] << " [" << trim1 << ", "
<< trim2 << "]";
std::string settingsfname1 = getTrimbitFilename(isettings, trim1);
std::string settingsfname2 = getTrimbitFilename(isettings, trim2);
LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and "
<< settingsfname2;
auto myMod1 = readSettingsFile(settingsfname1, trimbits);
auto myMod2 = readSettingsFile(settingsfname2, trimbits);
myMods[i] = interpolateTrim(&myMod1, &myMod2, energy[i], trim1,
trim2, trimbits);
}
}
sls_detector_module myMod{shm()->myDetectorType};
myMod = myMods[0];
// if multiple thresholds, combine
if (myMods.size() > 1) {
// average vtrim of enabled counters
int sum = 0;
for (size_t i = 0; i < counters.size(); ++i) {
sum += myMods[counters[i]].dacs[M_VTRIM];
}
myMod.dacs[M_VTRIM] = sum / counters.size();
// copy vth1, vth2 and vth3 from the correct threshold mods
myMod.dacs[VTH1] = myMods[0].dacs[VTH1];
myMod.dacs[VTH2] = myMods[1].dacs[VTH2];
myMod.dacs[VTH3] = myMods[2].dacs[VTH3];
// check if dacs are different
for (size_t j = 0; j < 16; ++j) {
if (j == M_VTRIM || j == M_VTH1 || j == M_VTH2 || j == M_VTH3)
continue;
if (myMods[0].dacs[j] != myMods[1].dacs[j]) {
throw RuntimeError("Dac Index " + std::to_string(j) +
" differs for threshold[0]:[" +
std::to_string(myMods[0].dacs[j]) +
"] and threshold[1]:" +
std::to_string(myMods[1].dacs[j]) + "]");
}
if (myMods[1].dacs[j] != myMods[2].dacs[j]) {
throw RuntimeError("Dac Index " + std::to_string(j) +
" differs for threshold[1]:[" +
std::to_string(myMods[1].dacs[j]) +
"] and threshold[2]:" +
std::to_string(myMods[2].dacs[j]) + "]");
}
}
// replace correct trim values (interleaved)
for (int i = 0; i < myMod.nchan; ++i) {
myMod.chanregs[i] = myMods[i % 3].chanregs[i];
}
}
myMod.reg = isettings;
std::copy(e_eV.begin(), e_eV.end(), myMod.eV);
LOG(logDEBUG) << "ev:" << ToString(myMod.eV);
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
}
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_ALL_THRESHOLD, e_eV, nullptr);
}
}
std::string Module::getSettingsDir() const {
return std::string(shm()->settingsDir);
}
std::string Module::setSettingsDir(const std::string &dir) {
sls::strcpy_safe(shm()->settingsDir, dir.c_str());
return shm()->settingsDir;
}
void Module::loadSettingsFile(const std::string &fname) { void Module::loadSettingsFile(const std::string &fname) {
// find specific file if it has detid in file name (.snxxx) // find specific file if it has detid in file name (.snxxx)
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) { if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
std::ostringstream ostfn; std::ostringstream ostfn;
ostfn << fname; ostfn << fname;
if (fname.find(".sn") == std::string::npos && int serialNumberWidth = 3;
fname.find(".trim") == std::string::npos && if (shm()->myDetectorType == MYTHEN3) {
fname.find(".settings") == std::string::npos) { serialNumberWidth = 4;
ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec }
<< getSerialNumber(); if (fname.find(".sn") == std::string::npos) {
ostfn << ".sn" << std::setfill('0') << std::setw(serialNumberWidth)
<< std::dec << getSerialNumber();
} }
auto myMod = readSettingsFile(ostfn.str()); auto myMod = readSettingsFile(ostfn.str());
setModule(myMod); setModule(myMod);
@ -178,6 +399,30 @@ void Module::setAllTrimbits(int val) {
sendToDetector<int>(F_SET_ALL_TRIMBITS, val); sendToDetector<int>(F_SET_ALL_TRIMBITS, val);
} }
std::vector<int> Module::getTrimEn() const {
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
throw RuntimeError("getTrimEn not implemented for this detector.");
}
return std::vector<int>(shm()->trimEnergies.begin(),
shm()->trimEnergies.end());
}
int Module::setTrimEn(const std::vector<int> &energies) {
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
throw RuntimeError("setTrimEn not implemented for this detector.");
}
if (energies.size() > MAX_TRIMEN) {
std::ostringstream os;
os << "Size of trim energies: " << energies.size()
<< " exceeds what can be stored in shared memory: " << MAX_TRIMEN
<< "\n";
throw RuntimeError(os.str());
}
shm()->trimEnergies = energies;
std::sort(shm()->trimEnergies.begin(), shm()->trimEnergies.end());
return shm()->trimEnergies.size();
}
bool Module::isVirtualDetectorServer() const { bool Module::isVirtualDetectorServer() const {
return sendToDetector<int>(F_IS_VIRTUAL); return sendToDetector<int>(F_IS_VIRTUAL);
} }
@ -1095,33 +1340,6 @@ void Module::setSubDeadTime(int64_t value) {
} }
} }
int Module::getThresholdEnergy() const {
return sendToDetector<int>(F_GET_THRESHOLD_ENERGY);
}
void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits) {
// check as there is client processing
if (shm()->myDetectorType == EIGER) {
setThresholdEnergyAndSettings(e_eV, isettings, trimbits);
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_THRESHOLD, e_eV, nullptr);
}
} else {
throw RuntimeError(
"Set threshold energy not implemented for this detector");
}
}
std::string Module::getSettingsDir() const {
return std::string(shm()->settingsDir);
}
std::string Module::setSettingsDir(const std::string &dir) {
sls::strcpy_safe(shm()->settingsDir, dir.c_str());
return shm()->settingsDir;
}
bool Module::getOverFlowMode() const { bool Module::getOverFlowMode() const {
return sendToDetector<int>(F_GET_OVERFLOW_MODE); return sendToDetector<int>(F_GET_OVERFLOW_MODE);
} }
@ -1138,29 +1356,6 @@ void Module::setFlippedDataX(bool value) {
sendToReceiver<int>(F_SET_FLIPPED_DATA_RECEIVER, static_cast<int>(value)); sendToReceiver<int>(F_SET_FLIPPED_DATA_RECEIVER, static_cast<int>(value));
} }
std::vector<int> Module::getTrimEn() const {
if (shm()->myDetectorType != EIGER) {
throw RuntimeError("getTrimEn not implemented for this detector.");
}
return std::vector<int>(shm()->trimEnergies.begin(),
shm()->trimEnergies.end());
}
int Module::setTrimEn(const std::vector<int> &energies) {
if (shm()->myDetectorType != EIGER) {
throw RuntimeError("setTrimEn not implemented for this detector.");
}
if (energies.size() > MAX_TRIMEN) {
std::ostringstream os;
os << "Size of trim energies: " << energies.size()
<< " exceeds what can be stored in shared memory: " << MAX_TRIMEN
<< "\n";
throw RuntimeError(os.str());
}
shm()->trimEnergies = energies;
return shm()->trimEnergies.size();
}
int64_t Module::getRateCorrection() const { int64_t Module::getRateCorrection() const {
return sendToDetector<int64_t>(F_GET_RATE_CORRECT); return sendToDetector<int64_t>(F_GET_RATE_CORRECT);
} }
@ -2749,9 +2944,9 @@ int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) {
ts += n; ts += n;
LOG(level) << "tau sent. " << n << " bytes. tau: " << myMod->tau; LOG(level) << "tau sent. " << n << " bytes. tau: " << myMod->tau;
n = client.Send(&(myMod->eV), sizeof(myMod->eV)); n = client.Send(myMod->eV, sizeof(myMod->eV));
ts += n; ts += n;
LOG(level) << "ev sent. " << n << " bytes. ev: " << myMod->eV; LOG(level) << "ev sent. " << n << " bytes. ev: " << ToString(myMod->eV);
n = client.Send(myMod->dacs, sizeof(int) * (myMod->ndac)); n = client.Send(myMod->dacs, sizeof(int) * (myMod->ndac));
ts += n; ts += n;
@ -2799,68 +2994,12 @@ void Module::updateRateCorrection() {
sendToDetector(F_UPDATE_RATE_CORRECTION); sendToDetector(F_UPDATE_RATE_CORRECTION);
} }
void Module::setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings,
bool trimbits) {
// verify e_eV exists in trimEneregies[]
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
(e_eV > shm()->trimEnergies.back())) {
throw RuntimeError("This energy " + std::to_string(e_eV) +
" not defined for this module!");
}
bool interpolate =
std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(),
[e_eV](const int &e) { return e != e_eV; });
sls_detector_module myMod{shm()->myDetectorType};
if (!interpolate) {
std::string settingsfname = getTrimbitFilename(isettings, e_eV);
LOG(logDEBUG1) << "Settings File is " << settingsfname;
myMod = readSettingsFile(settingsfname, trimbits);
} else {
// find the trim values
int trim1 = -1, trim2 = -1;
for (size_t i = 0; i < shm()->trimEnergies.size(); ++i) {
if (e_eV < shm()->trimEnergies[i]) {
trim2 = shm()->trimEnergies[i];
trim1 = shm()->trimEnergies[i - 1];
break;
}
}
std::string settingsfname1 = getTrimbitFilename(isettings, trim1);
std::string settingsfname2 = getTrimbitFilename(isettings, trim2);
LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and "
<< settingsfname2;
auto myMod1 = readSettingsFile(settingsfname1, trimbits);
auto myMod2 = readSettingsFile(settingsfname2, trimbits);
if (myMod1.iodelay != myMod2.iodelay) {
throw RuntimeError("setThresholdEnergyAndSettings: Iodelays do not "
"match between files");
}
myMod = interpolateTrim(&myMod1, &myMod2, e_eV, trim1, trim2, trimbits);
myMod.iodelay = myMod1.iodelay;
myMod.tau =
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
}
myMod.reg = isettings;
myMod.eV = e_eV;
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
}
}
sls_detector_module Module::interpolateTrim(sls_detector_module *a, sls_detector_module Module::interpolateTrim(sls_detector_module *a,
sls_detector_module *b, sls_detector_module *b,
const int energy, const int e1, const int energy, const int e1,
const int e2, bool trimbits) { const int e2, bool trimbits) {
// dacs specified only for eiger and mythen3
// only implemented for eiger currently (in terms of which dacs) if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
if (shm()->myDetectorType != EIGER) {
throw NotImplementedError( throw NotImplementedError(
"Interpolation of Trim values not implemented for this detector!"); "Interpolation of Trim values not implemented for this detector!");
} }
@ -2884,36 +3023,72 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
E_VCN, E_VCN,
E_VIS E_VIS
}; };
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
// Copy other dacs // create copy and interpolate dac lists
int dacs_to_copy[] = {E_SVP, E_VTR, E_SVN, E_VTGSTV, std::vector<int> dacs_to_copy, dacs_to_interpolate;
E_RXB_RB, E_RXB_LB, E_VCN, E_VIS}; if (shm()->myDetectorType == EIGER) {
int num_dacs_to_copy = sizeof(dacs_to_copy) / sizeof(dacs_to_copy[0]); dacs_to_copy.insert(
for (int i = 0; i < num_dacs_to_copy; ++i) { dacs_to_copy.end(),
{E_SVP, E_VTR, E_SVN, E_VTGSTV, E_RXB_RB, E_RXB_LB, E_VCN, E_VIS});
// interpolate vrf, vcmp, vcp
dacs_to_interpolate.insert(
dacs_to_interpolate.end(),
{E_VRF, E_VCMP_LL, E_VCMP_LR, E_VCMP_RL, E_VCMP_RR, E_VCP, E_VRS});
} else {
dacs_to_copy.insert(dacs_to_copy.end(),
{M_VCASSH, M_VRSHAPER, M_VRSHAPER_N, M_VIPRE_OUT,
M_VICIN, M_VCAS, M_VRPREAMP, M_VCAL_N, M_VIPRE,
M_VISHAPER, M_VCAL_P, M_VDCSH});
// interpolate vtrim, vth1, vth2, vth3
dacs_to_interpolate.insert(dacs_to_interpolate.end(),
{M_VTH1, M_VTH2, M_VTH3, M_VTRIM});
}
// Copy Dacs
for (size_t i = 0; i < dacs_to_copy.size(); ++i) {
if (a->dacs[dacs_to_copy[i]] != b->dacs[dacs_to_copy[i]]) { if (a->dacs[dacs_to_copy[i]] != b->dacs[dacs_to_copy[i]]) {
throw RuntimeError("Interpolate module: dacs different"); throw RuntimeError("Interpolate module: dacs " + std::to_string(i) +
" different");
} }
myMod.dacs[dacs_to_copy[i]] = a->dacs[dacs_to_copy[i]]; myMod.dacs[dacs_to_copy[i]] = a->dacs[dacs_to_copy[i]];
} }
// Copy irrelevant dacs (without failing): CAL // Interpolate Dacs
if (a->dacs[E_CAL] != b->dacs[E_CAL]) { for (size_t i = 0; i < dacs_to_interpolate.size(); ++i) {
LOG(logWARNING) << "DAC CAL differs in both energies ("
<< a->dacs[E_CAL] << "," << b->dacs[E_CAL]
<< ")!\nTaking first: " << a->dacs[E_CAL];
}
myMod.dacs[E_CAL] = a->dacs[E_CAL];
// Interpolate vrf, vcmp, vcp
int dacs_to_interpolate[] = {E_VRF, E_VCMP_LL, E_VCMP_LR, E_VCMP_RL,
E_VCMP_RR, E_VCP, E_VRS};
int num_dacs_to_interpolate =
sizeof(dacs_to_interpolate) / sizeof(dacs_to_interpolate[0]);
for (int i = 0; i < num_dacs_to_interpolate; ++i) {
myMod.dacs[dacs_to_interpolate[i]] = myMod.dacs[dacs_to_interpolate[i]] =
linearInterpolation(energy, e1, e2, a->dacs[dacs_to_interpolate[i]], linearInterpolation(energy, e1, e2, a->dacs[dacs_to_interpolate[i]],
b->dacs[dacs_to_interpolate[i]]); b->dacs[dacs_to_interpolate[i]]);
} }
// Copy irrelevant dacs (without failing)
if (shm()->myDetectorType == EIGER) {
// CAL
if (a->dacs[E_CAL] != b->dacs[E_CAL]) {
LOG(logWARNING)
<< "DAC CAL differs in both energies (" << a->dacs[E_CAL] << ","
<< b->dacs[E_CAL] << ")!\nTaking first: " << a->dacs[E_CAL];
}
myMod.dacs[E_CAL] = a->dacs[E_CAL];
}
// Interpolate all trimbits // Interpolate all trimbits
if (trimbits) { if (trimbits) {
for (int i = 0; i < myMod.nchan; ++i) { for (int i = 0; i < myMod.nchan; ++i) {
@ -2930,6 +3105,9 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
case STANDARD: case STANDARD:
ssettings = "/standard"; ssettings = "/standard";
break; break;
case FAST:
ssettings = "/fast";
break;
case HIGHGAIN: case HIGHGAIN:
ssettings = "/highgain"; ssettings = "/highgain";
break; break;
@ -2948,8 +3126,20 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
throw RuntimeError(ss.str()); throw RuntimeError(ss.str());
} }
std::ostringstream ostfn; std::ostringstream ostfn;
ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV" ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV";
<< "/noise.sn" << std::setfill('0') << std::setw(3) << std::dec if (shm()->myDetectorType == EIGER) {
ostfn << "/noise.sn";
} else if (shm()->myDetectorType == MYTHEN3) {
ostfn << "/trim.sn";
} else {
throw RuntimeError(
"Settings or trimbit files not defined for this detector.");
}
int serialNumberWidth = 3;
if (shm()->myDetectorType == MYTHEN3) {
serialNumberWidth = 4;
}
ostfn << std::setfill('0') << std::setw(serialNumberWidth) << std::dec
<< getSerialNumber() << std::setbase(10); << getSerialNumber() << std::setbase(10);
return ostfn.str(); return ostfn.str();
} }
@ -2976,6 +3166,11 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
infile.read(reinterpret_cast<char *>(&myMod.iodelay), infile.read(reinterpret_cast<char *>(&myMod.iodelay),
sizeof(myMod.iodelay)); sizeof(myMod.iodelay));
infile.read(reinterpret_cast<char *>(&myMod.tau), sizeof(myMod.tau)); infile.read(reinterpret_cast<char *>(&myMod.tau), sizeof(myMod.tau));
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG1) << "dac " << i << ":" << myMod.dacs[i];
}
LOG(logDEBUG1) << "iodelay:" << myMod.iodelay;
LOG(logDEBUG1) << "tau:" << myMod.tau;
if (trimbits) { if (trimbits) {
infile.read(reinterpret_cast<char *>(myMod.chanregs), infile.read(reinterpret_cast<char *>(myMod.chanregs),
sizeof(int) * (myMod.nchan)); sizeof(int) * (myMod.nchan));
@ -2985,28 +3180,24 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
"for settings for " + "for settings for " +
fname); fname);
} }
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG1) << "dac " << i << ":" << myMod.dacs[i];
}
LOG(logDEBUG1) << "iodelay:" << myMod.iodelay;
LOG(logDEBUG1) << "tau:" << myMod.tau;
} }
// mythen3 (dacs, trimbits) // mythen3 (dacs, trimbits)
else if (shm()->myDetectorType == MYTHEN3) { else if (shm()->myDetectorType == MYTHEN3) {
infile.read(reinterpret_cast<char *>(myMod.dacs), infile.read(reinterpret_cast<char *>(myMod.dacs),
sizeof(int) * (myMod.ndac)); sizeof(int) * (myMod.ndac));
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG) << "dac " << i << ":" << myMod.dacs[i];
}
if (trimbits) {
infile.read(reinterpret_cast<char *>(myMod.chanregs), infile.read(reinterpret_cast<char *>(myMod.chanregs),
sizeof(int) * (myMod.nchan)); sizeof(int) * (myMod.nchan));
}
if (!infile) { if (!infile) {
throw RuntimeError("readSettingsFile: Could not load all values " throw RuntimeError("readSettingsFile: Could not load all values "
"for settings for " + "for settings for " +
fname); fname);
} }
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG1) << "dac " << i << ":" << myMod.dacs[i];
}
} }
else { else {

View File

@ -101,9 +101,19 @@ class Module : public virtual slsDetectorDefs {
void updateNumberOfDetector(slsDetectorDefs::xy det); void updateNumberOfDetector(slsDetectorDefs::xy det);
detectorSettings getSettings() const; detectorSettings getSettings() const;
void setSettings(detectorSettings isettings); void setSettings(detectorSettings isettings);
int getThresholdEnergy() const;
std::array<int, 3> getAllThresholdEnergy() const;
void setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits);
void setAllThresholdEnergy(std::array<int, 3> e_eV,
detectorSettings isettings, bool trimbits);
std::string getSettingsDir() const;
std::string setSettingsDir(const std::string &dir);
void loadSettingsFile(const std::string &fname); void loadSettingsFile(const std::string &fname);
int getAllTrimbits() const; int getAllTrimbits() const;
void setAllTrimbits(int val); void setAllTrimbits(int val);
std::vector<int> getTrimEn() const;
int setTrimEn(const std::vector<int> &energies = {});
bool isVirtualDetectorServer() const; bool isVirtualDetectorServer() const;
/************************************************** /**************************************************
@ -308,17 +318,10 @@ class Module : public virtual slsDetectorDefs {
void setSubExptime(int64_t value); void setSubExptime(int64_t value);
int64_t getSubDeadTime() const; int64_t getSubDeadTime() const;
void setSubDeadTime(int64_t value); void setSubDeadTime(int64_t value);
int getThresholdEnergy() const;
void setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits);
std::string getSettingsDir() const;
std::string setSettingsDir(const std::string &dir);
bool getOverFlowMode() const; bool getOverFlowMode() const;
void setOverFlowMode(const bool enable); void setOverFlowMode(const bool enable);
bool getFlippedDataX() const; bool getFlippedDataX() const;
void setFlippedDataX(bool value); void setFlippedDataX(bool value);
std::vector<int> getTrimEn() const;
int setTrimEn(const std::vector<int> &energies = {});
int64_t getRateCorrection() const; int64_t getRateCorrection() const;
void setDefaultRateCorrection(); void setDefaultRateCorrection();
void setRateCorrection(int64_t t = 0); void setRateCorrection(int64_t t = 0);
@ -680,8 +683,6 @@ class Module : public virtual slsDetectorDefs {
void updateReceiverStreamingIP(); void updateReceiverStreamingIP();
void updateRateCorrection(); void updateRateCorrection();
void setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings,
bool trimbits = true);
/** Template function to do linear interpolation between two points (Eiger /** Template function to do linear interpolation between two points (Eiger
only) */ only) */
template <typename E, typename V> template <typename E, typename V>

View File

@ -319,80 +319,6 @@ TEST_CASE("subdeadtime", "[.cmd]") {
} }
} }
TEST_CASE("threshold", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::ostringstream oss1, oss2;
proxy.Call("threshold", {"4500", "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [4500, standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold 4500\n");
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("threshold", {}, -1, GET));
}
}
TEST_CASE("thresholdnotb", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::ostringstream oss1, oss2;
proxy.Call("thresholdnotb", {"4500 standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "thresholdnotb [4500 standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold 4500\n");
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
false, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("thresholdnotb", {}, -1, GET));
}
}
TEST_CASE("settingspath", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getSettingsPath();
{
std::ostringstream oss1, oss2;
proxy.Call("settingspath", {"/tmp"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "settingspath /tmp\n");
proxy.Call("settingspath", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "settingspath /tmp\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setSettingsPath(prev_val[i], {i});
}
}
TEST_CASE("overflow", "[.cmd]") { TEST_CASE("overflow", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
@ -435,27 +361,6 @@ TEST_CASE("flippeddatax", "[.cmd]") {
} }
} }
TEST_CASE("trimen", "[.cmd][.this]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto previous = det.getTrimEnergies();
std::ostringstream oss1, oss2;
proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "trimen [4500, 5400, 6400]\n");
proxy.Call("trimen", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "trimen [4500, 5400, 6400]\n");
for (int i = 0; i != det.size(); ++i) {
det.setTrimEnergies(previous[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("trimen", {}, -1, GET));
}
}
TEST_CASE("ratecorr", "[.cmd]") { TEST_CASE("ratecorr", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);

View File

@ -130,7 +130,7 @@ TEST_CASE("settingslist", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MYTHEN3) { if (det_type == defs::CHIPTESTBOARD) {
REQUIRE_THROWS(proxy.Call("settingslist", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("settingslist", {}, -1, GET));
} else { } else {
REQUIRE_NOTHROW(proxy.Call("settingslist", {}, -1, GET)); REQUIRE_NOTHROW(proxy.Call("settingslist", {}, -1, GET));
@ -174,6 +174,11 @@ TEST_CASE("settings", "[.cmd]") {
sett.push_back("g4_hg"); sett.push_back("g4_hg");
sett.push_back("g4_lg"); sett.push_back("g4_lg");
break; break;
case defs::MYTHEN3:
sett.push_back("standard");
sett.push_back("fast");
sett.push_back("highgain");
break;
default: default:
if (det_type == defs::EIGER) { if (det_type == defs::EIGER) {
// FIXME: need to remove when settings removed // FIXME: need to remove when settings removed
@ -206,6 +211,181 @@ TEST_CASE("settings", "[.cmd]") {
} }
} }
TEST_CASE("threshold", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("threshold", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold " + senergy + "\n");
REQUIRE_THROWS(proxy.Call(
"threshold", {senergy, senergy, senergy, "standard"}, -1, PUT));
REQUIRE_THROWS(
proxy.Call("threshold", {senergy, "undefined"}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else if (det_type == defs::MYTHEN3) {
auto prev_threshold = det.getAllThresholdEnergy();
auto prev_settings =
det.getSettings().tsquash("inconsistent settings to test");
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("threshold", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold [" + senergy + ", " + senergy +
", " + senergy + "]\n");
std::string senergy2 = std::to_string(prev_energies[1]);
std::string senergy3 = std::to_string(prev_energies[2]);
std::ostringstream oss3, oss4;
proxy.Call("threshold", {senergy, senergy2, senergy3, "standard"},
-1, PUT, oss3);
REQUIRE(oss3.str() == "threshold [" + senergy + ", " + senergy2 +
", " + senergy3 + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss4);
REQUIRE(oss4.str() == "threshold [" + senergy + ", " + senergy2 +
", " + senergy3 + "]\n");
REQUIRE_THROWS(proxy.Call("threshold",
{senergy, senergy, "standard"}, -1, PUT));
REQUIRE_THROWS(
proxy.Call("threshold", {senergy, "undefined"}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("threshold", {senergy}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("threshold",
{senergy, senergy2, senergy3}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i][0] >= 0) {
std::cout
<< "prev cvalues:" << sls::ToString(prev_threshold[i])
<< std::endl;
det.setThresholdEnergy(prev_threshold[i], prev_settings,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("threshold", {}, -1, GET));
}
}
TEST_CASE("thresholdnotb", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("thresholdnotb", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold " + senergy + "\n");
REQUIRE_THROWS(proxy.Call("thresholdnotb",
{senergy, senergy, senergy, "standard"},
-1, PUT));
REQUIRE_THROWS(
proxy.Call("thresholdnotb", {senergy, "undefined"}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
false, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else if (det_type == defs::MYTHEN3) {
auto prev_threshold = det.getAllThresholdEnergy();
auto prev_settings =
det.getSettings().tsquash("inconsistent settings to test");
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("thresholdnotb", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() ==
"thresholdnotb [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold [" + senergy + ", " + senergy +
", " + senergy + "]\n");
std::string senergy2 = std::to_string(prev_energies[1]);
std::string senergy3 = std::to_string(prev_energies[2]);
std::ostringstream oss3, oss4;
proxy.Call("thresholdnotb",
{senergy, senergy2, senergy3, "standard"}, -1, PUT,
oss3);
REQUIRE(oss3.str() == "thresholdnotb [" + senergy + ", " +
senergy2 + ", " + senergy3 +
", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss4);
REQUIRE(oss4.str() == "threshold [" + senergy + ", " + senergy2 +
", " + senergy3 + "]\n");
REQUIRE_THROWS(proxy.Call("thresholdnotb",
{senergy, senergy, "standard"}, -1, PUT));
REQUIRE_THROWS(
proxy.Call("thresholdnotb", {senergy, "undefined"}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("thresholdnotb", {senergy}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("thresholdnotb",
{senergy, senergy2, senergy3}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i][0] >= 0) {
det.setThresholdEnergy(prev_threshold[i], prev_settings,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("thresholdnotb", {}, -1, GET));
}
}
TEST_CASE("settingspath", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getSettingsPath();
{
std::ostringstream oss1, oss2;
proxy.Call("settingspath", {"/tmp"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "settingspath /tmp\n");
proxy.Call("settingspath", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "settingspath /tmp\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setSettingsPath(prev_val[i], {i});
}
}
TEST_CASE("trimbits", "[.cmd]") { TEST_CASE("trimbits", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
@ -246,6 +426,65 @@ TEST_CASE("trimval", "[.cmd]") {
} }
} }
TEST_CASE("trimen", "[.cmd][.this]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER || det_type == defs::MYTHEN3) {
auto previous = det.getTrimEnergies();
std::ostringstream oss1, oss2;
proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "trimen [4500, 5400, 6400]\n");
proxy.Call("trimen", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "trimen [4500, 5400, 6400]\n");
for (int i = 0; i != det.size(); ++i) {
det.setTrimEnergies(previous[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("trimen", {}, -1, GET));
}
}
TEST_CASE("gappixels", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
auto prev_val = det.getGapPixelsinCallback();
{
std::ostringstream oss;
proxy.Call("gappixels", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 1\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
det.setGapPixelsinCallback(prev_val);
} else {
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
REQUIRE_THROWS(proxy.Call("gappixels", {"1"}, -1, PUT));
}
}
/* acquisition parameters */ /* acquisition parameters */
// acquire: not testing // acquire: not testing
@ -1510,44 +1749,6 @@ TEST_CASE("scanerrmsg", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("scanerrmsg", {""}, -1, PUT)); REQUIRE_THROWS(proxy.Call("scanerrmsg", {""}, -1, PUT));
} }
TEST_CASE("gappixels", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
auto prev_val = det.getGapPixelsinCallback();
{
std::ostringstream oss;
proxy.Call("gappixels", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 1\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
det.setGapPixelsinCallback(prev_val);
} else {
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
REQUIRE_THROWS(proxy.Call("gappixels", {"1"}, -1, PUT));
}
}
/* Network Configuration (Detector<->Receiver) */ /* Network Configuration (Detector<->Receiver) */
TEST_CASE("numinterfaces", "[.cmd]") { TEST_CASE("numinterfaces", "[.cmd]") {

View File

@ -208,6 +208,7 @@ int ClientInterface::functionTable(){
flist[F_RECEIVER_SET_THRESHOLD] = &ClientInterface::set_threshold; flist[F_RECEIVER_SET_THRESHOLD] = &ClientInterface::set_threshold;
flist[F_GET_RECEIVER_STREAMING_HWM] = &ClientInterface::get_streaming_hwm; flist[F_GET_RECEIVER_STREAMING_HWM] = &ClientInterface::get_streaming_hwm;
flist[F_SET_RECEIVER_STREAMING_HWM] = &ClientInterface::set_streaming_hwm; flist[F_SET_RECEIVER_STREAMING_HWM] = &ClientInterface::set_streaming_hwm;
flist[F_RECEIVER_SET_ALL_THRESHOLD] = &ClientInterface::set_all_threshold;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" << LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -408,7 +409,14 @@ int ClientInterface::setup_receiver(Interface &socket) {
" due to fifo strucutre memory allocation"); " due to fifo strucutre memory allocation");
} }
impl()->setReadNLines(arg.numLinesReadout); impl()->setReadNLines(arg.numLinesReadout);
impl()->setThresholdEnergy(arg.thresholdEnergyeV); impl()->setThresholdEnergy(arg.thresholdEnergyeV[0]);
}
if (myDetectorType == MYTHEN3) {
std::array<int, 3> val;
for (int i = 0; i < 3; ++i) {
val[i] = arg.thresholdEnergyeV[i];
}
impl()->setThresholdEnergy(val);
} }
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) { if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
try { try {
@ -1677,3 +1685,13 @@ int ClientInterface::set_streaming_hwm(Interface &socket) {
impl()->setStreamingHwm(limit); impl()->setStreamingHwm(limit);
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::set_all_threshold(Interface &socket) {
auto eVs = socket.Receive<std::array<int, 3>>();
LOG(logDEBUG) << "Threshold:" << sls::ToString(eVs);
if (myDetectorType != MYTHEN3)
functionNotImplemented();
verifyIdle(socket);
impl()->setThresholdEnergy(eVs);
return socket.Send(OK);
}

View File

@ -161,6 +161,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_threshold(sls::ServerInterface &socket); int set_threshold(sls::ServerInterface &socket);
int get_streaming_hwm(sls::ServerInterface &socket); int get_streaming_hwm(sls::ServerInterface &socket);
int set_streaming_hwm(sls::ServerInterface &socket); int set_streaming_hwm(sls::ServerInterface &socket);
int set_all_threshold(sls::ServerInterface &socket);
Implementation *impl() { Implementation *impl() {
if (receiver != nullptr) { if (receiver != nullptr) {

View File

@ -758,6 +758,7 @@ void Implementation::SetupWriter() {
masterAttributes->dynamicRange = dynamicRange; masterAttributes->dynamicRange = dynamicRange;
masterAttributes->tenGiga = tengigaEnable; masterAttributes->tenGiga = tengigaEnable;
masterAttributes->thresholdEnergyeV = thresholdEnergyeV; masterAttributes->thresholdEnergyeV = thresholdEnergyeV;
masterAttributes->thresholdAllEnergyeV = thresholdAllEnergyeV;
masterAttributes->subExptime = subExpTime; masterAttributes->subExptime = subExpTime;
masterAttributes->subPeriod = subPeriod; masterAttributes->subPeriod = subPeriod;
masterAttributes->quad = quadEnable; masterAttributes->quad = quadEnable;
@ -1533,6 +1534,12 @@ void Implementation::setThresholdEnergy(const int value) {
LOG(logINFO) << "Threshold Energy: " << thresholdEnergyeV << " eV"; LOG(logINFO) << "Threshold Energy: " << thresholdEnergyeV << " eV";
} }
void Implementation::setThresholdEnergy(const std::array<int, 3> value) {
thresholdAllEnergyeV = value;
LOG(logINFO) << "Threshold Energy (eV): "
<< sls::ToString(thresholdAllEnergyeV);
}
void Implementation::setRateCorrections(const std::vector<int64_t> &t) { void Implementation::setRateCorrections(const std::vector<int64_t> &t) {
rateCorrections = t; rateCorrections = t;
LOG(logINFO) << "Rate Corrections: " << sls::ToString(rateCorrections); LOG(logINFO) << "Rate Corrections: " << sls::ToString(rateCorrections);

View File

@ -219,6 +219,7 @@ class Implementation : private virtual slsDetectorDefs {
void setReadNLines(const int value); void setReadNLines(const int value);
/** [Eiger] */ /** [Eiger] */
void setThresholdEnergy(const int value); void setThresholdEnergy(const int value);
void setThresholdEnergy(const std::array<int, 3> value);
/* [Eiger] */ /* [Eiger] */
void setRateCorrections(const std::vector<int64_t> &t); void setRateCorrections(const std::vector<int64_t> &t);
readoutMode getReadoutMode() const; readoutMode getReadoutMode() const;
@ -348,6 +349,7 @@ class Implementation : private virtual slsDetectorDefs {
bool deactivatedPaddingEnable{true}; bool deactivatedPaddingEnable{true};
int numLinesReadout{MAX_EIGER_ROWS_PER_READOUT}; int numLinesReadout{MAX_EIGER_ROWS_PER_READOUT};
int thresholdEnergyeV{-1}; int thresholdEnergyeV{-1};
std::array<int, 3> thresholdAllEnergyeV={{-1, -1, -1}};
std::vector<int64_t> rateCorrections; std::vector<int64_t> rateCorrections;
readoutMode readoutType{ANALOG_ONLY}; readoutMode readoutType{ANALOG_ONLY};
uint32_t adcEnableMaskOneGiga{BIT32_MASK}; uint32_t adcEnableMaskOneGiga{BIT32_MASK};

View File

@ -36,6 +36,7 @@ struct MasterAttributes {
uint32_t dynamicRange{0}; uint32_t dynamicRange{0};
uint32_t tenGiga{0}; uint32_t tenGiga{0};
int thresholdEnergyeV{0}; int thresholdEnergyeV{0};
std::array<int, 3> thresholdAllEnergyeV={{0, 0, 0}};
ns subExptime{0}; ns subExptime{0};
ns subPeriod{0}; ns subPeriod{0};
uint32_t quad{0}; uint32_t quad{0};
@ -353,6 +354,7 @@ class EigerMasterAttributes : public MasterAttributes {
<< "Ten Giga : " << tenGiga << '\n' << "Ten Giga : " << tenGiga << '\n'
<< "Exptime : " << sls::ToString(exptime) << '\n' << "Exptime : " << sls::ToString(exptime) << '\n'
<< "Period : " << sls::ToString(period) << '\n' << "Period : " << sls::ToString(period) << '\n'
<< "Threshold Energy : " << thresholdEnergyeV << '\n'
<< "SubExptime : " << sls::ToString(subExptime) << "SubExptime : " << sls::ToString(subExptime)
<< '\n' << '\n'
<< "SubPeriod : " << sls::ToString(subPeriod) << "SubPeriod : " << sls::ToString(subPeriod)
@ -450,7 +452,9 @@ class Mythen3MasterAttributes : public MasterAttributes {
<< '\n' << '\n'
<< "GateDelay3 : " << sls::ToString(gateDelay3) << "GateDelay3 : " << sls::ToString(gateDelay3)
<< '\n' << '\n'
<< "Gates : " << gates << '\n'; << "Gates : " << gates << '\n'
<< "Threshold Energies : "
<< sls::ToString(thresholdAllEnergyeV) << '\n';
std::string message = oss.str(); std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message); MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
@ -523,6 +527,14 @@ class Mythen3MasterAttributes : public MasterAttributes {
group->createDataSet("Gates", PredType::STD_U32LE, dataspace); group->createDataSet("Gates", PredType::STD_U32LE, dataspace);
dataset.write(&gates, PredType::STD_U32LE); dataset.write(&gates, PredType::STD_U32LE);
} }
// Threshold Energies
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 1024);
DataSet dataset = group->createDataSet("Threshold Energies",
strdatatype, dataspace);
dataset.write(sls::ToString(thresholdAllEnergyeV), strdatatype);
}
}; };
#endif #endif
}; };

View File

@ -100,6 +100,12 @@ template <typename T, size_t Capacity> class StaticVector {
constexpr const T &front() const noexcept { return data_.front(); } constexpr const T &front() const noexcept { return data_.front(); }
constexpr const T &back() const noexcept { return data_[current_size - 1]; } constexpr const T &back() const noexcept { return data_[current_size - 1]; }
bool anyEqualTo(const T value) {
return std::any_of(
data_.cbegin(), data_.cend(),
[value](const T &element) { return element == value; });
}
// iterators // iterators
iterator begin() noexcept { return data_.begin(); } iterator begin() noexcept { return data_.begin(); }
// auto begin() noexcept -> decltype(data_.begin()) { return data_.begin(); // auto begin() noexcept -> decltype(data_.begin()) { return data_.begin();

View File

@ -454,7 +454,7 @@ typedef struct {
int activate{0}; int activate{0};
int quad{0}; int quad{0};
int numLinesReadout{0}; int numLinesReadout{0};
int thresholdEnergyeV{0}; int thresholdEnergyeV[3]{0, 0, 0};
int dynamicRange{16}; int dynamicRange{16};
timingMode timMode{AUTO_TIMING}; timingMode timMode{AUTO_TIMING};
int tenGiga{0}; int tenGiga{0};
@ -571,14 +571,14 @@ typedef struct {
int reg; /**< is the module register settings (gain level) */ int reg; /**< is the module register settings (gain level) */
int iodelay; /**< iodelay */ int iodelay; /**< iodelay */
int tau; /**< tau */ int tau; /**< tau */
int eV; /**< threshold energy */ int eV[3]; /**< threshold energy */
int *dacs; /**< is the pointer to the array of the dac values (in V) */ int *dacs; /**< is the pointer to the array of the dac values (in V) */
int *chanregs; /**< is the pointer to the array of the channel registers */ int *chanregs; /**< is the pointer to the array of the channel registers */
#ifdef __cplusplus #ifdef __cplusplus
sls_detector_module() sls_detector_module()
: serialnumber(0), nchan(0), nchip(0), ndac(0), reg(-1), iodelay(0), : serialnumber(0), nchan(0), nchip(0), ndac(0), reg(-1), iodelay(0),
tau(0), eV(-1), dacs(nullptr), chanregs(nullptr) {} tau(0), eV{-1, -1, -1}, dacs(nullptr), chanregs(nullptr) {}
explicit sls_detector_module(slsDetectorDefs::detectorType type) explicit sls_detector_module(slsDetectorDefs::detectorType type)
: sls_detector_module() { : sls_detector_module() {
@ -607,7 +607,7 @@ typedef struct {
reg = other.reg; reg = other.reg;
iodelay = other.iodelay; iodelay = other.iodelay;
tau = other.tau; tau = other.tau;
eV = other.eV; std::copy(other.eV, other.eV + 3, eV);
dacs = new int[ndac]; dacs = new int[ndac];
std::copy(other.dacs, other.dacs + ndac, dacs); std::copy(other.dacs, other.dacs + ndac, dacs);
chanregs = new int[nchan]; chanregs = new int[nchan];

View File

@ -219,6 +219,7 @@ enum detFuncs {
F_IS_VIRTUAL, F_IS_VIRTUAL,
F_GET_PATTERN, F_GET_PATTERN,
F_LOAD_DEFAULT_PATTERN, F_LOAD_DEFAULT_PATTERN,
F_GET_ALL_THRESHOLD_ENERGY,
NUM_DET_FUNCTIONS, NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
@ -322,6 +323,7 @@ enum detFuncs {
F_RECEIVER_SET_THRESHOLD, F_RECEIVER_SET_THRESHOLD,
F_GET_RECEIVER_STREAMING_HWM, F_GET_RECEIVER_STREAMING_HWM,
F_SET_RECEIVER_STREAMING_HWM, F_SET_RECEIVER_STREAMING_HWM,
F_RECEIVER_SET_ALL_THRESHOLD,
NUM_REC_FUNCTIONS NUM_REC_FUNCTIONS
}; };
@ -543,6 +545,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_IS_VIRTUAL: return "F_IS_VIRTUAL"; case F_IS_VIRTUAL: return "F_IS_VIRTUAL";
case F_GET_PATTERN: return "F_GET_PATTERN"; case F_GET_PATTERN: return "F_GET_PATTERN";
case F_LOAD_DEFAULT_PATTERN: return "F_LOAD_DEFAULT_PATTERN"; case F_LOAD_DEFAULT_PATTERN: return "F_LOAD_DEFAULT_PATTERN";
case F_GET_ALL_THRESHOLD_ENERGY: return "F_GET_ALL_THRESHOLD_ENERGY";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
@ -645,6 +648,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_RECEIVER_SET_THRESHOLD: return "F_RECEIVER_SET_THRESHOLD"; case F_RECEIVER_SET_THRESHOLD: return "F_RECEIVER_SET_THRESHOLD";
case F_GET_RECEIVER_STREAMING_HWM: return "F_GET_RECEIVER_STREAMING_HWM"; case F_GET_RECEIVER_STREAMING_HWM: return "F_GET_RECEIVER_STREAMING_HWM";
case F_SET_RECEIVER_STREAMING_HWM: return "F_SET_RECEIVER_STREAMING_HWM"; case F_SET_RECEIVER_STREAMING_HWM: return "F_SET_RECEIVER_STREAMING_HWM";
case F_RECEIVER_SET_ALL_THRESHOLD: return "F_RECEIVER_SET_ALL_THRESHOLD";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";

View File

@ -3,10 +3,10 @@
#define APILIB 0x201119 #define APILIB 0x201119
#define APIRECEIVER 0x201119 #define APIRECEIVER 0x201119
#define APIGUI 0x201119 #define APIGUI 0x201119
#define APICTB 0x201130 #define APICTB 0x201214
#define APIGOTTHARD 0x201130 #define APIGOTTHARD 0x201214
#define APIJUNGFRAU 0x201130 #define APIGOTTHARD2 0x201214
#define APIEIGER 0x201130 #define APIJUNGFRAU 0x201214
#define APIGOTTHARD2 0x201208 #define APIMOENCH 0x201214
#define APIMOENCH 0x201207 #define APIEIGER 0x201214
#define APIMYTHEN3 0x201209 #define APIMYTHEN3 0x201214

View File

@ -54,7 +54,7 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) {
<< "activate:" << r.activate << std::endl << "activate:" << r.activate << std::endl
<< "quad:" << r.quad << std::endl << "quad:" << r.quad << std::endl
<< "numLinesReadout:" << r.numLinesReadout << std::endl << "numLinesReadout:" << r.numLinesReadout << std::endl
<< "thresholdEnergyeV:" << r.thresholdEnergyeV << std::endl << "thresholdEnergyeV:" << ToString(r.thresholdEnergyeV) << std::endl
<< "dynamicRange:" << r.dynamicRange << std::endl << "dynamicRange:" << r.dynamicRange << std::endl
<< "timMode:" << r.timMode << std::endl << "timMode:" << r.timMode << std::endl
<< "tenGiga:" << r.tenGiga << std::endl << "tenGiga:" << r.tenGiga << std::endl

View File

@ -12,7 +12,9 @@ TEST_CASE("sls_detector_module default construction", "[support][new]") {
CHECK(m.reg == -1); CHECK(m.reg == -1);
CHECK(m.iodelay == 0); CHECK(m.iodelay == 0);
CHECK(m.tau == 0); CHECK(m.tau == 0);
CHECK(m.eV == -1); CHECK(m.eV[0] == -1);
CHECK(m.eV[1] == -1);
CHECK(m.eV[2] == -1);
CHECK(m.dacs == nullptr); CHECK(m.dacs == nullptr);
CHECK(m.chanregs == nullptr); CHECK(m.chanregs == nullptr);
} }
@ -26,7 +28,9 @@ TEST_CASE("sls_detector_module from type", "[support]") {
CHECK(m.reg == -1); CHECK(m.reg == -1);
CHECK(m.iodelay == 0); CHECK(m.iodelay == 0);
CHECK(m.tau == 0); CHECK(m.tau == 0);
CHECK(m.eV == -1); CHECK(m.eV[0] == -1);
CHECK(m.eV[1] == -1);
CHECK(m.eV[2] == -1);
CHECK(m.dacs != nullptr); CHECK(m.dacs != nullptr);
CHECK(m.chanregs != nullptr); CHECK(m.chanregs != nullptr);
} }

View File

@ -30,6 +30,8 @@ fi
echo "this_path="$THIS_PATH echo "this_path="$THIS_PATH
export PATH=$THIS_PATH:$PATH export PATH=$THIS_PATH:$PATH
export LD_LIBRARY_PATH=$THIS_PATH:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=$THIS_PATH:$LD_LIBRARY_PATH
export PYTHONPATH=$THIS_PATH:$PYTHONPATH
echo "path="$PATH echo "path="$PATH
echo "ld_library_path="$LD_LIBRARY_PATH echo "ld_library_path="$LD_LIBRARY_PATH
echo "pythonpath="$PYTHON_PATH