-
Notifications
You must be signed in to change notification settings - Fork 37
/
SBSCherenkovDetector.cxx
328 lines (268 loc) · 10.4 KB
/
SBSCherenkovDetector.cxx
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
// *-- Author : Guido Maria Urciuoli 12 March 2001
//////////////////////////////////////////////////////////////////////////
//
// SBSCherenkovDetector
//
// The RICH detector
// Written by Guido Maria Urciuoli, INFN
// Adapted for Hall A Analyzer by Ole Hansen, JLab
// Adapted to SBS by Seamus Riordan, ANL and Eric Fuchey, UConn
//
//////////////////////////////////////////////////////////////////////////
#include "TMath.h"
#include "SBSCherenkovDetector.h"
#include "THaTrack.h"
#include "THaEvData.h"
#include "THaGlobals.h"
#include "THaDetMap.h"
#include "THaSpectrometer.h"
#include "TError.h"
#include "VarDef.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include "THaBenchmark.h"
using namespace std;
// cout<<"stay and stop here!!!"<<endl;
//_____________________________________________________________________________
SBSCherenkovDetector::SBSCherenkovDetector( const char* name, const char* description,
THaApparatus* apparatus ) :
SBSGenericDetector(name,description,apparatus),
fDoResolve(false), fDoTimeFilter(false)//,
//fTrackX(kBig), fTrackY(kBig)
{
SetModeTDC(SBSModeTDC::kTDC); // A TDC with leading & trailing edge info
SetModeADC(SBSModeADC::kNone); // Default is No ADC, but can be re-enabled later
//keep this line first
fBench = new THaBenchmark;
// Normal constructor with name and description
fHits = new TClonesArray("SBSCherenkov_Hit",500);
fClusters = new TClonesArray("SBSCherenkov_Cluster",50);
//fEmptyCluster = new SBSCherenkov_Cluster(); //dummy instance of cluster to initialize best cluster pointer for events with no found clusters
// fBestCluster = nullptr;
//fEmptyCluster->SetXcenter(kBig);
//fEmptyCluster->SetYcenter(kBig);
//The above lines are not necessary as we have other handles to identify events with no clusters found
//fBestCluster = fEmptyCluster;
//set default timing cuts wide open, these values are somewhat arbitrary:
fHit_tmin = -1000.0;
fHit_tmax = 4000.0;
Clear();
//fDebug=1;
}
//_____________________________________________________________________________
SBSCherenkovDetector::~SBSCherenkovDetector()
{
// Destructor. Remove variables from global list and free up the memory
// allocated by us.
Clear();// so the prgram doesn't complain when deleting clusters
RemoveVariables();
delete fHits;
// delete fResolvedHits;
delete fClusters;
// delete fResolvedClusters;
// delete [] fMIPs;
// delete [] fXseg;
delete fBench;
}
//_____________________________________________________________________________
void SBSCherenkovDetector::Clear( Option_t* opt )
{
// Reset event-by-event data
if(fDebug)cout << "SBSCherenkovDetector::Clear() " << endl;
if( fDoBench ) fBench->Begin("Clear");
SBSGenericDetector::Clear(opt);
if(fDebug)cout << "Clear hits() " << endl;
fHits->Clear("C");
//fResolvedHits->Clear();
DeleteClusters();
fNtrackMatch = 0;
fBestCluster.Clear("F");
if( fDoBench ) fBench->Stop("Clear");
}
//_____________________________________________________________________________
Int_t SBSCherenkovDetector::ReadDatabase( const TDatime& date )
{
//
// Read the database for this detector.
// This function is called once at the beginning of the analysis.
// 'date' contains the date/time of the run being analyzed.
//
static const char* const here = "ReadDatabase";
cout << here << endl;
// Open the database file
FILE* fi = OpenFile( date );
if( !fi ) return kFileError;
Int_t err = SBSGenericDetector::ReadDatabase(date);
if(err) {
return err;
}
fIsInit = false;
std::vector<Double_t> xpos,ypos;
std::vector<Double_t> amp_tot_coeffs;
DBRequest config_request[] = {
{ "xpos", &xpos, kDoubleV, 0, 1 },
{ "ypos", &ypos, kDoubleV, 0, 1 },
{ "hit_mintime", &fHit_tmin, kDouble, 0, 1 },
{ "hit_maxtime", &fHit_tmax, kDouble, 0, 1 },
{ "amp_tot_coeffs", &_tot_coeffs, kDoubleV, 0, true },
{ 0 } ///< Request must end in a NULL
};
err = LoadDB( fi, date, config_request, fPrefix );
fAmpToTCoeff.clear();
if(int(amp_tot_coeffs.size())==fNelem){
for(size_t i = 0; i<amp_tot_coeffs.size(); i++){
fAmpToTCoeff.push_back(amp_tot_coeffs[i]);
}
}else{
fAmpToTCoeff.push_back(1.0);
}
if (!xpos.empty()) {
if ((int)xpos.size() == fNelem) {
for (Int_t ne=0;ne<fNelem;ne++) {
fElements[ne]->SetX(xpos[ne]);
}
} else {
std::cout << " vector too small " << xpos.size() << " # of elements =" << fNelem << std::endl;
}
}
//
if (!ypos.empty()) {
if ((int)ypos.size() == fNelem) {
for (Int_t ne=0;ne<fNelem;ne++) {
fElements[ne]->SetY(ypos[ne]);
}
} else {
std::cout << " ypos vector too small " << ypos.size() << " # of elements =" << fNelem << std::endl;
}
}
fIsInit = true;
fclose(fi);
return kOK;
}
//_____________________________________________________________________________
Int_t SBSCherenkovDetector::DefineVariables( EMode mode )
{
// Define (or delete) global variables of the detector
if( mode == kDefine && fIsSetup ) return kOK;
//fIsSetup = ( mode == kDefine );
Int_t err = SBSGenericDetector::DefineVariables(mode);
if(err)
return err;
//Hits hits
RVarDef var1[] = {
{ "ngoodhits", " number of PMT hits", "GetNumHits()" },
{ "hit.pmtnum", " Hit PMT num", "fHits.SBSCherenkov_Hit.GetPMTNum()" },
{ "hit.row", " PMT hit row", "fHits.SBSCherenkov_Hit.GetRow()" },
{ "hit.col", " PMT hit column", "fHits.SBSCherenkov_Hit.GetCol()" },
{ "hit.xhit", " PMT hit X", "fHits.SBSCherenkov_Hit.GetX()" },
{ "hit.yhit", " PMT hit y", "fHits.SBSCherenkov_Hit.GetY()" },
{ "hit.amp", " PMT hit amplitude", "fHits.SBSCherenkov_Hit.GetAmp()" },
{ "hit.time", " PMT hit time", "fHits.SBSCherenkov_Hit.GetTime()" },
{ "hit.clustindex", " Index of cluster to which this hit belongs", "fHits.SBSCherenkov_Hit.GetClustIndex()" },
{ "hit.trackindex", " Index of track to which this hit belongs", "fHits.SBSCherenkov_Hit.GetTrackIndex()" },
{ "ntrackmatch", "Number of track-matched clusters", "fNtrackMatch" },
{ 0 }
};
DefineVarsFromList( var1, mode, "" );// (re)define path here...
// RVarDef var2[] = {
// { "nclus", " number of GRINCH PMT clusters", "GetNumClusters()" },
// { "clus.size", " GRINCH cluster size", "fClusters.SBSCherenkov_Cluster.GetNHits()" },
// { "clus.x_mean", " GRINCH cluster X center", "fClusters.SBSCherenkov_Cluster.GetXcenter()" },
// { "clus.y_mean", " GRINCH cluster Y center", "fClusters.SBSCherenkov_Cluster.GetYcenter()" },
// { "clus.tr_mean", " GRINCH cluster mean lead time", "fClusters.SBSCherenkov_Cluster.GetMeanRisingTime()" },
// { "clus.tf_mean", " GRINCH cluster mean trail time", "fClusters.SBSCherenkov_Cluster.GetMeanFallingTime()" },
// { "clus.adc", " GRINCH cluster total charge", "fClusters.SBSCherenkov_Cluster.GetCharge()" },
// { 0 }
// };
// DefineVarsFromList( var2, mode, "" );// (re)define path here...
return kOK;
}
//_____________________________________________________________________________
Int_t SBSCherenkovDetector::Decode( const THaEvData& evdata )
{
//Decode RICH data and fill hit array
if(fDebug){
cout << "SBSCherenkovDetector::Decode " << endl;
cout << " Is Init ? " << fIsInit << " Is Physics Trigger ? " << evdata.IsPhysicsTrigger() << endl;
}
if( !fIsInit ) return -255;
if( !evdata.IsPhysicsTrigger() ) return -1;
if( fDoBench ) fBench->Begin("Decode");
SBSGenericDetector::Decode(evdata);
if(fDebug)cout << "Finished decoding" << endl;
if( fDoBench ) fBench->Stop("Decode");
return GetNumHits();
}
//_____________________________________________________________________________
Int_t SBSCherenkovDetector::CoarseProcess( TClonesArray& tracks )
{
//
if(fDebug)cout << "Begin Coarse Process" << endl;
if( fDoBench ) fBench->Begin("CoarseProcess");
SBSGenericDetector::CoarseProcess(tracks);
double amp, x, y;
//double tmin, tmax;
Int_t nHit = 0;
SBSCherenkov_Hit* the_hit = nullptr;
fNtrackMatch = 0;
for(int k = 0; k<fNGoodTDChits; k++){
//tmin = -fElements[fGood.TDCelemID[k]]->TDC()->GetGoodTimeCut();
//tmax = +fElements[fGood.TDCelemID[k]]->TDC()->GetGoodTimeCut();
//double t0 = fElements[fGood.TDCelemID[k]]->TDC()->GetGoodTimeCut();
// if(tmin<=fGood.t[k] && fGood.t[k]<=tmax){
if( fHit_tmin <= fGood.t[k] && fGood.t[k] <= fHit_tmax ){
the_hit = new( (*fHits)[nHit++] ) SBSCherenkov_Hit();
the_hit->SetPMTNum(fGood.TDCelemID[k]);
the_hit->SetRow(fGood.TDCrow[k]);
the_hit->SetCol(fGood.TDCcol[k]);
the_hit->SetTime(fGood.t[k]);
x = (fElements[fGood.TDCelemID[k]])->GetX();
y = (fElements[fGood.TDCelemID[k]])->GetY();
if(k<(int)fAmpToTCoeff.size()){
amp = fGood.t_ToT[k]*fAmpToTCoeff[k];
}else{// we should be guaranteed that the array has at least one element
amp = fGood.t_ToT[k]*fAmpToTCoeff[0];
}
the_hit->SetX(x);
the_hit->SetY(y);
the_hit->SetAmp(amp);
}
}
//clustering to be done by dereived class...
if( fDoBench ) fBench->Stop("CoarseProcess");
if(fDebug)cout << "End Coarse Process" << endl;
return 0;
}
//_____________________________________________________________________________
Int_t SBSCherenkovDetector::FineProcess( TClonesArray& tracks )
{
// fine processing like association with tracks belong to
// derived classes such as SBSGRINCH
return 0;
}
//__________________________________________________________________________
void SBSCherenkovDetector::DeleteClusters()
{
//Delete all clusters
if(fDebug)cout << "Clear Clusters" << endl;
fClusters->Clear("C");
//fResolvedClusters->Clear("C");
}
//_____________________________________________________________________________
void SBSCherenkovDetector::PrintBenchmarks() const
{
// Print benchmark results
if( !fDoBench )
return;
fBench->Print("Clear");
fBench->Print("Decode");
fBench->Print("FineProcess");
fBench->Print("FindClusters");
//cout << endl << "Breakdown of time spent in FineProcess:" << endl;
}
ClassImp(SBSCherenkovDetector)