From 0895f77057cbcf4a7985043f3844d4da0606840c Mon Sep 17 00:00:00 2001 From: dberzano Date: Fri, 16 Jan 2015 12:12:40 +0100 Subject: [PATCH] Split: Tender*, EventMixing out of ANALYSIS --- EVENTMIX/AliAnalysisTaskMixInfo.cxx | 253 +++ EVENTMIX/AliAnalysisTaskMixInfo.h | 60 + EVENTMIX/AliMixEventCutObj.cxx | 395 ++++ EVENTMIX/AliMixEventCutObj.h | 70 + EVENTMIX/AliMixEventInputHandler.cxx | 249 +++ EVENTMIX/AliMixEventInputHandler.h | 65 + EVENTMIX/AliMixEventPool.cxx | 291 +++ EVENTMIX/AliMixEventPool.h | 64 + EVENTMIX/AliMixInfo.cxx | 463 +++++ EVENTMIX/AliMixInfo.h | 58 + EVENTMIX/AliMixInputEventHandler.cxx | 627 ++++++ EVENTMIX/AliMixInputEventHandler.h | 116 ++ EVENTMIX/AliMixInputHandlerInfo.cxx | 182 ++ EVENTMIX/AliMixInputHandlerInfo.h | 48 + EVENTMIX/CMakeLists.txt | 73 + EVENTMIX/EventMixingLinkDef.h | 11 + EVENTMIX/macros/ShowMixingInfo.C | 36 + TENDER/Tender/AliTender.cxx | 178 ++ TENDER/Tender/AliTender.h | 74 + TENDER/Tender/AliTenderSupply.cxx | 62 + TENDER/Tender/AliTenderSupply.h | 39 + TENDER/Tender/CMakeLists.txt | 67 + TENDER/Tender/TenderLinkDef.h | 10 + TENDER/TenderSupplies/AddTaskTender.C | 123 ++ .../AliAnalysisTaskVZEROEqFactorTask.cxx | 272 +++ .../AliAnalysisTaskVZEROEqFactorTask.h | 89 + .../TenderSupplies/AliEMCALTenderSupply.cxx | 1827 +++++++++++++++++ TENDER/TenderSupplies/AliEMCALTenderSupply.h | 275 +++ .../TenderSupplies/AliHMPIDTenderSupply.cxx | 103 + TENDER/TenderSupplies/AliHMPIDTenderSupply.h | 40 + TENDER/TenderSupplies/AliPHOSTenderSupply.cxx | 970 +++++++++ TENDER/TenderSupplies/AliPHOSTenderSupply.h | 94 + TENDER/TenderSupplies/AliPIDTenderSupply.cxx | 77 + TENDER/TenderSupplies/AliPIDTenderSupply.h | 40 + TENDER/TenderSupplies/AliT0TenderSupply.cxx | 188 ++ TENDER/TenderSupplies/AliT0TenderSupply.h | 44 + TENDER/TenderSupplies/AliTOFTenderSupply.cxx | 1335 ++++++++++++ TENDER/TenderSupplies/AliTOFTenderSupply.h | 124 ++ TENDER/TenderSupplies/AliTPCTenderSupply.cxx | 560 +++++ TENDER/TenderSupplies/AliTPCTenderSupply.h | 90 + TENDER/TenderSupplies/AliTRDTenderSupply.cxx | 651 ++++++ TENDER/TenderSupplies/AliTRDTenderSupply.h | 106 + .../AliTrackFixTenderSupply.cxx | 259 +++ .../TenderSupplies/AliTrackFixTenderSupply.h | 66 + .../TenderSupplies/AliVZEROTenderSupply.cxx | 263 +++ TENDER/TenderSupplies/AliVZEROTenderSupply.h | 52 + TENDER/TenderSupplies/AliVtxTenderSupply.cxx | 101 + TENDER/TenderSupplies/AliVtxTenderSupply.h | 44 + TENDER/TenderSupplies/CMakeLists.txt | 102 + TENDER/TenderSupplies/TenderSuppliesLinkDef.h | 22 + 50 files changed, 11408 insertions(+) create mode 100644 EVENTMIX/AliAnalysisTaskMixInfo.cxx create mode 100644 EVENTMIX/AliAnalysisTaskMixInfo.h create mode 100644 EVENTMIX/AliMixEventCutObj.cxx create mode 100644 EVENTMIX/AliMixEventCutObj.h create mode 100644 EVENTMIX/AliMixEventInputHandler.cxx create mode 100644 EVENTMIX/AliMixEventInputHandler.h create mode 100644 EVENTMIX/AliMixEventPool.cxx create mode 100644 EVENTMIX/AliMixEventPool.h create mode 100644 EVENTMIX/AliMixInfo.cxx create mode 100644 EVENTMIX/AliMixInfo.h create mode 100644 EVENTMIX/AliMixInputEventHandler.cxx create mode 100644 EVENTMIX/AliMixInputEventHandler.h create mode 100644 EVENTMIX/AliMixInputHandlerInfo.cxx create mode 100644 EVENTMIX/AliMixInputHandlerInfo.h create mode 100644 EVENTMIX/CMakeLists.txt create mode 100644 EVENTMIX/EventMixingLinkDef.h create mode 100644 EVENTMIX/macros/ShowMixingInfo.C create mode 100644 TENDER/Tender/AliTender.cxx create mode 100644 TENDER/Tender/AliTender.h create mode 100644 TENDER/Tender/AliTenderSupply.cxx create mode 100644 TENDER/Tender/AliTenderSupply.h create mode 100644 TENDER/Tender/CMakeLists.txt create mode 100644 TENDER/Tender/TenderLinkDef.h create mode 100644 TENDER/TenderSupplies/AddTaskTender.C create mode 100644 TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.cxx create mode 100644 TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.h create mode 100644 TENDER/TenderSupplies/AliEMCALTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliEMCALTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliHMPIDTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliHMPIDTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliPHOSTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliPHOSTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliPIDTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliPIDTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliT0TenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliT0TenderSupply.h create mode 100644 TENDER/TenderSupplies/AliTOFTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliTOFTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliTPCTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliTPCTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliTRDTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliTRDTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliTrackFixTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliTrackFixTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliVZEROTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliVZEROTenderSupply.h create mode 100644 TENDER/TenderSupplies/AliVtxTenderSupply.cxx create mode 100644 TENDER/TenderSupplies/AliVtxTenderSupply.h create mode 100644 TENDER/TenderSupplies/CMakeLists.txt create mode 100644 TENDER/TenderSupplies/TenderSuppliesLinkDef.h diff --git a/EVENTMIX/AliAnalysisTaskMixInfo.cxx b/EVENTMIX/AliAnalysisTaskMixInfo.cxx new file mode 100644 index 00000000000..1a20fe006f3 --- /dev/null +++ b/EVENTMIX/AliAnalysisTaskMixInfo.cxx @@ -0,0 +1,253 @@ +// +// Class AliAnalysisTaskMixInfo +// +// AliAnalysisTaskMixInfo is task +// for mixing info +// +// Mixing info can be enabled by setting one of following lines in UserCreateOutput() in your task +// // prints mixing info +// AliLog::SetClassDebugLevel("AliAnalysisTaskMixInfo", AliLog::kDebug); +// // prints mixing info + event info for both (main and mixed) events +// AliLog::SetClassDebugLevel("AliAnalysisTaskMixInfo", AliLog::kDebug+1); +// +// authors: +// Martin Vala (martin.vala@cern.ch) +// + +#include +#include + +#include "AliAnalysisManager.h" + +#include "AliMixInputEventHandler.h" +#include "AliAnalysisTaskMixInfo.h" +#include "AliMixInfo.h" +#include "AliMixEventPool.h" +#include "AliMixEventCutObj.h" + + +ClassImp(AliAnalysisTaskMixInfo) + +//________________________________________________________________________ +AliAnalysisTaskMixInfo::AliAnalysisTaskMixInfo(const char *name) + : AliAnalysisTaskSE(name), + fInputEHMain(0), + fInputEHMix(0), + fOutputList(0), + fMixInfo(0), + fCurrentEntryTmp(-1), + fLogType(AliLog::kInfo), + fLogClassesString() +{ + // + // Constructor + // + DefineOutput(1, TList::Class()); +} + +//________________________________________________________________________ +AliAnalysisTaskMixInfo::~AliAnalysisTaskMixInfo() +{ + // + // Destructor + // + if (fOutputList && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) delete fOutputList; +} + +//________________________________________________________________________ +void AliAnalysisTaskMixInfo::UserCreateOutputObjects() +{ + // Create histograms + // Called once + + SetDebugForAllClasses(); + fOutputList = new TList(); + fOutputList->SetOwner(kTRUE); + + // sets all Inuput Handler pointers + InitInputHandlers(); + + // inits mix info + InitMixInfo(); + + if (fInputEHMix) { + AliMixEventPool *evPool = fInputEHMix->GetEventPool(); + if (evPool) { + evPool->SetBufferSize(fInputEHMix->BufferSize()); + evPool->SetMixNumber(fInputEHMix->MixNumber()); + fMixInfo->SetEventPool(evPool); + } + } + if (fMixInfo) fOutputList->Add(fMixInfo); + + // Post output data. + PostData(1, fOutputList); +} + +//________________________________________________________________________ +void AliAnalysisTaskMixInfo::UserExec(Option_t *) +{ + // Main loop + // Called for each event + if (fMixInfo && fInputEHMix) { + if (fInputEHMix->BufferSize() > 1) { + if (fInputEHMix->NumberMixedTimes() >= fInputEHMix->BufferSize()) + fMixInfo->FillHistogram(AliMixInfo::kMainEvents, fInputEHMix->CurrentBinIndex()); + } else { + if ((!fInputEHMix->IsMixingIfNotEnoughEvents())) { + if (fInputEHMix->NumberMixed() == fInputEHMix->MixNumber()) + // add main entry only when there was enough mixed events mixed + fMixInfo->FillHistogram(AliMixInfo::kMainEvents, fInputEHMix->CurrentBinIndex()); + } else { + fMixInfo->FillHistogram(AliMixInfo::kMainEvents, fInputEHMix->CurrentBinIndex()); + } + } + AliDebug(AliLog::kDebug, Form("Main %lld %d [%lld,%lld] %d", fInputEHMix->CurrentEntry(), fInputEHMix->CurrentBinIndex(), fInputEHMix->CurrentEntryMain(), fInputEHMix->CurrentEntryMix(), fInputEHMix->NumberMixed())); + } + // Post output data. + PostData(1, fOutputList); +} + +//________________________________________________________________________ +void AliAnalysisTaskMixInfo::UserExecMix(Option_t *) +{ + // UserExecMix + + if (!fInputEHMix) return; + + // fills bin index (even when it is -1, so we know out of range combinations) + if (fMixInfo) { + if (fInputEHMix->CurrentBinIndex()==-1) { + fMixInfo->FillHistogram(AliMixInfo::kMixedEvents, fInputEHMix->CurrentBinIndex()); + } else { + for(Int_t iBuff=0; iBuffBufferSize(); iBuff++) { + fMixInfo->FillHistogram(AliMixInfo::kMixedEvents, fInputEHMix->CurrentBinIndex()); + } + } + } + + // just test + if (fInputEHMix->CurrentEntryMix() < 0) { + AliError("Mix entry is -1 and it should not happen !!!!!"); + return ; + } + AliDebug(AliLog::kDebug, Form("Mixing %lld %d [%lld,%lld] %d", fInputEHMix->CurrentEntry(), fInputEHMix->CurrentBinIndex(), fInputEHMix->CurrentEntryMain(), fInputEHMix->CurrentEntryMix(), fInputEHMix->NumberMixed())); + if (AliLog::GetDebugLevel("", IsA()->GetName()) > AliLog::kDebug) PrintEventInfo(); + // Post output data. + PostData(1, fOutputList); +} + +//________________________________________________________________________ +void AliAnalysisTaskMixInfo::FinishTaskOutput() +{ + // FinishTaskOutput + if (fMixInfo) fMixInfo->Print(); +} + + +//________________________________________________________________________ +void AliAnalysisTaskMixInfo::Terminate(Option_t *) +{ + // Draw result to the screen + // Called once at the end of the query + fOutputList = dynamic_cast(GetOutputData(1)); + if (!fOutputList) { + AliError("fOutputList not available"); + return; + } + fOutputList->Print(); + fMixInfo = (AliMixInfo *) fOutputList->FindObject("mixInfo"); + if (fMixInfo) { + fMixInfo->Draw("HIST"); + AliMixEventPool *evPool = (AliMixEventPool *) fMixInfo->GetEventPool("mixEventPool"); + if (evPool) evPool->Print(); + } +} + +//_____________________________________________________________________________ +void AliAnalysisTaskMixInfo::SetLogType(AliLog::EType_t type, TString allClasses) +{ + // + // Set Log level for this and other classes (list of their names) + // + AliDebug(AliLog::kDebug + 10, "<-"); + fLogType = type; + fLogClassesString = allClasses; + SetDebugForAllClasses(); + AliDebug(AliLog::kDebug + 10, "->"); +} + +//_____________________________________________________________________________ +void AliAnalysisTaskMixInfo::SetDebugForAllClasses() +{ + // + // Set debug level for all classes for which it is required + // + AliDebug(AliLog::kDebug + 10, "<-"); + TObjArray *array = fLogClassesString.Tokenize(":"); + TObjString *str; + TString strr; + for (Int_t i = 0; i < array->GetEntriesFast(); i++) { + str = (TObjString *) array->At(i); + strr = str->GetString(); + AliLog::SetClassDebugLevel(strr.Data(), fLogType); + AliDebug(AliLog::kDebug + 5, Form("Setting Debug level %d to %s ...", (Int_t)fLogType - AliLog::kDebug, strr.Data())); + } + delete array; + AliDebug(AliLog::kDebug + 10, "->"); +} + +//_____________________________________________________________________________ +void AliAnalysisTaskMixInfo::InitMixInfo() +{ + // + // Init mixing info + // + if (fInputEHMix) { + fMixInfo = new AliMixInfo("mixInfo", "Mix title"); + AliMixEventPool *evPool = fInputEHMix->GetEventPool(); + if (!evPool) { + // TList *list = new TList; + if (fMixInfo) fMixInfo->CreateHistogram(AliMixInfo::kMainEvents, 1, 1, 2); + if (fMixInfo) fMixInfo->CreateHistogram(AliMixInfo::kMixedEvents, 1, 1, 2); + } else { + if (evPool->NeedInit()) evPool->Init(); + Int_t num = evPool->GetListOfEntryLists()->GetEntriesFast(); + if (fMixInfo) fMixInfo->CreateHistogram(AliMixInfo::kMainEvents, num, 1, num + 1); + if (fMixInfo) fMixInfo->CreateHistogram(AliMixInfo::kMixedEvents, num, 1, num + 1); + } + } +} + +//_____________________________________________________________________________ +void AliAnalysisTaskMixInfo::PrintEventInfo() +{ + // + // Prints event info for all event mxing cuts + // + if (fInputEHMix) { + TObjArrayIter next(fInputEHMix->GetEventPool()->GetListOfEventCuts()); + AliMixEventCutObj *cut; + AliInputEventHandler *ihMain = fInputEHMain->GetFirstInputEventHandler(); + AliMultiInputEventHandler *ihMultiMix = fInputEHMix->GetFirstMultiInputHandler(); + AliInputEventHandler *ihMix = 0; + if (ihMultiMix) ihMix = ihMultiMix->GetFirstInputEventHandler(); + if (!ihMix) return; + while ((cut = (AliMixEventCutObj *) next())) { + cut->PrintValues(ihMain->GetEvent(), ihMix->GetEvent()); + } + } +} + +//_____________________________________________________________________________ +void AliAnalysisTaskMixInfo::InitInputHandlers() +{ + // + // Sets needed input handlers + // + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + fInputEHMain = dynamic_cast(mgr->GetInputEventHandler()); + if (fInputEHMain) { + fInputEHMix = dynamic_cast(fInputEHMain->GetFirstMultiInputHandler()); + } +} diff --git a/EVENTMIX/AliAnalysisTaskMixInfo.h b/EVENTMIX/AliAnalysisTaskMixInfo.h new file mode 100644 index 00000000000..196c1b8fa5e --- /dev/null +++ b/EVENTMIX/AliAnalysisTaskMixInfo.h @@ -0,0 +1,60 @@ +#ifndef ALIANALYSISTASKMIXINFO_H +#define ALIANALYSISTASKMIXINFO_H + +// +// Class AliAnalysisTaskMixInfo +// +// AliAnalysisTaskMixInfo is task +// for mixing info +// +// authors: +// Martin Vala (martin.vala@cern.ch) +// + +#include "AliLog.h" + +#include "AliAnalysisTaskSE.h" + +class AliMixInputEventHandler; +class TList; +class AliMixInfo; +class AliAnalysisTaskMixInfo : public AliAnalysisTaskSE { +public: + AliAnalysisTaskMixInfo(const char *name = ""); + virtual ~AliAnalysisTaskMixInfo(); + + virtual void UserCreateOutputObjects(); + virtual void UserExec(Option_t *option); + virtual void Terminate(Option_t *); + virtual void UserExecMix(Option_t *option = ""); + virtual void FinishTaskOutput(); + + void InitInputHandlers(); + void InitMixInfo(); + // sets log type to list of classes + void SetLogType(AliLog::EType_t type, TString allClasses = ""); + // sets correctly debug level to AliLog for all classes listed in fLogClassesString + void SetDebugForAllClasses(); + + void PrintEventInfo(); + +private: + + AliMultiInputEventHandler *fInputEHMain; //! input multi handler + AliMixInputEventHandler *fInputEHMix; //! mix input handler + + TList *fOutputList; //! output list + AliMixInfo *fMixInfo; //! mix info + + Long64_t fCurrentEntryTmp; //! temporary current entry number + + AliLog::EType_t fLogType; // log type + TString fLogClassesString; // all classes string divided with ":" + + AliAnalysisTaskMixInfo(const AliAnalysisTaskMixInfo &); // not implemented + AliAnalysisTaskMixInfo &operator=(const AliAnalysisTaskMixInfo &); // not implemented + + ClassDef(AliAnalysisTaskMixInfo, 1); // example of analysis +}; + +#endif diff --git a/EVENTMIX/AliMixEventCutObj.cxx b/EVENTMIX/AliMixEventCutObj.cxx new file mode 100644 index 00000000000..578616abbe8 --- /dev/null +++ b/EVENTMIX/AliMixEventCutObj.cxx @@ -0,0 +1,395 @@ +// +// Class AliMixEventCutObj +// +// AliMixEventCutObj object contains information about one cut on for event mixing +// used by AliMixEventPool class +// +// authors: +// Martin Vala (martin.vala@cern.ch) +// + +#include "AliLog.h" +#include "AliESDEvent.h" +#include "AliAODEvent.h" +#include "AliMultiplicity.h" +#include "AliAODVertex.h" +#include "AliEventplane.h" + +#include "AliMixEventCutObj.h" + +ClassImp(AliMixEventCutObj) + +//_________________________________________________________________________________________________ +AliMixEventCutObj::AliMixEventCutObj(AliMixEventCutObj::EEPAxis_t type, Float_t min, Float_t max, Float_t step, const char *opt) : TObject(), + fCutType((Int_t)type), + fCutOpt(opt), + fCutMin(min), + fCutMax(max), + fCutStep(step), + fCutSmallVal(0), + fCurrentVal(min) +{ + // + // Default constructor + // + AliDebug(AliLog::kDebug + 5, "<-"); + if (fCutStep < 1e-5) AliError("fCutStep is too small !!! This cut will not work !!!"); + AliDebug(AliLog::kDebug + 5, "->"); +} + +//_________________________________________________________________________________________________ +AliMixEventCutObj::AliMixEventCutObj(const AliMixEventCutObj &obj) : TObject(obj), + fCutType(obj.fCutType), + fCutOpt(obj.fCutOpt), + fCutMin(obj.fCutMin), + fCutMax(obj.fCutMax), + fCutStep(obj.fCutStep), + fCutSmallVal(obj.fCutSmallVal), + fCurrentVal(obj.fCurrentVal) +{ + // + // Copy constructor + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 5, "->"); +} + +//_________________________________________________________________________________________________ +AliMixEventCutObj &AliMixEventCutObj::operator=(const AliMixEventCutObj &obj) +{ + // + // Assigned operator + // + if (&obj != this) { + TObject::operator=(obj); + fCutType = obj.fCutType; + fCutOpt = obj.fCutOpt; + fCutMin = obj.fCutMin; + fCutMax = obj.fCutMax; + fCutStep = obj.fCutStep; + fCutSmallVal = obj.fCutSmallVal; + fCurrentVal = obj.fCurrentVal; +// fNoMore = obj.fNoMore; + } + return *this; +} + + +//_________________________________________________________________________________________________ +void AliMixEventCutObj::Reset() +{ + // + // Reset cut + // + AliDebug(AliLog::kDebug + 5, "<-"); + fCurrentVal = fCutMin - fCutStep; + AliDebug(AliLog::kDebug + 5, "->"); +} +//_________________________________________________________________________________________________ +Bool_t AliMixEventCutObj::HasMore() const +{ + // + // Return kTRUE when fCurrentVal is in interval of cut range + // + return ((fCurrentVal + fCutStep) < fCutMax); +} + +//_________________________________________________________________________________________________ +void AliMixEventCutObj::AddStep() +{ + // + // Adds step + // + fCurrentVal += fCutStep; +} + +//_________________________________________________________________________________________________ +void AliMixEventCutObj::Print(const Option_t *) const +{ + // + // Prints cut information + // + AliInfo(Form("%s %f %f %f", GetCutName(fCutType), fCutMin, fCutMax, fCutStep)); +} +//_________________________________________________________________________________________________ +void AliMixEventCutObj::PrintCurrentInterval() +{ + // + // Prints current cut interval information + // + AliDebug(AliLog::kDebug, Form("%s <%f,%f>", GetCutName(fCutType), GetCurrentMin(), GetCurrentMax())); +} + +//_________________________________________________________________________________________________ +Int_t AliMixEventCutObj::GetNumberOfBins() const +{ + // + // Returns number of bins + // + if (fCutStep < 1e-5) return -1; + return (Int_t)((fCutMax - fCutMin) / fCutStep); +} + +//_________________________________________________________________________________________________ +Int_t AliMixEventCutObj::GetBinNumber(Float_t num) const +{ + // + // Returns bin (index) number in current cut. + // Returns -1 in case of out of range + // + Int_t binNum = 0; + for (Float_t iCurrent = fCutMin; iCurrent < fCutMax; iCurrent += fCutStep) { + binNum++; + if ((num >= iCurrent) && (num < iCurrent + fCutStep - fCutSmallVal)) { + return binNum; + } + } + return -1; +} + +//_________________________________________________________________________________________________ +Int_t AliMixEventCutObj::GetIndex(AliVEvent *ev) +{ + // + // Finds bin (index) in current cut from event information. + // + return GetBinNumber(GetValue(ev)); +} + +//_________________________________________________________________________________________________ +Double_t AliMixEventCutObj::GetValue(AliVEvent *ev) +{ + // + // Returns value from event + // + + AliESDEvent *esd = dynamic_cast(ev); + if (esd) return GetValue(esd); + AliAODEvent *aod = dynamic_cast(ev); + if (aod) return GetValue(aod); + + AliFatal("Event is not supported in Event Mixing cuts!!!!"); + return -99999; +} + +//_________________________________________________________________________________________________ +Double_t AliMixEventCutObj::GetValue(AliESDEvent *ev) +{ + // + // Returns value from esd event + // + + const AliMultiplicity *multESD = 0; + + switch (fCutType) { + case kMultiplicity: + return (Double_t)ev->GetNumberOfTracks(); + case kZVertex: + return ev->GetVertex()->GetZ(); + case kNumberV0s: + return ev->GetNumberOfV0s(); + case kNumberTracklets: + multESD = ev->GetMultiplicity(); + if (multESD) return multESD->GetNumberOfTracklets(); + else AliFatal("esd->GetMultiplicity() is null"); + break; + case kCentrality: + { + AliCentrality *c = ev->GetCentrality(); + if (!c) AliFatal("esd->GetCentrality() is null"); + return c->GetCentralityPercentile(fCutOpt.Data()); + } + case kEventPlane: + { + AliEventplane *evtPlane = ev->GetEventplane(); + if (!evtPlane) evtPlane = new AliEventplane(); + Double_t val = evtPlane->GetEventplane("V0",ev,fCutOpt.Atoi()); + if (!ev->GetEventplane()) delete evtPlane; + return val; + } + case kEventPlaneV0A: + { + AliEventplane *evtPlane = ev->GetEventplane(); + if (!evtPlane) evtPlane = new AliEventplane(); + Double_t val = evtPlane->GetEventplane("V0A",ev,fCutOpt.Atoi()); + if (!ev->GetEventplane()) delete evtPlane; + return val; + } + case kEventPlaneV0C: + { + AliEventplane *evtPlane = ev->GetEventplane(); + if (!evtPlane) evtPlane = new AliEventplane(); + Double_t val = evtPlane->GetEventplane("V0C",ev,fCutOpt.Atoi()); + if (!ev->GetEventplane()) delete evtPlane; + return val; + } + } + + AliFatal("Mixing Cut TYPE is not supported for ESD"); + return -99999; + +} + +//_________________________________________________________________________________________________ +Double_t AliMixEventCutObj::GetValue(AliAODEvent *ev) +{ + // + // Returns value from aod event + // + + AliAODVertex *v=0; + switch (fCutType) { + case kMultiplicity: + return (Double_t) ev->GetNumberOfTracks(); + case kZVertex: + v = ev->GetVertex(0); + if (!v) return -99999; + return ev->GetVertex(0)->GetZ(); + // if verttex is null return -9999 + return -99999; + case kNumberV0s: + return ev->GetNumberOfV0s(); + case kCentrality: + { + AliCentrality *c = ev->GetCentrality(); + if (!c) AliFatal("esd->GetCentrality() is null"); + return c->GetCentralityPercentile(fCutOpt.Data()); + } + case kEventPlane: + { + AliEventplane *evtPlane = ev->GetEventplane(); + if (!evtPlane) evtPlane = new AliEventplane(); + Double_t val = evtPlane->GetEventplane("V0A",ev,fCutOpt.Atoi()); + if (!ev->GetEventplane()) delete evtPlane; + return val; + } + case kEventPlaneV0A: + { + AliEventplane *evtPlane = ev->GetEventplane(); + if (!evtPlane) evtPlane = new AliEventplane(); + Double_t val = evtPlane->GetEventplane("V0A",ev,fCutOpt.Atoi()); + if (!ev->GetEventplane()) delete evtPlane; + return val; + } + case kEventPlaneV0C: + { + AliEventplane *evtPlane = ev->GetEventplane(); + if (!evtPlane) evtPlane = new AliEventplane(); + Double_t val = evtPlane->GetEventplane("V0C",ev,fCutOpt.Atoi()); + if (!ev->GetEventplane()) delete evtPlane; + return val; + } + } + + AliFatal("Mixing Cut TYPE is not supported for AOD"); + return -99999; +} + +//_________________________________________________________________________________________________ +const char *AliMixEventCutObj::GetCutName(Int_t index) const +{ + // + // Retruns name of cut + // + + if (index < 0) index = fCutType; + switch (index) { + case kMultiplicity: + return "Multiplicity"; + case kZVertex: + return "ZVertex"; + case kNumberV0s: + return "NumberV0s"; + case kNumberTracklets: + return "NumberTracklets"; + case kCentrality: + return Form("kCentrality[%s]", fCutOpt.Data()); + case kEventPlane: + return Form("EventPlane[%s]", fCutOpt.Data()); + case kEventPlaneV0A: + return Form("EventPlaneV0A[%s]", fCutOpt.Data()); + case kEventPlaneV0C: + return Form("EventPlaneV0A[%s]", fCutOpt.Data()); + } + return ""; +} + +//_________________________________________________________________________________________________ +void AliMixEventCutObj::SetCurrentValueToIndex(Int_t index) +{ + // + // Sets current value to index + // + + fCurrentVal = fCutMin; + for (Int_t i = 0; i < index-1; i++) AddStep(); +} + +//_________________________________________________________________________________________________ +void AliMixEventCutObj::PrintValues(AliVEvent *main, AliVEvent *mix) +{ + // + // Prints values of both events for current type + // + AliInfo(Form("name=%s main=%f mix=%f", GetCutName(), GetValue(main), GetValue(mix))); +} + +//_________________________________________________________________________________________________ +Bool_t AliMixEventCutObj::IsValid() +{ + // + // Check if cut is valid + // + switch (fCutType) { + + case kCentrality: + { + if (fCutOpt.IsNull()) { + AliError("fCutOpt is null"); + return kFALSE; + } + break; + } + case kEventPlane: + { + if (fCutOpt.IsNull()) { + AliError("fCutOpt is null"); + return kFALSE; + } + if (!fCutOpt.IsDigit()) { + AliError("fCutOpt is not a digit string"); + return kFALSE; + } + break; + } + case kEventPlaneV0A: + { + if (fCutOpt.IsNull()) { + AliError("fCutOpt is null"); + return kFALSE; + } + if (!fCutOpt.IsDigit()) { + AliError("fCutOpt is not a digit string"); + return kFALSE; + } + break; + } + case kEventPlaneV0C: + { + if (fCutOpt.IsNull()) { + AliError("fCutOpt is null"); + return kFALSE; + } + if (!fCutOpt.IsDigit()) { + AliError("fCutOpt is not a digit string"); + return kFALSE; + } + break; + } + default: { + break; + } + } + + return kTRUE; +} diff --git a/EVENTMIX/AliMixEventCutObj.h b/EVENTMIX/AliMixEventCutObj.h new file mode 100644 index 00000000000..85fe4ffd6dc --- /dev/null +++ b/EVENTMIX/AliMixEventCutObj.h @@ -0,0 +1,70 @@ +// +// Class AliMixEventCutObj +// +// AliMixEventCutObj object contains information about one cut on for event mixing +// used by AliMixEventPool class +// +// authors: +// Martin Vala (martin.vala@cern.ch) +// + +#ifndef ALIMIXEVENTCUTOBJ_H +#define ALIMIXEVENTCUTOBJ_H + +#include +#include + +class AliVEvent; +class AliAODEvent; +class AliESDEvent; +class AliMixEventCutObj : public TObject { +public: + enum EEPAxis_t {kMultiplicity = 0, kZVertex = 1, kNumberV0s = 2, kNumberTracklets = 3, kCentrality = 4, kEventPlane = 5, + kEventPlaneV0A=6 , kEventPlaneV0C=7 , kAllEventAxis = 8 + }; + + AliMixEventCutObj(AliMixEventCutObj::EEPAxis_t type = kMultiplicity, Float_t min = 0.0, Float_t max = 0.0, Float_t step = 1.0, const char *opt = ""); + AliMixEventCutObj(const AliMixEventCutObj &obj); + AliMixEventCutObj &operator=(const AliMixEventCutObj &obj); + + virtual void Print(const Option_t *) const; + void PrintCurrentInterval(); + void PrintValues(AliVEvent *main, AliVEvent *mix); + void Reset(); + void AddStep(); + + Bool_t HasMore() const; + + Int_t GetNumberOfBins() const; + Float_t GetCurrentMin() const { return fCurrentVal; } + Float_t GetCurrentMax() const { return fCurrentVal + fCutStep - fCutSmallVal; } + Float_t GetMin() const { return fCutMin; } + Float_t GetMax() const { return fCutMax; } + Float_t GetStep() const { return fCutStep; } + Short_t GetType() const { return fCutType; } + Int_t GetBinNumber(Float_t num) const; + Int_t GetIndex(AliVEvent *ev); + Double_t GetValue(AliVEvent *ev); + Double_t GetValue(AliESDEvent *ev); + Double_t GetValue(AliAODEvent *ev); + + const char *GetCutName(Int_t index = -1) const; + + void SetCurrentValueToIndex(Int_t index); + + Bool_t IsValid(); + +private: + Int_t fCutType; // cut type + TString fCutOpt; // cut option string + Float_t fCutMin; // cut min + Float_t fCutMax; // cut max + Float_t fCutStep; // cut step + Float_t fCutSmallVal; // small value + + Float_t fCurrentVal; // current value + + ClassDef(AliMixEventCutObj, 3) +}; + +#endif diff --git a/EVENTMIX/AliMixEventInputHandler.cxx b/EVENTMIX/AliMixEventInputHandler.cxx new file mode 100644 index 00000000000..beacb17a790 --- /dev/null +++ b/EVENTMIX/AliMixEventInputHandler.cxx @@ -0,0 +1,249 @@ +// +// Class AliMixEventInputHandler +// +// Mixing input handler prepare N events before UserExec +// TODO example +// author: +// Martin Vala (martin.vala@cern.ch) +// + +#include +#include +#include +#include "AliLog.h" +#include "AliMixEventPool.h" +#include "AliMixEventInputHandler.h" +#include "AliAnalysisManager.h" + +#include "AliMixInputHandlerInfo.h" +#include + +ClassImp(AliMixEventInputHandler) + +//_____________________________________________________________________________ +AliMixEventInputHandler::AliMixEventInputHandler(const Int_t size) : + AliInputEventHandler(), + fBufferSize(size), + fInputHandlers(), + fMixTrees(), + fTreeMap(size), + fMixIntupHandlerInfoTmp(0), + fEntryCounter(0), + fEventPool(0), + fMixEventNumber(0) { +// +// Default constructor. +// + AliDebug(AliLog::kDebug + 10, "<-"); + AliDebug(AliLog::kDebug + 10, "->"); +} + +//_____________________________________________________________________________ +AliInputEventHandler *AliMixEventInputHandler::InputEventHandler(const Int_t index) { + // + // Returns input handler + // + AliDebug(AliLog::kDebug, Form("<-")); + if ((index >= 0) && (index < fBufferSize)) { + AliDebug(AliLog::kDebug, Form("->")); + return (AliInputEventHandler *) fInputHandlers.At(index); + } + AliDebug(AliLog::kDebug, Form("->")); + return 0; +} +//_____________________________________________________________________________ +void AliMixEventInputHandler::SetInputHandlerForMixing(const AliInputEventHandler *const inHandler) { + // + // Create N (fBufferSize) copies of input handler + // + AliDebug(AliLog::kDebug, Form("<-")); + AliDebug(AliLog::kDebug, Form("Creating %d input event handlers ...", fBufferSize)); + for (Int_t i = 0; i < fBufferSize; i++) { + AliDebug(AliLog::kDebug + 5, Form("Adding %d ...", i)); + fInputHandlers.Add((AliInputEventHandler *) inHandler->Clone()); + } + AliDebug(AliLog::kDebug, Form("->")); +} +//_____________________________________________________________________________ +Bool_t AliMixEventInputHandler::Init(Option_t *opt) { + // + // Init() is called for all mix input handlers. + // + AliDebug(AliLog::kDebug, Form("<- \"%s\"", opt)); + AliInputEventHandler *eh = 0; + TObjArrayIter next(&fInputHandlers); + while ((eh = (AliInputEventHandler *) next())) { + eh->Init(opt); + } + AliDebug(AliLog::kDebug, Form("->")); + return kTRUE; +} +//_____________________________________________________________________________ +Bool_t AliMixEventInputHandler::Init(TTree *tree, Option_t *) { + // + // Init(const char*path) is called for all mix input handlers. + // Create event pool if needed + // + AliDebug(AliLog::kDebug, Form("<- %p", tree)); + if (!tree) { + AliDebug(AliLog::kDebug, Form("->")); + return kFALSE; + } + AliDebug(AliLog::kDebug, Form("%s", tree->GetCurrentFile()->GetName())); + + // clears array of input handlers + fMixTrees.SetOwner(kTRUE); + fMixTrees.Clear(); + + // create AliMixInputHandlerInfo + if (!fMixIntupHandlerInfoTmp) fMixIntupHandlerInfoTmp = new AliMixInputHandlerInfo(tree->GetName()); + + // adds current file + fMixIntupHandlerInfoTmp->AddTreeToChain(tree); + Int_t lastIndex = fMixIntupHandlerInfoTmp->GetChain()->GetListOfFiles()->GetEntries(); + TChainElement *che = (TChainElement *)fMixIntupHandlerInfoTmp->GetChain()->GetListOfFiles()->At(lastIndex - 1); + AliMixInputHandlerInfo *mixIHI = 0; + for (Int_t i = 0; i < fInputHandlers.GetEntries(); i++) { + + AliDebug(AliLog::kDebug, Form("fInputHandlers[%d]", i)); + mixIHI = new AliMixInputHandlerInfo(fMixIntupHandlerInfoTmp->GetName(), fMixIntupHandlerInfoTmp->GetTitle()); + mixIHI->PrepareEntry(che, -1, InputEventHandler(i)); + AliDebug(AliLog::kDebug, Form("chain[%d]->GetEntries() = %lld", i, mixIHI->GetChain()->GetEntries())); + fMixTrees.Add(mixIHI); + } + AliDebug(AliLog::kDebug, Form("fEntryCounter=%lld", fEntryCounter)); + + if (fEventPool->NeedInit()) + fEventPool->Init(); + + AliDebug(AliLog::kDebug, Form("->")); + return kTRUE; +} +//_____________________________________________________________________________ +Bool_t AliMixEventInputHandler::Notify() { + // + // Notify() is called for all mix input handlers + // + AliDebug(AliLog::kDebug, Form("<-")); + AliInputEventHandler *eh = 0; + TObjArrayIter next(&fInputHandlers); + while ((eh = (AliInputEventHandler *) next())) { + eh->Notify(); + } + AliDebug(AliLog::kDebug, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixEventInputHandler::Notify(const char *path) { + // + // Notify(const char*path) is called for all mix input handlers + // + AliDebug(AliLog::kDebug, Form("<- %s", path)); + AliInputEventHandler *eh = 0; + TObjArrayIter next(&fInputHandlers); + while ((eh = (AliInputEventHandler *) next())) { + eh->Notify(path); + } + AliDebug(AliLog::kDebug, Form("->")); + return kTRUE; +} +//_____________________________________________________________________________ +Bool_t AliMixEventInputHandler::BeginEvent(Long64_t entry) { + // + // BeginEvent(Long64_t entry) is called for all mix input handlers + // + + AliDebug(AliLog::kDebug, Form("-> %lld", entry)); + AliInputEventHandler *eh = 0; + TObjArrayIter next(&fInputHandlers); + while ((eh = (AliInputEventHandler *) next())) { + eh->BeginEvent(entry); + } + AliDebug(AliLog::kDebug, Form("->")); + return kTRUE; +} + + +//_____________________________________________________________________________ +Bool_t AliMixEventInputHandler::GetEntry() { + // + // Sets correct events to every mix events + // + AliDebug(AliLog::kDebug, Form("<-")); + + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + AliInputEventHandler *inEvHMain = dynamic_cast(mgr->GetInputEventHandler()); + + Long64_t zeroChainEntries = fMixIntupHandlerInfoTmp->GetChain()->GetEntries() - inEvHMain->GetTree()->GetEntries(); + + // if fEntryCounter is 0 just add entry + if (!fEntryCounter) { + if (inEvHMain) { + + fEventPool->AddEntry(inEvHMain->GetTree()->GetReadEntry() + zeroChainEntries, inEvHMain->GetEvent()); + } + return kTRUE; + } + + AliDebug(AliLog::kDebug, Form("++++++++++++++ BEGIN SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + + fMixEventNumber = 0; + TEntryList *el = fEventPool->FindEntryList(inEvHMain->GetEvent()); + Long64_t elNum = 0; + if (el) + elNum = el->GetN(); + else + AliDebug(AliLog::kDebug, "el is null"); + + AliInputEventHandler *eh = 0; + AliMixInputHandlerInfo *mihi = 0; + TObjArrayIter next(&fInputHandlers); + Int_t counter = 0; + Long64_t entryMix = 0; + while ((eh = (AliInputEventHandler *) next())) { + if (fEventPool->GetListOfEventCuts()->GetEntries() > 0) { + entryMix = -1; + if (el && el->GetN() >= fBufferSize) { + Long64_t entryInEntryList = elNum - 1 - counter; + if (entryInEntryList < 0) break; + entryMix = el->GetEntry(entryInEntryList); + } + } else { + entryMix = fEntryCounter - 1 - counter ; + } + + AliDebug(AliLog::kDebug, Form("Handler[%d] entryMix %lld ", counter, entryMix)); + if (entryMix < 0) break; + + mihi = (AliMixInputHandlerInfo *) fMixTrees.At(counter); + TChainElement *te = fMixIntupHandlerInfoTmp->GetEntryInTree(entryMix); + mihi->PrepareEntry(te, entryMix, InputEventHandler(counter)); + fMixEventNumber++; + counter++; + } + + if (inEvHMain) { + fEventPool->AddEntry(inEvHMain->GetTree()->GetReadEntry() + zeroChainEntries, inEvHMain->GetEvent()); + } + + AliDebug(AliLog::kDebug, Form("fEntryCounter=%lld fMixEventNumber=%d", fEntryCounter, fMixEventNumber)); + AliDebug(AliLog::kDebug, Form("++++++++++++++ END SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + AliDebug(AliLog::kDebug, Form("->")); + return kTRUE; +} +//_____________________________________________________________________________ +Bool_t AliMixEventInputHandler::FinishEvent() { + // + // FinishEvent() is called for all mix input handlers + // + AliDebug(AliLog::kDebug, Form("<-")); + AliInputEventHandler *eh = 0; + TObjArrayIter next(&fInputHandlers); + while ((eh = (AliInputEventHandler *) next())) { + eh->FinishEvent(); + } + fEntryCounter++; + AliDebug(AliLog::kDebug, Form("->")); + return kTRUE; +} diff --git a/EVENTMIX/AliMixEventInputHandler.h b/EVENTMIX/AliMixEventInputHandler.h new file mode 100644 index 00000000000..8fb4920c6f6 --- /dev/null +++ b/EVENTMIX/AliMixEventInputHandler.h @@ -0,0 +1,65 @@ +// +// Class AliMixEventInputHandler +// +// Mixing input handler prepare N events before UserExec +// TODO example +// author: +// Martin Vala (martin.vala@cern.ch) +// + +#ifndef ALIMIXEVENTINPUTHANDLER_H +#define ALIMIXEVENTINPUTHANDLER_H + +#include + +#include "AliInputEventHandler.h" +#include + +class TChain; +class AliMixEventPool; +class AliMixInputHandlerInfo; +class AliMixEventInputHandler : public AliInputEventHandler { + +public: + AliMixEventInputHandler(const Int_t size=1); + virtual ~AliMixEventInputHandler() {;}; + + // From the interface + virtual Bool_t Init(Option_t *opt /*opt*/); + virtual Bool_t Init(TTree *tree, Option_t* /*opt*/); + virtual Bool_t BeginEvent(Long64_t entry /*entry*/); + virtual Bool_t GetEntry(); + virtual Bool_t FinishEvent(); + virtual Bool_t Notify(); + virtual Bool_t Notify(const char *path); + + + void SetInputHandlerForMixing(const AliInputEventHandler *const inHandler); + void SetEventPool(AliMixEventPool *const evPool) {fEventPool = evPool;} + + AliInputEventHandler *InputEventHandler(const Int_t index); + AliMixEventPool *GetEventPool() const { return fEventPool;} + Int_t BufferSize() const {return fBufferSize;} + Int_t MixedEventNumber() const {return fMixEventNumber;} + Long64_t EntryAll() const { return fEntryCounter;} +protected: + + Int_t fBufferSize; // Size of the buffer + TObjArray fInputHandlers; // buffer of input handlers + TObjArray fMixTrees; // buffer of input handlers + TArrayI fTreeMap; // tree map + AliMixInputHandlerInfo *fMixIntupHandlerInfoTmp; //! mix input handler info full chain + Long64_t fEntryCounter; // entry counter + AliMixEventPool *fEventPool; // event pool + + Int_t fMixEventNumber; // number mix + +private: + + AliMixEventInputHandler(const AliMixEventInputHandler &handler); + AliMixEventInputHandler &operator=(const AliMixEventInputHandler &handler); + + ClassDef(AliMixEventInputHandler, 1) +}; + +#endif diff --git a/EVENTMIX/AliMixEventPool.cxx b/EVENTMIX/AliMixEventPool.cxx new file mode 100644 index 00000000000..6472d58c6bb --- /dev/null +++ b/EVENTMIX/AliMixEventPool.cxx @@ -0,0 +1,291 @@ +// +// Class AliMixEventPool +// +// AliMixEventPool is used to find +// similar events +// +// author: +// Martin Vala (martin.vala@cern.ch) +// + +#include + +#include "AliLog.h" +#include "AliMixEventCutObj.h" + +#include "AliMixEventPool.h" + +ClassImp(AliMixEventPool) + +//_________________________________________________________________________________________________ +AliMixEventPool::AliMixEventPool(const char *name, const char *title) : TNamed(name, title), + fListOfEntryList(), + fListOfEventCuts(), + fBinNumber(0), + fBufferSize(0), + fMixNumber(0) +{ + // + // Default constructor. + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 5, "->"); +} +//_________________________________________________________________________________________________ +AliMixEventPool::AliMixEventPool(const AliMixEventPool &obj) : TNamed(obj), + fListOfEntryList(obj.fListOfEntryList), + fListOfEventCuts(obj.fListOfEventCuts), + fBinNumber(obj.fBinNumber), + fBufferSize(obj.fBufferSize), + fMixNumber(obj.fMixNumber) +{ + // + // Copy constructor + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 5, "->"); +} + +//_________________________________________________________________________________________________ +AliMixEventPool &AliMixEventPool::operator=(const AliMixEventPool &obj) +{ + // + // Assigned operator + // + if (&obj != this) { + TNamed::operator=(obj); + fListOfEntryList = obj.fListOfEntryList; + fListOfEventCuts = obj.fListOfEventCuts; + fBinNumber = obj.fBinNumber; + fBufferSize = obj.fBufferSize; + fMixNumber = obj.fMixNumber; + } + return *this; +} + + +//_________________________________________________________________________________________________ +AliMixEventPool::~AliMixEventPool() +{ + // + // Destructor + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 5, "->"); +} +//_________________________________________________________________________________________________ +void AliMixEventPool::AddCut(AliMixEventCutObj *cut) +{ + // + // Adds cut + // + if (cut && cut->IsValid()) fListOfEventCuts.Add(new AliMixEventCutObj(*cut)); +} +//_________________________________________________________________________________________________ +void AliMixEventPool::Print(const Option_t *option) const +{ + // + // Prints usefull information + // + TObjArrayIter next(&fListOfEventCuts); + // Int_t c=0; + AliMixEventCutObj *cut; + while ((cut = (AliMixEventCutObj *) next())) { + cut->Print(option); + } + AliDebug(AliLog::kDebug, Form("NumOfEntryList %d", fListOfEntryList.GetEntries())); + TEntryList *el; + for (Int_t i = 0; i < fListOfEntryList.GetEntries(); i++) { + el = (TEntryList *) fListOfEntryList.At(i); + AliDebug(AliLog::kDebug, Form("EntryList[%d] %lld", i, el->GetN())); + } +} +//_________________________________________________________________________________________________ +Int_t AliMixEventPool::Init() +{ + // + // Init event pool + // + AliDebug(AliLog::kDebug + 5, "<-"); + CreateEntryListsRecursivly(fListOfEventCuts.GetEntries() - 1); + fBinNumber++; + AliDebug(AliLog::kDebug, Form("fBinnumber = %d", fBinNumber)); + AddEntryList(); + AliDebug(AliLog::kDebug + 5, "->"); + return 0; +} + +//_________________________________________________________________________________________________ +void AliMixEventPool::CreateEntryListsRecursivly(Int_t index) +{ + // + // Helper function which create entrylist recursivly + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliMixEventCutObj *cut; + if (index >= 0) { + AliDebug(AliLog::kDebug + 1, Form("index = %d", index)); + cut = dynamic_cast(fListOfEventCuts.At(index)); + if (!cut) return; + cut->Reset(); + while (cut->HasMore()) { + cut->AddStep(); + CreateEntryListsRecursivly(index - 1); + if (cut->HasMore()) { + fBinNumber++; + AliDebug(AliLog::kDebug + 1, Form("fBinnumber = %d", fBinNumber)); + AddEntryList(); + // PrintCurrentCutIntervals(); + } + } + } + AliDebug(AliLog::kDebug + 5, "->"); +} + +//_________________________________________________________________________________________________ +TEntryList *AliMixEventPool::AddEntryList() +{ + // + // Adds endtry list + // + AliDebug(AliLog::kDebug + 5, "<-"); + TObjArrayIter next(&fListOfEventCuts); + AliMixEventCutObj *cut; + while ((cut = (AliMixEventCutObj *) next())) { + if (cut) cut->PrintCurrentInterval(); + } + TEntryList *el = new TEntryList; + fListOfEntryList.Add(el); + AliDebug(AliLog::kDebug + 1, Form("Number in Entry list -> %lld", el->GetN())); + AliDebug(AliLog::kDebug + 5, "->"); + return el; +} + +//_________________________________________________________________________________________________ +Bool_t AliMixEventPool::AddEntry(Long64_t entry, AliVEvent *ev) +{ + // + // Adds entry to correct entry list + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 5, Form("AddEntry(%lld,%p)", entry, (void *)ev)); + if (entry < 0) { + AliDebug(AliLog::kDebug, Form("Entry %lld was NOT added !!!", entry)); + return kFALSE; + } + Int_t idEntryList = -1; + TEntryList *el = FindEntryList(ev, idEntryList); + if (el) { + el->Enter(entry); + AliDebug(AliLog::kDebug, Form("Entry %lld was added with idEntryList %d !!!", entry, idEntryList)); + return kTRUE; + } + AliDebug(AliLog::kDebug, Form("Entry %lld was NOT added !!!", entry)); + AliDebug(AliLog::kDebug + 5, "->"); + return kFALSE; +} + +//_________________________________________________________________________________________________ +TEntryList *AliMixEventPool::FindEntryList(AliVEvent *ev, Int_t &idEntryList) +{ + // + // Find entrlist in list of entrlist + // + AliDebug(AliLog::kDebug + 5, "<-"); + Int_t num = fListOfEventCuts.GetEntriesFast(); + if (num < 1) return 0; + Int_t *indexes = new Int_t[num] ; + Int_t *lenght = new Int_t[num]; + Int_t i = 0; + TObjArrayIter next(&fListOfEventCuts); + AliMixEventCutObj *cut; + while ((cut = (AliMixEventCutObj *) next())) { + indexes[i] = cut->GetIndex(ev); + if (indexes[i] < 0) { + AliDebug(AliLog::kDebug, Form("idEntryList %d", -1)); + delete [] indexes; + delete [] lenght; + return 0; + } + lenght[i] = cut->GetNumberOfBins(); + AliDebug(AliLog::kDebug + 1, Form("indexes[%d] %d", i, indexes[i])); + i++; + } + idEntryList = 0; + SearchIndexRecursive(fListOfEventCuts.GetEntries() - 1, &indexes[0], &lenght[0], idEntryList); + AliDebug(AliLog::kDebug, Form("idEntryList %d", idEntryList - 1)); + // index which start with 0 (idEntryList-1) + delete [] indexes; + delete [] lenght; + AliDebug(AliLog::kDebug + 5, "->"); + return (TEntryList *) fListOfEntryList.At(idEntryList - 1); +} + +//_________________________________________________________________________________________________ +void AliMixEventPool::SearchIndexRecursive(Int_t num, Int_t *i, Int_t *d, Int_t &index) +{ + // + // Search for index of entrylist + // + AliDebug(AliLog::kDebug + 5, "<-"); + if (num > 0) { + index += (i[num] - 1) * d[num - 1]; + SearchIndexRecursive(num - 1, i, d, index); + } else { + index += i[num]; + } + AliDebug(AliLog::kDebug + 5, "->"); +} + +//_________________________________________________________________________________________________ +Bool_t AliMixEventPool::SetCutValuesFromBinIndex(Int_t index) +{ + // + // Sets cut value from bin index + // + + Int_t numCuts = fListOfEventCuts.GetEntriesFast(); + Int_t *lenght = new Int_t[numCuts]; + Int_t *indexes = new Int_t[numCuts]; + Long64_t timesNum = 1; + AliMixEventCutObj *cut; + Int_t i = 0, j = 0; + for (i = 0; i < numCuts; i++) { + cut = (AliMixEventCutObj *) fListOfEventCuts.At(i); + cut->Reset(); + lenght[i] = cut->GetNumberOfBins(); + indexes[i] = 1; + timesNum *= lenght[i]; + } + + if (index < 0 || index >= timesNum) { +// AliError(Form("index=%d is out of range !!!", index)); + delete [] lenght; + delete [] indexes; + return kFALSE; + } + + Long64_t indexNum = index; + for (i = 0; i < numCuts; i++) { + timesNum = 1; + for (j = 0; j < numCuts - i - 1; j++) timesNum *= lenght[j]; + indexNum /= timesNum; + indexes[numCuts - i - 1] = indexNum + 1; + index -= indexNum * timesNum; + indexNum = index; + } + + for (i = 0; i < numCuts; i++) { + cut = (AliMixEventCutObj *) fListOfEventCuts.At(i); + for (j = 0; j < indexes[i]; j++) cut->AddStep(); + cut->PrintCurrentInterval(); + + } + + for (i = 0; i < numCuts; i++) AliDebug(AliLog::kDebug, Form("indexes[%d]=%d", i, indexes[i])); + + delete [] lenght; + delete [] indexes; + + return kTRUE; +} diff --git a/EVENTMIX/AliMixEventPool.h b/EVENTMIX/AliMixEventPool.h new file mode 100644 index 00000000000..ab9d7c70a1e --- /dev/null +++ b/EVENTMIX/AliMixEventPool.h @@ -0,0 +1,64 @@ +// +// Class AliMixEventPool +// +// AliMixEventPool is used to find +// similar events +// +// author: +// Martin Vala (martin.vala@cern.ch) +// + +#ifndef ALIMIXEVENTPOOL_H +#define ALIMIXEVENTPOOL_H + +#include +#include + +class TEntryList; +class AliMixEventCutObj; +class AliVEvent; +class AliMixEventPool : public TNamed { +public: + AliMixEventPool(const char *name = "mixEventPool", const char *title = "Mix event pool"); + AliMixEventPool(const AliMixEventPool &obj); + AliMixEventPool &operator= (const AliMixEventPool &obj); + virtual ~AliMixEventPool(); + + // prints object info + virtual void Print(const Option_t *option = "") const; + + // inits correctly object + Int_t Init(); + + void CreateEntryListsRecursivly(Int_t index); + void SearchIndexRecursive(Int_t num, Int_t *i, Int_t *d, Int_t &index); + TEntryList *AddEntryList(); + + Bool_t AddEntry(Long64_t entry, AliVEvent *ev); + TEntryList *FindEntryList(AliVEvent *ev, Int_t &idEntryList); + + void AddCut(AliMixEventCutObj *cut); + + Bool_t NeedInit() { return (fListOfEntryList.GetEntries() == 0); } + TObjArray *GetListOfEntryLists() { return &fListOfEntryList; } + TObjArray *GetListOfEventCuts() { return &fListOfEventCuts; } + + Bool_t SetCutValuesFromBinIndex(Int_t index); + void SetBufferSize(Int_t buffer) { fBufferSize = buffer; } + void SetMixNumber(Int_t numMix) { fMixNumber = numMix; } + Int_t GetBufferSize() const { return fBufferSize; } + Int_t GetMixNumber() const { return fMixNumber; } + +private: + + TObjArray fListOfEntryList; // list of entry lists + TObjArray fListOfEventCuts; // list of entry lists + + Int_t fBinNumber; // bin number + Int_t fBufferSize; // buffer size + Int_t fMixNumber; // mixing number + + ClassDef(AliMixEventPool, 1) +}; + +#endif diff --git a/EVENTMIX/AliMixInfo.cxx b/EVENTMIX/AliMixInfo.cxx new file mode 100644 index 00000000000..9b579f104d9 --- /dev/null +++ b/EVENTMIX/AliMixInfo.cxx @@ -0,0 +1,463 @@ +// +// Class AliMixInfo +// +// AliMixInfo object contains information about one cut on for event mixing +// available for users containing mixing information +// +// authors: +// Martin Vala (martin.vala@cern.ch) +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliLog.h" + +#include "AliMixInfo.h" +#include "AliMixEventPool.h" +#include "AliMixEventCutObj.h" + +ClassImp(AliMixInfo) + +//_________________________________________________________________________________________________ +AliMixInfo::AliMixInfo(const char *name, const char *title) : + TNamed(name, title), + fHistogramList(0) +{ + // + // Default constructor. + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 5, "->"); +} +//_________________________________________________________________________________________________ +AliMixInfo::AliMixInfo(const AliMixInfo &obj) : + TNamed(obj), + fHistogramList(obj.fHistogramList) +{ + // + // Copy constructor. + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 5, "->"); +} +//_________________________________________________________________________________________________ +AliMixInfo::~AliMixInfo() +{ + // + // Destructor + // +} + +//_________________________________________________________________________________________________ +void AliMixInfo::CreateHistogram(AliMixInfo::EInfoHistorgramType type, Int_t nbins, Int_t min, Int_t max) +{ + // + // Create mix info histograms + // + if (!fHistogramList) { + fHistogramList = new TList; + fHistogramList->SetOwner(kTRUE); + } + TH1I *hist = (TH1I *) fHistogramList->FindObject(GetNameHistogramByType(type)); + if (hist) return; + hist = new TH1I(GetNameHistogramByType(type), GetTitleHistogramByType(type), nbins, min, max); + fHistogramList->Add(hist); +} + +//_________________________________________________________________________________________________ +void AliMixInfo::FillHistogram(AliMixInfo::EInfoHistorgramType type, Int_t value) +{ + // + // Create mix info histograms + // + if (type == kMixedEvents && value < 0) return; + if (!fHistogramList) { + AliError("fHistogramList is null"); + return; + } + TH1I *hist = (TH1I *) fHistogramList->FindObject(GetNameHistogramByType(type)); + if (hist) { + hist->Fill(value); + AliDebug(AliLog::kDebug, Form("%s was filled with %d sum is %.0f", GetNameHistogramByType(type), value, hist->GetBinContent(value))); + } else { + AliError(Form("Problem filling histogram %s", GetNameHistogramByType(type))); + } +} + +//_________________________________________________________________________________________________ +const char *AliMixInfo::GetNameHistogramByType(Int_t index) const +{ + // + // Retruns name of cut + // + switch (index) { + case kMainEvents: + return "hMainEvents"; + case kMixedEvents: + return "hMixedEvents"; + } + return ""; +} + +//_________________________________________________________________________________________________ +const char *AliMixInfo::GetTitleHistogramByType(Int_t index) const +{ + // + // Retruns name of cut + // + switch (index) { + case kMainEvents: + return "Main Events"; + case kMixedEvents: + return "Mixed Events"; + } + return ""; +} + +//_________________________________________________________________________________________________ +void AliMixInfo::Print(Option_t *option) const +{ + // + // Print Mix info + // + if (!fHistogramList) return; + if (option) + AliInfo(Form("Name %s with option is %s", GetName(), option)); + TIter next(fHistogramList); + TH1I *h = 0; + for (Int_t i = 0; i < fHistogramList->GetEntries(); i++) { + h = dynamic_cast(fHistogramList->At(i)); + if (h) { + h->Print(); + continue; + } + } +} +//_________________________________________________________________________________________________ +void AliMixInfo::Draw(Option_t *option) +{ + // + // Drwas mixi info canvas + // + if (!fHistogramList) return; + + // creating main canvas + TCanvas *cMain = new TCanvas("cMain", "Mixing Info", 500, 500); + if (!cMain) return; + cMain->Divide(1, 2, 0.001, 0.001); + cMain->cd(1); +// TVirtualPad *upperPad = cMain->cd(1); +// upperPad->Divide(2,1); +// TVirtualPad *upperPad1 = gPad->cd(2); +// upperPad1->Divide(1,2); +// upperPad1->cd(1); + TPavesText *text = new TPavesText(0.05, 0.05, 0.95, 0.95, 1); + text->SetName("mixInfoText"); + text->AddText("Help:"); + text->AddText("Move over histogram to see mix info for different bins"); + text->Draw(); + + // gets corresponding histograms + TH1I *hMain = GetHistogramByType(kMainEvents); + if (!hMain) { + AliError("hMain is null"); + return; + } + TH1I *hMix = GetHistogramByType(kMixedEvents); + if (!hMix) { + AliError("hMix is null"); + return; + } + + + TH2I *hMixInfo2D = 0; +// TH1I *hOK=0,*hBad=0; + AliMixEventPool *evPool = (AliMixEventPool *) GetEventPool("mixEventPool"); + if (evPool) { + Int_t mixNum = evPool->GetMixNumber(); + Int_t bufferSize = evPool->GetBufferSize(); +// hOK = (TH1I *) hMain->Clone(); +// hBad = (TH1I *) hMain->Clone(); + if (!hMixInfo2D) hMixInfo2D = new TH2I("hMixInfo2D", "hMixInfo2D", hMain->GetXaxis()->GetNbins() + 1, hMain->GetXaxis()->GetXmin() - 1, hMain->GetXaxis()->GetXmax(), 1, 0, 1); + for (Int_t iBin = 0; iBin < hMain->GetNbinsX() + 1; iBin++) { + if (!iBin) { + hMixInfo2D->SetBinContent(iBin + 1, 1, 1); + } else if (!hMain->GetBinContent(iBin) && !hMix->GetBinContent(iBin)) { + hMixInfo2D->SetBinContent(iBin + 1, 1, 2); + } else if (hMix->GetBinContent(iBin) == mixNum * bufferSize * hMain->GetBinContent(iBin)) { + hMixInfo2D->SetBinContent(iBin + 1, 1, 4); + } else { + hMixInfo2D->SetBinContent(iBin + 1, 1, 3); + } + } + } + + TStyle *style = gStyle; + Int_t cols[4] = { kYellow, kViolet, kRed, kGreen }; + style->SetPalette(4, cols); + cMain->cd(2); +// cMain->SetGrid(); + if (hMixInfo2D) { + hMixInfo2D->SetMaximum(4); + hMixInfo2D->SetStats(0); + hMixInfo2D->SetTitle(""); + hMixInfo2D->GetXaxis()->SetNdivisions(510); + hMixInfo2D->GetYaxis()->SetNdivisions(0); + } + + if (hMixInfo2D) hMixInfo2D->Draw(Form("COL %s", option)); +// +// TLegend *legend = new TLegend(0.55,0.65,0.76,0.82); +// legend->AddEntry(hOK,"OK","f"); +// legend->AddEntry(hBad,"NOT OK","f"); +// legend->Draw(); + + cMain->cd(2)->AddExec("dynamic", Form("AliMixInfo::DynamicExec((AliMixInfo*)0x%lx)", (ULong_t)this)); +} + +//_________________________________________________________________________________________________ +void AliMixInfo::DynamicExec(AliMixInfo *const mixInfo) +{ + // + // Function which is run when user move mouse over mix info + // + + if (!mixInfo) return; + + TObject *select = gPad->GetSelected(); + if (!select) return; + if (!select->InheritsFrom(TH2I::Class())) { + gPad->SetUniqueID(0); + return; + } + + TH2I *hSelected = (TH2I *) select; + gPad->GetCanvas()->FeedbackMode(kTRUE); + + //erase old position and draw a line at current position + Int_t uid = gPad->GetUniqueID(); +// int pxold = gPad->GetUniqueID(); + Int_t px = gPad->GetEventX(); +// Int_t py = gPad->GetEventY(); +// float uxmin = gPad->GetUxmin(); +// float uxmax = gPad->GetUxmax(); +// float uymin = gPad->GetUymin(); +// float uymax = gPad->GetUymax(); + // Int_t pxmin = gPad->XtoAbsPixel ( uxmin ); + // Int_t pxmax = gPad->XtoAbsPixel ( uxmax ); + // Int_t pymin = gPad->YtoAbsPixel ( uymin ); + // Int_t pymax = gPad->YtoAbsPixel ( uymax ); +// // if(pxold) gVirtualX->DrawLine(pxold,pymin,pxold,pymax); +// // else gVirtualX->DrawLine(px,pymin,px,pymax); +// gPad->SetUniqueID ( px ); + + Float_t upx = gPad->AbsPixeltoX(px); +// Float_t upy = gPad->AbsPixeltoY(py); + + Float_t x = gPad->PadtoX(upx); +// Float_t y = gPad->PadtoY ( upy ); + + Int_t binX = hSelected->GetXaxis()->FindBin(x) - 1; +// Int_t binY = hSelected->GetYaxis()->FindBin(y)-1; + + + + // return in case of same bin + if (uid == binX) return; +// Printf("%d %d",uid,binX); + + //create or set the new canvas cInfo + TPaveText *text = 0; + TVirtualPad *padsav = gPad; + TCanvas *cInfo = (TCanvas *) gROOT->GetListOfCanvases()->FindObject("cMain"); + if (cInfo) { + text = (TPaveText *)cInfo->GetPrimitive("mixInfoText"); + if (!text) { + text = new TPavesText(0.05, 0.05, 0.95, 0.95, 1); + } else { + text->DeleteText(); + } + + } else cInfo = new TCanvas("cInfo", "MixInfo Canvas", 510, 0, 350, 150); + + TVirtualPad *upperPad = cInfo->cd(1); +// TVirtualPad *upperPadL = upperPad->cd(1); +// TVirtualPad *upperPadR = upperPad->cd(2); +// TVirtualPad *upperPadR1 = upperPadR->cd(1); +// TVirtualPad *upperPadR2 = upperPadR->cd(2); +// TH1I *hMain = 0; +// TH1I *hMix = 0; + + +// mixInfo->Print(); +// return; + + // gets corresponding histograms + TH1I *hMain = mixInfo->GetHistogramByType(kMainEvents); + if (!hMain) { + Printf("hMain is null"); + return; + } + TH1I *hMix = mixInfo->GetHistogramByType(kMixedEvents); + if (!hMix) { + Printf("hMix is null"); + return; + } + + Double_t numMain = hMain->GetBinContent(binX); + Double_t numMix = hMix->GetBinContent(binX); + Int_t hist2DValue = (Int_t) hSelected->GetBinContent(binX + 1, 1); + +// Int_t mixNum = 1; + if (text) { + if (mixInfo) { + AliMixEventPool *evPool = (AliMixEventPool *) mixInfo->GetEventPool("mixEventPool"); + if (evPool) { +// mixNum = evPool->GetMixNumber(); + if (binX - 1 >= 0) { + if (!evPool->SetCutValuesFromBinIndex(binX - 1)) return; + } + text->SetName("mixInfoText"); + text->SetTextAlign(12); + text->SetToolTipText("Mixing Info about current binX"); + text->SetBorderSize(2); + text->AddText(Form("binX=%d", binX)); + text->AddText(Form("numMain=%.0f", numMain)); + text->AddText(Form("numMix=%.0f", numMix)); + text->AddText(Form("BINCONTENT=%d", hist2DValue)); + TObjArray *eventCuts = evPool->GetListOfEventCuts(); + if (eventCuts) { + TObjArrayIter next(eventCuts); + AliMixEventCutObj *cut; + while ((cut = (AliMixEventCutObj *) next())) { + if (hist2DValue > 1) text->AddText(Form("%s <%.2f,%.2f)", cut->GetCutName(), cut->GetCurrentMin(), cut->GetCurrentMax())); + else text->AddText(Form("%s ", cut->GetCutName())); + } + } + } + } + switch (hist2DValue) { + case 1 : + text->SetFillColor(kYellow); + break; + case 2 : + text->SetFillColor(kViolet); + break; + case 3 : + text->SetFillColor(kRed); + break; + case 4 : + text->SetFillColor(kGreen); + break; + default: + text->SetFillColor(kWhite); + break; + } + upperPad->cd(); + text->Draw(); +// upperPadR1->cd(); +// TH1D *proj1 = hSelected->ProjectionY("_xxx",binX); +// proj1->Draw(); +// upperPadR2->cd(); +// TH1D *proj2 = hSelected->ProjectionY("_xxx",binX); +// proj1->Draw(); + + } + cInfo->Update(); + padsav->cd(); + + gPad->SetUniqueID(binX); +} + +//_________________________________________________________________________________________________ +Long64_t AliMixInfo::Merge(TCollection *list) +{ + // + // Merge function + // + if (!list) return 0; + TIter nxfc(list); + AliMixInfo *mi = 0; + Long64_t counter = 0; + while ((mi = (AliMixInfo *) nxfc())) { + // Do not merge with ourself + if (mi == this) continue; + // Make sure that it is a AliMixInfo + if (!mi->InheritsFrom(AliMixInfo::Class())) { + Error("Merge", "attempt to add object of class: %s to a %s", mi->ClassName(), ClassName()); + return -1; + } + // Merge now + Add(mi); + counter++; + } + // Done + return counter; +} + +TH1I *AliMixInfo::GetHistogramByType(Int_t index) const +{ + // + // GetHistogramByType + // + return (TH1I *) fHistogramList->FindObject(GetNameHistogramByType(index)); +} + +//_________________________________________________________________________________________________ +void AliMixInfo::Add(AliMixInfo *mi) +{ + // + // adds AliMixInfo + // + +// AliInfo(Form("Adding %p", mi)); + if (!mi) return; + if (!fHistogramList) return; + TH1I *hMain = GetHistogramByType(kMainEvents); + if (!hMain) { + AliError("hMain is null"); + return; + } + TH1I *hMix = GetHistogramByType(kMixedEvents); + if (!hMix) { + AliError("hMain is null"); + return; + } + hMain->Add(mi->GetHistogramByType(kMainEvents)); + hMix->Add(mi->GetHistogramByType(kMixedEvents)); +} + +//_________________________________________________________________________________________________ +void AliMixInfo::SetEventPool(AliMixEventPool *evPool) +{ + // + // Sets event pool + // + if (!evPool) return; + + if (!fHistogramList) return; + + fHistogramList->Add(evPool); +} + +//_________________________________________________________________________________________________ +AliMixEventPool *AliMixInfo::GetEventPool(const char *name) +{ + // + // Gets event pool + // + if (!fHistogramList) return 0; + + return (AliMixEventPool *) fHistogramList->FindObject(name); +} + diff --git a/EVENTMIX/AliMixInfo.h b/EVENTMIX/AliMixInfo.h new file mode 100644 index 00000000000..098b1d28fcd --- /dev/null +++ b/EVENTMIX/AliMixInfo.h @@ -0,0 +1,58 @@ +// +// Class AliMixInfo +// +// AliMixInfo object contains information about one cut on for event mixing +// available for users containing mixing information +// +// authors: +// Martin Vala (martin.vala@cern.ch) +// + +#ifndef ALIMIXINFO_H +#define ALIMIXINFO_H + +#include +#include + +class AliMixEventPool; +class TH1I; +class TList; +class TCollection; +class AliMixInfo : public TNamed { +public: + enum EInfoHistorgramType { kMainEvents = 0, kMixedEvents = 1, kNumTypes }; + + AliMixInfo(const char *name = "mix", const char *title = "MixInfo"); + AliMixInfo(const AliMixInfo &obj); + virtual ~AliMixInfo(); + + void Reset(){;} // Not implemented + virtual void Print(Option_t *option = "") const; + virtual void Draw(Option_t *option = ""); + virtual Long64_t Merge(TCollection *list); + + void Add(AliMixInfo *mi); + + void SetOutputList(TList *const list) { fHistogramList = list; } + void CreateHistogram(EInfoHistorgramType type, Int_t nbins, Int_t min, Int_t max); + void FillHistogram(AliMixInfo::EInfoHistorgramType type, Int_t value); + const char *GetNameHistogramByType(Int_t index) const; + const char *GetTitleHistogramByType(Int_t index) const; + TH1I *GetHistogramByType(Int_t index) const; + + void SetEventPool(AliMixEventPool *evPool); + AliMixEventPool *GetEventPool(const char *name); + + + static void DynamicExec(AliMixInfo *const mixInfo); +private: + + TList *fHistogramList; // histogram list + + AliMixInfo &operator=(const AliMixInfo &) { return *this; } + + ClassDef(AliMixInfo, 1) + +}; + +#endif diff --git a/EVENTMIX/AliMixInputEventHandler.cxx b/EVENTMIX/AliMixInputEventHandler.cxx new file mode 100644 index 00000000000..d28b6784943 --- /dev/null +++ b/EVENTMIX/AliMixInputEventHandler.cxx @@ -0,0 +1,627 @@ +// +// Class AliMixEventInputHandler +// +// Mixing input handler prepare N events before UserExec +// TODO example +// author: +// Martin Vala (martin.vala@cern.ch) +// + +#include +#include +#include +#include + +#include "AliLog.h" +#include "AliAnalysisManager.h" +#include "AliInputEventHandler.h" + +#include "AliMixEventPool.h" +#include "AliMixInputEventHandler.h" +#include "AliMixInputHandlerInfo.h" + +#include "AliAnalysisTaskSE.h" + +ClassImp(AliMixInputEventHandler) + +//_____________________________________________________________________________ +AliMixInputEventHandler::AliMixInputEventHandler(const Int_t size, const Int_t mixNum): AliMultiInputEventHandler(size), + fMixTrees(), + fTreeMap(size > 0 ? size : 1), + fMixIntupHandlerInfoTmp(0), + fEntryCounter(0), + fEventPool(0), + fNumberMixed(0), + fMixNumber(mixNum), + fUseDefautProcess(kFALSE), + fDoMixExtra(kTRUE), + fDoMixIfNotEnoughEvents(kTRUE), + fDoMixEventGetEntryAuto(kTRUE), + fCurrentEntry(0), + fCurrentEntryMain(0), + fCurrentEntryMix(0), + fCurrentBinIndex(-1), + fOfflineTriggerMask(0), + fCurrentMixEntry(), + fCurrentEntryMainTree(0) +{ + // + // Default constructor. + // + AliDebug(AliLog::kDebug + 10, "<-"); + SetMixNumber(mixNum); + AliDebug(AliLog::kDebug + 10, "->"); +} + +//_____________________________________________________________________________ +AliMixInputEventHandler::~AliMixInputEventHandler() { + // + // Destructor + // + fMixTrees.Clear(); +} + +//_____________________________________________________________________________ +void AliMixInputEventHandler::SetInputHandlerForMixing(const AliInputEventHandler *const inHandler) +{ + // + // Create N (fBufferSize) copies of input handler + // + AliDebug(AliLog::kDebug + 5, Form("<-")); + fInputHandlers.Clear(); + AliDebug(AliLog::kDebug + 5, Form("Creating %d input event handlers ...", fBufferSize)); + for (Int_t i = 0; i < fBufferSize; i++) { + AliDebug(AliLog::kDebug + 5, Form("Adding %d ...", i)); + fInputHandlers.Add((AliInputEventHandler *) inHandler->Clone()); + } + + AliDebug(AliLog::kDebug + 5, Form("->")); +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::Init(TTree *tree, Option_t *opt) +{ + // + // Init(const char*path) is called for all mix input handlers. + // Create event pool if needed + // + AliDebug(AliLog::kDebug + 5, Form("<- %p %s", (void *)tree, opt)); + fAnalysisType = opt; + if (!tree) { + AliDebug(AliLog::kDebug + 5, Form("->")); + return kFALSE; + } + + if (!fDoMixIfNotEnoughEvents&&fDoMixExtra) { + fDoMixExtra = kFALSE; + AliWarning("fDoMixIfNotEnoughEvents=kFALSE -> setting fDoMixExtra=kFALSE"); + } + + // clears array of input handlers + fMixTrees.Delete(); + // create AliMixInputHandlerInfo + if (!fMixIntupHandlerInfoTmp) { + // loads first file TChain (tree) + tree->LoadTree(0); + fMixIntupHandlerInfoTmp = new AliMixInputHandlerInfo(tree->GetName()); + } + + AliInputEventHandler *ih = 0; + for (Int_t i = 0; i < fInputHandlers.GetEntries(); i++) { + ih = (AliInputEventHandler *) fInputHandlers.At(i); + ih->SetParentHandler(this); + } + + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::Notify() +{ + // + // Notify() is called for all mix input handlers + // + AliDebug(AliLog::kDebug + 5, Form("<-")); + if (fUseDefautProcess) { + AliDebug(AliLog::kDebug, Form("-> SKIPPED")); + return AliMultiInputEventHandler::Notify(); + } + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::Notify(const char *path) +{ + // + // Notify(const char*path) is called for all mix input handlers + // + AliDebug(AliLog::kDebug + 5, Form("<- %s", path)); + + Bool_t doPrepareEntry=kTRUE; + TString anType = fAnalysisType; + + // in case of local doPrepareEntry only first time + if (anType.CompareTo("proof")) doPrepareEntry = (fMixIntupHandlerInfoTmp->GetChain()->GetEntries()<=0); + + // adds current file + fMixIntupHandlerInfoTmp->AddTreeToChain(path); + Int_t lastIndex = fMixIntupHandlerInfoTmp->GetChain()->GetListOfFiles()->GetEntries(); + TChainElement *che = (TChainElement *)fMixIntupHandlerInfoTmp->GetChain()->GetListOfFiles()->At(lastIndex - 1); + AliMixInputHandlerInfo *mixIHI = 0; + for (Int_t i = 0; i < fInputHandlers.GetEntries(); i++) { + AliDebug(AliLog::kDebug + 5, Form("fInputHandlers[%d]", i)); + mixIHI = new AliMixInputHandlerInfo(fMixIntupHandlerInfoTmp->GetName(), fMixIntupHandlerInfoTmp->GetTitle()); + if (doPrepareEntry) mixIHI->PrepareEntry(che, -1, (AliInputEventHandler *)InputEventHandler(i), fAnalysisType); + AliDebug(AliLog::kDebug + 5, Form("chain[%d]->GetEntries() = %lld", i, mixIHI->GetChain()->GetEntries())); + fMixTrees.Add(mixIHI); + } + AliDebug(AliLog::kDebug + 5, Form("fEntryCounter=%lld", fEntryCounter)); + if (fEventPool && fEventPool->NeedInit()) + fEventPool->Init(); + if (fUseDefautProcess) { + AliDebug(AliLog::kDebug, Form("-> SKIPPED")); + return AliMultiInputEventHandler::Notify(path); + } + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::BeginEvent(Long64_t entry) +{ + // + // BeginEvent(Long64_t entry) is called for all mix input handlers + // + fCurrentEntryMainTree = entry; + + AliDebug(AliLog::kDebug + 5, Form("-> %lld", entry)); + if (fUseDefautProcess) { + AliDebug(AliLog::kDebug, Form("-> SKIPPED")); + AliMultiInputEventHandler::BeginEvent(entry);/* return GetEntry();*/ + } + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::GetEntry() +{ + // + // All mixed events are set + // + AliDebug(AliLog::kDebug + 5, Form("<-")); + + if (!fEventPool) { + MixStd(); + } + // if buffer size is higher then 1 + else if (fBufferSize > 1) { + MixBuffer(); + } + // if mix number is higher then 0 and buffer size is 1 + else if (fMixNumber > 0) { + MixEventsMoreTimesWithOneEvent(); + } else { + AliWarning("Not supported Mixing !!!"); + } + + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::MixStd() +{ + // + // Mix std - No event pool + // + AliDebug(AliLog::kDebug + 5, Form("<-")); + AliDebug(AliLog::kDebug + 1, "Mix method"); + // get correct handler + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + AliMultiInputEventHandler *mh = dynamic_cast(mgr->GetInputEventHandler()); + AliInputEventHandler *inEvHMain = 0; + if (mh) inEvHMain = dynamic_cast(mh->GetFirstInputEventHandler()); + else inEvHMain = dynamic_cast(mgr->GetInputEventHandler()); + if (!inEvHMain) return kFALSE; + + // check for PhysSelection + if (!IsEventCurrentSelected()) return kFALSE; + + // return in case of 0 entry in full chain + if (!fEntryCounter) { + AliDebug(AliLog::kDebug + 3, Form("-> fEntryCounter == 0")); + // runs UserExecMix for all tasks, if needed + UserExecMixAllTasks(fEntryCounter, 1, fEntryCounter, -1, 0); + return kTRUE; + } + // pre mix evetns + Int_t mixNum = fMixNumber; + if (fDoMixExtra) { + if (fEntryCounter <= 2 * fMixNumber) mixNum = 2 * fMixNumber + 2; + } + // start of + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ BEGIN SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + // reset mix number + fNumberMixed = 0; + AliMixInputHandlerInfo *mihi = 0; + Long64_t entryMix = 0, entryMixReal = 0; + Int_t counter = 0; + for (counter = 0; counter < mixNum; counter++) { + entryMix = fEntryCounter - 1 - counter ; + AliDebug(AliLog::kDebug + 5, Form("Handler[%d] entryMix %lld ", counter, entryMix)); + if (entryMix < 0) break; + entryMixReal = entryMix; + mihi = (AliMixInputHandlerInfo *) fMixTrees.At(0); + TChainElement *te = fMixIntupHandlerInfoTmp->GetEntryInTree(entryMix); + if (!te) { + AliError("te is null. this is error. tell to developer (#1)"); + } else { + if (fDoMixEventGetEntryAuto) mihi->PrepareEntry(te, entryMix, (AliInputEventHandler *)InputEventHandler(0), fAnalysisType); + // runs UserExecMix for all tasks + fNumberMixed++; + UserExecMixAllTasks(fEntryCounter, 1, fEntryCounter, entryMixReal, fNumberMixed); + InputEventHandler(0)->FinishEvent(); + } + } + AliDebug(AliLog::kDebug + 3, Form("fEntryCounter=%lld fMixEventNumber=%d", fEntryCounter, fNumberMixed)); + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + AliDebug(AliLog::kDebug + 5, Form("->")); + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::MixBuffer() +{ + // + // Mix in event buffer + // + AliDebug(AliLog::kDebug + 5, Form("<-")); + AliDebug(AliLog::kDebug + 1, "Mix method"); + // get correct handler + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + AliMultiInputEventHandler *mh = dynamic_cast(mgr->GetInputEventHandler()); + AliInputEventHandler *inEvHMain = 0; + if (mh) inEvHMain = dynamic_cast(mh->GetFirstInputEventHandler()); + else inEvHMain = dynamic_cast(mgr->GetInputEventHandler()); + if (!inEvHMain) return kFALSE; + + // check for PhysSelection + if (!IsEventCurrentSelected()) return kFALSE; + + fCurrentMixEntry.Reset(); + + // find out zero chain entries + Long64_t zeroChainEntries = fMixIntupHandlerInfoTmp->GetChain()->GetEntries() - inEvHMain->GetTree()->GetTree()->GetEntries(); + // fill entry + Long64_t currentMainEntry = inEvHMain->GetTree()->GetTree()->GetReadEntry() + zeroChainEntries; + // fills entry + if (fEventPool && inEvHMain) fEventPool->AddEntry(currentMainEntry, inEvHMain->GetEvent()); + // start of + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ BEGIN SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + // reset mix number + fNumberMixed = 0; + Long64_t elNum = 0; + TEntryList *el = 0; + Int_t idEntryList = -1; + if (fEventPool) el = fEventPool->FindEntryList(inEvHMain->GetEvent(), idEntryList); + // return in case of 0 entry in full chain + if (!fEntryCounter) { + AliDebug(AliLog::kDebug + 3, Form("-> fEntryCounter == 0")); + // runs UserExecMix for all tasks, if needed + if (el) UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, -1, 0); + else UserExecMixAllTasks(fEntryCounter, -1, currentMainEntry, -1, 0); + return kTRUE; + } + if (!el) { + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld SKIPPED (el null) +++++++++++++++++++", fEntryCounter)); + UserExecMixAllTasks(fEntryCounter, -1, fEntryCounter, -1, 0); + return kTRUE; + } else { + elNum = el->GetN(); + if (elNum < fBufferSize + 1) { + UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, -1, 0); + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld SKIPPED (%lld) LESS THEN BUFFER +++++++++++++++++++", fEntryCounter, elNum)); + return kTRUE; + } + } + + AliMixInputHandlerInfo *mihi = 0; + Long64_t entryMix = 0, entryMixReal = 0; + Int_t counter = 0; + AliInputEventHandler *eh = 0; + TObjArrayIter next(&fInputHandlers); + while ((eh = dynamic_cast(next()))) { + if (fEventPool && fEventPool->GetListOfEventCuts()->GetEntries() > 0) { + entryMix = -1; + if (elNum >= fBufferSize) { + Long64_t entryInEntryList = elNum - 2 - counter; + if (entryInEntryList < 0) break; + entryMix = el->GetEntry(entryInEntryList); + } + } + AliDebug(AliLog::kDebug + 5, Form("Handler[%d] entryMix %lld ", counter, entryMix)); + if (entryMix < 0) { + UserExecMixAllTasks(fEntryCounter, -1, currentMainEntry, -1, 0); + break; + } + entryMixReal = entryMix; + mihi = (AliMixInputHandlerInfo *) fMixTrees.At(counter); + TChainElement *te = fMixIntupHandlerInfoTmp->GetEntryInTree(entryMix); + if (!te) { + AliError("te is null. this is error. tell to developer (#1)"); + } else { + fCurrentMixEntry.Enter(entryMixReal); + AliDebug(AliLog::kDebug + 3, Form("Preparing InputEventHandler(%d)", counter)); + if (fDoMixEventGetEntryAuto) mihi->PrepareEntry(te, entryMix, (AliInputEventHandler *)InputEventHandler(counter), fAnalysisType); + fNumberMixed++; + } + counter++; + } + + if (fNumberMixed == fBufferSize) { + // runs UserExecMix for all tasks + UserExecMixAllTasks(fEntryCounter, idEntryList, fEntryCounter, entryMixReal, counter); + } + + AliDebug(AliLog::kDebug + 3, Form("fEntryCounter=%lld fMixEventNumber=%d", fEntryCounter, fNumberMixed)); + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + AliDebug(AliLog::kDebug + 5, Form("->")); + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::MixEventsMoreTimesWithOneEvent() +{ + // + // Mix in history with one event in buffer + // + AliDebug(AliLog::kDebug + 5, "<-"); + AliDebug(AliLog::kDebug + 1, "Mix method"); + // get correct handler + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + AliMultiInputEventHandler *mh = dynamic_cast(mgr->GetInputEventHandler()); + AliInputEventHandler *inEvHMain = 0; + if (mh) inEvHMain = dynamic_cast(mh->GetFirstInputEventHandler()); + else inEvHMain = dynamic_cast(mgr->GetInputEventHandler()); + if (!inEvHMain) return kFALSE; + + // check for PhysSelection + if (!IsEventCurrentSelected()) return kFALSE; + + fCurrentMixEntry.Reset(); + + // find out zero chain entries + Long64_t zeroChainEntries = fMixIntupHandlerInfoTmp->GetChain()->GetEntries() - inEvHMain->GetTree()->GetTree()->GetEntries(); + // fill entry + Long64_t currentMainEntry = inEvHMain->GetTree()->GetTree()->GetReadEntry() + zeroChainEntries; + if (fEventPool && inEvHMain) fEventPool->AddEntry(currentMainEntry, inEvHMain->GetEvent()); + // start of + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ BEGIN SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + // reset mix number + fNumberMixed = 0; + Long64_t elNum = 0; + Int_t idEntryList = -1; + TEntryList *el = 0; + if (fEventPool) el = fEventPool->FindEntryList(inEvHMain->GetEvent(), idEntryList); + // return in case of 0 entry in full chain + if (!fEntryCounter) { + // runs UserExecMix for all tasks, if needed + if (el && fDoMixIfNotEnoughEvents) { + UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, -1, 0); + } else { + idEntryList = -1; + UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, -1, 0); + } + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld SKIPPED (fEntryCounter=0, idEntryList=%d) +++++++++++++++++++", fEntryCounter, idEntryList)); + return kTRUE; + } + if (!el) { + if (fEventPool) { + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld SKIPPED (el null, idEntryList=%d) +++++++++++++++++++", fEntryCounter, idEntryList)); + UserExecMixAllTasks(fEntryCounter, -1, currentMainEntry, -1, 0); + return kTRUE; + } + } else { + elNum = el->GetN(); + if (elNum < fBufferSize + 1) { + if (fDoMixIfNotEnoughEvents) { + // include main event in to counter in this case (so idEntryList>0) + UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, -1, 0); + } else { + // dont include it in main event counter (idEntryList = -1) + idEntryList = -1; + UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, -1, 0); + } + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld SKIPPED [FIRST ENTRY in el] (elnum=%lld, idEntryList=%d) +++++++++++++++++++", fEntryCounter, elNum, idEntryList)); + return kTRUE; + } + if (!fDoMixIfNotEnoughEvents) { + if (elNum <= fMixNumber + 1) { + UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, -1, 0); + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld SKIPPED (%lld) NOT ENOUGH EVENTS TO MIX => NEED=%d +++++++++++++++++++", fEntryCounter, elNum, fMixNumber + 1)); + return kTRUE; + } + } + } + // pre mix evetns + Int_t mixNum = fMixNumber; + if (fDoMixExtra) { + if (elNum <= 2 * fMixNumber + 1) mixNum = elNum + 1; + } + AliMixInputHandlerInfo *mihi = 0; + Long64_t entryMix = 0, entryMixReal = 0; + Int_t counter = 0; + mihi = (AliMixInputHandlerInfo *) fMixTrees.At(0); + // fills num for main events + for (counter = 0; counter < mixNum; counter++) { + fCurrentMixEntry.Reset(); + Long64_t entryInEntryList = elNum - 2 - counter; + AliDebug(AliLog::kDebug + 3, Form("entryInEntryList=%lld", entryInEntryList)); + if (entryInEntryList < 0) break; + entryMix = el->GetEntry(entryInEntryList); + AliDebug(AliLog::kDebug + 3, Form("entryMix=%lld", entryMix)); + if (entryMix < 0) break; + entryMixReal = entryMix; + TChainElement *te = fMixIntupHandlerInfoTmp->GetEntryInTree(entryMix); + if (!te) { + AliError("te is null. this is error. tell to developer (#2)"); + } else { + fCurrentMixEntry.Enter(entryMixReal); + if (fDoMixEventGetEntryAuto) mihi->PrepareEntry(te, entryMix, (AliInputEventHandler *)InputEventHandler(0), fAnalysisType); + // runs UserExecMix for all tasks + fNumberMixed++; + UserExecMixAllTasks(fEntryCounter, idEntryList, currentMainEntry, entryMixReal, fNumberMixed); + InputEventHandler(0)->FinishEvent(); + } + } + AliDebug(AliLog::kDebug + 3, Form("fEntryCounter=%lld fMixEventNumber=%d", fEntryCounter, fNumberMixed)); + AliDebug(AliLog::kDebug + 3, Form("++++++++++++++ END SETUP EVENT %lld +++++++++++++++++++", fEntryCounter)); + AliDebug(AliLog::kDebug + 5, Form("->")); + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::MixEventsMoreTimesWithBuffer() +{ + // + // Mix more events in buffer with mixing with history + // + AliWarning("Not implemented"); + return kFALSE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::FinishEvent() +{ + // + // FinishEvent() is called for all mix input handlers + // + AliDebug(AliLog::kDebug + 5, Form("<-")); + AliMultiInputEventHandler::FinishEvent(); + fEntryCounter++; + AliDebug(AliLog::kDebug + 5, Form("->")); + return kTRUE; +} + +//_____________________________________________________________________________ +void AliMixInputEventHandler::AddInputEventHandler(AliVEventHandler *) +{ + // + // AddInputEventHandler will not be used + // + AliWarning("Function AddInputEventHandler is disabled for AliMixEventInputHandler !!!"); + AliWarning("Use AliMixEventInputHandler::SetInputHandlerForMixing instead. Exiting ..."); +} + +//_____________________________________________________________________________ +void AliMixInputEventHandler::UserExecMixAllTasks(Long64_t entryCounter, Int_t idEntryList, Long64_t entryMainReal, Long64_t entryMixReal, Int_t numMixed) +{ + // + // Execute all task and sets mixing parameters + // + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + AliAnalysisTaskSE *mixTask = 0; + TObjArrayIter next(mgr->GetTasks()); + while ((mixTask = dynamic_cast(next()))) { + AliDebug(AliLog::kDebug, Form("%s %lld %d [%lld,%lld] %d", mixTask->GetName(), entryCounter, numMixed, entryMainReal, entryMixReal, idEntryList)); + fCurrentEntry = entryCounter; + fCurrentEntryMain = entryMainReal; + fCurrentEntryMix = entryMixReal; + fCurrentBinIndex = idEntryList; + if (entryMixReal >= 0) mixTask->UserExecMix(""); + } +} + +//_____________________________________________________________________________ +void AliMixInputEventHandler::SetMixNumber(const Int_t mixNum) +{ + // + // Sets mix number + // + if (fMixNumber > 1 && fBufferSize > 1) { + AliWarning("Sleeping 10 sec to show Warning Message ..."); + AliWarning("========================================================================================="); + AliWarning(Form("BufferSize(%d) higher > 1 and fMixNumber(%d) > 1, which is not supported", fBufferSize, mixNum)); + AliWarning(""); + AliWarning("\tBufferSize will be set to 1"); + AliWarning(""); + AliWarning("Hints:"); + AliWarning(""); + AliWarning("\t1.If you want to use buffer do:"); + AliWarning(Form("\t\tAliMixInputEventHandler *mixH = new AliMixInputEventHandler(%d,1)", fBufferSize)); + AliWarning(""); + AliWarning("\t2.If you want to use mix more time with buffer size 1, then do:"); + AliWarning(Form("\t\tAliMixInputEventHandler *mixH = new AliMixInputEventHandler(1,%d)", mixNum)); + AliWarning(""); + AliWarning("========================================================================================="); + gSystem->Sleep(10000); + fBufferSize = 1; + } + fMixNumber = mixNum; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::IsEventCurrentSelected() +{ + // + // Check if event is selected by Physics selection + // + + AliDebug(AliLog::kDebug + 5, Form("<-")); + Bool_t isSelected = kTRUE; + if (fOfflineTriggerMask && fOfflineTriggerMask != AliVEvent::kAny) { + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + AliMultiInputEventHandler *mh = dynamic_cast(mgr->GetInputEventHandler()); + if (mh) { + AliInputEventHandler *ih = mh->GetFirstInputEventHandler(); + isSelected = fOfflineTriggerMask & ih->IsEventSelected(); + } + } + AliDebug(AliLog::kDebug + 1, Form("isSelected=%d", isSelected)); + AliDebug(AliLog::kDebug + 5, Form("-> %d", isSelected)); + return isSelected; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::GetEntryMainEvent() { + // + // Calling GetEntry for main event in input handler (Should be used in UserExecMix() only) + // + + AliInputEventHandler *ih = ((AliMultiInputEventHandler *)ParentHandler())->GetFirstInputEventHandler(); + ih->GetTree()->GetEntry(fCurrentEntryMainTree); + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliMixInputEventHandler::GetEntryMixedEvent(Int_t id) { + // + // Calling GetEntry for mixed event in input handler with id + // (Should be used in UserExecMix() only) + // + + AliMixInputHandlerInfo *mihi = (AliMixInputHandlerInfo *) fMixTrees.At(id); + + Long64_t entryMix = fCurrentMixEntry.GetEntry(fCurrentMixEntry.GetN()-id-1); + if(entryMix<0) { + AliError(Form("GetEntryMixedEvent(%d) => entryMix<0 [1]",id)); + return kFALSE; + } + TChainElement *te = fMixIntupHandlerInfoTmp->GetEntryInTree(entryMix); + if (!te) { + AliError("te is null. this is error. tell to developer (#3)"); + return kFALSE; + } + if(entryMix<0) { + AliError(Form("GetEntryMixedEvent(%d) => entryMix<0 [2]",id)); + return kFALSE; + } + mihi->PrepareEntry(te, entryMix, (AliInputEventHandler *)InputEventHandler(id), fAnalysisType); + + return kTRUE; +} diff --git a/EVENTMIX/AliMixInputEventHandler.h b/EVENTMIX/AliMixInputEventHandler.h new file mode 100644 index 00000000000..6eabd177ea1 --- /dev/null +++ b/EVENTMIX/AliMixInputEventHandler.h @@ -0,0 +1,116 @@ +// +// Class AliMixEventInputHandler +// +// Mixing input handler prepare N events before UserExec +// TODO example +// author: +// Martin Vala (martin.vala@cern.ch) +// + +#ifndef ALIMIXINPUTEVENTHANDLER_H +#define ALIMIXINPUTEVENTHANDLER_H + +#include +#include +#include + +#include + +#include "AliMultiInputEventHandler.h" + +class TChain; +class TChainElement; +class AliMixEventPool; +class AliMixInputHandlerInfo; +class AliInputEventHandler; +class AliMixInputEventHandler : public AliMultiInputEventHandler { + +public: + AliMixInputEventHandler(const Int_t size = 1, const Int_t mixNum = 1); + virtual ~AliMixInputEventHandler(); + // From the interface + virtual Bool_t Init(Option_t *opt) { return AliMultiInputEventHandler::Init(opt); } + virtual Bool_t Init(TTree *tree, Option_t *opt); + virtual Bool_t Notify(); + virtual Bool_t Notify(const char *path); + virtual Bool_t BeginEvent(Long64_t entry); + virtual Bool_t GetEntry(); + virtual Bool_t FinishEvent(); + + // removing default impementation + virtual void AddInputEventHandler(AliVEventHandler */*inHandler*/); + + void SetInputHandlerForMixing(const AliInputEventHandler *const inHandler); + void SetEventPool(AliMixEventPool *const evPool) { fEventPool = evPool; } + + AliMixEventPool *GetEventPool() const { return fEventPool; } + Int_t BufferSize() const { return fBufferSize; } + Int_t NumberMixedTimes() const { return fNumberMixed; } + Int_t MixNumber() const { return fMixNumber; } + Long64_t EntryAll() const { return fEntryCounter; } + void UseDefaultProcess(Bool_t b = kTRUE) { fUseDefautProcess = b; } + void DoMixExtra(Bool_t b = kTRUE) { fDoMixExtra = b; } + void DoMixIfNotEnoughEvents(Bool_t b = kTRUE) { fDoMixIfNotEnoughEvents = b; } + void SetMixNumber(const Int_t mixNum); + + void SetCurrentBinIndex(Int_t const index) { fCurrentBinIndex = index; } + void SetCurrentEntry(Long64_t const entry) { fCurrentEntry = entry ; } + void SetCurrentEntryMain(Long64_t const entry) { fCurrentEntryMain = entry ; } + void SetCurrentEntryMix(Long64_t const entry) { fCurrentEntryMix = entry ; } + void SetNumberMixed(Int_t const index) { fNumberMixed = index; } + + Int_t CurrentBinIndex() const { return fCurrentBinIndex; } + Long64_t CurrentEntry() const { return fCurrentEntry; } + Long64_t CurrentEntryMain() const { return fCurrentEntryMain; } + Long64_t CurrentEntryMix() const { return fCurrentEntryMix; } + Int_t NumberMixed() const { return fNumberMixed; } + + void SelectCollisionCandidates(UInt_t offlineTriggerMask = AliVEvent::kMB) {fOfflineTriggerMask = offlineTriggerMask;} + Bool_t IsEventCurrentSelected(); + Bool_t IsMixingIfNotEnoughEvents() { return fDoMixIfNotEnoughEvents;} + + void DoMixEventGetEntryAuto(Bool_t doAuto=kTRUE) { fDoMixEventGetEntryAuto = doAuto; } + + Bool_t GetEntryMainEvent(); + Bool_t GetEntryMixedEvent(Int_t idHandler=0); +protected: + + TObjArray fMixTrees; // buffer of input handlers + TArrayI fTreeMap; // tree map + AliMixInputHandlerInfo *fMixIntupHandlerInfoTmp;//! mix input handler info full chain + Long64_t fEntryCounter; // entry counter + AliMixEventPool *fEventPool; // event pool + Int_t fNumberMixed; // number of mixed events with current event + Int_t fMixNumber; // user's mix number request + +private: + + Bool_t fUseDefautProcess; // use default process + Bool_t fDoMixExtra; // mix extra events to get enough combinations + Bool_t fDoMixIfNotEnoughEvents;// mix events if they don't have enough events to mix + Bool_t fDoMixEventGetEntryAuto;// flag for preparing mixed events automatically (default on) + + // mixing info + Long64_t fCurrentEntry; //! current entry number (adds 1 for every event processed on each worker) + Long64_t fCurrentEntryMain; //! current entry in chain of processed files + Long64_t fCurrentEntryMix; //! current mixed entry in chain of processed files + Int_t fCurrentBinIndex; //! current bin index + ULong64_t fOfflineTriggerMask; // Task processes collision candidates only + + TEntryList fCurrentMixEntry; //! array of mix entries currently used (user should touch) + Long64_t fCurrentEntryMainTree; //! current entry in current tree (main event) + + virtual Bool_t MixStd(); + virtual Bool_t MixBuffer(); + virtual Bool_t MixEventsMoreTimesWithOneEvent(); + virtual Bool_t MixEventsMoreTimesWithBuffer(); + + void UserExecMixAllTasks(Long64_t entryCounter, Int_t idEntryList, Long64_t entryMainReal, Long64_t entryMixReal, Int_t numMixed); + + AliMixInputEventHandler(const AliMixInputEventHandler &handler); + AliMixInputEventHandler &operator=(const AliMixInputEventHandler &handler); + + ClassDef(AliMixInputEventHandler, 5) +}; + +#endif diff --git a/EVENTMIX/AliMixInputHandlerInfo.cxx b/EVENTMIX/AliMixInputHandlerInfo.cxx new file mode 100644 index 00000000000..bcd62daf64c --- /dev/null +++ b/EVENTMIX/AliMixInputHandlerInfo.cxx @@ -0,0 +1,182 @@ +// +// Class AliMixInputHandlerInfo +// +// AliMixInputHandlerInfo is interface with mixed +// input handlers +// +// author: +// Martin Vala (martin.vala@cern.ch) +// +#include +#include +#include +#include + +#include "AliLog.h" +#include "AliInputEventHandler.h" + +#include "AliMixInputHandlerInfo.h" + +ClassImp(AliMixInputHandlerInfo) + +//_____________________________________________________________________________ +AliMixInputHandlerInfo::AliMixInputHandlerInfo(const char *name, const char *title): TNamed(name, title), + fChain(0), + fChainEntriesArray(), + fZeroEntryNumber(0), + fNeedNotify(kFALSE) +{ + // + // Default constructor. + // +} +//_____________________________________________________________________________ +AliMixInputHandlerInfo::~AliMixInputHandlerInfo() +{ + // + // Destructor + // + if (fChain) delete fChain; +} + +//_____________________________________________________________________________ +TChain *AliMixInputHandlerInfo::GetChain() +{ + // + // Returns curren chain. When chain is null it will create it + // + if (!fChain) fChain = new TChain(GetName()); + return fChain; +} + +//_____________________________________________________________________________ +void AliMixInputHandlerInfo::AddChain(TChain *chain) +{ + // + // Add chain + // + AliDebug(AliLog::kDebug + 5, "<-"); + if (!chain) return; + if (fChain) delete fChain; + fChain = new TChain(GetName()); + fChain->Add(chain); + AliDebug(AliLog::kDebug + 5, "->"); +} + +//_____________________________________________________________________________ +void AliMixInputHandlerInfo::AddTreeToChain(const char *path) +{ + // + // Adds tree in to chain + // + AliDebug(AliLog::kDebug + 5, Form("<- %s", path)); + GetChain(); + fChain->AddFile(path); + AliDebug(AliLog::kDebug + 3, Form("Num files in fChain %d", fChain->GetListOfFiles()->GetEntries())); + Long64_t sumTree = fZeroEntryNumber; + for (Int_t i = 0; i < fChainEntriesArray.GetSize() ; i++) sumTree += fChainEntriesArray.At(i); + fChain->LoadTree(sumTree); + Int_t lastIndex = fChain->GetListOfFiles()->GetEntries(); + AliDebug(AliLog::kDebug + 3, Form("Num files in fChain %d", lastIndex)); + fChainEntriesArray.Set(lastIndex); + AliDebug(AliLog::kDebug + 3, Form("Adding %lld to id %d", fChain->GetTree()->GetEntries(), lastIndex - 1)); + fChainEntriesArray.AddAt((Int_t)fChain->GetTree()->GetEntries(), (Int_t)lastIndex - 1); + AliDebug(AliLog::kDebug + 5, Form("-> %s", path)); +} + +//_____________________________________________________________________________ +TChainElement *AliMixInputHandlerInfo::GetEntryInTree(Long64_t &entry) +{ + // + // Get entry in current tree + // + AliDebug(AliLog::kDebug + 5, Form("<- %lld", entry)); + fZeroEntryNumber = 0; + if (entry < fZeroEntryNumber) { + AliError(Form("Num %lld is less then ZeroEntryNumber(%lld)", entry, fZeroEntryNumber)); + entry = -1; + AliDebug(AliLog::kDebug + 5, "->"); + return 0; + } + Long64_t sumTree = fZeroEntryNumber; + for (Int_t i = 0; i < fChainEntriesArray.GetSize() ; i++) { + sumTree += fChainEntriesArray.At(i); + if (sumTree > entry) { + sumTree = entry - sumTree + fChainEntriesArray.At(i); + AliDebug(AliLog::kDebug + 1, Form("Entry in current tree num is %lld with i=%d", sumTree, i)); + entry = sumTree; + AliDebug(AliLog::kDebug + 5, "->"); + return (TChainElement *) fChain->GetListOfFiles()->At(i); + } + } + entry = -1; + AliDebug(AliLog::kDebug + 5, "->"); + return 0; +} + +//_____________________________________________________________________________ +void AliMixInputHandlerInfo::PrepareEntry(TChainElement *te, Long64_t entry, AliInputEventHandler *eh, Option_t *opt) +{ + // + // Prepare Entry + // + AliDebug(AliLog::kDebug + 5, Form("<- %lld", entry)); + if (!te) { + AliDebug(AliLog::kDebug + 5, "-> te is null"); + return; + } + if (entry < 0) { + AliDebug(AliLog::kDebug, Form("We are creating new chain from file %s ...", te->GetTitle())); + if (!fChain) { + fChain = new TChain(te->GetName()); + fChain->AddFile(te->GetTitle()); + fChain->GetEntry(0); + eh->Init(opt); + eh->Init(fChain->GetTree(), opt); + } + fNeedNotify = kTRUE; + AliDebug(AliLog::kDebug + 5, "->"); + return; + } + if (fChain) { + AliDebug(AliLog::kDebug, Form("Filename is %s", fChain->GetTree()->GetCurrentFile()->GetName())); + TString fn = fChain->GetTree()->GetCurrentFile()->GetName(); + if (fn.CompareTo(te->GetTitle())) { + AliDebug(AliLog::kDebug, Form("Filename %s is NOT same ...", te->GetTitle())); + AliDebug(AliLog::kDebug, Form("We are changing to file %s ...", te->GetTitle())); + // change file + delete fChain; + fChain = new TChain(te->GetName()); + fChain->AddFile(te->GetTitle()); + fChain->GetEntry(0); + eh->Init(opt); + eh->Init(fChain->GetTree(), opt); + eh->Notify(te->GetTitle()); + fChain->GetEntry(entry); + eh->BeginEvent(entry); + fNeedNotify = kFALSE; + } else { + AliDebug(AliLog::kDebug, Form("We are reusing file %s ...", te->GetTitle())); + if (fNeedNotify) eh->Notify(te->GetTitle()); + fNeedNotify = kFALSE; + AliDebug(AliLog::kDebug, Form("Entry is %lld fChain->GetEntries %lld ...", entry, fChain->GetEntries())); + fChain->GetEntry(entry); + eh->BeginEvent(entry); + // file is in tree fChain already + } + } + AliDebug(AliLog::kDebug, Form("We are USING file %s ...", te->GetTitle())); + AliDebug(AliLog::kDebug, Form("We are USING file from fChain->GetTree() %s ...", fChain->GetTree()->GetCurrentFile()->GetName())); + // here we have correct chain with 1 tree only + AliDebug(AliLog::kDebug + 5, "->"); +} + +//_____________________________________________________________________________ +Long64_t AliMixInputHandlerInfo::GetEntries() +{ + // + // Returns number of entries + // + if (fChain) return fChain->GetEntries(); + return -1; +} diff --git a/EVENTMIX/AliMixInputHandlerInfo.h b/EVENTMIX/AliMixInputHandlerInfo.h new file mode 100644 index 00000000000..13e2d66a209 --- /dev/null +++ b/EVENTMIX/AliMixInputHandlerInfo.h @@ -0,0 +1,48 @@ +// +// Class AliMixInputHandlerInfo +// +// AliMixInputHandlerInfo is interface with mixed +// input handlers +// +// author: +// Martin Vala (martin.vala@cern.ch) +// +#ifndef ALIMIXINPUTHANDLERINFO_H +#define ALIMIXINPUTHANDLERINFO_H +#include +#include + +class TTree; +class TChain; +class TChainElement; +class AliInputEventHandler; +class AliMixInputHandlerInfo : public TNamed { + +public: + AliMixInputHandlerInfo(const char *name = "defautlTree", const char *title = "Defautl tree"); + virtual ~AliMixInputHandlerInfo(); + TChain *GetChain(); + + void AddChain(TChain *chain); +// void AddTreeToChain(TTree *tree); + void AddTreeToChain(const char *path); + + void PrepareEntry(TChainElement *te, Long64_t entry, AliInputEventHandler *eh, Option_t *opt); + + void SetZeroEntryNumber(Long64_t num) { fZeroEntryNumber = num; } + TChainElement *GetEntryInTree(Long64_t &entry); + Long64_t GetEntries(); + +private: + TChain *fChain; // current chain + TArrayI fChainEntriesArray; // array of entries of every chaing + Long64_t fZeroEntryNumber; // zero entry number (will be used when we will delete not needed chains) + Bool_t fNeedNotify; // flag if Notify is needed for current input handler + + AliMixInputHandlerInfo(const AliMixInputHandlerInfo &handler); + AliMixInputHandlerInfo &operator=(const AliMixInputHandlerInfo &handler); + + ClassDef(AliMixInputHandlerInfo, 1); // Mix Input Handler info +}; + +#endif // ALIMIXINPUTHANDLERINFO_H diff --git a/EVENTMIX/CMakeLists.txt b/EVENTMIX/CMakeLists.txt new file mode 100644 index 00000000000..9d074140a7f --- /dev/null +++ b/EVENTMIX/CMakeLists.txt @@ -0,0 +1,73 @@ +# ************************************************************************** +# * Copyright(c) 1998-2014, 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. * +# ************************************************************************** + +# Module +set(MODULE EventMixing) + +# Module include folder +include_directories(${AliRoot_SOURCE_DIR}/ANALYSIS/${MODULE}) + +# Additional include folders in alphabetical order except ROOT +include_directories(${ROOT_INCLUDE_DIRS} + ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSIS + ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSISalice + ${AliRoot_SOURCE_DIR}/STEER/AOD + ${AliRoot_SOURCE_DIR}/STEER/ESD + ${AliRoot_SOURCE_DIR}/STEER/STEERBase + ) + +# Sources +set(SRCS + AliAnalysisTaskMixInfo.cxx + AliMixEventCutObj.cxx + AliMixEventPool.cxx + AliMixInfo.cxx + AliMixInputEventHandler.cxx + AliMixInputHandlerInfo.cxx + ) + +# Headers from sources +string(REPLACE ".cxx" ".h" HDRS "${SRCS}") + +# Generate the dictionary +# It will create G_ARG1.cxx and G_ARG1.h / ARG1 = function first argument +get_directory_property(incdirs INCLUDE_DIRECTORIES) +generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}") + +# Generate the ROOT map +# Dependecies +set(LIBDEPS ANALYSIS ANALYSISalice AOD ESD STEERBase Core Gpad Hist RIO Tree) +generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h") + +# Add a library to the project using the specified source files +add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx) +target_link_libraries(${MODULE} ANALYSIS ANALYSISalice AOD ESD STEERBase Core Gpad Hist RIO Tree) + +# Additional compilation flags +set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "") + +# Linking the library +target_link_libraries(${MODULE} ${LIBDEPS}) + +# System dependent: Modify the way the library is build +if(${CMAKE_SYSTEM} MATCHES Darwin) + set_target_properties(${MODULE} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") +endif(${CMAKE_SYSTEM} MATCHES Darwin) + +# Installation +install(TARGETS ${MODULE} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +install(FILES ${HDRS} DESTINATION include) \ No newline at end of file diff --git a/EVENTMIX/EventMixingLinkDef.h b/EVENTMIX/EventMixingLinkDef.h new file mode 100644 index 00000000000..757bff1e8e8 --- /dev/null +++ b/EVENTMIX/EventMixingLinkDef.h @@ -0,0 +1,11 @@ +#ifdef __CINT__ + +#pragma link C++ class AliMixEventCutObj+; +#pragma link C++ class AliMixEventPool+; + +#pragma link C++ class AliMixInfo+; +#pragma link C++ class AliMixInputHandlerInfo+; +#pragma link C++ class AliMixInputEventHandler+; +#pragma link C++ class AliAnalysisTaskMixInfo+; + +#endif diff --git a/EVENTMIX/macros/ShowMixingInfo.C b/EVENTMIX/macros/ShowMixingInfo.C new file mode 100644 index 00000000000..3733b235699 --- /dev/null +++ b/EVENTMIX/macros/ShowMixingInfo.C @@ -0,0 +1,36 @@ +Int_t ShowMixingInfo(TString filename="MixInfo.root") { + + Int_t num=0; + + if (gSystem->Load("libTree") < 0) {num++; return num;} + if (gSystem->Load("libGeom") < 0) {num++; return num;} + if (gSystem->Load("libVMC") < 0) {num++; return num;} + if (gSystem->Load("libMinuit") < 0) {num++; return num;} + if (gSystem->Load("libPhysics") < 0) {num++; return num;} + if (gSystem->Load("libSTEERBase") < 0) {num++; return num;} + if (gSystem->Load("libESD") < 0) {num++; return num;} + if (gSystem->Load("libAOD") < 0) {num++; return num;} + if (gSystem->Load("libANALYSIS") < 0) {num++; return num;} + if (gSystem->Load("libOADB") < 0) {num++; return num;} + if (gSystem->Load("libANALYSISalice") < 0) {num++; return num;} + if (gSystem->Load("libEventMixing") < 0) {num++; return num;} + + TFile *f = TFile::Open(filename.Data(),"READ"); + + + TList *fOutputList = (TList*)f->Get("cMixInfoList"); + if (!fOutputList) { + AliError("fOutputList not available"); + return; + } + fOutputList->Print(); + fMixInfo = (AliMixInfo *) fOutputList->FindObject("mixInfo"); + if (fMixInfo) { + fMixInfo->Draw("HIST"); + AliMixEventPool *evPool = (AliMixEventPool *) fMixInfo->GetEventPool("mixEventPool"); + if (evPool) evPool->Print(); + } + + + return 0; +} diff --git a/TENDER/Tender/AliTender.cxx b/TENDER/Tender/AliTender.cxx new file mode 100644 index 00000000000..0a6a0c8eece --- /dev/null +++ b/TENDER/Tender/AliTender.cxx @@ -0,0 +1,178 @@ +/************************************************************************** + * 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$ */ + +#include +#include + +#include "AliTender.h" +#include "AliTenderSupply.h" +#include "AliAnalysisManager.h" +#include "AliCDBManager.h" +#include "AliESDEvent.h" +#include "AliESDInputHandler.h" +#include "AliLog.h" + + +ClassImp(AliTender) + +//______________________________________________________________________________ +AliTender::AliTender(): + AliAnalysisTaskSE(), + fRun(0), + fRunChanged(kFALSE), + fCDBkey(0), + fDefaultStorage(), + fCDB(NULL), + fESDhandler(NULL), + fESD(NULL), + fSupplies(NULL), + fCDBSettings(NULL) +{ +// Dummy constructor +} + +//______________________________________________________________________________ +AliTender::AliTender(const char* name): + AliAnalysisTaskSE(name), + fRun(0), + fRunChanged(kFALSE), + fCDBkey(0), + fDefaultStorage(), + fCDB(NULL), + fESDhandler(NULL), + fESD(NULL), + fSupplies(NULL), + fCDBSettings(NULL) +{ +// Default constructor + DefineOutput(1, AliESDEvent::Class()); +} + +//______________________________________________________________________________ +AliTender::~AliTender() +{ +// Destructor + if (fSupplies) { + fSupplies->Delete(); + delete fSupplies; + } +} + +//______________________________________________________________________________ +void AliTender::AddSupply(AliTenderSupply *supply) +{ +// Addition of supplies. + if (!fSupplies) fSupplies = new TObjArray(); + if (fSupplies->FindObject(supply)) { + Error("AddSupply", "Tender supply %s already connected.", supply->GetName()); + return; + } + fSupplies->Add(supply); + supply->SetTender(this); +} + +//______________________________________________________________________________ +void AliTender::ConnectInputData(Option_t* option) +{ +// Connect the input data, create CDB manager. + if (fDebug > 1) Printf("AliTender::ConnectInputData()\n"); + + if (!fESDhandler) { + AliAnalysisTaskSE::ConnectInputData(option); + fESDhandler = dynamic_cast(fInputHandler); + } + + if (fESDhandler) { + fESD = fESDhandler->GetEvent(); + } else { + AliFatal("No ESD input event handler connected") ; + } + // Create CDB manager + if (!fDefaultStorage.Length()) AliFatal("Default CDB storage not set."); + fCDB = AliCDBManager::Instance(); + // SetDefault storage. Specific storages must be set by AliTenderSupply::Init() + fCDB->SetDefaultStorage(fDefaultStorage); + Int_t run = AliAnalysisManager::GetAnalysisManager()->GetRunFromPath(); + // Unlock CDB + fCDBkey = fCDB->SetLock(kFALSE, fCDBkey); + if (!run) { + AliWarning("AliTaskCDBconnect: Could not set run from path"); + } else { + fRun = run; + fRunChanged = kTRUE; + printf("AliTender: #### Setting run to: %d\n", fRun); + fCDB->SetRun(fRun); + } + TIter next(fSupplies); + AliTenderSupply *supply; + while ((supply=(AliTenderSupply*)next())) supply->Init(); + // Lock CDB + fCDBkey = fCDB->SetLock(kTRUE, fCDBkey); +} + +//______________________________________________________________________________ +void AliTender::UserCreateOutputObjects() +{ +// Nothing for the moment, but we may need ESD event replication here. + if (fDebug > 1) Printf("AliTender::CreateOutputObjects()\n"); + fESDhandler = dynamic_cast(fInputHandler); + if (fESDhandler && TObject::TestBit(kCheckEventSelection)) { + fESDhandler->SetUserCallSelectionMask(kTRUE); + Info("UserCreateOutputObjects","The TENDER will check the event selection. Make sure you add the tender as FIRST wagon!"); + } +} + +//______________________________________________________________________________ +void AliTender::UserExec(Option_t* option) +{ +// +// Execute all supplied analysis of one event. Notify run change via RunChanged(). + if (fDebug > 1) { + Long64_t entry = fESDhandler->GetReadEntry(); + Printf("AliTender::Exec() %s ==> processing event %lld\n", fESDhandler->GetTree()->GetCurrentFile()->GetName(),entry); + } + fESD = fESDhandler->GetEvent(); + +// Call the user analysis + // Unlock CDB + fCDBkey = fCDB->SetLock(kFALSE, fCDBkey); + // Intercept when the run number changed + if (fRun != fESD->GetRunNumber()) { + fRunChanged = kTRUE; + fRun = fESD->GetRunNumber(); + fCDB->SetRun(fRun); + } + TIter next(fSupplies); + AliTenderSupply *supply; + while ((supply=(AliTenderSupply*)next())) supply->ProcessEvent(); + fRunChanged = kFALSE; + + if (TObject::TestBit(kCheckEventSelection)) fESDhandler->CheckSelectionMask(); + + // Lock CDB + fCDBkey = fCDB->SetLock(kTRUE, fCDBkey); + + TString opt = option; + if (!opt.Contains("NoPost")) PostData(1, fESD); +} + +//______________________________________________________________________________ +void AliTender::SetDefaultCDBStorage(const char *dbString) +{ +// Set default CDB storage + fDefaultStorage = dbString; +} diff --git a/TENDER/Tender/AliTender.h b/TENDER/Tender/AliTender.h new file mode 100644 index 00000000000..dee218b96f2 --- /dev/null +++ b/TENDER/Tender/AliTender.h @@ -0,0 +1,74 @@ +#ifndef ALITENDER_H +#define ALITENDER_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ +// Author: Andrei Gheata, 31/08/2009 + +//============================================================================== +// AliTender - Tender wagon providing access to ESD event and CDB. +// The tender calls an arbitrary number of user algorithms that add or +// correct information in ESD based on CDB info that was not available +// during pass1 reconstruction. +//============================================================================== + +#ifndef ALIANALYSISTASKSE_H +#include "AliAnalysisTaskSE.h" +#endif + +// #ifndef ALIESDINPUTHANDLER_H +// #include "AliESDInputHandler.h" +// #endif +class AliCDBManager; +class AliESDEvent; +class AliESDInputHandler; +class AliTenderSupply; + +class AliTender : public AliAnalysisTaskSE { + +public: +enum ETenderFlags { + kCheckEventSelection = BIT(18) // up to 18 used by AliAnalysisTask +}; + +private: + Int_t fRun; //! Current run + Bool_t fRunChanged; //! Flag for run change. + ULong64_t fCDBkey; //! Key to unlock CDB manager + TString fDefaultStorage; // Default CDB storage + AliCDBManager *fCDB; //! Pointer to CDB manager + AliESDInputHandler *fESDhandler; //! Pointer to ESD input handler + AliESDEvent *fESD; //! Pointer to current ESD event + TObjArray *fSupplies; // Array of tender supplies + TObjArray *fCDBSettings; // Array with CDB configuration + + AliTender(const AliTender &other); + AliTender& operator=(const AliTender &other); + +public: + AliTender(); + AliTender(const char *name); + virtual ~AliTender(); + + void AddSupply(AliTenderSupply *supply); + Int_t GetRun() const {return fRun;} + AliCDBManager *GetCDBManager() const {return fCDB;} + AliESDInputHandler *GetESDhandler() const {return fESDhandler;} + AliESDEvent *GetEvent() const {return fESD;} + TObjArray *GetSupplies() const {return fSupplies;} + void SetCheckEventSelection(Bool_t flag=kTRUE) {TObject::SetBit(kCheckEventSelection,flag);} + Bool_t RunChanged() const {return fRunChanged;} + // Configuration + void SetDefaultCDBStorage(const char *dbString="local://$ALICE_ROOT/OCDB"); + void SetESDhandler(AliESDInputHandler*esdH) {fESDhandler = esdH;} + + // Run control + virtual void ConnectInputData(Option_t *option = ""); + virtual void UserCreateOutputObjects(); +// virtual Bool_t Notify() {return kTRUE;} + virtual void UserExec(Option_t *option); + + ClassDef(AliTender,4) // Class describing the tender car for ESD analysis +}; +#endif diff --git a/TENDER/Tender/AliTenderSupply.cxx b/TENDER/Tender/AliTenderSupply.cxx new file mode 100644 index 00000000000..0bf87a3ff9e --- /dev/null +++ b/TENDER/Tender/AliTenderSupply.cxx @@ -0,0 +1,62 @@ +/************************************************************************** + * 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$ */ + +#include "AliTender.h" +#include "AliTenderSupply.h" + +ClassImp(AliTenderSupply) + +//______________________________________________________________________________ +AliTenderSupply::AliTenderSupply() + :TNamed(), + fTender(NULL) +{ +// Dummy constructor +} + +//______________________________________________________________________________ +AliTenderSupply::AliTenderSupply(const char* name, const AliTender *tender) + :TNamed(name, "ESD analysis tender car"), + fTender(tender) +{ +// Default constructor +} + +//______________________________________________________________________________ +AliTenderSupply::AliTenderSupply(const AliTenderSupply &other) + :TNamed(other), + fTender(other.fTender) + +{ +// Copy constructor +} + +//______________________________________________________________________________ +AliTenderSupply::~AliTenderSupply() +{ +// Destructor +} + +//______________________________________________________________________________ +AliTenderSupply& AliTenderSupply::operator=(const AliTenderSupply &other) +{ +// Assignment + if (&other == this) return *this; + TNamed::operator=(other); + fTender = other.fTender; + return *this; +} diff --git a/TENDER/Tender/AliTenderSupply.h b/TENDER/Tender/AliTenderSupply.h new file mode 100644 index 00000000000..036e6c8e94d --- /dev/null +++ b/TENDER/Tender/AliTenderSupply.h @@ -0,0 +1,39 @@ +#ifndef ALITENDERSUPPLY_H +#define ALITENDERSUPPLY_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ +// Author: Andrei Gheata, 01/09/2009 + +//============================================================================== +// AliTenderSupply - Base class for user-defined ESD additions and corrections. +//============================================================================== + +#ifndef ROOT_TNamed +#include "TNamed.h" +#endif + +class AliTender; + +class AliTenderSupply : public TNamed { + +protected: + const AliTender *fTender; // Tender car + +public: + AliTenderSupply(); + AliTenderSupply(const char *name, const AliTender *tender=NULL); + AliTenderSupply(const AliTenderSupply &other); + virtual ~AliTenderSupply(); + AliTenderSupply& operator=(const AliTenderSupply &other); + + // Run control + virtual void Init() = 0; + virtual void ProcessEvent() = 0; + + void SetTender(const AliTender *tender) {fTender = tender;} + + ClassDef(AliTenderSupply,1) // Base class for tender user algorithms +}; +#endif diff --git a/TENDER/Tender/CMakeLists.txt b/TENDER/Tender/CMakeLists.txt new file mode 100644 index 00000000000..e54c5068cf3 --- /dev/null +++ b/TENDER/Tender/CMakeLists.txt @@ -0,0 +1,67 @@ +# ************************************************************************** +# * Copyright(c) 1998-2014, 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. * +# ************************************************************************** + +# Module +set(MODULE Tender) + +# Module include folder +include_directories(${AliRoot_SOURCE_DIR}/ANALYSIS/${MODULE}) + +# Additional include folders in alphabetical order except ROOT +include_directories(${ROOT_INCLUDE_DIRS} + ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSIS + ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSISalice + ${AliRoot_SOURCE_DIR}/STEER/CDB + ${AliRoot_SOURCE_DIR}/STEER/ESD + ${AliRoot_SOURCE_DIR}/STEER/STEERBase + ) + +# Sources in alphabetical order +set(SRCS + AliTender.cxx + AliTenderSupply.cxx + ) + +# Headers from sources +string(REPLACE ".cxx" ".h" HDRS "${SRCS}") + +# Generate the dictionary +# It will create G_ARG1.cxx and G_ARG1.h / ARG1 = function first argument +get_directory_property(incdirs INCLUDE_DIRECTORIES) +generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}") + +# Generate the ROOT map +# Dependecies +set(LIBDEPS ANALYSIS ANALYSISalice CDB ESD STEERBase Core RIO) +generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h") + +# Add a library to the project using the specified source files +add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx) +target_link_libraries(${MODULE} ANALYSIS ANALYSISalice CDB ESD STEERBase Core RIO) + +# Additional compilation flags +set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "") + +# System dependent: Modify the way the library is build +if(${CMAKE_SYSTEM} MATCHES Darwin) + set_target_properties(${MODULE} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") +endif(${CMAKE_SYSTEM} MATCHES Darwin) + +# Installation +install(TARGETS ${MODULE} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +install(FILES ${HDRS} DESTINATION include) + diff --git a/TENDER/Tender/TenderLinkDef.h b/TENDER/Tender/TenderLinkDef.h new file mode 100644 index 00000000000..f920be3da90 --- /dev/null +++ b/TENDER/Tender/TenderLinkDef.h @@ -0,0 +1,10 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class AliTender+; +#pragma link C++ class AliTenderSupply+; + +#endif diff --git a/TENDER/TenderSupplies/AddTaskTender.C b/TENDER/TenderSupplies/AddTaskTender.C new file mode 100644 index 00000000000..5f90b886417 --- /dev/null +++ b/TENDER/TenderSupplies/AddTaskTender.C @@ -0,0 +1,123 @@ +AliAnalysisTask *AddTaskTender(Bool_t useV0=kFALSE, + Bool_t useTPC=kTRUE, + Bool_t useTOF=kTRUE, + Bool_t useTRD=kTRUE, + Bool_t usePID=kTRUE, + Bool_t useVTX=kTRUE, + Bool_t useT0=kTRUE, + Bool_t useEmc=kFALSE, + Bool_t usePtFix=kFALSE) +{ + if (!(useV0 | useTPC | useTOF | useTRD | usePID | useVTX | | useT0 | useEmc | usePtFix)) { + ::Error("AddTaskTender", "No supply added to tender, so tender not created"); + return 0; + } + //get the current analysis manager + Bool_t checkEvtSelection = useV0; + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + if (!mgr) { + ::Error("AddTaskTender", "No analysis manager found."); + return 0; + } + // currently don't accept AOD input + if (!mgr->GetInputEventHandler()->InheritsFrom(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->SetCheckEventSelection(checkEvtSelection); + tender->SetDefaultCDBStorage("raw://"); + mgr->AddTask(tender); + + //check that that tender is the first task after the pid response + TString firstName(mgr->GetTasks()->First()->GetName()); + Bool_t isSecond=(mgr->GetTasks()->At(1) == (TObject*)tender); + + if (! (firstName=="PIDResponseTask" && isSecond )){ + Fatal("AddTaskTender","When using the tender the first task needs to be the PIDResponse and the tender the second task!!!"); + return NULL; + } + + //========= Attach VZERO supply ====== + if (useV0) { + AliVZEROTenderSupply *vzeroSupply=new AliVZEROTenderSupply("VZEROtender"); + vzeroSupply->SetDebug(kFALSE); + tender->AddSupply(vzeroSupply); + } + + + //========= Attach TPC supply ====== + if (useTPC) { + AliTPCTenderSupply *tpcSupply=new AliTPCTenderSupply("TPCtender"); + tpcSupply->SetDebugLevel(2); + //tpcSupply->SetMip(50.); + tender->AddSupply(tpcSupply); + } + + //========= Attach track 1/pt correction supply ====== + if (usePtFix) { + AliTrackFixTenderSupply *trfixSupply=new AliTrackFixTenderSupply("PTInvFix"); + //trfixSupply->SetDebugLevel(2); + tender->AddSupply(trfixSupply); + } + + //========= Attach T0 supply ====== + if (useT0) { + AliT0TenderSupply *t0Tender = new AliT0TenderSupply("T0tender"); + t0Tender ->SetPass4LHC11aCorrection(kTRUE); + tender->AddSupply(t0Tender); + } + + //========= Attach TOF supply ====== + if (useTOF) { + AliTOFTenderSupply *tofTender = new AliTOFTenderSupply("TOFtender"); + tender->AddSupply(tofTender); + } + + //========= Attach TRD supply ====== + if (useTRD) { + AliTRDTenderSupply *trdSupply=new AliTRDTenderSupply("TRDtender"); + + trdSupply->SetLoadDeadChambersFromCDB(); // Mask Bad chambers + trdSupply->SetPIDmethod(AliTRDTenderSupply::k1DLQpid); + trdSupply->SwitchOffGainCorrection(); // Correction only on pass 1 + trdSupply->SetNormalizationFactor(0.12697,114737,130850); // 1 otherwise + trdSupply->SetRedoTRDMatching(kTRUE); + tender->AddSupply(trdSupply); + } + + //========= Attach Primary Vertex supply ====== + if (useVTX) { + tender->AddSupply(new AliVtxTenderSupply("PriVtxtender")); + } + + //========= Attach EMCAL supply ====== + if (useEmc) { + AliEMCALTenderSupply *emcSupply = new AliEMCALTenderSupply("EmcTender"); + emcSupply->SetDefaults(); + tender->AddSupply(emcSupply); + } + + //========= Attach PID supply ====== + if (usePID) { + AliPIDTenderSupply *pidSupply=new AliPIDTenderSupply("PIDtender"); + tender->AddSupply(pidSupply); + } + + //================================================ + // 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, 1, coutput1); + + return tender; +} diff --git a/TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.cxx b/TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.cxx new file mode 100644 index 00000000000..ed3bed99aba --- /dev/null +++ b/TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.cxx @@ -0,0 +1,272 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// AliAnalysisTaskVZEROEqFactorTask.cxx, February 12th 2014 +// --- David Dobrigkeit Chinellato +// +// This task is meant to set correct VZERO equalization factors in AliESDRun +// so that AliCentrality makes use of the correct values. NB This task has to +// be executed prior to AliCentrality for this to work properly! It is meant +// to be used as a Tender. +// +// Comments, Suggestions, Bug reports: Please send them to: +// --- daviddc@ifi.unicamp.br +// +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +class TTree; +class TParticle; +class TVector3; + +//class AliMCEventHandler; +//class AliMCEvent; +//class AliStack; + +class AliESDVertex; +class AliAODVertex; +class AliESDv0; +class AliAODv0; + +#include +#include "TList.h" +#include "TH1.h" +#include "TH2.h" +#include "TH3.h" +#include "TFile.h" +#include "THnSparse.h" +#include "TVector3.h" +#include "TCanvas.h" +#include "TMath.h" +#include "TLegend.h" +//#include "AliLog.h" + +#include "AliAnalysisTaskSE.h" +#include "AliESDEvent.h" +#include "AliAODEvent.h" +#include "AliV0vertexer.h" +#include "AliCascadeVertexer.h" +#include "AliESDpid.h" +#include "AliESDRun.h" +#include "AliESDtrack.h" +#include "AliESDtrackCuts.h" +#include "AliInputEventHandler.h" +#include "AliAnalysisManager.h" +#include "AliMCEventHandler.h" +#include "AliMCEvent.h" +#include "AliStack.h" + +#include "AliCFContainer.h" +#include "AliMultiplicity.h" +#include "AliAODMCParticle.h" +#include "AliESDcascade.h" +#include "AliAODcascade.h" +#include "AliESDUtils.h" +#include "AliGenEventHeader.h" + +#include "AliAnalysisUtils.h" +#include "AliAnalysisTaskVZEROEqFactorTask.h" +#include "AliCDBManager.h" +#include "AliCDBStorage.h" +#include "AliCDBEntry.h" + +#include "AliVZEROCalibData.h" + +using std::cout; +using std::endl; + +ClassImp(AliAnalysisTaskVZEROEqFactorTask) + +AliAnalysisTaskVZEROEqFactorTask::AliAnalysisTaskVZEROEqFactorTask() +: AliAnalysisTaskSE(), fListHist(0), fEqFactors(0), fCalibData(0), fRunNumber(0), fHistEventCounter(0), fisAOD(kFALSE) +//------------------------------------------------ +// Tree Variables +{ + // Dummy Constructor +} + +AliAnalysisTaskVZEROEqFactorTask::AliAnalysisTaskVZEROEqFactorTask(const char *name) + : AliAnalysisTaskSE(name), fListHist(0), fEqFactors(0), fCalibData(0), fRunNumber(0), fHistEventCounter(0), fisAOD(kFALSE) +{ + // Constructor + DefineOutput(1, TList::Class()); +} + + +AliAnalysisTaskVZEROEqFactorTask::~AliAnalysisTaskVZEROEqFactorTask() +{ +//------------------------------------------------ +// DESTRUCTOR +//------------------------------------------------ + + if (fListHist){ + delete fListHist; + fListHist = 0x0; + } +} + +//________________________________________________________________________ +void AliAnalysisTaskVZEROEqFactorTask::UserCreateOutputObjects() +{ +//------------------------------------------------ +// Output: Empty at the moment +//------------------------------------------------ + + fListHist = new TList(); + fListHist->SetOwner(); // See http://root.cern.ch/root/html/TCollection.html#TCollection:SetOwner + + if(! fHistEventCounter ) { + //Histogram Output: Event-by-Event + // --- Single "Events Processed" Counter at this stage + fHistEventCounter = new TH1D( "fHistEventCounter", ";Evt. Sel. Step;Count",4,0,4); + fHistEventCounter->GetXaxis()->SetBinLabel(1, "Processed"); + fHistEventCounter->GetXaxis()->SetBinLabel(2, "Has ESD"); + fHistEventCounter->GetXaxis()->SetBinLabel(3, "Has ESDRun"); + fHistEventCounter->GetXaxis()->SetBinLabel(4, "Rewrote EqFactors"); + fListHist->Add(fHistEventCounter); + } + + //List of Histograms + PostData(1, fListHist); +}// end UserCreateOutputObjects + + +//________________________________________________________________________ +void AliAnalysisTaskVZEROEqFactorTask::UserExec(Option_t *) +{ + // Main loop + // Called for each event + + AliESDEvent *lESDevent = 0x0; + AliAODEvent *lAODevent = 0x0; + // Connect to the InputEvent + // After these lines, we should have an ESD/AOD event + the number of V0s in it. + + // Appropriate for ESD analysis! + //Count Processed Events + fHistEventCounter->Fill(0.5); + + if(fisAOD) { + lAODevent = dynamic_cast( InputEvent() ); + if (!lAODevent) { + AliError("AOD event not available \n"); + return; + } + } else { + lESDevent = dynamic_cast( InputEvent() ); + if (!lESDevent) { + AliError("ESD event not available \n"); + return; + } + } + fHistEventCounter->Fill(1.5); + + + //Acquire ESDRun object - Will be needed to invoke AliESDEvent::SetVZEROEqFactors + Int_t runNumber=-1; + // const AliESDRun *lESDRun; + if(fisAOD) { + runNumber = lAODevent->GetRunNumber(); + } else { + // lESDRun = lESDevent->GetESDRun(); + // if (!lESDRun) { + // AliError("ERROR: lESDRun not available, won't be able to write Equalization Factors! Exiting. \n"); + // return; + // } + runNumber = lESDevent->GetRunNumber(); + } + fHistEventCounter->Fill(2.5); + + //CDB Processing only necessary if Run Number changed! Check for change (no need to redo this every event) + if( runNumber != fRunNumber ){ + AliWarning("Run Changed! Reloading CDB values!"); + //Load CDB Entries - Mirroring AliVZEROReconstructor + AliCDBManager *cdbmanager = AliCDBManager::Instance(); + cdbmanager->SetDefaultStorage("raw://"); + cdbmanager->SetRun(runNumber); + if(!cdbmanager) AliFatal("No CDB Manager !"); + AliCDBEntry *entry7 = cdbmanager->Get("VZERO/Calib/EqualizationFactors"); + if (!entry7) AliFatal("VZERO equalization factors are not found in OCDB !"); + fEqFactors = (TH1F*)entry7->GetObject(); + + //Load Calibration object fCalibData + fCalibData = GetCalibData(); // Mirror AliVZEROReconstructor Functionality + fRunNumber = runNumber; //New Run + } + if(!fCalibData) AliFatal("No VZERO CalibData Object found!"); + + + Float_t factors[64]; + Float_t factorSum = 0; + for(Int_t i = 0; i < 64; ++i) { + factors[i] = fEqFactors->GetBinContent(i+1)*fCalibData->GetMIPperADC(i); + factorSum += factors[i]; + } + for(Int_t i = 0; i < 64; ++i) { + factors[i] *= (64./factorSum); + } + + // Set the equalized factors + if(fisAOD) { + lAODevent->SetVZEROEqFactors(factors); + } else { + lESDevent->SetVZEROEqFactors(factors); + } + fHistEventCounter->Fill(3.5); + + // Post output data. + PostData(1, fListHist); +} + +//________________________________________________________________________ +void AliAnalysisTaskVZEROEqFactorTask::Terminate(Option_t *) +{ + // Draw result to the screen + // Called once at the end of the query + + TList *cRetrievedList = 0x0; + cRetrievedList = (TList*)GetOutputData(1); + if(!cRetrievedList){ + Printf("ERROR - AliAnalysisTaskVZEROEqFactorTask : ouput data container list not available\n"); + return; + } + + fHistEventCounter = dynamic_cast ( cRetrievedList->FindObject("fHistEventCounter") ); + if (!fHistEventCounter) { + Printf("ERROR - AliAnalysisTaskVZEROEqFactorTask : fHistEventCounter not available"); + return; + } + + TCanvas *canCheck = new TCanvas("AliAnalysisTaskVZEROEqFactorTask","V0 Multiplicity",10,10,510,510); + canCheck->cd(1)->SetLogy(); + + fHistEventCounter->SetMarkerStyle(22); + fHistEventCounter->DrawCopy("E"); +} + +//_____________________________________________________________________________ +AliVZEROCalibData* AliAnalysisTaskVZEROEqFactorTask::GetCalibData() const +{ + // Gets calibration object for VZERO set + + AliCDBManager *man = AliCDBManager::Instance(); + AliCDBEntry *entry=0; + entry = man->Get("VZERO/Calib/Data"); + AliVZEROCalibData *calibdata = 0; + if (entry) calibdata = (AliVZEROCalibData*) entry->GetObject(); + if (!calibdata) AliFatal("No calibration data from calibration database !"); + return calibdata; +} diff --git a/TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.h b/TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.h new file mode 100644 index 00000000000..aaf8c9e7de5 --- /dev/null +++ b/TENDER/TenderSupplies/AliAnalysisTaskVZEROEqFactorTask.h @@ -0,0 +1,89 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Modified version of AliAnalysisTaskCheckCascade.h +// Used bits of code from AliAnalysisTaskCheckPerformanceStrange +// +// --- David Dobrigkeit Chinellato +// +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +#ifndef ALIANALYSISTASKVZEROEQFACTORTASK_H +#define ALIANALYSISTASKVZEROEQFACTORTASK_H + +//Needed for this task +#include "AliAnalysisTaskSE.h" + +class TList; +class TH1F; +class TH2F; +class TH3F; +class TVector3; +class THnSparse; + +class AliESDpid; +class AliESDtrackCuts; +class AliAnalysisUtils; +class AliESDEvent; +class AliPhysicsSelection; +class AliCFContainer; +class AliVZEROCalibData; +//class AliAnalysisTaskSE; + +//#include "TString.h" +//#include "AliESDtrackCuts.h" + + +class AliAnalysisTaskVZEROEqFactorTask : public AliAnalysisTaskSE { + public: + AliAnalysisTaskVZEROEqFactorTask(); + AliAnalysisTaskVZEROEqFactorTask(const char *name); + virtual ~AliAnalysisTaskVZEROEqFactorTask(); + + virtual void UserCreateOutputObjects(); + virtual void UserExec(Option_t *option); + virtual void Terminate(Option_t *); + AliVZEROCalibData* GetCalibData() const; + + void SetIsAODAnalysis(Bool_t flag) {fisAOD=flag;} + Bool_t GetIsAODAnalysis() const {return fisAOD;} + + private: + // Note : In ROOT, "//!" means "do not stream the data from Master node to Worker node" ... + // your data member object is created on the worker nodes and streaming is not needed. + // http://root.cern.ch/download/doc/11InputOutput.pdf, page 14 + TList *fListHist; //! List of Cascade histograms + + //Re-loaded per event if required, a la AliCentrality + TH1F* fEqFactors; //! Histogram with the equalization factors used in event-plane reconstruction + AliVZEROCalibData* fCalibData; //! calibration data + Long_t fRunNumber; //! Needed to make sure we haven't swapped runs + +//=========================================================================================== +// Histograms - Event Counting only +//=========================================================================================== + + TH1D *fHistEventCounter; //! + Bool_t fisAOD; // flag for analysis on AODs + + AliAnalysisTaskVZEROEqFactorTask(const AliAnalysisTaskVZEROEqFactorTask&); // not implemented + AliAnalysisTaskVZEROEqFactorTask& operator=(const AliAnalysisTaskVZEROEqFactorTask&); // not implemented + + ClassDef(AliAnalysisTaskVZEROEqFactorTask, 12); +}; + +#endif diff --git a/TENDER/TenderSupplies/AliEMCALTenderSupply.cxx b/TENDER/TenderSupplies/AliEMCALTenderSupply.cxx new file mode 100644 index 00000000000..4c4d6143e25 --- /dev/null +++ b/TENDER/TenderSupplies/AliEMCALTenderSupply.cxx @@ -0,0 +1,1827 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// EMCAL tender, apply corrections to EMCAL clusters and do track matching. // +// // +// Author: Deepa Thomas (Utrecht University) // +// Later mods/rewrite: Jiri Kral (University of Jyvaskyla) // +// S. Aiola, C. Loizides : Make it work for AODs // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include "AliAODEvent.h" +#include "AliAODMCParticle.h" +#include "AliAnalysisManager.h" +#include "AliEMCALAfterBurnerUF.h" +#include "AliEMCALClusterizer.h" +#include "AliEMCALClusterizerNxN.h" +#include "AliEMCALClusterizerv1.h" +#include "AliEMCALClusterizerv2.h" +#include "AliEMCALDigit.h" +#include "AliEMCALGeometry.h" +#include "AliEMCALRecParam.h" +#include "AliEMCALRecParam.h" +#include "AliEMCALRecPoint.h" +#include "AliEMCALRecoUtils.h" +#include "AliESDCaloCluster.h" +#include "AliESDEvent.h" +#include "AliLog.h" +#include "AliMagF.h" +#include "AliOADBContainer.h" +#include "AliTender.h" +#include "AliEMCALTenderSupply.h" + +ClassImp(AliEMCALTenderSupply) + +AliEMCALTenderSupply::AliEMCALTenderSupply() : + AliTenderSupply() + ,fTask(0) + ,fRun(0) + ,fEMCALGeo(0x0) + ,fEMCALGeoName("") + ,fEMCALRecoUtils(0) + ,fConfigName("") + ,fDebugLevel(0) + ,fNonLinearFunc(-1) + ,fNonLinearThreshold(-1) + ,fReCalibCluster(kFALSE) + ,fUpdateCell(kFALSE) + ,fCalibrateEnergy(kFALSE) + ,fCalibrateTime(kFALSE) + ,fCalibrateTimeParamAvailable(kFALSE) + ,fDoNonLinearity(kFALSE) + ,fBadCellRemove(kFALSE) + ,fRejectExoticCells(kFALSE) + ,fRejectExoticClusters(kFALSE) + ,fClusterBadChannelCheck(kFALSE) + ,fRecalClusPos(kFALSE) + ,fFiducial(kFALSE) + ,fNCellsFromEMCALBorder(-1) + ,fRecalDistToBadChannels(kFALSE) + ,fRecalShowerShape(kFALSE) + ,fInputTree(0) + ,fInputFile(0) + ,fGetPassFromFileName(kTRUE) + ,fFilepass(0) + ,fMass(-1) + ,fStep(-1) + ,fCutEtaPhiSum(kTRUE) + ,fCutEtaPhiSeparate(kFALSE) + ,fRcut(-1) + ,fEtacut(-1) + ,fPhicut(-1) + ,fBasePath("") + ,fReClusterize(kFALSE) + ,fClusterizer(0) + ,fGeomMatrixSet(kFALSE) + ,fLoadGeomMatrices(kFALSE) + ,fRecParam(0x0) + ,fDoTrackMatch(kFALSE) + ,fDoUpdateOnly(kFALSE) + ,fUnfolder(0) + ,fDigitsArr(0) + ,fClusterArr(0) + ,fMisalignSurvey(kdefault) + ,fExoticCellFraction(-1) + ,fExoticCellDiffTime(-1) + ,fExoticCellMinAmplitude(-1) + ,fSetCellMCLabelFromCluster(0) + ,fTempClusterArr(0) + ,fRemapMCLabelForAODs(0) + ,fUseAutomaticRecalib(1) + ,fUseAutomaticRunDepRecalib(1) + ,fUseAutomaticTimeCalib(1) + ,fUseAutomaticRecParam(1) +{ + // Default constructor. + + for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ; + for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1; +} + +//_____________________________________________________ +AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender) + ,fTask(0) + ,fRun(0) + ,fEMCALGeo(0x0) + ,fEMCALGeoName("") + ,fEMCALRecoUtils(0) + ,fConfigName("") + ,fDebugLevel(0) + ,fNonLinearFunc(-1) + ,fNonLinearThreshold(-1) + ,fReCalibCluster(kFALSE) + ,fUpdateCell(kFALSE) + ,fCalibrateEnergy(kFALSE) + ,fCalibrateTime(kFALSE) + ,fCalibrateTimeParamAvailable(kFALSE) + ,fDoNonLinearity(kFALSE) + ,fBadCellRemove(kFALSE) + ,fRejectExoticCells(kFALSE) + ,fRejectExoticClusters(kFALSE) + ,fClusterBadChannelCheck(kFALSE) + ,fRecalClusPos(kFALSE) + ,fFiducial(kFALSE) + ,fNCellsFromEMCALBorder(-1) + ,fRecalDistToBadChannels(kFALSE) + ,fRecalShowerShape(kFALSE) + ,fInputTree(0) + ,fInputFile(0) + ,fGetPassFromFileName(kTRUE) + ,fFilepass("") + ,fMass(-1) + ,fStep(-1) + ,fCutEtaPhiSum(kTRUE) + ,fCutEtaPhiSeparate(kFALSE) + ,fRcut(-1) + ,fEtacut(-1) + ,fPhicut(-1) + ,fBasePath("") + ,fReClusterize(kFALSE) + ,fClusterizer(0) + ,fGeomMatrixSet(kFALSE) + ,fLoadGeomMatrices(kFALSE) + ,fRecParam(0x0) + ,fDoTrackMatch(kFALSE) + ,fDoUpdateOnly(kFALSE) + ,fUnfolder(0) + ,fDigitsArr(0) + ,fClusterArr(0) + ,fMisalignSurvey(kdefault) + ,fExoticCellFraction(-1) + ,fExoticCellDiffTime(-1) + ,fExoticCellMinAmplitude(-1) + ,fSetCellMCLabelFromCluster(0) + ,fTempClusterArr(0) + ,fRemapMCLabelForAODs(0) + ,fUseAutomaticRecalib(1) + ,fUseAutomaticRunDepRecalib(1) + ,fUseAutomaticTimeCalib(1) + ,fUseAutomaticRecParam(1) +{ + // Named constructor + + for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ; + for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1; +} + +//_____________________________________________________ +AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, AliAnalysisTaskSE *task) : + AliTenderSupply(name) + ,fTask(task) + ,fRun(0) + ,fEMCALGeo(0x0) + ,fEMCALGeoName("") + ,fEMCALRecoUtils(0) + ,fConfigName("") + ,fDebugLevel(0) + ,fNonLinearFunc(-1) + ,fNonLinearThreshold(-1) + ,fReCalibCluster(kFALSE) + ,fUpdateCell(kFALSE) + ,fCalibrateEnergy(kFALSE) + ,fCalibrateTime(kFALSE) + ,fCalibrateTimeParamAvailable(kFALSE) + ,fDoNonLinearity(kFALSE) + ,fBadCellRemove(kFALSE) + ,fRejectExoticCells(kFALSE) + ,fRejectExoticClusters(kFALSE) + ,fClusterBadChannelCheck(kFALSE) + ,fRecalClusPos(kFALSE) + ,fFiducial(kFALSE) + ,fNCellsFromEMCALBorder(-1) + ,fRecalDistToBadChannels(kFALSE) + ,fRecalShowerShape(kFALSE) + ,fInputTree(0) + ,fInputFile(0) + ,fGetPassFromFileName(kTRUE) + ,fFilepass("") + ,fMass(-1) + ,fStep(-1) + ,fCutEtaPhiSum(kTRUE) + ,fCutEtaPhiSeparate(kFALSE) + ,fRcut(-1) + ,fEtacut(-1) + ,fPhicut(-1) + ,fBasePath("") + ,fReClusterize(kFALSE) + ,fClusterizer(0) + ,fGeomMatrixSet(kFALSE) + ,fLoadGeomMatrices(kFALSE) + ,fRecParam(0x0) + ,fDoTrackMatch(kFALSE) + ,fDoUpdateOnly(kFALSE) + ,fUnfolder(0) + ,fDigitsArr(0) + ,fClusterArr(0) + ,fMisalignSurvey(kdefault) + ,fExoticCellFraction(-1) + ,fExoticCellDiffTime(-1) + ,fExoticCellMinAmplitude(-1) + ,fSetCellMCLabelFromCluster(0) + ,fTempClusterArr(0) + ,fRemapMCLabelForAODs(0) + ,fUseAutomaticRecalib(1) + ,fUseAutomaticRunDepRecalib(1) + ,fUseAutomaticTimeCalib(1) + ,fUseAutomaticRecParam(1) +{ + // Named constructor. + + for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ; + for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1; +} + +//_____________________________________________________ +AliEMCALTenderSupply::~AliEMCALTenderSupply() +{ + //Destructor + + if (!AliAnalysisManager::GetAnalysisManager()) return; + + if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) + { + delete fEMCALRecoUtils; + delete fRecParam; + delete fUnfolder; + + if (!fClusterizer) + { + if (fDigitsArr) + { + fDigitsArr->Clear("C"); + delete fDigitsArr; + } + } + else + { + delete fClusterizer; + fDigitsArr = 0; + } + } +} + +//_____________________________________________________ +void AliEMCALTenderSupply::SetDefaults() +{ + // Set default settings. + + SwitchOnReclustering(); + SwitchOnTrackMatch(); +} + +//_____________________________________________________ +Bool_t AliEMCALTenderSupply::RunChanged() const +{ + // Get run number. + + return (fTender && fTender->RunChanged()) || (fTask && fRun != fTask->InputEvent()->GetRunNumber()); +} + +//_____________________________________________________ +void AliEMCALTenderSupply::Init() +{ + // Initialise EMCAL tender. + + if (fDebugLevel>0) + AliWarning("Init EMCAL Tender supply"); + + if (fConfigName.Length()>0 && gROOT->LoadMacro(fConfigName) >=0) { + AliDebug(1, Form("Loading settings from macro %s", fConfigName.Data())); + AliEMCALTenderSupply *tender = (AliEMCALTenderSupply*)gInterpreter->ProcessLine("ConfigEMCALTenderSupply()"); + fDebugLevel = tender->fDebugLevel; + fEMCALGeoName = tender->fEMCALGeoName; + fEMCALRecoUtils = tender->fEMCALRecoUtils; + fConfigName = tender->fConfigName; + fNonLinearFunc = tender->fNonLinearFunc; + fNonLinearThreshold = tender->fNonLinearThreshold; + fReCalibCluster = tender->fReCalibCluster; + fUpdateCell = tender->fUpdateCell; + fRecalClusPos = tender->fRecalClusPos; + fCalibrateEnergy = tender->fCalibrateEnergy; + fCalibrateTime = tender->fCalibrateTime; + fCalibrateTimeParamAvailable = tender->fCalibrateTimeParamAvailable; + fFiducial = tender->fFiducial; + fNCellsFromEMCALBorder = tender->fNCellsFromEMCALBorder; + fRecalDistToBadChannels = tender->fRecalDistToBadChannels; + fRecalShowerShape = tender->fRecalShowerShape; + fClusterBadChannelCheck = tender->fClusterBadChannelCheck; + fBadCellRemove = tender->fBadCellRemove; + fRejectExoticCells = tender->fRejectExoticCells; + fRejectExoticClusters = tender->fRejectExoticClusters; + fMass = tender->fMass; + fStep = tender->fStep; + fCutEtaPhiSum = tender->fCutEtaPhiSum; + fCutEtaPhiSeparate = tender->fCutEtaPhiSeparate; + fRcut = tender->fRcut; + fEtacut = tender->fEtacut; + fPhicut = tender->fPhicut; + fReClusterize = tender->fReClusterize; + fLoadGeomMatrices = tender->fLoadGeomMatrices; + fRecParam = tender->fRecParam; + fDoNonLinearity = tender->fDoNonLinearity; + fDoTrackMatch = tender->fDoTrackMatch; + fDoUpdateOnly = tender->fDoUpdateOnly; + fMisalignSurvey = tender->fMisalignSurvey; + fExoticCellFraction = tender->fExoticCellFraction; + fExoticCellDiffTime = tender->fExoticCellDiffTime; + fExoticCellMinAmplitude = tender->fExoticCellMinAmplitude; + + for(Int_t i = 0; i < 12; i++) + fEMCALMatrix[i] = tender->fEMCALMatrix[i] ; + } + + if (fDebugLevel>0){ + AliInfo("Emcal Tender settings: ======================================"); + AliInfo("------------ Switches --------------------------"); + AliInfo(Form("BadCellRemove : %d", fBadCellRemove)); + AliInfo(Form("ExoticCellRemove : %d", fRejectExoticCells)); + AliInfo(Form("CalibrateEnergy : %d", fCalibrateEnergy)); + AliInfo(Form("CalibrateTime : %d", fCalibrateTime)); + AliInfo(Form("UpdateCell : %d", fUpdateCell)); + AliInfo(Form("DoUpdateOnly : %d", fDoUpdateOnly)); + AliInfo(Form("Reclustering : %d", fReClusterize)); + AliInfo(Form("ClusterBadChannelCheck : %d", fClusterBadChannelCheck)); + AliInfo(Form("ClusterExoticChannelCheck : %d", fRejectExoticClusters)); + AliInfo(Form("CellFiducialRegion : %d", fFiducial)); + AliInfo(Form("ReCalibrateCluster : %d", fReCalibCluster)); + AliInfo(Form("RecalculateClusPos : %d", fRecalClusPos)); + AliInfo(Form("RecalShowerShape : %d", fRecalShowerShape)); + AliInfo(Form("NonLinearityCorrection : %d", fDoNonLinearity)); + AliInfo(Form("RecalDistBadChannel : %d", fRecalDistToBadChannels)); + AliInfo(Form("TrackMatch : %d", fDoTrackMatch)); + AliInfo("------------ Variables -------------------------"); + AliInfo(Form("DebugLevel : %d", fDebugLevel)); + AliInfo(Form("BasePath : %s", fBasePath.Data())); + AliInfo(Form("ConfigFileName : %s", fConfigName.Data())); + AliInfo(Form("EMCALGeometryName : %s", fEMCALGeoName.Data())); + AliInfo(Form("NonLinearityFunction : %d", fNonLinearFunc)); + AliInfo(Form("NonLinearityThreshold : %d", fNonLinearThreshold)); + AliInfo(Form("MisalignmentMatrixSurvey : %d", fMisalignSurvey)); + AliInfo(Form("NumberOfCellsFromEMCALBorder : %d", fNCellsFromEMCALBorder)); + AliInfo(Form("RCut : %f", fRcut)); + AliInfo(Form("Mass : %f", fMass)); + AliInfo(Form("Step : %f", fStep)); + AliInfo(Form("EtaCut : %f", fEtacut)); + AliInfo(Form("PhiCut : %f", fPhicut)); + AliInfo(Form("ExoticCellFraction : %f", fExoticCellFraction)); + AliInfo(Form("ExoticCellDiffTime : %f", fExoticCellDiffTime)); + AliInfo(Form("ExoticCellMinAmplitude : %f", fExoticCellMinAmplitude)); + AliInfo("============================================================="); + } + + // init reco utils + + if (!fEMCALRecoUtils) + fEMCALRecoUtils = new AliEMCALRecoUtils; + + // init geometry if requested + if (fEMCALGeoName.Length()>0) + fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ; + + // digits array + fDigitsArr = new TClonesArray("AliEMCALDigit",1000); + + // initialising non-linearity parameters + if (fNonLinearThreshold != -1) + fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold); + if (fNonLinearFunc != -1) + fEMCALRecoUtils->SetNonLinearityFunction(fNonLinearFunc); + + // missalignment function + fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal); + + // fiducial cut + // do not do the eta0 fiducial cut + if (fNCellsFromEMCALBorder != -1) + fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder); + fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0(); + + // exotic cell rejection + if (fExoticCellFraction != -1) + fEMCALRecoUtils->SetExoticCellFractionCut(fExoticCellFraction); + if (fExoticCellDiffTime != -1) + fEMCALRecoUtils->SetExoticCellDiffTimeCut(fExoticCellDiffTime); + if (fExoticCellMinAmplitude != -1) + fEMCALRecoUtils->SetExoticCellMinAmplitudeCut(fExoticCellMinAmplitude); + + // setting track matching parameters ... mass, step size and residual cut + if (fMass != -1) + fEMCALRecoUtils->SetMass(fMass); + if (fStep != -1) + fEMCALRecoUtils->SetStep(fStep); + + // spatial cut based on separate eta/phi or common processing + if (fCutEtaPhiSum) { + fEMCALRecoUtils->SwitchOnCutEtaPhiSum(); + if (fRcut != -1) + fEMCALRecoUtils->SetCutR(fRcut); + } else if (fCutEtaPhiSeparate) { + fEMCALRecoUtils->SwitchOnCutEtaPhiSeparate(); + if (fEtacut != -1) + fEMCALRecoUtils->SetCutEta(fEtacut); + if (fPhicut != -1) + fEMCALRecoUtils->SetCutPhi(fPhicut); + } +} + +//_____________________________________________________ +AliVEvent* AliEMCALTenderSupply::GetEvent() +{ + // Return the event pointer. + + if (fTender) { + return fTender->GetEvent(); + } else if (fTask) { + return fTask->InputEvent(); + } + + return 0; +} + +//_____________________________________________________ +void AliEMCALTenderSupply::ProcessEvent() +{ + // Event loop. + + AliVEvent *event = GetEvent(); + + if (!event) { + AliError("Event ptr = 0, returning"); + return; + } + + // Initialising parameters once per run number + if (RunChanged()) { + + fRun = event->GetRunNumber(); + AliWarning(Form("Run changed, initializing parameters for %d", fRun)); + if (dynamic_cast(event)) { + AliWarning("============================================================="); + AliWarning("=== Running on AOD is not equivalent to running on ESD! ==="); + AliWarning("============================================================="); + } + + // init geometry if not already done + if (fEMCALGeoName.Length()==0) { + fEMCALGeoName = "EMCAL_FIRSTYEARV1"; + if (fRun>139517) { + fEMCALGeoName = "EMCAL_COMPLETEV1"; + } + if (fRun>170593) { + fEMCALGeoName = "EMCAL_COMPLETE12SMV1"; + } + fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName); + if (!fEMCALGeo) { + AliFatal(Form("Can not create geometry: %s", fEMCALGeoName.Data())); + return; + } + } + + // get pass + if (fGetPassFromFileName) + GetPass(); + + // define what recalib parameters are needed for various switches + // this is based on implementation in AliEMCALRecoUtils + Bool_t needRecoParam = fReClusterize; + Bool_t needBadChannels = fBadCellRemove | fClusterBadChannelCheck | fRecalDistToBadChannels | fReClusterize; + Bool_t needRecalib = fCalibrateEnergy | fReClusterize; + Bool_t needTimecalib = fCalibrateTime | fReClusterize; + Bool_t needMisalign = fRecalClusPos | fReClusterize; + Bool_t needClusterizer = fReClusterize; + + // init bad channels + if (needBadChannels) { + Int_t fInitBC = InitBadChannels(); + if (fInitBC==0) + AliError("InitBadChannels returned false, returning"); + if (fInitBC==1) + AliWarning("InitBadChannels OK"); + if (fInitBC>1) + AliWarning(Form("No external hot channel set: %d - %s", event->GetRunNumber(), fFilepass.Data())); + } + + // init recalibration factors + if (needRecalib) { + if(fUseAutomaticRecalib) + { + Int_t fInitRecalib = InitRecalib(); + if (fInitRecalib==0) + AliError("InitRecalib returned false, returning"); + if (fInitRecalib==1) + AliWarning("InitRecalib OK"); + if (fInitRecalib>1) + AliWarning(Form("No recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data())); + } + + if(fUseAutomaticRunDepRecalib) + { + Int_t fInitRunDepRecalib = InitRunDepRecalib(); + if (fInitRunDepRecalib==0) + AliError("InitrunDepRecalib returned false, returning"); + if (fInitRunDepRecalib==1) + AliWarning("InitRecalib OK"); + if (fInitRunDepRecalib>1) + AliWarning(Form("No Temperature recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data())); + } + } + + // init time calibration + if (needTimecalib && fUseAutomaticTimeCalib) { + Int_t initTC = InitTimeCalibration(); + if (!initTC) + AliError("InitTimeCalibration returned false, returning"); + if (initTC==1) { + fCalibrateTimeParamAvailable = kTRUE; + AliWarning("InitTimeCalib OK"); + } + if (initTC > 1) + AliWarning(Form("No external time calibration available: %d - %s", event->GetRunNumber(), fFilepass.Data())); + } + + // init misalignment matrix + if (needMisalign) { + if (!InitMisalignMatrix()) + AliError("InitMisalignmentMatrix returned false, returning"); + else + AliWarning("InitMisalignMatrix OK"); + } + + // initiate reco params with some defaults + // will not overwrite, if those have been provided by user + if (needRecoParam && fUseAutomaticRecParam) { + Int_t initRC = InitRecParam(); + + if (initRC == 0) + AliInfo("Defaults reco params loaded."); + if (initRC > 1) + AliWarning("User defined reco params."); + } + + // init clusterizer + if (needClusterizer) { + if (!InitClusterization()) + AliError("InitClusterization returned false, returning"); + else + AliWarning("InitClusterization OK"); + } + + if (fDebugLevel>1) + fEMCALRecoUtils->Print(""); + } + + // disable implied switches ------------------------------------------------- + // AliEMCALRecoUtils or clusterizer functions alredy include some + // recalibration so based on those implied callibration te switches + // here are disabled to avoid duplication + + // clusterizer does cluster energy recalibration, position recomputation + // and shower shape + if (fReClusterize) { + fReCalibCluster = kFALSE; + fRecalClusPos = kFALSE; + fRecalShowerShape = kFALSE; + } + + // CONFIGURE THE RECO UTILS ------------------------------------------------- + // configure the reco utils + // this option does energy recalibration + if (fCalibrateEnergy) + fEMCALRecoUtils->SwitchOnRecalibration(); + else + fEMCALRecoUtils->SwitchOffRecalibration(); + + // allows time calibration + if (fCalibrateTime) + fEMCALRecoUtils->SwitchOnTimeRecalibration(); + else + fEMCALRecoUtils->SwitchOffTimeRecalibration(); + + // allows to zero bad cells + if (fBadCellRemove) + fEMCALRecoUtils->SwitchOnBadChannelsRemoval(); + else + fEMCALRecoUtils->SwitchOffBadChannelsRemoval(); + + // distance to bad channel recalibration + if (fRecalDistToBadChannels) + fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation(); + else + fEMCALRecoUtils->SwitchOffDistToBadChannelRecalculation(); + + // exclude exotic cells + if (fRejectExoticCells) + fEMCALRecoUtils->SwitchOnRejectExoticCell(); + else + fEMCALRecoUtils->SwitchOffRejectExoticCell(); + + // exclude clusters with exotic cells + if (fRejectExoticClusters) + fEMCALRecoUtils->SwitchOnRejectExoticCluster(); + else + fEMCALRecoUtils->SwitchOffRejectExoticCluster(); + + // TODO: not implemented switches + // SwitchOnClusterEnergySmearing + // SwitchOnRunDepCorrection + + // START PROCESSING --------------------------------------------------------- + // Test if cells present + AliVCaloCells *cells= event->GetEMCALCells(); + if (cells->GetNumberOfCells()<=0) + { + if (fDebugLevel>1) + AliWarning(Form("Number of EMCAL cells = %d, returning", cells->GetNumberOfCells())); + return; + } + + if (fDebugLevel>2) + AliInfo(Form("Re-calibrate cluster %d\n",fReCalibCluster)); + + // mark the cells not recalibrated in case of selected + // time, energy recalibration or bad channel removal + if (fCalibrateEnergy || fCalibrateTime || fBadCellRemove) + fEMCALRecoUtils->ResetCellsCalibrated(); + + // CELL RECALIBRATION ------------------------------------------------------- + // cell objects will be updated + // the cell calibrations are also processed locally any time those are needed + // in case that the cell objects are not to be updated here for later use + if (fUpdateCell) { + // do the update + // includes exotic cell check in the UpdateCells function - is not provided + // by the reco utils + UpdateCells(); + + // switch off recalibrations so those are not done multiple times + // this is just for safety, the recalibrated flag of cell object + // should not allow for farther processing anyways + fEMCALRecoUtils->SwitchOffRecalibration(); + fEMCALRecoUtils->SwitchOffTimeRecalibration(); + + if (fDoUpdateOnly) + return; + } + + // RECLUSTERIZATION --------------------------------------------------------- + if (fReClusterize) + { + FillDigitsArray(); + Clusterize(); + UpdateClusters(); + } + + // Store good clusters + TClonesArray *clusArr = dynamic_cast(event->FindListObject("caloClusters")); + if (!clusArr) + clusArr = dynamic_cast(event->FindListObject("CaloClusters")); + if (!clusArr) { + AliWarning(Form("No cluster array, number of cells in event = %d, returning", cells->GetNumberOfCells())); + return; + } + + // PROCESS SINGLE CLUSTER RECALIBRATION ------------------------------------- + // now go through clusters one by one and process separate correction + // as those were defined or not + Int_t nclusters = clusArr->GetEntriesFast(); + for (Int_t icluster=0; icluster < nclusters; ++icluster) + { + AliVCluster *clust = static_cast(clusArr->At(icluster)); + if (!clust) + continue; + if (!clust->IsEMCAL()) + continue; + + // REMOVE CLUSTERS WITH BAD CELLS ----------------------------- + if (fClusterBadChannelCheck) { + // careful, the the ClusterContainsBadChannel is dependent on + // SwitchOnBadChannelsRemoval, switching it ON automatically + // and returning to original value after processing + Bool_t badRemoval = fEMCALRecoUtils->IsBadChannelsRemovalSwitchedOn(); + fEMCALRecoUtils->SwitchOnBadChannelsRemoval(); + + Bool_t badResult = fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells()); + + // switch the bad channels removal back + if (!badRemoval) + fEMCALRecoUtils->SwitchOffBadChannelsRemoval(); + + if (badResult) + { + delete clusArr->RemoveAt(icluster); + continue; //TODO is it really needed to remove it? Or should we flag it? + } + } + + // REMOVE EXOTIC CLUSTERS ------------------------------------- + // does process local cell recalibration energy and time without replacing + // the global cell values, in case of no cell recalib done yet + if (fRejectExoticClusters) + { + // careful, the IsExoticCluster is dependent on + // SwitchOnRejectExoticCell, switching it ON automatically + // and returning to original value after processing + Bool_t exRemoval = fEMCALRecoUtils->IsRejectExoticCell(); + fEMCALRecoUtils->SwitchOnRejectExoticCell(); + + // get bunch crossing + Int_t bunchCrossNo = event->GetBunchCrossNumber(); + + Bool_t exResult = fEMCALRecoUtils->IsExoticCluster(clust, cells, bunchCrossNo); + + // switch the exotic channels removal back + if (!exRemoval) + fEMCALRecoUtils->SwitchOffRejectExoticCell(); + + if (exResult) { + delete clusArr->RemoveAt(icluster); + continue; //TODO is it really needed to remove it? Or should we flag it? + } + } + + // FIDUCIAL CUT ----------------------------------------------- + if (fFiducial) { + // depends on SetNumberOfCellsFromEMCALBorder + // SwitchOnNoFiducialBorderInEMCALEta0 + if (!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){ + delete clusArr->RemoveAt(icluster); + continue; //TODO it would be nice to store the distance + } + } + + // CLUSTER ENERGY --------------------------------------------- + // does process local cell recalibration energy and time without replacing + // the global cell values, in case of no cell recalib done yet + if (fReCalibCluster) { + fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells); + if (clust->E() < 1e-9) { + delete clusArr->RemoveAt(icluster); + continue; + } + } + + // CLUSTER POSITION ------------------------------------------- + // does process local cell energy recalibration, if enabled and cells + // not calibrated yet + if (fRecalClusPos) + fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust); + + // SHOWER SHAPE ----------------------------------------------- + if (fRecalShowerShape) + fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, cells, clust); + + // NONLINEARITY ----------------------------------------------- + if (fDoNonLinearity) { + Float_t correctedEnergy = fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust); + clust->SetE(correctedEnergy); + } + + // DISTANCE TO BAD CHANNELS ----------------------------------- + if (fRecalDistToBadChannels) + fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust); + } + + clusArr->Compress(); + + if (!fDoTrackMatch) + return; + + // TRACK MATCHING ----------------------------------------------------------- + if (!TGeoGlobalMagField::Instance()->GetField()) { + event->InitMagneticField(); + } + + fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo); + fEMCALRecoUtils->SetClusterMatchedToTrack(event); + fEMCALRecoUtils->SetTracksMatchedToCluster(event); +} + +//_____________________________________________________ +Bool_t AliEMCALTenderSupply::InitMisalignMatrix() +{ + // Initialising misalignment matrices + + AliVEvent *event = GetEvent(); + + if (!event) + return kFALSE; + + if (fGeomMatrixSet) + { + AliInfo("Misalignment matrix already set"); + return kTRUE; + } + + if (fDebugLevel>0) + AliInfo("Initialising misalignment matrix"); + + if (fLoadGeomMatrices) { + for(Int_t mod=0; mod < fEMCALGeo->GetNumberOfSuperModules(); ++mod) + { + if (fEMCALMatrix[mod]){ + if (fDebugLevel > 2) + fEMCALMatrix[mod]->Print(); + fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod); + } + } + fGeomMatrixSet = kTRUE; + return kTRUE; + } + + Int_t runGM = event->GetRunNumber(); + TObjArray *mobj = 0; + + if (fMisalignSurvey == kdefault) + { //take default alignment corresponding to run no + AliOADBContainer emcalgeoCont(Form("emcal")); + emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo")); + mobj=(TObjArray*)emcalgeoCont.GetObject(runGM,"EmcalMatrices"); + } + + if (fMisalignSurvey == kSurveybyS) + { //take alignment at sector level + if (runGM <= 140000) { //2010 data + AliOADBContainer emcalgeoCont(Form("emcal2010")); + emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo")); + mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10"); + } + else if (runGM>140000) + { // 2011 LHC11a pass1 data + AliOADBContainer emcalgeoCont(Form("emcal2011")); + emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo")); + mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS"); + } + } + + if (fMisalignSurvey == kSurveybyM) + { //take alignment at module level + if (runGM <= 140000) { //2010 data + AliOADBContainer emcalgeoCont(Form("emcal2010")); + emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo")); + mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10"); + } + else if (runGM>140000) + { // 2011 LHC11a pass1 data + AliOADBContainer emcalgeoCont(Form("emcal2011")); + emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo")); + mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byM"); + } + } + + if (!mobj) { + AliFatal("Geometry matrix array not found"); + return kFALSE; + } + + for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++) + { + fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod); + fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod); + fEMCALMatrix[mod]->Print(); + } + + return kTRUE; +} + +//_____________________________________________________ +Int_t AliEMCALTenderSupply::InitBadChannels() +{ + // Initialising bad channel maps + + AliVEvent *event = GetEvent(); + + if (!event) + return 0; + + if (fDebugLevel>0) + AliInfo("Initialising Bad channel map"); + + // init default maps first + if (!fEMCALRecoUtils->GetEMCALBadChannelStatusMapArray()) + fEMCALRecoUtils->InitEMCALBadChannelStatusMap() ; + + Int_t runBC = event->GetRunNumber(); + + AliOADBContainer *contBC = new AliOADBContainer(""); + if (fBasePath!="") + { //if fBasePath specified in the ->SetBasePath() + if (fDebugLevel>0) AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data())); + + TFile *fbad=new TFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"read"); + if (!fbad || fbad->IsZombie()) + { + AliFatal(Form("EMCALBadChannels.root was not found in the path provided: %s",fBasePath.Data())); + return 0; + } + + if (fbad) delete fbad; + + contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"AliEMCALBadChannels"); + } + else + { // Else choose the one in the $ALICE_ROOT directory + if (fDebugLevel>0) AliInfo("Loading Bad Channels OADB from $ALICE_ROOT/OADB/EMCAL"); + + TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","read"); + if (!fbad || fbad->IsZombie()) + { + AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root was not found"); + return 0; + } + + if (fbad) delete fbad; + + contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","AliEMCALBadChannels"); + } + + TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC); + if (!arrayBC) + { + AliError(Form("No external hot channel set for run number: %d", runBC)); + return 2; + } + + Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules(); + for (Int_t i=0; iGetEMCALChannelStatusMap(i); + if (h) + delete h; + h=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i)); + + if (!h) + { + AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i)); + continue; + } + h->SetDirectory(0); + fEMCALRecoUtils->SetEMCALChannelStatusMap(i,h); + } + return 1; +} + +//_____________________________________________________ +Int_t AliEMCALTenderSupply::InitRecalib() +{ + // Initialising recalibration factors. + + AliVEvent *event = GetEvent(); + + if (!event) + return 0; + + if (fDebugLevel>0) + AliInfo("Initialising recalibration factors"); + + // init default maps first + if (!fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray()) + fEMCALRecoUtils->InitEMCALRecalibrationFactors() ; + + Int_t runRC = event->GetRunNumber(); + + AliOADBContainer *contRF=new AliOADBContainer(""); + if (fBasePath!="") + { //if fBasePath specified in the ->SetBasePath() + if (fDebugLevel>0) AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data())); + + TFile *fRecalib= new TFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"read"); + if (!fRecalib || fRecalib->IsZombie()) + { + AliFatal(Form("EMCALRecalib.root not found in %s",fBasePath.Data())); + return 0; + } + + if (fRecalib) delete fRecalib; + + contRF->InitFromFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"AliEMCALRecalib"); + } + else + { // Else choose the one in the $ALICE_ROOT directory + if (fDebugLevel>0) AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL"); + + TFile *fRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","read"); + if (!fRecalib || fRecalib->IsZombie()) + { + AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root was not found"); + return 0; + } + + if (fRecalib) delete fRecalib; + + contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","AliEMCALRecalib"); + } + + TObjArray *recal=(TObjArray*)contRF->GetObject(runRC); + if (!recal) + { + AliError(Form("No Objects for run: %d",runRC)); + return 2; + } + + TObjArray *recalpass=(TObjArray*)recal->FindObject(fFilepass); + if (!recalpass) + { + AliError(Form("No Objects for run: %d - %s",runRC,fFilepass.Data())); + return 2; + } + + TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib"); + if (!recalib) + { + AliError(Form("No Recalib histos found for %d - %s",runRC,fFilepass.Data())); + return 2; + } + + if (fDebugLevel>0) recalib->Print(); + + Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules(); + for (Int_t i=0; iGetEMCALChannelRecalibrationFactors(i); + if (h) + delete h; + h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i)); + if (!h) + { + AliError(Form("Could not load EMCALRecalFactors_SM%d",i)); + continue; + } + h->SetDirectory(0); + fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(i,h); + } + return 1; +} + +//_____________________________________________________ +Int_t AliEMCALTenderSupply::InitRunDepRecalib() +{ + // Initialising recalibration factors. + + AliVEvent *event = GetEvent(); + + if (!event) + return 0; + + if (fDebugLevel>0) + AliInfo("Initialising recalibration factors"); + + // init default maps first + if (!fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray()) + fEMCALRecoUtils->InitEMCALRecalibrationFactors() ; + + Int_t runRC = event->GetRunNumber(); + + AliOADBContainer *contRF=new AliOADBContainer(""); + if (fBasePath!="") + { //if fBasePath specified in the ->SetBasePath() + if (fDebugLevel>0) AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data())); + + TFile *fRunDepRecalib= new TFile(Form("%s/EMCALTemperatureCorrCalib.root",fBasePath.Data()),"read"); + if (!fRunDepRecalib || fRunDepRecalib->IsZombie()) + { + AliFatal(Form("EMCALTemperatureCorrCalib.root not found in %s",fBasePath.Data())); + return 0; + } + + if (fRunDepRecalib) delete fRunDepRecalib; + + contRF->InitFromFile(Form("%s/EMCALTemperatureCorrCalib.root",fBasePath.Data()),"AliEMCALRunDepTempCalibCorrections"); + } + else + { // Else choose the one in the $ALICE_ROOT directory + if (fDebugLevel>0) AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL"); + + TFile *fRunDepRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root","read"); + if (!fRunDepRecalib || fRunDepRecalib->IsZombie()) + { + AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root was not found"); + return 0; + } + + if (fRunDepRecalib) delete fRunDepRecalib; + + contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root","AliEMCALRunDepTempCalibCorrections"); + } + + TH1S *rundeprecal=(TH1S*)contRF->GetObject(runRC); + if (!rundeprecal) + { + AliWarning(Form("No TemperatureCorrCalib Objects for run: %d",runRC)); + // let's get the closest runnumber instead then.. + Int_t lower = 0; + Int_t ic = 0; + Int_t maxEntry = contRF->GetNumberOfEntries(); + + while ((ic < maxEntry) && (contRF->UpperLimit(ic) < runRC)) { + lower = ic; + ic++; + } + + Int_t closest = lower; + if ((icLowerLimit(ic)-runRC) < (runRC - contRF->UpperLimit(lower))) { + closest = ic; + } + + AliWarning(Form("TemperatureCorrCalib Objects found closest id %d from run: %d", closest, contRF->LowerLimit(closest))); + rundeprecal = (TH1S*) contRF->GetObjectByIndex(closest); + } + + if (fDebugLevel>0) rundeprecal->Print(); + + Int_t nSM = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules(); + + for (Int_t ism=0; ismGetEMCALChannelRecalibrationFactor(ism,icol,irow); + + Int_t absID = fEMCALGeo->GetAbsCellIdFromCellIndexes(ism, irow, icol); // original calibration factor + factor *= rundeprecal->GetBinContent(absID) / 10000. ; // correction dependent on T + + fEMCALRecoUtils->SetEMCALChannelRecalibrationFactor(ism,icol,irow,factor); + } // columns + } // rows + } // SM loop + + return 1; +} + + +//_____________________________________________________ +Int_t AliEMCALTenderSupply::InitTimeCalibration() +{ + // Initialising bad channel maps + AliVEvent *event = GetEvent(); + + if (!event) + return 0; + + if (fDebugLevel>0) + AliInfo("Initialising time calibration map"); + + // init default maps first + if (!fEMCALRecoUtils->GetEMCALTimeRecalibrationFactorsArray()) + fEMCALRecoUtils->InitEMCALTimeRecalibrationFactors() ; + + Int_t runBC = event->GetRunNumber(); + + AliOADBContainer *contBC = new AliOADBContainer(""); + if (fBasePath!="") + { //if fBasePath specified in the ->SetBasePath() + if (fDebugLevel>0) AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data())); + + TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read"); + if (!fbad || fbad->IsZombie()) + { + AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data())); + return 0; + } + + if (fbad) delete fbad; + + contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib"); + } + else + { // Else choose the one in the $ALICE_ROOT directory + if (fDebugLevel>0) AliInfo("Loading time calibration OADB from $ALICE_ROOT/OADB/EMCAL"); + + TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","read"); + if (!fbad || fbad->IsZombie()) + { + AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root was not found"); + return 0; + } + + if (fbad) delete fbad; + + contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib"); + } + + TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC); + if (!arrayBC) + { + AliError(Form("No external time calibration set for run number: %d", runBC)); + return 2; + } + + // Here, it looks for a specific pass + TString pass = fFilepass; + if (fFilepass=="calo_spc") pass ="pass1"; + TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(pass); + if (!arrayBCpass) + { + AliError(Form("No external time calibration set for: %d -%s", runBC,pass.Data())); + return 2; + } + + if (fDebugLevel>0) arrayBCpass->Print(); + + for(Int_t i = 0; i < 4; i++) + { + TH1F *h = fEMCALRecoUtils->GetEMCALChannelTimeRecalibrationFactors(i); + if (h) + delete h; + + h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i)); + + if (!h) + { + AliError(Form("Can not get hAllTimeAvBC%d",i)); + continue; + } + h->SetDirectory(0); + fEMCALRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h); + } + return 1; +} + +//_____________________________________________________ +void AliEMCALTenderSupply::UpdateCells() +{ + //Remove bad cells from the cell list + //Recalibrate energy and time cells + //This is required for later reclusterization + + AliVEvent *event = GetEvent(); + + if (!event) return ; + + AliVCaloCells *cells = event->GetEMCALCells(); + Int_t bunchCrossNo = event->GetBunchCrossNumber(); + + fEMCALRecoUtils->RecalibrateCells(cells, bunchCrossNo); + + // remove exotic cells - loop through cells and zero the exotic ones + // just like with bad cell rejection in reco utils (inside RecalibrateCells) + if (fRejectExoticCells) + { + Short_t absId =-1; + Double_t ecell = 0; + Double_t tcell = 0; + Double_t efrac = 0; + Int_t mclabel = -1; + Bool_t isExot = kFALSE; + + // loop through cells + Int_t nEMcell = cells->GetNumberOfCells() ; + for (Int_t iCell = 0; iCell < nEMcell; iCell++) + { + cells->GetCell(iCell, absId, ecell, tcell, mclabel, efrac); + + isExot = fEMCALRecoUtils->IsExoticCell(absId, cells, bunchCrossNo); + // zero if exotic + if (isExot) + cells->SetCell(iCell, absId, 0.0, -1.0, mclabel, efrac); + } // cell loop + } // reject exotic cells + + cells->Sort(); +} + +//_____________________________________________________ +TString AliEMCALTenderSupply::GetBeamType() +{ + // Get beam type : pp-AA-pA + // ESDs have it directly, AODs get it from hardcoded run number ranges + + AliVEvent *event = GetEvent(); + + if (!event) { + AliError("Couldn't retrieve event!"); + return ""; + } + + TString beamType; + + AliESDEvent *esd = dynamic_cast(event); + if (esd) { + const AliESDRun *run = esd->GetESDRun(); + beamType = run->GetBeamType(); + } + else + { + Int_t runNumber = event->GetRunNumber(); + if ((runNumber >= 136851 && runNumber <= 139517) // LHC10h + || (runNumber >= 166529 && runNumber <= 170593)) // LHC11h + { + beamType = "A-A"; + } + else + { + beamType = "p-p"; + } + } + + return beamType; +} + +//_____________________________________________________ +Int_t AliEMCALTenderSupply::InitRecParam() +{ + // Init reco params if not yet exist (probably shipped by the user already) + + if (fRecParam != 0) + return 2; + + TString beamType = GetBeamType(); + + // set some default reco params + fRecParam = new AliEMCALRecParam(); + fRecParam->SetClusteringThreshold(0.100); + fRecParam->SetMinECut(0.050); + + if (!fCalibrateTimeParamAvailable) { + fRecParam->SetTimeCut(250*1.e-9); + fRecParam->SetTimeMin(425*1.e-9); + fRecParam->SetTimeMax(825*1.e-9); + } else { + fRecParam->SetTimeCut(100*1.e-9); + fRecParam->SetTimeMin(-50*1.e-9); + fRecParam->SetTimeMax(50*1.e-9); + } + + if (beamType == "A-A") { + fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv2); + } else { + fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv1); + } + + return 0; +} + +//_____________________________________________________ +Bool_t AliEMCALTenderSupply::InitClusterization() +{ + // Initialing clusterization/unfolding algorithm and set all the needed parameters. + + AliVEvent *event = GetEvent(); + + if (!event) + return kFALSE; + + if (fDebugLevel>0) + AliInfo(Form("Initialising reclustering parameters: Clusterizer type: %d",fRecParam->GetClusterizerFlag())); + + //---setup clusterizer + if (fClusterizer) { + // avoid deleting fDigitsArr + fClusterizer->SetDigitsArr(0); + delete fClusterizer; + fClusterizer = 0; + } + if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1) + fClusterizer = new AliEMCALClusterizerv1 (fEMCALGeo); + else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2) + fClusterizer = new AliEMCALClusterizerv2(fEMCALGeo); + else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN) + { + AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fEMCALGeo); + clusterizer->SetNRowDiff(fRecParam->GetNRowDiff()); + clusterizer->SetNColDiff(fRecParam->GetNColDiff()); + fClusterizer = clusterizer; + } + else + { + AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag())); + return kFALSE; + } + + // Set the clustering parameters + fClusterizer->SetECAClusteringThreshold(fRecParam->GetClusteringThreshold()); + fClusterizer->SetECALogWeight (fRecParam->GetW0() ); + fClusterizer->SetMinECut (fRecParam->GetMinECut() ); + fClusterizer->SetUnfolding (fRecParam->GetUnfold() ); + fClusterizer->SetECALocalMaxCut (fRecParam->GetLocMaxCut() ); + fClusterizer->SetTimeCut (fRecParam->GetTimeCut() ); + fClusterizer->SetTimeMin (fRecParam->GetTimeMin() ); + fClusterizer->SetTimeMax (fRecParam->GetTimeMax() ); + fClusterizer->SetInputCalibrated (kTRUE ); + fClusterizer->SetJustClusters (kTRUE ); + + // In case of unfolding after clusterization is requested, set the corresponding parameters + if (fRecParam->GetUnfold()) + { + for (Int_t i = 0; i < 8; ++i) + { + fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i)); + } + for (Int_t i = 0; i < 3; ++i) + { + fClusterizer->SetPar5 (i, fRecParam->GetPar5(i)); + fClusterizer->SetPar6 (i, fRecParam->GetPar6(i)); + } + fClusterizer->InitClusterUnfolding(); + } + + fClusterizer->SetDigitsArr(fDigitsArr); + fClusterizer->SetOutput(0); + fClusterArr = const_cast(fClusterizer->GetRecPoints()); + return kTRUE; +} + +//_____________________________________________________ +void AliEMCALTenderSupply::FillDigitsArray() +{ + // Fill digits from cells to a TClonesArray. + + AliVEvent *event = GetEvent(); + + if (!event) + return; + + // In case of MC productions done before aliroot tag v5-02-Rev09 + // assing the cluster label to all the cells belonging to this cluster + // very rough + Int_t cellLabels[12672]; + if (fSetCellMCLabelFromCluster) + { + for (Int_t i = 0; i < 12672; i++) + { + cellLabels [i] = 0 ; + fOrgClusterCellId[i] =-1 ; + } + + Int_t nClusters = event->GetNumberOfCaloClusters(); + for (Int_t i = 0; i < nClusters; i++) + { + AliVCluster *clus = event->GetCaloCluster(i); + + if (!clus) continue; + + if (!clus->IsEMCAL()) continue ; + + Int_t label = clus->GetLabel(); + UShort_t * index = clus->GetCellsAbsId() ; + + for(Int_t icell=0; icell < clus->GetNCells(); icell++) + { + cellLabels [index[icell]] = label; + fOrgClusterCellId[index[icell]] = i ; // index of the original cluster + } + }// cluster loop + } + + fDigitsArr->Clear("C"); + AliVCaloCells *cells = event->GetEMCALCells(); + Int_t ncells = cells->GetNumberOfCells(); + for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell) + { + Double_t cellAmplitude=0, cellTime=0, efrac = 0; + Short_t cellNumber=0; + Int_t mcLabel=-1; + + if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime, mcLabel, efrac) != kTRUE) + break; + + // Do not add if energy already too low (some cells set to 0 if bad channels) + if (cellAmplitude < fRecParam->GetMinECut()) + continue; + + // If requested, do not include exotic cells + if (fEMCALRecoUtils->IsExoticCell(cellNumber,cells,event->GetBunchCrossNumber())) + continue; + + if (fSetCellMCLabelFromCluster) mcLabel = cellLabels[cellNumber]; + else if (fRemapMCLabelForAODs ) RemapMCLabelForAODs(mcLabel); + + if (mcLabel > 0 && efrac < 1e-6) efrac = 1; + + new((*fDigitsArr)[idigit]) AliEMCALDigit(mcLabel, mcLabel, cellNumber, + (Float_t)cellAmplitude, (Float_t)cellTime, + AliEMCALDigit::kHG,idigit, 0, 0, efrac*cellAmplitude); + idigit++; + } +} + +//_____________________________________________________ +void AliEMCALTenderSupply::Clusterize() +{ + // Clusterize. + + fClusterizer->Digits2Clusters(""); +} + +//_____________________________________________________ +void AliEMCALTenderSupply::UpdateClusters() +{ + // Update ESD cluster list. + + AliVEvent *event = GetEvent(); + + if (!event) + return; + + TClonesArray *clus = dynamic_cast(event->FindListObject("caloClusters")); + if (!clus) + clus = dynamic_cast(event->FindListObject("CaloClusters")); + if (!clus) + { + AliError(" Null pointer to calo clusters array, returning"); + return; + } + + // Before destroying the orignal list, assign to the rec points the MC labels + // of the original clusters, if requested + if (fSetCellMCLabelFromCluster == 2) + SetClustersMCLabelFromOriginalClusters() ; + + Int_t nents = clus->GetEntriesFast(); + for (Int_t i=0; i < nents; ++i) + { + AliVCluster *c = dynamic_cast(clus->At(i)); + if (!c) + continue; + if (c->IsEMCAL()) + { + delete clus->RemoveAt(i); + } + } + + clus->Compress(); + + RecPoints2Clusters(clus); +} + +//_____________________________________________________ +void AliEMCALTenderSupply::RecPoints2Clusters(TClonesArray *clus) +{ + // Convert AliEMCALRecoPoints to AliESDCaloClusters/AliAODCaloClusters. + // Cluster energy, global position, cells and their amplitude fractions are restored. + + AliVEvent *event = GetEvent(); + + if (!event) + return; + + Int_t ncls = fClusterArr->GetEntriesFast(); + for(Int_t i=0, nout=clus->GetEntriesFast(); i < ncls; ++i) + { + AliEMCALRecPoint *recpoint = static_cast(fClusterArr->At(i)); + + Int_t ncellsTrue = 0; + const Int_t ncells = recpoint->GetMultiplicity(); + UShort_t absIds[ncells]; + Double32_t ratios[ncells]; + Int_t *dlist = recpoint->GetDigitsList(); + Float_t *elist = recpoint->GetEnergiesList(); + for (Int_t c = 0; c < ncells; ++c) + { + AliEMCALDigit *digit = static_cast(fDigitsArr->At(dlist[c])); + absIds[ncellsTrue] = digit->GetId(); + ratios[ncellsTrue] = elist[c]/digit->GetAmplitude(); + if (ratios[ncellsTrue] < 0.001) + continue; + ++ncellsTrue; + } + + if (ncellsTrue < 1) + { + AliWarning("Skipping cluster with no cells"); + continue; + } + + // calculate new cluster position + TVector3 gpos; + recpoint->GetGlobalPosition(gpos); + Float_t g[3]; + gpos.GetXYZ(g); + + AliVCluster *c = static_cast(clus->New(nout++)); + c->SetID(nout-1); + c->SetType(AliVCluster::kEMCALClusterv1); + c->SetE(recpoint->GetEnergy()); + c->SetPosition(g); + c->SetNCells(ncellsTrue); + c->SetDispersion(recpoint->GetDispersion()); + c->SetEmcCpvDistance(-1); //not yet implemented + c->SetChi2(-1); //not yet implemented + c->SetTOF(recpoint->GetTime()) ; //time-of-flight + c->SetNExMax(recpoint->GetNExMax()); //number of local maxima + Float_t elipAxis[2]; + recpoint->GetElipsAxis(elipAxis); + c->SetM02(elipAxis[0]*elipAxis[0]) ; + c->SetM20(elipAxis[1]*elipAxis[1]) ; + c->SetCellsAbsId(absIds); + c->SetCellsAmplitudeFraction(ratios); + + //MC labels + Int_t parentMult = 0; + Int_t *parentList = recpoint->GetParents(parentMult); + if (parentMult > 0) c->SetLabel(parentList, parentMult); + + } +} + +//___________________________________________________________ +void AliEMCALTenderSupply::RemapMCLabelForAODs(Int_t & label) +{ + // MC label for Cells not remapped after ESD filtering, do it here. + + if (label < 0) return; + + AliAODEvent * evt = dynamic_cast (GetEvent()) ; + if (!evt) return ; + + TClonesArray * arr = dynamic_cast(evt->FindListObject("mcparticles")) ; + if (!arr) return ; + + if (label < arr->GetEntriesFast()) + { + AliAODMCParticle * particle = dynamic_cast(arr->At(label)); + if (!particle) return ; + + if (label == particle->Label()) return ; // label already OK + } + + // loop on the particles list and check if there is one with the same label + for (Int_t ind = 0; ind < arr->GetEntriesFast(); ind++) + { + AliAODMCParticle * particle = dynamic_cast(arr->At(ind)); + if (!particle) continue ; + + if (label == particle->Label()) + { + label = ind; + return; + } + } + + label = -1; +} + +//_____________________________________________________________________________________________ +void AliEMCALTenderSupply::SetClustersMCLabelFromOriginalClusters() +{ + // Get the original clusters that contribute to the new rec point cluster, + // assign the labels of such clusters to the new rec point cluster. + // Only approximatedly valid when output are V1 clusters, or input/output clusterizer + // are the same handle with care + // Copy from same method in AliAnalysisTaskEMCALClusterize, but here modify the recpoint and + // not the output calocluster + + Int_t ncls = fClusterArr->GetEntriesFast(); + for(Int_t irp=0; irp < ncls; ++irp) + { + TArrayI clArray(300) ; //Weird if more than a few clusters are in the origin ... + clArray.Reset(); + Int_t nClu = 0; + Int_t nLabTotOrg = 0; + Float_t emax = -1; + Int_t idMax = -1; + + AliEMCALRecPoint *clus = static_cast(fClusterArr->At(irp)); + + //Find the clusters that originally had the cells + const Int_t ncells = clus->GetMultiplicity(); + Int_t *digList = clus->GetDigitsList(); + + for (Int_t iLoopCell = 0 ; iLoopCell < ncells ; iLoopCell++) + { + AliEMCALDigit *digit = static_cast(fDigitsArr->At(digList[iLoopCell])); + Int_t idCell = digit->GetId(); + + if (idCell>=0) + { + Int_t idCluster = fOrgClusterCellId[idCell]; + Bool_t set = kTRUE; + for (Int_t icl =0; icl < nClu; icl++) + { + if (((Int_t)clArray.GetAt(icl))==-1) continue; + if (idCluster == ((Int_t)clArray.GetAt(icl))) set = kFALSE; + } + if (set && idCluster >= 0) + { + clArray.SetAt(idCluster,nClu++); + nLabTotOrg+=(GetEvent()->GetCaloCluster(idCluster))->GetNLabels(); + + //Search highest E cluster + AliVCluster * clOrg = GetEvent()->GetCaloCluster(idCluster); + if (emax < clOrg->E()) + { + emax = clOrg->E(); + idMax = idCluster; + } + } + } + }// cell loop + + // Put the first in the list the cluster with highest energy + if (idMax != ((Int_t)clArray.GetAt(0))) // Max not at first position + { + Int_t maxIndex = -1; + Int_t firstCluster = ((Int_t)clArray.GetAt(0)); + for (Int_t iLoopCluster = 0 ; iLoopCluster < nClu ; iLoopCluster++) + { + if (idMax == ((Int_t)clArray.GetAt(iLoopCluster))) maxIndex = iLoopCluster; + } + + if (firstCluster >=0 && idMax >=0) + { + clArray.SetAt(idMax,0); + clArray.SetAt(firstCluster,maxIndex); + } + } + + // Get the labels list in the original clusters, assign all to the new cluster + TArrayI clMCArray(nLabTotOrg) ; + clMCArray.Reset(); + + Int_t nLabTot = 0; + for (Int_t iLoopCluster = 0 ; iLoopCluster < nClu ; iLoopCluster++) + { + Int_t idCluster = (Int_t) clArray.GetAt(iLoopCluster); + AliVCluster * clOrg = GetEvent()->GetCaloCluster(idCluster); + Int_t nLab = clOrg->GetNLabels(); + + for (Int_t iLab = 0 ; iLab < nLab ; iLab++) + { + Int_t lab = clOrg->GetLabelAt(iLab) ; + if (lab>=0) + { + Bool_t set = kTRUE; + for(Int_t iLabTot =0; iLabTot < nLabTot; iLabTot++) + { + if (lab == ((Int_t)clMCArray.GetAt(iLabTot))) set = kFALSE; + } + if (set) clMCArray.SetAt(lab,nLabTot++); + } + } + }// cluster loop + + // Set the final list of labels to rec point + + Int_t *labels = new Int_t[nLabTot]; + for(Int_t il = 0; il < nLabTot; il++) labels[il] = clMCArray.GetArray()[il]; + clus->SetParents(nLabTot,labels); + + } // rec point array +} + +//_____________________________________________________ +void AliEMCALTenderSupply::GetPass() +{ + // Get passx from filename + + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + fInputTree = mgr->GetTree(); + + if (!fInputTree) + { + AliError("Pointer to tree = 0, returning"); + return; + } + + fInputFile = fInputTree->GetCurrentFile(); + if (!fInputFile) { + AliError("Null pointer input file, returning"); + return; + } + + TString fname(fInputFile->GetName()); + if (fname.Contains("pass1")) fFilepass = TString("pass1"); + else if (fname.Contains("pass2")) fFilepass = TString("pass2"); + else if (fname.Contains("pass3")) fFilepass = TString("pass3"); + else if (fname.Contains("pass4")) fFilepass = TString("pass4"); + else if (fname.Contains("pass5")) fFilepass = TString("pass5"); + else if (fname.Contains("LHC11c") && + fname.Contains("spc_calo")) fFilepass = TString("spc_calo"); + else if (fname.Contains("calo") || fname.Contains("high_lumi")) + + { + //printf("AliEMCALTenderSupply::GetPass() - Path contains or , set as \n"); + fFilepass = TString("pass1"); + } + else if (fname.Contains("LHC14a1a")) fFilepass = TString("LHC14a1a"); + else + { + AliError(Form("Pass number string not found: %s", fname.Data())); + return; + } +} diff --git a/TENDER/TenderSupplies/AliEMCALTenderSupply.h b/TENDER/TenderSupplies/AliEMCALTenderSupply.h new file mode 100644 index 00000000000..f7e60612b94 --- /dev/null +++ b/TENDER/TenderSupplies/AliEMCALTenderSupply.h @@ -0,0 +1,275 @@ +#ifndef ALIEMCALTENDERSUPPLY_H +#define ALIEMCALTENDERSUPPLY_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +//////////////////////////////////////////////////////////////////////// +// // +// EMCAL tender, apply corrections to EMCAl clusters // +// and do track matching. // +// Author: Deepa Thomas (Utrecht University) // +// Later mods/rewrite: Jiri Kral (University of Jyvaskyla) // +// S. Aiola, C. Loizides : Make it work for AODs // +// // +//////////////////////////////////////////////////////////////////////// + +#include "AliTenderSupply.h" + +class TTree; +class TClonesArray; + +class AliVCluster; +class AliEMCALRecoUtils; +class AliEMCALGeometry; +class TGeoHMatrix; +class TTree; +class TFile; +class TString; +class AliEMCALClusterizer; +class AliEMCALAfterBurnerUF; +class AliEMCALRecParam; +class AliAnalysisTaskSE; +class AliVEvent; + +class AliEMCALTenderSupply: public AliTenderSupply { + +public: + AliEMCALTenderSupply(); + AliEMCALTenderSupply(const char *name, const AliTender *tender=NULL); + AliEMCALTenderSupply(const char *name, AliAnalysisTaskSE *task); + virtual ~AliEMCALTenderSupply(); + + enum NonlinearityFunctions{kPi0MC=0,kPi0GammaGamma=1,kPi0GammaConversion=2,kNoCorrection=3,kBeamTest=4,kBeamTestCorrected=5}; + enum MisalignSettings{kdefault=0,kSurveybyS=1,kSurveybyM=2}; + + virtual void Init(); + virtual void ProcessEvent(); + + void SetTask(AliAnalysisTaskSE *task) { fTask = task ;} + void SetDefaults(); + + void SetEMCALGeometryName(const char *name) { fEMCALGeoName = name ;} + TString EMCALGeometryName() const { return fEMCALGeoName ;} + + void SetDebugLevel(Int_t level) { fDebugLevel=level ;} + + void SetBasePath(const Char_t *basePath) { fBasePath = basePath ;} + + void SetConfigFileName(const char *name) { fConfigName = name ;} + + void SetNonLinearityFunction(Int_t fun) { fNonLinearFunc = fun ;} + Int_t GetNonLinearityFunction() const { return fNonLinearFunc ;} + + void SetNonLinearityThreshold(Int_t threshold) { fNonLinearThreshold = threshold ;} //only for Alexei's non linearity correction + Int_t GetNonLinearityThreshold() const { return fNonLinearThreshold ;} + + void SwitchOnNonLinearityCorrection() { fDoNonLinearity = kTRUE ;} + void SwitchOffNonLinearityCorrection() { fDoNonLinearity = kFALSE ;} + + void SwitchOnReCalibrateCluster() { fReCalibCluster = kTRUE ;} + void SwitchOffReCalibrateCluster() { fReCalibCluster = kFALSE ;} + + void SwitchOnRecalculateClusPos() { fRecalClusPos = kTRUE ;} + void SwitchOffRecalculateClusPos() { fRecalClusPos = kFALSE ;} + + void SetMisalignmentMatrixSurvey(Int_t misalignSurvey) { fMisalignSurvey = misalignSurvey ;} + Int_t GetMisalignmentMatrixSurvey() const { return fMisalignSurvey ;} + + void SwitchOnCellFiducialRegion() { fFiducial = kTRUE ;} + void SwitchOffCellFiducialRegion() { fFiducial = kFALSE ;} + + void SetNumberOfCellsFromEMCALBorder(Int_t n) { fNCellsFromEMCALBorder = n ;} + Int_t GetNumberOfCellsFromEMCALBorder() const { return fNCellsFromEMCALBorder ;} + + void SwitchOnRecalDistBadChannel() { fRecalDistToBadChannels = kTRUE ;} + void SwitchOffRecalDistBadChannel() { fRecalDistToBadChannels = kFALSE ;} + + void SwitchOnRecalShowerShape() { fRecalShowerShape = kTRUE ;} + void SwitchOffRecalShowerShape() { fRecalShowerShape = kFALSE ;} + + Float_t GetRCut() const { return fRcut ;} + void SetRCut(Float_t rcut) { fRcut = rcut ;} + + Double_t GetMass() const { return fMass ;} + void SetMass(Double_t mass) { fMass = mass ;} + + Double_t GetStep() const { return fStep ;} + void SetStep(Double_t step) { fStep = step ;} + + Double_t GetEtaCut() const { return fEtacut ;} + void SetEtaCut(Double_t eta) { fEtacut = eta ;} + + Double_t GetPhiCut() const { return fPhicut ;} + void SetPhiCut(Double_t phi) { fPhicut = phi ;} + + Float_t GetExoticCellFraction() const { return fExoticCellFraction ;} + void SetExoticCellFraction(Float_t f) { fExoticCellFraction = f ;} + + Float_t GetExoticCellDiffTime() const { return fExoticCellDiffTime ;} + void SetExoticCellDiffTime(Float_t f) { fExoticCellDiffTime = f ;} + + Float_t GetExoticCellMinAmplitude() const { return fExoticCellMinAmplitude ;} + void SetExoticCellMinAmplitude(Float_t f) { fExoticCellMinAmplitude = f ;} + + void SwitchOnReclustering() { fReClusterize = kTRUE ;} + void SwitchOffReclustering() { fReClusterize = kFALSE ;} + + void SwitchOnCutEtaPhiSum() { fCutEtaPhiSum=kTRUE; fCutEtaPhiSeparate=kFALSE ;} + void SwitchOnCutEtaPhiSeparate() { fCutEtaPhiSeparate=kTRUE; fCutEtaPhiSum=kFALSE ;} + + void SwitchOnLoadOwnGeometryMatrices() { fLoadGeomMatrices = kTRUE ;} + void SwitchOffLoadOwnGeometryMatrices() { fLoadGeomMatrices = kFALSE ;} + void SetGeometryMatrixInSM(TGeoHMatrix* m, Int_t i) { fEMCALMatrix[i] = m ;} + + AliEMCALRecParam *GetRecParam() const { return fRecParam ;} + void SetRecParam(AliEMCALRecParam *p) { fRecParam = p ;} + + AliEMCALRecoUtils *GetRecoUtils() const { return fEMCALRecoUtils ;} + void SetRecoUtils(AliEMCALRecoUtils *r) { fEMCALRecoUtils = r ;} + + void SwitchOnUpdateCell() { fUpdateCell = kTRUE ;} + void SwitchOffUpdateCell() { fUpdateCell = kFALSE ;} + + void SwitchOnBadCellRemove() { fBadCellRemove = kTRUE ;} + void SwitchOffBadCellRemove() { fBadCellRemove = kFALSE ;} + + void SwitchOnClusterBadChannelCheck() { fClusterBadChannelCheck = kTRUE ;} + void SwitchOffClusterBadChannelCheck() { fClusterBadChannelCheck = kFALSE ;} + + void SwitchOnExoticCellRemove() { fRejectExoticCells = kTRUE ;} + void SwitchOffExoticCellRemove() { fRejectExoticCells = kFALSE ;} + + void SwitchOnClusterExoticChannelCheck() { fRejectExoticClusters = kTRUE ;} + void SwitchOffClusterExoticChannelCheck() { fRejectExoticClusters = kFALSE ;} + + void SwitchOnCalibrateEnergy() { fCalibrateEnergy = kTRUE ;} + void SwitchOffCalibrateEnergy() { fCalibrateEnergy = kFALSE ;} + + void SwitchOnCalibrateTime() { fCalibrateTime = kTRUE ;} + void SwitchOffCalibrateTime() { fCalibrateTime = kFALSE ;} + + void SwitchOnUpdateCellOnly() { fDoUpdateOnly = kTRUE ;} + void SwitchOffUpdateCellOnly() { fDoUpdateOnly = kFALSE ;} + + void SwitchOnTrackMatch() { fDoTrackMatch = kTRUE ;} + void SwitchOffTrackMatch() { fDoTrackMatch = kFALSE ;} + + void SetPass(const char* p) { fFilepass = p; fGetPassFromFileName = kFALSE; } + void UnsetPass() { fFilepass = ""; fGetPassFromFileName = kTRUE; } + + //MC label methods + + void RemapMCLabelForAODs(Int_t &label); + void SwitchOnRemapMCLabelForAODs() { fRemapMCLabelForAODs = kTRUE ; } + void SwitchOffRemapMCLabelForAODs() { fRemapMCLabelForAODs = kFALSE ; } + + void SetClustersMCLabelFromOriginalClusters() ; + void SwitchOnUseClusterMCLabelForCell(Int_t opt = 2) { fSetCellMCLabelFromCluster = opt ; } + void SwitchOffUseClusterMCLabelForCell() { fSetCellMCLabelFromCluster = 0 ; } + + // Switch on/off the automatic setting of different calibrations, only experts + void SwitchOnUseAutomaticRecalibParam() { fUseAutomaticRecalib = kTRUE ; } + void SwitchOnUseAutomaticRunDepRecalibParam() { fUseAutomaticRunDepRecalib = kTRUE ; } + void SwitchOnUseAutomaticTimeCalibParam() { fUseAutomaticTimeCalib = kTRUE ; } + void SwitchOnUseAutomaticRecParam() { fUseAutomaticRecParam = kTRUE ; } + + void SwitchOffUseAutomaticRecalibParam() { fUseAutomaticRecalib = kFALSE ; } + void SwitchOffUseAutomaticRunDepRecalibParam() { fUseAutomaticRunDepRecalib = kFALSE ; } + void SwitchOffUseAutomaticTimeCalibParam() { fUseAutomaticTimeCalib = kFALSE ; } + void SwitchOffUseAutomaticRecParam() { fUseAutomaticRecParam = kFALSE ; } + +private: + + AliVEvent* GetEvent(); + TString GetBeamType(); + Bool_t RunChanged() const; + Int_t InitBadChannels(); + Bool_t InitClusterization(); + Int_t InitRecParam(); + Bool_t InitMisalignMatrix(); + Int_t InitRecalib(); + Int_t InitRunDepRecalib(); + Int_t InitTimeCalibration(); + void Clusterize(); + void FillDigitsArray(); + void GetPass(); + void RecPoints2Clusters(TClonesArray *clus); + void RecalibrateCells(); + void UpdateCells(); + void UpdateClusters(); + + AliAnalysisTaskSE *fTask; // analysis task + Int_t fRun; // current run number + AliEMCALGeometry *fEMCALGeo; // EMCAL geometry + TString fEMCALGeoName; // name of geometry to use. + AliEMCALRecoUtils *fEMCALRecoUtils; // pointer to EMCAL utilities for clusterization + TString fConfigName; // name of analysis configuration file + Int_t fDebugLevel; // debug level + Int_t fNonLinearFunc; // non linearity function + Int_t fNonLinearThreshold; // non linearity threshold value for kBeamTesh non linearity function + Bool_t fReCalibCluster; // switch for Recalibrate clusters + Bool_t fUpdateCell; // flag cell update + Bool_t fCalibrateEnergy; // flag cell energy calibration + Bool_t fCalibrateTime; // flag cell time calibration + Bool_t fCalibrateTimeParamAvailable; // Check if time calib param are available to set properly time cuts + Bool_t fDoNonLinearity; // nNon linearity correction flag + Bool_t fBadCellRemove; // zero bad cells + Bool_t fRejectExoticCells; // reject exotic cells + Bool_t fRejectExoticClusters; // recect clusters with exotic cells + Bool_t fClusterBadChannelCheck; // check clusters for bad channels + TGeoHMatrix *fEMCALMatrix[12]; // geometry matrices with misalignments + Bool_t fRecalClusPos; // switch for applying missalignment + Bool_t fFiducial; // switch for checking cells in the fiducial region + Int_t fNCellsFromEMCALBorder; // number os cells from EMCAL border + Bool_t fRecalDistToBadChannels; // switch for recalculation cluster position from bad channel + Bool_t fRecalShowerShape; // switch for recalculation of the shower shape + TTree *fInputTree; //!input data tree + TFile *fInputFile; //!input data file + Bool_t fGetPassFromFileName; // get fFilepass from file name + TString fFilepass; // input data pass number + Double_t fMass; // mass for track matching + Double_t fStep; // step size during track matching + Bool_t fCutEtaPhiSum; // swicth to apply residual cut together + Bool_t fCutEtaPhiSeparate; // swicth to apply residual cut separately + Float_t fRcut; // residual cut for track matching + Float_t fEtacut; // eta cut for track matching + Float_t fPhicut; // phi cut for track matching + TString fBasePath; // base folder path to get root files + Bool_t fReClusterize; // switch for reclustering + AliEMCALClusterizer *fClusterizer; //!clusterizer + Bool_t fGeomMatrixSet; // set geometry matrices only once, for the first event. + Bool_t fLoadGeomMatrices; // matrices set from configuration, not get from geometry.root or from ESDs/AODs + AliEMCALRecParam *fRecParam; // reconstruction parameters container + Bool_t fDoTrackMatch; // do track matching + Bool_t fDoUpdateOnly; // do only update of cells + AliEMCALAfterBurnerUF *fUnfolder; //!unfolding procedure + TClonesArray *fDigitsArr; //!digits array + TObjArray *fClusterArr; //!recpoints array + Int_t fMisalignSurvey; // misalignment matrix survey + Float_t fExoticCellFraction; // good cell if fraction < 1-ecross/ecell + Float_t fExoticCellDiffTime; // if time of candidate to exotic and close cell is too different (in ns), it must be noisy, set amp to 0 + Float_t fExoticCellMinAmplitude; // check for exotic only if amplitud is larger than this value + + // MC labels + Int_t fOrgClusterCellId[12672]; // Array ID of cluster to wich the cell belongs in unmodified clusters + + Int_t fSetCellMCLabelFromCluster; // Use cluster MC label as cell label: + // 0 - get the MC label stored in cells + // 1 - assign to the cell the MC lable of the cluster + // 2 - get the original clusters id, add all the MC labels + TClonesArray * fTempClusterArr ; //! Temporal clusters array to recover the MC of original cluster if fSetCellMCLabelFromCluster=2 + Bool_t fRemapMCLabelForAODs ; // Remap AOD cells MC label + + // Change to false if experts + Bool_t fUseAutomaticRecalib; // On by default the check in the OADB of the energy recalibration + Bool_t fUseAutomaticRunDepRecalib; // On by default the check in the OADB of the run dependent energy recalibration + Bool_t fUseAutomaticTimeCalib; // On by default the check in the OADB of the time recalibration + Bool_t fUseAutomaticRecParam; // On the auto setting of the rec param + + AliEMCALTenderSupply( const AliEMCALTenderSupply&c); + AliEMCALTenderSupply& operator= (const AliEMCALTenderSupply&c); + + ClassDef(AliEMCALTenderSupply, 17); // EMCAL tender task +}; +#endif diff --git a/TENDER/TenderSupplies/AliHMPIDTenderSupply.cxx b/TENDER/TenderSupplies/AliHMPIDTenderSupply.cxx new file mode 100644 index 00000000000..ae87aa0fb64 --- /dev/null +++ b/TENDER/TenderSupplies/AliHMPIDTenderSupply.cxx @@ -0,0 +1,103 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + + +/////////////////////////////////////////////////////////////////////////////// +// // +// HMPID tender: - recalculate pid bit using tighter cuts +// - this is needed for all 2010 and 11a-c data +// +// +// Contacts: Giacomo.Volpe@ba.infn.it // +// Jens.Wiechula@cern.ch // +/////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliHMPIDTenderSupply.h" + +ClassImp(AliHMPIDTenderSupply) + +AliHMPIDTenderSupply::AliHMPIDTenderSupply() : +AliTenderSupply() +{ + // + // default ctor + // +} + +//_____________________________________________________ +AliHMPIDTenderSupply::AliHMPIDTenderSupply(const char *name, const AliTender *tender) : +AliTenderSupply(name,tender) +{ + // + // named ctor + // +} + +//_____________________________________________________ +void AliHMPIDTenderSupply::Init() +{ + // Initialise HMPID tender + +} + +//_____________________________________________________ +void AliHMPIDTenderSupply::ProcessEvent() +{ + // + // recalculate HMPIDpid bit + // + + + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + + // re-evaluate the HMPIDpid bit for all tracks + Int_t ntracks=event->GetNumberOfTracks(); + for(Int_t itrack = 0; itrack < ntracks; itrack++){ + AliESDtrack *track=event->GetTrack(itrack); + if (!itrack) continue; + //reset pid bit first + track->ResetStatus(AliESDtrack::kHMPIDpid); + + Float_t xPc=0., yPc=0., xMip=0., yMip=0., thetaTrk=0., phiTrk=0.; + Int_t nPhot=0, qMip=0; + + track->GetHMPIDtrk(xPc,yPc,thetaTrk,phiTrk); + track->GetHMPIDmip(xMip,yMip,qMip,nPhot); + // + //make cuts, just an example, THIS NEEDS TO BE CHANGED + // + //if ((track->GetStatus()&AliESDtrack::kHMPIDout)!=AliESDtrack::kHMPIDout) continue; + + Float_t dist = TMath::Sqrt((xPc-xMip)*(xPc-xMip) + (yPc-yMip)*(yPc-yMip)); + + if(dist > 0.7 || nPhot> 30 || qMip < 100 ) continue; + + //set pid bit, track was accepted + track->SetStatus(AliESDtrack::kHMPIDpid); + + } + + +} diff --git a/TENDER/TenderSupplies/AliHMPIDTenderSupply.h b/TENDER/TenderSupplies/AliHMPIDTenderSupply.h new file mode 100644 index 00000000000..9f481d0b893 --- /dev/null +++ b/TENDER/TenderSupplies/AliHMPIDTenderSupply.h @@ -0,0 +1,40 @@ +#ifndef ALIHMPIDTENDERSUPPLY_H +#define ALIHMPIDTENDERSUPPLY_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +//////////////////////////////////////////////////////////////////////// +// // +// HMPID tender, reapply pid on the fly // +// // +//////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +class AliESDpid; + +class AliHMPIDTenderSupply: public AliTenderSupply { + +public: + AliHMPIDTenderSupply(); + AliHMPIDTenderSupply(const char *name, const AliTender *tender=NULL); + + virtual ~AliHMPIDTenderSupply(){;} + + virtual void Init(); + virtual void ProcessEvent(); + + +private: + + AliHMPIDTenderSupply(const AliHMPIDTenderSupply&c); + AliHMPIDTenderSupply& operator= (const AliHMPIDTenderSupply&c); + + ClassDef(AliHMPIDTenderSupply, 1); +}; + + +#endif diff --git a/TENDER/TenderSupplies/AliPHOSTenderSupply.cxx b/TENDER/TenderSupplies/AliPHOSTenderSupply.cxx new file mode 100644 index 00000000000..78c3a062b48 --- /dev/null +++ b/TENDER/TenderSupplies/AliPHOSTenderSupply.cxx @@ -0,0 +1,970 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + + +/////////////////////////////////////////////////////////////////////////////// +// // +// PHOS tender, recalibrate PHOS clusters // +// and do track matching // +// Author : Dmitri Peressounko (RRC KI) // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "TROOT.h" +#include "TH2.h" +#include "TFile.h" + +#include +#include +#include +#include +#include +#include +#include +#include "AliMagF.h" +#include "TGeoGlobalMagField.h" + +#include "AliVCluster.h" +#include "AliPHOSTenderSupply.h" +#include "AliPHOSCalibData.h" +#include "AliPHOSGeometry.h" +#include "AliPHOSEsdCluster.h" +#include "AliPHOSAodCluster.h" +#include "AliOADBContainer.h" +#include "AliAODCaloCells.h" +#include "AliESDCaloCells.h" + +ClassImp(AliPHOSTenderSupply) + +AliPHOSTenderSupply::AliPHOSTenderSupply() : + AliTenderSupply() + ,fOCDBpass("local://OCDB") + ,fNonlinearityVersion("Default") + ,fPHOSGeo(0x0) + ,fRecoPass(-1) //to be defined + ,fUsePrivateBadMap(0) + ,fUsePrivateCalib(0) + ,fPHOSCalibData(0x0) + ,fTask(0x0) + ,fIsMC(kFALSE) + ,fMCProduction("") +{ + // + // default ctor + // + for(Int_t i=0;i<10;i++)fNonlinearityParams[i]=0. ; + for(Int_t mod=0;mod<5;mod++)fPHOSBadMap[mod]=0x0 ; +} + +//_____________________________________________________ +AliPHOSTenderSupply::AliPHOSTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender) + ,fOCDBpass("alien:///alice/cern.ch/user/p/prsnko/PHOSrecalibrations/") + ,fNonlinearityVersion("Default") + ,fPHOSGeo(0x0) + ,fRecoPass(-1) //to be defined + ,fUsePrivateBadMap(0) + ,fUsePrivateCalib(0) + ,fPHOSCalibData(0x0) + ,fTask(0x0) + ,fIsMC(kFALSE) + ,fMCProduction("") +{ + // + // named ctor + // + for(Int_t i=0;i<10;i++)fNonlinearityParams[i]=0. ; + for(Int_t mod=0;mod<5;mod++)fPHOSBadMap[mod]=0x0 ; +} + +//_____________________________________________________ +AliPHOSTenderSupply::~AliPHOSTenderSupply() +{ + //Destructor + if(fPHOSCalibData) + delete fPHOSCalibData; + fPHOSCalibData=0x0 ; +} + +//_____________________________________________________ +void AliPHOSTenderSupply::InitTender() +{ + // + // Initialise PHOS tender + // + Int_t runNumber = 0; + if(fTender) + runNumber = fTender->GetRun(); + else{ + if(!fTask){ + AliError("Neither Tender not Taks was not set") ; + return ; + } + AliAODEvent *aod = dynamic_cast(fTask->InputEvent()) ; + if(aod) + runNumber = aod->GetRunNumber() ; + else{ + AliESDEvent *esd = dynamic_cast(fTask->InputEvent()) ; + if(esd) + runNumber = esd->GetRunNumber() ; + else{ + AliError("Taks does not contain neither ESD nor AOD") ; + return ; + } + } + } + + //In MC always reco pass 1 + if(fIsMC) + fRecoPass=1 ; + + if(fRecoPass<0){ //not defined yet + // read if from filename. + AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); + TTree * t = mgr->GetTree(); + if(t){ + TFile * f = t->GetCurrentFile() ; + if(f){ + TString fname(f->GetName()); + if(fname.Contains("pass1")) + fRecoPass=1; + else + if(fname.Contains("pass2")) + fRecoPass=2; + else + if(fname.Contains("pass3")) + fRecoPass=3; + else + if(fname.Contains("pass4")) + fRecoPass=4; + } + } + if(fRecoPass<0){ + AliError("Can not find pass number from file name, set it manually"); + } + } + + //Init geometry + if(!fPHOSGeo){ + AliOADBContainer geomContainer("phosGeo"); + if(fIsMC) //use excatly the same geometry as in simulation + geomContainer.InitFromFile("$ALICE_ROOT/OADB/PHOS/PHOSMCGeometry.root","PHOSMCRotationMatrixes"); + else //Use best approaximation to real geometry + geomContainer.InitFromFile("$ALICE_ROOT/OADB/PHOS/PHOSGeometry.root","PHOSRotationMatrixes"); + TObjArray *matrixes = (TObjArray*)geomContainer.GetObject(runNumber,"PHOSRotationMatrixes"); + fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ; + for(Int_t mod=0; mod<5; mod++) { + if(!matrixes->At(mod)) continue; + fPHOSGeo->SetMisalMatrix(((TGeoHMatrix*)matrixes->At(mod)),mod) ; + printf(".........Adding Matrix(%d), geo=%p\n",mod,fPHOSGeo) ; + ((TGeoHMatrix*)matrixes->At(mod))->Print() ; + } + } + + //Init Bad channels map + if(!fUsePrivateBadMap){ + AliOADBContainer badmapContainer(Form("phosBadMap")); + badmapContainer.InitFromFile("$ALICE_ROOT/OADB/PHOS/PHOSBadMaps.root","phosBadMap"); + TObjArray *maps = (TObjArray*)badmapContainer.GetObject(runNumber,"phosBadMap"); + if(!maps){ + AliError(Form("Can not read Bad map for run %d. \n You may choose to use your map with ForceUsingBadMap()\n",runNumber)) ; + } + else{ + AliInfo(Form("Setting PHOS bad map with name %s \n",maps->GetName())) ; + for(Int_t mod=0; mod<5;mod++){ + if(fPHOSBadMap[mod]) + delete fPHOSBadMap[mod] ; + TH2I * h = (TH2I*)maps->At(mod) ; + if(h) + fPHOSBadMap[mod]=new TH2I(*h) ; + } + } + } + + if(!fUsePrivateCalib){ + if(fIsMC){ //re/de-calibration for MC productions + //Init recalibration + AliOADBContainer calibContainer("phosRecalibration"); + calibContainer.InitFromFile("$ALICE_ROOT/OADB/PHOS/PHOSMCCalibrations.root","phosRecalibration"); + + TObjArray *recalib = (TObjArray*)calibContainer.GetObject(runNumber,"PHOSRecalibration"); + if(!recalib){ + AliFatal(Form("Can not read calibrations for run %d\n. You may choose your specific calibration with ForceUsingCalibration()\n",runNumber)) ; + } + else{ + //Now try to find object with proper name + for(Int_t i=0; iGetEntriesFast(); i++){ + AliPHOSCalibData * tmp = (AliPHOSCalibData*)recalib->At(i) ; + if(fMCProduction.CompareTo(tmp->GetName())==0){ + fPHOSCalibData = tmp ; + break ; + } + } + if(!fPHOSCalibData) { + AliFatal(Form("Can not find calibration for run %d, and name %s \n",runNumber, fMCProduction.Data())) ; + } + } + + } + else{ //real data + //Init recalibration + //Check the pass1-pass2-pass3 reconstruction + AliOADBContainer calibContainer("phosRecalibration"); + calibContainer.InitFromFile("$ALICE_ROOT/OADB/PHOS/PHOSCalibrations.root","phosRecalibration"); + TObjArray *recalib = (TObjArray*)calibContainer.GetObject(runNumber,"PHOSRecalibration"); + if(!recalib){ + AliFatal(Form("Can not read calibrations for run %d\n. You may choose your specific calibration with ForceUsingCalibration()\n",runNumber)) ; + } + else{ + fPHOSCalibData = (AliPHOSCalibData*)recalib->At(fRecoPass-1) ; + if(!fPHOSCalibData) { + AliFatal(Form("Can not find calibration for run %d, pass %d \n",runNumber, fRecoPass)) ; + } + } + } + } + +} + +//_____________________________________________________ +void AliPHOSTenderSupply::ProcessEvent() +{ + //Choose PHOS clusters and recalibrate them + //that it recalculate energy, position and distance + //to closest track extrapolation + + AliESDEvent *esd = 0x0 ; + AliAODEvent *aod = 0x0 ; + if(fTender){ + esd = fTender->GetEvent(); + if(!esd) + return ; + } + else{ + if(!fTask){ + return ; + } + esd = dynamic_cast(fTask->InputEvent()) ; + aod = dynamic_cast(fTask->InputEvent()) ; + if(!esd && !aod) + return ; + } + + if(!fPHOSCalibData + || (fTender && fTender->RunChanged())){ //In case of Task init called automatically + InitTender(); + + } + + TVector3 vertex ; + if(esd){ + const AliESDVertex *esdVertex = esd->GetPrimaryVertex(); + vertex.SetXYZ(esdVertex->GetX(),esdVertex->GetY(),esdVertex->GetZ()); + } + else{//AOD + const AliAODVertex *aodVertex = aod->GetPrimaryVertex(); + vertex.SetXYZ(aodVertex->GetX(),aodVertex->GetY(),aodVertex->GetZ()); + } + if(vertex.Mag()>99.) //vertex not defined? + vertex.SetXYZ(0.,0.,0.) ; + + + //For re-calibration + const Double_t logWeight=4.5 ; + + if(esd){ //To avoid multiple if in loops we made + //almost identical pecies of code. Please apply changes to both!!! + Int_t multClust=esd->GetNumberOfCaloClusters(); + AliESDCaloCells * cells = esd->GetPHOSCells() ; + + for (Int_t i=0; iGetCaloCluster(i); + if ( !clu->IsPHOS()) continue; + + + //Apply re-Calibreation + AliPHOSEsdCluster cluPHOS(*clu); + cluPHOS.Recalibrate(fPHOSCalibData,cells); // modify the cell energies + cluPHOS.EvalAll(logWeight,vertex); // recalculate the cluster parameters + cluPHOS.SetE(CorrectNonlinearity(cluPHOS.E()));// Users's nonlinearity + + Float_t position[3]; + cluPHOS.GetPosition(position); + clu->SetPosition(position); //rec.point position in MARS + TVector3 global(position) ; + Int_t relId[4] ; + fPHOSGeo->GlobalPos2RelId(global,relId) ; + Int_t mod = relId[0] ; + Int_t cellX = relId[2]; + Int_t cellZ = relId[3] ; + if ( !IsGoodChannel(mod,cellX,cellZ) ) { + clu->SetE(0.) ; + continue ; + } + + Double_t ecore=CoreEnergy(&cluPHOS) ; + ecore=CorrectNonlinearity(ecore) ; + + clu->SetE(cluPHOS.E()); //total particle energy + clu->SetCoreEnergy(ecore); //core particle energy + + //Eval FullDispersion + clu->SetDispersion(TestFullLambda(clu->E(),cluPHOS.GetM20(),cluPHOS.GetM02())) ; + //Eval CoreDispersion + Double_t m02=0.,m20=0.; + EvalLambdas(&cluPHOS,m02, m20); + clu->SetChi2(TestCoreLambda(clu->E(),m20,m02)); //not yet implemented + clu->SetM02(m02) ; //second moment M2x + clu->SetM20(m20) ; //second moment M2z + + //correct distance to track + Double_t dx=0.,dz=0. ; + fPHOSGeo->GlobalPos2RelId(global,relId) ; + TVector3 locPos; + fPHOSGeo->Global2Local(locPos,global,mod) ; + + Double_t pttrack=0.; + Int_t charge=0; + FindTrackMatching(mod,&locPos,dx,dz,pttrack,charge) ; + Double_t r=TestCPV(dx, dz, pttrack,charge) ; + clu->SetTrackDistance(dx,dz); + + clu->SetEmcCpvDistance(r); + + Double_t tof=EvalTOF(&cluPHOS,cells); +// if(TMath::Abs(tof-clu->GetTOF())>100.e-9) //something wrong in cell TOF! +// tof=clu->GetTOF() ; + clu->SetTOF(tof); + Double_t minDist=clu->GetDistanceToBadChannel() ;//Already calculated + DistanceToBadChannel(mod,&locPos,minDist); + clu->SetDistanceToBadChannel(minDist) ; + + Double_t ecross = EvalEcross(&cluPHOS); + clu->SetMCEnergyFraction(ecross) ; + } + } + else{//AOD + Int_t multClust=aod->GetNumberOfCaloClusters(); + AliAODCaloCells * cells = aod->GetPHOSCells() ; + + for (Int_t i=0; iGetCaloCluster(i); + if ( !clu->IsPHOS()) continue; + + + //Apply re-Calibreation + AliPHOSAodCluster cluPHOS(*clu); + cluPHOS.Recalibrate(fPHOSCalibData,cells); // modify the cell energies + cluPHOS.EvalAll(logWeight,vertex); // recalculate the cluster parameters + cluPHOS.SetE(CorrectNonlinearity(cluPHOS.E()));// Users's nonlinearity + + Float_t position[3]; + cluPHOS.GetPosition(position); + clu->SetPosition(position); //rec.point position in MARS + TVector3 global(position) ; + Int_t relId[4] ; + fPHOSGeo->GlobalPos2RelId(global,relId) ; + Int_t mod = relId[0] ; + Int_t cellX = relId[2]; + Int_t cellZ = relId[3] ; + if ( !IsGoodChannel(mod,cellX,cellZ) ) { + clu->SetE(0.) ; + continue ; + } + TVector3 locPosOld; //Use it to re-calculate distance to track + fPHOSGeo->Global2Local(locPosOld,global,mod) ; + + Double_t ecore=CoreEnergy(&cluPHOS) ; + ecore=CorrectNonlinearity(ecore) ; + + clu->SetE(cluPHOS.E()); //total particle energy + clu->SetCoreEnergy(ecore); //core particle energy + + //Eval FullDispersion + clu->SetDispersion(TestFullLambda(clu->E(),cluPHOS.GetM20(),cluPHOS.GetM02())) ; + //Eval CoreDispersion + Double_t m02=0.,m20=0.; + EvalLambdas(&cluPHOS,m02, m20); + clu->SetChi2(TestCoreLambda(clu->E(),m20,m02)); //not yet implemented + clu->SetM02(m02) ; //second moment M2x + clu->SetM20(m20) ; //second moment M2z + + //correct distance to track + Double_t dx=clu->GetTrackDx() ; + Double_t dz=clu->GetTrackDz() ; + TVector3 locPos; + fPHOSGeo->Global2Local(locPos,global,mod) ; + if(dx!=-999.){ //there is matched track + dx+=locPos.X()-locPosOld.X() ; + dz+=locPos.Z()-locPosOld.Z() ; + clu->SetTrackDistance(dx,dz); + } + Double_t r = 999. ; //Big distance + int nTracksMatched = clu->GetNTracksMatched(); + if(nTracksMatched > 0) { + AliVTrack* track = dynamic_cast (clu->GetTrackMatched(0)); + if ( track ) { + Double_t pttrack = track->Pt(); + Short_t charge = track->Charge(); + r=TestCPV(dx, dz, pttrack,charge) ; + } + } + clu->SetEmcCpvDistance(r); //Distance in sigmas + + + Double_t tof=EvalTOF(&cluPHOS,cells); +// if(TMath::Abs(tof-clu->GetTOF())>100.e-9) //something wrong in cell TOF! +// tof=clu->GetTOF() ; + clu->SetTOF(tof); + Double_t minDist=clu->GetDistanceToBadChannel() ;//Already calculated + DistanceToBadChannel(mod,&locPos,minDist); + clu->SetDistanceToBadChannel(minDist) ; + + Double_t ecross = EvalEcross(&cluPHOS); + clu->SetMCEnergyFraction(ecross) ; + } + } + +} +//___________________________________________________________________________________________________ +void AliPHOSTenderSupply::FindTrackMatching(Int_t mod,TVector3 *locpos, + Double_t &dx, Double_t &dz, + Double_t &pt,Int_t &charge){ + //Find track with closest extrapolation to cluster + AliESDEvent *esd = 0x0 ; + if(fTender) + esd= fTender->GetEvent(); + else{ + esd= dynamic_cast(fTask->InputEvent()); + } + + if(!esd){ + AliError("ESD is not found") ; + return ; + } + Double_t magF = esd->GetMagneticField(); + + Double_t magSign = 1.0; + if(magF<0)magSign = -1.0; + + if (!TGeoGlobalMagField::Instance()->GetField()) { + AliError("Margnetic filed was not initialized, use default") ; + AliMagF* field = new AliMagF("Maps","Maps", magSign, magSign, AliMagF::k5kG); + TGeoGlobalMagField::Instance()->SetField(field); + } + + // *** Start the matching + Int_t nt=0; + nt = esd->GetNumberOfTracks(); + //Calculate actual distance to PHOS module + TVector3 globaPos ; + fPHOSGeo->Local2Global(mod, 0.,0., globaPos) ; + const Double_t rPHOS = globaPos.Pt() ; //Distance to center of PHOS module + const Double_t kYmax = 72.+10. ; //Size of the module (with some reserve) in phi direction + const Double_t kZmax = 64.+10. ; //Size of the module (with some reserve) in z direction + const Double_t kAlpha0=330./180.*TMath::Pi() ; //First PHOS module angular direction + const Double_t kAlpha= 20./180.*TMath::Pi() ; //PHOS module angular size + Double_t minDistance = 1.e6; + + + Double_t gposTrack[3] ; + + Double_t bz = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->SolenoidField(); + bz = TMath::Sign(0.5*kAlmost0Field,bz) + bz; + + Double_t b[3]; + + for (Int_t i=0; iGetTrack(i); + + // Skip the tracks having "wrong" status (has to be checked/tuned) + ULong_t status = esdTrack->GetStatus(); + if ((status & AliESDtrack::kTPCout) == 0) continue; + + //Continue extrapolation from TPC outer surface + const AliExternalTrackParam *outerParam=esdTrack->GetOuterParam(); + if (!outerParam) continue; + AliExternalTrackParam t(*outerParam); + + t.GetBxByBz(b) ; + //Direction to the current PHOS module + Double_t phiMod=kAlpha0-kAlpha*mod ; + if(!t.Rotate(phiMod)) + continue ; + + Double_t y; // Some tracks do not reach the PHOS + if (!t.GetYAt(rPHOS,bz,y)) continue; // because of the bending + + Double_t z; + if(!t.GetZAt(rPHOS,bz,z)) + continue ; + if (TMath::Abs(z) > kZmax) + continue; // Some tracks miss the PHOS in Z + if(TMath::Abs(y) < kYmax){ + t.PropagateToBxByBz(rPHOS,b); // Propagate to the matching module + //t.CorrectForMaterial(...); // Correct for the TOF material, if needed + t.GetXYZ(gposTrack) ; + TVector3 globalPositionTr(gposTrack) ; + TVector3 localPositionTr ; + fPHOSGeo->Global2Local(localPositionTr,globalPositionTr,mod) ; + Double_t ddx = locpos->X()-localPositionTr.X(); + Double_t ddz = locpos->Z()-localPositionTr.Z(); + Double_t d2 = ddx*ddx + ddz*ddz; + if(d2 < minDistance) { + dx = ddx ; + dz = ddz ; + minDistance=d2 ; + pt=esdTrack->Pt() ; + charge=esdTrack->Charge() ; + } + } + }//Scanned all tracks + +} +//____________________________________________________________ +Float_t AliPHOSTenderSupply::CorrectNonlinearity(Float_t en){ + + //For backward compatibility, if no RecoParameters found + if(fNonlinearityVersion=="Default"){ + return 0.0241+1.0504*en+0.000249*en*en ; + } + if(fNonlinearityVersion=="MC"){ //Default + some correction + return (0.0241+1.0504*en+0.000249*en*en)*fNonlinearityParams[0]*(1+fNonlinearityParams[1]/(1.+en*en/fNonlinearityParams[2]/fNonlinearityParams[2])) ; + } + + if(fNonlinearityVersion=="NoCorrection"){ + return en ; + } + if(fNonlinearityVersion=="Gustavo2005"){ + return fNonlinearityParams[0]+fNonlinearityParams[1]*en + fNonlinearityParams[2]*en*en ; + } + if(fNonlinearityVersion=="Henrik2010"){ + return en*(fNonlinearityParams[0]+fNonlinearityParams[1]*TMath::Exp(-en*fNonlinearityParams[2]))*(1.+fNonlinearityParams[3]*TMath::Exp(-en*fNonlinearityParams[4]))*(1.+fNonlinearityParams[6]/(en*en+fNonlinearityParams[5])) ; + } + + return en ; +} +//_____________________________________________________________________________ +Double_t AliPHOSTenderSupply::TestCoreLambda(Double_t pt,Double_t l1,Double_t l2){ +//Parameterization for core dispersion +//For R=4.5 + Double_t l1Mean = 1.150200 + 0.097886/(1.+1.486645*pt+0.000038*pt*pt) ; + Double_t l2Mean = 1.574706 + 0.997966*exp(-0.895075*pt)-0.010666*pt ; + Double_t l1Sigma = 0.100255 + 0.337177*exp(-0.517684*pt)+0.001170*pt ; + Double_t l2Sigma = 0.232580 + 0.573401*exp(-0.735903*pt)-0.002325*pt ; + Double_t c = -0.110983 -0.017353/(1.-1.836995*pt+0.934517*pt*pt) ; + +/* + //Parameterizatino for full dispersion + Double_t l2Mean = 1.53126+9.50835e+06/(1.+1.08728e+07*pt+1.73420e+06*pt*pt) ; + Double_t l1Mean = 1.12365+0.123770*TMath::Exp(-pt*0.246551)+5.30000e-03*pt ; + Double_t l2Sigma = 6.48260e-02+7.60261e+10/(1.+1.53012e+11*pt+5.01265e+05*pt*pt)+9.00000e-03*pt; + Double_t l1Sigma = 4.44719e-04+6.99839e-01/(1.+1.22497e+00*pt+6.78604e-07*pt*pt)+9.00000e-03*pt; + Double_t c=-0.35-0.550*TMath::Exp(-0.390730*pt) ; +*/ + Double_t R2=0.5*(l1-l1Mean)*(l1-l1Mean)/l1Sigma/l1Sigma + + 0.5*(l2-l2Mean)*(l2-l2Mean)/l2Sigma/l2Sigma + + 0.5*c*(l1-l1Mean)*(l2-l2Mean)/l1Sigma/l2Sigma ; + return R2 ; + +} +//_____________________________________________________________________________ +Double_t AliPHOSTenderSupply::TestFullLambda(Double_t pt,Double_t l1,Double_t l2){ +//Parameterization for full dispersion + //Parameterizatino for full dispersion + Double_t l2Mean = 1.53126+9.50835e+06/(1.+1.08728e+07*pt+1.73420e+06*pt*pt) ; + Double_t l1Mean = 1.12365+0.123770*TMath::Exp(-pt*0.246551)+5.30000e-03*pt ; + Double_t l2Sigma = 6.48260e-02+7.60261e+10/(1.+1.53012e+11*pt+5.01265e+05*pt*pt)+9.00000e-03*pt; + Double_t l1Sigma = 4.44719e-04+6.99839e-01/(1.+1.22497e+00*pt+6.78604e-07*pt*pt)+9.00000e-03*pt; + Double_t c=-0.35-0.550*TMath::Exp(-0.390730*pt) ; + + Double_t R2=0.5*(l1-l1Mean)*(l1-l1Mean)/l1Sigma/l1Sigma + + 0.5*(l2-l2Mean)*(l2-l2Mean)/l2Sigma/l2Sigma + + 0.5*c*(l1-l1Mean)*(l2-l2Mean)/l1Sigma/l2Sigma ; + return R2 ; + +} +//____________________________________________________________________________ +Double_t AliPHOSTenderSupply::TestCPV(Double_t dx, Double_t dz, Double_t pt, Int_t charge){ + //Parameterization of LHC10h period + //_true if neutral_ + + Double_t meanX=0; + Double_t meanZ=0.; + Double_t sx=TMath::Min(5.4,2.59719e+02*TMath::Exp(-pt/1.02053e-01)+ + 6.58365e-01*5.91917e-01*5.91917e-01/((pt-9.61306e-01)*(pt-9.61306e-01)+5.91917e-01*5.91917e-01)+1.59219); + Double_t sz=TMath::Min(2.75,4.90341e+02*1.91456e-02*1.91456e-02/(pt*pt+1.91456e-02*1.91456e-02)+1.60) ; + + Double_t mf = 0.; //Positive for ++ and negative for -- + if(fTender){ + AliESDEvent *esd = fTender->GetEvent(); + mf = esd->GetMagneticField(); + } + else{ + if(fTask){ + AliESDEvent *esd= dynamic_cast(fTask->InputEvent()); + if(esd) + mf = esd->GetMagneticField(); + else{ + AliAODEvent *aod= dynamic_cast(fTask->InputEvent()); + if(aod) + mf = aod->GetMagneticField(); + } + }else{ + AliError("Neither Tender nor Task defined") ; + } + } + + if(mf<0.){ //field -- + meanZ = -0.468318 ; + if(charge>0) + meanX=TMath::Min(7.3, 3.89994*1.20679*1.20679/(pt*pt+1.20679*1.20679)+0.249029+2.49088e+07*TMath::Exp(-pt*3.33650e+01)) ; + else + meanX=-TMath::Min(7.7,3.86040*0.912499*0.912499/(pt*pt+0.912499*0.912499)+1.23114+4.48277e+05*TMath::Exp(-pt*2.57070e+01)) ; + } + else{ //Field ++ + meanZ= -0.468318; + if(charge>0) + meanX=-TMath::Min(8.0,3.86040*1.31357*1.31357/(pt*pt+1.31357*1.31357)+0.880579+7.56199e+06*TMath::Exp(-pt*3.08451e+01)) ; + else + meanX= TMath::Min(6.85, 3.89994*1.16240*1.16240/(pt*pt+1.16240*1.16240)-0.120787+2.20275e+05*TMath::Exp(-pt*2.40913e+01)) ; + } + + Double_t rz=(dz-meanZ)/sz ; + Double_t rx=(dx-meanX)/sx ; + return TMath::Sqrt(rx*rx+rz*rz) ; +} + +//________________________________________________________________________ +Bool_t AliPHOSTenderSupply::IsGoodChannel(Int_t mod, Int_t ix, Int_t iz) +{ + //Check if this channel belogs to the good ones + + if(mod>4 || mod<1){ +// AliError(Form("No bad map for PHOS module %d ",mod)) ; + return kTRUE ; + } + if(!fPHOSBadMap[mod]){ +// AliError(Form("No Bad map for PHOS module %d",mod)) ; + return kTRUE ; + } + if(fPHOSBadMap[mod]->GetBinContent(ix,iz)>0) + return kFALSE ; + else + return kTRUE ; +} +//________________________________________________________________________ +void AliPHOSTenderSupply::ForceUsingBadMap(const char * filename){ + //Read TH2I histograms with bad maps from local or alien file + TFile * fbm = TFile::Open(filename) ; + if(!fbm || !fbm->IsOpen()){ + AliError(Form("Can not open BadMaps file %s",filename)) ; + return ; + } + gROOT->cd() ; + char key[55] ; + for(Int_t mod=1;mod<4; mod++){ + snprintf(key,55,"PHOS_BadMap_mod%d",mod) ; + TH2I * h = (TH2I*)fbm->Get(key) ; + if(h) + fPHOSBadMap[mod] = new TH2I(*h) ; + } + fbm->Close() ; + fUsePrivateBadMap=kTRUE ; +} +//________________________________________________________________________ +void AliPHOSTenderSupply::ForceUsingCalibration(const char * filename){ + //Read PHOS recalibration parameters from the file. + //We assume that file contains single entry: AliPHOSCalibData + TFile * fc = TFile::Open(filename) ; + if(!fc || !fc->IsOpen()){ + AliFatal(Form("Can not open Calibration file %s",filename)) ; + return ; + } + fPHOSCalibData = (AliPHOSCalibData*)fc->Get("PHOSCalibration") ; + fc->Close() ; + fUsePrivateCalib=kTRUE; +} +//________________________________________________________________________ +void AliPHOSTenderSupply::CorrectPHOSMisalignment(TVector3 &global,Int_t mod){ + //Correct for PHOS modules misalignment + + //correct misalignment + const Float_t shiftX[6]={0.,-2.3,-2.11,-1.53,0.,0.} ; + const Float_t shiftZ[6]={0.,-0.4, 0.52, 0.8,0.,0.} ; + TVector3 localPos ; + fPHOSGeo->Global2Local(localPos,global,mod) ; + fPHOSGeo->Local2Global(mod,localPos.X()+shiftX[mod],localPos.Z()+shiftZ[mod],global); +} +//________________________________________________________________________ +void AliPHOSTenderSupply::EvalLambdas(AliVCluster * clu, Double_t &m02, Double_t &m20){ + //calculate dispecrsion of the cluster in the circle with radius distanceCut around the maximum + + const Double_t rCut=4.5 ; + + Double32_t * elist = clu->GetCellsAmplitudeFraction() ; +// Calculates the center of gravity in the local PHOS-module coordinates + Float_t wtot = 0; + Double_t xc[100]={0} ; + Double_t zc[100]={0} ; + Double_t x = 0 ; + Double_t z = 0 ; + Int_t mulDigit=TMath::Min(100,clu->GetNCells()) ; + const Double_t logWeight=4.5 ; + for(Int_t iDigit=0; iDigitAbsToRelNumbering(clu->GetCellAbsId(iDigit), relid) ; + fPHOSGeo->RelPosInModule(relid, xi, zi); + xc[iDigit]=xi ; + zc[iDigit]=zi ; + if (clu->E()>0 && elist[iDigit]>0) { + Float_t w = TMath::Max( 0., logWeight + TMath::Log( elist[iDigit] / clu->E() ) ) ; + x += xc[iDigit] * w ; + z += zc[iDigit] * w ; + wtot += w ; + } + } + if (wtot>0) { + x /= wtot ; + z /= wtot ; + } + + wtot = 0. ; + Double_t dxx = 0.; + Double_t dzz = 0.; + Double_t dxz = 0.; + Double_t xCut = 0. ; + Double_t zCut = 0. ; + for(Int_t iDigit=0; iDigitE()>0 && elist[iDigit]>0.) { + Double_t w = TMath::Max( 0., logWeight + TMath::Log( elist[iDigit] / clu->E() ) ) ; + Double_t xi= xc[iDigit] ; + Double_t zi= zc[iDigit] ; + if((xi-x)*(xi-x)+(zi-z)*(zi-z) < rCut*rCut){ + xCut += w * xi ; + zCut += w * zi ; + dxx += w * xi * xi ; + dzz += w * zi * zi ; + dxz += w * xi * zi ; + wtot += w ; + } + } + + } + if (wtot>0) { + xCut/= wtot ; + zCut/= wtot ; + dxx /= wtot ; + dzz /= wtot ; + dxz /= wtot ; + dxx -= xCut * xCut ; + dzz -= zCut * zCut ; + dxz -= xCut * zCut ; + + m02 = 0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ; + m20 = 0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ; + } + else { + m20=m02=0.; + } + +} +//____________________________________________________________________________ +Double_t AliPHOSTenderSupply::CoreEnergy(AliVCluster * clu){ + //calculate energy of the cluster in the circle with radius distanceCut around the maximum + + //Can not use already calculated coordinates? + //They have incidence correction... + const Double_t distanceCut =3.5 ; + const Double_t logWeight=4.5 ; + + Double32_t * elist = clu->GetCellsAmplitudeFraction() ; +// Calculates the center of gravity in the local PHOS-module coordinates + Float_t wtot = 0; + Double_t xc[100]={0} ; + Double_t zc[100]={0} ; + Double_t x = 0 ; + Double_t z = 0 ; + Int_t mulDigit=TMath::Min(100,clu->GetNCells()) ; + for(Int_t iDigit=0; iDigitAbsToRelNumbering(clu->GetCellAbsId(iDigit), relid) ; + fPHOSGeo->RelPosInModule(relid, xi, zi); + xc[iDigit]=xi ; + zc[iDigit]=zi ; + if (clu->E()>0 && elist[iDigit]>0) { + Float_t w = TMath::Max( 0., logWeight + TMath::Log( elist[iDigit] / clu->E() ) ) ; + x += xc[iDigit] * w ; + z += zc[iDigit] * w ; + wtot += w ; + } + } + if (wtot>0) { + x /= wtot ; + z /= wtot ; + } + Double_t coreE=0. ; + for(Int_t iDigit=0; iDigit < mulDigit; iDigit++) { + Double_t distance = TMath::Sqrt((xc[iDigit]-x)*(xc[iDigit]-x)+(zc[iDigit]-z)*(zc[iDigit]-z)) ; + if(distance < distanceCut) + coreE += elist[iDigit] ; + } + //Apply non-linearity correction + return coreE ; +} +//____________________________________________________________________________ +Double_t AliPHOSTenderSupply::EvalEcross(AliVCluster * clu){ + //Calculate propoerion of the cluster energy in cross around the + //cell with maximal energy deposition. Can be used to reject exotic clusters + + Double32_t * elist = clu->GetCellsAmplitudeFraction() ; + Int_t mulDigit=clu->GetNCells() ; + // Calculates the center of gravity in the local PHOS-module coordinates + //Find cell with max E + Double_t eMax=0.; + Int_t iMax=0; + for(Int_t iDigit=0; iDigiteMax){ + eMax=elist[iDigit] ; + iMax=iDigit ; + } + } + //Calculate e in cross + Double_t eCross=0 ; + Int_t relidMax[4] ; + fPHOSGeo->AbsToRelNumbering(clu->GetCellAbsId(iMax), relidMax) ; + Int_t relid[4] ; + for(Int_t iDigit=0; iDigitAbsToRelNumbering(clu->GetCellAbsId(iDigit), relid) ; + if(TMath::Abs(relid[2]-relidMax[2])+TMath::Abs(relid[3]-relidMax[3])==1) + eCross+= elist[iDigit] ; + } + if(eMax>0) + return 1.-eCross/eMax ; + else + return 0 ; +} + + +//________________________________________________________________________ +Double_t AliPHOSTenderSupply::EvalTOF(AliVCluster * clu,AliVCaloCells * cells){ + //Evaluate TOF of the cluster after re-calibration + //TOF here is weighted average of digits + // -within 50ns from the most energetic cell + // -not too soft. + + Double32_t * elist = clu->GetCellsAmplitudeFraction() ; + Int_t mulDigit=clu->GetNCells() ; + + Float_t tMax= 0.; //Time at the maximum + Float_t eMax=0. ; + for(Int_t iDigit=0; iDigitGetCellAbsId(iDigit) ; + Bool_t isHG=cells->GetCellHighGain(absId) ; + if( elist[iDigit]>eMax){ + tMax=CalibrateTOF(cells->GetCellTime(absId),absId,isHG) ; + eMax=elist[iDigit] ; + } + } + + //Try to improve accuracy + //Do not account time of soft cells: + // const Double_t part=0.5 ; + Double_t eMin=TMath::Min(0.5,0.2*eMax) ; + Float_t wtot = 0.; + Double_t t = 0. ; + for(Int_t iDigit=0; iDigitGetCellAbsId(iDigit) ; + Bool_t isHG=cells->GetCellHighGain(absId) ; + + Double_t ti=CalibrateTOF(cells->GetCellTime(absId),absId,isHG) ; + if(TMath::Abs(ti-tMax)>50.e-9) //remove soft cells with wrong time + continue ; + + //Remove too soft cells + if(elist[iDigit]0){ + //weight = 1./sigma^2 + //Sigma is parameterization of TOF resolution 16.05.2013 + Double_t wi2=0.; + if(isHG) + wi2=1./(2.4 + 3.9/elist[iDigit]) ; + else + wi2=1./(2.4 + 3.9/(0.1*elist[iDigit])) ; //E of LG digit is 1/16 of correcponding HG + t+=ti*wi2 ; + wtot+=wi2 ; + } + } + if(wtot>0){ + t=t/wtot ; + } + else{ + t=tMax ; + } + + return t ; + +} +//________________________________________________________________________ +Double_t AliPHOSTenderSupply::CalibrateTOF(Double_t tof, Int_t absId, Bool_t isHG){ + //Apply time re-calibration separately for HG and LG channels + //By default (if not filled) shifts are zero. + + Int_t relId[4]; + fPHOSGeo->AbsToRelNumbering(absId,relId) ; + Int_t module = relId[0]; + Int_t column = relId[3]; + Int_t row = relId[2]; + if(isHG) + tof-=fPHOSCalibData->GetTimeShiftEmc(module, column, row); + else{ + tof-=fPHOSCalibData->GetLGTimeShiftEmc(module, column, row); + } + return tof ; + +} +//________________________________________________________________________ +void AliPHOSTenderSupply::DistanceToBadChannel(Int_t mod, TVector3 * locPos, Double_t &minDist){ + //Check if distance to bad channel was reduced + Int_t range = minDist/2.2 +1 ; //Distance at which bad channels should be serached + + Int_t relid[4]={0,0,0,0} ; + fPHOSGeo->RelPosToRelId(mod, locPos->X(), locPos->Z(), relid) ; + Int_t xmin=TMath::Max(1,relid[2]-range) ; + Int_t xmax=TMath::Min(64,relid[2]+range) ; + Int_t zmin=TMath::Max(1,relid[3]-range) ; + Int_t zmax=TMath::Min(56,relid[3]+range) ; + + Float_t x=0.,z=0.; + for(Int_t ix=xmin;ix<=xmax;ix++){ + for(Int_t iz=zmin;iz<=zmax;iz++){ + if(fPHOSBadMap[mod]->GetBinContent(ix,iz)>0){ //Bad channel + Int_t relidBC[4]={mod,0,ix,iz} ; + fPHOSGeo->RelPosInModule(relidBC,x,z); + Double_t dist = TMath::Sqrt((x-locPos->X())*(x-locPos->X()) + (z-locPos->Z())*(z-locPos->Z())); + if(dist + +class TVector3; +class AliPHOSGeometry; +class AliPHOSCalibData ; +class TH2I ; +class AliVCluster ; +class AliVCaloCells ; +class AliAnalysisTaskSE ; + +class AliPHOSTenderSupply: public AliTenderSupply { + +public: + AliPHOSTenderSupply(); + AliPHOSTenderSupply(const char *name, const AliTender *tender=NULL); + virtual ~AliPHOSTenderSupply(); + + virtual void Init(){} + virtual void ProcessEvent(); + + void SetTask(AliAnalysisTaskSE * task){fTask=task;} //if work with AOD and special task + + void SetNonlinearityVersion(const char * ver="Gustavo2005"){fNonlinearityVersion=ver;} + void SetNonlinearityParams(Int_t n, const Double_t * par){ + if(n>10){printf("Only 10 parameters allowed \n"); return ;} + for(Int_t i=0;i +#include +#include +#include "AliTender.h" + +#include "AliPIDTenderSupply.h" + +ClassImp(AliPIDTenderSupply) + +AliPIDTenderSupply::AliPIDTenderSupply() : + AliTenderSupply(), + fCachePID(kFALSE) +{ + // + // default ctor + // +} + +//_____________________________________________________ +AliPIDTenderSupply::AliPIDTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender), + fCachePID(kFALSE) +{ + // + // named ctor + // +} + +//_____________________________________________________ +void AliPIDTenderSupply::ProcessEvent() +{ + // + // Combine PID information + // + + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + + AliESDpid *pid=fTender->GetESDhandler()->GetESDpid(); + if (!pid) return; + // chache pid if requested + if (fCachePID) { + pid->FillTrackDetectorPID(); + } + + // + // recalculate combined PID probabilities + // + Int_t ntracks=event->GetNumberOfTracks(); + for(Int_t itrack = 0; itrack < ntracks; itrack++) + pid->CombinePID(event->GetTrack(itrack)); + +} diff --git a/TENDER/TenderSupplies/AliPIDTenderSupply.h b/TENDER/TenderSupplies/AliPIDTenderSupply.h new file mode 100644 index 00000000000..59d0330b887 --- /dev/null +++ b/TENDER/TenderSupplies/AliPIDTenderSupply.h @@ -0,0 +1,40 @@ +#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 + +class AliPIDTenderSupply: public AliTenderSupply { + +public: + AliPIDTenderSupply(); + AliPIDTenderSupply(const char *name, const AliTender *tender=NULL); + + virtual ~AliPIDTenderSupply(){;} + + virtual void Init(){;} + virtual void ProcessEvent(); + + void SetCachePID(Bool_t cachePID) { fCachePID=cachePID; } +private: + Bool_t fCachePID; // Cache PID values in transient object + + AliPIDTenderSupply(const AliPIDTenderSupply&c); + AliPIDTenderSupply& operator= (const AliPIDTenderSupply&c); + + ClassDef(AliPIDTenderSupply, 2); // PID tender task +}; + + +#endif + diff --git a/TENDER/TenderSupplies/AliT0TenderSupply.cxx b/TENDER/TenderSupplies/AliT0TenderSupply.cxx new file mode 100644 index 00000000000..5b8a13a8c96 --- /dev/null +++ b/TENDER/TenderSupplies/AliT0TenderSupply.cxx @@ -0,0 +1,188 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/////////////////////////////////////////////////////////////////////////// +// // +// T0 Tender supply // +// // +// // +/////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include + +ClassImp(AliT0TenderSupply) + +//________________________________________________________________________ +AliT0TenderSupply::AliT0TenderSupply(): + AliTenderSupply(), + fCorrectMeanTime(kFALSE), + fCorrectStartTimeOnAmplSatur(kFALSE), + fAmplitudeThreshold(100), + fPass4LHC11aCorrection(kFALSE) +{ + // + // default constructor + // + for(int i=0; i<4; i++) fTimeOffset[i]=0; +} + +//________________________________________________________________________ +AliT0TenderSupply::AliT0TenderSupply(const char *name, const AliTender *tender): + AliTenderSupply(name,tender), + fCorrectMeanTime(kFALSE), + fCorrectStartTimeOnAmplSatur(kFALSE), + fAmplitudeThreshold(100), + fPass4LHC11aCorrection(kFALSE) +{ + // + // constructor + // + for(int i=0; i<4; i++) fTimeOffset[i]=0; + +} + +//________________________________________________________________________ +AliT0TenderSupply::~AliT0TenderSupply(){ + // + // destructor + // + +} + +//________________________________________________________________________ +void AliT0TenderSupply::Init(){ + // Init + // + Int_t run = fTender->GetRun(); + if (run == 0) return; // to skip first init, when we don't have yet a run number + Printf("----------- TZERO Tender ----------------"); + + fCorrectMeanTime = kFALSE; //reset + for(int i=0; i<4; i++) fTimeOffset[i]=0; + + // align T0s for LHC10def periods + if (fTender->GetRun()>=122195 && fTender->GetRun()<=130850){ + Printf("Loading TZERO OCBD entries"); + fCorrectMeanTime=kTRUE; + Printf("fCorrectMeanTime %i \n", fCorrectMeanTime); + + AliCDBManager* ocdbMan = AliCDBManager::Instance(); + ocdbMan->SetRun(fTender->GetRun()); + AliCDBEntry *entry = ocdbMan->Get("T0/Calib/TimeAdjust/"); + if(entry) { + AliT0CalibSeasonTimeShift *clb = (AliT0CalibSeasonTimeShift*) entry->GetObject(); + Float_t *t0means = clb->GetT0Means(); + for (Int_t i=0;i<4;i++) fTimeOffset[i] = t0means[i]; + } else { + for (Int_t i=0;i<4;i++) fTimeOffset[i] = 0; + AliWarning("T0Tender no T0 entry found T0shift set to 0"); + } + } + + // LHC11h + fCorrectStartTimeOnAmplSatur = kFALSE; + fAmplitudeThreshold = 100; //in mips + if(167693<= run && run<=170593){ + fCorrectStartTimeOnAmplSatur = kTRUE; + fAmplitudeThreshold = 50; //in mips + } + + + +} + +//________________________________________________________________________ +void AliT0TenderSupply::ProcessEvent(){ + + // + // loop over all online T0 candidates and flag + // selected daughter tracks using the status bis of the TObject + // + + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + //........................................... + //Do something when the run number changed, like loading OCDB entries etc. + if(fTender->RunChanged()) Init(); + + if(fTender->RunChanged()){ + Init(); + if (fTender->GetRun()>=139699&& fTender->GetRun()<=146860){ + AliESDInputHandler *esdIH = dynamic_cast (fTender->GetESDhandler()); + if (esdIH) { + TTree *tree= (TTree*)esdIH->GetTree(); + TFile *file= (TFile*)tree->GetCurrentFile(); + if (file){ + TString fileName(file->GetName()); + if (fileName.Contains("pass4") ) fPass4LHC11aCorrection=kTRUE; + } + } + } + } + + if(fPass4LHC11aCorrection) { + const Double32_t* mean = event->GetT0TOF(); + event->SetT0TOF(0, (mean[1]+mean[2])/2.); + + } + //........................................... + if(fCorrectStartTimeOnAmplSatur){ + //correct A side ORA on amplitude saturation + const Double32_t* time = event->GetT0time(); + const Double32_t* amplitude = event->GetT0amplitude(); + + Int_t idxOfFirstPmtA = -1; + Double32_t timeOrA = 99999; + for(int ipmt=12; ipmt<24; ipmt++){ //loop over A side + if( amplitude[ipmt] < fAmplitudeThreshold){ + if( time[ipmt] > -200 && time[ipmt]!=0 && time[ipmt] < timeOrA ){ + timeOrA = time[ipmt]; + idxOfFirstPmtA = ipmt; + } + } + } + + if(idxOfFirstPmtA>-1){ //a hit in aside with less than 40 mips + const Double32_t* mean = event->GetT0TOF(); + Double32_t timeOrC = mean[2]; + Double32_t timeOrAplusOrC = (timeOrA+timeOrC)/2; + + event->SetT0TOF(0, timeOrAplusOrC); + event->SetT0TOF(1, timeOrA); + } + } + + //........................................... + if(fCorrectMeanTime) { + // correct mean time offsets + const Double32_t* mean = event->GetT0TOF(); + for(int it0=0; it0<3; it0++){ + if( mean[it0] < 10000 || (mean[it0]>6499000 && mean[it0]<6555000 ) ) + event->SetT0TOF(it0, mean[it0] - fTimeOffset[it0]); + } + } + //........................................... + + +} + + diff --git a/TENDER/TenderSupplies/AliT0TenderSupply.h b/TENDER/TenderSupplies/AliT0TenderSupply.h new file mode 100644 index 00000000000..f998c632f5a --- /dev/null +++ b/TENDER/TenderSupplies/AliT0TenderSupply.h @@ -0,0 +1,44 @@ +#ifndef ALIT0TENDERSUPPLY_H +#define ALIT0TENDERSUPPLY_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/////////////////////////////////////////////////////////////////////////// +// // +// // +// // +// // +/////////////////////////////////////////////////////////////////////////// + +#include + +class AliT0TenderSupply: public AliTenderSupply { + + public: + AliT0TenderSupply(); + AliT0TenderSupply(const char *name, const AliTender *tender=NULL); + virtual ~AliT0TenderSupply(); + + virtual void Init(); + virtual void ProcessEvent(); + void SetCorrectMeanTime (Bool_t flag=kFALSE){fCorrectMeanTime=flag;}; + void SetAmplutudeCorrection (Bool_t flag=kFALSE){fCorrectStartTimeOnAmplSatur=flag;}; + void SetPass4LHC11aCorrection (Bool_t flag=kFALSE){fPass4LHC11aCorrection=flag;}; + + private: + + AliT0TenderSupply(const AliT0TenderSupply&c); + AliT0TenderSupply& operator= (const AliT0TenderSupply&c); + + + Bool_t fCorrectMeanTime; //! mean time shift will be corrected + Float_t fTimeOffset[4]; //! time offset to be used for fCorrectMeanTime + Bool_t fCorrectStartTimeOnAmplSatur; //! fix start times suffering from saturated amplitude in pmts + Float_t fAmplitudeThreshold; //! above this value pmt suffer from saturation + Bool_t fPass4LHC11aCorrection; //! above this value pmt suffer from saturation + + ClassDef(AliT0TenderSupply, 2); // T0 tender supply +}; + +#endif diff --git a/TENDER/TenderSupplies/AliTOFTenderSupply.cxx b/TENDER/TenderSupplies/AliTOFTenderSupply.cxx new file mode 100644 index 00000000000..9fd84478e49 --- /dev/null +++ b/TENDER/TenderSupplies/AliTOFTenderSupply.cxx @@ -0,0 +1,1335 @@ +/************************************************************************** + * 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: for a description of what this tender does see +// https://twiki.cern.ch/twiki/bin/viewauth/ALICE/TOF +// It has to be used on LHC2010 data (and old MC productions) +// +// Contacts: Pietro.Antonioli@bo.infn.it // +// Francesco.Noferini@bo.infn.it // +/////////////////////////////////////////////////////////////////////////////// +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +#include "AliTOFTenderSupply.h" + +ClassImp(AliTOFTenderSupply) + +Float_t AliTOFTenderSupply::fgT0Aresolution = 75.; +Float_t AliTOFTenderSupply::fgT0Cresolution = 65.; + +AliTOFTenderSupply::AliTOFTenderSupply() : + AliTenderSupply(), + fESDpid(0x0), + fTenderNoAction(kTRUE), + fIsMC(kFALSE), + fCorrectExpTimes(kTRUE), + fCorrectTRDBug(kFALSE), + fLHC10dPatch(kFALSE), + fT0DetectorAdjust(kFALSE), + fDebugLevel(0), + fAutomaticSettings(kTRUE), + fRecoPass(0), + fUserRecoPass(0), + fForceCorrectTRDBug(kFALSE), + fT0Simulate(kFALSE), + fTOFPIDParams(0x0), + fTOFCalib(0x0), + fTOFT0maker(0x0), + fT0IntercalibrationShift(0), + fGeomSet(kFALSE), + fIsEnteringInTRD(kFALSE), + fInTRD(kFALSE), + fIsComingOutTRD(kFALSE), + fOutTRD(kFALSE), + fRhoTRDin(288.38), // cm + fRhoTRDout(366.38), // cm + fStep(0.5), + fMagField(0.), + fCDBkey(0) + + + +{ + // + // default ctor + // + fT0shift[0] = 0; + fT0shift[1] = 0; + fT0shift[2] = 0; + fT0shift[3] = 0; +} + +//_____________________________________________________ +AliTOFTenderSupply::AliTOFTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender), + fESDpid(0x0), + fTenderNoAction(kTRUE), + fIsMC(kFALSE), + fCorrectExpTimes(kTRUE), + fCorrectTRDBug(kFALSE), + fLHC10dPatch(kFALSE), + fT0DetectorAdjust(kFALSE), + fDebugLevel(0), + fAutomaticSettings(kTRUE), + fRecoPass(0), + fUserRecoPass(0), + fForceCorrectTRDBug(kFALSE), + fT0Simulate(kFALSE), + fTOFPIDParams(0x0), + fTOFCalib(0x0), + fTOFT0maker(0x0), + fT0IntercalibrationShift(0), + fGeomSet(kFALSE), + fIsEnteringInTRD(kFALSE), + fInTRD(kFALSE), + fIsComingOutTRD(kFALSE), + fOutTRD(kFALSE), + fRhoTRDin(288.38), // cm + fRhoTRDout(366.38), // cm + fStep(0.5), + fMagField(0.), + fCDBkey(0) + +{ + // + // named ctor + // + + fT0shift[0] = 0; + fT0shift[1] = 0; + fT0shift[2] = 0; + fT0shift[3] = 0; +} + +//_____________________________________________________ +void AliTOFTenderSupply::Init() +{ + + fTenderNoAction = kFALSE; + // Initialise TOF tender (this is called at each detected run change) + AliLog::SetClassDebugLevel("AliTOFTenderSupply",10); + + // Setup PID object, check for MC, set AliTOFcalib and TOFT0 maker conf + Int_t run = fTender->GetRun(); + if (run == 0) return; // to skip first init, when we don't have yet a run number + + fGeomSet=kFALSE; + // Even if the user didn't set fIsMC, we force it on if we find the MC handler + AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager(); + if (mgr->GetMCtruthEventHandler() && !(fIsMC) ) { + AliWarning("This ESD is MC, fIsMC found OFF: fIsMC turned ON"); + fIsMC=kTRUE; + } + + if (fAutomaticSettings) { + if (!fIsMC) { + if (fUserRecoPass == 0) DetectRecoPass(); + else fRecoPass = fUserRecoPass; + } + if (run<114737) { + fTenderNoAction = kTRUE; + } + else if (run>=114737&&run<=117223) { //period="LHC10B"; + if (!fIsMC) { + if (fRecoPass == 2) { + fCorrectExpTimes=kTRUE; + fCorrectTRDBug=kFALSE;} + else if (fRecoPass == 3) { + fCorrectExpTimes=kFALSE; + fCorrectTRDBug=kTRUE; + } + fLHC10dPatch=kFALSE; + fT0IntercalibrationShift = 0; + fT0DetectorAdjust=kFALSE; // previously was true (we acted as a T0 tender) + } else if (fIsMC) { + fT0DetectorAdjust=kFALSE; + fT0Simulate=kTRUE; + fCorrectExpTimes=kTRUE; + } + } + else if (run>=118503&&run<=121040) { //period="LHC10C"; + if (!fIsMC) { + if (fRecoPass == 2) {fCorrectExpTimes=kTRUE; fCorrectTRDBug=kFALSE;} + else if (fRecoPass == 3) {fCorrectExpTimes=kFALSE; fCorrectTRDBug=kTRUE;} + fLHC10dPatch=kFALSE; + fT0IntercalibrationShift = 0; + fT0DetectorAdjust=kFALSE; // previously was true (we acted as a T0 tender) + } else if (fIsMC) { + fT0DetectorAdjust=kFALSE; + fT0Simulate=kTRUE; + fCorrectExpTimes=kTRUE; + } + } + else if (run>=122195&&run<=126437) { //period="LHC10D"; + if (!fIsMC) { + fCorrectExpTimes=kFALSE; + fLHC10dPatch=kTRUE; + fT0DetectorAdjust=kFALSE; // previously was true (we acted as a T0 tender) + fT0IntercalibrationShift = 0; + } else if (fIsMC) { + fCorrectExpTimes=kTRUE; // for old MC the expected times bug was there + fLHC10dPatch=kFALSE; // but not the fake geometry + fT0DetectorAdjust=kFALSE; + fT0Simulate=kTRUE; + } + } + else if (run>=127719&&run<=130850) { //period="LHC10E"; + if (!fIsMC) { + fCorrectExpTimes=kFALSE; + fLHC10dPatch=kFALSE; + fT0DetectorAdjust=kFALSE; // previously was true (we acted as a T0 tender) + fT0IntercalibrationShift = 0.; // this was 30 before, but it is now handled via TOFPIDResponse inside OADB + } else if (fIsMC) { + fCorrectExpTimes=kTRUE; // this is not fully correct for newer productions like LHC11b2 but we live with this + fT0DetectorAdjust=kFALSE; + fT0Simulate=kTRUE; + } + } + else if (run>=133004&&run<=135029) { //period="LHC10F"; + fTenderNoAction=kTRUE; + } + else if (run>=135654&&run<=136377) { //period="LHC10G"; + fTenderNoAction=kTRUE; + } + else if (run>=136851&&run<=139517) { //period="LHC10H" - pass2; + fCorrectExpTimes=kFALSE; + fLHC10dPatch=kFALSE; + fT0IntercalibrationShift = 0.; + fT0DetectorAdjust=kFALSE; // it was kTRUE + } + else if (run>=139699) { //period="LHC11A"; + fTenderNoAction=kTRUE; + } + } + + if (fTenderNoAction) { + AliInfo(" |---------------------------------------------------------------------------|"); + AliInfo(" | |"); + AliInfo(Form(" | TOF tender is not supported for run %d |",run)); + AliInfo(" | TOF tender will do nothing. |"); + AliInfo(" | Check TOF tender usage for run/periods at: |"); + AliInfo(" | https://twiki.cern.ch/twiki/bin/view/ALICE/TOF. |"); + AliInfo(" |---------------------------------------------------------------------------|"); + AliInfo(" "); + return; + } + + + // Load from OADB TOF resolution + LoadTOFPIDParams(run); + + // Check if another tender wagon 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); + } + + + // Configure TOF calibration class + if (!fTOFCalib)fTOFCalib=new AliTOFcalib(); // create if needed + fTOFCalib->SetRemoveMeanT0(!(fIsMC)); // must be kFALSE on MC (default is kTRUE) + fTOFCalib->SetCalibrateTOFsignal(!(fIsMC)); // must be kFALSE on MC (no new calibration) (default is kTRUE) + fTOFCalib->SetCorrectTExp(fCorrectExpTimes); // apply a fine tuning on the expected times at low momenta + // (this is done for LHC10b/LHC10c pass2) + + // Configure TOFT0 maker class + // if (!fTOFT0maker) fTOFT0maker = new AliTOFT0maker(fESDpid,fTOFCalib); // create if needed + if (!fTOFT0maker) fTOFT0maker = new AliTOFT0maker(fESDpid); // without passing AliTOFCalib it uses the diamond + fTOFT0maker->SetTimeResolution(fTOFPIDParams->GetTOFresolution()); // set TOF resolution for the PID + fTOFT0maker->SetTOFT0algorithm(2); + + AliInfo("|******************************************************|"); + AliInfo(Form("| Alice TOF Tender Initialisation (Run %d) |",fTender->GetRun())); + AliInfo("| Settings: |"); + AliInfo(Form("| Correct Exp Times : %d |",fCorrectExpTimes)); + AliInfo(Form("| Correct TRD Bug : %d |",fCorrectTRDBug)); + AliInfo(Form("| LHC10d patch : %d |",fLHC10dPatch)); + AliInfo(Form("| TOF resolution for TOFT0 maker : %5.2f (ps) |",fTOFPIDParams->GetTOFresolution())); + AliInfo(Form("| MC flag (start time added) : %d |",fIsMC)); + AliInfo(Form("| T0 detector offsets applied : %d |",fT0DetectorAdjust)); + AliInfo(Form("| T0 signal re-sampled : %d |",fT0Simulate)); + AliInfo(Form("| TOF/T0 intercalibration shift : %5.2f (ps) |",fT0IntercalibrationShift)); + AliInfo("|******************************************************|"); + + +} + +//_____________________________________________________ +void AliTOFTenderSupply::ProcessEvent() +{ + // + // Use updated calibrations for TOF and T0, reapply PID information + // For MC: timeZero sampling and additional smearing for T0 + + if (fDebugLevel > 1) AliInfo("process event"); + + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + if (fDebugLevel > 1) AliInfo("event read"); + + + + if (fTender->RunChanged()){ + + Init(); + + if (fTenderNoAction) return; + Int_t versionNumber = GetOCDBVersion(fTender->GetRun()); + fTOFCalib->SetRunParamsSpecificVersion(versionNumber); + fTOFCalib->Init(fTender->GetRun()); + + if(event->GetT0TOF()){ // read T0 detector correction from OCDB + // OCDB instance + if (fT0DetectorAdjust) { + AliCDBManager* ocdbMan = AliCDBManager::Instance(); + ocdbMan->SetRun(fTender->GetRun()); + AliCDBEntry *entry = ocdbMan->Get("T0/Calib/TimeAdjust/"); + if(entry) { + AliT0CalibSeasonTimeShift *clb = (AliT0CalibSeasonTimeShift*) entry->GetObject(); + Float_t *t0means= clb->GetT0Means(); + // Float_t *t0sigmas = clb->GetT0Sigmas(); + fT0shift[0] = t0means[0] + fT0IntercalibrationShift; + fT0shift[1] = t0means[1] + fT0IntercalibrationShift; + fT0shift[2] = t0means[2] + fT0IntercalibrationShift; + fT0shift[3] = t0means[3] + fT0IntercalibrationShift; + } else { + for (Int_t i=0;i<4;i++) fT0shift[i]=0; + AliWarning("TofTender no T0 entry found T0shift set to 0"); + } + } else { + for (Int_t i=0;i<4;i++) fT0shift[i]=0; + } + } + } + + if (fTenderNoAction) return; + + fTOFCalib->CalibrateESD(event); //recalculate TOF signal (no harm for MC, see settings inside init) + + + // patches for various reconstruction bugs + if (fLHC10dPatch && !(fIsMC)) RecomputeTExp(event); // LHC10d pass2: fake full TRD geometry + if ( (fCorrectTRDBug && !(fIsMC)) || (fForceCorrectTRDBug)) FixTRDBug(event); // LHC10b,c pass3: wrong TRD dE/dx + + Double_t startTime = 0.; + if (fIsMC) startTime = fTOFCalib->TuneForMC(event,fTOFPIDParams->GetTOFresolution()); // this is for old MC when we didn't jitter startTime in MC + + if (fDebugLevel > 1) Printf(" TofTender: startTime %f",startTime); + if (fDebugLevel > 1) Printf(" TofTender: T0 time (orig) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2)); + + // event by event TO detector treatment + if(event->GetT0TOF()){ // protection: we adjust T0 only if it is there.... + + if (event->GetT0TOF(0) == 0) event->SetT0TOF(0, 9999999.); // in case no information we set to unknown + if (event->GetT0TOF(1) == 0) event->SetT0TOF(1, 99999.); + if (event->GetT0TOF(2) == 0) event->SetT0TOF(2, 99999.); + + if ( (fT0DetectorAdjust) && !(fIsMC) ) { // DATA: apply shifts to align around T0: this is like a T0 tender!! + event->SetT0TOF(0,event->GetT0TOF(0) - fT0shift[0]); + event->SetT0TOF(1,event->GetT0TOF(1) - fT0shift[1]); + event->SetT0TOF(2,event->GetT0TOF(2) - fT0shift[2]); + } + if (fIsMC) { + if (fT0DetectorAdjust) { // MC case 1: add an additional contribution to resolution + // MC: add smearing for realistic T0A and T0C resolution + Double_t defResolutionT0A = 33.; // in future we will get this from ESDrun data structure or via OCDB + Double_t defResolutionT0C = 30.; // for the moment we don't trust them + if ( (fgT0Aresolution > defResolutionT0A) && (event->GetT0TOF(1)<90000.) ) { // add smearing only if signal is there + Double_t addedSmearingT0A = TMath::Sqrt(fgT0Aresolution*fgT0Aresolution - defResolutionT0A*defResolutionT0A); + Double_t smearingT0A = gRandom->Gaus(0.,addedSmearingT0A); + event->SetT0TOF(1,event->GetT0TOF(1) + smearingT0A); + } + if ( (fgT0Cresolution > defResolutionT0C) && (event->GetT0TOF(2)<90000.) ) { // add smearing only if signal is there + Double_t addedSmearingT0C = TMath::Sqrt(fgT0Cresolution*fgT0Cresolution - defResolutionT0C*defResolutionT0C); + Double_t smearingT0C = gRandom->Gaus(0.,addedSmearingT0C); + event->SetT0TOF(2,event->GetT0TOF(2) + smearingT0C); + } + if (event->GetT0TOF(0)<90000.) { // we recompute the AND only if it is already there... + Double_t smearedT0AC = (event->GetT0TOF(1)+event->GetT0TOF(2))/2.; + event->SetT0TOF(0,smearedT0AC); + } + if (fDebugLevel > 1) Printf(" TofTender: T0 time (postSmear) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2)); + } + else if (fT0Simulate) { // MC case 2: we completely simulate signal in T0 based on multiplicity in ITS and vtx position + event->SetT0TOF(0, 9999999.); // we wipe-out whatever is there + event->SetT0TOF(1, 99999.); + event->SetT0TOF(2, 99999.); + if (fDebugLevel > 1) Printf(" TofTender: T0 time (after wipe-out) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2)); + AliESDVertex *fvtx = (AliESDVertex*)event->GetPrimaryVertex(); + Double_t zvtx = fvtx->GetZ(); + Double_t tracklets[2] = {0.,0.}; + GetTrackletsForT0(event,&tracklets[0],&tracklets[1]); + if (fDebugLevel > 1) Printf(" TofTender: T0 simul (z vtx tracklets A/C) %f %f %f",zvtx,tracklets[0],tracklets[1]); + for (Int_t side = 0; side < 2; side ++) { // side 0 = T0A - side 1 = T0C + Double_t signal = SampleT0Signal(side,zvtx,tracklets[side]); // if not fired we return 99999. + event->SetT0TOF(side+1,signal); // but for the T0 structure we need to add 1... + } + if ( (event->GetT0TOF(1) < 1000.) && (event->GetT0TOF(2) < 1000.) ) { // both signals are there + Double_t meanT0AC=(event->GetT0TOF(1)+event->GetT0TOF(2))/2.; + event->SetT0TOF(0,meanT0AC); + } + if (fDebugLevel > 1) Printf(" TofTender: T0 simul (AC A C) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2)); + } + // add the startTime offset also to the T0 detector information + event->SetT0TOF(0,event->GetT0TOF(0) + startTime); + event->SetT0TOF(1,event->GetT0TOF(1) + startTime); + event->SetT0TOF(2,event->GetT0TOF(2) + startTime); + if (fDebugLevel > 1) Printf(" TofTender: T0 time (postStart AC A C) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2)); + } + // after shifts adjust (data) or smearing+offset (MC) we 'clean' to default if signals not there + if(event->GetT0TOF(0) > 900000) event->SetT0TOF(0, 999999.); + if(event->GetT0TOF(1) > 90000) event->SetT0TOF(1, 99999.); + if(event->GetT0TOF(2) > 90000) event->SetT0TOF(2, 99999.); + } + if (fDebugLevel > 1) Printf(" TofTender: T0 time (FINAL) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2)); + + //compute timeZero of the event via TOF-TO + fTOFT0maker->ComputeT0TOF(event); + fTOFT0maker->WriteInESD(event); + + // set preferred startTime: this is now done via AliPIDResponseTask + fESDpid->SetTOFResponse(event, (AliESDpid::EStartTimeType_t)fTOFPIDParams->GetStartTimeMethod()); + + // recalculate PID probabilities + // this is for safety, especially if the user doesn't attach a PID tender after TOF tender + Int_t ntracks=event->GetNumberOfTracks(); + // AliESDtrack *track = NULL; + // Float_t tzeroTrack = 0; + for(Int_t itrack = 0; itrack < ntracks; itrack++){ + // track = event->GetTrack(itrack); + // tzeroTrack = fESDpid->GetTOFResponse().GetStartTime(track->P()); + // Printf("================> Track # %d mom: %f tzeroTrack %f",itrack,track->P(),tzeroTrack); + fESDpid->MakeTOFPID(event->GetTrack(itrack),0); + } + + +} + + +//_____________________________________________________ +void AliTOFTenderSupply::RecomputeTExp(AliESDEvent *event) const +{ + /* + * calibrate TExp + */ + + + /* loop over tracks */ + AliESDtrack *track = NULL; + for (Int_t itrk = 0; itrk < event->GetNumberOfTracks(); itrk++) { + /* get track and calibrate */ + track = event->GetTrack(itrk); + RecomputeTExp(track); + } + +} + +//_____________________________________________________ +void AliTOFTenderSupply::RecomputeTExp(AliESDtrack *track) const +{ + /*** + THIS METHOD IS BASED ON THEORETICAL EXPECTED TIME COMPUTED + USING AVERAGE MOMENTUM BETWEEN INNER/OUTER TRACK PARAMS + IT IS A ROUGH APPROXIMATION APPLIED TO FIX LHC10d-pass2 DATA + WHERE A WRONG GEOMETRY (FULL TRD) WAS INSERTED + ***/ + + Double_t texp[AliPID::kSPECIESC]; + if (!track || !(track->GetStatus() & AliESDtrack::kTOFout)) return; + + + /* get track params */ + Float_t l = track->GetIntegratedLength(); + Float_t p = track->P(); + if (track->GetInnerParam() && track->GetOuterParam()) { + Float_t pin = track->GetInnerParam()->P(); + Float_t pout = track->GetOuterParam()->P(); + p = 0.5 * (pin + pout); + } + /* loop over particle types and compute expected time */ + for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) + texp[ipart] = GetExpTimeTh(AliPID::ParticleMass(ipart), p, l) - 37.; + // 37 is a final semiempirical offset to further adjust (calibrations were + // done with "standard" integratedTimes) + + // in old ESDs like this horridous LHC10d pass2 light nuclei were not supported... + for (Int_t ipart = AliPID::kProton+1; ipart < AliPID::kSPECIESC; ipart++) texp[ipart]=0.; + + /* set integrated times */ + track->SetIntegratedTimes(texp); + +} + + +//______________________________________________________________________________ +void AliTOFTenderSupply::DetectRecoPass() +{ + // + // Detect reconstruction information + // + + //reset information + fRecoPass=0; + + //Get the current file to check the reconstruction pass (UGLY, but not stored in ESD... ) + AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager(); + AliVEventHandler *inputHandler=mgr->GetInputEventHandler(); + if (!inputHandler) return; + + TTree *tree= (TTree*)inputHandler->GetTree(); + TFile *file= (TFile*)tree->GetCurrentFile(); + + if (!file) { + AliFatal("Current file not found"); + return; // coverity + } + + //find pass from file name (UGLY, but not stored in ESD... ) + TString fileName(file->GetName()); + if (fileName.Contains("pass1") ) { + fRecoPass=1; + } else if (fileName.Contains("pass2") ) { + fRecoPass=2; + } else if (fileName.Contains("pass3") ) { + fRecoPass=3; + } else if (fileName.Contains("pass4") ) { + fRecoPass=4; + } else if (fileName.Contains("pass5") ) { + fRecoPass=5; + } else if (fileName.Contains("pass6") ) { + fRecoPass=6; + } + if (fRecoPass == 0) { + AliInfo(Form("From file name %s reco pass cannot be detected",fileName.Data())); + AliInfo("Change file name or use SetUserRecoPass method"); + AliFatal("------------- TOF tender cannot run with reco pass unspecified, issuing FATAL error ---------- "); + } +} + + +//______________________________________________________________________________ +void AliTOFTenderSupply::InitGeom() +{ + + if (fGeomSet == kTRUE) return; + + // Printf("\n \n ----- calling InitGeom to fix TRD Bug ----- \n \n"); + AliCDBManager * man = AliCDBManager::Instance(); + man->SetDefaultStorage("raw://"); + fCDBkey = man->SetLock(kFALSE, fCDBkey); + Int_t run = fTender->GetRun(); + // Printf(" ---------> run is %d",run); + man->SetRun(run); + AliCDBEntry *entry = (AliCDBEntry*)man->Get("GRP/Geometry/Data"); + if (entry) { + AliGeomManager::LoadGeometry(); + AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF"); + // fCDBkey = man->SetLock(kTRUE, fCDBkey); + // Printf("\n \n ----- Geometry loaded ------ \n \n"); + } + fGeomSet=kTRUE; + +} + + +//______________________________________________________________________________ +void AliTOFTenderSupply::FixTRDBug(AliESDEvent* event) +// +// recompute texp fixing wrong dE/dx from TRD (LHC10b,c pass3) +// +{ + + if (fGeomSet == kFALSE) InitGeom(); + + // Printf("Running FixTRD bug "); + /* loop over tracks */ + AliESDtrack *track = NULL; + for (Int_t itrk = 0; itrk < event->GetNumberOfTracks(); itrk++) { + track = event->GetTrack(itrk); + FixTRDBug(track); + } +} + + +//_____________________________________________________ +void AliTOFTenderSupply::FixTRDBug(AliESDtrack *track) +{ + // + // + // + + + ULong_t status=track->GetStatus(); + if (!( ( (status & AliVTrack::kITSrefit)==AliVTrack::kITSrefit ) && + ( (status & AliVTrack::kTPCrefit)==AliVTrack::kTPCrefit ) && + ( (status & AliVTrack::kTPCout)==AliVTrack::kTPCout ) && + ( (status & AliVTrack::kTOFout)==AliVTrack::kTOFout ) && + ( (status & AliVTrack::kTIME)==AliVTrack::kTIME ) ) ) return; + + fIsEnteringInTRD=kFALSE; + fInTRD=kFALSE; + fIsComingOutTRD=kFALSE; + fOutTRD=kFALSE; + + // Printf("Track reached TOF %f",track->P()); + Double_t correctionTimes[AliPID::kSPECIES] = {0.,0.,0.,0.,0.}; // to be added to the expected times + FindTRDFix(track, correctionTimes); + Double_t expectedTimes[AliPID::kSPECIESC] = {0.,0.,0.,0.,0.,0.,0.,0.,0.}; + track->GetIntegratedTimes(expectedTimes,AliPID::kSPECIESC); + // Printf("Exp. times: %f %f %f %f %f", + // expectedTimes[0],expectedTimes[1],expectedTimes[2],expectedTimes[3],expectedTimes[4]); + // Printf("Corr. times: %f %f %f %f %f", + // correctionTimes[0],correctionTimes[1],correctionTimes[2],correctionTimes[3],correctionTimes[4]); + + for (Int_t jj=0; jjSetIntegratedTimes(expectedTimes); + +} + + +//________________________________________________________________________ +void AliTOFTenderSupply::FindTRDFix(AliESDtrack *track,Double_t *corrections) +{ + + Double_t pT = track->Pt(); + ULong_t status=track->GetStatus(); + Bool_t isTRDout = (status & AliVTrack::kTRDout)==AliVTrack::kTRDout; + + Double_t length = 0.; + + Double_t xyzIN[3]={0.,0.,0.}; + fIsEnteringInTRD = track->GetXYZAt(fRhoTRDin,fMagField,xyzIN); + + Double_t xyzOUT[3]={0.,0.,0.}; + fIsComingOutTRD = track->GetXYZAt(fRhoTRDout,fMagField,xyzOUT); + + if (fIsEnteringInTRD && fIsComingOutTRD) { + + + Double_t phiIN = TMath::Pi()+TMath::ATan2(-xyzIN[1],-xyzIN[0]); + phiIN *= TMath::RadToDeg(); + fInTRD = ( (phiIN>= 0. && phiIN<= 40.) || + (phiIN>=140. && phiIN<=220.) || + (phiIN>=340. && phiIN<=360.) ); // TRD SMs installed @ 2010 + + Double_t phiOUT = TMath::Pi()+TMath::ATan2(-xyzOUT[1],-xyzOUT[0]); + phiOUT *= TMath::RadToDeg(); + fOutTRD = ( (phiOUT>= 0. && phiOUT<= 40.) || + (phiOUT>=140. && phiOUT<=220.) || + (phiOUT>=340. && phiOUT<=360.) ); // TRD SMs installed @ 2010 + + length = 0.; + + if (fInTRD || fOutTRD) { + + if ( ( fInTRD && fOutTRD ) || ( fInTRD && !fOutTRD ) ) { + length = EstimateLengthInTRD1(track); + } else if ( !fInTRD && fOutTRD ) { + length = EstimateLengthInTRD2(track); + } + + } else { // ( !fInTRD && !fOutTRD ) + + length = EstimateLengthOutTRD(track); + + } + + } + // Printf("estimated length in TRD %f [isTRDout %d]",length,isTRDout); + CorrectDeltaTimes(pT,length,isTRDout,corrections); + +} + +//________________________________________________________________________ +void AliTOFTenderSupply::CorrectDeltaTimes(Double_t pT, + Double_t length, + Bool_t flagTRDout, + Double_t *corrections) +{ + + corrections[2] = CorrectExpectedPionTime(pT,length,flagTRDout); + corrections[0] = corrections[2]; // x electrons used pion corrections + corrections[1] = corrections[2]; // x muons used pion corrections + corrections[3] = CorrectExpectedKaonTime(pT,length,flagTRDout); + corrections[4] = CorrectExpectedProtonTime(pT,length,flagTRDout); + +} + +//________________________________________________________________________ +Double_t AliTOFTenderSupply::CorrectExpectedPionTime(Double_t pT, + Double_t length, + Bool_t isTRDout) +{ + // correction for expected time for pions + + Double_t delta=0.; + + // Printf("Flags Ent In ComingOut Out %d %d %d %d",fIsEnteringInTRD,fInTRD,fIsComingOutTRD,fOutTRD); + if (!fIsEnteringInTRD || !fIsComingOutTRD) { // zone 5 + + Float_t p[2]={0.,0.}; + + if (isTRDout) { + + if (pT<0.30) { + p[0] = 180.; p[1] = 0.; + } else if (pT>=0.30 && pT<0.35) { + p[0] = 740.; p[1] = -1800.; + } else if (pT>=0.35 && pT<0.40) { + p[0] = 488.; p[1] =-1080.; + } else if (pT>=0.40 && pT<0.45) { + p[0] = 179.; p[1] = -307.; + } else if (pT>=0.45 && pT<0.50) { + p[0] = 97.; p[1] = -123.; + } else { //if (pT>=0.50) + p[0] = 120.; p[1] = -172.; + } + + } else { + + if (pT<0.30) { + p[0] = 70.; p[1] = 0.; + } else if (pT>=0.30 && pT<0.35) { + p[0] = 339.; p[1] = -927.; + } else if (pT>=0.35 && pT<0.40) { + p[0] = 59.; p[1] = -121.; + } else if (pT>=0.40 && pT<0.50) { + p[0] = 21.; p[1] = -24.; + } else { //if (pT>=0.50) + p[0] = 42.; p[1] = -67.; + } + + } + + delta = p[0]+p[1]*pT; + // Printf("Pion time: %f %f %f %f",p[0],p[1],length,delta); + + } else { + + Float_t p[2] = {0.,0.}; + + if ( fInTRD && fOutTRD) { // zone 1 + + if (isTRDout) { + + if (length<130.) { + p[0] = 0.; p[1] = 0.; + } else if (length>=130. && length<170.) { + p[0] = -20.5; p[1] = 0.25; + } else {//if (length>=170.) + p[0] = 22.; p[1] = 0.; + } + + } else { // !isTRDout + + p[0] = 20.; p[1] = 0.; + + } + + } else if (!fInTRD && !fOutTRD) { // zone 2 + + p[0] = 0.; p[1] = 0.; + + } else if ( fInTRD && !fOutTRD) { // zone 3 + + if (isTRDout) { + + if (length< 75.) { + p[0] = 17.; p[1] = 0.; + } else if (length>= 75. && length< 95.) { + p[0] = 81.; p[1] = -0.85; + } else if (length>= 95. && length<155.) { + p[0] = 0.; p[1] = 0.; + } else {//if (length>=155.) + p[0] = 10.; p[1] = 0.; + } + + } else { // !isTRDout + + p[0] = 0.; p[1] = 0.; + + } + + } else if (!fInTRD && fOutTRD) { // zone 4 + + if (isTRDout) { + + if (length<80.) { + p[0] = 0.; p[1] = 0.; + } else {//if (length>=80.) + p[0] = 10.; p[1] = 0.; + } + + } else { // !isTRDout + + if (length<30.) { + p[0] = 0.; p[1] = 0.; + } else {//if (length>=30.) + p[0] = 6.; p[1] = 0.; + } + + } + + } + + delta = p[0]+p[1]*length; + // Printf("Pion time: %f %f %f %f",p[0],p[1],length,delta); + + } + + return delta; + +} + +//________________________________________________________________________ +Double_t AliTOFTenderSupply::CorrectExpectedKaonTime(Double_t pT, + Double_t length, + Bool_t isTRDout) +{ + // correction for expected time for kaons + + Double_t delta=0.; + // Printf("Flags Ent In ComingOut Out %d %d %d %d",fIsEnteringInTRD,fInTRD,fIsComingOutTRD,fOutTRD); + + if (!fIsEnteringInTRD || !fIsComingOutTRD) { // zone 5 + + Float_t p[2]={0.,0.}; + + if (isTRDout) { + + if (pT<0.4) { + p[0] = 900.; p[1] = 0.; + } else if (pT>=0.40 && pT<0.45) { + p[0] = 3100.; p[1] = -6000.; + } else if (pT>=0.45 && pT<0.50) { + p[0] = 1660.; p[1] = -2800.; + } else if (pT>=0.50 && pT<0.55) { + p[0] = 860.; p[1] = -1200.; + } else { //if (pT>=0.55) + p[0] = 200.; p[1] = 0.; + } + + } else { + + if (pT<0.30) { + p[0] = 0.; p[1] = 0.; + } else if (pT>=0.30 && pT<0.32) { + p[0] = 570.; p[1] = 0.; + } else if (pT>=0.32 && pT<0.35) { + p[0] = 3171.; p[1] = -8133.; + } else if (pT>=0.35 && pT<0.40) { + p[0] = 1815.; p[1] = -4260.; + } else if (pT>=0.40 && pT<0.45) { + p[0] = 715.; p[1] = -1471.; + } else if (pT>=0.45 && pT<0.50) { + p[0] = 233.; p[1] = -407.; + } else if (pT>=0.50 && pT<0.55) { + p[0] = 408.; p[1] = -752.; + } else { //if (pT>=0.55) + p[0] = 408.-752.*0.55; p[1] = 0.; + } + + } + + delta = p[0]+p[1]*pT; + // Printf("Kaon time: %f %f %f %f",p[0],p[1],length,delta); + + } else { + + Float_t p[2] = {0.,0.}; + + if ( fInTRD && fOutTRD) { // zone 1 + + if (isTRDout) { + + if (length<95.) { + p[0] = 20.; p[1] = 0.; + } else if (length>=95. && length<195.) { + p[0] = -24.0; p[1] = 0.10+0.0041*length; + } else {//if (length>=195.) + p[0] = 150.; p[1] = 0.; + } + + } else { // !isTRDout + + p[0] = 40.; p[1] = 0.; + + } + + } else if (!fInTRD && !fOutTRD) { // zone 2 + + p[0] = 0.; p[1] = 0.; + + } else if ( fInTRD && !fOutTRD) { // zone 3 + + if (isTRDout) { + + if (length< 15.) { + p[0] = 180.; p[1] = 0.; + } else if (length>= 15. && length< 55.) { + p[0] = 215.; p[1] = -2.5; + } else {//if (length>=55.) + p[0] = 78.; p[1] = 0.; + } + + } else { // !isTRDout + + p[0] = 0.; p[1] = 0.; + + } + + } else if (!fInTRD && fOutTRD) { // zone 4 + + if (isTRDout) { + + if (length< 55.) { + p[0] = 0.; p[1] = 0.; + } else if (length>= 55. && length<115.) { + p[0] = -85.; p[1] = 1.9; + } else {//if (length>=115.) + p[0] = 100.; p[1] = 0.; + } + + } else { // !isTRDout + + p[0] = 0.; p[1] = 0.; + + } + + } + + delta = p[0]+p[1]*length; + // Printf("Kaon time: %f %f %f %f",p[0],p[1],length,delta); + + } + + return delta; + +} + +//________________________________________________________________________ +Double_t AliTOFTenderSupply::CorrectExpectedProtonTime(Double_t pT, + Double_t length, + Bool_t isTRDout) +{ + // correction for expected time for protons + + Double_t delta=0.; + // Printf("Flags Ent In ComingOut Out %d %d %d %d",fIsEnteringInTRD,fInTRD,fIsComingOutTRD,fOutTRD); + + if (!fIsEnteringInTRD || !fIsComingOutTRD) { // zone 5 + Float_t p[2]={0.,0.}; + + + if (isTRDout) { + + if (pT<0.375) { + p[0] = 1000.; p[1] = 0.; + } else if (pT>=0.375 && pT<0.45) { + p[0] = 1500.; p[1] = 0.; + } else if (pT>=0.45 && pT<0.50) { + p[0] = 4650.; p[1] = -7000.; + } else if (pT>=0.50 && pT<0.55) { + p[0] = 3150.; p[1] = -4000.; + } else { //if (pT>=0.55) + p[0] = 3150. -4000.*0.55; p[1] = 0.; + } + + } else { + + if (pT<0.32) { + p[0] = 2963.-5670.*0.032; p[1] = 0.; + } else if (pT>=0.32 && pT<0.35) { + p[0] = 2963.; p[1] = -5670.; + } else if (pT>=0.35 && pT<0.40) { + p[0] = 4270.; p[1] = -9400.; + } else if (pT>=0.40 && pT<0.45) { + p[0] = 1550.; p[1] = -2600.; + } else if (pT>=0.45 && pT<0.50) { + p[0] = 1946.; p[1] = -3480.; + } else if (pT>=0.50 && pT<0.55) { + p[0] = 1193.; p[1] = -1974.; + } else { //if (pT>=0.55) + p[0] = 1193.-1974.*0.55; p[1] = 0.; + } + + } + + delta = p[0]+p[1]*pT; + // Printf("Proton time: %f %f %f %f",p[0],p[1],length,delta); + + } else { + + Float_t p[2] = {0.,0.}; + + if ( fInTRD && fOutTRD) { // zone 1 + + if (isTRDout) { + + if (length<90.) { + p[0] = 0.; p[1] = 0.; + } else if (length>=90. && length<200.) { + p[0] = 1063.; p[1] = -32.+0.30*length-0.00072*length*length; + } else {//if (length>=200.) + p[0] = 900.; p[1] = 0.; + } + + } else { // !isTRDout + + p[0] = 80.; p[1] = 0.; + + } + + } else if (!fInTRD && !fOutTRD) { // zone 2 + + if (isTRDout) { + p[0] = 0.; p[1] = 0.; + } else { + if (length<125.) { + p[0] = 0.; p[1] = 0.; + } else if (length>=125. && length<180.) { + p[0] = -132.; p[1] = 1.3; + } else { + p[0] = 100.; p[1] = 0.; + } + + } + + } else if ( fInTRD && !fOutTRD) { // zone 3 + + if (isTRDout) { + + if (length< 30.) { + p[0] = 670.; p[1] = 0.; + } else if (length>= 30. && length<155.) { + p[0] = 944.; p[1] = -11.+0.064*length; + } else {//if (length>=155.) + p[0] = 780.; p[1] = 0.; + } + + } else { // !isTRDout + + if (length< 30.) { + p[0] = 140.; p[1] = -4.5; + } else { + p[0] = 0.; p[1] = 0.; + } + + } + + } else if (!fInTRD && fOutTRD) { // zone 4 + + if (isTRDout) { + + if (length< 45.) { + p[0] = 130.; p[1] = 0.; + } else if (length>= 45. && length<120.) { + p[0] = -190.; p[1] = 6.5; + } else {//if (length>=120.) + p[0] = 750.; p[1] = 0.; + } + + } else { // !isTRDout + + if (length<75.5) { + p[0] = 0.; p[1] = 0.; + } else if (length>= 75.5 && length<90.) { + p[0] = -830.; p[1] = 11.; + } else { + p[0] = 160.; p[1] = 0.; + } + + } + + } + + delta = p[0]+p[1]*length; + // Printf("Proton time: %f %f %f %f",p[0],p[1],length,delta); + + } + + return delta; + +} + +//________________________________________________________________________ +Double_t AliTOFTenderSupply::EstimateLengthInTRD1(AliESDtrack *track) +{ + + Double_t xyz0[3]={0.,0.,0.}; + Bool_t stayInTRD = track->GetXYZAt(fRhoTRDin,fMagField,xyz0); + + Double_t phi0 = TMath::Pi()+TMath::ATan2(-xyz0[1],-xyz0[0]); + phi0 *= TMath::RadToDeg(); + stayInTRD = stayInTRD && ( (phi0>= 0. && phi0<= 40.) || + (phi0>=140. && phi0<=220.) || + (phi0>=340. && phi0<=360.) ); + + Double_t trackLengthInTRD = 0.; + Int_t iStep=0; + + Double_t b[3];track->GetBxByBz(b); + + Double_t xyz1[3]={0.,0.,0.}; + Double_t rho = fRhoTRDin; + while (stayInTRD && rho<=fRhoTRDout) { + iStep++; + rho += fStep; + + for (Int_t ii=0; ii<3; ii++) xyz1[ii]=0.; + stayInTRD = track->GetXYZAt(rho,fMagField,xyz1); + Double_t phi1 = TMath::Pi()+TMath::ATan2(-xyz1[1],-xyz1[0]); + phi1 *= TMath::RadToDeg(); + stayInTRD = stayInTRD && ( (phi1>= 0. && phi1<= 40.) || + (phi1>=140. && phi1<=220.) || + (phi1>=340. && phi1<=360.) ); + + Double_t l2 = TMath::Sqrt((xyz1[0]-xyz0[0])*(xyz1[0]-xyz0[0]) + + (xyz1[1]-xyz0[1])*(xyz1[1]-xyz0[1]) + + (xyz1[2]-xyz0[2])*(xyz1[2]-xyz0[2])); + trackLengthInTRD += l2; + + for (Int_t ii=0; ii<3; ii++) xyz0[ii]=xyz1[ii]; + } + + return trackLengthInTRD; + +} + +//________________________________________________________________________ +Double_t AliTOFTenderSupply::EstimateLengthInTRD2(AliESDtrack *track) +{ + + Double_t xyz0[3]={0.,0.,0.}; + Bool_t stayInTRD = track->GetXYZAt(fRhoTRDout,fMagField,xyz0); + + Double_t phi0 = TMath::Pi()+TMath::ATan2(-xyz0[1],-xyz0[0]); + phi0 *= TMath::RadToDeg(); + stayInTRD = stayInTRD && ( (phi0>= 0. && phi0<= 40.) || + (phi0>=140. && phi0<=220.) || + (phi0>=340. && phi0<=360.) ); + + Double_t trackLengthInTRD = 0.; + Int_t iStep=0; + + Double_t b[3];track->GetBxByBz(b); + + Double_t xyz1[3]={0.,0.,0.}; + Double_t rho = fRhoTRDout; + while (stayInTRD && rho>=fRhoTRDin) { + iStep++; + rho -= fStep; + + for (Int_t ii=0; ii<3; ii++) xyz1[ii]=0.; + stayInTRD = track->GetXYZAt(rho,fMagField,xyz1); + Double_t phi1 = TMath::Pi()+TMath::ATan2(-xyz1[1],-xyz1[0]); + phi1 *= TMath::RadToDeg(); + stayInTRD = stayInTRD && ( (phi1>= 0. && phi1<= 40.) || + (phi1>=140. && phi1<=220.) || + (phi1>=340. && phi1<=360.) ); + + Double_t l2 = TMath::Sqrt((xyz0[0]-xyz1[0])*(xyz0[0]-xyz1[0]) + + (xyz0[1]-xyz1[1])*(xyz0[1]-xyz1[1]) + + (xyz0[2]-xyz1[2])*(xyz0[2]-xyz1[2])); + trackLengthInTRD += l2; + + for (Int_t ii=0; ii<3; ii++) xyz0[ii]=xyz1[ii]; + } + + return trackLengthInTRD; + +} + +//________________________________________________________________________ +Double_t AliTOFTenderSupply::EstimateLengthOutTRD(AliESDtrack *track) +{ + + Double_t xyz0[3]={0.,0.,0.}; + Bool_t stayInTRD = track->GetXYZAt(fRhoTRDin,fMagField,xyz0); + + Double_t phi0 = TMath::Pi()+TMath::ATan2(-xyz0[1],-xyz0[0]); + phi0 *= TMath::RadToDeg(); + stayInTRD = stayInTRD && !( (phi0>= 0. && phi0<= 40.) || + (phi0>=140. && phi0<=220.) || + (phi0>=340. && phi0<=360.) ); + + Double_t trackLengthInTRD = 0.; + Int_t iStep=0; + + Double_t b[3];track->GetBxByBz(b); + + Double_t xyz1[3]={0.,0.,0.}; + Double_t rho = fRhoTRDin; + while (stayInTRD && rho<=fRhoTRDout) { + iStep++; + rho += fStep; + + for (Int_t ii=0; ii<3; ii++) xyz1[ii]=0.; + stayInTRD = track->GetXYZAt(rho,fMagField,xyz1); + Double_t phi1 = TMath::Pi()+TMath::ATan2(-xyz1[1],-xyz1[0]); + phi1 *= TMath::RadToDeg(); + stayInTRD = stayInTRD && !( (phi1>= 0. && phi1<= 40.) || + (phi1>=140. && phi1<=220.) || + (phi1>=340. && phi1<=360.) ); + + Double_t l2 = TMath::Sqrt((xyz1[0]-xyz0[0])*(xyz1[0]-xyz0[0]) + + (xyz1[1]-xyz0[1])*(xyz1[1]-xyz0[1]) + + (xyz1[2]-xyz0[2])*(xyz1[2]-xyz0[2])); + trackLengthInTRD += l2; + + for (Int_t ii=0; ii<3; ii++) xyz0[ii]=xyz1[ii]; + } + + return trackLengthInTRD; + +} + +//________________________________________________________________________ +Int_t AliTOFTenderSupply::GetOCDBVersion(Int_t runNo) +{ + Int_t verNo = -1; + if ( (runNo>=118503 && runNo <=121040) ) { // LHC10C + if (fRecoPass == 2) { // on pass2 + if (runNo >= 119159 && runNo <= 119163) verNo=3; + else if (runNo >= 119837 && runNo <= 119934) verNo=4; + else if (runNo >= 120067 && runNo <= 120244) verNo=4; + else if (runNo >= 120503 && runNo <= 120505) verNo=4; + else if (runNo >= 120616 && runNo <= 120671) verNo=4; + else if (runNo >= 120741 && runNo <= 120829) verNo=4; + } + } + return verNo; +} + + +//__________________________________________________________________________ +void AliTOFTenderSupply::LoadTOFPIDParams(Int_t runNumber) +{ + // + // Load the TOF pid params from the OADB + // + + if (fTOFPIDParams) delete fTOFPIDParams; + fTOFPIDParams=0x0; + + TFile *oadbf = new TFile("$ALICE_ROOT/OADB/COMMON/PID/data/TOFPIDParams.root"); + if (oadbf && oadbf->IsOpen()) { + AliInfo("Loading TOF Params from $ALICE_ROOT/OADB/COMMON/PID/data/TOFPIDParams.root"); + AliOADBContainer *oadbc = (AliOADBContainer *)oadbf->Get("TOFoadb"); + if (oadbc) fTOFPIDParams = dynamic_cast(oadbc->GetObject(runNumber,"TOFparams")); + oadbf->Close(); + delete oadbc; + } + delete oadbf; + + if (!fTOFPIDParams) { + AliError("TOFPIDParams.root not found in $ALICE_ROOT/OADB/COMMON/PID/data !!"); + fTOFPIDParams = new AliTOFPIDParams; + fTOFPIDParams->SetTOFresolution(90.); + fTOFPIDParams->SetStartTimeMethod(AliESDpid::kTOF_T0); + } +} + + +//__________________________________________________________________________ +Double_t AliTOFTenderSupply::SampleT0Signal(Int_t side, Double_t zvertex, Double_t tracklets) const +{ + Double_t p = 0.; + Double_t signal = 99999.; + if (TMath::Abs(zvertex) > 10.) return signal; + Double_t resolution[2] = {75.,65.}; + if (side == 0) { + if (zvertex >= 5. && zvertex <= 10.) { +// p = 0.84 - exp(-1.03 - 0.31*tracklets); + p = 0.88 - exp(-1.1 - 0.32*tracklets); + } + else if (zvertex >=-10. && zvertex <5.) { +// p = 0.82 - exp(-0.81 - 0.25*tracklets); + p = 0.77 - exp(-0.88 - 0.25*tracklets); + } + } else if (side == 1) { + if (zvertex >= -10. && zvertex < -5.) { + p = 0.99 - exp(-0.74 - 0.34*tracklets); + } + else if (zvertex >=-5. && zvertex <10.) { + p = 0.96 - exp(-0.51 - 0.27*tracklets); + } + } else { + return signal; + } + Double_t pu = gRandom->Rndm(); + if (fDebugLevel > 1) { + printf(" TofTender: T0 simul [side %d zvt %f track %f] %f [pu: %f]",side,zvertex,tracklets,p,pu); + if (pu signal will be generated: "); + else printf(" --> signal wil not be generated: "); + } + if (pu < p) signal = gRandom->Gaus(0.,resolution[side]); + if (fDebugLevel >1) Printf(" %f ",signal); + return signal; +} + +void AliTOFTenderSupply::GetTrackletsForT0(AliESDEvent* event, Double_t *trkA, Double_t *trkC) const +{ + Double_t minetaA = 0.7; + Double_t maxetaA = 1.4; + Double_t minetaC = -1.4; + Double_t maxetaC = -0.7; + AliMultiplicity *alimult = (AliMultiplicity *)event->GetMultiplicity(); + Int_t nTr=alimult->GetNumberOfTracklets(); + if (fDebugLevel > 1) Printf(" TofTender: T0 simul number of tracklets %d",nTr); + Int_t nTrackletsA=0, nTrackletsC=0; + for(Int_t iTr=0; iTrGetEta(iTr); + if(eta>minetaA && etaminetaC && eta 1) Printf(" TofTender: T0 simul [tracklet # %d] ETA: %f %d %d",nTr,eta,nTrackletsA,nTrackletsC); + } + *trkA=(Double_t)nTrackletsA; + *trkC=(Double_t)nTrackletsC; +} + + diff --git a/TENDER/TenderSupplies/AliTOFTenderSupply.h b/TENDER/TenderSupplies/AliTOFTenderSupply.h new file mode 100644 index 00000000000..d136dd8fab5 --- /dev/null +++ b/TENDER/TenderSupplies/AliTOFTenderSupply.h @@ -0,0 +1,124 @@ +#ifndef ALITOFTENDERSUPPLY_H +#define ALITOFTENDERSUPPLY_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +//////////////////////////////////////////////////////////////////////// +// // +// TOF tender, reapply pid on the fly // +// // +//////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +class AliESDpid; +class AliTOFcalib; +class AliTOFT0maker; +class AliESDEevent; +class AliESDtrack; +class AliTOFTenderSupply: public AliTenderSupply { + +public: + AliTOFTenderSupply(); + AliTOFTenderSupply(const char *name, const AliTender *tender=NULL); + + virtual ~AliTOFTenderSupply(){;} + + virtual void Init(); + virtual void ProcessEvent(); + + // TOF tender methods + void SetIsMC(Bool_t flag=kFALSE){fIsMC=flag;} + void SetCorrectExpTimes(Bool_t flag=kTRUE){fCorrectExpTimes=flag;} + void SetT0DetectorAdjust(Bool_t flag=kFALSE){fT0DetectorAdjust=flag;} + void SetDebugLevel(Int_t flag=0){fDebugLevel=flag;} + void SetLHC10dPatch(Bool_t flag=kFALSE){ + if (flag == kTRUE) { + AliInfo(" **** TOF Tender: special setting LHC10d patch is ON"); + AliInfo(" **** TOF Tender: this setting is valid only on LHC10d pass2"); + } + fLHC10dPatch=flag; + return; + } + void SetAutomaticSettings(Bool_t flag=kTRUE){fAutomaticSettings=flag;} + void SetForceCorrectTRDBug(Bool_t flag=kTRUE){fForceCorrectTRDBug=flag;} + void SetUserRecoPass(Int_t flag=0){fUserRecoPass=flag;} + Int_t GetRecoPass(void){return fRecoPass;} + void DetectRecoPass(); + + /* theoretical expected time: related stuff for LHC10d patch */ + static Float_t GetBetaTh(Float_t m, Float_t p) {return TMath::Sqrt(1. / (1. + m * m / (p * p)));}; // get beta th + static Float_t GetExpTimeTh(Float_t m, Float_t p, Float_t L) {return L / 2.99792457999999984e-02 / GetBetaTh(m, p);}; // get exp time th + void RecomputeTExp(AliESDEvent *event) const; + void RecomputeTExp(AliESDtrack *track) const; + void FixTRDBug(AliESDEvent *event); + void FixTRDBug(AliESDtrack *track); + void InitGeom(); + void FindTRDFix(AliESDtrack *track,Double_t *corr); + Double_t EstimateLengthInTRD1(AliESDtrack *track); + Double_t EstimateLengthInTRD2(AliESDtrack *track); + Double_t EstimateLengthOutTRD(AliESDtrack *track); + void CorrectDeltaTimes(Double_t pT, Double_t length, Bool_t isTRDout, Double_t *corrections); + Double_t CorrectExpectedProtonTime(Double_t pT,Double_t length, Bool_t isTRDout); + Double_t CorrectExpectedKaonTime(Double_t pT,Double_t length, Bool_t isTRDout); + Double_t CorrectExpectedPionTime(Double_t pT,Double_t length, Bool_t isTRDout); + Int_t GetOCDBVersion(Int_t runNumber); + void LoadTOFPIDParams(Int_t runNumber); + + /* to invent a T0 signal... */ + Double_t SampleT0Signal(Int_t side, Double_t zvertex, Double_t tracklets) const; + void GetTrackletsForT0(AliESDEvent *event, Double_t *trkA, Double_t *trkC) const; + +private: + AliESDpid *fESDpid; //! ESD pid object + + + Bool_t fTenderNoAction; // flag for periods when tender action is not requested/not supported + Bool_t fIsMC; // flag for MC data: adds start Time + Bool_t fCorrectExpTimes; // flag to apply Expected Time correction + Bool_t fCorrectTRDBug; // flag to fix wrong dE/dx inside TRD + Bool_t fLHC10dPatch; // flag to apply special patch for LHC10d (reconstructed with wrong geometry) + Bool_t fT0DetectorAdjust; // DATA: flag to apply offsets to T0 data (LHC10b, c, d, e) + // MC: add smearing to simulated data (LHC10b,c,d,e) + Int_t fDebugLevel; // debug purposes 0= no output, 1 Info, 2 lot of info.... + Bool_t fAutomaticSettings; // enable/disable automatic (per run) settings + Int_t fRecoPass; // reconstruction pass: the tender applies different recipes depending on the pass + Int_t fUserRecoPass; // when reco pass is selected by user + Bool_t fForceCorrectTRDBug; // force TRD bug correction (for some bad MC production...) + Bool_t fT0Simulate; // ignore existing T0 data (if any) and simulate them + + + // variables for TOF calibrations and timeZero setup + AliTOFPIDParams *fTOFPIDParams; //! TOF PID Params - period depending (OADB loaded) + AliTOFcalib *fTOFCalib; // recalibrate TOF signal with OCDB + AliTOFT0maker *fTOFT0maker; // computation of TOF-T0 + Float_t fT0shift[4]; // T0 detector correction from OCDB + Float_t fT0IntercalibrationShift; // extra-shift to adjust TOF/TO intercalibration issue in some period + + // variables to parametrize MC + static Float_t fgT0Aresolution; // T0 resolution A-Side (MC) + static Float_t fgT0Cresolution; // T0 resolution C-Side (MC) + + // variables to steer TRD bug fix + Bool_t fGeomSet; // steer loading GRP entry + Bool_t fIsEnteringInTRD; + Bool_t fInTRD; + Bool_t fIsComingOutTRD; + Bool_t fOutTRD; + Float_t fRhoTRDin; // cm + Float_t fRhoTRDout; // cm + Float_t fStep; // cm + Double_t fMagField; // magnetic field value [kGauss] + ULong64_t fCDBkey; + + AliTOFTenderSupply(const AliTOFTenderSupply&c); + AliTOFTenderSupply& operator= (const AliTOFTenderSupply&c); + + ClassDef(AliTOFTenderSupply, 12); +}; + + +#endif diff --git a/TENDER/TenderSupplies/AliTPCTenderSupply.cxx b/TENDER/TenderSupplies/AliTPCTenderSupply.cxx new file mode 100644 index 00000000000..3800dec1096 --- /dev/null +++ b/TENDER/TenderSupplies/AliTPCTenderSupply.cxx @@ -0,0 +1,560 @@ +/************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliTPCTenderSupply.h" + +ClassImp(AliTPCTenderSupply) + +AliTPCTenderSupply::AliTPCTenderSupply() : +AliTenderSupply(), +fESDpid(0x0), +fGainNew(0x0), +fGainOld(0x0), +fGainAttachment(0x0), +fIsMC(kFALSE), +fGainCorrection(kTRUE), +fAttachmentCorrection(kFALSE), +fPcorrection(kFALSE), +fMultiCorrection(kFALSE), +fArrPidResponseMaster(0x0), +fMultiCorrMean(0x0), +fMultiCorrSigma(0x0), +fSpecificStorages(0x0), +fDebugLevel(0), +fMip(50), +fGRP(0x0), +fBeamType("PP"), +fLHCperiod(), +fMCperiod(), +fRecoPass(0) +{ + // + // default ctor + // +} + +//_____________________________________________________ +AliTPCTenderSupply::AliTPCTenderSupply(const char *name, const AliTender *tender) : +AliTenderSupply(name,tender), +fESDpid(0x0), +fGainNew(0x0), +fGainOld(0x0), +fGainAttachment(0x0), +fIsMC(kFALSE), +fGainCorrection(kTRUE), +fAttachmentCorrection(kFALSE), +fPcorrection(kFALSE), +fMultiCorrection(kFALSE), +fArrPidResponseMaster(0x0), +fMultiCorrMean(0x0), +fMultiCorrSigma(0x0), +fSpecificStorages(0x0), +fDebugLevel(0), +fMip(50), +fGRP(0x0), +fBeamType("PP"), +fLHCperiod(), +fMCperiod(), +fRecoPass(0) +{ + // + // named ctor + // +} + +//_____________________________________________________ +void AliTPCTenderSupply::Init() +{ + // + // Initialise TPC tender + // + + AliLog::SetClassDebugLevel("AliTPCTenderSupply",10); + AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager(); + // + // Setup PID object + // + fIsMC=mgr->GetMCtruthEventHandler(); + + // 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(fIsMC); + fTender->GetESDhandler()->SetESDpid(fESDpid); + } + + //setup specific storages + if (fSpecificStorages){ + TNamed *storage; + TIter nextStorage(fSpecificStorages);; + while ( (storage=(TNamed*)nextStorage()) ){ + fTender->GetCDBManager()->SetSpecificStorage(storage->GetName(),storage->GetTitle()); + AliInfo(Form("Setting specific storage: %s (%s)",storage->GetName(), storage->GetTitle())); + } + } + + if (fIsMC){ + //force no gain and P correction in MC + fGainCorrection=kFALSE; + fPcorrection=kFALSE; + fAttachmentCorrection=kFALSE; + } +} + +//_____________________________________________________ +void AliTPCTenderSupply::ProcessEvent() +{ + // + // Reapply pid information + // + + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + + //load gain correction if run has changed + if (fTender->RunChanged()){ + SetBeamType(); + SetRecoInfo(); + if ( fBeamType == "PBPB" ) fMultiCorrection=kTRUE; + + if (fDebugLevel>0) AliInfo(Form("Run Changed (%d)",fTender->GetRun())); + SetParametrisation(); + if (fGainCorrection) SetSplines(); + } + + // + // get gain correction factor + // + Double_t corrFactor = GetGainCorrection(); + Double_t corrAttachSlope = 0; + Double_t corrGainMultiplicityPbPb=1; + if (fAttachmentCorrection && fGainAttachment) corrAttachSlope = fGainAttachment->Eval(event->GetTimeStamp()); + if (fMultiCorrection&&fMultiCorrMean) corrGainMultiplicityPbPb = fMultiCorrMean->Eval(GetTPCMultiplicityBin()); + + // + // - correct TPC signals + // - recalculate PID probabilities for TPC + // - correct TPC signal multiplicity dependence + + Int_t ntracks=event->GetNumberOfTracks(); + for(Int_t itrack = 0; itrack < ntracks; itrack++){ + AliESDtrack *track=event->GetTrack(itrack); + const AliExternalTrackParam *inner=track->GetInnerParam(); + + // skip tracks without TPC information + if (!inner) continue; + + //calculate total gain correction factor given by + // o gain calibration factor + // o attachment correction + // o multiplicity correction in PbPb + Float_t meanDrift= 250. - 0.5*TMath::Abs(2*inner->GetZ() + (247-83)*inner->GetTgl()); + Double_t corrGainTotal=corrFactor*(1 + corrAttachSlope*180.)/(1 + corrAttachSlope*meanDrift)/corrGainMultiplicityPbPb; + + // apply gain correction + track->SetTPCsignal(track->GetTPCsignal()*corrGainTotal ,track->GetTPCsignalSigma(), track->GetTPCsignalN()); + + // recalculate pid probabilities + fESDpid->MakeTPCPID(track); + } +} + +//_____________________________________________________ +Double_t AliTPCTenderSupply::GetTPCMultiplicityBin() +{ + // + // Get TPC multiplicity in bins of 150 + // + + AliESDEvent *event=fTender->GetEvent(); + const AliESDVertex* vertexTPC = event->GetPrimaryVertexTPC(); + Double_t tpcMulti=0.; + if(vertexTPC){ + Double_t vertexContribTPC=vertexTPC->GetNContributors(); + tpcMulti=vertexContribTPC/150.; + if (tpcMulti>20.) tpcMulti=20.; + } + return tpcMulti; +} + +//_____________________________________________________ +Double_t AliTPCTenderSupply::GetMultiplicityCorrectionMean(Double_t tpcMulti) +{ + // + // calculate correction factor for dEdx mean + // + Double_t meancorrection; + if (fIsMC) + { + // MC data + meancorrection=1.00054 + (0.00189566)*tpcMulti + (2.07777e-05)*tpcMulti*tpcMulti; + } + else + { + // real data + meancorrection=0.999509 + (-0.00271488)*tpcMulti + (-2.98873e-06)*tpcMulti*tpcMulti; + } + + return meancorrection; + +} + +//_____________________________________________________ +Double_t AliTPCTenderSupply::GetMultiplicityCorrectionSigma(Double_t tpcMulti) +{ + // + // calculate correction factor for dEdx sigma + // + Double_t sigmacorrection; + if (fIsMC) + { + // MC data + sigmacorrection=0.95972 + 0.0103721*tpcMulti; + } + else + { + // real data + sigmacorrection=1.01817 + 0.0143673*tpcMulti; + } + return sigmacorrection; + +} + +//_____________________________________________________ +void AliTPCTenderSupply::SetSplines() +{ + // + // Get Gain splines from OCDB + // + + AliInfo("Update Gain splines"); + + // + // Get GPR info for pressure correction + // + fPcorrection=kFALSE; + + AliCDBEntry *entryGRP=fTender->GetCDBManager()->Get("GRP/GRP/Data",fTender->GetRun()); + if (!entryGRP) { + AliError("No new GRP entry found"); + } else { + fGRP = (AliGRPObject*)entryGRP->GetObject(); + } + if (fDebugLevel>1) AliInfo(Form("GRP entry used: %s",entryGRP->GetId().ToString().Data())); + + fGainNew=0x0; + fGainOld=0x0; + // + //find previous entry from the UserInfo + // +// TTree *tree=((TChain*)fTender->GetInputData(0))->GetTree(); + AliAnalysisManager*mgr = AliAnalysisManager::GetAnalysisManager(); + AliAnalysisTaskSE *task = (AliAnalysisTaskSE*)mgr->GetTasks()->First(); + if (!task) return; + TTree *tree=((TChain*)task->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; + } + + if (fDebugLevel>1) AliInfo(Form("Used old Gain entry: %s",entry->GetId().ToString().Data())); + + 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 + // + + // This is in principle sill needed for the 2009 data and the 2010 b+c pass1 data + // however not supported any longer. + // For the LHC10c pass2 there is an exception and we still load the splines, but a defined version + // In case the attachment correction should be check again, this part of the code needs to be changed + // in order to load the gain entry again + Bool_t special10cPass2=fLHCperiod=="LHC10C" && fRecoPass==2; + + AliCDBEntry *entryNew=0x0; + if (special10cPass2) { + entryNew=fTender->GetCDBManager()->Get("TPC/Calib/TimeGain",fTender->GetRun(),8); + } + if (!entryNew) { + AliError("No new gain calibration entry found"); + return; + } + if (fDebugLevel>1) AliInfo(Form("Used new Gain entry: %s",entryNew->GetId().ToString().Data())); + + if (entryNew->GetId().GetLastRun()==AliCDBRunRange::Infinity()){ + if (fDebugLevel>0) AliInfo("Use P correction"); + fPcorrection=kTRUE; + } + + TObjArray *arrSplines=(TObjArray *)entryNew->GetObject(); + if (!arrSplines) { + AliError("Gain Splines array not found in new calibration entry"); + return; + } + + fGainNew = (AliSplineFit*)arrSplines->At(0); + fGainAttachment = (TGraphErrors*)arrSplines->FindObject("TGRAPHERRORS_MEAN_ATTACHMENT_BEAM_ALL"); + + 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 (fGainOld){ + //TODO TODO TODO + //first correction for the eval const problem + // needs to be removed when the fix is in AliROOT and + // the production was done with EvalGraphConst + // This should be the case from V4-20-Rev11 on + //TODO TODO TODO + if ( fLHCperiod.Contains("LHC09") || + ((fLHCperiod=="LHC10B" || fLHCperiod=="LHC10C" || fLHCperiod=="LHC10D") && fRecoPass==2) || + (fLHCperiod=="LHC10E" && fRecoPass==1) || + (fLHCperiod=="LHC10H" && fRecoPass==1) + ) { + Double_t valDefault = fGainOld->Eval(time); + Double_t valConst = AliTPCcalibDButil::EvalGraphConst(fGainOld, time); + gain = valDefault/valConst; + } + + if (fGainNew){ + gain *= AliTPCcalibDButil::EvalGraphConst(fGainOld,time)/AliTPCcalibDButil::EvalGraphConst(fGainNew,time); + } + } + + //If there is only the default calibration, at least apply correction for pressure + if (fPcorrection){ + if (fGRP) { + Double_t pressure=fGRP->GetCavernAtmosPressure()->GetValue(time); +// gain=fGainOld->Eval(time)/(7.03814-0.00459798*pressure)/49.53*fMip; +// gain=fGainOld->Eval(time)/(7.03814-0.00459798*pressure)/51.51*fMip; + gain=AliTPCcalibDButil::EvalGraphConst(fGainOld,time)/(7.03814-0.00459798*pressure)/51.51*fMip; + } + } + + return gain; +} + +//_____________________________________________________ +void AliTPCTenderSupply::SetBeamType() +{ + // + // Set the beam type + // + + fBeamType=fTender->GetEvent()->GetBeamType(); + if (fBeamType.IsNull()||fBeamType.Contains("No Beam")) fBeamType="p-p"; + fBeamType.ToUpper(); + fBeamType.ReplaceAll("-",""); +} + +//_____________________________________________________ +void AliTPCTenderSupply::SetRecoInfo() +{ + // + // Set reconstruction information + // + + //reset information + fRecoPass=0; + fLHCperiod=""; + fMCperiod=""; + + //Get the current file to check the reconstruction pass (UGLY, but not stored in ESD... ) + AliESDInputHandler *esdIH = dynamic_cast (fTender->GetESDhandler()); + if (!esdIH) return; + TTree *tree= (TTree*)esdIH->GetTree(); + TFile *file= (TFile*)tree->GetCurrentFile(); + if (!file) { + AliError("Current file not found, cannot set reconstruction information"); + return; + } + + TString fileName(file->GetName()); + + Int_t run=fTender->GetRun(); + + + TPRegexp reg(".*(LHC11[a-z]+[0-9]+[a-z]*)/.*"); + //find the period by run number (UGLY, but not stored in ESD... ) + if (run>=114737&&run<=117223) { fLHCperiod="LHC10B"; fMCperiod="LHC10D1"; } + else if (run>=118503&&run<=121040) { fLHCperiod="LHC10C"; fMCperiod="LHC10D1"; } + else if (run>=122195&&run<=126437) { fLHCperiod="LHC10D"; fMCperiod="LHC10F6A"; } + else if (run>=127719&&run<=130850) { fLHCperiod="LHC10E"; fMCperiod="LHC10F6A"; } + else if (run>=133004&&run<=135029) { fLHCperiod="LHC10F"; fMCperiod="LHC10F6A"; } + else if (run>=135654&&run<=136377) { fLHCperiod="LHC10G"; fMCperiod="LHC10F6A"; } + else if (run>=136851&&run<=139517) { + fLHCperiod="LHC10H"; + fMCperiod="LHC10H8"; + if (reg.MatchB(fileName)) fMCperiod="LHC11A10"; + } + else if ( (run>=144871 && run <=146459 ) || ( run >=146686 && run<= 146860) ) { + // low energy: 146686 - 146860 + fLHCperiod="LHC11A"; fMCperiod="LHC10F6A"; + } + else if ( run>=148541 ){ + fLHCperiod="LHC11B"; fMCperiod="LHC10F6A"; + } + + //exception new pp MC productions from 2011 + if (fBeamType=="PP" && reg.MatchB(fileName)) fMCperiod="LHC11B2"; + + //find pass from file name (UGLY, but not stored in ESD... ) + if (fileName.Contains("/pass1")) { + fRecoPass=1; + } else if (fileName.Contains("/pass2")) { + fRecoPass=2; + } else if (fileName.Contains("/pass3")) { + fRecoPass=3; + } + +} + +//_____________________________________________________ +void AliTPCTenderSupply::SetParametrisation() +{ + // + // Change PbPb multiplicity gain correction factor + // + + if (fLHCperiod.IsNull()) { + AliError("No period set, not changing parametrisation"); + return; + } + + //Get CDB Entry with pid response parametrisations + AliCDBEntry *pidCDB=fTender->GetCDBManager()->Get("TPC/Calib/PidResponse",fTender->GetRun()); + if (!fArrPidResponseMaster && pidCDB){ + fArrPidResponseMaster=dynamic_cast(pidCDB->GetObject()); + AliInfo(Form("Using pid response objects: %s",pidCDB->GetId().ToString().Data())); + } + + if (!fArrPidResponseMaster){ + AliError("No valid PidResponse master found in OCDB"); + return; + } + //data type + TString datatype="DATA"; + TString period=fLHCperiod; + //in case of mc fRecoPass is per default 1 + if (fIsMC) { + datatype="MC"; + fRecoPass=1; + period=fMCperiod; + } + + // Set PbPb correction + fMultiCorrMean=(TF1*)fArrPidResponseMaster->FindObject(Form("TF1_%s_ALL_%s_PASS%d_%s_MEAN",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data())); + + if (fMultiCorrMean) AliInfo(Form("Setting multiplicity correction function: %s",fMultiCorrMean->GetName())); + +} + +//____________________________________________________________ +void AliTPCTenderSupply::AddSpecificStorage(const char* cdbPath, const char* storage) +{ + // + // Add a specific storage to be set up in Init + // + if (!fSpecificStorages) fSpecificStorages=new TObjArray; + fSpecificStorages->Add(new TNamed(cdbPath, storage)); +} + diff --git a/TENDER/TenderSupplies/AliTPCTenderSupply.h b/TENDER/TenderSupplies/AliTPCTenderSupply.h new file mode 100644 index 00000000000..2a47148519f --- /dev/null +++ b/TENDER/TenderSupplies/AliTPCTenderSupply.h @@ -0,0 +1,90 @@ +#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 + +#include + +class TObjArray; +class AliESDpid; +class AliSplineFit; +class AliGRPObject; +class TGraphErrors; +class AliAnalysisManager; +class TF1; + +class AliTPCTenderSupply: public AliTenderSupply { + +public: + AliTPCTenderSupply(); + AliTPCTenderSupply(const char *name, const AliTender *tender=NULL); + + virtual ~AliTPCTenderSupply(){;} + + void SetGainCorrection(Bool_t gainCorr) {fGainCorrection=gainCorr;} + void SetAttachmentCorrection(Bool_t attCorr) {fAttachmentCorrection=attCorr;} + void SetDebugLevel(Int_t level) {fDebugLevel=level;} + void SetMip(Double_t mip) {fMip=mip;} + void SetResponseFunctions(TObjArray *arr) {fArrPidResponseMaster=arr;} + Double_t GetMultiplicityCorrectionMean(Double_t tpcMulti); + Double_t GetMultiplicityCorrectionSigma(Double_t tpcMulti); + + void AddSpecificStorage(const char* cdbPath, const char* storage); + + virtual void Init(); + virtual void ProcessEvent(); + +private: + AliESDpid *fESDpid; //! ESD pid object + AliSplineFit *fGainNew; //! New gain correction + AliSplineFit *fGainOld; //! Old gain correction + TGraphErrors *fGainAttachment; //! new attachment correction + + Bool_t fIsMC; //! if or not we have MC analysis + Bool_t fGainCorrection; // Perform gain correction + Bool_t fAttachmentCorrection; // Perform attachment correction + Bool_t fPcorrection; //!Perform pressure correction + Bool_t fMultiCorrection; //!Perform multiplicity correction + TObjArray *fArrPidResponseMaster; //array with gain curves + TF1 *fMultiCorrMean; //!multiplicity correction for mean + TF1 *fMultiCorrSigma; //!multiplicity correction for resolution + TObjArray *fSpecificStorages; //array with specific storages + + Int_t fDebugLevel; //debug level + Double_t fMip; //mip position + + AliGRPObject *fGRP; //!GRP for pressure temperature correction + + TString fBeamType; //! beam type (PP) or (PBPB) + TString fLHCperiod; //! LHC period + TString fMCperiod; //! corresponding MC period to use for the splines + Int_t fRecoPass; //! reconstruction pass + + void SetSplines(); + Double_t GetGainCorrection(); + + Double_t GetTPCMultiplicityBin(); + + void SetBeamType(); + + void SetParametrisation(); + void SetRecoInfo(); + + AliTPCTenderSupply(const AliTPCTenderSupply&c); + AliTPCTenderSupply& operator= (const AliTPCTenderSupply&c); + + ClassDef(AliTPCTenderSupply, 2); // TPC tender task +}; + + +#endif + diff --git a/TENDER/TenderSupplies/AliTRDTenderSupply.cxx b/TENDER/TenderSupplies/AliTRDTenderSupply.cxx new file mode 100644 index 00000000000..dff80e8c74f --- /dev/null +++ b/TENDER/TenderSupplies/AliTRDTenderSupply.cxx @@ -0,0 +1,651 @@ +/************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "AliTRDonlineTrackMatching.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliTRDTenderSupply.h" + +ClassImp(AliTRDTenderSupply) + +//_____________________________________________________ +AliTRDTenderSupply::AliTRDTenderSupply() : + AliTenderSupply(), + fESD(NULL), + fESDpid(NULL), + fTrdOnlineTrackMatcher(NULL), + fChamberGainOld(NULL), + fChamberGainNew(NULL), + fChamberVdriftOld(NULL), + fChamberVdriftNew(NULL), + fRunByRunCorrection(NULL), + fPIDmethod(k1DLQpid), + fNormalizationFactor(1.), + fPthreshold(0.8), + fNBadChambers(0), + fGeoFile(NULL), + fGainCorrection(kTRUE), +// fLoadReferences(kFALSE), +// fLoadReferencesFromCDB(kFALSE), + fLoadDeadChambers(kFALSE), + fHasReferences(kFALSE), + fHasNewCalibration(kTRUE), + fDebugMode(kFALSE), + fRedoTrdMatching(kTRUE), + fNameRunByRunCorrection(), + fNormalizationFactorArray(NULL) +{ + // + // default ctor + // + memset(fBadChamberID, 0, sizeof(Int_t) * kNChambers); + memset(fSlicesForPID, 0, sizeof(UInt_t) * 2); +} + +//_____________________________________________________ +AliTRDTenderSupply::AliTRDTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender), + fESD(NULL), + fESDpid(NULL), + fTrdOnlineTrackMatcher(NULL), + fChamberGainOld(NULL), + fChamberGainNew(NULL), + fChamberVdriftOld(NULL), + fChamberVdriftNew(NULL), + fRunByRunCorrection(NULL), + fPIDmethod(k1DLQpid), + fNormalizationFactor(1.), + fPthreshold(0.8), + fNBadChambers(0), + fGeoFile(NULL), + fGainCorrection(kTRUE), +// fLoadReferences(kFALSE), +// fLoadReferencesFromCDB(kFALSE), + fLoadDeadChambers(kFALSE), + fHasReferences(kFALSE), + fHasNewCalibration(kTRUE), + fDebugMode(kFALSE), + fRedoTrdMatching(kTRUE), + fNameRunByRunCorrection(), + fNormalizationFactorArray(NULL) +{ + // + // named ctor + // + memset(fSlicesForPID, 0, sizeof(UInt_t) * 2); + memset(fBadChamberID, 0, sizeof(Int_t) * kNChambers); +} + +//_____________________________________________________ +AliTRDTenderSupply::~AliTRDTenderSupply() +{ + // + // dtor + // + if(fNormalizationFactorArray) delete fNormalizationFactorArray; + delete fTrdOnlineTrackMatcher; +} + +//_____________________________________________________ +void AliTRDTenderSupply::Init() +{ + // + // Initialise TRD tender + // + + AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager(); + + // 1DLQ PID implemented in the AliESD object + fESDpid=fTender->GetESDhandler()->GetESDpid(); + if (!fESDpid) { + fESDpid=new AliESDpid; + fTender->GetESDhandler()->SetESDpid(fESDpid); + } + // Load References + //if(fLoadReferences && !fLoadReferencesFromCDB) LoadReferences(); + //fESDpid->GetTRDResponse().SetGainNormalisationFactor(fNormalizationFactor); + //fESDpid->SetTRDslicesForPID(fSlicesForPID[0], fSlicesForPID[1]); + + if(fNameRunByRunCorrection.Length()) LoadRunByRunCorrection(fNameRunByRunCorrection.Data()); + fTrdOnlineTrackMatcher=new AliTRDonlineTrackMatching(); + // Set Normalisation Factors + if(mgr->GetMCtruthEventHandler()){ + // Assume MC + //fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.); + SwitchOffGainCorrection(); + } + else{ + // Assume Data + //if(fPIDmethod == kNNpid) fPidRecal->SetGainScaleFactor(1.14); + //fESDpid->GetTRDResponse().SetGainNormalisationFactor(1.14); + SwitchOnGainCorrection(); + } +} + +//_____________________________________________________ +void AliTRDTenderSupply::ProcessEvent() +{ + // + // Reapply pid information + // + if (fTender->RunChanged()){ + AliDebug(0, Form("AliTPCTenderSupply::ProcessEvent - Run Changed (%d)\n",fTender->GetRun())); + if (fGainCorrection) SetChamberGain(); + //if(fLoadReferences && !fHasReferences) LoadReferences(); + if(fLoadDeadChambers) LoadDeadChambersFromCDB(); + // Load Geometry + if(AliGeomManager::GetGeometry()){ + AliInfo("Geometry already loaded by other tenders"); + } else { + if(fGeoFile) AliInfo(Form("Load geometry from file %s\n", fGeoFile)); + else AliInfo("Load Geometry from OCDB\n"); + AliGeomManager::LoadGeometry(fGeoFile); + } + } + + + fESD = fTender->GetEvent(); + if (!fESD) return; + if(fNormalizationFactorArray) fNormalizationFactor = GetNormalizationFactor(fESD->GetRunNumber()); + Int_t ntracks=fESD->GetNumberOfTracks(); + + + + if (fRedoTrdMatching) { + if (!fTrdOnlineTrackMatcher->ProcessEvent(fESD)) { + AliError("TRD online track matching failed!"); + } + } + + + + // + // recalculate PID probabilities + // + Int_t detectors[kNPlanes]; + for(Int_t itrack = 0; itrack < ntracks; itrack++){ + for(Int_t idet = 0; idet < 5; idet++) detectors[idet] = -1; + AliESDtrack *track=fESD->GetTrack(itrack); + // Recalculate likelihoods + if(!(track->GetStatus() & AliESDtrack::kTRDout)) continue; + AliDebug(2, Form("TRD track found, gain correction: %s, Number of bad chambers: %d\n", fGainCorrection ? "Yes" : "No", fNBadChambers)); + if(GetTRDchamberID(track, detectors)){ + if(fGainCorrection && fHasNewCalibration) ApplyGainCorrection(track, detectors); + if(fNBadChambers) MaskChambers(track, detectors); + } + if(fRunByRunCorrection) ApplyRunByRunCorrection(track); + if(fNormalizationFactor != 1.){ + //printf("Gain Factor: %f\n", fNormalizationFactor); + // Renormalize charge + Double_t qslice = -1; + for(Int_t ily = 0; ily < 6; ily++){ + for(Int_t is = 0; is < track->GetNumberOfTRDslices(); is++){ + qslice = track->GetTRDslice(ily, is); + //printf("Doing layer %d slice %d, value %f\n", ily, is, qslice); + if(qslice >0){ + qslice *= fNormalizationFactor; + //printf("qslice new: %f\n", qslice); + track->SetTRDslice(qslice, ily, is); + } + } + } + } + switch(fPIDmethod){ + case kNNpid: + break; + case k1DLQpid: + fESDpid->MakeTRDPID(fESD->GetTrack(itrack)); + break; + default: + AliError("PID Method not implemented (yet)"); + } + } +} + +//_____________________________________________________ +void AliTRDTenderSupply::LoadDeadChambersFromCDB(){ + // + // Load Dead Chambers from the OCDB + // + AliDebug(1, "Loading Dead Chambers from the OCDB"); + AliCDBEntry *en = fTender->GetCDBManager()->Get("TRD/Calib/ChamberStatus",fTender->GetRun()); + if(!en){ + AliError("Dead Chambers not in OCDB"); + return; + } + en->GetId().Print(); + + AliTRDCalChamberStatus* chamberStatus = 0; + if(en){ + chamberStatus = (AliTRDCalChamberStatus*)en->GetObject(); + if(!chamberStatus) AliError("List with the dead chambers not found"); + for(Int_t ichamber = 0; ichamber < 540; ichamber++) { + if(!chamberStatus->IsGood(ichamber)){ + //printf("Chamber not installed %d\n",ichamber); + AddBadChamber(ichamber); + } + } + } +} + +/* +//_____________________________________________________ +void AliTRDTenderSupply::LoadReferences(){ + // + // Load Reference from the OCDB/OADB into the PID Response + // + if(fLoadReferencesFromCDB){ + AliDebug(1, "Loading Reference Distributions from the OCDB"); + AliCDBEntry *en = fTender->GetCDBManager()->Get("TRD/Calib/PIDLQ1D"); + if(!en){ + AliError("References for 1D Likelihood Method not in OCDB"); + return; + } + en->GetId().Print(); + TObjArray *arr = dynamic_cast(en->GetObject()); + if(!arr) AliError("List with the references not found"); + + // Get new references + TIter refs(arr); + TObject *o = NULL; + AliTRDPIDReference *ref = NULL; + while((o = refs())){ + if(!TString(o->IsA()->GetName()).CompareTo("AliTRDPIDReference")){ + ref = dynamic_cast(o); + break; + } + } + if(ref){ + fESDpid->GetTRDResponse().Load(ref); + fHasReferences = kTRUE; + AliDebug(1, "Reference distributions loaded into the PID Response"); + } else { + AliError("References not found"); + } + } else { + // Backward compatibility mode + AliInfo("Loading Reference Distributions from ROOT file"); + fESDpid->GetTRDResponse().Load("$TRAIN_ROOT/util/tender/LQ1dRef_v3.root"); + fHasReferences = kTRUE; + } +} +*/ + +//_____________________________________________________ +void AliTRDTenderSupply::SetChamberGain(){ + // + // Load Chamber Gain factors into the Tender supply + // + + //find previous entry from the UserInfo + TTree *tree=((TChain*)fTender->GetInputData(0))->GetTree(); + if (!tree) { + fHasNewCalibration = kFALSE; + AliError("Tree not found in ESDhandler"); + return; + } + + TList *userInfo=(TList*)tree->GetUserInfo(); + if (!userInfo) { + fHasNewCalibration = kFALSE; + AliError("No UserInfo found in tree"); + return; + } + + TList *cdbList=(TList*)userInfo->FindObject("cdbList"); + if (!cdbList) { + fHasNewCalibration = kFALSE; + AliError("No cdbList found in UserInfo"); + if (AliLog::GetGlobalLogLevel()>=AliLog::kError) userInfo->Print(); + return; + } + fHasNewCalibration = kTRUE; + + TIter nextCDB(cdbList); + TObjString *os=0x0; + while ( (os=(TObjString*)nextCDB()) ){ + if(os->GetString().Contains("TRD/Calib/ChamberGainFactor")){ + // Get Old gain calibration + AliCDBId *id=AliCDBId::MakeFromString(os->GetString()); + + AliCDBEntry *entry=fTender->GetCDBManager()->Get(id->GetPath(), id->GetFirstRun(), id->GetVersion()); + if (!entry) { + AliError("No previous gain calibration entry found"); + return; + } + + fChamberGainOld = dynamic_cast(entry->GetObject()); + + AliDebug(1, Form("Used old Gain entry: %s\n",entry->GetId().ToString().Data())); + } else if(os->GetString().Contains("TRD/Calib/ChamberVdrift")){ + // Get Old drift velocity calibration + AliCDBId *id=AliCDBId::MakeFromString(os->GetString()); + + AliCDBEntry *entry=fTender->GetCDBManager()->Get(id->GetPath(), id->GetFirstRun(), id->GetVersion()); + if (!entry) { + AliError("No previous drift velocity calibration entry found"); + return; + } + + fChamberVdriftOld = dynamic_cast(entry->GetObject()); + + AliDebug(1, Form("Used old Drift velocity entry: %s\n",entry->GetId().ToString().Data())); + + } + } + + // Get Latest Gain Calib Object + AliCDBEntry *entryNew=fTender->GetCDBManager()->Get("TRD/Calib/ChamberGainFactor",fTender->GetRun()); + if (entryNew) { + AliDebug(1, Form("Used new Gain entry: %s\n",entryNew->GetId().ToString().Data())); + fChamberGainNew = dynamic_cast(entryNew->GetObject()); + } else + AliError("No new gain calibration entry found"); + + // Also get the latest Drift Velocity calibration object + entryNew=fTender->GetCDBManager()->Get("TRD/Calib/ChamberVdrift",fTender->GetRun()); + if (entryNew) { + AliDebug(1, Form("Used new Drift velocity entry: %s\n",entryNew->GetId().ToString().Data())); + fChamberVdriftNew = dynamic_cast(entryNew->GetObject()); + } else + AliError("No new drift velocity calibration entry found"); + + if(!fChamberGainNew || !fChamberVdriftNew){ + AliError("No recent calibration found"); + fHasNewCalibration = kFALSE; + } +} + +//_____________________________________________________ +void AliTRDTenderSupply::LoadRunByRunCorrection(const char *filename){ + // + // Define run by run gain correction for the charge + // + + TDirectory *bkp = gDirectory; + TFile *in = TFile::Open(filename); + bkp->cd(); + fRunByRunCorrection = dynamic_cast(in->Get("TRDchargeCorrection")); + delete in; + if(fRunByRunCorrection ) + AliDebug(2, Form("OADB Container has %d runs\n", fRunByRunCorrection->GetNumberOfEntries())); + /* Temporarily out due to a bug in AliOADBContainer + fRunByRunCorrection = new AliOADBContainer("TRDchargeCorrection"); + Int_t status = fRunByRunCorrection->InitFromFile(filename, "TRDchargeCorrection"); + if(!status) AliDebug(1, Form("Run-dependend gain correction factors loaded from OADB file %s", filename)); + else{ + AliDebug(1, "Failed Loading Run-dependend gain correction factors"); + delete fRunByRunCorrection; + fRunByRunCorrection = NULL; + } + */ +} + +//_____________________________________________________ +Bool_t AliTRDTenderSupply::IsBadChamber(Int_t chamberID){ + // + // Check if the chamber id is in the list of bad chambers + // + Bool_t isBad = kFALSE; + for(UInt_t icam = 0; icam < fNBadChambers; icam++) + if(fBadChamberID[icam] == chamberID){ + isBad = kTRUE; + //printf("cross checking: %i \n",chamberID); + break; + } + return isBad; +} + +//_____________________________________________________ +void AliTRDTenderSupply::ApplyGainCorrection(AliESDtrack * track, const Int_t * const chamberID){ + // + // Apply new gain factors to the track + // + if(!fChamberGainNew || !fChamberGainOld){ + AliError("Cannot apply gain correction."); + return; + } + + if(!(track->GetStatus() & AliESDtrack::kTRDout)) return; + Bool_t applyCorrectionVdrift = kFALSE; + if(fChamberVdriftOld && fChamberVdriftNew) applyCorrectionVdrift = kTRUE; + + for(Int_t iplane = 0; iplane < kNPlanes; iplane++){ + if(chamberID[iplane] < 0) continue; + if(IsBadChamber(chamberID[iplane])) continue; // Don't apply gain correction for chambers which are in the list of bad chambers + + // Take old and new gain factor and make ratio + Double_t facOld = fChamberGainOld->GetValue(chamberID[iplane]); + Double_t facNew = fChamberGainNew->GetValue(chamberID[iplane]); + Double_t correction = facNew/facOld; + if(applyCorrectionVdrift){ + // apply also correction for drift velocity calibration + Double_t vDriftOld = fChamberVdriftOld->GetValue(chamberID[iplane]); + Double_t vDriftNew = fChamberVdriftNew->GetValue(chamberID[iplane]); + correction *= vDriftNew/vDriftOld; + } + AliDebug(2, Form("Applying correction factor %f\n", correction)); + for(Int_t islice = 0; islice < track->GetNumberOfTRDslices(); islice++){ + Double_t qslice = track->GetTRDslice(iplane, islice); + if(qslice <= 0.) continue; + track->SetTRDslice(qslice / correction, iplane, islice); + } + } +} + +//_____________________________________________________ +void AliTRDTenderSupply::ApplyRunByRunCorrection(AliESDtrack *const track) { + // + // Equalize charge distribution by applying run-by-run correction (multiplicative) + // + + TVectorD *corrfactor = dynamic_cast(fRunByRunCorrection->GetObject(fTender->GetRun())); + if(!corrfactor){ + // No correction available - simply return + AliDebug(2, "Couldn't derive gain correction factor from OADB"); + return; + } + else AliDebug(2, Form("Gain factor from OADB %f", (*corrfactor)[0])); + Double_t slice = 0; + for(Int_t ily = 0; ily < kNPlanes; ily++){ + for(Int_t islice = 0; islice < track->GetNumberOfTRDslices(); islice++){ + slice = track->GetTRDslice(ily, islice); + if(slice < 0.001) continue; // do not modify slices which are 0 or negative + slice *= (*corrfactor)[0]; + track->SetTRDslice(slice, ily, islice); + } + } +} + +//_____________________________________________________ +void AliTRDTenderSupply::SetNormalizationFactor(Double_t norm, Int_t runMin, Int_t runMax) { + // + // Set the normalisation factor for a given run range + // + if(!fNormalizationFactorArray) + fNormalizationFactorArray = new TObjArray; + TVectorD *entry = new TVectorD(3); + TVectorD &myentry = *entry; + myentry(0) = runMin; + myentry(1) = runMax; + myentry(2) = norm; + fNormalizationFactorArray->Add(entry); +} + +//_____________________________________________________ +Double_t AliTRDTenderSupply::GetNormalizationFactor(Int_t runnumber){ + // + // Load the normalization factor + // + Double_t norm = 1.; + if(fNormalizationFactorArray){ + TVectorD *entry; + Int_t runMin, runMax; + TIter entries(fNormalizationFactorArray); + while((entry = dynamic_cast(entries()))){ + TVectorD &myentry = *entry; + runMin = TMath::Nint(myentry(0)); + runMax = TMath::Nint(myentry(1)); + if(runnumber >= runMin && runnumber <= runMax) norm = myentry(2); + } + } + AliDebug(1, Form("Gain normalization factor: %f\n", norm)); + return norm; +} + +//_____________________________________________________ +void AliTRDTenderSupply::MaskChambers(AliESDtrack *const track, const Int_t * const chamberID){ + // + // Mask out chambers which are in the list of bad chambers + // Set chamber signal to 0 and reduce the number of tracklets used for PID + // + AliDebug(2, "Masking bad chambers for TRD track"); + Int_t nTrackletsPID = 0, nslice = 0, nTracklets = track->GetTRDntracklets(); + Bool_t badChamber = kFALSE; + //Int_t nbad = 0 ; // Number of bad chambers which contain also a signal + //Int_t nsliceBad = 0; // Number of slices in tracklet in a bad chamber + for(Int_t iplane = 0; iplane < kNPlanes; iplane++){ + badChamber = kFALSE; + nslice = 0; //nsliceBad = 0; + if(IsBadChamber(chamberID[iplane])) badChamber = kTRUE; + for(Int_t islice = 0; islice < track->GetNumberOfTRDslices(); islice++){ + if(badChamber){ + //if(track->GetTRDslice(iplane, islice)) nsliceBad++; + track->SetTRDslice(-1, iplane, islice); + } else if(track->GetTRDslice(iplane, islice) > 0.001) nslice++; + } + //if(nsliceBad) nbad++; + if(nslice > 0) nTrackletsPID++; + } + //if(nbad) track->SetTRDncls(track->GetTRDncls() - 20 * nbad); // subtract mean number of clusters per tracklet for bad tracklets + // Use nTrackletsPID to indicate the number of tracklets from good + // chambers so they are used for the PID + track->SetTRDntracklets(nTrackletsPID | (nTracklets << 3)); +} + +//_____________________________________________________ +Bool_t AliTRDTenderSupply::GetTRDchamberID(AliESDtrack * const track, Int_t *detectors) { + // + // Calculate TRD chamber ID + // + Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P(); + if(p < fPthreshold) return kFALSE; // Apply low momentum cutoff + + Double_t xLayer[kNPlanes] = {300.2, 312.8, 325.4, 338., 350.6, 363.2}; + Double_t etamin[kNStacks] = {0.536, 0.157, -0.145, -0.527,-0.851}; + Double_t etamax[kNStacks] = {0.851, 0.527, 0.145, -0.157,-0.536}; + //Double_t zboundary[kNPlanes] = {302., 317., 328., 343., 350., 350.}; + for(Int_t ily = 0; ily < kNPlanes; ily++) detectors[ily] = -1; + + const AliExternalTrackParam *trueparam = NULL; + if(track->GetOuterParam()) trueparam = track->GetOuterParam(); + else if(track->GetTPCInnerParam()) trueparam = track->GetTPCInnerParam(); + else if(track->GetInnerParam()) trueparam = track->GetInnerParam(); + if(!trueparam){ + AliDebug(2, "No Track Params"); + return kFALSE; + } + + AliExternalTrackParam workparam(*trueparam); // Do calculation on working Copy + Double_t pos[3]; + Int_t nDet = 0; + for(Int_t ily = 0; ily < kNPlanes; ily++){ + //if(TMath::Abs(workparam.GetZ()) > zboundary[ily]) break; + //if(!AliTrackerBase::PropagateTrackToBxByBz(&workparam, xLayer[ily], 0.139, 100)){ // Assuming the pion mass + if(!workparam.PropagateTo(xLayer[ily], fESD->GetMagneticField())) { + AliDebug(2, "Propagation failed"); + break; + } + workparam.GetXYZ(pos); + Double_t trackAlpha = TMath::ATan2(pos[1], pos[0]); + if(trackAlpha < 0) trackAlpha = 2 * TMath::Pi() + trackAlpha; + Double_t secAlpha = 2 * TMath::Pi() / 18.; + + Int_t sector = static_cast(trackAlpha/secAlpha); +/* + if(fDebugMode){ + // Compare to simple propagation without magnetic field + AliExternalTrackParam workparam1(*trueparam); // Do calculation on working Copy + Double_t pos1[3]; + //if(!workparam1.PropagateTo(xLayer[ily], fESD->GetMagneticField())) { + if(!AliTrackerBase::PropagateTrackToBxByBz(&workparam1, xLayer[ily], 0.139, 100)){ // Assuming the pion mass + AliDebug(2, "Propagation failed"); + break; + } + workparam1.GetXYZ(pos1); + Double_t trackAlpha1 = TMath::ATan2(pos1[1], pos1[0]); + if(trackAlpha1 < 0) trackAlpha1 = 2 * TMath::Pi() + trackAlpha1; + + Int_t sector1 = static_cast(trackAlpha1/secAlpha); + AliDebug(2, Form("Alpha: Old %f, New %f, diff %f", trackAlpha, trackAlpha1, trackAlpha-trackAlpha1)); + AliDebug(2, Form("Sector: Old %d, New %d", sector, sector1)); + } +*/ + Double_t etaTrack = track->Eta(); + Int_t stack = -1; + for(Int_t istack = 0; istack < 5; istack++){ + if(etaTrack >= etamin[istack] && etaTrack <= etamax[istack]){ + stack = istack; + break; + } + } + if(stack < 0) { + AliDebug(2, "Dead Area"); + continue; + } + + detectors[ily] = sector * kNStacks * kNPlanes + stack * kNPlanes + ily; + nDet++; + } + return nDet ? kTRUE : kFALSE; +} + diff --git a/TENDER/TenderSupplies/AliTRDTenderSupply.h b/TENDER/TenderSupplies/AliTRDTenderSupply.h new file mode 100644 index 00000000000..98198f20d3a --- /dev/null +++ b/TENDER/TenderSupplies/AliTRDTenderSupply.h @@ -0,0 +1,106 @@ +#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 + +class AliTRDCalDet; +class AliESDEvent; +class AliOADBContainer; +class AliTRDonlineTrackMatching; + +class AliTRDTenderSupply: public AliTenderSupply { + +public: + enum{ + kNNpid = 0, + k1DLQpid = 1, + k2DLQpid = 2 + }; + AliTRDTenderSupply(); + AliTRDTenderSupply(const char *name, const AliTender *tender=NULL); + virtual ~AliTRDTenderSupply(); + + void SetRunByRunCorrection(const char *filename) { fNameRunByRunCorrection = filename; } +// void SetLoadReferencesFromCDB() { fLoadReferences = kTRUE; fLoadReferencesFromCDB = kTRUE; } +// void SetLoadReferencesFromFile() { fLoadReferences = kTRUE; fLoadReferencesFromCDB = kFALSE; } + void SetLoadDeadChambersFromCDB(){ fLoadDeadChambers = kTRUE;} ; + void SetPIDmethod(Int_t pidMethod) { fPIDmethod = pidMethod; } + void SetNormalizationFactor(Double_t norm, Int_t runMin, Int_t runMax); + void SetNormalizationFactor(Double_t norm) { fNormalizationFactor = norm; } + void SetCalibLowpThreshold(Double_t pmin) { fPthreshold = pmin; }; + void SetGeoFile(const char *filename) { fGeoFile = filename; } + void SetDebugMode() { fDebugMode = kTRUE; } + void SetRedoTRDMatching(Bool_t redo = kTRUE) {fRedoTrdMatching = redo;} + + virtual void Init(); + virtual void ProcessEvent(); + + void SwitchOnGainCorrection() { fGainCorrection = kTRUE; } + void SwitchOffGainCorrection() { fGainCorrection = kFALSE; } + void SetSlicesForPID(UInt_t min, UInt_t max) { fSlicesForPID[0] = min; fSlicesForPID[1] = max;} + void AddBadChamber(Int_t chamberID){fBadChamberID[fNBadChambers++] = chamberID;}; + +private: + enum{ + kNPlanes = 6, + kNStacks = 5, + kNChambers = 540 + }; + + Bool_t GetTRDchamberID(AliESDtrack * const track, Int_t *detectors); + void SetChamberGain(); + void ApplyGainCorrection(AliESDtrack *track, const Int_t * const detectors); + void ApplyRunByRunCorrection(AliESDtrack *const track); + void MaskChambers(AliESDtrack * const track, const Int_t * const detectors); + void LoadReferences(); + void LoadDeadChambersFromCDB(); + void LoadRunByRunCorrection(const char *filename); + Bool_t IsBadChamber(Int_t chamberID); + Double_t GetNormalizationFactor(Int_t runnumber); + + AliESDEvent *fESD; //! the ESD Event + AliESDpid *fESDpid; //! ESD PID object + AliTRDonlineTrackMatching *fTrdOnlineTrackMatcher; //! TRD online track matcher + + AliTRDCalDet *fChamberGainOld; // TRD Chamber Gain Factor used for producing the ESD + AliTRDCalDet *fChamberGainNew; // New TRD Chamber Gain Factor + AliTRDCalDet *fChamberVdriftOld; // Old drift velocity calibration + AliTRDCalDet *fChamberVdriftNew; // New drift velocity calibration + AliOADBContainer *fRunByRunCorrection; // Run by run gain correction + + Int_t fPIDmethod; // PID method + Double_t fNormalizationFactor; // dE/dx Normalization Factor + Double_t fPthreshold; // Low Momentum threshold for calibration + Int_t fBadChamberID[kNChambers]; // List of Bad Chambers + UInt_t fSlicesForPID[2]; // Select range of slices used in the PID response + UInt_t fNBadChambers; // Number of bad chambers + const char *fGeoFile; // File with geometry.root + Bool_t fGainCorrection; // Apply gain correction +// Bool_t fLoadReferences; // Tender Load references +// Bool_t fLoadReferencesFromCDB; // Load References from CDB + Bool_t fLoadDeadChambers; // Load dead chambers + Bool_t fHasReferences; // has references loaded + Bool_t fHasNewCalibration; // has new calibration + Bool_t fDebugMode; // Run in debug mode + Bool_t fRedoTrdMatching; // Redo Track Matching + TString fNameRunByRunCorrection; // filename with the run-by-run gain correction + TObjArray *fNormalizationFactorArray; // Array with normalisation Factors + + AliTRDTenderSupply(const AliTRDTenderSupply&c); + AliTRDTenderSupply& operator= (const AliTRDTenderSupply&c); + + ClassDef(AliTRDTenderSupply, 1); // TRD tender task +}; +#endif + diff --git a/TENDER/TenderSupplies/AliTrackFixTenderSupply.cxx b/TENDER/TenderSupplies/AliTrackFixTenderSupply.cxx new file mode 100644 index 00000000000..eff3f94b576 --- /dev/null +++ b/TENDER/TenderSupplies/AliTrackFixTenderSupply.cxx @@ -0,0 +1,259 @@ +/************************************************************************** + * 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 +#include "AliESDEvent.h" +#include "AliTender.h" +#include "AliVParticle.h" +#include "AliLog.h" +#include "AliOADBContainer.h" +#include "AliAnalysisManager.h" +#include "AliTrackFixTenderSupply.h" +#include "AliOADBTrackFix.h" + +ClassImp(AliTrackFixTenderSupply) + +AliTrackFixTenderSupply::AliTrackFixTenderSupply() : +fDebug(0), + fBz(0), + fParams(0), + fOADBObjPath("$OADB/PWGPP/data/CorrPTInv.root"), + fOADBObjName("CorrPTInv"), + fOADBCont(0) +{ + // default ctor +} + +//_____________________________________________________ +AliTrackFixTenderSupply::AliTrackFixTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender), + fDebug(0), + fBz(0), + fParams(0), + fOADBObjPath("$OADB/PWGPP/data/CorrPTInv.root"), + fOADBObjName("CorrPTInv"), + fOADBCont(0) +{ + // named ctor + // +} + +//_____________________________________________________ +AliTrackFixTenderSupply::~AliTrackFixTenderSupply() +{ + // d-tor + delete fOADBCont; +} + + +//_____________________________________________________ +void AliTrackFixTenderSupply::ProcessEvent() +{ + // + // Fix track kinematics + // + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + // + if (fTender->RunChanged() && !GetRunCorrections(fTender->GetRun())) return; + // + int nTracks = event->GetNumberOfTracks(); + fBz = event->GetMagneticField(); + if (TMath::Abs(fBz) < kAlmost0Field) return; + // + const AliESDVertex *vtx = 0, *vtxTPC = 0; + // + vtx = event->GetPrimaryVertexTracks(); // vertex to be used for update via RelateToVertex + if (!vtx || vtx->GetStatus()<1) { + vtx = event->GetPrimaryVertexSPD(); + if (vtx && vtx->GetStatus()<1) vtx = 0; + } + vtxTPC = event->GetPrimaryVertexTPC(); // vertex to be used for update via RelateToVertexTPC + if (vtxTPC && vtxTPC->GetStatus()<1) vtxTPC = 0; + // + AliExternalTrackParam* extPar = 0; + double xOrig = 0; + double xyzTPCInner[3] = {0,0,0}; + for (int itr=0;itrGetTrack(itr); + if (!trc->IsOn(AliESDtrack::kTPCin)) continue; + // + double sideAfraction = GetSideAFraction(trc); + // correct the main parameterization + int cormode = trc->IsOn(AliESDtrack::kITSin) ? AliOADBTrackFix::kCorModeGlob : AliOADBTrackFix::kCorModeTPCInner; + xOrig = trc->GetX(); + double xIniCor = fParams->GetXIniPtInvCorr(cormode); + const AliExternalTrackParam* parInner = trc->GetInnerParam(); + if (!parInner) { + AliError("Failed to extract inner param"); + continue; + } + parInner->GetXYZ(xyzTPCInner); + double phi = TMath::ATan2(xyzTPCInner[1],xyzTPCInner[0]); + if (phi<0) phi += 2*TMath::Pi(); + // + if (fDebug>1) { + AliInfo(Form("Tr:%4d kITSin:%d Phi=%+5.2f at X=%+7.2f | SideA fraction: %.3f",itr,trc->IsOn(AliESDtrack::kITSin),phi,parInner->GetX(),sideAfraction)); + AliInfo(Form("Main Param before corr. in mode %s, xIni:%.1f",cormode== AliOADBTrackFix::kCorModeGlob ? "Glo":"TPC",xIniCor)); + trc->AliExternalTrackParam::Print(); + } + // + if (xIniCor>0) trc->PropagateTo(xIniCor,fBz); + CorrectTrackPtInv(trc, cormode, sideAfraction, phi); + if (xIniCor>0) { // full update is requested + if (vtx) trc->RelateToVertex(vtx, fBz, kVeryBig); // redo DCA if vtx is available + else trc->PropagateTo(xOrig, fBz); // otherwise bring to original point + } + // + if (fDebug>1) { + AliInfo("Main Param after corr."); + trc->AliExternalTrackParam::Print(); + } + // correct TPCinner param + if ( (extPar=(AliExternalTrackParam*)trc->GetTPCInnerParam()) ) { + cormode = AliOADBTrackFix::kCorModeTPCInner; + xOrig = extPar->GetX(); + xIniCor = fParams->GetXIniPtInvCorr(cormode); + if (fDebug>1) { + AliInfo(Form("TPCinner Param before corr. in mode %s, xIni:%.1f",cormode== AliOADBTrackFix::kCorModeGlob ? "Glo":"TPC",xIniCor)); + extPar->AliExternalTrackParam::Print(); + } + // + if (xIniCor>0) extPar->PropagateTo(xIniCor,fBz); + CorrectTrackPtInv(extPar,cormode,sideAfraction, phi); + if (xIniCor>0) { // full update is requested + if (vtxTPC) trc->RelateToVertexTPC(vtxTPC, fBz, kVeryBig); // redo DCA if vtx is available + else extPar->PropagateTo(xOrig, fBz); // otherwise bring to original point + } + // + if (fDebug>1) { + AliInfo("TPCinner Param after corr."); + extPar->AliExternalTrackParam::Print(); + } + } + // + } + // +} + +//_____________________________________________________ +void AliTrackFixTenderSupply::CorrectTrackPtInv(AliExternalTrackParam* trc, Int_t mode, double sideAfraction, double phi) const +{ + // fix track kinematics + if (!trc) return; + double *param = (double*)trc->GetParameter(); + param[4] += fParams->GetPtInvCorr(mode,sideAfraction,phi); + // +} + +//_____________________________________________________ +Bool_t AliTrackFixTenderSupply::LoadOADBObjects() +{ + // Load OADB parameters + TString fileName = fOADBObjPath; + if (fileName.BeginsWith("$OADB")) fileName.ReplaceAll("$OADB",Form("%s/",AliAnalysisManager::GetOADBPath())); + gSystem->ExpandPathName(fileName); + AliInfo(Form("Loading correction parameters %s from %s",fOADBObjName.Data(),fileName.Data())); + // + fOADBCont = new AliOADBContainer("OADB"); + if (fOADBCont->InitFromFile(fileName.Data(),fOADBObjName.Data())) { + AliError("Failed to load OADB Container"); + delete fOADBCont; + fOADBCont = 0; + return kFALSE; + } + // + return kTRUE; +} + +//_____________________________________________________ +Bool_t AliTrackFixTenderSupply::GetRunCorrections(int run) +{ + // extract corrections for given run + fParams = 0; + if (!fOADBCont) if (!LoadOADBObjects()) return kFALSE; + fParams = dynamic_cast(fOADBCont->GetObject(run,"default")); + if (!fParams) {AliError(Form("No correction parameters for found for run %d",run)); return kFALSE;} + AliInfo(Form("Loaded correction parameters for run %d",run)); + // + return kTRUE; +} + +//_____________________________________________________ +Double_t AliTrackFixTenderSupply::GetSideAFraction(const AliESDtrack* track) const +{ + // decide A-side fraction of trajectory length in TPC + // for the moment just a placeholder... + // + const AliExternalTrackParam *trIn = track->GetInnerParam(); + if (!trIn) {AliError("Failed to onbtain InnerParam"); return 0.5;} + // + // easy cases: + double sideAfrac = 0.5; + if (trIn->GetZ()>0) { sideAfrac = 1.; if (trIn->GetTgl()>-kAlmost0) return sideAfrac;} + else if (trIn->GetZ()<0) { sideAfrac = 0.; if (trIn->GetTgl()< kAlmost0) return sideAfrac;} + // + // track may cross the membrane + // convert to usual helix param: + // x(t)=(dca+R)*cos(phi0) -R*cos(t+phi0); + // y(t)=(dca+R)*sin(phi0) -R*sin(t+phi0); + // z(t)=z0 - R*t*tgl + // + int sqb = fBz<0 ? -trIn->Charge() : trIn->Charge(); + double radq = TMath::Abs(trIn->GetC(fBz)); + radq = radq>kAlmost0 ? 1./radq : 1e4; // track radius + if (sqb<0) radq = -radq; + double cstCphi0 = trIn->GetSnp(); // tC is current t + double sntCphi0 = -TMath::Sqrt((1.-cstCphi0)*(1+cstCphi0)); + double xc0 = trIn->GetX() + radq*cstCphi0; // circle center + double yc0 = trIn->GetY() + radq*sntCphi0; + double phi0 = TMath::ATan2( yc0, xc0); + if (sqb<0) phi0 += TMath::Pi(); + if (phi0 > TMath::Pi()) phi0 -= 2.*TMath::Pi(); + else if (phi0 <-TMath::Pi()) phi0 += 2.*TMath::Pi(); + // + double csphi0 = TMath::Cos(phi0); + double snphi0 = TMath::Sin(phi0); + double dca = xc0*csphi0 + yc0*snphi0 - radq; + double tC = TMath::ATan2(sntCphi0,cstCphi0) - phi0; + double tglR = radq*trIn->GetTgl(); + double z0 = trIn->GetZ() + tglR*tC; + Double_t tCross = z0/tglR; // Z=0 is crossed at this t + // t is changed withing tCross:2pi range for the track moving forward + if (tCrossTMath::Pi()) return sideAfrac; // on the way forward does not cross the membrane + // + // find max t reached by the track in the TPC + const double kROutTPC2 = 250.*250.; + // find t at which the outer radius is crossed + // r^2 = (dca+R)^2 + R^2 - 2R(R+dca)*cos(t) + double dcaR = dca+radq; + double rmax2 = dcaR*dcaR + radq*radq + 2*radq*dcaR; // max rad at t=pi + double tmax = TMath::Pi(); + if (rmax2>kROutTPC2) { // traverses full TPC + double ct = 0.5*(dcaR/radq + radq/dcaR - kROutTPC2/radq/dcaR); + if (TMath::Abs(ct)<1-kAlmost0) tmax = TMath::ACos(ct); + } + if (tmax0.5 ? (tCross-tC)/(tmax-tC) : 1.-(tCross-tC)/(tmax-tC); + return sideAfrac; +} diff --git a/TENDER/TenderSupplies/AliTrackFixTenderSupply.h b/TENDER/TenderSupplies/AliTrackFixTenderSupply.h new file mode 100644 index 00000000000..fc874e3a355 --- /dev/null +++ b/TENDER/TenderSupplies/AliTrackFixTenderSupply.h @@ -0,0 +1,66 @@ +#ifndef ALITRACKFIXTENDERSUPPLY_H +#define ALITRACKFIXTENDERSUPPLY_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +//////////////////////////////////////////////////////////////////////// +// // +// Apply on-the-fly fix to tracks // +// // +// 19/06/2012: RS: Add 1/pt shift from AODB to TPC and TPC-ITS // +// Optionally correct also track coordinate // +// // +//////////////////////////////////////////////////////////////////////// + +#include +#include "AliTenderSupply.h" + + +class AliESDVertex; +class AliExternalTrackParam; +class AliOADBContainer; +class AliESDtrack; +class AliOADBTrackFix; + +class AliTrackFixTenderSupply: public AliTenderSupply { + +public: + // + AliTrackFixTenderSupply(); + AliTrackFixTenderSupply(const char *name, const AliTender *tender=NULL); + virtual ~AliTrackFixTenderSupply(); + virtual void ProcessEvent(); + virtual void Init() {} + // + Double_t GetSideAFraction(const AliESDtrack* track) const; + void CorrectTrackPtInv(AliExternalTrackParam* trc, int mode, double sideAfraction, double phi) const; + Bool_t GetRunCorrections(int run); + Bool_t LoadOADBObjects(); + // + void SetOADBObjPath(const char* path) { fOADBObjPath = path; } + void SetOADBObjName(const char* name) { fOADBObjName = name; } + TString& GetOADBObjPath() const { return (TString&)fOADBObjPath; } + TString& GetOADBObjName() const { return (TString&)fOADBObjName; } + // + void SetDebugLevel(Int_t l=1) {fDebug = l;} + Int_t GetDebugLevel() const {return fDebug;} + // +private: + + AliTrackFixTenderSupply(const AliTrackFixTenderSupply&c); + AliTrackFixTenderSupply& operator= (const AliTrackFixTenderSupply&c); + // + Int_t fDebug; // Debug level + Double_t fBz; // mag field from ESD + AliOADBTrackFix* fParams; // parameters for current run + TString fOADBObjPath; // path of file with parameters to use, starting from OADB dir + TString fOADBObjName; // name of the corrections object in the OADB container + AliOADBContainer* fOADBCont; // OADB container with parameters collection + // + ClassDef(AliTrackFixTenderSupply, 1); // track fixing tender task +}; + + +#endif + diff --git a/TENDER/TenderSupplies/AliVZEROTenderSupply.cxx b/TENDER/TenderSupplies/AliVZEROTenderSupply.cxx new file mode 100644 index 00000000000..34a17ba7187 --- /dev/null +++ b/TENDER/TenderSupplies/AliVZEROTenderSupply.cxx @@ -0,0 +1,263 @@ +/************************************************************************** + * 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 VZERO timing and decision using the tender // +// (in case the LHC phase drift is updated in OCDB) // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliVZEROTenderSupply.h" + +ClassImp(AliVZEROTenderSupply) + +AliVZEROTenderSupply::AliVZEROTenderSupply() : + AliTenderSupply(), + fCalibData(NULL), + fTimeSlewing(NULL), + fRecoParam(NULL), + fLHCClockPhase(0), + fDebug(kFALSE) +{ + // + // default ctor + // +} + +//_____________________________________________________ +AliVZEROTenderSupply::AliVZEROTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender), + fCalibData(NULL), + fTimeSlewing(NULL), + fRecoParam(NULL), + fLHCClockPhase(0), + fDebug(kFALSE) +{ + // + // named ctor + // +} + +//_____________________________________________________ +void AliVZEROTenderSupply::Init() +{ + // + // Initialise VZERO tender + // +} + +//_____________________________________________________ +void AliVZEROTenderSupply::ProcessEvent() +{ + // + // Reapply the LHC-clock phase drift + // + + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + + //load gain correction if run has changed + if (fTender->RunChanged()){ + if (fDebug) printf("AliVZEROTenderSupply::ProcessEvent - Run Changed (%d)\n",fTender->GetRun()); + GetPhaseCorrection(); + + AliCDBEntry *entryGeom = fTender->GetCDBManager()->Get("GRP/Geometry/Data",fTender->GetRun()); + if (!entryGeom) { + AliError("No geometry entry is found"); + return; + } else { + if (fDebug) printf("AliVZEROTenderSupply::Used geometry entry: %s\n",entryGeom->GetId().ToString().Data()); + } + + AliCDBEntry *entryCal = fTender->GetCDBManager()->Get("VZERO/Calib/Data",fTender->GetRun()); + if (!entryCal) { + AliError("No VZERO calibration entry is found"); + fCalibData = NULL; + return; + } else { + fCalibData = (AliVZEROCalibData*)entryCal->GetObject(); + if (fDebug) printf("AliVZEROTenderSupply::Used VZERO calibration entry: %s\n",entryCal->GetId().ToString().Data()); + } + + AliCDBEntry *entrySlew = fTender->GetCDBManager()->Get("VZERO/Calib/TimeSlewing",fTender->GetRun()); + if (!entrySlew) { + AliError("VZERO time slewing function is not found in OCDB !"); + fTimeSlewing = NULL; + return; + } else { + fTimeSlewing = (TF1*)entrySlew->GetObject(); + if (fDebug) printf("AliVZEROTenderSupply::Used VZERO time slewing entry: %s\n",entrySlew->GetId().ToString().Data()); + } + + AliCDBEntry *entryRecoParam = fTender->GetCDBManager()->Get("VZERO/Calib/RecoParam",fTender->GetRun()); + if (!entryRecoParam) { + AliError("VZERO reco-param object is not found in OCDB !"); + fRecoParam = NULL; + return; + } else { + TObjArray *recoParamArr = (TObjArray*)entryRecoParam->GetObject(); + if (fDebug) printf("AliVZEROTenderSupply::Used VZERO reco-param entry: %s\n",entryRecoParam->GetId().ToString().Data()); + fRecoParam = NULL; + for(Int_t i = 0; i < recoParamArr->GetEntriesFast(); i++) { + AliVZERORecoParam *par = (AliVZERORecoParam*)recoParamArr->At(i); + if (!par) continue; + if (par->IsDefault()) fRecoParam = par; + } + if (!fRecoParam) AliError("No default VZERO reco-param object is found in OCDB !"); + } + } + + if (!fCalibData || !fTimeSlewing || !fRecoParam) { + AliWarning("VZERO calibration objects not found!"); + return; + } + // + // correct VZERO time signals and decision + // + AliESDVZERO *esdVZERO = event->GetVZEROData(); + if (!esdVZERO) { + AliError("No VZERO object is found inside ESD!"); + return; + } + if (!esdVZERO->TestBit(AliESDVZERO::kDecisionFilled)) { + AliWarning("VZERO offline trigger decisions were not filled in ESD, the tender supply is disabled"); + return; + } + + if (fDebug) printf("LHC-clock phase correction: %f\n",fLHCClockPhase); + + if (fDebug) printf("Original VZERO decision %d (%f ns) and %d (%f ns)\n", + esdVZERO->GetV0ADecision(),esdVZERO->GetV0ATime(), + esdVZERO->GetV0CDecision(),esdVZERO->GetV0CTime()); + Float_t time[64]; + for(Int_t i = 0; i < 64; ++i) { + time[i] = esdVZERO->GetTime(i); + if (time[i] > (AliVZEROReconstructor::kInvalidTime + 1e-6)) + time[i] += fLHCClockPhase; + } + esdVZERO->SetTime(time); + + { + AliVZEROTriggerMask triggerMask; + triggerMask.SetRecoParam(fRecoParam); + triggerMask.FillMasks(esdVZERO, fCalibData, fTimeSlewing); + } + if (fDebug) printf("Modified VZERO decision %d (%f ns) and %d (%f ns)\n", + esdVZERO->GetV0ADecision(),esdVZERO->GetV0ATime(), + esdVZERO->GetV0CDecision(),esdVZERO->GetV0CTime()); + +} + +//_____________________________________________________ +void AliVZEROTenderSupply::GetPhaseCorrection() +{ + // + // Get Gain splines from OCDB + // + + AliInfo("Get LHC-clock phase correction"); + + // + //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; + } + + Float_t oldPhase = 0; + + TIter nextCDB(cdbList); + TObjString *os=0x0; + while ( (os=(TObjString*)nextCDB()) ){ + if (!(os->GetString().Contains("GRP/Calib/LHCClockPhase"))) continue; + AliCDBId *id=AliCDBId::MakeFromString(os->GetString()); + + AliCDBEntry *entry=fTender->GetCDBManager()->Get(*id); + if (!entry) { + AliError("The previous LHC-clock phase entry is not found"); + delete id; + return; + } + + if (fDebug) printf("AliVZEROTenderSupply::Used old LHC-clock phase entry: %s\n",entry->GetId().ToString().Data()); + + AliLHCClockPhase *phase = (AliLHCClockPhase*)entry->GetObject(); + if (!phase) { + AliError("Phase object is not found in the calibration entry"); + delete id; + return; + } + + oldPhase = phase->GetMeanPhase(); + + delete id; + break; + } + + // + //new LHC-clock phase entry + // + Float_t newPhase = 0; + AliCDBEntry *entryNew=fTender->GetCDBManager()->Get("GRP/Calib/LHCClockPhase",fTender->GetRun()); + if (!entryNew) { + AliError("No new LHC-clock phase calibration entry is found"); + return; + } + if (fDebug) printf("AliVZEROTenderSupply::Used new LHC-clock phase entry: %s\n",entryNew->GetId().ToString().Data()); + + AliLHCClockPhase *phase2 = (AliLHCClockPhase*)entryNew->GetObject(); + if (!phase2) { + AliError("Phase object is not found in the calibration entry"); + return; + } + + newPhase = phase2->GetMeanPhase(); + + fLHCClockPhase = newPhase - oldPhase; +} diff --git a/TENDER/TenderSupplies/AliVZEROTenderSupply.h b/TENDER/TenderSupplies/AliVZEROTenderSupply.h new file mode 100644 index 00000000000..0443cad2784 --- /dev/null +++ b/TENDER/TenderSupplies/AliVZEROTenderSupply.h @@ -0,0 +1,52 @@ +#ifndef ALIVZEROTENDERSUPPLY_H +#define ALIVZEROTENDERSUPPLY_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +//////////////////////////////////////////////////////////////////////// +// // +// Recalculate VZERO timing and decision using the tender // +// (in case the LHC phase drift is updated in OCDB) // +// // +//////////////////////////////////////////////////////////////////////// + + + +#include + +class TF1; +class AliVZEROCalibData; +class AliVZERORecoParam; + +class AliVZEROTenderSupply: public AliTenderSupply { + +public: + AliVZEROTenderSupply(); + AliVZEROTenderSupply(const char *name, const AliTender *tender=NULL); + + virtual ~AliVZEROTenderSupply(){;} + + virtual void Init(); + virtual void ProcessEvent(); + + void GetPhaseCorrection(); + + void SetDebug(Bool_t flag) { fDebug = flag; } + +private: + AliVZEROCalibData* fCalibData; //! calibration data + TF1* fTimeSlewing; //! Function for time slewing correction + AliVZERORecoParam* fRecoParam; //! pointer to reco-param object + Float_t fLHCClockPhase; //! the correction to the LHC-clock phase + Bool_t fDebug; // debug on/off + + AliVZEROTenderSupply(const AliVZEROTenderSupply&c); + AliVZEROTenderSupply& operator= (const AliVZEROTenderSupply&c); + + ClassDef(AliVZEROTenderSupply, 2) // VZERO tender task +}; + + +#endif + diff --git a/TENDER/TenderSupplies/AliVtxTenderSupply.cxx b/TENDER/TenderSupplies/AliVtxTenderSupply.cxx new file mode 100644 index 00000000000..a1d098a46e7 --- /dev/null +++ b/TENDER/TenderSupplies/AliVtxTenderSupply.cxx @@ -0,0 +1,101 @@ +/************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "AliVtxTenderSupply.h" + +ClassImp(AliVtxTenderSupply) + +AliVtxTenderSupply::AliVtxTenderSupply() : + AliTenderSupply(), + fDiamond(0x0), + fRefitAlgo(-1) +{ + // + // default ctor + // +} + +//_____________________________________________________ +AliVtxTenderSupply::AliVtxTenderSupply(const char *name, const AliTender *tender) : + AliTenderSupply(name,tender), + fDiamond(0x0), + fRefitAlgo(-1) +{ + // + // named ctor + // +} + +//_____________________________________________________ +void AliVtxTenderSupply::ProcessEvent() +{ + // + // Recalculate the Vertex with constraint + // + + AliESDEvent *event=fTender->GetEvent(); + if (!event) return; + + // + if (fRefitAlgo >=0 ) { // refit with user supplied algo and using the diamond stored in ESD + AliESDUtils::RefitESDVertexTracks(event, fRefitAlgo); + 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(3); + vertexer.SetVtxStart(fDiamond); + AliESDVertex *pvertex = vertexer.FindPrimaryVertex(event); + event->SetPrimaryVertexTracks(pvertex); + // write the diamond parameters + event->SetDiamond(fDiamond); + delete pvertex; + } +} diff --git a/TENDER/TenderSupplies/AliVtxTenderSupply.h b/TENDER/TenderSupplies/AliVtxTenderSupply.h new file mode 100644 index 00000000000..cb969972e7b --- /dev/null +++ b/TENDER/TenderSupplies/AliVtxTenderSupply.h @@ -0,0 +1,44 @@ +#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 + +class AliESDVertex; + +class AliVtxTenderSupply: public AliTenderSupply { + +public: + AliVtxTenderSupply(); + AliVtxTenderSupply(const char *name, const AliTender *tender=NULL); + + virtual ~AliVtxTenderSupply(){;} + + virtual void Init(){;} + virtual void ProcessEvent(); + // + Int_t GetRefitAlgo() const {return fRefitAlgo;} + void SetRefitAlgo(Int_t alg=-1) {fRefitAlgo = alg;} + // +private: + + AliVtxTenderSupply(const AliVtxTenderSupply&c); + AliVtxTenderSupply& operator= (const AliVtxTenderSupply&c); + + AliESDVertex *fDiamond; //!Information about mean vertex + Int_t fRefitAlgo; //! optional request for vertex refit + + ClassDef(AliVtxTenderSupply, 1); // Primary vertex tender task +}; + + +#endif + diff --git a/TENDER/TenderSupplies/CMakeLists.txt b/TENDER/TenderSupplies/CMakeLists.txt new file mode 100644 index 00000000000..725d658f5aa --- /dev/null +++ b/TENDER/TenderSupplies/CMakeLists.txt @@ -0,0 +1,102 @@ +# ************************************************************************** +# * Copyright(c) 1998-2014, 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. * +# ************************************************************************** + +# Module +set(MODULE TenderSupplies) + +# Module include folder +include_directories(${AliRoot_SOURCE_DIR}/ANALYSIS/${MODULE}) + +# Additional include folders in alphabetical order except ROOT +include_directories(${ROOT_INCLUDE_DIRS} + ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSIS + ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSISalice + ${AliRoot_SOURCE_DIR}/ANALYSIS/Tender + ${AliRoot_SOURCE_DIR}/EMCAL/EMCALbase + ${AliRoot_SOURCE_DIR}/EMCAL/EMCALrec + ${AliRoot_SOURCE_DIR}/EMCAL/EMCALUtils + ${AliRoot_SOURCE_DIR}/CORRFW + ${AliRoot_SOURCE_DIR}/OADB + ${AliRoot_SOURCE_DIR}/PHOS/PHOSbase + ${AliRoot_SOURCE_DIR}/PHOS/PHOSrec + ${AliRoot_SOURCE_DIR}/PHOS/PHOSUtils + ${AliRoot_SOURCE_DIR}/STEER/AOD + ${AliRoot_SOURCE_DIR}/STEER/CDB + ${AliRoot_SOURCE_DIR}/STEER/ESD + ${AliRoot_SOURCE_DIR}/STEER/STEER + ${AliRoot_SOURCE_DIR}/STEER/STEERBase + ${AliRoot_SOURCE_DIR}/T0/T0rec + ${AliRoot_SOURCE_DIR}/TOF/TOFbase + ${AliRoot_SOURCE_DIR}/TOF/TOFrec + ${AliRoot_SOURCE_DIR}/TPC/Base + ${AliRoot_SOURCE_DIR}/TPC/TPCbase + ${AliRoot_SOURCE_DIR}/TRD/TRDbase + ${AliRoot_SOURCE_DIR}/VZERO/VZERObase + ${AliRoot_SOURCE_DIR}/VZERO/VZEROrec + ) + +# Sources +set(SRCS + AliAnalysisTaskVZEROEqFactorTask.cxx + AliEMCALTenderSupply.cxx + AliHMPIDTenderSupply.cxx + AliPHOSTenderSupply.cxx + AliPIDTenderSupply.cxx + AliT0TenderSupply.cxx + AliTOFTenderSupply.cxx + AliTPCTenderSupply.cxx + AliTrackFixTenderSupply.cxx + AliTRDTenderSupply.cxx + AliVtxTenderSupply.cxx + AliVZEROTenderSupply.cxx + ) + +# Headers from sources +string(REPLACE ".cxx" ".h" HDRS "${SRCS}") + +# Generate the dictionary +# It will create G_ARG1.cxx and G_ARG1.h / ARG1 = function first argument +get_directory_property(incdirs INCLUDE_DIRECTORIES) +generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}") + +# Generate the ROOT map +# Dependecies +set(LIBDEPS ANALYSIS ANALYSISalice Tender EMCALbase EMCALrec EMCALUtils CORRFW OADB PHOSbase PHOSrec PHOSUtils AOD CDB ESD STEER STEERBase T0rec TOFbase TOFrec TPCbase TRDbase VZERObase VZEROrec Core Geom Gpad Graf Hist MathCore Matrix Physics RIO Tree) +generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h") + +# Add a library to the project using the specified source files +add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx) +target_link_libraries(${MODULE} ANALYSIS ANALYSISalice Tender EMCALbase EMCALrec EMCALUtils CORRFW OADB PHOSbase PHOSrec PHOSUtils AOD CDB ESD STEER STEERBase T0rec TOFbase TOFrec TPCbase TRDbase VZERObase VZEROrec Core Geom Gpad Graf Hist MathCore Matrix Physics RIO Tree) + +# Additional compilation flags +set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "") + +# Linking the library +target_link_libraries(${MODULE} ${LIBDEPS}) + +# System dependent: Modify the way the library is build +if(${CMAKE_SYSTEM} MATCHES Darwin) + set_target_properties(${MODULE} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") +endif(${CMAKE_SYSTEM} MATCHES Darwin) + +# Installation +install(TARGETS ${MODULE} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +install(FILES ${HDRS} DESTINATION include) + +# Install macros +install(FILES AddTaskTender.C DESTINATION ANALYSIS/TenderSupplies) + diff --git a/TENDER/TenderSupplies/TenderSuppliesLinkDef.h b/TENDER/TenderSupplies/TenderSuppliesLinkDef.h new file mode 100644 index 00000000000..90c941c460f --- /dev/null +++ b/TENDER/TenderSupplies/TenderSuppliesLinkDef.h @@ -0,0 +1,22 @@ +#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 AliPIDTenderSupply+; +#pragma link C++ class AliTOFTenderSupply+; +#pragma link C++ class AliTPCTenderSupply+; +#pragma link C++ class AliTRDTenderSupply+; +#pragma link C++ class AliVtxTenderSupply+; +#pragma link C++ class AliVZEROTenderSupply+; +#pragma link C++ class AliEMCALTenderSupply+; +#pragma link C++ class AliPHOSTenderSupply+; +#pragma link C++ class AliHMPIDTenderSupply+; +#pragma link C++ class AliT0TenderSupply+; +#pragma link C++ class AliTrackFixTenderSupply+; +#pragma link C++ class AliAnalysisTaskVZEROEqFactorTask+; + +#endif