Obtaining the Muon Position at the Spectrometer in the SingleTopDPDMaker
Introduction
This will show you how to implement the MuonPositionAtSpectrometerTool in the SingleTopDPDMaker. There has been a long discussion in mid-May 2009 on which muon eta to use (see hypernews). For the summer notes it was agreed to stick to the physics muon eta, obtained via Muon->eta(), but it was foreseen to use the spectrometer eta in the future. Here an excerpt from a mail by Ketevi Assamagan:
muon->eta() returns the eta of the primary track associated to the muon. In order of precedence, the primary track associated to a muon is:
- the combined track if it exists.
- the track extrapolated to the beam perigee if there is no combined track.
- the extended track - extrapolated from the vertex into the Muon Spectrometer (MS) if the first 2 are not present.
- the Inner Detector if none of the above is present.
Note also that muon->muonSpectrometerTrackParticle()->eta() does not return any detector eta - it is not clear what is meant by detector eta in this context. Rather, in this case, the track parameters are expressed at the "entrance" to the MS. One should think of the MS track and the track mentioned in (2) as the same track, with track parameters expressed at 2 different places.
On 30th September, 2009 a tool to calculate the correct track eta has been released:
A new general tool is now available to access the value of Theta/Eta of a muon at the Muon Spectrometer, rather than at the primary vertex. This is mainly suited for acceptance studies and fiducial cuts at the analysis level.
Main features:
- takes an Analysis::Muon object from AOD, ESD or DPD as an input
- works for any kind of muon (author) and for any of the (2) AOD containers
- returns the 3-D position of the FIRST hit associated with the Muon in the Muon Spectrometer
- it also returns directly the Theta of the first MS hit (better than Eta for probing of the acceptance, especially in the EC)
Implementation guide
A general (AnalysisSkeleton) example by Guiseppe Salaman can be found here: /afs/cern.ch/user/s/salaman/public/MSPosToolUse
Here it is shown for the SingleTopDPDMaker:
First you should check out the package, either head version or this tag:
cmt co -r MuonUtils-00-07-35 PhysicsAnalysis/MuonID/MuonUtils
Now back to the SingleTopDPDMaker: Add one line to the requirements file:
use MuonUtils MuonUtils-* PhysicsAnalysis/MuonID
In exeSingleTopDPDMaker.py you have to add (e.g. after Trigger Initialization):
# MuonPositionAtSpectrometerTool from MuonUtils.MuonUtilsConf import MuonPositionAtSpectrometerTool ToolSvc += MuonPositionAtSpectrometerTool('MuonPositionAtSpectrometerTool',OutputLevel = ERROR )
In TreeMaker.cxx, adjust this line:
TreeMaker::TreeMaker(const std::string& name, ISvcLocator* pSvcLocator) : Algorithm(name, pSvcLocator), aMuonAtMSPosTool("MuonPositionAtSpectrometerTool")
In TreeMaker.h, add these lines at the top:
#include "GaudiKernel/ToolHandle.h" #include "MuonUtils/MuonPositionAtSpectrometerTool.h"
and at the bottom in the private section add:
/** get a handle on the user tool to return a muon's position at MS */ ToolHandle<MuonPositionAtSpectrometerTool> aMuonAtMSPosTool;
In MuonTree.cxx add in void TreeMaker::SetMuons():
Muon_MS_eta[Label] = new std::vector<double>; Muon_MS_theta[Label] = new std::vector<double>; Muon_MS_thetaRes[Label] = new std::vector<double>; Muon_MS_posx[Label] = new std::vector<double>; Muon_MS_posy[Label] = new std::vector<double>; Muon_MS_posz[Label] = new std::vector<double>; std::string MS_eta = Label+"_"+"MS_eta"; std::string MS_theta = Label+"_"+"MS_theta"; std::string MS_thetaRes = Label+"_"+"MS_thetaRes"; std::string MS_posx = Label+"_"+"MS_posx"; std::string MS_posy = Label+"_"+"MS_posy"; std::string MS_posz = Label+"_"+"MS_posz"; aTree->Branch(MS_eta.c_str(), &Muon_MS_eta[Label]); aTree->Branch(MS_theta.c_str(), &Muon_MS_theta[Label]); aTree->Branch(MS_thetaRes.c_str(), &Muon_MS_thetaRes[Label]); aTree->Branch(MS_posx.c_str(), &Muon_MS_posx[Label]); aTree->Branch(MS_posy.c_str(), &Muon_MS_posy[Label]); aTree->Branch(MS_posz.c_str(), &Muon_MS_posz[Label]);
in void TreeMaker::DeleteMuons() add:
delete Muon_MS_eta[Label]; delete Muon_MS_theta[Label]; delete Muon_MS_thetaRes[Label]; delete Muon_MS_posx[Label]; delete Muon_MS_posy[Label]; delete Muon_MS_posz[Label];
in void TreeMaker::ClearMuons() add:
Muon_MS_eta[Label]->clear(); Muon_MS_theta[Label]->clear(); Muon_MS_thetaRes[Label]->clear(); Muon_MS_posx[Label]->clear(); Muon_MS_posy[Label]->clear(); Muon_MS_posz[Label]->clear();
and in void TreeMaker::FillMuons() add:
/** position at MS */ const HepPoint3D thePos = aMuonAtMSPosTool->evaluatePositionAtMS(*aMuon); double theEta = thePos.pseudoRapidity(); double thePosX = thePos.x(); double thePosY = thePos.y(); double thePosZ = thePos.z(); double theMSTheta = aMuonAtMSPosTool->evaluateThetaAtMS(thePos); double theMaxResidual = aMuonAtMSPosTool->evaluateMaxThetaResidual(*aMuon); Muon_MS_eta->push_back(theEta); Muon_MS_theta->push_back(theMSTheta); Muon_MS_thetaRes->push_back(theMaxResidual); Muon_MS_posx->push_back(thePosX); Muon_MS_posy->push_back(thePosY); Muon_MS_posz->push_back(thePosZ);
In MuonTree.h add:
std::map<std::string, std::vector<double>* > Muon_MS_eta; std::map<std::string, std::vector<double>* > Muon_MS_theta; std::map<std::string, std::vector<double>* > Muon_MS_thetaRes; std::map<std::string, std::vector<double>* > Muon_MS_posx; std::map<std::string, std::vector<double>* > Muon_MS_posy; std::map<std::string, std::vector<double>* > Muon_MS_posz;
CategorySingleTopDPDMaker