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