34 std::sort(this->track_id_map.begin(), this->track_id_map.end(), [](
const auto &
a,
const auto &
b){
return (
a.first <
b.first) ; } );
39 this->track_id_map.push_back(std::make_pair(track_id, gname));
40 generator_names.emplace(gname);
44 return static_cast<bool>(generator_names.count(gname));
50 return std::lower_bound(track_id_map.begin(), track_id_map.end(), tid,[](
const auto &
a,
const auto &
b){
return (a.first <
b) ; } )->
second;
59 private_HitLabel(pSet.
get<
art::InputTag>(
"HitLabel",
"gaushit")),
60 private_OpHitLabel(pSet.
get<
art::InputTag>(
"OpHitLabel",
"ophit")),
61 fWavLabel(pSet.
get<
art::InputTag>(
"WavLabel",
"opdigi"))
75 private_CalibrationTree = private_service_tfs->make<TTree>(
"CalibrationRecordTree",
" A TTree for storing hit and ophit values under their particles for each event in the simulation");
76 private_FlatCalibrationTree = private_service_tfs->make<TTree>(
"FlatCalibrationRecordTree",
" A TTree for storing hit and ophit values with their particles for each event in the simulation");
77 private_CalibrationRecord = private_CalibrationTree->Branch(
"event_records", &private_eventBuffer );
78 private_FlatCalibrationRecord = private_FlatCalibrationTree->Branch(
"flat_event_records", &fl,
"eve_x/D:eve_y:eve_z:eve_t:part_x:part_y:part_z:part_t:hit_charge:hit_energy:hit_time:hit_width:hit_split:ophit_pes:ophit_energy:ophit_time:ophit_width:ophit_split:hit_index/L:ophit_index:run/i:subrun:event_n:hit_wire:ophit_opchan:eve_index:part_index:eve_trackid/I:eve_pdgid:part_trackid:part_pdgid:part_iseve/O");
85 private_eventPrep.Clear();
86 private_eventBuffer.Clear();
88 this->PrepDivRec(evt);
96 auto const mcHandles = evt.
getMany<std::vector<simb::MCTruth>>();
97 std::vector< std::pair<int, std::string>> track_id_to_label;
99 for(
auto const& mcHandle : mcHandles ){
100 const std::string& sModuleLabel = mcHandle.provenance()->moduleLabel();
101 art::FindManyP<simb::MCParticle> findMCParts(mcHandle, evt,
"largeant");
102 std::vector<art::Ptr<simb::MCParticle> > mcParts = findMCParts.at(0);
104 int track_id = ptr->TrackId();
105 gf->
add(track_id, sModuleLabel);
109 std::vector<art::Ptr<recob::Hit>> hitList;
110 auto hitHandle = evt.
getHandle<std::vector<recob::Hit>>(private_HitLabel);
113 std::vector<art::Ptr<recob::OpHit>> opHitList;
114 auto opHitHandle = evt.
getHandle<std::vector<recob::OpHit>>(private_OpHitLabel);
119 private_eventBuffer.bunch_hits=
true;
120 private_eventBuffer.run=evt.
id().
run();
121 private_eventBuffer.subrun=evt.
id().
subRun();
122 private_eventBuffer.event=evt.
id().
event();
124 private_eventPrep.bunch_hits=
true;
125 private_eventPrep.run=evt.
id().
run();
126 private_eventPrep.subrun=evt.
id().
subRun();
127 private_eventPrep.event=evt.
id().
event();
130 unsigned int hitCounter=0;
131 for (
auto const&
hit : hitList){
133 if(!AddHit(clockData,
hit, hitCounter)){
134 mf::LogDebug(__FUNCTION__)<<
"Hit "<<hitCounter<<
" failed to add to the record. Is this hit caused by noise?";
139 for (
auto const&
hit : opHitList ){
141 if(!AddHit(
hit, hitCounter)){
142 mf::LogDebug(__FUNCTION__)<<
"OpHit "<<hitCounter<<
" failed to add to the record. Is this hit caused by noise?";
168 for(
auto eve : private_eventPrep.eves){
169 if(!private_eventPrep.eves.empty()){
171 for(
auto part : eve.particles){
173 int partial_hit_pos=0;
174 for(
auto partial_hit : part.partial_hits){
175 int ind = partial_hit.index;
177 if(hc_pos==private_eventPrep.hits.end()){
178 private_eventPrep.hits.emplace_back(ind);
179 if(hc_pos!=(private_eventPrep.hits.end()-1)){
180 hc_pos=private_eventPrep.hits.end()-1;
183 hc_pos->locations.emplace_back(eve_pos,part_pos,partial_hit_pos);
189 int partial_ophit_pos=0;
190 for(
auto partial_ophit : part.partial_ophits){
191 int ind = partial_ophit.index;
193 if(hc_pos==private_eventPrep.ophits.end()){
194 private_eventPrep.ophits.emplace_back(ind);
195 if(hc_pos!=(private_eventPrep.ophits.end()-1)){
196 hc_pos=private_eventPrep.ophits.end()-1;
199 hc_pos->locations.emplace_back(eve_pos,part_pos,partial_ophit_pos);
214 if( private_eventPrep.bunch_hits==
true){
215 for(
size_t eve_num=0; eve_num<private_eventPrep.eves.size(); ++eve_num ){
216 auto eve = private_eventPrep.eves.at(eve_num);
217 private_eventBuffer.eves.push_back(eve);
219 for(
size_t part_num=0; part_num<eve.particles.size(); ++part_num ){
220 auto part = eve.particles.at(part_num);
221 auto& npart = private_eventBuffer.eves.at(eve_num).particles.at(part_num);
222 npart.partial_hits.clear();
223 npart.partial_ophits.clear();
225 std::map<int64_t, CalibTreeRecord::PartialHit> bunched_hits;
226 std::map<int64_t, std::list<Double_t>> remembered_energies;
227 for(
auto partialhit : part.partial_hits){
228 auto emp_h = bunched_hits.emplace(std::make_pair(partialhit.index,partialhit));
229 std::list<Double_t>
dummy;
230 auto emp_e = remembered_energies.emplace(std::make_pair(partialhit.index, dummy));
231 if(emp_h.second==
true){
232 emp_e.first->second.emplace_back(partialhit.energy);
233 emp_h.first->second=partialhit;
235 if(emp_h.first->second.time != partialhit.time){
throw cet::exception(
"CalibrationTreeBuilder")<<
"Buncher failed. Trying to merge two of the same hit at different times?\n";}
236 emp_e.first->second.emplace_back(partialhit.energy);
237 emp_h.first->second.charge+=partialhit.charge;
238 emp_h.first->second.split+=partialhit.split;
239 emp_h.first->second.num_electrons+=partialhit.num_electrons;
241 emp_e.first->second.unique();
243 for(
auto en : emp_e.first->second){
246 emp_h.first->second.energy=
energy;
248 remembered_energies.clear();
249 std::map<int64_t, CalibTreeRecord::PartialOpHit> bunched_ophits;
250 for(
auto partialop : part.partial_ophits){
251 auto emp_o = bunched_ophits.emplace(std::make_pair(partialop.index,partialop));
252 std::list<Double_t>
dummy;
253 auto emp_e = remembered_energies.emplace(std::make_pair(partialop.index, dummy));
254 if(emp_o.second==
true){
255 emp_e.first->second.emplace_back(partialop.energy);
256 emp_o.first->second=partialop;
258 if(emp_o.first->second.time != partialop.time){
throw cet::exception(
"CalibrationTreeBuilder")<<
"Buncher failed. Trying to merge two of the same ophit at different times?\n";}
259 emp_e.first->second.emplace_back(partialop.energy);
260 emp_o.first->second.pes+=partialop.pes;
261 emp_o.first->second.split+=partialop.split;
262 emp_o.first->second.num_photons+=partialop.num_photons;
265 emp_e.first->second.unique();
267 for(
auto en : emp_e.first->second ){
270 emp_o.first->second.energy=
energy;
272 for(
auto entry : bunched_hits){
273 npart.partial_hits.push_back(
entry.second);
275 for(
auto entry : bunched_ophits){
278 npart.partial_ophits.push_back(
entry.second);
289 fl.run = private_eventBuffer.run;
290 fl.subrun = private_eventBuffer.subrun;
291 fl.event_n = private_eventBuffer.event;
292 for(
auto eve : private_eventBuffer.eves){
293 if(!private_eventBuffer.eves.empty()){
294 fl.eve_x = eve.x_pos;
295 fl.eve_y = eve.y_pos;
296 fl.eve_z = eve.z_pos;
297 fl.eve_t = eve.t_pos;
298 fl.eve_trackid = eve.trackId;
299 fl.eve_pdgid = eve.pdgid;
300 fl.eve_index = eve_pos;
302 for(
auto part : eve.particles){
303 fl.part_x = part.x_pos;
304 fl.part_y = part.y_pos;
305 fl.part_z = part.z_pos;
306 fl.part_t = part.t_pos;
307 fl.part_trackid = part.trackId;
308 fl.part_pdgid = part.pdgid;
309 fl.part_iseve = part.isEve;
310 fl.part_index = part_pos;
313 fl.ophit_energy = 0.0;
315 fl.ophit_width = 0.0;
316 fl.ophit_split = 0.0;
317 fl.ophit_index = 0.0;
318 fl.ophit_opchan = 0.0;
319 int partial_hit_pos=0;
320 for(
auto partial_hit : part.partial_hits){
322 fl.hit_charge = partial_hit.charge;
323 fl.hit_energy = partial_hit.energy;
324 fl.hit_time = partial_hit.time;
325 fl.hit_width = partial_hit.width;
326 fl.hit_split = partial_hit.split;
327 fl.hit_index = partial_hit.index;
328 fl.hit_wire = partial_hit.wire;
329 private_FlatCalibrationTree->Fill();
331 int ind = partial_hit.index;
333 if(hc_pos==private_eventBuffer.hits.end()){
334 private_eventBuffer.hits.emplace_back(ind);
335 if(hc_pos!=(private_eventBuffer.hits.end()-1)){
336 hc_pos=private_eventBuffer.hits.end()-1;
339 hc_pos->locations.emplace_back(eve_pos,part_pos,partial_hit_pos);
352 int partial_ophit_pos=0;
353 for(
auto partial_ophit : part.partial_ophits){
354 int ind = partial_ophit.index;
355 fl.ophit_pes = partial_ophit.pes;
356 fl.ophit_energy = partial_ophit.energy;
357 fl.ophit_time = partial_ophit.time;
358 fl.ophit_width = partial_ophit.width;
359 fl.ophit_split = partial_ophit.split;
360 fl.ophit_index = partial_ophit.index;
361 fl.ophit_opchan = partial_ophit.opchan;
362 private_FlatCalibrationTree->Fill();
366 if(hc_pos==private_eventBuffer.ophits.end()){
367 private_eventBuffer.ophits.emplace_back(ind);
368 if(hc_pos!=(private_eventBuffer.ophits.end()-1)){
369 hc_pos=private_eventBuffer.ophits.end()-1;
372 hc_pos->locations.emplace_back(eve_pos,part_pos,partial_ophit_pos);
384 }
else{ private_eventBuffer=private_eventPrep;}
387 private_CalibrationTree->Fill();
394 void CalibrationTreeBuilder::endJob(){
406 std::vector<const sim::IDE*> ides_ps = BTS->HitToSimIDEs_Ps(clockData, hit);
407 std::vector<std::pair<int, CalibTreeRecord::PartialHit>> track_partials;
409 if(ides_ps.empty()){
return false;}
410 for(
auto ide_p : ides_ps){
411 int track_id = ide_p->trackID;
413 total_charge += ide_p->numElectrons;
423 track_partials.push_back(std::make_pair(track_id, tmp));
425 for(
auto track_partial : track_partials){
426 track_partial.second.split = track_partial.second.num_electrons /
total_charge;
427 track_partial.second.charge = hit->
Integral()*track_partial.second.split;
429 const simb::MCParticle* part = PIS->TrackIdToParticle_P(track_partial.first);
432 part_marker.first->partial_hits.push_back(track_partial.second);
434 mf::LogDebug(__FUNCTION__)<<
"This partialhit is being added to the record with charge "<<track_partial.second.charge<<
"\n";
443 const std::vector< sim::SDP> sdps = this->OpHitToChannelWeightedSimSDPs(hit);
447 std::vector<std::pair<int, CalibTreeRecord::PartialOpHit>> track_partials;
449 if(sdps.empty()){
return false;}
450 for(
auto sdp : sdps){
451 int track_id = sdp.trackID;
453 total_charge += sdp.numPhotons;
464 track_partials.push_back(std::make_pair(track_id, tmp));
466 for(
auto track_partial : track_partials){
467 track_partial.second.split = track_partial.second.num_photons /
total_charge;
468 track_partial.second.pes = hit->
PE()*track_partial.second.split;
470 const simb::MCParticle* part = PIS->TrackIdToParticle_P(track_partial.first);
473 part_marker.first->partial_ophits.push_back(track_partial.second);
488 int track_id = part->
TrackId();
489 int eve_id = PIS->TrackIdToEveTrackId(part->
TrackId());
495 if(part_ptr!=eve_marker.first->particles.end()){
496 return std::make_pair(part_ptr,
false);
499 tmpRec.
isEve = (track_id==eve_id)?
true:
false;
504 mf::LogDebug(__FUNCTION__)<<
"The particle now enetered into the particle record has PDGID "<<part->
PdgCode()<<
"\n";
509 eve_marker.first->particles.push_back(tmpRec);
510 if(part_ptr == (eve_marker.first->particles.end()-1) ){
511 return std::make_pair(part_ptr,
true);
513 return std::make_pair(eve_marker.first->particles.end()-1,
true);
519 std::vector<CalibTreeRecord::EveRecord>& eves = private_eventPrep.eves;
522 if( eve_ptr != eves.end() ){
return std::make_pair(eve_ptr,
false); }
else{
527 mf::LogDebug(__FUNCTION__)<<
"The eve now enetered into the particle record has PDGID "<<eve->
PdgCode()<<
"\n";
532 eves.push_back(tmpRec);
533 if(eve_ptr == (eves.end()-1) ){
534 return std::make_pair(eve_ptr,
true);
536 return std::make_pair(eves.end()-1,
true);
548 for(
size_t detnum = 0; detnum < priv_DivRecs.size(); ++detnum){
549 if(priv_DivRecs.at(detnum)->OpDetNum() == opDetNum)
550 opDet = priv_DivRecs.at(detnum);
554 throw cet::exception(
"CalibTreeBuilder") <<
"No sim:: OpDetDivRec corresponding " 555 <<
"to opDetNum: " << opDetNum <<
"\n";
564 const std::vector< sim::SDP > CalibrationTreeBuilder::OpHitToChannelWeightedSimSDPs(
art::Ptr<recob::OpHit> const& opHit_P)
const 566 const double fDelay = PBS->GetDelay();
567 std::vector< sim::SDP > retVec;
568 double fPeakTime = opHit_P->
PeakTime();
569 double fWidth = opHit_P->
Width();
576 if(start_time > end_time){
throw;}
581 fBTR = PBS->FindOpDetBTR(fDet);
584 std::vector<sim::SDP> ret;
590 const std::vector<std::pair<double, std::vector<sim::SDP>> >& timeSDPMap
595 std::vector<const std::pair<double, std::vector<sim::SDP>>*> timePDclockSDPMap_SortedPointers;
596 std::vector<const sim::OpDet_Time_Chans*> div_rec_SortedPointers;
597 for (
auto& pair : timeSDPMap ){ timePDclockSDPMap_SortedPointers.push_back(&pair); }
598 auto pairSort = [](
auto&
a,
auto&
b) {
return a->first <
b->first ; } ;
599 if( !std::is_sorted( timePDclockSDPMap_SortedPointers.begin(), timePDclockSDPMap_SortedPointers.end(), pairSort)){
600 std::sort(timePDclockSDPMap_SortedPointers.begin(), timePDclockSDPMap_SortedPointers.end(), pairSort);
604 std::vector<sim::SDP> dummyVec;
605 std::pair<double, std::vector<sim::SDP>> start_timePair = std::make_pair(start_time, dummyVec);
606 std::pair<double, std::vector<sim::SDP>> end_timePair = std::make_pair(end_time, dummyVec);
607 auto start_timePair_P = &start_timePair;
608 auto end_timePair_P = &end_timePair;
611 auto map_pdsdp_itr = std::lower_bound(timePDclockSDPMap_SortedPointers.begin(), timePDclockSDPMap_SortedPointers.end(), start_timePair_P, pairSort);
613 auto map_pdsdp_last = std::upper_bound(map_pdsdp_itr, timePDclockSDPMap_SortedPointers.end(), end_timePair_P, pairSort);
617 for(
auto& sdp_time_pair = map_pdsdp_itr; sdp_time_pair != map_pdsdp_last; ++sdp_time_pair){
619 auto time=(*sdp_time_pair)->first;
620 for(
auto& sdp : (*sdp_time_pair)->second){
624 auto time_divr=time_divr_pair.first;
625 auto time_divr_found=time_divr_pair.second;
627 if( time_divr_found && time_divr->time ==
time){
634 retVec.emplace_back(tmp);
656 auto const& divrecHandle = evt.
getValidHandle <std::vector<sim::OpDetDivRec>>(fWavLabel);
657 if(divrecHandle.failedToGet()){
662 if (!std::is_sorted(priv_DivRecs.begin(), priv_DivRecs.end(), compareDivReclambda))
663 std::sort(priv_DivRecs.begin(), priv_DivRecs.end(), compareDivReclambda);
def analyze(root, level, gtrees, gbranches, doprint)
const TLorentzVector & Position(const int i=0) const
std::set< std::string > generator_names
CalibrationTreeBuilder(fhicl::ParameterSet const &pSet)
Handle< PROD > getHandle(SelectorBase const &) const
Bool_t is_collection_wire
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
bool has_gen(std::string gname)
unsigned int OpDetFromOpChannel(int opChannel) const
Convert unique channel to detector number.
#define DEFINE_ART_MODULE(klass)
void add(const int &track_id, const std::string &gname)
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const
double timePDclock_t
Type for iTimePDclock tick used in the interface.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition of data types for geometry description.
Detector simulation of raw signals on wires.
std::pair< int, std::string > track_id_to_string
float PeakTime() const
Time of the signal peak, in tick units.
Contains all timing reference information for the detector.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
float energy
energy deposited by ionization
const TLorentzVector & Momentum(const int i=0) const
std::string get_gen(int tid)
cet::LibraryManager dummy("noplugin")
EventNumber_t event() const
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
std::vector< track_id_to_string > track_id_map
auto const & get(AssnsNode< L, R, D > const &r)
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
second_as<> second
Type of time stored in seconds, in double precision.
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
const TLorentzVector & EndMomentum() const
SubRunNumber_t subRun() const
timePDclockSDPs_t const & timePDclockSDPsMap() const
Returns all the deposited energy information as stored.
cet::coded_exception< error, detail::translate > exception
Signal from collection planes.
std::pair< OpDetDivRec::Time_Chans_t::const_iterator, bool > FindClosestTimeChan(OpDet_Time_Chans::stored_time_t pdTime) const