--- /dev/null
+AliAnalysisTask *AddTaskTender(){
+ //get the current analysis manager
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ Error("AddTask_tender_Tender", "No analysis manager found.");
+ return 0;
+ }
+ // currently don't accept AOD input
+ if (mgr->GetInputEventHandler()->IsA()!=AliESDInputHandler::Class()) {
+ Error("AddTask_tender_Tender","The analysis tender only works with ESD input!");
+ return 0;
+ }
+
+
+ //========= Add tender to the ANALYSIS manager and set default storage =====
+ AliTender *tender=new AliTender("AnalysisTender");
+ tender->SetDefaultCDBStorage("raw://");
+ mgr->AddTask(tender);
+
+ //========= Attach TPC supply ======
+ AliTPCTenderSupply *tpcSupply=new AliTPCTenderSupply("TPCtender");
+ tender->AddSupply(tpcSupply);
+
+ //========= Attach TOF supply ======
+ AliTOFTenderSupply *TOFtender = new AliTOFTenderSupply("TOFtender");
+ tender->AddSupply(TOFtender);
+
+ //========= Attach TRD supply ======
+ AliTRDTenderSupply *trdSupply=new AliTRDTenderSupply("TRDtender");
+ tender->AddSupply(trdSupply);
+
+ //========= Attach PID supply ======
+ tender->AddSupply(new AliPIDTenderSupply("PIDtender"));
+
+ //========= Attach Primary Vertex supply ======
+ tender->AddSupply(new AliVtxTenderSupply("PriVtxtender"));
+
+ //================================================
+ // data containers
+ //================================================
+
+ // define output containers, please use 'username'_'somename'
+ AliAnalysisDataContainer *coutput1 =
+ mgr->CreateContainer("tender_event", AliESDEvent::Class(),
+ AliAnalysisManager::kExchangeContainer,"default_tender");
+
+ // connect containers
+ mgr->ConnectInput (tender, 0, mgr->GetCommonInputContainer() );
+ mgr->ConnectOutput (tender, 0, coutput1);
+
+ return tender;
+}
--- /dev/null
+/**************************************************************************
+ * 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. *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// PID tender: Do combined PID //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include <AliESDpid.h>
+#include <AliESDEvent.h>
+#include <AliESDInputHandler.h>
+#include "AliTender.h"
+
+#include "AliPIDTenderSupply.h"
+
+AliPIDTenderSupply::AliPIDTenderSupply() :
+ AliTenderSupply()
+{
+ //
+ // default ctor
+ //
+}
+
+//_____________________________________________________
+AliPIDTenderSupply::AliPIDTenderSupply(const char *name, const AliTender *tender) :
+ AliTenderSupply(name,tender)
+{
+ //
+ // named ctor
+ //
+}
+
+//_____________________________________________________
+void AliPIDTenderSupply::ProcessEvent()
+{
+ //
+ // Combine PID information
+ //
+
+ AliESDEvent *event=fTender->GetEvent();
+ if (!event) return;
+
+ AliESDpid *pid=fTender->GetESDhandler()->GetESDpid();
+ if (!pid) return;
+ //
+ // recalculate combined PID probabilities
+ //
+ Int_t ntracks=event->GetNumberOfTracks();
+ for(Int_t itrack = 0; itrack < ntracks; itrack++)
+ pid->CombinePID(event->GetTrack(itrack));
+
+}
--- /dev/null
+#ifndef ALIPIDTENDERSUPPLY_H
+#define ALIPIDTENDERSUPPLY_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////
+// //
+// PID tender, reapply pid on the fly //
+// //
+////////////////////////////////////////////////////////////////////////
+
+
+
+#include <AliTenderSupply.h>
+
+class AliPIDTenderSupply: public AliTenderSupply {
+
+public:
+ AliPIDTenderSupply();
+ AliPIDTenderSupply(const char *name, const AliTender *tender=NULL);
+
+ virtual ~AliPIDTenderSupply(){;}
+
+ virtual void Init(){;}
+ virtual void ProcessEvent();
+
+private:
+
+ AliPIDTenderSupply(const AliPIDTenderSupply&c);
+ AliPIDTenderSupply& operator= (const AliPIDTenderSupply&c);
+
+ ClassDef(AliPIDTenderSupply, 1); // PID tender task
+};
+
+
+#endif
+
--- /dev/null
+/**************************************************************************
+ * 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: AliTOFT0makerANA.cxx,v 1.8 2010/01/19 16:32:20 noferini Exp $ */
+
+/////////////////////////////////////////////////////////////////////////////
+// //
+// This class contains the basic functions for the time zero //
+// evaluation with TOF detector informations. //
+// Use case in an analysis task: //
+// //
+// Create the object in the task constructor (fTOFmakerANA is a private var) //
+// fTOFmakerANA = new AliTOFT0makerANA(); //
+// fTOFmakerANA->SetTimeResolution(130.0); // if you want set the TOF res //
+// 115 ps is the TOF default resolution value //
+// //
+// Use the RemakePID method in the task::Exec //
+// Double_t* calcolot0; //
+// calcolot0=fTOFmakerANA->RemakePID(fESD); //
+// //calcolot0[0] = calculated event time //
+// //calcolot0[1] = event time time resolution //
+// //calcolot0[2] = average event time for the current fill //
+// //calcolot0[3] = tracks at TOF //
+// //calcolot0[4] = calculated event time (only TOF) //
+// //calcolot0[5] = event time time resolution (only TOF) //
+// //calcolot0[6] = sigma t0 fill //
+// //calcolot0[7] = tracks at TOF really used in tht algorithm //
+// //
+// Let consider that: //
+// - the PIF is automatically recalculated with the event time subtrction //
+// //
+/////////////////////////////////////////////////////////////////////////////
+
+#include <AliPID.h>
+#include <AliESDpid.h>
+#include <AliESDEvent.h>
+#include <TFile.h>
+#include <TH1F.h>
+
+#include "AliTOFT0v2.h"
+#include "AliTOFT0makerANA.h"
+
+ClassImp(AliTOFT0makerANA)
+
+//____________________________________________________________________________
+AliTOFT0makerANA::AliTOFT0makerANA():
+ fPIDesd(0x0),
+ fnT0(0),
+ fiT0(0),
+ fNoTOFT0(0),
+ fTimeResolution(115),
+ fT0sigma(1000),
+ fHmapChannel(0),
+ fKmask(0)
+{
+ // ctr
+ fCalculated[0] = 0;
+ fCalculated[1] = 0;
+ fCalculated[2] = 0;
+ fCalculated[3] = 0;
+
+ if(AliPID::ParticleMass(0) == 0) new AliPID();
+
+ fPIDesd = new AliESDpid();
+
+}
+//____________________________________________________________________________
+AliTOFT0makerANA::AliTOFT0makerANA(AliESDpid *const externalPID):
+ fPIDesd(0x0),
+ fnT0(0),
+ fiT0(0),
+ fNoTOFT0(0),
+ fTimeResolution(115),
+ fT0sigma(1000),
+ fHmapChannel(0),
+ fKmask(0)
+{
+ // ctr
+ fCalculated[0] = 0;
+ fCalculated[1] = 0;
+ fCalculated[2] = 0;
+ fCalculated[3] = 0;
+
+ if(AliPID::ParticleMass(0) == 0) new AliPID();
+
+ fPIDesd = externalPID;
+ if(!fPIDesd){
+ fPIDesd = new AliESDpid();
+ printf("ATTENTION!!!\n New AliESDpid is created in AliTOFT0makerANA class!!!!\n");
+ }
+
+}
+//____________________________________________________________________________
+AliTOFT0makerANA::AliTOFT0makerANA(const AliTOFT0makerANA & t) :
+TObject(),
+fPIDesd(t.fPIDesd),
+fnT0(t.fnT0),
+fiT0(t.fiT0),
+fNoTOFT0(t.fNoTOFT0),
+fTimeResolution(t.fTimeResolution),
+fT0sigma(t.fT0sigma),
+fHmapChannel(t.fHmapChannel),
+fKmask(t.fKmask)
+{
+ // copy ctr
+}
+
+//____________________________________________________________________________
+AliTOFT0makerANA& AliTOFT0makerANA::operator=(const AliTOFT0makerANA &t)
+{
+ //
+ // assign. operator
+ //
+
+ if (this == &t)
+ return *this;
+ fTimeResolution = t.fTimeResolution;
+ fT0sigma = t.fT0sigma;
+
+ return *this;
+}
+//____________________________________________________________________________
+AliTOFT0makerANA::~AliTOFT0makerANA()
+{
+ // dtor
+}
+//____________________________________________________________________________
+Double_t* AliTOFT0makerANA::RemakePID(AliESDEvent *esd,Double_t t0time,Double_t t0sigma){
+ //
+ // Remake TOF PID probabilities
+ //
+
+ Double_t *t0tof;
+
+ if(fKmask) ApplyMask(esd);
+
+ AliTOFT0v2 t0makerANA(esd);
+ t0makerANA.SetTimeResolution(fTimeResolution*1e-12*1.1);
+
+ t0tof=t0makerANA.DefineT0("all");
+
+ Float_t lT0Current=0.;
+ fT0sigma=1000;
+
+ Double_t t0fill = GetT0Fill();
+ t0time += t0fill;
+
+ Float_t sigmaFill = (t0fill - Int_t(t0fill))*1000;
+ if(sigmaFill < 0) sigmaFill += 1000;
+
+ if(sigmaFill < 50) sigmaFill = 50;
+
+ fCalculated[0]=-1000*t0tof[0]; // best t0
+ fCalculated[1]=1000*t0tof[1]; // sigma best t0
+ fCalculated[2] = t0fill; //t0 fill
+ fCalculated[3] = t0tof[2]; // n TOF tracks
+ fCalculated[4]=-1000*t0tof[0]; // TOF t0
+ fCalculated[5]=1000*t0tof[1]; // TOF t0 sigma
+ fCalculated[6]=sigmaFill; // sigma t0 fill
+ fCalculated[7] = t0tof[3]; // n TOF tracks used for T0
+
+ if(fCalculated[1] < sigmaFill){
+ if(fnT0 < 10){
+ fT0fill[fiT0] = fCalculated[0];
+ fT0sigmaTOF[fiT0] = fCalculated[1];
+ fiT0++;
+ fnT0++;
+ }
+ else if(TMath::Abs(fCalculated[0] - t0fill) < 500){
+ fT0fill[fiT0] = fCalculated[0];
+ fT0sigmaTOF[fiT0] = fCalculated[1];
+ fiT0++;
+ fnT0++;
+ }
+
+ // printf("%i - %i) %f\n",fiT0,fnT0,t0fill);
+ }
+ if(fnT0==10) fiT0=0;
+
+ if(fiT0 > fgkNmaxT0step-1) fiT0=0;
+
+ if(fnT0 < 100){
+ t0time -= t0fill;
+ sigmaFill=200;
+ t0fill=0;
+ fCalculated[2] = t0fill; //t0 fill
+ }
+
+ if(fCalculated[1] < sigmaFill && TMath::Abs(fCalculated[0] - t0fill) < 500){
+ fT0sigma=fCalculated[1];
+ lT0Current=fCalculated[0];
+ }
+ else{
+ fCalculated[4] = t0fill;
+ fCalculated[5] = sigmaFill;
+ }
+
+ if(fCalculated[1] < 1 || fT0sigma > sigmaFill){
+ fT0sigma =1000;
+ fCalculated[4] = t0fill;
+ fCalculated[5] = sigmaFill;
+ }
+
+ if(t0sigma < 1000){
+ if(fT0sigma < 1000){
+ Double_t w1 = 1./t0sigma/t0sigma;
+ Double_t w2 = 1./fCalculated[1]/fCalculated[1];
+
+ Double_t wtot = w1+w2;
+
+ lT0Current = (w1*t0time + w2*fCalculated[0]) / wtot;
+ fT0sigma = TMath::Sqrt(1./wtot);
+ }
+ else{
+ lT0Current=t0time;
+ fT0sigma=t0sigma;
+ }
+ }
+
+ if(fT0sigma < sigmaFill && TMath::Abs(lT0Current - t0fill) < 500){
+ fCalculated[1]=fT0sigma;
+ fCalculated[0]=lT0Current;
+ }
+
+ if(fT0sigma >= 1000 || fNoTOFT0){
+ lT0Current = t0fill;
+ fT0sigma = sigmaFill;
+
+ fCalculated[0] = t0fill;
+ fCalculated[1] = sigmaFill;
+ }
+
+
+
+ RemakeTOFpid(/*esd,*/lT0Current);
+
+ return fCalculated;
+}
+//____________________________________________________________________________
+void AliTOFT0makerANA::RemakeTOFpid(/*AliESDEvent *esd,*/Float_t timezero){
+ //
+ // Recalculate TOF PID probabilities
+ //
+
+ fPIDesd->GetTOFResponse().SetTimeResolution(TMath::Sqrt(fT0sigma*fT0sigma + fTimeResolution*fTimeResolution));
+ // fPIDesd->MakePID(esd,kFALSE,timezero);
+ fPIDesd->GetTOFResponse().SetTimeZero(timezero);
+ // please call fESDpid->MakePID(fEvent, kFALSE,fESDpid->GetTOFResponse().GetTimeZero()); when you make new PID
+}
+//____________________________________________________________________________
+Double_t AliTOFT0makerANA::GetT0Fill() const {
+ //
+ // Return T0 of filling
+ //
+
+ Double_t t0=0.200;
+
+ Int_t n=fnT0;
+
+ if(n >10 && n <= 20) n = 10;
+ else if(n > 20){
+ n -= 10;
+ }
+
+ if(n > fgkNmaxT0step) n = fgkNmaxT0step;
+
+ if(n>1){
+ Double_t lT0av=0;
+ Double_t lT0sigmaav=0;
+ Double_t lT0avErr=0;
+ for(Int_t i=0;i<n;i++){
+ lT0av+=fT0fill[i];
+ lT0sigmaav += fT0sigmaTOF[fiT0];
+ lT0avErr+=fT0fill[i]*fT0fill[i];
+ }
+ lT0avErr -= lT0av*lT0av/n;
+ lT0av /= n;
+ lT0sigmaav /= n;
+ lT0avErr = TMath::Sqrt(TMath::Max(lT0avErr/(n-1) - lT0sigmaav*lT0sigmaav,0.00001));
+
+
+ if(lT0avErr > 300) lT0avErr = 300;
+
+ lT0av = Int_t(lT0av) + lT0avErr/1000.;
+
+ return lT0av;
+ }
+
+
+ return t0;
+}
+//____________________________________________________________________________
+void AliTOFT0makerANA::LoadChannelMap(char *filename){
+ // Load the histo with the channel off map
+ TFile *f= new TFile(filename);
+ if(!f){
+ printf("Cannot open the channel map file (%s)\n",filename);
+ return;
+ }
+
+ fHmapChannel = (TH1F *) f->Get("hChEnabled");
+
+ if(!fHmapChannel){
+ printf("Cannot laod the channel map histo (from %s)\n",filename);
+ return;
+ }
+
+}
+//____________________________________________________________________________
+void AliTOFT0makerANA::ApplyMask(AliESDEvent * const esd){
+ // Switch off the disable channel
+ if(!fHmapChannel){
+ printf("Channel Map is not available\n");
+ return;
+ }
+
+ Int_t ntracks = esd->GetNumberOfTracks();
+
+ while (ntracks--) {
+ AliESDtrack *t=esd->GetTrack(ntracks);
+
+ if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
+
+ Int_t chan = t->GetTOFCalChannel();
+
+ if(fHmapChannel->GetBinContent(chan) < 0.01){
+ t->ResetStatus(AliESDtrack::kTOFout);
+ }
+ }
+}
+
+//____________________________________________________________________________
--- /dev/null
+#ifndef ALITOFT0MAKERANA_H
+#define ALITOFT0MAKERANA_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id: AliTOFT0makerANA.h,v 1.8 2010/01/19 16:32:20 noferini Exp $ */
+
+///////////////////////////////////////////////
+// //
+// Manager class for time zero evaluation //
+// with TOF informations //
+// //
+///////////////////////////////////////////////
+
+
+#include "TObject.h"
+
+class TH1F;
+class AliESDEvent;
+
+class AliTOFT0v2;
+class AliESDpid;
+
+class AliTOFT0makerANA : public TObject {
+public:
+
+ AliTOFT0makerANA() ;
+ AliTOFT0makerANA(AliESDpid * const externalPID);
+ virtual ~AliTOFT0makerANA() ; // dtor
+ AliTOFT0makerANA(const AliTOFT0makerANA & t);
+ AliTOFT0makerANA & operator=(const AliTOFT0makerANA & t);
+
+ // return (fCalculated[0]=event time -- fCalculated[1]=sigma event time in ps -- fCalculated[2]=mean event time for each fill -- fCalculated[3]=number of tracks at the TOF level) if you can subtruct the event time -- ...
+ Double_t *RemakePID(AliESDEvent *esd,Double_t t0time=0.,Double_t t0sigma=1000.); // t0time and t0sigma in ps
+
+ void SetTimeResolution(Double_t timeresolution){fTimeResolution=timeresolution;};// TOF timeresolution in [s] e.g. for 120 ps -> 1.2e-10
+ Double_t GetTimeResolution() const {return fTimeResolution;}
+
+ void LoadChannelMap(char *filename="$ALICE_ROOT/TOF/enableMap.104892.root"); //load the enable channel map
+ void ApplyMask(AliESDEvent * const esd);
+
+ void SetNoTOFT0(Bool_t status=kTRUE){fNoTOFT0=status;}; // disable the TOF T0 info
+ void SetMaskOffChannel(Bool_t status=kTRUE){fKmask=status;}; // swith for the map off channel
+
+ private:
+ AliESDpid *fPIDesd; //!ESD pid object
+ void TakeTimeRawCorrection(AliESDEvent * const esd);
+ void RemakeTOFpid(/*AliESDEvent *esd,*/Float_t timezero);
+ Double_t GetT0Fill() const;
+
+ Int_t fnT0; //! total number of T0-TOF
+ Int_t fiT0; //! last T0-TOF used for T0 fill
+ Double_t fT0fill[1000]; //! array for dynamical t0 fill calculation
+ Double_t fT0sigmaTOF[1000]; //! array for dynamical t0 fill resolution
+
+ Bool_t fNoTOFT0; //! switch to avoid T0-TOF is used
+
+ Double_t fCalculated[8]; //! contains the parameters with the event time
+ Double_t fTimeResolution; //! global time resolution used to calculate T0
+
+ Float_t fT0sigma; //! T0 resolution
+
+ TH1F *fHmapChannel; //! histo with the channel map
+ Bool_t fKmask; //! switch if you want apply a channel filter
+
+ static const Int_t fgkNmaxT0step = 500; //number of steps in the t0 fill calculation
+
+ ClassDef(AliTOFT0makerANA,2); // Calculate the time zero using TOF detector */
+
+};
+
+#endif // ALITOFT0MAKERANA_H
--- /dev/null
+/**************************************************************************
+ * 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: AliTOFT0v2.cxx,v 1.8 2010/01/19 16:32:20 noferini Exp $ */
+
+//_________________________________________________________________________
+// This is a TTask that made the calculation of the Time zero using TOF.
+// Description: The algorithm used to calculate the time zero of interaction
+// using TOF detector is the following.
+// We select in the ESD some "primary" particles - or tracks in the following -
+// that strike the TOF detector (the larger part are pions, kaons or protons).
+// We choose a set of 10 selected tracks, for each track You have the length
+// of the track when the TOF is reached,
+// the momentum and the time of flight
+// given by the TOF detector.
+// Let consider now only one set of 10 tracks (the algorithm is the same for all sets).
+// Assuming the (mass) hypothesis that each track can be AUT a pion, AUT a kaon, AUT a proton,
+// we consider all the 3 at 10 possible cases.
+// For each track in each (mass) configuration
+// (a configuration can be e.g. pion/pion/kaon/proton/pion/proton/kaon/kaon/pion/pion)
+// we calculate the time zero (we know in fact the velocity of the track after
+// the assumption about its mass, the time of flight given by the TOF, and the
+// corresponding path travelled till the TOF detector). Then for each mass configuration we have
+// 10 time zero and we can calculate the ChiSquare for the current configuration using the
+// weighted mean over all 10 time zero.
+// We call the best assignment the mass configuration that gives the minimum value of the ChiSquare.
+// We plot the weighted mean over all 10 time zero for the best assignment,
+// the ChiSquare for the best assignment and the corresponding confidence level.
+// The strong assumption is the MC selection of primary particles. It will be introduced
+// in the future also some more realistic simulation about this point.
+// Use case:
+// root [0] AliTOFT0v2 * tzero = new AliTOFT0v2("galice.root")
+// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
+// root [1] tzero->ExecuteTask()
+// root [2] tzero->ExecuteTask("tim")
+// // available parameters:
+// tim - print benchmarking information
+// all - print usefull informations about the number of misidentified tracks
+// and a comparison about the true configuration (known from MC) and the best
+// assignment
+// Different Selections for pp and Pb-Pb: Momentum Range, Max Time, # pions
+//-- Author: F. Pierella
+//-- Mod By Silvia Arcelli, Francesco Noferini, Barbara Guerzoni
+//////////////////////////////////////////////////////////////////////////////
+
+#include "AliESDtrack.h"
+#include "AliESDEvent.h"
+#include "AliTOFT0v2.h"
+
+ClassImp(AliTOFT0v2)
+
+//____________________________________________________________________________
+AliTOFT0v2::AliTOFT0v2():
+ fLowerMomBound(0.5),
+ fUpperMomBound(1.5),
+ fTimeResolution(0.80e-10),
+ fTimeCorr(0.),
+ fEvent(0x0)
+// fCalib(0x0)
+{
+ //
+ // default constructor
+ //
+
+ fT0SigmaT0def[0]=-999.;
+ fT0SigmaT0def[1]=999.;
+ fT0SigmaT0def[2]=-999.;
+ fT0SigmaT0def[3]=-999.;
+
+}
+
+
+//____________________________________________________________________________
+AliTOFT0v2::AliTOFT0v2(AliESDEvent* event):
+ fLowerMomBound(0.5),
+ fUpperMomBound(1.5),
+ fTimeResolution(0.80e-10),
+ fTimeCorr(0.),
+ fEvent(event)
+// fCalib(0x0)
+{
+ //
+ // real constructor
+ //
+
+ fT0SigmaT0def[0]=-999.;
+ fT0SigmaT0def[1]= 999.;
+ fT0SigmaT0def[2]=-999.;
+ fT0SigmaT0def[3]=-999.;
+
+}
+
+//____________________________________________________________________________
+AliTOFT0v2::AliTOFT0v2(const AliTOFT0v2 & tzero):
+ TObject(),
+ fLowerMomBound(tzero.fLowerMomBound),
+ fUpperMomBound(tzero.fUpperMomBound),
+ fTimeResolution(tzero.fTimeResolution),
+ fTimeCorr(tzero.fTimeCorr),
+ fEvent(tzero.fEvent)
+// fCalib(tzero.fCalib)
+{
+ //
+ // copy constructor
+ //
+
+ fT0SigmaT0def[0]=tzero.fT0SigmaT0def[0];
+ fT0SigmaT0def[1]=tzero.fT0SigmaT0def[1];
+ fT0SigmaT0def[2]=tzero.fT0SigmaT0def[2];
+ fT0SigmaT0def[3]=tzero.fT0SigmaT0def[3];
+
+}
+
+//____________________________________________________________________________
+AliTOFT0v2& AliTOFT0v2::operator=(const AliTOFT0v2 &tzero)
+{
+ //
+ // assign. operator
+ //
+
+ if (this == &tzero)
+ return *this;
+
+ fLowerMomBound=tzero.fLowerMomBound;
+ fUpperMomBound=tzero.fUpperMomBound;
+ fTimeResolution=tzero.fTimeResolution;
+ fTimeCorr=tzero.fTimeCorr;
+ fEvent=tzero.fEvent;
+// fCalib=tzero.fCalib;
+ fT0SigmaT0def[0]=tzero.fT0SigmaT0def[0];
+ fT0SigmaT0def[1]=tzero.fT0SigmaT0def[1];
+ fT0SigmaT0def[2]=tzero.fT0SigmaT0def[2];
+ fT0SigmaT0def[3]=tzero.fT0SigmaT0def[3];
+
+ return *this;
+}
+//____________________________________________________________________________
+AliTOFT0v2::~AliTOFT0v2()
+{
+ // dtor
+// fCalib=NULL;
+ fEvent=NULL;
+
+}
+//____________________________________________________________________________
+void AliTOFT0v2::SetTimeResolution(Double_t timeresolution){
+ // Set the TOF time resolution
+ fTimeResolution=timeresolution;
+}
+//____________________________________________________________________________
+//____________________________________________________________________________
+Double_t * AliTOFT0v2::DefineT0(Option_t *option)
+{
+ // Caluclate the Event Time using the ESD TOF time
+
+ Float_t timeresolutioninns=fTimeResolution*(1.e+9); // convert in [ns]
+
+ const Int_t nmaxtracksinset=10;
+// if(strstr(option,"all")){
+// cout << "Selecting primary tracks with momentum between " << fLowerMomBound << " GeV/c and " << fUpperMomBound << " GeV/c" << endl;
+// cout << "Memorandum: 0 means PION | 1 means KAON | 2 means PROTON" << endl;
+// }
+
+
+ Int_t nsets=0;
+ Int_t nUsedTracks=0;
+ Int_t ngoodsetsSel= 0;
+ Float_t t0bestSel[300];
+ Float_t eT0bestSel[300];
+ Float_t chiSquarebestSel[300];
+ Float_t confLevelbestSel[300];
+ Float_t t0bestallSel=0.;
+ Float_t eT0bestallSel=0.;
+ Float_t sumWt0bestallSel=0.;
+ Float_t eMeanTzeroPi=0.;
+ Float_t meantzeropi=0.;
+ Float_t sumAllweightspi=0.;
+ Double_t t0def=-999;
+ Double_t deltat0def=999;
+ Int_t ngoodtrktrulyused=0;
+ Int_t ntracksinsetmyCut = 0;
+
+ Int_t ntrk=fEvent->GetNumberOfTracks();
+
+ AliESDtrack **tracks=new AliESDtrack*[ntrk];
+ Int_t ngoodtrk=0;
+ Int_t ngoodtrkt0 =0;
+ Float_t mintime =1E6;
+
+ // First Track loop, Selection of good tracks
+
+ for (Int_t itrk=0; itrk<ntrk; itrk++) {
+ AliESDtrack *t=fEvent->GetTrack(itrk);
+ Double_t momOld=t->GetP();
+ Double_t mom=momOld-0.0036*momOld;
+ if ((t->GetStatus()&AliESDtrack::kTIME)==0) continue;
+ if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
+ Double_t time=t->GetTOFsignal();
+
+ time*=1.E-3; // tof given in nanoseconds
+ if (!(mom<=fUpperMomBound && mom>=fLowerMomBound))continue;
+
+ if (!AcceptTrack(t)) continue;
+
+ if(t->GetP() < fLowerMomBound || t->GetIntegratedLength() < 350 || t->GetTOFsignalToT() < 0.000000001)continue; //skip decays
+ if(time <= mintime) mintime=time;
+ tracks[ngoodtrk]=t;
+ ngoodtrk++;
+ }
+
+
+// cout << " N. of ESD tracks : " << ntrk << endl;
+// cout << " N. of preselected tracks : " << ngoodtrk << endl;
+// cout << " Minimum tof time in set (in ns) : " << mintime << endl;
+
+ AliESDtrack **gtracks=new AliESDtrack*[ngoodtrk];
+
+ for (Int_t jtrk=0; jtrk< ngoodtrk; jtrk++) {
+ AliESDtrack *t=tracks[jtrk];
+ Double_t time=t->GetTOFsignal();
+
+ if((time-mintime*1.E3)<50.E3){ // For pp and per
+ gtracks[ngoodtrkt0]=t;
+ ngoodtrkt0++;
+ }
+ }
+
+
+ Int_t nseteq = (ngoodtrkt0-1)/nmaxtracksinset + 1;
+ Int_t nmaxtracksinsetCurrent=ngoodtrkt0/nseteq;
+ if(nmaxtracksinsetCurrent*nseteq < ngoodtrkt0) nmaxtracksinsetCurrent++;
+
+ if(ngoodtrkt0<2){
+// cout << "less than 2 tracks, skip event " << endl;
+ t0def=-999;
+ deltat0def=0.600;
+ fT0SigmaT0def[0]=t0def;
+ fT0SigmaT0def[1]=deltat0def;
+ fT0SigmaT0def[2]=ngoodtrkt0;
+ fT0SigmaT0def[3]=ngoodtrkt0;
+ //goto finish;
+ }
+ if(ngoodtrkt0>=2){
+ // Decide how many tracks in set
+ Int_t ntracksinset = std::min(ngoodtrkt0,nmaxtracksinsetCurrent);
+ Int_t nset=1;
+
+ if(ngoodtrkt0>nmaxtracksinsetCurrent) {nset= (Int_t)(ngoodtrkt0/ntracksinset)+1;}
+
+ // Loop over selected sets
+
+ if(nset>=1){
+ for (Int_t i=0; i< nset; i++) {
+
+ Float_t t0best=999.;
+ Float_t eT0best=999.;
+ Float_t chisquarebest=99999.;
+ Int_t npionbest=0;
+
+ Int_t ntracksinsetmy=0;
+ AliESDtrack **tracksT0=new AliESDtrack*[ntracksinset];
+ for (Int_t itrk=0; itrk<ntracksinset; itrk++) {
+ Int_t index = itrk+i*ntracksinset;
+ if(index < ngoodtrkt0){
+ AliESDtrack *t=gtracks[index];
+ tracksT0[itrk]=t;
+ ntracksinsetmy++;
+ }
+ }
+
+ // Analyse it
+
+ Int_t assparticle[nmaxtracksinset];
+ Float_t exptof[nmaxtracksinset][3];
+ Float_t timeofflight[nmaxtracksinset];
+ Float_t momentum[nmaxtracksinset];
+ Float_t timezero[nmaxtracksinset];
+ Float_t weightedtimezero[nmaxtracksinset];
+ Float_t beta[nmaxtracksinset];
+ Float_t texp[nmaxtracksinset];
+ Float_t dtexp[nmaxtracksinset];
+ Float_t sqMomError[nmaxtracksinset];
+ Float_t sqTrackError[nmaxtracksinset];
+ Float_t massarray[3]={0.13957,0.493677,0.9382723};
+ Float_t tracktoflen[nmaxtracksinset];
+ Float_t besttimezero[nmaxtracksinset];
+ Float_t besttexp[nmaxtracksinset];
+ Float_t besttimeofflight[nmaxtracksinset];
+ Float_t bestmomentum[nmaxtracksinset];
+ Float_t bestchisquare[nmaxtracksinset];
+ Float_t bestweightedtimezero[nmaxtracksinset];
+ Float_t bestsqTrackError[nmaxtracksinset];
+ Int_t imass[nmaxtracksinset];
+
+ for (Int_t j=0; j<ntracksinset; j++) {
+ assparticle[j] = 3;
+ timeofflight[j] = 0;
+ momentum[j] = 0;
+ timezero[j] = 0;
+ weightedtimezero[j] = 0;
+ beta[j] = 0;
+ texp[j] = 0;
+ dtexp[j] = 0;
+ sqMomError[j] = 0;
+ sqTrackError[j] = 0;
+ tracktoflen[j] = 0;
+ besttimezero[j] = 0;
+ besttexp[j] = 0;
+ besttimeofflight[j] = 0;
+ bestmomentum[j] = 0;
+ bestchisquare[j] = 0;
+ bestweightedtimezero[j] = 0;
+ bestsqTrackError[j] = 0;
+ imass[j] = 1;
+ }
+
+ for (Int_t j=0; j<ntracksinsetmy; j++) {
+ AliESDtrack *t=tracksT0[j];
+ Double_t momOld=t->GetP();
+ Double_t mom=momOld-0.0036*momOld;
+ Double_t time=t->GetTOFsignal();
+
+ time*=1.E-3; // tof given in nanoseconds
+ Double_t exptime[10]; t->GetIntegratedTimes(exptime);
+ Double_t toflen=t->GetIntegratedLength();
+ toflen=toflen/100.; // toflen given in m
+
+ timeofflight[j]=time;
+ tracktoflen[j]=toflen;
+ exptof[j][0]=exptime[2]*1.E-3+fTimeCorr;// in ns
+ exptof[j][1]=exptime[3]*1.E-3+fTimeCorr;
+ exptof[j][2]=exptime[4]*1.E-3+fTimeCorr;
+ momentum[j]=mom;
+ assparticle[j]=3;
+
+ } //end for (Int_t j=0; j<ntracksinsetmy; j++) {
+
+ for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
+ beta[itz]=momentum[itz]/sqrt(massarray[0]*massarray[0]
+ +momentum[itz]*momentum[itz]);
+ sqMomError[itz]= ((1.-beta[itz]*beta[itz])*0.01)*((1.-beta[itz]*beta[itz])*0.01)*(tracktoflen[itz]/(0.299792*beta[itz]))*(tracktoflen[itz]/(0.299792*beta[itz]));
+ sqTrackError[itz]=(timeresolutioninns*timeresolutioninns+sqMomError[itz]); //in ns
+ timezero[itz]=exptof[itz][0]-timeofflight[itz];// in ns
+ weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
+ sumAllweightspi+=1./sqTrackError[itz];
+ meantzeropi+=weightedtimezero[itz];
+ } // end loop for (Int_t itz=0; itz< ntracksinset;itz++)
+
+
+ // Then, Combinatorial Algorithm
+
+ if(ntracksinsetmy<2 )break;
+
+ for (Int_t j=0; j<ntracksinsetmy; j++) {
+ imass[j] = 3;
+ }
+
+ Int_t ncombinatorial = Int_t(TMath::Power(3,ntracksinsetmy));
+
+ // Loop on mass hypotheses
+ for (Int_t k=0; k < ncombinatorial;k++) {
+ for (Int_t j=0; j<ntracksinsetmy; j++) {
+ imass[j] = (k % Int_t(TMath::Power(3,ntracksinsetmy-j)))/Int_t(TMath::Power(3,ntracksinsetmy-j-1));
+ texp[j]=exptof[j][imass[j]];
+ dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
+ }
+ Float_t sumAllweights=0.;
+ Float_t meantzero=0.;
+ Float_t eMeanTzero=0.;
+
+ for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
+ sqTrackError[itz]=
+ (timeresolutioninns*
+ timeresolutioninns
+ +dtexp[itz]*dtexp[itz]*1E-6); //in ns2
+
+ timezero[itz]=texp[itz]-timeofflight[itz];// in ns
+
+ weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
+ sumAllweights+=1./sqTrackError[itz];
+ meantzero+=weightedtimezero[itz];
+
+ } // end loop for (Int_t itz=0; itz<15;itz++)
+
+ meantzero=meantzero/sumAllweights; // it is given in [ns]
+ eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
+
+ // calculate chisquare
+
+ Float_t chisquare=0.;
+ for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
+ chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
+
+ } // end loop for (Int_t icsq=0; icsq<15;icsq++)
+
+ if(chisquare<=chisquarebest){
+ for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
+
+ bestsqTrackError[iqsq]=sqTrackError[iqsq];
+ besttimezero[iqsq]=timezero[iqsq];
+ bestmomentum[iqsq]=momentum[iqsq];
+ besttimeofflight[iqsq]=timeofflight[iqsq];
+ besttexp[iqsq]=texp[iqsq];
+ bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
+ bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
+ }
+
+ Int_t npion=0;
+ for (Int_t j=0; j<ntracksinsetmy; j++) {
+ assparticle[j]=imass[j];
+ if(imass[j] == 0) npion++;
+ }
+ npionbest=npion;
+ chisquarebest=chisquare;
+ t0best=meantzero;
+ eT0best=eMeanTzero;
+ } // close if(dummychisquare<=chisquare)
+
+ }
+
+ Double_t chi2cut[nmaxtracksinset];
+ chi2cut[0] = 0;
+ chi2cut[1] = 6.6; // corresponding to a C.L. of 0.01
+ for (Int_t j=2; j<ntracksinset; j++) {
+ chi2cut[j] = chi2cut[1] * TMath::Sqrt(j*1.);
+ }
+
+ Double_t chi2singlecut = chi2cut[ntracksinsetmy-1]/ntracksinsetmy + TMath::Abs(chisquarebest-chi2cut[ntracksinsetmy-1])/ntracksinsetmy;
+
+// printf("tracks removed with a chi2 > %f (chi2total = %f w.r.t. the limit of %f)\n",chi2singlecut,chisquarebest,chi2cut[ntracksinsetmy-1]);
+
+ Bool_t kRedoT0 = kFALSE;
+ ntracksinsetmyCut = ntracksinsetmy;
+ Bool_t usetrack[nmaxtracksinset];
+ for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
+ usetrack[icsq] = kTRUE;
+ if((bestchisquare[icsq] > chisquarebest*0.5 && ntracksinsetmy > 2) || (bestchisquare[icsq] > chi2singlecut)){
+ kRedoT0 = kTRUE;
+ ntracksinsetmyCut--;
+ usetrack[icsq] = kFALSE;
+ }
+ } // end loop for (Int_t icsq=0; icsq<15;icsq++)
+
+ // printf("ntrackinsetmy = %i - %i\n",ntracksinsetmy,ntracksinsetmyCut);
+
+ // Loop on mass hypotheses Redo
+ if(kRedoT0 && ntracksinsetmyCut > 1){
+ // printf("Redo T0\n");
+ for (Int_t k=0; k < ncombinatorial;k++) {
+ for (Int_t j=0; j<ntracksinsetmy; j++) {
+ imass[j] = (k % Int_t(TMath::Power(3,ntracksinsetmy-j))) / Int_t(TMath::Power(3,ntracksinsetmy-j-1));
+ texp[j]=exptof[j][imass[j]];
+ dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
+ }
+
+ Float_t sumAllweights=0.;
+ Float_t meantzero=0.;
+ Float_t eMeanTzero=0.;
+
+ for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
+ if(! usetrack[itz]) continue;
+ sqTrackError[itz]=
+ (timeresolutioninns*
+ timeresolutioninns
+ +dtexp[itz]*dtexp[itz]*1E-6); //in ns2
+
+ timezero[itz]=texp[itz]-timeofflight[itz];// in ns
+
+ weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
+ sumAllweights+=1./sqTrackError[itz];
+ meantzero+=weightedtimezero[itz];
+
+ } // end loop for (Int_t itz=0; itz<15;itz++)
+
+ meantzero=meantzero/sumAllweights; // it is given in [ns]
+ eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
+
+ // calculate chisquare
+
+ Float_t chisquare=0.;
+ for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
+ if(! usetrack[icsq]) continue;
+ chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
+
+ } // end loop for (Int_t icsq=0; icsq<15;icsq++)
+
+ Int_t npion=0;
+ for (Int_t j=0; j<ntracksinsetmy; j++) {
+ assparticle[j]=imass[j];
+ if(imass[j] == 0) npion++;
+ }
+
+ if(chisquare<=chisquarebest){
+ for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
+ if(! usetrack[iqsq]) continue;
+ bestsqTrackError[iqsq]=sqTrackError[iqsq];
+ besttimezero[iqsq]=timezero[iqsq];
+ bestmomentum[iqsq]=momentum[iqsq];
+ besttimeofflight[iqsq]=timeofflight[iqsq];
+ besttexp[iqsq]=texp[iqsq];
+ bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
+ bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
+ }
+
+ npionbest=npion;
+ chisquarebest=chisquare;
+ t0best=meantzero;
+ eT0best=eMeanTzero;
+ } // close if(dummychisquare<=chisquare)
+
+ }
+ }
+
+ // filling histos
+ Float_t confLevel=999;
+
+ // Sets with decent chisquares
+
+ if(chisquarebest<999.){
+ Double_t dblechisquare=(Double_t)chisquarebest;
+ confLevel=(Float_t)TMath::Prob(dblechisquare,ntracksinsetmyCut-1);
+// cout << " Set Number " << nsets << endl;
+// cout << "Best Assignment, selection " << assparticle[0] <<
+// assparticle[1] << assparticle[2] <<
+// assparticle[3] << assparticle[4] <<
+// assparticle[5] << endl;
+// cout << " Chisquare of the set "<< chisquarebest <<endl;
+// cout << " C.L. of the set "<< confLevel <<endl;
+// cout << " T0 for this set (in ns) " << t0best << endl;
+
+ for(Int_t icsq=0; icsq<ntracksinsetmy;icsq++){
+
+ if(! usetrack[icsq]) continue;
+
+// cout << "Track # " << icsq << " T0 offsets = "
+// << besttimezero[icsq]-t0best <<
+// " track error = " << bestsqTrackError[icsq]
+// << " Chisquare = " << bestchisquare[icsq]
+// << " Momentum = " << bestmomentum[icsq]
+// << " TOF = " << besttimeofflight[icsq]
+// << " TOF tracking = " << besttexp[icsq]
+// << " is used = " << usetrack[icsq] << endl;
+ }
+
+ // Pick up only those with C.L. >1%
+ // if(confLevel>0.01 && ngoodsetsSel<200){
+ if(confLevel>0.01 && ngoodsetsSel<200){
+ chiSquarebestSel[ngoodsetsSel]=chisquarebest;
+ confLevelbestSel[ngoodsetsSel]=confLevel;
+ t0bestSel[ngoodsetsSel]=t0best/eT0best/eT0best;
+ eT0bestSel[ngoodsetsSel]=1./eT0best/eT0best;
+ t0bestallSel += t0best/eT0best/eT0best;
+ sumWt0bestallSel += 1./eT0best/eT0best;
+ ngoodsetsSel++;
+ ngoodtrktrulyused+=ntracksinsetmyCut;
+ }
+ else{
+ // printf("conflevel = %f -- ngoodsetsSel = %i -- ntrackset = %i\n",confLevel,ngoodsetsSel,ntracksinsetmy);
+ }
+ }
+ delete[] tracksT0;
+ nsets++;
+
+ } // end for the current set
+
+ nUsedTracks = ngoodtrkt0;
+ if(strstr(option,"all")){
+ if(sumAllweightspi>0.){
+ meantzeropi=meantzeropi/sumAllweightspi; // it is given in [ns]
+ eMeanTzeroPi=sqrt(1./sumAllweightspi); // it is given in [ns]
+ }
+
+ if(sumWt0bestallSel>0){
+ t0bestallSel = t0bestallSel/sumWt0bestallSel;
+ eT0bestallSel = sqrt(1./sumWt0bestallSel);
+
+ }// end of if(sumWt0bestallSel>0){
+
+// cout << "T0 all " << t0bestallSel << " +/- " << eT0bestallSel << "Number of tracks used: "<<ngoodtrktrulyused<<endl;
+ }
+
+ t0def=t0bestallSel;
+ deltat0def=eT0bestallSel;
+ if ((TMath::Abs(t0bestallSel) < 0.001)&&(TMath::Abs(eT0bestallSel)<0.001)){
+ t0def=-999; deltat0def=0.600;
+ }
+
+ fT0SigmaT0def[0]=t0def;
+ fT0SigmaT0def[1]=TMath::Sqrt(deltat0def*deltat0def);//*ngoodtrktrulyused/(ngoodtrktrulyused-1));
+ fT0SigmaT0def[2]=ngoodtrkt0;
+ fT0SigmaT0def[3]=ngoodtrktrulyused;
+ }
+ }
+
+ // if(strstr(option,"tim") || strstr(option,"all")){
+ // cout << "AliTOFT0v2:" << endl ;
+ //}
+
+ return fT0SigmaT0def;
+ }
+//__________________________________________________________________
+Float_t AliTOFT0v2::GetMomError(Int_t index, Float_t mom, Float_t texp) const
+{
+ // Take the error extimate for the TOF time in the track reconstruction
+
+ static const Double_t kMasses[]={
+ 0.000511, 0.105658, 0.139570, 0.493677, 0.938272, 1.875613
+ };
+
+ Double_t mass=kMasses[index+2];
+ Double_t dpp=0.01; //mean relative pt resolution;
+ if(mom > 1) dpp = 0.01*mom;
+ Double_t sigma=dpp*texp*1E3/(1.+ mom*mom/(mass*mass));
+
+ sigma =TMath::Sqrt(sigma*sigma);
+
+ return sigma;
+}
+
+//__________________________________________________________________
+Bool_t AliTOFT0v2::AcceptTrack(AliESDtrack *track)
+{
+
+ /* TPC refit */
+ if (!(track->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE;
+ /* do not accept kink daughters */
+ if (track->GetKinkIndex(0)>0) return kFALSE;
+ /* N clusters TPC */
+ if (track->GetTPCclusters(0) < 50) return kFALSE;
+ /* chi2 TPC */
+ if (track->GetTPCchi2()/Float_t(track->GetTPCclusters(0)) > 3.5) return kFALSE;
+ /* sigma to vertex */
+ if (GetSigmaToVertex(track) > 4.) return kFALSE;
+
+ /* accept track */
+ return kTRUE;
+
+}
+
+//____________________________________________________________________
+Float_t AliTOFT0v2::GetSigmaToVertex(AliESDtrack* esdTrack) const
+{
+ // Calculates the number of sigma to the vertex.
+
+ Float_t b[2];
+ Float_t bRes[2];
+ Float_t bCov[3];
+ esdTrack->GetImpactParameters(b,bCov);
+
+ if (bCov[0]<=0 || bCov[2]<=0) {
+ bCov[0]=0; bCov[2]=0;
+ }
+ bRes[0] = TMath::Sqrt(bCov[0]);
+ bRes[1] = TMath::Sqrt(bCov[2]);
+
+ // -----------------------------------
+ // How to get to a n-sigma cut?
+ //
+ // The accumulated statistics from 0 to d is
+ //
+ // -> Erf(d/Sqrt(2)) for a 1-dim gauss (d = n_sigma)
+ // -> 1 - Exp(-d**2) for a 2-dim gauss (d*d = dx*dx + dy*dy != n_sigma)
+ //
+ // It means that for a 2-dim gauss: n_sigma(d) = Sqrt(2)*ErfInv(1 - Exp((-d**2)/2)
+ // Can this be expressed in a different way?
+
+ if (bRes[0] == 0 || bRes[1] ==0)
+ return -1;
+
+ Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
+
+ // work around precision problem
+ // if d is too big, TMath::Exp(...) gets 0, and TMath::ErfInverse(1) that should be infinite, gets 0 :(
+ // 1e-15 corresponds to nsigma ~ 7.7
+ if (TMath::Exp(-d * d / 2) < 1e-15)
+ return 1000;
+
+ Float_t nSigma = TMath::ErfInverse(1 - TMath::Exp(-d * d / 2)) * TMath::Sqrt(2);
+ return nSigma;
+}
--- /dev/null
+#ifndef ALITOFT0V2_H
+#define ALITOFT0V2_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//----------------------------------------------------------------------------//
+// //
+// Description: class to performe an event time measurment with TOF. //
+// //
+//----------------------------------------------------------------------------//
+
+#include "TObject.h"
+
+class AliESDtrack;
+/* class AliTOFcalibHisto; */
+class AliESDEvent;
+
+class AliTOFT0v2: public TObject {
+public:
+
+ AliTOFT0v2() ;
+ AliTOFT0v2(const AliTOFT0v2 & tzero);
+ AliTOFT0v2 & operator=(const AliTOFT0v2 & tzero) ;
+ AliTOFT0v2(AliESDEvent *event);
+ virtual ~AliTOFT0v2() ; // dtor
+
+ // void SetCalib(AliTOFcalibHisto * const calib){fCalib = calib;};
+
+ Double_t* DefineT0(Option_t *option);
+
+ void SetTimeResolution(Double_t timeresolution);// timeresolution in [s] e.g. for 120 ps -> 1.2e-10
+
+ Double_t GetTimeResolution() const {return fTimeResolution;}
+
+ void SetMomBounds(Float_t pLow, Float_t pUp) { fLowerMomBound=pLow; fUpperMomBound=pUp;} // momenta are expressed in [GeV/c]
+ void SetTimeCorr(Float_t timecorr) {fTimeCorr=timecorr;} //in ns!!!
+ Float_t GetMomError(Int_t index, Float_t mom, Float_t texp) const;
+/* void Print(Option_t* option) const ; */
+
+ private:
+
+ Bool_t AcceptTrack(AliESDtrack *track); /* accept track */
+ Float_t GetSigmaToVertex(AliESDtrack *track) const; /* get sigma to vertex */
+
+
+ Float_t fLowerMomBound; // momentum lower bound for selected primary tracks
+ Float_t fUpperMomBound; // momentum upper bound for selected primary tracks
+ Double_t fTimeResolution; // global time resolution used to calculate T0
+ Float_t fTimeCorr; // global time resolution used to calculate T0
+ AliESDEvent* fEvent; //evento per il quale si vuole calcolare il T0
+/* AliTOFcalibHisto *fCalib; // pointer to the class with the TOF time corrections */
+
+ Double_t fT0SigmaT0def[4]; // array with the event information ([0]=event time -- [1] = sigma -- [2] = tracks on the TOF -- [3] = tracks used for the event time)
+
+ ClassDef(AliTOFT0v2,2); // Calculate the time zero using TOF detector */
+
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * 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. *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// TOF tender: reapply TOF pid on the fly //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include <AliLog.h>
+#include <AliESDEvent.h>
+#include <AliESDInputHandler.h>
+#include <AliAnalysisManager.h>
+#include <AliESDpid.h>
+#include <AliTender.h>
+
+#include "AliTOFcalibESD.h"
+#include "AliTOFT0makerANA.h"
+
+#include "AliTOFTenderSupply.h"
+
+
+AliTOFTenderSupply::AliTOFTenderSupply() :
+ AliTenderSupply(),
+ fESDpid(0x0),
+ fTOFesdCalib(0x0),
+ fTOFT0maker(0x0),
+ fTOFres(130.)
+{
+ //
+ // default ctor
+ //
+}
+
+//_____________________________________________________
+AliTOFTenderSupply::AliTOFTenderSupply(const char *name, const AliTender *tender) :
+ AliTenderSupply(name,tender),
+ fESDpid(0x0),
+ fTOFesdCalib(0x0),
+ fTOFT0maker(0x0),
+ fTOFres(130.)
+{
+ //
+ // named ctor
+ //
+}
+
+//_____________________________________________________
+void AliTOFTenderSupply::Init()
+{
+ //
+ // Initialise TOF tender
+ //
+
+
+ //
+ // Setup PID object
+ //
+
+ // Check if another detector already created the esd pid object
+ // if not we create it and set it to the ESD input handler
+ fESDpid=fTender->GetESDhandler()->GetESDpid();
+ if (!fESDpid) {
+ fESDpid=new AliESDpid;
+ fTender->GetESDhandler()->SetESDpid(fESDpid);
+ }
+
+ //Set proper resolution in case of MC
+ AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
+ if (mgr->GetMCtruthEventHandler()) fESDpid->GetTOFResponse().SetTimeResolution(80.);
+
+
+ //
+ // Create TOF calibration classes
+ //
+ if (!fTOFesdCalib) fTOFesdCalib=new AliTOFcalibESD;
+ if (!fTOFT0maker) {
+ fTOFT0maker = new AliTOFT0makerANA(fESDpid);
+ fTOFT0maker->SetTimeResolution(fTOFres); // set TOF resolution for the PID
+ }
+}
+
+//_____________________________________________________
+void AliTOFTenderSupply::ProcessEvent()
+{
+ //
+ // Reapply pid information
+ //
+
+ //no corrections for MC
+ AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
+ if (mgr->GetMCtruthEventHandler()) return;
+
+ AliESDEvent *event=fTender->GetEvent();
+ if (!event) return;
+
+ //recalculate TOF signal
+ if (fTender->RunChanged()){
+ fTOFesdCalib->Init(fTender->GetRun());
+ }
+ fTOFesdCalib->CalibrateESD(event);
+
+ //Calculate event time zero
+ Double_t* calcolot0;
+ calcolot0=fTOFT0maker->RemakePID(event); // calculate T0-TOF(T0-FILL) and
+ Double_t t0best=calcolot0[0]; // T0-Event = (T0-TOF .OR. T0-FILL) <- This is what you asked me
+ event->SetT0(t0best);
+
+ //
+ // recalculate PID probabilities
+ //
+
+ Int_t ntracks=event->GetNumberOfTracks();
+ for(Int_t itrack = 0; itrack < ntracks; itrack++){
+ fESDpid->MakeTOFPID(event->GetTrack(itrack),0);
+ }
+
+}
--- /dev/null
+#ifndef ALITOFTENDERSUPPLY_H
+#define ALITOFTENDERSUPPLY_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////
+// //
+// TPC tender, reapply pid on the fly //
+// //
+////////////////////////////////////////////////////////////////////////
+
+
+
+#include <AliTenderSupply.h>
+
+class AliESDpid;
+class AliTOFcalibESD;
+class AliTOFT0makerANA;
+
+class AliTOFTenderSupply: public AliTenderSupply {
+
+public:
+ AliTOFTenderSupply();
+ AliTOFTenderSupply(const char *name, const AliTender *tender=NULL);
+
+ virtual ~AliTOFTenderSupply(){;}
+
+ virtual void Init();
+ virtual void ProcessEvent();
+
+ // TOF method
+ void SetTOFres(Float_t res){fTOFres=res;}
+
+private:
+ AliESDpid *fESDpid; //! ESD pid object
+
+ // variables for TOF calibrations
+ AliTOFcalibESD *fTOFesdCalib; //! recalibrate TOF signal with OCDB
+ AliTOFT0makerANA *fTOFT0maker; //! TOF maker objects (apply all the correction for T0)
+
+ Float_t fTOFres; // TOF resolution
+
+ AliTOFTenderSupply(const AliTOFTenderSupply&c);
+ AliTOFTenderSupply& operator= (const AliTOFTenderSupply&c);
+
+ ClassDef(AliTOFTenderSupply, 1); // TPC tender task
+};
+
+
+#endif
+
--- /dev/null
+/**************************************************************************
+ * 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. *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////
+// //
+// recalculate the TOF signal from the TOF raw signal //
+// using the updates in the OCDB //
+// //
+////////////////////////////////////////////////////////////////////
+
+#include "AliTOFChannelOnlineStatusArray.h"
+#include "TObjArray.h"
+#include "AliTOFDeltaBCOffset.h"
+#include "AliTOFCTPLatency.h"
+#include "AliTOFRunParams.h"
+#include "AliESDEvent.h"
+#include "AliESDtrack.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliTOFChannelOffline.h"
+#include "AliTOFGeometry.h"
+
+#include "AliTOFcalibESD.h"
+
+ClassImp(AliTOFcalibESD)
+
+//______________________________________________________________-
+
+AliTOFcalibESD::AliTOFcalibESD() :
+ TObject(),
+ fInitFlag(kFALSE),
+ fChannelStatusArray(NULL),
+ fParOfflineArray(NULL),
+ fDeltaBCOffsetObj(NULL),
+ fCTPLatencyObj(NULL),
+ fRunParamsObj(NULL),
+ fTimeZero(0),
+ fTOFResolution(130)
+{
+ /*
+ * default constructor
+ */
+}
+
+//______________________________________________________________-
+
+AliTOFcalibESD::~AliTOFcalibESD()
+{
+ /*
+ * default destructor
+ */
+}
+
+//______________________________________________________________-
+
+Bool_t
+AliTOFcalibESD::Init(Int_t run)
+{
+ /*
+ * init
+ */
+
+ /* get cdb instance */
+ AliCDBManager *cdb = AliCDBManager::Instance();
+ AliCDBEntry *entry = NULL;
+
+ /* get channel status array */
+ entry = cdb->Get("TOF/Calib/Status", run);
+ if (!entry || !entry->GetObject()) return kFALSE;
+ fChannelStatusArray = (AliTOFChannelOnlineStatusArray *)entry->GetObject();
+ /* get par offline array */
+ entry = cdb->Get("TOF/Calib/ParOffline", run);
+ if (!entry || !entry->GetObject()) return kFALSE;
+ fParOfflineArray = (TObjArray *)entry->GetObject();
+ /* get deltaBC offset obj */
+ entry = cdb->Get("TOF/Calib/DeltaBCOffset", run);
+ if (!entry || !entry->GetObject()) return kFALSE;
+ fDeltaBCOffsetObj = (AliTOFDeltaBCOffset *)entry->GetObject();
+ /* get CTP latency obj */
+ entry = cdb->Get("TOF/Calib/CTPLatency", run);
+ if (!entry || !entry->GetObject()) return kFALSE;
+ fCTPLatencyObj = (AliTOFCTPLatency *)entry->GetObject();
+ /* get run params obj */
+ entry = cdb->Get("TOF/Calib/RunParams", run);
+ if (!entry || !entry->GetObject()) return kFALSE;
+ fRunParamsObj = (AliTOFRunParams *)entry->GetObject();
+
+ /* all done */
+ fInitFlag = kTRUE;
+ return kTRUE;
+}
+
+//______________________________________________________________-
+
+void
+AliTOFcalibESD::CalibrateESD(AliESDEvent *event)
+{
+ /*
+ * calibrate ESD
+ */
+
+ /* get global calibration params */
+ AliTOFChannelOffline *parOffline = NULL;
+// Int_t deltaBCOffset = fDeltaBCOffsetObj->GetDeltaBCOffset(); //see below
+ Float_t ctpLatency = fCTPLatencyObj->GetCTPLatency();
+ Float_t tdcLatencyWindow;
+ Float_t timezero = fRunParamsObj->EvalT0(event->GetTimeStamp());
+ fTimeZero=timezero;
+ fTOFResolution=fRunParamsObj->EvalTOFResolution(event->GetTimeStamp());
+
+ /* loop over tracks */
+ AliESDtrack *track = NULL;
+ Int_t index, l0l1, deltaBC;
+ Double_t time, tot;
+ for (Int_t itrk = 0; itrk < event->GetNumberOfTracks(); itrk++) {
+
+ /* get track */
+ track = event->GetTrack(itrk);
+ if (!track || !(track->GetStatus() & AliESDtrack::kTOFout)) continue;
+
+ /* get info */
+ index = track->GetTOFCalChannel();
+ time = track->GetTOFsignalRaw();
+ tot = track->GetTOFsignalToT();
+ l0l1 = track->GetTOFL0L1();
+ deltaBC = track->GetTOFDeltaBC();
+
+ /* get channel dependent calibration params */
+ parOffline = (AliTOFChannelOffline *)fParOfflineArray->At(index);
+ tdcLatencyWindow = fChannelStatusArray->GetLatencyWindow(index) * 1.e3;
+
+ /* deltaBC correction (inhibited for the time being) */
+ // time -= (deltaBC - deltaBCOffset) * AliTOFGeometry::BunchCrossingBinWidth();
+ /* L0-L1 latency correction */
+ time += l0l1 * AliTOFGeometry::BunchCrossingBinWidth();
+ /* CTP latency correction */
+ time += ctpLatency;
+ /* TDC latency window correction */
+ time -= tdcLatencyWindow;
+ /* time-zero correction */
+ time -= timezero;
+ /* time calibration correction */
+ if (tot < AliTOFGeometry::SlewTOTMin())
+ tot = AliTOFGeometry::SlewTOTMin();
+ if (tot > AliTOFGeometry::SlewTOTMax())
+ tot = AliTOFGeometry::SlewTOTMax();
+ for (Int_t islew = 0; islew < 6; islew++)
+ time -= parOffline->GetSlewPar(islew) * TMath::Power(tot, islew) * 1.e3;
+
+ /* set new TOF signal */
+ track->SetTOFsignal(time);
+
+ }
+
+}
--- /dev/null
+#ifndef ALITOFCALIBESD_H
+#define ALITOFCALIBESD_H
+
+
+////////////////////////////////////////////////////////////////////
+// //
+// recalculate the TOF signal from the TOF raw signal //
+// using the updates in the OCDB //
+// //
+////////////////////////////////////////////////////////////////////
+
+#include "TObject.h"
+
+class AliTOFChannelOnlineStatusArray;
+class TObjArray;
+class AliTOFDeltaBCOffset;
+class AliTOFCTPLatency;
+class AliTOFRunParams;
+class AliESDEvent;
+
+class AliTOFcalibESD :
+public TObject
+{
+
+ public:
+
+ AliTOFcalibESD(); // default constructor
+ virtual ~AliTOFcalibESD(); // default destructor
+
+ Bool_t Init(Int_t run = -1); // init
+ void CalibrateESD(AliESDEvent *event); // calibrate ESD
+
+ Float_t GetTimeZero() const {return fTimeZero;}
+ Float_t GetTOFResolution() const {return fTOFResolution;}
+ private:
+
+ AliTOFcalibESD(const AliTOFcalibESD &); // copy constructor
+ AliTOFcalibESD &operator=(const AliTOFcalibESD &); // operator=
+
+ Bool_t fInitFlag; //! init flag
+ AliTOFChannelOnlineStatusArray *fChannelStatusArray; //! channel status array
+ TObjArray *fParOfflineArray; //! par offline array
+ AliTOFDeltaBCOffset *fDeltaBCOffsetObj; //! deltaBC offset object
+ AliTOFCTPLatency *fCTPLatencyObj; //! CTP latency object
+ AliTOFRunParams *fRunParamsObj; //! run params object
+ Float_t fTimeZero; //! TOF Time0
+ Float_t fTOFResolution; //! TOF Time0
+
+ ClassDef(AliTOFcalibESD, 1);
+};
+
+#endif /* ALITOFCALIBESD_H */
--- /dev/null
+/**************************************************************************
+ * 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. *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// TPC tender: reapply pid on the fly //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+#include <TList.h>
+#include <TObjString.h>
+#include <TChain.h>
+
+#include <AliDCSSensor.h>
+#include <AliGRPObject.h>
+#include <AliESDpid.h>
+#include <AliLog.h>
+#include <AliESDEvent.h>
+#include <AliESDtrack.h>
+#include <AliESDInputHandler.h>
+#include <AliAnalysisManager.h>
+#include <AliSplineFit.h>
+#include <AliCDBId.h>
+#include <AliCDBManager.h>
+#include <AliCDBEntry.h>
+#include <AliTender.h>
+
+#include "AliTPCTenderSupply.h"
+
+
+AliTPCTenderSupply::AliTPCTenderSupply() :
+ AliTenderSupply(),
+ fESDpid(0x0),
+ fGainNew(0x0),
+ fGainOld(0x0),
+ fGainCorrection(kTRUE),
+ fGRP(0x0)
+{
+ //
+ // default ctor
+ //
+}
+
+//_____________________________________________________
+AliTPCTenderSupply::AliTPCTenderSupply(const char *name, const AliTender *tender) :
+ AliTenderSupply(name,tender),
+ fESDpid(0x0),
+ fGainNew(0x0),
+ fGainOld(0x0),
+ fGainCorrection(kTRUE),
+ fGRP(0x0)
+{
+ //
+ // named ctor
+ //
+}
+
+//_____________________________________________________
+void AliTPCTenderSupply::Init()
+{
+ //
+ // Initialise TPC tender
+ //
+
+ AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
+ //
+ // Setup PID object
+ //
+
+ // Check if another detector already created the esd pid object
+ // if not we create it and set it to the ESD input handler
+ fESDpid=fTender->GetESDhandler()->GetESDpid();
+ if (!fESDpid) {
+ fESDpid=new AliESDpid;
+ fTender->GetESDhandler()->SetESDpid(fESDpid);
+ }
+
+ //
+ //set bethe bloch parameters depending on whether we have MC or real data
+ //
+ // for the moment we set the values hardwired. In future they should be stored either in
+ // the OCDB or an equivalent calibration data base
+ //
+ Double_t alephParameters[5];
+ // simulation
+ alephParameters[0] = 2.15898e+00/50.;
+ alephParameters[1] = 1.75295e+01;
+ alephParameters[2] = 3.40030e-09;
+ alephParameters[3] = 1.96178e+00;
+ alephParameters[4] = 3.91720e+00;
+
+ // assume data if there is no mc handler
+ if (!mgr->GetMCtruthEventHandler()){
+ alephParameters[0] = 0.0283086/0.97;
+ //alephParameters[0] = 0.0283086;
+ alephParameters[1] = 2.63394e+01;
+ alephParameters[2] = 5.04114e-11;
+ alephParameters[3] = 2.12543e+00;
+ alephParameters[4] = 4.88663e+00;
+ //temporary solution
+ fESDpid->GetTPCResponse().SetMip(47.9);
+ //fESDpid->GetTPCResponse().SetMip(49.2);
+ } else {
+ //force no gain correction in MC
+ fGainCorrection=kFALSE;
+ }
+
+ fESDpid->GetTPCResponse().SetBetheBlochParameters(
+ alephParameters[0],alephParameters[1],alephParameters[2],
+ alephParameters[3],alephParameters[4]);
+
+ //set detector resolution parametrisation
+ fESDpid->GetTPCResponse().SetSigma(3.79301e-03, 2.21280e+04);
+}
+
+//_____________________________________________________
+void AliTPCTenderSupply::ProcessEvent()
+{
+ //
+ // Reapply pid information
+ //
+
+ AliESDEvent *event=fTender->GetEvent();
+ if (!event) return;
+
+ //load gain correction if run has changed
+ if (fTender->RunChanged()){
+ if (fGainCorrection) SetSplines();
+ }
+
+ //
+ // get gain correction factor
+ //
+ Double_t corrFactor = GetGainCorrection();
+
+ //
+ // - correct TPC signals
+ // - recalculate PID probabilities for TPC
+ //
+ Int_t ntracks=event->GetNumberOfTracks();
+ for(Int_t itrack = 0; itrack < ntracks; itrack++){
+ AliESDtrack *track=event->GetTrack(itrack);
+ if (fGainCorrection)
+ track->SetTPCsignal(track->GetTPCsignal()*corrFactor,track->GetTPCsignalSigma(),track->GetTPCsignalN());
+ fESDpid->MakeTPCPID(track);
+ }
+
+}
+
+//_____________________________________________________
+void AliTPCTenderSupply::SetSplines()
+{
+ //
+ // Get Gain splines from OCDB
+ //
+
+ AliInfo("Update Gain splines");
+
+ //
+ // Get GPR info for pressure correction
+ //
+ AliCDBEntry *entryGRP=fTender->GetCDBManager()->Get("GRP/GRP/Data",fTender->GetRun());
+ if (!entryGRP) {
+ AliError("No new GRP entry found");
+ } else {
+ fGRP = (AliGRPObject*)entryGRP->GetObject();
+ }
+
+ fGainNew=0x0;
+ fGainOld=0x0;
+ //
+ //find previous entry from the UserInfo
+ //
+ TTree *tree=((TChain*)fTender->GetInputData(0))->GetTree();
+ if (!tree) {
+ AliError("Tree not found in ESDhandler");
+ return;
+ }
+
+ TList *userInfo=(TList*)tree->GetUserInfo();
+ if (!userInfo) {
+ AliError("No UserInfo found in tree");
+ return;
+ }
+
+ TList *cdbList=(TList*)userInfo->FindObject("cdbList");
+ if (!cdbList) {
+ AliError("No cdbList found in UserInfo");
+ if (AliLog::GetGlobalLogLevel()>=AliLog::kError) userInfo->Print();
+ return;
+ }
+
+ TIter nextCDB(cdbList);
+ TObjString *os=0x0;
+ while ( (os=(TObjString*)nextCDB()) ){
+ if (!(os->GetString().Contains("TPC/Calib/TimeGain"))) continue;
+ AliCDBId *id=AliCDBId::MakeFromString(os->GetString());
+
+ AliCDBEntry *entry=fTender->GetCDBManager()->Get(*id);
+ if (!entry) {
+ AliError("No previous gain calibration entry found");
+ return;
+ }
+
+ TObjArray *arr=(TObjArray *)entry->GetObject();
+ if (!arr) {
+ AliError("Gain Splines array not found in calibration entry");
+ return;
+ }
+
+ AliSplineFit *fit=(AliSplineFit*)arr->At(0);
+ if (!fit) {
+ AliError("Spline fit not found in array");
+ return;
+ }
+
+ fGainOld = fit;
+ delete id;
+ break;
+ }
+
+ //
+ //new gain correction
+ //
+ AliCDBEntry *entryNew=fTender->GetCDBManager()->Get("TPC/Calib/TimeGain",fTender->GetRun());
+ if (!entryNew) {
+ AliError("No new gain calibration entry found");
+ return;
+ }
+
+ TObjArray *arrSplines=(TObjArray *)entryNew->GetObject();
+ if (!arrSplines) {
+ AliError("Gain Splines array not found in new calibration entry");
+ return;
+ }
+
+ fGainNew = (AliSplineFit*)arrSplines->At(0);
+
+ if (!fGainNew) AliError("No recent spline fit object found");
+}
+
+//_____________________________________________________
+Double_t AliTPCTenderSupply::GetGainCorrection()
+{
+ //
+ // Calculate gain correction factor
+ //
+ AliESDEvent *event=fTender->GetEvent();
+ UInt_t time=event->GetTimeStamp();
+
+ Double_t gain = 1;
+ if (fGainNew && fGainOld) gain = fGainOld->Eval(time)/fGainNew->Eval(time);
+
+ //If there is no new calibration, at least apply correction for pressure
+ if (TMath::Abs(gain-1)<1e-20){
+ if (fGRP) {
+ Double_t pressure=fGRP->GetCavernAtmosPressure()->GetValue(time);
+ gain=fGainOld->Eval(time)/(7.03814-0.00459798*pressure)/49.53*48.2;
+ }
+ }
+
+ return gain;
+}
+
--- /dev/null
+#ifndef ALITPCTENDERSUPPLY_H
+#define ALITPCTENDERSUPPLY_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////
+// //
+// TPC tender, reapply pid on the fly //
+// //
+////////////////////////////////////////////////////////////////////////
+
+
+
+#include <AliTenderSupply.h>
+
+class AliESDpid;
+class AliSplineFit;
+class AliGRPObject;
+
+class AliTPCTenderSupply: public AliTenderSupply {
+
+public:
+ AliTPCTenderSupply();
+ AliTPCTenderSupply(const char *name, const AliTender *tender=NULL);
+
+ virtual ~AliTPCTenderSupply(){;}
+
+ void SetGainCorrection(Bool_t gainCorr) {fGainCorrection=gainCorr;}
+
+ virtual void Init();
+ virtual void ProcessEvent();
+
+private:
+ AliESDpid *fESDpid; //! ESD pid object
+ AliSplineFit *fGainNew; //! New gain correction
+ AliSplineFit *fGainOld; //! Old gain correction
+
+ Bool_t fGainCorrection; //Perform gain correction
+ AliGRPObject *fGRP; //!GRP for pressure temperature correction
+
+ void SetSplines();
+ Double_t GetGainCorrection();
+
+ AliTPCTenderSupply(const AliTPCTenderSupply&c);
+ AliTPCTenderSupply& operator= (const AliTPCTenderSupply&c);
+
+ ClassDef(AliTPCTenderSupply, 1); // TPC tender task
+};
+
+
+#endif
+
--- /dev/null
+/**************************************************************************
+ * 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. *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// TRD tender: reapply pid on the fly //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include <AliLog.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <AliPID.h>
+#include <AliVEvent.h>
+#include <AliESDEvent.h>
+#include <AliESDpid.h>
+#include <AliESDtrack.h>
+#include <AliESDInputHandler.h>
+#include <AliAnalysisManager.h>
+#include <AliTRDPIDResponse.h>
+#include <AliTender.h>
+
+#include "AliTRDTenderSupply.h"
+
+
+AliTRDTenderSupply::AliTRDTenderSupply() :
+ AliTenderSupply(),
+ fESDpid(0x0),
+ fPIDmethod(k1DLQpid)
+{
+ //
+ // default ctor
+ //
+}
+
+//_____________________________________________________
+AliTRDTenderSupply::AliTRDTenderSupply(const char *name, const AliTender *tender) :
+ AliTenderSupply(name,tender),
+ fESDpid(0x0),
+ fPIDmethod(k1DLQpid)
+{
+ //
+ // named ctor
+ //
+}
+
+AliTRDTenderSupply::~AliTRDTenderSupply()
+{
+ //
+ // dtor
+ //
+}
+
+//_____________________________________________________
+void AliTRDTenderSupply::Init()
+{
+ //
+ // Initialise TRD tender
+ //
+
+ //
+ // Set event information
+ //
+ AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
+
+ // 1DLQ PID implemented in the AliESD object
+ fESDpid=fTender->GetESDhandler()->GetESDpid();
+ if (!fESDpid) {
+ fESDpid=new AliESDpid;
+ fTender->GetESDhandler()->SetESDpid(fESDpid);
+ }
+ // Set Normalisation Factors
+ if(mgr->GetMCtruthEventHandler()){
+ // Assume MC
+ fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.8315);
+ }
+ else{
+ // Assume Data
+ fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.14);
+ }
+
+}
+
+//_____________________________________________________
+void AliTRDTenderSupply::ProcessEvent()
+{
+ //
+ // Reapply pid information
+ //
+
+
+ AliESDEvent *event=fTender->GetEvent();
+ if (!event) return;
+ Int_t ntracks=event->GetNumberOfTracks();
+
+ //
+ // recalculate PID probabilities
+ //
+ switch(fPIDmethod){
+ case k1DLQpid:
+ for(Int_t itrack = 0; itrack < ntracks; itrack++)
+ fESDpid->MakeTRDPID(event->GetTrack(itrack));
+ break;
+ default:
+ AliError("PID Method not implemented (yet)");
+ }
+}
--- /dev/null
+#ifndef ALITRDTENDERSUPPLY_H
+#define ALITRDTENDERSUPPLY_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////
+// //
+// TRD tender, reapply pid on the fly //
+// //
+////////////////////////////////////////////////////////////////////////
+
+
+
+#include <AliTenderSupply.h>
+
+class AliTRDTenderSupply: public AliTenderSupply {
+
+public:
+ AliTRDTenderSupply();
+ AliTRDTenderSupply(const char *name, const AliTender *tender=NULL);
+ virtual ~AliTRDTenderSupply();
+
+ void SetPIDmethod(Int_t pidMethod) { fPIDmethod = pidMethod; }
+
+ virtual void Init();
+ virtual void ProcessEvent();
+
+
+private:
+ enum{
+ kNNpid = 0,
+ k1DLQpid = 1,
+ k2DLQpid = 2
+ };
+ AliESDpid *fESDpid; //! ESD PID object
+
+ Int_t fPIDmethod; // PID method
+
+ AliTRDTenderSupply(const AliTRDTenderSupply&c);
+ AliTRDTenderSupply& operator= (const AliTRDTenderSupply&c);
+
+ ClassDef(AliTRDTenderSupply, 1); // TRD tender task
+};
+
+
+#endif
+
--- /dev/null
+/**************************************************************************
+ * 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. *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Redo primary vertex on the fly, using the diamond constraint //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include <AliESDEvent.h>
+#include <AliESDInputHandler.h>
+#include <AliVertexerTracks.h>
+#include <AliTender.h>
+#include <AliCDBId.h>
+#include <AliCDBManager.h>
+#include <AliCDBEntry.h>
+
+#include "AliVtxTenderSupply.h"
+
+AliVtxTenderSupply::AliVtxTenderSupply() :
+ AliTenderSupply(),
+ fDiamond(0x0)
+{
+ //
+ // default ctor
+ //
+}
+
+//_____________________________________________________
+AliVtxTenderSupply::AliVtxTenderSupply(const char *name, const AliTender *tender) :
+ AliTenderSupply(name,tender),
+ fDiamond(0x0)
+{
+ //
+ // named ctor
+ //
+}
+
+//_____________________________________________________
+void AliVtxTenderSupply::ProcessEvent()
+{
+ //
+ // Recalculate the Vertex with constraint
+ //
+
+ AliESDEvent *event=fTender->GetEvent();
+ if (!event) return;
+
+ //
+
+ if (fTender->RunChanged()){
+ fDiamond=0x0;
+ AliCDBEntry *meanVertex=fTender->GetCDBManager()->Get("GRP/Calib/MeanVertex",fTender->GetRun());
+ if (!meanVertex) {
+ AliError("No new MeanVertex entry found");
+ return;
+ } else {
+ fDiamond=(AliESDVertex*)meanVertex->GetObject();
+ }
+ //printf("\nRun %d, sigmaX %f, sigmaY %f\n",fTender->GetRun(),fDiamond->GetXRes(),fDiamond->GetYRes());
+ }
+
+ if (!fDiamond) return;
+
+ // Redo the primary with the constraint ONLY if the updated mean vertex was found in the OCDB
+ if ( (fDiamond->GetXRes())<2){
+ AliVertexerTracks vertexer(event->GetMagneticField());
+ vertexer.SetITSMode();
+ vertexer.SetMinClusters(4);
+ vertexer.SetVtxStart(fDiamond);
+ AliESDVertex *pvertex = vertexer.FindPrimaryVertex(event);
+ event->SetPrimaryVertexTracks(pvertex);
+ }
+}
--- /dev/null
+#ifndef ALIVTXTENDERSUPPLY_H
+#define ALIVTXTENDERSUPPLY_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////
+// //
+// Vertex tender, redo primary vertex on the fly //
+// //
+////////////////////////////////////////////////////////////////////////
+
+#include <AliTenderSupply.h>
+
+class AliESDVertex;
+
+class AliVtxTenderSupply: public AliTenderSupply {
+
+public:
+ AliVtxTenderSupply();
+ AliVtxTenderSupply(const char *name, const AliTender *tender=NULL);
+
+ virtual ~AliVtxTenderSupply(){;}
+
+ virtual void Init(){;}
+ virtual void ProcessEvent();
+
+private:
+
+ AliVtxTenderSupply(const AliVtxTenderSupply&c);
+ AliVtxTenderSupply& operator= (const AliVtxTenderSupply&c);
+
+ AliESDVertex *fDiamond; //!Information about mean vertex
+
+ ClassDef(AliVtxTenderSupply, 1); // Primary vertex tender task
+};
+
+
+#endif
+
--- /dev/null
+
+include $(ROOTSYS)/test/Makefile.arch
+
+PACKAGE = TenderSupplies
+
+default-target: lib$(PACKAGE).so
+
+ALICEINC = -I.
+
+# add include paths from other par files
+ifneq ($(ESD_INCLUDE),)
+ ALICEINC += -I../$(ESD_INCLUDE)
+endif
+
+ifneq ($(AOD_INCLUDE),)
+ ALICEINC += -I../$(AOD_INCLUDE)
+endif
+
+ifneq ($(STEERBase_INCLUDE),)
+ ALICEINC += -I../$(STEERBase_INCLUDE)
+endif
+
+ifneq ($(ANALYSIS_INCLUDE),)
+ ALICEINC += -I../$(ANALYSIS_INCLUDE)
+endif
+
+ifneq ($(ANALYSISalice_INCLUDE),)
+ ALICEINC += -I../$(ANALYSISalice_INCLUDE)
+endif
+
+
+# only if no par file was loaded before
+ifeq ($(ALICEINC),-I.)
+ ifneq ($(ALICE_ROOT),)
+ ALICEINC += -I./dielectron -I$(ALICE_ROOT)/include -I$(ALICE_ROOT)/STEER -I$(ALICE_ROOT)/ANALYSIS -I$(ALICE_ROOT)/ANALYSIS/Tender -I$(ALICE_ROOT)/TPC -I$(ALICE_ROOT)/TOF
+ endif
+endif
+
+#include HFE in case of the train use the train checkout
+ifneq ($(TRAIN_ROOT),)
+# ALICEINC += -I$(TRAIN_ROOT)/util/hfe/hfe
+ CXXFLAGS += $(ALICEINC) -g
+else
+# ALICEINC += -I$(ALICE_ROOT)/PWG3/hfe
+ CXXFLAGS += -W -Wall -Weffc++ -Woverloaded-virtual -fPIC -pipe -fmessage-length=0 -Wno-long-long -pedantic-errors -ansi -Dlinux $(ALICEINC) -g
+endif
+
+
+include lib$(PACKAGE).pkg
+
+DHDR_TenderSupplies := $(DHDR)
+HDRS_TenderSupplies := $(HDRS)
+SRCS_TenderSupplies := $(SRCS) G__$(PACKAGE).cxx
+OBJS_TenderSupplies := $(SRCS_TenderSupplies:.cxx=.o)
+
+PARFILE = $(PACKAGE).par
+
+
+lib$(PACKAGE).so: $(OBJS_TenderSupplies)
+ @echo "Linking" $@ ...
+ @/bin/rm -f $@
+ifeq ($(ARCH),macosx)
+ @$(LD) -bundle -undefined $(UNDEFOPT) $(LDFLAGS) $^ -o $@
+else
+ @$(LD) $(SOFLAGS) $(LDFLAGS) $^ -o $@
+endif
+ @chmod a+x $@
+ @echo "done"
+
+%.o: %.cxx %.h
+ $(CXX) $(CXXFLAGS) $(PACKCXXFLAGS) -c $< -o $@
+
+clean:
+ @rm -f $(OBJS_TenderSupplies) *.so G__$(PACKAGE).* $(PARFILE)
+
+G__$(PACKAGE).cxx G__$(PACKAGE).h: $(HDRS) $(DHDR)
+ @echo "Generating dictionary ..."
+ rootcint -f $@ -c $(CINTFLAGS) $(ALICEINC) $^
+
+### CREATE PAR FILE
+
+$(PARFILE): $(patsubst %,$(PACKAGE)/%,$(filter-out G__%, $(HDRS_TenderSupplies) $(SRCS_TenderSupplies) $(DHDR_TenderSupplies) Makefile Makefile.arch lib$(PACKAGE).pkg PROOF-INF))
+ @echo "Creating archive" $@ ...
+ @tar cfzh $@ $(PACKAGE)
+ @rm -rf $(PACKAGE)
+ @echo "done"
+
+$(PACKAGE)/Makefile: Makefile #.$(PACKAGE)
+ @echo Copying $< to $@ with transformations
+ @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+ @sed 's/include \$$(ROOTSYS)\/test\/Makefile.arch/include Makefile.arch/' < $^ > $@
+
+$(PACKAGE)/Makefile.arch: $(ROOTSYS)/test/Makefile.arch
+ @echo Copying $< to $@
+ @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+ @cp -a $^ $@
+
+$(PACKAGE)/PROOF-INF: PROOF-INF.$(PACKAGE)
+ @echo Copying $< to $@
+ @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+ @cp -a -r $^ $@
+
+$(PACKAGE)/%: %
+ @echo Copying $< to $@
+ @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+ @cp -a $< $@
+
+test-%.par: %.par
+ @echo "INFO: The file $< is now tested, in case of an error check in par-tmp."
+ @mkdir -p par-tmp
+ @cd par-tmp; tar xfz ../$<; cd $(subst .par,,$<); PROOF-INF/BUILD.sh
+ @rm -rf par-tmp
+ @echo "INFO: Testing succeeded (already cleaned up)"
+
--- /dev/null
+#! /bin/bash
+
+make libTenderSupplies.so
--- /dev/null
+
+
+
+void SETUP()
+{
+ // Load some ROOT libraries
+ CheckLoadLibrary("libCore");
+ CheckLoadLibrary("libTree");
+ CheckLoadLibrary("libGeom");
+ CheckLoadLibrary("libVMC");
+ CheckLoadLibrary("libMinuit");
+
+ // Load the AliROOT library
+ CheckLoadLibrary("libANALYSIS");
+ CheckLoadLibrary("libSTEERBase");
+ CheckLoadLibrary("libESD");
+ CheckLoadLibrary("libCDB");
+ CheckLoadLibrary("libTENDER");
+ //Load libs needed for TOFbase
+ CheckLoadLibrary("libProof");
+ CheckLoadLibrary("libRAWDatabase");
+ CheckLoadLibrary("libSTEER");
+ CheckLoadLibrary("libTOFbase");
+
+ CheckLoadLibrary("libTenderSupplies");
+
+ // Set the include paths
+ gROOT->ProcessLine(".include TenderSupplies");
+
+ // Set our location, so that other packages can find us
+ gSystem->Setenv("TenderSupplies_INCLUDE", "TenderSupplies");
+}
+
+
+Int_t CheckLoadLibrary(const char* library)
+{
+ // checks if a library is already loaded, if not loads the library
+
+ if (strlen(gSystem->GetLibraries(Form("%s.so", library), "", kFALSE)) > 0)
+ return 1;
+
+ return gSystem->Load(library);
+}
--- /dev/null
+#ifdef __CINT__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class AliTOFcalibESD+;
+#pragma link C++ class AliTOFT0makerANA+;
+#pragma link C++ class AliTOFT0v2+;
+#pragma link C++ class AliPIDTenderSupply+;
+#pragma link C++ class AliTOFTenderSupply+;
+#pragma link C++ class AliTPCTenderSupply+;
+#pragma link C++ class AliTRDTenderSupply+;
+#pragma link C++ class AliVtxTenderSupply+;
+
--- /dev/null
+#-*- Mode: Makefile -*-
+
+SRCS= TenderSupplies/AliTOFcalibESD.cxx \
+ TenderSupplies/AliTOFT0makerANA.cxx \
+ TenderSupplies/AliTOFT0v2.cxx \
+ TenderSupplies/AliPIDTenderSupply.cxx \
+ TenderSupplies/AliTOFTenderSupply.cxx \
+ TenderSupplies/AliTPCTenderSupply.cxx \
+ TenderSupplies/AliTRDTenderSupply.cxx \
+ TenderSupplies/AliVtxTenderSupply.cxx
+
+HDRS= $(SRCS:.cxx=.h)
+
+DHDR= TenderSuppliesLinkDef.h
+
+EINCLUDE:= ANALYSIS ANALYSIS/Tender STEER TOF
+
+ifeq (win32gcc,$(ALICE_TARGET))
+PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) -lSTEERBase \
+-lESD -lSTEER -lANALYSISalice -lANALYSIS -lCORRFW -lTENDER -lTOFbase
+endif
+
+