1 #include "AliHLTEMCALUtils.h"
5 #include "TGeoManager.h"
6 #include "TUnixSystem.h"
8 #include "TClonesArray.h"
12 #include "AliCDBManager.h"
13 #include "AliCDBEntry.h"
14 #include "AliRawReaderMemory.h"
16 #include "AliEMCALRecParam.h"
17 #include "AliEMCALReconstructor.h"
18 #include "AliEMCALGeometry.h"
19 #include "AliEMCALClusterizerv1.h"
20 #include "AliEMCALRawUtils.h"
22 #include "AliESDCaloCells.h"
23 #include "AliESDCaloCluster.h"
24 #include "AliEMCALDigit.h"
25 #include "AliESDEvent.h"
26 #include "AliEMCALRecPoint.h"
27 #include "AliEMCALPID.h"
33 ClassImp(AliHLTEMCALUtils);
35 Int_t AliHLTEMCALUtils::fgDebug = 0;
36 AliEMCALGeometry* AliHLTEMCALUtils::fgGeom = NULL;
37 AliEMCALClusterizerv1* AliHLTEMCALUtils::fgClusterizer = NULL;
38 AliEMCALRecParam* AliHLTEMCALUtils::fgRecParam = NULL;
39 AliEMCALRawUtils* AliHLTEMCALUtils::fgRawUtils = NULL;
40 TFile* AliHLTEMCALUtils::fgGeometryFile = NULL;
41 TGeoManager* AliHLTEMCALUtils::fgGeoManager = NULL;
43 TTree* AliHLTEMCALUtils::fgClustersTreeTmp = NULL;
44 TTree* AliHLTEMCALUtils::fgDigitsTreeTmp = NULL;
45 TClonesArray* AliHLTEMCALUtils::fgDigitsArrTmp = NULL;
46 TBranch* AliHLTEMCALUtils::fgDigitsBranchTmp = NULL;
49 //____________________________________________________________________________
50 AliHLTEMCALUtils::AliHLTEMCALUtils()
54 // Default constructor
59 //____________________________________________________________________________
60 AliHLTEMCALUtils::~AliHLTEMCALUtils()
68 //____________________________________________________________________________
69 void AliHLTEMCALUtils::Cleanup()
71 DeleteStaticMembers();
72 DeleteReconstructionTrees();
75 //____________________________________________________________________________
76 void AliHLTEMCALUtils::DeleteStaticMembers()
78 if (fgRecParam != AliEMCALReconstructor::GetRecParam())
96 //____________________________________________________________________________
97 AliHLTEMCALUtils::AliHLTEMCALUtils(const AliHLTEMCALUtils & /*t*/)
101 // copy ctor not to be used
103 AliFatal("May not use.");
106 //____________________________________________________________________________
107 AliHLTEMCALUtils& AliHLTEMCALUtils::operator = (const AliHLTEMCALUtils & /*t*/)
110 // assignement operator not to be used
112 AliFatal("May not use.") ;
116 //____________________________________________________________________________
117 void AliHLTEMCALUtils::InitRecParam()
120 // Please check the AliEMCALReconstructor for comparison
121 // Check if the instance of AliEMCALRecParam exists,
122 // if not, get it from OCDB if available, otherwise create a default one
125 fgRecParam = (AliEMCALRecParam*) AliEMCALReconstructor::GetRecParam();
129 if (!fgRecParam && (AliCDBManager::Instance()->IsDefaultStorageSet()))
131 AliCDBEntry *entry = (AliCDBEntry*)
132 AliCDBManager::Instance()->Get("EMCAL/Config/RecParam");
133 if (entry) fgRecParam = (AliEMCALRecParam*) entry->GetObject();
138 AliWarningClass("The Reconstruction parameters initialized to default.");
139 fgRecParam = new AliEMCALRecParam;
144 AliErrorClass("Unable to init the reco params. Something is really wrong. Memory?");
147 AliEMCALReconstructor::SetRecParam(fgRecParam);
150 //____________________________________________________________________________
151 AliEMCALRecParam* AliHLTEMCALUtils::GetRecParam()
154 // Init the parameters and reuse the Reconstructor
157 AliHLTEMCALUtils::InitRecParam();
161 //____________________________________________________________________________
162 AliEMCALRawUtils* AliHLTEMCALUtils::GetRawUtils(AliEMCALGeometry *pGeometry)
165 // Init EMCAL raw utils
166 // Use the geometry or try to figure out the default
167 // The OCDB must be initialized.
168 // Otherwise the default contructor of the raw utils will complain.
171 if (fgRawUtils == NULL)
173 if (AliCDBManager::Instance()->IsDefaultStorageSet())
177 fgRawUtils = new AliEMCALRawUtils(pGeometry);
181 fgRawUtils = new AliEMCALRawUtils(AliHLTEMCALUtils::GetGeometry());
184 AliInfoClass("Raw Utils initialized.");
188 AliErrorClass("OCDB not initialized. Unable to init raw utils.");
195 //____________________________________________________________________________
196 AliEMCALClusterizerv1* AliHLTEMCALUtils::GetClusterizer()
199 // Init EMCAL clusterizer
202 if (fgClusterizer == NULL)
204 AliEMCALGeometry *geom = GetGeometry();
205 fgClusterizer = new AliEMCALClusterizerv1(geom);
206 AliInfoClass("ClusterizerV1 initialized.");
209 return fgClusterizer;
212 //____________________________________________________________________________
213 AliEMCALGeometry* AliHLTEMCALUtils::GetGeometry()
216 // Init EMCAL geometry
221 AliInfoClass(Form("Using default geometry"));
222 fgGeom = AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName());
227 //____________________________________________________________________________
228 void AliHLTEMCALUtils::DeleteGeoManager()
231 // Delete the geom manager and the geom TFile
236 fgGeometryFile->Close();
237 delete fgGeometryFile;
238 fgGeometryFile = NULL;
248 //____________________________________________________________________________
249 Bool_t AliHLTEMCALUtils::LoadGeoManagerFromFile(const char *fname)
252 // Open the geom file and get the geom manager
255 Bool_t bReturn = kFALSE;
259 fgGeometryFile = TFile::Open(fname);
262 fgGeoManager = (TGeoManager *)fgGeometryFile->Get("Geometry");
268 AliErrorClass(Form("Unable to retrieve TGeoManager <Geometry> from %s", fname));
276 //____________________________________________________________________________
277 Bool_t AliHLTEMCALUtils::InitFakeCDB(const char *cdbpath, Int_t runid)
280 // Init fake OCDB - use with care.
281 // For dummy usage only!
282 // Make sure there is no conflict with the existing ocdb instance.
285 Bool_t bReturn = kFALSE;
287 TString sPath = cdbpath;
289 if (sPath.Length() <= 0)
292 sPath += gSystem->Getenv("ALICE_ROOT");
293 AliInfoClass(Form("Setting cdbpath to %s", sPath.Data()));
296 AliCDBManager* pCDB = AliCDBManager::Instance();
299 AliErrorClass("Unable to get the CDBManager instance.");
303 pCDB->SetRun(runid); // THIS HAS TO BE RETRIEVED !!!
304 pCDB->SetDefaultStorage(sPath.Data());
305 AliInfoClass(Form("Fake CDB initialized with path %s", sPath.Data()));
312 //____________________________________________________________________________
313 Bool_t AliHLTEMCALUtils::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree, Option_t* sOption)
315 // This method is a reusage the corresponding one of AliEMCALReconstructor
316 // Conversion from raw data to EMCAL digits.
317 // Works on a single-event basis
319 // Make sure raw utils are initialized (they depend on geometry and OCDB) !
321 // We Assume the rawReader, digitsTree and sOption are valid!
323 // Here we assume the raw reader is setup properly, so we do not need extra reset!
324 // rawReader->Reset() ;
326 Bool_t bReturn = kFALSE;
329 // Try to initialize - this is potentially dangerous
330 // We will use default geometry - most probably
331 // The OCDB must exist! otherwise we will fail.
333 if (GetRawUtils() == NULL)
336 AliErrorClass("Failed. No RawUtils.");
343 // Again we try to init the RecParams to default
344 // One should better do it properly before!
345 // The ocdb has to be there! for the recparams init
347 if (GetRecParam() == NULL)
350 AliErrorClass("Failed. No RecParams.");
355 TClonesArray *digitsArr = new TClonesArray("AliEMCALDigit",200);
356 Int_t bufsize = 32000;
357 digitsTree->Branch("EMCAL", &digitsArr, bufsize);
359 fgRawUtils->SetOption(sOption);
361 fgRawUtils->SetRawFormatHighLowGainFactor(fgRecParam->GetHighLowGainFactor());
362 fgRawUtils->SetRawFormatOrder(fgRecParam->GetOrderParameter());
363 fgRawUtils->SetRawFormatTau(fgRecParam->GetTau());
364 fgRawUtils->SetNoiseThreshold(fgRecParam->GetNoiseThreshold());
365 fgRawUtils->SetNPedSamples(fgRecParam->GetNPedSamples());
367 fgRawUtils->Raw2Digits(rawReader,digitsArr);
377 //____________________________________________________________________________
378 TTree *AliHLTEMCALUtils::GetDigitsTree()
381 // Create the digits tree and the digits arrays
384 if (fgDigitsTreeTmp == NULL)
386 fgDigitsTreeTmp = new TTree("EMCALdigits", "EMCAL digits default");
389 if (fgDigitsArrTmp == NULL)
391 fgDigitsArrTmp = new TClonesArray("AliEMCALDigit",200);
394 if (fgDigitsBranchTmp == NULL)
396 Int_t bufsize = 32000;
397 fgDigitsBranchTmp = fgDigitsTreeTmp->Branch("EMCAL", &fgDigitsArrTmp, bufsize);
400 fgDigitsBranchTmp->SetAddress(&fgDigitsArrTmp);
402 return fgDigitsTreeTmp;
405 //____________________________________________________________________________
406 TTree *AliHLTEMCALUtils::GetClustersTree()
409 // Create the clusters tree if necessary
412 if (fgClustersTreeTmp == NULL)
414 fgClustersTreeTmp = new TTree("EMCALclusters", "EMCAL clusters");
417 return fgClustersTreeTmp;
420 //____________________________________________________________________________
421 void AliHLTEMCALUtils::ResetReconstructionTrees()
424 // Reset the content of the reconstruction trees (digits and clusters)
428 tmp = GetDigitsTree();
431 fgDigitsArrTmp->Delete();
435 tmp = GetClustersTree();
442 //____________________________________________________________________________
443 void AliHLTEMCALUtils::DeleteReconstructionTrees()
446 // Delete the reconstruction trees (digits and clusters)
450 tmp = GetDigitsTree();
453 fgDigitsArrTmp->Delete();
454 delete fgClustersTreeTmp;
455 fgClustersTreeTmp = NULL;
458 tmp = GetClustersTree();
461 delete fgDigitsTreeTmp;
466 //____________________________________________________________________________
467 Bool_t AliHLTEMCALUtils::Raw2Clusters(AliRawReader* rawReader, TTree* clustersTree, Option_t* sDigitsOption)
470 // Here we go from raw to clusters (not realeasing digits on the way)
471 // This method combines ConvertDigits and Reconstruct of AliEMCALReconstructor
474 // Here we assume the raw reader is setup properly, so we do not need extra reset!
475 // rawReader->Reset() ;
477 Bool_t bReturn = kFALSE;
480 // Try to initialize - this is potentially dangerous
481 // We will use default geometry - most probably
482 // The OCDB must exist! otherwise we will fail.
484 if (GetRawUtils() == NULL)
487 AliErrorClass("Failed. No RawUtils.");
494 // Again we try to init the RecParams to default
495 // One should better do it properly before!
496 // The ocdb has to be there! for the recparams init
498 if (GetRecParam() == NULL)
501 AliErrorClass("Failed. No RecParams.");
506 if (GetDigitsTree() == NULL)
509 AliErrorClass("Failed. No Digits Tree.");
513 if (GetClusterizer() == NULL)
516 AliErrorClass("Failed. No clusterizer.");
521 fgRawUtils->SetOption(sDigitsOption);
522 fgRawUtils->SetRawFormatHighLowGainFactor(fgRecParam->GetHighLowGainFactor());
523 fgRawUtils->SetRawFormatOrder(fgRecParam->GetOrderParameter());
524 fgRawUtils->SetRawFormatTau(fgRecParam->GetTau());
525 fgRawUtils->SetNoiseThreshold(fgRecParam->GetNoiseThreshold());
526 fgRawUtils->SetNPedSamples(fgRecParam->GetNPedSamples());
528 fgDigitsArrTmp->Delete();
529 fgRawUtils->Raw2Digits(rawReader, fgDigitsArrTmp);
530 fgDigitsTreeTmp->Fill();
533 fgClusterizer->SetOutput(clustersTree);
535 if (fgDigitsArrTmp->GetEntries() > 0)
537 fgClusterizer->SetInput(fgDigitsTreeTmp);
541 fgClusterizer->Digits2Clusters("deb all") ;
545 fgClusterizer->Digits2Clusters("");
548 fgClusterizer->Clear();
555 //____________________________________________________________________________
556 Bool_t AliHLTEMCALUtils::RawBuffer2Clusters(UChar_t *buffer, ULong_t buffSize,
558 TTree* clustersTree, Option_t* sDigitsOption)
561 // Method provided for convenience
562 // Take the raw (DDL) mem buffer and put the clusters into the tree
565 Bool_t bReturn = kFALSE;
567 AliRawReaderMemory rawReader;
569 rawReader.SetEquipmentID(eqID);
570 rawReader.SetMemory(buffer, buffSize);
572 bReturn = AliHLTEMCALUtils::Raw2Clusters(&rawReader, clustersTree, sDigitsOption);
577 //____________________________________________________________________________
578 TTree* AliHLTEMCALUtils::RawBuffer2Clusters(UChar_t *buffer, ULong_t buffSize,
580 Option_t* sDigitsOption)
583 // Method provided for convenience
584 // Take the raw (DDL) mem buffer and put the clusters into the tree
587 Bool_t bReturn = kFALSE;
589 AliRawReaderMemory rawReader;
591 rawReader.SetMemory(buffer, buffSize);
592 rawReader.SetEquipmentID(eqID);
594 TTree *clustersTree = GetClustersTree();
596 bReturn = AliHLTEMCALUtils::Raw2Clusters(&rawReader, clustersTree, sDigitsOption);
597 if (bReturn == kFALSE)
599 clustersTree->Delete();
607 //____________________________________________________________________________
608 UChar_t *AliHLTEMCALUtils::FileToMemory(const char *fname, UChar_t *outpbuffer, ULong_t &buffSize)
611 // Method provided for convenience
612 // Take the raw (DDL) file and copy it to a mem buffer
618 ifstream inputFile(fname, ifstream::in);
619 if (!inputFile.good())
621 AliErrorClass(Form("Unable to open file", fname));
625 inputFile.seekg (0, ios::end);
626 buffSize = inputFile.tellg();
627 inputFile.seekg (0, ios::beg);
629 void *buff = calloc(buffSize, sizeof(char));
633 AliErrorClass(Form("Unable to allocate memory: %d bytes", buffSize));
637 inputFile.read((char*)buff, buffSize);
638 outpbuffer = (UChar_t*)buff;
640 AliInfoClass(Form("File read: %s. Allocated %d bytes at 0x%x", fname, buffSize, outpbuffer));
644 //____________________________________________________________________________
645 Bool_t AliHLTEMCALUtils::FillESD(TTree* digitsTree, TTree* clustersTree, AliESDEvent* esd)
648 // Fill the ESD just like the AliEMCALReconstructor
650 // This is offline code taken directly from the AliEMCALReconstructor
651 // Factorization of the function in the AliEMCALReconstructor should allow calling the code directly
653 // Trigger part on raw data has been removed.
655 //########################################
656 //##############Fill CaloCells############
657 //########################################
661 AliErrorClass("Digits tree is NULL!");
665 if (clustersTree == 0)
667 AliErrorClass("Clusters tree is NULL!");
673 AliErrorClass("Pointer to ESD not set!");
677 TClonesArray *digits = new TClonesArray("AliEMCALDigit",1000);
678 TBranch *branchdig = digitsTree->GetBranch("EMCAL");
681 AliErrorClass("Can't get the branch with the PHOS digits !");
685 branchdig->SetAddress(&digits);
686 digitsTree->GetEvent(0);
687 Int_t nDigits = digits->GetEntries(), idignew = 0 ;
689 AliESDCaloCells &emcCells = *(esd->GetEMCALCells());
690 emcCells.CreateContainer(nDigits);
691 emcCells.SetType(AliESDCaloCells::kEMCALCell);
692 for (Int_t idig = 0 ; idig < nDigits ; idig++)
694 const AliEMCALDigit * dig = (const AliEMCALDigit*)digits->At(idig);
695 if(dig->GetAmp() > 0 )
697 emcCells.SetCell(idignew,dig->GetId(),dig->GetAmp(), dig->GetTime());
701 emcCells.SetNumberOfCells(idignew);
704 //------------------------------------------------------------
705 //-----------------CLUSTERS-----------------------------
706 //------------------------------------------------------------
708 TObjArray *clusters = new TObjArray(100);
709 TBranch *branch = clustersTree->GetBranch("EMCALECARP");
710 branch->SetAddress(&clusters);
711 clustersTree->GetEvent(0);
713 Int_t nClusters = clusters->GetEntries(), nClustersNew=0;
715 esd->SetFirstEMCALCluster(esd->GetNumberOfCaloClusters()); // Put after Phos clusters
717 //######################################################
718 //#######################TRACK MATCHING###############
719 //######################################################
720 //Fill list of integers, each one is index of track to which the cluster belongs.
722 // step 1 - initialize array of matched track indexes
723 Int_t *matchedTrack = new Int_t[nClusters];
724 for (Int_t iclus = 0; iclus < nClusters; iclus++)
725 matchedTrack[iclus] = -1; // neg. index --> no matched track
727 // step 2, change the flag for all matched clusters found in tracks
728 Int_t iemcalMatch = -1;
729 Int_t endtpc = esd->GetNumberOfTracks();
730 for (Int_t itrack = 0; itrack < endtpc; itrack++)
732 AliESDtrack * track = esd->GetTrack(itrack) ; // retrieve track
733 iemcalMatch = track->GetEMCALcluster();
734 if(iemcalMatch >= 0) matchedTrack[iemcalMatch] = itrack;
737 //########################################
738 //##############Fill CaloClusters#############
739 //########################################
740 esd->SetNumberOfEMCALClusters(nClusters);
741 for (Int_t iClust = 0 ; iClust < nClusters ; iClust++)
743 const AliEMCALRecPoint * clust = (const AliEMCALRecPoint*)clusters->At(iClust);
744 //if(clust->GetClusterType()== AliESDCaloCluster::kEMCALClusterv1) nRP++; else nPC++;
746 // Get information from EMCAL reconstruction points
749 clust->GetGlobalPosition(gpos);
750 for (Int_t ixyz=0; ixyz<3; ixyz++)
751 xyz[ixyz] = gpos[ixyz];
753 clust->GetElipsAxis(elipAxis);
754 //Create digits lists
755 Int_t cellMult = clust->GetMultiplicity();
756 //TArrayS digiList(digitMult);
757 Float_t *amplFloat = clust->GetEnergiesList();
758 Int_t *digitInts = clust->GetAbsId();
759 TArrayS absIdList(cellMult);
760 //Uncomment when unfolding is done
761 //TArrayD fracList(cellMult);
763 Int_t newCellMult = 0;
764 for (Int_t iCell=0; iCell<cellMult; iCell++)
766 if (amplFloat[iCell] > 0) {
767 absIdList[newCellMult] = (UShort_t)(digitInts[iCell]);
768 //Uncomment when unfolding is done
769 //fracList[newCellMult] = amplFloat[iCell]/emcCells.GetCellAmplitude(digitInts[iCell]);
774 absIdList.Set(newCellMult);
775 //Uncomment when unfolding is done
776 //fracList.Set(newCellMult);
778 if(newCellMult > 0) { // accept cluster if it has some digit
781 Int_t parentMult = 0;
782 Int_t *parentList = clust->GetParents(parentMult);
783 // fills the ESDCaloCluster
784 AliESDCaloCluster * ec = new AliESDCaloCluster() ;
785 ec->SetClusterType(AliESDCaloCluster::kEMCALClusterv1);
786 ec->SetPosition(xyz);
787 ec->SetE(clust->GetEnergy());
788 ec->SetNCells(newCellMult);
789 //Change type of list from short to ushort
790 UShort_t *newAbsIdList = new UShort_t[newCellMult];
791 //Uncomment when unfolding is done
792 //Double_t *newFracList = new Double_t[newCellMult];
793 for(Int_t i = 0; i < newCellMult ; i++)
795 newAbsIdList[i]=absIdList[i];
796 //Uncomment when unfolding is done
797 //newFracList[i]=fracList[i];
800 ec->SetCellsAbsId(newAbsIdList);
801 //Uncomment when unfolding is done
802 //ec->SetCellsAmplitudeFraction(newFracList);
803 ec->SetClusterDisp(clust->GetDispersion());
804 ec->SetClusterChi2(-1); //not yet implemented
805 ec->SetM02(elipAxis[0]*elipAxis[0]) ;
806 ec->SetM20(elipAxis[1]*elipAxis[1]) ;
807 ec->SetTOF(clust->GetTime()) ; //time-of-fligh
808 ec->SetNExMax(clust->GetNExMax()); //number of local maxima
809 TArrayI arrayTrackMatched(1);// Only one track, temporal solution.
810 arrayTrackMatched[0]= matchedTrack[iClust];
811 ec->AddTracksMatched(arrayTrackMatched);
813 TArrayI arrayParents(parentMult,parentList);
814 ec->AddLabels(arrayParents);
816 // add the cluster to the esd object
817 esd->AddCaloCluster(ec);
819 delete [] newAbsIdList ;
820 //delete [] newFracList ;
822 } // cycle on clusters
824 delete [] matchedTrack;
826 esd->SetNumberOfEMCALClusters(nClustersNew);
827 //if(nClustersNew != nClusters)
828 //printf(" ##### nClusters %i -> new %i ##### \n", nClusters, nClustersNew );
830 //Fill ESDCaloCluster with PID weights
831 AliEMCALPID *pid = new AliEMCALPID;
832 //pid->SetPrintInfo(kTRUE);
833 pid->SetReconstructor(kTRUE);
840 // printf(" ## AliEMCALReconstructor::FillESD() is ended : ncl %i -> %i ### \n ",nClusters, nClustersNew);