PDSPDataDrivenBeam_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: PDSPDataDrivenBeam
3 // Plugin Type: producer (art v3_05_01)
4 // File: PDSPDataDrivenBeam_module.cc
5 //
6 // Generated at Thu Aug 6 08:22:36 2020 by Jacob Calcutt using cetskelgen
7 // from cetlib version v3_10_00.
8 ////////////////////////////////////////////////////////////////////////
9 
17 #include "fhiclcpp/ParameterSet.h"
19 #include "art_root_io/TFileService.h"
24 
25 #include <memory>
26 #include <utility>
27 #include <map>
28 
29 #include "TFile.h"
30 #include "THnSparse.h"
31 #include "TVectorD.h"
32 #include "TRandom3.h"
33 #include "TTree.h"
34 #include "TH1D.h"
35 #include "TH2D.h"
36 #include "TF1.h"
37 #include "TDatabasePDG.h"
38 #include "TParticlePDG.h"
39 
40 class PDSPDataDrivenBeam;
41 
43 public:
44  explicit PDSPDataDrivenBeam(fhicl::ParameterSet const& p);
45  // The compiler-generated destructor is fine for non-base
46  // classes without bare pointers or other resource use.
47 
48  // Plugins should not be copied or assigned.
49  PDSPDataDrivenBeam(PDSPDataDrivenBeam const&) = delete;
52  operator=(PDSPDataDrivenBeam const&) = delete;
54 
55  // Required functions.
56  void produce(art::Event& e) override;
57  void beginJob() override;
58 
59 private:
60 
61  TFile* fInputFile = 0x0;
63  TFile* fResolutionFile = 0x0;
65  std::vector<std::string> fParticleTypes;
67  int fSeed;
68  TRandom3 fRNG;
69  bool fVerbose;
74  std::vector<double> fMinima, fMaxima;
76  bool fDoWeights;
77 
78 
79  std::map<std::string, THnSparseD *> fPDFs;
80  std::map<std::string, TH1D *> fResolutionHists;
81  std::map<std::string, TH2D *> fResolutionHists2D;
82  std::map<std::string, TH2D *> fResolutionHists2DPlus;
83  std::map<std::string, TH2D *> fResolutionHists2DMinus;
84  std::map<std::string, TF1 *> fResolutions;
85  std::map<std::string, double> fParticleNums;
86  double fTotalParticles = 0.;
87  std::map<std::string, double> fParticleFracs;
88  int fCurrentEvent = 0;
89 
90  std::vector<int> fRandPDG;
91  std::vector<double> fRandMomentum;
92  std::vector<double> fRandHUpstream, fRandVUpstream;
93  std::vector<double> fRandHDownstream, fRandVDownstream;
94 
95  TTree * fOutputTree;
102 
103  std::map<std::string, int> fNameToPDG = {
104  {"Protons", 2212},
105  {"Pions", 211},
106  {"Electrons", -11},
107  {"Muons", -13},
108  {"Kaons", 321}
109  };
110 
111  std::map<int, std::string> fPDGToName = {
112  {2212, "Protons"},
113  {211, "Pions"},
114  {-11, "Electrons"},
115  {-13, "Muons"},
116  {321, "Kaons"}
117  };
118 
119  TVector3 fBMBasisX = TVector3(1.,0.,0.);
120  TVector3 fBMBasisY = TVector3(0.,1.,0.);
121  TVector3 fBMBasisZ = TVector3(0.,0.,1.);
122 
123 
124  void Convert(double input_point[5], std::vector<double> minima,
125  std::vector<double> maxima, double output_point[5]);
126  //void Convert(double input_point[5], double minima[5],
127  // double maxima[5], double output_point[5]);
128 
129  void GenerateTrueEvent(simb::MCTruth &mcTruth);
131  void MakeTracks(beam::ProtoDUNEBeamEvent & beamEvent);
133  void SetPositionAndMomentum(TLorentzVector & position,
134  TLorentzVector & momentum);
135  TVector3 ConvertProfCoordinates(double x, double y, double z, double zOffset);
137  void RotateMonitorVector(TVector3 & vec);
138  void FitResolutions();
139  double UnsmearMomentum1D();
140  double UnsmearMomentum2D();
141  void GetSystWeights();
142 
143  void Setup1GeV(); //Shared by 2GeV
144  void Setup3GeV();
145  void Setup6GeV(); //Shared by 7GeV
146 
147  void Scale2DRes();
148 };
149 
150 
152  : EDProducer{p},
153  fInputFileName(p.get<std::string>("InputFileName")),
154  fResolutionFileName(p.get<std::string>("ResolutionFileName")),
155  fNGenerate(p.get<int>("NGenerate")),
156  fSeed(p.get<int>("Seed")),
157  fRNG(fSeed),
158  fVerbose(p.get<bool>("Verbose")),
159  fRotateMonitorXZ(p.get<double>("RotateMonitorXZ")),
160  fRotateMonitorYZ(p.get<double>("RotateMonitorYZ")),
161  fNP04FrontZ(p.get<double>("NP04FrontZ")),
162  fBeamX(p.get<double>("BeamX")),
163  fBeamY(p.get<double>("BeamY")),
164  fBeamZ(p.get<double>("BeamZ")),
165  fUpstreamZ(p.get<double>("UpstreamZ")),
166  fDownstreamZ(p.get<double>("DownstreamZ")),
167  fGeneratorZ(p.get<double>("GeneratorZ")),
168  fUnsmearType(p.get<int>("UnsmearType")),
169  fNominalMomentum(p.get<int>("NominalMomentum")),
170  fDoWeights(p.get<bool>("DoWeights")) {
171 
172  std::vector<std::pair<std::string, double>> temp_vec =
173  p.get<std::vector<std::pair<std::string, double>>>("ParticleTypes");
174 
175  for (auto it = temp_vec.begin(); it != temp_vec.end(); ++it) {
176  fParticleTypes.push_back(it->first);
177  fParticleNums[it->first] = it->second;
178  fTotalParticles += it->second;
179  if (fVerbose)
180  std::cout << it->first << " " << it->second << " " << fTotalParticles <<
181  std::endl;
182  }
183 
184  fMinima = p.get<std::vector<double>>("Minima");
185  fMaxima = p.get<std::vector<double>>("Maxima");
186 
187  produces<std::vector<simb::MCTruth>>();
188  produces<std::vector<beam::ProtoDUNEBeamEvent>>();
189 
190 }
191 
193 
194  // Define the truth collection for this event.
195  auto mcTruths = std::make_unique<std::vector<simb::MCTruth>>();
196 
197  //Create and produce the true event
198  simb::MCTruth truth;
199  GenerateTrueEvent(truth);
200 
201  //Set in the MCTruth vector and into the event
202  mcTruths->push_back(truth);
203  e.put(std::move(mcTruths));
204 
205  //Define beam event for the event
206  std::unique_ptr<std::vector<beam::ProtoDUNEBeamEvent>>
207  beamData(new std::vector<beam::ProtoDUNEBeamEvent>);
208  beam::ProtoDUNEBeamEvent beamEvent;
209 
210  GenerateBeamEvent(beamEvent);
211  beamData->push_back(beamEvent);
212  e.put(std::move(beamData));
213 
214  if (fVerbose) {
215  std::cout << fCurrentEvent << " " <<
216  fRandPDG[fCurrentEvent] << " " <<
217  fRandMomentum[fCurrentEvent] << " " <<
218  fRandHUpstream[fCurrentEvent] << " " <<
219  fRandVUpstream[fCurrentEvent] << " " <<
222  }
223 
224  //Some output to the hist file
231  fOutputTree->Fill();
232 
233  //Increment position in sampled particle list
234  ++fCurrentEvent;
235 }
236 
238  //Open input file
239  fInputFile = new TFile(fInputFileName.c_str(), "READ");
240  fResolutionFile = new TFile(fResolutionFileName.c_str(), "READ");
241 
242  //Get all the PDFs
243  //
244  //Move to:
245  //horiz/vert fibers in last XBPF
246  //Px, Py, Pz -- or P, theta, phi (I like this more I think)
247  //
248  //Where the directions are taken from the reconstructed
249  //tracks from the last 2 XBPFs.
250  //
251  //The momentum is a bit tricky: we need to sample in
252  //reco space, but generate in true space. We'll have to
253  //unfold from the reco momentum in the spectrometer to
254  //the true energy (taken from nominal MC?) at the generation
255  //point (what is called the face in the beam sim files I think)
256 
257  //Get all of the PDFs that we'll use to sample from
258  //One for each particle type we're interested in
259  //Also get the number of that type of particle
260  /*
261  for (size_t i = 0; i < fParticleTypes.size(); ++i) {
262  std::string part_type = fParticleTypes[i];
263  fPDFs[part_type] = (THnSparseD*)fInputFile->Get(part_type.c_str());
264 
265  std::string n_part_type = "n" + part_type;
266  TVectorD * n_parts = (TVectorD*)fInputFile->Get(n_part_type.c_str());
267  fParticleNums[part_type] = (*n_parts)[0];
268 
269  fTotalParticles += (*n_parts)[0];
270 
271 
272  //Also get the resolutions
273  std::string res_name = "h" + part_type + "Res";
274  fResolutionHists[part_type] = (TH1D*)fResolutionFile->Get(res_name.c_str());
275 
276  res_name += "2D";
277  fResolutionHists2D[part_type] = (TH2D*)fResolutionFile->Get(res_name.c_str());
278  //Scale according to the reco bin population
279  TH2D * this_hist = fResolutionHists2D[part_type];
280  for (int i = 1; i <= this_hist->GetNbinsX(); ++i) {
281  double integral = this_hist->TH1::Integral(i, i);
282  std::cout << "Integral: " << integral << std::endl;
283  double total = 0.;
284  for (int j = 1; j <= this_hist->GetNbinsY(); ++j) {
285  double content = this_hist->GetBinContent(i, j);
286  std::cout << "Content: " << content << std::endl;
287  this_hist->SetBinContent(i, j,
288  this_hist->GetBinContent(i, j) / integral);
289  total += this_hist->GetBinContent(i, j);
290  }
291  std::cout << "Bin " << i << " total " << total << std::endl;
292  }
293  }
294  */
295 
296  switch (fNominalMomentum) {
297  case 1:
298  Setup1GeV();
299  break;
300  case 2:
301  Setup1GeV();
302  break;
303  case 3:
304  Setup3GeV();
305  break;
306  case 6:
307  Setup6GeV();
308  break;
309  case 7:
310  Setup6GeV();
311  break;
312  default:
313  Setup1GeV();
314  break;
315  }
316 
317  Scale2DRes();
318 
319  //Compute fractions of particles to sample from
320  double running_total = 0.;
321  for (auto it = fParticleNums.begin(); it != fParticleNums.end(); ++it) {
322  running_total += it->second / fTotalParticles;
323  fParticleFracs[it->first] = running_total;
324  if (fVerbose) {
325  std::cout << it->second << " " << running_total << std::endl;
326  std::cout << fParticleFracs[it->first] << std::endl;
327  }
328  }
329 
330 
331  //Will need to throw some random numbers
332  //pdg type
333  //reco momentum
334  //vert/horiz fibers for both monitors
335  // --- Establish valid ranges?
336  //
337  //Then throw flat(0,1)
338  //and check against PDF in that 5D bin
339  //
340  //
341  //If rejected, go back to throwing in phase space
342  //and check against PDF again. This will fill the
343  //phase space according to the PDF
344  //
345  //
346  //
347  //Do this all in the beginJob step,
348  //where we throw all of the numbers until we get
349  //N events, where N is a fcl parameter describing how
350  //many events we would like to generate. Save the
351  //kinematics, position, and PDG for these N events and then use
352  //in the produce function to create the events.
353  int nSampled = 0;
354  double kin_samples[5]; //the point in phase space to check against pdf
355  double pdf_check; //the number used for the checking
356  double pdg_sample = 0.; //point to sample fractions of particle types
357  while (nSampled < fNGenerate) {
358  //Get the pdg from the random num
359  pdg_sample = fRNG.Rndm();
360  std::string part_type = "";
361  for (auto it = fParticleFracs.begin(); it != fParticleFracs.end(); ++it) {
362  if (pdg_sample <= it->second) {
363  if (fVerbose) {
364  std::cout << "Sampled " << it->first << " " <<
365  pdg_sample << std::endl;
366  }
367  fRandPDG.push_back(fNameToPDG[it->first]);
368  part_type = it->first;
369  break;
370  }
371  }
372 
373  //Now, find a random point in phase space, throw a number,
374  //and check against the PDF
375  //
376  //If successful, store the kinematics and store for later production
377  //If unsuccessful, select a new random point in phase, throw & check again
378  bool sample_again = true;
379  while (sample_again) {
380  fRNG.RndmArray(5, &kin_samples[0]);
381  pdf_check = fRNG.Rndm();
382 
383  //Need to convert the numbers sampled for the kinematics (0, 1)
384  //to within the sampling range
385  double kin_point[5];
386  //Convert(kin_samples, minima, maxima, kin_point);
387  Convert(kin_samples, fMinima, fMaxima, kin_point);
388 
389 
390  //Find the bin in the THnSparseD. If the bin has a value of 0,
391  //then it would not have been allocated to save on memory.
392  //The false parameter prevents that bin from being allocated here,
393  //to save memory
394  long long bin = fPDFs[part_type]->GetBin(&kin_point[0], false);
395 
396  //The bin has no chance of being populated, move on
397  if (bin == -1) continue;
398 
399  //Find how likely we are to populate this bin
400  double pdf_value = fPDFs[part_type]->GetBinContent(bin);
401 
402  //If successful, save info and move on
403  if (pdf_check <= pdf_value) {
404  if (fVerbose) {
405  std::cout << "bin: " << bin << " PDF val: " << pdf_value <<
406  " Check: " << pdf_check << std::endl;
407  std::cout << kin_samples[0] << " " << kin_samples[1] << " " <<
408  kin_samples[2] << " " << kin_samples[3] << " " <<
409  kin_samples[4] << std::endl;
410  std::cout << kin_point[0] << " " << kin_point[1] << " " <<
411  kin_point[2] << " " << kin_point[3] << " " <<
412  kin_point[4] << std::endl;
413  std::cout << "Will keep" << std::endl;
414  }
415 
416  fRandMomentum.push_back(kin_point[0]);
417  fRandVUpstream.push_back(kin_point[1]);
418  fRandHUpstream.push_back(kin_point[2]);
419  fRandVDownstream.push_back(kin_point[3]);
420  fRandHDownstream.push_back(kin_point[4]);
421 
422  ++nSampled;
423  sample_again = false;
424  }
425  }
426  }
427 
428  //For quick output info
430  fOutputTree = tfs->make<TTree>("tree", "");
431  fOutputTree->Branch("PDG", &fOutputPDG);
432  fOutputTree->Branch("Event", &fCurrentEvent);
433  fOutputTree->Branch("Momentum", &fOutputMomentum);
434  fOutputTree->Branch("UnfoldedMomentum", &fUnfoldedMomentum);
435  fOutputTree->Branch("HUpstream", &fOutputHUpstream);
436  fOutputTree->Branch("VUpstream", &fOutputVUpstream);
437  fOutputTree->Branch("HDownstream", &fOutputHDownstream);
438  fOutputTree->Branch("VDownstream", &fOutputVDownstream);
439  fOutputTree->Branch("PlusSigmaWeight", &fPlusSigmaWeight);
440  fOutputTree->Branch("MinusSigmaWeight", &fMinusSigmaWeight);
441 
442 
443  //Setting up for positioning/momentum projection
445 
446  //Fit the resolution hists
447  FitResolutions();
448 }
449 
450 //To turn the kinematic sample (range 0 --> 1)
451 //into the variable we use in the pdf (momentum, fiber numbers)
453  double input_point[5], std::vector<double> minima,
454  std::vector<double> maxima, double output_point[5]) {
455  for (int i = 0; i < 5; ++i) {
456  double delta = maxima[i] - minima[i];
457  output_point[i] = minima[i] + delta * input_point[i];
458  }
459 }
460 
462  TLorentzVector position(0, 0, 0, 0);
463  TLorentzVector momentum(0., 0., 0., 0.);
464  SetPositionAndMomentum(position, momentum);
465 
466  if (fVerbose) {
467  std::cout << "Position: ";
468  position.Print();
469  std::cout << "Momentum: ";
470  momentum.Print();
471  }
472 
474 
475  std::string process = "primary";
476  int trackID = 0; //Change?
477 
478  simb::MCParticle newParticle(trackID, fRandPDG[fCurrentEvent], process);
479  newParticle.AddTrajectoryPoint(position, momentum);
480 
481  // Add the MCParticle to the MCTruth for the event.
482  mcTruth.Add(newParticle);
483 }
484 
485 void PDSPDataDrivenBeam::SetPositionAndMomentum(TLorentzVector & position, TLorentzVector & momentum) {
486  //First, get the vector between the two sets of tracking monitors
487  //
488  //Shift to center of fibers. Middle is 96
489  //Fiber 0 is most-positive: 95.5
490  //Fiber 191 is most-negative: -95.5
491  /*
492  double upstreamX = 96. - int(fRandHUpstream[fCurrentEvent]) - .5;
493  double upstreamY = 96. - int(fRandVUpstream[fCurrentEvent]) - .5;
494 
495  double downstreamX = 96. - int(fRandHDownstream[fCurrentEvent]) - .5;
496  double downstreamY = 96. - int(fRandVDownstream[fCurrentEvent]) - .5;
497  */
498 
499  double upstreamX = 96. - fRandHUpstream[fCurrentEvent];
500  double upstreamY = 96. - fRandVUpstream[fCurrentEvent];
501  double downstreamX = 96. - fRandHDownstream[fCurrentEvent];
502  double downstreamY = 96. - fRandVDownstream[fCurrentEvent];
503 
504  TVector3 upstream_point = ConvertProfCoordinates(upstreamX, upstreamY, 0.,
505  fUpstreamZ);
506  TVector3 downstream_point = ConvertProfCoordinates(downstreamX, downstreamY, 0.,
507  fDownstreamZ);
508 
509  TVector3 dR = (downstream_point - upstream_point).Unit();
510 
511  if (fVerbose) {
512  std::cout << "Upstream: " << upstream_point.X() << " " <<
513  upstream_point.Y() << " " << upstream_point.Z() << std::endl;
514  std::cout << "Downstream: " << downstream_point.X() << " " <<
515  downstream_point.Y() << " " << downstream_point.Z() << std::endl;
516  std::cout << "dR: " << dR.X() << " " << dR.Y() << " " << dR.Z() << std::endl;
517  }
518 
519  //Project to generator point
520  double deltaZ = (fGeneratorZ - downstream_point.Z());
521  double deltaX = (dR.X() / dR.Z()) * deltaZ;
522  double deltaY = (dR.Y() / dR.Z()) * deltaZ;
523 
524  TVector3 generator_point = downstream_point +
525  TVector3(deltaX, deltaY, deltaZ);
526  //Set the position 4-vector
527  //Time = 0 for now?
528  position = TLorentzVector(generator_point, 0.);
529 
530  //Prints out the projected position at the face of the TPC
531  if (fVerbose) {
532  deltaZ = (-1.*fGeneratorZ);
533  deltaX = (dR.X() / dR.Z()) * deltaZ;
534  deltaY = (dR.Y() / dR.Z()) * deltaZ;
535 
536  TVector3 last_point = generator_point +
537  TVector3(deltaX, deltaY, deltaZ);
538 
539  std::cout << last_point.X() << " " << last_point.Y() << " " <<
540  last_point.Z() << std::endl;
541  }
542 
543  //Scales the trajectory between monitors by the momentum value
544  //Attempting to go from reco to true
545  int pdg = fRandPDG[fCurrentEvent];
546  switch (fUnsmearType) {
547  case 1:
549  break;
550  case 2:
552  if (fDoWeights) GetSystWeights();
553  break;
554  default:
555  //Just do 1D
557  break;
558  }
559 
560  //TVector3 mom_vec = fRandMomentum[fCurrentEvent]*dR;
561  //TVector3 mom_vec = unfolded_momentum*dR;
562  TVector3 mom_vec = fUnfoldedMomentum*dR;
563 
564  //Get the PDG and set the mass & energy accordingly
565  const TDatabasePDG * dbPDG = TDatabasePDG::Instance();
566  const TParticlePDG * def = dbPDG->GetParticle(pdg);
567  double mass = def->Mass();
568  double energy = sqrt(mass*mass + mom_vec.Mag2());
569 
570  //Set the momentum 4-vector
571  momentum = TLorentzVector(mom_vec, energy);
572 }
573 
575  double x, double y, double z, double zOffset) {
576 
577  double off = fNP04FrontZ - zOffset;
578 
579  TVector3 old(x,y,z);
580 
581  //Transform the positions relative to the center of the beam monitor to that
582  //relative to the end of the beam line
583  double newX = x*fBMBasisX.X() + y*fBMBasisY.X() + off*fabs(fBMBasisZ.X());
584  double newY = x*fBMBasisX.Y() + y*fBMBasisY.Y() + off*fabs(fBMBasisZ.Y());
585  double newZ = x*fBMBasisX.Z() + y*fBMBasisY.Z() - off*fabs(fBMBasisZ.Z());
586 
587  //Shift the position relative to the beam entrance on the cryostat
588  newX += fBeamX*10.;
589  newY += fBeamY*10.;
590  newZ += fBeamZ*10.;
591 
592  TVector3 result(newX/10., newY/10., newZ/10.);
593  return result;
594 }
595 
600 }
601 
603  vec.RotateX(fRotateMonitorYZ * TMath::Pi()/180.);
604  vec.RotateY(fRotateMonitorXZ * TMath::Pi()/180.);
605 }
606 
608  for (auto it = fResolutionHists.begin(); it != fResolutionHists.end(); ++it) {
609  TH1D * hist = it->second;
610  hist->Fit("gaus", "Q");
611  fResolutions[it->first] = (TF1 *)hist->GetFunction("gaus");
612  }
613 }
614 
616  beam::ProtoDUNEBeamEvent & beamEvent) {
617  beamEvent.SetTOFs(std::vector<double>{0.});
618  beamEvent.SetTOFChans(std::vector<int>{0});
619  beamEvent.SetUpstreamTriggers(std::vector<size_t>{0});
620  beamEvent.SetDownstreamTriggers(std::vector<size_t>{0});
621  beamEvent.SetCalibrations(0., 0., 0., 0.);
622  beamEvent.DecodeTOF();
623 
624  beamEvent.SetMagnetCurrent(0.);
625  beamEvent.SetTimingTrigger(12);
626 
628  dummy.trigger = 0;
629  dummy.pressure = 0.;
630  dummy.timeStamp = 0.;
631  beamEvent.SetCKov0(dummy);
632  beamEvent.SetCKov1(dummy);
633 
634  beamEvent.SetActiveTrigger(0);
635  beamEvent.SetT0(std::make_pair(0.,0.));
636 
637  //Dummy positions for these
638  beamEvent.SetFBMTrigger("XBPF022697", MakeFiberMonitor(.5));
639  beamEvent.SetFBMTrigger("XBPF022698", MakeFiberMonitor(.5));
640  beamEvent.SetFBMTrigger("XBPF022701", MakeFiberMonitor(.5));
641  beamEvent.SetFBMTrigger("XBPF022702", MakeFiberMonitor(.5));
642 
643  double upstream_x = fRandHUpstream[fCurrentEvent];
644  double upstream_y = fRandVUpstream[fCurrentEvent];
645  double downstream_x = fRandHDownstream[fCurrentEvent];
646  double downstream_y = fRandVDownstream[fCurrentEvent];
647 
648  beamEvent.SetFBMTrigger("XBPF022707", MakeFiberMonitor(96. - upstream_x));//X
649  beamEvent.SetFBMTrigger("XBPF022708", MakeFiberMonitor(96. - upstream_y));//Y
650 
651  beamEvent.SetFBMTrigger("XBPF022716", MakeFiberMonitor(96. - downstream_x));//X
652  beamEvent.SetFBMTrigger("XBPF022717", MakeFiberMonitor(96. - downstream_y));//Y
653 
654  MakeTracks(beamEvent);
655 
657 }
658 
660  beam::FBM theFBM;
661 
662  //I should probably just make this into
663  //a constructor for the FBM...
664  theFBM.ID = -1;
665  theFBM.glitch_mask = {};
666  std::uninitialized_fill(std::begin(theFBM.fiberData),
667  std::end(theFBM.fiberData), 0.);
668  std::uninitialized_fill(std::begin(theFBM.timeData),
669  std::end(theFBM.timeData), 0.);
670  theFBM.timeStamp = 0.;
671 
672  short f = 96 - short(floor(pos)) - 1;
673  theFBM.fibers[f] = 1;
674  theFBM.active.push_back(f);
675  theFBM.decoded = true;
676 
677  return theFBM;
678 }
679 
681 
682  //We should only have one active fiber at a time
683  short fx1 = beamEvent.GetFBM("XBPF022707").active[0];
684  short fy1 = beamEvent.GetFBM("XBPF022708").active[0];
685 
686  //Convert fiber number to position
687  //p = 96. - f - .5
688  double x1 = 96. - fx1 - .5;
689  double y1 = 96. - fy1 - .5;
690 
691  TVector3 pos1 = ConvertProfCoordinates(x1, y1, 0., fUpstreamZ);
692 
693  short fx2 = beamEvent.GetFBM("XBPF022716").active[0];
694  short fy2 = beamEvent.GetFBM("XBPF022717").active[0];
695 
696  double x2 = 96. - fx2 - .5;
697  double y2 = 96. - fy2 - .5;
698 
699  TVector3 pos2 = ConvertProfCoordinates(x2, y2, 0., fDownstreamZ);
700 
701  TVector3 dR = (pos2 - pos1).Unit();
702 
703  double deltaZ = (-1.*pos2.Z());
704  double deltaX = (dR.X() / dR.Z()) * deltaZ;
705  double deltaY = (dR.Y() / dR.Z()) * deltaZ;
706 
707  TVector3 tpc_point = pos2 + TVector3(deltaX, deltaY, deltaZ);
708  if (fVerbose) {
709  std::cout << "TPC point: " << tpc_point.X() << " " << tpc_point.Y() <<
710  " " << tpc_point.Z() << std::endl;
711  }
712 
713  std::vector< TVector3 > thePoints = {pos1, pos2, tpc_point};
714  std::vector< TVector3 > theMomenta = {
715  (pos2 - pos1).Unit(),
716  (pos2 - pos1).Unit(),
717  (pos2 - pos1).Unit()
718  };
719 
720  recob::Track track(
723  recob::Track::Flags_t(thePoints.size()),
724  false),
725  0, -1., 0, recob::tracking::SMatrixSym55(),
727 
728  beamEvent.AddBeamTrack(track);
729 }
730 
732  int pdg = fRandPDG[fCurrentEvent];
733  TF1 * res = fResolutions[fPDGToName[pdg]];
734  double mean = res->GetParameter(1);
735  double sigma = res->GetParameter(2);
736  double t = fRNG.Gaus(mean, sigma); //random number from momentum resolution
737  return (fRandMomentum[fCurrentEvent]/(t + 1.));
738 }
739 
741 
742  if (fVerbose) {
743  std::cout << "Using 2D Unsmear method" << std::endl;
744  }
745 
746  int pdg = fRandPDG[fCurrentEvent];
747  TH2D * res = fResolutionHists2D[fPDGToName[pdg]];
748 
749  int xBin = res->GetXaxis()->FindBin(fRandMomentum[fCurrentEvent]);
750  if (fVerbose) {
751  std::cout << "Momentum & bin: " << fRandMomentum[fCurrentEvent] << " " <<
752  xBin << std::endl;
753  }
754 
755  double true_min = res->GetYaxis()->GetXmin();
756  double true_max = res->GetYaxis()->GetXmax();
757  for (int i = 1; i <= res->GetNbinsY(); ++i) {
758  if (res->GetBinContent(xBin, i) > 0.) {
759  true_min = res->GetYaxis()->GetBinLowEdge(i);
760  break;
761  }
762  }
763  for (int i = res->GetNbinsY(); i >= 1; --i) {
764  if (res->GetBinContent(xBin, i) > 0.) {
765  true_max = res->GetYaxis()->GetBinUpEdge(i);
766  break;
767  }
768  }
769 
770  if (fVerbose)
771  std::cout << "True min and max: " << true_min << " " << true_max << std::endl;
772 
773  double unsmeared_momentum = 0.;
774  while (true) {
775  double t = fRNG.Uniform(true_min, true_max);
776  double pdf_check = fRNG.Rndm(); //random number to check against PDF
777 
778  int yBin = res->GetYaxis()->FindBin(t);
779  double pdf_value = res->GetBinContent(xBin, yBin);
780  if (fVerbose) {
781  std::cout << "True mom & bin: " << t << " " << yBin << std::endl;
782  std::cout << "Check & val: " << pdf_check << " " << pdf_value <<
783  std::endl;
784  }
785  if (pdf_check < pdf_value) {
786  unsmeared_momentum = t;
787  if (fVerbose) std::cout << "Setting momentum to " << t << std::endl;
788  break;
789  }
790  }
791 
792  return unsmeared_momentum;
793 }
794 
796  for (auto it = fResolutionHists2D.begin();
797  it != fResolutionHists2D.end(); ++it) {
798  TH2D * this_hist = it->second;
799  for (int i = 1; i <= this_hist->GetNbinsX(); ++i) {
800  double integral = this_hist->TH1::Integral(i, i);
801  double total = 0.;
802  for (int j = 1; j <= this_hist->GetNbinsY(); ++j) {
803  this_hist->SetBinContent(i, j,
804  this_hist->GetBinContent(i, j) / integral);
805  total += this_hist->GetBinContent(i, j);
806  }
807  }
808  }
809 
810  if (fDoWeights) {
811  for (auto it = fResolutionHists2DPlus.begin();
812  it != fResolutionHists2DPlus.end(); ++it) {
813  TH2D * this_hist = it->second;
814  for (int i = 1; i <= this_hist->GetNbinsX(); ++i) {
815  double integral = this_hist->TH1::Integral(i, i);
816  double total = 0.;
817  for (int j = 1; j <= this_hist->GetNbinsY(); ++j) {
818  this_hist->SetBinContent(i, j,
819  this_hist->GetBinContent(i, j) / integral);
820  total += this_hist->GetBinContent(i, j);
821  }
822  }
823 
824  this_hist->Divide(fResolutionHists2D[it->first]);
825  }
826 
827  for (auto it = fResolutionHists2DMinus.begin();
828  it != fResolutionHists2DMinus.end(); ++it) {
829  TH2D * this_hist = it->second;
830  for (int i = 1; i <= this_hist->GetNbinsX(); ++i) {
831  double integral = this_hist->TH1::Integral(i, i);
832  double total = 0.;
833  for (int j = 1; j <= this_hist->GetNbinsY(); ++j) {
834  this_hist->SetBinContent(i, j,
835  this_hist->GetBinContent(i, j) / integral);
836  total += this_hist->GetBinContent(i, j);
837  }
838  }
839 
840  this_hist->Divide(fResolutionHists2D[it->first]);
841  }
842  }
843 }
844 
846  for (size_t i = 0; i < fParticleTypes.size(); ++i) {
847  std::string part_type = fParticleTypes[i];
848  if (part_type == "Muons") {
849  fPDFs[part_type] = (THnSparseD*)fInputFile->Get("Pions");
850  }
851  else {
852  fPDFs[part_type] = (THnSparseD*)fInputFile->Get(part_type.c_str());
853  }
854 
855  //Also get the resolutions
856  std::string res_name = "";
857  if (part_type == "Muons") {
858  res_name = "hPionsRes";
859  }
860  else {
861  res_name = "h" + part_type + "Res";
862  }
863 
864  fResolutionHists[part_type] = (TH1D*)fResolutionFile->Get(res_name.c_str());
865 
866  res_name += "2D";
867  fResolutionHists2D[part_type] = (TH2D*)fResolutionFile->Get(res_name.c_str());
868 
869  if (fDoWeights) {
870  std::string plus_name = res_name + "Plus";
871  fResolutionHists2DPlus[part_type] = (TH2D*)fResolutionFile->Get(plus_name.c_str());
872 
873  std::string minus_name = res_name + "Minus";
874  fResolutionHists2DMinus[part_type] = (TH2D*)fResolutionFile->Get(minus_name.c_str());
875  }
876  }
877 }
878 
880 
881 
882  for (size_t i = 0; i < fParticleTypes.size(); ++i) {
883  std::string part_type = fParticleTypes[i];
884  if (part_type == "Muons") {
885  fPDFs[part_type] = (THnSparseD*)fInputFile->Get("Pions");
886  }
887  else if (part_type == "Kaons") {
888  fPDFs[part_type] = (THnSparseD*)fInputFile->Get("Protons");
889  }
890  else {
891  fPDFs[part_type] = (THnSparseD*)fInputFile->Get(part_type.c_str());
892  }
893 
894  //Also get the resolutions
895  std::string res_name = "";
896  if (part_type == "Muons") {
897  res_name = "hPionsRes";
898  }
899  /*
900  else if (part_type == "Kaons") {
901  res_name = "hProtonsRes";
902  }*/
903  else {
904  res_name = "h" + part_type + "Res";
905  }
906 
907  fResolutionHists[part_type] = (TH1D*)fResolutionFile->Get(res_name.c_str());
908 
909  res_name += "2D";
910  fResolutionHists2D[part_type] = (TH2D*)fResolutionFile->Get(res_name.c_str());
911 
912  if (fDoWeights) {
913  std::string plus_name = res_name + "Plus";
914  fResolutionHists2DPlus[part_type] = (TH2D*)fResolutionFile->Get(plus_name.c_str());
915 
916  std::string minus_name = res_name + "Minus";
917  fResolutionHists2DMinus[part_type] = (TH2D*)fResolutionFile->Get(minus_name.c_str());
918  }
919  }
920 }
921 
923  for (size_t i = 0; i < fParticleTypes.size(); ++i) {
924  std::string part_type = fParticleTypes[i];
925  if (part_type == "Muons" || part_type == "Electrons") {
926  fPDFs[part_type] = (THnSparseD*)fInputFile->Get("Pions");
927  }
928  else {
929  fPDFs[part_type] = (THnSparseD*)fInputFile->Get(part_type.c_str());
930  }
931 
932  //Also get the resolutions
933  std::string res_name = "";
934  if (part_type == "Muons") {
935  res_name = "hPionsRes";
936  }
937  else {
938  res_name = "h" + part_type + "Res";
939  }
940 
941  fResolutionHists[part_type] = (TH1D*)fResolutionFile->Get(res_name.c_str());
942 
943  res_name += "2D";
944  fResolutionHists2D[part_type] = (TH2D*)fResolutionFile->Get(res_name.c_str());
945 
946  if (fDoWeights) {
947  std::string plus_name = res_name + "Plus";
948  fResolutionHists2DPlus[part_type] = (TH2D*)fResolutionFile->Get(plus_name.c_str());
949 
950  std::string minus_name = res_name + "Minus";
951  fResolutionHists2DMinus[part_type] = (TH2D*)fResolutionFile->Get(minus_name.c_str());
952  }
953  }
954 }
955 
957  int pdg = fRandPDG[fCurrentEvent];
958 
959  TH2D * plus_map = fResolutionHists2DPlus[fPDGToName[pdg]];
960  TH2D * minus_map = fResolutionHists2DMinus[fPDGToName[pdg]];
961  int xBin = plus_map->GetXaxis()->FindBin(fRandMomentum[fCurrentEvent]);
962  int yBin = plus_map->GetYaxis()->FindBin(fUnfoldedMomentum);
963  fPlusSigmaWeight = plus_map->GetBinContent(xBin, yBin);
964  fMinusSigmaWeight = minus_map->GetBinContent(xBin, yBin);
965 }
966 
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
const FBM & GetFBM(std::string) const
std::vector< double > fRandVUpstream
std::map< std::string, int > fNameToPDG
std::map< std::string, TH2D * > fResolutionHists2D
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
Definition: MCParticle.h:257
static QCString result
PDSPDataDrivenBeam & operator=(PDSPDataDrivenBeam const &)=delete
void SetOrigin(simb::Origin_t origin)
Definition: MCTruth.h:82
std::string string
Definition: nybbler.cc:12
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
Definition: TrackingTypes.h:85
std::map< std::string, TF1 * > fResolutions
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
Definition: TrackingTypes.h:58
std::vector< double > fMinima
void SetTimingTrigger(int theTrigger)
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
void GenerateBeamEvent(beam::ProtoDUNEBeamEvent &beamEvent)
TrackTrajectory::Flags_t Flags_t
Definition: Track.h:68
std::map< std::string, double > fParticleFracs
std::vector< double > fRandHUpstream
beam::FBM MakeFiberMonitor(double pos)
Particle class.
std::vector< short > active
std::map< std::string, double > fParticleNums
void SetFBMTrigger(std::string, FBM)
void SetCKov0(CKov theCKov)
def process(f, kind)
Definition: search.py:254
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
void SetMagnetCurrent(double theMagnetCurrent)
void RotateMonitorVector(TVector3 &vec)
A trajectory in space reconstructed from hits.
single particles thrown at the detector
Definition: MCTruth.h:26
def move(depos, offset)
Definition: depos.py:107
std::vector< double > fRandMomentum
p
Definition: test.py:223
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
Definition: TrackingTypes.h:55
void AddBeamTrack(recob::Track theTrack)
std::vector< std::string > fParticleTypes
void AddRecoBeamMomentum(double theMomentum)
std::map< std::string, TH1D * > fResolutionHists
std::array< short, 192 > fibers
void MakeTracks(beam::ProtoDUNEBeamEvent &beamEvent)
void Add(simb::MCParticle const &part)
Definition: MCTruth.h:80
std::vector< double > fRandVDownstream
std::map< std::string, THnSparseD * > fPDFs
void Convert(double input_point[5], std::vector< double > minima, std::vector< double > maxima, double output_point[5])
void produce(art::Event &e) override
void SetDownstreamTriggers(std::vector< size_t > theContent)
void GenerateTrueEvent(simb::MCTruth &mcTruth)
std::vector< double > fMaxima
TVector3 ConvertProfCoordinates(double x, double y, double z, double zOffset)
QTextStream & bin(QTextStream &s)
std::vector< double > fRandHDownstream
void SetUpstreamTriggers(std::vector< size_t > theContent)
std::array< short, 192 > glitch_mask
cet::LibraryManager dummy("noplugin")
std::map< int, std::string > fPDGToName
list x
Definition: train.py:276
void SetT0(std::pair< double, double > theT0)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
void SetCKov1(CKov theCKov)
double fiberData[6]
Event generator information.
Definition: MCTruth.h:32
void SetPositionAndMomentum(TLorentzVector &position, TLorentzVector &momentum)
def momentum(x1, x2, x3, scale=1.)
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
std::map< std::string, TH2D * > fResolutionHists2DPlus
void SetTOFs(std::vector< double > theContent)
PDSPDataDrivenBeam(fhicl::ParameterSet const &p)
double timeData[4]
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
void SetCalibrations(double TOFCalAA, double TOFCalBA, double TOFCalAB, double TOFCalBB)
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
std::map< std::string, TH2D * > fResolutionHists2DMinus
void SetTOFChans(std::vector< int > theContent)
QTextStream & endl(QTextStream &s)
void SetActiveTrigger(size_t theTrigger)