ATLAS Offline Software
Loading...
Searching...
No Matches
TrkDriftCircleMath::MdtSegmentT0Fitter Class Reference

#include <MdtSegmentT0Fitter.h>

Inheritance diagram for TrkDriftCircleMath::MdtSegmentT0Fitter:
Collaboration diagram for TrkDriftCircleMath::MdtSegmentT0Fitter:

Public Member Functions

 MdtSegmentT0Fitter (const std::string &, const std::string &, const IInterface *)
virtual ~MdtSegmentT0Fitter ()=default
virtual StatusCode initialize () override
virtual StatusCode finalize () override
virtual bool fit (Segment &result, const Line &line, const DCOnTrackVec &dcs, double t0Seed) const override
virtual bool fit (Segment &result, const Line &line, const DCOnTrackVec &dcs, const HitSelection &selection, double t0Seed) const override
virtual const DCSLFittergetFitter () const override
 fitter factory
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Static Public Member Functions

static const InterfaceID & interfaceID ()

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Private Attributes

SG::ReadCondHandleKey< MuonCalib::MdtCalibDataContainerm_calibDbKey
ServiceHandle< Muon::IMuonIdHelperSvcm_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
Gaudi::Property< bool > m_rejectWeakTopologies {this,"RejectWeakTopologies",true,"reject topolgies that do not have at least one +- combination in one multilayer"}
Gaudi::Property< bool > m_scaleErrors {this,"RescaleErrors",true,"rescale errors in fit"}
Gaudi::Property< bool > m_propagateErrors {this,"PropagateErrors",true,"propagate errors"}
Gaudi::Property< int > m_minHits {this,"MinimumHits",4,"minimum number of selected hits for t0 fit. Otherwise use default"}
Gaudi::Property< float > m_dRTol {this,"dRTolerance",0.1}
Gaudi::Property< bool > m_floatDir
std::atomic_uint m_ntotalCalls {0}
std::atomic_uint m_npassedNHits {0}
std::atomic_uint m_npassedSelectionConsistency {0}
std::atomic_uint m_npassedNSelectedHits {0}
std::atomic_uint m_npassedMinHits {0}
std::atomic_uint m_npassedMinuitFit {0}
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default).
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default).
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

Definition at line 25 of file MdtSegmentT0Fitter.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ MdtSegmentT0Fitter()

TrkDriftCircleMath::MdtSegmentT0Fitter::MdtSegmentT0Fitter ( const std::string & ty,
const std::string & na,
const IInterface * pa )

Definition at line 170 of file MdtSegmentT0Fitter.cxx.

171 : AthAlgTool(ty,na,pa),
172 DCSLFitter() {
173 declareInterface <IDCSLFitProvider> (this);
174 }
AthAlgTool()
Default constructor:

◆ ~MdtSegmentT0Fitter()

virtual TrkDriftCircleMath::MdtSegmentT0Fitter::~MdtSegmentT0Fitter ( )
virtualdefault

Member Function Documentation

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ finalize()

StatusCode TrkDriftCircleMath::MdtSegmentT0Fitter::finalize ( )
overridevirtual

Definition at line 181 of file MdtSegmentT0Fitter.cxx.

181 {
182
183 double scaleFactor = m_ntotalCalls != 0 ? 1./(double)m_ntotalCalls : 1.;
184
185 ATH_MSG_INFO( "Summarizing fitter statistics " << "\n"
186 << " Total fits " << std::setw(10) << m_ntotalCalls << " " << scaleFactor*m_ntotalCalls << "\n"
187 << " hits > 2 " << std::setw(10) << m_npassedNHits << " " << scaleFactor*m_npassedNHits << "\n"
188 << " hit consis. " << std::setw(10) << m_npassedSelectionConsistency << " " << scaleFactor*m_npassedSelectionConsistency << "\n"
189 << " sel. hits > 2 " << std::setw(10) << m_npassedNSelectedHits << " " << scaleFactor*m_npassedNSelectedHits << "\n"
190 << " Hits > min hits " << std::setw(10) << m_npassedMinHits << " " << scaleFactor*m_npassedMinHits << "\n"
191 << " Passed Fit " << std::setw(10) << m_npassedMinuitFit << " " << scaleFactor*m_npassedMinuitFit );
192 return StatusCode::SUCCESS;
193 }
#define ATH_MSG_INFO(x)

◆ fit() [1/2]

bool TrkDriftCircleMath::MdtSegmentT0Fitter::fit ( Segment & result,
const Line & line,
const DCOnTrackVec & dcs,
const HitSelection & selection,
double t0Seed ) const
overridevirtual

Normalize the mean positions

go to coordinates centered at the average of the hits

Reimplemented from TrkDriftCircleMath::DCSLFitter.

Definition at line 195 of file MdtSegmentT0Fitter.cxx.

195 {
197 const MdtIdHelper& id_helper{m_idHelperSvc->mdtIdHelper()};
198 ATH_MSG_DEBUG("New seg: ");
199 const EventContext& ctx{Gaudi::Hive::currentContext()};
200 SG::ReadCondHandle<MuonCalib::MdtCalibDataContainer> calibData{m_calibDbKey, ctx};
201 if (!calibData.isValid()) {
202 ATH_MSG_FATAL("Failed to retrieve Mdt calibration object "<<m_calibDbKey.fullKey());
203 return false;
204 }
205 std::array<const MuonCalib::MdtRtRelation*, 2> rtRelations{};
206 {
207 unsigned int nRel{0};
208 for (unsigned int i = 0; i < dcs.size() ; ++i) {
209 const Identifier id = dcs[i].rot()->identify();
210 const int mlIdx = id_helper.multilayer(id) -1;
211 if (rtRelations[mlIdx]) continue;
212 rtRelations[mlIdx] = calibData->getCalibData(id, msgStream())->rtRelation.get();
213 ++nRel;
214 if (nRel == 2) break;
215 }
216 }
217 const DCOnTrackVec& dcs_keep = dcs;
218
219 unsigned int N = dcs_keep.size();
220
221 result.setT0Shift(-99999,-99999);
222
223 if(N<2) {
224 return false;
225 }
227 if( selection.size() != N ) {
228 ATH_MSG_ERROR("MdtSegmentT0Fitter.cxx:fit with t0 <bad HitSelection>");
229 return false;
230 }
232 int used=0;
233 for(unsigned int i=0;i<N;++i){
234 if( selection[i] == 0 ) ++used;
235 }
236 if(used < 2){
237 ATH_MSG_DEBUG("TOO FEW HITS SELECTED");
238 return false;
239 }
241
242 if(used < m_minHits) {
243 ATH_MSG_DEBUG("FEWER THAN Minimum HITS N " << m_minHits << " total hits " <<N<<" used " << used);
244
245 //
246 // Copy driftcircles and reset the drift radii as they might have been overwritten
247 // after a succesfull t0 fit
248 //
249
250 DCOnTrackVec dcs_new;
251 dcs_new.reserve(dcs.size());
252
253 double chi2p = 0.;
254 int n_elements = dcs.size();
255 for(int i=0; i< n_elements; ++i ){
256 const DriftCircle* ds = & dcs[i];
257 if(std::abs(ds->r()-ds->rot()->driftRadius())>m_dRTol) ATH_MSG_DEBUG("Different radii on dc " << ds->r() << " rot " << ds->rot()->driftRadius());
258
259 DriftCircle dc_keep(ds->position(), ds->rot()->driftRadius(), ds->dr(), ds->drPrecise(), ds->driftState(), ds->id(), ds->rot(), ds->index());
260 DCOnTrack dc_new(dc_keep, 0., 0.);
261
262 dc_new.state(dcs[i].state());
263 dcs_new.push_back( dc_new );
264 if( selection[i] == 0 ){
265 double t = ds->rot()->driftTime();
266 const unsigned int mlIdx = id_helper.multilayer(ds->rot()->identify()) - 1;
267 const MuonCalib::MdtRtRelation *rtInfo = rtRelations[mlIdx];
268
269 double tUp = rtInfo->rt()->tUpper();
270 double tLow = rtInfo->rt()->tLower();
271
272 if(t<tLow) chi2p += sq(t-tLow)*0.1;
273 else if(t>tUp) chi2p += sq(t-tUp)*0.1;
274 }
275 }
276
277 if(chi2p>0) ATH_MSG_DEBUG("NO Minuit Fit TOO few hits Chi2 penalty " << chi2p);
278
279 bool oldrefit = DCSLFitter::fit( result, line, dcs_new, selection );
280
281 chi2p += result.chi2();
282 // add chi2 penalty for too large or too small driftTimes t < 0 or t> t upper
283 result.set(chi2p, result.ndof(), result.dtheta(), result.dy0());
284 int iok = 0;
285 if(oldrefit) iok = 1;
286 ATH_MSG_DEBUG(" chi2 total " << result.chi2() << " angle " << result.line().phi() << " y0 " << result.line().y0() << " nhits "<< selection.size() << " refit ok " << iok);
287 return oldrefit;
288
289 }
290
291 ATH_MSG_DEBUG("FITTING FOR T0 N "<<N<<" used " << used);
292
293
295
296
297 ATH_MSG_DEBUG(" in MdtSegmentT0Fitter::fit with N dcs "<< N << " hit selection size " << selection.size());
298 ATH_MSG_DEBUG("in fit "<<result.hasT0Shift()<< " " <<result.t0Shift());
299
300
301 double Zc{0.}, Yc{0.}, S{0.}, Sz{0.}, Sy{0};
302
303 std::vector<HitCoords> hits{};
304 hits.reserve(N);
305 FunctionToMinimize minFunct(used);
306
307 {
308 unsigned int ii{0};
309 for(const DCOnTrack& keep_me : dcs_keep ){
310 const Muon::MdtDriftCircleOnTrack *roto = keep_me.rot();
311 const unsigned int mlIdx = id_helper.multilayer(roto->identify()) - 1;
312 const MuonCalib::MdtRtRelation *rtInfo = rtRelations[mlIdx];
313
314 const double newerror = m_scaleErrors ? keep_me.drPrecise() : keep_me.dr();
315 const double w = newerror >0. ? sq(1./newerror) : 0.;
316 hits.emplace_back(keep_me.x(), roto->driftTime(), keep_me.y(), w, std::abs(roto->driftRadius()), rtInfo->rt());
317 HitCoords& coords = hits.back();
318 coords.dr = keep_me.dr();
319 coords.rejected = selection[ii];
320 ATH_MSG_DEBUG("DC: (" << coords.y << "," << coords.z << ") R = " << coords.r << " W " << coords.w
321 <<" t " <<coords.t<< " id: "<<keep_me.id()<<" sel " <<coords.rejected);
322 if (!coords.rejected) {
323 S += coords.w;
324 Sz+= coords.z* coords.w;
325 Sy+= coords.y * coords.w;
326 }
327 ++ii;
328 }
329 }
330
332 const double inv_S = 1. / S;
333 Zc = Sz*inv_S;
334 Yc = Sy*inv_S;
335
336 ATH_MSG_DEBUG("Yc " << Yc << " Zc " << Zc);
337
339 for(HitCoords& coords : hits) {
340 coords.y -= Yc;
341 coords.z -= Zc;
342 }
343
344 int selcount{0};
345
346 // replicate for the case where the external rt is used...
347 // each hit has an rt function with some range...we want to fit such that
348 // tlower_i < ti - t0 < tupper_i
349 double min_tlower{std::numeric_limits<float>::max()}, max_tupper{-std::numeric_limits<float>::max()};
350
351 double t0seed=0; // the average t0 of the hit
352 double st0 = 0; // the std deviation of the hit t0s
353 double min_t0 = 1e10; // the smallest t0 seen
354
355 for(HitCoords& coords : hits) {
356 if(coords.rejected) continue;
357
358 double r2tval = r2t_ext(coords.rt, coords.r) ;
359 const double tl = coords.rt->tLower();
360 const double th = coords.rt->tUpper();
361 const double tee0 = coords.t - r2tval;
362
363 min_tlower = std::min(min_tlower, coords.t - tl);
364 max_tupper = std::max(max_tupper, coords.t - th);
365
366
367 ATH_MSG_DEBUG(" z "<<coords.z <<" y "<<coords.y<<" r "<<coords.r
368 <<" t "<<coords.t<<" t0 "<<tee0<<" tLower "<<tl<<" tUpper "<<th);
369 t0seed += tee0;
370 st0 += sq(tee0);
371 if(tee0 < min_t0 && std::abs(r2tval) < R2TSPURIOUS) min_t0 = tee0;
372
373 minFunct.addCoords(coords);
374
375 selcount++;
376
377 }
378 t0seed /= selcount;
379 st0 = st0/selcount - t0seed*t0seed;
380 st0 = st0 > 0. ? std::sqrt(st0) : 0.;
381
382 ATH_MSG_DEBUG(" t0seed "<<t0seed<<" sigma "<<st0<< " min_t0 "<<min_t0);
383
384 // ************************* seed the parameters
385 const double theta = line.phi();
386 double cosin = std::cos(theta);
387 double sinus = std::sin(theta);
388
389 if ( sinus < 0.0 ) {
390 sinus = -sinus;
391 cosin = -cosin;
392 } else if ( sinus == 0.0 && cosin < 0.0 ) {
393 cosin = -cosin;
394 }
395
396 ATH_MSG_DEBUG("before fit theta "<<theta<<" sinus "<<sinus<< " cosin "<< cosin);
397
398 double d = line.y0() + Zc*sinus-Yc*cosin;
399
400
401 ATH_MSG_DEBUG(" line x y "<<line.position().x()<<" "<<line.position().y());
402 ATH_MSG_DEBUG(" Zc Yc "<< Zc <<" "<<Yc);
403 ATH_MSG_DEBUG(" line x0 y0 "<<line.x0()<<" "<<line.y0());
404 ATH_MSG_DEBUG(" hit shift " << -Zc*sinus+Yc*cosin);
405
406// Calculate signed radii
407
408 int nml1p{0}, nml2p{0}, nml1n{0}, nml2n{0};
409 int ii{-1};
410 for(const DCOnTrack& keep_me : dcs_keep){
411 ++ii;
412 const HitCoords& coords = hits[ii];
413 if(coords.rejected) continue;
414 const double sdist = d*cosin + coords.z*sinus - coords.y*cosin; // same thing as |a*z - y + b|/sqrt(1. + a*a);
415 nml1p+=(keep_me.id().ml()==0&&sdist > 0);
416 nml1n+=(keep_me.id().ml()==0&&sdist < 0);
417 nml2p+=(keep_me.id().ml()==1&&sdist > 0);
418 nml2n+=(keep_me.id().ml()==1&&sdist < 0);
419 }
420
421// Define t0 constraint in Minuit
422 int t0Error = STRONG_TOPO_T0ERROR;
423 if (nml1p+nml2p < 2 || nml1n+nml2n < 2) t0Error = WEAK_TOPO_T0ERROR;
424
425 minFunct.setT0Error(t0Error);
426
427// Reject topologies where in one of the Multilayers no +- combination is present
428 if((nml1p<1||nml1n<1)&&(nml2p<1||nml2n<1)&&m_rejectWeakTopologies) {
429 ATH_MSG_DEBUG("Combination rejected for positive radii ML1 " << nml1p << " ML2 " << nml2p << " negative radii ML1 " << nml1n << " ML " << nml2n << " used hits " << used << " t0 Error " << t0Error);
430 DCOnTrackVec::const_iterator it = dcs.begin();
431 DCOnTrackVec::const_iterator it_end = dcs.end();
432 double chi2p = 0.;
433 DCOnTrackVec dcs_new;
434 dcs_new.reserve(dcs.size());
435 for(int i=0; it!=it_end; ++it, ++i ){
436 const DriftCircle* ds = & dcs[i];
437 if(std::abs(ds->r()-ds->rot()->driftRadius())>m_dRTol) ATH_MSG_DEBUG("Different radii on dc " << ds->r() << " rot " << ds->rot()->driftRadius());
438 DriftCircle dc_keep(ds->position(), ds->rot()->driftRadius(), ds->dr(), ds->drPrecise(), ds->driftState(), ds->id(), ds->rot(), ds->index() );
439 DCOnTrack dc_new(dc_keep, 0., 0.);
440 dc_new.state(dcs[i].state());
441 dcs_new.push_back( std::move(dc_new) );
442 if( selection[i] == 0 ){
443 double t = ds->rot()->driftTime();
444 const unsigned int mlIdx = id_helper.multilayer(ds->rot()->identify()) - 1;
445 const MuonCalib::MdtRtRelation *rtInfo = rtRelations[mlIdx];
446 double tUp = rtInfo->rt()->tUpper();
447 double tLow = rtInfo->rt()->tLower();
448 if(t<tLow) chi2p += sq(t-tLow)*0.1;
449 if(t>tUp) chi2p += sq(t-tUp)*0.1;
450 }
451 }
452 if(chi2p>0) ATH_MSG_DEBUG(" Rejected weak topology Chi2 penalty " << chi2p);
453 bool oldrefit = DCSLFitter::fit( result, line, dcs_new, selection );
454 chi2p += result.chi2();
455// add chi2 penalty for too large or too small driftTimes t < 0 or t> t upper
456 result.set( chi2p, result.ndof(), result.dtheta(), result.dy0() );
457 return oldrefit;
458 } // end rejection of weak topologies
459
460 ATH_MSG_DEBUG("positive radii ML1 " << nml1p << " ML2 " << nml2p << " negative radii ML1 " << nml1n << " ML " << nml2n << " used hits " << used << " t0 Error " << t0Error);
461
462 constexpr std::array<Double_t,3> step{0.01 , 0.01 , 0.1 };
463 // starting point
464 std::array<Double_t,3> variable{theta,d,0};
465 // if t0Seed value from outside use this
466 if(t0Seed > -999.) variable[2] = t0Seed;
467
468 ROOT::Minuit2::Minuit2Minimizer minimum("algoName");
469 minimum.SetMaxFunctionCalls(10000);
470 minimum.SetTolerance(0.001);
471 minimum.SetPrintLevel(-1);
472 if(msgLvl(MSG::VERBOSE)) minimum.SetPrintLevel(1);
473
474 if (m_floatDir){
475 minimum.SetVariable(0,"a",variable[0], step[0]);
476 minimum.SetVariable(1,"b",variable[1], step[1]);
477 } else {
478 minimum.SetFixedVariable(0,"a", variable[0]);
479 minimum.SetFixedVariable(1,"b", variable[1]);
480 }
481
482 minimum.SetVariable(2,"t0",variable[2], step[2]);
483
484 minimum.SetFunction(minFunct);
485
486
487 // Suppress the FPE, for future we should study topology and eliminate bad input candidates before it reaches minuit
488 // An example: MuGirlStauAlg.MuonStauRecoToo...MdtSegmentT0Fitter positive radii ML1 3 ML2 3 negative radii ML1 1 ML 0 used hits 7 t0 Error 10
489 // For more details see: ATLASRECTS-8052
490 {
491
492 CxxUtils::FPControl ctl;
493 ctl.disable (CxxUtils::FPControl::Exc::divbyzero);
494 ctl.disable (CxxUtils::FPControl::Exc::invalid);
495
496
497 // do the minimization
498 const bool minuit_succedded = minimum.Minimize();
499 const int minuitStatus = minimum.Status();
500 if (!minuit_succedded || minuitStatus != 0) {
501 ATH_MSG_DEBUG("Minuit fit failed with status " << minuitStatus);
502 return false;
503 }
504
505 }
506
507 const double *results = minimum.X();
508 const double *errors = minimum.Errors();
509 ATH_MSG_DEBUG("Minimum: f(" << results[0] << "+-" << errors[0] << "," << results[1]<< "+-" << errors[1]<< "," << results[2] << "+-" << errors[2]<< "): " << minimum.MinValue());
510
512
513 // Get the fit values
514 double aret=results[0];
515 double aErr=errors[0];
516 double dtheta = aErr;
517 double tana = std::tan(aret); // tangent of angle
518 double ang = aret; // between zero and pi
519 cosin = std::cos(ang);
520 sinus = std::sin(ang);
521 if ( sinus < 0.0 ) {
522 sinus = -sinus;
523 cosin = -cosin;
524 } else if ( sinus == 0.0 && cosin < 0.0 ) {
525 cosin = -cosin;
526 }
527 ang = std::atan2(sinus, cosin);
528 double b=results[1];
529 double bErr=errors[1];
530 double t0=results[2];
531 double t0Err=errors[2];
532 double dy0 = cosin * bErr - b * sinus * aErr;
533
534 const double del_t = std::abs(hits[0].rt->radius((t0+t0Err)) - hits[0].rt->radius(t0)) ;
535
536
537 ATH_MSG_DEBUG("____________FINAL VALUES________________" );
538 ATH_MSG_DEBUG("Values: a "<<tana<<" d "<<b * cosin <<" t0 "<<t0);
539 ATH_MSG_DEBUG("Errors: a "<<aErr<<" b "<<dy0 <<" t0 "<<t0Err);
540
541 d = b * cosin;
542 if(msg().level() <=MSG::DEBUG) {
543 msg() << MSG::DEBUG <<"COVAR ";
544 for(int it1=0; it1<3; it1++) {
545 for(int it2=0; it2<3; it2++) {
546 msg() << MSG::DEBUG <<minimum.CovMatrix(it1,it2)<<" ";
547 }
548 msg() << MSG::DEBUG << endmsg;
549 }
550 }
551
552 result.dcs().clear();
553 result.clusters().clear();
554 result.emptyTubes().clear();
555
556 ATH_MSG_DEBUG("after fit theta "<<ang<<" sinus "<<sinus<< " cosin "<< cosin);
557
558 double chi2 = 0;
559 unsigned int nhits(0);
560
561 // calculate predicted hit positions from track parameters
562
563 ATH_MSG_DEBUG("------NEW HITS------");
564 int i{-1};
565 for(const HitCoords& coords : hits){
566 ++i;
567 const DCOnTrack& keep_me{dcs_keep[i]};
568 const double uppercut = coords.rt->tUpper();
569 const double lowercut = coords.rt->tLower();
570
571 double rad = coords.rt->radius(coords.t-t0);
572 if(coords.t-t0<lowercut) rad = coords.rt->radius(lowercut);
573 if(coords.t-t0>uppercut) rad = coords.rt->radius(uppercut);
574 if (coords.w==0) {
575 ATH_MSG_WARNING("coords.w==0, continuing");
576 continue;
577 }
578 double drad = 1.0/std::sqrt(coords.w) ;
579
580 double yl = (coords.y - tana*coords.z - b);
581
582 ATH_MSG_DEBUG("i "<<i<<" ");
583
584
585 double dth = -(sinus*coords.y + cosin*coords.z)*dtheta;
586 double residuals = std::abs(yl)/std::sqrt(1+tana*tana) - rad;
587
588 ATH_MSG_DEBUG(" dth "<<dth<<" dy0 "<<dy0<<" del_t "<<del_t);
589
590
591 double errorResiduals = std::hypot(dth, dy0, del_t);
592
593 // derivatives of the residual 'R'
594 std::array<double,3> deriv{};
595 // del R/del theta
596 double dd = coords.z * sinus + b *cosin - coords.y * cosin;
597 deriv[0] = sign(dd) * (coords.z * cosin - b * sinus + coords.y * sinus);
598 // del R / del b
599 deriv[1] = sign(dd) * cosin ;
600 // del R / del t0
601
602 deriv[2] = -1* coords.rt->driftVelocity(coords.t-t0);
603
604 double covsq=0;
605 for(int rr=0; rr<3; rr++) {
606 for(int cc=0; cc<3; cc++) {
607 covsq += deriv[rr]*minimum.CovMatrix(rr,cc)* deriv[cc];
608 }
609 }
610 ATH_MSG_DEBUG(" covsquared " << covsq);
611 if( covsq < 0. && msgLvl(MSG::DEBUG)){
612 for(int rr=0; rr<3; rr++) {
613 for(int cc=0; cc<3; cc++) {
614 double dot = deriv[rr]*minimum.CovMatrix(rr,cc)* deriv[cc];
615 ATH_MSG_DEBUG(" adding term " << dot << " dev1 " << deriv[rr] << " cov " << minimum.CovMatrix(rr,cc) << " dev2 " << deriv[cc]);
616 }
617 }
618 }
619
620 covsq = covsq > 0. ? std::sqrt(covsq) : 0.;
621 const DriftCircle* ds = & keep_me;
622 if (m_propagateErrors) drad = coords.dr;
623
624 DriftCircle dc_newrad(keep_me.position(), rad, drad, ds->driftState(), keep_me.id(), ds->rot(), keep_me.index() );
625 DCOnTrack dc_new(dc_newrad, residuals, covsq);
626 dc_new.state(keep_me.state());
627
628 ATH_MSG_DEBUG("T0 Segment hit res "<<residuals<<" eres "<<errorResiduals<<" covsq "<<covsq<<" ri " << coords.r<<" ro "<<rad<<" drad "<<drad << " sel "<<selection[i]<< " inv error " << coords.w);
629
630 if(!coords.rejected) {
631 ++nhits;
632 if (!m_propagateErrors) {
633 chi2 += sq(residuals)*coords.w;
634 } else {
635 chi2 += sq(residuals)/sq(drad);
636 }
637 ATH_MSG_DEBUG("T0 Segment hit res "<<residuals<<" eres "<<errorResiduals<<" covsq "<<covsq<<" ri " << coords.r<<" radius after t0 "<<rad<<" radius error "<< drad << " original error " << coords.dr);
638// Put chi2 penalty for drift times outside window
639 if (coords.t-t0> uppercut ) { // too large
640 chi2 += sq(coords.t-t0-uppercut)*0.1;
641 }else if (coords.t-t0 < lowercut ) {// too small
642 chi2 += sq(coords.t-t0-lowercut)*0.1;
643 }
644 }
645 result.dcs().push_back( dc_new );
646 }
647
648 double oldshift = result.t0Shift();
649 ATH_MSG_DEBUG("end fit old "<<oldshift<< " new " <<t0);
650 // Final Minuit Fit result
651 if(nhits==NUMPAR) {
652 nhits++;
653 chi2 += 1.;
654 }
655 result.set( chi2, nhits-NUMPAR, dtheta, -1.*dy0 );
656 result.line().set( LocVec2D( Zc - sinus*d, Yc + cosin*d ), ang );
657 if(t0==0.) t0=0.00001;
658 result.setT0Shift(t0,t0Err);
659
660 ATH_MSG_DEBUG("Minuit Fit complete: Chi2 " << chi2 << " angle " << result.line().phi() << " nhits "<< nhits << " t0result " << t0);
661 ATH_MSG_DEBUG("Minuit Fit complete: Chi2 " << chi2 << " angle " << result.line().phi() << " nhits "<<nhits<<" numpar "<<NUMPAR << " per dof " << chi2/(nhits-NUMPAR));
662 ATH_MSG_DEBUG("Fit complete: Chi2 " << chi2 <<" nhits "<<nhits<<" numpar "<<NUMPAR << " per dof " << chi2/(nhits-NUMPAR)<<(chi2/(nhits-NUMPAR) > 5 ? " NOT ":" ")<< "GOOD");
663 ATH_MSG_DEBUG("chi2 "<<chi2<<" per dof "<<chi2/(nhits-NUMPAR));
664
665 return true;
666 }
const std::regex rr(r_r)
Scalar theta() const
theta method
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define sq(x)
static Double_t t0
int sign(int a)
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
int multilayer(const Identifier &id) const
Access to components of the ID.
virtual double tLower() const =0
Returns the lower time covered by the r-t.
virtual double radius(double t) const =0
returns drift radius for a given time
virtual double tUpper() const =0
Returns the upper time covered by the r-t.
virtual double driftVelocity(double t) const =0
Returns the drift velocity for a given time.
const IRtRelation * rt() const
rt relation
double driftRadius() const
Returns the value of the drift radius.
double driftTime() const
Returns the value of the drift time used to obtain the drift radius.
virtual bool fit(Segment &result, const Line &line, const DCOnTrackVec &dcs, double t0Seed=-99999.) const
Gaudi::Property< bool > m_rejectWeakTopologies
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
SG::ReadCondHandleKey< MuonCalib::MdtCalibDataContainer > m_calibDbKey
Identifier identify() const
return the identifier -extends MeasurementBase
double chi2(TH1 *h0, TH1 *h1)
const std::string selection
@ Zc
Z -> cc, nC = 1 (partial containment).
constexpr std::size_t N
std::vector< DCOnTrack > DCOnTrackVec
Definition DCOnTrack.h:59
dot(G, fn, nodesToHighlight=[])
Definition dot.py:5

◆ fit() [2/2]

bool TrkDriftCircleMath::MdtSegmentT0Fitter::fit ( Segment & result,
const Line & line,
const DCOnTrackVec & dcs,
double t0Seed ) const
inlineoverridevirtual

Reimplemented from TrkDriftCircleMath::DCSLFitter.

Definition at line 63 of file MdtSegmentT0Fitter.h.

63 {
64 HitSelection selection(dcs.size(),0);
65 return fit( result, line, dcs, selection, t0Seed );
66 }
virtual bool fit(Segment &result, const Line &line, const DCOnTrackVec &dcs, double t0Seed) const override
std::vector< bool > HitSelection
Definition HitSelection.h:9

◆ getFitter()

virtual const DCSLFitter * TrkDriftCircleMath::MdtSegmentT0Fitter::getFitter ( ) const
inlineoverridevirtual

fitter factory

Returns
provides pointer to fitter, ownsership not passed to client

Implements Muon::IDCSLFitProvider.

Definition at line 36 of file MdtSegmentT0Fitter.h.

36{ return this; }

◆ initialize()

StatusCode TrkDriftCircleMath::MdtSegmentT0Fitter::initialize ( )
overridevirtual

Definition at line 176 of file MdtSegmentT0Fitter.cxx.

176 {
177 ATH_CHECK(m_calibDbKey.initialize());
178 return StatusCode::SUCCESS;
179 }
#define ATH_CHECK
Evaluate an expression and check for errors.

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ interfaceID()

const InterfaceID & Muon::IDCSLFitProvider::interfaceID ( )
inlinestaticinherited

Definition at line 21 of file IDCSLFitProvider.h.

21 {
22 static const InterfaceID IID_IDCSLFitProvider("Muon::IDCSLFitProvider",1,0);
23 return IID_IDCSLFitProvider;
24 }

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, and AthCheckedComponent<::AthAlgTool >.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

Member Data Documentation

◆ m_calibDbKey

SG::ReadCondHandleKey<MuonCalib::MdtCalibDataContainer> TrkDriftCircleMath::MdtSegmentT0Fitter::m_calibDbKey
private
Initial value:
{this, "CalibDataKey", "MdtCalibConstants",
"Conditions object containing the calibrations"}

Definition at line 40 of file MdtSegmentT0Fitter.h.

40 {this, "CalibDataKey", "MdtCalibConstants",
41 "Conditions object containing the calibrations"};

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default).

Definition at line 393 of file AthCommonDataStore.h.

◆ m_dRTol

Gaudi::Property<float> TrkDriftCircleMath::MdtSegmentT0Fitter::m_dRTol {this,"dRTolerance",0.1}
private

Definition at line 49 of file MdtSegmentT0Fitter.h.

49{this,"dRTolerance",0.1};

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default).

Definition at line 390 of file AthCommonDataStore.h.

◆ m_floatDir

Gaudi::Property<bool> TrkDriftCircleMath::MdtSegmentT0Fitter::m_floatDir
private
Initial value:
{this, "FloatSegDirection", false,
"If set to true, the line of the segment is simultaenously fitted with t0"}

Definition at line 51 of file MdtSegmentT0Fitter.h.

51 {this, "FloatSegDirection", false,
52 "If set to true, the line of the segment is simultaenously fitted with t0"};

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> TrkDriftCircleMath::MdtSegmentT0Fitter::m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
private

Definition at line 43 of file MdtSegmentT0Fitter.h.

43{this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};

◆ m_minHits

Gaudi::Property<int> TrkDriftCircleMath::MdtSegmentT0Fitter::m_minHits {this,"MinimumHits",4,"minimum number of selected hits for t0 fit. Otherwise use default"}
private

Definition at line 48 of file MdtSegmentT0Fitter.h.

48{this,"MinimumHits",4,"minimum number of selected hits for t0 fit. Otherwise use default"};

◆ m_npassedMinHits

std::atomic_uint TrkDriftCircleMath::MdtSegmentT0Fitter::m_npassedMinHits {0}
mutableprivate

Definition at line 58 of file MdtSegmentT0Fitter.h.

58{0};

◆ m_npassedMinuitFit

std::atomic_uint TrkDriftCircleMath::MdtSegmentT0Fitter::m_npassedMinuitFit {0}
mutableprivate

Definition at line 59 of file MdtSegmentT0Fitter.h.

59{0};

◆ m_npassedNHits

std::atomic_uint TrkDriftCircleMath::MdtSegmentT0Fitter::m_npassedNHits {0}
mutableprivate

Definition at line 55 of file MdtSegmentT0Fitter.h.

55{0};

◆ m_npassedNSelectedHits

std::atomic_uint TrkDriftCircleMath::MdtSegmentT0Fitter::m_npassedNSelectedHits {0}
mutableprivate

Definition at line 57 of file MdtSegmentT0Fitter.h.

57{0};

◆ m_npassedSelectionConsistency

std::atomic_uint TrkDriftCircleMath::MdtSegmentT0Fitter::m_npassedSelectionConsistency {0}
mutableprivate

Definition at line 56 of file MdtSegmentT0Fitter.h.

56{0};

◆ m_ntotalCalls

std::atomic_uint TrkDriftCircleMath::MdtSegmentT0Fitter::m_ntotalCalls {0}
mutableprivate

Definition at line 54 of file MdtSegmentT0Fitter.h.

54{0};

◆ m_propagateErrors

Gaudi::Property<bool> TrkDriftCircleMath::MdtSegmentT0Fitter::m_propagateErrors {this,"PropagateErrors",true,"propagate errors"}
private

Definition at line 47 of file MdtSegmentT0Fitter.h.

47{this,"PropagateErrors",true,"propagate errors"};

◆ m_rejectWeakTopologies

Gaudi::Property<bool> TrkDriftCircleMath::MdtSegmentT0Fitter::m_rejectWeakTopologies {this,"RejectWeakTopologies",true,"reject topolgies that do not have at least one +- combination in one multilayer"}
private

Definition at line 45 of file MdtSegmentT0Fitter.h.

45{this,"RejectWeakTopologies",true,"reject topolgies that do not have at least one +- combination in one multilayer"};

◆ m_scaleErrors

Gaudi::Property<bool> TrkDriftCircleMath::MdtSegmentT0Fitter::m_scaleErrors {this,"RescaleErrors",true,"rescale errors in fit"}
private

Definition at line 46 of file MdtSegmentT0Fitter.h.

46{this,"RescaleErrors",true,"rescale errors in fit"};

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files: