1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 // Analysis task to perform embedding of the simulated AOD
17 // into real data (ESD)
18 // Output conntainer contain AOD with
19 // 0. Data before embedding
20 // 1. Data+with embedded signal
21 // 2. MC information from signal
22 // Data for embedding are obtained using standard Manager
23 // Signal is read from TChain with aodTree
25 // Authors: Dmitri Peressounko
31 #include "TClonesArray.h"
33 #include "TGeoManager.h"
34 #include "TGeoGlobalMagField.h"
36 #include "AliGeomManager.h"
37 #include "AliGRPObject.h"
38 #include "AliCDBPath.h"
39 #include "AliCDBEntry.h"
40 #include "AliESDEvent.h"
41 #include "AliAODEvent.h"
42 #include "AliAnalysisManager.h"
43 #include "AliVEventHandler.h"
44 #include "AliInputEventHandler.h"
45 #include "AliMultiplicity.h"
46 #include "AliAODMCParticle.h"
47 #include "AliAODMCHeader.h"
48 #include "AliCDBManager.h"
49 #include "AliAODHandler.h"
52 #include "AliPHOSReconstructor.h"
53 #include "AliPHOSClusterizerv1.h"
54 #include "AliPHOSDigit.h"
55 #include "AliPHOSGeometry.h"
57 #include "AliPHOSEmbedding.h"
59 ClassImp(AliPHOSEmbedding)
62 //________________________________________________________________________
63 AliPHOSEmbedding::AliPHOSEmbedding(const char *name)
64 : AliAnalysisTaskSE(name),
70 fEmbeddedClusters(0x0),
74 fPHOSReconstructor(0x0),
80 for(int i=0;i<5;i++)fOldPHOSCalibration[i]=0x0 ;
84 //________________________________________________________________________
85 void AliPHOSEmbedding::UserCreateOutputObjects()
87 //prepare output containers
89 //Create branch for output MC particles
90 TClonesArray *mcparticles = new TClonesArray("AliAODMCParticle",0);
91 mcparticles->SetName(AliAODMCParticle::StdBranchName());
92 AddAODBranch("TClonesArray", &mcparticles);
94 //Branch with clusters after embedding
95 fEmbeddedClusters = new TClonesArray("AliAODCaloCluster",0);
96 fEmbeddedClusters->SetName("EmbeddedCaloClusters");
97 AddAODBranch("TClonesArray", &fEmbeddedClusters);
100 //Branch with cells after embedding
101 fEmbeddedCells = new AliAODCaloCells();
102 fEmbeddedCells->SetName("EmbeddedPHOScells");
103 AddAODBranch("AliAODCaloCells", &fEmbeddedCells);
106 fDigitsArr = new TClonesArray("AliPHOSDigit",3*56*64) ;
108 AliAODHandler* handler = (AliAODHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
110 fTreeOut = handler->GetTree();
113 AliWarning("No output AOD Event Handler connected.") ;
118 //________________________________________________________________________
119 void AliPHOSEmbedding::UserExec(Option_t *) {
120 // Main loop, called for each event
123 AliESDEvent *event = dynamic_cast<AliESDEvent*>(InputEvent());
125 Printf("ERROR: Could not retrieve event");
126 PostData(0, fTreeOut);
130 AliCentrality *centrality = event->GetCentrality();
131 Float_t acentrality=centrality->GetCentralityPercentileUnchecked("V0M");
132 if( acentrality <= 0. || acentrality>80.){
136 //Read next AOD event
137 //If necesary method checks if AOD event is good to embed
138 //e.g. there are PHOS clusters etc.
139 AliAODEvent * signal = GetNextSignalEvent() ;
141 Printf("ERROR: Could not retrieve signal");
142 PostData(0, fTreeOut);
148 //Remember PHOS digits before any modification
149 CopyRecalibrateDigits() ;
151 //First re-reconstruct existing digits to ensure identical reconstruction before and
153 AliAODEvent * nullSignal=0x0 ;
154 MakeEmbedding(event,nullSignal) ;
156 //Convert ESD + MC information from signal to AOD
157 ConvertESDtoAOD(event);
159 //Now perform real embedding
160 //Embed signal clusters into event
161 MakeEmbedding(event,signal) ;
164 ConvertEmbeddedClusters(event) ;
166 //Fill MC information
167 ConvertMCParticles(signal) ;
171 PostData(0, fTreeOut);
173 //______________________________________________________________________________
174 void AliPHOSEmbedding::CopyRecalibrateDigits(){
175 //Recalibrate digits if there is better calibration ("new")
176 //exists than one used in reconstruction ("ESD")
178 AliESDEvent *event = dynamic_cast<AliESDEvent*>(InputEvent());
180 AliError("No ESD event!");
185 fCellsPHOS = new AliESDCaloCells() ;
186 fCellsPHOS->CreateContainer(event->GetPHOSCells()->GetNumberOfCells());
188 //Apply recalibration if necessary to account for
189 //difference between calibration used in reconstruction and
191 // if(fOldPHOSCalibration[0]){ //there is a difference in calibrations
192 for (Short_t icell = 0; icell < event->GetPHOSCells()->GetNumberOfCells(); icell++) {
194 Double_t time=0., amp=0. ;
197 // if (fCellsPHOS->GetCell(icell, id, amp,time,mclabel,efrac) != kTRUE)
198 if (event->GetPHOSCells()->GetCell(icell, id, amp,time,mclabel,efrac) != kTRUE)
201 AliPHOSGeometry::GetInstance()->AbsToRelNumbering(id,relId);
202 Float_t calibESD=fOldPHOSCalibration[relId[0]-1]->GetBinContent(relId[2],relId[3]) ;
203 Float_t calibNew=fPHOSReconstructor->Calibrate(1.,id) ;
205 amp=amp*calibNew/calibESD ;
206 fCellsPHOS->SetCell(icell, id, amp, time,mclabel,efrac);
210 //______________________________________________________________________________
211 void AliPHOSEmbedding::Init(){
215 AliESDEvent *event = dynamic_cast<AliESDEvent*>(InputEvent());
217 AliError("Can not obtain InputEvent!") ;
220 Int_t runNum = event->GetRunNumber();
221 AliCDBManager::Instance()->SetRun(runNum);
223 fPHOSReconstructor = new AliPHOSReconstructor() ;
224 AliCDBPath path("PHOS","Calib","RecoParam");
225 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
227 AliError(Form("Can not get OCDB entry %s",path.GetPath().Data())) ;
231 TObjArray* recoParamArray = (TObjArray*)entry->GetObject();
232 AliPHOSRecoParam* recoParam = (AliPHOSRecoParam*)recoParamArray->At(2);
233 fPHOSReconstructor->SetRecoParam(recoParam) ;
241 //________________________________________________________________________
242 AliAODEvent* AliPHOSEmbedding::GetNextSignalEvent(){
243 //Read signal AOD event from the chain
246 AliError("No chain to read signal events") ;
250 AliAODEvent* aod = new AliAODEvent;
251 aod->ReadFromTree(fAODChain);
253 if(fNSignal>=fAODChain->GetEntries()){
257 fAODChain->GetEvent(fNSignal) ;
260 //check if event is read and there is at least 2 PHOS clusters
261 //Otherwise fill histogram and read next event
268 //________________________________________________________________________
269 void AliPHOSEmbedding::MakeEmbedding(AliESDEvent *event,AliAODEvent * signal){
270 //Perform embedding of the signal to the event
272 gROOT->cd(); //make sure that the digits and RecPoints Trees are memory resident
276 fDigitsTree = new TTree("digitstree","digitstree");
277 fDigitsTree->Branch("PHOS","TClonesArray", &fDigitsArr, 32000);
280 delete fClustersTree ;
282 fClustersTree = new TTree("clustertree","clustertree");
284 //Remember number of Clusters before we added new ones...
285 fNCaloClustersOld=event->GetNumberOfCaloClusters() ;
289 printf("---------------Before---------\n") ;
290 Int_t n=event->GetNumberOfCaloClusters() ;
291 for (Int_t iClust=0; iClust<event->GetNumberOfCaloClusters(); ++iClust) {
292 AliESDCaloCluster * cluster = event->GetCaloCluster(iClust);
293 if(!cluster->IsPHOS())
295 Float_t pos[3] = { 0.};
296 cluster->GetPosition(pos);
297 printf("Cluster(%d): E=%f, x=%f, z=%f, CPV=%f \n",iClust,cluster->E(),pos[0],pos[2],cluster->GetEmcCpvDistance()) ;
298 UShort_t * index = cluster->GetCellsAbsId() ;
299 for(Int_t ic=0; ic < cluster->GetNCells(); ic++ )
300 printf("Dig(%d)=%d, ",ic,index[ic]) ;
305 printf("---------------END Before---------\n") ;
313 for(Int_t i=0;i<fDigitsArr->GetEntriesFast();i++){
314 AliPHOSDigit * d = (AliPHOSDigit *) fDigitsArr->At(i) ;
315 printf(" Digit(%d) = %d, E=%f \n",i,d->GetId(),d->GetEnergy()) ;
319 //clusterize and make tracking
320 fPHOSReconstructor->Reconstruct(fDigitsTree,fClustersTree) ;
322 //Note that the cirrent ESDEvent will be modified!
323 fPHOSReconstructor->FillESD(fDigitsTree, fClustersTree, event) ;
327 printf("---------------After---------\n") ;
328 for (Int_t iClust=n; iClust<event->GetNumberOfCaloClusters(); ++iClust) {
329 AliESDCaloCluster * cluster = event->GetCaloCluster(iClust);
330 if(!cluster->IsPHOS())
332 Float_t pos[3] = { 0.};
333 cluster->GetPosition(pos);
334 printf("Cluster(%d): E=%f, x=%f, z=%f, CPV=%f, Label=%d \n",iClust-n,cluster->E(),pos[0],pos[2],cluster->GetEmcCpvDistance(),cluster->GetLabel()) ;
335 UShort_t * index = cluster->GetCellsAbsId() ;
336 for(Int_t ic=0; ic < cluster->GetNCells(); ic++ )
337 printf("Dig(%d)=%d, ",ic,index[ic]) ;
340 printf("---------------END After---------\n") ;
345 //______________________________________________________________________________
346 void AliPHOSEmbedding::ConvertESDtoAOD(AliESDEvent* esd)
348 // ESD Filter analysis task executed for each event
352 AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kTRUE);
353 AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillExtension(kTRUE);
357 // Fetch Stack for debuggging if available
360 Int_t nTracks = esd->GetNumberOfTracks();
361 Int_t nV0s = esd->GetNumberOfV0s();
362 Int_t nCascades = esd->GetNumberOfCascades();
363 Int_t nKinks = esd->GetNumberOfKinks();
364 Int_t nVertices = nV0s + nCascades /*V0 wihtin cascade already counted*/+ nKinks + 1 /* = prim. vtx*/;
365 Int_t nPileSPDVertices=1+esd->GetNumberOfPileupVerticesSPD(); // also SPD main vertex
366 Int_t nPileTrkVertices=esd->GetNumberOfPileupVerticesTracks();
367 nVertices+=nPileSPDVertices;
368 nVertices+=nPileTrkVertices;
370 Int_t nCaloClus = esd->GetNumberOfCaloClusters();
372 Int_t nPmdClus = esd->GetNumberOfPmdTracks();
375 AODEvent()->ResetStd(nTracks, nVertices, nV0s, nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
377 ConvertPrimaryVertices(*esd);
379 ConvertCaloClusters(*esd);
381 ConvertEMCALCells(*esd);
383 ConvertPHOSCells(*esd);
386 //______________________________________________________________________________
387 void AliPHOSEmbedding::ConvertPHOSCells(const AliESDEvent& esd)
389 // fill PHOS cell info
390 if (esd.GetPHOSCells()) { // protection against missing ESD information
391 AliESDCaloCells &esdPHcells = *(esd.GetPHOSCells());
392 Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
394 AliAODCaloCells &aodPHcells = *(AODEvent()->GetPHOSCells());
395 aodPHcells.CreateContainer(nPHcell);
396 aodPHcells.SetType(AliAODCaloCells::kPHOSCell);
397 for (Int_t iCell = 0; iCell < nPHcell; iCell++) {
398 aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell),esdPHcells.GetTime(iCell),-1,0.);
404 //______________________________________________________________________________
405 void AliPHOSEmbedding::ConvertEMCALCells(const AliESDEvent& esd)
407 // fill EMCAL cell info
408 if (esd.GetEMCALCells()) { // protection against missing ESD information
409 AliESDCaloCells &esdEMcells = *(esd.GetEMCALCells());
410 Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
412 AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
413 aodEMcells.CreateContainer(nEMcell);
414 aodEMcells.SetType(AliAODCaloCells::kEMCALCell);
415 for (Int_t iCell = 0; iCell < nEMcell; iCell++) {
416 aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell),esdEMcells.GetTime(iCell));
421 //______________________________________________________________________________
422 void AliPHOSEmbedding::ConvertCaloClusters(const AliESDEvent& esd)
425 // Access to the AOD container of clusters
426 TClonesArray &caloClusters = *(AODEvent()->GetCaloClusters());
429 for (Int_t iClust=fNCaloClustersOld; iClust<esd.GetNumberOfCaloClusters(); ++iClust) {
431 AliESDCaloCluster * cluster = esd.GetCaloCluster(iClust);
433 Int_t id = cluster->GetID();
434 Int_t nLabel = cluster->GetNLabels();
435 Int_t *labels = cluster->GetLabels();
437 Float_t energy = cluster->E();
438 Float_t posF[3] = { 0.};
439 cluster->GetPosition(posF);
441 AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
447 cluster->GetType(),0);
449 Double_t dx=cluster->GetTrackDx() ;
450 Double_t dz=cluster->GetTrackDz() ;
451 Float_t cpv=99. ; //No track matched by default
452 TArrayI * itracks = cluster->GetTracksMatched() ;
453 if(itracks->GetSize()>0){
454 Int_t iTr = itracks->At(0);
455 if(iTr>=0 && iTr<esd.GetNumberOfTracks()){
456 AliESDtrack *track = esd.GetTrack(iTr) ;
457 Double_t pt = track->Pt() ;
458 Short_t charge = track->Charge() ;
459 cpv=TestCPV(dx, dz, pt,charge) ;
463 caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
464 cluster->GetDispersion(),
465 cluster->GetM20(), cluster->GetM02(),
467 cluster->GetNExMax(),cluster->GetTOF()) ;
469 caloCluster->SetPIDFromESD(cluster->GetPID());
470 caloCluster->SetNCells(cluster->GetNCells());
471 caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
472 caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
475 TArrayI* matchedT = cluster->GetTracksMatched();
476 if (fNumberOfTracks>0 && matchedT && cluster->GetTrackMatchedIndex() >= 0) {
477 for (Int_t im = 0; im < matchedT->GetSize(); im++) {
478 Int_t iESDtrack = matchedT->At(im);;
479 if (fAODTrackRefs->At(iESDtrack) != 0) {
480 caloCluster->AddTrackMatched((AliAODTrack*)fAODTrackRefs->At(iESDtrack));
487 caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters
489 //______________________________________________________________________________
490 void AliPHOSEmbedding::ConvertEmbeddedClusters(const AliESDEvent* esd)
492 //Copy PHOS clusters and cells after embedding
494 // Access to the AOD container of clusters
496 fEmbeddedClusters->Clear();
497 fEmbeddedClusters->Expand(esd->GetNumberOfCaloClusters()-fNCaloClustersOld) ;
498 for (Int_t iClust=fNCaloClustersOld; iClust<esd->GetNumberOfCaloClusters(); ++iClust) {
500 AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
502 Int_t id = cluster->GetID();
503 Int_t nLabel = cluster->GetNLabels();
504 Int_t *labels = cluster->GetLabels();
506 Float_t energy = cluster->E();
507 Float_t posF[3] = { 0.};
508 cluster->GetPosition(posF);
510 AliAODCaloCluster *caloCluster = new((*fEmbeddedClusters)[jClusters++]) AliAODCaloCluster(id,
516 cluster->GetType(),0);
519 Double_t dx=cluster->GetTrackDx() ;
520 Double_t dz=cluster->GetTrackDz() ;
521 Float_t cpv=99. ; //No track matched by default
522 TArrayI * itracks = cluster->GetTracksMatched() ;
523 if(itracks->GetSize()>0){
524 Int_t iTr = itracks->At(0);
525 if(iTr>=0 && iTr<esd->GetNumberOfTracks()){
526 AliESDtrack *track = esd->GetTrack(iTr) ;
527 Double_t pt = track->Pt() ;
528 Short_t charge = track->Charge() ;
529 cpv=TestCPV(dx, dz, pt,charge) ;
533 caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
534 cluster->GetDispersion(),
535 cluster->GetM20(), cluster->GetM02(),
537 cluster->GetNExMax(),cluster->GetTOF()) ;
539 caloCluster->SetPIDFromESD(cluster->GetPID());
540 caloCluster->SetNCells(cluster->GetNCells());
541 caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
542 caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
545 for(Int_t i=0;i<fEmbeddedClusters->GetEntriesFast();i++){
546 AliAODCaloCluster *caloCluster =(AliAODCaloCluster *)fEmbeddedClusters->At(i) ;
547 caloCluster->GetID() ;
552 if (esd->GetPHOSCells()) { // protection against missing ESD information
553 AliESDCaloCells &esdPHcells = *(esd->GetPHOSCells());
554 Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
555 fEmbeddedCells->CreateContainer(nPHcell);
556 fEmbeddedCells->SetType(AliAODCaloCells::kPHOSCell);
557 for (Int_t iCell = 0; iCell < nPHcell; iCell++) {
558 fEmbeddedCells->SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell),esdPHcells.GetTime(iCell));
560 fEmbeddedCells->Sort();
565 //______________________________________________________________________________
566 void AliPHOSEmbedding::ConvertMCParticles(const AliAODEvent* aod)
568 //Copy MC branches to new AOD
570 TClonesArray *mcArray = (TClonesArray*)aod->FindListObject(AliAODMCParticle::StdBranchName());
571 TClonesArray * aodMcParticles = (TClonesArray*)AODEvent()->FindListObject(AliAODMCParticle::StdBranchName());
572 for(Int_t i=0;i<mcArray->GetEntriesFast();i++){
574 AliAODMCParticle* aodpart = (AliAODMCParticle*) mcArray->At(i);
575 // AliAODMCParticle * mcp =new ((*aodMcParticles)[i]) AliAODMCParticle(*aodpart);
576 new ((*aodMcParticles)[i]) AliAODMCParticle(*aodpart);
582 AliAODMCHeader * mcHeader = (AliAODMCHeader *)aod.FindListObject(AliAODMCHeader::StdBranchName());
583 AliAODMCHeader * aodMcHeader = new AliAODMCHeader(*mcHeader);
584 aodMcHeader->SetName(AliAODMCHeader::StdBranchName());
585 AddAODBranch("AliAODMCHeader",&aodMcHeader);
589 //______________________________________________________________________________
590 void AliPHOSEmbedding::ConvertHeader(AliESDEvent & esd){
592 AliAODHeader* header = dynamic_cast<AliAODHeader*>(AODEvent()->GetHeader());
593 if(!header) AliFatal("Not a standard AOD");
595 header->SetRunNumber(esd.GetRunNumber());
596 header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection
598 TTree* tree = fInputHandler->GetTree();
600 TFile* file = tree->GetCurrentFile();
601 if (file) header->SetESDFileName(file->GetName());
604 header->SetBunchCrossNumber(esd.GetBunchCrossNumber());
605 header->SetOrbitNumber(esd.GetOrbitNumber());
606 header->SetPeriodNumber(esd.GetPeriodNumber());
607 header->SetEventType(esd.GetEventType());
609 header->SetEventNumberESDFile(esd.GetHeader()->GetEventNumberInFile());
610 if(const_cast<AliESDEvent&>(esd).GetCentrality()){
611 header->SetCentrality(const_cast<AliESDEvent&>(esd).GetCentrality());
614 header->SetCentrality(0);
616 if(const_cast<AliESDEvent&>(esd).GetEventplane()){
617 header->SetEventplane(const_cast<AliESDEvent&>(esd).GetEventplane());
620 header->SetEventplane(0);
624 header->SetFiredTriggerClasses(esd.GetFiredTriggerClasses());
625 header->SetTriggerMask(esd.GetTriggerMask());
626 header->SetTriggerCluster(esd.GetTriggerCluster());
627 header->SetL0TriggerInputs(esd.GetHeader()->GetL0TriggerInputs());
628 header->SetL1TriggerInputs(esd.GetHeader()->GetL1TriggerInputs());
629 header->SetL2TriggerInputs(esd.GetHeader()->GetL2TriggerInputs());
631 header->SetMagneticField(esd.GetMagneticField());
632 header->SetMuonMagFieldScale(esd.GetCurrentDip()/6000.);
633 header->SetZDCN1Energy(esd.GetZDCN1Energy());
634 header->SetZDCP1Energy(esd.GetZDCP1Energy());
635 header->SetZDCN2Energy(esd.GetZDCN2Energy());
636 header->SetZDCP2Energy(esd.GetZDCP2Energy());
637 header->SetZDCEMEnergy(esd.GetZDCEMEnergy(0),esd.GetZDCEMEnergy(1));
639 // ITS Cluster Multiplicty
640 const AliMultiplicity *mult = esd.GetMultiplicity();
641 for (Int_t ilay = 0; ilay < 6; ilay++) header->SetITSClusters(ilay, mult->GetNumberOfITSClusters(ilay));
643 // TPC only Reference Multiplicty
644 // Int_t refMult = fTPCaloneTrackCuts ? (Short_t)fTPCaloneTrackCuts->GetReferenceMultiplicity(&esd, kTRUE) : -1;
645 header->SetTPConlyRefMultiplicity(-1);
648 Float_t diamxy[2]={static_cast<Float_t>(esd.GetDiamondX()),static_cast<Float_t>(esd.GetDiamondY())};
650 esd.GetDiamondCovXY(diamcov);
651 header->SetDiamond(diamxy,diamcov);
652 header->SetDiamondZ(esd.GetDiamondZ(),esd.GetSigma2DiamondZ());
658 for(Int_t mod=0; mod<5; mod++){
659 snprintf(path,255,"/ALIC_1/PHOS_%d",mod+1) ; //In Geometry modules numbered 1,2,.,5
660 if (gGeoManager->cd(path)){
661 m = gGeoManager->GetCurrentMatrix() ;
662 header->SetPHOSMatrix(new TGeoHMatrix(*m),mod) ;
665 header->SetPHOSMatrix(NULL,mod) ;
670 AliEventplane *eventplane = esd.GetEventplane();
671 Double_t epQ = eventplane->GetEventplane("Q");
673 //Standard Eventplane setter is too complicated...
675 header->SetZDCN1Energy(epQ) ;
677 AliCentrality *centrality = esd.GetCentrality();
678 Double_t acentrality=centrality->GetCentralityPercentileUnchecked("V0M");
679 header->SetZDCN2Energy(acentrality) ;
682 }//______________________________________________________________________________
683 void AliPHOSEmbedding::ConvertPrimaryVertices(AliESDEvent const&esd){
684 // Access to the AOD container of vertices
686 // Access to the AOD container of vertices
687 Int_t fNumberOfVertices = 0;
689 Double_t pos[3] = { 0. };
690 Double_t covVtx[6] = { 0. };
692 // Add primary vertex. The primary tracks will be defined
693 // after the loops on the composite objects (V0, cascades, kinks)
694 const AliESDVertex *vtx = esd.GetPrimaryVertex();
696 vtx->GetXYZ(pos); // position
697 vtx->GetCovMatrix(covVtx); //covariance matrix
699 TClonesArray * vertexes=AODEvent()->GetVertices();
701 AliAODVertex* primaryVertex = new((*vertexes)[fNumberOfVertices++])
702 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
703 primaryVertex->SetName(vtx->GetName());
704 primaryVertex->SetTitle(vtx->GetTitle());
706 TString vtitle = vtx->GetTitle();
707 if (!vtitle.Contains("VertexerTracks"))
708 primaryVertex->SetNContributors(vtx->GetNContributors());
710 if (fDebug > 0) primaryVertex->Print();
712 // Add SPD "main" vertex
713 const AliESDVertex *vtxS = esd.GetPrimaryVertexSPD();
714 vtxS->GetXYZ(pos); // position
715 vtxS->GetCovMatrix(covVtx); //covariance matrix
716 AliAODVertex * mVSPD = new((*vertexes)[fNumberOfVertices++])
717 AliAODVertex(pos, covVtx, vtxS->GetChi2toNDF(), NULL, -1, AliAODVertex::kMainSPD);
718 mVSPD->SetName(vtxS->GetName());
719 mVSPD->SetTitle(vtxS->GetTitle());
720 mVSPD->SetNContributors(vtxS->GetNContributors());
722 // Add SPD pileup vertices
723 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesSPD(); ++iV)
725 const AliESDVertex *vtxP = esd.GetPileupVertexSPD(iV);
726 vtxP->GetXYZ(pos); // position
727 vtxP->GetCovMatrix(covVtx); //covariance matrix
728 AliAODVertex * pVSPD = new((*vertexes)[fNumberOfVertices++])
729 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupSPD);
730 pVSPD->SetName(vtxP->GetName());
731 pVSPD->SetTitle(vtxP->GetTitle());
732 pVSPD->SetNContributors(vtxP->GetNContributors());
735 // Add TRK pileup vertices
736 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesTracks(); ++iV)
738 const AliESDVertex *vtxP = esd.GetPileupVertexTracks(iV);
739 vtxP->GetXYZ(pos); // position
740 vtxP->GetCovMatrix(covVtx); //covariance matrix
741 AliAODVertex * pVTRK = new((*vertexes)[fNumberOfVertices++])
742 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupTracks);
743 pVTRK->SetName(vtxP->GetName());
744 pVTRK->SetTitle(vtxP->GetTitle());
745 pVTRK->SetNContributors(vtxP->GetNContributors());
750 //__________________________________________________________________________________
751 void AliPHOSEmbedding::MakeDigits(AliAODEvent * signal){
753 //-------------------------------------------------------------------------------------
754 //Transform CaloCells into Digits which can be used for standard reconstruction
755 //Add signal digits to the event
756 //-------------------------------------------------------------------------------------
758 fDigitsArr->Clear() ;
759 fDigitsTree->Branch("PHOS","TClonesArray", &fDigitsArr, 32000);
761 //First copy data digits
763 for (Short_t icell = 0; icell < fCellsPHOS->GetNumberOfCells(); icell++) {
765 Double_t time=0., amp=0. ;
768 if (fCellsPHOS->GetCell(icell, id, amp, time,mclabel, efrac) != kTRUE)
771 new((*fDigitsArr)[ndigit]) AliPHOSDigit(-1,id,float(amp),float(time),ndigit);
776 //Add Digits from Signal
777 TClonesArray sdigits("AliPHOSDigit",0) ;
780 AliAODCaloCells* cellsS = signal->GetPHOSCells();
781 Int_t cellLabels[1000]={0} ; //1000 should be enough for simulated
782 // Int_t cellSecondLabels[1000]={0} ; //low-statistics event.
783 for(Int_t i=0;i<cellsS->GetNumberOfCells();i++){
785 // cellSecondLabels[i]=-1;
787 //------------------------------------------------------------------------------------
788 //Ancestry information
789 //Celect digits contributing to signal clusters and add primary information
790 //(it is not stored in CaloCells)
791 //------------------------------------------------------------------------------------
792 sdigits.Expand(cellsS->GetNumberOfCells());
793 for(Int_t i=0; i<signal->GetNumberOfCaloClusters(); i++) {
794 //cluster from embedded signal
795 AliVCluster *clus = signal->GetCaloCluster(i);
800 Int_t label = clus->GetLabel();
801 // Int_t label2 = -1 ;
802 // if (clus->GetNLabels()>=2) label2 = clus->GetLabelAt(1) ;
804 UShort_t * index = clus->GetCellsAbsId() ;
805 for(Int_t ic=0; ic < clus->GetNCells(); ic++ ){
806 for (Int_t icell = 0; icell < cellsS->GetNumberOfCells(); icell++){
808 Double_t cellAmplitude=0., cellTime=0. ;
811 cellsS->GetCell(icell, cellNumber, cellAmplitude, cellTime,mclabel,efrac) ;
812 if(cellNumber==index[ic]){
813 cellLabels[icell]=label;
814 // cellSecondLabels[icell]=label2;
821 for (Int_t icell = 0; icell < cellsS->GetNumberOfCells(); icell++) {
823 Double_t cellAmplitude=0., cellTime=0. ;
826 if (cellsS->GetCell(icell, cellNumber, cellAmplitude, cellTime,mclabel,efrac) != kTRUE)
828 //Add only digits related to the cluster, no noisy digits...
829 if(cellLabels[icell]==-1){
832 new(sdigits[isdigit]) AliPHOSDigit(cellLabels[icell],cellNumber,float(cellAmplitude),float(cellTime),isdigit);
839 Int_t icurrent = 0 ; //index of the last used digit in underlying event
840 fDigitsArr->Expand(ndigit+isdigit) ;
841 for(Int_t i=0; i<isdigit;i++){
842 AliPHOSDigit * sdigit=static_cast<AliPHOSDigit*>(sdigits.At(i)) ;
843 Bool_t added=kFALSE ;
844 for(Int_t id=icurrent;id<ndigit;id++){
845 AliPHOSDigit * digit=static_cast<AliPHOSDigit*>(fDigitsArr->At(id)) ;
846 if(sdigit->GetId() == digit->GetId() ){
847 *digit += *sdigit ; //add energies
850 break ; //no more digits with same ID in the list
852 if(sdigit->GetId() < digit->GetId() ){
854 break ; //no more digits with same ID in the list
858 new((*fDigitsArr)[ndigit]) AliPHOSDigit(*sdigit) ;
863 //Change Amp back from Energy to ADC counts
864 //Note that Reconstructor uses best ("new") calibration
865 for(Int_t i=0; i<ndigit;i++){
866 AliPHOSDigit * digit=static_cast<AliPHOSDigit*>(fDigitsArr->At(i)) ;
867 Float_t calib =fPHOSReconstructor->Calibrate(1.,digit->GetId()) ;
869 digit->SetEnergy(digit->GetEnergy()/calib) ;
873 for (Int_t i = 0 ; i < ndigit ; i++) {
874 AliPHOSDigit *digit = static_cast<AliPHOSDigit*>( fDigitsArr->At(i) ) ;
875 digit->SetIndexInList(i) ;
877 fDigitsTree->Fill() ;
880 //__________________________________________________________________________________
881 void AliPHOSEmbedding::SetOldCalibration(TH2F **calibH){
882 //Copy histograms with calibration coeff
885 for(Int_t i=0;i<5;i++){
886 fOldPHOSCalibration[i] = new TH2F(*((TH2F*)calibH[i])) ;
887 snprintf(name,55,"OldPHOSCalibrationMod%d",i) ;
888 fOldPHOSCalibration[i]->SetName(name) ;
891 //____________________________________________________________________________
892 void AliPHOSEmbedding::InitMF(){
894 printf("............Init MF \n") ;
895 //------------------------------------
896 // Initialization of the Mag.Fiels from GRP entry
897 // Copied from AliReconstruction::InitGRP()
898 //------------------------------------
899 AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
900 AliGRPObject * aGRPData=0 ;
903 TMap* m = dynamic_cast<TMap*>(entry->GetObject()); // old GRP entry
906 AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
908 aGRPData = new AliGRPObject();
909 aGRPData->ReadValuesFromMap(m);
913 AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
914 aGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject()); // new GRP entry
920 AliError("No GRP entry found in OCDB!");
923 //*** Dealing with the magnetic field map
925 TString lhcState = aGRPData->GetLHCState();
926 if (lhcState==AliGRPObject::GetInvalidString()) {
927 AliError("GRP/GRP/Data entry: missing value for the LHC state ! Using UNKNOWN");
928 lhcState = "UNKNOWN";
931 TString beamType = aGRPData->GetBeamType();
932 if (beamType==AliGRPObject::GetInvalidString()) {
933 AliError("GRP/GRP/Data entry: missing value for the beam type ! Using UNKNOWN");
934 beamType = "UNKNOWN";
937 Float_t beamEnergy = aGRPData->GetBeamEnergy();
938 if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
939 AliError("GRP/GRP/Data entry: missing value for the beam energy ! Using 0");
943 TString runType = aGRPData->GetRunType();
944 if (runType==AliGRPObject::GetInvalidString()) {
945 AliError("GRP/GRP/Data entry: missing value for the run type ! Using UNKNOWN");
949 if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
950 if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
951 AliInfo("PHOSEmbedding: MF is locked - GRP information will be ignored !");
952 AliInfo("Running with the externally locked B field !");
955 AliInfo("Destroying existing B field instance!");
956 delete TGeoGlobalMagField::Instance();
959 if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
960 // Construct the field map out of the information retrieved from GRP.
963 Float_t l3Current = aGRPData->GetL3Current((AliGRPObject::Stats)0);
964 if (l3Current == AliGRPObject::GetInvalidFloat()) {
965 AliError("GRP/GRP/Data entry: missing value for the L3 current !");
969 Char_t l3Polarity = aGRPData->GetL3Polarity();
970 if (l3Polarity == AliGRPObject::GetInvalidChar()) {
971 AliError("GRP/GRP/Data entry: missing value for the L3 polarity !");
976 Float_t diCurrent = aGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
977 if (diCurrent == AliGRPObject::GetInvalidFloat()) {
978 AliError("GRP/GRP/Data entry: missing value for the dipole current !");
982 Char_t diPolarity = aGRPData->GetDipolePolarity();
983 if (diPolarity == AliGRPObject::GetInvalidChar()) {
984 AliError("GRP/GRP/Data entry: missing value for the dipole polarity !");
988 // read special bits for the polarity convention and map type
989 Int_t polConvention = aGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
990 Bool_t uniformB = aGRPData->IsUniformBMap();
993 AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1),
994 TMath::Abs(diCurrent) * (diPolarity ? -1:1),
995 polConvention,uniformB,beamEnergy, beamType.Data());
997 TGeoGlobalMagField::Instance()->SetField( fld );
998 TGeoGlobalMagField::Instance()->Lock();
999 AliInfo("Running with the B field constructed out of GRP !");
1001 else AliFatal("Failed to create a B field map !");
1003 else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
1007 //____________________________________________________________________________
1008 void AliPHOSEmbedding::InitGeometry(){
1010 // Import ideal TGeo geometry and apply misalignment
1012 AliGeomManager::LoadGeometry("geometry.root");
1014 AliFatal("Can not load geometry");
1016 if(!AliGeomManager::CheckSymNamesLUT("PHOS")) {
1017 AliFatal("CheckSymNamesLUT");
1022 TString detStr = "PHOS";
1023 TString loadAlObjsListOfDets = "PHOS";
1025 if(AliGeomManager::GetNalignable("GRP") != 0)
1026 loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
1027 // AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
1029 AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
1030 AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
1033 //____________________________________________________________________________
1034 Float_t AliPHOSEmbedding::TestCPV(Double_t dx, Double_t dz, Double_t pt, Int_t charge){
1035 //Parameterization of LHC10h period
1040 Double_t sx=TMath::Min(5.4,2.59719e+02*TMath::Exp(-pt/1.02053e-01)+
1041 6.58365e-01*5.91917e-01*5.91917e-01/((pt-9.61306e-01)*(pt-9.61306e-01)+5.91917e-01*5.91917e-01)+1.59219);
1042 Double_t sz=TMath::Min(2.75,4.90341e+02*1.91456e-02*1.91456e-02/(pt*pt+1.91456e-02*1.91456e-02)+1.60) ;
1044 AliESDEvent *event = static_cast<AliESDEvent*>(InputEvent());
1045 Double_t mf = event->GetMagneticField(); //Positive for ++ and negative for --
1047 if(mf<0.){ //field --
1050 meanX=TMath::Min(7.3, 3.89994*1.20679*1.20679/(pt*pt+1.20679*1.20679)+0.249029+2.49088e+07*TMath::Exp(-pt*3.33650e+01)) ;
1052 meanX=-TMath::Min(7.7,3.86040*0.912499*0.912499/(pt*pt+0.912499*0.912499)+1.23114+4.48277e+05*TMath::Exp(-pt*2.57070e+01)) ;
1057 meanX=-TMath::Min(8.0,3.86040*1.31357*1.31357/(pt*pt+1.31357*1.31357)+0.880579+7.56199e+06*TMath::Exp(-pt*3.08451e+01)) ;
1059 meanX= TMath::Min(6.85, 3.89994*1.16240*1.16240/(pt*pt+1.16240*1.16240)-0.120787+2.20275e+05*TMath::Exp(-pt*2.40913e+01)) ;
1062 Double_t rz=(dz-meanZ)/sz ;
1063 Double_t rx=(dx-meanX)/sx ;
1064 return TMath::Sqrt(rx*rx+rz*rz) ;