Grundlagen der fortgeschrittenen Teilchenphysik-Analyse

ETP-Wiki

https://wiki.physik.uni-muenchen.de/etp/index.php/Main_Page

Die typische Teilchenphysik-Analyse

Software Framework I

Software Framework II

Wo läuft Analyse-Software

Generelle Vorgehensweise von Datenanalyse I

Prinzipielle Idee der meisten Frameworks

Generelle Vorgehensweise von Datenanalyse II

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;
}

Datenformate: Zwei Ansätze

Um eine aufgenommene Teilchenkollision zu beschreiben werden bei ATLAS grob zwei Methoden verwendet

NTupels

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.ä.

Objekt-Orientierte Datenformate, speziell xAOD

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

Beispiele von xAOD Datentypen

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

ATLAS Software Umgebung

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.

CVMFS

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

ACM (asetup und CMake)

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

Kleine xAOD Analyse: Umgebung aufsetzen

# 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.

Erste Kompilierung

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

Intermezzo: Kate

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

Überblick über die Dateien

Daten lesen

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

Histogramme

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

Physik!

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);
    }

Aufgaben

Event-Typ: Daten oder Simulation

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
    }

Myon Kalibrierung

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

Fortgeschritten: SUSYTools

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