2 - "Contact:" - henrik.tydesjo@cern.ch
4 - "Run Type:" - PHYSICS
6 - "Number of events needed:"
7 - "Input Files:" - daq db config files: spd_physics_params , previous dead ref: ./calibResults/DeadReferenceTmp/* , previous dead lists: ./calibResults/DeadToFXS/*
8 - "Output Files:" - Ref Data: ./calibResults/NoisyReference/* , Ref Data: ./calibResults/DeadReference/* , noisy lists: ./calibResults/NoisyToFXS/* , persistent files: ./calibResults/DeadReferenceTmp/*,./calibResults/DeadToFXS/*
9 - "Trigger types used:" PHYSICS
12 ////////////////////////////////////////////////////////////////////////////////
13 // This program can be compiled in two modes. //
15 // 1. Online. With the DAQ DA framework. This is the default operating mode. //
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. //
21 ////////////////////////////////////////////////////////////////////////////////
28 #include "AliRawReaderDate.h"
29 #include "AliITSRawStreamSPD.h"
30 #include "AliITSOnlineSPDphys.h"
31 #include "AliITSOnlineSPDphysAnalyzer.h"
32 #include "AliITSOnlineCalibrationSPDhandler.h"
37 #include <TPluginManager.h>
38 #include <TObjArray.h>
41 int main(int argc, char **argv) {
43 printf("Wrong number of arguments\n");
47 // directory structure, hard coded
48 char *saveDirDeadToFXS = "./calibResults/DeadToFXS"; // may NOT delete content
49 char *saveDirDeadRef = "./calibResults/DeadReference"; // may delete content
50 char *saveDirDeadRefTmp = "./calibResults/DeadReferenceTmp"; // may NOT delete content
51 char *saveDirNoisyToFXS = "./calibResults/NoisyToFXS"; // may delete content
52 char *saveDirNoisyRef = "./calibResults/NoisyReference"; // may delete content
53 char *configFilesDir = "./configFiles"; // may delete content
54 // make sure the directory structure is put up correctly:
55 system("mkdir ./calibResults >& /dev/null");
56 system("mkdir ./calibResults/DeadToFXS >& /dev/null");
57 system("mkdir ./calibResults/DeadReference >& /dev/null");
58 system("mkdir ./calibResults/DeadReferenceTmp >& /dev/null");
59 system("mkdir ./calibResults/NoisyToFXS >& /dev/null");
60 system("mkdir ./calibResults/NoisyReference >& /dev/null");
61 system("mkdir ./configFiles >& /dev/null");
62 // parameters config file
63 TString paramsFileName = Form("%s/physics_params.txt",configFilesDir);
65 // This line is needed in case of a stand-alone application w/o
66 // $ROOTSYS/etc/system.rootrc file
67 gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
73 // turn off annoying warning messages
75 AliLog::Instance()->SetGlobalDebugLevel(-20);
78 // ********* STEP 0: Get configuration files from db (if there are any) , then read parameters*********
79 UInt_t nrTuningParams = 0;
80 TObjArray paramNames; paramNames.SetOwner(kTRUE);
81 TObjArray paramVals; paramVals.SetOwner(kTRUE);
86 TString idp = "spd_physics_params";
87 par_status=daqDA_DB_getFile(idp.Data(),paramsFileName.Data());
89 printf("Failed to get config file %s: status=%d. Using default tuning parameters.\n",idp.Data(),par_status);
94 paramsFile.open(paramsFileName.Data(), ifstream::in);
95 if (paramsFile.fail()) {
96 printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
102 paramsFile >> paramN;
103 if (paramsFile.eof()) break;
104 paramsFile >> paramV;
105 TString* paramNS = new TString(paramN);
106 TString* paramVS = new TString(paramV);
107 paramNames.AddAtAndExpand((TObject*)paramNS,nrTuningParams);
108 paramVals.AddAtAndExpand((TObject*)paramVS,nrTuningParams);
110 if (paramsFile.eof()) break;
115 // for (UInt_t i=0; i<nrTuningParams; i++) {
116 // printf("Entry %d: N=%s , V=%s\n",i,((TString*)paramNames.At(i))->Data(),((TString*)paramVals.At(i))->Data());
123 // ********* STEP 1: Produce phys container files (Reference Data). ***********************************
126 int runNr = atoi(getenv("DATE_RUN_NUMBER"));
128 int runNr = atoi(argv[1]);
134 AliITSOnlineSPDphys *physObj[20];
135 Bool_t bPhysInit[20];
136 for (UInt_t eqId=0; eqId<20; eqId++) {
138 bPhysInit[eqId]=kFALSE;
142 // loop over run segments in case of offline mode
144 for (int segNr=startSeg; segNr<argc; segNr++) {
149 /* define data source : */
151 status=monitorSetDataSource( argv[1] ); // should be "^SPD" in order to get full detector online
153 status=monitorSetDataSource( argv[segNr] );
156 printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
159 /* declare monitoring program */
160 status=monitorDeclareMp("ITS_SPD_PHYS");
162 printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
165 /* define wait event timeout - 1s max */
167 monitorSetNoWaitNetworkTimeout(1000);
172 /* main loop (infinite) */
175 struct eventHeaderStruct *event;
176 eventTypeType eventT;
178 /* check shutdown condition */
180 if (daqDA_checkShutdown()) {break;}
183 /* get next event (blocking call until timeout) */
184 status=monitorGetEventDynamic((void **)&event);
185 if (status==MON_ERR_EOF) {
186 printf ("End of File detected\n");
187 break; /* end of monitoring file has been reached */
191 printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
195 /* retry if got no event */
200 eventT=event->eventType;
201 if (eventT == PHYSICS_EVENT){
204 // printf("eventNr %d\n",eventNr);
206 AliRawReader *reader = new AliRawReaderDate((void*)event);
207 AliITSRawStreamSPD *str = new AliITSRawStreamSPD(reader);
209 // for (UInt_t eqId=0; eqId<20; eqId++) {
211 // reader->Select("ITSSPD",eqId,eqId);
213 while (str->Next()) {
215 Int_t eqId = reader->GetDDLID();
216 if (eqId>=0 && eqId<20) {
217 if (!bPhysInit[eqId]) {
218 TString fileName = Form("%s/SPDphys_run_%d_eq_%d.root",saveDirNoisyRef,runNr,eqId);
219 physObj[eqId] = new AliITSOnlineSPDphys(fileName.Data());
220 physObj[eqId]->AddRunNr(runNr);
221 physObj[eqId]->SetEqNr(eqId);
222 bPhysInit[eqId]=kTRUE;
225 UInt_t hs = str->GetHalfStaveNr();
226 UInt_t chip = str->GetChipAddr();
227 physObj[eqId]->IncrementHits(hs,chip,str->GetChipCol(),str->GetChipRow());
232 for (UInt_t eqId=0; eqId<20; eqId++) {
233 if (bPhysInit[eqId]) {
234 physObj[eqId]->IncrementNrEvents();
252 printf("progress: %d\n",(unsigned int)( ((Float_t)(segNr-startSeg+1))/(argc-startSeg)*50 ));
256 // clean up phys objects (also saves them)
257 for (UInt_t eqId=0; eqId<20; eqId++) {
258 if (physObj[eqId]!=NULL) delete physObj[eqId];
265 // ********* STEP 2: Analyze phys container files. ************************************************
267 // clear noisyToFXS dir:
269 command = Form("cd %s; rm -f *",saveDirNoisyToFXS);
270 system(command.Data());
271 // delete dead.tar file
272 command = Form("cd %s; rm -f dead.tar",saveDirDeadToFXS);
273 system(command.Data());
276 // create calibration handler and read dead from previous calibrations
277 AliITSOnlineCalibrationSPDhandler* handler = new AliITSOnlineCalibrationSPDhandler();
278 handler->SetFileLocation(saveDirDeadToFXS);
279 handler->ReadDeadFromFiles();
282 UInt_t firstRunNrDead = runNr;
285 UInt_t nrEnoughStatNoisy = 0;
286 UInt_t nrEqActiveNoisy = 0;
287 Bool_t eqActiveNoisy[20];
289 // *** *** *** start loop over equipments (eq_id)
290 for (UInt_t eqId=0; eqId<20; eqId++) {
291 eqActiveNoisy[eqId] = kFALSE;
293 // create analyzer for this eq
294 TString fileName = Form("%s/SPDphys_run_%d_eq_%d.root",saveDirNoisyRef,runNr,eqId);
295 AliITSOnlineSPDphysAnalyzer *noisyAnalyzer = new AliITSOnlineSPDphysAnalyzer(fileName.Data(),handler);
297 // check data in container
298 if (noisyAnalyzer->GetEqNr() != eqId) {
299 if (noisyAnalyzer->GetEqNr() != 999) {
300 printf("Error: Mismatching EqId in Container data and filename (%d!=%d). Skipping.\n",
301 noisyAnalyzer->GetEqNr(),eqId);
303 delete noisyAnalyzer;
308 eqActiveNoisy[eqId] = kTRUE;
310 // configure analyzer with tuning parameters etc:
311 for (UInt_t i=0; i<nrTuningParams; i++) {
312 noisyAnalyzer->SetParam(((TString*)paramNames.At(i))->Data(),((TString*)paramVals.At(i))->Data());
315 printf("SPD phys STEP 2: Noisy search for eq %d\n",eqId);
317 // search for noisy pixels:
318 nrEnoughStatNoisy += noisyAnalyzer->ProcessNoisyPixels();
320 // copy this phys obj to temporary dead reference dir to process after noisy search
321 TString fileNameDead = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eqId);
322 AliITSOnlineSPDphys* physObj = new AliITSOnlineSPDphys(fileNameDead.Data());
323 physObj->AddPhys(noisyAnalyzer->GetOnlinePhys());
324 if (physObj->GetNrRuns()>0) {
325 UInt_t firstRunNr = physObj->GetRunNr(0);
326 if (firstRunNrDead>firstRunNr) {
327 firstRunNrDead=firstRunNr;
330 // remove noisy pixels from dead hitmap
331 for (UInt_t iModule=0; iModule<12; iModule++) {
332 UInt_t module = AliITSRawStreamSPD::GetModuleNumber(eqId,iModule);
333 for (UInt_t ind=0; ind<handler->GetNrNoisy(module); ind++) {
334 UInt_t hs = handler->GetNoisyHSAt(module,ind);
335 UInt_t chip = handler->GetNoisyChipAt(module,ind);
336 UInt_t col = handler->GetNoisyColAt(module,ind);
337 UInt_t row = handler->GetNoisyRowAt(module,ind);
338 physObj->AddHits(hs,chip,col,row,-noisyAnalyzer->GetOnlinePhys()->GetHits(hs,chip,col,row));
343 delete noisyAnalyzer;
346 daqDA_progressReport((unsigned int)((eqId+1)*2.5));
348 printf("progress: %d\n",(unsigned int)(50+(eqId+1)*1.25));
351 // *** *** *** end loop over equipments (eq_id)
353 printf("Noisy search finished. %d noisy pixels found. %d chips (%d) had enough statistics.\n",
354 handler->GetNrNoisy(),nrEnoughStatNoisy,nrEqActiveNoisy*60);
355 handler->SetFileLocation(saveDirNoisyToFXS);
356 handler->WriteNoisyToFiles();
365 UInt_t nrEnoughStatChips = 0;
366 UInt_t nrDeadChips = 0;
367 UInt_t nrInefficientChips = 0;
368 UInt_t nrEqActiveDead = 0;
369 Bool_t eqActiveDead[20];
371 // *** *** *** start loop over equipments (eq_id)
372 for (UInt_t eqId=0; eqId<20; eqId++) {
373 eqActiveDead[eqId] = kFALSE;
375 // setup analyzer for dead search
376 TString fileNameDead = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eqId);
377 AliITSOnlineSPDphys* physObj = new AliITSOnlineSPDphys(fileNameDead.Data());
378 AliITSOnlineSPDphysAnalyzer* deadAnalyzer = new AliITSOnlineSPDphysAnalyzer(physObj,handler);
379 // check data in container
380 if (deadAnalyzer->GetEqNr() != eqId) {
381 if (deadAnalyzer->GetEqNr() != 999) {
382 printf("Error: Mismatching EqId in Dead Container data and filename (%d!=%d). Skipping.\n",
383 deadAnalyzer->GetEqNr(),eqId);
390 eqActiveDead[eqId] = kTRUE;
392 // configure analyzer with tuning parameters etc:
393 for (UInt_t i=0; i<nrTuningParams; i++) {
394 deadAnalyzer->SetParam(((TString*)paramNames.At(i))->Data(),((TString*)paramVals.At(i))->Data());
397 printf("SPD phys STEP 2: Dead search for eq %d\n",eqId);
399 // search for dead pixels:
400 nrEnoughStatChips += deadAnalyzer->ProcessDeadPixels();
401 nrDeadChips += deadAnalyzer->GetNrDeadChips();
402 nrInefficientChips += deadAnalyzer->GetNrInefficientChips();
407 daqDA_progressReport((unsigned int)(50+(eqId+1)*2.5));
409 printf("progress: %d\n",(unsigned int)(75+(eqId+1)*1.25));
412 // *** *** *** end loop over equipments (eq_id)
415 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);
416 handler->SetFileLocation(saveDirDeadToFXS);
417 handler->WriteDeadToFilesAlways();
426 // if there is no chip in category "needsMoreStat"
427 if (nrEnoughStatChips+nrDeadChips+nrInefficientChips == nrEqActiveDead*60) {
428 // calibration is complete
429 printf("Dead calibration is complete.\n");
430 for (UInt_t eqId=0; eqId<20; eqId++) {
431 if (eqActiveDead[eqId]) {
432 TString fileName = Form("%s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eqId);
433 //!!! // find out the run span
434 //!!! AliITSOnlineSPDphys* physObj = new AliITSOnlineSPDphys(fileName.Data());
435 //!!! UInt_t nrRuns = physObj->GetNrRuns();
436 //!!! UInt_t firstRun = physObj->GetRunNr(0);
437 //!!! UInt_t lastRun = physObj->GetRunNr(nrRuns-1);
438 //!!! delete physObj;
439 // move file to ref dir
440 TString newFileName = Form("%s/SPDphys_dead_run_%d_%d_eq_%d.root",saveDirDeadRef,firstRunNrDead,runNr,eqId);
441 TString command = Form("mv -f %s %s",fileName.Data(),newFileName.Data());
442 system(command.Data());
444 // send ref data to FXS
445 TString id = Form("SPD_ref_phys_dead_%d",eqId);
446 Int_t status = daqDA_FES_storeFile(newFileName.Data(),id.Data());
448 printf("Failed to export file %s , status %d\n",newFileName.Data(),status);
454 TString command = Form("rm -f %s/SPDphys_dead_run_0_0_eq_%d.root",saveDirDeadRefTmp,eqId);
455 system(command.Data());
460 // send reference data for this run to FXS
462 for (UInt_t eqId=0; eqId<20; eqId++) {
463 if (eqActiveNoisy[eqId]) {
464 TString fileName = Form("%s/SPDphys_run_%d_eq_%d.root",saveDirNoisyRef,runNr,eqId);
465 TString id = Form("SPD_ref_phys_%d",eqId);
466 Int_t status = daqDA_FES_storeFile(fileName.Data(),id.Data());
468 printf("Failed to export file %s , status %d\n",fileName.Data(),status);
475 // send dead files to FXS
476 // send a tared file of all the dead files
477 TString send_command = Form("cd %s; tar -cf dead_phys.tar *",saveDirDeadToFXS);
478 // printf("\n\n%s\n\n",command.Data());
479 system(send_command.Data());
481 TString fileName = Form("%s/dead_phys.tar",saveDirDeadToFXS);
482 TString id = "SPD_phys_dead";
483 Int_t send_status = daqDA_FES_storeFile(fileName.Data(),id.Data());
484 if (send_status!=0) {
485 printf("Failed to export file %s , status %d\n",fileName.Data(),send_status);
490 // send noisy files to FXS
491 if (handler->GetNrNoisy()>0) { // there must be at least one file created
492 // send a tared file of all the noisy files
493 TString command = Form("cd %s; tar -cf noisy_phys.tar *",saveDirNoisyToFXS);
494 // printf("\n\n%s\n\n",command.Data());
495 system(command.Data());
497 TString fileName = Form("%s/noisy_phys.tar",saveDirNoisyToFXS);
498 TString id = "SPD_phys_noisy";
499 Int_t status = daqDA_FES_storeFile(fileName.Data(),id.Data());
501 printf("Failed to export file %s , status %d\n",fileName.Data(),status);