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/etp/fhoenig/Bachelor2017/xAOD/data16_13TeV/DAOD_HIGG3D1.10910335._000227.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
rcSetup Base,2.4.30
Umgebung wieder-aufsetzen
source rcSetup.sh
Alles Kompilierte löschen, sauberer Neuanfang
rc clean
Verfügbare Pakete finden
rc find_packages
Kompilieren
rc 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/etp/fhoenig/Bachelor2017/ROOTAnalysisTutorial . # Analyse Skelett herkopieren
cd ROOTAnalysisTutorial # In Verzeichnis wechseln
source rcSetup.sh # RootCore aufsetzen
Wenn alles gut gegangen ist, sollte erscheinen:
In current directory, found previous release with config=x86_64-slc6-gcc49-opt at the following location, going to set up its env:
/cvmfs/atlas.cern.ch/repo/sw/ASG/AnalysisBase/2.4.30
Going to set up ROOT-6.04.16-x86_64-slc6-gcc49-opt from cvmfs
In der selben Konsole
rc find_packages
rc compile
Erfolg wenn letzte Zeile lautet
xAOD::Init INFO Environment initialised for data access
Code ausführen mittels
runAnalysis.py /project/etp/fhoenig/Bachelor2017/xAOD/data16_13TeV/DAOD_HIGG3D1.10910335._000227.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 # Verzeichnis betreten
kate MyAnalysis/Root/MyxAODAnalysis.cxx \
MyAnalysis/MyAnalysis/MyxAODAnalysis.h \
MyAnalysis/cmt/Makefile.RootCore \
MyAnalysis/scripts/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 "Makefile.RootCore" bei "PACKAGE_DEP" hinzufügen:
PACKAGE_DEP = EventLoop xAODRootAccess xAODMuon
und in "MyxAODAnalysis.h" das folgende Include Statement am Anfang der Datei:
#include "xAODMuon/MuonContainer.h"
In der MyAnalysis.cxx execute Funktion:
EL::StatusCode MyxAODAnalysis :: execute ()
{
...
const xAOD::MuonContainer* muons = 0;
event->retrieve( muons, "Muons" );
Info("execute", "Anzahl Myonen: %d", 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));
}
...
return EL::StatusCode::SUCCESS;
}
Warnung: Info() Funktion erzeugt hierbei SEHR viel Output, nur für Testzwecke sinnvoll!
Nach jeder Änderung am Code ist es notwendig erneut zu kompilieren. Ausserdem muss "rc find_packages" ausgeführt werden sofern an "Makefile.RootCore" etwas geändert wurde:
rc find_packages
rc compile
runAnalysis.py /project/etp/fhoenig/Bachelor2017/xAOD/data16_13TeV/DAOD_HIGG3D1.10910335._000227.pool.root.1
Eventloop übernimmt einen Grossteil des Output Managements, das einzige was zu tun ist ist am Anfang von "MyxAODAnalysis.h" den ROOT Histogram Header zu inkludieren:
#include <TH1F.h>
und um z.B. ein Histogramm für den Myon Impuls zu erzeugen müssen wir in "MyxAODAnalysis.h" einen Pointer unter "public:" deklarieren:
TH1 *h_muon_pt; //!
Hinweis: //! ist aus technischen Gründen notwendig!
"MyxAODAnalysis.cxx" hat eine dedizierte Funktion zum initialisieren von Histogrammen, "histInitialize()". In dieser erzeugen wir ein neues Histogramm (, lassen den Pointer darauf zeigen) und sagen Eventloop dass wir das Histogramm dem Output hinzufügen mochten:
EL::StatusCode MyxAODAnalysis :: histInitialize ()
{
...
h_muon_pt = new TH1F("h_muon_pt", "Transverser Myon Impuls", 100, 0, 100);
wk()->addOutput (h_muon_pt);
...
return EL::StatusCode::SUCCESS;
}
In der Schleife über die Myonen das Histogramm füllen
for (xAOD::Muon *muon: *muons){
...
h_muon_pt->Fill(muon->pt() * 0.001 );
...
}
Kompilieren und Code ausführen:
rc compile
runAnalysis.py /project/etp/fhoenig/Bachelor2017/xAOD/data16_13TeV/DAOD_HIGG3D1.10910335._000227.pool.root.1
Jetzt sollte das Histogramm in dem Output "submitDir/hist-xAOD.root" sein. Mit ROOT öffnen, und mit TBrowser ansehen:
root submitDir/hist-xAOD.root
TBrowser b
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:
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/etp/fhoenig/Bachelor2017/xAOD/mc15_13TeV_Zmumu/DAOD_HIGG3D1.11074620._000011.pool.root.1
Wie sieht es aus wenn wir ein paar mehr echte Daten-Ereignisse hinzu nehmen:
runAnalysis.py /project/etp/fhoenig/Bachelor2017/xAOD/data16_13TeV/*
Was passiert wenn man z.B. verlangt dass der Transversalimpuls der Myonen mindestens 15 GeV betragen muss:
EL::StatusCode MyxAODAnalysis :: execute ()
{
...
if (muons->size() == 2) { // falls wir genau 2 Myonen haben
...
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)
h_mll->Fill(Mll);
h_dphi->Fill(dphi);
}
...
}
...
return EL::StatusCode::SUCCESS;
}
Für Fortgeschrittene die insbesondere an SUSY arbeiten: Myonen Selektion mittels SUSYTools (letzte Folie).
In "Makefile.RootCore":
PACKAGE_DEP = EventLoop xAODRootAccess xAODMuon xAODEventInfo
In "MyxAODAnalysis.h":
#include "xAODEventInfo/EventInfo.h"
In "MyxAODAnalysis.cxx", execute (am besten vor der Myonenschleife):
EL::StatusCode MyxAODAnalysis :: execute ()
{
...
bool isMC = false; // wir nehmen an es ist keine Simulation
const xAOD::EventInfo* eventInfo = 0;
event->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
}
...
return EL::StatusCode::SUCCESS;
}
In simulierten Daten müssen Myonen kalibriert werden, wofür wir das offizielle ATLAS Tool "MuonMomentumCorrections" benutzen.
In "Makefile.RootCore":
PACKAGE_DEP = EventLoop xAODRootAccess xAODMuon xAODEventInfo MuonMomentumCorrections
In "MyxAODAnalysis.h":
#include "MuonMomentumCorrections/MuonCalibrationAndSmearingTool.h"
#include "PATInterfaces/CorrectionCode.h"
#include "xAODCore/ShallowAuxContainer.h"
#include "xAODCore/ShallowCopy.h"
Tool deklarieren in "MyxAODAnalysis.h", unter "public:":
CP::MuonCalibrationAndSmearingTool *m_muonCalibrationAndSmearingTool; //!
Hinweis: //! ist aus technischen Gründen notwendig!
In "MyxAODAnalysis.cxx", initialize:
EL::StatusCode MyxAODAnalysis :: initialize ()
{
...
m_muonCalibrationAndSmearingTool = new CP::MuonCalibrationAndSmearingTool( "MuonCorrectionTool" );
m_muonCalibrationAndSmearingTool->initialize();
...
return EL::StatusCode::SUCCESS;
}
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 "MyxAODAnalysis.cxx", execute:
EL::StatusCode MyxAODAnalysis :: execute ()
{
...
std::pair< xAOD::MuonContainer*, xAOD::ShallowAuxContainer* > muons_shallowCopy = xAOD::shallowCopyContainer( *muons );
xAOD::MuonContainer *muons_copy = muons_shallowCopy.first;
for (xAOD::Muon *muon: *muons_copy){
Info("execute()", " Myon pt = %.5f GeV", (muon->pt() * 0.001));
if (isMC) {
m_muonCalibrationAndSmearingTool->applyCorrection(*muon);
Info("execute()", " Korrigierter Myon pt = %.5f GeV", (muon->pt() * 0.001));
}
}
// Kopien wieder aufräumen. Erst machen wenn wir sie nicht mehr brauchen!!!!
delete muons_shallowCopy.first;
delete muons_shallowCopy.second;
...
return EL::StatusCode::SUCCESS;
}
Kompilieren und ausführen:
rc find_packages
rc compile
runAnalysis.py /project/etp/fhoenig/Bachelor2017/xAOD/mc15_13TeV_Zmumu/DAOD_HIGG3D1.11074620._000011.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 "Makefile.RootCore":
PACKAGE_DEP = EventLoop xAODRootAccess xAODMuon xAODEventInfo MuonMomentumCorrections SUSYTools
In "MyxAODAnalysis.h":
#include "SUSYTools/SUSYObjDef_xAOD.h"
Tool deklarieren in "MyxAODAnalysis.h", unter "public:":
ST::SUSYObjDef_xAOD *m_objTool; //!
Hinweis: //! ist aus technischen Gründen notwendig!
In "MyxAODAnalysis.cxx", initialize. Hier passiert sehr viel was im Moment nicht fürs Verständnis (aber trotzdem technisch) notwendig ist:
EL::StatusCode MyxAODAnalysis :: initialize ()
{
...
m_objTool = new ST::SUSYObjDef_xAOD("SUSYObjDef_xAOD");
m_objTool->setProperty("ConfigFile", "SUSYTools_Config.conf");
std::vector<std::string> prw_conf;
prw_conf.push_back("dev/PileupReweighting/mc15c_v2_defaults.NotRecommended.prw.root");
m_objTool->setProperty("PRWConfigFiles", prw_conf);
std::vector<std::string> prw_lumicalc;
prw_lumicalc.push_back("GoodRunsLists/data16_13TeV/20160720/physics_25ns_20.7.lumicalc.OflLumi-13TeV-005.root");
m_objTool->setProperty("PRWLumiCalcFiles", prw_lumicalc);
// 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();
...
return EL::StatusCode::SUCCESS;
}
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 "MyxAODAnalysis.cxx", execute:
EL::StatusCode MyxAODAnalysis :: execute ()
{
...
// Technische Notwendigkeit
m_objTool->ApplyPRWTool();
// 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));
}
...
return EL::StatusCode::SUCCESS;
}
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:
rc find_packages
rc compile
runAnalysis.py /project/etp/fhoenig/Bachelor2017/xAOD/mc15_13TeV_Zmumu/DAOD_HIGG3D1.11074620._000011.pool.root.1