141141#include " sbnanaobj/StandardRecord/Flat/FlatRecord.h"
142142#include " lardataobj/RawData/ExternalTrigger.h"
143143#include " lardataobj/RawData/TriggerData.h"
144+ #include " lardataobj/Simulation/AuxDetSimChannel.h"
144145
145146// // CAFMaker
146147#include " sbncode/CAFMaker/AssociationUtil.h"
@@ -288,6 +289,11 @@ class CAFMaker : public art::EDProducer {
288289 std::vector<std::vector<geo::BoxBoundedGeo>> fTPCVolumes ;
289290 std::vector<geo::BoxBoundedGeo> fActiveVolumes ;
290291
292+ // CRT geometry info
293+ //
294+ // ICARUS
295+ std::map<std::pair<int , int >, int > fFEBChannel2AuxDetID ;
296+
291297 // random number generator for fake reco
292298 CLHEP::HepRandomEngine& fFakeRecoRandomEngine ;
293299
@@ -316,6 +322,7 @@ class CAFMaker : public art::EDProducer {
316322 double GetBlindPOTScale () const ;
317323
318324 void InitVolumes (); // /< Initialize volumes from Gemotry service
325+ void InitCRTMapping (); // /< Initialize CRT mapping
319326
320327 void FixPMTReferenceTimes (StandardRecord &rec, double PMT_reference_time);
321328 void FixCRTReferenceTimes (StandardRecord &rec, double CRTT0_reference_time, double CRTT1_reference_time);
@@ -424,6 +431,9 @@ class CAFMaker : public art::EDProducer {
424431 // setup volume definitions
425432 InitVolumes ();
426433
434+ // setup CRT mapping
435+ InitCRTMapping ();
436+
427437 fSaveGENIEEventRecord = fParams .SaveGENIEEventRecord ();
428438
429439}
@@ -597,6 +607,36 @@ void CAFMaker::FixCRTReferenceTimes(StandardRecord &rec, double CRTT0_reference_
597607
598608}
599609
610+ void CAFMaker::InitCRTMapping () {
611+
612+ // ICARUS
613+ cet::search_path searchPath (" FW_SEARCH_PATH" );
614+ std::string fullFileName;
615+ searchPath.find_file (" feb_map.txt" ,fullFileName);
616+ std::ifstream fin;
617+ fin.open (fullFileName, std::ios::in);
618+
619+ if (fin.good ()) {
620+ std::string line;
621+
622+ while (std::getline (fin,line)) {
623+ std::vector<std::string> row;
624+ std::string word;
625+
626+ std::stringstream s (line);
627+ while (std::getline (s, word, ' ,' )) {
628+ row.push_back (word);
629+ }
630+ int auxDetID = std::stoi (row[0 ]); // auxDetID
631+ int mac5 = std::stoi (row[1 ]); // FEB ID
632+ int chan = std::stoi (row[2 ]); // FEB channel
633+ fFEBChannel2AuxDetID [std::make_pair (mac5, chan)] = auxDetID;
634+ }
635+
636+ fin.close ();
637+ }
638+ }
639+
600640void CAFMaker::InitVolumes () {
601641 const geo::GeometryCore *geometry = lar::providerFrom<geo::Geometry>();
602642
@@ -1600,7 +1640,7 @@ void CAFMaker::produce(art::Event& evt) noexcept {
16001640 // #######################################################
16011641 // Fill detector & reco
16021642 // #######################################################
1603-
1643+
16041644 // Beam gate and Trigger info
16051645 art::Handle<sbn::ExtraTriggerInfo> extratrig_handle;
16061646 GetByLabelStrict (evt, fParams .TriggerLabel ().encode (), extratrig_handle);
@@ -1612,16 +1652,40 @@ void CAFMaker::produce(art::Event& evt) noexcept {
16121652 if (!isRealData)
16131653 GetByLabelStrict (evt, fParams .UnshiftedTriggerLabel ().encode (), unshifted_trig_handle);
16141654
1655+ // Trigger emulation handles
1656+ art::Handle<std::vector<int >> monpulses_handle;
1657+ GetByLabelStrict (evt, fParams .MonPulsesTriggerLabel ().encode (), monpulses_handle);
1658+
1659+ art::Handle<std::vector<int >> monpulse_sizes_handle;
1660+ GetByLabelStrict (evt, fParams .MonPulseSizesTriggerLabel ().encode (), monpulse_sizes_handle);
1661+
1662+ art::Handle<int > pairs_handle;
1663+ GetByLabelStrict (evt, fParams .PairsTriggerLabel ().encode (), pairs_handle);
1664+
1665+ art::Handle<bool > trigemu_handle;
1666+ GetByLabelStrict (evt, fParams .EmulatedTriggerLabel ().encode (), trigemu_handle);
1667+
1668+ // Check trigger handles
16151669 const bool isValidTrigger = extratrig_handle.isValid () && trig_handle.isValid () && trig_handle->size () == 1 ;
16161670 const bool isValidUnshiftedTrigger = unshifted_trig_handle.isValid () && unshifted_trig_handle->size () == 1 ;
1671+ const bool isValidEmulationTrigger = monpulses_handle.isValid () && monpulse_sizes_handle.isValid () && pairs_handle.isValid () && trigemu_handle.isValid ();
16171672
16181673 const double triggerShift = (isValidUnshiftedTrigger && isValidTrigger)?
16191674 unshifted_trig_handle->at (0 ).TriggerTime () - trig_handle->at (0 ).TriggerTime () : 0 .;
16201675
1676+ // Fill local ExtraTriggerInfo struct
1677+ sbn::ExtraTriggerInfo extratrig;
1678+ if (extratrig_handle.isValid ()) extratrig = *extratrig_handle;
1679+
16211680 caf::SRTrigger srtrigger;
16221681 if (isValidTrigger) {
16231682 FillTrigger (*extratrig_handle, trig_handle->at (0 ), srtrigger, triggerShift);
16241683 }
1684+ // Fill trigger emulation information
1685+ if (isValidEmulationTrigger) {
1686+ FillTriggerEmulation (monpulses_handle, monpulse_sizes_handle, pairs_handle, trigemu_handle, srtrigger);
1687+ }
1688+
16251689 // If not real data, fill in enough of the SRTrigger to make (e.g.) the CRT
16261690 // time referencing work. TODO: add more stuff to a "MC"-Trigger?
16271691 // No longer needed with incorporation of trigger emulation in the MC.
@@ -1652,16 +1716,36 @@ void CAFMaker::produce(art::Event& evt) noexcept {
16521716 caf::SRSBNDFrameShiftInfo srsbndframeshiftinfo;
16531717 caf::SRSBNDTimingInfo srsbndtiminginfo;
16541718
1719+ // Mapping of (feb, channel) to truth information (AuxDetSimChannel) -- filled for ICARUS
1720+ std::map<std::pair<int , int >, sim::AuxDetSimChannel> crtsimchanmap;
1721+
16551722 if (fDet == kICARUS )
16561723 {
16571724 art::Handle<std::vector<sbn::crt::CRTHit>> crthits_handle;
16581725 GetByLabelStrict (evt, fParams .CRTHitLabel (), crthits_handle);
1726+
1727+ art::Handle<std::vector<sim::AuxDetSimChannel>> auxdetsimchan_handle;
1728+ GetByLabelStrict (evt, fParams .CRTSimChanLabel (), auxdetsimchan_handle);
1729+
16591730 // fill into event
16601731 if (crthits_handle.isValid ()) {
16611732 const std::vector<sbn::crt::CRTHit> &crthits = *crthits_handle;
1733+
1734+ std::vector<sim::AuxDetSimChannel> empty;
1735+ const std::vector<sim::AuxDetSimChannel> &crtsimchanvec = (auxdetsimchan_handle.isValid ()) ? *auxdetsimchan_handle : empty;
1736+ // Turn the AuxDetSimChannel's into a map that can be looked up from a CRT Hit
1737+ for (const sim::AuxDetSimChannel &crtsimchan: crtsimchanvec) {
1738+ for (auto const &map_pair: fFEBChannel2AuxDetID ) {
1739+ if (map_pair.second == (int )crtsimchan.AuxDetID ()) {
1740+ crtsimchanmap[map_pair.first ] = crtsimchan;
1741+ break ;
1742+ }
1743+ }
1744+ }
1745+
16621746 for (unsigned i = 0 ; i < crthits.size (); i++) {
16631747 srcrthits.emplace_back ();
1664- FillCRTHit (crthits[i], fParams .CRTUseTS0 (), CRT_T0_reference_time, CRT_T1_reference_time, srcrthits.back ());
1748+ FillCRTHit (crthits[i], fParams .CRTUseTS0 (), CRT_T0_reference_time, CRT_T1_reference_time, crtsimchanmap, srcrthits.back ());
16651749 }
16661750 }
16671751
@@ -2359,7 +2443,7 @@ void CAFMaker::produce(art::Event& evt) noexcept {
23592443 crthittagginginfo = fmCRTHitMatchInfo.at (iPart);
23602444 }
23612445
2362- FillTrackCRTHit (fmCRTHitMatch.at (iPart), crthitmatch, crthittagginginfo, fParams .CRTUseTS0 (), CRT_T0_reference_time, CRT_T1_reference_time, trk);
2446+ FillTrackCRTHit (fmCRTHitMatch.at (iPart), crthitmatch, crthittagginginfo, fParams .CRTUseTS0 (), CRT_T0_reference_time, CRT_T1_reference_time, crtsimchanmap, trk);
23632447 }
23642448 // NOTE: SEE TODO AT fmCRTTrackMatch
23652449 if (fmCRTTrackMatch.isValid () && fDet == kICARUS ) {
0 commit comments