Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaCoincTime.cxx
Go to the documentation of this file.
1//*-- Author : Rob Feuerbach 9-Sep-03 */
2
4//
5// THaCoincTime
6//
7// Calculate coincidence time between tracks in two spectrometers.
8//
9// Loop through all combinations of tracks in the two spectrometers.
10// Here we assume that the time difference+fixed delay between the
11// common TDC starts is measured.
12//
14
15#include "TMath.h"
16#include "THaCoincTime.h"
17#include "THaTrack.h"
18#include "THaDetMap.h"
19#include "THaSpectrometer.h"
20#include "THaEvData.h"
21#include "VarDef.h"
22#include <cassert>
23
24using namespace std;
25
26// Reserve initial space for 10 tracks per spectrometer (can grow dynamically)
27#define NTR 10
28
29//_____________________________________________________________________________
31 const char* description,
32 const char* spec1, const char* spec2,
33 Double_t m1, Double_t m2,
34 const char* ch_name1, const char* ch_name2 )
35 : THaPhysicsModule(name,description), fSpectN1(spec1), fSpectN2(spec2),
36 fpmass1(m1), fpmass2(m2), fSpect1(nullptr), fSpect2(nullptr),
37 fDetMap{new THaDetMap()},
38 fTdcRes{0,0}, fTdcOff{0,0}, fTdcData{0, 0}
39
40{
41 // Normal constructor.
42
43 fVxTime1.reserve(NTR);
44 fVxTime2.reserve(NTR);
45 fTimeCombos.reserve(NTR*NTR);
46
47 if (ch_name1 && strlen(ch_name1)>0) {
48 fTdcLabels[0] = ch_name1;
49 } else {
50 fTdcLabels[0] = Form("%sby%s",spec2,spec1);
51 }
52 if (ch_name2 && strlen(ch_name2)>0) {
53 fTdcLabels[1] = ch_name2;
54 } else {
55 fTdcLabels[1] = Form("%sby%s",spec1,spec2);
56 }
57}
58
59//_____________________________________________________________________________
61{
62 // Destructor
64}
65
66//_____________________________________________________________________________
68{
69 // Clear all internal variables
70 // some overkill, but is event-independent (back to a known state)
72 fVxTime1.clear();
73 fVxTime2.clear();
74 fTimeCombos.clear();
75}
76
77//_____________________________________________________________________________
79{
80 // Define/delete global variables.
81
82 RVarDef vars[] = {
83 { "d_trig","Measured TDC start+delay of spec 2 (1), by spec 1 (2)", "fdTdc" },
84 { "ntr1", "Number of tracks in first spec.", "GetNTr1()" },
85 { "ntr2", "Number of tracks in first spec.", "GetNTr2()" },
86 { "vx_t1", "Time of track from spec1 at target vertex", "fVxTime1" },
87 { "vx_t2", "Time of track from spec2 at target vertex", "fVxTime2" },
88 { "ncomb", "Number of track combinations considered", "GetNTimes()" },
89 { "ct_2by1", "Coinc. times of tracks, d_trig from spec 1", "fTimeCombos.fDiffT2by1" },
90 { "ct_1by2", "Coinc. times of tracks, d_trig from spec 2", "fTimeCombos.fDiffT1by2" },
91 { "trind1", "Track indices for spec1 match entries in ct_*", "fTimeCombos.fTrInd1" },
92 { "trind2", "Track indices for spec2 match entries in ct_*", "fTimeCombos.fTrInd2" },
93 { nullptr }
94 };
95 return DefineVarsFromList( vars, mode );
96}
97
98//_____________________________________________________________________________
100{
101 // Initialize the module.
102
103
104 // Locate the spectrometer apparatus named in fSpectroName and save
105 // pointer to it.
106
107 // Standard initialization. Calls this object's DefineVariables().
108 if( THaPhysicsModule::Init( run_time ) != kOK )
109 return fStatus;
110
111 fSpect1 = dynamic_cast<THaSpectrometer*>
112 ( FindModule( fSpectN1, "THaSpectrometer"));
113 fSpect2 = dynamic_cast<THaSpectrometer*>
114 ( FindModule( fSpectN2, "THaSpectrometer"));
115
116 if( !fSpect1 || !fSpect2 )
118
119 return fStatus;
120}
121
122//_____________________________________________________________________________
124{
125 // Read configuration parameters from the database.
126 // 'date' contains the date/time of the run being analyzed.
127
128 const char* const here = "ReadDatabase";
129
130 FILE* file = OpenFile( date );
131 if( !file ) {
132 // look for more general coincidence-timing database
133 file = Podd::OpenDBFile("CT", date);
134 }
135 if ( !file )
136 return kFileError;
137
138 fDetMap->Clear();
139
140 // the list of detector names to use is in fTdcLabels, set
141 // at creation time as "{spec2Name}by{spec1Name}"
142 // and the inverse
143
144 Int_t err = 0;
145 for( int i=0; i<2 && !err; i++) {
146 vector<Int_t> detmap;
147 fTdcOff[i] = 0.0;
148 DBRequest request[] = {
149 { "detmap", &detmap, kIntV },
150 { "tdc_res", &fTdcRes[i] },
151 { "tdc_offset", &fTdcOff[i], kDouble, 1 },
152 { nullptr }
153 };
154 TString pref(fPrefix); pref.Append(fTdcLabels[i]); pref.Append(".");
155 err = LoadDB( file, date, request, pref );
156
157 if( !err ) {
158 if( detmap.size() != 6 ) {
159 Error( Here(here), "Invalid number of detector map values = %d for "
160 "database key %sdetmap. Must be exactly 6. Fix database.",
161 static_cast<Int_t>(detmap.size()), pref.Data() );
162 err = kInitError;
163 } else {
164 if( detmap[2] != detmap[3] ) {
165 Warning( Here(here), "Detector map %sdetmap must have exactly 1 "
166 "channel. Setting last = first. Fix database.",
167 pref.Data() );
168 detmap[3] = detmap[2];
169 }
170 Int_t ret =
173 if( ret <= 0 ) {
174 Error( Here(here), "Error %d filling detector map element %d",
175 ret, i );
176 err = kInitError;
177 }
178 }
179 }
180 }
181 fclose(file);
182 if( err )
183 return err;
184
185 if( fDetMap->GetSize() != 2 ) {
186 Error( Here(here), "Unexpected number of detector map modules = %d. "
187 "Must be exactly 2. Fix database.", fDetMap->GetSize() );
188 return kInitError;
189 }
190
191 fIsInit = true;
192 return kOK;
193}
194
195//_____________________________________________________________________________
197{
198 // Read in coincidence TDCs
199
200 const char* const here = "Process";
201
202 if( !IsOK() ) return -1;
203
204 // read in the two relevant channels
205 int detmap_pos=0;
206 for( double tdcres : fTdcRes ) {
207 if( tdcres != 0. ) {
208 THaDetMap::Module* d = fDetMap->GetModule(detmap_pos);
209 // grab only the first hit in a TDC
210 if( evdata.GetNumHits(d->crate, d->slot, d->lo) > 0 ) {
211 fTdcData[d->first] =
212 evdata.GetData(d->crate, d->slot, d->lo, 0) * fTdcRes[d->first]
213 - fTdcOff[d->first];
214 }
215 detmap_pos++;
216 }
217 }
218
219 // Calculate the time at the vertex (relative to the trigger time)
220 // for each track in each spectrometer
221 // Use the Beta of the assumed particle type.
222 class Spec_short {
223 public:
224 THaSpectrometer* Sp;
225 vector<Double_t>& Vxtime;
226 Double_t Mass;
227 };
228
229 const vector<Spec_short> SpList = {
232 };
233
234 for( const auto& sp : SpList ) {
235 assert(sp.Vxtime.empty()); // else Clear() not called in order
236 Int_t ntr = sp.Sp->GetNTracks();
237 TClonesArray* tracks = sp.Sp->GetTracks();
238 for( Int_t i = 0; i < ntr; i++ ) {
239 auto* tr = dynamic_cast<THaTrack*>(tracks->At(i));
240 // this should be safe to assume -- only THaTracks go into the tracks array
241 if( !tr ) {
242 Warning(Here(here), "non-THaTrack in %s's tracks array at %d.",
243 sp.Sp->GetName(), i);
244 continue;
245 }
246 Double_t p = tr->GetP();
247 if( tr->GetBeta() != 0. && p > 0. ) {
248 Double_t beta = p / TMath::Sqrt(p * p + sp.Mass * sp.Mass);
249 Double_t c = TMath::C();
250 sp.Vxtime.push_back(tr->GetTime() - tr->GetPathLen() / (beta * c));
251 } else {
252 // Using (i+1)*kBig here prevents differences from being zero
253 sp.Vxtime.push_back((i + 1) * kBig);
254 }
255 }
256 }
257
258 // now, we have the vertex times -- go through the combinations
259
260 // Take the tracks and the coincidence TDC and construct
261 // the coincidence time
262 assert(fTimeCombos.empty()); // else Clear() not called in order
263 for( size_t i = 0; i < fVxTime1.size(); i++ ) {
264 for( size_t j = 0; j < fVxTime2.size(); j++ ) {
265 fTimeCombos.emplace_back( i, j,
266 fVxTime2[j] - fVxTime1[i] + fTdcData[0],
267 fVxTime1[i] - fVxTime2[j] + fTdcData[1]
268 );
269 }
270 }
271
272 fDataValid = true;
273 return 0;
274}
275
277
278
int Int_t
const Data_t kBig
Definition DataType.h:15
#define d(i)
#define c(i)
double Double_t
const char Option_t
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char mode
char name[80]
#define NTR
static const char *const here
Definition THaVar.cxx:64
char * Form(const char *fmt,...)
static Int_t LoadDB(FILE *file, const TDatime &date, const DBRequest *request, const char *prefix, Int_t search=0, const char *here="THaAnalysisObject::LoadDB")
static Int_t DefineVarsFromList(const void *list, EType type, EMode mode, const char *def_prefix, const TObject *obj, const char *prefix, const char *here, const char *comment_subst="")
virtual const char * Here(const char *) const
THaAnalysisObject * FindModule(const char *name, const char *classname, bool do_error=true)
Bool_t IsOK() const
virtual FILE * OpenFile(const TDatime &date)
virtual Int_t ReadDatabase(const TDatime &date)
TString fSpectN1
THaSpectrometer * fSpect2
TString fSpectN2
virtual ~THaCoincTime()
virtual void Clear(Option_t *opt="")
std::vector< Double_t > fVxTime2
Double_t fTdcRes[2]
TString fTdcLabels[2]
Double_t fTdcOff[2]
std::vector< TimeCombo > fTimeCombos
std::unique_ptr< THaDetMap > fDetMap
THaCoincTime(const char *name, const char *description, const char *spec1="L", const char *spec2="R", Double_t mass1=.938272, Double_t mass2=0.000511, const char *ch_name1=nullptr, const char *ch_name2=nullptr)
Double_t fpmass2
Double_t fpmass1
THaSpectrometer * fSpect1
virtual Int_t DefineVariables(EMode mode=kDefine)
virtual Int_t Process(const THaEvData &)
std::vector< Double_t > fVxTime1
Double_t fTdcData[2]
@ kFillLogicalChannel
Definition THaDetMap.h:96
@ kDoNotClear
Definition THaDetMap.h:94
UInt_t GetNumHits(UInt_t crate, UInt_t slot, UInt_t chan) const
Definition THaEvData.h:264
UInt_t GetData(UInt_t crate, UInt_t slot, UInt_t chan, UInt_t hit) const
Definition THaEvData.h:273
virtual void Clear(Option_t *opt="")
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual void Error(const char *method, const char *msgfmt,...) const
const char * Data() const
TString & Append(char c, Ssiz_t rep=1)
double beta(double x, double y)
constexpr Double_t C()
Double_t Sqrt(Double_t x)
STL namespace.
ClassImp(TPyArg)
void tracks()