1717#include " fhiclcpp/ParameterSet.h"
1818#include " messagefacility/MessageLogger/MessageLogger.h"
1919
20+ #include " artdaq-core/Data/RawEvent.hh"
21+
2022#include " Math/GenVector/PositionVector2D.h"
2123#include " Math/GenVector/DisplacementVector2D.h"
2224
2325#include " lardata/Utilities/AssociationUtil.h"
26+ #include " sbndcode/Timing/SBNDRawTimingObj.h"
2427
28+ #include " sbnobj/SBND/Timing/DAQTimestamp.hh"
2529#include " sbnobj/SBND/CRT/CRTEnums.hh"
2630#include " sbnobj/SBND/CRT/CRTCluster.hh"
2731#include " sbnobj/SBND/CRT/CRTSpacePoint.hh"
3236#include " sbndcode/CRT/CRTUtils/CRTCommonUtils.h"
3337#include " lardata/Utilities/AssociationUtil.h"
3438
39+ #include " art_root_io/TFileService.h"
40+ #include " TNtuple.h"
41+
3542#include " TMath.h"
3643
3744#include < memory>
@@ -52,6 +59,8 @@ class sbnd::crt::CRTVetoProducer : public art::EDProducer {
5259 CRTVetoProducer& operator =(CRTVetoProducer&&) = delete ;
5360
5461 void produce (art::Event& e) override ;
62+ // void beginJob() override;
63+ bool SPECTDCReference (art::Event& e, const uint64_t &raw_ts, uint64_t &ref_time, const uint32_t channel);
5564
5665 // Functions to check if a point is in a specific Tagger
5766 bool inSouth (const CRTTagger t);
@@ -68,10 +77,27 @@ class sbnd::crt::CRTVetoProducer : public art::EDProducer {
6877 double fWindowEnd ;
6978 std::string fCRTClusterModuleLabel ;
7079 std::string fCRTSpacePointModuleLabel ;
80+ std::string fCRTTimingReferenceInfoLabel ;
81+ std::string fSPECTDCModuleLabel ;
7182 bool fIsData ;
83+
84+ // raw timestamp correction variables
85+ std::string fDAQHeaderModuleLabel ;
86+ std::string fDAQHeaderInstanceLabel ;
87+ uint32_t fRawTSCorrection ;
88+ uint32_t fMaxAllowedRefTimeDiff ;
7289
7390 std::vector<int > fVetoSpacePointIndices ;
7491 std::vector<art::Ptr<CRTSpacePoint>> fVetoSpacePoints ;
92+
93+ std::vector<double > fVetoSouthTimes ;
94+
95+ // store South Wall Top Hat for debugging
96+ unsigned int fEventID ;
97+ unsigned int fRun ;
98+ unsigned int fSubRun ;
99+ // TNtuple *fSouth_tree;
100+
75101};
76102
77103
@@ -82,7 +108,13 @@ sbnd::crt::CRTVetoProducer::CRTVetoProducer(fhicl::ParameterSet const& p)
82108 , fWindowEnd (p.get<double >(" WindowEnd" ))
83109 , fCRTClusterModuleLabel (p.get<std::string>(" CRTClusterModuleLabel" ))
84110 , fCRTSpacePointModuleLabel (p.get<std::string>(" CRTSpacePointModuleLabel" ))
111+ , fCRTTimingReferenceInfoLabel (p.get<std::string>(" CRTTimingReferenceInfoLabel" ))
112+ , fSPECTDCModuleLabel (p.get<std::string>(" SPECTDCModuleLabel" ))
85113 , fIsData (p.get<bool >(" IsData" ))
114+ , fDAQHeaderModuleLabel (p.get<std::string>(" DAQHeaderModuleLabel" , " " ))
115+ , fDAQHeaderInstanceLabel (p.get<std::string>(" DAQHeaderInstanceLabel" , " " ))
116+ , fRawTSCorrection (p.get<uint32_t >(" RawTSCorrection" , 0 ))
117+ , fMaxAllowedRefTimeDiff (p.get<uint32_t >(" MaxAllowedRefTimeDiff" , 0 ))
86118{
87119 produces<std::vector<CRTVeto>>();
88120 produces<art::Assns<CRTVeto, CRTSpacePoint>>();
@@ -94,10 +126,80 @@ void sbnd::crt::CRTVetoProducer::produce(art::Event& e)
94126 fVetoSpacePoints .clear ();
95127 fVetoSpacePointIndices .clear ();
96128
129+ fVetoSouthTimes .clear ();
130+
131+ fEventID = e.id ().event ();
132+ fRun = e.run ();
133+ fSubRun = e.subRun ();
134+
135+ std::cout << std::endl;
136+ std::cout << " Filling CRTVeto for Run " << fRun << " SubRun " << fSubRun << " Event " << fEventID << std::endl;
137+ std::cout << std::endl;
138+
139+ // May only be needed for BNB+Light Data --> TODO
140+ uint64_t raw_ts = 0 , ref_time = 0 ;
141+ uint32_t ref_time_ns = 0 ;
142+
143+ // Data needs to be handled differently than MC
144+
97145 if (fIsData ) {
98- std::cout << " Filling CRT Veto for Data" << std::endl;
146+
147+ // First Need to calculate the raw_ts in the same way as the CRTStripProducer
148+ art::Handle<artdaq::detail::RawEventHeader> DAQHeaderHandle;
149+ e.getByLabel (fDAQHeaderModuleLabel , fDAQHeaderInstanceLabel , DAQHeaderHandle);
150+
151+ if (DAQHeaderHandle.isValid ())
152+ {
153+ std::cout << " DAQHeader is valid --> Calculate raw ts" << std::endl;
154+ artdaq::RawEvent rawHeaderEvent = artdaq::RawEvent (*DAQHeaderHandle);
155+ raw_ts = rawHeaderEvent.timestamp () - fRawTSCorrection ;
156+ }
99157
100- }
158+ art::Handle<raw::TimingReferenceInfo> TimingReferenceHandle;
159+ e.getByLabel (fCRTTimingReferenceInfoLabel , TimingReferenceHandle);
160+ if (TimingReferenceHandle.isValid ())
161+ {
162+ uint16_t TType = TimingReferenceHandle->timingType ;
163+ uint16_t TChannel = TimingReferenceHandle->timingChannel ;
164+
165+ // the CRTStripProducer should reference the Event Trigger
166+ // If we don't find this --> return false
167+ if (TType != 0 || TChannel != 4 ) {
168+
169+ std::cout << std::endl;
170+ std::cout << " ETrig was not referenced for this event --> Don't Flag Event!" << std::endl;
171+ std::cout << std::endl;
172+ auto crtveto = std::make_unique<CRTVeto>(false , false , false , false , false , fVetoSouthTimes );
173+ auto vetoVec = std::make_unique<std::vector<CRTVeto>>();
174+ vetoVec->push_back (*crtveto);
175+ auto vetoSpacePointAssn = std::make_unique<art::Assns<CRTVeto, CRTSpacePoint>>();
176+ e.put (std::move (vetoVec));
177+ e.put (std::move (vetoSpacePointAssn));
178+ return ;
179+
180+ }
181+
182+ }
183+
184+ // The Strip Hits were referenced properly --> Change to RWM
185+ uint64_t spec_tdc_ref_time_etrig = 0 ;
186+ uint64_t spec_tdc_ref_time_rwm = 0 ;
187+ if (SPECTDCReference (e, raw_ts, spec_tdc_ref_time_etrig, 4 ) && SPECTDCReference (e, raw_ts, spec_tdc_ref_time_rwm, 2 )) {
188+
189+ ref_time += spec_tdc_ref_time_rwm;
190+ ref_time -= spec_tdc_ref_time_etrig;
191+
192+ }
193+ else {
194+ std::cout << std::endl;
195+ std::cout << std::endl;
196+ std::cout << " Was NOT able to reference time to the RWM !!!" << std::endl;
197+ std::cout << std::endl;
198+ std::cout << std::endl;
199+ }
200+ ref_time_ns = ref_time % static_cast <uint64_t >(1e9 );
201+
202+ } // end of check for Data
101203
102204
103205 // Get the Clusters for this event
@@ -110,31 +212,8 @@ void sbnd::crt::CRTVetoProducer::produce(art::Event& e)
110212 std::vector<art::Ptr<CRTCluster>> CRTClusterVec;
111213 art::fill_ptr_vector (CRTClusterVec, CRTClusterHandle);
112214
113- // Get the Space Points for this event
114- art::Handle<std::vector<CRTSpacePoint>> CRTSpacePointHandle;
115- e.getByLabel (fCRTSpacePointModuleLabel , CRTSpacePointHandle);
116- if (!CRTSpacePointHandle.isValid ()){
117- std::cout << " CRTSpacePoint product " << fCRTSpacePointModuleLabel << " not found..." << std::endl;
118- throw std::exception ();
119- }
120- std::vector<art::Ptr<CRTSpacePoint>> CRTSpacePointVec;
121- art::fill_ptr_vector (CRTSpacePointVec, CRTSpacePointHandle);
122-
123215 art::FindManyP<CRTSpacePoint> cluster_sps (CRTClusterVec, e, fCRTSpacePointModuleLabel );
124216
125- // Get indices of Veto Space Points
126- /*
127- for (unsigned int i = 0; i < CRTSpacePointVec.size(); ++i) {
128-
129- double t = CRTSpacePointVec.at(i)->Ts0()/1000; // Convert to us
130- if ((t > fWindowEnd) || (t < fWindowStart)) {
131- continue;
132- }
133- fVetoSpacePointIndices.push_back(i);
134-
135- }
136- */
137-
138217 // initialize counters for veto hits in different taggers
139218 int S = 0 ;
140219 int N = 0 ;
@@ -145,29 +224,38 @@ void sbnd::crt::CRTVetoProducer::produce(art::Event& e)
145224
146225 // loop over clusters in this event
147226 // Note: there are usually more clusters than space points
227+ //
228+ std::cout << std::endl;
229+ std::cout << " Start Loop over Clusters ..." << std::endl;
230+ std::cout << std::endl;
148231 for (auto const &cluster : CRTClusterVec) {
149232
150233 std::vector<art::Ptr<CRTSpacePoint>> clusterSpacePoints = cluster_sps.at (cluster.key ());
151234
152235 // loop over the space points in this cluster --> should be one per cluster
153236 for (auto const &sp : clusterSpacePoints) {
154-
237+
155238 // Get the time and tagger for this space point
156- double t = sp->Ts0 ()/1000 ; // Convert to us
239+ double t = sp->Ts0 (); // Starts in ns
240+ t -= ref_time_ns;
241+
242+ t /= 1000 ; // convert to us
243+
157244 CRTTagger tag = cluster->Tagger ();
158245
159246 // check if in the beam window --> Make configureable
160247 if ((t > fWindowEnd ) || (t < fWindowStart )) {
161248 continue ;
162249 }
163- std::cout << std::endl;
164- std::cout << " Found Space Point in time with the beam !!!" << std::endl;
165- std::cout << std::endl;
166-
250+
251+ // We Found a Space Point in our Veto Window !!!
252+
167253 fVetoSpacePoints .push_back (sp);
168254 fVetoSpacePointIndices .push_back (sp.key ());
169255
170256 if (inSouth (tag)) {
257+ // fSouth_tree->Fill(fRun, fSubRun, fEventID, t);
258+ fVetoSouthTimes .push_back (t);
171259 S += 1 ;
172260 }
173261 else if (inNorth (tag)) {
@@ -221,11 +309,8 @@ void sbnd::crt::CRTVetoProducer::produce(art::Event& e)
221309 v4 = true ;
222310 }
223311
224- // crtveto = CRTVeto(v0, v1, v2, v3);
225- //
226- //
227312 // Make Products for the Event
228- auto crtveto = std::make_unique<CRTVeto>(v0, v1, v2, v3, v4);
313+ auto crtveto = std::make_unique<CRTVeto>(v0, v1, v2, v3, v4, fVetoSouthTimes );
229314 auto vetoVec = std::make_unique<std::vector<CRTVeto>>();
230315 vetoVec->push_back (*crtveto);
231316
@@ -243,21 +328,58 @@ void sbnd::crt::CRTVetoProducer::produce(art::Event& e)
243328
244329 util::CreateAssn (*this , e, *vetoVec, fVetoSpacePoints , *vetoSpacePointAssn);
245330
246- /*
247- for (unsigned int i = 0; i < fVetoSpacePoints.size(); ++i) {
248- std::cout << "Veto SP index " << fVetoSpacePointIndices.at(i) << std::endl;
249- //auto const CRTSpacePointPtr = CRTSpacePointPtrMaker(fVetoSpacePointIndices.at(i));
250- //vetoSpacePointAssn->addSingle(vetoPtr, CRTSpacePointPtr);
251- //vetoSpacePointAssn->addSingle(crtveto, CRTSpacePointPtr);
252- util::CreateAssn(*this, e, *vetoVec, fVetoSpacePoints.at(i), *vetoSpacePointAssn);
253- }
254- */
255-
256- // e.put(std::move(crtveto));
257331 e.put (std::move (vetoVec));
258332 e.put (std::move (vetoSpacePointAssn));
259333
260334} // end of produce
335+ /*
336+ void sbnd::crt::CRTVetoProducer::beginJob()
337+ {
338+ art::ServiceHandle<art::TFileService> tfs;
339+
340+ fSouth_tree = tfs->make<TNtuple>("crtveto_south_tree", "crtveto_south_tree", "run:subrun:evt:t");
341+
342+ }
343+ */
344+ bool sbnd::crt::CRTVetoProducer::SPECTDCReference (art::Event& e, const uint64_t &raw_ts, uint64_t &ref_time, const uint32_t channel)
345+ {
346+ bool found = false ;
347+
348+ art::Handle<std::vector<sbnd::timing::DAQTimestamp>> TDCHandle;
349+ e.getByLabel (fSPECTDCModuleLabel , TDCHandle);
350+
351+ if (!TDCHandle.isValid () || TDCHandle->size () == 0 )
352+ return found;
353+
354+ std::vector<art::Ptr<sbnd::timing::DAQTimestamp>> TDCVec;
355+ art::fill_ptr_vector (TDCVec, TDCHandle);
356+
357+ uint64_t min_diff = std::numeric_limits<int64_t >::max ();
358+ uint64_t min_diff_ts = 0 ;
359+
360+ for (auto ts : TDCVec)
361+ {
362+ // For the CRT Veto, we want to use the RWM --> Channel 2
363+ if (ts->Channel () == channel)
364+ {
365+ uint64_t diff = raw_ts > ts->Timestamp () ? raw_ts - ts->Timestamp () : ts->Timestamp () - raw_ts;
366+
367+ if (diff < min_diff)
368+ {
369+ min_diff = diff;
370+ min_diff_ts = ts->Timestamp ();
371+ found = true ;
372+ }
373+ }
374+ }
375+
376+ if (min_diff > fMaxAllowedRefTimeDiff )
377+ return false ;
378+
379+ ref_time = min_diff_ts;
380+
381+ return found;
382+ }
261383
262384bool sbnd::crt::CRTVetoProducer::inSouth (const CRTTagger t)
263385{
@@ -266,6 +388,7 @@ bool sbnd::crt::CRTVetoProducer::inSouth(const CRTTagger t)
266388 }
267389 return false ;
268390}
391+
269392bool sbnd::crt::CRTVetoProducer::inNorth (const CRTTagger t)
270393{
271394 if (t == kNorthTagger ) {
@@ -308,6 +431,4 @@ bool sbnd::crt::CRTVetoProducer::inTopHigh(const CRTTagger t)
308431 return false ;
309432}
310433
311-
312-
313434DEFINE_ART_MODULE (sbnd::crt::CRTVetoProducer)
0 commit comments