Merge branch '2404-pedestal-sc-int' into 'main'

Use internal trigger to take pedestal + fix fixedG1 pedestal with SCs

See merge request jungfraujoch/nextgendcu!44
This commit is contained in:
2024-04-13 14:27:38 +02:00
9 changed files with 120 additions and 92 deletions

View File

@@ -158,8 +158,9 @@ void JFJochStateMachine::TakePedestalInternalG0(std::unique_lock<std::mutex> &ul
state = JFJochState::Pedestal;
services.ConfigureDetector(local_experiment);
services.Start(local_experiment, *calibration);
if (!experiment.IsPulsedSource())
services.Trigger();
services.Trigger();
ul.unlock();
// Allow to cancel/abort during the pedestal data collection
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
@@ -196,8 +197,9 @@ void JFJochStateMachine::TakePedestalInternalG1(std::unique_lock<std::mutex> &ul
state = JFJochState::Pedestal;
services.ConfigureDetector(local_experiment);
services.Start(local_experiment, *calibration);
if (!experiment.IsPulsedSource())
services.Trigger();
services.Trigger();
ul.unlock();
// Allow to cancel/abort during the pedestal data collection
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock
@@ -234,8 +236,9 @@ void JFJochStateMachine::TakePedestalInternalG2(std::unique_lock<std::mutex> &ul
state = JFJochState::Pedestal;
services.ConfigureDetector(local_experiment);
services.Start(local_experiment, *calibration);
if (!experiment.IsPulsedSource())
services.Trigger();
services.Trigger();
ul.unlock();
// Allow to cancel/abort during the pedestal data collection
// Must ensure that while state is Pedestal, nothing can take lock for longer time, to avoid deadlock

View File

@@ -47,7 +47,7 @@ components:
default: 1
description: |
For standard synchrotron data collection - this is number of images collected per one TTL trigger
For XFEL mode - this number is ignored and set to 1
For XFEL (pulsed source) - this number is ignored and set to 1
For storage cell mode - this number is ignored and set to number of storage cells
ntrigger:
type: integer
@@ -62,8 +62,11 @@ components:
minimum: 1
maximum: 256
default: 1
description:
description: |
FPGA frame summation. For summation above two 32-bit pixel format will be used, unless explicitly specified.
Frame summation factor applies only to conversion mode (assumed as 1 for raw data).
In XFEL mode: summation happens for frames collected with multiple triggers.
Ignored for storage cells (assumed as 1).
beam_x_pxl:
type: number
format: float

File diff suppressed because one or more lines are too long

View File

@@ -272,23 +272,15 @@ DiffractionExperiment &DiffractionExperiment::SampleName(std::string input) {
int64_t DiffractionExperiment::GetNumTriggers() const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
if (IsPulsedSource())
return dataset.GetNumTriggers() * GetSummation();
else
return dataset.GetNumTriggers();
case DetectorMode::Raw:
return dataset.GetNumTriggers();
case DetectorMode::PedestalG0:
if (IsPulsedSource())
return pedestal_g0_frames;
else
return 1;
case DetectorMode::PedestalG1:
if (IsPulsedSource())
return pedestal_g1_frames;
else
return 1;
case DetectorMode::PedestalG2:
if (IsPulsedSource())
return pedestal_g2_frames;
else
return 1;
default:
return 1;
}
@@ -311,6 +303,26 @@ std::chrono::microseconds DiffractionExperiment::GetFrameTime() const {
}
}
std::chrono::microseconds DiffractionExperiment::GetDetectorPeriod() const {
// Without storage cells - this is just frame time
if (GetStorageCellNumber() == 1)
return GetFrameTime();
// With storage cells
// Do 100 Hz repetition for pedestal G1/G2
// Do 2 kHz repetition for conversion/raw/pedestal G0
switch (GetDetectorMode()) {
case DetectorMode::PedestalG1:
case DetectorMode::PedestalG2:
return frame_time_pedestalG1G2;
case DetectorMode::Conversion:
case DetectorMode::Raw:
case DetectorMode::PedestalG0:
default:
return std::chrono::microseconds(MIN_FRAME_TIME_FULL_SPEED_IN_US) * GetStorageCellNumber();
}
}
std::chrono::microseconds DiffractionExperiment::GetImageTime() const {
switch (GetDetectorMode()) {
case DetectorMode::PedestalG1:
@@ -328,21 +340,9 @@ std::chrono::microseconds DiffractionExperiment::GetImageTime() const {
int64_t DiffractionExperiment::GetImageNum() const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
return GetFrameNum() / GetSummation();
case DetectorMode::Raw:
return GetImageNumPerTrigger() * GetNumTriggers();
case DetectorMode::PedestalG0:
case DetectorMode::PedestalG1:
case DetectorMode::PedestalG2:
default:
return 0;
}
}
int64_t DiffractionExperiment::GetImageNumPerTrigger() const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
return GetFrameNumPerTrigger() / GetSummation();
return GetFrameNum();
case DetectorMode::PedestalG0:
case DetectorMode::PedestalG1:
case DetectorMode::PedestalG2:
@@ -356,12 +356,15 @@ int64_t DiffractionExperiment::GetFrameNum() const {
}
int64_t DiffractionExperiment::GetFrameNumPerTrigger() const {
if (IsPulsedSource())
return GetStorageCellNumber() * GetSummation();
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
return dataset.GetImageNumPerTrigger() * GetSummation();
if (GetStorageCellNumber() > 1)
return GetStorageCellNumber();
else if (IsPulsedSource())
return 1;
else
return dataset.GetImageNumPerTrigger() * GetSummation();
case DetectorMode::PedestalG0:
return pedestal_g0_frames * GetStorageCellNumber();
case DetectorMode::PedestalG1:
@@ -428,10 +431,12 @@ std::string DiffractionExperiment::GetFilePrefix() const {
}
int64_t DiffractionExperiment::GetTimePointNumber() const {
if ((GetNumTriggers() < 5) || (GetImageNumPerTrigger() > 250)) // these are heuristic parameters
if ((GetNumTriggers() < 5)
|| (GetFrameNumPerTrigger() / GetSummation() > 250)
|| (GetFrameNumPerTrigger() / GetSummation() < 1)) // these are heuristic parameters
return 1;
else
return GetImageNumPerTrigger();
return GetFrameNumPerTrigger() / GetSummation();
}
CompressionAlgorithm DiffractionExperiment::GetCompressionAlgorithm() const {
@@ -606,6 +611,8 @@ int64_t DiffractionExperiment::GetSpaceGroupNumber() const {
int64_t DiffractionExperiment::GetStorageCellNumber() const {
switch (GetDetectorMode()) {
case DetectorMode::PedestalG1:
if (IsFixedGainG1())
return storage_cells;
case DetectorMode::PedestalG2:
if (storage_cells > 1)
return 2;
@@ -863,13 +870,14 @@ int64_t DiffractionExperiment::GetSummation() const {
case DetectorMode::PedestalG0:
case DetectorMode::PedestalG1:
case DetectorMode::PedestalG2:
case DetectorMode::Raw:
return 1;
default:
case DetectorMode::Conversion:
case DetectorMode::Raw:
// FPGA summation for raw data makes zero sense - but it is still available as a means for debug, etc.
return dataset.GetSummation();
if (GetStorageCellNumber() > 1)
return 1;
else
return dataset.GetSummation();
}
}
@@ -1084,10 +1092,7 @@ DiffractionExperiment &DiffractionExperiment::PulsedSource(bool input) {
}
bool DiffractionExperiment::IsPulsedSource() const {
if (GetStorageCellNumber() > 1)
return true;
else
return pulsed_source;
return pulsed_source;
}
bool DiffractionExperiment::IsSpotFindingEnabled() const {
@@ -1164,3 +1169,4 @@ int64_t DiffractionExperiment::GetImagesPerFile() const {
else
return tmp;
}

View File

@@ -199,6 +199,7 @@ public:
int64_t GetFrameNumPerTrigger() const;
std::chrono::microseconds GetFrameTime() const;
std::chrono::microseconds GetDetectorPeriod() const;
std::chrono::microseconds GetImageTime() const;
std::chrono::microseconds GetImageCountTime() const;
@@ -317,7 +318,6 @@ public:
CompressionAlgorithm GetCompressionAlgorithm() const;
int64_t GetNumTriggers() const;
int64_t GetImageNumPerTrigger() const;
ROIMask& ROI();
const ROIMask& ROI() const;

View File

@@ -125,10 +125,7 @@ void DetectorWrapper::Start(const DiffractionExperiment& experiment) {
InternalStop();
det.setNextFrameNumber(1);
if ((experiment.GetStorageCellNumber() == 1) && (!experiment.IsPulsedSource()))
det.setNumberOfFrames(experiment.GetFrameNumPerTrigger() + DELAY_FRAMES_STOP_AND_QUIT);
det.setNumberOfFrames(experiment.GetFrameNumPerTrigger() / experiment.GetStorageCellNumber());
det.setNumberOfTriggers(experiment.GetNumTriggers());
det.startDetector();
@@ -328,13 +325,7 @@ void DetectorWrapper::Configure(const DiffractionExperiment &experiment) {
det.setNumberOfAdditionalStorageCells(experiment.GetStorageCellNumber() - 1);
det.setStorageCellDelay(experiment.GetStorageCellDelay() - std::chrono::nanoseconds(MIN_STORAGE_CELL_DELAY_IN_NS));
if ((experiment.GetStorageCellNumber() > 1) || (experiment.IsPulsedSource()))
det.setNumberOfFrames(1);
if (experiment.IsPulsedSource()) {
det.setPeriod((experiment.GetFrameCountTime() + std::chrono::microseconds(10)) * experiment.GetStorageCellNumber() );
} else
det.setPeriod(experiment.GetFrameTime());
det.setPeriod(experiment.GetDetectorPeriod());
det.setExptime(std::chrono::microseconds(experiment.GetFrameCountTime()));

View File

@@ -216,7 +216,9 @@ void JFJochReceiver::AcquireThread(uint16_t data_stream) {
void JFJochReceiver::RetrievePedestal() {
try {
if (experiment.GetDetectorMode() == DetectorMode::PedestalG0) {
if ((experiment.GetDetectorMode() == DetectorMode::PedestalG0)
|| ((experiment.GetDetectorMode() == DetectorMode::PedestalG1)
&& experiment.IsFixedGainG1())) {
pedestal_result.resize(experiment.GetModulesNum() * experiment.GetStorageCellNumber());
for (int s = 0; s < experiment.GetStorageCellNumber(); s++) {
for (int d = 0; d < ndatastreams; d++) {

View File

@@ -568,7 +568,6 @@ TEST_CASE("DiffractionExperiment_StorageCells","[DiffractionExperiment]") {
const int64_t num_triggers = 20;
DiffractionExperiment x;
x.FrameTime(std::chrono::milliseconds(1)).ImagesPerTrigger(5).NumTriggers(num_triggers);
REQUIRE(x.GetImageNumPerTrigger() == 5);
REQUIRE(x.GetNumTriggers() == num_triggers);
REQUIRE_NOTHROW(x.StorageCells(5));
@@ -591,13 +590,11 @@ TEST_CASE("DiffractionExperiment_StorageCells","[DiffractionExperiment]") {
x.StorageCells(16);
REQUIRE(x.GetStorageCellNumber() == 16);
REQUIRE(x.GetImageNumPerTrigger() == x.GetStorageCellNumber());
REQUIRE(x.GetFrameNumPerTrigger() == x.GetStorageCellNumber());
REQUIRE(x.GetImageNum() == x.GetStorageCellNumber() * num_triggers);
REQUIRE(x.GetFrameNum() == x.GetStorageCellNumber() * num_triggers);
x.UseInternalPacketGenerator(true);
REQUIRE(x.GetImageNumPerTrigger() == x.GetStorageCellNumber());
REQUIRE(x.GetFrameNumPerTrigger() == x.GetStorageCellNumber());
REQUIRE(x.GetImageNum() == x.GetStorageCellNumber() * num_triggers);
REQUIRE(x.GetFrameNum() == x.GetStorageCellNumber() * num_triggers);
@@ -609,53 +606,72 @@ TEST_CASE("DiffractionExperiment_StorageCells_Pedestal","[DiffractionExperiment]
x.Mode(DetectorMode::PedestalG0);
REQUIRE(x.GetStorageCellNumber() == 16);
REQUIRE(x.GetNumTriggers() == 1456);
REQUIRE(x.GetFrameNumPerTrigger() == 16);
REQUIRE(x.GetNumTriggers() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 1456*16);
REQUIRE(x.GetFrameNum() == 1456 * 16);
x.Mode(DetectorMode::PedestalG1);
REQUIRE(x.GetStorageCellNumber() == 2);
REQUIRE(x.GetNumTriggers() == 323);
REQUIRE(x.GetFrameNumPerTrigger() == 2);
REQUIRE(x.GetNumTriggers() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 2 * 323);
REQUIRE(x.GetFrameNum() == 323 * 2);
x.StorageCells(8);
x.Mode(DetectorMode::PedestalG2);
REQUIRE(x.GetStorageCellNumber() == 2);
REQUIRE(x.GetNumTriggers() == 456);
REQUIRE(x.GetFrameNumPerTrigger() == 2);
REQUIRE(x.GetNumTriggers() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 2 * 456);
}
TEST_CASE("DiffractionExperiment_StorageCells_Pedestal_FixedG1","[DiffractionExperiment]") {
DiffractionExperiment x;
x.PedestalG0Frames(1456).PedestalG1Frames(323).PedestalG2Frames(456).StorageCells(15).FixedGainG1(true);
x.Mode(DetectorMode::PedestalG1);
REQUIRE(x.GetStorageCellNumber() == 15);
REQUIRE(x.GetNumTriggers() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 15 * 323);
REQUIRE(x.GetFrameNum() == 323 * 15);
}
TEST_CASE("DiffractionExperiment_PulsedSource","[DiffractionExperiment]") {
DiffractionExperiment x;
REQUIRE(!x.IsPulsedSource()); // default must be off
x.ImagesPerTrigger(50).NumTriggers(100).Mode(DetectorMode::Raw).PedestalG0Frames(1000)
x.ImagesPerTrigger(50).NumTriggers(100).Mode(DetectorMode::Conversion).PedestalG0Frames(1000)
.PedestalG1Frames(200).PedestalG2Frames(100);
REQUIRE(x.GetImageNumPerTrigger() == 50);
x.PulsedSource(true);
REQUIRE(x.GetImageNumPerTrigger() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
REQUIRE(x.GetImageNum() == 100);
x.Summation(10);
REQUIRE(x.GetImageNumPerTrigger() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 10);
x.Mode(DetectorMode::PedestalG0);
REQUIRE(x.GetImageNumPerTrigger() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
REQUIRE(x.GetNumTriggers() == 1000);
REQUIRE(x.GetNumTriggers() == 100 * 10);
REQUIRE(x.GetFrameNum() == 100 * 10);
REQUIRE(x.GetImageNum() == 100);
x.Mode(DetectorMode::PedestalG1);
REQUIRE(x.GetImageNumPerTrigger() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
REQUIRE(x.GetNumTriggers() == 200);
x.Mode(DetectorMode::PedestalG2);
REQUIRE(x.GetImageNumPerTrigger() == 0);
x.Mode(DetectorMode::Raw);
REQUIRE(x.GetSummation() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
REQUIRE(x.GetNumTriggers() == 100);
REQUIRE(x.GetFrameNum() == 100);
REQUIRE(x.GetImageNum() == 100);
x.Mode(DetectorMode::PedestalG0);
REQUIRE(x.GetImageNum() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 1000);
REQUIRE(x.GetNumTriggers() == 1);
x.Mode(DetectorMode::PedestalG1);
REQUIRE(x.GetImageNum() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 200);
REQUIRE(x.GetNumTriggers() == 1);
x.Mode(DetectorMode::PedestalG2);
REQUIRE(x.GetImageNum() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 100);
REQUIRE(x.GetNumTriggers() == 1);
}
TEST_CASE("DiffractionExperiment_DefaultDataProcessingSettings","[DiffractionExperiment]") {

View File

@@ -1742,8 +1742,9 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_summation", "[FPGA][Full]"
for (auto &i: test_frame)
i = dist(g1);
x.Mode(DetectorMode::Raw);
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0).Summation(nsummation);
x.Mode(DetectorMode::Conversion);
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0).Summation(nsummation)
.ConversionOnFPGA(false);
HLSSimulatedDevice test(0, 64);
for (int m = 0; m < x.GetModulesNum(); m++)