1#include <catch2/catch_approx.hpp>
2#include <catch2/catch_test_macros.hpp>
3#include <catch2/matchers/catch_matchers.hpp>
6#include "Ecal/Event/EcalHit.h"
7#include "Framework/Configure/Python.h"
11#include "Recon/Event/HgcrocTrigDigi.h"
23static const double MIP_SI_ENERGY = 0.130;
32static const double MEV_PER_FC = MIP_SI_ENERGY / (37 * 0.1602);
43static const double MAX_ENERGY_PERCENT_ERROR_DAQ = 0.025;
54static const double MAX_ENERGY_PERCENT_ERROR_TP = 0.15;
65static const double MAX_ENERGY_ERROR_DAQ = MIP_SI_ENERGY / 2;
76static const double MAX_ENERGY_ERROR_TP = 2 * MIP_SI_ENERGY;
88static const int NUM_TEST_SIM_HITS = 2000;
113 double const &rel_diff)
125 bool match(
const double &daq_energy)
const override {
134 std::ostringstream ss;
183 header.setDetectorName(
"ldmx-det-v14-8gev");
188 std::vector<ldmx::SimCalorimeterHit> pretend_sim_hits(1);
191 pretend_sim_hits[0].setID(
id.raw());
194 pretend_sim_hits[0].addContrib(-1, -1, 0,
curr_energy_, 1.);
196 pretend_sim_hits[0].setPosition(0., 0., 299.);
199 REQUIRE_NOTHROW(event.add(
"EcalSimHits", pretend_sim_hits));
220 std::string ecal_simhits_passname_;
221 std::string ecal_digis_passname_;
222 std::string ecal_rechits_passname_;
223 std::string ecal_trig_digis_passname_;
231 ecal_simhits_passname_ =
232 parameters.get<std::string>(
"ecal_simhits_passname",
"");
233 ecal_digis_passname_ =
234 parameters.get<std::string>(
"ecal_digis_passname",
"");
235 ecal_rechits_passname_ =
236 parameters.get<std::string>(
"ecal_rechits_passname",
"");
237 ecal_trig_digis_passname_ =
238 parameters.get<std::string>(
"ecal_trig_digis_passname",
"");
258 "EcalSimHits", ecal_simhits_passname_);
260 REQUIRE(sim_hits.size() == 1);
262 float truth_energy = sim_hits.at(0).getEdep();
266 "EcalDigis", ecal_digis_passname_)};
268 if (daq_digis.getNumDigis() == 1) {
269 auto daq_digi = daq_digis.getDigi(0);
271 bool is_in_adc_mode = daq_digi.isADC();
277 "EcalRecHits", ecal_rechits_passname_);
278 CHECK(rec_hits.size() == 1);
280 auto hit = rec_hits.at(0);
282 CHECK_FALSE(hit.isNoise());
283 CHECK(
id.raw() == sim_hits.at(0).getID());
285 double daq_energy{hit.getAmplitude()};
286 CHECK_THAT(daq_energy,
IsCloseEnough(truth_energy, MAX_ENERGY_ERROR_DAQ,
287 MAX_ENERGY_PERCENT_ERROR_DAQ));
290 const auto trig_digis{
event.getObject<ldmx::HgcrocTrigDigiCollection>(
291 "ecalTrigDigis", ecal_trig_digis_passname_)};
292 CHECK(trig_digis.size() == 1);
294 auto trig_digi = trig_digis.at(0);
296 8 * trig_digi.linearPrimitive() * 320. / 1024 * MEV_PER_FC;
298 CHECK_THAT(tp_energy,
IsCloseEnough(truth_energy, MAX_ENERGY_ERROR_TP,
299 MAX_ENERGY_PERCENT_ERROR_TP));
301 ntuple_.
setVar<
int>(
"TrigPrimDigiEncoded", trig_digi.getPrimitive());
302 ntuple_.
setVar<
int>(
"TrigPrimDigiLinear", trig_digi.linearPrimitive());
328TEST_CASE(
"Ecal Digi Pipeline test",
"[Ecal][functionality]") {
329 const std::string config_file{
"ecal_digi_pipeline_test_config.py"};
330 char **args{
nullptr};
334 auto p{std::make_unique<framework::Process>(cfg)};
Class that defines an ECal detector ID with a cell number.
Base classes for all user event processing components to extend.
#define DECLARE_ANALYZER(CLASS)
Macro which allows the framework to construct an analyzer given its name during configuration.
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Class that represents a digitized hit in a calorimeter cell readout by an HGCROC.
Class which represents the process under execution.
Class which stores simulated calorimeter hit information.
void onProcessStart() final override
Callback for the EventProcessor to take any necessary action when the processing of events starts,...
void configure(framework::config::Parameters ¶meters) final override
Callback for the EventProcessor to configure itself from the given set of parameters.
void analyze(const framework::Event &event) final override
Process the event and make histograms or summaries.
const double MAX_ENERGY
Maximum energy to make a simulated hit for [MeV].
const double MIN_ENERGY
Minimum energy to make a sim hit for [MeV] Needs to be above readout threshold (after internal EcalDi...
const double ENERGY_STEP
The step between energies is calculated depending on the min, max energy and the total number of sim ...
void beforeNewRun(ldmx::RunHeader &header) final override
Callback for Producers to add parameters to the run header before conditions are initialized.
void produce(framework::Event &event) final override
Process the event and put new data products into it.
double curr_energy_
current energy of the sim hit we are on
Our custom energy checker which makes sure that the input energy is "close enough" to the truth energ...
IsCloseEnough(double const &truth, double const &abs_diff, double const &rel_diff)
Constructor.
virtual std::string describe() const override
Describes matcher for printing to terminal.
bool match(const double &daq_energy) const override
Performs the test for this matcher.
const double MAX_ABSOLUTE_DIFF
maximum absolute energy difference [MeV]
const double MAX_RELATIVE_DIFF
maximum relative energy difference
double truth_
correct (sim-level) energy [MeV]
Base class for a module which does not produce a data product.
NtupleManager & ntuple_
Manager for any ntuples.
TDirectory * getHistoDirectory()
Access/create a directory in the histogram file for this event processor to create histograms and ana...
Implements an event buffer system for storing event data.
void addVar(const std::string &tname, const std::string &vname)
Add a variable of type VarType to the ROOT tree with name 'tname'.
void create(const std::string &tname)
Create a ROOT tree to hold the ntuple variables (ROOT leaves).
void setVar(const std::string &vname, const T &value)
Set the value of the variable named 'vname'.
Class which represents the process under execution.
Base class for a module which produces a data product.
Producer(const std::string &name, Process &process)
Class constructor.
Class encapsulating parameters for configuring a processor.
Stores reconstructed hit information from the ECAL.
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Represents a collection of the digi hits readout by an HGCROC.
Stores simulated calorimeter hit information.
Parameters run(const std::string &root_object, const std::string &pythonScript, char *args[], int nargs)
run the python script and extract the parameters
All classes in the ldmx-sw project use this namespace.