HorizontalMuonTrigger_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: HorizontalMuonTrigger
3 // Plugin Type: filter (art v1_17_06)
4 // File: HorizontalMuonTrigger_module.cc
5 //
6 // Generated at Fri Dec 8 17:11:54 2017 by Connor Johnson using cetskelgen
7 // from cetlib version v1_15_03.
8 ////////////////////////////////////////////////////////////////////////
9 
18 #include "fhiclcpp/ParameterSet.h"
20 
21 #include <memory>
22 
23 // // ROOT Includes
24 #include <TTree.h>
25 #include <TVector3.h>
26 
27 // #include "DDTBaseDataProducts/Track.h"
36 
37 const uint16_t TOTAL_FD_PLANES = 896;
38 
39 namespace novaddt {
40 
42  public:
44  // The compiler-generated destructor is fine for non-base
45  // classes without bare pointers or other resource use.
46 
47  // Plugins should not be copied or assigned.
52 
53  // Required functions.
54  virtual bool filter(art::Event & e) override;
55 
56  // Selected optional functions
57  void endJob() override;
58 
59  private:
60  // FHICL Parameters
63  int16_t fMaxMissing;
64  double fMaxTime;
66  unsigned _prescale;
69 
70  // Trigger counts and prescaling
71  unsigned _trigger_counts = 0;
72  unsigned _after_prescale = 0;
73  unsigned _multi_horz_muon= 0;
74  unsigned _kept_multimuons= 0;
75 
76  // Module variables for endJob
77  int nEvents = 0;
78  int nTracks = 0;
79  int n3DTracks = 0;
80 
81  // Helper functions. Perhaps make public/protected so logic can be reused.
82  bool FrontBackPlanesHits (const std::vector<uint16_t> & missedFrontPlanes, const std::vector<uint16_t> & missedBackPlaness);
83  bool MissingPlanesInBounds(const std::vector<uint16_t> & allMissingPlanes);
84  bool TimingInBounds (const unsigned long long & minTime, const unsigned long long & maxTime);
85  bool IsHorzMuonTrack (const novaddt::HitList & track, unsigned long long & minTime, unsigned long long & maxTime);
86  };
87 
88  // Constructor from FHICL file
90  :
91  fNumFrontBackPlanes( p.get<uint16_t> ("numFrontBackPlanes")),
92  fMinFrontBackPlanes( p.get<int16_t> ("minFrontBackPlanes")),
93  fMaxMissing( p.get<int16_t> ("maxMissingPlanes")),
94  fMaxTime( p.get<double> ("maxTime")),
95  fTracksTag( p.get<std::string> ("tracksTag")),
96  _prescale( p.get<unsigned> ("prescale")),
97  fPreTriggerOffset( p.get<unsigned> ("preTriggerOffset")),
98  fTriggerDuration( p.get<int16_t> ("triggerDuration"))
99 
100  {
101  produces<std::vector<novaddt::TriggerDecision> >();
102  }
103 
104  // Filter rules, using IsHorzMuonTrack() decision function.
106  {
107  nEvents++;
108  // Holder for trigger decisions
109  std::unique_ptr<std::vector<TriggerDecision>> trigger_decisions(new std::vector<TriggerDecision>);
110 
111  // Grab all Track objects from event
113  // art::Handle<novaddt::HitList> eventHits;
114  e.getByLabel(fTracksTag, eventTracks);
115  if (eventTracks.failedToGet()){
116  mf::LogError("HorizontalMuonTrigger") << "Error: " << eventTracks.whyFailed()->what() << std::endl;
117  e.put(std::move(trigger_decisions));
118  return false;
119  }
120 
121  bool result = false;
122  art::FindOneP<novaddt::Track3D> houghTrack(eventTracks, e, fTracksTag);
123 
124  // Loop through tracks. Only one needs to pass to accept the event.
125  for(unsigned long trackIndex = 0; trackIndex < eventTracks->size(); trackIndex++){
126  nTracks++;
127  // Look at each track HitList, set up corresponding Track3D
128  novaddt::HitList trackHits = eventTracks->at(trackIndex);
129  art::Ptr<novaddt::Track3D> thisTrack3d = houghTrack.at(trackIndex);
130  if (thisTrack3d->Is3D()){
131  n3DTracks++;
132 
133  // Holders for track time (passed by reference)
134  unsigned long long minTime = ULLONG_MAX - 1;
135  unsigned long long maxTime = 0;
136  if (IsHorzMuonTrack(trackHits, minTime, maxTime)){
137  // Only trigger once per event.
138  _trigger_counts++;
139 
140  // Count how many multi-muon events we see.
141  if (result)
143 
144  // Decide whether to keep the trigger, or prescale it away
145  if(_trigger_counts%_prescale == 0){
146  if(result)
148  result = true;
149  _after_prescale++;
150 
151  // Define the trigger window. This has a t0 of the earliest hit in the track minus some offset (can be 0), with the requirement that minTime - offset > 0
152  unsigned long long triggerT0 = (minTime > fPreTriggerOffset) ? minTime - fPreTriggerOffset : 0;
153 
154  // Define the minimum duration as T0 to the last hit in the track
155  unsigned long long minTriggerDuration = maxTime - triggerT0;
156 
157  // If a duratation is provided, use it UNLESS it wouldn't capture the end of the track. Otherwise use the minimum duration that will
158  unsigned long long triggerDuration = (fTriggerDuration > 0 && ((uint32_t) fTriggerDuration) > minTriggerDuration) ? fTriggerDuration : minTriggerDuration;
159 
160  trigger_decisions->emplace_back(triggerT0, triggerDuration, daqdataformats::trigID::TRIG_ID_DATA_H_MU, _prescale);
161  }
162  }
163  }
164  }
165  e.put(std::move(trigger_decisions));
166  return result;
167  }
168 
169  bool HorizontalMuonTrigger::FrontBackPlanesHits(const std::vector<uint16_t> & missedFrontPlanes, const std::vector<uint16_t> & missedBackPlanes){
170  // If there is a minimum number of acceptable planes (numFound = Total - numRemaining : numFound >= minFound)
171  if (fMinFrontBackPlanes > 0)
172  return ((int16_t) (fNumFrontBackPlanes - missedFrontPlanes.size()) >= fMinFrontBackPlanes && (int16_t) (fNumFrontBackPlanes - missedBackPlanes.size()) >= fMinFrontBackPlanes);
173 
174  // If no minimum provided, they all must be found.
175  return (missedFrontPlanes.empty() && missedBackPlanes.empty());
176  }
177 
178  bool HorizontalMuonTrigger::MissingPlanesInBounds(const std::vector<uint16_t> & allMissingPlanes){
179  if (fMaxMissing < 0) return true;
180  return ((int16_t) allMissingPlanes.size() <= fMaxMissing);
181  }
182 
183  bool HorizontalMuonTrigger::TimingInBounds(const unsigned long long & minTime, const unsigned long long & maxTime){
184  if (fMaxTime < 0) return true;
185  return (maxTime - minTime <= fMaxTime);
186  }
187 
188  bool HorizontalMuonTrigger::IsHorzMuonTrack(const novaddt::HitList & track, unsigned long long & minTime, unsigned long long & maxTime){
189  // Make list of planes which must have a hit in them.
190  // Different sets for front and back planes, in case requirements differ between them
191  std::vector<uint16_t> RequiredFrontPlanes, RequiredBackPlanes, AllPlanes;
192  for (uint16_t i = 0; i < fNumFrontBackPlanes; i++)
193  RequiredFrontPlanes.push_back(i);
194  for (uint16_t i = 0; i < fNumFrontBackPlanes; i++)
195  RequiredBackPlanes.push_back(TOTAL_FD_PLANES - i - 1);
196  for (uint16_t i = 0; i < TOTAL_FD_PLANES; i++)
197  AllPlanes.push_back(i);
198 
199  // Loop through hits, keeping track of Planes and timing.
200  for (const novaddt::DAQHit & hit : track){
201  if (hit.TDC().val > maxTime)
202  maxTime = hit.TDC().val;
203  if (hit.TDC().val < minTime)
204  minTime = hit.TDC().val;
205 
206  // If the plane matches any required plane, remove it from the list to search through.
207  RequiredFrontPlanes.erase(
208  std::remove(RequiredFrontPlanes.begin(), RequiredFrontPlanes.end(), hit.Plane().val),
209  RequiredFrontPlanes.end());
210 
211  RequiredBackPlanes.erase(
212  std::remove(RequiredBackPlanes.begin(), RequiredBackPlanes.end(), hit.Plane().val),
213  RequiredBackPlanes.end());
214 
215  AllPlanes.erase(
216  std::remove(AllPlanes.begin(), AllPlanes.end(), hit.Plane().val),
217  AllPlanes.end());
218  }
219 
220  bool result = TimingInBounds(minTime, maxTime) && MissingPlanesInBounds(AllPlanes) && FrontBackPlanesHits(RequiredFrontPlanes, RequiredBackPlanes);
221 
222  return result;
223  }
224 
226  std::cout << "=== novaddt::HorizontalMuonTrigger endJob" << std::endl;
227  std::cout << "\tNumber of Events: " << nEvents << std::endl;
228  std::cout << "\tNumber of Tracks: " << nTracks << std::endl;
229  std::cout << "\tNumber of 3D tracks: " << n3DTracks << std::endl;
230  std::cout << "\tNumber of Triggers: " << _trigger_counts << std::endl;
231  std::cout << "\tNumber triggers after prescale: " << _after_prescale << std::endl;
232  std::cout << "\tNumber of Multi-tracks seen: " << _multi_horz_muon << std::endl;
233  std::cout << "\tNumber of Multi-tracks kept: " << _kept_multimuons << std::endl;
234  }
235 
237 
238 } // novaddt namespace
bool TimingInBounds(const unsigned long long &minTime, const unsigned long long &maxTime)
const uint16_t TOTAL_FD_PLANES
HorizontalMuonTrigger(fhicl::ParameterSet const &p)
bool MissingPlanesInBounds(const std::vector< uint16_t > &allMissingPlanes)
std::vector< DAQHit > HitList
Definition: HitList.h:15
const char * p
Definition: xmltok.h:285
Definition: event.h:19
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
DEFINE_ART_MODULE(TestTMapFile)
bool IsHorzMuonTrack(const novaddt::HitList &track, unsigned long long &minTime, unsigned long long &maxTime)
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
bool const & Is3D() const
Definition: Track3D.h:43
OStream cout
Definition: OStream.cxx:6
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
Definition: structs.h:12
std::shared_ptr< art::Exception const > whyFailed() const
Definition: Handle.h:219
Float_t e
Definition: plot.C:35
HorizontalMuonTrigger & operator=(HorizontalMuonTrigger const &)=delete
virtual bool filter(art::Event &e) override
Definition: fwd.h:28
bool FrontBackPlanesHits(const std::vector< uint16_t > &missedFrontPlanes, const std::vector< uint16_t > &missedBackPlaness)
bool failedToGet() const
Definition: Handle.h:196
enum BeamMode string