Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//*-- Author : Stephen Wood 20-Apr-2012
//////////////////////////////////////////////////////////////////////////
//
// THcHallCSpectrometer
//
// A standard Hall C spectrometer.
// Contains no standard detectors,
// May add hodoscope
//
// The usual name of this object is either "H", "S", or "P"
// for HMS, SOS, or suPerHMS respectively
//
// Defines the functions FindVertices() and TrackCalc(), which are common
// to both the LeftHRS and the RightHRS.
//
// Special configurations of the HRS (e.g. more detectors, different
// detectors) can be supported in on e of three ways:
//
// 1. Use the AddDetector() method to include a new detector
// in this apparatus. The detector will be decoded properly,
// and its variables will be available for cuts and histograms.
// Its processing methods will also be called by the generic Reconstruct()
// algorithm implemented in THaSpectrometer::Reconstruct() and should
// be correctly handled if the detector class follows the standard
// interface design.
//
// 2. Write a derived class that creates the detector in the
// constructor. Write a new Reconstruct() method or extend the existing
// one if necessary.
//
// 3. Write a new class inheriting from THaSpectrometer, using this
// class as an example. This is appropriate if your HRS
// configuration has fewer or different detectors than the
// standard HRS. (It might not be sensible to provide a RemoveDetector()
// method since Reconstruct() relies on the presence of the
// standard detectors to some extent.)
//
// For timing calculations, S1 is treated as the scintillator at the
// 'reference distance', corresponding to the pathlength correction
// matrix.
//
//////////////////////////////////////////////////////////////////////////
#include "THcHallCSpectrometer.h"
#include "THaTrackingDetector.h"
#include "THaTrack.h"
#include "THaTrackProj.h"
#include "THaTriggerTime.h"
#include "TMath.h"
#include "TList.h"
#include "TList.h"
#include "TMath.h"
#ifdef WITH_DEBUG
#include <iostream>
#endif
using namespace std;
//_____________________________________________________________________________
THcHallCSpectrometer::THcHallCSpectrometer( const char* name, const char* description ) :
THaSpectrometer( name, description )
{
// Constructor. Defines the standard detectors for the HRS.
// AddDetector( new THaTriggerTime("trg","Trigger-based time offset"));
//sc_ref = static_cast<THaScintillator*>(GetDetector("s1"));
SetTrSorting(kFALSE);
}
//_____________________________________________________________________________
THcHallCSpectrometer::~THcHallCSpectrometer()
{
// Destructor
}
//_____________________________________________________________________________
Bool_t THcHallCSpectrometer::SetTrSorting( Bool_t set )
{
if( set )
fProperties |= kSortTracks;
else
fProperties &= ~kSortTracks;
return set;
}
//_____________________________________________________________________________
Bool_t THcHallCSpectrometer::GetTrSorting() const
{
return ((fProperties & kSortTracks) != 0);
}
//_____________________________________________________________________________
Int_t THcHallCSpectrometer::FindVertices( TClonesArray& tracks )
{
// Reconstruct target coordinates for all tracks found in the focal plane.
TIter nextTrack( fTrackingDetectors );
nextTrack.Reset();
while( THaTrackingDetector* theTrackDetector =
static_cast<THaTrackingDetector*>( nextTrack() )) {
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "Call FineTrack() for "
<< theTrackDetector->GetName() << "... ";
#endif
theTrackDetector->FindVertices( tracks );
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "done.\n";
#endif
}
// If enabled, sort the tracks by chi2/ndof
if( GetTrSorting() )
fTracks->Sort();
// Find the "Golden Track".
if( GetNTracks() > 0 ) {
// Select first track in the array. If there is more than one track
// and track sorting is enabled, then this is the best fit track
// (smallest chi2/ndof). Otherwise, it is the track with the best
// geometrical match (smallest residuals) between the U/V clusters
// in the upper and lower VDCs (old behavior).
//
// Chi2/dof is a well-defined quantity, and the track selected in this
// way is immediately physically meaningful. The geometrical match
// criterion is mathematically less well defined and not usually used
// in track reconstruction. Hence, chi2 sortiing is preferable, albeit
// obviously slower.
fGoldenTrack = static_cast<THaTrack*>( fTracks->At(0) );
fTrkIfo = *fGoldenTrack;
fTrk = fGoldenTrack;
} else
fGoldenTrack = NULL;
return 0;
}
//_____________________________________________________________________________
Int_t THcHallCSpectrometer::TrackCalc()
{
// Additioal track calculations. At present, we only calculate beta here.
return TrackTimes( fTracks );
}
//_____________________________________________________________________________
Int_t THcHallCSpectrometer::TrackTimes( TClonesArray* Tracks ) {
// Do the actual track-timing (beta) calculation.
// Use multiple scintillators to average together and get "best" time at S1.
//
// To be useful, a meaningful timing resolution should be assigned
// to each Scintillator object (part of the database).
if ( !Tracks ) return -1;
THaTrack *track=0;
Int_t ntrack = GetNTracks();
// linear regression to: t = t0 + pathl/(beta*c)
// where t0 is the time of the track at the reference plane (sc_ref).
// t0 and beta are solved for.
//
#if 0
for ( Int_t i=0; i < ntrack; i++ ) {
track = static_cast<THaTrack*>(Tracks->At(i));
THaTrackProj* tr_ref = static_cast<THaTrackProj*>
(sc_ref->GetTrackHits()->At(i));
Double_t pathlref = tr_ref->GetPathLen();
Double_t wgt_sum=0.,wx2=0.,wx=0.,wxy=0.,wy=0.;
Int_t ncnt=0;
// linear regression to get beta and time at ref.
TIter nextSc( fNonTrackingDetectors );
THaNonTrackingDetector *det;
while ( ( det = static_cast<THaNonTrackingDetector*>(nextSc()) ) ) {
THaScintillator *sc = dynamic_cast<THaScintillator*>(det);
if ( !sc ) continue;
const THaTrackProj *trh = static_cast<THaTrackProj*>(sc->GetTrackHits()->At(i));
Int_t pad = trh->GetChannel();
if (pad<0) continue;
Double_t pathl = (trh->GetPathLen()-pathlref);
Double_t time = (sc->GetTimes())[pad];
Double_t wgt = (sc->GetTuncer())[pad];
if (pathl>.5*kBig || time>.5*kBig) continue;
if (wgt>0) wgt = 1./(wgt*wgt);
else continue;
wgt_sum += wgt;
wx2 += wgt*pathl*pathl;
wx += wgt*pathl;
wxy += wgt*pathl*time;
wy += wgt*time;
ncnt++;
}
Double_t beta = kBig;
Double_t dbeta = kBig;
Double_t time = kBig;
Double_t dt = kBig;
Double_t delta = wgt_sum*wx2-wx*wx;
if (delta != 0.) {
time = (wx2*wy-wx*wxy)/delta;
dt = TMath::Sqrt(wx2/delta);
Double_t invbeta = (wgt_sum*wxy-wx*wy)/delta;
if (invbeta != 0.) {
#if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
Double_t c = TMath::C();
#else
Double_t c = 2.99792458e8;
#endif
beta = 1./(c*invbeta);
dbeta = TMath::Sqrt(wgt_sum/delta)/(c*invbeta*invbeta);
}
}
track->SetBeta(beta);
track->SetdBeta(dbeta);
track->SetTime(time);
track->SetdTime(dt);
}
#endif
return 0;
}
//_____________________________________________________________________________
ClassImp(THcHallCSpectrometer)