Photon and neutral meson identification, isolation and correlation with tracks or jets analysis frame: CaloTrackCorrelations


IMPORTANT: The maintenance of this page is discontinued. For a most up-to-date documentation please visit THIS PAGE.



Gustavo Conesa Balbastre (




1 Introduction

The analysis tools and classes presented in the following lines are intended for particle identification and correlations analysis within the analysis frame of the ALICE experiment. We refer to the ensemble of tools as CaloTrackCorr package. Originally, CaloTrackCorr (or PartCorr in the times when there was a PWG4) was designed for photon identification and isolation and correlations with jets but its purpose has been extended to any kind of particle identification, with special attention to calorimeters information, and correlation with other particles and jets. This package is based in the philosophy of the old JETAN package. This package can be found in AliRoot split in 2 directories: $ALICE_ROOT/PWG/CaloTrackCorrBase and $ALICE_ROOT/PWGGA/CaloTrackCorrelations. Essentially, this package works as follows:

  • The user, via a configuration file (AddTask), defines all analysis to be done and the settings of these analysis.
  • Three input lists with reconstructed clusters from EMCal, PHOS and tracks are filled event by event. DCal will be implemented in the near future. The user can select which lists will be used in the configuration file.
  • Several analysis are executed in the order listed in the configuration file. The output of the precedent analysis can be used as input for the next one. For example:
  1. a first analysis finds maximum energy photon in PHOS and stores it in a new AOD branch,
  2. a second analysis studies if this photon is isolated looking to the tracks close to the photons in the TPC and PHOS,
  3. and a third analysis correlates the isolated photon with a jet on the opposite side, in the TPC and/or EMCAL.
  • Each analysis can produce histograms or AODs as output, although AOD generation has not been used so far.

In the next lines, the basic structure of the code is explained and a HowTo execute the analysis. Finally, The analysis available in the frame for the moment are listed, and how they work is explained.

For the present documentation, let's assume that reader knows how to work with CaloClusters, CaloCells and Track ESD/AOD objects and other Root objects, and a general idea on how the ALICE analysis frame works.

This package is open to everybody, any improvement is welcomed.

2 Basic structure

The ALICE analysis frame provides access to the data produced in the experiment or in simulations in format of ESDs, AODs or MonteCarlo (MC) generator information. In particular, the task class AliAnalysisTaskSE provides a convenient frame to access the data event by event, execute the analysis, and to create new types of output data (AOD format) or histograms. An example on how to do an analysis class for calorimeters deriving from AliAnalysisTaskSE can be found in $ALICE_ROOT/PWGGA/EMCALTasks/AliAnalysisTaskPi0CalibSelection, other examples can be found in the different directories $ALICE_ROOT/PWG*.

The CaloTrackCorr package is divided in 2 directories/libraries, PWG/CaloTrackCorrBase that contains the main steering and common helper-analysis classes, and PWGGA/CaloTrackCorrelations that contains the analysis classes. In PWG/CaloTrackCorrBase we can find 4 main classes

  1. AliAnalysisTaskCaloTrackCorr: derives from AliAnalysisTaskSE; Interface with the main analysis frame, it does the call to all the CaloTrackCorr analysis machinery.
  2. AliAnaCaloTrackCorrMaker: referred in the text as MakerThe CaloTrackCorr  analysis manager class  that:
    1. Executes the different analysis requested and also the data filtering/correction/preparation classes.
    2. Initializes all the analysis and histograms.
  3. AliCaloTrackReader: referred in the text as Readeraccesses the data to be analyzed (calorimeter clusters, tracks, other), filters the events or the analysis objects it and corrects it if needed (for clusters, avoid this if tender can do it).
    1. Event and data filtering executed by AliAnaCaloTrackCorrMaker.
    2. It is accessed by the analysis classes to get its output or other data information.
  4. AliAnaCaloTrackCorrBaseClass: All the analysis classes executed in AliAnaCaloTrackCorrMaker must derive from this class that already includes some common getters and setters useful to access the data needed for the analysis.

In the base repository you can find also different classes with tools for the analysis: 

  • AliFidutialCut: Set the analyzable acceptance of PHOS, DCAL and Tracks, eta/phi cuts, multiple regions.
  • AliCalorimeterUtils: Tools for correcting the data, for EMCal mainly it gives the acces to AliEMCALRecoUtils.
  • AliCaloPID: Tools to identify clusters as photon or pi0: Shower shape, cluster splitting, track matching.
  • AliHistogramRanges: Stores the bin size and ranges of the most common parameters of the histograms used.
  • AliIsolationCut: Isolation algorithm and criteria.
  • AliMCAnalysisUtils: Tools to check the origin of the MC particles generating the calorimeter clusters.
  • AliNeutralMesonSelection: Invariant mass pairs event by event selection.

More details can be found in the corresponding section.

Several sub-analysis (or Seats considering CaloTrackCorr an Analysis Wagon of the Analysis Train) can be executed one after the other, being possible to be the input of an analysis the output of a precedent one, typically in the form of AODs. The analysis frame allows to create additional AOD branches, different from the standard branches (Tracks, CaloClusters, Jets, etc.), to do more specialized analysis compared to the standard ones. The AOD class AliAODPWG4Particle and its derived class AliAODPWG4ParticleCorrelation  (to be renamed to AliAODCaloTrackParticle(Correlations)) have been designed so that they can be used to create objects adequate for any analysis, that can be passed from one analysis to the other. These AOD classes are currently sitting in the directory $ALICE_ROOT/STEER/AOD and linked via the AOD library. 

Here you have a list of the available analysis with a brief description, a more detailed description can be found later:

  • AliAnaCalorimeterQA: Fill QA histograms for EMCAL or PHOS clusters. Currently used as QA task for EMCal.
  • Identification tasks:
    • AliAnaPhoton: Select EMCal or PHOS clusters depending on shower shape, track matching and other criteria. Produce Photon AOD object (AliAODPWG4Particle or AliAODPWG4ParticleCorrelation)
    • AliAnaPhotonConvInCalo: Select EMCal or PHOS clusters, do invariant mass, concentrate on the low mass region, check if the pair comes from conversion and add the pair in a Conversion Photon AOD object.
    • AliAnaPi0: Input are Photon AOD objects (AliAODPWG4Particle is enough), do invariant mass analysis for Pi0 and Eta identification. Included mixing. 
    • AliAnaPi0EbE: create a Pi0 AOD object Event by Event, 3 options:
  1. Same as AliAnaPi0, but select the Photon AOD objects pairs using AliAnaNeutralMesonSelection. 
  2. Photon AOD objects with Photon Conversion objects  from PWGGA/GammaConv package.
  3. Select EMCal clusters as Pi0 or Eta based on shower shape and cluster spliting and other criteria implemented in AliCaloPID.
  • AliAnaInsideClusterInvariantMass: Same as AliAnaPi0EbE option 3, but output are just histograms.
  • AliAnaElectron: Select EMCal or PHOS clusters, identify them as electrons or charged hadrons, produce Electron AOD objects or Hadron AOD objects.
  • AliAnaChargedParticles: Select tracks and create charge hadron AOD object.
  • AliAnaOmegaToPi0Gamma: Identify Omega particles combining Photon and Pi0 AOD objects (AliAODPWG4Particle is enough).
  • AliAnaRandomTrigger: Generate random AOD objects over a defined acceptance.
  • Correlation tasks, for most of all input trigger are identified particle AOD objects (it must be AliAODPWG4ParticleCorrelation) generated with the classes above:
    • AliAnaParticleIsolation: Check if the object is isolated looking to the PHOS or EMCal clusters and/or Tracks in a cone centered in the trigger. Adds to the particle AOD object the list of tracks/clusters in the cone and a flag setting the isolation.
    • AliAnaParticleHadronCorrelation: Correlated the trigger with the tracks (or clusters but not tested) of the event. Do azimuthal correlation and xE, zT distributions. Adds to the particle AOD object the list of correlated tracks and a flag about the leadingness of the particle.
    • AliAnaParticleJetFinderCorrelation: Correlate the trigger with jets obtained with other ALICE packages, namely JETAN. Add to the Particle AOD object a reference to the selected jet.
    • AliAnaParticleJetLeadingConeCorrelation: Correlate the trigger with the leading particle and the jet formed with this leading particle and the particles in a cone around it (not used currently).
    • AliAnaParticlePartonCorrelation: Correlate the trigger particle with partons stored in MC ESDs (not adapted to AOD input). Store the partons in an AOD object.
    • AliAnaGeneratorKine: Pure ESD MC analysis (not adapted for AODs). Correlate Pythia (Herwig?) pure partons and jets. No Particle AOD object is used as input. 

Here you have a schematic view of how the package works

CaloTrackCorr package schema


In the next subsections, the functioning of the classes mentioned before is explained with more detail.

2.1 AliAnalysisTaskParticleCorrelation

This task connects the general ALICE analysis frame and the CaloTrackCorr analysis package. This task, like all the tasks deriving from AliAnalysisTaskSE, contains 4 methods necessary to do an analysis, its content and how they work are explained in the next sub-sections. There is a fifth method FinishTaskOutput() that stores in the output some general summary histograms with statistics of the event for ESDs not AODs.

The main data members of this task are:

  • AliAnaCaloTrackCorrMaker* fAna: pointer to the steering class, executes all the analysis steps
  • TList * fOutputContainer: List of output histograms
  • TString fConfigName: Name of the configuration file, currently not used.
  • TList * fCuts: List with analysis cuts that are stored in a separate container to the histograms.

There is a separate analysis task called AliAnalysisTaskCaloTrackCorrelationsM ,  that contains basically the same but it also interfaces with the mixing frame since it derives from AliAnalysisTaskME. Right now this frame is not used and this class is becoming obsolete. To be seen in the future if we remove it.

2.1.1 Task configuration

This task is configured via an analysis execution macro, as explained in Sect. 3.3. The task is configured either passing to it a name and a configuration file for all the analysis, that will be executed at the Init method of the class; or configuring all at the same time via an AddTask (see Sect. 3.2):

The old way to configure the analysis is like this:

AliAnalysisTaskParticleCorrelation * task = new AliAnalysisTaskParticleCorrelation ("AnalysisName");

task->SetConfigFileName("ConfigOfMyAnalysis");//Default: ConfigAnalysis

or via the pointer to the analysis manager class AliAnaCaloTrackCorrMaker (see Sect. 2.2) that should have been initialized previously with all the analysis:

AliAnalysisTaskParticleCorrelation * task = new AliAnalysisTaskParticleCorrelation ("AnalysisName");

task->SetConfigFileName("ConfigOfMyAnalysis");//Default: ConfigAnalysis

task->SetAnalysisMaker(maker);   // AliAnaCaloTrackCorrMaker * maker = new AliAnaCaloTrackCorrMaker()

Right now all the settings are passed in the a different way, close to what is proposed in the second option, via a configuration task "AddTask" like the ones you have in $ALICE_ROOT/PWGGA/CaloTrackCorrelations/macros, and the only think needed in the execution macro is to do something like:

AliAnalysisTaskParticleCorrelation * task = AddTaskForMyAnalysis(setting1, setting2, ...);

2.1.2 Init()

Here we initialize the analysis pointers and do the analysis configuration if the configuration file is provided, the main lines are:

  • gROOT->LoadMacro(fConfigName+".C"); 

    fAna = (AliAnaCaloTrackCorrMaker*) gInterpreter->ProcessLine("ConfigAnalysis()"); 

    • The configuration macro, if the name is provided, is read here. This macro should return the Maker pointer fAnaNow the manager knows the data to be used and the analysis to be executed. As mentioned below, this can be done earlier via the "AddTaskmacro.

  • fAna->Init();

    • Init all analysis histograms and objects​. See the corresponding section in the Maker to view what is done here.

  • if((fAna->GetReader())->GetDeltaAODFileName()!="") 


    • we define if we want to create an extra AOD file with the output (AOD type) of our analysis. For that, the name of this output file name is passed previously to the manager. By default it creates one AOD file called "deltaAODCaloTrackCorr.root". If no name was given, it will put the analysis AOD output in the common output AOD file where the standard AOD branches (Tracks, CaloClusters, etc) are stored. The name of this file is stored in the Reader class since this one is the one handling the data.
  •  if(fAna->GetReader()->IsEventTriggerAtSEOn()) fAna->GetReader()->SetEventTriggerMask(GetCollisionCandidates());

    • Via the analysis frame we select what kind of triggered data is analized. There is the option to not do the event selection via the general frame but via a selection of the trigger name or bit in the Reader. Here we just store the selected trigger bit in the Reader.

This method is directly called by the Localnit() method, that is needed for some particular cases and it does just that.

2.1.3 UserCreateOutputObjects()

Here the call to the outputs generation and preparation is done. The outputs can be histograms and/or delta AODs. The histograms of the different analysis are initialized via the Maker pointer fAna with the lines:   

OpenFile(1);  (tell the analysis frame to create the file for the histograms)

fOutputContainer = fAna->GetOutputContainer(); (see the Maker section to view what is done here)


This list of histograms is posted to the frame via the line:


The analysis can contain different sub-analysis generating different AOD branches. The AOD branches used in the analysis are created via the Maker. Each of these branches is a TClonesArray with objects of the type AliAODPWG4Particle (see Sect. 2.5) or any other object needed by the user analysis. They are initialized here:

TList * list = fAna->FillAndGetAODBranchList(); //Loop the analysis and create the list of branches

If requested, those created AODs are passed to the general analysis output container for AODs: 


If true, then the branches will be stored in the AOD file output of the analysis or in a new one requested by us:

TString deltaAODName = (fAna->GetReader())->GetDeltaAODFileName();

TClonesArray * array = (TClonesArray*) list->At(iaod); // loop each of the created branches

if(deltaAODName!="") AddAODBranch("TClonesArray", &array, deltaAODName);//Put it in new DeltaAOD file

else AddAODBranch("TClonesArray", &array);//Put it in standard AOD file

In the Reader, the name of the delta AOD file, and the bool deciding if we store this AOD in a file is stored.    

2.1.4 UserExec()

This is the main analysis method:

  • Checks if the Reader is properly initialized to analyze ESDs/AODs/pure MC data. (move this check to the Init?)
    • Int_t  datatype = fAna->GetReader()->GetDataType();
  • Calls the setting of the data in the proper containers in the Reader.
    • fAna->GetReader()->SetInputOutputMCEvent(InputEvent(), AODEvent(), MCEvent());

  • Executes the analysis requested via the Maker:
    • fAna->ProcessEvent((Int_t) Entry(), CurrentFileName());

  • Posts the produced data
    • PostData(1, fOutputContainer);

2.1.5 Terminate()

This method is right now not used for its main/original purpose which is to do final calculations and plots once the analysis ended. It is executed at the end of the analysis of all the events.. Due to the architecture of the frame, we have to pass to it the list with the output histograms, so that in case of PROOF analysis this method can be used. 


We store the analysis parameter in a separate branch or file, those parameters are recovered via the Maker and then posted:

fCuts = fAna->GetListOfAnalysisCuts();

fCuts ->SetOwner(kTRUE);

PostData(2, fCuts);


2.2 AliAnaCaloTrackCorrMaker

This is the manager class that steers the analysis in CaloTrackCorr package. This class keeps: the list of pointers of the analysis classes to be used in fAnalysisContainer (TList*); the histograms used in the analysis in the data member fOutputContainer (TList*); the list of parameters for each analysis fCuts (TList); and the list of AOD branches (TClonesArray*) created by the analysis in the data member fAODBranchList (TList*). The analysis container list is set in the configuration macro through the setter method:

 void AddAnalysis(TObject * ana, Int_t analysis_order)

The analysis classes should contain 2 differentiated analysis parts, one doing output AOD objects creation and AOD branch filling, and other creating histograms from the AODs produced previously. The manager can enable/disable any of both parts with the methods void SwitchOn(Off)HistogramsMaker() and void SwitchOn(Off)AODsMaker(). By default, both kind of analysis are done. 

Other important data members of this class are : fReader (AliCaloTrackReader *) which gives access to the data reader class. This data member is passed to the "maker" via the configuration file; and fCaloUtils (AliCalorimeterUtils*) that gives acess to some calorimeter specific utilities.

The main methods are described in the next subsections.

2.2.1 Init()

Here fReader and analysis classes are initialized:

  • Reader:
    •   GetReader()->Init();

        GetReader()->SetCaloUtils(GetCaloUtils()); // pass the calo utils pointer to the reader

  • ​Loop on list of declared analysis

    •     AliAnaCaloTrackCorrBaseClass * ana =  ((AliAnaCaloTrackCorrBaseClass *) fAnalysisContainer->At(iana)) ; 

          ana->SetReader(fReader);       // Set Reader for each analysis

          ana->SetCaloUtils(fCaloUtils); // Set CaloUtils for each analysis


2.2.2 GetOutputContainer()

Here the histograms of all the different analysis are initialized and passed to the output container.

AliAnaCaloTrackCorrBaseClass * ana =  ((AliAnaCaloTrackCorrBaseClass *) fAnalysisContainer->At(iana)) ;

TList * templist =  ana ->GetCreateOutputObjects();

Since different analysis can be called several times with different settings, cuts, etc., and the histograms will be the same, at this level we change the name of the histogram object so that there is no conflict. The name is changed adding a string, this string is set by the analysis that produces this histogram (done here and not at the analysis class just for simplicity).

 snprintf(newname,buffersize, "%s%s", (ana->GetAddedHistogramsStringToName()).Data(), (templist->At(i))->GetName());

          ((TH1*) templist->At(i))->SetName(newname);

A set of control histograms independent of the individual analysis is created here. They check basic event properties, the number of accepted events, triggers, the position of the vertices etc. Those histograms are filled in the methods  FillControlHistograms() and FillTriggerControlHistograms(), the second one being dedicated to the EMCal trigger nature (how many bad/good triggers). Most of the histograms are not always needed like in simulation, and they can be not filled/created/stored if the data member fFillDataControlHisto is false, set by the corresponding switch method ( Switch(On)OffDataControlHistograms() ). Some of the control histograms filled are:

  • Event counters: fhNEventsIn (all events given by physics selection task), fhNEvents (after event selection), fhNExoticEvents (triggered by exotic clusters in EMCal), fhNPileUpEvents
  • Vertex position: fhXVertex, fhYVertex, fhZVertex
  • ​Scale factor for MC production in jet pT hard bins: fhScaleFactor, fhNMergedFiles
  • ...


2.2.3 FillAndGetAODBranchList()

This method is called by the task AliAnalysisTaskParticleCorrelation, in the method UserCreateOutputObjects(), and creates and fills the list of AOD branches.

The list of AOD branches is stored in the Reader class and is recovered:

TList *aodBranchList = fReader->GetAODBranchList() ;

The different analysis executed might need or not to fill a non standard AOD branch (known via the method NewOutputAOD() set in the base class of the analysis), this method recovers/initializes the AOD branch and passes it to the task through a TList

AliAnaCaloTrackCorrBaseClass * ana =  ((AliAnaCaloTrackCorrBaseClass *) fAnalysisContainer->At(iana)) ; //loop

if(ana->NewOutputAOD()) aodBranchList->Add(ana->GetCreateOutputAODBranch()); //loop

return aodBranchList ;


2.2.4 ProcessEvent(Int_t iEntry, const char * currentFileName)

Main method where all the analysis are executed. The method is executed event by event and it does the following per event:

  1. The AOD branches are emptied, we don't want to have objects added in other events to enter in the analysis.
  2. The geometry OADB with EMCal calibration/bad maps is initialized/opened for the first event via theAliCalorimeterUtils (fCaloUtils)
    • fCaloUtils->AccessGeometry(fReader->GetInputEvent());

    •  fCaloUtils->AccessOADB(fReader->GetInputEvent());

  3. The Reader fills the data lists with EMCal, PHOS and Track, ESD or AOD. The reader also might tell us that some events need to be skipped. The data file name and the event number are passed to the reader.
    •   Bool_t accept = fReader->FillInputEvent(iEntry, currentFileName);

  4. Checks on the event trigger type and the filling of trigger and general control histograms is done, before rejection/acceptance of the event. If event rejected, lists with clusters/tracks etc of the Reader are cleaned.
  5. Once the event is accepted, there is a loop on the analysis to be done. They are executed in the order of the list fAnalysisContainer, first the AOD analysis algorithm is executed, and after the analysis and histogram filling algorithm
    •     AliAnaCaloTrackCorrBaseClass * ana =  ((AliAnaCaloTrackCorrBaseClass *) fAnalysisContainer->At(iana)) ;

          ana->ConnectInputOutputAODBranches(); //Sets branches for each analysi   

          if(!fReader->IsEventTriggerAtSEOn() && isMBTrigger)//Fill pool for mixed event with Min Bias trigger for the analysis that need it

           ana->FillEventMixPool(); if(!isTrigger) continue; // pool filled do not try to fill AODs or histograms if trigger is not MB

          if(fMakeAOD  )  ana->MakeAnalysisFillAOD()  ;

          if(fMakeHisto)  ana->MakeAnalysisFillHistograms()  ;

  6. The data lists of the reader are reset and the remaining control histograms are filled, the last ones only for the requested kind of events, for mixing studies the Min Bias is used as pool of events but not used for the real analysis.



2.2.5 Terminate()

This method is called by the task AliAnalysisTaskParticleCorrelation, in the method Terminate(), and executes the Terminate() method defined in all the analysis classes, it recovers the output list with the histograms and passes it to the analysis class.

AliAnaCaloTrackCorrBaseClass * ana = ((AliAnaCaloTrackCorrBaseClass *) fAnalysisContainer->At(iana)) ;


 2.3 AliCaloTrackReader

AliCaloTrackReader is the class in charge to "read" the data, meaning that filtering and selection of the events, tracks and clusters is done here. The analysis can be done with different types of data ESDs (final output of the reconstruction), AODs (filtered ESDs) or MC (event generator data).  

Since there are format differences between ESDs/AODs and pure MC data, three classes derive from AliCaloTrackReader: AliCaloTrackESDReader, AliCaloTrackAODReader, AliCaloTrackMCReader. If in the configuration we initialize a particular Reader, the type of data analysis is fixed at this moment:

AliCaloTrackReader::kESD,  AliCaloTrackReader::kAOD or AliCaloTrackReader::kMC

You can know in the analysis code which type of data you are analyzing invoking the method Int_t GetDataType(). Although the differences between ESDs and AODs are minor as compared to their origin, just a method differs between the 2 readers up to AliRoot release v5.5

SetInputOutputMCEvent(AliVEvent* esd, AliAODEvent* aod, AliMCEvent* mc) 

that selects what is the:

  • input event : AliAnalysisTaskSE::InputEvent(). In case of ESD filtering task running before the analysis then the input is  AliAnalysisTaskSE::AODEvent() (this option is discouraged now that we have AOD productions automatically).
  • the output event: AliAnalysisTaskSE::AODEvent()
  • MC event: For ESDs it is AliAnalysisTaskSE::MCEvent() (AliStack), for AODs it is not implemented (still true?) and in the analysis we have to access directly the AOD branch AODMCParticles. 

The larger differences between ESDs and AODs come from the Track selection and the access to the MC information. Up to AliRoot release v5.5 everything for each kind of data was implemented in the mother class AliCaloTrackReader. Recently, different methods are implemented in both classes to deal properly with the ESD/AOD handling. The methods are:

  • SelectTrack(AliVTrack* track, Double_t trackMomentum): the selection of tracks is quite different in both cases. Different settings are passed to select the track for ESDs and AODs. More details below.
  • CheckForPrimaryVertex(): Checks the goodness of the reconstructed vertex looking to the number of contributors, unfortunally the access to such numbers is not common.
  • TClonesArray* GetAODMCParticles() and AliAODMCHeader* GetAODMCHeader(), only available for AODs.

AliCaloTrackMCReader transforms the pure kinematic particles (TParticles for ESDs not AliAODMCParticles form AODs) into AOD objects so that the analysis can be done in the same way as for real data streams, see last sub-section for more details.

Event information like the ESD, AOD and stack event pointers, or the event headers can also be accessed through the readers at the analysis clases:

AliStack* GetStack(); AliHeader* GetHeader(); AliGenEventHeader* GetGenEventHeader(); void GetVertex(Double_t * ); AliESDEvent* GetESD(); virtual AliAODEvent* GetAOD(); virtual AliMCEvent* GetMC(); virtual AliVEvent* GetInputEvent() (returns the input ESD, AOD o MC).

Another method interesting is GetVertexBC() that returns the Bunch Crossing of the vertex stored in the vertex object, but ti also allows its recalculation for old AODs.

Particular characteristics of the reader classes in the filling methods are mentioned in next subsections.

2.3.1 Event and data and filtering: FillnputEvent()

The method FillInputEvent() is the main method of this class. It is called in AliAnaCaloTrackCorrMaker::ProcessEvent(), which is executed once each event. This method is in charge of the event selection and detector specific data filtering. 

Events are selected or rejected depending on factors like the vertex position, trigger of the event or pile-up, among others, and will be discussed in next section.

Once the events are selected, three data lists (TObjArrays*) are produced: fCTSTracks (AliVTrack) (CTS stands for Central Tracking System) fEMCALClusters (AliVCaloClusters) and fPHOSClusters (AliVCaloClusters). All these data lists are accessed in the analysis via the corresponding getter methods: GetCTSTracks(), GetEMCALClusters() and GetPHOSClusters(); and filled with the corresponding methods:  FillInputCTS(), FillInputEMCAL() and FillInputPHOS() The analysis may not need to access all the kinds of data so some SwitchOn/SwitchOff methods are provided to avoid the list filling. They are set in the configuration file via methods like SwitchOnCTS() or SwitchOffCTS() for example.

The calorimeters cell information stored in ESDs and AODs (not in MC mode), can also be accessed via the data members (TNamed*fEMCALCells and fPHOSCells and the corresponding getter methods: GetEMCALCells() and GetPHOSCells(), and they are also filled in filling methods which are executed in FillInputEvent(), but cells are not really filtered.

Also, the V0 information is accessed via specific Getters: GetV0Signal(Int_t i),  GetV0Multiplicity(Int_t i), where i indicates A or C side. 

At the end of the method, jet containers produced by PWGJE tasks are accessed for jet and correlations analysis if requested via the methods FillInputNonStandardJets() and FillInputBackgroundJets(), jets are stored here for correlations analysis. Ask Adam Matyja for details.

In the next subsections the event, clusters and track selection is more detailed. Event selection

Several criteria have been implemented to select the events, here we list them in the order of application in the method:

  1. Trigger type and quality via the method CheckEventTriggers(). There are different rejections implemented here:
    1. ​Accept events triggered with a given trigger name. The fired clases is recovered via the method GetFiredTriggerClasses(), and the string we want is set in fFiredTriggerClassName.
    2. Accept LED events. Case not considered so far, a relic.
    3. In case of mixing analysis (not with mixing frame) and when using EMCal triggered events, accept Min Bias events to fill the pull of tracks or clusters to be used later, reject other kind of triggers
    4. Accept or reject events with a particular trigger bit in coincidence with the trigger we are interested: AcceptEventWithTriggerBit() and RejectEventWithTriggerBit().
    5. Reject EMCal triggered events that are likely produced by exotic or bad channels or that the trigger is not found in the trigger data stream. Different steps:
      1. ​Identify what kind of triggered event we have SetEventTriggerBit(). Set the following bools: 
        • fEventTrigMinBias, fEventTrigCentral, fEventTrigSemiCentral, fEventTrigEMCALL0, fEventTrigEMCALL1Gamma1, fEventTrigEMCALL1Gamma2, fEventTrigEMCALL1JEt1, fEventTrigEMCALL1Jet2.
      2. Find the trigger patch that triggered the event in TArrayI patches = GetTriggerPatches()
      3. Match the patch and a cluster in the EMCal, look if this clusters is bad/exotic/pile-up
      4. Decide to remove events without trigger cluster, cluster is bad, cluster is exotic, cluster is out ot expected time. Posility to redo the matching opening the time window (only L0) or checkiing the patches around the ones that triggered.
    6. ​Remove events in FAST cluster for LHC11a

    7. Remove events where EMCal was having LED systems misbehaving (LHC11a)

  2. Pythia hard parton simulations: rejection of extreme events with too large jet or cluster energy with respect the parton energy via the methods ComparePtHardAndJetPt() and ComparePtHardAndClusterPt().
  3. Time stamp: To study events at the begining or end of the fill, only for ESDs (move to AliCaloTrackESDReader?)
  4. Vertex selection: Typically a cut on the z vertex of -+10 cm is used, also the goodness of the primary vertex reconstruction is required via the method CheckForPrimaryVertex() that checks the number of contributors in ITS and TPC to the vertex (ESD/AOD differences, might move to different derived classes). Method FillVertexArray() fills the data member fVertex for the current event and for mixed events in case the Mixing Frame is used.
  5. Pile-up rejection in the same BC via InputEvent()::IsPileUpFromSPD().
  6. Events with trigger on V0AND, triggering mode not implemented for LHC10* and LHC11a.
  7. Centrality bin selection. The centrality is recovered with the method GetEventCentrality() also used in the analysis classes. It considers the different centrarlity estimators and bin widths available.
  8. Rejection of events without tracks, done after the fill of the Track array is done.

Each of the rejections has its own switch and default parameters that can be used/accessed via their corresponding setters/getters. Cluster selection

The cluster filtering for the caloriemters is done in FillInputEMCAL() and FilInputPHOS().  The selection criteria is similar for both calorimeters but it is more complete for the EMCal nowadays. In particular, the EMCal method allows the possiblity to do the analysis from the default list of ESD or AOD EMCal clusters or from a list of clusters generated in parallel or stored previously in the AOD by a clusterizer. Thus, this method contains the access to the different clusters arrays and the actual filtering is done by a separate method called by this one, FillInputEMCALAlgorigthm().  

The common or similar selection criteria are:

  • In MC productions with HIJING+added signals, non pure HIJING clusters are rejected. To be extended to a more general case.
  • Rejection of clusters with bad channels or close to the calorimeter borders via the utils in AliCalorimeterUtils if requested.
  • Recalibration of the clusters energy if requested. For EMCal besides we can recalculate the track-matching, distance to bad channels, time calibration and shower shape parameters. All these done accesing the utilities of AliCalorimeterUtils or directly AliEMCALRecoUtils. Currently it is preferred to leave this to the clusterization task or to the tender.
  • A minimal energy selection
  • An acceptance selection, eta/phi cut via the class AliFidutialCut, see Sect. 4.1.1.

More specific to the EMCal, and some things repeated, here are the selections applied: 

  1. If required, clusters are modified/recalculated on the flight like in the tender (energy, time calibration, position, shower shape etc). This MUST be off when the tender is applied or any other task runs after because the clusters are changed.
  2. Removes bad clusters via the standard method AliEMCALRecoUtils::IsGoodCluster() which basically
    1. Removes clusters with bad cells (if the option was set)
    2. Removes exotic clusters (if the option was set)
    3. Removes clusters close to the border (if the option was set)
    4. Checks that it is an EMCal cluster … and this I think will have to change to include DCal.
    5. Even if the tender does all those cuts, it does not harm to double apply them here. And in case you wonder, the pointer to the AliEMCALRecoUtils is not the pointer used by the tender, so ANY analysis can create its own instance of AliEMCALRecoUtils and use the common tools for your analysis instead of reinventing the wheel, as most of people does.
  3. Removes clusters within certain regions behind dense material, for certain eta columns via the method AliCalorimeterUtils::MaskFrameCluster(iSupMod, ieta)Corrects the energy linearity of the cluster if requested. Like in point 1) do not use if tender does it already and if another task runs after.

  4. Applies the time cut (simple or parametrized a la Evi).

  5. There is the possibility to smear the cluster energy resolution.

Cuts 6 and 7 are applied at the reader level but you can switch it off and in some of the analysis seats like AliAnaPhoton or AliAnaPi0XXX or AliAnaParticleIsolation, they can be also applied there. 

In the EMCal methods, there is also the recovery of the timing of the cluster that triggered used to fill a control histogram in the maker where the EMCal triggered event timing distribution if shown. Track selection

The track selection is composed of the following steps:

  1. In MC productions with HIJING+added signals, non pure HIJING clusters are rejected. To be extended to a more general case.
  2. Track status selection. Only tracks with for example ITSRefit are accepted. The status bit is stored in fTrackStatus
    1.     reader->SetTrackStatus(AliVTrack::kITSrefit);  

  3. Track filter bits/track cuts selection. Depends on  ESD or AOD tracks, implemented in SelectTrack() method after AliRoot release v5.5 in AliCaloTrackESD(AOD)Reader:

  • ESD:
    • The main selection is based on the cuts applied via the class AliESDtrackCuts.
    • We usually trust the settings of the macro maintained by the jet group in PWGJE/macros/CreateTrackCutsPWGJE.C. Different codes are passed depending on the track type.
    • For analysis we usually work with Hybrid tracks composed of 2 type of tracks, that is why we implement a set of track cuts for the main global constrained track fESDtrackCuts and a second one for constrained tracks but without hit on SPD fESDtrackComplementaryCuts. If the second set of cuts is not created, only one track type is considered.
    • The option to select constrained tracks only or track with hits in the SPD is also given, both are unnecessary for Hybrid tracks with the cuts predefined since they already are like that. 
  • AOD:
    • ​Optionally select hybrid tracks via the method aodtrack->IsHybridGlobalConstrainedGlobal()
    • Or select tracks via a filter bit aodtrack->TestFilterBit(fTrackFilterMask). Possibility to select hybrid tracks via 2 filter bits is also given: aodtrack->TestFilterBit(fTrackFilterMaskComplementary)
    • Possibility to select tracks with hits on SPD, not needed if hybrid tracks used before.
    • Cut tracks with a given fraction of shared clusters: 
      • ​Double_t frac = Double_t(aodtrack->GetTPCnclsS()) / Double_t(aodtrack->GetTPCncls());

            if frac > fCutTPCSharedClustersFraction = 0.4 reject.

    • Possibility to select primary tracks, ON by default until recently.

      • aodtrack->GetType()!= AliAODTrack::kPrimary

  1. TOF cut, select tracks in main Bunch Crossing or within a time window. Not used by default.

  2. DCA cut, cut dependent on parametrization, AcceptDCA(Float_t pt, Float_t dca). Not used by default.

  3. Transverse momentum cut, usually 0.2

  4. An acceptance selection, eta/phi cut via the class AliFidutialCut.

All the cuts and settings mentioned here, have their corresponding getting and setting method in the header file.

Besides, the track multiplicity in a pseudorapidity window |eta|fTrackMultEtaCut = 0.9, is counted to later fill a control histogram and reject events with no tracks.

2.3.2 AliCaloTrackMCReader

This class only works right now for ESD kinematics and has not been tested for a long time. The filling methods put neutral particles, in the calorimeters lists, and charged particles in the CTS list, depending on acceptance and momentum cuts. I left the freedom to put in the 3 cluster/track lists either AOD objects or TParticle objects which are stored in stack, this is set doing in the configuration file SetClonesArrayType(Int_t type), where type is kAliAOD or kTParticle. By default AODs are created.

Knowing that not all type of neutral particles can be measured in the calorimeter (neutrino, neutrons, k0) and some charged particles can be measured (electrons), particle selection lists have been defined and taken into account when filling the lists: (TArrayI *) fNeutralParticlesArray (exclude neutral particles with PDG number of the list) and fChargedParticlesArray (add charged particles with PDG number of the list). They are set in the configuration file via methods AddNeutralParticlesArray(TArrayI & array) and AddChargedParticlesArray(TArrayI & array), respectively.

You may want also to do analysis only with final state particles from the generator (status code 1), or exclude GEANT generated particles (status code 0), or select only partons (status code 21), etc. There is also a particle selection as a function of the particle status, which depends on the generator. The data member is (TArrayI *) fStatusArray (keep particles with status of the list) and the setter is AddStatusArray(TArrayI & array). If you don't want to select particles via their status, just set SwitchOffStatusSelection() in the configuration file. By default, no selection on the status is done.

Some generators produce pi0 particles but do not decay them. If this is the case, you have not done the GEANT particle transport and you want to work with the decay photons, it is possible to decay pi0 into 2 photons, with the method MakePi0Decay(). This option is set doing SwitchOnPi0Decay(). By default, it is off.


2.4 AliAnaCaloTrackCorrBaseClass

This is the base class of all analysis classes used in this frame, all must derive from it. Several common data members for the analysis are set here:

  • fInputAODBranch and fOutputAODBranch, :
    • TClonesArray of AliAODPWG4Particle(Correlation) or other kind of objects. To recover the lists you can do it with the getters: (TClonesArray*) GetInputAODBranch(),(TClonesArray*) GetOutputAODBranch(). Why 2 AOD branches? An analysis can create non standard AODs (output) that can be used in a second analysis (input), for example AliAnaPhoton produces output photons, input for AliAnaPi0. Also, it is possible that you want to create a new AOD output from an already AOD input branch, for example AliAnaPhoton produces output photons, input for AliAnaPi0EbE (EbE: event by event), which produces output pi0. These input/ouput arrays can be accessed during the analysis for each event and add objects or modify the content of these objects.
    • I consider that all analysis will create or have acces to one input or output AOD, for this reason the method ConnectInputOutputAOD(), that connects the input/output AOD branch with the corresponding branch in memory, is called for each event by the manager.
    • To add a selected AOD object into the output AOD list you have to do just AddAODParticle(AliAODParticle pc).
      Using this method, you can only add to the output list objects of the type AliAODPWG4Particle(Correlation), if the user wants to add other type of objects, he will have to add them in a similar way as in this method. You can set the type of the objects to be added via the setter SetOutputAODBranchName(TString name). Be careful, if you fill a branch with objects of the type AliAODPWG4Particle and in the next analysis it is expecting objects of the type AliAODPWG4ParticleCorrelation, the analysis will break, make sure that you request the appropriate type of objects. For example, AliAnaPhoton can produce an output of AliAODPWG4Particle or AliAODPWG4ParticleCorrelation objects but the analysis AliAnaParticle* work only with AliAODPWG4Particle objects. The idea of the input AOD list is that the objects of the list can be modified but not new objects added, only to output AOD, but this is left to the user. If your analysis fills an output AOD it must be setted in the initialization of the class the name of the branch with the method SetOutputAODName(TString name). You must also specify the name of the input AOD that needs the analysis via SetInputAODName(TString name). Make sure that the names are correct setting them in the configuration file.
  • Common analysis classes data members (see Sect 4.1 for details on the algorithms):
    • AliCaloPID * fCaloPID, accessed via GetCaloPID(). Switch on its use via fCheckCaloPID.
    • AliCalorimeterUtils * fCaloUtils, accessed via GetCaloUtils()
    • AliFidutialCut * fFidCut, accessed via GetFidutialCut(). Switch on its use via the bool fCheckFidCut.
    • AliIsolationCut * fIC, accessed via GetIsolationCut()
    • AliNeutralMesonSelection * fNMS, accessed via GetNeutralMesonSelection()
    • AliHistogramRanges * fHisto, accessed via GetHistogramRanges() 
    • AliMCAnalysisUtils * fMCUtils, accessed via GetMCAnalysisUtils()
    • The corresponding setters are also defined to be used in the configuration file to add the common analysis initialized pointers to the main analysis class, after their working parameters are set. Also switch on/off methods and data member are provided.
  • Bool_t fDataMC: Flag to access MC information when working with ESDs or AODs (only useful in case of simulations). The corresponding switch on/off methods are defined. This flag must be placed by the user where it corresponds.
  • Float_t fMinPt, Float_t fMaxPt: Since most of analysis usually plays with momentum or energy cuts, I left the possibility. Corresponding setters and getters defined: GetMaxPt(), GetMinPt(), SetMaxPt(Float_t pt), SetMinPt(Float_t pt).
  • Int_t fDebug: Flag for printing debugging information, different levels of debug possible: GetDebug(), SetDebug(Int_t d). Not mentioned before, but the reader, maker and base task have also their own debug levels.
  • Bool_t fDoOwnMix, for the analysis where they have the mixing implemented inside, this must be set to true via SwitchOn(Off)OwnMix().  Check in the code via method DoOwnMixing(). See analysis classes AliAnaPi0 and AliAnaParticleHadronCorrelation.

The most important methods that should be defined in all analysis deriving from this class are:

  • TList* GetCreateOutputObjects(): Here, all histograms needed in the analysis must be initialized, they must be previously defined as data members of the analysis class. It returns to the maker and then to the task mother class the list of histograms.
  • MakeAnalysisFillAOD() and MakeAnalysisFillHistograms(): The analysis algorithms should be in these methods. It is advisable to differentiate algorithms that do particle selection and filling of AODs, and algorithms that take these selected particles and fill needed histograms.
  • Init(): Initializations needed for the analysis.

Access to data lists or reader information is provided via the following getters: TClonesArray* GetAODCTS(); TClonesArray* GetAODEMCAL(); TClonesArray* GetAODPHOS(); TNamed * GetEMCALCells(); TNamed * GetPHOSCells(); AliCaloTrackReader * GetReader(), AliStack * GetMCStack(), AliHeader* GetMCHeader(), AliGenEventHeader* GetMCGenEventHeader().

Other interesting methods are those providing in which event multiplicity, centrality reaction plane , etc. bin the analysis is running. To define a bin, a range and a number of bins has to be provided for the corresponding parameter.

  • GetEventCentralityBin(): Returns the centrality via the common centralityt frame. If  requested, some hard coded multiplicity bins are considered (fUseTrackMultBins=kTRUE)

  • GetEventRPBin(): Reaction plane bin.

  • GetEventVzBin(): z vertex bins.

  • GetEventMixBin(): a bin combination of the 3 above.

2.5 AliAODPWG4Particle and AliAODPWG4ParticleCorrelation (to be renamed to  AliAODCaloTrackParticle(Correlations))

The class AliAODPWG4Particle derives from AliVParticle and produces objects that contain information of the reconstructed cluster/tracks found during the analysis. These objects are output/input for analysis (output of a first analysis, input for a second, for example). Basically, AliAODPWG4ParticleCorrelation objects are TLorentzVectors plus additional information necessary for the analysis. Here, there is the list of data members and informations that can be added to such objects:

  • TLorentzVector* fMomentum: 4-momentum vector. Methods to access its properties are available: Px(), Py(), Pz(), Pt(), P(), PxPyPz(Double_t p[3]), OneOverPt(), Phi(), Theta(), E(), M(), Eta(), Y(). You can recover directly the TLorentzVector via the method TLorentzVector * Momentum(). The way to set this data member is when the object AliAODPWG4Particle is created, for example: ``TLorentzVector mom(px,py,pz,e); AliAODParticleCorrelation ph = AliAODParticleCorrelation(mom);'' or just ``AliAODParticleCorrelation ph = AliAODParticleCorrelation(px,py,pz,e);''
  • Int_t fPdg: PDG number of the particle set after PID selection. Set with SetPdg(Int_t pdg) and get with Int_t GetPdg().
  • Int_t fTag: Free additional tag to identify the particle type. For example in AliCaloPID::CheckOrigin(), I set in the tag from the MC information if the particle is a photon from decay, fragmention or prompt etc. Set with SetTag(Int_t tag) and get with Int_t GetTag().
  • Int_t fLabel: MC label in stack of most probable generated particle. Set with SetLabel(Int_t pdg) and get with Int_t GetLabel().
  • TString fDetector: Detector where particle was measured. Set with SetDetector(TString det) and get with TString GetDetector().
  • Int_t fCaloLabel[2]: For input CaloClusters, ID number in the original CaloCluster list. If the AOD particle is a combination of 2 CaloClusters (pi0 analysis) then put the ID number of both. Set with SetCaloLabel(Int_t i, Int_t j) and get with Int_t GetCaloLabel(i).
  • Int_t fTrackLabel[4]: For input Tracks, ID number in the original Track list. If the AOD particle is a combination of 2 Tracks (gamma conversion analysis) then put the ID number of both. Set with SetTrackLabel(Int_t i, Int_t j) and get with Int_t GetTrackLabel(i).
  • Bool_t fDisp: For CaloClusters, Dispersion bit. Set with SetDispBit(Int_t bit) and get with Int_t GetDispBit().
  • Bool_t fTof: For CaloClusters, TOF bit. Set with SetTOFBit(Int_t bit) and get with Int_t GetTOFBit().
  • Bool_t fCharged: For PHOS CaloClusters, Charged bit. Set with SetChargedBit(Int_t bit) and get with Int_t GetChargedBit().
  • Int_t fBadDist: Distance to bad calorimeter cell in cell units. Set with SetDistToBad(Int_t dist) and get with Int_t DistToBad().

The method Bool_t IsPIDOk(Int_t ipidoption, Int_t pdgwanted), check if the pid bits or the pdg are the good ones for the identification of our particle. There are 9 PID combinations.

  • 0 - No PID, accept all
  • 1 - Check if pdg given in method is the same as the one stored in AOD
  • 2, 3, 4 - Check single PID bit, dispersion, TOF and charge respectively
  • 5 - Check that dispersion and TOF bits are set
  • 6 - Check that dispersion and charge bits are set
  • 7 - Check that TOF and charge bits are set
  • 8 - Check that all bits are set.

The setting of the bits is responsibility of the user. The setting of bits is done in AliCaloPID for the case of photons.

AliAODPWG4Particle contains the minimum information for particle identification analysis. For pi0 invariant mass analysis the memory size of the object is small. If we want to do correlation analysis we need to add more information to the object. The class AliAODPWG4ParticleCorrelation is daughter of AliAODPWG4Particle with additional data members needed for correlation studies:

  • Bool_t fIsolated: Flag for isolation studies. Set with SetIsolated(Bool_t iso) and get with Bool_t IsIsolated().
  • TRefArray* fRefTracks: For correlation studies, array of references to the tracks belonging to the jet or all selected hadrons. To recover or set the tracks: TRefArray* GetRefTracks(), AddTrack(TObject *tr), TObject* GetTrack(Int_t i).
  • TRefArray* fRefClusters: For correlation studies, array of references to the CaloClusters belonging to the jet or all selected clusters. To recover or set the CaloClusters: TRefArray* GetRefClusters(), AddCluster(TObject *tr), TObject* GetCluster(Int_t i).
  • TRefArray* fRefIsolationConeTracks: For isolation studies, array of references to the tracks that fall in the cone around the candidate for isolation. To recover or set the tracks: TRefArray* GetRefIsolationConeTracks(), AddIsolationConeTrack(TObject *tr), TObject* GetIsolationConeTrack(Int_t i).
  • TRefArray* fRefIsolationConeClusters: For isolation studies, array of references to the CaloClusters that fall in the cone around the candidate for isolation. To recover or set the CaloClusters: TRefArray* GetRefIsolationConeClusters(), AddIsolationConeCluster(TObject *tr), TObject* GetIsolationConeCluster(Int_t i).
  • TRefArray* fRefBackgroundTracks: For correlation studies, array of references to the tracks used for background estimation. To recover or set the tracks: TRefArray* GetRefBackgroundTracks(), AddBackgroundTrack(TObject *tr), TObject* GetBackgroundTrack(Int_t i).
  • TRefArray* fRefBackgroundClusters: For correlation studies, array of references to the CaloClusters used for background estimation. To recover or set the CaloClusters: TRefArray* GetRefBackgroundClusters(), AddBackgroundCluster(TObject *tr), TObject* GetBackgroundCluster(Int_t i).
  • TString fLeadingDetector: Detector where jet leading particle was measured. Set with SetLeadingDetector(TString det) and get with TString GetLeadingDetector().
  • Bool_t fLeadingParticle: Tag this particle as the most energetic in the event. Set with SetLeadingParticle(Bool_t le) and get with Bool_t IsLeadingParticle().
  • TLorentzVector fLeading: Correlated jet leading particle 4-momentum vector. Set with SetLeading(TLorentzVector leading) and get with TLorentzVector GetLeading().
  • TLorentzVector fCorrJet; Correlated jet 4-momentum vector. Set with SetCorrelatedJet(TLorentzVector jet) and get with TLorentzVector GetCorrelatedJet().
  • TLorentzVector fCorrBkg; Correlated jet bakcground 4-momentum vector. Set with SetCorrelatedBackground(TLorentzVector bkg) and get with TLorentzVector GetCorrelatedBackground().
  • TRef fRefJet: Reference to jet found with JETAN and correlated with particle. Set with SetRefJet(AliAODJet* jet) and get with AliAODJet* GetJet().

If needed, more data members with information needed for analysis can be added.


3 How to create and execute an analysis

This section is devoted to explain how to write an analysis class via existing examples, how to set the analysis needed parametres and finally how to execute it. The basic things that a user needs are:


  1. Root installed (unless yor analysis needs to access AliRoot)
  2. Data in ESD, AOD or MC format.
  3. ``.par'' files or analysis libraries with your analysis class inside.
  4. Analysis configuration file.
  5. Analysis macro: ana.C

If everything is there, you just have to execute: root -q -b -l ana.C and the analysis begins.


3.1 Analysis Example

In $ALICE_ROOT/PWGGA/CaloTrackCorrelations you can find the class AliAnaPhoton, a quite general example analysis class, with examples on how to access the different data lists, how to fill AODs and how to define and fill histograms. As mentioned in Sect. 2.4, this class derives from AliAnaCaloTrackCorrBaseClass, like all the analysis used in this frame.

This class produces as output AODs and a few simple histograms like particle momentum/phi/eta distribution, calorimeters cells multiplicity and cells amplitude distribution:


TH1F * fhPt; //! pT distribution
TH1F * fhPhi; //! phi distribution
TH1F * fhEta; //! eta distribution
TH2F * fh2Pt; //! pT distribution, reconstructed vs generated
TH2F * fh2Phi; //! phi distribution, reconstructed vs generated
TH2F * fh2Eta; //! eta distribution, reconstructed vs generated
TH1F * fhNCells; //! Number of towers/crystals with signal
TH1F * fhAmplitude; //! Amplitude measured in towers/crystals



Histograms should be defined as data members and in the class header file (AliAnaExample.h). In the main class file (AliAnaExample.cxx), in the constructors all data members should be initialized with a default initialization. In method TList * GetCreateOutputObjects(), all histograms are initialized with their corresponding binning and axis ranges:


Int_t nptbins = GetHistoNPtBins(); Int_t nphibins = GetHistoNPhiBins(); Int_t netabins = GetHistoNEtaBins();
Float_t ptmax = GetHistoPtMax(); Float_t phimax = GetHistoPhiMax(); Float_t etamax = GetHistoEtaMax();
Float_t ptmin = GetHistoPtMin(); Float_t phimin = GetHistoPhiMin(); Float_t etamin = GetHistoEtaMin();
fhPt = new TH1F ("hPt","p_T distribution", nptbins,ptmin,ptmax); fhPt->SetXTitle("p_{T} (GeV/c)");
fhPhi = new TH1F ("hPhi","#phi distribution",nphibins,phimin,phimax); fhPhi->SetXTitle("#phi (rad)");
fhEta = new TH1F ("hEta","#eta distribution",netabins,etamin,etamax); fhEta->SetXTitle("#eta ");
//For histograms filled with cells, cells not available in analysis of MC generator data (Kinematics.root).
if(GetReader()->GetDataType()!= AliCaloTrackReader::kMC) {
fhNCells = new TH1F ("hNCells","# cells per event", 100,0,1000);
fhNCells->SetXTitle("n cells");
outputContainer->Add(fhNCells); // added to the ouput list.
//In case we want to combine MC generated data and reconstructed data
fh2Pt = new TH2F ("h2Pt","p_T distribution, reconstructed vs generated",
nptbins,ptmin,ptmax, nptbins,ptmin,ptmax);
fh2Pt->SetXTitle("p_{T,rec} (GeV/c)"); fh2Pt->SetYTitle("p_{T,gen} (GeV/c)");
outputContainer->Add(fh2Pt); // added to the ouput list.



Here we have checked that the type of data is the correct one to fill the different histograms (calorimeter cells histograms cannot be filled with MC data). Also, we checked if we wanted to combine information of reconstructed particles and their original generator particles. The method returns the TList * outputContainer which is read in AliAnalisysTaskParticleCorrelation and passed to the analysis frame.

You can initialize some parameters relevant for the analysis in the InitParameters() method, that you should put in the contructor or directly initialize them in the contructor data members list. In this particular analysis we have defined 2 parameters, Int_t fPdg to set which kind of identified particle we want to work with, and TString fDetector, to select one of the three data lists possible. The appropriate setters and getters of these methods are also provided in the header file. Also here you have to give a default value for the AOD branch that you are going to fill and which type of AOD objects do you want to work


fPdg = 22; //Keep photons
fDetector = "PHOS";



The analysis algorithms should go to the methods MakeAnalysisFillAOD(), where AOD output objects are created, and MakeAnalysisFillHistograms(), where the AOD analysis objects and other general data is used to fill histograms. MakeAnalysisFillAOD()

First, we select the type of data list that we want to use for our analysis and put then in the list partList:


//Get List with tracks or clusters
TClonesArray * partList = new TClonesArray;
if(fDetector == "CTS") partList = GetAODCTS();
else if(fDetector == "EMCAL") partList = GetAODEMCAL();
else if(fDetector == "PHOS") partList = GetAODPHOS();



In case that we want to analyze CaloClusters, we can either send the created AODCaloClusters to the output AOD file or the new output AOD branch with AliAODPWG4Particle objects. If you want to send the CaloClusters to the output, it is necessary that you put the line ConnectCaloClusters() as explained in the first item of Sect. 2.4. If you want to do a loop on the list of CaloClusters and later add it to the ouput, you have just to do:


for(Int_t i = 0; i GetEntriesFast(); i++){
AliAODCaloCluster * calo = dynamic_cast (partList->At(i));
//Apply any calocluster selection algorithm.
//Fill AODCaloClusters



You can access other analysis algorithm listed in Sect. 4.1 and explained how to access in the second item of Sect. 2.4. In the next lines, the calorimeter particle identification class is called and only clusters are selected if their most likely ID returned by the method GetPdg() is equal to the value of fPdg. Also an acceptance selection of the cluster is done via the class AliFidutialCut.


//PID selection
Double_t pid[13]; calo->GetPID(pid);
pdg = GetCaloPID()->GetPdg(fDetector,pid,mom.E());}
//Acceptance selection
Bool_t in = kTRUE;
if(IsFidutialCutOn()) in = GetFidutialCut()->IsInFidutialCut(mom,fDetector) ;
//Select cluster if momentum, pdg and acceptance are good
if(mom.Pt() > GetMinPt() && pdg ==fPdg && in) {



Finally, with the selected clusters you can fill your AOD branch with AliAODPWG4Particle objects:


AliAODParticleCorrelation ph = AliAODParticleCorrelation(mom);
ph.SetPdg(pdg); ph.SetDetector(fDetector);



If you want to work with Tracks, a similar procedure can be followed. In this case, the way to do a loop of tracks is:


for(Int_t i = 0; i GetEntriesFast(); i++){
AliAODTrack * track = dynamic_cast (GetAODCTS()->At(i));
//Analysis algorythm



The last option is to work with CaloCells. Like for CaloClusters, you can create directly CaloCells as AOD output, for that you have to put the following line:


AliESDCaloCells * esdCell = new AliESDCaloCells ;
if(fDetector == "PHOS") {
ConnectAODPHOSCells(); //Do Only when filling AODCaloCells
esdCell = (AliESDCaloCells *) GetPHOSCells(); }//Get PHOS cells from ESD
else {
ConnectAODEMCALCells(); //Do Only when filling
AODCaloCells esdCell = (AliESDCaloCells *) GetEMCALCells();} //Get EMCAL cells from ESD



Then, you have to initalize the AODCaloCells container, and then fill the container with the amplitudes and cell ID. Here we are just copying the content from ESDs to AODs:


//Fill AODCells in file Int_t ncells = esdCell->GetNumberOfCells() ;//Get number of ESD CaloCells
//Set number of entries in AOD container
//Set type of AODCaloCells (PHOS or EMCAL)
GetAODCaloCells()->SetType((AliAODCaloCells::AODCells_t) esdCell->GetType());
for (Int_t iCell = 0; iCell
//Fill AODCaloCells with amplitudes and cell ID.
GetAODCaloCells()->SetCell(iCell,esdCell->GetCellNumber(iCell),esdCell->GetAmplitude(iCell)); }
GetAODCaloCells()->Sort(); //Order the contents of the list.

In this method, we fill histograms from the AOD branch with AliAODParticleCorrelation objects, created in the previous method, but the other lists can be called as well. Notice that if we have as an input an AOD containing this AOD branch, we can just execute this method and read the already existing list to fill the histograms. To access the objects of the AOD list and fill simple histograms, you do just:


Int_t naod = GetAODBranch()->GetEntriesFast();
for(Int_t iaod = 0; iaod
AliAODPWG4Particle* ph = (AliAODPWG4Particle*) (GetOutputAODBranch()->At(iaod));
//Fill Histograms
fhPt->Fill(ph->Pt()); fhPhi->Fill(ph->Phi()); fhEta->Fill(ph->Eta()); }



If you want to combine information from reconstructed events and the generator (only in case of MC events), you have to access the stack of MC events, recover the original particle (TParticle) with the label stored in the AliAODPWG4Particle object:


AliStack * stack = GetMCStack() ;
TParticle * mom = GetMCStack()->Particle(ph->GetLabel());
//Fill histograms
fh2Pt->Fill(ph->Pt(), mom->Pt());
fh2Phi->Fill(ph->Phi(), mom->Phi()); fh2Eta->Fill(ph->Eta(), mom->Eta()); }



You can also access to the AODCaloCells created before, and fill some histograms, just doing:


Int_t ncells = GetAODCaloCells()->GetNumberOfCells();
fhNCells->Fill(ncells) ;
for (Int_t iCell = 0; iCell
}//calo cells container exist



You can see in the code that I fill AODCaloClusters, AODCaloCells or histograms as a function of the data type, if the data is just generator input I exclude the filling of such objects. To recover the type of data you have just to do: GetReader()->GetDataType().


3.2 Configuration file (rewrite to include AddTask description)

This macro contains a single method that returns a pointer of the CaloTrackCorr manager class: AliAnaCaloTrackCorrMaker* ConfigAnalysis(){...}. Examples of different configuration files can be found in $ALICE_ROOT/PWGGA/CaloTrackCorrelations/macros. We can differenciate three parts: Reader

Here, first we set the acceptance cuts with the common analysis class AliFidutialCut, that we want to apply at the reader level (see Sect. 4.1.1for all setting options). Then we initialize the reader, we set the necessary parameters:


//Init here the XXX reader, XXX=ESD, AOD, MC
AliCaloTrackXXXReader *reader = new AliCaloTrackXXXReader();
//Switch on or off the detectors information that you want
//It will fill the corresponding detector arrays
//Min particle pT
reader->SetFidutialCut(fidCut);//AliFidutialCut pointer
 Analysis algorithms

Here first you initialize the pointers of the common analysis classes (AliCaloPID, AliIsolationCut, AliNeutralMesonSelection, AliFidutialCut, see next sections) that you may need, and then your analysis class:


//First analysis
AliAnaExample *ana = new AliAnaExample();
ana->SetDebug(3); //Print debug information, -1 no print (default).
//Do PID selection with settings defined before
//Do Acceptance selection with settings defined before
ana->SetPdg(AliCaloPID::kPhoton); //plot identified photons
ana->SetDetector("PHOS"); //Detector for the analysis
ana->SetMinPt(2);// Minimum pt of clusters/tracks
ana->SwitchOnDataMC() ; //Access to the stack and fill some histograms with MC information
//AOD branch type and name
ana->SetOutputAODClassName("AliAODPWG4Particle"); //Or AliAODPWG4ParticleCorrelation
//Set Histrograms bins and ranges
ana->SetHistoPtRangeAndNBins(0, 50, 100) ;
ana->SetHistoPhiRangeAndNBins(215*TMath::DegToRad(), 325*TMath::DegToRad(), 100) ;
ana->SetHistoEtaRangeAndNBins(-0.15, 0.15, 100) ;





//Second analysis
AliAnaExample *ana2 = new AliAnaExample();
ana2->SetDebug(3); //Print debug information, -1 no print (default).
//Do PID selection with settings defined before
//Do Acceptance selection with settings defined before
ana2->SetPdg(AliCaloPID::kPhoton); //plot identified photons
ana2->SetDetector("EMCAL"); //Detector for the analysis
ana2->SetMinPt(3);// Minimum pt of clusters/tracks
ana2->SwitchOnDataMC() ; //Access to the stack and fill some histograms with MC information
//AOD branch type and name
ana2->SetOutputAODClassName("AliAODPWG4Particle"); //Or AliAODPWG4ParticleCorrelation
//Set Histrograms bins and ranges
ana2->SetHistoPtRangeAndNBins(0, 50, 100) ;
ana2->SetHistoPhiRangeAndNBins(75*TMath::DegToRad(), 195*TMath::DegToRad(), 100) ;
ana2->SetHistoEtaRangeAndNBins(-0.75, 0.75, 100) ;
 Manager initialization

Finally here, all the analysis previously setted are passed to the manager, and some additional settings are done:


maker = new AliAnaCaloTrackCorrMaker();
maker->SetReader(reader);//pointer to reader
maker->AddAnalysis(ana,0); // Execute first
maker->AddAnalysis(ana2,1); //Execute second
maker->SetAnaDebug(1) ;
maker->SwitchOnAODsMaker() ; //maker->SwitchOffAODsMaker() ;
maker->SwitchOnHistogramsMaker() ; //maker->SwitchOffHistogramsMaker() ;
return maker ;




3.3 Analysis execution macro

In directory $ALICE_ROOT/PWGGA/CaloTrackCorrelations/macros/ you can find the macro ana.C, a quite complete macro that allows to do analysis in different configurations (local, grid, proof), different kinds of data, contains all the options for data handling, defines the outputs (histograms, AODs) and scales your histograms to correct cross sections if requested. In the following lines I will explain the structure of the macro. We can find 5 different parts: analysis libraries loading, data chaining, analysis setting, histogram scaling and analysis execution. At the begining of the macro, we define the different parameter options needed in the macro, when explaining the 5 parts of the macro, I will introduce their meaning. Analysis libraries loading

The analysis can be done with AliRoot or with Root. Since not all the libraries necessary for the analysis are loaded, and certainly not when using Root, the first thing to do is load them. In the main method of the macro we load the necessary libraries via de call to the method LoadLibraries(Int_t mode), that can be found after the main method. There is an input parameter for this method and is the analysis environment: mLocal (in your PC, farm), mLocalCAF (local but with files on the CAF), mPROOF (analysis on CAF), mGrid (local but with files on the grid, or all in the grid). This option is set directly in the main method of the macro ana.C: void ana(Int_t mode=mLocal, TString configName = "ConfigAnalysisESDExample").

First of all we load the obligatory libraries


gSystem->Load(""); gSystem->Load("");
gSystem->Load(""); gSystem->Load("");



Then you have to load the analysis related libraries, that may change because of modifications of the user, or of the AliRoot system, or any other reason. These libraries are: STEERBASE, ESD, AOD, ANALYSIS, ANALYSISALICE, PWGCaloTrackCorrBase and PWGGACaloTrackCorrelations. Other libraries might be needed, if you want to perform an analysis on data produced by other analysis, like jets ( see Sect. 4.6.4). In all the analysis modes, except the mPROOF mode, you have 2 options, either you already have AliRoot in your system and you load them directly:


gSystem->Load("libSTEERBase"); gSystem->Load("libESD"); gSystem->Load("libAOD");
gSystem->Load("libANALYSIS"); gSystem->Load("libANALYSISalice");



Or you call the method void SetUpPar(``LibraryName'') for each of the libraries:


SetupPar("STEERBase"); SetupPar("ESD"); SetupPar("AOD");
SetupPar("ANALYSIS"); SetupPar("ANALYSISalice");



This method is quite clever and is based on the existence of compresed files, ``par'' files (ESD.par, for example), containing the classes of the libraries. These ``par'' files can be created executing in the AliRoot directory the command ``make LibraryName.par'' (make ESD.par, for example, you need writing permission in the aliroot directory for that). The method SetUpPar() works as follows:


  1. If there is no par file in the directory that the analysis macro is executed, it goes to the $ALICE_ROOT directory, and creates for you the par files and copies them to your directory. If you don't have rights to write in the AliRoot directory, this will not be possible.
  2. If the par files are in the analysis execution directory, the method decompresses them and compiles the classes, creating the needed libraries.
  3. If already compiled before, it does nothing, it just loads them.
  4. If you modify locally one of your analysis classes, it will be compiled when executed the analysis macro.

Some analysis require the PHOS geometry. In this case you have to put here the following lines:


//Create Geometry, need file "geometry.root" in local dir!
TGeoManager::Import("geometry.root") ;



You must have created the PHOSUtils.par and the geometry.root file in order to be able to work.

In case of analysis performed on CAF the way to proceed is different, in the macro you can see how to proceed, but it might be obsolete, we need to check if this is still valid. Data chaining

The analysis frame expects that we pass a TChain with the list of AliESDs.root or or AODs or galice.root files(for MC analysis but MC analysis also works with chains of ESDs, the frame looks for the galice.root and Kinematics.root in the same location as the ESDs file). The chain of data is done just before the load of the libraries via the method CreateChain:


TChain *chain = new TChain("esdTree") ;
TChain * chainxs = new TChain("Xsection") ;
CreateChain(mode, chain, chainxs);



We create 2 chains, one with the data and other with the cross sections in case of MC data, used for histogram scaling as explained later. The chaining method needs as input also the analysis mode: mLocal:

In this case we consider all data files are placed in a directory kInDir, in subdirectories kPattern+N where N is a number going from 0 to kEvent. There variables can be passed to the macro with linux environmental variables, just defining with ``setenv'' or ``export'' the variables INDIR, PATTERN and NEVENT, respectively. In case none of these variables is set, by default the method will add to the chain an AliESDs.root file that should be in the same place as the analysis is being done. mGrid:

In case that we want to analyze data sitting on the grid we have to play with ``xml'' files. An xml is a file format that contains the collection of files to be analyzed and is readable by the analysis frame. The way to produce one of these files is in aliensh, typing the following:

find -x Name_Of_Collection /address/of/data/ DataFile > collection.xml


find -x CollectionTest /alice/sim/PDC_08/LHC08v/280040/ AliESDs.root > col.xml

the file col.xml is created in your local directory where you executed aliensh.

We pass to the macro the name of the collection xml file setting in your linux environment the variable XML Analysis setting

Here first, we initialize the analysis manager, set the type of input/output data we want to analyze. If we want to work with MC data we have to set the variable kMC to kTRUE. The input data can be ESD or AOD, and this is specified in the variable kInputData=''ESD'' or ``AOD''.


AliAnalysisManager *mgr = new AliAnalysisManager("Manager", "Manager");
if(kMC){ // MC handler
AliMCEventHandler* mcHandler = new AliMCEventHandler();
mcHandler->SetReadTR(kFALSE);//Do not search TrackRef file
mgr->SetMCtruthEventHandler(mcHandler); }
// AOD output handler
AliAODHandler* aodoutHandler = new AliAODHandler();
if(kInputData == "ESD"){ // ESD handler
AliESDInputHandler *esdHandler = new AliESDInputHandler();
mgr->SetInputEventHandler(esdHandler); }
if(kInputData == "AOD"){ // AOD handler
AliAODInputHandler *aodHandler = new AliAODInputHandler();
mgr->SetInputEventHandler(aodHandler); }
//mgr->SetDebugLevel(-1); // For debugging, do not uncomment if you want no messages.



After, comes the analysis task initialization and the input/output containers definition:


AliAnalysisTaskParticleCorrelation * task = new AliAnalysisTaskParticleCorrelation ("Particle");
task->SetConfigFileName(configName); //Default name is ConfigAnalysis
mgr->AddTask(taskpwg4); // Create containers for input/output
AliAnalysisDataContainer *cinput1 =
mgr->CreateContainer("cchain",TChain::Class(), AliAnalysisManager::kInputContainer);
AliAnalysisDataContainer *coutput1 =
mgr->CreateContainer("tree", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
AliAnalysisDataContainer *coutput2 =
mgr->CreateContainer("histos", TList::Class(), AliAnalysisManager::kOutputContainer, "histos.root");
mgr->ConnectInput (task, 0, cinput1);
mgr->ConnectOutput (task, 0, coutput1 ); mgr->ConnectOutput (task, 1, coutput2 );

In case of analysis of simulations, we may want to scale our results to the cross section given by the generator. The class AliAnaScale scales the output histograms of your analysis but the corresponding cross section. If you want this option to be executed you have to set kGetXSectionFromFileAndScale=kTRUE and you have to give the name of the file with the cross section, kXSFileName, which should be placed in the same place as the ESD.


Int_t nfiles = chainxs->GetEntries();
if(kGetXSectionFromFileAndScale && nfiles > 0){
//Get the cross section
Double_t xsection=0; Float_t ntrials = 0;
//Calculates average cross section of all events analyzed
GetAverageXsection(chainxs, xsection, ntrials);
AliAnaScale * scale = new AliAnaScale("scale") ;
scale->Set(xsection/ntrials/kNumberOfEventsPerFile/nfiles) ; // Set normalization scale
scale->MakeSumw2(kFALSE); // Root calculates the statistical errors?
//Set previous task histograms as input and produce new normalized histograms.
AliAnalysisDataContainer *coutput3 =
mgr->CreateContainer("histosscaled", TList::Class(),
AliAnalysisManager::kOutputContainer, "histosscaled.root");
mgr->ConnectInput (scale, 0, coutput2);
mgr->ConnectOutput (scale, 0, coutput3 ); }
 Anaysis execution

In the end, with the analysis manager already filled with all the necessary tasks, data chains and execution mode, it is executed:


TString smode = "";
if (mode==mLocal || mode == mLocalCAF) smode = "local";
else if (mode==mPROOF) smode = "proof";
else if (mode==mGRID) smode = "grid";





4 Analysis available

In this section, I list the analysis available in the CaloTrackCorr package and explain how they work.


4.1 Common analysis helper classes

In AliAnaCaloTrackCorrBase you can find pieces of analysis in different classes that can be used by any analysis dependent on the frame.


4.1.1 AliFidutialCut

Class for selection of the analysis objects (CaloClusters, Tracks, AliAODPWG4Particle(Correlation), ...) as a function of eta (pseudorapidity)-phi (azimuthal angle) cuts. The cuts are done separately for PHOS, EMCAL and CTS (tracks). N regions in each of these detectors can be defined. For each detector a an array of cuts is defined, this array has de size of the regions under consideration:


Bool_t fXXXFidutialCut ;//Apply fidutial cuts to XXX (=CTS,EMCAL,PHOS)
TArrayF * fXXXFidCutMinEta ; //Take particles in XXX with eta > fXXXFidCutMinEta
TArrayF * fXXXFidCutMinPhi ; //Take particles in XXX with phi > fXXXFidCutMinPhi
TArrayF * fXXXFidCutMaxEta ; //Take particles in XXX with eta
TArrayF * fXXXFidCutMaxPhi ; //Take particles in XXX with phi > fXXXFidCutMaxPhi



The cuts are applied only if we request it via the method DoXXXFidutialCut(Bool_t b), by default no cut is applied. To fill the arrays the corresponding method is defined:


void AddXXXFidCutMaxEtaArray(TArrayF & array)
TArrayF * GetXXXFidCutMaxEtaArray()
void AddXXXFidCutMaxPhiArray(TArrayF & array)
TArrayF * GetXXXFidCutMaxPhiArray()
void AddXXXFidCutMinEtaArray(TArrayF & array)
TArrayF * GetXXXFidCutMinEtaArray()
void AddXXXFidCutMinPhiArray(TArrayF & array)
TArrayF * GetXXXFidCutMinPhiArray()



If you just want a simple selection in one region, you can do that via the method SetSimpleCTSFidutialCut(const Float_t abseta, const Float_t phimin, const Float_t phimax) ;

An example on how to define the cuts in the analysis configuration file:


AliFidutialCut * fidCut = new AliFidutialCut();
fidCut->DoCTSFidutialCut(kFALSE) ; //Accept all tracks
fidCut->DoEMCALFidutialCut(kTRUE) ;
fidCut->DoPHOSFidutialCut(kTRUE) ;
//PHOS, one region
//EMCAL,5 regions
Float_t etamax[]={0.67,0.51,0.16,-0.21,-0.61};
TArrayF etamaxarr(5,etamax);
Float_t etamin[]={0.61,0.21,-0.16,-0.51,-0.67};
TArrayF etaminarr(5,etamin);
Float_t phimax[]={99.*TMath::DegToRad(), 119.*TMath::DegToRad(),
139.*TMath::DegToRad(), 159.*TMath::DegToRad(), 179.*TMath::DegToRad(), 189.*TMath::DegToRad()};
TArrayF phimaxarr(6,phimax);
Float_t phimin[]={81.*TMath::DegToRad(), 101.*TMath::DegToRad(),
121.*TMath::DegToRad(), 141.*TMath::DegToRad(), 161.*TMath::DegToRad(), 181.*TMath::DegToRad()};
TArrayF phiminarr(6,phimin);




AliCaloTrackReader *reader = new AliCaloTrackESDReader();
//Other angular cuts in the analysis class
AliFidutialCut * fidCut2 = new AliFidutialCut();
AliAnaPhoton *ana = new AliAnaPhoton();



In the analysis, the way to know if your particle/cluster/track is in the acceptance is doing: Bool_t accepted = GetFidutialCut()->IsInFidutialCut(TLorentzVector mom, TString fDetector) ;


4.1.2 AliCaloPID

Class for particle identification in the calorimeters. The main methods are:


  • Int_t GetPdg(const TString calo, const Double_t * pid, const Float_t energy) : returns the most probable identity of the particle: kPhoton, kPhotonConv, kPi0, kEta, kElectron, kEleCon, kNeutralHadron, kChargedHadron, kNeutralUnknown, kChargedUnknown. This method works with the bayesian probability weights stored in the CaloClusters. Depending on the values of the PID weights and probability selection cuts defined in data members:


Float_t fEMCALPhotonWeight; //Bayesian PID weight for photons in EMCAL
Float_t fEMCALPi0Weight; //Bayesian PID weight for pi0 in EMCAL
Float_t fEMCALElectronWeight; //Bayesian PID weight for electrons in EMCAL
Float_t fEMCALChargeWeight; //Bayesian PID weight for charged hadrons in EMCAL
Float_t fEMCALNeutralWeight; //Bayesian PID weight for neutral hadrons in EMCAL
Float_t fPHOSPhotonWeight; //Bayesian PID weight for photons in PHOS
Float_t fPHOSPi0Weight; //Bayesian PID weight for pi0 in PHOS
Float_t fPHOSElectronWeight; //Bayesian PID weight for electrons in PHOS
Float_t fPHOSChargeWeight; //Bayesian PID weight for charged hadrons in PHOS
Float_t fPHOSNeutralWeight; //Bayesian PID weight for neutral hadrons in PHOS



it will return the particle type. The weight cuts data members have their corresponding setters, SetEMCALPhotonWeight(Float_t w) for example. In the case of PHOS, a more refined selection can be done to separate photons and overlapped pi0:


void UsePHOSPIDWeightFormula(Bool_t par) { fPHOSWeightFormula = par; }
void SetPHOSPhotonWeightFormula(TFormula * photon) { fPHOSPhotonWeightFormula = photon; }
void SetPHOSPi0WeightFormula(TFormula * pi0) { fPHOSPi0WeightFormula = pi0; }
Bool_t fPHOSWeightFormula ; //Use parametrized weight threshold, function of energy
TFormula * fPHOSPhotonWeightFormula ; //Formula for photon weight
TFormula * fPHOSPi0WeightFormula ; //Formula for pi0 weight




  • Int_t GetPdg(const TString calo,const TLorentzVector mom, const AliAODCaloCluster * cluster) : As the previous method, this one is intended to return the most probable particle type. Since the bayesian approach will not work for the first years, this place is intended to be filled with any identification code necessary. Right now just a simple case for EMCAL photon/pi0 separation.
  • void SetPIDBits(const TString calo, const AliAODCaloCluster * cluster, AliAODPWG4Particle *aodph) : Method that sets some PID bits depending on the cuts defined. The PID bits are the ones defined in AliAODPWG4Particle (see Sect. 2.5): dispersion, TOF and charge. The charge bit is set if there is no match between the CaloCluster and the tracks. The dispersion and TOD bits are set if their values are smaller than the cuts defined in the data members:


void SetDispersionCut(Float_t dcut )
Float_t GetDispersionCut()
void SetTOFCut(Float_t tcut )
Float_t GetTOFCut()
Float_t fDispCut; //Cut on dispersion, used in PID evaluation
Float_t fTOFCut; //Cut on TOF, used in PID evaluation




  • Int_t CheckOrigin(const Int_t label, AliStack * stack) const : Method that looks in the kinematic stack the origin of the particles and tags them depending on their mother: kMCPrompt (prompt photon), kMCFragmentation (fragmentation photon), kMCPi0Decay (pi0 decay photon), kMCEtaDecay (eta decay photon), kMCOtherDecay (photon decay, not from eta or pi0), kMCPi0 , kMCEta , kMCElectron, kMCConversion, kMCHadron, kMCUnknown. Needs to be completed.

An example on how to set it in the configuration analysis file :


AliCaloPID * pid = new AliCaloPID();
// use selection with simple weights
//use more complicated selection, particle weight depending on cluster energy
TFormula*photonF = newTFormula("photonWeight",
TFormula * pi0F = new TFormula("pi0Weight",
AliAnaPhoton *ana = new AliAnaPhoton();




4.1.3 AliNeutralMesonSelection

Class for pair selection depending on their aperture angle and invariant mass. The main data members cuts for the selection and their setters and getters are:


Double_t GetAngleMaxParam(Int_t i)
void SetAngleMaxParam(Int_t i, Double_t par)
Double_t GetInvMassMaxCut()
Double_t GetInvMassMinCut()
void SetInvMassCutRange(Double_t invmassmin, Double_t invmassmax)
Double_t GetMass()
void SetMass(Double_t m)
Double_t fM ; //mass of the neutral meson, default pi0
Double_t fInvMassMaxCut ; // Invariant Mass cut maximum
Double_t fInvMassMinCut ; // Invariant Masscut minimun
TArrayD fAngleMaxParam ; //Maximum opening angle selection parameters



In the user analysis class you have to call the method Bool_t selected = GetNeutralMesonSelection()->SelectPair(TLorentzVector gammai, TLorentzVector gammaj). This method just finds if the 2 particles/clusters have an aperture angle inside a certain angular window, decided in method Bool_t IsAngleInWindow(Float_t angle, Float_t energy) , and if their invariant mass is in the appropriate mass window. The angular window is set but the formulas (see internal note ... for details) :


Double_t maxangle=fAngleMaxParam.At(0)*TMath::Exp(fAngleMaxParam.At(1)*e)+
Double_t arg = (e*e-2*fM*fM)/(e*e);
Double_t minangle = 100. ; if(arg>0.) minangle = TMath::ACos(arg);



This aperture selection has to be revisited.

This class produces also histograms, if it is requested via de method void KeepNeutralMesonSelectionHistos(Bool_t keep). The histograms are the invariant mass or aperture angle of the pairs without cuts, after the aperture window cut, and after the invariant mass cut:


TH2F * fhAnglePairNoCut ; //Aperture angle of decay photons, no cuts
TH2F * fhAnglePairOpeningAngleCut ; //Aperture angle of decay photons, cut on opening angle
TH2F * fhAnglePairAllCut ; //Aperture angle of decay photons, all cuts
TH2F * fhInvMassPairNoCut ; //Invariant mass of decay photons, no cuts
TH2F * fhInvMassPairOpeningAngleCut ; //Invariant mass of decay photons, cut on opening angle
TH2F * fhInvMassPairAllCut ; //Invariant mass of decay photons, all cuts



Like in AliAnaParCorrBaseClass (see Sect. 2.4), different setters and getters for the binning and ranges of the histograms have been defined.

In the configuration analysis file you have just to put:


AliNeutralMesonSelection *nms = new AliNeutralMesonSelection();
nms->SetInvMassCutRange(0.10, 0.17) ;
AliAnaPi0EbE *anapi0 = new AliAnaPi0EbE();




4.1.4 AliIsolationCut

Class for particle isolation. For the moment, 4 different types of isolation: in a cone of size around the candidate, it is isolated if:


  1. kPtThresIC: No particle with fPtThreshold inside cone
  2. kSumPtIC: The sum of the particles inside the cone fPtThreshold
  3. kPtFrac: No particle with fPtFraction inside cone.
  4. kSumPtFrac: The sum of the particles inside the cone divided by the of the candidate fPtThreshold

The main data members and it setters are:


void SetConeSize(Float_t r)
void SetPtThreshold(Float_t pt)
void SetPtFraction(Float_t pt)
void SetICMethod(Int_t i )
Float_t fConeSize ; //Size of the isolation cone
Float_t fPtThreshold ; //Minimum pt of the particles in the cone or sum in cone
Float_t fPtFraction ; //Fraction of the momentum of particles in cone or sum in cone
Int_t fICMethod ; //Isolation cut method to be used



The method that performs de analysis is void MakeIsolationCut(TSeqCollection * plCTS, TSeqCollection * plNe, Double_t * vertex, const Bool_t fillAOD, AliAODPWG4ParticleCorrelation *pCandidate, Int_t & n, Int_t & nfrac, Float_t &coneptsum, Bool_t &isolated) and returns if it is isolated (for all 4 criteria), the sum of particles in cone and the number of particles in cone passing the selections on the threshold and fraction. The way to access this method in the analysis is via GetIsolationCut()->MakeIsolationCut(...).

An example on how to initialize it in the configuration analysis macro is:


AliIsolationCut * ic = new AliIsolationCut();
ic->SetConeSize(0.5); ic->SetPtThreshold(1.);
AliAnaParticleIsolation *anaisol = new AliAnaParticleIsolation();




4.2 AliAnaPhoton

Class for photon identification and selection. The input of this class are CaloClusters of PHOS or EMCAL, the calorimeter has to be specified in the method SetCalorimeter(TString det). Other parameters that have to be set in this analysis are the window of the photons, the distance to bad channels cuts and the acceptance cut with AliFidutialCut. The output are histograms and AODs containing AliAODPWG4Particle objects created from the selected CaloClusters. It is important that the method SetOutputAODName(TString name) is called in the configuration analysis file or the constructor of the class, if not the branch will not be created. Also, you have to specify the type of AOD objects AliAODPWG4Particle or AliAODPWG4ParticleCorrelation, by default it is AliAODPWG4Particle. You have to select one type or the other depending on the type of objects read or modified in the analysis class that takes the output AOD of AliAnaPhoton as input (for example AliAnaPi0 needs AliAODPWG4Particle and AliAnaParticle* need AliAODPWG4ParticleCorrelation).

The algorithm in the main method MakeAnalysisFillAOD() works as follows: Select the list of CaloClusters PHOS or EMCAL, loop on the list of CaloClusters and for each of them:


  1. Get the momentum vector and check if the CaloCluster is in the desired window and angular acceptance (with AliFidutialCut, see Sect. 4.1.1),
  2. If the cluster is in a user time window (noisy channels can be out), then it is accepted. The way to set the window is via SetTimeCut(Double_t min, Double_t max), values set in ns.
  3. Accept  CaloClusters containing more than N CaloCells. The way to set this number is via SetNCaloCell(Int_t n).
  4. Create the AliAODPWG4Particle object with the momentum vector, and add to it the MonteCarlo label, the CaloCluster label and calorimeter it was found (see Sect. 2.5).
  5. Check if the CaloCluster is too close to a bad channel, in which case it is rejected. If not so close, fill the DistToBad channel entry depending on the cuts set.
  6. Check PID. If in the analysis configuration file we set SwitchOnCaloPID(), then we get the PDG value for the CaloCluster calculated with bayesian probabilities with AliCaloPID, if besides the method SwitchOnCaloPIDRecalculation() is set in the configuration file, the PDG is calculted by other methods (see Sect. 4.1.2). If PDG is the one of the photon then the object is accepted. If we set in the analysis configuration file SwitchOnCaloPID(), then we fill the PID bits (see Sect. 2.5and 4.1.2), no selection is done.
  7. Remove pair of CaloClusters with low mass and add the sum to the list of photons. This option is off by default, to use it you have to set SwitchOnConversionChecker(), and set the mass window with SetMassCut(Float_t mass) (window is 0 to mass). If we want to add the pair to the photons AOD then SwitchOnAdditionConvertedPairsToAOD().
  8. Check origin of the CaloCluster in MonteCarlo. This is only done if in the analysis configuration file we request SwitchOnDataMC().
  9. Add the AliAODPWG4Particle object to the AOD output list.

In MakeAnalysisFillHistograms(), the AOD list filled in MakeAnalysisFillAOD() is read. And the following histograms are filled:


TH1F * fhPtPhoton ; //! Number of identified photon vs transerse momentum
TH2F * fhPhiPhoton ; //! Azimuthal angle of identified photon vs transerse momentum
TH2F * fhEtaPhoton ; //! Pseudorapidity of identified photon vs transerse momentum



In case we access the kinematics stack (SwitchOnDataMC() ) few more histograms are filled. The same 3 by default times the number of possible cluster origin cases (prompt, fragmentation, decay or hadron).

In the analysis configuration file we have to put for example (see PWGGA/CaloTrackCorrelations/macros/AddTaskIsoPhoton.C):


AliAnaPhoton *anaph = new AliAnaPhoton();
anaph->SetMinDistanceToBadChannel(2, 4, 5);
anaph->SetCaloPID(pid); ana->SetFidutialCut(fidCut2);
anaph->SwitchOnDataMC() ;//Access MC stack and fill more histograms
anaph->SwitchOffCaloPIDRecalculation(); //recommended for EMCAL ana->SwitchOffFidutialCut();
//Set Histrograms bins and ranges
anaph->SetHistoPtRangeAndNBins(0, 50, 100) ;
anaph->SetHistoPhiRangeAndNBins(0, TMath::TwoPi(), 100) ;
anaph->SetHistoEtaRangeAndNBins(-0.7, 0.7, 100) ;




4.3 AliAnaPi0

Class for pi0 invariant mass studies. The input are photons produced in AliAnaPhoton. The type of the AOD objects of the photons must be AliAODPWG4Particle. The input AOD branch name is set in the configuration file with SetInputAODName(TString name), make sure that the output branch name of AliAnaPhoton and the input AOD branch name of AliAnaPi0 are the same.

The main method of this class is MakeAnalysisFillHistograms() since no AOD is filled in this class. What is done here very schematically is: loop on the photons list and combine with all the possible photon pairs, getting the invariant mass and filling histograms depending on the PID bit possible combinations (AliAODPWG4Particle::IsPIDOK(Int_t ibit, Int_t pdg)). Each PID bit combination fills a different invariant mass histogram. The number of PID combinations is set in the data member Int_t fNPID and set with the method SetNPID(). Also, the histograms depend on the distance to bad channels set in the AOD. For each event, the photons are kept in a pool, the number of events in the pool is defined in the data member Int_t fNmaxMixEv set with the method SetNMaxEvMix(). The pool is also filled depending on the centrality of the collision and reaction plane,


Int_t fNCentrBin ; //number of bins in event container for centrality
Int_t fNZvertBin ; //number of bins in event container for vertex position
Int_t fNrpBin ; //number of bins in event container for reaction plain



but we do not know still how to access such values so right now they are set to 0. Once the pool is filled, combinations between photons in the first loop event and photons in the pool is preformed, in order to reproduce the background in the pi0 peak. Other set of histograms are filled for this mixed pairs for different events. The histograms are:


//Invariant mass histograms, number indicates distance to bad channel.
TH3D ** fhRe1 ; //!REAL two-photon invariant mass distribution for different centralities and PID
TH3D ** fhMi1 ; //!MIXED two-photon invariant mass distribution for different centralities and PID
TH3D ** fhRe2 ; //!REAL two-photon invariant mass distribution for different centralities and PID
TH3D ** fhMi2 ; //!MIXED two-photon invariant mass distribution for different centralities and PID
TH3D ** fhRe3 ; //!REAL two-photon invariant mass distribution for different centralities and PID
TH3D ** fhMi3 ; //!MIXED two-photon invariant mass distribution for different centralities and PID



After the invariant mass filling, ifwe are working with simulated data (SwitchOnDataMC()), an study of the acceptance of the 2 photon pairs from the pi0 in the calorimeter is done. You have to select the calorimeter under study (SetCalorimeter(TString name)). There is a loop in the kinematic stack looking for pi0, and then their photon daughters. If the photons fall in the calorimeter acceptance, then few more histograms are filled:


TH1D * fhPrimPt ; //! Spectrum of Primary pi0
TH1D * fhPrimAccPt ; //! Spectrum of primary with accepted daughters
TH1D * fhPrimY ; //! Rapidity distribution of primary pi0
TH1D * fhPrimAccY ; //! Rapidity distribution of primary with accepted daughters
TH1D * fhPrimPhi ; //! Azimutal distribution of primary pi0
TH1D * fhPrimAccPhi; //! Azimutal distribution of primary with accepted daughters



The geometrical acceptance selection can be done with the help of AliFidutialCut, so you set by hand in the analysis configuration file the size of the detector. In the case of PHOS, it is possible to acces the real detector geometry. For this reason we define and initialize the PHOS geometry data member AliPHOSGeoUtils * fPHOSGeo. PHOS geometry is only taken into account if the library with the geometry is loaded. To load the PHOS real geometry see in Sect. 3.3 what has to be done in ana.C.

An example on how to configure this analysis (see PWGGA/CaloTrackCorrelations/macros/AddTaskPi0.C):


AliAnaPi0 *anapi0 = new AliAnaPi0(); anapi0->SetDebug(-1);//10 for lots of messages
anapi0->SetNCentrBin(5); //number of bins in centrality
anapi0->SetNZvertBin(5); //number of bins for vertex position
anapi0->SetNRPBin(6); //number of bins in reaction plain
anapi0->SetNMaxEvMix(20);//Maximal number of events for mixing
anapi0->SetFidutialCut(fidCut2); //More acceptance selections if needed at this level.
//AliFidutialCut Not used if real geometry
anapi0->SwitchOnDataMC() ;//Access MC stack and fill more histograms
anapi0->SetInputAODName("Photons"); anapi0->Print("");




4.4 AliAnaPi0EbE

Class for pi0 identification event by event. Three types of analysis


  1. kIMCalo: Search 2 photons selected in AliAnaPhoton, select it as pi0 with AliNeutralMesonSelection
  2. kIMCaloConv: Combine photons selected in AliAnaPhoton and photons reconstructed with the GammaConv package
  3. kSS: Identify pi0 with shower shape analysis.



4.5 AliAnaParticleIsolation

Given an input aod with photons from AliAnaPhoton, pi0 from AliAnaPi0EbE or any other input particle, study its isolation via de class AliIsolationCut TO BE COMPLETED


4.6 Correlation Classes


4.6.1 AliAnaParticlePartonCorrelation

Given an input aod with photons from AliAnaPhoton, pi0 from AliAnaPi0EbE or any other input particle, isolated or not, study its correlation with partons, only with simulations. TO BE COMPLETED


4.6.2 AliAnaParticleHadronCorrelation

Given an input aod with photons from AliAnaPhoton, pi0 from AliAnaPi0EbE or any other input particle, isolated or not, study its correlation with hadrons (tracks or clusters) in the opposite side. TO BE COMPLETED


4.6.3 AliAnaParticleJetLeadingConeCorrelation

Given an input aod with photons from AliAnaPhoton, pi0 from AliAnaPi0EbE or any other input particle, isolated or not, study its correlation with jets reconstructed in this class. TO BE COMPLETED


4.6.4 AliAnaParticleJetFinderCorrelation

Given an input aod with photons from AliAnaPhoton, pi0 from AliAnaPi0EbE or any other input particle, isolated or not, study its correlation with jets reconstructed with JETAN package. TO BE COMPLETED SOON