Remove stale email recipient.
[u/mrichter/AliRoot.git] / VZERO / VZEROda.cxx
1 /*********************************************************************************
2 - Contact:    Brigitte Cheynis     b.cheynis@ipnl.in2p3.fr
3 - Link:       http
4 - Raw data test file :          
5 - Reference run number :              
6 - Run Type:   PHYSICS
7 - DA Type:    MON
8 - Number of events needed: >=500
9 - Input Files:  argument list
10 - Output Files: local files  VZERO_Histos.root, V0_Pedestals.dat (Online mapping)
11                 FXS file     V0_Ped_Width_Gain.dat (Offline mapping)
12 - Trigger types used: PHYSICS_EVENT
13 **********************************************************************************/
14
15 /**********************************************************************************
16 *                                                                                 *
17 * VZERO Detector Algorithm used for extracting calibration parameters             *
18 *                                                                                 *
19 * This program connects to the DAQ data source passed as argument.                *
20 * It computes calibration parameters, populates local "./V0_Ped_Width_Gain.dat"   *            
21 * file, exports it to the FES, and stores it into DAQ DB                          *
22 * The program exits when being asked to shut down (daqDA_checkshutdown)           *
23 * or on End of Run event.                                                         *
24 * We have 128 channels instead of 64 as expected for V0 due to the two sets of    *
25 * charge integrators which are used by the FEE ...                                *
26 *                                                                                 *
27 ***********************************************************************************/
28
29 // DATE
30 #include "event.h"
31 #include "monitor.h"
32 #include "daqDA.h"
33
34 //AliRoot
35 #include <AliVZERORawStream.h>
36 #include <AliRawReaderDate.h>
37 #include <AliRawReader.h>
38 #include <AliDAQ.h>
39
40 // standard
41 #include <stdio.h>
42 #include <stdlib.h>
43
44 //ROOT
45 #include "TROOT.h"
46 #include "TPluginManager.h"
47 #include <TFile.h>
48 #include <TH1F.h>
49 #include <TMath.h>
50
51 Int_t GetOfflineChannel(Int_t channel);
52
53 /* Main routine --- Arguments: monitoring data source */
54       
55 int main(int argc, char **argv) {
56
57 /* magic line from Cvetan */
58   gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
59                     "*",
60                     "TStreamerInfo",
61                     "RIO",
62                     "TStreamerInfo()");
63   int status;
64   if (argc!=2) {
65      printf("Wrong number of arguments\n");
66      return -1;
67   }
68   
69   // Online values (using FEE channel numbering), 
70   // stored into local V0_Pedestals.dat:
71   Double_t adcMean[128];
72   Double_t adcSigma[128];
73   Double_t pedMean[128];
74   Double_t pedSigma[128];
75   // Offline values(same but ordered as in aliroot for offliners)
76   // stored into V0_Ped_Width_Gain.dat: 
77   Double_t adcMeanOff[128];
78   Double_t adcSigmaOff[128];
79   Double_t pedMeanOff[128];
80   Double_t pedSigmaOff[128];
81        
82 //___________________________________________________
83 // Get cuts from V00DA.config file
84
85   Int_t    kClockMin;   // = 16;   LHC Clock Min for pedestal calculation
86   Int_t    kClockMax;   // = 19;   LHC Clock Max for pedestal calculation
87   Int_t    kLowCut;     // = 60;   low cut on signal distribution - to be tuned
88   Int_t    kHighCut;    // = 50;   high cut on pedestal distribution - to be tuned
89   Int_t    kClockMinRef;   // = 16;   LHC Clock Min for Flag checking
90   Int_t    kClockMaxRef;   // = 20;   LHC Clock Max for Flag checking
91   Float_t  kChi2Max;            // = 1.  Maximum chi2 
92
93   status = daqDA_DB_getFile("V00DA.config","./V00DA.config");
94   if (status) {
95       printf("Failed to get Config file (V00DA.config) from DAQ DB, status=%d\n", status);
96       printf("Take default values of parameters for pedestal calculation \n");
97       kClockMin  =  16; 
98       kClockMax  =  19; 
99       kLowCut    =  60;   
100       kHighCut   =  50;  
101       kClockMinRef  =  16; 
102       kClockMaxRef  =  20; 
103       kChi2Max          =  1.;
104   } else {
105       /* open the config file and retrieve cuts */
106       FILE *fpConfig = fopen("V00DA.config","r");
107       int res = fscanf(fpConfig,"%d %d %d %d %d %d %f",&kClockMin,&kClockMax,&kLowCut,&kHighCut,&kClockMinRef,&kClockMaxRef,&kChi2Max);
108       if(res!=7) {
109             printf("Failed to get values from Config file (V00DA.config): wrong file format - 4 integers are expected - \n");
110             kClockMin  =  16; 
111         kClockMax  =  19; 
112         kLowCut    =  60;   
113         kHighCut   =  50; 
114         kClockMinRef  =  16; 
115         kClockMaxRef  =  20; 
116         kChi2Max          =  1.;
117       }
118       fclose(fpConfig);
119   }
120   
121   printf("LHC Clock Min for pedestal calculation = %d; LHC Clock Max for pedestal calculation = %d; LowCut on signal = %d ; HighCut on pedestal = %d\n",
122           kClockMin, kClockMax, kLowCut, kHighCut);
123
124 //___________________________________________________
125 // Book HISTOGRAMS - dynamics of p-p collisions -
126       
127   char     adcName[6]; 
128   char     pedName[6]; 
129   TH1F     *hADCname[128];
130   TH1F     *hPEDname[128];  
131   
132   char  texte[12];
133   for (Int_t i=0; i<128; i++) {
134        sprintf(adcName,"hADC%d",i);
135        sprintf(texte,"ADC cell%d",i);
136        hADCname[i]  = new TH1F(adcName,texte,1024,-0.5, 1023.5);
137        sprintf(pedName,"hPED%d",i);
138        sprintf(texte,"PED cell%d",i);
139        hPEDname[i]  = new TH1F(pedName,texte,1024,-0.5, 1023.5);
140   }
141 //___________________________________________________ 
142
143   /* open result file to be exported to FES */
144   FILE *fpLocal=NULL;
145   fpLocal=fopen("./V0_Pedestals.dat","w");
146   if (fpLocal==NULL) {
147       printf("Failed to open local result file\n");
148       return -1;}
149    
150   /* open result file to be exported to FES */
151   FILE *fp=NULL;
152   fp=fopen("./V0_Ped_Width_Gain.dat","w");
153   if (fp==NULL) {
154       printf("Failed to open result file\n");
155       return -1;}
156
157   /* define data source : this is argument 1 */  
158   status=monitorSetDataSource( argv[1] );
159   if (status!=0) {
160      printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
161      return -1;
162   }
163
164   /* declare monitoring program */
165   status=monitorDeclareMp( __FILE__ );
166   if (status!=0) {
167     printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
168     return -1;
169   }
170
171   /* define wait event timeout - 1s max */
172   monitorSetNowait();
173   monitorSetNoWaitNetworkTimeout(1000);
174   
175   /* init counters on events */
176   int neventsPhysics=0;
177   int neventsTotal=0;
178
179   /* loop on events (infinite) */
180   for(;;) {
181       struct eventHeaderStruct *event;
182       eventTypeType eventT;
183
184       /* check shutdown condition */
185       if (daqDA_checkShutdown()) {break;}   
186
187       /* get next event (blocking call until timeout) */
188       status=monitorGetEventDynamic((void **)&event);
189       if (status==MON_ERR_EOF) {
190           printf ("End of File detected\n");
191       break; /* end of monitoring file has been reached */
192       }
193     
194       if (status!=0) {
195            printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
196       break;
197       }
198
199       /* retry if got no event */
200       if (event==NULL) continue;
201                
202       /* decode event */
203       eventT=event->eventType;
204         
205       switch (event->eventType){
206       
207       case START_OF_RUN:
208            break;
209       
210       case END_OF_RUN:
211            printf("End Of Run detected\n");
212            break;
213       
214       case PHYSICS_EVENT:
215            neventsPhysics++;
216                          
217            AliRawReader *rawReader = new AliRawReaderDate((void*)event);
218   
219            AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader); 
220            if (rawStream->Next()) {     
221            for(Int_t i=0; i<64; i++) {
222                         Int_t nFlag = 0;
223                         for(Int_t j=kClockMinRef; j <= kClockMaxRef; j++) {  // Check flags on clock range used for pedestal calculation
224                                 if((rawStream->GetBBFlag(i,j)) || (rawStream->GetBGFlag(i,j))) nFlag++; 
225                         }
226                         if(nFlag == 0){       // Fill 64*2 pedestal histograms  - 2 integrators -
227                                 Float_t sum[2] = {0.,0.};
228                                 Float_t sumwi[2] = {0.,0.};
229                                 for(Int_t j=kClockMin;j <= kClockMax;j++){
230                                 Int_t integrator = rawStream->GetIntegratorFlag(i,j);
231                                 Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
232                                 sum[integrator] += pedestal;
233                                         sumwi[integrator] += 1.;
234                                 }       
235                                 Float_t mean[2] =  {0.,0.};
236                                 Float_t chi2[2] =  {0.,0.};
237                                 
238                                 for(int ii=0;ii<2;ii++) if(sumwi[ii]>1.e-6) mean[ii] = sum[ii] / sumwi[ii];
239
240                                 for(Int_t j=kClockMin;j <= kClockMax;j++){
241                                 Int_t integrator = rawStream->GetIntegratorFlag(i,j);
242                                 Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
243                                         chi2[integrator] += (mean[integrator] - pedestal) * (mean[integrator] - pedestal);
244                                 }       
245                                 if(chi2[0]<kChi2Max && chi2[1]<kChi2Max) {
246                                         for(int ii=0;ii<2;ii++){
247                                                 if(mean[ii] >1.e-6) hPEDname[i + 64*ii]->Fill(mean[ii]);
248                                         }
249                                 }
250
251                         } 
252                         if((rawStream->GetBBFlag(i,10)) || (rawStream->GetBGFlag(i,10))){ // Charge
253                         Int_t integrator = rawStream->GetIntegratorFlag(i,10);
254                         Float_t charge = (float)(rawStream->GetADC(i));   // Fill 64*2 ADCmax histograms 
255                         hADCname[i + 64 * integrator]->Fill(charge);
256                         }                          
257         } // End loop over channels
258            }   // End : if rawstream
259            delete rawStream;
260            rawStream = 0x0;      
261            delete rawReader;
262            rawReader = 0x0;                                                                      
263       } // end of switch on event type 
264         
265       neventsTotal++;
266       /* free resources */
267       free(event);
268         
269       /* exit when last event received, no need to wait for TERM signal */
270       if (eventT==END_OF_RUN) {
271            printf("End Of Run event detected\n");
272       break;
273     }
274
275   }  // loop over events
276   
277   printf("%d physics events processed\n",neventsPhysics);
278     
279 //___________________________________________________________________________
280 //  Computes mean values, converts FEE channels into Offline AliRoot channels
281 //  and dumps the ordered values into the output text file for SHUTTLE
282         
283   for(Int_t i=0; i<128; i++) {
284       hPEDname[i]->GetXaxis()->SetRange(0,kHighCut);
285       pedMean[i]  = hPEDname[i]->GetMean(); 
286       pedSigma[i] = hPEDname[i]->GetRMS(); 
287       hADCname[i]->GetXaxis()->SetRange(kLowCut,1024);
288       adcMean[i]  = hADCname[i]->GetMean();
289       adcSigma[i] = hADCname[i]->GetRMS(); 
290 //      printf(" i = %d, %.3f %.3f %.3f %.3f\n",i,pedMean[i],pedSigma[i],adcMean[i],adcSigma[i]);
291       fprintf(fpLocal," %.3f %.3f %.3f %.3f\n",pedMean[i],pedSigma[i],
292                                                adcMean[i],adcSigma[i]);
293       if (i < 64) {
294           Int_t j = GetOfflineChannel(i);     
295           pedMeanOff[j]  = pedMean[i];
296           pedSigmaOff[j] = pedSigma[i];
297           adcMeanOff[j]  = adcMean[i];
298           adcSigmaOff[j] = adcSigma[i]; }
299       else{
300           Int_t j = GetOfflineChannel(i-64);     
301           pedMeanOff[j+64]  = pedMean[i];
302           pedSigmaOff[j+64] = pedSigma[i];
303           adcMeanOff[j+64]  = adcMean[i];
304           adcSigmaOff[j+64] = adcSigma[i];
305       }
306   }
307   
308   for(Int_t j=0; j<128; j++) {
309 //      printf(" j = %d, %.3f %.3f %.3f %.3f\n",j,pedMeanOff[j],pedSigmaOff[j],
310 //                                                adcMeanOff[j],adcSigmaOff[j]);
311       fprintf(fp," %.3f %.3f %.3f %.3f\n",pedMeanOff[j],pedSigmaOff[j],
312                                           adcMeanOff[j],adcSigmaOff[j]);                                       
313   }
314    
315 //________________________________________________________________________
316 // Write root file with histos for users further check - just in case - 
317
318   TFile *histoFile = new TFile("VZERO_histos.root","RECREATE");
319     
320   for (Int_t i=0; i<128; i++) {
321        hADCname[i]->GetXaxis()->SetRange(0,1024);
322        hADCname[i]->Write(); 
323        hPEDname[i]->Write(); }
324
325   histoFile->Close(); 
326   delete histoFile;
327   
328 //________________________________________________________________________
329    
330   /* close local result file and FXS result file*/
331   fclose(fpLocal);
332   fclose(fp);
333  
334   /* export result file to FES */
335   status=daqDA_FES_storeFile("./V0_Ped_Width_Gain.dat","V00da_results");
336   if (status)    {
337       printf("Failed to export file : %d\n",status);
338       return -1; }
339
340   /* store result file into Online DB */
341   status=daqDA_DB_storeFile("./V0_Pedestals.dat","V00da_results");
342   if (status)    {
343       printf("Failed to store file into Online DB: %d\n",status);
344       return -1; }
345       
346   return status;
347 }
348
349  Int_t GetOfflineChannel(Int_t channel) {
350
351 // Channel mapping Online - Offline:
352  
353  Int_t fOfflineChannel[64] = {39, 38, 37, 36, 35, 34, 33, 32, 
354                               47, 46, 45, 44, 43, 42, 41, 40, 
355                               55, 54, 53, 52, 51, 50, 49, 48, 
356                               63, 62, 61, 60, 59, 58, 57, 56,
357                                7,  6,  5,  4,  3,  2,  1,  0, 
358                               15, 14, 13, 12, 11, 10,  9,  8,
359                               23, 22, 21, 20, 19, 18, 17, 16, 
360                               31, 30, 29, 28, 27, 26, 25, 24};
361  return fOfflineChannel[channel];                     
362 }