#include "AliVAnalysisMuon.h"
#include "TROOT.h"
#include "TH1.h"
#include "TH2.h"
#include "TAxis.h"
#include "TCanvas.h"
#include "TLegend.h"
#include "TMath.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "THashList.h"
#include "TStyle.h"
#include "TLorentzVector.h"
#include "TRegexp.h"
#include "AliInputEventHandler.h"
#include "AliCentrality.h"
#include "AliAODEvent.h"
#include "AliAODTrack.h"
#include "AliAODMCParticle.h"
#include "AliMCEvent.h"
#include "AliMCParticle.h"
#include "AliESDEvent.h"
#include "AliESDMuonTrack.h"
#include "AliCounterCollection.h"
#include "AliVVertex.h"
#include "AliAnalysisManager.h"
#include "AliAnalysisTaskSE.h"
#include "AliAnalysisDataSlot.h"
#include "AliAnalysisDataContainer.h"
#include "AliCFGridSparse.h"
#include "AliMergeableCollection.h"
#include "AliMuonEventCuts.h"
#include "AliMuonTrackCuts.h"
#include "AliMuonPairCuts.h"
#include "AliAnalysisMuonUtility.h"
#include "AliUtilityMuonAncestor.h"
ClassImp(AliVAnalysisMuon)
AliVAnalysisMuon::AliVAnalysisMuon() :
AliAnalysisTaskSE(),
fMuonEventCuts(0x0),
fMuonTrackCuts(0x0),
fMuonPairCuts(0x0),
fESDEvent(0x0),
fAODEvent(0x0),
fTerminateOptions(0x0),
fChargeKeys(0x0),
fSrcKeys(0x0),
fPhysSelKeys(0x0),
fWeights(0x0),
fUtilityMuonAncestor(0x0),
fEventCounters(0x0),
fMergeableCollection(0x0),
fOutputList(0x0),
fOutputPrototypeList(0x0)
{
}
AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts, const AliMuonPairCuts& pairCuts) :
AliAnalysisTaskSE(name),
fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
fESDEvent(0x0),
fAODEvent(0x0),
fTerminateOptions(0x0),
fChargeKeys(0x0),
fSrcKeys(0x0),
fPhysSelKeys(0x0),
fWeights(new THashList()),
fUtilityMuonAncestor(0x0),
fEventCounters(0x0),
fMergeableCollection(0x0),
fOutputList(0x0),
fOutputPrototypeList(0x0)
{
InitKeys();
SetTrigClassPatterns("");
SetCentralityClasses();
fWeights->SetOwner();
DefineOutput(1, TObjArray::Class());
}
AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts) :
AliAnalysisTaskSE(name),
fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
fMuonPairCuts(0x0),
fESDEvent(0x0),
fAODEvent(0x0),
fTerminateOptions(0x0),
fChargeKeys(0x0),
fSrcKeys(0x0),
fPhysSelKeys(0x0),
fWeights(new THashList()),
fUtilityMuonAncestor(0x0),
fEventCounters(0x0),
fMergeableCollection(0x0),
fOutputList(0x0),
fOutputPrototypeList(0x0)
{
InitKeys();
SetTrigClassPatterns("");
SetCentralityClasses();
fWeights->SetOwner();
DefineOutput(1, TObjArray::Class());
}
AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonPairCuts& pairCuts) :
AliAnalysisTaskSE(name),
fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
fMuonTrackCuts(0x0),
fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
fESDEvent(0x0),
fAODEvent(0x0),
fTerminateOptions(0x0),
fChargeKeys(0x0),
fSrcKeys(0x0),
fPhysSelKeys(0x0),
fWeights(new THashList()),
fUtilityMuonAncestor(0x0),
fEventCounters(0x0),
fMergeableCollection(0x0),
fOutputList(0x0),
fOutputPrototypeList(0x0)
{
InitKeys();
SetTrigClassPatterns("");
SetCentralityClasses();
fWeights->SetOwner();
DefineOutput(1, TObjArray::Class());
}
AliVAnalysisMuon::~AliVAnalysisMuon()
{
delete fMuonEventCuts;
delete fMuonTrackCuts;
delete fMuonPairCuts;
delete fTerminateOptions;
delete fChargeKeys;
delete fSrcKeys;
delete fPhysSelKeys;
delete fWeights;
delete fUtilityMuonAncestor;
delete fOutputPrototypeList;
if ( ! AliAnalysisManager::GetAnalysisManager() || ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) {
delete fOutputList;
}
}
void AliVAnalysisMuon::FinishTaskOutput()
{
fMergeableCollection->PruneEmptyObjects();
if ( fInputHandler ) {
for ( Int_t istat=0; istat<2; istat++ ) {
TString statType = ( istat == 0 ) ? "ALL" : "BIN0";
TH2* hStat = dynamic_cast<TH2*>(fInputHandler->GetStatistics(statType.Data()));
if ( hStat ) {
TString objectName = Form("%s_%s", hStat->GetName(), GetName());
TH2* cloneStat = static_cast<TH2*>(hStat->Clone(objectName.Data()));
cloneStat->SetDirectory(0);
fOutputList->Add(cloneStat);
}
else {
AliWarning("Stat histogram not available");
break;
}
}
}
}
void AliVAnalysisMuon::NotifyRun()
{
if ( fMuonTrackCuts ) fMuonTrackCuts->SetRun(fInputHandler);
if ( fMuonPairCuts ) fMuonPairCuts->SetRun(fInputHandler);
}
void AliVAnalysisMuon::UserCreateOutputObjects()
{
AliInfo(Form(" CreateOutputObjects of task %s\n", GetName()));
fOutputList = new TObjArray();
fOutputList->SetOwner();
fEventCounters = new AliCounterCollection("eventCounters");
if ( ! GetCentralityClasses() ) SetCentralityClasses();
TString centralityClasses = "";
for ( Int_t icent=1; icent<=GetCentralityClasses()->GetNbins(); ++icent ) {
if ( ! centralityClasses.IsNull() ) centralityClasses += "/";
centralityClasses += GetCentralityClasses()->GetBinLabel(icent);
}
fEventCounters->AddRubric("selected", "yes/no");
fEventCounters->AddRubric("trigger", 100);
fEventCounters->AddRubric("centrality", centralityClasses);
fEventCounters->AddRubric("run", 10000);
fEventCounters->Init();
fOutputList->Add(fEventCounters);
fMergeableCollection = new AliMergeableCollection("outputObjects");
fOutputList->Add(fMergeableCollection);
PostData(1, fOutputList);
fMuonEventCuts->Print();
MyUserCreateOutputObjects();
fUtilityMuonAncestor = new AliUtilityMuonAncestor();
}
void AliVAnalysisMuon::UserExec(Option_t * )
{
fAODEvent = dynamic_cast<AliAODEvent*> (InputEvent());
if ( ! fAODEvent )
fESDEvent = dynamic_cast<AliESDEvent*> (InputEvent());
if ( ! fAODEvent && ! fESDEvent ) {
AliError ("AOD or ESD event not found. Nothing done!");
return;
}
if ( ! fMuonEventCuts->IsSelected(fInputHandler) ) return;
Int_t physSel = ( fInputHandler->IsEventSelected() & AliVEvent::kAny ) ? kPhysSelPass : kPhysSelReject;
const TObjArray* selectTrigClasses = fMuonEventCuts->GetSelectedTrigClassesInEvent(InputEvent());
Double_t centrality = fMuonEventCuts->GetCentrality(InputEvent());
Int_t centralityBin = GetCentralityClasses()->FindBin(centrality);
TString centralityBinLabel = GetCentralityClasses()->GetBinLabel(centralityBin);
TString selKey = ( physSel == kPhysSelPass ) ? "yes" : "no";
for ( Int_t itrig=0; itrig<selectTrigClasses->GetEntries(); ++itrig ) {
TString trigName = selectTrigClasses->At(itrig)->GetName();
fEventCounters->Count(Form("trigger:%s/selected:%s/centrality:%s/run:%i", trigName.Data(), selKey.Data(), centralityBinLabel.Data(),fCurrentRunNumber));
}
ProcessEvent(fPhysSelKeys->At(physSel)->GetName(), *selectTrigClasses, centralityBinLabel);
PostData(1, fOutputList);
}
void AliVAnalysisMuon::Terminate(Option_t *)
{
if ( ! fTerminateOptions ) SetTerminateOptions();
TString furtherOpt = ((TObjString*)fTerminateOptions->At(3))->GetString();
furtherOpt.ToUpper();
if ( gROOT->IsBatch() && ! furtherOpt.Contains("FORCEBATCH") ) return;
fOutputList = dynamic_cast<TObjArray*>(GetOutputData(1));
if ( ! fOutputList ) return;
fEventCounters = static_cast<AliCounterCollection*>(fOutputList->FindObject("eventCounters"));
fMergeableCollection = static_cast<AliMergeableCollection*>(fOutputList->FindObject("outputObjects"));
if ( ! fMergeableCollection ) return;
AliInfo(Form("Mergeable collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
if ( fTerminateOptions->At(3) ) {
TString sopt = fTerminateOptions->At(3)->GetName();
if ( sopt.Contains("verbose") ) fMergeableCollection->Print("*");
}
SetCentralityClassesFromOutput();
}
Int_t AliVAnalysisMuon::GetParticleType ( AliVParticle* track )
{
if ( fUtilityMuonAncestor->IsUnidentified(track,MCEvent()) ) return kUnidentified;
if ( fUtilityMuonAncestor->IsBeautyMu(track,MCEvent()) ) return kBeautyMu;
if ( fUtilityMuonAncestor->IsCharmMu(track,MCEvent()) ) return kCharmMu;
if ( fUtilityMuonAncestor->IsWBosonMu(track,MCEvent()) ) return kWbosonMu;
if ( fUtilityMuonAncestor->IsZBosonMu(track,MCEvent()) ) return kZbosonMu;
if ( fUtilityMuonAncestor->IsDecayMu(track,MCEvent()) ) return kDecayMu;
if ( fUtilityMuonAncestor->IsQuarkoniumMu(track,MCEvent()) ) return kQuarkoniumMu;
if ( fUtilityMuonAncestor->IsHadron(track,MCEvent()) ) return kRecoHadron;
if ( fUtilityMuonAncestor->IsSecondaryMu(track,MCEvent()) ) return kSecondaryMu;
return kDecayMu;
}
Bool_t AliVAnalysisMuon::AddObjectToCollection(TObject* object, Int_t index)
{
if ( ! fOutputPrototypeList ) {
fOutputPrototypeList = new TObjArray();
fOutputPrototypeList->SetOwner();
}
if ( fOutputPrototypeList->FindObject(object->GetName() ) ) {
AliWarning(Form("Object with name %s already in the list", object->GetName()));
return kFALSE;
}
if ( index < 0 ) fOutputPrototypeList->Add(object);
else fOutputPrototypeList->AddAtAndExpand(object, index);
return kTRUE;
}
TObject* AliVAnalysisMuon::GetMergeableObject(TString physSel, TString trigClassName, TString centrality, TString objectName)
{
TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
TObject* obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
if ( ! obj ) {
CreateMergeableObjects(physSel, trigClassName, centrality);
obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
AliInfo(Form("Mergeable object collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
}
return obj;
}
TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TString centrality, TString objectPattern)
{
if ( ! fMergeableCollection ) return 0x0;
Int_t firstCentrality = 1;
Int_t lastCentrality = GetCentralityClasses()->GetNbins();
TObjArray* centralityRange = centrality.Tokenize("_");
Float_t range[2] = {0., 100.};
if ( centralityRange->GetEntries() >= 2 ) {
for ( Int_t irange=0; irange<2; ++irange ) {
range[irange] = ((TObjString*)centralityRange->At(irange))->GetString().Atof();
}
firstCentrality = GetCentralityClasses()->FindBin(range[0]+0.0001);
lastCentrality = GetCentralityClasses()->FindBin(range[1]-0.0001);
}
delete centralityRange;
TString sumCentralityString = "";
for ( Int_t icent=firstCentrality; icent<=lastCentrality; ++icent ) {
if ( ! sumCentralityString.IsNull() ) sumCentralityString += ",";
sumCentralityString += GetCentralityClasses()->GetBinLabel(icent);
}
TObjArray objectNameInCollection;
objectNameInCollection.SetOwner();
TObjArray* physSelList = physSel.Tokenize(",");
TObjArray* trigClassList = trigClassNames.Tokenize(",");
TObjArray* centralityList = sumCentralityString.Tokenize(",");
for ( Int_t isel=0; isel<physSelList->GetEntries(); isel++ ) {
for ( Int_t itrig = 0; itrig<trigClassList->GetEntries(); itrig++ ) {
for ( Int_t icent=0; icent<centralityList->GetEntries(); icent++ ) {
TString currId = Form("/%s/%s/%s/", physSelList->At(isel)->GetName(), trigClassList->At(itrig)->GetName(),centralityList->At(icent)->GetName());
TList* objNameList = fMergeableCollection->CreateListOfObjectNames(currId.Data());
for ( Int_t iobj=0; iobj<objNameList->GetEntries(); iobj++ ) {
TString objName = objNameList->At(iobj)->GetName();
if ( ! objectNameInCollection.FindObject(objName.Data()) ) objectNameInCollection.Add(new TObjString(objName.Data()));
}
delete objNameList;
}
}
}
delete physSelList;
delete trigClassList;
delete centralityList;
TObjArray* objPatternList = objectPattern.Tokenize(",");
TString matchingObjectNames = "";
for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
TString objName = objectNameInCollection.At(iobj)->GetName();
for ( Int_t ipat=0; ipat<objPatternList->GetEntries(); ipat++ ) {
TString currPattern = ((TObjString*)objPatternList->At(ipat))->GetString();
if ( currPattern.Contains("*") ) {
if ( ! objName.Contains(TRegexp(currPattern.Data(),kTRUE)) ) continue;
}
else if ( objName != currPattern ) continue;
if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
matchingObjectNames += objName;
}
}
delete objPatternList;
TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
idPattern.ReplaceAll(" ","");
AliDebug(1,Form("Sum pattern %s", idPattern.Data()));
return fMergeableCollection->GetSum(idPattern.Data());
}
void AliVAnalysisMuon::CreateMergeableObjects(TString physSel, TString trigClassName, TString centrality)
{
TObject* obj = 0x0;
TString objectName = "";
TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
for ( Int_t iobj=0; iobj<fOutputPrototypeList->GetEntries(); ++iobj ) {
objectName = fOutputPrototypeList->At(iobj)->GetName();
obj = fOutputPrototypeList->At(iobj)->Clone(objectName.Data());
fMergeableCollection->Adopt(identifier, obj);
}
}
Bool_t AliVAnalysisMuon::SetSparseRange(AliCFGridSparse* gridSparse,
Int_t ivar, TString labelName,
Double_t varMin, Double_t varMax,
TString option)
{
return AliAnalysisMuonUtility::SetSparseRange(gridSparse,ivar,labelName,varMin, varMax,option);
}
TString AliVAnalysisMuon::GetDefaultTrigClassPatterns() const
{
return fMuonEventCuts->GetDefaultTrigClassPatterns();
}
void AliVAnalysisMuon::SetTrigClassPatterns(const TString pattern)
{
TString currPattern = pattern;
if ( currPattern.IsNull() ) {
currPattern = GetDefaultTrigClassPatterns();
currPattern.Append(",!CMUP*");
}
fMuonEventCuts->SetTrigClassPatterns(currPattern);
}
TList* AliVAnalysisMuon::GetAllSelectedTrigClasses() const
{
return fMuonEventCuts->GetAllSelectedTrigClasses();
}
void AliVAnalysisMuon::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
{
fMuonEventCuts->SetCentralityClasses(nCentralityBins, centralityBins);
}
TAxis* AliVAnalysisMuon::GetCentralityClasses() const
{
return fMuonEventCuts->GetCentralityClasses();
}
Bool_t AliVAnalysisMuon::SetCentralityClassesFromOutput()
{
if ( ! fMergeableCollection ) return kFALSE;
TList* centrKeyList = fMergeableCollection->CreateListOfKeys(2);
TObjArray centrLimitsList;
centrLimitsList.SetOwner();
if ( ! centrKeyList ) return kFALSE;
for ( Int_t ikey=0; ikey<centrKeyList->GetEntries(); ikey++ ) {
TString centr = static_cast<TObjString*>(centrKeyList->At(ikey))->GetString();
TObjArray* array = centr.Tokenize("_");
for ( Int_t ilim=0; ilim<array->GetEntries(); ilim++ ) {
TString currLim = static_cast<TObjString*>(array->At(ilim))->GetString();
if ( ! centrLimitsList.FindObject(currLim.Data()) ) centrLimitsList.Add(new TObjString(currLim));
}
delete array;
}
delete centrKeyList;
TArrayD bins(centrLimitsList.GetEntries());
for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
bins[ibin] = static_cast<TObjString*>(centrLimitsList.At(ibin))->GetString().Atof();
}
Int_t index[bins.GetSize()];
TMath::Sort(bins.GetSize(),bins.GetArray(),index, kFALSE);
TArrayD sortedBins(bins.GetSize());
for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
sortedBins[ibin] = bins[index[ibin]];
}
SetCentralityClasses(sortedBins.GetSize()-1, sortedBins.GetArray());
return kTRUE;
}
void AliVAnalysisMuon::SetTerminateOptions(TString physSel, TString trigClass, TString centralityRange, TString furtherOpts)
{
if ( ! fTerminateOptions ) {
fTerminateOptions = new TObjArray(4);
fTerminateOptions->SetOwner();
}
fTerminateOptions->AddAt(new TObjString(physSel), 0);
fTerminateOptions->AddAt(new TObjString(trigClass), 1);
fTerminateOptions->AddAt(new TObjString(centralityRange),2);
fTerminateOptions->AddLast(new TObjString(furtherOpts));
}
void AliVAnalysisMuon::InitKeys()
{
TString chargeKeys = "MuMinus MuPlus";
fChargeKeys = chargeKeys.Tokenize(" ");
TString srcKeys = "CharmMu BeautyMu QuarkoniumMu WbosonMu ZbosonMu DecayMu SecondaryMu Hadron Unidentified";
fSrcKeys = srcKeys.Tokenize(" ");
TString physSelKeys = "PhysSelPass PhysSelReject";
fPhysSelKeys = physSelKeys.Tokenize(" ");
}
void AliVAnalysisMuon::SetWeight ( TObject* wgtObj )
{
if ( fWeights->FindObject(wgtObj->GetName()) ) {
AliWarning(Form("Weight object %s is already in the list",wgtObj->GetName()));
return;
}
fWeights->Add(wgtObj);
}
TObject* AliVAnalysisMuon::GetWeight ( const Char_t* wgtName )
{
return fWeights->FindObject(wgtName);
}