CalibrationdEdXPDSP_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: CalibrationdEdXPDSP
3 // Module Type: producer
4 // File: CalibrationdEdXPDSP_module.cc
5 //
6 // Generated at Thu Nov 30 15:55:16 2017 by Tingjun Yang using artmod
7 // from cetpkgsupport v1_13_00.
8 ////////////////////////////////////////////////////////////////////////
9 
17 #include "canvas/Persistency/Common/FindManyP.h"
18 #include "fhiclcpp/ParameterSet.h"
20 
30 
33 
34 #include "TH2F.h"
35 #include "TH1F.h"
36 #include "TFile.h"
37 #include "TTimeStamp.h"
38 
39 #include <memory>
40 
41 namespace dune {
42  class CalibrationdEdXPDSP;
43 }
44 
46 public:
47  explicit CalibrationdEdXPDSP(fhicl::ParameterSet const & p);
48  // The destructor generated by the compiler is fine for classes
49  // without bare pointers or other resource use.
50 
51  // Plugins should not be copied or assigned.
52  CalibrationdEdXPDSP(CalibrationdEdXPDSP const &) = delete;
56 
57  // Required functions.
58  void produce(art::Event & e) override;
59 
60 private:
61 
65 
67 
68  double fModBoxA;
69  double fModBoxB;
70 
71  bool fSCE;
76  bool fUseLifetimeFromDatabase; // true: lifetime from database; false: lifetime from DetectorProperties
77  std::vector<double> fReferencedQdx;
78 
79  double fLifetime; // [us]
80 
81  double vDrift;
82  double xAnode;
83 
84  bool first;
85 };
86 
87 
89  : EDProducer(p)
90  , fTrackModuleLabel (p.get< std::string >("TrackModuleLabel"))
91  , fCalorimetryModuleLabel(p.get< std::string >("CalorimetryModuleLabel"))
92  , fHitModuleLabel (p.get< std::string >("HitModuleLabel"))
93  , caloAlg (p.get< fhicl::ParameterSet >("CaloAlg"))
94  , fModBoxA (p.get< double >("ModBoxA"))
95  , fModBoxB (p.get< double >("ModBoxB"))
96  , fSCE (p.get< bool >("CorrectSCE"))
97  , fApplyNormCorrection (p.get< bool >("ApplyNormCorrection"))
98  , fApplyXCorrection (p.get< bool >("ApplyXCorrection"))
99  , fApplyYZCorrection (p.get< bool >("ApplyYZCorrection"))
100  , fApplyLifetimeCorrection(p.get< bool >("ApplyLifetimeCorrection"))
101  , fUseLifetimeFromDatabase(p.get< bool >("UseLifetimeFromDatabase"))
102  , fReferencedQdx (p.get<std::vector<double>>("ReferencedQdx"))
103 {
104  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService>()->DataForJob();
105  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService>()->DataForJob(clockData);
106  vDrift = detProp.DriftVelocity(); //cm/us
107  xAnode = std::abs(detProp.ConvertTicksToX(trigger_offset(clockData),0,0,0));
108  //create calorimetry product and its association with track
109  produces< std::vector<anab::Calorimetry> >();
110  produces< art::Assns<recob::Track, anab::Calorimetry> >();
111  first = true;
112 }
113 
115 {
116 
118  calib::XYZCalibService & xyzcalibService = *xyzcalibHandler;
119  calib::XYZCalib *xyzcalib = xyzcalibService.provider();
120 
121  // Electron lifetime from database calibration service provider
123  calib::LifetimeCalibService & lifetimecalibService = *lifetimecalibHandler;
124  calib::LifetimeCalib *lifetimecalib = lifetimecalibService.provider();
125  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
126 
129  fLifetime = lifetimecalib->GetLifetime()*1000.0; // [ms]*1000.0 -> [us]
130  //std::cout << "use lifetime from database " << fLifetime << std::endl;
131  }
132  else {
133  fLifetime = detProp.ElectronLifetime(); // [us]
134  }
135  }
136 
137  //int run = evt.run();
138  //int subrun = evt.subRun();
139  //int event = evt.id().event();
140  // evttime
141  art::Timestamp ts = evt.time();
142  TTimeStamp tts(ts.timeHigh(), ts.timeLow());
143  uint64_t evttime = tts.AsDouble();
144 
145  std::cout << "run: " << evt.run() << " ; subrun: " << evt.subRun() << " ; event: " << evt.id().event() << std::endl;
146  std::cout << "evttime: " << evttime << std::endl;
147  if (fApplyLifetimeCorrection) std::cout << "fLifetime: " << fLifetime << " [us]" << std::endl;
148  if (first){
149  std::cout<<"fApplyNormCorrection: "<<fApplyNormCorrection<<std::endl;
150  std::cout<<"fApplyXCorrection: "<<fApplyXCorrection<<std::endl;
151  std::cout<<"fApplyYZCorrection: "<<fApplyYZCorrection<<std::endl;
152  std::cout<<"fApplyLifetimeCorrection: "<<fApplyLifetimeCorrection<<std::endl;
153  std::cout<<"fUseLifetimeFromDatabase: "<<fUseLifetimeFromDatabase<<std::endl;
154  std::cout<<"Plane\tReference dQ/dx\tGlobal median dQ/dx\tCalorimetry constant"<<std::endl;
155  for (int i = 0; i<3; ++i){
156  printf("Plane[%d]\t%f\t%f\t%f\n",i,fReferencedQdx[i], xyzcalib->GetNormCorr(i), 1./caloAlg.ElectronsFromADCArea(1, i));
157  }
158  first = false;
159  }
160  //Spacecharge services provider
161  auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
162 
163  //create anab::Calorimetry objects and make association with recob::Track
164  std::unique_ptr< std::vector<anab::Calorimetry> > calorimetrycol(new std::vector<anab::Calorimetry>);
165  std::unique_ptr< art::Assns<recob::Track, anab::Calorimetry> > assn(new art::Assns<recob::Track, anab::Calorimetry>);
166 
167  //get existing track/calorimetry objects
168  auto trackListHandle = evt.getHandle< std::vector<recob::Track> >(fTrackModuleLabel);
169 
170  std::vector<art::Ptr<recob::Track> > tracklist;
171  art::fill_ptr_vector(tracklist, trackListHandle);
172 
173  art::FindManyP<anab::Calorimetry> fmcal(trackListHandle, evt, fCalorimetryModuleLabel);
174 
175  //get hits
176  auto hitListHandle = evt.getHandle< std::vector<recob::Hit> >(fHitModuleLabel);
177 
178  std::vector<art::Ptr<recob::Hit> > hitlist;
179  art::fill_ptr_vector(hitlist, hitListHandle);
180 
181  if (!fmcal.isValid()){
183  <<"Could not get assocated Calorimetry objects";
184  }
185 
186  for (size_t trkIter = 0; trkIter < tracklist.size(); ++trkIter){
187  for (size_t i = 0; i<fmcal.at(trkIter).size(); ++i){
188  auto & calo = fmcal.at(trkIter)[i];
189 
190  if (!(calo->dEdx()).size()){
191  //empty calorimetry product, just copy it
192  calorimetrycol->push_back(*calo);
193  util::CreateAssn(*this, evt, *calorimetrycol, tracklist[trkIter], *assn);
194  }
195  else{
196  //start calibrating dQdx
197 
198  //get original calorimetry information
199  //double Kin_En = calo->KineticEnergy();
200  std::vector<float> vdEdx = calo->dEdx();
201  std::vector<float> vdQdx = calo->dQdx();
202  std::vector<float> vresRange = calo->ResidualRange();
203  std::vector<float> deadwire = calo->DeadWireResRC();
204  float Trk_Length = calo->Range();
205  std::vector<float> fpitch = calo->TrkPitchVec();
206  const auto& fHitIndex = calo->TpIndices();
207  const auto& vXYZ = calo->XYZ();
208  geo::PlaneID planeID = calo->PlaneID();
209 
210  //make sure the vectors are of the same size
211  if (vdEdx.size()!=vXYZ.size()||
212  vdQdx.size()!=vXYZ.size()||
213  vresRange.size()!=vXYZ.size()||
214  fpitch.size()!=vXYZ.size()){
216  <<"Vector sizes mismatch for vdEdx, vdQdx, vresRange, fpitch, vXYZ";
217  }
218 
219  //make sure the planeID is reasonable
220  if (!planeID.isValid){
222  <<"planeID is invalid";
223  }
224  if (planeID.Plane>2){
226  <<"plane is invalid "<<planeID.Plane;
227  }
228  // update the kinetic energy
229  double EkinNew = 0.;
230 
231  for (size_t j = 0; j<vdQdx.size(); ++j){
232  auto & hit = hitlist[fHitIndex[j]];
233  if (hit->WireID().Plane != planeID.Plane){
235  <<"Hit plane = "<<hit->WireID().Plane<<" calo plane = "<<planeID.Plane;
236  }
237  double normcorrection = 1;
239  normcorrection = xyzcalib->GetNormCorr(planeID.Plane);
240  if (normcorrection) normcorrection = fReferencedQdx[planeID.Plane]/normcorrection;
241  if (!normcorrection) normcorrection = 1.;
242  }
243  double xcorrection = 1;
244  if (fApplyXCorrection){
245  xcorrection = xyzcalib->GetXCorr(planeID.Plane, vXYZ[j].X());
246  if (!xcorrection) xcorrection = 1.;
247  }
248  double yzcorrection = 1;
249  if (fApplyYZCorrection){
250  yzcorrection = xyzcalib->GetYZCorr(planeID.Plane, vXYZ[j].X()>0, vXYZ[j].Y(), vXYZ[j].Z());
251  if (!yzcorrection) yzcorrection = 1.;
252  }
254  xcorrection *= exp((xAnode-std::abs(vXYZ[j].X()))/(fLifetime*vDrift));
255  }
256  //if (planeID.Plane == 2 && tracklist[trkIter]->ID() == 0) std::cout<<"plane = "<<planeID.Plane<<" x = "<<vXYZ[j].X()<<" y = "<<vXYZ[j].Y()<<" z = "<<vXYZ[j].Z()<<" normcorrection = "<<normcorrection<<" xcorrection = "<<xcorrection<<" yzcorrection = "<<yzcorrection<<" "<<vdQdx[j]<<std::endl;
257 
258  vdQdx[j] = normcorrection*xcorrection*yzcorrection*vdQdx[j];
259 
260 
261  //set time to be trgger time so we don't do lifetime correction
262  //we will turn off lifetime correction in caloAlg, this is just to be double sure
263  //vdEdx[j] = caloAlg.dEdx_AREA(vdQdx[j], detProp.TriggerOffset(), planeID.Plane, 0);
264 
265 
266  //Calculate dE/dx uisng the new recombination constants
267  double dQdx_e = caloAlg.ElectronsFromADCArea(vdQdx[j], planeID.Plane);
268  double rho = detProp.Density(); // LAr density in g/cm^3
269  double Wion = 1000./util::kGeVToElectrons; // 23.6 eV = 1e, Wion in MeV/e
270  double E_field_nominal = detProp.Efield(); // Electric Field in the drift region in KV/cm
271 
272  //correct Efield for SCE
273  geo::Vector_t E_field_offsets = {0., 0., 0.};
274 
275  if(sce->EnableCalEfieldSCE()&&fSCE) E_field_offsets = sce->GetCalEfieldOffsets(geo::Point_t{vXYZ[j].X(), vXYZ[j].Y(), vXYZ[j].Z()},hit->WireID().TPC);
276 
277  TVector3 E_field_vector = {E_field_nominal*(1 + E_field_offsets.X()), E_field_nominal*E_field_offsets.Y(), E_field_nominal*E_field_offsets.Z()};
278  double E_field = E_field_vector.Mag();
279 
280  //calculate recombination factors
281  double Beta = fModBoxB / (rho * E_field);
282  double Alpha = fModBoxA;
283  //double old_vdEdx = vdEdx[j];
284  vdEdx[j] = (exp(Beta * Wion * dQdx_e) - Alpha) / Beta;
285  //if (planeID.Plane == 2 && tracklist[trkIter]->ID() == 1) std::cout<<calo->dQdx()[j]<<" "<<vdEdx[j]<<" "<<vdQdx[j]<<" "<<vresRange[j]<<" "<<E_field<<" "<<rho<<" "<<Beta<<" "<<Alpha<<" "<<E_field_nominal<<" "<<E_field<<" "<<E_field_offsets.X()<<" "<<E_field_offsets.Y()<<" "<<E_field_offsets.Z()<<" "<<vXYZ[j].X()<<" "<<vXYZ[j].Y()<<" "<<vXYZ[j].Z()<<" "<<hit->WireID().TPC<<" "<<fHitIndex[j]<<" "<<normcorrection<<" "<<xcorrection<<" "<<yzcorrection<<std::endl;
286 
287  /*if (planeID.Plane==2){
288  std::cout << sce->EnableCalEfieldSCE() << " " << fSCE << std::endl;
289  std::cout << E_field << " " << E_field_nominal << std::endl;
290  std::cout << vdQdx[j] << " " << dQdx_e << std::endl;
291  std::cout << old_vdEdx << " " << vdEdx[j] << std::endl;
292  std::cout << rho << " " << Wion << " " << Beta << "\n" << std::endl; }
293  */
294  //update kinetic energy calculation
295  if (j>=1) {
296  if ( (vresRange[j] < 0) || (vresRange[j-1] < 0) ) continue;
297  EkinNew += fabs(vresRange[j]-vresRange[j-1]) * vdEdx[j];
298  }
299  if (j==0){
300  if ( (vresRange[j] < 0) || (vresRange[j+1] < 0) ) continue;
301  EkinNew += fabs(vresRange[j]-vresRange[j+1]) * vdEdx[j];
302  }
303 
304  }
305  //save new calorimetry information
306  calorimetrycol->push_back(anab::Calorimetry(EkinNew,// Kin_En, // change by David C. to update kinetic energy calculation
307  vdEdx,
308  vdQdx,
309  vresRange,
310  deadwire,
311  Trk_Length,
312  fpitch,
313  vXYZ,
314  fHitIndex,
315  planeID));
316  util::CreateAssn(*this, evt, *calorimetrycol, tracklist[trkIter], *assn);
317  }//calorimetry object not empty
318  }//loop over calorimetry objects
319  }//loop over tracks
320 
321  evt.put(std::move(calorimetrycol));
322  evt.put(std::move(assn));
323 
324  return;
325 }
326 
CalibrationdEdXPDSP(fhicl::ParameterSet const &p)
constexpr std::uint32_t timeLow() const
Definition: Timestamp.h:29
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
virtual double GetNormCorr(int plane)=0
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
constexpr std::uint32_t timeHigh() const
Definition: Timestamp.h:34
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
virtual double GetLifetime()=0
virtual calib::XYZCalib * provider() const =0
STL namespace.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
virtual calib::LifetimeCalib * provider() const =0
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
double ElectronsFromADCArea(double area, unsigned short plane) const
T abs(T value)
constexpr double kGeVToElectrons
23.6eV per ion pair, 1e9 eV/GeV
const double e
Timestamp time() const
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
def move(depos, offset)
Definition: depos.py:107
void produce(art::Event &e) override
p
Definition: test.py:223
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
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.
RunNumber_t run() const
Definition: DataViewImpl.cc:71
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
CalibrationdEdXPDSP & operator=(CalibrationdEdXPDSP const &)=delete
Detector simulation of raw signals on wires.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
virtual double GetXCorr(int plane, double x)=0
Provides recob::Track data product.
int trigger_offset(DetectorClocksData const &data)
EventNumber_t event() const
Definition: EventID.h:116
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
double Wion
Definition: doAna.cpp:16
virtual double GetYZCorr(int plane, int side, double x, double y)=0
int bool
Definition: qglobal.h:345
EventID id() const
Definition: Event.cc:34
calorimetry
QTextStream & endl(QTextStream &s)