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