Prinzipielle Idee der meisten Frameworks
bool Analysis::initialize(){
...
std::cout << "Number of total events: " << n_events << std::endl;
...
return true;
}
bool Analysis::execute(){
...
my_histogram->Fill(muon_pt);
...
return true;
}
bool Analysis::finalize(){
...
my_histogram->Write();
...
return true;
}
Um eine aufgenommene Teilchenkollision zu beschreiben werden bei ATLAS grob zwei Methoden verwendet
Beispiel: Um N Myonen eines Events zu beschreiben sind muon_px, muon_py, muon_pz, muon_E Listen von je N doubles.
muon_py[3] // ist die Impulskomponente in y-Richtung des 4. Myons.
Werden generell bearbeitet mit TSelector-basierenden Frameworks o.ä.
muons // Liste von Myonen
muons->at(3) // 4. Myon
muons->at(3)->p4() // 4er Vektor des 4. Myons
muons->at(3)->p4().Py() // Impulskomponente in y-Richtung des 4. Myons
xAOD::MuonContainer *muons // Liste aller Myonen im Event
xAOD::Muon *mu = muon->at(0); // einzelnes Myon, gepickt aus der Liste
xAOD::ElectronContainer, xAOD::Electron, xAOD::JetContainer, xAOD::Jet, ...
xAOD::EventInfo // Metainformationen über das Event, ob Simulation oder Daten, Eventnummer, ...
Eine volle Liste aller Objekte in einem xAOD gibt checkxAOD.py (in der später aufgesetzten Umgebung)
checkxAOD.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/data17_13TeV/DAOD_HIGG3D1.12646063._000108.pool.root.1
Nach Eingabe von
source /project/etp3/ThomasMaier/Singularity/setup_slc6.sh # erzeugt 'slc6' Befehl
kann man mit folgendem Befehl in eine SL Umgebung wechseln
slc6
In dieser kann man dann die ATLAS Software Umgebung von CVMFS aufsetzen
source /project/etp/ThomasMaier/Scripts/setupATLAS.sh # erzeugt 'setupATLAS' Befehl
setupATLAS
Um sich das Leben einfacher zu machen kann man sich diese zwei Zeilen auch in "~/.bashrc" schreiben
source /project/etp3/ThomasMaier/Singularity/setup_slc6.sh
source /project/etp/ThomasMaier/Scripts/setupATLAS.sh
dann hat man slc6 und setupATLAS in jeder neuen Konsole zur Verfügung.
Netzwerk-Dateisystem, das unsere spezielle ATLAS-Software bereitstellt (ROOT, Athena, RootCore, ...)
Ausführen des Befehls auf der vorherigen Folie:
setupATLAS
Zeigt eine Übersicht zum Aufsetzen einzelner Pakete an.
Zum Beispiel um ROOT aufzusetzen
lsetup root
Aufsetzen einer bestimmten Version von AnalysisBase
acmSetup AnalysisBase,21.2.25
Umgebung wieder-aufsetzen (im "build" Verzeichnis, siehe nächste Seite)
acmSetup
Alles Kompilierte löschen, sauberer Neuanfang
acm clean
Lokale Pakete finden
acm find_packages
Kompilieren
acm compile
# Nach /tmp wechseln
cd /tmp
source /project/etp3/ThomasMaier/Singularity/setup_slc6.sh # Sofern nicht in "~/.bashrc"
# In SL Umgebung wechseln
slc6
source /project/etp/ThomasMaier/Scripts/setupATLAS.sh # Sofern nicht in "~/.bashrc"
# ATLAS Software von CVMFS aufsetzen
setupATLAS
cp -r /project/etp3/ThomasMaier/Bachelor2018/ROOTAnalysisTutorial . # Analyse Skelett herkopieren
cd ROOTAnalysisTutorial/build # In "ROOTAnalysisTutorial/build" Verzeichnis wechseln
acmSetup AnalysisBase,21.2.25 # AnalysisBase aufsetzen und CMake configuration ausführen
Wenn alles gut gegangen ist, sollte erscheinen:
ACM Setup complete. Use
acm help
to get started.
In der selben Konsole
acm compile
Erfolg wenn letzte Zeile lautet
[100%] Built target Package_MyAnalysis
Code ausführen mittels (in einem dediziertem "run" Verzeichnis)
cd ../run
runAnalysis.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/data17_13TeV/DAOD_HIGG3D1.12646063._000108.pool.root.1
Ergebnisse werden in submitDir gespeichert
ls submitDir
Dieses Verzeichnis wird bei jedem Ausführen von runAnalysis.py überschrieben. Sofern Ergebnisse behalten werden sollen müssen wir sie woanders hin tun:
mv submitDir results-data
In einer NEUEN Konsole (die SL Umgebung kennt kein kate)
cd /tmp/ROOTAnalysisTutorial/source # Verzeichnis betreten
kate MyAnalysis/Root/MyxAODAnalysis.cxx \
MyAnalysis/MyAnalysis/MyxAODAnalysis.h \
MyAnalysis/CMakeLists.txt \
MyAnalysis/share/runAnalysis.py
Wir werden uns hier auf Myonen beschränken, da diese ohne viel Aufwand eine saubere Signatur liefern
Für Myonen wird das Paket xAODMuon benötigt, d.h. wir müssen es in MyAnalysis/CMakeLists.txt nach LINK_LIBRARIES AnaAlgorithmLib hinzufügen:
LINK_LIBRARIES AnaAlgorithmLib xAODMuon
und in MyAnalysis/MyxAODAnalysis.cxx das folgende Include Statement am Anfang der Datei:
#include "xAODMuon/MuonContainer.h"
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: execute ():
const xAOD::MuonContainer* muons = 0;
evtStore()->retrieve( muons, "Muons" );
Info("execute", "Anzahl Myonen: %ld", muons->size());
for (const xAOD::Muon* muon: *muons) {
// Grössen wie Energie und Impuls werden konventionell in MeV gespeichert -> Umrechnung in GeV
Info("execute()", " Originaler Myon pt = %.3f GeV", (muon->pt() * 0.001));
}
Warnung: Info() Funktion erzeugt hierbei SEHR viel Output, nur für Testzwecke sinnvoll!
Nach jeder Änderung am Code ist es notwendig erneut zu kompilieren:
acm compile
runAnalysis.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/data17_13TeV/DAOD_HIGG3D1.12646063._000108.pool.root.1
# Abbrechen mit Strg+c
Eventloop übernimmt einen Grossteil des Output Managements, das einzige was zu tun ist ist am Anfang von MyxAODAnalysis.cxx den ROOT Histogram Header zu inkludieren:
#include <TH1F.h>
Wir können nun Gebrauch von der book und hist Funktion in Eventloop machen um Histogramme zu initialisieren und zu befüllen. Um z.B. ein Histogramm für den Myon Impuls zu erzeugen müssen wir book in initialize () aufrufen.
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: initialize ():
book(TH1F("h_muon_pt", "Transverser Myon Impuls", 100, 0, 100));
In der Schleife über die Myonen können wir nun das Histogramm befüllen, welches wir mit hist aufrufen mit dem Namen "h_muon_pt" den wir bei book vorher benutzt haben.
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: execute ():
for (const xAOD::Muon* muon: *muons) {
// Grössen wie Energie und Impuls werden konventionell in MeV gespeichert -> Umrechnung in GeV
Info("execute()", " Originaler Myon pt = %.3f GeV", (muon->pt() * 0.001));
// Histogram befüllen
hist("h_muon_pt")->Fill(muon->pt() * 0.001 );
}
Kompilieren und Code ausführen:
acm compile
runAnalysis.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/data17_13TeV/DAOD_HIGG3D1.12646063._000108.pool.root.1
Jetzt sollte das Histogramm in dem Output submitDir/hist-xAOD.root sein. Mit ROOT öffnen, und mit TBrowser ansehen:
rootbrowse submitDir/hist-xAOD.root
Interessante Messgrössen für Ereignisse mit Zwei Myonen sind unter Anderem die invariante Masse des Zwei-Myon-Systems und der Öffnungswinkel zwischen den Myonen.
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: execute ():
if (muons->size() == 2) { // falls wir genau 2 Myonen haben
const xAOD::Muon *mu1 = muons->at(0); // Numerierung fängt bei 0 an!
const xAOD::Muon *mu2 = muons->at(1);
TLorentzVector dimuon = mu1->p4() + mu2->p4();
double Mll = dimuon.M() *0.001; // umrechnen von MeV in GeV
Info("execute()", "Die Dimuon-Masse ist %.2f GeV", Mll);
double dphi = fabs(mu1->p4().DeltaPhi(mu2->p4()));
Info("execute()", "Der Öffnungswinkel ist %.2f Rad", dphi);
}
Wie sieht das mit simulierten Daten aus:
runAnalysis.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/mc16_13TeV_Zmumu/DAOD_HIGG3D1.12804983._001959.pool.root.1
Wie sieht es aus wenn wir ein paar mehr echte Daten-Ereignisse hinzu nehmen:
runAnalysis.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/data17_13TeV/*
Was passiert wenn man z.B. verlangt dass der Transversalimpuls der Myonen mindestens 15 GeV betragen muss:
if(mu1->pt() > 15000. && mu2->pt() > 15000.){
// Befülle Histogramme nur wenn Myonen Transversalimpuls mindestens 15 GeV beträgt ("h_mll" und "h_dphi" müssen vorher erzeugt werden)
hist("h_mll")->Fill(Mll);
hist("h_dphi")->Fill(dphi);
}
Für Fortgeschrittene die insbesondere an SUSY arbeiten: Myonen Selektion mittels SUSYTools (letzte Folie).
In MyAnalysis/CMakeLists.txt:
LINK_LIBRARIES AnaAlgorithmLib xAODMuon xAODEventInfo
In MyAnalysis/MyxAODAnalysis.cxx:
#include "xAODEventInfo/EventInfo.h"
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: execute () (am besten vor der Myonenschleife):
bool isMC = false; // wir nehmen an es ist keine Simulation
const xAOD::EventInfo* eventInfo = 0;
evtStore()->retrieve( eventInfo, "EventInfo"); // wir laden das EventInfo Objekt
if(eventInfo->eventType( xAOD::EventInfo::IS_SIMULATION ) ){
isMC = true; // falls es doch Simulation ist, setzen wir isMC auf wahr
}
In simulierten Daten müssen Myonen kalibriert werden, wofür wir das offizielle ATLAS Tool MuonCalibrationAndSmearingTool benutzen. Dazu benutzen wir die Pakete AsgAnalysisInterfaces und MuonAnalysisInterfacesLib.
In MyAnalysis/CMakeLists.txt:
LINK_LIBRARIES AnaAlgorithmLib xAODMuon xAODEventInfo AsgAnalysisInterfaces MuonAnalysisInterfacesLib
In MyAnalysis/MyxAODAnalysis.h:
#include <AsgTools/AnaToolHandle.h>
#include <MuonAnalysisInterfaces/IMuonCalibrationAndSmearingTool.h>
ToolHandle deklarieren in MyAnalysis/MyxAODAnalysis.h, unter public::
// MuonCalibrationAndSmearing
asg::AnaToolHandle<CP::IMuonCalibrationAndSmearingTool> m_muonCalibrationAndSmearingTool; //!
Hinweis: //! ist aus technischen Gründen notwendig!
Das Tool selber soll erst erzeugt werden wenn der Algorithmus erstellt wird. Also schreiben wir eine entsprechende Zeile in die Initializer Liste des Konstruktors in MyAnalysis/MyxAODAnalysis.cxx (am Anfang der Datei, unter den Include Statements). Dieser sollte hinterher so aussehen:
MyxAODAnalysis :: MyxAODAnalysis (const std::string& name, ISvcLocator *pSvcLocator) :
EL::AnaAlgorithm (name, pSvcLocator),
m_muonCalibrationAndSmearingTool ("CP::MuonCalibrationAndSmearingTool/MuonCorrectionTool",this)
{
// Here you put any code for the base initialization of variables,
// e.g. initialize all pointers to 0. Note that things like resetting
// statistics variables should rather go into the initialize() function.
}
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: initialize () (direkt unterhalb der Histogram Initialisierung):
m_muonCalibrationAndSmearingTool.initialize();
Wir brauchen eine veränderbare Kopie unserer Myonen ("Shallow Copy"). Danach laufen wir über die Myonen und wenden die Kalibrierung an, sofern es sich um MC Ereignisse handelt.
In MyAnalysis/MyxAODAnalysis.cxx:
#include <xAODCore/ShallowAuxContainer.h>
#include <xAODCore/ShallowCopy.h>
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: execute ():
// Eine "shallow copy" vom Myon Container erstellen
auto muons_shallowCopy = xAOD::shallowCopyContainer( *muons );
std::unique_ptr<xAOD::MuonContainer> muonsSC (muons_shallowCopy.first);
std::unique_ptr<xAOD::ShallowAuxContainer> muonsAuxSC (muons_shallowCopy.second);
// Über die Kopien iterieren
for (xAOD::Muon* muonSC : *muonsSC) {
if (isMC) {
// Kalibrierung anwenden
m_muonCalibrationAndSmearingTool->applyCorrection(*muonSC);
Info("execute()", " Korrigierter Myon pt = %.5f GeV", (muonSC->pt() * 0.001));
}
}
Kompilieren und ausführen:
acm compile
runAnalysis.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/mc16_13TeV_Zmumu/DAOD_HIGG3D1.12804983._001959.pool.root.1
SUSYTools übernimmt generelle Aufgaben, die jede Physik-/SUSY-Analyse in ATLAS ausführen muss, z.B. Kalibrierung und Selektion von Myonen. In "ROOTAnalysisTutorial" findet ihr eine Konfigurationsdatei ("SUSYTools_Config.conf") für SUSYTools. In dieser ist eine lange Liste an verschiedenen Selektions-Cuts und Definitionen für Objekte wie Myonen oder Elektronen.
Wir konzentrieren uns hier nur auf Myonen. In der Datei sind Einträge wie "MuonBaseline.Pt:" oder "MuonBase.Pt:", die die Cuts für den pt von "baseline" und "signal" Myonen definiert. "Baseline" Myonen sind solche die wir in der Analyse generell betrachten wollen (alle anderen verwerfen wir) und "signal" Myonen sind die, die wir insbesondere für unser potentielles SUSY(oder was man sich anschauen will) Signal berücksichtigen wollen. Im Folgenden werden wir SUSYTools benutzen um schon fertig kalibrierte und selektierte Myonen zu bekommen.
In MyAnalysis/CMakeLists.txt:
LINK_LIBRARIES AnaAlgorithmLib xAODMuon xAODEventInfo AsgAnalysisInterfaces MuonAnalysisInterfacesLib SUSYToolsLib
In MyAnalysis/MyxAODAnalysis.h:
#include "SUSYTools/SUSYObjDef_xAOD.h"
ToolHandle deklarieren in MyAnalysis/MyxAODAnalysis.h, unter public::
// SUSYTools
asg::AnaToolHandle<ST::SUSYObjDef_xAOD> m_objTool; //!
Hinweis: //! ist aus technischen Gründen notwendig!
Wie schon beim Myon Kalibrierungs Tool zuvor muss das SUSYTools Objekt Tool in der Initializer Liste des Algorithm Konstruktors erstellt werden:
MyxAODAnalysis :: MyxAODAnalysis (const std::string& name, ISvcLocator *pSvcLocator) :
EL::AnaAlgorithm (name, pSvcLocator),
m_muonCalibrationAndSmearingTool ("CP::MuonCalibrationAndSmearingTool/MuonCorrectionTool",this),
m_objTool ("ST::SUSYObjDef_xAOD/SusyTool", this)
{
// Here you put any code for the base initialization of variables,
// e.g. initialize all pointers to 0. Note that things like resetting
// statistics variables should rather go into the initialize() function.
}
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: initialize () (hier passiert sehr viel was im Moment nicht fürs Verständnis, aber trotzdem technisch notwendig ist):
m_objTool.setProperty("ConfigFile", "/tmp/ROOTAnalysisTutorial/SUSYTools_Config.conf");
// SUSYTools muss wissen ob wir über Daten oder MC laufen bevor wir es initialisieren
bool isData = false;
ST::ISUSYObjDef_xAODTool::DataSource datasource = (isData ? ST::ISUSYObjDef_xAODTool::Data : ST::ISUSYObjDef_xAODTool::FullSim);
m_objTool.setProperty("DataSource", datasource);
m_objTool.initialize();
Hinweis: SUSYTools muss schon im initialize Schritt wissen ob wir über simulierte Daten (isData=false) oder echte Daten (isData=true) laufen. In diesem Beispiel ist das hart in den C++ Code geschrieben, was nicht optimal ist. Im Idealfall ist sowas konfigurierbar wenn man den Code ausführen will.
In MyAnalysis/MyxAODAnalysis.cxx, Funktion StatusCode MyxAODAnalysis :: execute ():
// Fertig kalibrierte Myonen mit zusätzlichen tags ob baseline oder signal cuts erfüllt sind
xAOD::MuonContainer* muons_susy(0);
xAOD::ShallowAuxContainer* muons_susy_aux(0);
m_objTool->GetMuons(muons_susy, muons_susy_aux);
for (xAOD::Muon *muon: *muons_susy){
// Weiter springen wenn baseline cuts nicht erfüllt wurden
if (!muon->auxdata<char>("baseline")) continue;
Info("execute()", " Baseline Myon pt = %.5f GeV", (muon->pt() * 0.001));
// Weiter springen wenn signal cuts nicht erfüllt wurden
if (!muon->auxdata<char>("signal")) continue;
Info("execute()", " Signal Myon pt = %.5f GeV", (muon->pt() * 0.001));
}
Hinweis: Die Myonen die SUSYTools liefert sind markiert mit tags die sagen ob ein Myonen z.B. "baseline" oder "signal" ist. Wenn der jeweilige tag true ist, dann haben die Myonen die Selektion entsprechend der Konfiguration in "SUSYTools_Config.conf" erfüllt.
Kompilieren und ausführen:
acm compile
runAnalysis.py /project/etp3/ThomasMaier/Bachelor2018/xAOD/mc16_13TeV_Zmumu/DAOD_HIGG3D1.12804983._001959.pool.root.1