Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaHRS.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 2-Oct-01
2
4//
5// THaHRS
6//
7// The standard Hall A High Resolution Spectrometers (HRS).
8//
9// The usual name of this object is either "R" or "L", for Left
10// and Right HRS, respectively.
11//
12// Defines the functions FindVertices() and TrackCalc(), which are common
13// to both the LeftHRS and the RightHRS.
14//
15// By default, the THaHRS class does not define any detectors. (This is new
16// in analyzer 1.6 and later.) In this way, the user has full control over
17// the detector configuration in the analysis script.
18// Detectors should be added with AddDetector() as usual.
19//
20// However: To maintain backward compatibility with old scripts, the THaHRS
21// will auto-create the previous set of standard detectors, "vdc", "s1" and
22// "s2", if no "vdc" detector is defined at Init() time.
23// This can be turned off by calling AutoStandardDetectors(false).
24//
25// For timing calculations, one can specify a reference detector via SetRefDet
26// (usually a scintillator) as the detector at the 'reference distance',
27// corresponding to the pathlength correction matrix.
28//
30
31#include "THaHRS.h"
32#include "THaTrackingDetector.h"
33#include "THaTrack.h"
34#include "THaScintillator.h" // includes THaNonTrackingDetector
35#include "THaVDC.h"
36#include "THaTrackProj.h"
37#include "THaTriggerTime.h"
38#include "TMath.h"
39#include "TList.h"
40#include <cassert>
41
42#ifdef WITH_DEBUG
43#include <iostream>
44#endif
45
46
47using namespace std;
48
49//_____________________________________________________________________________
50THaHRS::THaHRS( const char* name, const char* description ) :
51 THaSpectrometer( name, description ), fRefDet(nullptr)
52{
53 // Constructor
54
55 SetTrSorting(false);
56 AutoStandardDetectors(true); // for backward compatibility
57}
58
59//_____________________________________________________________________________
60THaHRS::~THaHRS() = default;
61
62//_____________________________________________________________________________
64{
65 Bool_t oldset = TestBit(kSortTracks);
66 SetBit( kSortTracks, set );
67 return oldset;
68}
69
70//_____________________________________________________________________________
72{
73 return TestBit(kSortTracks);
74}
75
76//_____________________________________________________________________________
78{
79 Bool_t oldset = TestBit(kAutoStdDets);
80 SetBit( kAutoStdDets, set );
81 return oldset;
82}
83
84//_____________________________________________________________________________
86{
87 // Special HRS Init method for approximate backward compatibility with old
88 // scripts. If no "vdc" detector has been defined by the user, assume we
89 // are being run from an old script and create the old set of "standard
90 // detectors" ("vdc", "s1", "s2") at the beginning of the detector list.
91 // Note that the old script may have defined non-standard detectors, e.g.
92 // Cherenkov, Shower, FPP etc.
93 // This behavior can be turned off by calling AutoStandardDetectors(false).
94
95 if( TestBit(kAutoStdDets) ) {
96 auto* pdet = dynamic_cast<THaDetector*>( fDetectors->FindObject("vdc") );
97 if( !pdet ) {
98 AddDetector( new THaScintillator("s2", "S2 scintillator"), true, true );
99 AddDetector( new THaScintillator("s1", "S1 scintillator"), true, true );
100#ifndef NDEBUG
101 Int_t ret =
102#endif
103 AddDetector( new THaVDC("vdc", "Vertical Drift Chamber"), true, true );
104 assert(ret==0); // else "vdc" was already defined after all
105 assert( fDetectors->GetSize() >= 3 );
106 }
107 }
108
109 // If the reference detector hasn't been defined yet (via SetRefDet),
110 // use "s1", if it exists.
111 if( !fRefDet )
112 fRefDet = dynamic_cast<THaScintillator*>( GetDetector("s1") );
113
114 // Continue with standard initialization as before
115 return THaSpectrometer::Init(run_time);
116}
117
118//_____________________________________________________________________________
119Int_t THaHRS::SetRefDet( const char* name )
120{
121 // Set reference detector for TrackTimes calculation to the detector
122 // with the given name (typically a scintillator)
123
124 const char* const here = "SetRefDet";
125
126 if( !name || !*name ) {
127 Error( Here(here), "Invalid detector name" );
128 return 1;
129 }
130
131 fRefDet = dynamic_cast<THaNonTrackingDetector*>
133
134 if( !fRefDet ) {
135 Error( Here(here), "Can't find detector \"%s\"", name );
136 return 1;
137 }
138
139 return 0;
140}
141
142//_____________________________________________________________________________
144{
145 const char* const here = "SetRefDet";
146
147 if( !obj ) {
148 Error( Here(here), "Invalid detector pointer" );
149 return 1;
150 }
151
152 fRefDet = dynamic_cast<THaNonTrackingDetector*>
154
155 if( !fRefDet ) {
156 Error( Here(here), "Can't find given detector. "
157 "Is it a THaNonTrackingDetector?");
158 return 1;
159 }
160
161 return 0;
162}
163
164//_____________________________________________________________________________
166{
167 // Reconstruct target coordinates for all tracks found in the focal plane.
168
169 TIter nextTrack( fTrackingDetectors );
170
171 nextTrack.Reset();
172 while( auto* theTrackDetector =
173 static_cast<THaTrackingDetector*>( nextTrack() )) {
174#ifdef WITH_DEBUG
175 if( fDebug>1 ) cout << "Call FineTrack() for "
176 << theTrackDetector->GetName() << "... ";
177#endif
178 theTrackDetector->FindVertices( tracks );
179#ifdef WITH_DEBUG
180 if( fDebug>1 ) cout << "done.\n";
181#endif
182 }
183
184 // If enabled, sort the tracks by chi2/ndof
185 if( GetTrSorting() ) {
186 fTracks->Sort();
187 // Reassign track indexes. Sorting may have changed the order
188 for( int i = 0; i < fTracks->GetLast()+1; i++ ) {
189 auto* theTrack = static_cast<THaTrack*>( fTracks->At(i) );
190 assert( theTrack );
191 theTrack->SetIndex(i);
192 }
193 }
194
195 // Find the "Golden Track".
196 if( GetNTracks() > 0 ) {
197 // Select first track in the array. If there is more than one track
198 // and track sorting is enabled, then this is the best fit track
199 // (smallest chi2/ndof). Otherwise, it is the track with the best
200 // geometrical match (smallest residuals) between the U/V clusters
201 // in the upper and lower VDCs (old behavior).
202 //
203 // Chi2/dof is a well-defined quantity, and the track selected in this
204 // way is immediately physically meaningful. The geometrical match
205 // criterion is mathematically less well defined and not usually used
206 // in track reconstruction. Hence, chi2 sorting is preferable, albeit
207 // obviously slower.
208
209 fGoldenTrack = static_cast<THaTrack*>( fTracks->At(0) );
212 } else
213 fGoldenTrack = nullptr;
214
215 return 0;
216}
217
218//_____________________________________________________________________________
220{
221 // Additional track calculations. At present, we only calculate beta here.
222
223 return TrackTimes( fTracks );
224}
225
226//_____________________________________________________________________________
228{
229 // Do the actual track-timing (beta) calculation.
230 // Use multiple scintillators to average together and get "best" time at S1.
231 //
232 // To be useful, a meaningful timing resolution should be assigned
233 // to each Scintillator object (part of the database).
234
235 if ( !Tracks || !fRefDet ) return -1;
236
237 Int_t ntrack = GetNTracks();
238
239 // linear regression to: t = t0 + pathl/(beta*c)
240 // where t0 is the time of the track at the reference plane (fRefDet).
241 // t0 and beta are solved for.
242 //
243 for ( Int_t i=0; i < ntrack; i++ ) {
244 auto* track = static_cast<THaTrack*>(Tracks->At(i));
245 auto* tr_ref = static_cast<THaTrackProj*>(fRefDet->GetTrackHits()->At(i));
246
247 Double_t pathlref = tr_ref->GetPathLen();
248
249 Double_t wgt_sum=0.,wx2=0.,wx=0.,wxy=0.,wy=0.;
250 //Int_t ncnt=0;
251
252 // linear regression to get beta and time at ref.
254 while( auto* det = static_cast<THaNonTrackingDetector*>(nextSc()) ) {
255 auto* sc = dynamic_cast<THaScintillator*>(det);
256 if ( !sc ) continue;
257
258 const auto* trh = static_cast<THaTrackProj*>(sc->GetTrackHits()->At(i));
259
260 Int_t pad = trh->GetChannel();
261 if (pad<0 || pad>=sc->GetNelem()) continue;
262 Double_t pathl = (trh->GetPathLen()-pathlref);
263 const auto& padinfo = sc->GetPad(pad);
264 Double_t time = padinfo.time;
265 Double_t wgt = padinfo.dtime;
266
267 if (pathl>.5*kBig || time>.5*kBig) continue;
268 if (wgt>0) wgt = 1./(wgt*wgt);
269 else continue;
270
271 wgt_sum += wgt;
272 wx2 += wgt*pathl*pathl;
273 wx += wgt*pathl;
274 wxy += wgt*pathl*time;
275 wy += wgt*time;
276 //ncnt++;
277 }
278
280 Double_t dbeta = kBig;
282 Double_t dt = kBig;
283
284 Double_t delta = wgt_sum*wx2-wx*wx;
285
286 if (delta != 0.) {
287 time = (wx2*wy-wx*wxy)/delta;
288 dt = TMath::Sqrt(wx2/delta);
289 Double_t invbeta = (wgt_sum*wxy-wx*wy)/delta;
290 if (invbeta != 0.) {
291 Double_t c = TMath::C();
292 beta = 1./(c*invbeta);
293 dbeta = TMath::Sqrt(wgt_sum/delta)/(c*invbeta*invbeta);
294 }
295 }
296
297 track->SetBeta(beta);
298 track->SetdBeta(dbeta);
299 track->SetTime(time);
300 track->SetdTime(dt);
301 }
302 return 0;
303}
304
305//_____________________________________________________________________________
int Int_t
const Data_t kBig
Definition DataType.h:15
uint32_t time
#define c(i)
bool Bool_t
double Double_t
char name[80]
static const char *const here
Definition THaVar.cxx:64
void Sort(Int_t upto=kMaxInt) override
virtual Int_t GetSize() const
virtual const char * Here(const char *) const
virtual THaDetector * GetDetector(const char *name)
TList * fDetectors
virtual Int_t SetRefDet(const char *name)
Definition THaHRS.cxx:119
Bool_t GetTrSorting() const
Definition THaHRS.cxx:71
Bool_t SetTrSorting(Bool_t set=false)
Definition THaHRS.cxx:63
virtual ~THaHRS()
Bool_t AutoStandardDetectors(Bool_t set=true)
Definition THaHRS.cxx:77
THaNonTrackingDetector * fRefDet
Definition THaHRS.h:36
@ kAutoStdDets
Definition THaHRS.h:41
@ kSortTracks
Definition THaHRS.h:40
THaHRS(const char *name, const char *description)
Definition THaHRS.cxx:50
virtual Int_t FindVertices(TClonesArray &tracks)
Definition THaHRS.cxx:165
virtual Int_t TrackCalc()
Definition THaHRS.cxx:219
virtual Int_t TrackTimes(TClonesArray *tracks)
Definition THaHRS.cxx:227
const TClonesArray * GetTrackHits() const
virtual Int_t AddDetector(THaDetector *det, Bool_t quiet=false, Bool_t first=false)
THaTrack * fGoldenTrack
Int_t GetNTracks() const
TClonesArray * fTracks
TList * fNonTrackingDetectors
Double_t GetPathLen() const
Int_t GetChannel() const
void Reset()
TObject * FindObject(const char *name) const override
TObject * At(Int_t idx) const override
Int_t GetLast() const override
void SetBit(UInt_t f)
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void Error(const char *method, const char *msgfmt,...) const
double beta(double x, double y)
constexpr Double_t C()
Double_t Sqrt(Double_t x)
STL namespace.
ClassImp(TPyArg)
void tracks()