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

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/etp/fhoenig/Bachelor2017/xAOD/data16_13TeV/DAOD_HIGG3D1.10910335._000227.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

RootCore

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

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/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

Erste Kompilierung

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

Intermezzo: Kate

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

Ü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 "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

Histogramme

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

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:

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

Myon Kalibrierung

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

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 "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