c12208b8 |
1 | /* |
9c754ce7 |
2 | TPC DA for online calibration |
3 | |
4 | Contact: Haavard.Helstrup@cern.ch |
5 | Link: |
1b37fc95 |
6 | Run Type: PEDESTAL |
9c754ce7 |
7 | DA Type: LDC |
8 | Number of events needed: 100 |
9 | Input Files: |
10 | Output Files: tpcPedestal.root, to be exported to the DAQ FXS |
bd955ed2 |
11 | fileId: pedestals |
9c754ce7 |
12 | Trigger types used: CALIBRATION_EVENT |
13 | |
14 | */ |
15 | |
9c754ce7 |
16 | /* |
c12208b8 |
17 | |
18 | TPCda_pedestal.cxx - calibration algorithm for TPC pedestal runs |
19 | |
20 | 10/06/2007 sylvain.chapeland@cern.ch : first version - clean skeleton based on DAQ DA case1 |
49efac78 |
21 | 19/10/2007 christian.lippmann@cern.ch : Possibility to write output to ASCII file |
22 | 24/10/2007 christian.lippmann@cern.ch : Including pedestal calibration for time bins |
23 | 23/11/2007 christian.lippmann@cern.ch : Fix in order to avoid streamer problems in case of |
24 | invalid ROOTSTYS. The famous magic line provided by Rene. |
25 | 28/11/2007 christian.lippmann@cern.ch : TPC mapping file is read from DaqDetDB |
ac940b58 |
26 | 18/09/2008 christian.lippmann@cern.ch : Noisy channels are output to ASCII file. Use max noise in ALTRO. |
27 | 19/09/2008 J.Wiechula@gsi.de: Added export of the calibration data to the AMORE data base. |
28 | Added support for configuration files. |
c12208b8 |
29 | |
30 | contact: marian.ivanov@cern.ch |
31 | |
c12208b8 |
32 | This process reads RAW data from the files provided as command line arguments |
33 | and save results in a file (named from RESULT_FILE define - see below). |
34 | |
35 | */ |
36 | |
49efac78 |
37 | #define RESULT_FILE "tpcPedestal.root" |
bd955ed2 |
38 | #define FILE_ID "pedestals" |
49efac78 |
39 | #define MAPPING_FILE "tpcMapping.root" |
ac940b58 |
40 | #define CONFIG_FILE "TPCPEDESTALda.conf" |
b401648b |
41 | #define AliDebugLevel() -1 |
c12208b8 |
42 | |
43 | extern "C" { |
44 | #include <daqDA.h> |
45 | } |
46 | #include "event.h" |
47 | #include "monitor.h" |
49efac78 |
48 | |
49 | #include "stdio.h" |
50 | #include "stdlib.h" |
51 | #include <fstream> |
c12208b8 |
52 | |
53 | // |
54 | //Root includes |
55 | // |
49efac78 |
56 | #include "TFile.h" |
57 | #include "TArrayF.h" |
58 | #include "TROOT.h" |
59 | #include "TPluginManager.h" |
ac940b58 |
60 | #include "TSystem.h" |
61 | #include "TString.h" |
62 | #include "TObjString.h" |
63 | #include "TDatime.h" |
c12208b8 |
64 | // |
65 | //AliRoot includes |
66 | // |
67 | #include "AliRawReader.h" |
68 | #include "AliRawReaderDate.h" |
87d57858 |
69 | #include "AliTPCmapper.h" |
c12208b8 |
70 | #include "AliTPCRawStream.h" |
71 | #include "AliTPCROC.h" |
72 | #include "AliTPCCalROC.h" |
73 | #include "AliTPCCalPad.h" |
74 | #include "AliMathBase.h" |
75 | #include "TTreeStream.h" |
b401648b |
76 | #include "AliLog.h" |
ac940b58 |
77 | #include "AliTPCConfigDA.h" |
78 | |
79 | // |
80 | //AMORE |
81 | // |
82 | #include <AmoreDA.h> |
c12208b8 |
83 | |
84 | // |
85 | // TPC calibration algorithm includes |
86 | // |
87 | #include "AliTPCCalibPedestal.h" |
88 | |
bdf99a93 |
89 | /* |
90 | Main routine, TPC pedestal detector algorithm to be run on TPC LDC |
91 | Arguments: list of DATE raw data files |
c12208b8 |
92 | */ |
bdf99a93 |
93 | |
c12208b8 |
94 | int main(int argc, char **argv) { |
bdf99a93 |
95 | // |
96 | // Main for TPC pedestal detector algorithm |
97 | // |
ac940b58 |
98 | /* log start of process */ |
99 | printf("TPC DA started - %s\n",__FILE__); |
100 | |
c12208b8 |
101 | if (argc<2) { |
102 | printf("Wrong number of arguments\n"); |
103 | return -1; |
104 | } |
ac940b58 |
105 | AliLog::SetClassDebugLevel("AliTPCRawStream",-5); |
106 | AliLog::SetClassDebugLevel("AliRawReaderDate",-5); |
107 | AliLog::SetClassDebugLevel("AliTPCAltroMapping",-5); |
108 | AliLog::SetModuleDebugLevel("RAW",-5); |
c12208b8 |
109 | |
49efac78 |
110 | /* magic line */ |
111 | gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo", |
ac940b58 |
112 | "*", |
113 | "TStreamerInfo", |
114 | "RIO", |
115 | "TStreamerInfo()"); |
c12208b8 |
116 | |
c12208b8 |
117 | /* declare monitoring program */ |
ac940b58 |
118 | int i, status; |
c12208b8 |
119 | status=monitorDeclareMp( __FILE__ ); |
120 | if (status!=0) { |
121 | printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status)); |
122 | return -1; |
123 | } |
ac940b58 |
124 | |
125 | // variables |
b401648b |
126 | AliTPCmapper *mapping = 0; // The TPC mapping |
ac940b58 |
127 | char localfile[255]; |
128 | unsigned long32 runNb=0; // run number |
129 | // configuration options |
130 | Bool_t timeAnalysis = kTRUE; |
131 | Bool_t fastDecoding = kFALSE; |
132 | |
b401648b |
133 | if (!mapping){ |
134 | /* copy locally the mapping file from daq detector config db */ |
ac940b58 |
135 | sprintf(localfile,"./%s",MAPPING_FILE); |
136 | status = daqDA_DB_getFile(MAPPING_FILE,localfile); |
b401648b |
137 | if (status) { |
138 | printf("Failed to get mapping file (%s) from DAQdetDB, status=%d\n", MAPPING_FILE, status); |
ac940b58 |
139 | return -1; |
b401648b |
140 | } |
49efac78 |
141 | |
b401648b |
142 | /* open the mapping file and retrieve mapping object */ |
143 | TFile *fileMapping = new TFile(MAPPING_FILE, "read"); |
144 | mapping = (AliTPCmapper*) fileMapping->Get("tpcMapping"); |
49efac78 |
145 | delete fileMapping; |
b401648b |
146 | } |
147 | |
148 | if (mapping == 0) { |
149 | printf("Failed to get mapping object from %s. ...\n", MAPPING_FILE); |
ac940b58 |
150 | return -1; |
49efac78 |
151 | } else { |
152 | printf("Got mapping object from %s\n", MAPPING_FILE); |
153 | } |
154 | |
ac940b58 |
155 | // |
156 | // DA configuration from configuration file |
157 | // |
158 | // retrieve configuration file |
159 | sprintf(localfile,"./%s",CONFIG_FILE); |
160 | status = daqDA_DB_getFile(CONFIG_FILE,localfile); |
161 | if (status) { |
162 | printf("Failed to get configuration file (%s) from DAQdetDB, status=%d\n", CONFIG_FILE, status); |
163 | return -1; |
164 | } |
165 | AliTPCConfigDA config(CONFIG_FILE); |
166 | // check configuration |
167 | if ( (Int_t)config.GetValue("NoTimeAnalysis") == 1 ) { |
168 | printf("WARNING: Time analysis was switched off in the configuration file!\n"); |
169 | timeAnalysis=kFALSE; |
170 | } |
171 | if ( (Int_t)config.GetValue("UseFastDecoder") == 1 ){ |
172 | printf("Info: The fast decoder will be used for the processing.\n"); |
173 | fastDecoding=kTRUE; |
b401648b |
174 | } |
ac940b58 |
175 | |
176 | // create calibration object |
177 | AliTPCCalibPedestal calibPedestal(config.GetConfigurationMap()); // pedestal and noise calibration |
178 | calibPedestal.SetAltroMapping(mapping->GetAltroMapping()); // Use altro mapping we got from daqDetDb |
30255695 |
179 | calibPedestal.SetTimeAnalysis(timeAnalysis); // pedestal(t) calibration |
ac940b58 |
180 | |
181 | //===========================// |
182 | // loop over RAW data files // |
183 | //==========================// |
c12208b8 |
184 | int nevents=0; |
bdf99a93 |
185 | for ( i=1; i<argc; i++ ) { |
ac940b58 |
186 | |
c12208b8 |
187 | /* define data source : this is argument i */ |
188 | printf("Processing file %s\n", argv[i]); |
189 | status=monitorSetDataSource( argv[i] ); |
190 | if (status!=0) { |
49efac78 |
191 | printf("monitorSetDataSource() failed. Error=%s. Exiting ...\n", monitorDecodeError(status)); |
c12208b8 |
192 | return -1; |
193 | } |
ac940b58 |
194 | |
c12208b8 |
195 | /* read until EOF */ |
bdf99a93 |
196 | for ( ; ; ) { |
c12208b8 |
197 | struct eventHeaderStruct *event; |
ac940b58 |
198 | |
c12208b8 |
199 | /* check shutdown condition */ |
200 | if (daqDA_checkShutdown()) {break;} |
ac940b58 |
201 | |
c12208b8 |
202 | /* get next event (blocking call until timeout) */ |
203 | status=monitorGetEventDynamic((void **)&event); |
204 | if (status==MON_ERR_EOF) { |
ac940b58 |
205 | printf ("End of File %d (%s) detected\n", i, argv[i]); |
206 | break; /* end of monitoring file has been reached */ |
c12208b8 |
207 | } |
ac940b58 |
208 | |
c12208b8 |
209 | if (status!=0) { |
ac940b58 |
210 | printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status)); |
211 | break; |
c12208b8 |
212 | } |
213 | |
bdf99a93 |
214 | /* skip start/end of run events */ |
215 | if ( (event->eventType != physicsEvent) && (event->eventType != calibrationEvent) ) |
ac940b58 |
216 | continue; |
bdf99a93 |
217 | |
c12208b8 |
218 | /* retry if got no event */ |
49efac78 |
219 | if (event==NULL) |
ac940b58 |
220 | continue; |
221 | |
c12208b8 |
222 | nevents++; |
ac940b58 |
223 | // get the run number |
224 | runNb = event->eventRunNb; |
c12208b8 |
225 | // Pedestal calibration |
5312f439 |
226 | calibPedestal.ProcessEvent(event); |
c12208b8 |
227 | |
228 | /* free resources */ |
229 | free(event); |
230 | } |
231 | } |
232 | |
49efac78 |
233 | // |
234 | // Analyse pedestals and write them to rootfile |
235 | // |
49efac78 |
236 | calibPedestal.Analyse(); |
237 | calibPedestal.AnalyseTime(nevents); |
238 | printf ("%d physics/calibration events processed.\n",nevents); |
c12208b8 |
239 | |
bdf99a93 |
240 | TFile *fileTPC = new TFile(RESULT_FILE, "recreate"); |
e73181c9 |
241 | calibPedestal.Write("tpcCalibPedestal"); |
c12208b8 |
242 | delete fileTPC; |
49efac78 |
243 | printf("Wrote %s.\n",RESULT_FILE); |
f2c72763 |
244 | |
ac940b58 |
245 | /* store the result file on FES */ |
246 | status=daqDA_FES_storeFile(RESULT_FILE,FILE_ID); |
247 | if (status) { |
248 | status = -2; |
249 | } |
250 | // |
251 | //Send objects to the AMORE DB |
252 | // |
253 | printf ("AMORE part\n"); |
254 | const char *amoreDANameorig=gSystem->Getenv("AMORE_DA_NAME"); |
255 | //cheet a little -- temporary solution (hopefully) |
256 | // |
257 | //currently amoreDA uses the environment variable AMORE_DA_NAME to create the mysql |
258 | //table in which the calib objects are stored. This table is dropped each time AmoreDA |
259 | //is initialised. This of course makes a problem if we would like to store different |
260 | //calibration entries in the AMORE DB. Therefore in each DA which writes to the AMORE DB |
261 | //the AMORE_DA_NAME env variable is overwritten. |
6a02fd57 |
262 | |
263 | //find processed sector |
264 | Char_t sideName='A'; |
265 | Int_t sector = 0; |
266 | for ( Int_t roc = 0; roc < 72; roc++ ) { |
267 | if ( !calibPedestal.GetCalRocPedestal(roc) ) continue; |
268 | if (mapping->GetSideFromRoc(roc)==1) sideName='C'; |
269 | sector = mapping->GetSectorFromRoc(roc); |
ac940b58 |
270 | } |
6a02fd57 |
271 | gSystem->Setenv("AMORE_DA_NAME",Form("TPC-%c%02d-%s",sideName,sector,FILE_ID)); |
f2c72763 |
272 | |
6a02fd57 |
273 | // |
274 | // end cheet |
275 | TDatime time; |
276 | TObjString info(Form("Run: %u; Date: %s",runNb,time.AsString())); |
277 | |
278 | amore::da::AmoreDA amoreDA(amore::da::AmoreDA::kSender); |
279 | Int_t statusDA=0; |
280 | statusDA+=amoreDA.Send("Pedestals",calibPedestal.GetCalPadPedestal()); |
281 | statusDA+=amoreDA.Send("Noise",calibPedestal.GetCalPadRMS()); |
282 | statusDA+=amoreDA.Send("Info",&info); |
283 | if ( statusDA ) |
284 | printf("Waring: Failed to write one of the calib objects to the AMORE database\n"); |
285 | // reset env var |
286 | if (amoreDANameorig) gSystem->Setenv("AMORE_DA_NAME",amoreDANameorig); |
f2c72763 |
287 | |
ac940b58 |
288 | |
bdf99a93 |
289 | // |
49efac78 |
290 | // Now prepare ASCII files for local ALTRO configuration through DDL. |
bdf99a93 |
291 | // |
bdf99a93 |
292 | ofstream pedfile; |
293 | ofstream noisefile; |
294 | ofstream pedmemfile; |
ac940b58 |
295 | ofstream noisychannelfile; |
296 | |
87d57858 |
297 | char filename[255]; |
bdf99a93 |
298 | sprintf(filename,"tpcPedestals.data"); |
299 | pedfile.open(filename); |
300 | sprintf(filename,"tpcNoise.data"); |
301 | noisefile.open(filename); |
302 | sprintf(filename,"tpcPedestalMem.data"); |
303 | pedmemfile.open(filename); |
ac940b58 |
304 | sprintf(filename,"tpcNoisyChannels.data"); |
305 | noisychannelfile.open(filename); |
bdf99a93 |
306 | |
49efac78 |
307 | TArrayF **timePed = calibPedestal.GetTimePedestals(); // pedestal values for each time bin |
87d57858 |
308 | |
bdf99a93 |
309 | Int_t ctr_channel = 0; |
ac940b58 |
310 | Int_t ctr_altro = 0; |
bdf99a93 |
311 | Int_t ctr_pattern = 0; |
ac940b58 |
312 | Int_t ctr_noisy = 0; |
87d57858 |
313 | |
ac940b58 |
314 | pedfile << 10 << std::endl; // Mark file to contain PEDESTALS per channel |
315 | noisefile << 11 << std::endl; // Mark file to contain NOISE per altro |
316 | pedmemfile << 12 << std::endl; // Mark file to contain PEDESTALs per time bin |
317 | noisychannelfile << 14 << std::endl; // Mark file to contain NOISY CHANNELS |
87d57858 |
318 | |
bdf99a93 |
319 | for ( Int_t roc = 0; roc < 72; roc++ ) { |
320 | if ( !calibPedestal.GetCalRocPedestal(roc) ) continue; |
49efac78 |
321 | Int_t side = mapping->GetSideFromRoc(roc); |
322 | Int_t sector = mapping->GetSectorFromRoc(roc); |
bdf99a93 |
323 | //printf("Analysing ROC %d (side %d, sector %d) ...\n", roc, side, sector); |
49efac78 |
324 | Int_t nru = mapping->IsIROC(roc) ? 2 : 4; |
bdf99a93 |
325 | for ( int rcu = 0; rcu < nru; rcu++ ) { |
49efac78 |
326 | Int_t patch = mapping->IsIROC(roc) ? rcu : rcu+2; |
bdf99a93 |
327 | for ( int branch = 0; branch < 2; branch++ ) { |
ac940b58 |
328 | for ( int fec = 0; fec < mapping->GetNfec(patch, branch); fec++ ) { |
329 | for ( int altro = 0; altro < 8; altro++ ) { |
330 | Float_t rms = 0.; |
331 | Float_t maxrms = 0.; |
332 | Float_t ctr_altrochannel = 0.; |
333 | for ( int channel = 0; channel < 16; channel++ ) { |
334 | Int_t hwadd = mapping->CodeHWAddress(branch, fec, altro, channel); |
335 | Int_t row = mapping->GetPadRow(patch, hwadd); // row in a ROC |
336 | Int_t globalrow = mapping->GetGlobalPadRow(patch, hwadd); // row in full sector |
337 | Int_t pad = mapping->GetPad(patch, hwadd); |
338 | Float_t ped = calibPedestal.GetCalRocPedestal(roc)->GetValue(row,pad); |
339 | // fixed pedestal |
340 | pedfile << ctr_channel++ << "\t" << side << "\t" << sector << "\t" << patch << "\t" |
341 | << hwadd << "\t" << ped << std::endl; |
342 | // pedestal(t) |
343 | if ( timePed && fabs(timePed[globalrow][pad].GetSum()) > 1e-10 ) { |
344 | pedmemfile << ctr_pattern++ << "\t" << side << "\t" << sector << "\t" << patch |
345 | << "\t" << hwadd; |
346 | for ( Int_t timebin = 0; timebin < 1024; timebin++ ) |
347 | pedmemfile << "\t" << timePed[globalrow][pad].At(timebin); |
348 | pedmemfile << std::endl; |
349 | } |
350 | // rms=noise |
351 | Float_t rms2 = calibPedestal.GetCalRocRMS(roc)->GetValue(row,pad); |
352 | if ( fabs(ped) < 1.e-10 ) { // dead channel |
353 | noisychannelfile << ctr_noisy++ << "\t" << side << "\t" << sector << "\t" |
354 | << patch << "\t" << hwadd << "\t" << rms2 << std::endl; |
355 | } else if ( (ped > 1.e-10) && (rms2 > 1.e-10) ) { // not dead |
356 | // Find noisy channels |
357 | if ( ((roc<36) && (rms2 > 2.0)) || // IROC |
358 | ((roc>35) && (row<65) && (rms2 > 2.0)) || // OROC, small pads |
359 | ((roc>35) && (row>64) && (rms2 > 3.0)) ) { // OROC, large pads (50% more signal) |
360 | noisychannelfile << ctr_noisy++ << "\t" << side << "\t" << sector << "\t" |
361 | << patch << "\t" << hwadd << "\t" << rms2 << std::endl; |
362 | } else { |
363 | // Not noisy. Get average and maximum noise in this ALTRO |
364 | rms += rms2; |
365 | ctr_altrochannel += 1.; |
366 | if (rms2 > maxrms) maxrms = rms2; |
367 | } // end if noisy |
368 | } // end if some signal |
369 | } // end channel for loop |
370 | Int_t hwadd = mapping->CodeHWAddress(branch, fec, altro, 0); // ALTRO address |
371 | // Noise data (rms) averaged over all channels in this ALTRO. |
372 | if ( ctr_altrochannel > 1.e-10 ) { |
373 | /* |
374 | // average noise of this ALTRO (excluding high-noise channels) |
375 | noisefile << ctr_altro << "\t" << side << "\t" << sector << "\t" << patch << "\t" |
376 | << hwadd << "\t" << rms/ctr_altrochannel << std::endl; |
377 | */ |
378 | // maximum noise of this ALTRO (excluding high-noise channels) |
379 | noisefile << ctr_altro << "\t" << side << "\t" << sector << "\t" << patch << "\t" |
380 | << hwadd << "\t" << maxrms << std::endl; |
381 | ctr_altro++; |
382 | } |
383 | } // end altro for loop |
384 | } // end fec for loop |
bdf99a93 |
385 | } // end branch for loop |
386 | } // end rcu for loop |
387 | } // end roc loop |
ac940b58 |
388 | |
bdf99a93 |
389 | pedfile.close(); |
390 | noisefile.close(); |
391 | pedmemfile.close(); |
ac940b58 |
392 | noisychannelfile.close(); |
393 | printf("Wrote ASCII files. Found %d noisy channels.\n", ctr_noisy); |
87d57858 |
394 | |
c12208b8 |
395 | return status; |
ac940b58 |
396 | |
c12208b8 |
397 | } |