3636
3737#include " sbndcode/Geometry/GeometryWrappers/CRTGeoAlg.h"
3838#include " sbndcode/Geometry/GeometryWrappers/TPCGeoAlg.h"
39+ #include " sbndcode/ChannelMaps/CRT/CRTChannelMapService.h"
3940#include " sbndcode/CRT/CRTBackTracker/CRTBackTrackerAlg.h"
4041#include " sbndcode/CRT/CRTUtils/CRTCommonUtils.h"
4142#include " sbndcode/Decoders/PTB/sbndptb.h"
43+ #include " sbndcode/Timing/SBNDRawTimingObj.h"
4244
4345namespace sbnd ::crt {
4446 class CRTAnalysis ;
@@ -94,8 +96,10 @@ class sbnd::crt::CRTAnalysis : public art::EDAnalyzer {
9496 std::string fMCParticleModuleLabel , fSimDepositModuleLabel , fFEBDataModuleLabel , fCRTStripHitModuleLabel ,
9597 fCRTClusterModuleLabel , fCRTSpacePointModuleLabel , fCRTTrackModuleLabel , fTPCTrackModuleLabel ,
9698 fCRTSpacePointMatchingModuleLabel , fCRTTrackMatchingModuleLabel , fPFPModuleLabel , fPTBModuleLabel ,
97- fTDCModuleLabel ;
99+ fTDCModuleLabel , fTimingReferenceModuleLabel ;
98100 bool fDebug , fDataMode , fNoTPC , fHasPTB , fHasTDC ;
101+ // ! Adding some of the reco parameters to save corrections
102+ double fPEAttenuation , fTimeWalkNorm , fTimeWalkScale , fPropDelay ;
99103
100104 TTree* fTree ;
101105
@@ -104,6 +108,8 @@ class sbnd::crt::CRTAnalysis : public art::EDAnalyzer {
104108 int _run;
105109 int _subrun;
106110 int _event;
111+ int _crt_timing_reference_type;
112+ int _crt_timing_reference_channel;
107113
108114 // mc truth
109115 std::vector<int16_t > _mc_trackid;
@@ -178,6 +184,11 @@ class sbnd::crt::CRTAnalysis : public art::EDAnalyzer {
178184 std::vector<uint8_t > _cl_composition;
179185 std::vector<std::vector<uint32_t >> _cl_channel_set;
180186 std::vector<std::vector<uint16_t >> _cl_adc_set;
187+ std::vector<std::vector<uint32_t >> _cl_sh_ts0_set; // ! To store t0 from x-y coincidences
188+ std::vector<std::vector<uint32_t >> _cl_sh_ts1_set; // ! To store t1 from x-y coincidences
189+ std::vector<std::vector<uint16_t >> _cl_sh_feb_mac5_set; // ! MAC5 addresses of StripHit FEBs
190+ std::vector<std::vector<double >> _cl_sh_time_walk_set; // ! Time walk correction
191+ std::vector<std::vector<double >> _cl_sh_prop_delay_set; // ! Light propagation correction
181192 std::vector<int > _cl_truth_trackid;
182193 std::vector<double > _cl_truth_completeness;
183194 std::vector<double > _cl_truth_purity;
@@ -331,11 +342,17 @@ sbnd::crt::CRTAnalysis::CRTAnalysis(fhicl::ParameterSet const& p)
331342 fPFPModuleLabel = p.get <std::string>(" PFPModuleLabel" , " pandora" );
332343 fPTBModuleLabel = p.get <std::string>(" PTBModuleLabel" , " ptbdecoder" );
333344 fTDCModuleLabel = p.get <std::string>(" TDCModuleLabel" , " tdcdecoder" );
345+ fTimingReferenceModuleLabel = p.get <std::string>(" TimingReferenceModuleLabel" , " crtstrips" );
334346 fDebug = p.get <bool >(" Debug" , false );
335347 fDataMode = p.get <bool >(" DataMode" , false );
336348 fNoTPC = p.get <bool >(" NoTPC" , false );
337349 fHasPTB = p.get <bool >(" HasPTB" , false );
338350 fHasTDC = p.get <bool >(" HasTDC" , false );
351+ // ! Adding some of the reco parameters to save corrections
352+ fPEAttenuation = p.get <double >(" PEAttenuation" , 1.0 );
353+ fTimeWalkNorm = p.get <double >(" TimeWalkNorm" , 0.0 );
354+ fTimeWalkScale = p.get <double >(" TimeWalkScale" , 0.0 );
355+ fPropDelay = p.get <double >(" PropDelay" , 0.0 );
339356
340357 if (!fDataMode )
341358 fCRTBackTrackerAlg = CRTBackTrackerAlg (p.get <fhicl::ParameterSet>(" CRTBackTrackerAlg" , fhicl::ParameterSet ()));
@@ -346,6 +363,8 @@ sbnd::crt::CRTAnalysis::CRTAnalysis(fhicl::ParameterSet const& p)
346363 fTree ->Branch (" run" , &_run);
347364 fTree ->Branch (" subrun" , &_subrun);
348365 fTree ->Branch (" event" , &_event);
366+ fTree ->Branch (" crt_timing_reference_type" , &_crt_timing_reference_type);
367+ fTree ->Branch (" crt_timing_reference_channel" , &_crt_timing_reference_channel);
349368
350369 if (!fDataMode )
351370 {
@@ -421,6 +440,11 @@ sbnd::crt::CRTAnalysis::CRTAnalysis(fhicl::ParameterSet const& p)
421440 fTree ->Branch (" cl_composition" , " std::vector<uint8_t>" , &_cl_composition);
422441 fTree ->Branch (" cl_channel_set" , " std::vector<std::vector<uint32_t>>" , &_cl_channel_set);
423442 fTree ->Branch (" cl_adc_set" , " std::vector<std::vector<uint16_t>>" , &_cl_adc_set);
443+ fTree ->Branch (" cl_sh_ts0_set" , " std::vector<std::vector<uint32_t>>" , &_cl_sh_ts0_set);
444+ fTree ->Branch (" cl_sh_ts1_set" , " std::vector<std::vector<uint32_t>>" , &_cl_sh_ts1_set);
445+ fTree ->Branch (" cl_sh_feb_mac5_set" , " std::vector<std::vector<uint16_t>>" , &_cl_sh_feb_mac5_set);
446+ fTree ->Branch (" cl_sh_time_walk_set" , " std::vector<std::vector<double>>" , &_cl_sh_time_walk_set);
447+ fTree ->Branch (" cl_sh_prop_delay_set" , " std::vector<std::vector<double>>" , &_cl_sh_prop_delay_set);
424448 if (!fDataMode )
425449 {
426450 fTree ->Branch (" cl_truth_trackid" , " std::vector<int>" , &_cl_truth_trackid);
@@ -621,6 +645,17 @@ void sbnd::crt::CRTAnalysis::analyze(art::Event const& e)
621645
622646 if (fDebug ) std::cout << " This is event " << _run << " -" << _subrun << " -" << _event << std::endl;
623647
648+ _crt_timing_reference_type = -1 ;
649+ _crt_timing_reference_channel = -1 ;
650+
651+ art::Handle<raw::TimingReferenceInfo> TimingReferenceHandle;
652+ e.getByLabel (fTimingReferenceModuleLabel , TimingReferenceHandle);
653+ if (TimingReferenceHandle.isValid ())
654+ {
655+ _crt_timing_reference_type = TimingReferenceHandle->timingType ;
656+ _crt_timing_reference_channel = TimingReferenceHandle->timingChannel ;
657+ }
658+
624659 if (fHasPTB )
625660 {
626661 // Get PTBs
@@ -1076,6 +1111,11 @@ void sbnd::crt::CRTAnalysis::AnalyseCRTClusters(const art::Event &e, const std::
10761111 _cl_composition.resize (nClusters);
10771112 _cl_channel_set.resize (nClusters);
10781113 _cl_adc_set.resize (nClusters);
1114+ _cl_sh_ts0_set.resize (nClusters);
1115+ _cl_sh_ts1_set.resize (nClusters);
1116+ _cl_sh_feb_mac5_set.resize (nClusters);
1117+ _cl_sh_time_walk_set.resize (nClusters);
1118+ _cl_sh_prop_delay_set.resize (nClusters);
10791119 _cl_truth_trackid.resize (nClusters);
10801120 _cl_truth_completeness.resize (nClusters);
10811121 _cl_truth_purity.resize (nClusters);
@@ -1106,6 +1146,8 @@ void sbnd::crt::CRTAnalysis::AnalyseCRTClusters(const art::Event &e, const std::
11061146 _cl_sp_ets1.resize (nClusters);
11071147 _cl_sp_complete.resize (nClusters);
11081148
1149+ art::ServiceHandle<SBND ::CRTChannelMapService> ChannelMapService;
1150+
11091151 for (unsigned i = 0 ; i < nClusters; ++i)
11101152 {
11111153 const auto cluster = CRTClusterVec[i];
@@ -1117,16 +1159,52 @@ void sbnd::crt::CRTAnalysis::AnalyseCRTClusters(const art::Event &e, const std::
11171159 _cl_tagger[i] = cluster->Tagger ();
11181160 _cl_composition[i] = cluster->Composition ();
11191161
1162+ const auto spacepoints = clustersToSpacePoints.at (cluster.key ());
1163+
11201164 const auto striphits = clustersToStripHits.at (cluster.key ());
11211165 _cl_channel_set[i].resize (_cl_nhits[i]);
11221166 _cl_adc_set[i].resize (2 * _cl_nhits[i]);
1167+ _cl_sh_ts0_set[i].resize (_cl_nhits[i] );
1168+ _cl_sh_ts1_set[i].resize (_cl_nhits[i] );
1169+ _cl_sh_feb_mac5_set[i].resize (_cl_nhits[i]);
1170+ _cl_sh_time_walk_set[i].resize (_cl_nhits[i]);
1171+ _cl_sh_prop_delay_set[i].resize (_cl_nhits[i]);
11231172
11241173 for (unsigned ii = 0 ; ii < _cl_nhits[i]; ++ii)
11251174 {
11261175 const auto striphit = striphits[ii];
11271176 _cl_channel_set[i][ii] = striphit->Channel ();
11281177 _cl_adc_set[i][2 *ii] = striphit->ADC1 ();
11291178 _cl_adc_set[i][2 *ii+1 ] = striphit->ADC2 ();
1179+ _cl_sh_ts0_set[i][ii] = striphit->Ts0 ();
1180+ _cl_sh_ts1_set[i][ii] = striphit->Ts1 ();
1181+ SBND ::CRTChannelMapService::ModuleInfo_t module_info = ChannelMapService->GetModuleInfoFromOfflineID ( striphit->Channel () / 32 );
1182+ _cl_sh_feb_mac5_set[i][ii] = ( module_info.valid ) ? module_info.feb_mac5 : 0 ;
1183+
1184+ /*
1185+ * The below segment reimplements the CorrectTime() method
1186+ * from CRTReco/CRTClusterCharacterisationAlg.cc .
1187+ * Because the Ts0(), Ts1() getters invoked in _cl_sp_ts*, _cl_sh_ts*_set are raw T0/1
1188+ * counters, the time walk and propagation delay are saved as explicit branches here.
1189+ */
1190+ if (spacepoints.size () == 1 ) { // need unique position of spacepoint
1191+ double pe0 = fCRTGeoAlg .GetSiPM ( striphit->Channel () ).gain * striphit->ADC1 ();
1192+ double pe1 = fCRTGeoAlg .GetSiPM ( striphit->Channel () + 1 ).gain * striphit->ADC2 ();
1193+ double pe = pe0 + pe1;
1194+
1195+ double dist = fCRTGeoAlg .DistanceDownStrip ( spacepoints[0 ]->Pos (), striphit->Channel () );
1196+
1197+ double corr = std::pow ( dist - fPEAttenuation , 2.0 ) / std::pow ( fPEAttenuation , 2.0 );
1198+ double tw_pe = pe * corr;
1199+
1200+ _cl_sh_time_walk_set[i][ii] = fTimeWalkNorm * std::exp ( -fTimeWalkScale * tw_pe );
1201+ _cl_sh_prop_delay_set[i][ii] = fPropDelay * dist;
1202+
1203+ } else { // fill with nonsense
1204+ _cl_sh_time_walk_set[i][ii] = -999999 .;
1205+ _cl_sh_prop_delay_set[i][ii] = -999999 .;
1206+ }
1207+
11301208 }
11311209
11321210 if (!fDataMode )
@@ -1150,7 +1228,6 @@ void sbnd::crt::CRTAnalysis::AnalyseCRTClusters(const art::Event &e, const std::
11501228 _cl_truth_core_z[i] = truthMatch.deposit .coreZ ;
11511229 }
11521230
1153- const auto spacepoints = clustersToSpacePoints.at (cluster.key ());
11541231 if (spacepoints.size () == 1 )
11551232 {
11561233 const auto spacepoint = spacepoints[0 ];
0 commit comments