DiffractionExperiment: solid angle correction

This commit is contained in:
2023-05-09 14:03:59 +02:00
parent 5d63bac30f
commit a867b1c596
10 changed files with 163 additions and 117 deletions

View File

@@ -48,6 +48,7 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) {
dataset.set_images_per_trigger(1);
dataset.set_summation(1);
dataset.set_space_group_number(0); // not set
dataset.set_rad_int_solid_angle_corr(false);
dataset.set_compression(JFJochProtoBuf::BSHUF_LZ4);
@@ -766,6 +767,17 @@ float DiffractionExperiment::ResToPxl(float resolution) const {
return tan_2theta * GetDetectorDistance_mm() / GetPixelSize_mm();
}
float DiffractionExperiment::CalcRadIntSolidAngleCorr(float q) const {
if (!GetSolidAngleCorrection())
return 1.0f;
float sin_theta = q * GetWavelength_A() / (4 * static_cast<float>(M_PI));
float theta = asinf(sin_theta);
float cos_two_theta = cosf(2 * theta);
float cos_two_theta_3 = cos_two_theta * cos_two_theta * cos_two_theta;
return cos_two_theta_3;
}
Coord DiffractionExperiment::LabCoord(float detector_x, float detector_y) const {
// Assumes planar detector, 90 deg towards beam
return {(detector_x - GetBeamX_pxl()) * GetPixelSize_mm() ,
@@ -1173,4 +1185,14 @@ void DiffractionExperiment::GetDetectorModuleHostname(std::vector<std::string> &
std::string DiffractionExperiment::GetDetectorDescription() const {
return internal.detector().description();
}
}
bool DiffractionExperiment::GetSolidAngleCorrection() const {
return dataset.rad_int_solid_angle_corr();
}
DiffractionExperiment &DiffractionExperiment::RadIntSolidAngleCorr(bool input) {
dataset.set_rad_int_solid_angle_corr(input);
return *this;
}

View File

@@ -93,6 +93,7 @@ public:
DiffractionExperiment& InstrumentNameShort(std::string input);
DiffractionExperiment& Binning2x2(bool input);
DiffractionExperiment& ApplyPixelMaskInFPGA(bool input);
DiffractionExperiment& RadIntSolidAngleCorr(bool input);
operator JFJochProtoBuf::JungfraujochSettings() const;
operator JFJochProtoBuf::DetectorInput() const;
@@ -187,6 +188,7 @@ public:
float ResToPxl(float resolution) const;
Coord LabCoord(float detector_x, float detector_y) const;
float PxlToRes(float detector_x, float detector_y) const;
float CalcRadIntSolidAngleCorr(float q) const;
float GetLowQForRadialInt_recipA() const;
float GetHighQForRadialInt_recipA() const;
@@ -207,6 +209,7 @@ public:
bool GetApplyPixelMaskInFPGA() const;
float GetPixelSize_mm() const;
bool GetBinning2x2() const;
bool GetSolidAngleCorrection() const;
std::string GetSourceName() const;
std::string GetSourceNameShort() const;

View File

@@ -100,6 +100,7 @@ message DatasetSettings {
bool apply_pixel_mask = 16;
bool binning2x2 = 17;
bool rad_int_solid_angle_corr = 18;
}
message DetectorSettings {

View File

@@ -23,19 +23,24 @@ void RadialIntegrationProfile::Add(const std::vector<int32_t> &in_sum, const std
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mismatch in size of sum/count datasets");
}
std::vector<float> RadialIntegrationProfile::GetResult() const {
std::vector<float> RadialIntegrationProfile::GetResult(const DiffractionExperiment &experiment) const {
std::vector<float> rad_int_profile(sum.size(), 0);
for (int i = 0; i < sum.size(); i++) {
float tmp = 0;
if (count[i] > 0)
rad_int_profile[i] = static_cast<float>(sum[i]) / static_cast<float>(count[i]);
tmp = static_cast<float>(sum[i]) / static_cast<float>(count[i]);
if (experiment.GetSolidAngleCorrection())
tmp /= experiment.CalcRadIntSolidAngleCorr(bin_to_q[i]);
rad_int_profile[i] = tmp;
}
return rad_int_profile;
}
void RadialIntegrationProfile::GetPlot(JFJochProtoBuf::Plot &plot) const {
void RadialIntegrationProfile::GetPlot(JFJochProtoBuf::Plot &plot, const DiffractionExperiment &experiment) const {
std::unique_lock<std::mutex> ul(m);
std::vector<float> rad_int_profile = GetResult();
std::vector<float> rad_int_profile = GetResult(experiment);
*plot.mutable_x() = {bin_to_q.begin(), bin_to_q.end()};
*plot.mutable_y() = {rad_int_profile.begin(), rad_int_profile.end()};

View File

@@ -18,8 +18,8 @@ class RadialIntegrationProfile {
public:
explicit RadialIntegrationProfile(RadialIntegrationMapping &mapping);
void Add(const std::vector<int32_t> &sum, const std::vector<int32_t> &count);
std::vector<float> GetResult() const;
void GetPlot(JFJochProtoBuf::Plot &plot) const;
std::vector<float> GetResult(const DiffractionExperiment &experiment) const;
void GetPlot(JFJochProtoBuf::Plot &plot, const DiffractionExperiment &experiment) const;
};
#endif //JUNGFRAUJOCH_RADIALINTEGRATIONPROFILE_H

File diff suppressed because one or more lines are too long

View File

@@ -588,9 +588,11 @@ void JFJochReceiver::FinalizeMeasurement() {
message.write_master_file = true;
if (rad_int_profile)
message.rad_int_result["dataset"] = rad_int_profile->GetResult();
message.rad_int_result["dataset"]
= rad_int_profile->GetResult(experiment);
for (int i = 0; i < rad_int_profile_per_file.size(); i++)
message.rad_int_result["file" + std::to_string(i)] = rad_int_profile_per_file[i]->GetResult();
message.rad_int_result["file" + std::to_string(i)]
= rad_int_profile_per_file[i]->GetResult(experiment);
image_pusher.EndDataCollection(message);
logger.Info("Disconnected from writers");
@@ -646,10 +648,10 @@ JFJochProtoBuf::Plot JFJochReceiver::GetPlots(const JFJochProtoBuf::PlotRequest
case JFJochProtoBuf::RAD_INT:
if (request.has_file_number()) {
if (request.file_number() < rad_int_profile_per_file.size())
rad_int_profile_per_file[request.file_number()]->GetPlot(ret);
rad_int_profile_per_file[request.file_number()]->GetPlot(ret, experiment);
} else {
if (rad_int_profile)
rad_int_profile->GetPlot(ret);
rad_int_profile->GetPlot(ret, experiment);
}
break;
case JFJochProtoBuf::SPOT_COUNT:

View File

@@ -967,4 +967,17 @@ TEST_CASE("DiffractionExperiment_DetectorModuleHostname","[DiffractionExperiment
REQUIRE(h == h_out);
REQUIRE_NOTHROW(det_cfg = x.DetectorConfig(net_cfg));
}
}
TEST_CASE("DiffractionExperiment_SolidAngleCorrection","[DiffractionExperiment]") {
DiffractionExperiment x;
x.PhotonEnergy_keV(WVL_1A_IN_KEV);
x.RadIntSolidAngleCorr(false);
REQUIRE (x.CalcRadIntSolidAngleCorr(0.0) == 1.0f);
REQUIRE (x.CalcRadIntSolidAngleCorr(1.0) == 1.0f);
x.RadIntSolidAngleCorr(true);
REQUIRE(x.CalcRadIntSolidAngleCorr(0.0) == 1.0f);
REQUIRE(x.CalcRadIntSolidAngleCorr(2*M_PI) == Approx(0.5f*0.5f*0.5f));
}

View File

@@ -155,8 +155,8 @@ TEST_CASE("HDF5MasterFile_RadInt", "[HDF5][Full]") {
start_message.rad_int_bin_to_q = mapping.GetBinToQ();
EndMessage end_message;
end_message.number_of_images = x.GetImageNum();
end_message.rad_int_result["avg1"] = profile.GetResult();
end_message.rad_int_result["avg2"] = profile.GetResult();
end_message.rad_int_result["avg1"] = profile.GetResult(x);
end_message.rad_int_result["avg2"] = profile.GetResult(x);
REQUIRE_NOTHROW(HDF5Metadata::NXmx(start_message, end_message));
}

View File

@@ -100,7 +100,7 @@ TEST_CASE("RadialIntegrationProfile","[RadialIntegration]") {
REQUIRE_THROWS(profile.Add(sum_wr, count));
JFJochProtoBuf::Plot plot;
profile.GetPlot(plot);
profile.GetPlot(plot, x);
REQUIRE(plot.x_size() == mapping.GetBinNumber());
REQUIRE(plot.y_size() == mapping.GetBinNumber());