Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaCherenkov.cxx
Go to the documentation of this file.
1
2// //
3// THaCherenkov //
4// //
5// Class for a generic Cherenkov consisting of one or more phototubes. //
6// //
8
9#include "THaCherenkov.h"
10#include "THaEvData.h"
11#include "THaDetMap.h"
12#include "VarDef.h"
13#include "VarType.h"
14#include "THaTrack.h"
15#include "TClonesArray.h"
16#include "TDatime.h"
17#include "TMath.h"
18
19#include <cstdlib>
20#include <cassert>
21#include <iostream>
22#include <iomanip>
23
24using namespace std;
25using namespace Podd;
26
27// Macro for better readability
28#if __cplusplus >= 201402L
29# define MKPMTDATA(name,title,nelem) make_unique<PMTData>((name),(title),(nelem))
30#else
31# define MKPMTDATA(name,title,nelem) unique_ptr<PMTData>(new PMTData((name),(title),(nelem)))
32#endif
33
34//_____________________________________________________________________________
35THaCherenkov::THaCherenkov( const char* name, const char* description,
36 THaApparatus* apparatus )
37 : THaPidDetector(name,description,apparatus), fPMTData(nullptr),
38 fASUM_p(kBig), fASUM_c(kBig)
39{
40 // Constructor
41}
42
43//_____________________________________________________________________________
45 : THaPidDetector(), fPMTData(nullptr), fASUM_p(kBig), fASUM_c(kBig)
46{
47 // Default constructor (for ROOT I/O)
48}
49
50//_____________________________________________________________________________
52{
53 // Read parameters from the database.
54 // 'date' contains the date/time of the run being analyzed.
55
56 const char* const here = "ReadDatabase";
57
58 VarType kDataType = std::is_same<Data_t, Float_t>::value ? kFloat : kDouble;
59 VarType kDataTypeV = std::is_same<Data_t, Float_t>::value ? kFloatV : kDoubleV;
60
61 // Read database
63 if( err )
64 return err;
65
66 FILE* file = OpenFile( date );
67 if( !file ) return kFileError;
68
69 // Read fOrigin and fSize (required!)
70 err = ReadGeometry( file, date, true );
71 if( err ) {
72 fclose(file);
73 return err;
74 }
75
76 enum { kModeUnset = -255, kCommonStop = 0, kCommonStart = 1 };
77
78 vector<Int_t> detmap;
79 Int_t nelem = 0;
80 Int_t tdc_mode = kModeUnset;
81 Data_t tdc2t = 5e-10; // TDC resolution (s/channel)
82
83 // Read configuration parameters
84 DBRequest config_request[] = {
85 { "detmap", &detmap, kIntV },
86 { "npmt", &nelem, kInt },
87 { "tdc.res", &tdc2t, kDataType, 0, true }, // optional to support old DBs
88 { "tdc.cmnstart", &tdc_mode, kInt, 0, true },
89 { nullptr }
90 };
91 err = LoadDB( file, date, config_request, fPrefix );
92
93 // Sanity checks
94 if( !err && nelem <= 0 ) {
95 Error( Here(here), "Invalid number of PMTs: %d. Must be > 0. "
96 "Fix database.", nelem );
97 err = kInitError;
98 }
99
100 // Reinitialization only possible for same basic configuration
101 if( !err ) {
102 if( fIsInit && nelem != fNelem ) {
103 Error( Here(here), "Cannot re-initialize with different number of PMTs. "
104 "(was: %d, now: %d). Detector not re-initialized.", fNelem, nelem );
105 err = kInitError;
106 } else
107 fNelem = nelem;
108 }
109
111 if( !err && FillDetMap(detmap, flags, here) <= 0 ) {
112 err = kInitError; // Error already printed by FillDetMap
113 }
114
115 const UInt_t nval = fNelem;
116 if( !err ) {
117 UInt_t tot_nchan = fDetMap->GetTotNumChan();
118 if( tot_nchan != 2*nval ) {
119 Error(Here(here), "Number of detector map channels (%u) "
120 "inconsistent with 2*number of PMTs (%d)",
121 tot_nchan, 2*fNelem);
122 err = kInitError;
123 }
124 }
125
126 // Deal with the TDC mode (common stop (default) vs. common start).
127 if( tdc_mode == kModeUnset ) {
128 // TDC mode not specified. Mimic the behavior of previous analyzer versions.
129 // TDCs are always common stop unless c.start mode is explicitly requested.
130 tdc_mode = kCommonStop;
131 } else {
132 // TDC mode IS explicitly specified
133 if( tdc_mode != kCommonStop && tdc2t < 0.0 ) {
134 // A negative TDC resolution, tdc2t, in a legacy databases indicates
135 // common stop mode. Warn user if tdc_mode and tdc2t are inconsistent.
136 // tdc_mode takes preference.
137 Warning(Here(here), "Negative TDC resolution = %lf converted to "
138 "positive since TDC mode explicitly set to common start.",tdc2t);
139 }
140 }
141 assert( tdc_mode != kModeUnset );
142 // Ensure tdc2t is positive. The tdc_mode flag handles the sign now.
143 tdc2t = TMath::Abs(tdc2t);
144
145 // Set module capability flags for legacy databases without model info
146 UInt_t nmodules = fDetMap->GetSize();
147 for( UInt_t i = 0; i < nmodules; i++ ) {
149 if( !d->model ) {
150 if( i < nmodules/2 ) d->MakeADC(); else d->MakeTDC();
151 }
152 if( d->IsTDC() ) {
153 d->SetTDCMode(tdc_mode);
154 }
155 }
156
157 if( err ) {
158 fclose(file);
159 return err;
160 }
161
162 fDetectorData.clear();
163 auto detdata = MKPMTDATA(GetPrefixName(), fTitle, nval);
164 fPMTData = detdata.get();
165 fDetectorData.emplace_back(std::move(detdata));
166 assert(fPMTData->GetSize() == nval);
167
168 // Read calibration parameters
169 vector<Data_t> off, ped, gain;
170 DBRequest calib_request[] = {
171 { "tdc.offsets", &off, kDataTypeV, nval, true },
172 { "adc.pedestals", &ped, kDataTypeV, nval, true },
173 { "adc.gains", &gain, kDataTypeV, nval, true },
174 { nullptr }
175 };
176 err = LoadDB( file, date, calib_request, fPrefix );
177 fclose(file);
178 if( err )
179 return err;
180
181 for( UInt_t i = 0; i < nval; ++i ) {
182 auto& calib = fPMTData->GetCalib(i);
183 calib.tdc2t = tdc2t;
184 calib.off = off[i];
185 calib.ped = ped[i];
186 calib.gain = gain[i];
187 }
188
189#ifdef WITH_DEBUG
190 // Debug printout
191 if ( fDebug > 2 ) {
192 const auto N = static_cast<UInt_t>(fNelem);
193 Double_t pos[3]; fOrigin.GetXYZ(pos);
194 DBRequest list[] = {
195 { "Number of mirrors", &fNelem, kInt },
196 { "Detector position", pos, kDouble, 3 },
197 { "Detector size", fSize, kDouble, 3 },
198 { "TDC offsets", &off, kDataTypeV, N },
199 { "ADC pedestals", &ped, kDataTypeV, N },
200 { "ADC gains", &gain, kDataTypeV, N },
201 { nullptr }
202 };
203 DebugPrint( list );
204 }
205#endif
206
207 fIsInit = true;
208 return kOK;
209}
210
211//_____________________________________________________________________________
213{
214 // Initialize global variables
215
216 // Set up standard variables, including objects in fDetectorData
218 if( ret )
219 return ret;
220
221 RVarDef vars[] = {
222 {"asum_p", "Sum of ADC minus pedestal values", "fASUM_p"},
223 {"asum_c", "Sum of corrected ADC amplitudes", "fASUM_c"},
224 {nullptr}
225 };
226 return DefineVarsFromList(vars, mode);
227}
228
229//_____________________________________________________________________________
231{
232 // Destructor. Remove variables from global list.
233
235}
236
237//_____________________________________________________________________________
239{
240 // Clear event data
241
243 fASUM_p = fASUM_c = 0;
244}
245
246//_____________________________________________________________________________
248{
249 // Put decoded frontend data into fDetectorData. Used by Decode().
250 // hitinfo: channel info (crate/slot/channel/hit/type)
251 // data: data registered in this channel
252
254
255 // Add channels with signals to the amplitude sums
256 const auto& PMT = fPMTData->GetPMT(hitinfo);
257 if( PMT.adc_p > 0 )
258 fASUM_p += PMT.adc_p; // Sum of ADC minus ped
259 if( PMT.adc_c > 0 )
260 fASUM_c += PMT.adc_c; // Sum of ADC corrected
261
262 return 0;
263}
264
265//_____________________________________________________________________________
267{
268 // Reconstruct coordinates of where a particle track crosses
269 // the Cherenkov plane, and copy the point into the fTrackProj array.
270
272
273 return 0;
274}
275
276//_____________________________________________________________________________
278{
279 // Fine Cherenkov processing
280
281 // Redo the track matching since tracks might have been thrown out
282 // during the FineTracking stage.
283
285
286 return 0;
287}
288
289//_____________________________________________________________________________
290void THaCherenkov::PrintDecodedData( const THaEvData& evdata ) const
291{
292 // Print decoded data (for debugging). Called form Decode()
293
294// cout << endl << endl;
295 cout << "Event " << evdata.GetEvNum() << " Trigger " << evdata.GetEvType()
296 << " Cherenkov " << GetPrefix() << endl;
297 int ncol=3;
298 for (int i=0; i<ncol; i++) {
299 cout << " Mirror TDC ADC ADC_p ";
300 }
301 cout << endl;
302
303 for (int i=0; i<(fNelem+ncol-1)/ncol; i++ ) {
304 for (int c=0; c<ncol; c++) {
305 int ind = c*fNelem/ncol+i;
306 if (ind < fNelem) {
307 const auto& PMT = fPMTData->GetPMT(ind);
308 cout << " " << setw(3) << ind+1;
309 cout << " "; WriteValue(PMT.tdc);
310 cout << " "; WriteValue(PMT.adc);
311 cout << " "; WriteValue(PMT.adc_p);
312 cout << " ";
313 } else {
314 // cout << endl;
315 break;
316 }
317 }
318 cout << endl;
319 }
320}
321
322//_____________________________________________________________________________
#define kOK
Definition BdataLoc.cxx:40
#define kInitError
Definition BdataLoc.cxx:41
int Int_t
unsigned int UInt_t
Double_t Data_t
Definition DataType.h:13
const Data_t kBig
Definition DataType.h:15
#define d(i)
#define c(i)
#define e(i)
double Double_t
const char Option_t
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char mode
char name[80]
#define MKPMTDATA(name, title, nelem)
static const char *const here
Definition THaVar.cxx:64
PMTData_t & GetPMT(size_t i)
UInt_t GetSize() const override
PMTCalib_t & GetCalib(size_t i)
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
const char * GetPrefix() const
virtual Int_t ReadDatabase(const TDatime &date)
TString GetPrefixName() const
virtual Int_t DefineVariables(EMode mode=kDefine)
virtual FILE * OpenFile(const TDatime &date)
virtual Int_t ReadDatabase(const TDatime &date)
virtual void PrintDecodedData(const THaEvData &evdata) const
virtual Int_t CoarseProcess(TClonesArray &tracks)
virtual Int_t FineProcess(TClonesArray &tracks)
virtual Int_t DefineVariables(EMode mode=kDefine)
Podd::PMTData * fPMTData
virtual void Clear(Option_t *="")
virtual Int_t StoreHit(const DigitizerHitInfo_t &hitinfo, UInt_t data)
virtual ~THaCherenkov()
UInt_t GetSize() const
Definition THaDetMap.h:125
@ kFillLogicalChannel
Definition THaDetMap.h:96
Module * GetModule(UInt_t i) const
Definition THaDetMap.h:248
UInt_t GetTotNumChan() const
Int_t FillDetMap(const std::vector< Int_t > &values, UInt_t flags=0, const char *here="FillDetMap")
THaDetMap * fDetMap
virtual Int_t StoreHit(const DigitizerHitInfo_t &hitinfo, UInt_t data)
virtual Int_t ReadGeometry(FILE *file, const TDatime &date, Bool_t required=false)
Double_t fSize[3]
VecDetData_t fDetectorData
UInt_t GetEvType() const
Definition THaEvData.h:53
UInt_t GetEvNum() const
Definition THaEvData.h:56
Int_t CalcTrackProj(TClonesArray &tracks)
TString fTitle
void Clear(Option_t *option="") override
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual void Error(const char *method, const char *msgfmt,...) const
void GetXYZ(Double_t *carray) const
Double_t Abs(Double_t d)
STL namespace.
ClassImp(TPyArg)
void tracks()