Bool_t RsnConfigTest ( AliRsnAnalysisTask *task, Bool_t isMC ) { // cutBPIDKaonSet // find the index of the corresponding list in the RsnInputHandler const char *listNameQuality = "qualityTPC"; const char *listNamePID = "kaonTPC"; Int_t qualityID = -1; Int_t pidID = -1; AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); AliMultiInputEventHandler *multi = dynamic_cast<AliMultiInputEventHandler*>(mgr->GetInputEventHandler()); if (multi) { TObjArray *array = multi->InputEventHandlers(); TObjArrayIter next(array); TObject *obj; while ( (obj = next()) ) { if (obj->InheritsFrom(AliRsnInputHandler::Class())) { AliRsnInputHandler *rsn = (AliRsnInputHandler*)obj; AliRsnDaughterSelector *sel = rsn->GetSelector(); qualityID = sel->GetID(listNameQuality, kTRUE); pidID = sel->GetID(listNamePID, kTRUE); } } } // if (qualityID < 0) { // ::Error("RsnConfigTest", "Selector does not contain list for quality only"); // return kFALSE; // } // if (pidID < 0) { // ::Error("RsnConfigTest", "Selector does not contain list for quality+PID"); // return kFALSE; // } ::Info("RsnConfigTest", "ID for cut set named '%10s' = %d", listNameQuality, qualityID); // ::Info("RsnConfigTest", "ID for cut set named '%10s' = %d", listNamePID, pidID); // add pair computation AddPairLoop(task, isMC, 0, 0, "test"); // add monitor computation AddMonitorLoop(task, isMC, 0, "test"); // // add pair computation // AddPairLoop(task, isMC, qualityID, qualityID, "test"); // // add monitor computation // AddMonitorLoop(task, isMC, qualityID, "test"); // AddMonitorLoop(task, isMC, pidID, "test"); return kTRUE; }
void PrintManager(TObject *mgrObj) { AliAnalysisManager *mgr = (AliAnalysisManager *)mgrObj; if (!mgr->InitAnalysis()) return; mgr->RunLocalInit(); mgr->PrintStatus(); Printf("Analysis Manager : %s '%s'",mgr->GetName(),mgr->GetTitle() ); TObjArray *a = mgr->GetTasks(); if (a) Printf("Tasks total : %d",a->GetEntries()); TIter next(mgr->GetTasks()); AliAnalysisTask *task; while ((task = (AliAnalysisTask *) next())) { if (task->IsA() == AliRsnMiniAnalysisTask::Class()) { Printf(" Task [RSN-MINI] : %s '%s'",task->GetName(),task->GetTitle()); AliRsnMiniAnalysisTask *rsnMiniTask = (AliRsnMiniAnalysisTask *)task; rsnMiniTask->Print(); } else if (task->IsA() == AliRsnAnalysisTask::Class()) { Printf(" Task [RSN-----] : %s '%s'",task->GetName(),task->GetTitle()); AliRsnAnalysisTask *rsnTask = (AliRsnAnalysisTask *)task; rsnTask->Print(); AliVEventHandler *ih = mgr->GetInputEventHandler(); if (ih == AliMultiInputEventHandler::Class()) { AliMultiInputEventHandler *ihMulti = (AliMultiInputEventHandler *) ih; TIter nextIH(ihMulti->InputEventHandlers()); AliRsnInputHandler *rsnIH = 0; while ((ih = (AliVEventHandler *) nextIH())) { if (ih->IsA() == AliRsnInputHandler::Class()) { rsnIH = ih; AliRsnDaughterSelector *ds = rsnIH->GetSelector(); ds->Print(); } } } } else { Printf(" Task [--------] : %s '%s'",task->GetName(),task->GetTitle()); } } }
// // *** Configuration script for phi->KK analysis with 2010 runs *** // // A configuration script for RSN package needs to define the followings: // // (1) decay tree of each resonance to be studied, which is needed to select // true pairs and to assign the right mass to all candidate daughters // (2) cuts at all levels: single daughters, tracks, events // (3) output objects: histograms or trees // Bool_t RsnConfigPhiTPC ( AliRsnAnalysisTask *task, Bool_t isMC, Bool_t isMix, Bool_t useCentrality, AliRsnCutSet *eventCuts ) { if (!task) ::Error("RsnConfigPhiTPC", "NULL task"); // we define here a suffix to differentiate names of different setups for the same resonance // and we define also the name of the list of tracks we want to select for the analysis // (if will fail if no lists with this name were added to the RsnInputHandler) const char *suffix = "tpc"; const char *listName = "kaonTPC"; Bool_t useCharged = kTRUE; Int_t listID = -1; // find the index of the corresponding list in the RsnInputHandler AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); AliMultiInputEventHandler *multi = dynamic_cast<AliMultiInputEventHandler*>(mgr->GetInputEventHandler()); if (multi) { TObjArray *array = multi->InputEventHandlers(); AliRsnInputHandler *rsn = (AliRsnInputHandler*)array->FindObject("rsnInputHandler"); if (rsn) { AliRsnDaughterSelector *sel = rsn->GetSelector(); listID = sel->GetID(listName, useCharged); } } if (listID >= 0) ::Info ("RsnConfigPhiTPC.C", "Required list '%s' stays in position %d", listName, listID); else { ::Error("RsnConfigPhiTPC.C", "Required list '%s' absent in handler!", listName); return kFALSE; } // ---------------------------------------------------------------------------------------------- // -- DEFINITIONS ------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- // PAIR DEFINITIONS: // this contains the definition of particle species and charge for both daughters of a resonance, // which are used for the following purposes: // --> species is used to assign the mass to the daughter (e.g. for building invariant mass) // --> charge is used to select what tracks to use when doing the computation loops // When a user wants to compute a like-sign background, he must define also a pair definition // for each like-sign: in case of charged track decays, we need one for ++ and one for -- // Last two arguments are necessary only in some cases (but it is not bad to well initialize them): // --> PDG code of resonance, which is used for selecting true pairs, when needed // --> nominal resonance mass, which is used for computing quantities like Y or Mt AliRsnPairDef *phi_kaonP_kaonM = new AliRsnPairDef(AliRsnDaughter::kKaon, '+', AliRsnDaughter::kKaon, '-', 333, 1.019455); AliRsnPairDef *phi_kaonP_kaonP = new AliRsnPairDef(AliRsnDaughter::kKaon, '+', AliRsnDaughter::kKaon, '+', 333, 1.019455); AliRsnPairDef *phi_kaonM_kaonM = new AliRsnPairDef(AliRsnDaughter::kKaon, '-', AliRsnDaughter::kKaon, '-', 333, 1.019455); // PAIR LOOPS: // these are the objects which drive the computations and fill the output histograms // each one requires to be initialized with an AliRsnPairDef object, which provided masses, // last argument tells if the pair is for mixing or not (this can be also set afterwards, anyway) const Int_t nPairs = 5; Bool_t addPair[nPairs] = {1, 1, 1, 1, 1}; AliRsnLoopPair *phiLoop[nPairs]; phiLoop[0] = new AliRsnLoopPair(Form("%s_phi_kaonP_kaonM" , suffix), phi_kaonP_kaonM, kFALSE); phiLoop[1] = new AliRsnLoopPair(Form("%s_phi_kaonP_kaonM_true", suffix), phi_kaonP_kaonM, kFALSE); phiLoop[2] = new AliRsnLoopPair(Form("%s_phi_kaonP_kaonM_mix" , suffix), phi_kaonP_kaonM, kTRUE ); phiLoop[3] = new AliRsnLoopPair(Form("%s_phi_kaonP_kaonP" , suffix), phi_kaonP_kaonP, kFALSE); phiLoop[4] = new AliRsnLoopPair(Form("%s_phi_kaonM_kaonM" , suffix), phi_kaonM_kaonM, kFALSE); // set additional option for true pairs // 1) we select only pairs coming from the same mother, which must have the right PDG code (from pairDef) // 2) we select only pairs decaying according to the right channel (from pairDef species+charge definitions) phiLoop[1]->SetOnlyTrue(kTRUE); phiLoop[1]->SetCheckDecay(kTRUE); // don't add true pairs if not MC if (!isMC) addPair[1] = 0; addPair[0] = !isMix; addPair[1] = !isMix; addPair[2] = isMix; addPair[3] = !isMix; addPair[4] = !isMix; // ---------------------------------------------------------------------------------------------- // -- COMPUTED VALUES & OUTPUTS ----------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- // All values which should be computed are defined here and passed to the computation objects, // since they define all that is computed bye each one, and, in case one output is a histogram // they define the binning and range for that value // // NOTE: // --> multiplicity bins have variable size Double_t mult[] = { 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 30., 35., 40., 50., 60., 70., 80., 90., 100., 120., 140., 160., 180., 200., 500.}; Int_t nmult = sizeof(mult) / sizeof(mult[0]); AliRsnValuePair *axisIM = new AliRsnValuePair("IM" , AliRsnValuePair::kInvMass ); AliRsnValuePair *axisRes = new AliRsnValuePair("RES", AliRsnValuePair::kInvMassRes); AliRsnValuePair *axisPt = new AliRsnValuePair("PT" , AliRsnValuePair::kPt ); AliRsnValuePair *axisY = new AliRsnValuePair("Y" , AliRsnValuePair::kY); AliRsnValueEvent*axisCentV0 = new AliRsnValueEvent("CNT" , AliRsnValueEvent::kCentralityV0); AliRsnValueEvent*axisMultESD = new AliRsnValueEvent("MESD", AliRsnValueEvent::kMultESDCuts ); AliRsnValueEvent*axisMultSPD = new AliRsnValueEvent("MSPD", AliRsnValueEvent::kMultSPD ); AliRsnValueEvent*axisMultTRK = new AliRsnValueEvent("MTRK", AliRsnValueEvent::kMult ); AliRsnValueEvent*axisMultMC = new AliRsnValueEvent("MMC" , AliRsnValueEvent::kMultMC ); axisIM ->SetBins(500, 0.9, 1.4); axisRes ->SetBins(-0.5, 0.5, 0.001); axisPt ->SetBins(50, 0.0, 5.0); axisY ->SetBins(1, -0.5, 0.5); axisCentV0 ->SetBins(20, 0.0, 100.0); axisMultESD->SetBins(nmult, mult); axisMultSPD->SetBins(nmult, mult); axisMultTRK->SetBins(nmult, mult); axisMultMC ->SetBins(nmult, mult); // create outputs: // we define one for true pairs, where we add resolution, and another without it, for all others // it seems that it is much advantageous to use sparse histograms when adding more than 2 axes AliRsnListOutput *out[2]; out[0] = new AliRsnListOutput("res" , AliRsnListOutput::kHistoSparse); out[1] = new AliRsnListOutput("nores", AliRsnListOutput::kHistoSparse); // add values to outputs: // if centrality is required, we add it only, otherwise we add all multiplicities // other axes (invmass, pt) are always added for (Int_t i = 0; i < 2; i++) { out[i]->AddValue(axisIM); out[i]->AddValue(axisPt); out[i]->AddValue(axisY); if (useCentrality) { ::Info("RsnConfigPhiTPC.C", "Adding centrality axis"); out[i]->AddValue(axisCentV0); } else { ::Info("RsnConfigPhiTPC.C", "Adding multiplicity axes"); //out[i]->AddValue(axisMultESD); //out[i]->AddValue(axisMultSPD); out[i]->AddValue(axisMultTRK); if (isMC) out[i]->AddValue(axisMultMC); } } // resolution only in the first out[0]->AddValue(axisRes); // ---------------------------------------------------------------------------------------------- // -- ADD SETTINGS TO LOOPS AND LOOPS TO TASK --------------------------------------------------- // ---------------------------------------------------------------------------------------------- for (Int_t ip = 0; ip < nPairs; ip++) { // skip pairs not to be added if (!addPair[ip]) continue; // assign list IDs phiLoop[ip]->SetListID(0, listID); phiLoop[ip]->SetListID(1, listID); // assign event cuts phiLoop[ip]->SetEventCuts(eventCuts); // assign outputs if (ip != 1) phiLoop[ip]->AddOutput(out[1]); else phiLoop[ip]->AddOutput(out[0]); // add to task task->AddLoop(phiLoop[ip]); } return kTRUE; }
// // Test config macro for RSN package. // It configures: // 1) a monitor for all tracks passing quality cuts // 2) a monitor for all tracks passing quality + PID cuts // 3) an unlike-sign invariant-mass + pt distribution for K+K- pairs // Bool_t RsnConfigPhiKaonTest ( AliRsnAnalysisTask *task, Bool_t isMC ) { if (!task) { ::Error("RsnConfigPhiKaonTest.C", "NULL task"); return kFALSE; } const char *suffix = "test"; // ---------------------------------------------------------------------------------------------- // -- DEFINITIONS ------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- // daughter definition for monitor loops // since it is intended to loop over all 'track' like objects (in the sense that we exclude V0s and cascades), // we initialize it using the constructor that requires an AliRsnDaughter::EType and a charge, but since // we want to loop over both charges, we set it to anything which is not '+' '-' or '0', which are tokens for // selecting only positive, only negative or only neutral AliRsnDaughterDef *tracks = new AliRsnDaughterDef(AliRsnDaughter::kTrack, 0); // definition of pair decay tree for phi resonance // here we *must* specify a particle species and a charge, in order to check the decay tree // last arguments are the PDG code and nominal mass of the resonance, which are needed when // one wants to select true pairs only and/or he wants to compute rapidity or Mt AliRsnPairDef *pairDef = new AliRsnPairDef(AliRsnDaughter::kKaon, '+', AliRsnDaughter::kKaon, '-', 333, 1.019455); // definition of loop objects: // (a) 1 monitor for all tracks passing quality cuts // (b) 1 monitor for all tracks passing quality+PID cuts // (c) 1 pair filled with all tracks passing same cuts as (b) // (d) 1 pair like (c) but for mixing // (e) 1 pair like (c) but with true pairs only // NOTE: (c) and (d) are instantiated with same settings, they will be made // different after some settings done in second moment AliRsnLoopDaughter *loopQuality = new AliRsnLoopDaughter(Form("%s_mon_quality", suffix), 0, tracks); AliRsnLoopDaughter *loopPID = new AliRsnLoopDaughter(Form("%s_mon_pid" , suffix), 0, tracks); AliRsnLoopPair *loopPhi = new AliRsnLoopPair (Form("%s_unlike" , suffix), pairDef); AliRsnLoopPair *loopPhiMix = new AliRsnLoopPair (Form("%s_unlike" , suffix), pairDef); AliRsnLoopPair *loopPhiTrue = new AliRsnLoopPair (Form("%s_trues" , suffix), pairDef); // set additional option for true pairs (slot [0]) loopPhiTrue->SetOnlyTrue(kTRUE); loopPhiTrue->SetCheckDecay(kTRUE); // set mixing options loopPhi ->SetMixed(kFALSE); loopPhiMix ->SetMixed(kTRUE); loopPhiTrue->SetMixed(kFALSE); // assign the ID of the entry lists to be used by each pair to get selected daughters // in our case, the AliRsnInputHandler contains only one list for selecting kaons Int_t idQuality, idPID; AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager(); AliMultiInputEventHandler *multi = dynamic_cast<AliMultiInputEventHandler*>(mgr->GetInputEventHandler()); if (!multi) { myError("Needed a multi input handler!"); return kFALSE; } TObjArray *array = multi->InputEventHandlers(); AliRsnInputHandler *rsn = (AliRsnInputHandler*)array->FindObject("rsnInputHandler"); if (!rsn) { myError("Needed an RSN event handler"); return kFALSE; } AliRsnDaughterSelector *sel = rsn->GetSelector(); idQuality = sel->GetID("qualityTPC", kTRUE); idPID = sel->GetID("kaonTPC", kTRUE); if (idQuality < 0 || idPID < 0) { myError("List problems"); return kFALSE; } loopQuality->SetListID(idQuality); loopPID ->SetListID(idPID); loopPhi ->SetListID(0, idPID); loopPhi ->SetListID(1, idPID); loopPhiMix ->SetListID(0, idPID); loopPhiMix ->SetListID(1, idPID); loopPhiTrue->SetListID(0, idPID); loopPhiTrue->SetListID(1, idPID); // ---------------------------------------------------------------------------------------------- // -- EVENT CUTS -------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- // primary vertex: // - 2nd argument --> |Vz| range // - 3rd argument --> minimum required number of contributors // - 4th argument --> tells if TPC stand-alone vertexes must be accepted // we switch on the check for pileup AliRsnCutPrimaryVertex *cutVertex = new AliRsnCutPrimaryVertex("cutVertex", 10.0, 0, kFALSE); cutVertex->SetCheckPileUp(kTRUE); // primary vertex is always used AliRsnCutSet *eventCuts = new AliRsnCutSet("eventCuts", AliRsnTarget::kEvent); eventCuts->AddCut(cutVertex); eventCuts->SetCutScheme(cutVertex->GetName()); // add the event cuts to all loops loopQuality->SetEventCuts(eventCuts); loopPID ->SetEventCuts(eventCuts); loopPhi ->SetEventCuts(eventCuts); loopPhi ->SetEventCuts(eventCuts); loopPhiMix ->SetEventCuts(eventCuts); loopPhiMix ->SetEventCuts(eventCuts); loopPhiTrue->SetEventCuts(eventCuts); loopPhiTrue->SetEventCuts(eventCuts); // ---------------------------------------------------------------------------------------------- // -- PAIR CUTS --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- // for pairs we define a rapidity windows, defined through a cut // --> NOTE: it needs a support AliRsnPairDef from which it takes the mass AliRsnValueStd *valRapidity = new AliRsnValueStd("valY", AliRsnValueStd::kPairY); AliRsnCutValue *cutRapidity = new AliRsnCutValue("cutY", -0.5, 0.5, isMC); valRapidity->SetSupportObject(pairDef); cutRapidity->SetValueObj(valRapidity); // cut set AliRsnCutSet *pairCuts = new AliRsnCutSet("pairCuts", AliRsnTarget::kMother); pairCuts->AddCut(cutRapidity); pairCuts->SetCutScheme(cutRapidity->GetName()); // add cut to pair loops only loopPhi ->SetPairCuts(pairCuts); loopPhi ->SetPairCuts(pairCuts); loopPhiMix ->SetPairCuts(pairCuts); loopPhiMix ->SetPairCuts(pairCuts); loopPhiTrue->SetPairCuts(pairCuts); loopPhiTrue->SetPairCuts(pairCuts); // ---------------------------------------------------------------------------------------------- // -- COMPUTED VALUES & OUTPUTS ----------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- AliRsnValueStd *axisIM = new AliRsnValueStd("IM" , AliRsnValueStd::kPairInvMass , 0.9, 1.4, 0.001); AliRsnValueStd *axisPt = new AliRsnValueStd("PT" , AliRsnValueStd::kPairPt , 0.0, 5.0, 0.1 ); AliRsnValueStd *axisMomTPC = new AliRsnValueStd("pTPC", AliRsnValueStd::kTrackPtpc , 0.0, 5.0, 0.01 ); AliRsnValueStd *axisSigTPC = new AliRsnValueStd("sTPC", AliRsnValueStd::kTrackTPCsignal, 0.0, 500.0, 2.0 ); // output for monitors: // 2D histogram with TPC signal vs TPC momentum AliRsnListOutput *outMonitor = new AliRsnListOutput("mon", AliRsnListOutput::kHistoDefault); outMonitor->AddValue(axisMomTPC); outMonitor->AddValue(axisSigTPC); // output for pairs: // 2D histogram with inv.mass vs pt AliRsnListOutput *outPair = new AliRsnListOutput("pair", AliRsnListOutput::kHistoDefault); outPair->AddValue(axisIM); outPair->AddValue(axisPt); // add outputs to loops loopQuality->AddOutput(outMonitor); loopPID ->AddOutput(outMonitor); loopPhi ->AddOutput(outPair); loopPhiMix ->AddOutput(outPair); loopPhiTrue->AddOutput(outPair); // ---------------------------------------------------------------------------------------------- // -- CONCLUSION -------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- task->Add(loopQuality); task->Add(loopPID ); task->Add(loopPhi ); task->Add(loopPhiMix ); task->Add(loopPhiTrue); return kTRUE; }