]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/ITSSPDPHYSda.cxx
modified SubStave.. to HalfStave
[u/mrichter/AliRoot.git] / ITS / ITSSPDPHYSda.cxx
1 /*
2 Contact: henrik.tydesjo@cern.ch
3 Link: tydes.home.cern.ch/tydes/doc/CalibrationOverview/CalibrationAlgorithms/
4 Run Type: PHYSICS
5 DA Type: MON
6 Number of events needed: Depending on muliplicity per event
7 Input Files: spd_physics_params ,  ./calibResults/DeadReferenceTmp/* ,  ./calibResults/DeadToFXS/*
8 Output Files: ./calibResults/NoisyReference/* ,  ./calibResults/DeadReference/* ,  ./calibResults/NoisyToFXS/* ,  ./calibResults/DeadReferenceTmp/*,./calibResults/DeadToFXS/*
9 Trigger types used: PHYSICS
10 */
11
12 ////////////////////////////////////////////////////////////////////////////////
13 // This program can be compiled in two modes.                                 //
14 //                                                                            //
15 // 1. Online. With the DAQ DA framework. This is the default operating mode.  //
16 //                                                                            //
17 // 2. Offline. Without the DAQ DA framework. Define the SPD_DA_OFF            //
18 //    environment var. Call this program with the name of the executable      //
19 //    followed by the runNr and the data files to process.                    //
20 //                                                                            //
21 ////////////////////////////////////////////////////////////////////////////////
22
23 #ifndef SPD_DA_OFF
24 extern "C" {
25 #include "daqDA.h"
26 }
27 #endif
28 #include "event.h"
29 #include "monitor.h"
30 #include "AliRawReaderDate.h"
31 #include "AliITSRawStreamSPD.h"
32 #include "AliITSOnlineSPDphys.h"
33 #include "AliITSOnlineSPDphysAnalyzer.h"
34 #include "AliITSOnlineCalibrationSPDhandler.h"
35 #include "AliLog.h"
36 #include <iostream>
37 #include <fstream>
38 #include <time.h>
39 #include <TROOT.h>
40 #include <TPluginManager.h>
41 #include <TObjArray.h>
42 #include <TObjString.h>
43 #include <TString.h>
44 #include <cstdlib>
45
46
47 int main(int argc, char **argv) {
48   if (argc<2) {
49     printf("SPD DA ERROR: Wrong number of arguments\n");
50     return -1;
51   }
52
53   UInt_t nrErrors = 0;
54
55   // directory structure, hard coded                              //   FOR OFFLINE VERSION:
56   char *saveDirDead          = "./calibResults/Dead";             // may NOT delete content
57   char *saveDirDeadToFXS     = "./calibResults/DeadToFXS";        //     may delete content
58   char *saveDirDeadRef       = "./calibResults/DeadReference";    //     may delete content
59   char *saveDirDeadRefTmp    = "./calibResults/DeadReferenceTmp"; // may NOT delete content
60   char *saveDirNoisyToFXS    = "./calibResults/NoisyToFXS";       //     may delete content
61   char *saveDirNoisyRef      = "./calibResults/NoisyReference";   //     may delete content
62   char *saveDirIdsToFXS      = "./calibResults/IdsToFXS";         //     may delete content
63   char *configFilesDir       = "./configFiles";                   //     may delete content
64   // clean up and make sure the directory structure is put up correctly:
65 #ifndef SPD_DA_OFF
66   system("rm ./calibResults -rf >& /dev/null");
67   system("rm ./ITS -rf >& /dev/null");
68 #else
69   system("rm ./calibResults/DeadToFXS -rf >& /dev/null");
70   system("rm ./calibResults/DeadReference -rf >& /dev/null");
71   system("rm ./calibResults/NoisyToFXS -rf >& /dev/null");
72   system("rm ./calibResults/NoisyReference -rf >& /dev/null");
73   system("rm ./calibResults/IdsToFXS -rf >& /dev/null");
74 #endif
75   system("mkdir ./calibResults >& /dev/null");
76   system("mkdir ./calibResults/Dead >& /dev/null");
77   system("mkdir ./calibResults/DeadToFXS >& /dev/null");
78   system("mkdir ./calibResults/DeadReference >& /dev/null");
79   system("mkdir ./calibResults/DeadReferenceTmp >& /dev/null");
80   system("mkdir ./calibResults/NoisyToFXS >& /dev/null");
81   system("mkdir ./calibResults/NoisyReference >& /dev/null");
82   system("mkdir ./calibResults/IdsToFXS >& /dev/null");
83   system("mkdir ./configFiles >& /dev/null");
84 #ifndef SPD_DA_OFF
85   system("mkdir ./ITS >& /dev/null");
86   system("mkdir ./ITS/Calib >& /dev/null");
87   system("mkdir ./ITS/Calib/SPDNoisy >& /dev/null");
88 #endif
89   // parameters config file
90   TString paramsFileName = Form("%s/physics_params.txt",configFilesDir);
91
92   // This line is needed in case of a stand-alone application w/o
93   // $ROOTSYS/etc/system.rootrc file
94   gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
95                                         "*",
96                                         "TStreamerInfo",
97                                         "RIO",
98                                         "TStreamerInfo()");
99
100   // turn off annoying warning messages
101   // NB: Should not be handled here
102   AliLog* logger = AliLog::GetRootLogger();
103   logger->SetGlobalDebugLevel(-20);
104
105   // ********* STEP 0: Get configuration files from db (if there are any) , then read parameters*********
106   UInt_t nrTuningParams = 0;
107   TObjArray paramNames;  paramNames.SetOwner(kTRUE);
108   TObjArray paramVals;  paramVals.SetOwner(kTRUE);
109   
110   // tuning parameters:
111   Int_t par_status = 0;
112 #ifndef SPD_DA_OFF
113   TString idp = "spd_physics_params";
114   par_status=daqDA_DB_getFile(idp.Data(),paramsFileName.Data());
115   if (par_status) {
116     printf("SPD DA: Failed to get config file %s: status=%d. Using default tuning parameters.\n",idp.Data(),par_status);
117     TString rmCmd = Form("rm -f %s",paramsFileName.Data());
118     system(rmCmd.Data());
119   }
120 #endif
121   if (par_status==0) {
122     ifstream paramsFile;
123     paramsFile.open(paramsFileName.Data(), ifstream::in);
124     if (paramsFile.fail()) {
125       printf("SPD DA: No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
126     }
127     else {
128       while(1) {
129         Char_t paramN[50];
130         Char_t paramV[50];
131         paramsFile >> paramN;
132         if (paramsFile.eof()) break;
133         paramsFile >> paramV;
134         paramNames.AddAtAndExpand(new TObjString(paramN),nrTuningParams);
135         paramVals.AddAtAndExpand(new TObjString(paramV),nrTuningParams);
136         nrTuningParams++;
137         if (paramsFile.eof()) break;
138       }
139       paramsFile.close();
140     }
141   }
142   //  for (UInt_t i=0; i<nrTuningParams; i++) {
143   //  //    printf("Entry %d: N=%s , V=%s\n",i,((TString*)paramNames.At(i))->Data(),((TString*)paramVals.At(i))->Data());
144   //    printf("Entry %d: N=%s , V=%s\n",i,((TObjString*)paramNames.At(i))->GetString().Data(),((TObjString*)paramVals.At(i))->GetString().Data());
145   //  }
146
147
148
149
150
151   // create calibration handler (needed already at step 1 in order to fill which eq,hs,chips are active
152   AliITSOnlineCalibrationSPDhandler* handler = new AliITSOnlineCalibrationSPDhandler();
153
154   // Read silent=dead+inactive info from previous calibrations
155 #ifndef SPD_DA_OFF
156   for (UInt_t eq=0; eq<20; eq++) {
157     Int_t getPreviousDead_status = 0;
158     TString idpd = Form("spd_previous_dead_%d",eq);
159     TString fileName = Form("%s/SPD_Dead_%d.root",saveDirDead,eq);
160     getPreviousDead_status = daqDA_DB_getFile(idpd.Data(),fileName.Data());
161     //        printf("daqDA_DB_getFile(%s,%s)\n",idpd.Data(),fileName.Data());
162     if (getPreviousDead_status) {
163       printf("SPD DA: Failed to get dead file %s: status=%d. Dead search will start from zero for this eq.\n",idpd.Data(),getPreviousDead_status);
164       TString rmCmd = Form("rm -f %s",fileName.Data());
165       system(rmCmd.Data());
166     }
167   }
168 #endif
169   handler->SetFileLocation(saveDirDead);
170   handler->ReadSilentFromFiles();
171   printf("SPD DA: Number of single dead pixels from previous runs: %d\n",handler->GetNrDead());
172
173   // Read hit-maps from previous runs
174 #ifndef SPD_DA_OFF
175   for (UInt_t eq=0; eq<20; eq++) {
176     Int_t getPreviousHitmap_status = 0;
177     TString idph = Form("spd_previous_hitmap_%d",eq);
178     TString fileName = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eq);
179     getPreviousHitmap_status = daqDA_DB_getFile(idph.Data(),fileName.Data());
180     //    printf("daqDA_DB_getFile(%s,%s)\n",idph.Data(),fileName.Data());
181     if (getPreviousHitmap_status) {
182       printf("SPD DA: Failed to get previous hitmap file %s: status=%d. Dead search will start with empty hitmap for this eq.\n",idph.Data(),getPreviousHitmap_status);
183       TString rmCmd = Form("rm -f %s",fileName.Data());
184       system(rmCmd.Data());
185     }
186   }
187 #endif
188
189
190
191
192   // ********* STEP 1: Produce phys container files (Reference Data). ***********************************
193
194 #ifndef SPD_DA_OFF
195   if (getenv("DATE_RUN_NUMBER")==0) {
196     printf("SPD DA ERROR: DATE_RUN_NUMBER not properly set.\n");
197     return -1;
198   }
199   int runNr = atoi(getenv("DATE_RUN_NUMBER"));
200 #else
201   int runNr = atoi(argv[1]);
202   int startSeg = 2;
203 #endif
204
205
206   // container objects
207   AliITSOnlineSPDphys *physObj[20];
208   Bool_t bPhysInit[20];
209   for (UInt_t eq=0; eq<20; eq++) {
210     physObj[eq]=NULL;
211     bPhysInit[eq]=kFALSE;
212   }
213
214
215   UInt_t eventNr=0;
216
217   // loop over run segments in case of offline mode
218 #ifdef SPD_DA_OFF
219   for (int segNr=startSeg; segNr<argc; segNr++) {
220 #endif
221
222     int status;
223
224     /* define data source : */  
225 #ifndef SPD_DA_OFF
226     status=monitorSetDataSource( argv[1] ); // should be "^SPD" in order to get full detector online
227 #else
228     status=monitorSetDataSource( argv[segNr] );
229 #endif
230     if (status!=0) {
231       printf("SPD DA ERROR: monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
232       return -1;
233     }
234     /* declare monitoring program */
235     status=monitorDeclareMp("ITS_SPD_PHYS");
236     if (status!=0) {
237       printf("SPD DA ERROR: monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
238       return -1;
239     }
240     /* define wait event timeout - 1s max */
241     monitorSetNowait();
242     monitorSetNoWaitNetworkTimeout(1000);
243
244
245     /* main loop (infinite) */
246     for(;;) {
247
248       struct eventHeaderStruct *event;
249       eventTypeType eventT;
250
251       /* check shutdown condition */
252 #ifndef SPD_DA_OFF
253       if (daqDA_checkShutdown()) {break;}
254 #endif
255
256       /* get next event (blocking call until timeout) */
257       status=monitorGetEventDynamic((void **)&event);
258       if (status==MON_ERR_EOF) {
259         printf ("SPD DA: End of File detected\n");
260         break; /* end of monitoring file has been reached */
261       }
262
263       if (status!=0) {
264         printf("SPD DA: monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
265         break;
266       }
267
268       /* retry if got no event */
269       if (event==NULL) {
270         continue;
271       }
272
273       eventT=event->eventType;
274       if (eventT == PHYSICS_EVENT){
275
276         //      printf("eventNr %d\n",eventNr);
277
278         AliRawReader *reader = new AliRawReaderDate((void*)event);
279         AliITSRawStreamSPD *str = new AliITSRawStreamSPD(reader);
280
281         while (str->Next()) {
282
283           Int_t eq = reader->GetDDLID();
284           // check that this hs is active in handler object
285           if (!(handler->IsActiveEq(eq))) {
286             printf("SPD DA: Found Eq (%d) , previously inactive\n",eq);
287             handler->ActivateEq(eq);
288           }
289           if (eq>=0 && eq<20) {
290             if (!bPhysInit[eq]) { // this code is duplicated for the moment... (see also below)
291               TString fileName = Form("%s/SPDphys_run_%d_eq_%d.root",saveDirNoisyRef,runNr,eq);
292               physObj[eq] = new AliITSOnlineSPDphys(fileName.Data());
293               physObj[eq]->AddRunNr(runNr);
294               physObj[eq]->SetEqNr(eq);
295               bPhysInit[eq]=kTRUE;
296             }
297
298             UInt_t hs = str->GetHalfStaveNr();
299             // check that this hs is active in handler object
300             if (!(handler->IsActiveHS(eq,hs))) {
301               printf("SPD DA: Found HS (%d,%d) , previously inactive\n",eq,hs);
302               handler->ActivateHS(eq,hs);
303             }
304             UInt_t chip = str->GetChipAddr();
305             // check that this chip is active in handler object
306             if (!(handler->IsActiveChip(eq,hs,chip))) {
307               printf("SPD DA: Found Chip (%d,%d,%d) , previously inactive\n",eq,hs,chip);
308               handler->ActivateChip(eq,hs,chip);
309             }
310             physObj[eq]->IncrementHits(hs,chip,str->GetChipCol(),str->GetChipRow());
311             
312           }
313         }
314
315
316         // check which eq and hs are active, for first event only
317         if (eventNr==0) {
318           for (UInt_t eq=0; eq<20; eq++) {
319             // activate Eq and HSs in handler object
320             if (str->IsActiveEq(eq)) {
321               handler->ActivateEq(eq);
322               for (UInt_t hs=0; hs<6; hs++) {
323                 if (str->IsActiveHS(eq,hs)) {
324                   handler->ActivateHS(eq,hs);
325                   for (UInt_t chip=0; chip<10; chip++) {
326                     if (str->IsActiveChip(eq,hs,chip)) {
327                       handler->ActivateChip(eq,hs,chip);
328                     }
329                     else {
330                       handler->ActivateChip(eq,hs,chip,kFALSE);
331                     }
332                   }
333                 }
334                 else {
335                   handler->ActivateHS(eq,hs,kFALSE);
336                 }
337               }
338               if (!bPhysInit[eq]) { // this code is duplicated for the moment... (see also above)
339                 TString fileName = Form("%s/SPDphys_run_%d_eq_%d.root",saveDirNoisyRef,runNr,eq);
340                 physObj[eq] = new AliITSOnlineSPDphys(fileName.Data());
341                 physObj[eq]->AddRunNr(runNr);
342                 physObj[eq]->SetEqNr(eq);
343                 bPhysInit[eq]=kTRUE;
344               }
345             }
346             else {
347               handler->ActivateEq(eq,kFALSE);
348             }
349           }
350         }
351
352
353         for (UInt_t eq=0; eq<20; eq++) {
354           if (bPhysInit[eq]) {
355             physObj[eq]->IncrementNrEvents();
356           }
357         }
358
359         delete str;
360         delete reader;
361
362         eventNr++;
363
364       }
365
366       /* free resources */
367       free(event);
368
369     }
370     
371
372 #ifdef SPD_DA_OFF
373     printf("SPD DA: progress: %d\n",(unsigned int)( ((Float_t)(segNr-startSeg+1))/(argc-startSeg)*50 ));
374   }
375 #endif
376
377   // clean up phys objects (also saves them)
378   for (UInt_t eq=0; eq<20; eq++) {
379     if (physObj[eq]!=NULL) delete physObj[eq];
380   }
381
382   printf("SPD DA: %d events collected for this run.\n",eventNr);
383
384
385
386
387   // ********* STEP 2: Analyze phys container files. ************************************************
388
389   time_t timeStamp = time(NULL);
390   //  printf("*** Start step2 , %d\n",time(NULL) - timeStamp);
391
392   UInt_t firstRunNrDead = runNr;
393
394
395   UInt_t nrEnoughStatNoisy = 0;
396   UInt_t nrEqActiveNoisy = 0;
397   Bool_t eqActiveNoisy[20];
398
399   // *** *** *** start loop over equipments (eq_id)
400   for (UInt_t eq=0; eq<20; eq++) {
401     eqActiveNoisy[eq] = kFALSE;
402
403     // create analyzer for this eq
404     TString fileName = Form("%s/SPDphys_run_%d_eq_%d.root",saveDirNoisyRef,runNr,eq);
405     AliITSOnlineSPDphysAnalyzer *noisyAnalyzer = new AliITSOnlineSPDphysAnalyzer(fileName.Data(),handler);
406
407     // check data in container
408     if (noisyAnalyzer->GetEqNr() != eq) {
409       if (noisyAnalyzer->GetEqNr() != 999) {
410         printf("SPD DA ERROR: Mismatching EqId in Container data and filename (%d!=%d). Skipping eq.\n",noisyAnalyzer->GetEqNr(),eq);
411       }
412       delete noisyAnalyzer;
413       continue;
414     }
415
416     nrEqActiveNoisy++;
417     eqActiveNoisy[eq] = kTRUE;
418
419     // configure analyzer with tuning parameters etc:
420     for (UInt_t i=0; i<nrTuningParams; i++) {
421       noisyAnalyzer->SetParam(((TObjString*)paramNames.At(i))->GetString().Data(),((TObjString*)paramVals.At(i))->GetString().Data());
422     }
423
424     printf("SPD DA: SPD phys STEP 2: Noisy search for eq %d\n",eq);  
425
426     // search for noisy pixels:
427     nrEnoughStatNoisy += noisyAnalyzer->ProcessNoisyPixels();
428
429     // copy this phys obj to temporary dead reference dir to process after noisy search
430     TString fileNameDead = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eq);
431     AliITSOnlineSPDphys* physObj = new AliITSOnlineSPDphys(fileNameDead.Data());
432     physObj->AddPhys(noisyAnalyzer->GetOnlinePhys());
433     if (physObj->GetNrRuns()>0) {
434       UInt_t firstRunNr = physObj->GetRunNr(0);
435       if (firstRunNrDead>firstRunNr) {
436         firstRunNrDead=firstRunNr;
437       }
438     }
439     // remove noisy pixels from dead hitmap
440     for (UInt_t hs=0; hs<6; hs++) {
441       for (UInt_t chip=0; chip<10; chip++) {
442         for (UInt_t ind=0; ind<handler->GetNrNoisyC(eq,hs,chip); ind++) {
443           UInt_t col  = handler->GetNoisyColAtC(eq,hs,chip,ind);
444           UInt_t row  = handler->GetNoisyRowAtC(eq,hs,chip,ind);
445           physObj->AddHits(hs,chip,col,row,-noisyAnalyzer->GetOnlinePhys()->GetHits(hs,chip,col,row));
446         }
447       }
448     }
449
450     delete physObj;
451     delete noisyAnalyzer;
452
453 #ifndef SPD_DA_OFF
454     //    daqDA_progressReport((unsigned int)((eq+1)*2.5));
455     printf("SPD DA: progress: %d , %ld\n",(unsigned int)(50+(eq+1)*2.5), time(NULL) - timeStamp);
456 #else
457     //    printf("SPD DA: progress: %d\n",(unsigned int)(50+(eq+1)*1.25));
458     printf("SPD DA: progress: %d , %ld\n",(unsigned int)(50+(eq+1)*1.25), time(NULL) - timeStamp);
459 #endif
460   }
461   // *** *** *** end loop over equipments (eq_id)
462
463   printf("SPD DA: Noisy search finished. %d noisy pixels found. %d chips had enough statistics.\n",
464          handler->GetNrNoisy(),nrEnoughStatNoisy);
465   handler->SetFileLocation(saveDirNoisyToFXS);
466   UInt_t nrNoisyFilesProduced = handler->WriteNoisyToFiles();
467 #ifndef SPD_DA_OFF
468   // save noisy to local OCDB
469   handler->WriteNoisyToDB(runNr,9999999,".");
470   // store local OCDB file in daq Det DB
471   TString ocdb_fileName = Form("./ITS/Calib/SPDNoisy/Run%d_9999999_v0_s0.root",runNr);
472   TString idod = "spd_noisy_ocdb";
473   Int_t ocdb_store_status = daqDA_DB_storeFile(ocdb_fileName.Data(),idod.Data());
474   //    printf("daqDA_DB_storeFile(%s,%s)\n",ocdb_fileName.Data(),idod.Data());
475   if (ocdb_store_status) {
476     printf("SPD DA ERROR: Failed to store noisy ocdb file %s in daqDetDB: status=%d.\n",idod.Data(),ocdb_store_status);
477   }
478 #endif
479
480
481
482
483
484   UInt_t nrEnoughStatChips = 0;
485   UInt_t nrDeadChips = 0;
486   UInt_t nrInefficientChips = 0;
487   UInt_t nrEqActiveDead = 0;
488   Bool_t eqActiveDead[20];
489
490   // *** *** *** start loop over equipments (eq_id)
491   for (UInt_t eq=0; eq<20; eq++) {
492     eqActiveDead[eq] = kFALSE;
493
494     // setup analyzer for dead search
495     TString fileNameDead = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eq);
496     AliITSOnlineSPDphys* physObj = new AliITSOnlineSPDphys(fileNameDead.Data());
497     AliITSOnlineSPDphysAnalyzer* deadAnalyzer = new AliITSOnlineSPDphysAnalyzer(physObj,handler);
498     // check data in container
499     if (deadAnalyzer->GetEqNr() != eq) {
500       if (deadAnalyzer->GetEqNr() != 999) {
501         printf("SPD DA ERROR: Mismatching EqId in Dead Container data and filename (%d!=%d). Skipping eq.\n",deadAnalyzer->GetEqNr(),eq);
502       }
503       delete deadAnalyzer;
504       nrDeadChips+=60; // since this eq is inactive...
505       continue;
506     }
507
508     nrEqActiveDead++;
509     eqActiveDead[eq] = kTRUE;
510
511     // configure analyzer with tuning parameters etc:
512     for (UInt_t i=0; i<nrTuningParams; i++) {
513       deadAnalyzer->SetParam(((TObjString*)paramNames.At(i))->GetString().Data(),((TObjString*)paramVals.At(i))->GetString().Data());
514     }
515
516     UInt_t nrEventsCollected = physObj->GetNrEvents();
517     printf("SPD DA: SPD phys STEP 2: Dead search for eq %d (%d events)\n",eq,nrEventsCollected);  
518
519     // search for dead pixels:
520     nrEnoughStatChips += deadAnalyzer->ProcessDeadPixels();
521     nrDeadChips += deadAnalyzer->GetNrDeadChips();
522     nrInefficientChips += deadAnalyzer->GetNrInefficientChips();
523
524     delete deadAnalyzer;
525
526
527 #ifndef SPD_DA_OFF
528     //    daqDA_progressReport((unsigned int)(50+(eq+1)*2.5));
529     printf("SPD DA: progress: %d , %ld\n",(unsigned int)(50+(eq+1)*2.5), time(NULL) - timeStamp);
530 #else
531     //    printf("SPD DA: progress: %d\n",(unsigned int)(75+(eq+1)*1.25));
532     printf("SPD DA: progress: %d , %ld\n",(unsigned int)(75+(eq+1)*1.25), time(NULL) - timeStamp);
533 #endif
534   }
535   // *** *** *** end loop over equipments (eq)
536
537
538
539   
540   printf("SPD DA: Dead search finished.\n");
541   printf("SPD DA: %d single dead pixels , %d dead or inactive pixels in total.\n",handler->GetNrDead(),handler->GetNrSilent());
542   printf("SPD DA: %d chips had enough statistics. %d chips are dead. %d chips are inefficient.\n",nrEnoughStatChips,nrDeadChips,nrInefficientChips);
543   handler->SetFileLocation(saveDirDead);
544   handler->WriteSilentToFilesAlways();
545   handler->SetFileLocation(saveDirDeadToFXS);
546   handler->WriteSilentToFilesAlways();
547
548
549   //  printf("SPD DA: Opening id list file\n");
550   printf("SPD DA: Opening id list file , %ld\n",time(NULL) - timeStamp);
551   TString idsFXSFileName = Form("%s/FXSids_run_%d.txt",saveDirIdsToFXS,runNr);
552   ofstream idsFXSfile;
553   idsFXSfile.open(idsFXSFileName.Data());
554
555
556   // store dead+inactive pixels in DB, used as starting point for later runs
557 #ifndef SPD_DA_OFF
558   printf("store previous dead in DB , %ld\n",time(NULL) - timeStamp);
559   for (UInt_t eq=0; eq<20; eq++) {
560     Int_t storePreviousDead_status = 0;
561     TString idpd = Form("spd_previous_dead_%d",eq);
562     TString fileName = Form("%s/SPD_Dead_%d.root",saveDirDead,eq);
563     storePreviousDead_status = daqDA_DB_storeFile(fileName.Data(),idpd.Data());
564     //    printf("daqDA_DB_storeFile(%s,%s)\n",fileName.Data(),idpd.Data());
565     if (storePreviousDead_status) {
566       printf("SPD DA ERROR: Failed to store dead file %s in daqDetDB: status=%d.\n",idpd.Data(),storePreviousDead_status);
567     }
568   }
569 #endif
570
571
572   // send (dead) reference data for this run to FXS - only if there is no chip in category "needsMoreStat"
573   if (nrEnoughStatChips>0 && nrEnoughStatChips+nrDeadChips+nrInefficientChips == 1200) {
574     printf("SPD DA: Dead calibration is complete.\n");
575     printf("SPD DA: Preparing dead reference data\n");
576     // send reference data for dead pixels to FXS
577     TString tarFiles = "";
578     for (UInt_t eq=0; eq<20; eq++) {
579       if (eqActiveDead[eq]) {
580         printf("SPD DA: Preparing dead pixels for eq %d\n",eq);
581         // move file to ref dir
582         TString fileName = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eq);
583         TString newFileName = Form("%s/SPDphys_dead_run_%d_%d_eq_%d.root",saveDirDeadRef,firstRunNrDead,runNr,eq);
584         TString command = Form("mv -f %s %s",fileName.Data(),newFileName.Data());
585         system(command.Data());
586         tarFiles.Append(Form("SPDphys_dead_run_%d_%d_eq_%d.root ",firstRunNrDead,runNr,eq));
587         // create empty hitmap file to send to DB later
588         AliITSOnlineSPDphys* physObj = new AliITSOnlineSPDphys(fileName.Data());
589         physObj->SetEqNr(eq);
590         delete physObj;
591       }
592     }
593     if  (tarFiles.Length() > 0) {   // make sure there are some files to send
594       TString send_command = Form("cd %s; tar -cf ref_phys_dead.tar %s",saveDirDeadRef,tarFiles.Data());
595       system(send_command.Data());
596       TString fileName = Form("%s/ref_phys_dead.tar",saveDirDeadRef);
597       TString id = "SPD_ref_phys_dead";
598 #ifndef SPD_DA_OFF
599       status = daqDA_FES_storeFile(fileName.Data(),id.Data());
600       if (status!=0) {
601         printf("SPD DA ERROR: Failed to export file %s , status %d\n",fileName.Data(),status);
602         nrErrors++;
603       }
604 #endif
605       idsFXSfile << Form("%s\n",id.Data());
606     }
607   }
608
609   // store hitmaps (maybe empty) in DB, used as starting point for later runs:
610 #ifndef SPD_DA_OFF
611   printf("store previous hitmaps in DB , %ld\n",time(NULL) - timeStamp);
612   for (UInt_t eq=0; eq<20; eq++) {
613     Int_t storePreviousHitmap_status = 0;
614     TString idph = Form("spd_previous_hitmap_%d",eq);
615     TString fileName = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eq);
616     storePreviousHitmap_status = daqDA_DB_storeFile(fileName.Data(),idph.Data());
617     //    printf("daqDA_DB_storeFile(%s,%s)\n",fileName.Data(),idph.Data());
618     if (storePreviousHitmap_status) {
619       printf("SPD DA ERROR: Failed to store hitmap file %s in daqDetDB: status=%d.\n",idph.Data(),storePreviousHitmap_status);
620     }
621   }
622 #endif
623
624
625
626   // send (noisy) reference data for this run to FXS
627   //  printf("SPD DA: Preparing physics reference data for this run\n");
628   printf("SPD DA: Preparing physics reference data for this run , %ld\n",time(NULL) - timeStamp);
629   TString tarFiles = "";
630   for (UInt_t eq=0; eq<20; eq++) {
631     if (eqActiveNoisy[eq]) {
632       tarFiles.Append(Form("SPDphys_run_%d_eq_%d.root ",runNr,eq));
633     }
634   }
635   if  (tarFiles.Length() > 0) {   // make sure there are any files to send
636     TString send_command = Form("cd %s; tar -cf ref_phys.tar %s",saveDirNoisyRef,tarFiles.Data());
637     system(send_command.Data());
638     TString fileName = Form("%s/ref_phys.tar",saveDirNoisyRef);
639     TString id = "SPD_ref_phys";
640 #ifndef SPD_DA_OFF
641     status = daqDA_FES_storeFile(fileName.Data(),id.Data());
642     if (status!=0) {
643       printf("SPD DA ERROR: Failed to export file %s , status %d\n",fileName.Data(),status);
644       nrErrors++;
645     }
646 #endif
647     idsFXSfile << Form("%s\n",id.Data());
648   }
649
650
651
652   // send dead pixels to FXS
653   //  printf("SPD DA: Preparing dead files for FXS\n");
654   printf("SPD DA: Preparing dead files for FXS , %ld\n",time(NULL) - timeStamp);
655   // send a tared file of all the dead files
656   TString send_command = Form("cd %s; tar -cf dead_phys.tar *",saveDirDeadToFXS);
657   //  printf("\n\n%s\n\n",command.Data());
658   system(send_command.Data());
659   TString fileName = Form("%s/dead_phys.tar",saveDirDeadToFXS);
660   TString id = "SPD_phys_dead";
661 #ifndef SPD_DA_OFF
662   Int_t send_status = daqDA_FES_storeFile(fileName.Data(),id.Data());
663   if (send_status!=0) {
664     printf("SPD DA ERROR: Failed to export file %s , status %d\n",fileName.Data(),send_status);
665     nrErrors++;
666   }
667 #endif
668   idsFXSfile << Form("%s\n",id.Data());
669
670
671
672   // send noisy pixels to FXS
673   if (nrNoisyFilesProduced > 0) {   // make sure there is at least one file created
674     //    printf("SPD DA: Preparing noisy files for FXS\n");
675     printf("SPD DA: Preparing noisy files for FXS , %ld\n",time(NULL) - timeStamp);
676     // send a tared file of all the noisy files
677     TString command = Form("cd %s; tar -cf noisy_phys.tar *",saveDirNoisyToFXS);
678     //    printf("\n\n%s\n\n",command.Data());
679     system(command.Data());
680     TString fileName = Form("%s/noisy_phys.tar",saveDirNoisyToFXS);
681     TString id = "SPD_phys_noisy";
682 #ifndef SPD_DA_OFF
683     status = daqDA_FES_storeFile(fileName.Data(),id.Data());
684     if (status!=0) {
685       printf("SPD DA ERROR: Failed to export file %s , status %d\n",fileName.Data(),status);
686       nrErrors++;
687     }
688 #endif
689     idsFXSfile << Form("%s\n",id.Data());
690   }
691
692
693
694   // send ids file to FXS
695   idsFXSfile.close();
696   id = "SPD_id_list";
697 #ifndef SPD_DA_OFF
698   status = daqDA_FES_storeFile(idsFXSFileName.Data(),id.Data());
699   if (status!=0) {
700     printf("SPD DA ERROR: Failed to export file %s , status %d\n",idsFXSFileName.Data(),status);
701     nrErrors++;
702   }
703 #endif
704
705
706
707
708   delete handler;
709
710   printf("SPD DA: End of all operations, %d errors, %ld\n", nrErrors, time(NULL) - timeStamp);
711
712   if (nrErrors>0) return -1;
713
714   return 0;
715
716 }