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