LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
ShowerReco_module.cc
Go to the documentation of this file.
1 //
3 // \file ShowerReco_module.cc
4 //
5 // biagio.rossi@lhep.unibe.ch (FWMK : argoslope.resize(fNPlanes);neut specific)
6 // thomas.strauss@lhep.unibe.ch (ART : general detector)
7 //
8 // andrzej.szelc@yale.edu (port to detector agnostic version)
9 // jasaadi@fnal.gov (Try to rewrite the code to make it more readable and to be able to handle
10 // multiple TPC's and cryostats and more than one cluster per plane.)
11 //
12 // This algorithm is designed to reconstruct showers
13 //
15 
16 #ifndef SHOWERRECO_H
17 #define SHOWERRECO_H
18 
19 // ### Generic C++ includes ###
20 #include <vector>
21 #include <string>
22 #include <cmath> // std::tan() ...
23 #include <algorithm>
24 #include <iostream>
25 #include <fstream>
26 #include <sstream>
27 #include <stdint.h>
28 extern "C" {
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 }
32 
33 // ### Framework includes ###
38 #include "fhiclcpp/ParameterSet.h"
46 
47 // ### ROOT includes ###
48 #include "TMatrixD.h"
49 #include "TVectorD.h"
50 #include "TDecompSVD.h"
51 #include "TH1.h"
52 #include "TH2.h"
53 #include "TF1.h"
54 #include "TFile.h"
55 #include "TMath.h"
56 #include "TTree.h"
57 
58 // ### LArSoft includes ###
59 
75 
76 
77 namespace shwf {
78 
79  class ShowerReco : public art::EDProducer {
80 
81  public:
82 
84  explicit ShowerReco(fhicl::ParameterSet const& pset);
85  virtual ~ShowerReco();
86  void beginJob();
87  void beginRun(art::Run& run);
88  void reconfigure(fhicl::ParameterSet const& pset);
89  void produce(art::Event& evt);
91  void GetVertexAndAnglesFromCluster(art::Ptr< recob::Cluster > clust,unsigned int plane); // Get shower vertex and slopes.
92  // void GetVertexN(art::Event& evt);
94 
95  void LongTransEnergy(unsigned int set, std::vector< art::Ptr<recob::Hit> > hitlist, bool isData=false); //Longtudinal
96 
97 
98 
99  private:
100 
101  void ClearandResizeVectors(unsigned int nPlanes);
102 
103 
105  // calo::CalorimetryAlg calorim;
106 //input labels:
107  float slope[3]; // in cm, cm
108  float angle[3]; // in radians
109 
110 
111  std::string fClusterModuleLabel;
112 
113  float ftimetick; // time sample in us
114  double xyz_vertex[3];
115 
116 
118  double fMean_wire_pitch ; // wire pitch in cm
120 
121  std::vector<double> fRMS_2cm;
122  std::vector<int> fNpoints_2cm;
123  std::vector<double> fCorr_MeV_2cm;
124  std::vector<double> fCorr_Charge_2cm;
125 
126  std::vector<int> fNpoints_corr_ADC_2cm;
127  std::vector<int> fNpoints_corr_MeV_2cm;
128 
129  std::vector<double> fTotChargeADC; //Total charge in ADC/cm for each plane
130  std::vector<double> fTotChargeMeV; //Total charge in MeV/cm for each plane
131  std::vector<double> fTotChargeMeV_MIPs; //Total charge in MeV/cm for each plane
132 
133  std::vector<double> fChargeADC_2cm; //Initial charge in ADC/cm for each plane first 4cm
134  std::vector<double> fChargeMeV_2cm; //initial charge in MeV/cm for each plane first 4cm
135 
136  std::vector<double> fChargeMeV_2cm_refined;
137  std::vector<double> fChargeMeV_2cm_axsum;
138 
139  std::vector<std::vector<double> > fDistribChargeADC; //vector with the first De/Dx points ADC
140  std::vector<std::vector<double> > fDistribChargeMeV; //vector with the first De/Dx points converted energy
141  std::vector<std::vector<double> > fDistribHalfChargeMeV;
142  std::vector<std::vector<double> > fDistribChargeposition; //vector with the first De/Dx points' positions
143 
144  std::vector<std::vector<double> > fSingleEvtAngle; //vector with the first De/Dx points
145  std::vector<std::vector<double> > fSingleEvtAngleVal; //vector with the first De/Dx points
146 
147 
148  std::vector<unsigned int> fWire_vertex; // wire coordinate of vertex for each plane
149  std::vector<double> fTime_vertex; // time coordinate of vertex for each plane
150 
151  std::vector<double> fWire_vertexError; // wire coordinate of vertex for each plane
152  std::vector<double> fTime_vertexError; // time coordinate of vertex for each plane
153 
154  std::vector<unsigned int> fWire_last; // wire coordinate of last point for each plane
155  std::vector<double> fTime_last; // time coordinate of last point for each plane
156 
157 
158 
159 
160  //reconstructed 3D position of shower start
161  std::vector<double> xyz_vertex_fit;
162 
163  std::vector< std::vector<double> > fNPitch; // double array, to use each plane for each set of angles
164 
165  //calorimetry variables
166  double Kin_En;
167  std::vector<double> vdEdx;
168  std::vector<double> vresRange;
169  std::vector<double> vdQdx;
170  std::vector<double> deadwire; //residual range for dead wires
171  double Trk_Length;
172  double fTrkPitchC;
173  double fdEdxlength; //distance that gets used to determine e/gamma separation
174  double fcalodEdxlength; // cutoff distance for hits saved to the calo object.
175  bool fUseArea;
176 
177  double xphi,xtheta; // new calculated angles.
178  unsigned int fTPC; //tpc type
179  unsigned int fNPlanes; // number of planes
180  unsigned int fNAngles;
181  TTree* ftree_shwf;
182 
183  //conversion and useful constants
184  double fWirePitch; //wire pitch in cm
185  double fTimeTick;
186  double fDriftVelocity;
188 
189  std::vector< int > fNhitsperplane;
190  std::vector< double > fTotADCperplane;
191  //services
192 
194  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
195 
196 // //temporary
197 // int mcpdg;
198 // double mcenergy;
199 // double mcphi;
200 // double mctheta;
201 // std::vector< unsigned int> mcwirevertex; // wire coordinate of vertex for each plane
202 // std::vector< double> mctimevertex; // time coordinate of vertex for each plane
203 
204 
205 
206 
207  }; // class ShowerReco
208 
209 
210 
211 //------------------------------------------------------------------------------
213 {
214  this->reconfigure(pset);
215  produces< std::vector<recob::Shower> >();
216  produces< art::Assns<recob::Shower, recob::Cluster> >();
217  produces< art::Assns<recob::Shower, recob::Hit> >();
218  produces< std::vector<anab::Calorimetry> >();
219  produces< art::Assns<recob::Shower, anab::Calorimetry> >();
220 }
221 
222 //------------------------------------------------------------------------------
224 {
225  fClusterModuleLabel = pset.get< std::string >("ClusterModuleLabel");
226 // fVertexCLusterModuleLabel=pset.get<std::string > ("VertexClusterModuleLabel");
227  fCaloPSet=pset.get< fhicl::ParameterSet >("CaloAlg");
228 
229  fdEdxlength= pset.get< double >("dEdxlength"); //distance that gets used to determine e/gamma separation
230  fcalodEdxlength= pset.get< double >("calodEdxlength"); // cutoff distance for hits saved to the calo object.
231  fUseArea= pset.get< bool >("UseArea");
232 
233  return;
234 }
235 
236 //------------------------------------------------------------------------------
238 {
239 }
240 
241 // struct SortByWire
242 // {
243 // bool operator() (art::Ptr<recob::Hit> const& h1, art::Ptr<recob::Hit> const& h2) const
244 // {
245 // return (h1->Wire()->RawDigit()->Channel() < h2->Wire()->RawDigit()->Channel());
246 // }
247 // };
248 
249 // ***************** //
251 {
252 
253 
254 
257 
258  detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
259 
262  fNPlanes = geo->Nplanes();
263  fMean_wire_pitch = geo->WirePitch(); //wire pitch in cm
264 
267 
268  // auto const* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
269  ftimetick=detprop->SamplingRate()/1000.;
270 
271 
272 
273 
274 
275 
276  ftree_shwf =tfs->make<TTree>("ShowerReco","Results");
278  // ftree_shwf->Branch("ftheta_Mean","std::vector<double>",&fTheta_Mean);
279  // ftree_shwf->Branch("ftheta_RMS","std::vector<double>",&fTheta_RMS );
280 
281  ftree_shwf->Branch("run",&fRun,"run/I");
282  ftree_shwf->Branch("subrun",&fSubRun,"subrun/I");
283  ftree_shwf->Branch("event",&fEvent,"event/I");
284  ftree_shwf->Branch("nplanes",&fNPlanes,"nplanes/I");
285  ftree_shwf->Branch("nangles",&fNAngles,"nangles/I");
286 
287 // ftree_shwf->Branch("fthetaN","std::vector<double>",&fThetaN_ang);
288 // ftree_shwf->Branch("fphiN","std::vector<double>",&fPhiN_ang);
289 
290  ftree_shwf->Branch("xtheta",&xtheta,"xtheta/D");
291  ftree_shwf->Branch("xphi",&xphi,"xphi/D");
292 
293  ftree_shwf->Branch("ftotChargeADC","std::vector<double>",&fTotChargeADC);
294  ftree_shwf->Branch("ftotChargeMeV","std::vector<double>",&fTotChargeMeV);
295  ftree_shwf->Branch("fTotChargeMeV_MIPs","std::vector<double>",&fTotChargeMeV_MIPs);
296 
297  ftree_shwf->Branch("NPitch","std::vector< std::vector<double> >", &fNPitch);
298  // ftree_shwf->Branch("Pitch","std::vector<double>", &fPitch);
299 
300  // this should be temporary - until the omega is sorted out.
301  ftree_shwf->Branch("RMS_2cm","std::vector<double>",&fRMS_2cm);
302  ftree_shwf->Branch("Npoints_2cm","std::vector<int>",&fNpoints_2cm);
303 // ftree_shwf->Branch("RMS_4cm","std::vector<double>",&fRMS_4cm);
304 // ftree_shwf->Branch("Npoints_4cm","std::vector<int>",&fNpoints_4cm);
305 
306  ftree_shwf->Branch("ChargeADC_2cm","std::vector<double>",&fChargeADC_2cm);
307  ftree_shwf->Branch("ChargeMeV_2cm","std::vector<double>",&fChargeMeV_2cm);
308 // ftree_shwf->Branch("ChargeADC_4cm","std::vector<double>",&fChargeADC_4cm);
309 // ftree_shwf->Branch("ChargeMeV_4cm","std::vector<double>",&fChargeMeV_4cm);
310 
311  ftree_shwf->Branch("ChargeMeV_2cm_refined","std::vector<double>",&fChargeMeV_2cm_refined);
312 // ftree_shwf->Branch("ChargeMeV_4cm_refined","std::vector<double>",&fChargeMeV_4cm_refined);
313 
314  ftree_shwf->Branch("ChargeMeV_2cm_axsum","std::vector<double>",&fChargeMeV_2cm_axsum);
315 // ftree_shwf->Branch("ChargeMeV_4cm_axsum","std::vector<double>",&fChargeMeV_4cm_axsum);
316 
317 
318  ftree_shwf->Branch("fNhitsperplane","std::vector<int>",&fNhitsperplane);
319  ftree_shwf->Branch("fTotADCperplane","std::vector<double>",&fTotADCperplane);
320 
321 
322 
323  ftree_shwf->Branch("ChargedistributionADC","std::vector<std::vector<double>>",&fDistribChargeADC);
324 
325  ftree_shwf->Branch("ChargedistributionMeV","std::vector<std::vector<double>>",&fDistribChargeMeV);
326  ftree_shwf->Branch("DistribHalfChargeMeV","std::vector<std::vector<double>>",&fDistribHalfChargeMeV);
327  ftree_shwf->Branch("ChargedistributionPosition","std::vector<std::vector<double>>",&fDistribChargeposition);
328  ftree_shwf->Branch("xyz_vertex_fit","std::vector<double>", &xyz_vertex_fit);
329 
330 }
331 
332 
334 {
335  detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
336 
337  fWirePitch = geom->WirePitch(); //wire pitch in cm
338  fTimeTick=detprop->SamplingRate()/1000.;
341 
342 }
343 
344 
345 
346 
347  void ShowerReco::ShowerReco::ClearandResizeVectors(unsigned int /*nPlanes*/) {
348  //calculate factorial for number of angles
349  int fact=1;
350  for (unsigned int i = 1; i <= fNPlanes; ++i) fact *= i;
351 
352  fNAngles=fact/2;
353 
354  fDistribChargeADC.clear();
355  fDistribChargeMeV.clear();
356  fDistribChargeposition.clear();
357 
358 
359  fDistribChargeADC.resize(fNPlanes);
360  fDistribChargeMeV.resize(fNPlanes);
362 
363 
364  fNPitch.clear();
365  fDistribChargeADC.clear();
366  fDistribChargeMeV.clear();
367  fDistribHalfChargeMeV.clear();
368  fDistribChargeposition.clear();
369 
370  fNPitch.resize(fNAngles);
371  fDistribChargeADC.resize(fNPlanes);
372  fDistribChargeMeV.resize(fNPlanes);
375 
376  for(unsigned int ii=0;ii<fNAngles;ii++) {
377  fNPitch[ii].resize(fNPlanes,-1);
378  }
379 
380  fNpoints_corr_ADC_2cm.clear();
381  fNpoints_corr_MeV_2cm.clear();
382 
383  fNpoints_corr_ADC_2cm.resize(fNAngles,-1);
384  fNpoints_corr_MeV_2cm.resize(fNAngles,-1);
385 // fNpoints_corr_ADC_4cm.resize(fNAngles,-1);
386 // fNpoints_corr_MeV_4cm.resize(fNAngles,-1);
387 
388 
389 
390  for(unsigned int ii=0;ii<fNPlanes;ii++)
391  { fDistribChargeADC[ii].resize(0); //vector with the first De/Dx points
392  fDistribChargeMeV[ii].resize(0); //vector with the first De/Dx points
393  fDistribHalfChargeMeV[ii].resize(0);
394  fDistribChargeposition[ii].resize(0); //vector with the first De/Dx points' positions
395  }
396 
397 
398  fWire_vertex.clear();
399  fTime_vertex.clear();
400  fWire_vertexError.clear();
401  fTime_vertexError.clear();
402  fWire_last.clear();
403  fTime_last.clear();
404  fTotChargeADC.clear();
405  fTotChargeMeV.clear();
406  fTotChargeMeV_MIPs.clear();
407  fRMS_2cm.clear();
408  fNpoints_2cm.clear();
409 
410  fNhitsperplane.clear();
411  fTotADCperplane.clear();
412 
413 
414 
415  fWire_vertex.resize(fNAngles,-1);
416  fTime_vertex.resize(fNAngles,-1);
417  fWire_vertexError.resize(fNPlanes,-1);
418  fTime_vertexError.resize(fNPlanes,-1);
419  fWire_last.resize(fNAngles,-1);
420  fTime_last.resize(fNAngles,-1);
421  fTotChargeADC.resize(fNAngles,0);
422  fTotChargeMeV.resize(fNAngles,0);
423  fTotChargeMeV_MIPs.resize(fNAngles,0);
424  fRMS_2cm.resize(fNAngles,0);
425  fNpoints_2cm.resize(fNAngles,0);
426 
427  fCorr_MeV_2cm.clear();
428  fCorr_Charge_2cm.clear();
429  xyz_vertex_fit.clear();
430 
431  fChargeADC_2cm.clear();
432  fChargeMeV_2cm.clear();
433  fChargeMeV_2cm_refined.clear();
434  fChargeMeV_2cm_refined.clear();
435  fChargeMeV_2cm_axsum.clear();
436 
437 
438  fCorr_MeV_2cm.resize(fNAngles,0);
439  fCorr_Charge_2cm.resize(fNAngles,0);
440  xyz_vertex_fit.resize(3);
441 
442  fChargeADC_2cm.resize(fNAngles,0); //Initial charge in ADC/cm for each plane angle calculation 4cm
443  fChargeMeV_2cm.resize(fNAngles,0); //initial charge in MeV/cm for each angle calculation first 4cm
444  fChargeMeV_2cm_refined.resize(0);
445  fChargeMeV_2cm_refined.resize(fNAngles,0);;
446  fChargeMeV_2cm_axsum.resize(fNAngles,0);;
447 
448  fNhitsperplane.resize(fNPlanes,-1);
449  fTotADCperplane.resize(fNPlanes,-1);
450 
451 
452  vdEdx.clear();
453  vresRange.clear();
454  vdQdx.clear();
455 
456 
457  }
458 
459 
460 
461 
462 
463 // ***************** //
465 {
466 
467  detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
468 
470  fNPlanes = geom->Nplanes();
471  //fdriftvelocity = detprop->DriftVelocity(Efield_SI,Temperature);
472  std::unique_ptr<std::vector<recob::Shower> > Shower3DVector(new std::vector<recob::Shower>);
473  std::unique_ptr< art::Assns<recob::Shower, recob::Cluster> > cassn(new art::Assns<recob::Shower, recob::Cluster>);
474  std::unique_ptr< art::Assns<recob::Shower, recob::Hit> > hassn(new art::Assns<recob::Shower, recob::Hit>);
475  std::unique_ptr< std::vector<anab::Calorimetry> > calorimetrycol(new std::vector<anab::Calorimetry>);
476  std::unique_ptr< art::Assns< anab::Calorimetry,recob::Shower> > calassn(new art::Assns<anab::Calorimetry,recob::Shower>);
477 
478 
484  art::Handle< std::vector<recob::Cluster> > clusterListHandle;
485  evt.getByLabel(fClusterModuleLabel,clusterListHandle);
486 
488  evt.getByLabel(fClusterModuleLabel,clusterAssociationHandle);
489 
490 
491  art::FindManyP<recob::Hit> fmh(clusterListHandle, evt,fClusterModuleLabel);
492 
493 // std::cout << " ---------- ShowerReco!!! -------------- " << std::endl;
494  fRun = evt.id().run();
495  fSubRun = evt.id().subRun();
496  fEvent = evt.id().event();
497 // unsigned int nCollections= clusterAssociationHandle->size();
498 // std::vector < art::PtrVector<recob::Cluster> >::const_iterator clusterSet = clusterAssociationHandle->begin();
499 // for(unsigned int iCol=0;iCol<nCollections;iCol++)
500 // {
501 // const art::PtrVector<recob::Cluster> pvcluster(*(clusterSet++));
502 // auto it = pvcluster.begin();
503 // int nClusts = pvcluster.size();
504 // ClearandResizeVectors(nClusts); // need to do this smarter (coutn at start and have an overall index?)
505 // for(int iClust = 0; iClust < nClusts; ++iClust) {
506 // const art::Ptr<recob::Cluster> pclust(*(it++));
507 // auto pcoll { pclust };
508 // art::FindManyP<recob::Hit> fs( pcoll, evt, fClusterModuleLabel);
509 // std::vector< art::Ptr<recob::Hit> > hitlist = fs.at(0);
510 // //std::cout << " hitlist size for coll " << iCol << " clust " << iClust << " " << hitlist.size() << std::endl;
511 // }
512 // }
513 
514 
515  // find all the hits associated to all the clusters (once and for all);
516  // the index of the query matches the index of the cluster in the collection
517  // (conveniently carried around in its art pointer)
518  art::FindManyP<recob::Hit> ClusterHits(clusterListHandle, evt, fClusterModuleLabel);
519 
520  std::vector < art::PtrVector<recob::Cluster> >::const_iterator clusterSet = clusterAssociationHandle->begin();
521  // loop over vector of vectors (each size of NPlanes) and reconstruct showers from each of those
522  for(size_t iClustSet = 0;iClustSet < clusterAssociationHandle->size(); iClustSet++){
523 
524  const art::PtrVector<recob::Cluster> CurrentClusters=(*(clusterSet++));
525 
526  // do some error checking - i.e. are the clusters themselves present.
527  if(clusterListHandle->size() < 2 || CurrentClusters.size() < 2) {
528  //std::cout << "not enough clusters to reconstruct" << std::endl;
529  //std::cout << "emergency filling tree @ run, evt," << fRun << " " << fEvent << std::endl;
530  ftree_shwf->Fill();
531  return;
532  }
533  //std::cout << " Cluster Set: " << iClustSet << " " << std::endl;
534 
536 
537  std::vector< std::vector< art::Ptr<recob::Hit> > > hitlist_all;
538  hitlist_all.resize(fNPlanes);
539 
540  // int nClusts = CurrentClusters.size();
541  for(size_t iClust = 0; iClust < CurrentClusters.size(); iClust++){
542  art::Ptr<recob::Cluster> const& pclust = CurrentClusters[iClust];
543  //size_t ii=0;
544  //std::cout << " clusterListHandle " << clusterListHandle->size() << " fNPlanes " << fNPlanes << " "<< CurrentClusters.size() << std::endl;
545 
546  // get all the hits for this cluster;
547  // pclust is a art::Ptr to the original cluster collection stored in the event;
548  // its key corresponds to its index in the collection
549  // (and therefore to the index in the query)
550  std::vector< art::Ptr<recob::Hit> > const& hitlist = ClusterHits.at(pclust.key());
551  //std::cout << " hitlist size for coll " << iClustSet << " clust " << iClust << " " << hitlist.size() << std::endl;
552 
553  unsigned int p(0); //c=channel, p=plane, w=wire
554 
555  //std::cout << " hitlist size " << hitlist.size() << std::endl;
556  if(hitlist.size() == 0) continue;
557 
558  p= (*hitlist.begin())->WireID().Plane;
559  //art::Ptr<recob::Cluster> cl(clusterListHandle, iClust);
560  //get vertex position and slope information to start with - ii is the posistion of the correct cluster:
562 
563 
564  double ADCcharge=0;
565  //loop over cluster hits
566  for(art::Ptr<recob::Hit> const& hit: hitlist){
567  p= hit->WireID().Plane;
568  hitlist_all[p].push_back(hit);
569  ADCcharge+= hit->PeakAmplitude();
570  }
571  fNhitsperplane[p]=hitlist_all[p].size();
572  fTotADCperplane[p]=ADCcharge;
573  // unsigned int nCollections= clusterAssociationHandle->size();
574 // std::vector < art::PtrVector<recob::Cluster> >::const_iterator clusterSet = clusterAssociationHandle->begin();
575 // for(unsigned int iCol=0;iCol<nCollections;iCol++)
576 // {
577 // const art::PtrVector<recob::Cluster> pvcluster(*(clusterSet++));
578 // auto it = pvcluster.begin();
579 // int nClusts = pvcluster.size();
580 // ClearandResizeVectors(nClusts); // need to do this smarter (coutn at start and have an overall index?)
581 // for(int iClust = 0; iClust < nClusts; ++iClust) {
582 // const art::Ptr<recob::Cluster> pclust(*(it++));
583 // auto pcoll { pclust };
584 // art::FindManyP<recob::Hit> fs( pcoll, evt, fClusterModuleLabel);
585 // std::vector< art::Ptr<recob::Hit> > hitlist = fs.at(0);
586 // //std::cout << " hitlist size for coll " << iCol << " clust " << iClust << " " << hitlist.size() << std::endl;
587 // }
588 // }
589 
590 
591 
592 
593 
594  // Find the right cluster from the standard cluster list -> to get the hitlist associations.
595 // for( ii = 0; ii < clusterListHandle->size(); ii++){
596 // art::Ptr<recob::Cluster> cl(clusterListHandle, ii);
597 // if((*cl).ID() == (*CurrentClusters[iClust]).ID() ) //find the right cluster out of the list of associated clusters
598 // break;
599 // }
600 //
601  //get vertex position and slope information to start with - ii is the posistion of the correct cluster:
602  // std::vector< art::Ptr<recob::Hit> > hitlist = fmh.at(ii);
603  // std::sort(hitlist.begin(), hitlist.end(), SortByWire());
604 
605 
606  } // End loop on clusters.
607  // Now I have the Hitlists and the relevent clusters parameters saved.
608 
609 
610 // for(unsigned int i = 0; i < fNPlanes; ++i){
611 // std::sort(hitlist_all[i].begin(), hitlist_all[i].end(),SortByWire());
612 //
613 // }
614 
615  //find best set:
616  unsigned int bp1 = 0,bp2 = 0;
617  double minerror1=99999999,minerror2=9999999;
618  for(unsigned int ii = 0; ii < fNPlanes; ++ii)
619  {
620  double locerror=fWire_vertexError[ii]*fWire_vertexError[ii]+ fTime_vertexError[ii]*fTime_vertexError[ii]; // time coordinate of vertex for each plane
621 
622  if(minerror1 >= locerror ) // the >= sign is to favorize collection
623  {
624  minerror1=locerror;
625  bp1=ii;
626  }
627  }
628  for(unsigned int ij = 0; ij < fNPlanes; ++ij)
629  {
630  double locerror=fWire_vertexError[ij]*fWire_vertexError[ij]+ fTime_vertexError[ij]*fTime_vertexError[ij]; // time coordinate of vertex for each plane
631 
632  if(minerror2 >= locerror && ij!=bp1 )
633  {
634  minerror2=locerror;
635  bp2=ij;
636  }
637  }
638  //bp1=0;
639  //bp1=2;
640  //std::cout << " best planes " << bp1 << " " << bp2 << std::endl;
641 for(unsigned int ij = 0; ij < fNPlanes; ++ij)
642  {
643  //std::cout << " wire distances: " << ij << " " << fabs((double)fWire_vertex[ij]-(double)fWire_last[ij]);
644 
645  }
646 
647 
648  //std::cout << " angles in: " << bp1 << " " << bp2 << " " << slope[bp1]*TMath::Pi()/180. << " " << slope[bp2]*TMath::Pi()/180. << " " << slope[bp1] << " " << slope[bp2] << std::endl;
649 // gser.Get3DaxisN(bp1,bp2,slope[bp1]*TMath::Pi()/180.,slope[bp2]*TMath::Pi()/180.,xphi,xtheta);
650  gser.Get3DaxisN(bp1,bp2,angle[bp1],angle[bp2],xphi,xtheta);
651 
653  const double origin[3] = {0.};
654  std::vector <std::vector < double > > position;
655  // auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
656  double fTimeTick=detprop->SamplingRate()/1000.;
658  // get starting positions for all planes
659  for(unsigned int xx=0;xx<fNPlanes;xx++){
660  double pos1[3];
661  geom->Plane(xx).LocalToWorld(origin, pos1);
662  std::vector <double > pos2;
663  pos2.push_back(pos1[0]);
664  pos2.push_back(pos1[1]);
665  pos2.push_back(pos1[2]);
666  position.push_back(pos2);
667  }
668  // Assuming there is no problem ( and we found the best pair that comes close in time )
669  // we try to get the Y and Z coordinates for the start of the shower.
670  try{
671  int chan1=geom->PlaneWireToChannel(bp1,fWire_vertex[bp1], 0);
672  int chan2=geom->PlaneWireToChannel(bp2,fWire_vertex[bp2], 0);
673 
674  double y,z;
675 // bool wires_cross = geom->ChannelsIntersect(chan1,chan2,y,z);
676  geom->ChannelsIntersect(chan1,chan2,y,z);
677  // geom->ChannelsIntersect(chan1,chan2,y,z);
678 
679  xyz_vertex_fit[1]=y;
680  xyz_vertex_fit[2]=z;
681  xyz_vertex_fit[0]=(fTime_vertex[bp1]-detprop->TriggerOffset()) *fDriftVelocity*fTimeTick+position[0][0];
682 
683 
684  //std::cout << ":::::: found x,y,z vertex " << wires_cross << " " << xyz_vertex_fit[0] << " " << y << " " << z << " " << wires_cross << std::endl;
685  }
686  catch(cet::exception e) {
687  mf::LogWarning("ShowerReco") << "caught exception \n" << e;
688  xyz_vertex_fit[1]=0;
689  xyz_vertex_fit[2]=0;
690  xyz_vertex_fit[0]=0;
691  }
692 
693 
694  // if collection is not best plane, project starting point from that
695  if(bp1!=fNPlanes-1 && bp2!=fNPlanes-1)
696  {
697  double pos[3];
698  unsigned int wirevertex;
699 
700  geom->Plane(fNPlanes-1).LocalToWorld(origin, pos);
701  //planex[p] = pos[0];
702  //std::cout << "plane X positionp " << 2 << " " << pos[0] << std::endl;
703 
704  pos[1]=xyz_vertex_fit[1];
705  pos[2]=xyz_vertex_fit[2];
706  wirevertex = geom->NearestWire(pos,fNPlanes-1);
707  //geo->ChannelToWire(channel2,cs,t,p,wirevertex); //\fixme!
708  //wirevertex= (*a)->WireID().Wire;
709 
710 
711 
712 
713  double drifttick=(xyz_vertex_fit[0]/detprop->DriftVelocity(detprop->Efield(),detprop->Temperature()))*(1./fTimeTick);
714  fWire_vertex[fNPlanes-1]= wirevertex; // wire coordinate of vertex for each plane
715  fTime_vertex[fNPlanes-1] = drifttick-(pos[0]/detprop->DriftVelocity(detprop->Efield(),detprop->Temperature()))*(1./fTimeTick)+detprop->TriggerOffset();
716 
717 
718  }
719 
720 
721  // std::cout << "^^^^^^cross-check xphi and xtheta: " << xphi << " " << xtheta << std::endl;
722 
723 
724  if(fabs(xphi) < 5. )
725  { xtheta= gser.Get3DSpecialCaseTheta(bp1,bp2,fWire_last[bp1]-fWire_vertex[bp1], fWire_last[bp2]-fWire_vertex[bp2]);
726 
727  //std::cout << "xphi, xtheta1:,alt" << xphi << " " << xtheta <<std::endl;
728  }
729  //}
730 
731 // zero the arrays just to make sure
732  for(unsigned int i = 0; i < fNAngles; ++i){
733  fTotChargeADC[i]=0;
734  fTotChargeMeV[i]=0;
735  fTotChargeMeV_MIPs[i]=0;
738 
739  fRMS_2cm[i]=0;
740  fNpoints_2cm[i]=0;
741 
742  fCorr_MeV_2cm[i]=0;
743  fCorr_Charge_2cm[i]=0;
744 
745  fChargeADC_2cm[i]=0; //Initial charge in ADC/cm for each plane angle calculation 4cm
746  fChargeMeV_2cm[i]=0; //initial charge in MeV/cm for each angle calculation first 4cm
747 
748  }
749 
750 
751  // do loop and choose Collection. With ful calorimetry can do all.
752  //for(unsigned int set=0;set<fNAngles;set++)
753  if(!(fabs(xphi) >89 && fabs(xphi)<91)) // do not calculate pitch for extreme angles
754  LongTransEnergy(0,hitlist_all[fNPlanes-1]); //temporary only plane 2.
755 
756 
758 
759  //std::vector< recob::SpacePoint > spacepoints = std::vector<recob::SpacePoint>()
760 
761 
762 
763  // make an art::PtrVector of the clusters
765  for(unsigned int i = 0; i < clusterListHandle->size(); ++i){
766  art::Ptr<recob::Cluster> prod(clusterListHandle, i);
767  prodvec.push_back(prod);
768  }
769 
770  //create a singleSpacePoint at vertex.
771  std::vector< recob::SpacePoint > spcpts;
772 
773  //get direction cosines and set them for the shower
774  // TBD determine which angle to use for the actual shower
775  double fPhi=xphi;
776  double fTheta=xtheta;
777 
778  TVector3 dcosVtx(TMath::Cos(fPhi*TMath::Pi()/180)*TMath::Sin(fTheta*TMath::Pi()/180),
779  TMath::Cos(fTheta*TMath::Pi()/180),
780  TMath::Sin(fPhi*TMath::Pi()/180)*TMath::Sin(fTheta*TMath::Pi()/180));
782  // fill with bogus values for now
783  TVector3 dcosVtxErr(util::kBogusD, util::kBogusD, util::kBogusD);
784  //double maxTransWidth[2] = { util::kBogusD };
785  //double distMaxWidth = util::kBogusD;
786  //recob::Shower singShower(dcosVtx, dcosVtxErr, maxTransWidth, distMaxWidth, 1);
787  recob::Shower singShower;
788  singShower.set_direction(dcosVtx);
789  singShower.set_direction_err(dcosVtxErr);
790 
791  Shower3DVector->push_back(singShower);
792  // associate the shower with its clusters
793  util::CreateAssn(*this, evt, *Shower3DVector, prodvec, *cassn);
794 
795  // get the hits associated with each cluster and associate those with the shower
796  for(size_t p = 0; p < prodvec.size(); ++p){
797  std::vector< art::Ptr<recob::Hit> > hits = fmh.at(p);
798  util::CreateAssn(*this, evt, *Shower3DVector, hits, *hassn);
799  }
800 
801 
802  geo::PlaneID planeID(0,0,fNPlanes-1);
803  calorimetrycol->push_back(anab::Calorimetry(Kin_En,
804  vdEdx,
805  vdQdx,
806  vresRange,
807  deadwire,
808  Trk_Length,
809  fTrkPitchC,
810  planeID));
811 
813 
814  //for(unsigned int ip=0;ip<1;ip++) {
815  art::ProductID aid = this->getProductID< std::vector < recob::Shower > >();
816  art::Ptr< recob::Shower > aptr(aid, 0, evt.productGetter(aid));
817  ssvec.push_back(aptr);
818  //}
819 
820 
821  //util::CreateAssn(*this, evt, *Shower3DVector, calorimetrycol, *calassn);
822  util::CreateAssn(*this, evt, *calorimetrycol,ssvec,*calassn);
824  //std::cout << " filling tree @ run, evt," << fRun << " " << fEvent << std::endl;
825  ftree_shwf->Fill();
826 
827  //for(unsigned int iplane = 0; iplane < fNPlanes; ++iplane)
828  //fh_theta[iplane]->Write(Form("fh_theta_%d_%d",iplane,evt.id().event()));
829  // This needs work, clearly.
830  //for(int p=0;p<2;p++)Shower3DVector->push_back(shower);
831 
832  } // end loop on Vectors of "Associated clusters"
833 
834  evt.put(std::move(Shower3DVector));
835  evt.put(std::move(cassn));
836  evt.put(std::move(hassn));
837  evt.put(std::move(calorimetrycol));
838  evt.put(std::move(calassn));
839 
840 
841 
842 }
843 
844 
845 
846 //------------------------------------------------------------------------------
847 void ShowerReco::LongTransEnergy(unsigned int set, std::vector < art::Ptr<recob::Hit> > hitlist, bool /*isData*/)
848 {
849  // alogorithm for energy vs dx of the shower (roto-translation) COLLECTION VIEW
850  // double wire_cm, time_cm;
851  // int loop_nrg = 0;
852 
855 
856 
857 
858  double totCnrg = 0,totCnrg_corr =0;//, totNewCnrg=0 ; // tot enegry of the shower in collection
859 // art::ServiceHandle<geo::Geometry> geom;
860 // auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
861 
862  double time;
863  unsigned int wire=0,plane=fNPlanes-1;
864 
865 
866  double mevav2cm=0.;
867  double sum=0.;
868  double npoints_calo=0;
869 
870  int direction=-1;
871 
872  //override direction if phi (XZ angle) is less than 90 degrees
873  if(fabs(xphi)<90)
874  direction=1;
875 
876  //variables to check whether a hit is close to the shower axis.
877  double ortdist,linedist;
878  double wire_on_line,time_on_line;
879 
880  //get effective pitch using 3D angles
881  double newpitch=gser.PitchInView(plane,xphi,xtheta);
882 
883 
884 
885  for(art::PtrVector<recob::Hit>::const_iterator hitIter = hitlist.begin(); hitIter != hitlist.end(); hitIter++){
886  art::Ptr<recob::Hit> theHit = (*hitIter);
887  time = theHit->PeakTime() ;
888 
889  wire= theHit->WireID().Wire;
890  plane= theHit->WireID().Plane;
891 
892  double dEdx_new;
893  // double dEdx_MIP;
894 
895  if(fUseArea)
896  { dEdx_new = calalg.dEdx_AREA((*hitIter), newpitch );
897  // dEdx_MIP = calalg.dEdx_AREA_forceMIP((*hitIter), newpitch );
898  }
899  else //this will hopefully go away, once all of the calibration factors are calculated.
900  {
901  dEdx_new = calalg.dEdx_AMP((*hitIter), newpitch );
902  // dEdx_MIP = calalg.dEdx_AMP_forceMIP((*hitIter), newpitch );
903  }
904 
905  //calculate total energy.
906  totCnrg_corr += dEdx_new;
907  //totNewCnrg+=dEdx_MIP;
908 
909  // calculate the wire,time coordinates of the hit projection on to the 2D shower axis
910  gser.GetPointOnLine(slope[plane]/fWireTimetoCmCm,fWire_vertex[plane],fTime_vertex[plane],wire,time,wire_on_line,time_on_line);
911  linedist=gser.Get2DDistance(wire_on_line,time_on_line,fWire_vertex[plane],fTime_vertex[plane]);
912  ortdist=gser.Get2DDistance(wire_on_line,time_on_line,wire,time);
913 
914 
915 
916  //calculate the distance from the vertex using the effective pitch metric
917  double wdist=(((double)wire-(double)fWire_vertex[plane])*newpitch)*direction; //wdist is always positive
918 
919 
920 // if( (fabs(wdist)<fcalodEdxlength)&&(fabs(wdist)>0.2)){
921  if( (wdist<fcalodEdxlength)&&(wdist>0.2)){
922 
923  vdEdx.push_back(dEdx_new);
924  vresRange.push_back(fabs(wdist));
925  vdQdx.push_back((*hitIter)->PeakAmplitude()/newpitch);
926  Trk_Length=wdist;
927  fTrkPitchC=fNPitch[set][plane];
928  Kin_En+=dEdx_new*newpitch;
929  npoints_calo++;
930  sum+=dEdx_new;
931 
932 
933 
934 //std::cout << " CALORIMETRY:" << " Pitch " <<newpitch << " dist: " << wdist << " dE/dx: " << dEdx_new << "MeV/cm " << " average: " << sum/npoints_calo << "hit: wire, time " << wire << " " << time << " line,ort " << linedist << " " << ortdist<< " direction " << direction << std::endl;
935 
936 
937  if(wdist<fdEdxlength
938  && ((direction==1 && wire>fWire_vertex[plane]) //take no hits before vertex (depending on direction)
939  || (direction==-1 && wire<fWire_vertex[plane]) )
940  && ortdist<4.5 && linedist < fdEdxlength ){
941  fChargeMeV_2cm[set]+= dEdx_new ;
942  fNpoints_2cm[set]++;
943  // std::cout << " CALORIMETRY:" << " Pitch " <<newpitch << " dist: " << wdist << " dE/dx: " << dEdx_new << "MeV/cm " << " average: " << sum/npoints_calo << "hit: wire, time " << wire << " " << time << " line,ort " << linedist << " " << ortdist<< " direction " << direction << std::endl;
944  }
945 
946  // fill out for 4cm preshower
947 
948  //fDistribChargeADC[set].push_back(ch_adc); //vector with the first De/Dx points
949  fDistribChargeMeV[set].push_back(dEdx_new); //vector with the first De/Dx points
950  //fDistribHalfChargeMeV[set].push_back(Bcorr_half);
951  fDistribChargeposition[set].push_back(wdist); //vector with the first De/Dx points' positions
952 
953  }//end inside range if statement
954 
955  }// end first loop on hits.
956 
957  auto const signalType
958  = hitlist.empty()? geo::kMysteryType: geom->SignalType(hitlist.front()->WireID());
959 
960  if(signalType == geo::kCollection)
961  {
962  fTotChargeADC[set]=totCnrg*newpitch;
963  fTotChargeMeV[set]=totCnrg_corr*newpitch;
964  //fTotChargeMeV_MIPs[set]=totNewCnrg*newpitch;
965  }
966 
967 
968  //calculate average dE/dx
969  if(fNpoints_2cm[set]>0) {
970  mevav2cm=fChargeMeV_2cm[set]/fNpoints_2cm[set];
971  }
972  //double RMS_ADC_2cm=0.;
973 
974 
975 
976  //second loop to calculate RMS
977  for(art::PtrVector<recob::Hit>::const_iterator hitIter = hitlist.begin(); hitIter != hitlist.end(); hitIter++){
978  art::Ptr<recob::Hit> theHit = (*hitIter);
979  time = theHit->PeakTime() ;
980  wire= theHit->WireID().Wire;
981  plane= theHit->WireID().Plane;
982  double dEdx=0;
983 
984  if(fUseArea)
985  { dEdx = calalg.dEdx_AREA((*hitIter), newpitch );
986  }
987  else //this will hopefully go away, once all of the calibration factors are calculated.
988  {
989  dEdx = calalg.dEdx_AMP((*hitIter), newpitch );
990  }
991 
992 
993 
994  gser.GetPointOnLine(slope[plane]/fWireTimetoCmCm,fWire_vertex[plane],fTime_vertex[plane],wire,time,wire_on_line,time_on_line);
995  linedist=gser.Get2DDistance(wire_on_line,time_on_line,fWire_vertex[plane],fTime_vertex[plane]);
996  ortdist=gser.Get2DDistance(wire_on_line,time_on_line,wire,time);
997 
998 
999 
1000  double wdist=(((double)wire-(double)fWire_vertex[plane])*newpitch)*direction;
1001 
1002  // //std::cout << dEdx << " MeV, outside of if;; wd " << wdist << " ld " << linedist << " od " << ortdist << std::endl;
1003 
1004  if( (wdist<fcalodEdxlength)&&(wdist>0.2)){
1005  if(wdist<fdEdxlength
1006  && ((direction==1 && wire>fWire_vertex[plane]) ||
1007  (direction==-1 && wire<fWire_vertex[plane]) )
1008  && ortdist<4.5 && linedist < fdEdxlength)
1009  {
1010 // //std::cout << dEdx << " MeV " << std::endl;
1011  fRMS_2cm[set]+= (dEdx-mevav2cm)*(dEdx-mevav2cm);
1012  }
1013 
1014 
1015  } //end if on correct hits.
1016  } //end RMS_calculating loop.
1017 
1018  if(fNpoints_2cm[set]>0)
1019  {
1020  fRMS_2cm[set]=TMath::Sqrt(fRMS_2cm[set]/fNpoints_2cm[set]);
1021  }
1022 
1023  //std::cout << " average dE/dx: " << mevav2cm << " RMS:: " << fRMS_2cm[set] << " " << fNpoints_2cm[set] << std::endl;
1024 
1026 
1027  for(art::PtrVector<recob::Hit>::const_iterator hitIter = hitlist.begin(); hitIter != hitlist.end(); hitIter++){
1028  art::Ptr<recob::Hit> theHit = (*hitIter);
1029  time = theHit->PeakTime() ;
1030  wire= theHit->WireID().Wire;
1031  plane= theHit->WireID().Plane;
1032 
1033  double dEdx=0;
1034  if(fUseArea)
1035  { dEdx = calalg.dEdx_AREA((*hitIter), newpitch );
1036  }
1037  else //this will hopefully go away, once all of the calibration factors are calculated.
1038  {
1039  dEdx = calalg.dEdx_AMP((*hitIter), newpitch );
1040  }
1041 
1042  gser.GetPointOnLine(slope[plane]/fWireTimetoCmCm,fWire_vertex[plane],fTime_vertex[plane],wire,time,wire_on_line,time_on_line);
1043  linedist=gser.Get2DDistance(wire_on_line,time_on_line,fWire_vertex[plane],fTime_vertex[plane]);
1044  ortdist=gser.Get2DDistance(wire_on_line,time_on_line,wire,time);
1045 
1046  double wdist=(((double)wire-(double)fWire_vertex[plane])*newpitch)*direction;
1047 
1048 
1049  if( (wdist < fcalodEdxlength) && (wdist > 0.2
1050  && ((direction==1 && wire>fWire_vertex[plane]) ||
1051  (direction==-1 && wire<fWire_vertex[plane]) )
1052  && ortdist<4.5 && linedist < fdEdxlength ))
1053  {
1054  if(wdist < fdEdxlength)
1055  {
1056  if( ((dEdx > (mevav2cm-fRMS_2cm[set]) )
1057  && (dEdx < (mevav2cm+fRMS_2cm[set]) ))
1058  || (newpitch > 0.3*fdEdxlength ) ) {
1059  fCorr_MeV_2cm[set]+= dEdx;
1060  fNpoints_corr_MeV_2cm[set]++;
1061  }
1062 
1063  } // end if on good hits
1064 
1065 
1066  }
1067  } //end of third loop on hits
1068 
1069  if(fNpoints_corr_MeV_2cm[set]>0){
1070  //std::cout << " ++ NPoints 2cm, ADC and MeV "
1071  // << fNpoints_corr_MeV_2cm[set] << " "
1072  // << fNpoints_corr_ADC_2cm[set]
1073  // << " corrected average De/Dx, charge, MeV: "
1074  // << fCorr_Charge_2cm[set]/fNpoints_corr_ADC_2cm[set]
1075  // << " " << fCorr_MeV_2cm[set]/fNpoints_corr_MeV_2cm[set] << std::endl;
1076  //fCorr_Charge_2cm[set]/=fNpoints_corr_ADC_2cm[set];
1079  }
1080 
1081 
1083 // std::cout << " total ENERGY, birks: " << fTotChargeMeV[set] << " MeV " << " |average: " << fChargeMeV_2cm_refined[set] << std::endl;
1084 }
1085 
1086 
1087 
1088 //------------------------------------------------------------------------------------//
1090 // Get shower vertex and slopes.
1091 {
1092  //convert to cm/cm units needed in the calculation
1093 // slope[plane]=clust->dTdW();//*(ftimetick*fdriftvelocity)/fMean_wire_pitch;
1094  angle[plane]=clust->StartAngle();
1095  slope[plane]=std::tan(clust->StartAngle());
1096  fWire_vertex[plane]=clust->StartWire();
1097  fTime_vertex[plane]=clust->StartTick();
1098 
1099  fWire_vertexError[plane]=clust->SigmaStartWire(); // wire coordinate of vertex for each plane
1100  fTime_vertexError[plane]=clust->SigmaStartTick(); // time coordinate of vertex for each plane
1101 
1102  fWire_last[plane]=clust->EndWire(); // wire coordinate of last point for each plane
1103  fTime_last[plane]=clust->EndTick();
1104 
1106 
1107  // std::cout << "======= setting slope for view: " << plane
1108 // << " " << slope[plane] << " " << fWire_vertex[plane]
1109 // << " " << fTime_vertex[plane] << " " << std::endl;
1110  // << fWire_vertex[plane]+50<< " "
1111  // << fTime_vertex[plane] + slope[plane]*(fWire_vertex[plane]+50)<< std::endl;
1112 
1113 }
1114 
1115 
1116 // //------------------------------------------------------------------------------
1117 // //to be moved to an _ana module
1118 // void ShowerReco::GetVertexN(art::Event& evt){
1119 //
1120 //
1121 //
1122 // double fTimeTick=detprop->SamplingRate()/1000.;
1123 //
1124 // art::Handle< std::vector<simb::MCTruth> > mctruthListHandle;
1125 // evt.getByLabel("generator",mctruthListHandle);
1126 //
1127 // art::PtrVector<simb::MCTruth> mclist;
1128 // for (unsigned int ii = 0; ii < mctruthListHandle->size(); ++ii)
1129 // {
1130 // art::Ptr<simb::MCTruth> mctparticle(mctruthListHandle,ii);
1131 // mclist.push_back(mctparticle);
1132 // }
1133 //
1134 //
1135 // mf::LogVerbatim("ShowerAngleClusterAna") << "%%%%%%% mc size size, "<<mclist.size() << std::endl;
1136 //
1137 //
1138 // art::Ptr<simb::MCTruth> mc(mclist[0]);
1139 // simb::MCParticle neut(mc->GetParticle(0));
1140 //
1141 // mcpdg=neut.PdgCode();
1142 // mcenergy=neut.E();
1143 // //std::cout << " ----------- mcenergy:: " << mcenergy << std::endl;
1144 // if (neut.P()){
1145 // double lep_dcosx_truth = neut.Px()/neut.P();
1146 // double lep_dcosy_truth = neut.Py()/neut.P();
1147 // double lep_dcosz_truth = neut.Pz()/neut.P();
1148 //
1149 // mf::LogVerbatim("ShowerAngleClusterAna") << "----- cx,cy,cz " << lep_dcosx_truth << " " << lep_dcosy_truth << " " << lep_dcosz_truth << std::endl;
1150 //
1151 //
1152 // mcphi= (lep_dcosx_truth == 0.0 && lep_dcosz_truth == 0.0) ? 0.0 : TMath::ATan2(lep_dcosx_truth,lep_dcosz_truth);
1153 // mctheta= (lep_dcosx_truth == 0.0 && lep_dcosy_truth == 0.0 && lep_dcosz_truth == 0.0) ? 0.0 : TMath::Pi()*0.5-TMath::ATan2(std::sqrt(lep_dcosx_truth*lep_dcosx_truth + lep_dcosz_truth*lep_dcosz_truth),lep_dcosy_truth);
1154 //
1155 //
1156 // mcphi=180*mcphi/TMath::Pi();
1157 // mctheta= 180*mctheta/TMath::Pi();
1158 // mf::LogVerbatim("ShowerAngleClusterAna") << "----- phi, theta " << mcphi << " " << mctheta << std::endl;
1159 //
1160 // }
1161 //
1162 // int npart=0;
1163 // // while(&& npart < mc->NParticles() )
1164 // // {
1165 // mf::LogVerbatim("ShowerAngleClusterAna") << "%%%%%%%####### is PDG: "<< npart <<" " << neut.PdgCode() << std::endl;
1166 // // neut=mc->GetParticle(npart++);
1167 //
1168 // // }
1169 //
1170 // mf::LogVerbatim("ShowerAngleClusterAna") << "%%%%%%%####### after loop is PDG: "<< npart <<" " << neut.PdgCode() << std::endl;
1171 // //if((neut.PdgCode()==11 || neut.PdgCode()==-11 )&& neut.StatusCode()==1){
1172 //
1173 //
1174 // xyz_vertex[0] =neut.Vx();
1175 // xyz_vertex[1] =neut.Vy();
1176 // xyz_vertex[2] =neut.Vz();
1177 //
1178 // mf::LogVerbatim("ShowerAngleClusterAna") <<"neut.Vx()= "<<neut.Vx()<<" ,y= "<<neut.Vy()<<" ,z= "<<neut.Vz()<<std::endl;
1179 // //if(((neut.PdgCode()==11 || neut.PdgCode()==-11 )&& neut.StatusCode()==1))
1180 // // break;
1181 //
1182 //
1183 // double drifttick=(xyz_vertex[0]/detprop->DriftVelocity(detprop->Efield(),detprop->Temperature()))*(1./fTimeTick);
1184 //
1185 // const double origin[3] = {0.};
1186 // for(unsigned int iplane=0;iplane<fNPlanes;iplane++)
1187 // {
1188 // double pos[3];
1189 // geom->Plane(iplane).LocalToWorld(origin, pos);
1190 // //planex[p] = pos[0];
1191 // mf::LogVerbatim("ShowerAngleClusterAna") << "plane X positionp " << iplane << " " << pos[0] << std::endl;
1192 //
1193 // pos[1]=xyz_vertex[1];
1194 // pos[2]=xyz_vertex[2];
1195 // ///\todo: have to change to use cryostat and TPC in NearestWire too
1196 // unsigned int wirevertex = geom->NearestWire(pos,iplane);
1197 //
1198 //
1199 // mcwirevertex[iplane]=wirevertex; // wire coordinate of vertex for each plane
1200 // mctimevertex[iplane]=drifttick-(pos[0]/detprop->DriftVelocity(detprop->Efield(),detprop->Temperature()))*(1./fTimeTick)+detprop->TriggerOffset(); // time coordinate of vertex for each plane
1201 //
1202 // //fWireVertex[p]=wirevertex;
1203 // //fTimeVertex[p]=drifttick-(pos[0]/detprop->DriftVelocity(detprop->Efield(),detprop->Temperature()))*(1./fTimeTick)+60;
1204 // mf::LogVerbatim("ShowerAngleClusterAna") << "wirevertex= "<< wirevertex
1205 // << " timevertex " << mctimevertex[iplane]
1206 // << " correction "
1207 // << (pos[0]/detprop->DriftVelocity(detprop->Efield(),
1208 // detprop->Temperature()))*(1./fTimeTick)
1209 // << " " << pos[0];
1210 //
1211 //
1212 // }
1213 //
1214 //
1215 //
1216 // return (void)0;
1217 // }
1218 
1219 
1220 
1221 
1222 
1223 
1224 
1226 
1227 
1228 }
1229 
1230 #endif // SHOWERRECO_H
1231 
1232 
1233 
1234 
1235 
1236 
1237 
1238 
std::vector< double > fTime_last
key_type key() const
Definition: Ptr.h:356
fhicl::ParameterSet fCaloPSet
std::vector< double > fWire_vertexError
ShowerReco(fhicl::ParameterSet const &pset)
std::vector< double > fTotChargeADC
std::vector< double > fCorr_Charge_2cm
void set_direction_err(const TVector3 &dir_e)
Definition: Shower.h:136
Double_t xx
Definition: macro.C:12
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
Who knows?
Definition: geo_types.h:94
Encapsulate the construction of a single cyostat.
virtual int TriggerOffset() const =0
Double_t Get2DDistance(Double_t wire1, Double_t time1, Double_t wire2, Double_t time2) const
void Get2DVariables(art::PtrVector< recob::Hit > hitlist)
double dEdx_AREA(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
std::vector< int > fNhitsperplane
Declaration of signal hit object.
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:279
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
std::vector< double > vdEdx
std::vector< double > fTotADCperplane
std::vector< std::vector< double > > fDistribChargeMeV
float StartWire() const
Returns the wire coordinate of the start of the cluster.
Definition: Cluster.h:286
bool ChannelsIntersect(raw::ChannelID_t c1, raw::ChannelID_t c2, double &y, double &z) const
Returns an intersection point of two channels.
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
std::vector< int > fNpoints_corr_MeV_2cm
std::vector< std::vector< double > > fSingleEvtAngle
shower finding
std::vector< double > fTime_vertex
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
art::ServiceHandle< geo::Geometry > geom
float EndTick() const
Returns the tick coordinate of the end of the cluster.
Definition: Cluster.h:342
std::vector< unsigned int > fWire_last
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
EDProductGetter const * productGetter(ProductID const) const
Definition: Event.cc:64
std::vector< std::vector< double > > fDistribHalfChargeMeV
float StartAngle() const
Returns the starting angle of the cluster.
Definition: Cluster.h:475
std::vector< double > fChargeMeV_2cm_refined
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
RunNumber_t run() const
Definition: EventID.h:99
void GetVertexAndAnglesFromCluster(art::Ptr< recob::Cluster > clust, unsigned int plane)
Definition: Run.h:30
Double_t PitchInView(UInt_t plane, Double_t phi, Double_t theta) const
std::vector< double > vresRange
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
std::vector< int > fNpoints_2cm
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
std::vector< double > fTime_vertexError
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
std::vector< std::vector< double > > fSingleEvtAngleVal
void LongTransEnergy(unsigned int set, std::vector< art::Ptr< recob::Hit > > hitlist, bool isData=false)
void hits()
Definition: readHits.C:15
void set_direction(const TVector3 &dir)
Definition: Shower.h:135
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:441
std::vector< double > vdQdx
virtual double Temperature() const =0
T get(std::string const &key) const
Definition: ParameterSet.h:231
geo::WireID::WireID_t NearestWire(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the index of wire closest to position in the specified TPC.
std::vector< double > fRMS_2cm
void produce(art::Event &evt)
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
float SigmaStartWire() const
Returns the uncertainty on wire coordinate of the start of the cluster.
Definition: Cluster.h:306
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
Declaration of cluster object.
std::vector< std::vector< double > > fNPitch
void reconfigure(fhicl::ParameterSet const &pset)
size_type size() const
Definition: PtrVector.h:308
Detector simulation of raw signals on wires.
std::vector< double > fCorr_MeV_2cm
Encapsulate the geometry of a wire.
Int_t GetPointOnLine(Double_t slope, Double_t intercept, Double_t wire1, Double_t time1, Double_t &wireout, Double_t &timeout) const
std::string fClusterModuleLabel
data_t::const_iterator const_iterator
Definition: PtrVector.h:61
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
std::vector< double > xyz_vertex_fit
T * make(ARGS...args) const
void beginRun(art::Run &run)
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane.
std::vector< double > fChargeMeV_2cm
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
std::vector< double > fTotChargeMeV_MIPs
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
const detinfo::DetectorProperties * detprop
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
float SigmaStartTick() const
Returns the uncertainty on tick coordinate of the start of the cluster.
Definition: Cluster.h:315
std::vector< double > fChargeADC_2cm
std::vector< std::vector< double > > fDistribChargeADC
EventNumber_t event() const
Definition: EventID.h:117
constexpr double kBogusD
obviously bogus double value
std::vector< double > fChargeMeV_2cm_axsum
void ClearandResizeVectors(unsigned int nPlanes)
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
Float_t e
Definition: plot.C:34
std::vector< int > fNpoints_corr_ADC_2cm
Namespace collecting geometry-related classes utilities.
std::vector< std::vector< double > > fDistribChargeposition
float StartTick() const
Returns the tick coordinate of the start of the cluster.
Definition: Cluster.h:297
std::vector< unsigned int > fWire_vertex
SubRunNumber_t subRun() const
Definition: EventID.h:111
void LocalToWorld(const double *plane, double *world) const
Transform point from local plane frame to world frame.
Definition: PlaneGeo.h:1124
std::vector< double > deadwire
double dEdx_AMP(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
EventID id() const
Definition: Event.h:56
art framework interface to geometry description
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:230
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.
std::vector< double > fTotChargeMeV
Signal from collection planes.
Definition: geo_types.h:93
float EndWire() const
Returns the wire coordinate of the end of the cluster.
Definition: Cluster.h:329