From e1e15593cd0a60422e18c898205b59e804910c4e Mon Sep 17 00:00:00 2001 From: cmantill Date: Wed, 1 Sep 2021 11:51:16 -0500 Subject: [PATCH 1/5] correct voltage by a factor of 2 --- src/Hcal/HcalRecProducer.cxx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Hcal/HcalRecProducer.cxx b/src/Hcal/HcalRecProducer.cxx index 609f66c..2fa35b8 100644 --- a/src/Hcal/HcalRecProducer.cxx +++ b/src/Hcal/HcalRecProducer.cxx @@ -243,9 +243,8 @@ void HcalRecProducer::produce(framework::Event& event) { double att_negend = exp(-1. * ((distance_negend + position_bar) / 1000.) / attlength_); - // set voltage - voltage = (voltage_posend / att_posend + voltage_negend / att_negend) / - 2; // mV + // set voltage as the sum for both bars + voltage = (voltage_posend / att_posend + voltage_negend / att_negend); // mV voltage_min = std::min(voltage_posend / att_posend, voltage_negend / att_negend); @@ -317,6 +316,20 @@ void HcalRecProducer::produce(framework::Event& event) { double energy_deposited = num_mips_equivalent * mip_energy_; // TODO: need to incorporate corrections if necessary + /** + * Simple calculation of sampling fraction: + * Thickness per layer: scintillator (0.2cm) + steel (0.25cm) + * Radiation length and nuclear interaction length: + * scintillator: X0 = 41.31cm, Lambda = 77.07cm https://pdg.lbl.gov/2017/AtomicNuclearProperties/HTML/polystyrene.html + * steel X0 = 1.757cm, Lambda = 16.77cm https://pdg.lbl.gov/2012/AtomicNuclearProperties/HTML_PAGES/026.html + * Prob of EM interaction (e.g. pi+/-): thickness/X0*100 + * = (0.2/41.31)/ ((0.2/41.31) + (0.25/1.757)) ~ 3.3% + * Prob of Had interaction (e.g. pi0): + * = (0.2/77.07)/ ((0.2/77.07) + (0.25/16.77)) ~ 15% + * Then e.g. for neutron assuming 1/3 pi0 and 2/3 pi+/- composition: + * sampling fraction ~ (1/3)*3.3.% + (2/3)*15% ~ 11% + * energy of neutron = energy_deposited / 0.11; + **/ double reconstructed_energy = energy_deposited; int PEs = num_mips_equivalent * pe_per_mip_; From c71adc33c5834aa0dd2120b4f221c33bcaa62c54 Mon Sep 17 00:00:00 2001 From: cmantill Date: Wed, 1 Sep 2021 11:57:48 -0500 Subject: [PATCH 2/5] change amplitude too --- src/Hcal/HcalRecProducer.cxx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Hcal/HcalRecProducer.cxx b/src/Hcal/HcalRecProducer.cxx index 2fa35b8..6ae4b3c 100644 --- a/src/Hcal/HcalRecProducer.cxx +++ b/src/Hcal/HcalRecProducer.cxx @@ -164,6 +164,7 @@ void HcalRecProducer::produce(framework::Event& event) { double voltage_min(0.); double hitTime(0.); + double amplT(0.); double amplT_posend(0.), amplTm1_posend(0.); double amplT_negend(0.), amplTm1_negend(0.); @@ -248,6 +249,9 @@ void HcalRecProducer::produce(framework::Event& event) { voltage_min = std::min(voltage_posend / att_posend, voltage_negend / att_negend); + // set amplitude + amplT = amplT_posend / att + amplT_negend / att; + // set position along the bar if ((id_posend.layer() % 2) == 1) { position.SetX(position_bar); @@ -286,6 +290,7 @@ void HcalRecProducer::produce(framework::Event& event) { amplTm1_posend = digi_posend.soi().adc_tm1() - the_conditions.adcPedestal(id_posend); voltage_i = amplT_posend * the_conditions.adcGain(id_posend); + } // reverse voltage attenuation @@ -299,6 +304,9 @@ void HcalRecProducer::produce(framework::Event& event) { voltage = voltage_i / att; voltage_min = voltage_i / att; + // set amplitude + amplT = amplT_posend / att; + // get TOA double TOA = getTOA(digi_posend, the_conditions.adcPedestal(id_posend), iSOI); @@ -343,7 +351,7 @@ void HcalRecProducer::produce(framework::Event& event) { recHit.setZPos(position.Z()); recHit.setPE(PEs); recHit.setMinPE(minPEs); - recHit.setAmplitude(amplT_posend); + recHit.setAmplitude(amplT); recHit.setEnergy(energy_deposited); recHit.setTime(hitTime); hcalRecHits.push_back(recHit); From c828fac22d4007f2fc925331112b6f2f6303f8d9 Mon Sep 17 00:00:00 2001 From: cmantill Date: Wed, 1 Sep 2021 12:20:10 -0500 Subject: [PATCH 3/5] fix typo --- src/Hcal/HcalRecProducer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hcal/HcalRecProducer.cxx b/src/Hcal/HcalRecProducer.cxx index 6ae4b3c..4fc2491 100644 --- a/src/Hcal/HcalRecProducer.cxx +++ b/src/Hcal/HcalRecProducer.cxx @@ -250,7 +250,7 @@ void HcalRecProducer::produce(framework::Event& event) { std::min(voltage_posend / att_posend, voltage_negend / att_negend); // set amplitude - amplT = amplT_posend / att + amplT_negend / att; + amplT = amplT_posend / att_posend + amplT_negend / att_negend; // set position along the bar if ((id_posend.layer() % 2) == 1) { From c46ef2e64921eca79fb58969d659f4a240c7abab Mon Sep 17 00:00:00 2001 From: cmantill Date: Wed, 1 Sep 2021 14:43:28 -0500 Subject: [PATCH 4/5] add sampling fraction in test --- test/HcalDigiPipelineTest.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/HcalDigiPipelineTest.cxx b/test/HcalDigiPipelineTest.cxx index 53fb821..66dd38b 100644 --- a/test/HcalDigiPipelineTest.cxx +++ b/test/HcalDigiPipelineTest.cxx @@ -271,7 +271,8 @@ class HcalCheckReconstruction : public framework::Analyzer { } // define target energy by using the settings at the top - double daq_energy{hit.getEnergy()}; + double sampling_fraction = 0.11; + double daq_energy{hit.getEnergy()*sampling_fraction}; CHECK_THAT(daq_energy, isCloseEnough(truth_energy, MAX_ENERGY_ERROR_DAQ, MAX_ENERGY_PERCENT_ERROR_DAQ)); From 9214abed9c056d68608e75c75c2449bf2135522b Mon Sep 17 00:00:00 2001 From: cmantill Date: Mon, 27 Sep 2021 17:09:28 -0500 Subject: [PATCH 5/5] keep both sum and average and format --- src/Hcal/HcalRecProducer.cxx | 52 ++++++++++++++++++----------------- test/HcalDigiPipelineTest.cxx | 43 +++++++++++++++-------------- test/HcalGeometryTest.cxx | 3 +- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/Hcal/HcalRecProducer.cxx b/src/Hcal/HcalRecProducer.cxx index 4fc2491..1088364 100644 --- a/src/Hcal/HcalRecProducer.cxx +++ b/src/Hcal/HcalRecProducer.cxx @@ -77,7 +77,6 @@ void HcalRecProducer::configure(framework::config::Parameters& ps) { if (n == 0) minAmpl_ = ampl_t; n++; } - } double HcalRecProducer::getTOA( @@ -239,19 +238,20 @@ void HcalRecProducer::produce(framework::Event& event) { // reverse voltage attenuation // if position along the bar is positive, then the positive end will have // less attenuation than the negative end + // NOTE: For now, reverse attenuation is not applied to the energy + // deposited since both ends of the bar are summed. double att_posend = exp(-1. * ((distance_posend - position_bar) / 1000.) / attlength_); double att_negend = exp(-1. * ((distance_negend + position_bar) / 1000.) / attlength_); - // set voltage as the sum for both bars - voltage = (voltage_posend / att_posend + voltage_negend / att_negend); // mV - voltage_min = - std::min(voltage_posend / att_posend, voltage_negend / att_negend); + // set voltage as the sum of both bars + voltage = (voltage_posend + voltage_negend); + voltage_min = std::min(voltage_posend, voltage_negend); + + // set amplitude as the average of both bars (reverse attenuated) + amplT = (amplT_posend / att_posend + amplT_negend / att_negend) / 2; - // set amplitude - amplT = amplT_posend / att_posend + amplT_negend / att_negend; - // set position along the bar if ((id_posend.layer() % 2) == 1) { position.SetX(position_bar); @@ -290,7 +290,6 @@ void HcalRecProducer::produce(framework::Event& event) { amplTm1_posend = digi_posend.soi().adc_tm1() - the_conditions.adcPedestal(id_posend); voltage_i = amplT_posend * the_conditions.adcGain(id_posend); - } // reverse voltage attenuation @@ -301,18 +300,18 @@ void HcalRecProducer::produce(framework::Event& event) { attlength_); // set voltage - voltage = voltage_i / att; - voltage_min = voltage_i / att; + voltage = voltage_i; + voltage_min = voltage_i; - // set amplitude + // set amplitude (reverse attenuated) amplT = amplT_posend / att; - + // get TOA double TOA = getTOA(digi_posend, the_conditions.adcPedestal(id_posend), iSOI); // correct TOA - TOA = correctionTOA_.Eval(amplT_posend) - TOA; + TOA = correctionTOA_.Eval(amplT) - TOA; // set hit time hitTime = TOA; // ns @@ -323,20 +322,23 @@ void HcalRecProducer::produce(framework::Event& event) { double num_mips_equivalent = voltage / voltage_per_mip_; double energy_deposited = num_mips_equivalent * mip_energy_; + // reconstructed energy in the layer (approximate) // TODO: need to incorporate corrections if necessary /** * Simple calculation of sampling fraction: * Thickness per layer: scintillator (0.2cm) + steel (0.25cm) * Radiation length and nuclear interaction length: - * scintillator: X0 = 41.31cm, Lambda = 77.07cm https://pdg.lbl.gov/2017/AtomicNuclearProperties/HTML/polystyrene.html - * steel X0 = 1.757cm, Lambda = 16.77cm https://pdg.lbl.gov/2012/AtomicNuclearProperties/HTML_PAGES/026.html - * Prob of EM interaction (e.g. pi+/-): thickness/X0*100 - * = (0.2/41.31)/ ((0.2/41.31) + (0.25/1.757)) ~ 3.3% - * Prob of Had interaction (e.g. pi0): - * = (0.2/77.07)/ ((0.2/77.07) + (0.25/16.77)) ~ 15% - * Then e.g. for neutron assuming 1/3 pi0 and 2/3 pi+/- composition: - * sampling fraction ~ (1/3)*3.3.% + (2/3)*15% ~ 11% - * energy of neutron = energy_deposited / 0.11; + * scintillator: X0 = 41.31cm, Lambda = 77.07cm + *https://pdg.lbl.gov/2017/AtomicNuclearProperties/HTML/polystyrene.html + * steel X0 = 1.757cm, Lambda = 16.77cm + *https://pdg.lbl.gov/2012/AtomicNuclearProperties/HTML_PAGES/026.html Prob + *of EM interaction (e.g. pi0): thickness/X0*100 = (0.2/41.31)/ ((0.2/41.31) + *+ (0.25/1.757)) ~ 3.3% Prob of Had interaction (e.g. pi+/pi-): = + *(0.2/77.07)/ ((0.2/77.07) + (0.25/16.77)) ~ 15% Then e.g. for neutron + *assuming 1/3 pi0 and 2/3 pi+/- composition: sampling fraction ~ + *(1/3)*3.3.% + (2/3)*15% ~ 11% energy of neutron = energy_deposited / 0.11; + * + * NOTE: For now, sampling fraction is not applied. **/ double reconstructed_energy = energy_deposited; @@ -351,8 +353,8 @@ void HcalRecProducer::produce(framework::Event& event) { recHit.setZPos(position.Z()); recHit.setPE(PEs); recHit.setMinPE(minPEs); - recHit.setAmplitude(amplT); - recHit.setEnergy(energy_deposited); + recHit.setAmplitude((amplT / voltage_per_mip_) * mip_energy_); + recHit.setEnergy(reconstructed_energy); recHit.setTime(hitTime); hcalRecHits.push_back(recHit); } diff --git a/test/HcalDigiPipelineTest.cxx b/test/HcalDigiPipelineTest.cxx index 66dd38b..515b034 100644 --- a/test/HcalDigiPipelineTest.cxx +++ b/test/HcalDigiPipelineTest.cxx @@ -3,11 +3,10 @@ #include "Framework/ConfigurePython.h" #include "Framework/EventProcessor.h" #include "Framework/Process.h" -#include "catch.hpp" //for TEST_CASE, REQUIRE, and other Catch2 macros - -#include "SimCore/Event/SimCalorimeterHit.h" -#include "Recon/Event/HgcrocDigiCollection.h" #include "Hcal/Event/HcalHit.h" +#include "Recon/Event/HgcrocDigiCollection.h" +#include "SimCore/Event/SimCalorimeterHit.h" +#include "catch.hpp" //for TEST_CASE, REQUIRE, and other Catch2 macros namespace hcal { namespace test { @@ -28,17 +27,20 @@ static const double PE_ENERGY = 4.66 / 68; // 0.069 MeV static const double MeV_per_mV = PE_ENERGY / 5; // 0.013 MeV/mV /** - * Maximum error that a single hit energy + * Maximum error that a single hit energy/PE * can be reconstructed with before failing the test * - * Comparing energy deposited that was + * Comparing energy deposited/PE that was * "simulated" (input into digitizer) and the reconstructed - * energy deposited output by reconstructor. + * energy deposited/PE output by reconstructor. * * NOTE: Currently Digitization not implemented for TOT mode */ -static const double MAX_ENERGY_ERROR_DAQ = 4 * PE_ENERGY; -static const double MAX_ENERGY_PERCENT_ERROR_DAQ = 0.12; +// static const double MAX_ENERGY_ERROR_DAQ = 4 * PE_ENERGY; +// static const double MAX_ENERGY_PERCENT_ERROR_DAQ = 0.2; +static const double MAX_PE_ERROR_DAQ = 40; +static const double MAX_PE_PERCENT_ERROR_DAQ = + 0.4; // large percentage error for now /** * Maximum error that a single hit position along the bar @@ -267,20 +269,21 @@ class HcalCheckReconstruction : public framework::Analyzer { ntuple_.setVar("RecY", hit.getYPos()); ntuple_.setVar("RecZ", hit.getZPos()); ntuple_.setVar("RecTime", hit.getTime()); + ntuple_.setVar("RecPE", hit.getPE()); ntuple_.setVar("RecEnergy", hit.getEnergy()); } - // define target energy by using the settings at the top - double sampling_fraction = 0.11; - double daq_energy{hit.getEnergy()*sampling_fraction}; - CHECK_THAT(daq_energy, isCloseEnough(truth_energy, MAX_ENERGY_ERROR_DAQ, - MAX_ENERGY_PERCENT_ERROR_DAQ)); - - // std::cout << "rec energy " << hit.getEnergy() << " truth " << - // truth_energy - // << std::endl; - - // ntuple_.setVar("RecEnergy", hit.getEnergy()); + // define target pe by using the settings at the top + double daq_pe{hit.getPE()}; + CHECK_THAT(daq_pe, isCloseEnough(truth_energy / PE_ENERGY, MAX_PE_ERROR_DAQ, + MAX_PE_PERCENT_ERROR_DAQ)); + + // std::cout << "rec energy " << hit.getEnergy() << " * approx sampl + // fraction " << hit.getEnergy()*sampling_fraction << " truth " << + // truth_energy + // << std::endl; + // std::cout << "npes " << hit.getPE() << " approx PE " << int(truth_energy + // / PE_ENERGY) << std::endl; if (id.section() == 0) { double truth_pos, rec_pos; diff --git a/test/HcalGeometryTest.cxx b/test/HcalGeometryTest.cxx index 5143f4b..688c6e8 100644 --- a/test/HcalGeometryTest.cxx +++ b/test/HcalGeometryTest.cxx @@ -4,9 +4,8 @@ #include "Framework/ConfigurePython.h" #include "Framework/EventProcessor.h" #include "Framework/Process.h" -#include "catch.hpp" //for TEST_CASE, REQUIRE, and other Catch2 macros - #include "SimCore/Event/SimCalorimeterHit.h" +#include "catch.hpp" //for TEST_CASE, REQUIRE, and other Catch2 macros namespace hcal { namespace test {