Minor issues solved. Additional printouts for debugging purposes (H. Tydesjo)
[u/mrichter/AliRoot.git] / ITS / ITSSPDSCANda.cxx
1 /*
2 - Contact: - henrik.tydesjo@cern.ch
3 - Link: - http://tydes.home.cern.ch/tydes/doc/CalibrationOverview/CalibrationAlgorithms/
4 - Run Type: - DAQ_MIN_TH_SCAN,DAQ_MEAN_TH_SCAN,DAQ_UNIFORMITY_SCAN,DAQ_NOISY_PIX_SCAN,DAQ_PIX_DELAY_SCAN,DAQ_FO_UNIF_SCAN
5 - DA Type: - LDC
6 - Number of events needed:
7 - Input Files: - daq db config files: spd_standal_params,spd_perm_noisy ,  previous noisy lists: ./calibResults/ScanNoisy/* ,  raw data
8 - Output Files: - Ref Data: ./calibResults/ScanReference/* ,  DCS update: ./calibResults/ScanDCSconfigToFXS/* ,  OCDB update: ./calibResults/ScanNoisyToFXS/* ,  persistent files: ./calibResults/ScanNoisy/*
9 - Trigger types used: 
10 */
11
12 ////////////////////////////////////////////////////////////////////////////////
13 // This program can be compiled in two modes.                                 //
14 //                                                                            //
15 // 1. With the DAQ DA framework on. This is the default operating mode.       //
16 // Call this program with the name of the executable followed by the          //
17 // data files to process.                                                     //
18 //                                                                            //
19 // 2. Without the DAQ DA framework on. Define the SPD_DA_OFF environment var. //
20 // Call this program with the name of the executable followed by the          //
21 // runNr and the data files to process.                                       //
22 //                                                                            //
23 ////////////////////////////////////////////////////////////////////////////////
24
25 #ifndef SPD_DA_OFF
26 extern "C" {
27 #include "daqDA.h"
28 }
29 #endif
30 #include "event.h"
31 #include "monitor.h"
32 #include "AliRawReaderDate.h"
33 #include "AliITSRawStreamSPD.h"
34 #include "AliITSOnlineSPDscan.h"
35 #include "AliITSOnlineSPDscanSingle.h"
36 #include "AliITSOnlineSPDscanMultiple.h"
37 #include "AliITSOnlineSPDscanMeanTh.h"
38 #include "AliITSOnlineSPDscanAnalyzer.h"
39 #include "AliITSOnlineCalibrationSPDhandler.h"
40 #include "AliLog.h"
41 #include <iostream>
42 #include <fstream>
43 #include <TROOT.h>
44 #include <TPluginManager.h>
45 #include <TObjArray.h>
46 #include <TString.h>
47 #include <TFitter.h>
48
49 int main(int argc, char **argv) {
50   if (argc<2) {
51     printf("Wrong number of arguments\n");
52     return -1;
53   }
54
55   // directory structure, hard coded
56   char *saveDirNoisy         = "./calibResults/ScanNoisy";          // may NOT delete content
57   char *saveDirNoisyToFXS    = "./calibResults/ScanNoisyToFXS";     //     may delete content
58   char *saveDirDCSconfigToFXS= "./calibResults/ScanDCSconfigToFXS"; //     may delete content
59   char *saveDirRef           = "./calibResults/ScanReference";      //     may delete content
60   char *saveDirIdsToFXS      = "./calibResults/IdsToFXS";           //     may delete content
61   char *configFilesDir       = "./configFiles";                     //     may delete content
62
63   // make sure the directory structure is correct:
64   system("mkdir ./calibResults >& /dev/null");
65   system("mkdir ./calibResults/ScanNoisy >& /dev/null");
66   system("mkdir ./calibResults/ScanNoisyToFXS >& /dev/null");
67   system("mkdir ./calibResults/ScanDCSconfigToFXS >& /dev/null");
68   system("mkdir ./calibResults/ScanReference >& /dev/null");
69   system("mkdir ./calibResults/IdsToFXS >& /dev/null");
70   system("mkdir ./configFiles >& /dev/null");
71   // prameters config files
72   TString paramsFileName = Form("%s/standal_params.txt",configFilesDir);
73   TString permNoisyFileName = Form("%s/perm_noisy.txt",configFilesDir);
74
75   TFitter *fitter = new TFitter(3);
76   TVirtualFitter::SetFitter(fitter);
77
78   // This line is needed in case of a stand-alone application w/o
79   // $ROOTSYS/etc/system.rootrc file
80   gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
81                                         "*",
82                                         "TStreamerInfo",
83                                         "RIO",
84                                         "TStreamerInfo()");
85
86   // turn off annoying warning messages
87   new AliLog;
88   AliLog::Instance()->SetGlobalDebugLevel(-20);
89
90   // calib scan types
91   enum calib_types{MINTH,MEANTH,DAC,UNIMA,NOISE,DELAY};
92
93
94   // ********* STEP 0: Get configuration files from db (if there are any) , then read parameters*********
95   UInt_t nrTuningParams = 0;
96   TObjArray paramNames;  paramNames.SetOwner(kTRUE);
97   TObjArray paramVals;  paramVals.SetOwner(kTRUE);
98   
99   // tuning parameters:
100   Int_t status = 0;
101 #ifndef SPD_DA_OFF
102   TString idp = "spd_standal_params";
103   status=daqDA_DB_getFile(idp.Data(),paramsFileName.Data());
104   if (status) {
105     printf("Failed to get config file %s: status=%d. Using default tuning parameters.\n",idp.Data(),status);
106   }
107 #endif
108   if (status==0) {
109     ifstream paramsFile;
110     paramsFile.open(paramsFileName.Data(), ifstream::in);
111     if (paramsFile.fail()) {
112       printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
113     }
114     else {
115       while(1) {
116         Char_t paramN[50];
117         Char_t paramV[50];
118         paramsFile >> paramN;
119         if (paramsFile.eof()) break;
120         paramsFile >> paramV;
121         TString* paramNS = new TString(paramN);
122         TString* paramVS = new TString(paramV);
123         paramNames.AddAtAndExpand((TObject*)paramNS,nrTuningParams);
124         paramVals.AddAtAndExpand((TObject*)paramVS,nrTuningParams);
125         nrTuningParams++;
126         if (paramsFile.eof()) break;
127       }
128       paramsFile.close();
129     }
130   }
131   //  for (UInt_t i=0; i<nrTuningParams; i++) {
132   //    printf("Entry %d: N=%s , V=%s\n",i,((TString*)paramNames.At(i))->Data(),((TString*)paramVals.At(i))->Data());
133   //  }
134
135   // perm noisy list:
136   Int_t permstatus = 0;
137 #ifndef SPD_DA_OFF
138   TString idn = "spd_perm_noisy";
139   permstatus=daqDA_DB_getFile(idn.Data(),permNoisyFileName.Data());
140   if (permstatus) {
141     printf("Failed to get config file %s: status=%d. No permanently noisy pixels will be added.\n",idn.Data(),permstatus);
142   }
143 #endif
144
145
146
147
148   // ********* STEP 1: Produce scan container files (Reference Data). ***********************************
149   int startSeg = 1;
150
151 #ifndef SPD_DA_OFF
152   if (getenv("DATE_RUN_NUMBER")==0) {
153     printf("DATE_RUN_NUMBER not properly set.\n");
154     return -1;
155   }
156   int runNr = atoi(getenv("DATE_RUN_NUMBER"));
157 #else
158   int runNr = atoi(argv[1]);
159   startSeg = 2;
160 #endif
161
162   // container objects
163   AliITSOnlineSPDscan *scanObj[20];
164   Bool_t bScanInit[20];
165   for (UInt_t eqId=0; eqId<20; eqId++) {
166     scanObj[eqId]=NULL;
167     bScanInit[eqId]=kFALSE;
168   }
169   // header data variables
170   UInt_t routerNr[20];
171   Bool_t halfStaveScanned[20][6];
172   UInt_t type[20];
173   Bool_t dataFormat[20];
174   UInt_t triggers[20];
175   Bool_t chipPresent[20][6][10];
176   UInt_t dacStart[20];  
177   UInt_t dacEnd[20];
178   UInt_t dacStep[20];
179   UInt_t dacId[20];
180   UInt_t rowStart[20];  
181   UInt_t rowEnd[20];
182   UInt_t rowValue[20];
183   UInt_t dacValue[20];
184   UInt_t dacHigh[20][6];
185   UInt_t dacLow[20][6];
186   UInt_t TPAmp[20][6];
187   Bool_t minTHchipPresent[20][10];
188   // current scan step flag
189   Int_t currentStep[20];
190   for (UInt_t eqId=0; eqId<20; eqId++) currentStep[eqId] = 9999;
191
192   // loop over run segments
193   for (int segNr=startSeg; segNr<argc; segNr++) {
194
195     int status;
196
197     /* define data source : this is argument 1 */  
198     status=monitorSetDataSource( argv[segNr] );
199     if (status!=0) {
200       printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
201       return -1;
202     }
203     /* declare monitoring program */
204     status=monitorDeclareMp("ITS_SPD_CAL");
205     if (status!=0) {
206       printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
207       return -1;
208     }
209     /* define wait event timeout - 1s max */
210     monitorSetNowait();
211     monitorSetNoWaitNetworkTimeout(1000);
212     
213     
214     UInt_t eventNr=0;
215
216     /* main loop (infinite) */
217     for(;;) {
218       
219       struct eventHeaderStruct *event;
220       eventTypeType eventT;
221       
222       /* check shutdown condition */
223 #ifndef SPD_DA_OFF
224       if (daqDA_checkShutdown()) {break;}
225 #endif
226       /* get next event (blocking call until timeout) */
227       status=monitorGetEventDynamic((void **)&event);
228       if (status==MON_ERR_EOF) {
229         printf ("End of File detected\n");
230         break; /* end of monitoring file has been reached */
231       }
232       if (status!=0) {
233         printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
234         break;
235       }
236       /* retry if got no event */
237       if (event==NULL) {
238         continue;
239       }
240
241       eventT=event->eventType;
242       if (eventT == PHYSICS_EVENT) {
243         
244         eventNr++;
245         //      printf("eventNr %d\n",eventNr);
246         
247         AliRawReader *reader = new AliRawReaderDate((void*)event);
248         AliITSRawStreamSPD *str = new AliITSRawStreamSPD(reader);
249         
250         for (UInt_t eqId=0; eqId<20; eqId++) {
251           
252           reader->Reset();
253           reader->Select("ITSSPD",eqId,eqId);
254           
255           // Hit Event flags, specific for one event
256           Bool_t hitEventHSIncremented[6];
257           Bool_t hitEventChipIncremented[6][10];
258           for (UInt_t hs=0; hs<6; hs++) {
259             hitEventHSIncremented[hs] = kFALSE;
260             for (UInt_t chip=0; chip<10; chip++) {
261               hitEventChipIncremented[hs][chip] = kFALSE;
262             }
263           }
264           
265           if (str->ReadCalibHeader()>0) {
266             // first check the type:
267             if (bScanInit[eqId] && type[eqId]!=str->GetHtype()) {
268               printf("Calib header problem. Type changed (%d -> %d)!\n",type[eqId],str->GetHtype());
269             }
270
271             // read calib values
272             routerNr[eqId]    = str->GetHrouterNr();
273             type[eqId]        = str->GetHtype();
274             dataFormat[eqId]  = str->GetHdataFormat();
275             triggers[eqId]    = str->GetHtriggers();
276             dacStart[eqId]    = str->GetHdacStart();
277             dacEnd[eqId]      = str->GetHdacEnd();
278             dacStep[eqId]     = str->GetHdacStep();
279             dacId[eqId]       = str->GetHdacId();
280             rowStart[eqId]    = str->GetHrowStart();
281             rowEnd[eqId]      = str->GetHrowEnd();
282             rowValue[eqId]    = str->GetHrowValue();
283             dacValue[eqId]    = str->GetHdacValue();
284             for (UInt_t hs=0; hs<6; hs++) {
285               halfStaveScanned[eqId][hs] = str->GetHhalfStaveScanned(hs);
286               dacHigh[eqId][hs]          = str->GetHdacHigh(hs);
287               dacLow[eqId][hs]           = str->GetHdacLow(hs);
288               TPAmp[eqId][hs]            = str->GetHTPAmp(hs);
289               for (UInt_t chip=0; chip<10; chip++) {
290                 chipPresent[eqId][hs][chip]      = str->GetHchipPresent(hs,chip);
291               }
292             }
293             for (UInt_t chip=0; chip<10; chip++) {
294               minTHchipPresent[eqId][chip] = str->GetHminTHchipPresent(chip);
295             }
296
297             currentStep[eqId] = (dacValue[eqId]-dacStart[eqId])/dacStep[eqId];
298             if (type[eqId]==DELAY) {
299               currentStep[eqId]=currentStep[eqId]*2;
300               dacValue[eqId]=dacValue[eqId]*2;
301               if (dacHigh[eqId][0]==128) { // misc_ctrl value
302                 currentStep[eqId]=currentStep[eqId]+1;
303                 dacValue[eqId]=dacValue[eqId]+1;
304               }
305             }
306
307             // router nr check:
308             if (routerNr[eqId]!=eqId) {
309               printf("Router nr problem? Router nr %d != EqID %d\n",routerNr[eqId],eqId);
310             }
311
312             if (!bScanInit[eqId]) {
313               // initialize container object
314               TString fileName = Form("%s/SPDcal_run_%d_eq_%d.root",saveDirRef,runNr,eqId);
315               switch (type[eqId]) {
316               case NOISE:
317               case UNIMA:
318                 scanObj[eqId] = new AliITSOnlineSPDscanSingle(fileName.Data());
319                 ((AliITSOnlineSPDscanSingle*)scanObj[eqId])->ClearThis();
320                 bScanInit[eqId]=kTRUE;
321                 break;
322               case MINTH:
323               case DAC:
324               case DELAY:
325                 scanObj[eqId] = new AliITSOnlineSPDscanMultiple(fileName.Data());
326                 scanObj[eqId]->ClearThis();
327                 bScanInit[eqId]=kTRUE;
328                 break;
329               case MEANTH: 
330                 scanObj[eqId] = new AliITSOnlineSPDscanMeanTh(fileName.Data());
331                 scanObj[eqId]->ClearThis();
332                 bScanInit[eqId]=kTRUE;
333                 break;
334               default:
335                 printf("Unknown scan type: %d.\n",type[eqId]);
336               }
337               // some multiple scan data
338               if (type[eqId]==MINTH || type[eqId]==MEANTH || type[eqId]==DAC || type[eqId]==DELAY) {
339                 ((AliITSOnlineSPDscanMultiple*)scanObj[eqId])->SetDacId(dacId[eqId]);
340               }
341               // some common data
342               scanObj[eqId]->SetRunNr((UInt_t)runNr);
343               scanObj[eqId]->SetRouterNr(routerNr[eqId]);
344               for (UInt_t hs=0; hs<6; hs++) {
345                 scanObj[eqId]->SetHalfStaveScanned(hs,halfStaveScanned[eqId][hs]);
346               }
347               scanObj[eqId]->SetType(type[eqId]);
348               scanObj[eqId]->SetDataFormat(dataFormat[eqId]);
349               for (Int_t hs=0; hs<6; hs++) {
350               
351                 // remove later when the chip present is set correctly !!!!!!!!!!!!!!!!!!!!!!!!!!!
352                 Bool_t halfStavePresent = str->GetHalfStavePresent(hs);
353                 // remove later when the chip present is set correctly !!!!!!!!!!!!!!!!!!!!!!!!!!!
354
355                 for (UInt_t chip=0; chip<10; chip++) {
356                   scanObj[eqId]->SetChipPresent(hs,chip,chipPresent[eqId][hs][chip]);
357
358                   // remove later when the chip present is set correctly !!!!!!!!!!!!!!!!!!!!!!!!!!!
359                   if (halfStavePresent) scanObj[eqId]->SetChipPresent(hs,chip,kTRUE);
360                   // remove later when the chip present is set correctly !!!!!!!!!!!!!!!!!!!!!!!!!!!
361
362                 }
363               }
364               scanObj[eqId]->SetRowStart(rowStart[eqId]);
365               scanObj[eqId]->SetRowEnd(rowEnd[eqId]);
366               scanObj[eqId]->SetDacStart(dacStart[eqId]);
367               scanObj[eqId]->SetDacEnd(dacEnd[eqId]);
368               scanObj[eqId]->SetDacStep(dacStep[eqId]);
369             }
370
371             if (type[eqId]==MINTH) {
372               scanObj[eqId]->SetTriggers(currentStep[eqId],triggers[eqId]);
373             }
374             if (type[eqId]==UNIMA || type[eqId]==NOISE) {
375               if (currentStep[eqId]==9999) printf("SPDcalibratorStep1 (eq %d): single step\n",eqId);
376               currentStep[eqId]=0;
377             }
378             if (type[eqId]==MINTH || type[eqId]==MEANTH || type[eqId]==DAC || type[eqId]==DELAY) {
379               ((AliITSOnlineSPDscanMultiple*)scanObj[eqId])->SetDacValue(currentStep[eqId],dacValue[eqId]);
380               if (type[eqId]==DELAY) {
381                 printf("SPDcalibratorStep1 (eq %d): DAC %d/%d , step %d\n",eqId,dacValue[eqId]/2,dacHigh[eqId][0],currentStep[eqId]);
382               }
383               else {
384                 printf("SPDcalibratorStep1 (eq %d): DAC %d , step %d\n",eqId,dacValue[eqId],currentStep[eqId]);
385               }
386             }
387             if (type[eqId]==MEANTH) {
388               for (Int_t hs=0; hs<6; hs++) {
389                 ((AliITSOnlineSPDscanMeanTh*)scanObj[eqId])->SetDacLow(currentStep[eqId],hs,dacLow[eqId][hs]);
390                 ((AliITSOnlineSPDscanMeanTh*)scanObj[eqId])->SetDacHigh(currentStep[eqId],hs,dacHigh[eqId][hs]);
391                 ((AliITSOnlineSPDscanMeanTh*)scanObj[eqId])->SetTPAmp(currentStep[eqId],hs,TPAmp[eqId][hs]);
392               }
393             }
394
395
396           }
397
398           if (bScanInit[eqId]) {
399             while (str->Next()) {
400               UInt_t hs = str->GetHalfStaveNr();
401               UInt_t chip = str->GetChipAddr();
402               //***remove last condition when minthpresent put correctly in calib header?
403 #ifndef SPD_DA_OFF
404               if (type[eqId]!=MINTH || minTHchipPresent[eqId][chip] || runNr<=416900) {
405 #else
406               if (type[eqId]!=MINTH || minTHchipPresent[eqId][chip] || runNr<=416900) {
407 #endif
408                 //*************************************************************************
409                 scanObj[eqId]->IncrementHits(currentStep[eqId],hs,chip,str->GetChipCol(),str->GetChipRow());
410                 
411                 if (!hitEventHSIncremented[hs]) {
412                   scanObj[eqId]->IncrementHitEventsTot(currentStep[eqId],hs);
413                   hitEventHSIncremented[hs]=kTRUE;
414                 }
415                 
416                 if (!hitEventChipIncremented[hs][chip]) {
417                   scanObj[eqId]->IncrementHitEvents(currentStep[eqId],hs,chip);
418                   hitEventChipIncremented[hs][chip]=kTRUE;
419                 }
420               }
421
422             }
423
424             if (type[eqId]!=MINTH) { // for minth, triggers are set from header info
425               scanObj[eqId]->IncrementTriggers(currentStep[eqId]);
426             }
427
428           }
429
430         }
431
432         delete str;
433         delete reader;
434
435       }
436
437       /* free resources */
438       free(event);
439
440     }
441
442 #ifndef SPD_DA_OFF
443     daqDA_progressReport((unsigned int)( ((Float_t)(segNr-startSeg+1))/(argc-startSeg)*50 ));
444 #else
445     printf("progress: %d\n",(unsigned int)( ((Float_t)(segNr-startSeg+1))/(argc-startSeg)*50 ));
446 #endif
447
448   }
449
450   
451   // clean up scan objects (which also saves them) , check if something happened...
452     Bool_t somethingHappened = kFALSE;
453   for (UInt_t eqId=0; eqId<20; eqId++) {
454     if (scanObj[eqId]!=NULL) {
455       delete scanObj[eqId];
456       somethingHappened = kTRUE;
457     }
458   }
459   if (!somethingHappened) {
460     printf("WARNING: No data processed. Are the calibration headers missing?\n");
461   }
462
463
464
465
466   // ********* STEP 2: Analyze scan container files. ************************************************
467
468   // clear noisyToFXS and DCSconfigToFXS dirs:
469   TString command = Form("cd %s; rm -f *",saveDirNoisyToFXS);
470   system(command.Data());
471   TString command2 = Form("cd %s; rm -f *",saveDirDCSconfigToFXS);
472   system(command2.Data());
473   UInt_t nrNoisyFilesProduced=0;
474   UInt_t nrDCSconfigFilesProduced=0;
475
476   AliITSOnlineCalibrationSPDhandler* handler = new AliITSOnlineCalibrationSPDhandler();
477   AliITSOnlineSPDscanAnalyzer *analyzer = NULL;
478   AliITSOnlineCalibrationSPDhandler* handlerPermNoisy = NULL;
479   // fill permanent noisy list to add later...
480   if (permstatus==0) { 
481     handlerPermNoisy = new AliITSOnlineCalibrationSPDhandler();
482     UInt_t permNoisy = handlerPermNoisy->ReadNoisyFromText(permNoisyFileName.Data(),240); // 240 = read for all modules
483     if (permNoisy>0) {
484       printf("%d noisy pixels read from permanent list.\n",permNoisy);
485     }
486   }
487
488   Bool_t reset_made = kFALSE;
489
490   // *** *** *** start loop over equipments (eq_id)
491   for (int eqId=0; eqId<20; eqId++) {
492
493     // create analyzer for this eq
494     TString fileName = Form("%s/SPDcal_run_%d_eq_%d.root",saveDirRef,runNr,eqId);
495     analyzer = new AliITSOnlineSPDscanAnalyzer(fileName.Data(),handler);
496
497     // configure analyzer with tuning parameters etc:
498     for (UInt_t i=0; i<nrTuningParams; i++) {
499       analyzer->SetParam(((TString*)paramNames.At(i))->Data(),((TString*)paramVals.At(i))->Data());
500     }
501
502     UInt_t type  = analyzer->GetType();
503     UInt_t dacId = analyzer->GetDacId();
504     UInt_t routerNr = analyzer->GetRouterNr();
505     if (type!=99) {
506       if (type==DAC) {
507         printf("SPD scan calibrator Step2: eqId %d, type %d, dacId %d\n",eqId,type,dacId);
508       }
509       else printf("SPD scan calibrator Step2: eqId %d type %d\n",eqId,type);  
510     }
511
512
513
514     // algorithms for the different types of scans:
515
516     if (type==UNIMA) {
517
518     }
519
520     else if (type==NOISE) {
521       // read previous noisy list (clear if overwriting)
522       handler->SetFileLocation(saveDirNoisy);
523       if (analyzer->IsOverWriteSet() && !reset_made) {
524         handler->ResetNoisy();
525         handler->WriteToFilesAlways();
526         reset_made=kTRUE;
527       }
528       else {
529         handler->ReadFromFiles();
530       }
531       if (analyzer->ProcessNoisyPixels(/*saveDirNoisy*/)) {
532         if (permstatus==0) {
533           handler->AddNoisyFrom(handlerPermNoisy);
534         }
535         // init dcs config text file
536         TString dcsConfigFileName = Form("%s/dcsConfig_run_%d_eq_%d.txt",saveDirDCSconfigToFXS,runNr,eqId);
537         ofstream dcsfile;
538         dcsfile.open(dcsConfigFileName.Data());
539         dcsfile << "[SPD SCAN]\n";
540         dcsfile << "RunNumber=" << runNr << "\n";
541         dcsfile << "Type=" << type << "\n";
542         dcsfile << "Router=" << routerNr << "\n";
543         dcsfile << "ActualDetConfiguration=" << "0,-1,-1\n"; // dummy values for now
544         dcsfile << "[NOISY]\n";
545         nrDCSconfigFilesProduced++;
546
547         for (UInt_t hs=0; hs<6; hs++) {
548           for (UInt_t chip=0; chip<10; chip++) {
549             if (analyzer->IsChipPresent(hs,chip) || analyzer->IsOverWriteSet()) {
550               dcsfile << "-" << eqId << "," << hs << "," << chip << "\n";
551               UInt_t nrNoisy = handler->GetNrNoisyC(eqId,hs,chip);
552               for (UInt_t ind=0; ind<nrNoisy; ind++) {
553                 UInt_t col = handler->GetNoisyColAtC(eqId,hs,chip,ind);
554                 UInt_t row = handler->GetNoisyRowAtC(eqId,hs,chip,ind);
555                 dcsfile << col << "," << row << "\n";
556               }
557             }
558           }
559         }
560         handler->SetFileLocation(saveDirNoisy);
561         handler->WriteNoisyToFile(eqId);
562         handler->SetFileLocation(saveDirNoisyToFXS);
563         handler->WriteNoisyToFile(eqId);
564         nrNoisyFilesProduced++;
565         
566         dcsfile.close();
567       }
568     }
569
570     else if (type==MINTH || (type==DAC && dacId==39)) {
571       // init dcs config text file
572       TString dcsConfigFileName = Form("%s/dcsConfig_run_%d_eq_%d.txt",saveDirDCSconfigToFXS,runNr,eqId);
573       ofstream dcsfile;
574       dcsfile.open(dcsConfigFileName.Data());
575       dcsfile << "[SPD SCAN]\n";
576       dcsfile << "RunNumber=" << runNr << "\n";
577       dcsfile << "Type=" << type << "\n";
578       dcsfile << "Router=" << routerNr << "\n";
579       dcsfile << "ActualDetConfiguration=" << "0,-1,-1\n"; // dummy values for now
580       dcsfile << "[DACvalues]\n";
581       nrDCSconfigFilesProduced++;
582       for (UInt_t hs=0; hs<6; hs++) {
583         for (UInt_t chipNr=0; chipNr<10; chipNr++) {
584           Int_t minTh = -1;
585           if (analyzer->GetOnlineScan()->GetChipPresent(hs,chipNr)) {
586             minTh = analyzer->GetMinTh(hs,chipNr);
587             if (minTh!=-1) {
588               dcsfile << "39," << eqId << "," << hs << "," << chipNr << "=" << minTh << "\n";
589             }
590             else {
591               printf("MinTh failed for Eq %d , HS %d , Chip %d\n",eqId,hs,chipNr);
592             }
593           }
594         }
595       }
596       dcsfile.close();
597     }
598
599     else if (type==DELAY) {
600       // init dcs config text file
601       TString dcsConfigFileName = Form("%s/dcsConfig_run_%d_eq_%d.txt",saveDirDCSconfigToFXS,runNr,eqId);
602       ofstream dcsfile;
603       dcsfile.open(dcsConfigFileName.Data());
604       dcsfile << "[SPD SCAN]\n";
605       dcsfile << "RunNumber=" << runNr << "\n";
606       dcsfile << "Type=" << type << "\n";
607       dcsfile << "Router=" << routerNr << "\n";
608       dcsfile << "ActualDetCoonfiguration=" << "0,-1,-1\n"; // dummy values for now
609       dcsfile << "[DACvalues]\n";
610       nrDCSconfigFilesProduced++;
611       for (UInt_t hs=0; hs<6; hs++) {
612         for (UInt_t chipNr=0; chipNr<10; chipNr++) {
613           Int_t clockCycle = -1;
614           Int_t delayCtrl = -1;
615           Int_t miscCtrl = -1;
616           if (analyzer->GetOnlineScan()->GetChipPresent(hs,chipNr)) {
617             clockCycle = analyzer->GetDelay(hs,chipNr);
618             delayCtrl = clockCycle/2;
619             miscCtrl = 192;
620             if (clockCycle!=-1) {
621               if (clockCycle%2==1) miscCtrl = 128;
622               dcsfile << "42," << eqId << "," << hs << "," << chipNr << "=" << delayCtrl << "\n";
623               dcsfile << "43," << eqId << "," << hs << "," << chipNr << "=" << miscCtrl << "\n";
624             }
625             else {
626               printf("Delay failed for Eq %d , HS %d , Chip %d\n",eqId,hs,chipNr);
627             }
628           }
629         }
630       }
631       dcsfile.close();
632     }
633
634     delete analyzer;
635
636 #ifndef SPD_DA_OFF
637     daqDA_progressReport((unsigned int)(50+(eqId+1)*2.5));
638 #else
639     printf("progress: %d\n",(unsigned int)(50+(eqId+1)*2.5));
640 #endif
641
642   }
643   // *** *** *** end loop over equipments (eq_id)
644
645
646   delete handler;
647   if (handlerPermNoisy!=NULL) {
648     delete handlerPermNoisy;
649   }
650
651   printf("Opening id list file\n");
652   TString idsFXSFileName = Form("%s/FXSids_run_%d.txt",saveDirIdsToFXS,runNr);
653   ofstream idsFXSfile;
654   idsFXSfile.open(idsFXSFileName.Data());
655
656
657
658   // send noisy data to FXS
659   if (nrNoisyFilesProduced>0) {
660     printf("Preparing noisy files\n");
661     // send a tared file of all new noisy maps
662     TString command = Form("cd %s; tar -cf noisy_scan.tar *",saveDirNoisyToFXS);
663     //    printf("\n\n%s\n\n",command.Data());
664     system(command.Data());
665     TString fileName = Form("%s/noisy_scan.tar",saveDirNoisyToFXS);
666     TString id = "SPD_scan_noisy";
667 #ifndef SPD_DA_OFF
668     Int_t status = daqDA_FES_storeFile(fileName.Data(),id.Data());
669     if (status!=0) {
670       printf("Failed to export file %s , status %d\n",fileName.Data(),status);
671       return -1;
672     }
673 #endif
674     idsFXSfile << Form("%s\n",id.Data());
675   }
676
677   // send dcs config files to FXS
678   if (nrDCSconfigFilesProduced>0) {
679     printf("Preparing DCS config files\n");
680     // send a tared file of all the dcsConfig text files
681     TString command = Form("cd %s; tar -cf dcsConfig.tar *",saveDirDCSconfigToFXS);
682     //    printf("\n\n%s\n\n",command.Data());
683     system(command.Data());
684     TString fileName = Form("%s/dcsConfig.tar",saveDirDCSconfigToFXS);
685     TString id = "SPD_dcsConfig";
686 #ifndef SPD_DA_OFF
687     Int_t status = daqDA_FES_storeFile(fileName.Data(),id.Data());
688     if (status!=0) {
689       printf("Failed to export file %s , status %d\n",fileName.Data(),status);
690       return -1;
691     }
692 #endif
693     //idsFXSfile << Form("%s\n",id.Data()); // do NOT write this id (this is not for preprocessor)
694   }
695
696   // send reference data to FXS
697   for (UInt_t eqId=0; eqId<20; eqId++) {
698     if (bScanInit[eqId]) {
699       printf("Preparing reference data for eq %d\n",eqId);
700       TString fileName = Form("%s/SPDcal_run_%d_eq_%d.root",saveDirRef,runNr,eqId);
701       TString id = Form("SPD_ref_scan_%d",eqId);
702 #ifndef SPD_DA_OFF
703       Int_t status = daqDA_FES_storeFile(fileName.Data(),id.Data());
704       if (status!=0) {
705         printf("Failed to export file %s , status %d\n",fileName.Data(),status);
706         return -1;
707       }
708 #endif
709       idsFXSfile << Form("%s\n",id.Data());
710     }
711   }
712
713
714   printf("Preparing id list file\n");
715   idsFXSfile.close();
716   TString id = "SPD_id_list";
717 #ifndef SPD_DA_OFF
718   status = daqDA_FES_storeFile(idsFXSFileName.Data(),id.Data());
719   if (status!=0) {
720     printf("Failed to export file %s , status %d\n",idsFXSFileName.Data(),status);
721     return -1;
722   }
723 #endif
724
725
726   printf("DA finished.\n");
727
728   return 0;
729 }