]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Second attempt to add UNICOR. In its present version it is
authormisko <misko@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 10 Jun 2009 14:30:12 +0000 (14:30 +0000)
committermisko <misko@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 10 Jun 2009 14:30:12 +0000 (14:30 +0000)
increadibly compatible with the ALICE computing rules.

27 files changed:
PWG2/CMakeLists.txt
PWG2/CMake_libPWG2unicor.txt [new file with mode: 0644]
PWG2/PWG2unicorLinkDef.h
PWG2/UNICOR/AliAnalysisTaskUnicor.cxx [new file with mode: 0644]
PWG2/UNICOR/AliAnalysisTaskUnicor.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnal.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnal.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalCorrel.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalCorrel.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalGlobal.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalGlobal.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalHighpt.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalHighpt.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalPtfluc.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalPtfluc.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalSingle.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorAnalSingle.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorEvent.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorEvent.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorEventAliceESD.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorEventAliceESD.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorHN.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorHN.h [new file with mode: 0644]
PWG2/UNICOR/AliUnicorPair.cxx [new file with mode: 0644]
PWG2/UNICOR/AliUnicorPair.h [new file with mode: 0644]
PWG2/UNICOR/runAsTask.C [new file with mode: 0644]
PWG2/libPWG2unicor.pkg [new file with mode: 0644]

index 455cd0dd3106b1590010973c8d33f17059c3ecae..f787c2a0e95ecf39d90c8c897b0a4e7aa9cf89c5 100644 (file)
@@ -9,14 +9,13 @@ ${CMAKE_SOURCE_DIR}/PWG2
 ${CMAKE_SOURCE_DIR}/PWG2/AOD
 ${CMAKE_SOURCE_DIR}/PWG2/EBYE
 ${CMAKE_SOURCE_DIR}/PWG2/EBYE/LRC
-${CMAKE_SOURCE_DIR}/PWG2/EVCHAR
 ${CMAKE_SOURCE_DIR}/PWG2/FEMTOSCOPY
 ${CMAKE_SOURCE_DIR}/PWG2/FEMTOSCOPY/AliFemto
 ${CMAKE_SOURCE_DIR}/PWG2/FEMTOSCOPY/AliFemtoUser
 ${CMAKE_SOURCE_DIR}/PWG2/FLOW/AliFlowCommon
 ${CMAKE_SOURCE_DIR}/PWG2/FLOW/AliFlowTasks
-${CMAKE_SOURCE_DIR}/PWG2/KINK
 ${CMAKE_SOURCE_DIR}/PWG2/SPECTRA
+${CMAKE_SOURCE_DIR}/PWG2/UNICOR
 ${CMAKE_SOURCE_DIR}/STEER
 ${CMAKE_SOURCE_DIR}/CORRFW
 ${ALIROOT_INSTALL_DIR}/include 
@@ -35,8 +34,6 @@ SetModule()
 
 include(CMake_libPWG2spectra.txt)
 
-include(CMake_libPWG2kink.txt)
-
 include(CMake_libPWG2flowCommon.txt)
 
 include(CMake_libPWG2flowTasks.txt)
@@ -49,6 +46,7 @@ include(CMake_libPWG2ebye.txt)
 
 include(CMake_libPWG2AOD.txt)
 
-include(CMake_libPWG2evchar.txt)
+include(CMake_libPWG2UNICOR.txt)
+
 
 
diff --git a/PWG2/CMake_libPWG2unicor.txt b/PWG2/CMake_libPWG2unicor.txt
new file mode 100644 (file)
index 0000000..1d8f480
--- /dev/null
@@ -0,0 +1,21 @@
+# -*- mode: cmake -*-
+
+Set(SRCS
+UNICOR/AliAnalysisTaskUnicor.cxx
+UNICOR/AliUnicorAnalCorrel.cxx
+UNICOR/AliUnicorAnal.cxx
+UNICOR/AliUnicorAnalGlobal.cxx
+UNICOR/AliUnicorAnalHighpt.cxx
+UNICOR/AliUnicorAnalPtfluc.cxx
+UNICOR/AliUnicorAnalSingle.cxx
+UNICOR/AliUnicorEventAliceESD.cxx
+UNICOR/AliUnicorEvent.cxx
+UNICOR/AliUnicorHN.cxx
+UNICOR/AliUnicorPair.cxx
+)
+
+# fill list of header files from list of source files
+# by exchanging the file extension
+String(REPLACE ".cxx" ".h" HDRS "${SRCS}")
+
+AddLibrary(PWG2UNICOR "${SRCS}" "${HDRS}")
index 3fbeb28942f408e374014b5601aabb35660fc604..9989d6e709f63bb58dc191b64c000fdadca599d9 100644 (file)
@@ -1,24 +1,19 @@
 #ifdef __CINT__
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice                               */
 
-/* $Id: ZDCbaseLinkDef.h 27132 2008-07-06 13:56:18Z coppedis $ */
-
-#pragma link off all globals;
+#pragma link off all glols;
 #pragma link off all classes;
 #pragma link off all functions;
-#pragma link C++ class AliDAnal+;
-#pragma link C++ class AliDAnalCorrel+;
-#pragma link C++ class AliDAnalGlobal+;
-#pragma link C++ class AliDAnalPtfluc+;
-#pragma link C++ class AliDAnalSingle+;
-#pragma link C++ class AliDAnalysisTask+;
-#pragma link C++ class AliDEvent+;
-#pragma link C++ class AliDEventAliceESD+;
-#pragma link C++ class AliDHN+;
-#pragma link C++ class AliDLoop+;
-#pragma link C++ class AliDPair+;
 
+#pragma link C++ class AliAnalysisTaskUnicor+;
+#pragma link C++ class AliUnicorAnalCorrel+;
+#pragma link C++ class AliUnicorAnal+;
+#pragma link C++ class AliUnicorAnalGlobal+;
+#pragma link C++ class AliUnicorAnalHighpt+;
+#pragma link C++ class AliUnicorAnalPtfluc+;
+#pragma link C++ class AliUnicorAnalSingle+;
+#pragma link C++ class AliUnicorEventAliceESD+;
+#pragma link C++ class AliUnicorEvent+;
+#pragma link C++ class AliUnicorHN+;
+#pragma link C++ class AliUnicorPair+;
 
 #endif
diff --git a/PWG2/UNICOR/AliAnalysisTaskUnicor.cxx b/PWG2/UNICOR/AliAnalysisTaskUnicor.cxx
new file mode 100644 (file)
index 0000000..4e67076
--- /dev/null
@@ -0,0 +1,85 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+//Author: Dariusz Miskowiec 2007
+
+//=============================================================================
+// unicor analysis task
+//=============================================================================
+#include "AliESDInputHandler.h"
+#include "AliAnalysisManager.h"
+#include "AliUnicorAnalGlobal.h"
+#include "AliUnicorAnalSingle.h"
+#include "AliUnicorAnalCorrel.h"
+#include "AliUnicorAnalPtfluc.h"
+#include "AliUnicorEventAliceESD.h"
+#include "AliAnalysisTaskUnicor.h"
+
+ClassImp(AliAnalysisTaskUnicor)
+
+//=============================================================================
+AliAnalysisTaskUnicor::AliAnalysisTaskUnicor(const char *name) : 
+  AliAnalysisTaskSE(name), 
+  fEv0(0),
+  fOutputList(0)
+{
+  // constructor
+
+  fEv0 = new AliUnicorEventAliceESD(); // needed for eta ranges only
+  DefineOutput(1, TList::Class());
+}
+//=============================================================================
+void AliAnalysisTaskUnicor::UserCreateOutputObjects() 
+{
+  // executed once on each worker 
+
+  fOutputList = new TList();
+  fOutputList->Add(new AliUnicorAnalGlobal("dag"));
+  fOutputList->Add(new AliUnicorAnalSingle("all",fEv0->Etamin(),fEv0->Etamax(),0));
+  fOutputList->Add(new AliUnicorAnalSingle("pim",fEv0->Etamin(),fEv0->Etamax(),-211));
+  fOutputList->Add(new AliUnicorAnalSingle("pip",fEv0->Etamin(),fEv0->Etamax(), 211));
+  fOutputList->Add(new AliUnicorAnalCorrel("cnn",fEv0->Etamin(),fEv0->Etamax(),-211,-211));
+  fOutputList->Add(new AliUnicorAnalCorrel("cpp",fEv0->Etamin(),fEv0->Etamax(), 211, 211));
+  fOutputList->Add(new AliUnicorAnalPtfluc("ptf",0,0));
+}
+//=============================================================================
+void AliAnalysisTaskUnicor::UserExec(Option_t */*option*/)
+{
+  // process one event
+
+  fEv0->SetESD(((AliESDEvent*) InputEvent()));
+  if (!fEv0->Good()) return;
+  ((AliUnicorAnalGlobal *) fOutputList->At(0))->Process(fEv0);
+  ((AliUnicorAnalSingle *) fOutputList->At(1))->Process(fEv0);
+  ((AliUnicorAnalSingle *) fOutputList->At(2))->Process(fEv0);
+  ((AliUnicorAnalSingle *) fOutputList->At(3))->Process(fEv0);
+  ((AliUnicorAnalCorrel *) fOutputList->At(4))->Process(0,fEv0,fEv0,0);
+  ((AliUnicorAnalCorrel *) fOutputList->At(4))->Process(2,fEv0,fEv0,TMath::DegToRad()*180);
+  ((AliUnicorAnalCorrel *) fOutputList->At(5))->Process(0,fEv0,fEv0,0);
+  ((AliUnicorAnalCorrel *) fOutputList->At(5))->Process(2,fEv0,fEv0,TMath::DegToRad()*180);
+  ((AliUnicorAnalPtfluc *) fOutputList->At(6))->Process(0,fEv0,fEv0);
+  PostData(1, fOutputList);
+} 
+//=============================================================================
+void AliAnalysisTaskUnicor::Terminate(Option_t */*option*/)
+{
+  // terminate
+  printf("terminate\n");
+  int n = fOutputList->GetEntries();
+  if (n) ((AliUnicorAnal *) fOutputList->At(0))->Save("unicor-result.root","recreate");
+  for (int i=1; i<n; i++) ((AliUnicorAnal *) fOutputList->At(i))->Save("unicor-result.root");
+}
+//=============================================================================
+
diff --git a/PWG2/UNICOR/AliAnalysisTaskUnicor.h b/PWG2/UNICOR/AliAnalysisTaskUnicor.h
new file mode 100644 (file)
index 0000000..860ae23
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef ALIANALYSISTASKUNICOR_H
+#define ALIANALYSISTASKUNICOR_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec 2007
+
+#include "AliAnalysisTaskSE.h"
+class AliUnicorEventAliceESD;
+
+/*****************************************************************************/
+class AliAnalysisTaskUnicor : public AliAnalysisTaskSE {
+   
+ public:                                        
+  AliAnalysisTaskUnicor(const char *name="dali");           // default constructor
+  AliAnalysisTaskUnicor(const AliAnalysisTaskUnicor &ta): AliAnalysisTaskSE(ta), fEv0(ta.fEv0), fOutputList(ta.fOutputList) {}
+  AliAnalysisTaskUnicor &operator=(const AliAnalysisTaskUnicor &) {return (*this);} 
+  virtual ~AliAnalysisTaskUnicor() {}                       // destructor
+  virtual void UserCreateOutputObjects();
+  virtual void UserExec(Option_t *option);
+  virtual void Terminate(Option_t *option);
+
+ protected:
+  AliUnicorEventAliceESD *fEv0;                       //! data/analysis interface
+  TList          *fOutputList;                //  list of analysis objects
+
+  ClassDef(AliAnalysisTaskUnicor,1)
+};
+/*****************************************************************************/
+
+#endif
diff --git a/PWG2/UNICOR/AliUnicorAnal.cxx b/PWG2/UNICOR/AliUnicorAnal.cxx
new file mode 100644 (file)
index 0000000..4bf6eea
--- /dev/null
@@ -0,0 +1,57 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// parent class of all analyzers
+// keeps the obj array of histograms filled by the daughter
+// takes care of storing them on file at the end
+//=============================================================================
+
+#include <TROOT.h>
+#include <TFile.h>
+#include "AliUnicorAnal.h"
+
+ClassImp(AliUnicorAnal)
+  
+TDatabasePDG AliUnicorAnal::fgPDG;
+
+//=============================================================================
+AliUnicorAnal::AliUnicorAnal(char *nam) : TNamed(nam,nam), fHistos() 
+{
+  // constructor
+
+  fHistos.SetOwner(1);
+  TDirectory *dir = gROOT->mkdir(GetName());
+  dir->cd();
+
+  printf("%s object named %s created\n",ClassName(),GetName());
+}
+//=============================================================================
+void AliUnicorAnal::Save(const char *outfil, const char *mode) 
+{
+  // store histograms on file in a directory named after the object
+  // mode should be "update" (default) or "new"
+
+  printf("%s saving  histograms on %s (%s)\n",GetName(),outfil,mode);  
+  TFile * f = TFile::Open(outfil, mode);
+  TDirectory *dest = f->mkdir(GetName());
+  dest->cd();
+  fHistos.Write();
+  gROOT->cd();
+  f->Close();
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorAnal.h b/PWG2/UNICOR/AliUnicorAnal.h
new file mode 100644 (file)
index 0000000..09bfec3
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef ALIUNICORANAL_H
+#define ALIUNICORANAL_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// parent class of all analyzers
+//=============================================================================
+
+#include <TNamed.h>
+#include <TObjArray.h>
+#include <TDatabasePDG.h>
+
+//=============================================================================
+class AliUnicorAnal : public TNamed {
+   
+ public:
+  AliUnicorAnal(char *nam="anal");                                   // constructor
+  virtual ~AliUnicorAnal()     {printf("%s object named %s deleted\n",ClassName(),GetName());}
+  void Save(const char *outfil, const char *mode="update");  // save histograms 
+
+ protected:
+  static TDatabasePDG fgPDG; // particle database
+  TObjArray fHistos;          // histograms
+
+  ClassDef(AliUnicorAnal,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/AliUnicorAnalCorrel.cxx b/PWG2/UNICOR/AliUnicorAnalCorrel.cxx
new file mode 100644 (file)
index 0000000..49b9a91
--- /dev/null
@@ -0,0 +1,120 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2005
+
+//=============================================================================
+// two-particle correlation analyzer
+// Loop over pairs and fill pair histograms. The first particle is always 
+// taken from ev0 and the second from ev1 so for ev0=ev1 one is getting true 
+// pairs, otherwise mixed ones. 
+//=============================================================================
+
+#include <TROOT.h>
+#include <TMath.h>
+#include <TRandom2.h>
+#include "AliUnicorEvent.h"
+#include "AliUnicorHN.h"
+#include "AliUnicorAnalCorrel.h"
+
+ClassImp(AliUnicorAnalCorrel)
+//=============================================================================
+AliUnicorAnalCorrel::AliUnicorAnalCorrel(Char_t *nam, Double_t emi, Double_t ema, 
+                        Int_t pid0, Int_t pid1): 
+  AliUnicorAnal(nam), fPid0(pid0), fPid1(pid1), fMass0(0), fMass1(0), fPa()
+{
+  // constructor
+  // emi and ema define the rapidity range for histogram
+
+  TParticlePDG *part0 = AliUnicorAnal::fgPDG.GetParticle(fPid0);
+  TParticlePDG *part1 = AliUnicorAnal::fgPDG.GetParticle(fPid1);
+  fMass0 = part0? part0->Mass() : 0;
+  fMass1 = part1? part1->Mass() : 0;
+
+  double pi = TMath::Pi();
+  TAxis *ax[8];
+  ax[0] = new TAxis(3,-0.5,2.5);ax[0]->SetTitle("trumixrot");
+  ax[1] = new TAxis(5,0,0.5);   ax[1]->SetTitle("centrality");
+  ax[2] = new TAxis(3,emi,ema); ax[2]->SetTitle("pair y");
+  //ax[3] = new TAxis(8,-pi,pi);  ax[3]->SetTitle("pair phi"); // wrt event plane
+  ax[3] = new TAxis(1,-pi,pi);  ax[3]->SetTitle("pair phi"); // wrt event plane
+  double a0[]={0,0.1,0.2,0.3,0.4,0.5,0.7,1.0};
+  ax[4] = new TAxis(7,a0);      ax[4]->SetTitle("(pair pt)/2 (GeV)");
+  ax[5] = new TAxis(8,0,pi);    ax[5]->SetTitle("q-theta");
+  ax[6] = new TAxis(16,-pi,pi); ax[6]->SetTitle("q-phi");
+  double a1[100];
+  for (int i=0;i<20;i++) a1[i]=i*0.005;
+  for (int i=0;i<45;i++) a1[20+i]=0.1+i*0.02;
+  ax[7] = new TAxis(64,a1);     ax[7]->SetTitle("q (GeV/c)");
+  AliUnicorHN *pair = new AliUnicorHN("pair",8,ax);
+  for (int i=0; i<8; i++) delete ax[i];
+  fHistos.Add(pair);
+  gROOT->cd();
+  printf("%s object named %s created\n",ClassName(),GetName());
+}
+//=============================================================================
+void AliUnicorAnalCorrel::Process(Int_t tmr, AliUnicorEvent *ev0, AliUnicorEvent *ev1, Double_t phirot) 
+{
+  // process pairs from one or two (if mixing) events
+  // tmr tells which histogram (bins) to fill: tru,mix,rot
+
+  // Could be possibly accelerated by checking the "good particle" only once 
+  // and caching the result. (Maybe the optimizer does it already.)
+
+  static TRandom2 ran;
+  AliUnicorHN *pair = (AliUnicorHN*) fHistos.At(0);
+
+  // mixing-and-rotating-proof centrality and reaction plane angle
+  // (but not rotation-proof for rotation angles much different from 0 and 180)
+  // true and rotated pairs are within the triangle (j<i), mixed - all
+  // thus, proper rotation is either by 180, or by 170 AND 190, etc. 
+
+  double cent = (ev0->Centrality()+ev1->Centrality())/2.0;
+  double q0x,q0y,q1x,q1y;
+  ev0->RP(q0x,q0y);
+  ev1->RP(q1x,q1y); 
+  double rpphi = atan2(q0y+q1y,q0x+q1x);
+
+  // loop over pairs 
+
+  for (int i=0; i<ev0->NParticles(); i++) {
+    if (!ev0->ParticleGood(i,fPid0)) continue;
+    for (int j=0; j<ev1->NParticles(); j++) {
+      if (ev0==ev1 && j<i && fPid0==fPid1 ) continue; 
+      if (ev0==ev1 && j==i) continue; // beware, not even when rotated or non-identical
+      if (!ev1->ParticleGood(j,fPid1)) continue;
+      if (!ev0->PairGood(ev0->ParticleP(i),ev0->ParticleTheta(i),ev0->ParticlePhi(i),
+                        ev1->ParticleP(j),ev1->ParticleTheta(j),ev1->ParticlePhi(j)+phirot)) continue;
+      fPa.Set0(fMass0,ev0->ParticleP(i),ev0->ParticleTheta(i),ev0->ParticlePhi(i));
+      fPa.Set1(fMass1,ev1->ParticleP(j),ev1->ParticleTheta(j),ev1->ParticlePhi(j)+phirot);
+      if (ev0==ev1 && fPid0==fPid1 && ran.Rndm()>=0.5) fPa.Swap();
+      fPa.CalcLAB();
+      fPa.CalcPairCM();
+      if (fPa.QCM()==0) return; // should not be too frequent
+      double phi = TVector2::Phi_mpi_pi(fPa.Phi()-rpphi);
+      pair->Fill(tmr,                    // 0 for tru, 1 for mix, 2 for rot
+                cent,                   // centrality
+                fPa.Rapidity(),         // pair rapidity
+                phi,                    // pair phi wrt reaction plane
+                fPa.Pt()/2.0,           // half of pair pt
+                fPa.QCMTheta(),         // polar angle of Q
+                fPa.QCMPhiOut(),        // azimuthal angle of Q w.r.t. out
+                fPa.QCM(),              // |p2-p1| in c.m.s.
+                1.0);                   // weigth
+    }
+  }
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorAnalCorrel.h b/PWG2/UNICOR/AliUnicorAnalCorrel.h
new file mode 100644 (file)
index 0000000..3cb2ddb
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef ALIUNICORANALCORREL_H
+#define ALIUNICORANALCORREL_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2005
+
+//=============================================================================
+// two-particle correlation analyzer
+//=============================================================================
+
+#include "AliUnicorAnal.h"
+#include "AliUnicorPair.h"
+class AliUnicorEvent;
+
+//=============================================================================
+class AliUnicorAnalCorrel : public AliUnicorAnal {
+   
+ public:
+  AliUnicorAnalCorrel(Char_t *nam="correl", 
+             Double_t emi=-1, Double_t ema=1, 
+             Int_t pid0=0, Int_t pid1=0);     // constructor
+  virtual ~AliUnicorAnalCorrel(){}                     // destructor
+  // process one (tru) or two (mix) events
+  void Process(Int_t tmr, AliUnicorEvent *ev0, AliUnicorEvent *ev1, Double_t phirot);
+
+ protected:
+  Int_t    fPid0;                       // particle species 0
+  Int_t    fPid1;                       // particle species 1
+  Double_t fMass0;                      // mass 0
+  Double_t fMass1;                      // mass 1
+  AliUnicorPair    fPa;                         // pair buffer for calculations
+
+  ClassDef(AliUnicorAnalCorrel,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/AliUnicorAnalGlobal.cxx b/PWG2/UNICOR/AliUnicorAnalGlobal.cxx
new file mode 100644 (file)
index 0000000..3384e07
--- /dev/null
@@ -0,0 +1,72 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// event global variable analyzer
+// Histogram the event variables like multiplicity, flow vector, vertex z, 
+// etc. 
+//=============================================================================
+
+#include <TROOT.h>
+#include <TH1.h>
+#include <TH2.h>
+#include "AliUnicorEvent.h"
+#include "AliUnicorAnalGlobal.h"
+
+
+class TH2;
+ClassImp(AliUnicorAnalGlobal)
+  
+//=============================================================================
+AliUnicorAnalGlobal::AliUnicorAnalGlobal(Char_t *nam) : AliUnicorAnal(nam) 
+{
+  // constructor
+
+  TH1D *mult = new TH1D("mult","mult",5000,-0.5,4999.5);
+  mult->SetXTitle("multiplicity");
+  TH1D *cent = new TH1D("cent","cent",100,0,1);
+  cent->SetXTitle("centrality");
+  TH2D *dire = new TH2D("dire","dire",100,-40,40,100,-40,40);
+  dire->SetXTitle("Qx (GeV)");
+  dire->SetYTitle("Qy (GeV)");
+  TH1D *zver = new TH1D("zver","zver",120,-1.2,1.2);
+  zver->SetXTitle("normalized z-vertex");
+  fHistos.Add(mult);
+  fHistos.Add(cent);
+  fHistos.Add(dire);
+  fHistos.Add(zver);
+  gROOT->cd();
+  printf("%s object named %s created\n",ClassName(),GetName());
+}
+//=============================================================================
+void AliUnicorAnalGlobal::Process(AliUnicorEvent *ev) const
+{
+  // fill event variable histograms
+
+  TH1D *mult = (TH1D*) fHistos.At(0);
+  TH1D *cent = (TH1D*) fHistos.At(1);
+  TH2D *dire = (TH2D*) fHistos.At(2);
+  TH1D *zver = (TH1D*) fHistos.At(3);
+
+  mult->Fill(ev->NParticles(),1.0);
+  cent->Fill(ev->Centrality(),1.0);
+  Double_t qx,qy;
+  ev->RP(qx,qy);
+  dire->Fill(qx,qy,1.0);
+  zver->Fill(ev->Zver(),1.0);
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorAnalGlobal.h b/PWG2/UNICOR/AliUnicorAnalGlobal.h
new file mode 100644 (file)
index 0000000..ef81f53
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef ALIUNICORANALGLOBAL_H
+#define ALIUNICORANALGLOBAL_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// event global variable analyzer
+//=============================================================================
+
+#include "AliUnicorAnal.h"
+class AliUnicorEvent;
+
+//=============================================================================
+class AliUnicorAnalGlobal : public AliUnicorAnal {
+   
+ public:
+  AliUnicorAnalGlobal(Char_t *nam="global"); // constructor
+  virtual ~AliUnicorAnalGlobal(){}           // destructor
+  void Process(AliUnicorEvent *ev) const;    // fill histograms
+
+  ClassDef(AliUnicorAnalGlobal,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/AliUnicorAnalHighpt.cxx b/PWG2/UNICOR/AliUnicorAnalHighpt.cxx
new file mode 100644 (file)
index 0000000..06d86c7
--- /dev/null
@@ -0,0 +1,102 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2008
+
+//=============================================================================
+// high-pt correlation analyzer
+// Loop over pairs and fill pair histograms. The first particle is always 
+// taken from ev0 and the second from ev1 so for ev0=ev1 one is getting true 
+// pairs, otherwise mixed ones. Overlaps a bit with AliUnicorAnalCorrel. 
+//=============================================================================
+
+#include <TROOT.h>
+#include <TMath.h>
+#include <TVector2.h>
+#include "AliUnicorEvent.h"
+#include "AliUnicorHN.h"
+#include "AliUnicorAnalHighpt.h"
+
+ClassImp(AliUnicorAnalHighpt)
+//=============================================================================
+AliUnicorAnalHighpt::AliUnicorAnalHighpt(Char_t *nam, Double_t emi, Double_t ema, Int_t pid0, 
+                        Int_t pid1): AliUnicorAnal(nam), fPid0(pid0), fPid1(pid1)
+{
+  // constructor
+  // emi and ema define the rapidity range for histogram
+
+  Double_t ewi = ema-emi; // width of the pseudorapidity range
+  double pi = TMath::Pi();
+  TAxis *ax[8];
+  ax[0] = new TAxis(2,-0.5,1.5);   ax[0]->SetTitle("trumix");
+  ax[1] = new TAxis(2,-0.5,1.5);   ax[1]->SetTitle("weigth"); // 1 or ass pt
+  ax[2] = new TAxis(5,0,0.5);      ax[2]->SetTitle("centrality");
+  ax[3] = new TAxis(3,emi,ema);    ax[3]->SetTitle("trig eta");
+  ax[4] = new TAxis(8,-pi,pi);     ax[4]->SetTitle("trig phi"); // w.r.t. RP
+  double a5[]={0,2.5,3,4,6,8,10,15,20,30,50,100};
+  ax[5] = new TAxis(11,a5);        ax[5]->SetTitle("trig pt (GeV)");
+  ax[6] = new TAxis(20,-ewi,ewi);  ax[6]->SetTitle("ass eta - trig eta"); 
+  ax[7] = new TAxis(36,-1,2*pi-1); ax[7]->SetTitle("ass phi - trig phi"); 
+  ax[8] = new TAxis(10,0,1);       ax[8]->SetTitle("ass pt / trig pt");
+
+  AliUnicorHN *pair = new AliUnicorHN("pair",9,ax);
+  for (int i=0; i<9; i++) delete ax[i];
+  fHistos.Add(pair);
+  gROOT->cd();
+  printf("%s object named %s created\n",ClassName(),GetName());
+}
+//=============================================================================
+void AliUnicorAnalHighpt::Process(AliUnicorEvent *ev0, AliUnicorEvent *ev1) 
+{
+  // process pairs from one or two (if mixing) events
+  // true pairs are within the triangle (j<i), mixed - all
+
+  // mixing-proof centrality and reaction plane angle
+
+  double cent = (ev0->Centrality()+ev1->Centrality())/2.0;
+  double q0x,q0y,q1x,q1y;
+  ev0->RP(q0x,q0y);
+  ev1->RP(q1x,q1y); 
+  double rpphi = atan2(q0y+q1y,q0x+q1x);
+
+  // loop over pairs 
+
+  int tmr = (ev0!=ev1); // 0 for true, 1 for mixed
+  AliUnicorHN *pair = (AliUnicorHN*) fHistos.At(0);
+  for (int i=0; i<ev0->NParticles(); i++) {
+    if (!ev0->ParticleGood(i,fPid0)) continue;
+    double eta0 = ev0->ParticleEta(i);
+    double phi0 = ev0->ParticlePhi(i);
+    double pt0 = ev0->ParticlePt(i);
+    for (int j=0; j<ev1->NParticles(); j++) {
+      if (ev0==ev1 && j==i) continue; // same particle
+      if (ev0==ev1 && j<i && fPid0==fPid1) continue;
+      if (!ev1->ParticleGood(j,fPid1)) continue;
+      double eta1 = ev1->ParticleEta(j);
+      double phi1 = ev1->ParticlePhi(j);
+      double pt1 = ev1->ParticlePt(j);
+      int order = (pt0>pt1); 
+      double deta = order*(eta1-eta0); // ass-trig
+      double dphi = order*(phi1-phi0);
+      dphi = TVector2::Phi_mpi_pi(dphi);
+      if (dphi<-1) dphi+=2*TMath::Pi(); 
+      phi0 = TVector2::Phi_mpi_pi(phi0-rpphi);  // wrt. reaction plane
+      pair->Fill(tmr,0,cent,eta0,phi0,pt0,deta,dphi,pt1/pt0,1);   // number of pairs
+      pair->Fill(tmr,1,cent,eta0,phi0,pt0,deta,dphi,pt1/pt0,pt1); // weigthed with ass pt
+    }
+  }
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorAnalHighpt.h b/PWG2/UNICOR/AliUnicorAnalHighpt.h
new file mode 100644 (file)
index 0000000..8e08f52
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef ALIUNICORANALHIGHPT_H
+#define ALIUNICORANALHIGHPT_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2008
+
+//=============================================================================
+// high-pt correlation analyzer
+//=============================================================================
+
+#include "AliUnicorAnal.h"
+class AliUnicorEvent;
+
+//=============================================================================
+class AliUnicorAnalHighpt : public AliUnicorAnal {
+   
+ public:
+  AliUnicorAnalHighpt(Char_t *nam="highpt", 
+             Double_t emi=-1, Double_t ema=1, 
+             Int_t pid0=0, Int_t pid1=0);   // constructor
+  virtual ~AliUnicorAnalHighpt(){}                   // destructor
+  void Process(AliUnicorEvent *ev0, AliUnicorEvent *ev1);    // process 1 (tru) or 2 (mix) events
+
+ protected:
+  Int_t    fPid0;                            // particle species 0
+  Int_t    fPid1;                            // particle species 1
+
+  ClassDef(AliUnicorAnalHighpt,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/AliUnicorAnalPtfluc.cxx b/PWG2/UNICOR/AliUnicorAnalPtfluc.cxx
new file mode 100644 (file)
index 0000000..efc92ba
--- /dev/null
@@ -0,0 +1,112 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2008
+
+//=============================================================================
+// pt-fluctuations analyzer
+// Loop over pairs and fill pair histograms. The first particle is always 
+// taken from ev0 and the second from ev1 so for ev0=ev1 one is getting true 
+// pairs, otherwise mixed ones. 
+//=============================================================================
+
+#include <TROOT.h>
+#include <TRandom2.h>
+#include <TVector2.h>
+#include <TMath.h>
+#include "AliUnicorEvent.h"
+#include "AliUnicorHN.h"
+#include "AliUnicorAnalPtfluc.h"
+
+ClassImp(AliUnicorAnalPtfluc)
+
+//=============================================================================
+AliUnicorAnalPtfluc::AliUnicorAnalPtfluc(Char_t *nam, Int_t pid0, Int_t pid1) : 
+  AliUnicorAnal(nam), fPid0(pid0), fPid1(pid1) 
+{
+  // constructor
+
+  TAxis *ax[5];
+  ax[0] = new TAxis(2,-0.5,1.5);   ax[0]->SetTitle("trumix");
+  ax[1] = new TAxis(9,0,0.9);      ax[1]->SetTitle("centrality");
+  ax[2] = new TAxis(6,-0.5,5.5);   ax[2]->SetTitle("n-pt0-pt1-pt00-pt11-pt01");
+  ax[3] = new TAxis(48,-180,180);  ax[3]->SetTitle("dphi (deg)");
+  ax[4] = new TAxis(40,-2,2);      ax[4]->SetTitle("deta");
+  AliUnicorHN *pair = new AliUnicorHN("pair",5,ax);
+  for (int i=0; i<5; i++) delete ax[i];
+  fHistos.Add(pair);
+  gROOT->cd();
+  printf("%s object named %s created\n",ClassName(),GetName());
+}
+//=============================================================================
+void AliUnicorAnalPtfluc::Process(Int_t tmr, AliUnicorEvent *ev0, AliUnicorEvent *ev1) 
+{
+  // process pairs from one or two (if mixing) events
+
+  double ptmin=0.1;  // GeV
+  double ptmax=1.5;  // GeV
+  double etamin=-9;  
+  double etamax=9;  
+
+  // mixing-and-rotating-proof centrality
+
+  double cent = (ev0->Centrality()+ev1->Centrality())/2.0;
+
+  // loop over pairs 
+
+  AliUnicorHN *pair = (AliUnicorHN*) fHistos.At(0);
+  static TRandom2 ran;
+  for (int i=0; i<ev0->NParticles(); i++) {
+    if (!ev0->ParticleGood(i,fPid0)) continue;
+    double eta0 = ev0->ParticleEta(i);
+    double phi0 = ev0->ParticlePhi(i);
+    double pt0 = ev0->ParticlePt(i);
+    if (eta0 < etamin) continue;
+    if (eta0 > etamax) continue;
+    if (pt0 < ptmin) continue;
+    if (pt0 > ptmax) continue;
+    for (int j=0; j<ev1->NParticles(); j++) {
+      if (ev0==ev1 && j==i) continue;
+      if (ev0==ev1 && j<i && fPid0==fPid1) continue;
+      if (!ev1->ParticleGood(j,fPid1)) continue;
+      double eta1 = ev1->ParticleEta(j);
+      double phi1 = ev1->ParticlePhi(j);
+      double pt1 = ev1->ParticlePt(j);
+      if (eta1 < etamin) continue;
+      if (eta1 > etamax) continue;
+      if (pt1 < ptmin) continue;
+      if (pt1 > ptmax) continue;
+      double deta = eta1-eta0;
+      double dphi = phi1-phi0;
+      // randomize order
+      if (ran.Rndm()<0.5) { 
+       double buf = pt0;
+       pt0 = pt1;
+       pt1 = buf;
+       deta = -deta;
+       dphi = -dphi;
+      }
+      dphi = TVector2::Phi_mpi_pi(dphi);
+      dphi*=TMath::RadToDeg();
+      pair->Fill(tmr, cent, 0, dphi, deta, 1);   // number of pairs
+      pair->Fill(tmr, cent, 1, dphi, deta, pt0);
+      pair->Fill(tmr, cent, 2, dphi, deta, pt1);
+      pair->Fill(tmr, cent, 3, dphi, deta, pt0*pt0);
+      pair->Fill(tmr, cent, 4, dphi, deta, pt1*pt1);
+      pair->Fill(tmr, cent, 5, dphi, deta, pt0*pt1);
+    }
+  }
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorAnalPtfluc.h b/PWG2/UNICOR/AliUnicorAnalPtfluc.h
new file mode 100644 (file)
index 0000000..8f9fad9
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef ALIUNICORANALPTFLUC_H
+#define ALIUNICORANALPTFLUC_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2005
+
+//=============================================================================
+// pt-fluctuations analyzer
+//=============================================================================
+
+#include "AliUnicorAnal.h"
+class AliUnicorEvent;
+class AliUnicorHN;
+
+//=============================================================================
+class AliUnicorAnalPtfluc : public AliUnicorAnal {
+   
+ public:
+  AliUnicorAnalPtfluc(Char_t *nam="correl", Int_t pid0=0, Int_t pid1=0);  // constructor
+  virtual ~AliUnicorAnalPtfluc(){}                                        // destructor
+  void Process(Int_t tmr, AliUnicorEvent *ev0, AliUnicorEvent *ev1);              // process event(s)
+
+ protected:
+  Int_t    fPid0;                       // particle species 0
+  Int_t    fPid1;                       // particle species 1
+  ClassDef(AliUnicorAnalPtfluc,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/AliUnicorAnalSingle.cxx b/PWG2/UNICOR/AliUnicorAnalSingle.cxx
new file mode 100644 (file)
index 0000000..1a56618
--- /dev/null
@@ -0,0 +1,88 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// single particle analyzer
+// Loop over tracks of one event and, for tracks that fulfill the quality 
+// and pid cuts, fill single track histograms. 
+//=============================================================================
+
+#include <cmath>
+#include <TROOT.h>
+#include <TMath.h>
+#include <TAxis.h>
+#include <TParticlePDG.h>
+#include "AliUnicorHN.h"
+#include "AliUnicorEvent.h"
+#include "AliUnicorAnalSingle.h"
+
+ClassImp(AliUnicorAnalSingle)
+
+//=============================================================================
+AliUnicorAnalSingle::AliUnicorAnalSingle(Char_t *nam, Double_t emi, Double_t ema, Int_t pid) : 
+  AliUnicorAnal(nam), fPid(pid), fMass(0.0) 
+{
+  // constructor
+  // emi and ema define the rapidity range for histograms
+
+  fPid = pid;
+  TParticlePDG *part = AliUnicorAnal::fgPDG.GetParticle(fPid);
+  fMass = part? part->Mass() : 0;
+
+  double pi = TMath::Pi();
+  TAxis *ax[10];
+  ax[0] = new TAxis(30,-1,1);    ax[0]->SetTitle("vertex z");
+  ax[1] = new TAxis(80,emi,ema); ax[1]->SetTitle("eta");
+  ax[2] = new TAxis(90,-pi,pi);  ax[2]->SetTitle("phi");
+  AliUnicorHN *zep = new AliUnicorHN("zep",3,ax);
+  for (int i=0; i<3; i++) delete ax[i];
+
+  ax[0] = new TAxis(20,0,1);     ax[0]->SetTitle("centrality");
+  ax[1] = new TAxis(80,emi,ema); ax[1]->SetTitle("y");
+  ax[2] = new TAxis(80,0,2);     ax[2]->SetTitle("pt (GeV)");
+  AliUnicorHN *cyp = new AliUnicorHN("cyp",3,ax);
+  for (int i=0; i<3; i++) delete ax[i];
+
+  ax[0] = new TAxis(10,emi,ema); ax[0]->SetTitle("eta");
+  ax[1] = new TAxis(150,0,3);    ax[1]->SetTitle("p (GeV)");
+  ax[2] = new TAxis(150,0.5,3.5);ax[2]->SetTitle("sqrt(dedx (mips))");
+  AliUnicorHN *epd = new AliUnicorHN("epd",3,ax);
+  for (int i=0; i<3; i++) delete ax[i];
+
+  fHistos.Add(zep);
+  fHistos.Add(cyp);
+  fHistos.Add(epd);
+  gROOT->cd();
+  printf("%s object named %s created\n",ClassName(),GetName());
+}
+//=============================================================================
+void AliUnicorAnalSingle::Process(AliUnicorEvent *ev) 
+{
+  // fill single particle histograms
+
+  AliUnicorHN *zep = (AliUnicorHN*) fHistos.At(0);
+  AliUnicorHN *cyp = (AliUnicorHN*) fHistos.At(1);
+  AliUnicorHN *epd = (AliUnicorHN*) fHistos.At(2);
+  for (int i=0; i<ev->NParticles(); i++) {
+    if (!ev->ParticleGood(i,fPid)) continue;
+    zep->Fill(ev->Zver(),ev->ParticleEta(i),ev->ParticlePhi(i),1.0);
+    double y = fMass>0? ev->ParticleY(i,fMass) : ev->ParticleEta(i);
+    cyp->Fill(ev->Centrality(),y,ev->ParticlePt(i),1.0);
+    epd->Fill(ev->ParticleEta(i),ev->ParticleP(i),sqrt(ev->ParticleDedx(i)),1.0);
+  }
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorAnalSingle.h b/PWG2/UNICOR/AliUnicorAnalSingle.h
new file mode 100644 (file)
index 0000000..b13619a
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef ALIUNICORANALSINGLE_H
+#define ALIUNICORANALSINGLE_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// single particle analyzer
+//=============================================================================
+
+#include "AliUnicorAnal.h"
+class AliUnicorEvent;
+class AliUnicorHN;
+
+//=============================================================================
+class AliUnicorAnalSingle : public AliUnicorAnal {
+   
+ public:
+  AliUnicorAnalSingle(Char_t *nam="single", 
+             Double_t emi=-1, Double_t ema=1, 
+             Int_t pid=0);                       // constructor
+  virtual ~AliUnicorAnalSingle(){}                        // destructor
+  void Process(AliUnicorEvent *ev);                       // fill histograms
+
+ protected:
+  Int_t    fPid;                                  // pid; 0 means all
+  Double_t fMass;                                 // mass (if pid!=0)
+
+  ClassDef(AliUnicorAnalSingle,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/AliUnicorEvent.cxx b/PWG2/UNICOR/AliUnicorEvent.cxx
new file mode 100644 (file)
index 0000000..17f4757
--- /dev/null
@@ -0,0 +1,64 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// parent class of all events; analyzers access data via this class
+//=============================================================================
+
+#include <TMath.h>
+#include "AliUnicorEvent.h"
+
+ClassImp(AliUnicorEvent)
+
+//=============================================================================
+void AliUnicorEvent::RP(Double_t &qx, Double_t &qy, Int_t harmonic) const 
+{
+  // simplest flow vector
+
+  qx=0; 
+  qy=0;
+  for (int i=0; i<NParticles(); i++) {
+    if (!ParticleGood(i,0)) continue;
+    double pt = ParticlePt(i);
+    if (pt>2.0) pt = 2.0; // from 2 GeV flow saturates anyway
+    qx += pt*cos(harmonic*ParticlePhi(i));
+    qy += pt*sin(harmonic*ParticlePhi(i));
+  }
+}
+//=============================================================================
+Double_t AliUnicorEvent::ParticleEta(Int_t i) const 
+{
+  // pseudorapidity
+
+  double the = ParticleTheta(i); 
+  if (the<0.0001) return 10; 
+  else if (the>TMath::Pi()-0.0001) return -10;
+  return -log(tan(the/2));
+}
+//=============================================================================
+Double_t AliUnicorEvent::ParticleY(Int_t i, Double_t mass) const 
+{
+  // rapidity
+
+  double pp = ParticleP(i);
+  double ee = sqrt(fabs(mass*mass + pp*pp));
+  double pz = ParticlePz(i);
+  double yy = log((ee+pz)/(ee-pz))/2;
+  return yy;
+}
+//=============================================================================
+
diff --git a/PWG2/UNICOR/AliUnicorEvent.h b/PWG2/UNICOR/AliUnicorEvent.h
new file mode 100644 (file)
index 0000000..d62b8b1
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef ALIUNICOREVENT_H
+#define ALIUNICOREVENT_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// parent class of all events; analyzers access data via this class
+//=============================================================================
+
+#include <cmath>
+#include <TObject.h>
+
+class TTree;
+
+//=============================================================================
+class AliUnicorEvent : public TObject {
+ public:
+  AliUnicorEvent() : TObject(){printf("AliUnicorEvent object created\n");}
+  virtual ~AliUnicorEvent()   {printf("AliUnicorEvent object deleted\n");}
+
+  // interface part
+
+  virtual void        AttachTree(TTree *tr) = 0;
+  virtual Double_t    Etamin() const = 0;     // experiment's acceptance
+  virtual Double_t    Etamax() const = 0;
+  virtual Bool_t      Good() const = 0;  
+  virtual Double_t    Centrality() = 0;       // centrality (0,1); 0 is most central
+  virtual void        RP(Double_t &qx, Double_t &qy) const = 0;
+  virtual Double_t    RPphi() const = 0;
+  virtual Double_t    Zver() const = 0;       // z-vertex (-1,1)
+  virtual Int_t       NParticles() const = 0;
+
+  virtual Bool_t      ParticleGood(Int_t i, Int_t pidi) const = 0;
+  virtual Double_t    ParticleP(Int_t i) const = 0;
+  virtual Double_t    ParticleTheta(Int_t i) const = 0;
+  virtual Double_t    ParticlePhi(Int_t i) const = 0;
+  virtual Double_t    ParticleDedx(Int_t i) const = 0;
+  virtual Bool_t      PairGood(Double_t p0, Double_t the0, Double_t phi0, 
+                              Double_t p1, Double_t the1, Double_t phi1) const = 0;
+
+  // toolkit part
+
+  void     RP(Double_t &qx, Double_t &qy, Int_t harmonic) const;
+  Double_t ParticlePt(Int_t i) const {return ParticleP(i)*sin(ParticleTheta(i));}
+  Double_t ParticlePz(Int_t i) const {return ParticleP(i)*cos(ParticleTheta(i));}
+  Double_t ParticleEta(Int_t i) const;
+  Double_t ParticleY(Int_t i, Double_t mass) const; 
+
+  ClassDef(AliUnicorEvent,0)
+};
+#endif 
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorEventAliceESD.cxx b/PWG2/UNICOR/AliUnicorEventAliceESD.cxx
new file mode 100644 (file)
index 0000000..e81ba17
--- /dev/null
@@ -0,0 +1,100 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2008
+
+//=============================================================================
+// AliUnicorEvent-AliESD interface                                                   //
+//=============================================================================
+
+#include <cmath>
+#include "AliESDEvent.h"
+#include "AliUnicorEventAliceESD.h"
+
+ClassImp(AliUnicorEventAliceESD)
+
+//=============================================================================
+AliUnicorEventAliceESD::AliUnicorEventAliceESD(AliESDEvent *esd) : AliUnicorEvent(), fESD(esd) 
+{
+  // constructor 
+
+  //  printf("%s object created\n",ClassName());
+  if (!fESD) fESD = new AliESDEvent();
+}
+//=============================================================================
+AliUnicorEventAliceESD::~AliUnicorEventAliceESD()
+{
+  // destructor
+
+}
+//=============================================================================
+Bool_t AliUnicorEventAliceESD::Good() const 
+{
+  // event cuts
+
+  if (fabs(Zver())>1) return kFALSE;
+  if (fESD->GetPrimaryVertex()->GetZRes()>0.1) return kFALSE;
+  return kTRUE;
+}
+//=============================================================================
+Bool_t AliUnicorEventAliceESD::ParticleGood(Int_t i, Int_t pidi) const 
+{
+  // track cuts and particle id cuts; pidi=0 means take all species
+  // consider using the standard ESDcut
+
+  // track quality cuts
+
+  AliESDtrack *track = fESD->GetTrack(i);
+  if (!track->IsOn(AliESDtrack::kTPCrefit)) return 0;        // TPC refit
+  if (track->GetTPCNcls() < 120) return 0;                   // number of TPC clusters
+  const AliExternalTrackParam *tp = track->GetTPCInnerParam();
+  if (!tp) return 0;           
+
+  Float_t r,z;
+  track->GetImpactParameters(r,z);
+  //  if (fabs(z)>0.2) return 0;                          // impact parameter in z
+  //  if (fabs(r)>0.1) return 0;                          // impact parameter in xy
+
+  // pid
+
+  if (pidi==0) return 1;
+  if (!track->IsOn(AliESDtrack::kTPCpid)) return 0;
+  Double_t p[AliPID::kSPECIES];
+  track->GetTPCpid(p);
+  Int_t q = tp->Charge();
+  if (pidi == -211) return p[AliPID::kPion]+p[AliPID::kMuon]>0.5 && q==-1;
+  else if (pidi == 211) return p[AliPID::kPion]+p[AliPID::kMuon]>0.5 && q==1;
+  else return 0;
+}
+//=============================================================================
+Bool_t AliUnicorEventAliceESD::PairGood(Double_t /*p0*/, Double_t the0, Double_t phi0, 
+                               Double_t /*p1*/, Double_t the1, Double_t phi1) const {
+
+  // two-track separation cut
+
+  double r = 85; // TPC entrance radius in cm
+  double x0 = r*sin(the0)*cos(phi0);
+  double x1 = r*sin(the1)*cos(phi0);
+  double y0 = r*sin(the0)*sin(phi0);
+  double y1 = r*sin(the1)*sin(phi1);
+  double z0 = r*cos(the0);
+  double z1 = r*cos(the1);
+  double dx = x1-x0;
+  double dy = y1-y0;
+  double dz = z1-z0;
+  double dist2 = dx*dx+dy*dy+dz*dz;
+  return dist2>2*2;
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorEventAliceESD.h b/PWG2/UNICOR/AliUnicorEventAliceESD.h
new file mode 100644 (file)
index 0000000..4c190fc
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef ALIUNICOREVENTALICEESD_H
+#define ALIUNICOREVENTALICEESD_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2008
+
+#include <cmath>
+#include "TVector2.h"
+#include "AliESDEvent.h"
+#include "AliUnicorEvent.h"
+
+//=============================================================================
+class AliUnicorEventAliceESD : public AliUnicorEvent {
+
+ public:
+              AliUnicorEventAliceESD(AliESDEvent *esd=0);
+              AliUnicorEventAliceESD(const AliUnicorEventAliceESD &ev): AliUnicorEvent(ev), fESD(ev.fESD) {}
+  virtual     ~AliUnicorEventAliceESD();
+  AliUnicorEventAliceESD &operator=(const AliUnicorEventAliceESD &source) {fESD = source.fESD; return *this;}
+  Double_t    Etamin() const {return -0.75;}
+  Double_t    Etamax() const {return  0.75;}
+  void        AttachTree(TTree *tr) {fESD->ReadFromTree(tr);}
+  Bool_t      Good() const;
+  Double_t    Centrality() {return 0.9999*exp(-NParticles()/20.0);} // OK for pp
+  void        RP(Double_t &qx, Double_t &qy) const {AliUnicorEvent::RP(qx,qy,2);}
+  Double_t    RPphi() const {Double_t qx,qy; RP(qx,qy); return atan2(qy,qx);}
+  Double_t    Zver() const {return fESD->GetPrimaryVertex()->GetZv()/10.0;}
+  Int_t       NParticles() const {return fESD->GetNumberOfTracks();}
+
+  Bool_t      ParticleGood(Int_t i, Int_t pidi=0) const;
+  Double_t    ParticleP(Int_t i)     const {return fESD->GetTrack(i)->GetTPCInnerParam()->P();}
+  Double_t    ParticleTheta(Int_t i) const {return fESD->GetTrack(i)->GetTPCInnerParam()->Theta();}
+  Double_t    ParticlePhi(Int_t i)   const {return TVector2::Phi_mpi_pi(fESD->GetTrack(i)->GetTPCInnerParam()->Phi());}
+  Double_t    ParticleDedx(Int_t i)  const {return fESD->GetTrack(i)->GetTPCsignal()/47.0;}
+  Bool_t      PairGood(Double_t p0, Double_t the0, Double_t phi0, 
+                      Double_t p1, Double_t the1, Double_t phi1) const;
+  // alternative: GetTPCInnerParam, GetConstrainedParam
+  void        SetESD(AliESDEvent *esd) {fESD = esd;}
+  AliESDEvent *GetESD() const {return fESD;}
+
+ protected:
+  AliESDEvent *fESD;   //! pointer to the actual source of data
+
+  ClassDef(AliUnicorEventAliceESD,0)
+};
+#endif 
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorHN.cxx b/PWG2/UNICOR/AliUnicorHN.cxx
new file mode 100644 (file)
index 0000000..5727def
--- /dev/null
@@ -0,0 +1,396 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// multidimensional histogram 
+// Physically, the data are kept in one single one-dimensional histogram. 
+// Projecting on 1, 2, and n-1 dimensions is implemented.
+// The histogram can be saved on root file as the one-dimensional data 
+// histogram and the axes, thus eternal forward compatibility is ensured. 
+//=============================================================================
+
+#include <cmath>
+#include <stdlib.h>
+#include <TFile.h>
+#include <TDirectory.h>
+#include <TAxis.h>
+#include <TH2.h>
+#include "AliUnicorHN.h"
+
+ClassImp(AliUnicorHN)
+
+//=============================================================================
+AliUnicorHN::AliUnicorHN(Char_t *nam, Int_t ndim, TAxis **ax) 
+  : TH1D(nam, nam, Albins(ndim,ax), 0.5, Albins(ndim,ax)+0.5), 
+    fNdim(ndim) 
+{
+  // Constructor for building from scratch.
+  // Above, we just have managed to create a single one-dimensional histogram 
+  // with number of bins equal to the product of the numbers of bins in all 
+  // dimensions. For easy inspection the histogram range was set to -0.5,n-0.5.
+
+  for (int i=0; i<fNdim; i++) ax[i]->Copy(fAxis[i]); 
+
+  // for speed reasons, number of bins of each axis is stored on fNbins
+  // and the running product of the latter on fMbins
+  // so fMbins = {...,fNbins[fNdim-2]*fNbins[fNdim-1],fNbins[fNdim-1],1}
+
+  fMbins[fNdim-1] = 1;
+  for (int i=0; i<fNdim; i++) fNbins[i] = fAxis[i].GetNbins();
+  for (int i=fNdim-1; i>0; i--) fMbins[i-1] = fMbins[i]*fNbins[i];
+  printf("%d-dimensional histogram %s with %d bins created\n",fNdim,nam,GetNbinsX());
+}
+//=============================================================================
+AliUnicorHN::AliUnicorHN(Char_t *filnam, Char_t *nam) 
+  : TH1D(*((TH1D*) TFile::Open(filnam,"read")->GetDirectory(nam)->Get("histo"))), 
+    fNdim(0) 
+{
+  // Constructor for reading from file.
+
+  TFile *f = TFile::Open(filnam,"read");
+  f->cd(nam);
+  TAxis *ax[fgkMaxNdim];
+  char axnam[1000];
+  for (fNdim=0; fNdim<fgkMaxNdim; fNdim++) {
+    sprintf(axnam,"axis%d",fNdim);
+    ax[fNdim] = (TAxis *) gDirectory->Get(axnam);
+    if (ax[fNdim]) ax[fNdim]->Copy(fAxis[fNdim]); 
+    else break;
+  }
+  f->Close();
+
+  fMbins[fNdim-1] = 1;
+  for (int i=0; i<fNdim; i++) fNbins[i] = fAxis[i].GetNbins();
+  for (int i=fNdim-1; i>0; i--) fMbins[i-1] = fMbins[i]*fNbins[i];
+
+  if (GetNbinsX()!=Albins(fNdim,ax)) {
+    printf("number of bins of histo %d differs from product of nbins of axes %d\n",
+          GetNbinsX(),Albins(fNdim,ax));
+    printf("bombing\n");
+    exit(-1);
+  }
+  printf("%d-dimensional histogram %s with %d bins read from file %s\n",
+        fNdim,nam,GetNbinsX(),filnam);
+}
+//=============================================================================
+Int_t AliUnicorHN::Albins(Int_t n, TAxis **ax) 
+{
+  // Calculate product of nbins of ax[0]...ax[n-1]
+  // (= total number of bins of the multidimensional histogram to be made). 
+
+  Int_t nbins = 1;
+  //  while (n--) nbins *= ax[n]->GetNbins();
+  for (int i=0; i<n; i++) nbins *= ax[i]->GetNbins();
+  return nbins;
+}
+//=============================================================================
+Int_t AliUnicorHN::MulToOne(Int_t *k) const 
+{
+  // Calculate the 1-dim index n from n-dim indices k[fNdim].
+  // Valid k[i] should be between 0 and fNbins[i]-1.
+  // Valid result will be between 0 and GetNbinsX()-1. 
+  // Return -1 if under- or overflow in any dimension.
+
+  Int_t n = 0;
+  for (int i=0; i<fNdim; i++) {
+    if (k[i]<0) return -1;
+    if (k[i]>=fNbins[i]) return -1;
+    n += fMbins[i]*k[i];
+  }
+  return n;
+}
+//=============================================================================
+Int_t AliUnicorHN::MulToOne(Double_t *x) 
+{
+  // Calculate the 1-dim index n from n-dim vector x, representing the 
+  // abscissa of the n-dim histogram. The result will be between 0 and 
+  // GetNbinsX()-1. 
+
+  Int_t k[fgkMaxNdim];
+  for (int i=0; i<fNdim; i++) k[i] = fAxis[i].FindBin(x[i])-1;
+  return MulToOne(k);
+}
+//=============================================================================
+void AliUnicorHN::OneToMul(Int_t n, Int_t *k) const 
+{
+  // Calculate the n-dim indices k[fNdim] from 1-dim index n.
+  // Valid n should be between 0 and GetNbinsX()-1. 
+  // Valid results will be between 0 and fNbins[i]-1.
+
+  div_t idi; // integer division structure 
+  for (int i=0; i<fNdim; i++) {
+    idi  = div(n,fMbins[i]);
+    k[i] = idi.quot;  // quotient
+    n    = idi.rem;   // remainder
+  }
+}
+//=============================================================================
+Int_t AliUnicorHN::Fill(Double_t *xx, Double_t w) 
+{
+  // Fill the histogram. The array xx holds the abscissa information, w is the 
+  // weigth. The 1-dim histogram is filled using the standard Fill method 
+  // (direct access to the arrays was tried and was not faster). 
+
+  int nbin = MulToOne(xx);
+  if (nbin == -1) return 0;
+  return TH1D::Fill(nbin+1,w); 
+}
+//=============================================================================
+Int_t AliUnicorHN::Fill(Double_t x0, Double_t x1, ...) 
+{
+  // Fill the histogram. Arguments are passed as doubles rather than array. 
+  va_list ap;
+  Double_t xx[fgkMaxNdim] = {x0, x1};
+  va_start(ap,x1);
+  for (int i=2; i<fNdim; i++) xx[i] = va_arg(ap,Double_t);
+  Double_t weigth = va_arg(ap,Double_t);
+  va_end(ap);
+  return Fill(xx,weigth);
+}
+//=============================================================================
+Int_t AliUnicorHN::Write() const  
+{
+  // Save the 1-dim histo and the axes in a subdirectory on file. This might 
+  // not be the most elegant way but it is very simple and backward and forward 
+  // compatible. 
+
+  Int_t nbytes = 0;
+  TH1D histo(*this);
+  histo.SetName("histo"); // hadd bug fix; actually, does not cost memory, strange
+
+  TDirectory *dest = gDirectory->mkdir(GetName());
+  if (dest) {
+    dest->cd();
+    nbytes += histo.Write("histo");
+    char axnam[1000];
+    for (int i=0; i<fNdim; i++) {
+      sprintf(axnam,"axis%d",i);
+      nbytes += fAxis[i].Write(axnam);
+    }
+    printf("   %s stored in %s\n",GetName(),dest->GetPath());
+    dest->cd("..");
+  }
+  return nbytes;
+}
+//=============================================================================
+AliUnicorHN *AliUnicorHN::ProjectAlong(char *nam, Int_t dim, Int_t first, Int_t last) 
+{
+  // Reduce dimension dim by summing up its bins between first and last. 
+  // Use root convention: bin=1 is the first bin, bin=nbins is the last. 
+  // Return the resulting fNdim-1 dimensional histogram. 
+
+  if (dim<0 || dim>fNdim-1) return 0;
+  if (first<0) first = 1;
+  if (last<0) last = fNbins[dim];
+
+  // create new (reduced) histogram
+
+  TAxis *ax[fgkMaxNdim-1];
+  int n=0;
+  for (int i=0; i<fNdim; i++) if (i!=dim) ax[n++] = GetAxis(i);
+  char *name = strlen(nam)? nam : Form("%s_wo%d",GetName(),dim);
+  char *eame = Form("%s_error",name); 
+  AliUnicorHN *his = new AliUnicorHN(name,fNdim-1,ax); // result histogram
+  AliUnicorHN *eis = new AliUnicorHN(eame,fNdim-1,ax); // temporary storage for errors
+
+  // sum up the content and errors squared
+
+  Int_t *k = new Int_t[fNdim];   // old hist multiindex
+  Int_t *m = new Int_t[fNdim-1]; // new hist multiindex
+  for (int i=0; i<GetNbinsX(); i++) {
+    OneToMul(i,k);
+    if (k[dim]+1<first) continue;
+    if (k[dim]+1>last) continue;
+    n = 0;
+    for (int j=0; j<fNdim; j++) if (j!=dim) m[n++] = k[j];
+    n = his->MulToOne(m);
+    his->AddBinContent(n+1,GetBinContent(i+1));
+    eis->AddBinContent(n+1,GetBinError(i+1)*GetBinError(i+1));
+  }
+
+  // combine content and errors in one histogram
+
+  for (int i=0; i<his->GetNbinsX(); i++) {
+    his->SetBinError(i+1,sqrt(eis->GetBinContent(i+1)));
+  }
+
+  his->SetLineColor(this->GetLineColor());
+  his->SetFillColor(this->GetFillColor());
+  his->SetMarkerColor(this->GetMarkerColor());
+  his->SetMarkerStyle(this->GetMarkerStyle());
+
+  // some cleanup
+
+  delete eis;
+  return his;
+}
+//=============================================================================
+TH1D *AliUnicorHN::ProjectOn(char *nam, Int_t dim, Int_t *first, Int_t *last) const 
+{
+  // Project on dimension dim. Use only bins between first[i] and last[i]. 
+  // Use root convention: bin=1 is the first bin, bin=nbins is the last. 
+  // first[i]=0 means from the first bin
+  // last[i]=0 means till the last bin
+
+  if (dim<0 || dim>fNdim-1) return 0;
+
+  // calculate the projection; lowest index 0
+
+  double *yy = new double[fNbins[dim]]; // value
+  double *ey = new double[fNbins[dim]]; // error
+  for (int i=0; i<fNbins[dim]; i++) yy[i]=0;
+  for (int i=0; i<fNbins[dim]; i++) ey[i]=0;
+  Int_t *k = new Int_t[fNdim];
+  for (int i=0; i<GetNbinsX(); i++) {
+    OneToMul(i,k);
+    int isgood = 1; // bin within the range?
+    for (int j=0; j<fNdim; j++) {
+      if (first) if (first[j]) if (k[j]+1<first[j]) {isgood = 0; break;}
+      if (last)  if (last[j])  if (k[j]+1>last[j])  {isgood = 0; break;}
+    }
+    if (isgood) {
+      yy[k[dim]]+=GetBinContent(i+1);
+      ey[k[dim]]+=GetBinError(i+1)*GetBinError(i+1);
+    }
+  }
+
+  // make the projection histogram
+  // use name nam if specified; otherwise generate one
+
+  TH1D *his;
+  char *name = strlen(nam)? nam : Form("%s_proj%d",GetName(),dim);
+  if (fAxis[dim].IsVariableBinSize()) 
+    his = new TH1D(name,name,fNbins[dim],fAxis[dim].GetXbins()->GetArray());
+  else 
+    his = new TH1D(name,name,fNbins[dim],fAxis[dim].GetXmin(),fAxis[dim].GetXmax());
+  his->SetXTitle(fAxis[dim].GetTitle());
+  // or his->GetXaxis()->ImportAttributes(ax);
+  his->Sumw2();
+  his->SetLineColor(this->GetLineColor());
+  his->SetFillColor(this->GetFillColor());
+  his->SetMarkerColor(this->GetMarkerColor());
+  his->SetMarkerStyle(this->GetMarkerStyle());
+  for (int i=0; i<his->GetNbinsX(); i++) {
+    his->SetBinContent(i+1,yy[i]);
+    his->SetBinError(i+1,sqrt(ey[i]));
+  }
+
+  // some cleanup
+
+  delete [] yy;
+  delete [] ey;
+  delete [] k;
+  //  if (name!=nam) delete [] name;
+
+  return his;
+}
+//=============================================================================
+TH1D *AliUnicorHN::ProjectOn(char *nam, Int_t dim, Double_t *first, Double_t *last) 
+{
+  // Project on dimension dim. Use only bins between first[i] and last[i]. 
+
+  if (dim<0 || dim>fNdim-1) return 0;
+  Int_t kfirst[fgkMaxNdim];
+  Int_t klast[fgkMaxNdim];
+  for (int i=0; i<fNdim; i++) {
+    kfirst[i] = fAxis[i].FindBin(first[i]);
+    klast[i] = fAxis[i].FindBin(last[i]);
+  }
+  return ProjectOn(nam,dim,kfirst,klast);
+}
+//=============================================================================
+TH2D *AliUnicorHN::ProjectOn(char *nam, Int_t dim0, Int_t dim1, Int_t *first, Int_t *last) const
+{
+  // Project on dim1 vs dim0. Use only bins between first[i] and last[i]. 
+  // Use root convention: bin=1 is the first bin, bin=nbins is the last. 
+  // first[i]=0 means from the first bin
+  // last[i]=0 means till the last bin
+
+  if (dim0<0 || dim0>fNdim-1) return 0;
+  if (dim1<0 || dim1>fNdim-1) return 0;
+
+  // calculate the projection
+
+  double **yy = new double*[fNbins[dim0]]; // value
+  double **ey = new double*[fNbins[dim0]]; // error
+  for (int i=0; i<fNbins[dim0]; i++) yy[i] = new double[fNbins[dim1]]; 
+  for (int i=0; i<fNbins[dim0]; i++) ey[i] = new double[fNbins[dim1]]; 
+  for (int i=0; i<fNbins[dim0]; i++) for (int j=0; j<fNbins[dim1]; j++) yy[i][j]=0;
+  for (int i=0; i<fNbins[dim0]; i++) for (int j=0; j<fNbins[dim1]; j++) ey[i][j]=0;
+  Int_t *k = new Int_t[fNdim];
+  for (int i=0; i<GetNbinsX(); i++) {
+    OneToMul(i,k);
+    int isgood = 1; // bin within the range?
+    for (int j=0; j<fNdim; j++) {
+      if (first) if (first[j]) if (k[j]+1<first[j]) {isgood = 0; break;}
+      if (last)  if (last[j])  if (k[j]+1>last[j])  {isgood = 0; break;}
+    }
+    if (isgood) {
+      yy[k[dim0]][k[dim1]]+=GetBinContent(i+1);
+      ey[k[dim0]][k[dim1]]+=GetBinError(i+1)*GetBinError(i+1);
+    }
+  }
+
+  // make the projection histogram
+  // use name nam if specified; otherwise generate one
+
+  TH2D *his=0;
+  char *name = strlen(nam)? nam : Form("%s_proj%dvs%d",GetName(),dim1,dim0);
+  if (fAxis[dim0].IsVariableBinSize() && fAxis[dim1].IsVariableBinSize()) 
+    his = new TH2D(name,name,
+                  fNbins[dim0],fAxis[dim0].GetXbins()->GetArray(),
+                  fNbins[dim1],fAxis[dim1].GetXbins()->GetArray());
+  else if (!fAxis[dim0].IsVariableBinSize() && fAxis[dim1].IsVariableBinSize()) 
+    his = new TH2D(name,name,
+                  fNbins[dim0],fAxis[dim0].GetXmin(),fAxis[dim0].GetXmax(),
+                  fNbins[dim1],fAxis[dim1].GetXbins()->GetArray());
+  else if (fAxis[dim0].IsVariableBinSize() && !fAxis[dim1].IsVariableBinSize()) 
+    his = new TH2D(name,name,
+                  fNbins[dim0],fAxis[dim0].GetXbins()->GetArray(),
+                  fNbins[dim1],fAxis[dim1].GetXmin(),fAxis[dim1].GetXmax());
+  else if (!fAxis[dim0].IsVariableBinSize() && !fAxis[dim1].IsVariableBinSize()) 
+    his = new TH2D(name,name,
+                  fNbins[dim0],fAxis[dim0].GetXmin(),fAxis[dim0].GetXmax(),
+                  fNbins[dim1],fAxis[dim1].GetXmin(),fAxis[dim1].GetXmax());
+  his->SetXTitle(fAxis[dim0].GetTitle());
+  his->SetYTitle(fAxis[dim1].GetTitle());
+  // or his->GetXaxis()->ImportAttributes(ax0);
+  // or his->GetYaxis()->ImportAttributes(ax1);
+  his->Sumw2();
+  his->SetLineColor(this->GetLineColor());
+  his->SetFillColor(this->GetFillColor());
+  his->SetMarkerColor(this->GetMarkerColor());
+  his->SetMarkerStyle(this->GetMarkerStyle());
+  for (int i=0; i<his->GetNbinsX(); i++) 
+  for (int j=0; j<his->GetNbinsY(); j++) {
+    his->SetBinContent(i+1,j+1,yy[i][j]);
+    his->SetBinError(i+1,j+1,sqrt(ey[i][j]));
+  }
+
+  // some cleanup
+
+  for (int i=0; i<fNbins[dim0]; i++) delete [] yy[i];
+  for (int i=0; i<fNbins[dim0]; i++) delete [] ey[i];
+  delete [] yy;
+  delete [] ey;
+  delete [] k;
+  //  if (name!=nam) delete [] name;
+
+  return his;
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorHN.h b/PWG2/UNICOR/AliUnicorHN.h
new file mode 100644 (file)
index 0000000..ce4712f
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef AliUnicorHN_H
+#define AliUnicorHN_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2007
+
+//=============================================================================
+// multidimensional histogram 
+//=============================================================================
+
+#include <TH1.h>
+class TH2D;
+class TAxis;
+
+//=============================================================================
+class AliUnicorHN : public TH1D {
+
+ public:
+  AliUnicorHN() : TH1D(), fNdim(0)                  {printf("default AliUnicorHN object created\n");}
+  AliUnicorHN(Char_t *nam, Int_t ndim, TAxis **ax); // constructor from scratch
+  AliUnicorHN(Char_t *filename, Char_t *name);      // constructor from file
+  virtual ~AliUnicorHN()                            {printf("AliUnicorHN object %s deleted\n",GetName());}
+  Int_t GetNdim() const                     {return fNdim;}
+  TAxis *GetAxis(Int_t i) const             {return (TAxis*) &fAxis[i];}
+
+  Int_t Fill(Double_t *xx, Double_t y=1);   // fill histo
+  Int_t Fill(Double_t)                      {return -1;} // insufficient number of arguments
+  Int_t Fill(Double_t x0, Double_t w)       {return Fill(&x0,w);} // 1-dim histo fill
+  Int_t Fill(Double_t x0, Double_t x1, ...);// 2 or more dim histo fill
+  Int_t Fill(const char*, Double_t)         {return -1;} // overload TH1
+
+  Int_t Write() const;                      // save histo and axis on file 
+  Int_t Write()                             {return ((const AliUnicorHN*)this)->Write();}
+  Int_t Write(const char *, Int_t, Int_t)   {return Write();} // overload TObject
+  Int_t Write(const char *, Int_t, Int_t) const {return Write();} 
+
+  // project along (integrate over) one axis
+  AliUnicorHN  *ProjectAlong(char *nam, Int_t dim, Int_t first=-1, Int_t last=-1);
+  // project on 1-dim histogram
+  TH1D *ProjectOn(char *nam, Int_t dim, Int_t *first=0, Int_t *last=0) const;
+  // project on 1-dim histogram
+  TH1D *ProjectOn(char *nam, Int_t dim, Double_t *first, Double_t *last);
+  // project on 2-dim histogram
+  TH2D *ProjectOn(char *nam, Int_t dim0, Int_t dim1, Int_t *first=0, Int_t *last=0) const;
+
+ protected:
+
+  static const Int_t fgkMaxNdim=10;         // maximum number of dimensions
+  Int_t              fNdim;                 // number of dimensions
+  TAxis              fAxis[fgkMaxNdim];     // axes
+  Int_t              fNbins[fgkMaxNdim];    // {fAxis[0]->GetNbins(),fAxis[1]->...
+  Int_t              fMbins[fgkMaxNdim];    // {...[fNdim-2]*fNbins[fNdim-1],fNbins[fNdim-1],1}
+  static Int_t Albins(Int_t n, TAxis **ax); // product of nbins of ax[0]...ax[n-1]
+  Int_t MulToOne(Int_t *k) const;           // calc 1-dim index from n-dim indices
+  Int_t MulToOne(Double_t *x);              // calc 1-dim index from n-dim vector
+  void  OneToMul(Int_t n, Int_t *k) const;  // calc n-dim indices from 1-dim index
+
+  ClassDef(AliUnicorHN,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/AliUnicorPair.cxx b/PWG2/UNICOR/AliUnicorPair.cxx
new file mode 100644 (file)
index 0000000..415f71e
--- /dev/null
@@ -0,0 +1,36 @@
+/************************************************************************* 
+* Copyright(c) 1998-2048, 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.                  * 
+**************************************************************************/
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2002
+
+//=============================================================================
+// particle (track) pair
+// Allows to calculate the kinematic pair variables typically used in 
+// two-particle correlation analyses. 
+//=============================================================================
+
+#include "AliUnicorPair.h"
+
+ClassImp(AliUnicorPair)
+
+//=============================================================================
+AliUnicorPair::AliUnicorPair() : fP0(), fP1(), fP(), fQ(), fBeta(), fBetat(), fBetaz(), fUbeta(), 
+                fUbetat(), fUbetaz(), fCMp(), fCMq(), fBuf() 
+{
+  // constructor
+
+  printf("AliUnicorPair object created\n");
+}
+//=============================================================================
diff --git a/PWG2/UNICOR/AliUnicorPair.h b/PWG2/UNICOR/AliUnicorPair.h
new file mode 100644 (file)
index 0000000..1604c63
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef ALIUNICORPAIR_H
+#define ALIUNICORPAIR_H
+
+/* Copyright(c) 1998-2048, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id$ */
+
+// Author: Dariusz Miskowiec <mailto:d.miskowiec@gsi.de> 2002
+
+//=============================================================================
+// particle (track) pair
+//=============================================================================
+
+#include <cmath>
+#include <TObject.h>
+#include <TLorentzVector.h>
+
+//=============================================================================
+class AliUnicorPair : public TObject {
+   
+ public:
+   AliUnicorPair();                       // constructor
+   virtual ~AliUnicorPair()               {printf("AliUnicorPair object deleted\n");}
+   void Set0(double m,double p,double theta,double phi)  {fP0.SetXYZM(0,0,p,m); fP0.SetTheta(theta); fP0.SetPhi(phi);}
+   void Set1(double m,double p,double theta,double phi)  {fP1.SetXYZM(0,0,p,m); fP1.SetTheta(theta); fP1.SetPhi(phi);}
+   void SetMXYZ0(double m,double px,double py,double pz) {fP0.SetXYZM(px,py,pz,m);}
+   void SetMXYZ1(double m,double px,double py,double pz) {fP1.SetXYZM(px,py,pz,m);}
+   void CalcLAB()                 {fP=fP0+fP1; fQ=fP1-fP0; fBeta=fP.BoostVector(); 
+                                   fBetaz.SetXYZ(0,0,fBeta.Z()); fBetat=fBeta; fBetat.SetZ(0); 
+                                   fUbeta=fBeta.Unit(); fUbetat=fBetat.Unit(); fUbetaz=fBetaz.Unit();}
+   double Rapidity()        const {return fP.Rapidity();}
+   double Pt()              const {return fP.Pt();}
+   double Phi()             const {return fP.Phi();}
+   double DTheta()          const {return fP1.Theta()-fP0.Theta();}
+   double DPhi()            const {return TVector2::Phi_mpi_pi(fP1.Phi()-fP0.Phi());}
+   void CalcPairCM()              {fCMp=fP; fCMp.Boost(-fBeta);  fCMq=fQ; fCMq.Boost(-fBeta);}
+   void CalcLcmsCM()              {fCMp=fP; fCMp.Boost(-fBetaz); fCMq=fQ; fCMq.Boost(-fBetaz);}
+   void Swap()                    {fBuf=fP0; fP0=fP1; fP1=fBuf; fQ=-fQ; fCMq=-fCMq;}
+   double Minv()            const {return fP.M();}
+   double Qinv2()           const {return -fQ.M2();}
+   double QCM()             const {return fCMq.Vect().Mag();}
+   double QCMpar()          const {return fCMq.Vect()*fUbeta;}
+   double QCMper()          const {return sqrt(fabs(QCM()*QCM()-QCMpar()*QCMpar()));}
+   double QCMout()          const {return +fCMq.Vect().X()*fUbetat.X()+fCMq.Vect().Y()*fUbetat.Y();}
+   double QCMside()         const {return -fCMq.Vect().X()*fUbetat.Y()+fCMq.Vect().Y()*fUbetat.X();}
+   double QCMlong()         const {return fCMq.Vect().Z();}
+   double QCMTheta()        const {return fCMq.Theta();}
+   double QCMPhi()          const {return fCMq.Phi();}
+   double QCMPhiOut()       const {return atan2(QCMside(),QCMout());} // phi w.r.t. out
+
+ protected:
+   TLorentzVector fP0;            // LAB four-momentum of track 0
+   TLorentzVector fP1;            // LAB four-momentum of track 1
+   TLorentzVector fP;             // LAB total four-momentum
+   TLorentzVector fQ;             // LAB four-momentum difference
+   TVector3 fBeta;                // LAB pair velocity
+   TVector3 fBetat;               // LAB pair velocity transverse
+   TVector3 fBetaz;               // LAB pair velocity along z
+   TVector3 fUbeta;               // LAB pair velocity direction
+   TVector3 fUbetat;              // LAB pair velocity transverse direction
+   TVector3 fUbetaz;              // LAB pair velocity along z direction (hm)
+   TLorentzVector fCMp;           // CM total four-momentum
+   TLorentzVector fCMq;           // CM four-momentum difference
+   TLorentzVector fBuf;           // dummy buffer for swapping
+
+   ClassDef(AliUnicorPair,1)
+};
+//=============================================================================
+#endif
diff --git a/PWG2/UNICOR/runAsTask.C b/PWG2/UNICOR/runAsTask.C
new file mode 100644 (file)
index 0000000..81e1af8
--- /dev/null
@@ -0,0 +1,25 @@
+{
+gSystem->Load("libVMC.so"); 
+gSystem->Load("libSTEERBase.so");
+gSystem->Load("libESD.so");
+gSystem->Load("libAOD.so");
+gSystem->Load("libANALYSIS");
+gSystem->Load("libANALYSISalice");
+gSystem->Load("libPWG2unicor");
+
+gROOT->LoadMacro("makechain.C");
+tr = makechain("esdTree","/data.local1/alice/data/silvia/0000*AliESDs.root");    // local emergency copy
+
+AliAnalysisManager *mgr = new AliAnalysisManager("TestManager");
+AliVEventHandler* esdH = new AliESDInputHandler;
+mgr->SetInputEventHandler(esdH);  
+AliAnalysisTaskUnicor *mytask = new AliAnalysisTaskUnicor();
+mgr->AddTask(mytask);
+AliAnalysisDataContainer *cinput = mgr->CreateContainer("cinput",TChain::Class(),AliAnalysisManager::kInputContainer);
+AliAnalysisDataContainer *coutpt = mgr->CreateContainer("unilis", TList::Class(),AliAnalysisManager::kOutputContainer,"unicor-result-as-list.root");
+mgr->ConnectInput (mytask,0,cinput);
+mgr->ConnectOutput(mytask,1,coutpt);
+mgr->InitAnalysis();
+mgr->PrintStatus(); 
+mgr->StartAnalysis("local",tr);
+}
diff --git a/PWG2/libPWG2unicor.pkg b/PWG2/libPWG2unicor.pkg
new file mode 100644 (file)
index 0000000..0d7d1c9
--- /dev/null
@@ -0,0 +1,26 @@
+#-*- Mode: Makefile -*-
+
+SRCS= UNICOR/AliAnalysisTaskUnicor.cxx \
+      UNICOR/AliUnicorAnalCorrel.cxx \
+      UNICOR/AliUnicorAnal.cxx \
+      UNICOR/AliUnicorAnalGlobal.cxx \
+      UNICOR/AliUnicorAnalHighpt.cxx    \
+      UNICOR/AliUnicorAnalPtfluc.cxx    \
+      UNICOR/AliUnicorAnalSingle.cxx    \
+      UNICOR/AliUnicorEventAliceESD.cxx \
+      UNICOR/AliUnicorEvent.cxx \
+      UNICOR/AliUnicorHN.cxx \
+      UNICOR/AliUnicorPair.cxx 
+
+HDRS= $(SRCS:.cxx=.h) 
+
+DHDR:= PWG2unicorLinkDef.h
+
+EXPORT:=
+
+EINCLUDE:= PWG2/UNICOR 
+
+ifeq (win32gcc,$(ALICE_TARGET))
+PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) -lSTEERBase \
+                         -lESD -lAOD 
+endif