new module for hadron correlations
authorgconesab <gconesab@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 20 Jan 2010 10:57:42 +0000 (10:57 +0000)
committergconesab <gconesab@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 20 Jan 2010 10:57:42 +0000 (10:57 +0000)
31 files changed:
PWG4/JetCorrel/AliAnalysisTaskJetCorrel.cxx [new file with mode: 0644]
PWG4/JetCorrel/AliAnalysisTaskJetCorrel.h [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelMaker.cxx [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelMaker.h [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelMixer.cxx [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelMixer.h [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelReader.cxx [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelReader.h [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelSelector.cxx [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelSelector.h [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelWriter.cxx [new file with mode: 0644]
PWG4/JetCorrel/AliJetCorrelWriter.h [new file with mode: 0644]
PWG4/JetCorrel/CorrelDefs.h [new file with mode: 0644]
PWG4/JetCorrel/CorrelKFTrack.cxx [new file with mode: 0644]
PWG4/JetCorrel/CorrelKFTrack.h [new file with mode: 0644]
PWG4/JetCorrel/CorrelList.cxx [new file with mode: 0644]
PWG4/JetCorrel/CorrelList.h [new file with mode: 0644]
PWG4/JetCorrel/CorrelParticle.cxx [new file with mode: 0644]
PWG4/JetCorrel/CorrelParticle.h [new file with mode: 0644]
PWG4/JetCorrel/CorrelRecoParent.cxx [new file with mode: 0644]
PWG4/JetCorrel/CorrelRecoParent.h [new file with mode: 0644]
PWG4/JetCorrel/CorrelTrack.cxx [new file with mode: 0644]
PWG4/JetCorrel/CorrelTrack.h [new file with mode: 0644]
PWG4/JetCorrel/README [new file with mode: 0644]
PWG4/Makefile
PWG4/PROOF-INF.PWG4JetCorrel/BUILD.sh [new file with mode: 0755]
PWG4/PROOF-INF.PWG4JetCorrel/SETUP.C [new file with mode: 0644]
PWG4/PWG4JetCorrelLinkDef.h [new file with mode: 0644]
PWG4/libPWG4JetCorrel.pkg [new file with mode: 0644]
PWG4/macros/AddTaskJetCorrel.C [new file with mode: 0644]
PWG4/macros/ConfigJetCorrel.C [new file with mode: 0644]

diff --git a/PWG4/JetCorrel/AliAnalysisTaskJetCorrel.cxx b/PWG4/JetCorrel/AliAnalysisTaskJetCorrel.cxx
new file mode 100644 (file)
index 0000000..c2d4d38
--- /dev/null
@@ -0,0 +1,154 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//__________________________________________
+// Main class for two-particle correlations.
+// Calls AliJetCorrelSelector and AliJetCorrelMaker for setup, then
+// AliJetCorrelReader for ESD/AOD input reading into CorrelList_t lists, then
+// AliJetCorrelMixer for event mixing and AliJetCorrelWriter for output histos
+//-- Author: Paul Constantin
+
+#include "AliAnalysisTaskJetCorrel.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+ClassImp(AliAnalysisTaskJetCorrel)
+
+AliAnalysisTaskJetCorrel::AliAnalysisTaskJetCorrel(AliJetCorrelSelector *s) : 
+  AliAnalysisTaskSE("JetCorrelTask"), fOutputContainer(new TList),
+  fSelector(s), fNumCorrel(0), fNumTrigg(0), fNumAssoc(0), fNumEvts(0),
+  fMaker(new AliJetCorrelMaker), fWriter(new AliJetCorrelWriter), fReader(new AliJetCorrelReader),
+  fMixer(new AliJetCorrelMixer), fTriggList(NULL), fAssocList(NULL) {
+  // constructor
+
+  fNumCorrel = fSelector->NoOfCorrel();
+  if(!fMaker->Init(fNumCorrel,fSelector->CorrelTypes()))
+    {std::cerr<<"AliJetCorrelMaker initialization failed. Bye!"<<std::endl; exit(-1);}
+  fNumTrigg  = fMaker->NoOfTrigg();
+  fNumAssoc  = fMaker->NoOfAssoc();
+//  fMaker->Show();
+
+  fWriter->Init(fSelector,fMaker);
+  fReader->Init(fSelector,fWriter);
+  fMixer->Init(fSelector,fMaker,fWriter);
+
+  fTriggList = new CorrelList_t[fNumTrigg];
+  fAssocList = new CorrelList_t[fNumAssoc];
+
+  DefineInput(0, TChain::Class());
+  DefineOutput(1, TList::Class());
+}
+
+AliAnalysisTaskJetCorrel::~AliAnalysisTaskJetCorrel(){
+  // destructor
+  if(fTriggList) {delete [] fTriggList;}
+  if(fAssocList) {delete [] fAssocList;}
+  if(fOutputContainer) {fOutputContainer->Clear(); delete fOutputContainer;}
+  if(fMaker) delete fMaker;
+  if(fReader) delete fReader;
+  if(fWriter) delete fWriter;
+  if(fMixer) delete fMixer;
+  fNumEvts=0;
+}
+
+void AliAnalysisTaskJetCorrel::UserCreateOutputObjects(){  
+  // call writer object methods for histogram booking inside the output container list
+  //  OpenFile(1);
+  fOutputContainer->SetName("JetCorrelHistos");
+  fWriter->CreateGeneric(fOutputContainer);
+  if(fSelector->GenQA()) fWriter->CreateQA(fOutputContainer);
+  fWriter->CreateCorrelations(fOutputContainer);
+}
+
+void AliAnalysisTaskJetCorrel::UserExec(Option_t */*option*/){
+  // get the event and pass it to the data reader object
+  AliVEvent *fEVT = (AliVEvent*)InputEvent();
+  if(!fEVT){
+    std::cerr<<"AliAnalysisTaskJetCorrel::UserExec() - ERROR: Cannot get event #"<<fNumEvts<<std::endl;
+    exit(-1);
+  }
+  fReader->SetEvent(fEVT);
+
+  // get global event pars and apply global cuts
+  Float_t cent = fReader->GetMultiplicity(); // use multiplicity in p-p
+  Float_t zvtx = fReader->GetVertex();
+  Int_t cBin = fSelector->GetBin(centr,cent);
+  Int_t vBin = fSelector->GetBin(zvert,zvtx);
+  if(cBin<0 || vBin<0) return; // event fails centrality or vertex selection
+  fWriter->FillGlobal(cent,zvtx);
+  fNumEvts++;
+  //  std::cout<<"Event:"<<fNumEvts<<" cBin="<<cBin<<" vBin="<<vBin<<std::endl;
+
+  // loop over correlations
+  for(UInt_t iCor=0; iCor<fNumCorrel; iCor++){
+    UInt_t idxTrigg = fMaker->IdxTrigg(iCor);
+    UInt_t idxAssoc = fMaker->IdxAssoc(iCor);
+    Bool_t tFilled = fTriggList[idxTrigg].Filled();
+    Bool_t aFilled = fAssocList[idxAssoc].Filled();
+
+    fTriggList[idxTrigg].Label(fMaker->TriggType(iCor),triggs,fNumEvts);
+    fAssocList[idxAssoc].Label(fMaker->AssocType(iCor),assocs,fNumEvts);
+    fReader->FillLists(&fTriggList[idxTrigg],&fAssocList[idxAssoc]);
+
+    UInt_t nTriggs = fTriggList[idxTrigg].Size();
+    UInt_t nAssocs = fAssocList[idxAssoc].Size();    
+//     std::cout<<" Correl:"<<fMaker->Descriptor(iCor)<<"("<<idxTrigg<<"/"<<idxAssoc<<")"
+//          <<" triggs:"<<nTriggs<<" assocs:"<<nAssocs<<std::endl;
+
+    if(nTriggs<1 && nAssocs<1) continue;
+    if(!tFilled) fWriter->FillSingleHistos(&fTriggList[idxTrigg], cBin, idxTrigg);
+    
+    CrossCorrelate(&fTriggList[idxTrigg], &fAssocList[idxAssoc], cBin, vBin, iCor); // same-event correlation
+    
+    if(!tFilled) fMixer->FillPool(&fTriggList[idxTrigg], idxTrigg, vBin, cBin);
+    if(!aFilled) fMixer->FillPool(&fAssocList[idxAssoc], idxAssoc, vBin, cBin);
+    if(nTriggs>0) fMixer->Mix(vBin, cBin, idxTrigg, idxAssoc, iCor);
+    
+    PostData(1, fOutputContainer);
+  } // loop over correlations
+
+  // clear the lists
+  for(UInt_t it=0; it<fNumTrigg; it++) fTriggList[it].Reset();
+  for(UInt_t ia=0; ia<fNumAssoc; ia++) fAssocList[ia].Reset();
+}
+
+void AliAnalysisTaskJetCorrel::Terminate(Option_t */*option*/){
+  // clean pools, print stats
+  fMixer->CleanPool(triggs);
+  fMixer->CleanPool(assocs);
+//   std::cout<<"CorrelParticle="<<sizeof(CorrelParticle_t)
+//        <<" CorrelTrack="<<sizeof(CorrelTrack_t)
+//        <<" CorrelRecoParent="<<sizeof(CorrelRecoParent_t)<<std::endl;
+//   fWriter->ShowStats();
+}
+
+void AliAnalysisTaskJetCorrel::CrossCorrelate(CorrelList_t * const TriggList, CorrelList_t * const AssocList,
+                                             UInt_t cBin, UInt_t vBin, UInt_t iCor){
+  // do the same event histogram filling
+  if(TriggList->Size()<1 || AssocList->Size()<1) return;
+  CorrelListIter_t iterTrigg = TriggList->Head();
+  CorrelListIter_t iterAssoc = AssocList->Head();
+  while(!iterTrigg.HasEnded()){
+    while(!iterAssoc.HasEnded()){
+      fWriter->FillCorrelations(real,iCor,cBin,vBin,iterTrigg.Data(),iterAssoc.Data()); // trigg first!
+      iterAssoc.Move();
+    }
+    iterAssoc = AssocList->Head(); // reset associated particle iterator to list head
+    iterTrigg.Move();
+  }
+  iterTrigg = TriggList->Head(); // reset trigger particle iterator to list head
+}
diff --git a/PWG4/JetCorrel/AliAnalysisTaskJetCorrel.h b/PWG4/JetCorrel/AliAnalysisTaskJetCorrel.h
new file mode 100644 (file)
index 0000000..b69c859
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __ALIANALYSISTASKJETCORREL_H__
+#define __ALIANALYSISTASKJETCORREL_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//__________________________________________
+// Main class for two-particle correlations.
+// Calls AliJetCorrelSelector and AliJetCorrelMaker for setup, then
+// AliJetCorrelReader for ESD/AOD input reading into CorrelList_t lists, then
+// AliJetCorrelMixer for event mixing and AliJetCorrelWriter for output histos
+//-- Author: Paul Constantin
+
+#include "AliJetCorrelMaker.h"
+#include "AliJetCorrelSelector.h"
+#include "AliJetCorrelReader.h"
+#include "AliJetCorrelMixer.h"
+#include "AliJetCorrelWriter.h"
+
+namespace JetCorrelHD {
+
+  class AliAnalysisTaskJetCorrel : public AliAnalysisTaskSE {
+    
+  public:
+    AliAnalysisTaskJetCorrel(AliJetCorrelSelector* s);
+    virtual ~AliAnalysisTaskJetCorrel();
+    
+    // Implementation of interface methods
+    virtual void UserCreateOutputObjects();
+    virtual void UserExec(Option_t *option);
+    virtual void Terminate(Option_t *option);
+    
+  private:
+    TList *fOutputContainer;                           // Histogram container
+    AliJetCorrelSelector *fSelector;                   // User selection object
+    UInt_t fNumCorrel, fNumTrigg, fNumAssoc, fNumEvts; // counters
+    AliJetCorrelMaker *fMaker;                         // Correlation maker object
+    AliJetCorrelWriter *fWriter;                       // Output writer object
+    AliJetCorrelReader *fReader;                       // Input reader object
+    AliJetCorrelMixer *fMixer;                         // Event mixing object
+    CorrelList_t *fTriggList, *fAssocList;             // Trigger&Associated particle lists
+    
+    void CrossCorrelate(CorrelList_t * const TriggList,CorrelList_t * const AssocList, UInt_t cBin, UInt_t vBin, UInt_t iCor);
+
+    // disable (make private) default/copy constructor and assignment operator:
+    AliAnalysisTaskJetCorrel();
+    AliAnalysisTaskJetCorrel(const AliAnalysisTaskJetCorrel&);
+    AliAnalysisTaskJetCorrel& operator=(const AliAnalysisTaskJetCorrel&);
+    
+    ClassDef(AliAnalysisTaskJetCorrel, 1);
+  };
+
+} // namespace declaration
+#endif
diff --git a/PWG4/JetCorrel/AliJetCorrelMaker.cxx b/PWG4/JetCorrel/AliJetCorrelMaker.cxx
new file mode 100644 (file)
index 0000000..ac52bb1
--- /dev/null
@@ -0,0 +1,194 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//__________________________________________
+// Class that uses info from the AliJetCorrelSelector object to set up the
+// two-particle correlations to be run in one instance of the analysis module.
+//-- Author: Paul Constantin
+
+#include "AliJetCorrelMaker.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+ClassImp(AliJetCorrelMaker)
+
+AliJetCorrelMaker::AliJetCorrelMaker() : 
+  fNumCorrel(0), fNumTrigg(0), fNumAssoc(0), 
+  fCorrelType(NULL), fCorrelStr(NULL),
+  fTriggType(NULL), fAssocType(NULL),
+  fIdxTrigg(NULL), fIdxAssoc(NULL){
+  // (default) constructor
+}
+
+AliJetCorrelMaker::~AliJetCorrelMaker(){
+  // destructor
+  fNumCorrel = 0;
+  fNumTrigg  = 0;
+  fNumAssoc  = 0;
+  if(fCorrelType)  delete [] fCorrelType;
+  if(fCorrelStr)   delete [] fCorrelStr;
+  if(fTriggType)   delete [] fTriggType;
+  if(fAssocType)   delete [] fAssocType;
+  if(fIdxTrigg)    delete [] fIdxTrigg;
+  if(fIdxAssoc)    delete [] fIdxAssoc;
+}
+
+Bool_t AliJetCorrelMaker::Init(UInt_t s, UInt_t * const v){
+  // Main method. Returns false on initialisation error
+  fNumCorrel = s;
+  if(fNumCorrel<1){
+    std::cerr<<"AliJetCorrelMaker::Initialize - ERROR: non-pozitive fNumCorrel"
+            <<fNumCorrel<<std::endl;
+    return kFALSE; 
+  }
+  if(fNumCorrel>=kMAXNUMCORREL){
+    std::cerr<<"AliJetCorrelMaker::Initialize - ERROR: increase kMAXNUMCORREL above "
+            <<fNumCorrel<<std::endl;
+    return kFALSE; 
+  }
+  fCorrelType = new UInt_t[fNumCorrel];
+  fCorrelStr  = new TString[fNumCorrel];
+  fTriggType  = new PartType_t[fNumCorrel];
+  fAssocType  = new PartType_t[fNumCorrel];
+  for(UInt_t k=0; k<fNumCorrel; k++){
+    fCorrelType[k] = v[k];
+    switch(fCorrelType[k]){
+    case 0:
+      fTriggType[k] = hadron;     fAssocType[k] = hadron; fCorrelStr[k] = "DiHadron";
+      break;
+    case 1:
+      fTriggType[k] = diphoton;   fAssocType[k] = hadron; fCorrelStr[k] = "Pi0Hadron";
+      break;
+    case 2:
+      fTriggType[k] = photon;     fAssocType[k] = hadron; fCorrelStr[k] = "PhotHadron";
+      break;
+    case 3:
+      fTriggType[k] = dielectron; fAssocType[k] = hadron; fCorrelStr[k] = "Z0Hadron";
+      break;
+    case 4:
+      fTriggType[k] = jet;        fAssocType[k] = jet;    fCorrelStr[k] = "JetJet";
+      break;
+    case 5:
+      fTriggType[k] = photon;     fAssocType[k] = jet;    fCorrelStr[k] = "PhotJet";
+      break;
+    case 6:
+      fTriggType[k] = dielectron; fAssocType[k] = jet;    fCorrelStr[k] = "Z0Jet";
+      break;
+    default:
+      std::cerr<<"AliJetCorrelMaker::Initialize - ERROR: unknown correlation type!"<<std::endl;
+      return kFALSE;
+      break;
+    }
+  } // loop over correlations
+
+  Bool_t notStored;
+  fIdxTrigg  = new UInt_t[fNumCorrel];
+  PartType_t *fTriggUniq = new PartType_t[fNumCorrel];
+  for(UInt_t k=0; k<fNumCorrel; k++){
+    notStored = kTRUE;
+    for(UInt_t i=0; i<fNumTrigg; i++) 
+      if(fTriggUniq[i]==fTriggType[k]) notStored = kFALSE;
+    if(notStored){fTriggUniq[fNumTrigg]=fTriggType[k]; fNumTrigg++;}
+  }
+  for(UInt_t k=0; k<fNumCorrel; k++)
+    for(UInt_t i=0; i<fNumTrigg; i++)
+      if(fTriggType[k]==fTriggUniq[i]) fIdxTrigg[k] = i;
+  delete [] fTriggUniq;
+
+  fIdxAssoc  = new UInt_t[fNumCorrel];
+  PartType_t *fAssocUniq = new PartType_t[fNumCorrel];
+  for(UInt_t k=0; k<fNumCorrel; k++){
+    notStored = kTRUE;
+    for(UInt_t i=0; i<fNumAssoc; i++) 
+      if(fAssocUniq[i]==fAssocType[k]) notStored = kFALSE;
+    if(notStored){fAssocUniq[fNumAssoc]=fAssocType[k]; fNumAssoc++;}
+  }
+  for(UInt_t k=0; k<fNumCorrel; k++)
+    for(UInt_t i=0; i<fNumAssoc; i++)
+      if(fAssocType[k]==fAssocUniq[i]) fIdxAssoc[k] = i;
+  delete [] fAssocUniq;
+
+  if(!Check()){
+    std::cerr<<"AliJetCorrelMaker::Initialize - array sanity check failed!"<<std::endl;
+    return kFALSE;
+  }
+
+  return kTRUE;
+}
+
+Bool_t AliJetCorrelMaker::Check(){
+  // performs initialization sanity checks
+  if(fNumTrigg<1 || fNumAssoc<1) return kFALSE;
+  if(fNumTrigg>fNumCorrel || fNumAssoc>fNumCorrel) return kFALSE;
+  for(UInt_t k=0; k<fNumCorrel; k++){
+    if(fIdxTrigg[k]>=fNumTrigg) return kFALSE;
+    if(fIdxAssoc[k]>=fNumAssoc) return kFALSE;
+  }
+  return kTRUE;
+}
+
+TString AliJetCorrelMaker::Descriptor(UInt_t k) const {
+  if(k>=fNumCorrel)
+    {std::cerr<<"AliJetCorrelMaker::Descriptor overflow!"<<std::endl; return "?";}
+  return fCorrelStr[k];
+}
+
+UInt_t AliJetCorrelMaker::IdxTrigg(UInt_t k) const {
+  if(k>=fNumCorrel)
+    {std::cerr<<"AliJetCorrelMaker::IdxTrigg overflow!"<<std::endl; exit(-1);}
+  return fIdxTrigg[k];
+}
+
+UInt_t AliJetCorrelMaker::IdxAssoc(UInt_t k) const {
+  if(k>=fNumCorrel)
+    {std::cerr<<"AliJetCorrelMaker::IdxAssoc overflow!"<<std::endl; exit(-1);}
+  return fIdxAssoc[k];
+}
+
+PartType_t AliJetCorrelMaker::TriggType(UInt_t k) const {
+  if(k>=fNumCorrel)
+    {std::cerr<<"AliJetCorrelMaker::TriggType overflow!"<<std::endl; return unknown;}
+  return fTriggType[k];
+}
+
+PartType_t AliJetCorrelMaker::AssocType(UInt_t k) const {
+  if(k>=fNumCorrel)
+    {std::cerr<<"AliJetCorrelMaker::AssocType overflow!"<<std::endl; return unknown;}
+  return fAssocType[k];
+}
+
+Bool_t AliJetCorrelMaker::RecoTrigger(UInt_t k) const {
+  if(fTriggType[k]==diphoton || fTriggType[k]==dielectron)
+    return kTRUE;
+  return kFALSE;
+}
+
+Bool_t AliJetCorrelMaker::RecoTrigger() const {
+  for(UInt_t k=0; k<fNumCorrel; k++)
+    if(RecoTrigger(k)) return kTRUE;
+  return kFALSE;
+}
+
+void AliJetCorrelMaker::Show(){
+  // print out whole correlation setup
+  std::cout<<"Number of Correlations:"<<fNumCorrel
+          <<" Triggers:"<<fNumTrigg<<" Associated:"<<fNumAssoc<<std::endl;
+  for(UInt_t k=0; k<fNumCorrel; k++)
+    std::cout<<"Correlation("<<k<<"):"<<fCorrelStr[k]
+            <<" TriggType="<<fTriggType[k]<<" AssocType="<<fAssocType[k]
+            <<" IdxTrigg="<<fIdxTrigg[k]<<" IdxAssoc="<<fIdxAssoc[k]<<std::endl;
+}
diff --git a/PWG4/JetCorrel/AliJetCorrelMaker.h b/PWG4/JetCorrel/AliJetCorrelMaker.h
new file mode 100644 (file)
index 0000000..448ee9c
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __ALIJETCORRELMAKER_H__
+#define __ALIJETCORRELMAKER_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//__________________________________________
+// Class that uses info from the AliJetCorrelSelector object to set up the
+// two-particle correlations to be run in one instance of the analysis module.
+//-- Author: Paul Constantin
+
+#include "CorrelDefs.h"
+
+namespace JetCorrelHD {
+  
+  class AliJetCorrelMaker : public TObject {
+    
+  public:
+    AliJetCorrelMaker();
+    ~AliJetCorrelMaker();
+    
+    Bool_t Init(UInt_t s, UInt_t * const v);
+    Bool_t Check();
+    void Show();
+    
+    UInt_t NoOfCorrel() const {return fNumCorrel;}
+    UInt_t NoOfTrigg()  const {return fNumTrigg;}
+    UInt_t NoOfAssoc()  const {return fNumAssoc;}
+    UInt_t IdxTrigg(UInt_t k) const;
+    UInt_t IdxAssoc(UInt_t k) const;
+    PartType_t TriggType(UInt_t k) const;
+    PartType_t AssocType(UInt_t k) const;
+    TString Descriptor(UInt_t k) const;
+    Bool_t RecoTrigger(UInt_t k) const;
+    Bool_t RecoTrigger() const;
+    
+  private: 
+    UInt_t fNumCorrel, fNumTrigg, fNumAssoc; // counters
+    UInt_t *fCorrelType;                  // array of correlation types
+    TString *fCorrelStr;                  // array of correlation string descriptors
+    PartType_t *fTriggType, *fAssocType;  // arrays of trigger&associated particle types
+    UInt_t *fIdxTrigg, *fIdxAssoc;        // arrays with trigger&associated indices
+    
+    // disable (make private) copy constructor, and assignment operator:
+    AliJetCorrelMaker(const AliJetCorrelMaker&);
+    AliJetCorrelMaker& operator=(const AliJetCorrelMaker&);
+
+    ClassDef(AliJetCorrelMaker, 1);
+  };
+
+} // namespace
+
+#endif 
diff --git a/PWG4/JetCorrel/AliJetCorrelMixer.cxx b/PWG4/JetCorrel/AliJetCorrelMixer.cxx
new file mode 100644 (file)
index 0000000..9a19e69
--- /dev/null
@@ -0,0 +1,156 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//__________________________________________
+// Event mixing class. A 6-dimensinal pool fPool is maintained:
+// type(fixed), type_idx(fixed), vertex(fixed), centrality(fixed), 
+// and event(dynamic), particle(dynamic)
+// fixed dimensions are fixed at task initialization time (via AliJetCorrelSelector)
+// event&particle are allow to float during runtime (via linked lists TList=event & CorrelList_t=particle)
+//-- Author: Paul Constantin
+
+#include "AliJetCorrelMixer.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+ClassImp(AliJetCorrelMixer)
+
+AliJetCorrelMixer::AliJetCorrelMixer() :
+  fSelector(NULL), fMaker(NULL), fWriter(NULL),
+  TriggEvnt(new CorrelList_t), AssocEvnt(new CorrelList_t),
+  fNumCentBins(0), fNumVertBins(0), fPoolDepth(0), fNumCorrel(0), fNumTriggs(0), fNumAssocs(0){
+  // constructor
+}
+
+AliJetCorrelMixer::~AliJetCorrelMixer(){
+  // destructor
+  CleanPool(triggs);
+  CleanPool(assocs);
+  if(TriggEvnt) delete TriggEvnt;
+  if(AssocEvnt) delete AssocEvnt;
+}
+
+void AliJetCorrelMixer::Init(AliJetCorrelSelector * const s, AliJetCorrelMaker * const m, AliJetCorrelWriter * const w){
+  // initialization method
+  fSelector = s;
+  fMaker = m;
+  fWriter = w;
+  
+  fNumCentBins = fSelector->NoOfBins(centr);  
+  fNumVertBins = fSelector->NoOfBins(zvert);
+  fPoolDepth   = fSelector->PoolDepth();
+  fNumCorrel = fMaker->NoOfCorrel();
+  fNumTriggs = fMaker->NoOfTrigg();
+  fNumAssocs = fMaker->NoOfAssoc();
+  
+  for(UInt_t vBin=0; vBin<fNumVertBins; vBin++){
+    for(UInt_t cBin=0; cBin<fNumCentBins; cBin++){
+      for(UInt_t it=0; it<fNumTriggs; it++)
+       fPool[triggs][it][vBin][cBin] = new TList;
+      for(UInt_t ia=0; ia<fNumAssocs; ia++)
+       fPool[assocs][ia][vBin][cBin] = new TList;
+    }
+  }
+}
+
+void AliJetCorrelMixer::FillPool(CorrelList_t *partList, UInt_t pIdx, UInt_t vBin, UInt_t cBin){
+  // pool filling method
+  if(partList->Size()<1) return;
+  PoolType_t pType = partList->PoolID();
+  UInt_t pSize = fPool[pType][pIdx][vBin][cBin]->GetSize();
+  // when pool depth is reached, pop pool before new event push (keep const depth)
+  if(pSize>=fPoolDepth) fPool[pType][pIdx][vBin][cBin]->RemoveFirst();
+  // incoming list is cleared at end-of-event; hence, store in pool a deep copy:
+  fPool[pType][pIdx][vBin][cBin]->AddLast(partList->DeepCopy());
+}
+
+void AliJetCorrelMixer::Mix(UInt_t vBin, UInt_t cBin, UInt_t it, UInt_t ia, UInt_t ic){
+  // rolling buffer mixing method
+  TListIter* iterAssocPool=(TListIter*)fPool[assocs][ia][vBin][cBin]->MakeIterator();
+  while(fPool[triggs][it][vBin][cBin]->GetSize()>0){ // evaluate here due to popping
+    TriggEvnt = (CorrelList_t*)fPool[triggs][it][vBin][cBin]->First();
+    TriggIter = TriggEvnt->Head();
+    
+    while((AssocEvnt=(CorrelList_t*)iterAssocPool->Next())){
+      AssocIter = AssocEvnt->Head();
+      
+      if(TriggEvnt->EvtID()==AssocEvnt->EvtID()) continue; // don't mix same event!
+      
+      while(!TriggIter.HasEnded()){
+       while(!AssocIter.HasEnded()){
+         fWriter->FillCorrelations(mixed,ic,cBin,vBin,TriggIter.Data(),AssocIter.Data()); // trigg first!
+         AssocIter.Move();
+       } // loop over associated particles
+       AssocIter = AssocEvnt->Head(); // reset associated particle iterator to list head
+       TriggIter.Move();
+      } // loop over trigger particles
+      TriggIter = TriggEvnt->Head(); // reset trigger particle iterator to list head
+    } // loop over associated pool
+    fPool[triggs][it][vBin][cBin]->RemoveFirst();
+  } // if trigger pool is not empty
+}
+
+void AliJetCorrelMixer::CleanPool(PoolType_t pType){
+  // pool cleaning
+  UInt_t size = 0;
+  if(pType==triggs) size = fNumTriggs;
+  if(pType==assocs) size = fNumAssocs;
+  for(UInt_t k=0; k<size; k++){
+    for(UInt_t vBin=0; vBin<fNumVertBins; vBin++)
+      for(UInt_t cBin=0; cBin<fNumCentBins; cBin++)
+       fPool[pType][k][vBin][cBin]->Delete(); // Remove all list objects AND delete all heap based objects
+  }
+}
+
+UInt_t AliJetCorrelMixer::PoolSize(PoolType_t pType, UInt_t vBin, UInt_t cBin){
+  // computes (static) pool size
+  UInt_t totalPoolSize=0;
+  UInt_t partSize = sizeof(CorrelParticle_t);
+  UInt_t listOverhead = sizeof(CorrelListNode_t);
+  CorrelList_t* partList; TListIter* iter;
+  UInt_t fNum = fNumAssocs; if(pType==triggs) fNum = fNumTriggs;
+  for(UInt_t i=0; i<fNum; i++){
+    iter=(TListIter*)fPool[pType][i][vBin][cBin]->MakeIterator();
+    while((partList=(CorrelList_t*)iter->Next()))
+      totalPoolSize += partList->Size()*(partSize+listOverhead);
+  }
+  return totalPoolSize/1024;
+}
+
+void AliJetCorrelMixer::ShowSummary(PoolType_t pType, UInt_t pIdx, UInt_t vBin, UInt_t cBin){
+  // pool printout method
+  UInt_t totalPoolSize=0;
+  TListIter* iter=(TListIter*)fPool[pType][pIdx][vBin][cBin]->MakeIterator();
+  CorrelList_t* partList;
+  while((partList=(CorrelList_t*)iter->Next())) totalPoolSize += partList->Size();
+
+  if(pType==triggs) std::cout<<"TriggPool[";
+  if(pType==assocs) std::cout<<"AssocPool[";
+  std::cout<<vBin<<"]["<<cBin<<"]: nevt="<<fPool[pType][pIdx][vBin][cBin]->GetSize()<<" npart="<<totalPoolSize<<std::endl;
+}
+
+void AliJetCorrelMixer::ShowPool(PoolType_t pType, UInt_t vBin, UInt_t cBin){
+  // all pools printout
+  CorrelList_t* tempList; TListIter* iter;
+  UInt_t size = 0;
+  if(pType==triggs) size = fNumTriggs;
+  if(pType==assocs) size = fNumAssocs;
+  for(UInt_t k=0; k<size; k++){
+    iter=(TListIter*)fPool[pType][k][vBin][cBin]->MakeIterator();
+    while((tempList=(CorrelList_t*)iter->Next())) tempList->Show();
+  }
+}
diff --git a/PWG4/JetCorrel/AliJetCorrelMixer.h b/PWG4/JetCorrel/AliJetCorrelMixer.h
new file mode 100644 (file)
index 0000000..39cf74b
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __ALIJETCORRELMIXER_H__
+#define __ALIJETCORRELMIXER_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//__________________________________________
+// Event mixing class. A 6-dimensinal pool fPool is maintained:
+// type(fixed), type_idx(fixed), vertex(fixed), centrality(fixed), 
+// and event(dynamic), particle(dynamic)
+// fixed dimensions are fixed at task initialization time (via AliJetCorrelSelector)
+// event&particle are allow to float during runtime (via linked lists TList=event & CorrelList_t=particle)
+//-- Author: Paul Constantin
+
+#include  "AliJetCorrelSelector.h"
+#include  "AliJetCorrelWriter.h"
+
+namespace JetCorrelHD {
+  class AliJetCorrelMixer : public TObject {
+    
+  public:
+    AliJetCorrelMixer();
+    ~AliJetCorrelMixer();
+    void Init(AliJetCorrelSelector * const s, AliJetCorrelMaker * const m, AliJetCorrelWriter * const w);
+    
+    // pool manipulation:
+    void FillPool(CorrelList_t *partList, UInt_t pIdx, UInt_t vBin, UInt_t cBin);
+    UInt_t PoolSize(PoolType_t pType, UInt_t vBin, UInt_t cBin);
+    void CleanPool(PoolType_t pType);
+    // mixing methods:  
+    void Mix(UInt_t vBin, UInt_t cBin, UInt_t it, UInt_t ia, UInt_t ic);
+    // print methods:
+    void ShowPool(PoolType_t pType, UInt_t vBin, UInt_t cBin);
+    void ShowSummary(PoolType_t pType, UInt_t pIdx, UInt_t vBin, UInt_t cBin);
+    
+  private:
+    AliJetCorrelSelector* fSelector;       // user selection object
+    AliJetCorrelMaker* fMaker;             // correlation maker object
+    AliJetCorrelWriter* fWriter;           // output writer object
+    CorrelList_t *TriggEvnt, *AssocEvnt;   // particle lists
+    CorrelListIter_t AssocIter, TriggIter; // particle list iterators
+    UInt_t fNumCentBins, fNumVertBins, fPoolDepth, fNumCorrel, fNumTriggs, fNumAssocs; // counters
+    TList* fPool[2][kMAXNUMCORREL][kMAXVERTBIN][kMAXCENTBIN]; // the particle pools used for mixing
+
+    // disable (make private) copy constructor and assignment operator:
+    AliJetCorrelMixer(const AliJetCorrelMixer&);
+    AliJetCorrelMixer* operator=(const AliJetCorrelMixer&);
+
+    ClassDef(AliJetCorrelMixer, 1);
+  };
+
+} // namespace
+
+#endif
+
diff --git a/PWG4/JetCorrel/AliJetCorrelReader.cxx b/PWG4/JetCorrel/AliJetCorrelReader.cxx
new file mode 100644 (file)
index 0000000..db58463
--- /dev/null
@@ -0,0 +1,290 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//______________________________________________________________________________________
+// Class for input (ESD or AOD) reading and filling of Trigger&Associated particle lists
+//-- Author: Paul Constantin
+
+#include "AliJetCorrelReader.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+ClassImp(AliJetCorrelReader)
+
+AliJetCorrelReader::AliJetCorrelReader() :
+  fEVT(NULL), fSelector(NULL), fWriter(NULL){
+  // constructor
+}
+
+AliJetCorrelReader::~AliJetCorrelReader(){
+  // destructor
+}
+
+void AliJetCorrelReader::Init(AliJetCorrelSelector * const s, AliJetCorrelWriter * const w){
+  // initialization method
+  fSelector = s;
+  fWriter = w;
+}
+
+Float_t AliJetCorrelReader::GetMultiplicity(){
+  // event multiplicity
+  if(!fEVT){
+    std::cerr<<"AliJetCorrelReader::GetVertex() - ERROR : fEVT not set!"<<std::endl; 
+    exit(-1);
+  }
+  if(IsESDEvt(fEVT)){
+    // return ((AliESDEvent*)fEVT)->GetNumberOfTracks(); // ESD no of global tracks
+    const AliMultiplicity* m = ((AliESDEvent*)fEVT)->GetMultiplicity(); // SPD no of tracklets
+    return m->GetNumberOfTracklets();
+  } else {
+    return ((AliAODEvent*)fEVT)->GetNTracks(); // AOD no of global tracks
+  }
+}
+
+Float_t AliJetCorrelReader::GetVertex(){
+  // event vertex
+  if(!fEVT){
+    std::cerr<<"AliJetCorrelReader::GetVertex() - ERROR : fEVT not set!"<<std::endl; 
+    exit(-1);
+  }
+  if(IsESDEvt(fEVT)){
+    Double_t v[3];
+    ((AliESDEvent*)fEVT)->GetVertex()->GetXYZ(v);
+    return v[2];
+  } else {
+    return ((AliAODEvent*)fEVT)->GetVertex(0)->GetZ();
+  }
+}
+
+void AliJetCorrelReader::FillLists(CorrelList_t *list1, CorrelList_t *list2){
+  // fills the trigger&associated particle lists
+  Bool_t useESD = IsESDEvt(fEVT);
+  PartType_t partType1 = list1->PartID();
+  PartType_t partType2 = list2->PartID();
+  Bool_t filled1 = list1->Filled();
+  Bool_t filled2 = list2->Filled();
+  // when needed, fill both lists simultaneously for speed:
+  if(!filled1 && !filled2 && partType1==partType2){
+    switch(partType1){
+    case hadron:
+      if(useESD) FillESDTrackLists(list1,list2);
+      else {
+       std::cerr<<"AliJetCorrelReader::FillLists() - ERROR: AOD dihadron not implemented!"<<std::endl;
+       exit(-1);
+      }
+      break;
+    default:
+      std::cerr<<"AliJetCorrelReader::FillLists() - ERROR: type not implemented!"<<std::endl;
+      exit(-1);
+    }
+    list1->SetFilled(kTRUE);
+    list2->SetFilled(kTRUE);
+  } else {
+    if(!filled1){
+      FillList(list1);
+      list1->SetFilled(kTRUE);
+    }
+    if(!filled2){
+      FillList(list2);
+      list2->SetFilled(kTRUE);
+    }
+  }
+}
+
+void AliJetCorrelReader::FillList(CorrelList_t *list){
+  // calls the appropriate Fill method for the list's particle type
+  Bool_t useESD = IsESDEvt(fEVT);
+  PartType_t partType = list->PartID();
+  switch(partType){
+  case hadron:
+    if(useESD) FillESDTrackList(list);
+    else{
+      std::cerr<<"AliJetCorrelReader::FillLists() - ERROR: AOD hadron not implemented!"<<std::endl;
+      exit(-1);
+    }
+    break;
+  case electron: 
+    if(useESD) FillESDTrackList(list);
+    else{
+      std::cerr<<"AliJetCorrelReader::FillLists() - ERROR: AOD hadron not implemented!"<<std::endl;
+      exit(-1);
+    }
+    break;
+  case dielectron:
+    if(useESD) FillESDDielectronList(list);
+    else{
+      std::cerr<<"AliJetCorrelReader::FillLists() - ERROR: AOD dielectron not implemented!"<<std::endl;
+      exit(-1);
+    }
+    break;
+  case photon:
+    if(useESD) FillESDPhotonList(list);
+    else{
+      std::cerr<<"AliJetCorrelReader::FillLists() - ERROR: AOD photon not implemented!"<<std::endl;
+      exit(-1);
+    }
+    break;
+  case diphoton:
+    if(useESD) FillESDDiphotonList(list);
+    else{
+      std::cerr<<"AliJetCorrelReader::FillLists() - ERROR: AOD diphoton not implemented!"<<std::endl;
+      exit(-1);
+    }
+    break;
+  default:
+    std::cerr<<"AliJetCorrelReader::FillList() - ERROR: type not implemented!"<<std::endl;
+    exit(-1);
+  }
+}
+
+void AliJetCorrelReader::FillESDTrackLists(CorrelList_t *list1, CorrelList_t *list2){
+  // fills trigg&assoc lists simultaneously with ESD tracks
+  PartType_t partType = list1->PartID(); // by definition the two lists store same particle
+
+  UInt_t nTracks = fEVT->GetNumberOfTracks() ;
+  if(nTracks<1) return;
+  for(register UInt_t i=0; i<nTracks; i++){
+    AliESDtrack *track = (AliESDtrack*)fEVT->GetTrack(i);
+
+    Float_t pT = track->Pt();
+    if(pT<fSelector->MinAssocPt()) continue;
+    if(fSelector->GenQA()) fWriter->FillTrackQA(track,0);
+    if(fSelector->LowQualityTrack(track)) continue;
+    if(!fSelector->PassPID(track,partType)) continue;
+    if(fSelector->GenQA()) fWriter->FillTrackQA(track,1);
+
+    // fill CorrelList_t object with CorrelTrack_t if two-track cuts (TPC entrance) are used and
+    // with CorrelParticle_t if not (base particle uses much less memory). Pair (ghost) cuts need
+    // to be applied for both real/mixed pairs, but it's not clear yet whether this is necessary.
+    CorrelTrack_t *hadr = new CorrelTrack_t;
+    const AliExternalTrackParam* tpcEntry = track->GetInnerParam();
+    hadr->SetTPCEntry(tpcEntry->GetX(),tpcEntry->GetY(),tpcEntry->GetZ());
+//     CorrelParticle_t *hadr = new CorrelParticle_t; // comment out above 4 lines first
+    hadr->SetPt(pT*track->Charge());
+    hadr->SetPhi(track->Phi());
+    hadr->SetEta(track->Eta());
+    hadr->SetMass(track->GetMass());
+    hadr->SetID(partType);
+
+    if(list1->PoolID()==assocs && fSelector->IsAssoc(pT)) list1->Push(hadr->Copy());
+    if(list1->PoolID()==triggs && fSelector->IsTrigg(pT)) list1->Push(hadr->Copy());
+    if(list2->PoolID()==assocs && fSelector->IsAssoc(pT)) list2->Push(hadr->Copy());
+    if(list2->PoolID()==triggs && fSelector->IsTrigg(pT)) list2->Push(hadr->Copy());
+    delete hadr;
+  } // ESD track loop
+}
+
+void AliJetCorrelReader::FillESDTrackList(CorrelList_t *list){
+  // this method is called for: (1) associated hadrons, when trigger is not hadron;
+  // (2) electrons to be used in dielectron reconstruction. Assoc pT cuts apply then...
+  PartType_t partType = list->PartID();
+
+  UInt_t nTracks = fEVT->GetNumberOfTracks();
+  if(nTracks<1) return;
+  for(register UInt_t i=0; i<nTracks; i++){
+    AliESDtrack *track = (AliESDtrack*)fEVT->GetTrack(i);
+
+    Float_t pT = track->Pt();
+    if(pT<fSelector->MinAssocPt()) continue; 
+    if(fSelector->GenQA()) fWriter->FillTrackQA(track,0);
+    if(fSelector->LowQualityTrack(track)) continue;
+    if(fSelector->GenQA()) fWriter->FillTrackQA(track,1);
+    if(!fSelector->PassPID(track,partType)) continue;
+    
+    // fill CorrelList_t object with CorrelKFTrack_t if AliKFParticle is used for di-electrons and 
+    // with CorrelParticle_t if this is done via TLorentzVector in CorrelRecoParent_t (less memory).
+    // AliKFParticle allows for a vertex cut on the reconstructed di-electron
+    if(partType==electron && kUseAliKF){
+      CorrelKFTrack_t *elec = new CorrelKFTrack_t;
+      const AliExternalTrackParam* tPar = track->GetConstrainedParam();
+      elec->SetParam(tPar->GetParameter());
+      elec->SetCovar(tPar->GetCovariance());
+      elec->SetPt(pT*track->Charge());
+      elec->SetPhi(track->Phi());
+      elec->SetEta(track->Eta());
+      elec->SetMass(track->GetMass());
+      elec->SetID(partType);
+      list->Push(elec);
+    } else {
+      CorrelParticle_t *hadr = new CorrelParticle_t;
+      hadr->SetPt(pT*track->Charge());
+      hadr->SetPhi(track->Phi());
+      hadr->SetEta(track->Eta());
+      hadr->SetMass(track->GetMass());
+      hadr->SetID(partType);
+      list->Push(hadr);
+    }   
+  }
+}
+
+void AliJetCorrelReader::FillESDPhotonList(CorrelList_t *list){
+  // TBI
+  std::cerr<<"WARNING : FillESDPhotonList() not emplemented yet. Doing nothing..."<<std::endl;
+  std::cerr<<"Photon list size:"<<list->Size()<<std::endl;
+}
+
+void AliJetCorrelReader::FillESDDiphotonList(CorrelList_t* list){
+  // makes a diphoton list (see above warning!)
+  CorrelList_t *fPhotonList = new CorrelList_t;
+  fPhotonList->Label(photon,assocs,0); // event number unimportant here
+  FillESDPhotonList(fPhotonList);
+  FillParentList(list, fPhotonList);
+  fWriter->FillParentNtuple(list);
+  delete fPhotonList;
+}
+
+void AliJetCorrelReader::FillESDDielectronList(CorrelList_t* list){
+  // makes a dielectron list
+  CorrelList_t *fElectronList = new CorrelList_t;
+  fElectronList->Label(electron,assocs,0); // event number unimportant here
+  FillESDTrackList(fElectronList);
+  FillParentList(list, fElectronList);
+  fWriter->FillParentNtuple(list);
+  delete fElectronList;
+}
+
+void AliJetCorrelReader::FillParentList(CorrelList_t *ParentList, CorrelList_t *ChildList){
+  // makes a list of parent particles from a list of children of same type
+  if(ChildList->Size()<2) return;
+
+  CorrelListIter_t iterChild1, iterChild2;
+  iterChild1 = ChildList->Head();
+  while(!iterChild1.HasEnded()){
+    CorrelParticle_t *child1 = iterChild1.Data(); iterChild1.Move();
+    iterChild2 = iterChild1;
+    while(!iterChild2.HasEnded()){
+      CorrelParticle_t *child2 = iterChild2.Data(); iterChild2.Move();
+      CorrelRecoParent_t *parent = new CorrelRecoParent_t;
+      parent->SetEvent(fEVT);
+      Bool_t goodParent = parent->Reconstruct(child1, child2);
+      Bool_t inPtRange = (ParentList->PoolID()==assocs && fSelector->IsAssoc(parent->Pt())) ||
+       (ParentList->PoolID()==triggs && fSelector->IsTrigg(parent->Pt()));
+      if(goodParent && inPtRange) ParentList->Push(parent);
+    } // 2nd particle loop
+  } // 1st particle loop
+}
+
+Bool_t AliJetCorrelReader::IsESDEvt(AliVEvent * const inEvt){
+  // checks input type
+  TString inputName = (TString)inEvt->ClassName();
+  if(inputName=="AliESDEvent") return kTRUE;
+  else if(inputName=="AliAODEvent") return kFALSE;
+  else {
+    std::cerr<<"AliJetCorrelReader::IsESDEvt() - ERROR: Unknown event input!"<<std::endl; 
+    exit(0);
+  }
+}
diff --git a/PWG4/JetCorrel/AliJetCorrelReader.h b/PWG4/JetCorrel/AliJetCorrelReader.h
new file mode 100644 (file)
index 0000000..4c6619f
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef __ALIJETCORRELREADER_H__
+#define __ALIJETCORRELREADER_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//______________________________________________________________________________________
+// Class for input (ESD or AOD) reading and filling of Trigger&Associated particle lists
+//-- Author: Paul Constantin
+#include "AliJetCorrelWriter.h"
+#include "AliJetCorrelSelector.h"
+
+namespace JetCorrelHD {
+  
+  class AliJetCorrelReader : public TObject {
+    
+  public:
+    AliJetCorrelReader(); 
+    ~AliJetCorrelReader();
+
+    void Init(AliJetCorrelSelector * const s, AliJetCorrelWriter * const w);    
+    void SetEvent(AliVEvent * const e) {fEVT=e;}
+
+    Float_t GetMultiplicity(); 
+    Float_t GetVertex();
+    void FillLists(CorrelList_t* list1, CorrelList_t* list2);
+    
+  private:    
+    AliVEvent *fEVT;                 // input event (ESD/AOD)
+    AliJetCorrelSelector *fSelector; // user selection object
+    AliJetCorrelWriter *fWriter;     // output writer object
+
+    void FillList(CorrelList_t* list);
+    void FillESDTrackLists(CorrelList_t* list1,CorrelList_t* list2);
+    void FillESDTrackList(CorrelList_t* list);
+    void FillESDPhotonList(CorrelList_t* list);
+    void FillESDDiphotonList(CorrelList_t* list);
+    void FillESDDielectronList(CorrelList_t* list);
+    void FillParentList(CorrelList_t* list1, CorrelList_t* list2);
+    Bool_t IsESDEvt(AliVEvent* const e);    
+
+    // disable (make private) copy constructor and assignment operator:
+    AliJetCorrelReader(const AliJetCorrelReader&);
+    AliJetCorrelReader& operator=(const AliJetCorrelReader&);
+
+    ClassDef(AliJetCorrelReader, 1);
+  };
+
+} // namespace
+
+#endif
diff --git a/PWG4/JetCorrel/AliJetCorrelSelector.cxx b/PWG4/JetCorrel/AliJetCorrelSelector.cxx
new file mode 100644 (file)
index 0000000..f95577a
--- /dev/null
@@ -0,0 +1,253 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//__________________________________________
+// Class for user selections. Object is created by ConfigJetCorrel.C macro
+// and passed to AddTaskJetCorrel.C running macro.
+//-- Author: Paul Constantin
+
+#include "AliJetCorrelSelector.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+ClassImp(AliJetCorrelSelector)
+
+AliJetCorrelSelector::AliJetCorrelSelector() : 
+  fNumCorrel(0), fPoolDepth(0), fCorrelType(NULL), fGenQA(kFALSE),
+  minTriggPt(0), maxTriggPt(0), bwTriggPt(0), minAssocPt(0), maxAssocPt(0), bwAssocPt(0),
+  fITSRefit(kFALSE), fTPCRefit(kFALSE), fTRDRefit(kFALSE), fRejectKinkChild(kFALSE),
+  fMaxNsigmaVtx(0), fMaxITSChi2(0), fMaxTPCChi2(0), fMinNClusITS(0), fMinNClusTPC(0) {
+  // (default) constructor
+  fNumBins[centr] = 0; fBinning[centr] = NULL;
+  fNumBins[zvert] = 0; fBinning[zvert] = NULL;
+}
+
+AliJetCorrelSelector::~AliJetCorrelSelector(){
+  // destructor
+  if(fCorrelType) delete [] fCorrelType;
+  fNumCorrel = 0;
+  if(fBinning[centr]) delete [] fBinning[centr];
+  fNumBins[centr] = 0;
+  if(fBinning[zvert]) delete [] fBinning[zvert];
+  fNumBins[zvert] = 0;
+}
+
+void AliJetCorrelSelector::SetCorrelTypes(UInt_t s, UInt_t * const v){
+  // fills the array of correlation types
+  if(s<1){std::cerr<<"AliJetCorrelSelector::SetCorrelTypes - empty array"<<std::endl; exit(-1);}
+  if(s>kMAXNUMCORREL){std::cerr<<"AliJetCorrelSelector: correlation array too big!"<<std::endl; exit(-1);}
+  fNumCorrel = s;
+  fCorrelType = new UInt_t[fNumCorrel];
+  for(UInt_t k=0; k<fNumCorrel; k++){
+    if(v[k]>99){
+      std::cerr<<"AliJetCorrelSelector::SetCorrelTypes - read error? val["<<k<<"]="<<v[k]<<std::endl;
+      exit(-1);
+    }
+    else fCorrelType[k] = v[k];
+  } 
+}
+
+void AliJetCorrelSelector::SetBinningCentr(UInt_t s, Float_t * const v){
+  // fills array of centrality bins
+  if(s<1){std::cerr<<"AliJetCorrelSelector::SetBinningCentr - empty array"<<std::endl; exit(-1);}
+  if(s>kMAXCENTBIN){std::cerr<<"AliJetCorrelSelector: centrality array too big!"<<std::endl; exit(-1);}
+  fNumBins[centr] = s;
+  fBinning[centr] = new Float_t[fNumBins[centr]]; 
+  for(UInt_t k=0; k<fNumBins[centr]; k++){
+    if(TMath::Abs(v[k])>999.){
+      std::cerr<<"AliJetCorrelSelector::SetBinningCentr - read error? val["<<k<<"]="<<v[k]<<std::endl;
+      exit(-1);
+    }
+    else fBinning[centr][k] = v[k];
+  }
+}
+
+void AliJetCorrelSelector::SetBinningZvert(UInt_t s, Float_t * const v){
+  // fills array of vertex bins
+  if(s<1){std::cerr<<"AliJetCorrelSelector::SetBinningZvert - empty array"<<std::endl; exit(-1);}
+  if(s>kMAXVERTBIN){std::cerr<<"AliJetCorrelSelector: vertex array too big!"<<std::endl; exit(-1);}
+  fNumBins[zvert] = s;
+  fBinning[zvert] = new Float_t[fNumBins[zvert]]; 
+  for(UInt_t k=0; k<fNumBins[zvert]; k++){
+    if(TMath::Abs(v[k])>999.){
+      std::cerr<<"AliJetCorrelSelector::SetBinningZvert - read error? val["<<k<<"]="<<v[k]<<std::endl;
+      exit(-1);
+    }
+    else fBinning[zvert][k] = v[k];
+  }
+}
+
+void AliJetCorrelSelector::SetBinningTrigg(Float_t min, Float_t max, Float_t bw){
+  // sets trigger Pt binning
+  minTriggPt = min;
+  maxTriggPt = max;
+  bwTriggPt  = bw;
+}
+
+void AliJetCorrelSelector::SetBinningAssoc(Float_t min, Float_t max, Float_t bw){
+  // sets associated Pt binning
+  minAssocPt = min;
+  maxAssocPt = max;
+  bwAssocPt  = bw;
+}
+
+void AliJetCorrelSelector::Show(){
+  // print out all user selections
+  std::cout<<"Generic selections: "<<std::endl<<" PoolDepth="<<fPoolDepth;
+  std::cout<<std::endl<<" Correlation Types: ";
+  for(UInt_t k=0; k<fNumCorrel; k++) std::cout<<fCorrelType[k]<<" ";
+  std::cout<<std::endl<<" Centrality/Multiplicity binning: ";
+  for(UInt_t k=0; k<fNumBins[centr]; k++) std::cout<<fBinning[centr][k]<<" ";
+  std::cout<<std::endl<<" Vertex binning: ";
+  for(UInt_t k=0; k<fNumBins[zvert]; k++) std::cout<<fBinning[zvert][k]<<" ";
+  std::cout<<std::endl<<" Trigg binning:"<<minTriggPt<<"->"<<maxTriggPt<<"/"<<bwTriggPt;
+  std::cout<<std::endl<<" Assoc binning:"<<minAssocPt<<"->"<<maxAssocPt<<"/"<<bwAssocPt;
+  std::cout<<std::endl<<"Track selections: "<<std::endl<<" MaxNsigmaVtx="<<fMaxNsigmaVtx<<std::endl
+          <<" MaxITSChi2="<<fMaxITSChi2<<" MaxTPCChi2="<<fMaxTPCChi2<<std::endl
+          <<" MinNClusITS="<<fMinNClusITS<<" MinNClusTPC="<<fMinNClusTPC<<std::endl
+          <<" ITSRefit="<<fITSRefit<<" TPCRefit="<<fTPCRefit<<" TRDRefit="<<fTRDRefit<<std::endl
+          <<" RejectKinkChild="<<fRejectKinkChild<<std::endl;
+}
+
+Float_t AliJetCorrelSelector::BinBorder(BinType_t cType, UInt_t k){
+  // returns bin margins
+  if(k<=NoOfBins(cType)) return fBinning[cType][k];
+  else {std::cerr<<"BinBorder Error: bin of type "<<cType<<" outside range "<<k<<std::endl;  exit(0);}
+}
+
+Int_t AliJetCorrelSelector::GetBin(BinType_t cType, Float_t val){
+  // returns bin number
+  Int_t iBin=-1; UInt_t nBins=NoOfBins(cType);
+  for(UInt_t i=0; i<nBins; i++)
+    if(BinBorder(cType,i)<=val && val<BinBorder(cType,i+1)) iBin=i;
+  return iBin;
+}
+
+//////////////////////////////////////////////////////////
+// Cutting Methods
+/////////////////////////////////////////////////////////
+
+Bool_t AliJetCorrelSelector::GoodTrackPair(CorrelTrack_t *t1, CorrelTrack_t *t2){
+  // meant for two-track cuts (like TPC entrance); but hopes are that single-track cuts,
+  // like a high no of TPC clusters, will avoid double counting of split tracks...
+  t1->Show(); t2->Show();
+  return kTRUE;
+}
+
+Bool_t AliJetCorrelSelector::LowQualityTrack(AliESDtrack* track){
+  // selects low quality tracks
+  UInt_t status = track->GetStatus();
+  if(fITSRefit && !(status & AliESDtrack::kITSrefit)) return kTRUE;
+  if(fTPCRefit && !(status & AliESDtrack::kTPCrefit)) return kTRUE;
+
+  UInt_t nClusITS = track->GetITSclusters(0);
+  UInt_t nClusTPC = track->GetTPCclusters(0); // or track->GetTPCNcls() ?
+  if(nClusITS<fMinNClusITS) return kTRUE;
+  if(nClusTPC<fMinNClusTPC) return kTRUE;
+
+  Float_t chi2ITS=-1., chi2TPC=-1.;
+  if(nClusITS!=0) chi2ITS = track->GetITSchi2()/Float_t(nClusITS);
+  if(nClusTPC!=0) chi2TPC = track->GetTPCchi2()/Float_t(nClusTPC);
+  if(chi2ITS<0 || chi2ITS>fMaxITSChi2) return kTRUE;
+  if(chi2TPC<0 || chi2TPC>fMaxTPCChi2) return kTRUE;
+
+  if(fRejectKinkChild && track->GetKinkIndex(0)>0) return kTRUE;
+  if(GetSigmaToVertex(track)>fMaxNsigmaVtx) return kTRUE;
+
+  return kFALSE;
+}
+
+Bool_t AliJetCorrelSelector::PassPID(AliESDtrack* track, PartType_t PartType){
+  // checks if a track has the required ID
+  Bool_t hasReqPID = kFALSE;
+  Stat_t fPid;
+  Stat_t fWeight;
+  GetPID(track, fPid, fWeight);
+  
+  switch(PartType){
+    case hadron:
+      // if(fPID!=0) hasReqPID = kTRUE;
+      hasReqPID = kTRUE;
+      break;
+    case electron:
+      // if(fTRDRefit && !(status & AliESDtrack::kTRDrefit)) hasReqPID = kFALSE;
+      // if(fPID!=0) hasReqPID = kFALSE;
+      hasReqPID = kTRUE;
+      break;
+    case pion:
+      // if(fPID!=2) hasReqPID = kFALSE;
+      hasReqPID = kTRUE;
+      break;
+    case kaon:
+      // if(fPID!=3) hasReqPID = kFALSE;
+      hasReqPID = kTRUE;
+      break;
+    case proton:
+      // if(fPID!=4) hasReqPID = kFALSE;
+      hasReqPID = kTRUE;
+      break;
+    default:
+      std::cerr<<"AliJetCorrelSelector::PassPID() - ERROR: wrong type!"<<std::endl;
+      exit(-1);
+  }
+  return hasReqPID;
+}
+
+Float_t AliJetCorrelSelector::GetSigmaToVertex(AliESDtrack* track){
+  // Calculates the number of sigma to the vertex; from ANALYSIS/AliESDtrackCuts
+  Float_t b[2], bRes[2], bCov[3];
+  track->GetImpactParameters(b,bCov);
+  if(bCov[0]<=0 || bCov[2]<=0) return -1.;
+  bRes[0] = TMath::Sqrt(bCov[0]);
+  bRes[1] = TMath::Sqrt(bCov[2]);
+
+  Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
+
+  if(TMath::Exp(-d*d/2)<1e-10) return 1000;
+
+  Float_t nSigma = TMath::ErfInverse(1-TMath::Exp(-d*d/2))*TMath::Sqrt(2);
+  return nSigma;
+}
+
+void AliJetCorrelSelector::GetPID(AliESDtrack* track, Stat_t& fpid, Stat_t& fweight){
+  // Finds most probable particle: 0=Electron, 1=Muon, 2=Pion, 3=Kaon, 4=Proton
+  fpid = -1;
+  fweight = -1;
+  
+  Double_t wpart[5], wpartbayes[5];
+  track->GetESDpid(wpart); // probability of the different particle types
+  Double_t c[5]={1., 1., 1., 1., 1.}; // Tentative particle type "concentrations"
+  //  Double_t c[5]={0.01, 0.01, 0.85, 0.10, 0.05};
+  
+  //Bayes formula
+  Double_t rcc = 0.;
+  for(Int_t i=0; i<5; i++) {rcc += c[i]*wpart[i];}
+  if(TMath::Abs(rcc)<1e-10) return;
+  for(Int_t i=0; i<5; i++) {wpartbayes[i] = c[i]*wpart[i]/rcc;}
+  
+  Int_t ipid=-1;
+  Float_t max=0.;
+  for(Int_t i=0; i<5; i++) {
+    if(wpartbayes[i]>max) {
+      ipid = i; 
+      max = wpartbayes[i];
+    }
+  }
+
+  fpid = ipid;
+  fweight = max;
+}
diff --git a/PWG4/JetCorrel/AliJetCorrelSelector.h b/PWG4/JetCorrel/AliJetCorrelSelector.h
new file mode 100644 (file)
index 0000000..79b9121
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef __ALIJETCORRELSELECTOR_H__
+#define __ALIJETCORRELSELECTOR_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//__________________________________________
+// Class for user selections. Object is created by ConfigJetCorrel.C macro
+// and passed to AddTaskJetCorrel.C running macro.
+//-- Author: Paul Constantin
+
+#include "CorrelTrack.h"
+#include "CorrelKFTrack.h"
+#include "CorrelRecoParent.h"
+#include "CorrelList.h"
+
+namespace JetCorrelHD {
+  
+  class AliJetCorrelSelector : public TObject {
+    
+  public:
+    AliJetCorrelSelector();
+    ~AliJetCorrelSelector();
+
+    // Selection getters:
+    UInt_t PoolDepth() {return fPoolDepth;}
+    UInt_t NoOfCorrel() {return fNumCorrel;}
+    UInt_t* CorrelTypes() {return fCorrelType;}
+    const UInt_t NoOfBins(BinType_t cType) {return fNumBins[cType]-1;}  
+    Float_t BinBorder(BinType_t cType, UInt_t ii);
+    Int_t GetBin(BinType_t cType, Float_t val);
+    Float_t MinAssocPt() {return minAssocPt;}
+    Float_t MaxAssocPt() {return maxAssocPt;}
+    UInt_t  NumAssocPt() {return UInt_t((maxAssocPt-minAssocPt)/bwAssocPt);}
+    Float_t MinTriggPt() {return minTriggPt;}
+    Float_t MaxTriggPt() {return maxTriggPt;}
+    UInt_t  NumTriggPt() {return UInt_t((maxTriggPt-minTriggPt)/bwTriggPt);}
+    Bool_t GenQA() {return fGenQA;};
+    void Show();
+    // Selection Setters:
+    void SetPoolDepth(UInt_t v)      {fPoolDepth=v;}
+    void SetCorrelTypes(UInt_t s,  UInt_t * const v);
+    void SetBinningCentr(UInt_t s, Float_t * const v);
+    void SetBinningZvert(UInt_t s, Float_t * const v);
+    void SetBinningTrigg(Float_t min, Float_t max, Float_t bw);
+    void SetBinningAssoc(Float_t min, Float_t max, Float_t bw);
+    void SetITSRefit(Bool_t v)    {fITSRefit=v;}
+    void SetTPCRefit(Bool_t v)    {fTPCRefit=v;}
+    void SetTRDRefit(Bool_t v)    {fTRDRefit=v;}
+    void SetMaxITSChi2(Float_t v) {fMaxITSChi2=v;}
+    void SetMaxTPCChi2(Float_t v) {fMaxTPCChi2=v;}
+    void SetMinNClusITS(UInt_t v) {fMinNClusITS=v;}
+    void SetMinNClusTPC(UInt_t v) {fMinNClusTPC=v;}
+    void SetMaxNsigmaVtx(Float_t v) {fMaxNsigmaVtx=v;}
+    void SetRejectKinkChild(Bool_t v) {fRejectKinkChild=v;}
+    void SetQA(Bool_t v) {fGenQA=v;}
+    // Cutting methods:
+    Bool_t IsAssoc(Float_t pT) {return (pT>=minAssocPt && pT<=maxAssocPt);}
+    Bool_t IsTrigg(Float_t pT) {return (pT>=minTriggPt && pT<=maxTriggPt);}
+    Bool_t GoodTrackPair(CorrelTrack_t* t1, CorrelTrack_t* t2);
+    Bool_t LowQualityTrack(AliESDtrack* t);  
+    Bool_t PassPID(AliESDtrack* t, PartType_t pType);
+    Float_t GetSigmaToVertex(AliESDtrack* trk);
+    void GetPID(AliESDtrack* trk, Stat_t& fpid, Stat_t& fweight);
+
+  private: 
+    // Generic Selections:
+    UInt_t fNumCorrel, fPoolDepth; // number of correlations, pool depth
+    UInt_t *fCorrelType;           // array of correlation types
+    UInt_t fNumBins[2];            // number of bins: centr, zvert
+    Float_t* fBinning[2];          // bin margins: centr, zvert
+    Bool_t fGenQA;                 // generate QA histos
+    Float_t minTriggPt, maxTriggPt, bwTriggPt; // trigg Pt binning
+    Float_t minAssocPt, maxAssocPt, bwAssocPt; // assoc Pt binning
+    // Track Selections:
+    Bool_t fITSRefit, fTPCRefit, fTRDRefit, fRejectKinkChild; // on/off cuts
+    Float_t fMaxNsigmaVtx;
+    Float_t fMaxITSChi2, fMaxTPCChi2;
+    UInt_t fMinNClusITS, fMinNClusTPC;
+    
+    // disable (make private) copy constructor, and assignment operator:
+    AliJetCorrelSelector(const AliJetCorrelSelector&);
+    AliJetCorrelSelector& operator=(const AliJetCorrelSelector&);
+
+    ClassDef(AliJetCorrelSelector, 1);
+  };
+
+} // namespace
+
+#endif 
diff --git a/PWG4/JetCorrel/AliJetCorrelWriter.cxx b/PWG4/JetCorrel/AliJetCorrelWriter.cxx
new file mode 100644 (file)
index 0000000..b0832f6
--- /dev/null
@@ -0,0 +1,283 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//______________________________________________________
+// Class for output (histograms) definition and filling.
+//-- Author: Paul Constantin
+
+#include "AliJetCorrelWriter.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+ClassImp(AliJetCorrelWriter)
+
+AliJetCorrelWriter::AliJetCorrelWriter() :
+  fSelector(NULL), fMaker(NULL), hname(""), htit(""), fRecoTrigg(kFALSE), fRndm(6251093),
+  hBinsCentr(NULL), hBinsZVert(NULL), hCentr(NULL), hZVert(NULL), ntuParent(NULL) {
+  // constructor
+  for(UInt_t i=0; i<kMAXNUMCORREL; i++) 
+    for(UInt_t j=0; j<kMAXCENTBIN; j++) 
+      {fNumReal[i][j]=0; fNumMix[i][j]=0;}
+}
+
+AliJetCorrelWriter::~AliJetCorrelWriter(){
+  // destructor
+}
+
+void AliJetCorrelWriter::Init(AliJetCorrelSelector * const s, AliJetCorrelMaker * const m){
+  // initialization method
+  fSelector = s;
+  fMaker = m;
+  fRecoTrigg = m->RecoTrigger();
+}
+
+////////////////////////////////////////////
+// METHODS FOR CREATION OF OUTPUT HISTOGRAMS
+////////////////////////////////////////////
+
+void AliJetCorrelWriter::CreateGeneric(TList *histosContainer){
+  // books generic histograms
+  UInt_t nTypeTrigg = fMaker->NoOfTrigg();
+  UInt_t nBinsCentr = fSelector->NoOfBins(centr);
+  UInt_t nBinsZVert = fSelector->NoOfBins(zvert);
+  UInt_t nBinsTrigg = fSelector->NumTriggPt();
+  Float_t minTrigg  = fSelector->MinTriggPt();
+  Float_t maxTrigg  = fSelector->MaxTriggPt();
+
+  for(UInt_t tt=0; tt<nTypeTrigg; tt++){ // loop over trigger types
+    for(UInt_t ic=0; ic<nBinsCentr; ic++){ // loop over centrality bins
+      htit="type:"; htit+=tt; htit+=" cent:"; htit+=ic;
+      hname = "hTriggPt"; hname+=tt; hname+=ic;
+      hTriggPt[tt][ic] = new TH1F(hname,  htit, nBinsTrigg, minTrigg, maxTrigg);
+      histosContainer->AddLast(hTriggPt[tt][ic]);
+    } // centrality binning loop
+  } // loop over trigger types
+
+  hCentr = new TH1F("hCentr","centrality distribution",100, 0., 100.);
+  histosContainer->AddLast(hCentr);
+  hZVert = new TH1F("hZVert","vertex distribution",100, -50., 50.);
+  histosContainer->AddLast(hZVert);
+
+  hBinsCentr = new TH1F("hBinsCentr","centrality binning", nBinsCentr+1, 0, 1); 
+  histosContainer->AddLast(hBinsCentr);
+  for(UInt_t i=1;i<=nBinsCentr+1; i++)
+    hBinsCentr->SetBinContent(i,fSelector->BinBorder(centr,i-1));
+  hBinsZVert = new TH1F("hBinsZVert","centrality binning", nBinsZVert+1, 0, 1); 
+  histosContainer->AddLast(hBinsZVert);
+  for(UInt_t i=1;i<=nBinsZVert+1; i++)
+    hBinsZVert->SetBinContent(i,fSelector->BinBorder(zvert,i-1));
+}
+
+void AliJetCorrelWriter::CreateQA(TList *histosContainer){
+  // books QA histograms
+  TString when[2] = {"before cuts","after cuts"};
+  for(UInt_t i=0; i<2; i++){
+    hname = "hTrkITSQA"; hname += i;
+    htit = "ITS nClust vs Chi2/nClust "; htit += when[i];
+    hTrkITSQA[i] = new TH2F(hname,htit,20,0.,20.,50,0.,10.);
+    histosContainer->AddLast(hTrkITSQA[i]);
+    hname = "hTrkTPCQA"; hname += i;
+    htit = "TPC nClust vs Chi2/nClust "; htit += when[i];
+    hTrkTPCQA[i] = new TH2F(hname,htit,30,0.,150.,50,0.,10.);
+    histosContainer->AddLast(hTrkTPCQA[i]);
+    hname = "hTrkVTXQA"; hname += i;
+    htit = "VTX KinkIndex vs nSigma "; htit += when[i];
+    hTrkVTXQA[i] = new TH2F(hname,htit,21,-10.,10,50,0.,10.);
+    histosContainer->AddLast(hTrkVTXQA[i]);
+  }
+
+  UInt_t nBinsCentr = fSelector->NoOfBins(centr);
+  UInt_t nBinsTrigg = fSelector->NumTriggPt();
+  Float_t minTrigg  = fSelector->MinTriggPt();
+  Float_t maxTrigg  = fSelector->MaxTriggPt();
+  UInt_t nBinsAssoc = fSelector->NumAssocPt();
+  Float_t minAssoc  = fSelector->MinAssocPt();
+  Float_t maxAssoc  = fSelector->MaxAssocPt();
+  for(UInt_t it=0; it<2; it++){ // mixing type loop (real/mixed)
+    for(UInt_t ic=0; ic<nBinsCentr; ic++){ // centrality loop
+         hname="hTrkProx"; hname+=it; hname+=ic;
+         htit="hTrkProx"; htit+=it; htit+=ic;
+         hTrkProx[it][ic] = new TH3F(hname,htit,100,0.,10.,
+                                     nBinsTrigg,minTrigg,maxTrigg,nBinsAssoc,minAssoc,maxAssoc);
+         histosContainer->AddLast(hTrkProx[it][ic]);
+    } // loop over correlation types
+  } // loop over mixing type
+}
+
+void AliJetCorrelWriter::CreateCorrelations(TList* histosContainer){
+  // books correlation histograms
+  const Float_t lr=-0.5*pi, ur=1.5*pi, bwPout=0.2;
+  UInt_t nTypeCorrel = fMaker->NoOfCorrel();
+  UInt_t nBinsCentr = fSelector->NoOfBins(centr);
+  UInt_t nBinsZVert = fSelector->NoOfBins(zvert);
+  UInt_t nBinsTrigg = fSelector->NumTriggPt();
+  Float_t minTrigg  = fSelector->MinTriggPt();
+  Float_t maxTrigg  = fSelector->MaxTriggPt();
+  UInt_t nBinsAssoc = fSelector->NumAssocPt();
+  Float_t minAssoc  = fSelector->MinAssocPt();
+  Float_t maxAssoc  = fSelector->MaxAssocPt();
+  UInt_t nPoutBins = UInt_t(TMath::Ceil(2.2*maxAssoc/bwPout)); // since |p_out|<p_Ta       
+
+  if(fRecoTrigg) {  // if any correlation has reconstructed trigger, define ntuple; use id to differentiate
+    ntuParent = new TNtuple("ntuParent","Reconstructed Parent Ntuple","id:q:m:pT:phi:eta:assym:open");
+    histosContainer->AddLast(ntuParent);
+  }
+  for(UInt_t ityp=0; ityp<2; ityp++){ // mixing type loop (real/mixed)
+    for(UInt_t htc=0; htc<nTypeCorrel; htc++){ // loop over correlation types
+      for(UInt_t hic=0; hic<nBinsCentr; hic++){ // centrality loop
+       for(UInt_t hiv=0; hiv<nBinsZVert; hiv++){ // vertex loop
+         htit = fMaker->Descriptor(htc);
+         htit+=":"; htit+=ityp; htit+=hic; htit+=hiv;
+         hname="hDPhi"; hname+=ityp; hname+=htc; hname+=hic; hname+=hiv;         
+         hDPhi[ityp][htc][hic][hiv] = new TH3F(hname, htit, kDPhiNumBins, lr, ur,
+                                               nBinsTrigg,minTrigg,maxTrigg, nBinsAssoc,minAssoc,maxAssoc);
+         histosContainer->AddLast(hDPhi[ityp][htc][hic][hiv]);
+         hname="hDEta"; hname+=ityp; hname+=htc; hname+=hic; hname+=hiv;         
+         hDEta[ityp][htc][hic][hiv] = new TH3F(hname, htit, kDEtaNumBins, -2., 2.,
+                                               nBinsTrigg,minTrigg,maxTrigg, nBinsAssoc,minAssoc,maxAssoc);
+         histosContainer->AddLast(hDEta[ityp][htc][hic][hiv]);
+         hname="hPout"; hname+=ityp; hname+=htc; hname+=hic; hname+=hiv;         
+         hPout[ityp][htc][hic][hiv] = new TH3F(hname, htit, nPoutBins, -1.1*maxAssoc, 1.1*maxAssoc,
+                                               nBinsTrigg,minTrigg,maxTrigg, nBinsAssoc,minAssoc,maxAssoc);
+         histosContainer->AddLast(hPout[ityp][htc][hic][hiv]);
+       } // loop over vertex bins
+      } // loop over centrality bins
+    } // loop over correlation types
+  } // loop over mixing type
+}
+
+/////////////////////////////////////////////////////////
+// METHODS FOR FILLING THE OUTPUT HISTOGRAMS
+/////////////////////////////////////////////////////////
+
+void AliJetCorrelWriter::FillGlobal(Float_t cent, Float_t zvert){
+  // some global event histos
+  hCentr->Fill(cent);
+  hZVert->Fill(zvert);
+}
+
+void AliJetCorrelWriter::FillSingleHistos(CorrelList_t * const TrigList, UInt_t cBin, UInt_t pIdx){
+  // fils single-particle histograms
+  if(TrigList->Size()<1) return;
+  CorrelListIter_t partIter = TrigList->Head();
+  while(!partIter.HasEnded()){
+    CorrelParticle_t *particle = partIter.Data();
+    hTriggPt[pIdx][cBin]->Fill(particle->Pt());
+    partIter.Move();
+  }
+}
+
+void AliJetCorrelWriter::FillTrackQA(AliESDtrack * const track, UInt_t idx){
+  // fills single-particle QA
+  if(idx>1){std::cerr<<"AliJetCorrelWriter::FillTrackQA: wrong idx!"<<std::endl; exit(-1);}
+
+  UInt_t nClusITS = track->GetITSclusters(0);
+  UInt_t nClusTPC = track->GetTPCclusters(0); // or track->GetTPCNcls() ?
+  Float_t chi2ITS=-1., chi2TPC=-1.;
+  if(nClusITS!=0) chi2ITS = track->GetITSchi2()/Float_t(nClusITS);
+  if(nClusTPC!=0) chi2TPC = track->GetTPCchi2()/Float_t(nClusTPC);
+  UInt_t kinkIndex = track->GetKinkIndex(0);
+  Float_t sigVtx = fSelector->GetSigmaToVertex(track);
+
+  hTrkITSQA[idx]->Fill(Float_t(nClusITS),chi2ITS);
+  hTrkTPCQA[idx]->Fill(Float_t(nClusTPC),chi2TPC);
+  hTrkVTXQA[idx]->Fill(Float_t(kinkIndex),sigVtx);
+}
+
+void AliJetCorrelWriter::FillParentNtuple(CorrelList_t * const ParentList){
+  // fills ntuple of triggers when they are reconstructed parents (pi0,Z0,etc.)
+  if(!fRecoTrigg)
+    {std::cerr<<"AliJetCorrelWriter::FillParentNtuple: you shouldn't be here!"<<std::endl; exit(-1);}
+  if(ParentList->Size()<1) return;
+  Float_t parVar[8]={0.};
+  CorrelListIter_t parIter = ParentList->Head();
+  while(!parIter.HasEnded()){
+    CorrelRecoParent_t *parent = dynamic_cast<CorrelRecoParent_t*>(parIter.Data());
+    if(!parent)
+      {std::cerr<<"AliJetCorrelWriter::FillParentNtuple: failed casting!"<<std::endl; exit(-1);}
+    parVar[0] = parent->ID();
+    parVar[1] = parent->Q();
+    parVar[2] = parent->M();
+    parVar[3] = parent->Pt();
+    parVar[4] = parent->Phi();
+    parVar[5] = parent->Eta();
+    parVar[6] = parent->Assym();
+    parVar[7] = parent->OpenAng();
+    ntuParent->Fill(parVar);
+    parIter.Move();
+  }
+}
+
+void AliJetCorrelWriter::FillCorrelations(FillType_t fTyp, UInt_t iCorr, UInt_t cBin, UInt_t vBin, 
+                                         CorrelParticle_t * const Trigg, CorrelParticle_t * const Assoc){
+  // fills the correlation (two-particle) histograms
+  // trigger information (this is why the first particle has to be the trigger):
+  Float_t ptt  = Trigg->Pt();
+  Float_t phit = Trigg->Phi();
+  Float_t etat = Trigg->Eta();
+  // associated information:
+  Float_t pta  = Assoc->Pt();
+  Float_t phia = Assoc->Phi();
+  Float_t etaa = Assoc->Eta();
+
+  if(!fSelector->IsAssoc(pta) || !fSelector->IsTrigg(ptt)) return;
+  if(fabs(ptt-pta)<kEPS && fabs(phit-phia)<kEPS && fabs(etat-etaa)<kEPS) return; // don't auto-correlate
+
+  // store track pair proximity
+  if(fSelector->GenQA())
+    if(Trigg->ID()==hadron && Assoc->ID()==hadron){
+      CorrelTrack_t* trk1 = dynamic_cast<CorrelTrack_t*>(Trigg);
+      CorrelTrack_t* trk2 = dynamic_cast<CorrelTrack_t*>(Assoc);
+      if(!trk1 || !trk2)
+       {std::cerr<<"AliJetCorrelWriter::FillCorrelations: failed casting!"<<std::endl; exit(-1);}
+      hTrkProx[fTyp][cBin]->Fill(trk1->Dist(trk2),ptt,pta);
+    }
+  // Fill correlation histograms:
+  Float_t dphi = DeltaPhi(phit,phia);
+  Float_t deta = etat-etaa;
+  Float_t pout = pta*TMath::Sin(dphi);
+  hDPhi[fTyp][iCorr][cBin][vBin]->Fill(dphi,ptt,pta);
+  hDEta[fTyp][iCorr][cBin][vBin]->Fill(deta,ptt,pta);
+  hPout[fTyp][iCorr][cBin][vBin]->Fill(pout,ptt,pta);
+  
+  if(fTyp==real) fNumReal[iCorr][cBin]++; else fNumMix[iCorr][cBin]++;
+}
+
+void AliJetCorrelWriter::ShowStats(){
+  // stats printout method
+  UInt_t nTypeCorrel = fMaker->NoOfCorrel();
+  UInt_t nBinsCentr = fSelector->NoOfBins(centr);
+  for(UInt_t i=0; i<nTypeCorrel; i++){
+    std::cout<<"Correlation:"<<fMaker->Descriptor(i)<<std::endl;
+    for(UInt_t j=0; j<nBinsCentr; j++){
+      Float_t cb1 = fSelector->BinBorder(centr, j);
+      Float_t cb2 = fSelector->BinBorder(centr, j+1);
+      std::cout<<" Centrality:"<<cb1<<"-"<<cb2
+              <<"\t Real Pairs="<<fNumReal[i][j]<<"\t Mixed Pairs="<<fNumMix[i][j]<<std::endl;
+    }
+  }
+}
+
+Float_t AliJetCorrelWriter::DeltaPhi(Float_t  phi1, Float_t phi2){
+// wrapps dphi in (-pi/2, 3*pi/2)
+  Float_t res = phi2-phi1;
+  if(fRndm.Uniform()<0.5) res = phi1 - phi2;
+  if(1.5*pi<res && res<=2*pi) res-=2*pi;
+  else if(-2*pi<=res && res<-0.5*pi) res+=2*pi;
+  return res;  
+}
+
diff --git a/PWG4/JetCorrel/AliJetCorrelWriter.h b/PWG4/JetCorrel/AliJetCorrelWriter.h
new file mode 100644 (file)
index 0000000..ac5d422
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef  __ALIJETCORRELWRITER_H__
+#define  __ALIJETCORRELWRITER_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//______________________________________________________
+// Class for output (histograms) definition and filling.
+//-- Author: Paul Constantin
+
+#include "AliJetCorrelSelector.h"
+#include "AliJetCorrelMaker.h"
+
+namespace JetCorrelHD {
+
+  class AliJetCorrelWriter : public TObject {
+
+  public:
+    AliJetCorrelWriter();
+    ~AliJetCorrelWriter();    
+    void Init(AliJetCorrelSelector * const s, AliJetCorrelMaker * const m);
+
+    void CreateGeneric(TList* histosContainer);
+    void CreateQA(TList *histosContainer);
+    void CreateCorrelations(TList* histosContainer);
+    
+    void FillGlobal(Float_t cent, Float_t zvert);
+    void FillSingleHistos(CorrelList_t * const PartList, UInt_t cBin, UInt_t pIdx);
+    void FillTrackQA(AliESDtrack * const track, UInt_t idx);
+    void FillParentNtuple(CorrelList_t * const ParentList);
+    void FillCorrelations(FillType_t fTyp, UInt_t iCorr, UInt_t cBin, UInt_t vBin,
+                         CorrelParticle_t * const Trigger, CorrelParticle_t * const Associated);
+    
+    Float_t DeltaPhi(Float_t phi1, Float_t phi2);
+    void  ShowStats();
+    
+  private:
+    AliJetCorrelSelector *fSelector;  // user selection object
+    AliJetCorrelMaker *fMaker;        // correlation maker object
+    TString hname, htit;              // histos name&title
+    Bool_t fRecoTrigg;                // is trigger reconstructed
+    TRandom2 fRndm;                   // random number generator
+    UInt_t fNumReal[kMAXNUMCORREL][kMAXCENTBIN], fNumMix[kMAXNUMCORREL][kMAXCENTBIN]; // counters
+    
+    // Output Histograms
+    TH1F *hBinsCentr, *hBinsZVert, *hCentr, *hZVert;         // binning histos
+    TH2F *hTrkITSQA[2], *hTrkTPCQA[2], *hTrkVTXQA[2];        // track QA histos
+    TH3F *hTrkProx[2][kMAXCENTBIN];                          // distance at TPC entrance between tracks
+    TNtuple *ntuParent;                                      // reconstructed parent ntuple
+    TH1F *hTriggPt[kMAXNUMCORREL][kMAXCENTBIN];              // trigger Pt
+    TH3F *hDPhi[2][kMAXNUMCORREL][kMAXCENTBIN][kMAXVERTBIN]; // DeltaPhi correlation histos
+    TH3F *hDEta[2][kMAXNUMCORREL][kMAXCENTBIN][kMAXVERTBIN]; // DeltaEta correlation histos
+    TH3F *hPout[2][kMAXNUMCORREL][kMAXCENTBIN][kMAXVERTBIN]; // Pout correlation histos
+    
+    // disable (make private) copy constructor and assignment operator:
+    AliJetCorrelWriter(const AliJetCorrelWriter&);
+    AliJetCorrelWriter& operator=(const AliJetCorrelWriter&);
+    
+    ClassDef(AliJetCorrelWriter, 1);
+  };
+
+} // namespace
+
+#endif
diff --git a/PWG4/JetCorrel/CorrelDefs.h b/PWG4/JetCorrel/CorrelDefs.h
new file mode 100644 (file)
index 0000000..7eb0f86
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __CORRELDEFS_H__
+#define __CORRELDEFS_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+// CorrelDefs.h is at the top of preprocessor includes,
+// hence we add the general headers here
+//-- Author: Paul Constantin
+
+// C++ headers:
+#include <iostream>
+
+// ROOT headers:
+#include <TROOT.h>
+#include <TSystem.h>
+#include <Riostream.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TLorentzVector.h>
+#include <TVector3.h>
+#include <TClonesArray.h>
+#include <TList.h>
+#include <TMath.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TH3F.h>
+#include <TNtuple.h>
+#include <TString.h>
+#include <TRandom2.h>
+
+// AliRoot headers:
+#include "AliAnalysisManager.h"
+#include "AliAnalysisTaskSE.h"
+#include "AliVEvent.h"
+#include "AliVParticle.h"
+#include "AliKFParticle.h"
+#include "AliKFVertex.h"
+#include "AliESDInputHandler.h"
+#include "AliESDEvent.h"
+#include "AliESDVertex.h"
+#include "AliMultiplicity.h"
+#include "AliESDtrack.h"
+#include "AliAODInputHandler.h"
+#include "AliAODEvent.h"
+#include "AliAODVertex.h"
+#include "AliAODTrack.h"
+
+namespace JetCorrelHD {
+
+  enum FillType_t {real, mixed};
+  enum PoolType_t {triggs, assocs};
+  enum BinType_t  {centr, zvert}; 
+  enum PartType_t {unknown, hadron, proton, kaon, pion, photon, electron, jet, 
+                  dihadron, diphoton, dielectron, dijet};
+
+  const Float_t kEPS = 1.e-6;
+  const Float_t pi = TMath::Pi();
+  const Bool_t kUseAliKF = kFALSE; // reconstruction with AliKFParticle or TLorentzVector
+  const Float_t kZ0MassMean = 91.;
+  const Float_t kZ0MassSig  = 3.;
+  const Float_t kPi0MassMean = 0.140;  // Pi0 mass range for diphoton selection
+  const Float_t kPi0MassSig  = 0.010;
+
+  const UInt_t kDPhiNumBins = 62;       // number of bins in DeltaPhi histos (2pi-bin=0.1)
+  const UInt_t kDEtaNumBins = 40;       // number of bins in DeltaEta histos (3.6-bin=0.1)
+  
+  const UInt_t kMAXNUMCORREL = 3;     // Maximum no of correlations
+  const UInt_t kMAXVERTBIN   = 10;    // Maximum no of vertex bins
+  const UInt_t kMAXCENTBIN   = 3;     // Maximum no of centrality bins
+
+} // namespace declaration
+
+#endif
diff --git a/PWG4/JetCorrel/CorrelKFTrack.cxx b/PWG4/JetCorrel/CorrelKFTrack.cxx
new file mode 100644 (file)
index 0000000..f0018dc
--- /dev/null
@@ -0,0 +1,69 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//__________________________________________________
+// Container class for a track with AliKF parameters
+//-- Author: Paul Constantin
+
+#include "CorrelKFTrack.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+CorrelKFTrack_t::CorrelKFTrack_t() : CorrelParticle_t(), fParam(NULL), fCovar(NULL){
+  // default constructor:
+}
+
+CorrelKFTrack_t::CorrelKFTrack_t(Float_t pt, Float_t p, Float_t e, Float_t m, PartType_t i, 
+                                  Double_t* par, Double_t* cov) : 
+  CorrelParticle_t(pt,p,e,m,i), fParam(par), fCovar(cov){
+  // constructor:
+}
+
+CorrelKFTrack_t::CorrelKFTrack_t(const CorrelKFTrack_t &p) : 
+  CorrelParticle_t(p.fPt,p.fPhi,p.fEta,p.fMass,p.fID), fParam(p.fParam), fCovar(p.fCovar){
+  // copy constructor:
+}
+
+CorrelKFTrack_t* CorrelKFTrack_t::operator=(const CorrelKFTrack_t& rhs){
+  fPt      = rhs.Pt()*rhs.Q();
+  fPhi     = rhs.Phi();
+  fEta     = rhs.Eta();
+  fMass    = rhs.M();
+  fID      = rhs.ID();
+  fParam   = rhs.Param();
+  fCovar   = rhs.Covar();
+  return this;
+}
+
+CorrelKFTrack_t* CorrelKFTrack_t::Copy(){
+  // creates and returns a copy object
+  CorrelKFTrack_t *copy = new CorrelKFTrack_t;
+  copy->fPt    = this->Pt()*this->Q();
+  copy->fPhi   = this->Phi();
+  copy->fEta   = this->Eta();
+  copy->fMass  = this->M();
+  copy->fID    = this->ID();
+  copy->fParam = this->Param();
+  copy->fCovar = this->Covar();
+  return copy;
+}
+
+void CorrelKFTrack_t::Show(){
+  // printout method
+  std::cout<<" Electron pT="<<Pt()<<" phi="<<Phi()<<" eta="<<Eta()<<" m="<<M()<<" id="<<ID()
+          <<" param="<<Param()<<" covar="<<Covar()<<std::endl;
+}
diff --git a/PWG4/JetCorrel/CorrelKFTrack.h b/PWG4/JetCorrel/CorrelKFTrack.h
new file mode 100644 (file)
index 0000000..422807d
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __CORRELKFTRACK_H__
+#define __CORRELKFTRACK_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//__________________________________________________
+// Container class for a track with AliKF parameters
+//-- Author: Paul Constantin
+
+#include "CorrelParticle.h"
+
+namespace JetCorrelHD {
+
+  class CorrelKFTrack_t : public CorrelParticle_t {
+  public:
+
+    CorrelKFTrack_t();
+    CorrelKFTrack_t(Float_t pt, Float_t p, Float_t e, Float_t m, PartType_t i, 
+                   Double_t* par, Double_t* cov);
+    CorrelKFTrack_t(const CorrelKFTrack_t &p);
+    virtual ~CorrelKFTrack_t() {;}
+    CorrelKFTrack_t* operator=(const CorrelKFTrack_t& rhs);
+    virtual CorrelKFTrack_t* Copy();
+   
+    void SetParam(const Double_t* v) {fParam=(Double_t*)v;}
+    void SetCovar(const Double_t* v) {fCovar=(Double_t*)v;}
+    Double_t* Param() const {return fParam;}
+    Double_t* Covar() const {return fCovar;}
+
+    virtual void Show();
+
+  private:
+    Double_t* fParam; // Param[6] = {X, Y, Z, Px, Py, Pz} - position and momentum
+    Double_t* fCovar; // Covar[21] = lower-triangular part of the covariance matrix
+  };
+
+} // namespace declaration
+
+#endif
diff --git a/PWG4/JetCorrel/CorrelList.cxx b/PWG4/JetCorrel/CorrelList.cxx
new file mode 100644 (file)
index 0000000..dfabde7
--- /dev/null
@@ -0,0 +1,129 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//__________________________________________
+// Three classes: a particle list class CorrelList_t with its
+// node class CorrelListNode_t and iterator class CorrelListIter_t
+//-- Author: Paul Constantin
+
+#include "CorrelList.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+const CorrelListNode_t& CorrelListNode_t::operator=(const CorrelListNode_t& rhs){
+  fPart = rhs.fPart;
+  fNext = rhs.fNext;
+  return *this;
+}
+
+void CorrelListIter_t::Check(){
+  // performs bounds check
+  if(HasEnded()){
+    std::cerr<<"CorrelListIter_t::Check() - ERROR: attempt to access null iterator!"<<std::endl; 
+    exit(-1);
+  }
+}  
+
+const CorrelListIter_t& CorrelListIter_t::operator=(const CorrelListIter_t& rhs){
+  fCurr = rhs.fCurr;
+  return *this;
+}
+
+CorrelList_t::CorrelList_t() : 
+  fSize(0), fEvtID(0), fFilled(kFALSE), fPartID(unknown), fPoolID(assocs), fHead(NULL) {
+  // constructor
+}
+
+const CorrelList_t& CorrelList_t::operator=(const CorrelList_t& rhs){
+  fSize   = rhs.Size();
+  fEvtID  = rhs.EvtID();
+  fFilled = rhs.Filled();
+  fPartID = rhs.PartID();
+  fPoolID = rhs.PoolID();
+  fHead   = rhs.Head().Node();
+  return *this;
+}
+
+void CorrelList_t::Push(CorrelParticle_t* p){
+  // Push method creates new node, fills it with data object, hangs list to current fHead
+  // (NULL on first insertion), then moves the fHead to this new node.
+
+  if(!p){std::cerr<<"CorrelList_t::Push() - ERROR: cannot push undefined object!"<<std::endl; exit(-1);}
+  CorrelListNode_t* newNode = new CorrelListNode_t(p,fHead);
+  fHead = newNode;
+  fSize++;
+}
+
+CorrelList_t* CorrelList_t::DeepCopy(){
+  // returns deep copy of caller list
+  // use it to store lists in memory for mixing pools 
+  
+  CorrelList_t *copy = new CorrelList_t;
+  copy->Label(this->PartID(), this->PoolID(), this->EvtID());
+  copy->SetFilled(this->Filled());
+  // fHead and fSize are set by Push() below
+
+  CorrelListIter_t iter = this->Head();
+  while(!iter.HasEnded()){
+    CorrelParticle_t*   gener = iter.Data();
+    CorrelTrack_t*      track = dynamic_cast<CorrelTrack_t*>(gener);
+    CorrelRecoParent_t* recon = dynamic_cast<CorrelRecoParent_t*>(gener);
+    if(track)      copy->Push(track->Copy());
+    else if(recon) copy->Push(recon->Copy());
+    else           copy->Push(gener->Copy());
+    iter.Move();
+  } // iterator loop over caller list
+
+  return copy;
+}
+
+void CorrelList_t::Reset(){
+  // deep delete
+  if(fSize>0){
+    CorrelListIter_t iter = Head();
+    while(!iter.HasEnded()){
+      CorrelListIter_t current = iter; // get current node
+      iter.Move();                     // move iterator to next node
+      if(current.Node())               // redundant deletes happen in same part corr (dihadron)
+       delete current.Node();         // with overlapping pT bins
+      fSize--;
+    }
+  }
+  fEvtID = 0;
+  fFilled = kFALSE;
+  fPartID = unknown;
+  fPoolID = assocs;
+  fHead = NULL;
+}
+
+void CorrelList_t::ShowHead(){
+  // top printout
+  std::cout<<" CorrelList_t("<<this<<") head="<<fHead<<" size="<<Size()<<" filled="<<Filled()<<" evt="<<EvtID()<<" part="<<PartID()<<" pool="<<PoolID()<<std::endl;
+}
+
+void CorrelList_t::Show(){
+  // full printout
+  ShowHead();
+  CorrelListIter_t iter = Head();
+  while(!iter.HasEnded()){
+    std::cout<<"At node("<<iter.Node()<<")";
+    CorrelParticle_t* part = iter.Data();
+    std::cout<<" is particle("<<part<<"):";
+    if(part) part->Show(); else std::cout<<std::endl;
+    iter.Move();
+  }
+}
diff --git a/PWG4/JetCorrel/CorrelList.h b/PWG4/JetCorrel/CorrelList.h
new file mode 100644 (file)
index 0000000..72a6872
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef __CORRELLIST_H__
+#define __CORRELLIST_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//__________________________________________
+// Three classes: a particle list class CorrelList_t with its
+// node class CorrelListNode_t and iterator class CorrelListIter_t
+//-- Author: Paul Constantin
+
+#include "CorrelParticle.h"
+#include "CorrelTrack.h"
+#include "CorrelRecoParent.h"
+
+namespace JetCorrelHD {
+
+  class CorrelList_t;
+  class CorrelListIter_t;
+  
+  class CorrelListNode_t {
+    public:
+      CorrelListNode_t(CorrelParticle_t* p, CorrelListNode_t* n) : fPart(p), fNext(n) {}
+      ~CorrelListNode_t() {if(fPart) delete fPart; fNext = NULL;}
+      const CorrelListNode_t& operator=(const CorrelListNode_t& rhs);
+      CorrelParticle_t* GetData() const {return fPart;}
+      CorrelListNode_t* GetNext() const {return fNext;}
+
+    private:
+      CorrelParticle_t* fPart;
+      CorrelListNode_t* fNext;      
+  };
+
+  class CorrelListIter_t {
+    public:
+      CorrelListIter_t() : fCurr(NULL) {}
+      CorrelListIter_t(CorrelListNode_t* theNode) : fCurr(theNode) {}
+      ~CorrelListIter_t(){;}
+      CorrelListIter_t(const CorrelListIter_t& rhs) : fCurr(rhs.fCurr) {}
+      const CorrelListIter_t& operator=(const CorrelListIter_t& rhs);
+
+      Bool_t HasEnded() const {return (fCurr==NULL);}
+      void Check();
+      void Move() {Check(); fCurr=fCurr->GetNext();}
+      CorrelListNode_t* Node() {Check(); return fCurr;}
+      CorrelParticle_t* Data() {Check(); return fCurr->GetData();}
+
+    private:
+      CorrelListNode_t* fCurr; // iterator "current node"
+  };
+
+  class CorrelList_t : public TObject {
+    public:
+      CorrelList_t();
+      virtual ~CorrelList_t() {Reset();}
+      void Reset();
+      const CorrelList_t& operator=(const CorrelList_t& rhs); // makes shallow copy
+      CorrelList_t* DeepCopy();                     // use this method to get a deep copy
+
+      void Push(CorrelParticle_t* p);
+      UInt_t Size() const {return fSize;}
+      UInt_t EvtID() const {return fEvtID;}
+      PartType_t PartID() const {return fPartID;}
+      PoolType_t PoolID() const {return fPoolID;}
+      Bool_t Filled() const {return fFilled;}
+      void SetFilled(Bool_t f) {fFilled=f;}
+      void Label(PartType_t p, PoolType_t l, UInt_t e) {fPartID=p; fPoolID=l; fEvtID=e;}
+      CorrelListIter_t Head() const {return CorrelListIter_t(fHead);}
+      void ShowHead();
+      void Show();
+
+    private:
+      UInt_t fSize;             // list size
+      UInt_t fEvtID;            // event ID
+      Bool_t fFilled;           // is filled
+      PartType_t fPartID;       // particle ID
+      PoolType_t fPoolID;       // pool type
+      CorrelListNode_t* fHead;  // list head
+
+      CorrelList_t(const CorrelList_t& rhs);        // forbid copy constructor
+  };
+
+} // namespace declaration
+
+#endif
diff --git a/PWG4/JetCorrel/CorrelParticle.cxx b/PWG4/JetCorrel/CorrelParticle.cxx
new file mode 100644 (file)
index 0000000..046bd08
--- /dev/null
@@ -0,0 +1,52 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//________________________________________________
+// Main container class - stores generic particle.
+//-- Author: Paul Constantin
+
+#include "CorrelParticle.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+CorrelParticle_t::CorrelParticle_t() : fPt(-999.), fPhi(-999.), fEta(-999.), fMass(-999.), fID(unknown){
+  // default constructor
+}
+
+CorrelParticle_t::CorrelParticle_t(Float_t pt, Float_t p, Float_t t, Float_t m, PartType_t i) : fPt(pt), fPhi(p), fEta(t), fMass(m), fID(i){
+  // constructor
+}
+
+CorrelParticle_t::CorrelParticle_t(const CorrelParticle_t& p) : fPt(p.fPt), fPhi(p.fPhi), fEta(p.fEta), fMass(p.fMass), fID(p.fID){
+  // copy constructor
+}
+
+CorrelParticle_t* CorrelParticle_t::Copy(){
+  // creates and returns a deep object copy
+  CorrelParticle_t *copy = new CorrelParticle_t;
+  copy->fPt    = this->Pt()*this->Q();
+  copy->fPhi   = this->Phi();
+  copy->fEta   = this->Eta();
+  copy->fMass  = this->M();
+  copy->fID    = this->ID();
+  return copy;
+}
+
+void CorrelParticle_t::Show(){
+  // printout method
+  std::cout<<" Particle pT="<<Pt()<<" phi="<<Phi()<<" eta="<<Eta()<<" m="<<M()<<" id="<<ID()<<std::endl;
+}
diff --git a/PWG4/JetCorrel/CorrelParticle.h b/PWG4/JetCorrel/CorrelParticle.h
new file mode 100644 (file)
index 0000000..aeb6c87
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef __CORRELPARTICLE_H__
+#define __CORRELPARTICLE_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//________________________________________________
+// Main container class - stores generic particle.
+//-- Author: Paul Constantin
+
+#include "CorrelDefs.h"
+
+namespace JetCorrelHD {
+
+  class CorrelParticle_t {        
+  public:
+    CorrelParticle_t();
+    CorrelParticle_t(Float_t pt, Float_t p, Float_t t, Float_t m, PartType_t i);
+    CorrelParticle_t(const CorrelParticle_t& p);
+    virtual ~CorrelParticle_t() {;}
+    virtual CorrelParticle_t* Copy();
+
+    // data setters
+    void SetPt(Float_t v)    {fPt=v;}
+    void SetPhi(Float_t v)   {fPhi=v;}
+    void SetEta(Float_t v)   {fEta=v;}
+    void SetMass(Float_t v)  {fMass=v;}
+    void SetID(PartType_t v) {fID=v;}
+    
+    // data getters
+    virtual Float_t Pt()    const {return TMath::Abs(fPt);}
+    virtual Float_t Phi()   const {return fPhi;}
+    virtual Float_t Eta()   const {return fEta;}    
+    virtual Float_t M()     const {return fMass;}
+    virtual PartType_t ID() const {return fID;}
+
+    // derived data getters
+    virtual Short_t Q()     const {return (Pt()>0)?(Short_t(fPt/Pt())):(-99);}
+    virtual Float_t Theta() const {return 2.*TMath::ATan(TMath::Exp(-fEta));}
+    virtual Float_t SinT()  const {return TMath::Sin(Theta());}
+    virtual Float_t TanT()  const {return TMath::Tan(Theta());}
+    virtual Float_t Px()    const {return Pt()*TMath::Cos(fPhi);}
+    virtual Float_t Py()    const {return Pt()*TMath::Sin(fPhi);}
+    virtual Float_t Pz()    const {return (TMath::Abs(TanT())>0)?(Pt()/TanT()):(-99.);}
+    virtual Float_t P()     const {return (TMath::Abs(SinT())>0)?(Pt()/SinT()):(-99.);}
+    virtual Float_t E()     const {return TMath::Sqrt(P()*P()+fMass*fMass);}
+    virtual Float_t Et()    const {return TMath::Sqrt(Pt()*Pt()+fMass*fMass);}
+    virtual Float_t Y()     const {return 0.5*TMath::Log((E()+Pz())/(E()-Pz()));}
+
+    virtual void Show();
+    
+  protected:
+    Float_t fPt;    // pt; store charge as its sign
+    Float_t fPhi;   // phi
+    Float_t fEta;   // eta
+    Float_t fMass;  // mass
+    PartType_t fID; // ID
+  };
+
+} // namespace declaration
+
+#endif
diff --git a/PWG4/JetCorrel/CorrelRecoParent.cxx b/PWG4/JetCorrel/CorrelRecoParent.cxx
new file mode 100644 (file)
index 0000000..f14a8e1
--- /dev/null
@@ -0,0 +1,152 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//______________________________________________________________________________
+// Container class for reconstructed parents. Reconstruction method uses
+// AliKFParticle or TLorentzVector as indicated by kUseAliKF set in CorrelDefs.h
+//-- Author: Paul Constantin
+
+#include "CorrelRecoParent.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+CorrelRecoParent_t::CorrelRecoParent_t() :
+  CorrelParticle_t(), fAssym(-999.), fOpenAng(-999.), fEVT(NULL){
+  // default constructor
+}
+
+CorrelRecoParent_t* CorrelRecoParent_t::operator=(const CorrelRecoParent_t& rhs){
+  fPt      = rhs.Pt()*rhs.Q();
+  fPhi     = rhs.Phi();
+  fEta     = rhs.Eta();
+  fMass    = rhs.M();
+  fID      = rhs.ID();
+  fAssym   = rhs.Assym();
+  fOpenAng = rhs.OpenAng();
+  fEVT     = rhs.Evt();
+  return this;
+}
+
+CorrelRecoParent_t* CorrelRecoParent_t::Copy(){
+  // creates and returns deep object copy
+  CorrelRecoParent_t *copy = new CorrelRecoParent_t;
+  copy->fPt      = this->Pt()*this->Q();
+  copy->fPhi     = this->Phi();
+  copy->fEta     = this->Eta();
+  copy->fMass    = this->M();
+  copy->fID      = this->ID();
+  copy->fAssym   = this->Assym();
+  copy->fOpenAng = this->OpenAng();
+  copy->fEVT     = this->Evt();
+  return copy;
+}
+
+Bool_t CorrelRecoParent_t::Reconstruct(CorrelParticle_t *p1, CorrelParticle_t *p2){
+  // main method for parent reconstruction
+
+  if(p1->ID()==photon && p2->ID()==photon) fID = diphoton;
+  else if(p1->ID()==electron && p2->ID()==electron) fID = dielectron;
+  else if(p1->ID()==jet && p2->ID()==jet) fID = dijet;
+  else fID = dihadron;
+  
+  if(fID==dielectron && kUseAliKF){
+    // code for parent reconstruction based on AliKFParticle:
+    if(!fEVT)
+      {std::cerr<<"CorrelRecoParent_t::Reconstruct - undefined event"<<std::endl; exit(-1);}
+    AliESDEvent* fESD = dynamic_cast<AliESDEvent*>(fEVT);
+    if(!fESD)
+      {std::cerr<<"CorrelRecoParent_t::Reconstruct - failed event casting"<<std::endl; exit(-1);}
+    CorrelKFTrack_t* e1 = dynamic_cast<CorrelKFTrack_t*>(p1);
+    CorrelKFTrack_t* e2 = dynamic_cast<CorrelKFTrack_t*>(p2);
+    if(!e1 || !e2)
+      {std::cerr<<"CorrelRecoParent_t::Reconstruct - failed particle casting"<<std::endl; exit(-1);}
+
+    AliKFVertex primVtx(*(fESD->GetPrimaryVertex()));
+    if(primVtx.GetNContributors()<=0) return kFALSE;
+    AliKFParticle::SetField(fESD->GetMagneticField());
+    AliKFParticle* pKF1 = new AliKFParticle; AliKFParticle* pKF2 = new AliKFParticle;
+    if(e1->Param()==NULL || e1->Covar()==NULL || e2->Param()==NULL || e2->Covar()==NULL)
+      {std::cerr<<"CorrelRecoParent_t::Reconstruct - null parameter pointer"<<std::endl; exit(-1);}      
+    pKF1->Create(e1->Param(), e1->Covar(), e1->Q(), 11*e1->Q());  // AliKFParticle uses Pythia PIDs
+    pKF2->Create(e2->Param(), e2->Covar(), e2->Q(), 11*e2->Q());  // so electron=11 and positron=-11
+
+    AliKFParticle DiElectron(*pKF1,*pKF2);
+    DiElectron.SetMassConstraint(kZ0MassMean,kZ0MassSig); // the dielectron mass cut (1st=mass,2nd=sigma)
+    primVtx += DiElectron;
+    DiElectron.SetProductionVertex(primVtx);
+    Double_t chi2=100000.;
+    if(DiElectron.GetNDF()!=0) chi2=DiElectron.GetChi2()/DiElectron.GetNDF();
+    if(chi2>3.5) return kFALSE; // the dielectron vertex cut
+
+    Float_t px = DiElectron.GetPx();
+    Float_t py = DiElectron.GetPy();
+    Float_t pz = DiElectron.GetPz();
+    Float_t ener = DiElectron.GetE();
+    Float_t theta = TMath::ATan(TMath::Sqrt(px*px+py*py)/pz);
+    fPt = TMath::Sqrt(px*px+py*py)*Float_t(p1->Q()*p2->Q());
+    fPhi = TMath::ATan(py/px);
+    fEta = -TMath::Log(TMath::Tan(theta/2.));
+    fMass = ener - TMath::Sqrt(px*px+py*py+pz*pz);
+    fAssym = TMath::Abs((e1->P()-e2->P())/(e1->P()+e2->P()));
+    fOpenAng = -999.; // compute opening angle
+
+    delete pKF1; delete pKF2;
+    
+  } else {
+
+    // code for parent reconstruction based on TLorentzVector:
+    TLorentzVector part1, part2, fPartSum;
+    part1.SetPxPyPzE(p1->Px(), p1->Py(), p1->Pz(), p1->E());
+    part2.SetPxPyPzE(p2->Px(), p2->Py(), p2->Pz(), p2->E());
+
+    fPartSum.SetPxPyPzE(0.,0.,0.,0.);
+    fPartSum = part1 + part2;
+    Float_t pT = fPartSum.Pt();
+    if(TMath::Abs(p1->Q())>0 && TMath::Abs(p2->Q())>0)
+      fPt = pT*Float_t(p1->Q()*p2->Q()); // fPt stores charge as its sign
+    else
+      fPt = pT;
+    fPhi = fPartSum.Phi();
+    fEta = fPartSum.Eta();
+    fMass = fPartSum.M();
+    fAssym = TMath::Abs((p1->P()-p2->P())/(p1->P()+p2->P()));
+    fOpenAng = part1.Angle(part2.Vect());
+    if(NotInMass(fID,fMass)) return kFALSE;
+  }
+  
+  return kTRUE;
+}
+
+Bool_t CorrelRecoParent_t::NotInMass(PartType_t pID, Float_t mass){
+  // THE MASS RANGES SHOULD PROBABLY BE MOMENTUM AND CENTRALITY DEPENDENT!!!
+  if(pID!=dielectron && pID!=diphoton) return kFALSE;
+
+  const Float_t kZ0MassMin = kZ0MassMean - 3*kZ0MassSig;
+  const Float_t kZ0MassMax = kZ0MassMean + 3*kZ0MassSig;
+  const Float_t kPi0MassMin = kPi0MassMean - 3*kPi0MassSig;
+  const Float_t kPi0MassMax = kPi0MassMean + 3*kPi0MassSig;
+  if(pID==dielectron && mass>kZ0MassMin && mass<kZ0MassMax) return kFALSE;
+  if(pID==diphoton && mass>kPi0MassMin && mass<kPi0MassMax) return kFALSE;
+
+  return kTRUE;
+}
+
+void CorrelRecoParent_t::Show(){
+  // printout method
+  std::cout<<" RecoParent pT="<<Pt()<<" phi="<<Phi()<<" eta="<<Eta()<<" m="<<M()<<" id="<<ID()
+          <<" assym="<<Assym()<<" open="<<OpenAng()<<std::endl;
+}
diff --git a/PWG4/JetCorrel/CorrelRecoParent.h b/PWG4/JetCorrel/CorrelRecoParent.h
new file mode 100644 (file)
index 0000000..cdc6c61
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef __CORRELRECOPARENT_H__
+#define __CORRELRECOPARENT_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//______________________________________________________________________________
+// Container class for reconstructed parents. Reconstruction method uses
+// AliKFParticle or TLorentzVector as indicated by kUseAliKF set in CorrelDefs.h
+//-- Author: Paul Constantin
+
+#include "CorrelParticle.h"
+#include "CorrelKFTrack.h"
+
+namespace JetCorrelHD {
+   
+  class CorrelRecoParent_t : public CorrelParticle_t {      
+  public:
+    CorrelRecoParent_t();
+    virtual ~CorrelRecoParent_t() {;}
+    CorrelRecoParent_t* operator=(const CorrelRecoParent_t& rhs);
+    virtual CorrelRecoParent_t* Copy();
+
+    Float_t Assym()   const {return fAssym;}
+    Float_t OpenAng() const {return fOpenAng;}
+    AliVEvent* Evt()  const {return fEVT;}
+    Bool_t Reconstruct(CorrelParticle_t* p1, CorrelParticle_t* p2);
+    void SetEvent(AliVEvent * const v) {fEVT=v;}
+
+    virtual void Show();
+    
+  private:
+    Float_t fAssym;   // children energy assymetry
+    Float_t fOpenAng; // children opening angle
+    AliVEvent* fEVT;  // input event (ESD or AOD)
+
+    // disable (make private) the copy constructor
+    CorrelRecoParent_t(const CorrelRecoParent_t &p);
+
+    Bool_t NotInMass(PartType_t ID, Float_t mass);
+  };
+  
+} // namespace declaration
+
+#endif
diff --git a/PWG4/JetCorrel/CorrelTrack.cxx b/PWG4/JetCorrel/CorrelTrack.cxx
new file mode 100644 (file)
index 0000000..04cf8a6
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id: $ */
+
+//_____________________________________________________
+// Container class for global tracks
+// Use CorrelKFTrack_t to reconstruct parent with AliKF
+//-- Author: Paul Constantin
+
+#include "CorrelTrack.h"
+
+using namespace std;
+using namespace JetCorrelHD;
+
+CorrelTrack_t::CorrelTrack_t() : CorrelParticle_t(), fTPCx(-999.), fTPCy(-999.), fTPCz(-999.) {
+  // default constructor:
+}
+
+CorrelTrack_t::CorrelTrack_t(Float_t pt, Float_t p, Float_t e, Float_t m, PartType_t i, Float_t x, Float_t y, Float_t z) : 
+  CorrelParticle_t(pt,p,e,m,i), fTPCx(x), fTPCy(y), fTPCz(z){
+  // constructor:
+}
+
+CorrelTrack_t::CorrelTrack_t(const CorrelTrack_t &p) : 
+  CorrelParticle_t(p.fPt,p.fPhi,p.fEta,p.fMass,p.fID), fTPCx(p.fTPCx), fTPCy(p.fTPCy), fTPCz(p.fTPCz) {
+  // copy constructor:
+}
+
+CorrelTrack_t* CorrelTrack_t::Copy(){
+  // creates and returns a deep object copy
+  CorrelTrack_t *copy = new CorrelTrack_t;
+  copy->fPt    = this->Pt()*this->Q();
+  copy->fPhi   = this->Phi();
+  copy->fEta   = this->Eta();
+  copy->fMass  = this->M();
+  copy->fID    = this->ID();
+  copy->fTPCx  = this->X();
+  copy->fTPCy  = this->Y();
+  copy->fTPCz  = this->Z();
+  return copy;
+}
+
+Float_t CorrelTrack_t::Dist(CorrelTrack_t * const that) {
+  return TMath::Sqrt((this->X()-that->X())*(this->X()-that->X()) +
+                    (this->Y()-that->Y())*(this->Y()-that->Y()) +
+                    (this->Z()-that->Z())*(this->Z()-that->Z()));
+}
+
+void CorrelTrack_t::Show(){
+  std::cout<<" Track pT="<<Pt()<<" phi="<<Phi()<<" eta="<<Eta()<<" m="<<M()<<" id="<<ID()
+          <<" x="<<X()<<" y="<<Y()<<" z="<<Z()<<std::endl;
+}
diff --git a/PWG4/JetCorrel/CorrelTrack.h b/PWG4/JetCorrel/CorrelTrack.h
new file mode 100644 (file)
index 0000000..470fbe3
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef __CORRELTRACK_H__
+#define __CORRELTRACK_H__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+/* $Id:  $ */
+
+//_____________________________________________________
+// Container class for global tracks
+// Use CorrelKFTrack_t to reconstruct parent with AliKF
+//-- Author: Paul Constantin
+#include "CorrelParticle.h"
+
+namespace JetCorrelHD {
+
+  class CorrelTrack_t : public CorrelParticle_t {
+  public:
+
+    CorrelTrack_t();
+    CorrelTrack_t(Float_t pt, Float_t p, Float_t e, Float_t m, PartType_t i, Float_t x, Float_t y, Float_t z);
+    CorrelTrack_t(const CorrelTrack_t &p);
+    virtual ~CorrelTrack_t() {;}
+    virtual CorrelTrack_t* Copy();
+   
+    Float_t X() const {return fTPCx;}
+    Float_t Y() const {return fTPCy;}
+    Float_t Z() const {return fTPCz;}
+    Float_t Dist(CorrelTrack_t * const trk);
+
+    void SetTPCEntry(Float_t x, Float_t y, Float_t z) {fTPCx=x; fTPCy=y; fTPCz=z;}
+    virtual void Show();
+
+  private:
+    Float_t fTPCx;   // x-coord TPC entrance
+    Float_t fTPCy;   // y-coord TPC entrance
+    Float_t fTPCz;   // z-coord TPC entrance
+  };
+
+} // namespace declaration
+
+#endif
diff --git a/PWG4/JetCorrel/README b/PWG4/JetCorrel/README
new file mode 100644 (file)
index 0000000..2ce0165
--- /dev/null
@@ -0,0 +1,130 @@
+The libJetCorrel library implements generic two-particle correlations between 
+a "trigger" and an "associated" particle, where these to can be any physical 
+particle ((un)identified hadron, photon, pi0, (di)electron, jet, etc.). It can 
+run several correlations at the same time with the advantage of keeping the 
+minimum number of mixing pools in memory (for eg., if one runs di-hadron and 
+pi0-hadron correlations, only one associated pool of hadrons is stored).
+
+The running/JetCorrelSelector.C macro that accompanies the main running macro 
+instantiates and returns the AliJetCorrelSelector class (see below) that sets 
+all the input parameters needed for running. The parameter names should be 
+obvious. Comments:
+(a) the binning (vertex, centrality/multiplicity, trigger&associated pT) is
+loaded thru simple dynamic arrays (originally STL vectors, but forbidden in
+AliRoot), hence not only they values, but their number can be changed;
+(b) the CorrelTypes dynamic array has the same property and allows the running
+of many types of "trigger"-"associated" correlations simultaneously (thus
+reducing the CPU&memory since most correlations typically share the same assoc
+types - hadrons). Finally, adding a new type of correlation to JetCorrel implies
+only two new methods: one in AliJetCorrelSelector that reads and applies the
+cuts specific to any new type of particle and another one in AliJetCorrelReader
+that fills the internal lists of that particle type. JetCorrel then takes care
+automatically of all the rest (mixing, histogramming, etc.) because for it
+the new list becomes just a trigger and/or associated list... 
+
+Analysis Task Classes:
+(1) AliAnalysisTaskJetCorrel class
+Main class which inherits from AliAnalysisTaskSE and runs the show by delegating
+sub-tasks to the following classes: 
+(2) AliJetCorrelSelector class
+Is the class that reads user-defined selections and propagates them thru the 
+rest of the code. The macro JetCorrelSelector.C instantiates it and sets:
+the correlations to be run, the centrality/vertex/momentum binnings and various
+selections and cuts to be applied.
+(3) AliJetCorrelMaker class
+Reads the list of correlations to be run from the Selector and builds the
+interface needed to manipulate them.         
+(4) AliJetCorrelReader class
+Reads the list of selections and cuts from the Selector and builds the two 
+trigger and associated CorrelList_t lists for one event and one correlation.
+For example, if in the current run we ask for hadron-hadron, Z0-hadron and
+gamma-hadron, then 3 trigger lists but only 1 associated list are built each
+event. 
+(5) AliJetCorrelWriter class
+Reads the list of binnings from the Selector and books the arrays of output 
+correlation histograms; it also has methods for filling them.
+(6) AliJetCorrelMixer class
+Manages the event mixing pools. The mixing method is rolling buffer (hence is
+kept in memory) and the mixing pools are 4-dimensional static arrays of 
+2-dimensional dynamic lists; the 4 static dimensions correspond to pool type
+(triggs/assocs), pool type bin, vertex bin, centrality bin and they are all 
+fixed at task initialization time (via the Selector). Then, each of these pools 
+is a TList of events, each event being a CorrelList_t of particles (CorrelParticle_t 
+or upper class). Taking into account that sizeof(CorrelParticle_t)=20b and 
+sizeof(CorrelListNode_t)=8b (two pointers are used by CorrelList_t to store a 
+particle) one gets the pool sizes: 
+- for p-p analyses: 
+2(type)x2(centrality)x10(vertex)x20(events)x30(particles)x28b<0.7Mb
+- for Pb-Pb analyses:
+2(type)x7(centrality)x10(vertex)x20(events)x3000(particles)x28b<250Mb
+Caveats: these values are for one associated pool (which dominates) and consider
+rather high stored particle multiplicities per event (3000 associates per event).
+For eg., in jet induced correlation studies, we are interested only in pT>1GeV/c.
+
+Particle Container Classes:
+(1) CorrelParticle_t class.
+Base particle for correlations: implements only the essential kinematics needed 
+for correlations. Since this is the object to go into the mixing pools (and into 
+the memory) DON'T CLUTTER IT!!! As it stands now, its size is 20b (4xFloat_t+
+1xUInt_t) on 32b machines. Also, it MUST NOT inherit from TObject since this will 
+impose an overhead of 12b (>30%) by inheritance, a burden that cannot be carried 
+in Pb-Pb analysis. BTW, this is the main reason to have CorrelList_t instead of
+another TList for particles.
+(2) CorrelList_t class.
+A custom-designed single-linked list class written because the main two options
+(STL and ROOT) couldn't be used - STL because is not allowed in AliRoot and ROOT
+because its lists (TList/TClonesArray) store only objects of classes inheriting
+from TObject (thus inheriting a significant overhead for small particle objects
+like CorrelParticle_t). Note that CorrelList_t itself does inherit from TObject
+in order to be storeable in a TList (our mixing pools are TLists of CorrelLists)
+but this is OK since we have one CorrelList_t per event, not per particle. There
+are two helper classes: CorrelListNode_t for the data node and CorrelListIter_t
+provides utilities for list iteration. See CorrelList.h for interface description.
+(3) CorrelTrack_t class.
+Inherits from CorrelParticle_t and allows storage of global track parameters 
+(TPC entrance coordinates) to be used in pair cuts (to eliminate detector 
+resolution effects). Whether this cut (and hence this class altogether) will be
+used remains to be seen since it is possible that such effects can be eliminated 
+thru single-track cuts (like high number of TPC clusters) - highly desireable 
+because CorrelTrack_t would additionally store 12b for something like TPC entrance 
+point (x,y,z).Note: any cut applied to the same event pairs must be applied to 
+mixed event pairs (hence pair cut parameters must be stored in the mixing pools).
+On the other hand the high number of TPC clusters cut reduces the efficiency...
+(4) CorrelRecoParent_t class.
+Inherits from CorrelParticle_t and reconstructs (using TLorentzVector) parent
+particles from two children; intended for diphotons (pi0), dielectrons (Z0), etc.
+In the case of dielectrons (Z0), a reconstruction via the AliKFParticle class is
+provided since this also allows for a vertex cut on the reconstructed mother (see
+the CorrelKFTrack_t class). To switch between a TLorentzVector based reconstruction
+and a AliKFParticle based reconstruction, set kUseAliKF in CorrelDefs.h.
+(5) CorrelKFTrack_t class.
+Inherits from CorrelParticle_t and allows storage of ESD track parameters needed
+as input by the AliKFParticle to reconstruct the parent particle.
+
+CorrelList_t class implements a single-linked list with pointer to head node 
+(last inserted). It is labelled by 3 identifiers: the event number EvtID, the 
+pool type (triggs/assocs) PoolID, and the particle type PartID. Interface:
+ - CorrelList_t() creates empty list; ~CorrelList_t() destroys the list;
+ - Clear() deletes all data nodes but leaves list defined (and empty);
+ - Push() adds a new data node at head;
+ - Head() returns iterator to head node;
+ - assignment operator = performs a deep list copy;
+ - Size() returns the current size of the list;
+ - Filled() and SetFilled() gets/sets a boolean with the current fill status;
+ - EvtID(), PartID(), and PoolID() return the list identifiers;
+ - Label() sets the above list identifiers.
+CorrelList_t must inherit from TObject to be storable in a TList - the mixing 
+pool becomes a TList of CorrelList. Access to the list data is made thru the 
+iterator class.
+CorrelListIter_t class implements an iterator for CorrelList_t. Interface:
+ - hasEnded() returns true if current node terminates list;
+ - Move() moves iterator to next node in list;
+ - Node() returns the current node pointed to by the iterator;
+ - Data() returns the data contained in the current node;
+
+
+TO DO LIST AS OF 24 MARCH 2009:
+(1) finish the macros for output merging, acceptance study and correlation
+    building in the analysis directory;
+(2) add a dynamic array CorrelArray_t implementation for the particle lists.
+(3) implement the official AliRoot logging (AliDebug/AliError/etc)
\ No newline at end of file
index aa8ff70183a189c76d0efbae2b10c1f8afdbce52..eee666fff4c042da831dab0a5e78434e9b3adfc6 100644 (file)
@@ -69,6 +69,10 @@ ifneq ($(JETAN_INCLUDE),)
   ALICEINC += -I../$(JETAN_INCLUDE)
 endif
 
+ifneq ($(PWG4JetCorrel_INCLUDE),)
+  ALICEINC += -I../$(PWG4JetCorrel_INCLUDE)
+endif
+
 
 # only if no par file was loaded before
 #ifeq ($(ALICEINC),-I.)
diff --git a/PWG4/PROOF-INF.PWG4JetCorrel/BUILD.sh b/PWG4/PROOF-INF.PWG4JetCorrel/BUILD.sh
new file mode 100755 (executable)
index 0000000..fc9490a
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+make 
diff --git a/PWG4/PROOF-INF.PWG4JetCorrel/SETUP.C b/PWG4/PROOF-INF.PWG4JetCorrel/SETUP.C
new file mode 100644 (file)
index 0000000..09debe0
--- /dev/null
@@ -0,0 +1,11 @@
+void SETUP()
+{
+   gSystem->Load("libPWG4JetCorrel");
+
+   // Set the Include paths
+   gSystem->SetIncludePath("-I$ROOTSYS/include -IPWG4JetCorrel");
+   gROOT->ProcessLine(".include PWG4JetCorrel/JetCorrel");
+
+   // Set our location, so that other packages can find us
+   gSystem->Setenv("PWG4JetCorrel_INCLUDE", "PWG4JetCorrel/JetCorrel");
+}
diff --git a/PWG4/PWG4JetCorrelLinkDef.h b/PWG4/PWG4JetCorrelLinkDef.h
new file mode 100644 (file)
index 0000000..69a8956
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef __CINT__
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class JetCorrelHD::AliJetCorrelMaker+;
+#pragma link C++ class JetCorrelHD::AliJetCorrelSelector+;
+#pragma link C++ class JetCorrelHD::AliJetCorrelReader+;
+#pragma link C++ class JetCorrelHD::AliJetCorrelMixer+;
+#pragma link C++ class JetCorrelHD::AliJetCorrelWriter+;
+#pragma link C++ class JetCorrelHD::AliAnalysisTaskJetCorrel+;
+
+#endif
diff --git a/PWG4/libPWG4JetCorrel.pkg b/PWG4/libPWG4JetCorrel.pkg
new file mode 100644 (file)
index 0000000..def58a0
--- /dev/null
@@ -0,0 +1,21 @@
+#-*- Mode: Makefile -*-
+
+SRCS = JetCorrel/AliAnalysisTaskJetCorrel.cxx  \
+       JetCorrel/AliJetCorrelMaker.cxx JetCorrel/AliJetCorrelSelector.cxx JetCorrel/AliJetCorrelReader.cxx JetCorrel/AliJetCorrelMixer.cxx JetCorrel/AliJetCorrelWriter.cxx \
+       JetCorrel/CorrelList.cxx JetCorrel/CorrelParticle.cxx JetCorrel/CorrelRecoParent.cxx JetCorrel/CorrelTrack.cxx JetCorrel/CorrelKFTrack.cxx
+
+HDRS:= JetCorrel/CorrelDefs.h $(SRCS:.cxx=.h) 
+
+DHDR:= PWG4JetCorrelLinkDef.h
+
+EXPORT:=$(SRCS:.cxx=.h)
+
+EINCLUDE:= PWG4/JetCorrel ANALYSIS
+
+ifeq (win32gcc,$(ALICE_TARGET))
+PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) -lSTEERBase \
+                         -lESD -lAOD -lANALYSIS -lANALYSISalice \
+                         -L$(ROOTLIBDIR) -lEG
+endif
+
+
diff --git a/PWG4/macros/AddTaskJetCorrel.C b/PWG4/macros/AddTaskJetCorrel.C
new file mode 100644 (file)
index 0000000..3789a2e
--- /dev/null
@@ -0,0 +1,36 @@
+AliAnalysisTaskJetCorrel *AddTaskJetCorrel(){
+  //get the current analysis manager
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if(!mgr) {
+    ::Error("AddTaskJetCorrel", "No analysis manager found.");
+    return NULL;
+  }
+  if(!mgr->GetInputEventHandler()) {
+    ::Error("AddTaskJetCorrel", "This task requires an input event handler.");
+    return NULL;
+  }
+  TString inputDataType = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
+  if(inputDataType.CompareTo("ESD")!=0) {
+    ::Error("AddTaskJetCorrel", "This task uses ESD as input.");
+    return NULL;
+  }
+
+  using namespace JetCorrelHD;
+  gROOT->LoadMacro("$ALICE_ROOT/PWG4/macros/ConfigJetCorrel.C");
+  AliJetCorrelSelector* Selector = JetCorrelSelector();
+  AliAnalysisTaskJetCorrel *task = new AliAnalysisTaskJetCorrel(Selector);
+
+  //add the task to the current analysis manager
+  mgr->AddTask(task);
+  //----------------------
+  //create data containers
+  //----------------------
+  AliAnalysisDataContainer *output = 
+    mgr->CreateContainer("JetCorrelHistos", TList::Class(),
+                        AliAnalysisManager::kOutputContainer,"JetCorrelHistos.root");    
+  mgr->ConnectInput(task,0,mgr->GetCommonInputContainer());
+  mgr->ConnectOutput(task,0,mgr->GetCommonOutputContainer());
+  mgr->ConnectOutput(task,1,output);
+  
+  return task;
+}
diff --git a/PWG4/macros/ConfigJetCorrel.C b/PWG4/macros/ConfigJetCorrel.C
new file mode 100644 (file)
index 0000000..d0aee6e
--- /dev/null
@@ -0,0 +1,43 @@
+AliJetCorrelSelector* JetCorrelSelector(){
+
+  ///////////////////////////////////
+  // set correlation input parameters
+  ///////////////////////////////////
+  // set generic selections:
+  UInt_t PoolDepth = 10;
+  UInt_t CorrelTypes[] = {0};
+  Float_t TriggBins[] = {5.,7.,10.,15.,25.};
+  Float_t AssocBins[] = {0.3,0.5,1.,2.,5.,7.};
+  Float_t CentrBins[] = {0.,50.,200.,500.};
+  Float_t ZVertBins[] = {-30.,-15.,-5.,-1.,1.,5.,15.,30.};
+  // set track selections:
+  Bool_t ITSRefit = kTRUE;
+  Bool_t TPCRefit = kTRUE;
+  Bool_t TRDRefit = kTRUE;          // used only for electron tracks
+  UInt_t MinNClusITS = 1;
+  UInt_t MinNClusTPC = 50; 
+  Float_t MaxITSChi2 = 3.5;         // max track Chi2 per ITS cluster
+  Float_t MaxTPCChi2 = 3.5;         // max track Chi2 per TPC cluster
+  Float_t MaxNsigVtx = 3.5;         // max dist to primary vertex
+  Bool_t RejectKinkChild = kTRUE;   // reject track comming from a kink
+
+  //////////////////////////////////
+  // load them into selector object:
+  //////////////////////////////////
+  AliJetCorrelSelector* Selector = new AliJetCorrelSelector();
+  Selector->SetPoolDepth(PoolDepth);
+  Selector->SetCorrelTypes(sizeof(CorrelTypes)/sizeof(Int_t),CorrelTypes);
+  Selector->SetBinningTrigg(sizeof(TriggBins)/sizeof(Float_t),TriggBins);
+  Selector->SetBinningAssoc(sizeof(AssocBins)/sizeof(Float_t),AssocBins);
+  Selector->SetBinningCentr(sizeof(CentrBins)/sizeof(Float_t),CentrBins);
+  Selector->SetBinningZvert(sizeof(ZVertBins)/sizeof(Float_t),ZVertBins);
+  Selector->SetITSRefit(ITSRefit); Selector->SetTPCRefit(TPCRefit);
+  Selector->SetTRDRefit(TRDRefit);
+  Selector->SetMinNClusITS(MinNClusITS); Selector->SetMinNClusTPC(MinNClusTPC);
+  Selector->SetMaxITSChi2(MaxITSChi2); Selector->SetMaxTPCChi2(MaxTPCChi2);
+  Selector->SetMaxNsigmaVtx(MaxNsigVtx);
+  Selector->SetRejectKinkChild(RejectKinkChild);
+  Selector->Print();
+
+  return Selector;
+}