Skip to content

Commit 3c80e4a

Browse files
authored
Merge pull request #205 from edcallaghan/track_copy_constructor
Implement Track<> copy-constructor and backing graph-copy infrastructure
2 parents 46ea3db + 05e472a commit 3c80e4a

18 files changed

+373
-1
lines changed

Detector/ElementXing.hh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
// Describe the material effects of a particle crossing a detector element (piece of the detector)
55
// Used in the kinematic Kalman fit
66
//
7+
#include "KinKal/General/CloneContext.hh"
78
#include "KinKal/General/MomBasis.hh"
89
#include "KinKal/Detector/MaterialXing.hh"
910
#include "KinKal/Trajectory/ParticleTrajectory.hh"
1011
#include "KinKal/Fit/MetaIterConfig.hh"
1112
#include <vector>
1213
#include <array>
1314
#include <ostream>
15+
#include <stdexcept>
16+
#include <string>
1417

1518
namespace KinKal {
1619
template <class KTRAJ> class ElementXing {
@@ -19,6 +22,9 @@ namespace KinKal {
1922
using KTRAJPTR = std::shared_ptr<KTRAJ>;
2023
ElementXing() {}
2124
virtual ~ElementXing() {}
25+
// clone op for reinstantiation
26+
ElementXing(ElementXing const& rhs) = default;
27+
virtual std::shared_ptr< ElementXing<KTRAJ> > clone(CloneContext&) const;
2228
virtual void updateReference(PTRAJ const& ptraj) = 0; // update the trajectory reference
2329
virtual void updateState(MetaIterConfig const& config,bool first) =0; // update the state according to this meta-config
2430
virtual Parameters params() const =0; // parameter change induced by this element crossing WRT the reference parameters going forwards in time
@@ -40,6 +46,14 @@ namespace KinKal {
4046
private:
4147
};
4248

49+
// cloning requires domain knowledge of pointer members of the cloned object,
50+
// which must be reassigned explicitly; the default action is thus to throw
51+
// an error if a clone routine has not been explicitly provided.
52+
template<class KTRAJ> std::shared_ptr< ElementXing<KTRAJ> > ElementXing<KTRAJ>::clone(CloneContext&) const{
53+
std::string msg = "Attempt to clone KinKal::Hit subclass with no clone() implementation";
54+
throw std::runtime_error(msg);
55+
}
56+
4357
template <class KTRAJ> void ElementXing<KTRAJ>::momentumChange(SVEC3& dmom, SMAT& dmomvar) const {
4458
// compute the parameter effect for forwards time
4559
double dm, paramomvar, perpmomvar;

Detector/Hit.hh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
// Base class to describe a measurement that constrains some aspect of the track fit
55
// The constraint is expressed as a weight WRT a set of reference parameters.
66
//
7+
#include "KinKal/General/CloneContext.hh"
78
#include "KinKal/General/Weights.hh"
89
#include "KinKal/General/Parameters.hh"
910
#include "KinKal/General/Chisq.hh"
1011
#include "KinKal/Trajectory/ParticleTrajectory.hh"
1112
#include "KinKal/Fit/MetaIterConfig.hh"
1213
#include <memory>
1314
#include <ostream>
15+
#include <stdexcept>
16+
#include <string>
1417

1518
namespace KinKal {
1619
template <class KTRAJ> class Hit {
@@ -22,6 +25,8 @@ namespace KinKal {
2225
// disallow copy and equivalence
2326
Hit(Hit const& ) = delete;
2427
Hit& operator =(Hit const& ) = delete;
28+
// clone op for reinstantiation
29+
virtual std::shared_ptr< Hit<KTRAJ> > clone(CloneContext&) const;
2530
// hits may be active (used in the fit) or inactive; this is a pattern recognition feature
2631
virtual bool active() const =0;
2732
virtual unsigned nDOF() const=0;
@@ -45,6 +50,14 @@ namespace KinKal {
4550
Chisq chisquared() const;
4651
};
4752

53+
// cloning requires domain knowledge of pointer members of the cloned object,
54+
// which must be reassigned explicitly; the default action is thus to throw
55+
// an error if a clone routine has not been explicitly provided.
56+
template<class KTRAJ> std::shared_ptr< Hit<KTRAJ> > Hit<KTRAJ>::clone(CloneContext& context) const{
57+
std::string msg = "Attempt to clone KinKal::Hit subclass with no clone() implementation";
58+
throw std::runtime_error(msg);
59+
}
60+
4861
template<class KTRAJ> Parameters Hit<KTRAJ>::unbiasedParameters() const {
4962
if(active()){
5063
// convert the parameters to a weight, and subtract this hit's weight

Detector/ParameterHit.hh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ namespace KinKal {
1515
using PTRAJ = ParticleTrajectory<KTRAJ>;
1616
using KTRAJPTR = std::shared_ptr<KTRAJ>;
1717

18+
// copy constructor
19+
ParameterHit(ParameterHit<KTRAJ> const& rhs):
20+
time_(rhs.time()),
21+
params_(rhs.constraintParameters()),
22+
pweight_(rhs.parameterWeights()),
23+
weight_(rhs.weight()),
24+
pmask_(rhs.constraintMask()),
25+
mask_(rhs.maskMatrix()),
26+
ncons_(rhs.numConstrainedParameters()){
27+
/**/
28+
};
29+
// clone op for reinstantiation
30+
std::shared_ptr< Hit<KTRAJ> > clone(CloneContext& context) const override{
31+
auto rv = std::make_shared< ParameterHit<KTRAJ> >(*this);
32+
return rv;
33+
};
1834
// Hit interface overrrides
1935
bool active() const override { return ncons_ > 0; }
2036
Chisq chisq(Parameters const& pdata) const override;
@@ -32,6 +48,9 @@ namespace KinKal {
3248
unsigned nDOF() const override { return ncons_; }
3349
Parameters const& constraintParameters() const { return params_; }
3450
PMASK const& constraintMask() const { return pmask_; }
51+
Weights parameterWeights() const { return pweight_; };
52+
DMAT maskMatrix() const { return mask_; }
53+
unsigned numConstrainedParameters() const { return ncons_; };
3554
private:
3655
double time_; // time of this constraint: must be supplied on construction and does not change
3756
KTRAJPTR reftraj_; // reference WRT this hits weight was calculated

Detector/ResidualHit.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ namespace KinKal {
1010

1111
template <class KTRAJ> class ResidualHit : public Hit<KTRAJ> {
1212
public:
13+
// copy constructor
14+
ResidualHit(ResidualHit<KTRAJ> const& rhs): weight_(rhs.weight()){
15+
/**/
16+
};
1317
// override of some Hit interface. Subclasses must still implement update and material methods
1418
using HIT = Hit<KTRAJ>;
1519
using PTRAJ = ParticleTrajectory<KTRAJ>;

Examples/ScintHit.hh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,30 @@ namespace KinKal {
1717
using RESIDHIT = ResidualHit<KTRAJ>;
1818
using HIT = Hit<KTRAJ>;
1919
using KTRAJPTR = std::shared_ptr<KTRAJ>;
20+
// copy constructor
21+
ScintHit(ScintHit<KTRAJ> const& rhs):
22+
ResidualHit<KTRAJ>(rhs),
23+
saxis_(rhs.sensorAxis()),
24+
tvar_(rhs.timeVariance()),
25+
wvar_(rhs.widthVariance()),
26+
tpca_(
27+
rhs.closestApproach().particleTraj(),
28+
saxis_,
29+
rhs.closestApproach().hint(),
30+
rhs.closestApproach().precision()
31+
),
32+
rresid_(rhs.refResidual()){
33+
/**/
34+
};
35+
// clone op for reinstantiation
36+
std::shared_ptr< Hit<KTRAJ> > clone(CloneContext& context) const override{
37+
auto rv = std::make_shared< ScintHit<KTRAJ> >(*this);
38+
auto ca = rv->closestApproach();
39+
auto trajectory = std::make_shared<KTRAJ>(ca.particleTraj());
40+
ca.setTrajectory(trajectory);
41+
rv->setClosestApproach(ca);
42+
return rv;
43+
};
2044
// ResidualHit interface implementation
2145
unsigned nResid() const override { return 1; } // 1 time residual
2246
Residual const& refResidual(unsigned ires=0) const override;
@@ -40,6 +64,9 @@ namespace KinKal {
4064
double wvar_; // variance in transverse position of the sensor/measurement in mm. Assumes cylindrical error, could be more general
4165
CA tpca_; // reference time and position of closest approach to the axis
4266
Residual rresid_; // residual WRT most recent reference parameters
67+
68+
// modifiers to support cloning
69+
void setClosestApproach(const CA& ca){ tpca_ = ca; }
4370
};
4471

4572
template <class KTRAJ> ScintHit<KTRAJ>::ScintHit(PCA const& pca, double tvar, double wvar) :

Examples/SimpleWireHit.hh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,36 @@ namespace KinKal {
2727
SimpleWireHit(BFieldMap const& bfield, PCA const& pca, WireHitState const& whstate, double mindoca,
2828
double driftspeed, double tvar, double tot, double totvar, double rcell,int id);
2929
unsigned nResid() const override { return 2; } // 2 residuals
30+
// clone op for reinstantiation
31+
SimpleWireHit(SimpleWireHit<KTRAJ> const& rhs):
32+
ResidualHit<KTRAJ>(rhs),
33+
bfield_(rhs.bfield()),
34+
whstate_(rhs.hitState()),
35+
wire_(rhs.wire()),
36+
ca_(
37+
rhs.closestApproach().particleTraj(),
38+
wire_,
39+
rhs.closestApproach().hint(),
40+
rhs.closestApproach().precision()
41+
),
42+
rresid_(rhs.residuals()),
43+
mindoca_(rhs.minDOCA()),
44+
dvel_(driftVelocity()),
45+
tvar_(timeVariance()),
46+
tot_(rhs.tot()),
47+
totvar_(rhs.totVariance()),
48+
rcell_(rhs.cellRadius()),
49+
id_(rhs.id()){
50+
/**/
51+
};
52+
std::shared_ptr< Hit<KTRAJ> > clone(CloneContext& context) const override{
53+
auto rv = std::make_shared< SimpleWireHit<KTRAJ> >(*this);
54+
auto ca = rv->closestApproach();
55+
auto trajectory = std::make_shared<KTRAJ>(ca.particleTraj());
56+
ca.setTrajectory(trajectory);
57+
rv->setClosestApproach(ca);
58+
return rv;
59+
};
3060
double time() const override { return ca_.particleToca(); }
3161
VEC3 dRdX(unsigned ires) const;
3262
Residual const& refResidual(unsigned ires=dresid) const override;
@@ -48,6 +78,10 @@ namespace KinKal {
4878
auto const& wire() const { return wire_; }
4979
auto const& bfield() const { return bfield_; }
5080
auto precision() const { return ca_.precision(); }
81+
auto const& residuals() const { return rresid_; }
82+
double tot() const { return tot_; }
83+
double totVariance() const { return totvar_; }
84+
5185
private:
5286
BFieldMap const& bfield_; // drift calculation requires the BField for ExB effects
5387
WireHitState whstate_; // current state
@@ -65,6 +99,9 @@ namespace KinKal {
6599
double rcell_; // straw radius
66100
int id_; // id
67101
void updateResiduals();
102+
103+
// modifiers to support cloning
104+
void setClosestApproach(const CA& ca){ ca_ = ca; }
68105
};
69106

70107
//trivial 'updater' that sets the wire hit state to null

Examples/StrawXing.hh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,33 @@ namespace KinKal {
2121
// construct from PCA and material
2222
StrawXing(PCA const& pca, StrawMaterial const& smat);
2323
virtual ~StrawXing() {}
24+
// copy constructor
25+
StrawXing(StrawXing const& rhs):
26+
ElementXing<KTRAJ>(rhs),
27+
axis_(rhs.axis_),
28+
smat_(rhs.smat_),
29+
tpca_(
30+
rhs.closestApproach().particleTraj(),
31+
axis_,
32+
rhs.closestApproach().hint(),
33+
rhs.closestApproach().precision()
34+
),
35+
toff_(rhs.toff_),
36+
sxconfig_(rhs.sxconfig_),
37+
varscale_(rhs.varscale_),
38+
mxings_(rhs.mxings_),
39+
fparams_(rhs.fparams_){
40+
/**/
41+
}
42+
// clone op for reinstantiation
43+
std::shared_ptr< ElementXing<KTRAJ> > clone(CloneContext& context) const override{
44+
auto rv = std::make_shared< StrawXing<KTRAJ> >(*this);
45+
auto ca = rv->closestApproach();
46+
auto trajectory = std::make_shared<KTRAJ>(ca.particleTraj());
47+
ca.setTrajectory(trajectory);
48+
rv->setClosestApproach(ca);
49+
return rv;
50+
}
2451
// ElementXing interface
2552
void updateReference(PTRAJ const& ptraj) override;
2653
void updateState(MetaIterConfig const& config,bool first) override;
@@ -35,6 +62,7 @@ namespace KinKal {
3562
auto const& strawMaterial() const { return smat_; }
3663
auto const& config() const { return sxconfig_; }
3764
auto precision() const { return tpca_.precision(); }
65+
3866
private:
3967
SensorLine axis_; // straw axis, expressed as a timeline
4068
StrawMaterial const& smat_;
@@ -44,6 +72,9 @@ namespace KinKal {
4472
double varscale_; // variance scale
4573
std::vector<MaterialXing> mxings_;
4674
Parameters fparams_; // parameter change for forwards time
75+
76+
// modifiers to support cloning
77+
void setClosestApproach(const CA& ca){ tpca_ = ca; }
4778
};
4879

4980
template <class KTRAJ> StrawXing<KTRAJ>::StrawXing(PCA const& pca, StrawMaterial const& smat) :

Fit/Domain.hh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44
// domain used to compute magnetic field corrections. Magnetic bending not described by the intrinsic parameterization is assumed
55
// to be negligible over the domain
66
//
7+
#include <memory>
8+
#include "KinKal/General/CloneContext.hh"
79
#include "KinKal/General/TimeRange.hh"
810
#include "KinKal/General/Vectors.hh"
911
namespace KinKal {
1012
class Domain : public TimeRange {
1113
public:
1214
Domain(double lowtime, double range, VEC3 const& bnom, double tol) : range_(lowtime,lowtime+range), bnom_(bnom), tol_(tol) {}
1315
Domain(TimeRange const& range, VEC3 const& bnom, double tol) : range_(range), bnom_(bnom), tol_(tol) {}
16+
// clone op for reinstantiation
17+
Domain(Domain const&);
18+
std::shared_ptr< Domain > clone(CloneContext&) const;
1419
bool operator < (Domain const& other) const {return begin() < other.begin(); }
1520
auto const& range() const { return range_; }
1621
// forward range functions
@@ -25,6 +30,19 @@ namespace KinKal {
2530
VEC3 bnom_; // nominal BField for this domain
2631
double tol_; // tolerance used to create this domain
2732
};
33+
34+
// clone op for reinstantiation
35+
Domain::Domain(Domain const& rhs):
36+
range_(rhs.range()),
37+
bnom_(rhs.bnom()),
38+
tol_(rhs.tolerance()){
39+
/**/
40+
}
41+
42+
std::shared_ptr<Domain> Domain::clone(CloneContext& context) const{
43+
auto rv = std::make_shared<Domain>(*this);
44+
return rv;
45+
}
2846
}
2947
#endif
3048

Fit/DomainWall.hh

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,33 @@ namespace KinKal {
3434
auto const& parameterChange() const { return dpfwd_; }
3535
virtual ~DomainWall(){}
3636
// disallow copy and equivalence
37-
DomainWall(DomainWall const& ) = delete;
37+
// DomainWall(DomainWall const& ) = delete;
3838
DomainWall& operator =(DomainWall const& ) = delete;
39+
// clone op for reinstantiation
40+
DomainWall(DomainWall const&);
41+
std::unique_ptr< Effect<KTRAJ> > clone(CloneContext&) const override;
3942
// specific DomainWall interface
4043
DomainWall(DOMAINPTR const& prevdomain,DOMAINPTR const& nextdomain, PTRAJ const& ptraj);
4144
// previous and next domains
4245
auto const& prevDomain() const { return *prev_; }
4346
auto const& nextDomain() const { return *next_; }
47+
// other accessors
48+
auto const& prevPtr() const { return prev_; }
49+
auto const& nextPtr() const { return next_; }
50+
auto const& fwdChange() const { return dpfwd_; }
51+
auto const& prevWeight() const { return prevwt_; }
52+
auto const& nextWeight() const { return nextwt_; }
53+
auto const& fwdCovarianceRotation() const { return dpdpdb_; }
4454

4555
private:
4656
DOMAINPTR prev_, next_; // pointers to previous and next domains
4757
DVEC dpfwd_; // parameter change across this domain wall in the forwards time direction
4858
Weights prevwt_, nextwt_; // cache of weights
4959
PSMAT dpdpdb_; // forward rotation of covariance matrix going in the forwards direction
5060

61+
// modifiers to support cloning
62+
void setPrevPtr(DOMAINPTR const& ptr){ prev_ = ptr; }
63+
void setNextPtr(DOMAINPTR const& ptr){ next_ = ptr; }
5164
};
5265

5366
template<class KTRAJ> DomainWall<KTRAJ>::DomainWall(
@@ -132,5 +145,26 @@ namespace KinKal {
132145
return ost;
133146
}
134147

148+
// clone op for reinstantiation
149+
template <class KTRAJ>
150+
DomainWall<KTRAJ>::DomainWall(DomainWall const& rhs):
151+
dpfwd_(rhs.fwdChange()),
152+
prevwt_(rhs.prevWeight()),
153+
nextwt_(rhs.nextWeight()),
154+
dpdpdb_(rhs.fwdCovarianceRotation()){
155+
/**/
156+
}
157+
158+
template <class KTRAJ>
159+
std::unique_ptr< Effect<KTRAJ> > DomainWall<KTRAJ>::clone(CloneContext& context) const{
160+
auto casted = std::make_unique< DomainWall<KTRAJ> >(*this);
161+
DOMAINPTR prev = context.get(prev_);
162+
casted->setPrevPtr(prev);
163+
DOMAINPTR next = context.get(next_);
164+
casted->setNextPtr(next);
165+
//auto rv = std::make_unique< Effect<KTRAJ> >(casted);
166+
auto rv = std::move(casted);
167+
return rv;
168+
}
135169
}
136170
#endif

0 commit comments

Comments
 (0)