ATLAS Offline Software
Loading...
Searching...
No Matches
InDetBeamSpotRooFit.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "GaudiKernel/ITHistSvc.h"
9#include <RooRealVar.h>
10#include <RooDataSet.h>
11#include <RooArgSet.h>
12
13using namespace RooFit;
14using namespace InDet;
15
17 const std::string& name,
18 const IInterface* parent):
19 AthAlgTool(type,name,parent),
20 m_cov(10), m_ax(0),m_ay(0),m_k(0),
21 m_mx(0),m_my(0),m_mz(0),m_rho(0),
22 m_sx(0),m_sy(0),m_sz(0),m_nUsed(0),
25{
26 declareInterface<IInDetBeamSpotTool>(this);
27 declareProperty("vtxResCut", m_vtxResCut = 0.05 );//m_vtxCut="abs(vxx) < .0025 && abs(vyy) < .0025 && abs(z) < 300 && abs(x)<3 && abs(y)<3");
28 declareProperty("InitialKFactor", m_kStart=1.0);
29 declareProperty("RMSCut", m_rmsCutNum = 16);
30 declareProperty("ConstantKFactor", m_kConst=false);
31}
32
33//Copy constructor: any variables that can be set with job options should be copied here
36 AthAlgTool(rhs.type(), rhs.name(), rhs.parent()),
37 m_cov(10), m_ax(0),m_ay(0),m_k(0),
38 m_mx(0),m_my(0),m_mz(0),m_rho(0),
39 m_sx(0),m_sy(0),m_sz(0),m_nUsed(0),
43 m_kStart(rhs.m_kStart),
46{}
47
49 ATH_MSG_DEBUG( "In initialize" );
50 return StatusCode::SUCCESS;
51}
52
54 ATH_MSG_DEBUG( "In finalize");
55 return StatusCode::SUCCESS;
56}
57
58InDetBeamSpotRooFit::FitStatus InDetBeamSpotRooFit::fit(std::vector< BeamSpot::VrtHolder > &vtxData){
59 m_vertexData = vtxData;
60
61 //This is to determine the min and max values of the data for setting up the RooDataSet
62 double xMin = m_vertexData[0].x ;
63 double xMax = xMin;
64 double yMin = m_vertexData[0].y ;
65 double yMax = yMin;
66 double zMin = m_vertexData[0].z;
67 double zMax = zMin;
68 double vxxMin=m_vertexData[0].vxx ;
69 double vxxMax=vxxMin;
70 double vyyMin=m_vertexData[0].vyy;
71 double vyyMax=vyyMin;
72 double vxyMin=m_vertexData[0].vxy;
73 double vxyMax=vxyMin;
74
75 for(Int_t i = 1;i < (Int_t)m_vertexData.size() ; i++){
76 if (m_vertexData[i].x < xMin) xMin = m_vertexData[i].x;
77 if (m_vertexData[i].x > xMax) xMax = m_vertexData[i].x;
78 if (m_vertexData[i].y < yMin) yMin = m_vertexData[i].y;
79 if (m_vertexData[i].y > yMax) yMax = m_vertexData[i].y;
80 if (m_vertexData[i].z < zMin) zMin = m_vertexData[i].z;
81 if (m_vertexData[i].z > zMax) zMax = m_vertexData[i].z;
82 if (m_vertexData[i].vxx < vxxMin) vxxMin = m_vertexData[i].vxx;
83 if (m_vertexData[i].vxx > vxxMax) vxxMax = m_vertexData[i].vxx;
84 if (m_vertexData[i].vyy < vyyMin) vyyMin = m_vertexData[i].vyy;
85 if (m_vertexData[i].vyy > vyyMax) vyyMax = m_vertexData[i].vyy;
86 if (m_vertexData[i].vxy < vxyMin) vxyMin = m_vertexData[i].vxy;
87 if (m_vertexData[i].vxy > vxyMax) vxyMax = m_vertexData[i].vxy;
88 }
89
90 //Declare the observables
91 RooRealVar x("x","Primary Vertex x [mm]",xMin,xMax);
92 RooRealVar y("y","Primary Vertex y [mm]",yMin,yMax);
93 RooRealVar z("z","Primary Vertex z [mm]",zMin,zMax);
94 RooRealVar vxx("vxx","vxx [mm^2]",vxxMin,vxxMax);
95 RooRealVar vyy("vyy","vyy [mm^2]",vyyMin,vyyMax);
96 RooRealVar vxy("vxy","vyy [mm^2]",vxyMin,vxyMax);
97
98
99 m_vtxCutString = "abs(x) < 3 && abs(y) < 3 && abs(z) < 300";
100 m_vtxCutString += " && abs(vxx) < "+std::to_string(m_vtxResCut*m_vtxResCut)+" && abs(vyy) < "+std::to_string(m_vtxResCut*m_vtxResCut)
101 + " && abs(vxy) < 1000.";
102 const char *vtxCut = (const char*)m_vtxCutString.c_str();
103
104 //Declare the RooDataSet and add data to it
105 RooDataSet rfData("rfData","RooFit data",RooArgSet(x,y,z,vxx,vyy,vxy));
106
108
109 for( unsigned int j = 0; j < m_vertexCount; j++){
110 x.setVal(m_vertexData[j].x);
111 y.setVal(m_vertexData[j].y);
112 z.setVal(m_vertexData[j].z);
113 vxx.setVal(m_vertexData[j].vxx);
114 vyy.setVal(m_vertexData[j].vyy);
115 vxy.setVal(m_vertexData[j].vxy);
116 rfData.add(RooArgSet(x,y,z,vxx,vyy,vxy));
117 }
118
119 // ROOT assumes the user takes ownership of the reduced dataset
120 // Therefore, wrap it into a unique pointer so that we don't leak it
121 auto reducedDSvtxCut = std::unique_ptr<RooAbsData>(rfData.reduce(Cut(vtxCut)));
122
123 Double_t vxxMean = reducedDSvtxCut->mean(vxx);
124 Double_t vyyMean = reducedDSvtxCut->mean(vyy);
125 Double_t axStart = 0, ayStart = 0, kStart = m_kStart;
126 Double_t wxxStart = reducedDSvtxCut->sigma(x);
127 Double_t wyyStart = reducedDSvtxCut->sigma(y);
128 Double_t sxStart = sqrt(std::abs(wxxStart*wxxStart - kStart*kStart*vxxMean));
129 Double_t syStart = sqrt(std::abs(wyyStart*wyyStart - kStart*kStart*vyyMean));
130 Double_t szStart = reducedDSvtxCut->sigma(z);
131 Double_t mxStart = reducedDSvtxCut->mean(x);
132 Double_t myStart = reducedDSvtxCut->mean(y);
133 Double_t mzStart = reducedDSvtxCut->mean(z);
134 Double_t rhoStart = 0;
135
136 RooRealVar ax("ax","Tilt x",axStart,-1,1);
137 RooRealVar ay("ay","Tilt y",ayStart,-1,1);
138 RooRealVar k("k","k factor",kStart,0,3);
139 if (m_kConst){ k.setConstant(kTRUE); }
140 RooRealVar mx("mx","Mean x",mxStart,xMin,xMax);
141 RooRealVar my("my","Mean y",myStart,yMin,yMax);
142 RooRealVar mz("mz","Mean z",mzStart,zMin,zMax);
143 RooRealVar rho("rho","x-y correlation",rhoStart,-1,1);
144 RooRealVar sx("sx","Width x",sxStart,0,1);
145 RooRealVar sy("sy","Width y",syStart,0,1);
146 RooRealVar sz("sz","Width z",szStart,1,200);
147
148
149 //Perform the fit and add results to member variables
150
151 BeamSpotPdf fitModel("fitModel","BeamSpot PDF",x,y,z,vxx,vyy,vxy,mx,sx,ax,my,sy,ay,mz,sz,k,rho);
152
153 //Apply the specified cut on position and vertex resolution
154 //RooDataSet *reducedData = (RooDataSet*)rfData.reduce( Cut(vtxCut) );
155 //We now need to combine the vtx resolution cut with the rms cut
156 //std::string combinedCutString = combineCuts(rfData);
157 //const char *combinedCut = (const char*)combinedCutString.c_str();
158
159 double rmsCutXLow = mxStart - m_rmsCutNum * wxxStart;
160 double rmsCutXHigh = mxStart + m_rmsCutNum * wxxStart;
161 double rmsCutYLow = myStart - m_rmsCutNum * wyyStart;
162 double rmsCutYHigh = myStart + m_rmsCutNum * wyyStart;
163 double rmsCutZLow = mzStart - m_rmsCutNum * szStart;
164 double rmsCutZHigh = mzStart + m_rmsCutNum * szStart;
165
166 std::ostringstream ss;
167 ss << "x > " << rmsCutXLow << " && "
168 << "x < " << rmsCutXHigh << " && "
169 << "y > " << rmsCutYLow << " && "
170 << "y < " << rmsCutYHigh << " && "
171 << "z > " << rmsCutZLow << " && "
172 << "z < " << rmsCutZHigh;
173 std::string rmsCutString = ss.str();
174
175 std::string combinedCutString = m_vtxCutString + std::string(" && ") + rmsCutString;
176 const char *combinedCut = (const char*)combinedCutString.c_str();
177
178 ATH_MSG_INFO( "combinedCut = "<<combinedCut );
179
180
181 //Convert these numbers to strings, then concatenate the strings
182 //rmsCutX = x > rmsCutLow && x < rmsCutXHigh;
183 //repeat for y and z
184
185
186 // ROOT assumes the user takes ownership of the reduced dataset
187 // Therefore, wrap it into a unique pointer so that we don't leak it
188 auto reducedDScombinedCut = std::unique_ptr<RooAbsData>(rfData.reduce(Cut(combinedCut)));
189
190 RooFitResult *r = fitModel.fitTo( *(reducedDScombinedCut.get()) ,ConditionalObservables(RooArgSet(vxx,vyy,vxy)),Save(),PrintLevel(-1),PrintEvalErrors(-1));
191
192 r->Print();
193 m_nUsed = reducedDScombinedCut->numEntries();
194
195 ATH_MSG_INFO( "A total of " << m_vertexCount << " vertices passed pre-selection. Of which "
196 << reducedDScombinedCut->numEntries()<<" vertices will be used in the ML fit.") ;
197
198
199 if ( r->edm() <= 10e-04 && r->covQual() == 3){
201 }
202 else m_fitStatus = failed;
203 m_ax = ax.getVal();
204 m_ay = ay.getVal();
205 m_k = k.getVal();
206 m_mx = mx.getVal();
207 m_my = my.getVal();
208 m_mz = mz.getVal();
209 m_rho = rho.getVal();
210 m_sx = sx.getVal();
211 m_sy = sy.getVal();
212 m_sz = sz.getVal();
213
214 if( m_kConst ){
215 m_cov.ResizeTo(9,9);
216 }
217 m_cov = r->covarianceMatrix();
218
219 return ( m_fitStatus );
220}
221
222
223std::map< std::string, double > InDetBeamSpotRooFit::getCovMap() const{
224 int numParams=0;
225 if (m_kConst){
226 numParams = 9;
227 }
228 else{
229 numParams = 10;
230 }
231
232 const std::string offDiagArr[] = {"TiltX","TiltY","k","X","Y","Z","RhoXY","Sx","Sy","Sz"};
233 const std::string diagArr[] = {"tiltX","tiltY","k","posX","posY","posZ","rhoXY","sigmaX","sigmaY","sigmaZ"};
234
235 const std::string offDiagArrConstK[] = {"TiltX","TiltY","X","Y","Z","RhoXY","Sx","Sy","Sz"};
236 const std::string diagArrConstK[] = {"tiltX","tiltY","posX","posY","posZ","rhoXY","sigmaX","sigmaY","sigmaZ"};
237
238 std::map< std::string, double > covMap;
239 std::vector< std::string > offDiagVector;
240 std::vector< std::string > diagVector;
241 std::string covString = "cov";
242 std::string errString = "Err";
243
244 std::string key;
245
246 for(int i = 0; i < numParams; i++){
247 if(m_kConst){
248 offDiagVector.push_back(offDiagArrConstK[i]);
249 diagVector.push_back(diagArrConstK[i]);
250 }
251 else{
252 offDiagVector.push_back(offDiagArr[i]);
253 diagVector.push_back(diagArr[i]);
254 }
255 }
256
257 for( unsigned int i = 0; i < offDiagVector.size(); i++){
258 for( unsigned int j = 0; j <= i; j++){
259 if( i == j ){
260 key = diagVector[i] + errString;
261 covMap[key] = sqrt(m_cov[i][j]);
262 }
263 else {
264 key = covString + offDiagVector[i] + offDiagVector[j];
265 covMap[key] = m_cov[i][j];
266 key = covString + offDiagVector[j] + offDiagVector[i];
267 covMap[key] = m_cov[i][j];
268 }
269
270 }
271 }
272
273 if( m_kConst ){
274 covMap["kErr"] = 0;
275 }
276
277 //We've filled the entire covariance matrix, but we only want to keep the top half, in the order:
278 //x,y,z,ax,ay,sx,sy,sz,rho,k
279 const std::string offDiagRemoveArr[] = {"k","RhoXY","Sz","Sy","Sx","TiltY","TiltX","Z","Y","X"};
280 const std::string offDiagRemoveArrConstK[] = {"RhoXY","Sz","Sy","Sx","TiltY","TiltX","Z","Y","X"};
281 std::vector< std::string > offDiagRemoveVector;
282 for (int i = 0; i < numParams; i++){
283 if( m_kConst ){
284 offDiagRemoveVector.push_back(offDiagRemoveArrConstK[i]);
285 }
286 else{
287 offDiagRemoveVector.push_back(offDiagRemoveArr[i]);
288 }
289 }
290 for( unsigned int i = 0; i < offDiagRemoveVector.size(); i++){
291 for( unsigned int j = i+1; j < offDiagRemoveVector.size(); j++){
292 covMap.erase(covString+offDiagRemoveVector[i]+offDiagRemoveVector[j]);
293 }
294 }
295
296 return covMap;
297}
298
299std::map<std::string,double> InDetBeamSpotRooFit::getParamMap() const{
300
301 std::map<std::string,double> paramMap;
302 paramMap["tiltX"] = m_ax;
303 paramMap["tiltY"] = m_ay;
304 paramMap["k"] = m_k;
305 paramMap["posX"] = m_mx;
306 paramMap["posY"] = m_my;
307 paramMap["posZ"] = m_mz;
308 paramMap["sigmaX"] = m_sx;
309 paramMap["sigmaY"] = m_sy;
310 paramMap["sigmaZ"] = m_sz;
311 paramMap["rhoXY"] = m_rho;
312 paramMap["nUsed"] = m_nUsed;
313
314 return paramMap;
315}
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
static Double_t sz
static Double_t ss
#define y
#define x
#define z
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Abstract class for all beamspot determination algorithms.
FitStatus
Internally used enum for fit status.
virtual std::map< std::string, double > getParamMap() const
virtual FitStatus fit(std::vector< BeamSpot::VrtHolder > &)
Attempt a to find a solution of the beamspot.
virtual StatusCode initialize()
Standard initialize.
std::vector< BeamSpot::VrtHolder > m_vertexData
virtual std::map< std::string, double > getCovMap() const
InDetBeamSpotRooFit(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode finalize()
Standard finalize.
int r
Definition globals.cxx:22
Primary Vertex Finder.