]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/TOFdaPhysics.cxx
Possibility to propagate tracks to the DCA to the primary vertex at the AOD level...
[u/mrichter/AliRoot.git] / TOF / TOFdaPhysics.cxx
1 /*
2
3 TOF DA for online calibration
4
5 Contact: Chiara.Zampolli@bo.infn.it
6          Roberto.Preghenella@bo.infn.it
7
8 Run Type: PHYSICS
9 DA Type: MON
10 Number of events needed:
11 Input Files: no input
12 Output Files: TOFdaHits.root TOFdaReadout.root
13 Event types used: PHYSICS_EVENT
14
15 */
16
17 #define FILE_HITS "TOFdaHits.root"
18 #define FILE_READOUT "TOFdaReadout.root"
19
20 #define READOUT_INFO_HISTO 1
21
22 // DATE
23 #include "event.h"
24 #include "monitor.h"
25 #include "daqDA.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30
31 //AliRoot
32 #include "TROOT.h"
33 #include "AliTOFRawStream.h"
34 #include "AliRawReaderDate.h"
35 #include "AliRawReader.h"
36 #include "AliDAQ.h"
37 #include "AliTOFHitData.h"
38 #include "AliTOFHitDataBuffer.h"
39 #include "AliTOFDaConfigHandler.h"
40 #include "AliTOFHitField.h"
41 #include "AliLog.h"
42 #include "AliTOFGeometry.h"
43 #include "AliTOFDecoderV2.h"
44 #include "AliTOFDecoderSummaryData.h"
45 #include "AliTOFDRMSummaryData.h"
46 #include "AliTOFTRMSummaryData.h"
47 #include "AliTOFChainSummaryData.h"
48 #include "AliTOFTDCHitBuffer.h"
49 #include "AliTOFTDCHit.h"
50 #include "AliTOFTDCErrorBuffer.h"
51 #include "AliTOFTDCError.h"
52
53 //ROOT
54 #include "TFile.h"
55 #include "TKey.h"
56 #include "TH2S.h"
57 #include "TObject.h"
58 #include "TMath.h"
59 #include "TSystem.h"
60 #include "TROOT.h"
61 #include "TPluginManager.h"
62 #include "TSAXParser.h"
63 #include "TTree.h"
64
65 /* Main routine
66       Arguments: 
67       1- monitoring data source
68 */
69 int 
70 main(int argc, char **argv) 
71 {
72   
73   /* magic line from Rene */
74   gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
75                                         "*",
76                                         "TStreamerInfo",
77                                         "RIO",
78                                         "TStreamerInfo()");
79   
80
81   /* log start of process */
82   printf("TOF DA started\n");  
83   
84   /* check that we got some arguments = list of files */
85   if (argc!=2) {
86     printf("Wrong number of arguments\n");
87     return -1;
88   }
89
90   /*
91    * CONFIG
92    */
93   
94   /* retrieve config file */
95   int getConfigFile = daqDA_DB_getFile("TOFPhysicsConfig.xml","TOFPhysicsConfig.xml");
96   if (getConfigFile != 0){
97     printf("Failed to retrieve config file from DB! returning...\n");
98     return -1;
99   }
100   /* parse config file */
101   AliTOFDaConfigHandler* tofHandler = new AliTOFDaConfigHandler();
102   TSAXParser *parser = new TSAXParser();
103   parser->ConnectToHandler("AliTOFDaConfigHandler", tofHandler);  
104   if (parser->ParseFile("./TOFPhysicsConfig.xml") != 0) {
105     printf("Failed parsing config file! retunring... \n");
106     return -1;
107   }
108   /* setup config params */
109   Int_t meanMultiplicity = tofHandler->GetMeanMultiplicity(); /* average expected TOF multiplicity */
110   Int_t maxHits = tofHandler->GetMaxHits(); /* max number of hits to be collected */
111   printf("current settings:\n");
112   printf(" - meanMultiplicity = %d\n", meanMultiplicity);
113   printf(" - maxHits          = %d\n", maxHits);
114   /* constants */
115   const Int_t nChannels = 157248;
116   Int_t noiseCheckTrigger = 10; /* first noise check after 10 events */
117   Float_t meanChannelRate = (Float_t)meanMultiplicity / (Float_t)nChannels; /* average expected channel rate (hits/event) */
118   Float_t noiseThreshold = 10. * meanChannelRate; /* noise threshold (hits/event) */
119   Int_t minNoiseHits = 10; /* min number of channel hits to check noise */
120   /* counters and flags */
121   Int_t nPhysicsEvents, nCollectedPhysicsEvents, totHits;
122   Int_t nChHits[nChannels];
123   Bool_t inhibitCollection;
124   Bool_t noiseFlag[nChannels];
125   /* variables */
126   Int_t ddl, slot, trm, chain, tdc, channel, index, timebin, totbin, deltaBC, l0l1latency, det[5], dummy;
127   Float_t noiseHitThreshold;
128
129   /*
130    * INIT 
131    */
132
133   /* init counters and flags */
134   nPhysicsEvents = 0;
135   nCollectedPhysicsEvents = 0;
136   totHits = 0;
137   inhibitCollection = kFALSE;
138   for (Int_t ich = 0; ich < nChannels; ich++) {
139     nChHits[ich] = 0;
140     noiseFlag[ich] = kFALSE;
141   }
142
143   /* TOF raw data handling */
144   AliTOFRawStream *rawStream = new AliTOFRawStream();
145   AliTOFDecoderV2 *decoder = rawStream->GetDecoderV2();
146   AliTOFDecoderSummaryData *decodersd;
147   AliTOFDRMSummaryData *drmsd;
148   //  AliTOFLTMSummaryData *ltmsd;
149   AliTOFTRMSummaryData *trmsd;  
150   AliTOFChainSummaryData *chainsd;
151   AliTOFTDCHitBuffer *hitBuffer;
152   AliTOFTDCHit *hit;
153   AliTOFTDCErrorBuffer *errorBuffer;
154   AliTOFTDCError *error;
155   UShort_t errorFlags;
156   UChar_t *data = 0x0;
157   Int_t dataSize;
158   Int_t dataWords;
159   Int_t currentDDL;
160   const AliRawDataHeader *currentCDH;
161   Int_t currentMiniEventID;
162   Int_t currentEventID1;
163   Int_t currentL0BCID ;
164   Int_t currentBunchID;
165   Bool_t skipTRM, skipChain;
166   Int_t trmIndex, chainIndex, tdcIndex;
167   Double_t chainEff;
168   
169   /* open HITS output file */
170   TFile *fileOutHits = new TFile(FILE_HITS, "RECREATE"); 
171   /* create hit field data structure */
172   AliTOFHitField *hitField = new AliTOFHitField();
173   /* create temporary tree */
174   TTree *tempTree = new TTree("tempTree", "temporary tree");
175   tempTree->Branch("hit", "AliTOFHitField", &hitField);
176   /* create output tree */
177   TTree *outTree = new TTree("hitTree", "hit tree");
178   outTree->Branch("hit", "AliTOFHitField", &hitField);
179
180   /* open READOUT output file */
181   TFile *fileOutReadout = new TFile(FILE_READOUT, "RECREATE"); 
182   /* create chain readout efficiency histo */
183   TH1F *hChainEfficiency = new TH1F("hChainEfficiency", "Chain efficiency;chain;efficiency", 1440, 0., 1440.);
184
185 #if READOUT_INFO_HISTO
186   /* create TRM data histo */
187   TH1F *hTRMData = new TH1F("hTRMData", "TRM data;TRM;frequency", 720, 0., 720.);
188   /* create TRM empty event frequency histo */
189   TH1F *hTRMEmptyEvent = new TH1F("hTRMEmptyEvent", "TRM empty event error;TRM;frequency", 720, 0., 720.);
190   /* create TRM bad event counter frequency histo */
191   TH1F *hTRMBadEventCounter = new TH1F("hTRMBadEventCounter", "TRM bad event counter;TRM;frequency", 720, 0., 720.);
192   /* create TRM bad CRC frequency histo */
193   TH1F *hTRMBadCRC = new TH1F("hTRMBadCRC", "TRM bad CRC;TRM;frequency", 720, 0., 720.);
194
195   /* create chain data histo */
196   TH1F *hChainData = new TH1F("hChainData", "Chain data;chain;frequency", 1440, 0., 1440.);
197   /* create chain bad status frequency histo */
198   TH1F *hChainBadStatus = new TH1F("hChainBadStatus", "Chain bad status;chain;frequency", 1440, 0., 1440.);
199   /* create chain bad event counter frequency histo */
200   TH1F *hChainBadEventCounter = new TH1F("hChainBadEventCounter", "Chain bad event counter;chain;status;frequency", 1440, 0., 1440.);
201
202   /* create TDC error frequency histo */
203   TH1F *hTDCError = new TH1F("hTDCError", "TDC error;TDC;frequency", 21600, 0., 21600.);
204   /* create TDC error flags frequency histo */
205   TH2F *hTDCErrorFlags = new TH2F("hTDCErrorFlags", "TDC error flags;TDC;error flag;frequency", 21600, 0., 21600., 15, 0., 15);
206 #endif
207   
208
209   /*
210    * ONLINE MONITOR
211    */
212
213   AliLog::SetGlobalLogLevel(AliLog::kFatal);
214   struct eventHeaderStruct *event;
215   int ret;
216   /* define monitoring table */
217   char *monTable[5] = {
218     "ALL", "no",
219     "PHY", "yes",
220     NULL
221   };
222   ret = monitorDeclareTable(monTable);
223   if (ret != 0) {
224     printf("monitorDeclareTable() failed: %s\n", monitorDecodeError(ret));
225     return -1;
226   }
227   /* define data source : this is argument 1 */  
228   ret = monitorSetDataSource(argv[1]);
229   if (ret != 0) {
230     printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(ret));
231     return -1;
232   }
233   /* declare monitoring program */
234   ret = monitorDeclareMp("TOFdaPhysics");
235   if (ret != 0) {
236     printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(ret));
237     return -1;
238   }
239   /* define wait event timeout - 1s max */
240   monitorSetNowait();
241   monitorSetNoWaitNetworkTimeout(1000);
242
243   /* variables */
244   
245   /* loop over events */
246   while (1) {
247     
248     /* check shutdown condition */
249     if (daqDA_checkShutdown()) break;
250     
251     /*
252      * NOISE CHECK
253      */
254
255     /* check inhibit collection */
256     if (!inhibitCollection) {
257       /* check number of events and check noise */
258       if (nCollectedPhysicsEvents >= noiseCheckTrigger || totHits >= maxHits) {
259         noiseHitThreshold = noiseThreshold * nCollectedPhysicsEvents;
260         printf("noise check triggered after %d events: threshold is %f hits\n", nCollectedPhysicsEvents, noiseHitThreshold);
261         /* loop over all channels */
262         for (Int_t ich = 0; ich < nChannels; ich++) {
263           /* check */
264           if (nChHits[ich] < minNoiseHits || noiseFlag[ich] || nChHits[ich] < noiseHitThreshold) continue;
265           printf("channel %d tagged as noisy (%d hits): disabled\n", ich, nChHits[ich]);
266           noiseFlag[ich] = kTRUE;
267           totHits -= nChHits[ich];
268         } /* end of loop over all channels */
269         /* set new noise check trigger value */
270         noiseCheckTrigger *= 10;
271       } /* end of noise check */    
272       
273       /* inhibit hit collection when maximum number of hits exceeded */
274       if (totHits >= maxHits) {
275         printf("maximum number of hits exceeded (%d): inhibit hit collection\n", maxHits);
276         inhibitCollection = kTRUE;
277       }
278     }
279     
280     /*
281      * GET EVENT
282      */
283
284     /* get next event (blocking call until timeout) */
285     ret = monitorGetEventDynamic((void **)&event);
286     if (ret == MON_ERR_EOF) {
287       printf ("End of File detected\n");
288       break; /* end of monitoring file has been reached */
289     }
290     if (ret != 0) {
291       printf("monitorGetEventDynamic() failed (ret=%d errno=%d): %s\n", ret, errno, monitorDecodeError(ret));
292       break;
293     }
294     /* retry if got no event */
295     if (event==NULL) continue;
296     /* check TOF in partecipating detectors */
297     if (!TEST_DETECTOR_IN_PATTERN(event->eventDetectorPattern, EVENT_DETECTOR_TOF)) {
298       free(event);
299       continue;
300     }
301     /* check event type */
302     if (event->eventType != PHYSICS_EVENT) {
303       printf("not a physics event: %d\n", event->eventType);
304       free(event);
305       continue;
306     }
307     /* increment number of physics events */
308     nPhysicsEvents++;
309     if (!inhibitCollection) nCollectedPhysicsEvents++;
310
311     /*
312      * DECODE EVENT
313      */
314
315     /* create and setup raw reader */
316     AliRawReader *rawReader = new AliRawReaderDate((void *)event);
317     rawReader->Reset();
318     rawReader->Select("TOF", 0, AliDAQ::NumberOfDdls("TOF") - 1);
319     /* setup raw stream */
320     rawStream->SetRawReader(rawReader);
321
322     /* loop over DDLs - rawReader->ReadHeader() */
323     while (rawReader->ReadHeader()) {
324
325       /* read equipment data */
326       dataSize = rawReader->GetDataSize();
327       data = new UChar_t[dataSize];
328       if (!rawReader->ReadNext(data, dataSize)){
329         delete [] data;
330         continue;
331       }
332
333       /* decode data */
334       dataWords = dataSize / 4;
335       decoder->Decode((UInt_t *)data, dataWords);
336       delete [] data;
337
338       /* read equipment info */
339       currentDDL = rawReader->GetDDLID();
340       currentCDH = rawReader->GetDataHeader();
341       currentMiniEventID = currentCDH->GetMiniEventID();
342       currentEventID1 = currentCDH->GetEventID1();
343
344       /* read decoder summary data */
345       decodersd = decoder->GetDecoderSummaryData();
346       
347       /* check DRM header/trailer */
348       drmsd = decodersd->GetDRMSummaryData();
349       if (!drmsd->GetHeader() || !drmsd->GetTrailer()) continue;
350
351       /* get DRM data */
352       currentL0BCID = drmsd->GetL0BCID();
353       
354       /* loop over TRM to get hits */
355       for (Int_t itrm = 0; itrm < 10; itrm++) {
356         trmsd = drmsd->GetTRMSummaryData(itrm);
357         trmIndex = itrm + 10 * currentDDL;
358         skipTRM = kFALSE;
359         
360         /* check header/trailer */
361         if (!trmsd->GetHeader() || !trmsd->GetTrailer()) continue;
362         
363 #if READOUT_INFO_HISTO
364         /* fill TRM data */
365         hTRMData->Fill(trmIndex);
366         /* fill TRM empty event */
367         if (trmsd->GetEBit() != 0) {
368           hTRMEmptyEvent->Fill(trmIndex);
369           skipTRM = kTRUE;
370         }
371         /* fill TRM bad event counter */
372         if (trmsd->GetEventCounter() != drmsd->GetLocalEventCounter()) {
373           hTRMBadEventCounter->Fill(trmIndex);
374           skipTRM = kTRUE;
375         }
376         /* fill TRM bad CRC */
377         if (trmsd->GetEventCRC() != trmsd->GetDecoderCRC()) {
378           hTRMBadCRC->Fill(trmIndex);
379           skipTRM = kTRUE;
380         }
381 #else
382         /* check bad condition and skip TRM */
383         if ( trmsd->GetEBit() != 0 ||
384              trmsd->GetEventCounter() != drmsd->GetLocalEventCounter() ||
385              trmsd->GetEventCRC() != trmsd->GetDecoderCRC() ) continue;
386 #endif
387         
388         /* loop over chains */
389         for (Int_t ichain = 0; ichain < 2; ichain++) {
390           chainsd = trmsd->GetChainSummaryData(ichain);
391           chainIndex = ichain + 2 * itrm + 20 * currentDDL;
392           skipChain = kFALSE;
393           
394           /* check header/trailer */
395           if (!chainsd->GetHeader() || !chainsd->GetTrailer()) continue;
396           currentBunchID = chainsd->GetBunchID();
397           hitBuffer = chainsd->GetTDCPackedHitBuffer();
398           errorBuffer = chainsd->GetTDCErrorBuffer();
399
400 #if READOUT_INFO_HISTO
401           /* fill chain data */
402           hChainData->Fill(chainIndex);
403           /* check chain bad status */
404           if (chainsd->GetStatus() != 0) {
405             hChainBadStatus->Fill(chainIndex);
406             skipChain = kTRUE;
407           }
408           /* check chain bad event counter */
409           if (chainsd->GetEventCounter() != drmsd->GetLocalEventCounter()) {    
410             hChainBadEventCounter->Fill(chainIndex);
411             skipChain = kTRUE;
412           }
413           /* fill TDC error frequency histo */
414           for (Int_t ierr = 0; ierr < errorBuffer->GetEntries(); ierr++) {
415             error = errorBuffer->GetError(ierr);
416             tdc = error->GetTDCID();
417             tdcIndex = tdc + 15 * ichain + 30 * itrm + 300 * currentDDL;
418             hTDCError->Fill(tdcIndex); 
419             errorFlags = error->GetErrorFlags();
420             for (Int_t ierflg = 0; ierflg < 15; ierflg++)
421               if (errorFlags & (1 << ierflg))
422                 hTDCErrorFlags->Fill(tdcIndex, ierflg); 
423           }
424 #else
425           /* check bad condition and skip chain */
426           if ( chainsd->GetStatus() != 0 ||
427                chainsd->GetEventCounter() != drmsd->GetLocalEventCounter() ) continue;
428 #endif
429           
430           /*
431            * CHAIN READOUT EFFICIENCY
432            */
433           
434           /* compute number of available channels removing TDCs in error */
435           chainEff = (120. - 8. * errorBuffer->GetEntries()) / 120.;
436           /* fill chain readout efficiency histo */
437           if (!skipTRM && !skipChain)
438             hChainEfficiency->Fill(chainIndex, chainEff);
439           
440           /*
441            * HIT MANIPULATION
442            */
443           
444           /* check inhibit collection */
445           if (inhibitCollection) continue;
446
447           /* loop over hits in buffer */
448           for (Int_t ihit = 0; ihit < hitBuffer->GetEntries(); ihit++) {
449             
450             /* get hit */
451             hit = hitBuffer->GetHit(ihit);
452             
453             /* get channel info */
454             ddl = currentDDL;
455             slot = trmsd->GetSlotID();
456             trm = slot - 3;
457             chain = chainsd->GetChain();
458             tdc = hit->GetTDCID();
459             channel = hit->GetChan();
460             /* get index */
461             rawStream->EquipmentId2VolumeId(ddl, slot, chain, tdc, channel, det);
462             dummy = det[4];
463             det[4] = det[3];
464             det[3] = dummy;
465             /* check valid index */
466             if (det[0] < 0 || det[0] > 17 ||
467                 det[1] < 0 || det[1] > 5 ||
468                 det[2] < 0 || det[2] > 18 ||
469                 det[3] < 0 || det[3] > 1 ||
470                 det[4] < 0 || det[4] > 47) continue;
471             index = AliTOFGeometry::GetIndex(det);
472             
473             /* check noise flag */
474             if (noiseFlag[index]) continue;
475             /* increment number of channel hits and total hits */
476             nChHits[index]++;
477             totHits++;
478             /* get signal info */
479             timebin = hit->GetHitTime();
480             totbin = hit->GetTOTWidth();
481             deltaBC = currentBunchID - currentEventID1;
482             l0l1latency = currentMiniEventID - currentL0BCID;
483             /* set hit field data */
484             hitField->SetIndex(index);
485             hitField->SetTimeBin(timebin);
486             hitField->SetTOTBin(totbin);
487             hitField->SetDeltaBC(deltaBC);
488             hitField->SetL0L1Latency(l0l1latency);
489             /* fill temp tree */
490             tempTree->Fill();
491
492           } /* end of loop over hits in buffer */
493         } /* end of loop over chains */
494       } /* end of loop over TRMs */
495     } /* end of loop over DDLs - rawReader->ReadHeader() */
496     
497     /* delete raw reader */
498     delete rawReader;
499     /* free event */
500     free(event);
501     
502   } /* end of loop over events */
503   
504   /* final noise check */
505   noiseHitThreshold = noiseThreshold * nCollectedPhysicsEvents;
506   printf("final noise check after collectiong %d events: threshold is %f hits\n", nCollectedPhysicsEvents, noiseHitThreshold);
507   /* loop over all channels */
508   for (Int_t ich = 0; ich < nChannels; ich++) {
509     /* check */
510     if (nChHits[ich] < minNoiseHits || noiseFlag[ich] || nChHits[ich] < noiseHitThreshold) continue;
511     printf("channel %d tagged as noisy (%d hits): disabled\n", ich, nChHits[ich]);
512     noiseFlag[ich] = kTRUE;
513     totHits -= nChHits[ich];
514   } /* end of loop over all channels */
515   
516   /* copy hits into output tree from temp tree */
517   printf("copy hits from temporary tree into output tree\n");
518   printf("temporary tree contains %d hits\n", (Int_t)tempTree->GetEntries());
519   for (Int_t ihit = 0; ihit < tempTree->GetEntries(); ihit++) {
520     /* get entry */
521     tempTree->GetEntry(ihit);
522     /* check noise flag */
523     if (noiseFlag[hitField->GetIndex()]) continue;
524     /* fill output tree */
525     outTree->Fill();
526   } /* end of copy hits into output tree from temp tree */
527   printf("output tree contains %d hits\n", (Int_t)outTree->GetEntries());
528
529   /* write output tree on HITS file */
530   fileOutHits->cd();
531   outTree->Write();
532   fileOutHits->Close();
533   /* export file to FXS */
534   if (daqDA_FES_storeFile(FILE_HITS, "HITS"))
535     return -2;
536
537 #if READOUT_INFO_HISTO
538   hTRMData->Sumw2();
539   hTRMEmptyEvent->Sumw2();
540   hTRMBadEventCounter->Sumw2();
541   hTRMBadCRC->Sumw2();
542
543   hChainData->Sumw2();
544   hChainBadStatus->Sumw2();
545   hChainBadEventCounter->Sumw2();
546
547   hTDCError->Sumw2();
548   hTDCErrorFlags->Sumw2();
549
550   /* divide histos */
551   if (nPhysicsEvents > 0) {
552     hTRMEmptyEvent->Divide(hTRMData);
553     hTRMBadEventCounter->Divide(hTRMData);
554     hTRMBadCRC->Divide(hTRMData);
555     hTRMData->Scale(1. / nPhysicsEvents);
556
557     hChainBadStatus->Divide(hChainData);
558     hChainBadEventCounter->Divide(hChainData);
559     hChainData->Scale(1. / nPhysicsEvents);
560
561     hTDCError->Scale(1. / nPhysicsEvents);
562     hTDCErrorFlags->Scale(1. / nPhysicsEvents);
563   }
564 #endif
565   
566   /* scale chain efficiency by number of physics events */
567   printf("found %d physics events\n", nPhysicsEvents);
568   hChainEfficiency->Sumw2();
569   if (nPhysicsEvents > 0) hChainEfficiency->Scale(1. / (nPhysicsEvents));
570   
571   /* write efficiency histo on READOUT file */
572   fileOutReadout->cd();
573 #if READOUT_INFO_HISTO
574   hTRMData->Write();
575   hTRMEmptyEvent->Write();
576   hTRMBadEventCounter->Write();
577   hTRMBadCRC->Write();
578   
579   hChainData->Write();
580   hChainBadStatus->Write();
581   hChainBadEventCounter->Write();
582   
583   hTDCError->Write();
584   hTDCErrorFlags->Write();
585 #endif
586   hChainEfficiency->Write();
587   fileOutReadout->Close();
588   /* export file to FXS */
589   if (daqDA_FES_storeFile(FILE_READOUT, "READOUT"))
590     return -2;
591
592   return 0;
593 }