Simplifications, now that pedestal subprocessor is taking care of deciding whether...
[u/mrichter/AliRoot.git] / MUON / MUONTRKGAINda.cxx
1 /*
2  Contact: Jean-Luc Charvet <jean-luc.charvet@cern.ch>
3  Link: http://aliceinfo.cern.ch/static/Offline/dimuon/muon_html/README_mchda.html
4  Reference Runs: (station 3)
5  Index          Run
6  1              109303
7  2              109304
8  3              109305
9  4              109306
10  5              109307
11  6              109308
12  7              109309
13  8              109310
14  9              109311
15  10             109312
16  11             109313
17  Run Type: CALIBRATION
18  DA Type: LDC
19  Number of events needed: 400 events for each calibration run (11)
20  Input Files:  mutrkcalibvalues and config_ldc-MTRK-S3-0 in path : /afs/cern.ch/user/j/jcharvet/public/DA_validation
21  Output Files: local dir (not persistent) -> MUONTRKGAINda.par   FXS -> run<#>_MCH_<ldc>_GAINS
22  Trigger types used:
23  */
24
25 /**************************************************************************
26  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
27  *                                                                        *
28  * Author: The ALICE Off-line Project.                                    *
29  * Contributors are mentioned in the code where appropriate.              *
30  *                                                                        *
31  * Permission to use, copy, modify and distribute this software and its   *
32  * documentation strictly for non-commercial purposes is hereby granted   *
33  * without fee, provided that the above copyright notice appears in all   *
34  * copies and that both the copyright notice and this permission notice   *
35  * appear in the supporting documentation. The authors make no claims     *
36  * about the suitability of this software for any purpose. It is          *
37  * provided "as is" without express or implied warranty.                  *
38  **************************************************************************/
39
40 /* $Id$ */
41
42 /*
43  -------------------------------------------------------------------------
44  2010-02-16 New version: MUONTRKGAINda.cxx,v 1.5
45  -------------------------------------------------------------------------
46  
47  Version for MUONTRKGAINda MUON tracking
48  (A. Baldisseri, J.-L. Charvet)
49  
50  
51  Rem:  AliMUON2DMap stores all channels, even those which are not connected
52  if pedMean == -1, channel not connected to a pad  
53  
54  
55  */
56 extern "C" {
57 #include <daqDA.h>
58 }
59
60 #include "event.h"
61 #include "monitor.h"
62
63 #include <Riostream.h>
64 #include <stdio.h>
65 #include <stdlib.h>
66 #include <sstream>
67 #include <math.h> 
68
69 //AliRoot
70 #include "AliMUONRawStreamTrackerHP.h"
71 #include "AliRawReader.h"
72 #include "AliMUONVStore.h"
73 #include "AliMUON2DMap.h"
74 #include "AliMUONCalibParamND.h"
75 #include "AliMpIntPair.h"
76 #include "AliMpConstants.h"
77 #include "AliRawDataErrorLog.h"
78 #include "AliMUONTrackerIO.h"
79
80 //ROOT
81 #include "TFile.h"
82 #include "TSystem.h"
83 #include "TTree.h"
84 #include "TH1F.h"
85 #include "TString.h"
86 #include "TStopwatch.h"
87 #include "TMath.h"
88 #include "TTimeStamp.h"
89 #include "TGraphErrors.h"
90 #include "TF1.h"
91 #include "TROOT.h"
92 #include "TPluginManager.h"
93 #include "TFitter.h"
94 #include "TObjString.h"
95 #include "THashTable.h"
96 #include <THashList.h>
97 //
98 //AMORE
99 //
100 #ifdef ALI_AMORE
101 #include <AmoreDA.h>
102 #endif
103
104 #include "AliMUONPedestal.h"
105 #include "AliMUONGain.h"
106 #include "AliMUONErrorCounter.h"
107
108 // main routine
109 int main(Int_t argc, const char** argv) 
110 {
111   Int_t status=0;
112   TStopwatch timers;
113   timers.Start(kTRUE); 
114   
115   const char* prefixDA = "MUONTRKGAINda"; // program prefix
116   printf(" ######## Begin execution : %s ######## \n\n",prefixDA); 
117   
118   TString inputFile;
119   // decode the input line
120   if (argc!=2) { printf("Wrong number of arguments\n");  return -1; }
121   
122   inputFile = argv[1];
123   
124   // needed for streamer application
125   gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
126                                         "*",
127                                         "TStreamerInfo",
128                                         "RIO",
129                                         "TStreamerInfo()"); 
130   // needed for Minuit plugin
131   gROOT->GetPluginManager()->AddHandler("ROOT::Math::Minimizer",
132                                         "Minuit",
133                                         "TMinuitMinimizer",
134                                         "Minuit",
135                                         "TMinuitMinimizer(const char*)");
136   Int_t skipEvents = 0;
137   Int_t maxEvents  = 1000000;
138   Int_t maxDateEvents  = 1000000;
139   
140   Int_t nDateEvents = 0;
141   Int_t nGlitchErrors= 0;
142   Int_t nParityErrors= 0;
143   Int_t nPaddingErrors= 0;
144   Int_t nTokenlostErrors= 0;
145   Int_t nEventsRecovered = 0;
146   Int_t nEvents = 0;
147   
148   TString logOutputFile;
149   Char_t flatFile[256]="";
150   TString shuttleFile;
151   
152   UInt_t runNumber   = 0;
153   ofstream filcout;
154   Int_t nIndex = -1; 
155   
156   // For DA Gain
157   Int_t nEntries = daqDA_ECS_getTotalIteration(); // usually = 11 = Nb of calibration runs
158   Int_t nInit=1;  // = 0 all DAC values ; = 1 DAC=0 excluded (default=1)
159   Int_t nbpf1=6;  // nb of points for linear fit (default=6) 
160   Int_t printLevel  = 0;  // printout (default=0, =1 =>.ped , => .peak & .param)
161   Int_t plotLevel  = 1;  // plotout (default=1 => tree , =2 tree+Tgraph+fit)
162   Int_t nbev=0; 
163   Int_t injCharge; 
164   
165   // Reading current iteration
166   nIndex = daqDA_ECS_getCurrentIteration();
167   if(nIndex<0 || nIndex>nEntries) {printf("\n Failed: nIndex = %d\n",nIndex); return -1 ;}
168   
169   //Gain object
170   AliMUONGain* muonGain = new AliMUONGain();
171   muonGain->SetprefixDA(prefixDA);
172   muonGain->SetAliRootDataFileName(); // MUONTRKGAINda_data.root
173   
174   UShort_t manuId;  
175   UChar_t channelId;
176   UShort_t charge;
177   
178   // DAC values stored in array vDAC (reading dbfile in DETDB)
179   //   Int_t vDAC[11] = {0,200,400,800,1200,1600,2000,2500,3000,3500,4000}
180   Int_t nConfig = 1; // flag to read or not configuration ascii file in detDB
181   Int_t vDAC[11]; // DAC values
182   Char_t dbfile[256]="";
183   sprintf(dbfile,"mutrkcalibvalues");
184   status=daqDA_DB_getFile(dbfile,dbfile);
185   if(status) {printf(" Failed  : input file %s is missing, status = %d\n",dbfile,status); return -1; } 
186   
187   ifstream filein(dbfile,ios::in); Int_t k=0, kk;
188   while (k<nEntries ) { filein >> kk >> vDAC[k] ; k++; }
189   injCharge=vDAC[nIndex-1];
190   
191   filein >> nInit; // = 0 all DAC values fitted ; = 1 DAC=0 excluded (default=1)
192   filein >> nbpf1; // nb of points for linear fit (default=6) 
193   filein >> printLevel;  // printout (default=0, =1 =>.ped /run, =2 => .peak & .param)
194   filein >> plotLevel;  // plotout (default=1 => tree , =2 tree+Tgraph+fit)
195   filein >> nConfig;  //nConfig (default=1 => read config in DetDB, otherwise =0)
196   filein >> nbev;  // Nb of events to read  (default = 0 => reading all events)
197   if(nbev>0)maxEvents=nbev;
198   
199   //  printf(" *** Copy: %s from DetDB to working directory  ***      Config= %d\n",dbfile,nConfig);
200   printf(" Input parameters:  nInit= %d   Nb linear pts= %d   Print level= %d   Plot Level= %d    nConfig= %d",nInit,nbpf1,printLevel,plotLevel,nConfig);
201   if(nbev==0)printf("\n");
202   else printf("  Nb_max evt = %d\n",maxEvents);
203   
204   muonGain->SetAliPrintLevel(printLevel);
205   muonGain->SetAliPlotLevel(plotLevel);
206   muonGain->SetconfigDA(nConfig);
207   
208   if(nConfig)
209   {
210     // Laod configuration ascii file from DetDB
211     sprintf(dbfile,"config_%s",getenv("DATE_ROLE_NAME"));
212     status=daqDA_DB_getFile(dbfile,dbfile);
213     if(status) {printf(" Failed  : Configuration file %s is missing, status = %d\n",dbfile,status); return -1; }
214     //    else printf(" *** Copy ascii config file: %s from DetDB to working directory and reading ...*** \n",dbfile);
215     muonGain->LoadConfig(dbfile);  
216   } 
217   
218   // Rawdeader, RawStreamHP
219   AliRawReader* rawReader = AliRawReader::Create(inputFile.Data());
220   AliMUONRawStreamTrackerHP* rawStream  = new AliMUONRawStreamTrackerHP(rawReader);    
221   rawStream->DisableWarnings();
222   rawStream->EnabbleErrorLogger();
223   
224   cout << "\n" << prefixDA << " : Reading data from file " << inputFile.Data()  << endl;
225   
226   while (rawReader->NextEvent())
227   {
228     if (nDateEvents >= maxDateEvents) break;
229     if (nEvents >= maxEvents) break;
230     if (nDateEvents>0 &&  nDateEvents % 100 == 0)       
231       cout<<"Cumulated:  DATE events = " << nDateEvents << "   Used events = " << nEvents << endl;
232     
233     // check shutdown condition 
234     if (daqDA_checkShutdown()) 
235       break;
236     //Skip events
237     while (skipEvents)
238     {
239       rawReader->NextEvent();
240       skipEvents--;
241     }
242     
243     Int_t eventType = rawReader->GetType();
244     runNumber = rawReader->GetRunNumber();
245     
246     // Output log file initialisations
247     if(nDateEvents==0)
248     {
249       sprintf(flatFile,"%s.log",prefixDA);
250       logOutputFile=flatFile;
251       
252       filcout.open(logOutputFile.Data());
253       filcout<<"//=================================================" << endl;
254       filcout<<"//       " << prefixDA << " for run = " << runNumber << "  (DAC=" << injCharge << ")" << endl;
255       filcout<<"//=================================================" << endl;
256       filcout<<"//   * Date          : " << muonGain->GetDate()->AsString("l") << "\n" << endl;
257       
258       cout<<"\n ********  " << prefixDA << " for run = " << runNumber << "  (Index= " << nIndex << "/" << nEntries << "  DAC=" << injCharge << ") ********\n" << endl;
259       cout<<" * Date : " << muonGain->GetDate()->AsString("l") << "\n" << endl;
260     }
261     
262     muonGain->SetAlifilcout(&filcout);
263     
264     nDateEvents++;
265     if (eventType != PHYSICS_EVENT)
266       continue; // for the moment
267     
268     // First lopp over DDL's to find good events
269     // Error counters per event (counters in the decoding lib are for each DDL)
270     Bool_t eventIsErrorMessage = kFALSE;
271     int eventGlitchErrors = 0;
272     int eventParityErrors = 0;
273     int eventPaddingErrors = 0;
274     int eventTokenlostErrors = 0;
275     rawStream->First();
276     do
277     {
278       if (rawStream->IsErrorMessage()) eventIsErrorMessage = kTRUE;
279       eventGlitchErrors += rawStream->GetGlitchErrors();
280       eventParityErrors += rawStream->GetParityErrors();
281       eventPaddingErrors += rawStream->GetPaddingErrors();
282       eventTokenlostErrors += rawStream->GetTokenLostErrors();
283     } while(rawStream->NextDDL()); 
284     
285     AliMUONRawStreamTrackerHP::AliBusPatch* busPatch;
286     if (!eventIsErrorMessage) 
287     {
288       // Good events (no error) -> compute pedestal for all channels
289       rawStream->First(); 
290       while( (busPatch = (AliMUONRawStreamTrackerHP::AliBusPatch*) rawStream->Next())) 
291             {
292               for(int i = 0; i < busPatch->GetLength(); ++i)
293         {
294           busPatch->GetData(i, manuId, channelId, charge);
295           muonGain->MakePed(busPatch->GetBusPatchId(), (Int_t)manuId, (Int_t)channelId, (Int_t)charge);
296         }
297             }
298       nEvents++;
299     }
300     else
301     {
302       // Events with errors
303       if (eventParityErrors && !eventGlitchErrors&& !eventPaddingErrors)
304             {
305               // Recover parity errors -> compute pedestal for all good buspatches
306               if ( TEST_SYSTEM_ATTRIBUTE( rawReader->GetAttributes(),
307                                    ATTR_ORBIT_BC )) 
308         {
309           filcout <<"Event recovered -> Period:"<<EVENT_ID_GET_PERIOD( rawReader->GetEventId() )
310           <<" Orbit:"<<EVENT_ID_GET_ORBIT( rawReader->GetEventId() )
311           <<" BunchCrossing:"<<EVENT_ID_GET_BUNCH_CROSSING( rawReader->GetEventId() )<<endl;                            
312         } 
313               else 
314         {
315           filcout <<"Event recovered -> nbInRun:"<<EVENT_ID_GET_NB_IN_RUN( rawReader->GetEventId() )
316           <<" burstNb:"<<EVENT_ID_GET_BURST_NB( rawReader->GetEventId() )
317           <<" nbInBurst:"<<EVENT_ID_GET_NB_IN_BURST( rawReader->GetEventId() )<<endl;
318         }
319               rawStream->First();
320               while( (busPatch = (AliMUONRawStreamTrackerHP::AliBusPatch*) rawStream->Next())) 
321         {
322           // Check the buspatch -> if error not use it in the pedestal calculation
323           int errorCount = 0;
324           for(int i = 0; i < busPatch->GetLength(); ++i)
325           {
326             if (!busPatch->IsParityOk(i)) errorCount++;
327           }
328           if (!errorCount) 
329           {
330             // Good buspatch
331             for(int i = 0; i < busPatch->GetLength(); ++i)
332             {
333               busPatch->GetData(i, manuId, channelId, charge);
334               muonGain->MakePed(busPatch->GetBusPatchId(), (Int_t)manuId, (Int_t)channelId, (Int_t)charge);
335             }
336           }
337           else
338           {
339             char bpname[256];
340             AliMUONErrorCounter* errorCounter;
341             // Bad buspatch -> not used (just print)
342             filcout<<"bpId "<<busPatch->GetBusPatchId()<<" words "<<busPatch->GetLength()
343             <<" parity errors "<<errorCount<<endl;
344             // Number of events where this buspatch is missing
345             sprintf(bpname,"bp%d",busPatch->GetBusPatchId());                                           
346             if (!(errorCounter = (AliMUONErrorCounter*) (muonGain->GetErrorBuspatchTable()->FindObject(bpname))))
347             {
348               // New buspatch
349               errorCounter = new AliMUONErrorCounter(busPatch->GetBusPatchId());
350               errorCounter->SetName(bpname);
351               muonGain->GetErrorBuspatchTable()->Add(errorCounter);
352             }
353             else
354             {
355               // Existing buspatch
356               errorCounter->Increment();
357             }   
358             // errorCounter->Print();                                           
359           } // end of if (!errorCount)
360         } // end of while( (busPatch = (AliMUONRawStreamTrackerHP ...
361               nEvents++;
362               nEventsRecovered++;
363             } //end of if (eventParityErrors && !eventGlitchErrors&& !eventPaddingErrors)
364       else
365             {
366               // Fatal errors reject the event
367               if ( TEST_SYSTEM_ATTRIBUTE( rawReader->GetAttributes(),
368                                    ATTR_ORBIT_BC )) 
369         {
370           filcout <<"Event rejected -> Period:"<<EVENT_ID_GET_PERIOD( rawReader->GetEventId() )
371           <<" Orbit:"<<EVENT_ID_GET_ORBIT( rawReader->GetEventId() )
372           <<" BunchCrossing:"<<EVENT_ID_GET_BUNCH_CROSSING( rawReader->GetEventId() )<<endl;                            
373         } 
374               else 
375         {
376           filcout <<"Event rejected -> nbInRun:"<<EVENT_ID_GET_NB_IN_RUN( rawReader->GetEventId() )
377           <<" burstNb:"<<EVENT_ID_GET_BURST_NB( rawReader->GetEventId() )
378           <<" nbInBurst:"<<EVENT_ID_GET_NB_IN_BURST( rawReader->GetEventId() )<<endl;
379           
380         }
381             } // end of if (!rawStream->GetGlitchErrors() && !rawStream->GetPaddingErrors() ...
382       filcout<<"Number of errors : Glitch "<<eventGlitchErrors
383       <<" Parity "<<eventParityErrors
384       <<" Padding "<<eventPaddingErrors
385       <<" Token lost "<<eventTokenlostErrors<<endl;
386       filcout<<endl;                    
387     } // end of if (!rawStream->IsErrorMessage())
388     
389     if (eventGlitchErrors)  nGlitchErrors++;
390     if (eventParityErrors)  nParityErrors++;
391     if (eventPaddingErrors) nPaddingErrors++;
392     if (eventTokenlostErrors) nTokenlostErrors++;
393
394   } // while (rawReader->NextEvent())
395   delete rawReader;
396   delete rawStream;
397   
398   // process and store mean peak values in .root file
399   sprintf(flatFile,"%s.par",prefixDA);
400   if(shuttleFile.IsNull())shuttleFile=flatFile;
401   injCharge=vDAC[nIndex-1];
402   muonGain->SetAliIndex(nIndex); // fIndex 
403   muonGain->SetAliInjCharge(injCharge);
404   muonGain->SetAliNEvents(nEvents);
405   muonGain->SetAliRunNumber(runNumber);
406   muonGain->MakePedStoreForGain(shuttleFile);
407   
408   
409   // writing some counters
410   cout << endl;
411   cout << prefixDA << " : Nb of DATE events           = " << nDateEvents    << endl;
412   cout << prefixDA << " : Nb of Glitch errors         = "   << nGlitchErrors  << endl;
413   cout << prefixDA << " : Nb of Parity errors         = "   << nParityErrors  << endl;
414   cout << prefixDA << " : Nb of Padding errors        = "   << nPaddingErrors << endl;          
415   cout << prefixDA << " : Nb of Token lost errors     = "   << nTokenlostErrors << endl;
416   cout << prefixDA << " : Nb of events recovered      = "   << nEventsRecovered<< endl;
417   cout << prefixDA << " : Nb of events without errors = "   << nEvents-nEventsRecovered<< endl;
418   cout << prefixDA << " : Nb of events used           = "   << nEvents        << endl;
419   
420   filcout << endl;
421   filcout << prefixDA << " : Nb of DATE events           = " << nDateEvents    << endl;
422   filcout << prefixDA << " : Nb of Glitch errors         = "   << nGlitchErrors << endl;
423   filcout << prefixDA << " : Nb of Parity errors         = "   << nParityErrors << endl;
424   filcout << prefixDA << " : Nb of Padding errors        = "   << nPaddingErrors << endl;
425   filcout << prefixDA << " : Nb of Token lost errors     = "   << nTokenlostErrors << endl;
426   filcout << prefixDA << " : Nb of events recovered      = "   << nEventsRecovered<< endl;      
427   filcout << prefixDA << " : Nb of events without errors = "   << nEvents-nEventsRecovered<< endl;
428   filcout << prefixDA << " : Nb of events used           = "   << nEvents        << endl;
429   
430   // Computing gain 
431   if(nIndex==nEntries)
432   {
433     muonGain->SetAliInit(nInit); // fnInit
434     muonGain->SetAliEntries(nEntries); // fnEntries
435     muonGain->SetAliNbpf1(nbpf1); // fnbpf1
436     muonGain->MakeGainStore(shuttleFile);
437 #ifdef ALI_AMORE  
438     std::ifstream in(shuttleFile.Data());
439     ostringstream stringout;
440     char line[1024];
441     while ( in.getline(line,1024) )
442       stringout << line << "\n";  
443     in.close();
444           
445     amore::da::AmoreDA amoreDA(amore::da::AmoreDA::kSender);
446     TObjString gaindata(stringout.str().c_str());
447     status = amoreDA.Send("Gains",&gaindata);
448     if ( status )
449       cout << "Warning: Failed to write Pedestals in the AMORE database : " << status << endl;
450     else 
451       cout << "amoreDA.Send(Gains) ok" << endl;  
452 #else
453     cout << "Warning: MCH DA not compiled with AMORE support" << endl;
454 #endif
455   }
456   
457   // ouput files
458   filcout << endl;
459   filcout << prefixDA << " : Root data file         : " << muonGain->GetRootDataFileName() << endl;
460   filcout << prefixDA << " : Output logfile         : " << logOutputFile  << endl;
461   filcout << prefixDA << " : Gain Histo file        : " << muonGain->GetHistoFileName() << endl;
462   filcout << prefixDA << " : Gain file (to SHUTTLE) : " << shuttleFile << endl;
463   
464   //     Copying files to local DB folder defined by DAQ_DETDB_LOCAL
465   Char_t *dir;
466   dir= getenv("DAQ_DETDB_LOCAL");
467   unsigned int nLastVersions = 50;
468   printf("\n ***  Local DataBase: %s  (Max= %d) ***\n",dir,nLastVersions);
469   status = daqDA_localDB_storeFile(logOutputFile.Data(),nLastVersions);
470   if(status)printf(" Store file : %s   status = %d\n",logOutputFile.Data(),status);
471   if(nIndex==nEntries)
472   {
473     status = daqDA_localDB_storeFile(muonGain->GetRootDataFileName(),nLastVersions);
474     if(status)printf(" Store file : %s   status = %d\n",muonGain->GetRootDataFileName(),status);
475     status = daqDA_localDB_storeFile(muonGain->GetHistoFileName(),nLastVersions);
476     if(status)printf(" Store file : %s   status = %d\n",muonGain->GetHistoFileName(),status);
477     status = daqDA_localDB_storeFile(shuttleFile.Data(),nLastVersions);
478     if(status)printf(" Store file : %s   status = %d\n",shuttleFile.Data(),status);
479   }      
480   
481   
482   // ouput files
483   cout << endl;
484   cout << prefixDA << " : Root data file         : " << muonGain->GetRootDataFileName() << endl;
485   cout << prefixDA << " : Output logfile         : " << logOutputFile  << endl;
486   cout << prefixDA << " : Gain Histo file        : " << muonGain->GetHistoFileName() << endl;
487   cout << prefixDA << " : Gain file (to SHUTTLE) : " << shuttleFile << endl;   
488   
489   filcout.close();
490   
491   // Transferring to calibration file to  FES
492   // be sure that env variable DAQDALIB_PATH is set in script file
493   //       gSystem->Setenv("DAQDALIB_PATH", "$DATE_SITE/infoLogger");
494   printf("\n *****  STORE calibration FILE to FES ****** \n");
495   status = daqDA_FES_storeFile(shuttleFile.Data(),"GAINS");
496   if (status) { printf(" Failed to export file : %s , status = %d\n",shuttleFile.Data(),status); return -1; }
497   //  else printf(" %s successfully exported to FES  \n",shuttleFile.Data());
498   
499   printf("\n ######## End execution : %s ######## \n",prefixDA); 
500   timers.Stop();
501   printf("\nExecution time : R:%7.2fs C:%7.2fs\n", timers.RealTime(), timers.CpuTime());
502   return status;
503 }
504