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