slsDetectorPackage/integrationTests/test-integrationDectector.cpp
Dhanya Thattil d2c4827b31
increasing default rx tcp port (#562)
* increasing rx tcp port by default when creating shm
2022-10-18 15:24:04 +02:00

523 lines
16 KiB
C++

// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "catch.hpp"
#include "DetectorImpl.h"
#include "Module.h"
#include "sls/ClientSocket.h"
#include "sls/logger.h"
#include "sls/sls_detector_defs.h"
#include "sls/Timer.h"
#include "sls/sls_detector_funcs.h"
#include <iostream>
#include <vector>
#define VERBOSE
// Header holding all configurations for different detectors
#include "tests/config.h"
#include "tests/globals.h"
// using namespace test;
// using dt = slsDetectorDefs::detectorType;
// extern std::string hostname;
// extern std::string detector_type;
// extern dt type;
namespace sls {
TEST_CASE("Single detector no receiver", "[.integration][.single]") {
auto t = Module::getTypeFromDetector(test::hostname);
CHECK(t == test::type);
Module d(t);
CHECK(d.getDetectorTypeAsEnum() == t);
CHECK(d.getDetectorTypeAsString() == test::detector_type);
d.setHostname(test::hostname);
CHECK(d.getHostname() == test::hostname);
CHECK(d.setDetectorType() == test::type);
d.freeSharedMemory();
}
TEST_CASE("Set control port then create a new object with this control port",
"[.integration][.single]") {
/*
TODO!
Standard port but should not be hardcoded
Is this the best way to initialize the detectors
Using braces to make the object go out of scope
*/
int old_cport = DEFAULT_TCP_CNTRL_PORTNO;
int old_sport = DEFAULT_TCP_STOP_PORTNO;
int new_cport = 1993;
int new_sport = 2000;
{
Module d(test::type);
d.setHostname(test::hostname);
CHECK(d.getControlPort() == old_cport);
d.setControlPort(new_cport);
CHECK(d.getStopPort() == old_sport);
d.setStopPort(new_sport);
d.freeSharedMemory();
}
{
Module d(test::type);
d.setHostname(test::hostname);
d.setControlPort(new_cport);
d.setStopPort(new_sport);
CHECK(d.getControlPort() == new_cport);
CHECK(d.getStopPort() == new_sport);
// Reset standard ports
d.setControlPort(old_cport);
d.setStopPort(old_sport);
d.freeSharedMemory();
}
Module d(test::type);
d.setHostname(test::hostname);
CHECK(d.getStopPort() == DEFAULT_TCP_STOP_PORTNO);
d.freeSharedMemory();
}
TEST_CASE("single EIGER detector no receiver basic set and get",
"[.integration][eiger]") {
// TODO! this test should take command line arguments for config
SingleDetectorConfig c;
// Read type by connecting to the detector
auto type = Module::getTypeFromDetector(c.hostname);
CHECK(type == c.type_enum);
// Create Module of said type and set hostname and detector online
Module d(type);
CHECK(d.getDetectorTypeAsEnum() == type);
CHECK(d.getDetectorTypeAsString() == c.type_string);
d.setHostname(c.hostname);
CHECK(d.getHostname() == c.hostname);
CHECK(d.getUseReceiverFlag() == false);
CHECK_NOTHROW(d.checkDetectorVersionCompatibility());
// Setting and reading exposure time
auto t = 1000000000;
d.setExptime(t);
CHECK(d.getExptime() == t);
// size of an eiger half module with and without gap pixels
CHECK(d.getTotalNumberOfChannels() == 256 * 256 * 4);
CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::X) == 1024);
CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::Y) == 256);
// CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getTotalNumberOfChannelsInclGapPixels(
slsDetectorDefs::dimension::X) == 1024);
CHECK(d.getTotalNumberOfChannelsInclGapPixels(
slsDetectorDefs::dimension::Y) == 256);
// CHECK(d.getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::dimension::Z)
// == 1);
CHECK(d.getNChans() == 256 * 256);
CHECK(d.getNChans(slsDetectorDefs::dimension::X) == 256);
CHECK(d.getNChans(slsDetectorDefs::dimension::Y) == 256);
// CHECK(d.getNChans(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getNChips() == 4);
CHECK(d.getNChips(slsDetectorDefs::dimension::X) == 4);
CHECK(d.getNChips(slsDetectorDefs::dimension::Y) == 1);
// CHECK(d.getNChips(slsDetectorDefs::dimension::Z) == 1);
d.freeSharedMemory();
}
TEST_CASE("Locking mechanism and last ip", "[.integration][.single]") {
Module d(test::type);
d.setHostname(test::hostname);
// Check that detector server is unlocked then lock
CHECK(d.lockServer() == 0);
d.lockServer(1);
CHECK(d.lockServer() == 1);
// Can we still access the detector while it's locked
auto t = 1300000000;
d.setExptime(t);
CHECK(d.getExptime() == t);
// unlock again and free
d.lockServer(0);
CHECK(d.lockServer() == 0);
CHECK(d.getLastClientIP() == test::my_ip);
d.freeSharedMemory();
}
TEST_CASE("Set settings", "[.integration][.single]") {
Module d(test::type);
d.setHostname(test::hostname);
CHECK(d.setSettings(defs::STANDARD) == defs::STANDARD);
}
TEST_CASE("Timer functions", "[.integration][cli]") {
// FRAME_NUMBER, /**< number of real time frames: total number of
// acquisitions is number or frames*number of triggers */ ACQUISITION_TIME,
// /**< exposure time */ FRAME_PERIOD, /**< period between exposures */
// DELAY_AFTER_TRIGGER, /**< delay between trigger and start of exposure or
// readout (in triggered mode) */ GATES_NUMBER, /**< number of gates per
// frame (in gated mode) */ TRIGGER_NUMBER, /**< number of triggers: total
// number of acquisitions is number or frames*number of triggers */
// ACTUAL_TIME, /**< Actual time of the detector's internal timer */
// MEASUREMENT_TIME, /**< Time of the measurement from the detector (fifo)
// */
// PROGRESS, /**< fraction of measurement elapsed - only get! */
// MEASUREMENTS_NUMBER,
// FRAMES_FROM_START,
// FRAMES_FROM_START_PG,
// SAMPLES,
// SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */
// STORAGE_CELL_NUMBER, /**<number of storage cells */
// SUBFRAME_DEADTIME, /**< subframe deadtime */
// MEASURED_PERIOD, /**< measured period */
// MEASURED_SUBPERIOD, /**< measured subperiod */
// MAX_TIMERS
Module d(test::type);
d.setHostname(test::hostname);
// Number of frames
auto frames = 5;
d.setNumberOfFrames(frames);
CHECK(d.getNumberOfFrames() == frames);
auto exptime = 2000000000;
d.setExptime(exptime);
CHECK(d.getExptime() == exptime);
auto period = 2000000000;
d.setPeriod(period);
CHECK(d.getPeriod() == period);
if (test::type != dt::EIGER) {
auto delay = 10000;
d.setDelayAfterTrigger(delay);
CHECK(d.getDelayAfterTrigger() == delay);
}
auto triggers = 2;
d.setNumberOfTriggers(triggers);
CHECK(d.getNumberOfTriggers() == triggers);
if (test::type == dt::EIGER) {
auto subtime = 200;
d.setSubExptime(subtime);
CHECK(d.getSubExptime() == subtime);
}
// for (int i =0; i!=frames; ++i)
d.startAndReadAll();
d.freeSharedMemory();
}
// TEST_CASE("Aquire", "[.integration][eiger]"){
// SingleDetectorConfig c;
// auto type = Module::getTypeFromDetector(c.hostname);
// Module d(type);
// d.setHostname(c.hostname);
// auto period = 1000000000;
// auto exptime = 100000000;
// d.setNumberOfFrames(5);
// d.setExptime(exptime);
// d.setPeriod(period);
// d.startAndReadAll();
// auto rperiod =
// d.getMeasuredPeriod();
// CHECK(rperiod == 0.1);
// d.freeSharedMemory();
// }
TEST_CASE(
"Eiger Dynamic Range with effect on rate correction and clock divider",
"[.eigerintegration]") {
SingleDetectorConfig c;
int ratecorr = 125;
// pick up multi detector from shm id 0
DetectorImpl m(0);
// ensure eiger detector type, hostname and online
REQUIRE(m.getDetectorTypeAsEnum() == c.type_enum);
REQUIRE(m.getHostname() == c.hostname);
// starting state with rate correction off
m.setRateCorrection(0);
// dr 16: clk divider, no change for ratecorr
CHECK(m.setDynamicRange(16) == 16);
CHECK(m.setSpeed(slsDetectorDefs::CLOCK_DIVIDER) == 1);
CHECK(m.getRateCorrection() == 0);
// dr 32: clk divider, no change for ratecorr
CHECK(m.setDynamicRange(32) == 32);
CHECK(m.setSpeed(slsDetectorDefs::CLOCK_DIVIDER) == 2);
CHECK(m.getRateCorrection() == 0);
// other drs: no change for clk divider, no change for ratecorr
CHECK(m.setDynamicRange(8) == 8);
CHECK(m.setSpeed(slsDetectorDefs::CLOCK_DIVIDER) == 2);
CHECK(m.getRateCorrection() == 0);
CHECK(m.setDynamicRange(4) == 4);
CHECK(m.setSpeed(slsDetectorDefs::CLOCK_DIVIDER) == 2);
CHECK(m.getRateCorrection() == 0);
// switching on rate correction with dr 16, 32
m.setDynamicRange(16);
m.setRateCorrection(ratecorr);
CHECK(m.getRateCorrection() == ratecorr);
m.setDynamicRange(32);
CHECK(m.getRateCorrection() == ratecorr);
// ratecorr fail with dr 4 or 8
CHECK_THROWS_AS(m.setDynamicRange(8), RuntimeError);
CHECK(m.getRateCorrection() == 0);
m.setDynamicRange(16);
m.setDynamicRange(16);
m.setRateCorrection(ratecorr);
m.setDynamicRange(16);
m.setRateCorrection(ratecorr);
CHECK_THROWS_AS(m.setDynamicRange(4), RuntimeError);
CHECK(m.getRateCorrection() == 0);
}
TEST_CASE("Chiptestboard Loading Patterns", "[.ctbintegration]") {
SingleDetectorConfig c;
// pick up multi detector from shm id 0
DetectorImpl m(0);
// ensure ctb detector type, hostname and online
REQUIRE(m.getDetectorTypeAsEnum() == c.type_enum);
REQUIRE(m.getHostname() == c.hostname);
uint64_t word = 0;
int addr = 0;
int level = 0;
const int MAX_ADDR = 0x7fff;
word = 0xc000000000f47ff;
CHECK(m.setPatternIOControl(word) == word);
CHECK(m.setPatternIOControl(-1) == word);
CHECK(m.setPatternIOControl(0) == 0);
CHECK(m.setPatternClockControl(word) == word);
CHECK(m.setPatternClockControl(-1) == word);
CHECK(m.setPatternClockControl(0) == 0);
// testing pattern word will execute the pattern as well
addr = 0;
m.setPatternWord(addr, word);
CHECK(m.setPatternWord(addr, -1) == word);
addr = MAX_ADDR - 1;
m.setPatternWord(addr, word);
CHECK(m.setPatternWord(addr, -1) == word);
addr = 0x2FF;
m.setPatternWord(addr, word);
CHECK(m.setPatternWord(addr, -1) == word);
addr = MAX_ADDR;
CHECK_THROWS_AS(m.setPatternWord(addr, word), RuntimeError);
CHECK_THROWS_WITH(m.setPatternWord(addr, word),
Catch::Matchers::Contains("be between 0 and"));
addr = -1;
CHECK_THROWS_AS(m.setPatternWord(addr, word), RuntimeError);
CHECK_THROWS_WITH(m.setPatternWord(addr, word),
Catch::Matchers::Contains("be between 0 and"));
addr = 0x2FF;
for (level = 0; level < 3; ++level) {
CHECK(m.setPatternWaitAddr(level, addr) == addr);
CHECK(m.setPatternWaitAddr(level, -1) == addr);
}
CHECK_THROWS_WITH(m.setPatternWaitAddr(-1, addr),
Catch::Matchers::Contains("be between 0 and"));
CHECK_THROWS_WITH(m.setPatternWaitAddr(0, MAX_ADDR),
Catch::Matchers::Contains("be between 0 and"));
for (level = 0; level < 3; ++level) {
CHECK(m.setPatternWaitTime(level, word) == word);
CHECK(m.setPatternWaitTime(level, -1) == word);
}
CHECK_THROWS_WITH(m.setPatternWaitTime(-1, word),
Catch::Matchers::Contains("be between 0 and"));
{
int startaddr = addr;
int stopaddr = addr + 5;
int nloops = 2;
for (level = 0; level < 3; ++level) {
m.setPatternLoops(level, startaddr, stopaddr, nloops);
auto r = m.getPatternLoops(level);
CHECK(r[0] == startaddr);
CHECK(r[1] == stopaddr);
CHECK(r[2] == nloops);
}
m.setPatternLoops(-1, startaddr, stopaddr, nloops);
auto r = m.getPatternLoops(-1);
CHECK(r[0] == startaddr);
CHECK(r[1] == stopaddr);
CHECK(r[2] == -1);
CHECK_THROWS_WITH(m.setPatternLoops(-1, startaddr, MAX_ADDR, nloops),
Catch::Matchers::Contains("be less than"));
CHECK_THROWS_WITH(m.setPatternLoops(-1, MAX_ADDR, stopaddr, nloops),
Catch::Matchers::Contains("be less than"));
}
}
TEST_CASE("Chiptestboard Dbit offset, list, sampling, advinvert",
"[.ctbintegration][dbit]") {
SingleDetectorConfig c;
// pick up multi detector from shm id 0
DetectorImpl m(0);
// ensure ctb detector type, hostname and online
REQUIRE(m.getDetectorTypeAsEnum() == c.type_enum);
REQUIRE(m.getHostname() == c.hostname);
// dbit offset
m.setReceiverDbitOffset(0);
CHECK(m.getReceiverDbitOffset() == 0);
m.setReceiverDbitOffset(-1);
CHECK(m.getReceiverDbitOffset() == 0);
m.setReceiverDbitOffset(5);
CHECK(m.getReceiverDbitOffset() == 5);
// dbit list
std::vector<int> list = m.getReceiverDbitList();
list.clear();
for (int i = 0; i < 10; ++i)
list.push_back(i);
m.setReceiverDbitList(list);
CHECK(m.getReceiverDbitList().size() == 10);
list.push_back(64);
CHECK_THROWS_AS(m.setReceiverDbitList(list), RuntimeError);
CHECK_THROWS_WITH(m.setReceiverDbitList(list),
Catch::Matchers::Contains("be between 0 and 63"));
list.clear();
for (int i = 0; i < 65; ++i)
list.push_back(i);
CHECK(list.size() == 65);
CHECK_THROWS_WITH(m.setReceiverDbitList(list),
Catch::Matchers::Contains("be greater than 64"));
list.clear();
m.setReceiverDbitList(list);
CHECK(m.getReceiverDbitList().empty());
// adcinvert
m.setADCInvert(0);
CHECK(m.getADCInvert() == 0);
m.setADCInvert(5);
CHECK(m.getADCInvert() == 5);
m.setADCInvert(-1);
CHECK(m.getADCInvert() == -1);
// ext sampling reg
m.setExternalSamplingSource(0);
CHECK(m.getExternalSamplingSource() == 0);
m.setExternalSamplingSource(62);
CHECK(m.getExternalSamplingSource() == 62);
CHECK_THROWS_WITH(m.setExternalSamplingSource(64),
Catch::Matchers::Contains("be 0-63"));
CHECK(m.getExternalSamplingSource() == 62);
m.setExternalSampling(1);
CHECK(m.getExternalSampling() == 1);
m.setExternalSampling(0);
CHECK(m.getExternalSampling() == 0);
m.setExternalSampling(1);
CHECK(m.getExternalSampling() == 1);
CHECK(m.readRegister(0x7b) == 0x1003E);
}
TEST_CASE("Eiger or Jungfrau nextframenumber",
"[.eigerintegration][.jungfrauintegration][nextframenumber]") {
SingleDetectorConfig c;
// pick up multi detector from shm id 0
DetectorImpl m(0);
// ensure ctb detector type, hostname and online
REQUIRE(
((m.getDetectorTypeAsEnum() == slsDetectorDefs::detectorType::EIGER) ||
(m.getDetectorTypeAsEnum() ==
slsDetectorDefs::detectorType::JUNGFRAU)));
REQUIRE(m.getHostname() == c.hostname);
CHECK(m.setNumberOfFrames(1) == 1);
// starting fnum
uint64_t val = 8;
m.setNextFrameNumber(val);
CHECK(m.getNextFrameNumber() == val);
CHECK(m.acquire() == slsDetectorDefs::OK);
CHECK(m.getReceiverCurrentFrameIndex() == val);
++val;
CHECK(m.acquire() == slsDetectorDefs::OK);
CHECK(m.getReceiverCurrentFrameIndex() == val);
CHECK_THROWS_AS(m.setNextFrameNumber(0), RuntimeError);
if (m.getDetectorTypeAsString() == "Eiger") {
val = 281474976710655;
} else if (m.getDetectorTypeAsString() == "Jungfrau") {
val = 18446744073709551615;
}
m.setNextFrameNumber(val);
CHECK(m.getNextFrameNumber() == val);
CHECK(m.acquire() == slsDetectorDefs::OK);
CHECK(m.getReceiverCurrentFrameIndex() == val);
CHECK(m.getNextFrameNumber() == (val + 1));
}
TEST_CASE("Eiger partialread", "[.eigerintegration][partialread]") {
SingleDetectorConfig c;
// pick up multi detector from shm id 0
DetectorImpl m(0);
// ensure detector type, hostname
REQUIRE(
(m.getDetectorTypeAsEnum() == slsDetectorDefs::detectorType::EIGER));
REQUIRE(m.getHostname() == c.hostname);
m.setDynamicRange(16);
m.enableTenGigabitEthernet(0);
m.setPartialReadout(256);
CHECK(m.getPartialReadout() == 256);
m.setPartialReadout(1);
CHECK(m.getPartialReadout() == 1);
m.setDynamicRange(8);
m.setPartialReadout(256);
CHECK(m.getPartialReadout() == 256);
CHECK_THROWS_AS(m.setPartialReadout(1), RuntimeError);
CHECK(m.getPartialReadout() == 256);
CHECK_THROWS_AS(m.setPartialReadout(0), RuntimeError);
m.setPartialReadout(256);
}
} // namespace sls