Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement dEdx mass estimator to do PID with recoil tracker #1510

Merged
merged 13 commits into from
Jan 13, 2025
1 change: 1 addition & 0 deletions .github/validation_samples/ecal_pn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@
seed_recoil_dqm.title = ""
seed_recoil_dqm.buildHistograms()


recoil_dqm = tkdqm.TrackingRecoDQM("RecoilDQM")
recoil_dqm.track_collection = tracking_recoil.out_trk_collection
recoil_dqm.truth_collection = "RecoilTruthTracks"
Expand Down
46 changes: 46 additions & 0 deletions DQM/include/DQM/TrkDeDxMassEstFeatures.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef DQM_TRKDEDXMASSESTFEATURES_H
#define DQM_TRKDEDXMASSESTFEATURES_H

// LDMX Framework
#include "Framework/Configure/Parameters.h" // Needed to import parameters from configuration file
#include "Framework/EventProcessor.h" //Needed to declare processor

namespace dqm {

/**
* @class TrkDeDxMassEstFeatures
* @brief Generate histograms to check tracker dE/dx mass estimate features
*/
class TrkDeDxMassEstFeatures : public framework::Analyzer {
public:
/**
* Constructor
*
* Blank Analyzer constructor
*/
TrkDeDxMassEstFeatures(const std::string& name, framework::Process& process)
: framework::Analyzer(name, process) {}

/**
* Input python configuration parameters
*/
virtual void configure(framework::config::Parameters& ps);

/**
* Fills histograms
*/
virtual void analyze(const framework::Event& event);

/// Method executed before processing of events begins.
void onProcessStart() override;

private:
/// Collection Name for mass estimate object
std::string mass_estimate_name_;

/// Pass Name for mass estimate object
std::string mass_estimate_pass_;
};
} // namespace dqm

#endif /* DQM_TRKDEDXMASSESTFEATURES_H */
27 changes: 27 additions & 0 deletions DQM/python/dqm.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,30 @@ def __init__(self,name='RecoilTracker') :
self.build1DHistogram("tpy%s" % t, "Recoil e^{-} Truth p_{y} (MeV)", 100, -10, 10)
self.build1DHistogram("tpz%s" % t, "Recoil e^{-} Truth p_{z} (MeV)", 260, -100, 2500)

class TrkDeDxMassEstFeatures(ldmxcfg.Analyzer) :
"""Configured TrkDeDxMassEstFeatures python object

Contains an instance of TrkDeDxMassEstFeatures that
has already been configured.

Builds the necessary histograms as well.

Examples
--------
from LDMX.DQM import dqm
p.sequence.append( dqm.TrkDeDxMassEstFeatures() )
"""

def __init__(self,name='TrkDeDxMassEstFeatures') :
super().__init__(name, "dqm::TrkDeDxMassEstFeatures",'DQM')

self.mass_estimate_name = "TrackDeDxMassEstimate"
self.mass_estimate_pass = ""

self.build1DHistogram("mass_estimate", "Mass Estimate [MeV]", 100, 0, 2000)
self.build1DHistogram("track_type", "Track Type", 3, 0, 3)


class TrigScintSimDQM(ldmxcfg.Analyzer) :
"""Configured TrigScintSimDQM python object

Expand Down Expand Up @@ -712,6 +736,9 @@ def __init__(self, name='SampleValidation') :
RecoilTrackerDQM()
]

dEdx_dqm = [
TrkDeDxMassEstFeatures()
]

trigScint_dqm = [
TrigScintSimDQM('TrigScintSimPad1','TriggerPad1SimHits','pad1'),
Expand Down
40 changes: 40 additions & 0 deletions DQM/src/DQM/TrkDeDxMassEstFeatures.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

#include "DQM/TrkDeDxMassEstFeatures.h"

#include "Recon/Event/TrackDeDxMassEstimate.h"

namespace dqm {

void TrkDeDxMassEstFeatures::configure(framework::config::Parameters &ps) {
mass_estimate_name_ = ps.getParameter<std::string>("mass_estimate_name");
mass_estimate_pass_ = ps.getParameter<std::string>("mass_estimate_pass");

return;
}

void TrkDeDxMassEstFeatures::analyze(const framework::Event &event) {
auto massEstimates{event.getCollection<ldmx::TrackDeDxMassEstimate>(
mass_estimate_name_, mass_estimate_pass_)};

for (const auto &massEst : massEstimates) {
histograms_.fill("mass_estimate", massEst.getMass());
histograms_.fill("track_type", massEst.getTrackType());
}

return;
}

void TrkDeDxMassEstFeatures::onProcessStart() {
std::vector<std::string> labels = {"Other", // 0
"Tagger", // 1
"Recoil", // 2
""};
TH1 *hist = histograms_.get("track_type");
for (int ilabel{1}; ilabel < labels.size(); ++ilabel) {
hist->GetXaxis()->SetBinLabel(ilabel, labels[ilabel - 1].c_str());
}
}

} // namespace dqm

DECLARE_ANALYZER_NS(dqm, TrkDeDxMassEstFeatures);
12 changes: 7 additions & 5 deletions Recon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,19 @@ if(BUILD_EVENT_ONLY)
class "TriggerResult" )
register_event_object( module_path "Recon/Event" namespace "ldmx"
class "HgcrocDigiCollection" )
register_event_object( module_path "Recon/Event"
register_event_object( module_path "Recon/Event"
namespace "ldmx" class "HgcrocTrigDigi"
type "collection" )
register_event_object( module_path "Recon/Event"
register_event_object( module_path "Recon/Event"
namespace "ldmx" class "CaloTrigPrim"
type "collection" )
register_event_object(module_path "Recon/Event" namespace "ldmx"
register_event_object(module_path "Recon/Event" namespace "ldmx"
class "PFCandidate" type "collection" )
register_event_object( module_path "Recon/Event" namespace "ldmx"
register_event_object( module_path "Recon/Event" namespace "ldmx"
class "BeamElectronTruth" type "collection" )
setup_library(module Recon name Event
register_event_object( module_path "Recon/Event" namespace "ldmx"
class "TrackDeDxMassEstimate" type "collection" )
setup_library(module Recon name Event
dependencies ROOT::Core
register_target)

Expand Down
107 changes: 107 additions & 0 deletions Recon/include/Recon/Event/TrackDeDxMassEstimate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* @file TrackDeDxMassEstimate.h
* @brief Class that represents the estimated mass of a particle
* using tracker dE/dx information
* @author Danyi Zhang, Tamas Almos Vami (UCSB)
*/

#ifndef RECON_TRACKDEDXMASSESTIMATE_H_
#define RECON_TRACKDEDXMASSESTIMATE_H_

#include <iostream>

// ROOT
#include "TObject.h" //For ClassDef

// LDMX
// #include "Event/Track.h"
// #include "Event/Measurement.h"

namespace ldmx {
/**
* @class TrackDeDxMassEstimate
* @brief Represents the estimated mass of a particle
* using tracker dE/dx information
* @note This class represents the estimated mass information
* from a tracker including mass, track index, and the track type
*/

class TrackDeDxMassEstimate {
public:
/**
* Class constructor.
*/
TrackDeDxMassEstimate();

/**
* Class destructor.
*/
virtual ~TrackDeDxMassEstimate();

/**
* Clear the data in the object.
*/
void Clear();

/**
* Print out the object.
*/
void Print() const;

/**
* Set the estimated mass of the particle/track.
* @param mass The estimated mass of the particle/track.
*/
void setMass(double mass) { mass_ = mass; }

/**
* Set the index of the track.
* @param trackIndex The index of the track.
*/
void setTrackIndex(int trackIndex) { trackIndex_ = trackIndex; }

/**
* Set the type of the track.
* @param trackType The type of the track.
* 1: tagger track, 2: recoil track
* Possibly consider truth with 0
* and ECAL with 3
*/
void setTrackType(int trackType) { trackType_ = trackType; }

/**
* Get the estimated mass of the particle/track.
* @return The estimated mass of the particle/track.
*/
double getMass() const { return mass_; }

/**
* Get the index of the track.
* @return The index of the track.
*/
int getTrackIndex() const { return trackIndex_; }

/**
* Get the type of the track.
* @return The type of the track.
*/
int getTrackType() const { return trackType_; }

private:
/* The estimated mass of the particle/track */
double mass_{0.};

/* The index of the track */
int trackIndex_{-1};

/* The type of the track */
int trackType_{-1};

/**
* The ROOT class definition.
*/
ClassDef(TrackDeDxMassEstimate, 1);
};
} // namespace ldmx

#endif // RECON_TRACKDEDXMASSESTIMATE_H_
52 changes: 52 additions & 0 deletions Recon/include/Recon/TrackDeDxMassEstimator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @file TrackDeDxMassEstimator.h
* @brief Class that estimates the mass of a particle using tracker dE/dx
* information
* @author Danyi Zhang, Tamas Almos Vami (UCSB)
*/

#ifndef RECON_TRACKDEDXMASSESTIMATOR_H_
#define RECON_TRACKDEDXMASSESTIMATOR_H_

// LDMX Framework
#include "Framework/Configure/Parameters.h"
#include "Framework/EventProcessor.h"
#include "Recon/Event/TrackDeDxMassEstimate.h"
#include "Tracking/Event/Measurement.h"
#include "Tracking/Event/Track.h"

namespace recon {

/**
* @class TrackDeDxMassEstimator
* @brief
*/
class TrackDeDxMassEstimator : public framework::Producer {
public:
TrackDeDxMassEstimator(const std::string& name, framework::Process& process)
: framework::Producer(name, process) {}

virtual void configure(framework::config::Parameters& ps) override;

virtual void produce(framework::Event& event) override;

private:
// specific verbosity of this producer
int verbose_{0};

float fit_res_C_{0.};
float fit_res_K_{-9999.};

float si_sensor_thickness_mm{0.32};

// name of input track collection
std::string trackCollection_;

// name of input simhit collection
std::string simhitCollection_;

}; // TrackDeDxMassEstimator

} // namespace recon

#endif // RECON_TRACKDEDXMASSESTIMATOR_H_
40 changes: 40 additions & 0 deletions Recon/python/trackDeDxMassEstimator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Configuration for TrackDeDxMassEstimator

The tracker dE/dx vs momentum 2d distribution profile
histogram can be fitted using an approximated
Bethe-Bloch parametrization at low relativistic regime:
dE/dx = K * m^2 / p^2 + C,
where m is the particle mass, p is the particle momentum,
K and C are fit parameters.
Using the fitted result of the parameters, the mass of
the particle can be calculated from its dE/dx and momentum.

Attributes:
-------------
track_collection : string
Name of the track collection used as input
fit_res_C : float
The fitted result of the constant term C (unit: MeV/mm)
fit_res_K : float
The fitted result of the factor K of the quadratic term (dimentionless)

Examples
--------
from LDMX.Recon.trackDeDxMassEstimator import reoilTrackMassEstimator
p.sequence.append( reoilTrackMassEstimator )
"""

from LDMX.Framework import ldmxcfg

class trackDeDxMassEstimator(ldmxcfg.Producer) :
"""Configuration for the mass estimator from tracker dEdx"""

def __init__(self, name="TrackDeDxMassEstimator") :
super().__init__(name,'recon::TrackDeDxMassEstimator','Recon')

self.track_collection = "RecoilTruthTracks"
self.fit_res_C = 3.094
self.fit_res_K = 1.862

recoilTrackMassEstimator = trackDeDxMassEstimator("RecoilTrackMassEstimator")
recoilTrackMassEstimator.track_collection = "RecoilTruthTracks"
23 changes: 23 additions & 0 deletions Recon/src/Recon/Event/TrackDeDxMassEstimate.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "Recon/Event/TrackDeDxMassEstimate.h"

ClassImp(ldmx::TrackDeDxMassEstimate);

namespace ldmx {
TrackDeDxMassEstimate::TrackDeDxMassEstimate() {}

TrackDeDxMassEstimate::~TrackDeDxMassEstimate() { Clear(); }

void TrackDeDxMassEstimate::Clear() {
mass_ = 0.;
trackIndex_ = -1;
trackType_ = -1;
}

void TrackDeDxMassEstimate::Print() const {
std::cout << "TrackDeDxMassEstimate { "
<< "Mass: " << mass_ << ", "
<< "Track Index: " << trackIndex_ << ", "
<< "Track Type: " << trackType_ << " }" << std::endl;
}

} // namespace ldmx
Loading