3 Version 1 for MUONTRKda MUON tracking
4 Working version for pedestal
5 Framework for gain computing
9 Rem: AliMUON2DMap stores all channels, even those which are not connected
10 if pedMean == -1, channel not connected to a pad
12 Pb with static root libraries ??
23 #include <Riostream.h>
28 #include "AliMUONRawStreamTracker.h"
29 #include "AliMUONDspHeader.h"
30 #include "AliMUONBlockHeader.h"
31 #include "AliMUONBusStruct.h"
32 #include "AliMUONDDLTracker.h"
33 #include "AliMUONV2DStore.h"
34 #include "AliMUON2DMap.h"
35 #include "AliMUONCalibParamNF.h"
36 #include "AliMUONObjectPair.h"
37 #include "AliMUONVDataIterator.h"
38 #include "AliMpDDLStore.h"
39 #include "AliMpIntPair.h"
41 #include "AliRawReaderDate.h"
49 #include "TStopwatch.h"
51 #include "TTimeStamp.h"
52 #include "TGraphErrors.h"
57 AliMUONV2DStore* pedestalStore = new AliMUON2DMap(kFALSE);
58 const Int_t kNchannels = 64;
63 TH1F* pedMeanHisto = 0x0;
64 TH1F* pedSigmaHisto = 0x0;
65 Char_t histoFileName[256];
66 TString command("ped");
71 Double_t fitFunc(Double_t *x, Double_t *par)
73 //fit function for gains
79 f = par[0] + par[1]*xx;
81 f= par[0] + par[1]*xx + par[2]*xx*xx;
89 void MakePed(Int_t busPatchId, Int_t manuId, Int_t channelId, Int_t charge)
92 AliMUONVCalibParam* ped =
93 static_cast<AliMUONVCalibParam*>(pedestalStore->Get(busPatchId, manuId));
97 ped = new AliMUONCalibParamNF(2, kNchannels, -1.); // put default wise -1, not connected channel
98 pedestalStore->Set(busPatchId, manuId, ped, kFALSE);
102 ped->SetValueAsFloat(channelId, 0, 0.);
103 ped->SetValueAsFloat(channelId, 1, 0.);
106 Float_t pedMean = ped->ValueAsFloat(channelId, 0) + charge;
107 Float_t pedSigma = ped->ValueAsFloat(channelId, 1) + charge*charge;
109 ped->SetValueAsFloat(channelId, 0, pedMean);
110 ped->SetValueAsFloat(channelId, 1, pedSigma);
115 void MakePedStore(TString flatOutputFile = "")
126 sprintf(histoFileName,"mutrkped-%d.root",runNumber);
127 TFile* histoFile = new TFile(histoFileName,"RECREATE","MUON Tracking pedestals");
131 sprintf(name,"pedmean_allch");
132 sprintf(title,"Pedestal mean all channels");
136 pedMeanHisto = new TH1F(name,title,nx,xmin,xmax);
137 pedMeanHisto->SetDirectory(histoFile);
139 sprintf(name,"pedsigma_allch");
140 sprintf(title,"Pedestal sigma all channels");
144 pedSigmaHisto = new TH1F(name,title,nx,xmin,xmax);
145 pedSigmaHisto->SetDirectory(histoFile);
147 TTree* tree = new TTree("t","Pedestal tree");
148 tree->Branch("bp",&busPatchId,"bp/I");
149 tree->Branch("manu",&manuId,",manu/I");
150 tree->Branch("channel",&channelId,",channel/I");
152 if (!flatOutputFile.IsNull()) {
153 fileout.open(flatOutputFile.Data());
154 fileout<<"//===========================================================================" << endl;
155 fileout<<"// Pedestal file calculated by MUONTRKda"<<endl;
156 fileout<<"//===========================================================================" << endl;
157 fileout<<"// * Run : " << runNumber << endl;
158 fileout<<"// * Date : " << date.AsString("l") <<endl;
159 fileout<<"// * Statictics : " << nEvents << endl;
160 fileout<<"// * # of MANUS : " << nManu << endl;
161 fileout<<"// * # of channels : " << nChannel << endl;
163 fileout<<"//---------------------------------------------------------------------------" << endl;
164 fileout<<"//---------------------------------------------------------------------------" << endl;
165 fileout<<"//format : BUS_PATCH MANU_ID CHANNEL MEAN SIGMA"<<endl;
166 fileout<<"//---------------------------------------------------------------------------" << endl;
170 // iterator over pedestal
171 AliMUONVDataIterator* it = pedestalStore->Iterator();
173 AliMUONObjectPair* p;
175 while ( ( p = dynamic_cast<AliMUONObjectPair*>(it->Next() ) ) )
177 AliMUONVCalibParam* ped = dynamic_cast<AliMUONVCalibParam*>(p->Value());
178 AliMpIntPair* pair = dynamic_cast<AliMpIntPair*>(p->Key());
179 busPatchId = pair->GetFirst();
180 manuId = pair->GetSecond();
182 for (channelId = 0; channelId < ped->Size() ; ++channelId) {
184 pedMean = ped->ValueAsFloat(channelId, 0);
186 if (pedMean > 0) { // connected channels
188 ped->SetValueAsFloat(channelId, 0, pedMean/(Float_t)nEvents);
190 pedMean = ped->ValueAsFloat(channelId, 0);
191 pedSigma = ped->ValueAsFloat(channelId, 1);
193 ped->SetValueAsFloat(channelId, 1, TMath::Sqrt(TMath::Abs(pedSigma/(Float_t)nEvents - pedMean*pedMean)));
195 pedMean = ped->ValueAsFloat(channelId, 0) + 0.5 ;
196 pedSigma = ped->ValueAsFloat(channelId, 1);
199 if (!flatOutputFile.IsNull()) {
200 fileout << "\t" << busPatchId << "\t" << manuId <<"\t"<< channelId << "\t"
201 << pedMean <<"\t"<< pedSigma << endl;
204 pedMeanHisto->Fill(pedMean);
205 pedSigmaHisto->Fill(pedSigma);
211 delete p; // cos create a new object for each iteration
215 if (!flatOutputFile.IsNull())
224 // not usable need an update of DATE ->5.28, but it compiles
225 // uncomment when DATE version ok.
226 // setenv DATE_FES_PATH
227 // setenv DATE_RUN_NUMBER
228 // setenv DATE_ROLE_NAME
229 // setenv DATE_DETECTOR_CODE
231 // if (!flatOutputFile.IsNull()) {
233 // flatOutputFile.Prepend("./");
235 // status = daqDA_FES_storeFile(flatOutputFile.Data(),"MUONTRKda_results");
237 // printf("Failed to export file : %d\n",status);
245 void MakePedStoreForGain()
247 // store pedestal map in root file
249 Int_t injCharge = 200;
253 // compute and store pedestals
256 // store in root file
257 sprintf(histoFileName,"mutrkgain.root");
259 TString mode("UPDATE");
261 if (command.Contains("cre")) {
264 TFile* histoFile = new TFile(histoFileName, mode.Data(), "MUON Tracking Gains");
266 // second argument should be the injected charge, taken from config crocus file
267 // put also info about run number could be usefull
268 AliMpIntPair* pair = new AliMpIntPair(runNumber, injCharge);
270 if (mode.CompareTo("UPDATE") == 0) {
271 tree = (TTree*)histoFile->Get("t");
272 tree->SetBranchAddress("run",&pair);
273 tree->SetBranchAddress("ped",&pedestalStore);
276 tree = new TTree("t","Pedestal tree");
277 tree->Branch("run", "AliMpIntPair",&pair);
278 tree->Branch("ped", "AliMUON2DMap",&pedestalStore);
279 tree->SetBranchAddress("run",&pair);
280 tree->SetBranchAddress("ped",&pedestalStore);
285 tree->Write("t", TObject::kOverwrite); // overwrite the tree
292 void MakeGainStore(TString flatOutputFile)
295 // open file mutrkgain.root
296 // read again the pedestal for the calibration runs (9 runs ?)
297 // need the injection charge from config file (to be done)
298 // For each channel make a TGraphErrors (mean, sigma) vs injected charge
299 // Fit with a polynomial fct
300 // store the result in a flat file.
303 Float_t pedSigma[10];
304 Float_t injCharge[10];
305 Float_t injChargeErr[10];
310 if (!flatOutputFile.IsNull()) {
311 fileout.open(flatOutputFile.Data());
312 fileout<<"//===========================================================================" << endl;
313 fileout<<"// Pedestal file calculated by MUONTRKda"<<endl;
314 fileout<<"//===========================================================================" << endl;
315 fileout<<"// * Run : " << runNumber << endl;
316 fileout<<"// * Date : " << date.AsString("l") <<endl;
317 fileout<<"// * Statictics : " << nEvents << endl;
318 fileout<<"// * # of MANUS : " << nManu << endl;
319 fileout<<"// * # of channels : " << nChannel << endl;
321 fileout<<"//---------------------------------------------------------------------------" << endl;
322 fileout<<"//---------------------------------------------------------------------------" << endl;
323 fileout<<"//format : BUS_PATCH MANU_ID CHANNEL GAIN0 GAIN1 GAIN2 XLIM CHI2"<<endl;
324 fileout<<"//---------------------------------------------------------------------------" << endl;
329 sprintf(histoFileName,"mutrkgain.root");
330 TFile* histoFile = new TFile(histoFileName);
332 AliMUON2DMap* map[10];
333 AliMUONVCalibParam* ped[10];
335 AliMpIntPair* run[10];
337 //read back from root file
338 TTree* tree = (TTree*)histoFile->Get("t");
339 Int_t nEntries = tree->GetEntries();
341 //pb with static libraries of Root to read back info
342 for (Int_t i = 0; i < nEntries; ++i) {
343 printf("nEntry %d\n", i);
344 tree->SetBranchAddress("ped",&map[i]);
345 tree->SetBranchAddress("run",&run[i]);
350 TF1* func = new TF1("func",fitFunc, 0., 2500., 4);
352 // iterates over the first pedestal run
353 AliMUONVDataIterator* it = map[0]->Iterator();
355 AliMUONObjectPair* p;
357 while ( ( p = dynamic_cast<AliMUONObjectPair*>(it->Next() ) ) )
359 ped[0] = dynamic_cast<AliMUONVCalibParam*>(p->Value());
360 pair = dynamic_cast<AliMpIntPair*>(p->Key());
362 Int_t busPatchId = pair->GetFirst();
363 Int_t manuId = pair->GetSecond();
365 // read back pedestal from the other runs for the given (bupatch, manu)
366 printf("nEntries %d\n", nEntries);
367 for (Int_t i = 1; i < nEntries; ++i) {
368 ped[i] = static_cast<AliMUONVCalibParam*>(map[i]->Get(busPatchId, manuId));
371 // compute for each channel the gain parameters
372 for ( Int_t channelId = 0; channelId < ped[0]->Size() ; ++channelId ) {
375 for (Int_t i = 0; i < nEntries; ++i) {
377 if (!ped[i]) continue; //shouldn't happen.
378 pedMean[i] = ped[i]->ValueAsFloat(channelId, 0);
379 pedSigma[i] = ped[i]->ValueAsFloat(channelId, 1);
380 injCharge[i] = (Float_t)run[i]->GetSecond();
381 injChargeErr[i] = 1.;
383 if (pedMean[i] < 0) n--; // not connected
385 if (pedSigma[i] <= 0) pedSigma[i] = 1.; // should not happen.
390 //fit if you can.... not working with present static version of Root
391 TGraph *gain = new TGraphErrors(n, pedMean, pedSigma, injCharge, injChargeErr);
392 //should set some initial parameters
393 func->SetParameter(0,-300); // a0
394 func->SetParameter(1, 1.); // a1
395 func->SetParameter(2, 0.00001);// a2
396 func->SetParameter(3, 1100.); // xlim in ADC
398 gain->Fit("func","q");
400 if (!flatOutputFile.IsNull()) {
401 fileout << "\t" << busPatchId << "\t" << manuId <<"\t"<< channelId << "\t"
402 << setw(8) << func->GetParameter(0) <<"\t"<< setw(8) << func->GetParameter(1)
403 << setw(8) << func->GetParameter(2) <<"\t"<< setw(5) << func->GetParameter(3)
404 << "\t" << func->GetChisquare() << endl;
413 // file outputs for gain
414 if (!flatOutputFile.IsNull())
421 //*************************************************************//
424 int main(Int_t argc, Char_t **argv)
427 Int_t printLevel = 0; // Global variable defined as extern in the others .cxx files
428 Int_t skipEvents = 0;
429 Int_t maxEvents = 1000000;
431 Int_t threshold = -1;
432 Char_t inputFile[256];
433 TString flatOutputFile;
434 TString crocusOutputFile;
435 TString crocusConfigFile;
437 Int_t totalParityErr = 0;
438 Int_t totalGlitchErr = 0;
442 // decode the input line
443 for (Int_t i = 1; i < argc; i++) // argument 0 is the executable name
448 if (arg[0] != '-') continue;
453 sprintf(inputFile,argv[i]);
457 flatOutputFile = argv[i];
461 crocusOutputFile = argv[i];
465 crocusConfigFile = argv[i];
473 printLevel=atoi(argv[i]);
477 skipEvents=atoi(argv[i]);
481 sscanf(argv[i],"%d",&maxEvents);
485 sscanf(argv[i],"%f",&nSigma);
489 sscanf(argv[i],"%d",&threshold);
493 printf("\n******************* %s usage **********************",argv[0]);
494 printf("\n%s -options, the available options are :",argv[0]);
495 printf("\n-h help (this screen)");
498 printf("\n-f <raw data file> (default = %s)",inputFile);
499 printf("\n-c <Crocus config. file> (default = %s)",crocusConfigFile.Data());
502 printf("\n-a <Flat ASCII file> (default = %s)",flatOutputFile.Data());
503 printf("\n-o <CROUCUS cmd file> (default = %s)",crocusOutputFile.Data());
505 printf("\n Options");
506 printf("\n-d <print level> (default = %d)",printLevel);
507 printf("\n-s <skip events> (default = %d)",skipEvents);
508 printf("\n-n <max events> (default = %d)",maxEvents);
509 printf("\n-p <n sigmas> (default = %f)",nSigma);
510 printf("\n-t <threshold (-1 = no)> (default = %d)",threshold);
511 printf("\n-e <execute ped/gain> (default = %s)",command.Data());
512 printf("\n-e <gain create> make gain & create a new root file");
513 printf("\n-e <gain> make gain & update root file");
514 printf("\n-e <gain compute> make gain & compute gains");
519 printf("%s : bad argument %s (please check %s -h)\n",argv[0],argv[i],argv[0]);
520 argc = 2; exit(-1); // exit if error
524 // set command to lower case
527 // decoding the events
530 Int_t nDateEvents = 0;
535 AliMUONDDLTracker* ddlTracker = 0x0;
536 AliMUONBlockHeader* blkHeader = 0x0;
537 AliMUONDspHeader* dspHeader = 0x0;
538 AliMUONBusStruct* busStruct = 0x0;
547 // once we have a configuration file in db
548 // copy locally a file from daq detector config db
549 // The current detector is identified by detector code in variable
550 // DATE_DETECTOR_CODE. It must be defined.
551 // If environment variable DAQDA_TEST_DIR is defined, files are copied from DAQDA_TEST_DIR
552 // instead of the database. The usual environment variables are not needed.
553 if (!crocusConfigFile.IsNull()) {
554 status = daqDA_DB_getFile("myconfig", crocusConfigFile.Data());
556 printf("Failed to get config file : %d\n",status);
562 status = monitorSetDataSource(inputFile);
564 cerr << "ERROR : monitorSetDataSource status (hex) = " << hex << status
565 << " " << monitorDecodeError(status) << endl;
568 status = monitorDeclareMp("MUON Tracking monitoring");
570 cerr << "ERROR : monitorDeclareMp status (hex) = " << hex << status
571 << " " << monitorDecodeError(status) << endl;
575 cout << "MUONTRKda : Reading data from file " << inputFile <<endl;
579 if (nEvents >= maxEvents) break;
580 if (nEvents && nEvents % 100 == 0)
581 cout<<"Cumulated events " << nEvents << endl;
583 // check shutdown condition
584 if (daqDA_checkShutdown())
587 // Skip Events if needed
589 status = monitorGetEventDynamic(&event);
594 status = monitorGetEventDynamic(&event);
596 cout<<"EOF found"<<endl;
602 // decoding rawdata headers
603 AliRawReader *rawReader = new AliRawReaderDate(event);
605 Int_t eventType = rawReader->GetType();
606 runNumber = rawReader->GetRunNumber();
608 if (eventType != PHYSICS_EVENT)
609 continue; // for the moment
613 // decoding MUON payload
614 AliMUONRawStreamTracker* rawStream = new AliMUONRawStreamTracker(rawReader);
617 while((status = rawStream->NextDDL())) {
619 if (printLevel) printf("\niDDL %d\n", rawStream->GetDDL());
621 ddlTracker = rawStream->GetDDLTracker();
623 // loop over block (CRT) structure
624 Int_t nBlock = ddlTracker->GetBlkHeaderEntries();
625 for(Int_t iBlock = 0; iBlock < nBlock ;iBlock++){
627 blkHeader = ddlTracker->GetBlkHeaderEntry(iBlock);
628 if (printLevel) printf("Block Total length %d\n",blkHeader->GetTotalLength());
630 // loop over DSP (FRT) structure
631 Int_t nDsp = blkHeader->GetDspHeaderEntries();
632 for(Int_t iDsp = 0; iDsp < nDsp ;iDsp++){ //DSP loop
634 dspHeader = blkHeader->GetDspHeaderEntry(iDsp);
635 if (printLevel) printf("Dsp length %d\n",dspHeader->GetTotalLength());
637 // loop over BusPatch structure
638 Int_t nBusPatch = dspHeader->GetBusPatchEntries();
639 for(Int_t iBusPatch = 0; iBusPatch < nBusPatch; iBusPatch++) {
641 busStruct = dspHeader->GetBusPatchEntry(iBusPatch);
643 if (printLevel) printf("busPatchId %d", busStruct->GetBusPatchId());
644 if (printLevel) printf(" BlockId %d", busStruct->GetBlockId());
645 if (printLevel) printf(" DspId %d\n", busStruct->GetDspId());
647 Int_t busPatchId = busStruct->GetBusPatchId();
650 Int_t dataSize = busStruct->GetLength();
651 for (Int_t iData = 0; iData < dataSize; iData++) {
655 Int_t manuId = busStruct->GetManuId(iData);
656 Int_t channelId = busStruct->GetChannelId(iData);
657 Int_t charge = busStruct->GetCharge(iData);
659 if (printLevel) printf("manuId: %d, channelId: %d charge: %d\n", manuId,
662 MakePed(busPatchId, manuId, channelId, charge);
669 totalParityErr += rawStream->GetPayLoad()->GetParityErrors();
670 totalGlitchErr += rawStream->GetPayLoad()->GetGlitchErrors();
678 nEvents -= totalGlitchErr; // skipped event cos of Glitch errors
681 cout << " Total number of parity errors in the Run: " << totalParityErr << endl;
682 cout << " Total number of glitch errors in the Run: " << totalGlitchErr << endl;
684 if (command.CompareTo("ped") == 0)
685 MakePedStore(flatOutputFile);
687 // option gain -> update root file with pedestal results
688 // gain + create -> recreate root file
689 // gain + comp -> update root file and compute gain parameters
691 if (command.Contains("gain"))
692 MakePedStoreForGain();
694 if (command.Contains("comp"))
695 MakeGainStore(flatOutputFile);
698 delete pedestalStore;
702 if (!(crocusConfigFile.IsNull()))
703 cout << "MUONTRKda : CROCUS command file generated : " << crocusOutputFile.Data() << endl;
705 cout << "MUONTRKda : WARNING no CROCUS command file generated" << endl;
707 cout << "MUONTRKda : Flat ASCII file generated : " << flatOutputFile << endl;
708 cout << "MUONTRKda : Histo file generated : " << histoFileName << endl;
709 cout << "MUONTRKda : Nb of DATE events = " << nDateEvents << endl;
710 cout << "MUONTRKda : Nb of events used = " << nEvents << endl;
712 printf("Execution time : R:%7.2fs C:%7.2fs\n", timers.RealTime(), timers.CpuTime());