26 #include "art_root_io/TFileService.h" 28 #include "canvas/Persistency/Common/FindManyP.h" 45 #include "TInterpreter.h" 84 Name(
"CalorimetryAlg"),
Comment(
"Used to calculate electrons from ADC area.")
88 Name (
"CalWireModuleLabel"),
Comment(
"Calwire data product name")
92 Name (
"HitModuleLabel"),
Comment(
"Hit data product name")
96 Name (
"ClusterModuleLabel"),
Comment(
"Cluster data product name")
100 Name (
"TrackModuleLabel"),
Comment(
"Track data product name")
104 Name (
"TotalGain"),
Comment(
"Total Gain of the detector")
108 Name (
"EnergyCut"),
Comment(
"Cut over the event energy")
112 Name (
"Length"),
Comment(
"minimal length to define a mip")
116 Name(
"StitchAngle"),
Comment(
"Max. stitching angle")
120 Name(
"StitchDistance"),
Comment(
"Max. stitching distance")
124 Name(
"VolCut"),
Comment(
"Volume Cut to select a going trougth muon")
128 Name(
"NumOfBins"),
Comment(
"Number of histogram for the purity analysis")
150 void MakeDataProduct();
152 void endJob()
override;
154 void FillEventHitsTree(std::vector<recob::Hit> hits);
155 double GetCharge(std::vector<recob::Hit> hits);
157 bool IsCrossing(TVector3
Start, TVector3
End);
159 void Make_dEdx(std::vector< double > &
dEdx, std::vector< double > & range,
160 const std::vector< pdunedp::bHitInfo > & hits,
recob::Track mip,
int Flip,
unsigned int plane);
161 void FillTajectoryGraph(std::map<size_t, recob::Track > MipCandidate,
162 art::FindManyP<recob::Hit> HitsTrk);
166 double GetCorrectedCharge(
recob::Track trk,
double charge,
unsigned int plane);
187 int Events=0;
int SkipEvents=0;
int BadEvents=0;
204 double fMipCharge, fMipLength, fMipPhi, fMipTheta;
int fNHitsMip;
205 double fCosX;
double fCosY;
double fCosZ;
208 double fADCIntegral_corrected;
double fADCIntegral;
double fADCPeak;
double fADCPeak_corrected;
double fCorrectedCharge;
double fCharge;
209 double fDrift;
int fWire;
double fCorrection;
double fdQds;
217 double fElectronCharge = 1.60217662e-4;
218 double fMipChargeCm = 10;
225 TTree *fTree; TTree *
fTreeTrk; TTree *fTreeMip; TTree *fTreeHitsMip; TTree *fTreeCalib;
228 TH1D *htbin[3][100]; TH1D *htbin_singlehits[3][100]; TH1D *htbin_num[3][100];
233 fCalorimetryAlg(config().CalorimetryAlg()),
234 fCalWireModuleLabel(config().CalWireModuleLabel()),
235 fHitModuleLabel(config().HitModuleLabel()),
236 fClusterModuleLabel(config().ClusterModuleLabel()),
237 fTrackModuleLabel(config().TrackModuleLabel()),
238 fTotalGain(config().TotalGain()),
239 fECut(config().EnergyCut()),
241 fStitchAngle(config().StitchAngle()),
242 fStitchDistance(config().StitchDistance()),
243 fVolCut(config().VolCut()),
244 fNumOfBins(config().NumOfBins()),
245 fADCtoCharge(config().ADCtoCharge()),
246 fMinDx(config().MinDx())
263 fTree = tfs->make<TTree>(
"Event",
"LAr purity analysis information");
274 fTreeHits =tfs->make<TTree>(
"HitsEvent",
"Info on hits in event");
290 fTreeTrk = tfs->make<TTree>(
"TrkInfo",
"Information on tracks");
301 fTreeMip = tfs->make<TTree>(
"MipInfo",
"Information on mips");
315 fTreeHitsMip =tfs->make<TTree>(
"HitsMip",
"Info hits in mips");
343 fTreeCalib = tfs->make<TTree>(
"Calibration",
"dE/dx info");
353 fTreePurity =tfs->make<TTree>(
"PurityHit",
"Corrected charge for purity analysis");
363 fTreePurityMean =tfs->make<TTree>(
"PurityMean",
"Summed values for every drift bin");
373 hTrkTrajectory_0 = tfs->make<TH2D>(
"hTrkTrajectory_0",
"Selected mips hit position view 0;Channel;Ticks", 320, 0, 319, 1667, 0, 1666);
374 hTrkTrajectory_1 = tfs->make<TH2D>(
"hTrkTrajectory_1",
"Selected mips hit position view 1;Channel;Ticks", 960, 0, 959, 1667, 0, 1666);
382 htbin_singlehits[plane][
nb] = tfs->make<TH1D>(histname_singlehits.c_str(),
";Single hits charge distribution (fC)", 100, 0, 200);
383 htbin[plane][
nb] = tfs->make<TH1D>(histname_average.c_str(),
";Average charge (fC)", 100, 0, 200);
384 htbin_num[plane][
nb] = tfs->make<TH1D>(histname_num.c_str(),
";Number of bins per track", 100, 0, 200);
403 if(!CalwireHandle || !HitHandle || !ClusterHandle || !TrackHandle){
410 for(
auto const& Calwire : *CalwireHandle){
411 for(
float ADC : Calwire.Signal()){
417 mf::LogVerbatim(
"pdunedp::Purity")<<
"Energy: " << Edep <<
" " << Efrac;
419 mf::LogVerbatim(
"pdunedp::Purity") <<
"Too much energy energy deposited! Not a mip";
438 art::FindManyP< recob::Hit, recob::TrackHitMeta > TrackHitMeta(TrackHandle, e,
fTrackModuleLabel);
444 auto track = TrackHandle->at(
t);
456 std::map<size_t, recob::Track > fMipCandidate;
466 if (fMipCandidate.find(It->first) != fMipCandidate.end()){
470 TVector3
Start = (It->second).Vertex<TVector3>(); TVector3
End = (It->second).End<TVector3>();
474 if(It->first == It2->first){
continue; }
475 TVector3 newStart; TVector3 newEnd;
476 if(!
StitchTracks(It->second, It2->second, newStart, newEnd)){
480 fMipCandidate[It->first] = It->second;
481 fMipCandidate[It2->first] = It2->second;
490 fMipCandidate[It->first] = It->second;
494 if(!fMipCandidate.size()){
511 auto vhit = TrackHitMeta.at(mip->first);
512 auto vmeta = TrackHitMeta.data(mip->first);
522 if (fMipCandidate[trkEntry.first].End().Z() < fMipCandidate[trkEntry.first].Vertex().Z()){ Flip = 1; }
524 for(
unsigned int plane=0; plane <
geom->
Nplanes(0); plane++){
525 std::vector< double >
dEdx, range;
526 auto const &
info = trkEntry.second;
527 Make_dEdx(dEdx, range,
info[plane], fMipCandidate[trkEntry.first], Flip, plane);
528 for (
size_t i = 0; i < dEdx.size(); ++i){
545 if(!hits.size()){
return 0.0;}
548 for(
auto const hit : hits){
550 double dqadc =
hit->Integral();
551 if (!std::isnormal(dqadc) || (dqadc < 0))
continue;
560 if(!hits.size()){
return 0.0;}
563 for(
auto hit : hits){
565 double dqadc =
hit.Integral();
566 if (!std::isnormal(dqadc) || (dqadc < 0))
continue;
575 if(!hits.size()){
return;}
577 for(
auto hit : hits){
578 unsigned short plane =
hit.WireID().Plane;
579 int wire =
hit.WireID().Wire;
580 double dqadc =
hit.Integral();
581 double tdrift =
hit.PeakTime();
582 if (!std::isnormal(dqadc) || (dqadc < 0))
continue;
609 if(Dx > sqrt(
pow(Track1.
End().X()-Track2.
End().X(),2) +
pow(Track1.
End().Y()-Track2.
End().Y(),2) +
pow(Track1.
End().Z()-Track2.
End().Z(),2)))
611 Dx= sqrt(
pow(Track1.
End().X()-Track2.
End().X(),2) +
pow(Track1.
End().Y()-Track2.
End().Y(),2) +
pow(Track1.
End().Z()-Track2.
End().Z(),2));
635 Edge1 = Track1.
Vertex<TVector3>(); Edge2 = Track2.
End<TVector3>();
638 Edge1 = Track1.
Vertex<TVector3>(); Edge2 = Track2.
Vertex<TVector3>();
641 Edge1 = Track1.
End<TVector3>(); Edge2 = Track2.
Vertex<TVector3>();
644 Edge1 = Track1.
End<TVector3>(); Edge2 = Track2.
End<TVector3>();
655 bool isCrossing =
false;
657 double vtx[3] = {0, 0, 150};
709 if( (End-Start).Mag() >
fLength ){
712 if( (End.Z() - Start.Z()) > 0 ){
713 if( Start.Z() > minz && End.Z() < maxz){
715 if(End.X() > Start.X()){
716 if((Start.X() <= minx && End.X() >= maxx)){
719 }
else if(End.X() < Start.X()){
720 if((End.X() <= minx && Start.X() >= maxx)){
725 }
else if((End.Z() - Start.Z()) < 0){
726 if( End.Z() > minz && Start.Z() < maxz){
728 if(End.X() > Start.X()){
729 if((Start.X() <= minx && End.X() >= maxx)){
732 }
else if(End.X() < Start.X()){
733 if((End.X() <= minx && Start.X() >= maxx)){
739 mf::LogError(
"pdunedp::Purity") <<
"Track starts and ends in the same Z coordinate";
747 art::FindManyP<recob::Hit> HitsTrk){
751 for(It = MipCandidate.begin(); It !=MipCandidate.end(); It++){
752 auto hits = HitsTrk.at(It->first);
753 if(!hits.size()){
continue; }
754 for(
auto const hit : hits){
755 unsigned short plane =
hit->WireID().Plane;
779 if(!vhits.size()){
return;}
780 for(
size_t h =0;
h< vhits.size();
h++){
781 unsigned int plane= vhits[
h]->WireID().Plane;
782 int wire= vhits[
h]->WireID().Wire;
784 double dQadc = vhits[
h]->Integral();
785 if (!std::isnormal(dQadc) || (dQadc < 0))
continue;
786 size_t idx = vmeta[
h]->Index();
787 double dx = vmeta[
h]->Dx();
794 TVector3 Dir = mip.
Vertex<TVector3>() - mip.
End<TVector3>();
796 double CosX = 1./Dir.Unit().X();
797 double CosY = 1./Dir.Unit().Y();
798 double CosZ = 1./Dir.Unit().Z();
801 double PeakTime = vhits[
h]->PeakTime();
833 const std::vector< pdunedp::bHitInfo > & hits,
recob::Track mip,
int Flip,
unsigned int plane){
834 if (!hits.size())
return;
836 dEdx.clear(); range.clear();
838 double rmax = mip.
Length();
840 int i0 = hits.size() - 1;
int i1 = -1;
int di = -1;
841 if (Flip) {i0 = 0; i1 = hits.size(); di = 1;}
845 double r0 = 0.0;
double r1 = 0.0;
double r = 0.0;
849 while ((i0 != i1) && (r < rmax))
852 while ((i0 != i1) && (dx <= minDx))
863 if ((de > 0.0) && (dx > 0.0) && (r < rmax))
865 dEdx.push_back(de/dx);
879 int TicksPerBin = detProp.NumberTimeSamples()/
fNumOfBins;
881 double charge[100];
double num[100];
885 mf::LogError(
"pdunedp::Purity") <<
"The track has no hit associated!";
888 int nfound =0;
int nstart;
int nstop;
890 for (
size_t nh=0; nh<hits.size(); nh++){
892 double dqadc = hits[nh]->Integral();
893 double htime = hits[nh]->PeakTime();
894 unsigned short plane = hits[nh]->WireID().Plane;
895 if(plane != pl) {
continue;}
898 double dq = dqadc*conv;
909 nstop =
std::min(nfound+5,fNumOfBins);
912 for(
int nb=nstart;
nb<nstop;
nb++) {
913 double tmin=TicksPerBin*
nb;
914 double tmax=TicksPerBin*(nb+1);
917 if ( (htime>=tmin) && (htime<tmax) ){
939 if (charge[
nb]>0 && num[
nb] >0) {
941 if (
nb<ifirst) ifirst=
nb;
942 if (
nb>ilast) ilast=
nb;
948 for (
int nb=0;
nb<ilast-ifirst-1;
nb++){
949 mf::LogVerbatim(
"pdunedp::Purity") <<
"plane " << pl <<
" nb " <<
nb+ifirst+1<<
" charge bin " << charge[
nb+ifirst+1]/num[
nb+ifirst+1];
951 htbin[pl][
nb]->Fill( charge[
nb+ifirst+1]/num[
nb+ifirst+1] );
968 double charge_corr =0.;
972 angle = atan( fabs( (trk.
End().X()-trk.
Vertex().X())/(trk.
End().Y()-trk.
Vertex().Y()) ) );
975 angle = atan( fabs( (trk.
End().X()-trk.
Vertex().X())/(trk.
End().Z()-trk.
Vertex().Z()) ) );
978 mf::LogError(
"pdunedp::Purity") <<
"Invalid plane number!";
981 if(fabs(cos(angle))>0.){ charge_corr = charge*fabs(cos(angle)); }
988 double correction =0.;
992 angle = atan( fabs( (trk.
End().X()-trk.
Vertex().X())/(trk.
End().Y()-trk.
Vertex().Y()) ) );
995 angle = atan( fabs( (trk.
End().X()-trk.
Vertex().X())/(trk.
End().Z()-trk.
Vertex().Z()) ) );
998 mf::LogError(
"pdunedp::Purity") <<
"Invalid plane number!";
1001 if(fabs(cos(angle))>0.){ correction = fabs(cos(angle)); }
1017 mf::LogVerbatim(
"pdunedp::Purity") <<
"SubRun: " << goodevent->first <<
" Event: " << goodevent->second ;
def analyze(root, level, gtrees, gbranches, doprint)
Store parameters for running LArG4.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
float Length(const PFPStruct &pfp)
static constexpr double nb
void FindMipInfo(recob::Track mip, std::vector< art::Ptr< recob::Hit >> vhits, const std::vector< const recob::TrackHitMeta *, std::allocator< const recob::TrackHitMeta * > > vmeta)
CryostatGeo const & GetElement(geo::CryostatID const &cryoid) const
bool IsCrossing(TVector3 Start, TVector3 End)
std::map< size_t, recob::Track > TrackList
double MinX() const
Returns the world x coordinate of the start of the box.
Geometry information for a single TPC.
ChannelGroupService::Name Name
calo::CalorimetryAlg fCalorimetryAlg
Vector_t VertexDirection() const
art::InputTag fClusterModuleLabel
double MaxX() const
Returns the world x coordinate of the end of the box.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
art framework interface to geometry description
TH1D * htbin_singlehits[3][100]
double GetCharge(std::vector< recob::Hit > hits)
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
art::InputTag fCalWireModuleLabel
std::map< int, int > goodevents
double dEdx(float dqdx, float Efield)
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
double fSummedADC_corrected
double Length(size_t p=0) const
Access to various track properties.
#define DEFINE_ART_MODULE(klass)
art::InputTag fTrackModuleLabel
void FillTajectoryGraph(std::map< size_t, recob::Track > MipCandidate, art::FindManyP< recob::Hit > HitsTrk)
void FillPurityHist(recob::Track track, std::vector< art::Ptr< recob::Hit >> hits)
Point_t const & Vertex() const
double GetCorrection(recob::Track trk, unsigned int plane)
Purity(Parameters const &config)
double MinZ() const
Returns the world z coordinate of the start of the box.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
void analyze(art::Event const &e) override
TrajectoryPoint_t TrajectoryPoint(size_t i) const
Access to i-th TrajectoryPoint or its Flags.
SubRunNumber_t subRun() const
static int max(int a, int b)
The data type to uniquely identify a TPC.
art::ServiceHandle< geo::Geometry > geom
double GetCorrectedCharge(recob::Track trk, double charge, unsigned int plane)
Detector simulation of raw signals on wires.
void FillEventHitsTree(std::vector< recob::Hit > hits)
std::vector< double > fVolCut
double fADCIntegral_corrected
bool HasTPC(geo::TPCID const &tpcid) const
Returns whether we have the specified TPC.
Declaration of signal hit object.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Vector_t EndDirection() const
double MaxZ() const
Returns the world z coordinate of the end of the box.
void Make_dEdx(std::vector< double > &dEdx, std::vector< double > &range, const std::vector< pdunedp::bHitInfo > &hits, recob::Track mip, int Flip, unsigned int plane)
Provides recob::Track data product.
double fADCPeak_corrected
EventNumber_t event() const
Point_t const & End() const
bool StitchTracks(recob::Track Track1, recob::Track Track2, TVector3 &Edge1, TVector3 &Edge2)
Declaration of basic channel signal object.
bHitInfo(size_t i, double x, double e, int w)
art::InputTag fHitModuleLabel
std::map< size_t, std::vector< pdunedp::bHitInfo >[3] > fTrk2InfoMap
std::string to_string(ModuleType const mt)
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
static TemplateFilterFactory::AutoRegister< FilterLength > fLength("length")