CosmicsdQdx_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: CosmicsdQdx
3 // Plugin Type: analyzer (art v3_05_01)
4 // File: CosmicsdQdx_module.cc
5 //
6 // Generate simple summary tree from track dQ/dx measurements for each
7 // collection view to check track calorimetry and effecit CRP gains
8 // Follow the same logic as in TrackCalorimetryAlg
9 //
10 // Generated at Tue May 26 16:28:38 2020 by Vyacheslav Galymov using cetskelgen
11 // from cetlib version v3_10_00.
12 ////////////////////////////////////////////////////////////////////////
13 #include <iostream>
14 #include <vector>
15 #include <utility>
16 
24 #include "fhiclcpp/ParameterSet.h"
26 
27 #include "art_root_io/TFileService.h"
28 
29 // LArSoft includes
38 
39 //
42 
43 // ROOT
44 #include "TTree.h"
45 //#include "TMath.h"
46 //#include "TH1F.h"
47 //#include "TFile.h"
48 
49 //
50 using std::cerr;
51 using std::cout;
52 using std::endl;
53 using std::vector;
54 using std::string;
55 using std::pair;
56 
57 //
58 namespace pddpana {
59  class CosmicsdQdx;
60 }
61 
62 //
63 namespace {
64  //from calo::TrackCalorimetryAlg
65  class dist_projected{
66  public:
67  dist_projected(recob::Hit const* h, geo::Geometry const* g):
68  hit(h), geom(g){}
69  bool operator() (std::pair<geo::WireID,float> i, std::pair<geo::WireID,float> j)
70  {
71  float dw_i = ((int)(i.first.Wire) - (int)(hit->WireID().Wire))*geom->WirePitch(i.first.Plane);
72  float dw_j = ((int)(j.first.Wire) - (int)(hit->WireID().Wire))*geom->WirePitch(j.first.Plane);
73  float dt_i = i.second - hit->PeakTime();
74  float dt_j = j.second - hit->PeakTime();
75  return (std::sqrt(dw_i*dw_i + dt_i*dt_i) < std::sqrt(dw_j*dw_j + dt_j*dt_j));
76  }
77  private:
78  recob::Hit const* hit;
79  geo::Geometry const* geom;
80  };
81 }
82 
83 
85 public:
86  explicit CosmicsdQdx(fhicl::ParameterSet const& p);
87  // The compiler-generated destructor is fine for non-base
88  // classes without bare pointers or other resource use.
89 
90  // Plugins should not be copied or assigned.
91  CosmicsdQdx(CosmicsdQdx const&) = delete;
92  CosmicsdQdx(CosmicsdQdx&&) = delete;
93  CosmicsdQdx& operator=(CosmicsdQdx const&) = delete;
94  CosmicsdQdx& operator=(CosmicsdQdx&&) = delete;
95 
96  // Required functions.
97  void analyze(art::Event const& e) override;
98 
99  // Selected optional functions.
100  void beginJob() override;
101  void endJob() override;
102 
103 private:
104 
112 
113  unsigned fDrift;
114 
115  unsigned fTotalTracks;
116  unsigned fSelectedTracks;
117  unsigned fHitCutTracks;
118  unsigned fGeoCutTracks;
119 
120  // summary tree
121  TTree *fTree;
122 
123  //
124  unsigned fEventNum;
125  unsigned fTrackId;
126  unsigned fTrajPoints;
127  float fTrackLen;
129  float fStartX;
130  float fStartY;
131  float fStartZ;
132  float fStartNx;
133  float fStartNy;
134  float fStartNz;
135  float fEndX;
136  float fEndY;
137  float fEndZ;
138  float fEndNx;
139  float fEndNy;
140  float fEndNz;
141 
142  //
143  unsigned fPlane;
144  float fHitAdcSum;
146  float fHitPeak;
147  float fHitTime;
148  float fPitch;
149  float fdQdx;
150  float fX;
151  float fY;
152  float fZ;
153  float fQAsym;
154 
155  // plane hits
156  vector< vector< const recob::Hit* > > fPlaneHits;
157 
158  // track utils
160 
161  // CRP Geo util
163 
164  // detector geometry
166 
167  bool checkCutsAndGetT0( const recob::Track& track, float &T0 );
168  bool checkTrackHitInfo( const recob::Track& track, art::Event const& e);
169 };
170 
171 
173  : EDAnalyzer{p} ,
174  fLogLevel( p.get< int >("LogLevel") ),
175  fTrackModuleLabel( p.get< std::string >("TrackModuleLabel") ),
176  fTrackMinLen( p.get< float >("TrackMinLen") ),
177  fTrackDriftCut( p.get< float >("TrackDriftCut") ),
178  fTrackWallCut( p.get< float >("TrackWallCut") ),
179  fTrackLemCut( p.get< float >("TrackLemCut") ),
180  fMaxHitMultiplicity( p.get< float >("MaxHitMultiplicity") )
181  {
183 
184  //auto const &tpc = ;
186  if( fDrift != 1 ){
187  throw cet::exception("CosmicsdQdx") << "Drift direction "<<fDrift
188  << " is not support\n";
189  }
190  }
191 
192 //
194 {
195  const string myname = "pddpana::CosmicsdQdx::analyze: ";
196 
197  // get tracks
198  auto Tracks = e.getValidHandle<vector<recob::Track>>(fTrackModuleLabel);
199  fTotalTracks += Tracks->size();
200 
201  if( fLogLevel >= 2 ){
202  cout<<myname<<"The event contains "<< Tracks->size() <<" tracks\n";
203  }
204 
205  //
206  fEventNum = e.id().event();
207 
208  // loop over tracks
209  for (unsigned itrk = 0; itrk < Tracks->size(); ++itrk) {
210  const recob::Track& track = Tracks->at(itrk);
211 
212  fTrackId = itrk;
214  fTrackLen = track.Length();
215 
216  //
217  fStartX = track.Vertex().X();
218  fStartY = track.Vertex().Y();
219  fStartZ = track.Vertex().Z();
220 
221  fEndX = track.End().X();
222  fEndY = track.End().Y();
223  fEndZ = track.End().Z();
224 
225  fStartNx = track.VertexDirection().X();
226  fStartNy = track.VertexDirection().Y();
227  fStartNz = track.VertexDirection().Z();
228 
229  fEndNx = track.EndDirection().X();
230  fEndNy = track.EndDirection().Y();
231  fEndNz = track.EndDirection().Z();
232 
233  fQAsym = 0;
234  if( !checkTrackHitInfo( track, e ) ){
235  if( fLogLevel >= 2 ){
236  cout<<myname<<"Skipping track ID "<<fTrackId
237  <<" due to hit plane mismatch "<<endl;
238  }
239  fHitCutTracks++;
240  continue;
241  }
242 
243  fDriftOffset = 0;
244  if( !checkCutsAndGetT0( track, fDriftOffset) ){
245  if( fLogLevel >= 2 ){
246  cout<<myname<<"Skipping track ID "<<fTrackId<<" has "
247  <<fTrajPoints<<" points and is "<<fTrackLen<<" cm long\n";
248  }
249  fGeoCutTracks++;
250  continue;
251  }
252 
253  //
254  if( fLogLevel >= 3 ){
255  cout<<myname<<"Track ID "<<fTrackId<<" has "
256  <<fTrajPoints<<" points and is "<<fTrackLen<<" cm long"
257  << "\n start at: ( " << track.Vertex().X()
258  << " ; " << track.Vertex().Y()
259  << " ; " << track.Vertex().Z()
260  << "\n end at: ( " << track.End().X()
261  << " ; " << track.End().Y()
262  << " ; " << track.End().Z()<<" )"<<endl;
263  }
264 
265  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService>()->DataFor(e);
266  // loop over the planes
267  for(size_t i_plane=0; i_plane<fGeom->Nplanes(); i_plane++) {
268  fPlane = i_plane;
269 
270  // get hits in this plane
271  //auto hits = trackUtil.GetRecoTrackHitsFromPlane( track, e, fTrackModuleLabel, i_plane );
272  auto hits = fPlaneHits[ i_plane ]; // loaded in checkTrackHitInfo
273  if( fLogLevel >= 3 ){
274  cout<<myname<<"Hits in plane "<<i_plane<<" "<<hits.size()<<endl;
275  }
276  //
277 
278  //project down the track into wire/tick space for this plane
279  vector< unsigned > traj_points_idx;
280  vector< pair<geo::WireID,float> > traj_points_in_plane; //(track.NumberTrajectoryPoints());
281  for(size_t i_trjpt=0; i_trjpt<track.NumberTrajectoryPoints(); i_trjpt++){
282  auto pnt = track.LocationAtPoint(i_trjpt);
283  if( !track.HasValidPoint( i_trjpt ) ){
284  if( fLogLevel>=4 ){
285  cerr<<"track point "<<i_trjpt<<" has position ("
286  <<pnt.X()<<", "<<pnt.Y()<<", "<<pnt.Z()<<") \n"
287  <<" and is not a valid point "<<track.HasValidPoint( i_trjpt )<<endl;
288  }
289  continue;
290  }
291 
292  double x_pos = pnt.X();
293  float tick = detProp.ConvertXToTicks(x_pos,(int)i_plane,0,0);
294  try{
295  auto tpcid = fGeom->PositionToTPCID(pnt);
296  // if( tpcid.TPC >= fGeom->NTPC() ){
297  // if( fLogLevel>=3 ){
298  // cerr<<myname<<"tpc no "<<tpcid.TPC<<" is not valid \n"
299  // <<" track id "<<fTrackId<<" at ("
300  // <<pnt.X()<<", "<<pnt.Y()<<", "<<pnt.Z()<<") \n"
301  // <<" has valid point "<<track.HasValidPoint( i_trjpt )<<endl;
302  // }
303  // continue;
304  // }
305  geo::WireID wid = fGeom->NearestWireID(pnt, geo::PlaneID(tpcid, i_plane));
306  //traj_points_in_plane[i_trjpt] = std::make_pair(wid, tick);
307  traj_points_in_plane.push_back( std::make_pair(wid, tick) );
308  traj_points_idx.push_back( i_trjpt );
309  }
310  catch(cet::exception &e){
311  if( fLogLevel>=4 ){
312  cout<<e;
313  }
314  continue;
315  }
316  }
317 
318  //
319  // from calo::TrackCalorimetryAlg::AnalyzeHit
320  for(auto const &hit: hits ){
321  //skip high mulitplicity hits
322  if(hit->Multiplicity() > (int)fMaxHitMultiplicity) continue;
323 
324  //
325  size_t traj_iter = std::distance( traj_points_in_plane.begin(),
326  std::min_element( traj_points_in_plane.begin(),
327  traj_points_in_plane.end(),
328  dist_projected(hit, fGeom) ) );
329  size_t traj_pnt_idx = traj_points_idx[traj_iter];
330  try{
331  // fGeom->View(hit->WireID().Plane) always returns 3 (geo::kY) for some reason
332  //fPitch = lar::util::TrackPitchInView(track, fGeom->View(hit->WireID().Plane), traj_pnt_idx);
333  fPitch = lar::util::TrackPitchInView(track, hit->View(), traj_pnt_idx);
334  }
335  catch(cet::exception &e){
336  if( fLogLevel>=3 ){
337  cout<<e;
338  }
339  continue;
340  }
341 
342  // hit properties
343  fHitAdcSum = hit->SummedADC();
344  fHitIntegral = hit->Integral();
345  fHitPeak = hit->PeakAmplitude();
346  fHitTime = hit->PeakTime();
347  fdQdx = fHitAdcSum / fPitch;
348 
349  auto pnt = track.LocationAtPoint(traj_iter);
350  fX = pnt.X();
351  fY = pnt.Y();
352  fZ = pnt.Z();
353 
354  // if( fEventNum == 11540 && fTrackId == 0 ){
355  // auto dir1 = track.DirectionAtPoint(traj_iter);
356  // cout<<i_plane<<" "<<fPitch<<" "<<fX<<" "<<fY<<" "<<fZ<<" "
357  // <<dir1.X()<<" "<<dir1.Y()<<" "<<dir1.Z()<<endl;
358  //}
359 
360  fTree->Fill();
361  }// loop over track plane hits
362 
363  }// end plane loop
364 
365  //
366  fSelectedTracks++;
367  }// end track loop
368 
369 } // end analyze()
370 
371 //
373 {
374  fPlaneHits.resize( fGeom->Nplanes() );
375 
376  fTotalTracks = 0;
377  fSelectedTracks = 0;
378  fHitCutTracks = 0;
379  fGeoCutTracks = 0;
380 
381  // init summary tree
383  fTree = tfs->make<TTree>("cranaTree","Check cosmics dQdx");
384  fTree->Branch("EventNum", &fEventNum, "EventNum/i");
385  fTree->Branch("TrackId", &fTrackId, "TrackId/i");
386  fTree->Branch("TrajPoints", &fTrajPoints, "TrajPoints/i");
387  fTree->Branch("TrackLen", &fTrackLen, "TrackLen/F");
388  fTree->Branch("DriftOffset", &fDriftOffset, "DriftOffset/F");
389  fTree->Branch("StartX", &fStartX, "StartX/F");
390  fTree->Branch("StartY", &fStartY, "StartY/F");
391  fTree->Branch("StartZ", &fStartZ, "StartZ/F");
392  fTree->Branch("StartNx", &fStartNx, "StartNx/F");
393  fTree->Branch("StartNy", &fStartNy, "StartNy/F");
394  fTree->Branch("StartNz", &fStartNz, "StartNz/F");
395  fTree->Branch("EndX", &fEndX, "EndX/F");
396  fTree->Branch("EndY", &fEndY, "EndY/F");
397  fTree->Branch("EndZ", &fEndZ, "EndZ/F");
398  fTree->Branch("EndNx", &fEndNx, "EndNx/F");
399  fTree->Branch("EndNy", &fEndNy, "EndNy/F");
400  fTree->Branch("EndNz", &fEndNz, "EndNz/F");
401 
402  fTree->Branch("Plane", &fPlane, "Plane/i");
403  fTree->Branch("HitAdcSum", &fHitAdcSum, "HitAdcSum/F");
404  fTree->Branch("HitIntegral", &fHitIntegral, "HitIntegral/F");
405  fTree->Branch("HitPeak", &fHitPeak, "HitPeak/F");
406  fTree->Branch("HitTime", &fHitTime, "HitTime/F");
407  fTree->Branch("Pitch", &fPitch, "Pitch/F");
408  fTree->Branch("dQdx", &fdQdx, "dQdx/F");
409  fTree->Branch("QAsym", &fQAsym, "QAsym/F");
410  fTree->Branch("X", &fX, "X/F");
411  fTree->Branch("Y", &fY, "Y/F");
412  fTree->Branch("Z", &fZ, "Z/F");
413 }
414 
415 //
417 {
418  const string myname = "pddpana::CosmicsdQdx::endJob: ";
419  cout<<myname<<"tracks processed total : "<<fTotalTracks<<endl;
420  cout<<myname<<"tracks processed selected : "<<fSelectedTracks<<endl;
421  cout<<myname<<"tracks cut due to hit info : "<<fHitCutTracks<<endl;
422  cout<<myname<<"tracks cut due to geo info : "<<fGeoCutTracks<<endl;
423 
424 }
425 
426 //
427 //
429 {
430  const string myname = "pddpana::CosmicsdQdx::checkCutsAndGetT0: ";
431 
432  //
433  T0 = 0; // track distance in cm from the top
434 
435  if( track.Length() < fTrackMinLen ){
436  if( fLogLevel>=3 ){
437  cout<<myname<<"Failed to pass length cut "<<track.Length()<<endl;
438  }
439  return false;
440  }
441 
442  auto tstart = track.Vertex();
443  auto tend = track.End();
444 
445  // cosmics are downward going and anode is at +300cm
446  if( tstart.X() < tend.X() ){
447  tstart = tend;
448  }
449 
450  auto crp_geo_info = crpGeoUtil.GetCRPGeoInfo( tstart );
451  if( not crp_geo_info.valid ) return false;
452 
453  // drift distance to the anode
454  T0 = crp_geo_info.danode;
455  if( T0 < fTrackDriftCut ){
456  if( fLogLevel>=3 ){
457  cout<<myname<<"Failed to pass T0 cut "<<T0<<endl;
458  }
459  return false;
460  }
461 
462  // distance to CRP border
463  if( crp_geo_info.dedge < fTrackWallCut ){
464  if( fLogLevel>=3 ){
465  cout<<myname<<"Failed to pass wall cut ("
466  <<tstart.X()<<", "<<tstart.Y()<<", "<<tstart.Z()<<")"<<endl;
467  }
468 
469  return false;
470  }
471 
472  // distance to LEM border
473  if( crp_geo_info.dlem < fTrackLemCut ){
474  if( fLogLevel>=3 ){
475  cout<<myname<<"Failed to pass LEM edge cut ("
476  <<tstart.X()<<", "<<tstart.Y()<<", "<<tstart.Z()<<")"<<endl;
477  }
478 
479  return false;
480  }
481 
482  return true;
483 }
484 
485 //
486 // check that hits associated to a track belong to the same CRP
488  const string myname = "pddpana::CosmicsdQdx::checkTrackHitInfo: ";
489 
490  //
491  unsigned EventId = e.id().event();
492 
493 
494  // loop over the planes and get all the hits
495  for(size_t i_plane = 0; i_plane<fGeom->Nplanes(); i_plane++) {
496  // get hits in this plane
497  auto hits = trackUtil.GetRecoTrackHitsFromPlane( track, e, fTrackModuleLabel, i_plane );
498  fPlaneHits[i_plane] = hits;
499  }
500 
501  //
502  // calculate charge asymmetry
503  //
504  // charge in view 0
505  double v0 = 0;
506  for( auto const &h: fPlaneHits[0] ){
507  v0 += h->SummedADC();
508  }
509  // charge in view 1
510  double v1 = 0;
511  for( auto const &h: fPlaneHits[1] ){
512  v1 += h->SummedADC();
513  }
514  // charge asymmetry
515  fQAsym = (v0 - v1)/(v0 + v1);
516 
517  //
518  //
519  // check for TPC mismatches
520  vector<unsigned> hitsTpcId( fGeom->Nplanes() );
521 
522  for(size_t i_plane = 0; i_plane<fGeom->Nplanes(); i_plane++) {
523  auto hits = fPlaneHits[i_plane];
524 
525  vector<unsigned> plane_hits_tpcid( hits.size() );
526  // loop over hits
527  for(size_t i_hit = 0; i_hit<hits.size(); i_hit++ ){
528  plane_hits_tpcid[i_hit] = hits[i_hit]->WireID().TPC;
529  }
530 
531  int this_tpcid = -1;
532  auto start = plane_hits_tpcid.begin();
533  auto end = plane_hits_tpcid.end();
534  if( std::equal(start + 1, end, start)) {
535  this_tpcid = (int)(*start);
536  } //
537  else {
538  if( fLogLevel>= 3){
539  cout<<myname<<"hits for the same plane have mixed TPC IDs. Skipping...\n";
540  }
541  }
542  if( this_tpcid < 0 ){
543  hitsTpcId.clear();
544  break;
545  }
546  else{
547  hitsTpcId[i_plane] = (unsigned)this_tpcid;
548  }
549  }// end plane loop
550 
551  if( hitsTpcId.empty() ) return true;
552 
553  auto start = hitsTpcId.begin();
554  auto end = hitsTpcId.end();
555  if( !std::equal(start + 1, end, start)) {
556  if( fLogLevel >= 3){
557  cout<<myname<<"mismatch in TPC ID for the initial hits: ";
558  cout<<" event ID "<<EventId<<"; hit TPC IDs ";
559  for( auto const &v: hitsTpcId ){ cout<<v<<" ";}
560  cout<<endl;
561  }
562  return false;
563  } //
564 
565  return true;
566 }
567 
568 
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
CosmicsdQdx & operator=(CosmicsdQdx const &)=delete
bool checkTrackHitInfo(const recob::Track &track, art::Event const &e)
static constexpr double g
Definition: Units.h:144
std::string string
Definition: nybbler.cc:12
Point_t const & LocationAtPoint(size_t i) const
Definition: Track.h:126
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
struct vector vector
bool HasValidPoint(size_t i) const
Definition: Track.h:111
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:102
Vector_t VertexDirection() const
Definition: Track.h:132
geo::TPCID PositionToTPCID(geo::Point_t const &point) const
Returns the ID of the TPC at specified location.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
art framework interface to geometry description
crpgeoinfo GetCRPGeoInfo(geo::Point_t const &pnt) const
T abs(T value)
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
const double e
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
protoana::ProtoDUNETrackUtils trackUtil
Point_t const & Vertex() const
Definition: Track.h:124
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
p
Definition: test.py:223
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
The geometry of one entire detector, as served by art.
Definition: Geometry.h:196
vector< vector< const recob::Hit * > > fPlaneHits
Detector simulation of raw signals on wires.
const std::vector< const recob::Hit * > GetRecoTrackHitsFromPlane(const recob::Track &track, art::Event const &evt, const std::string trackModule, unsigned int planeID) const
Get the hits from a given reco track from a specific plane.
void analyze(art::Event const &e) override
Declaration of signal hit object.
bool checkCutsAndGetT0(const recob::Track &track, float &T0)
short int DetectDriftDirection() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.cxx:157
Vector_t EndDirection() const
Definition: Track.h:133
protoana::ProtoDUNEDPCRPGeo crpGeoUtil
double TrackPitchInView(recob::Track const &track, geo::View_t view, size_t trajectory_point=0U)
Returns the projected length of track on a wire pitch step [cm].
Definition: TrackUtils.cxx:78
Provides recob::Track data product.
CosmicsdQdx(fhicl::ParameterSet const &p)
EventNumber_t event() const
Definition: EventID.h:116
Point_t const & End() const
Definition: Track.h:125
geo::WireID NearestWireID(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the ID of wire closest to position in the specified TPC.
Declaration of basic channel signal object.
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
Utility functions to extract information from recob::Track
EventID id() const
Definition: Event.cc:34
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
const geo::Geometry * fGeom
QTextStream & endl(QTextStream &s)