8 #include "art/Framework/Core/EDProducer.h"
9 #include "art/Framework/Core/ModuleMacros.h"
10 #include "art/Framework/Principal/Event.h"
11 #include "art/Framework/Principal/Handle.h"
13 #include "canvas/Persistency/Common/Assns.h"
14 #include "canvas/Utilities/InputTag.h"
15 #include "fhiclcpp/types/Atom.h"
16 #include "fhiclcpp/types/Sequence.h"
17 #include "fhiclcpp/types/Table.h"
40 Name(
"inputTrajectoryLabel"),
41 Comment(
"Label of recob::Trajectory or recob::TrackTrajectory Collection to be fit")};
43 Name(
"isTrackTrajectory"),
44 Comment(
"If true, we assume the input collection is made of recob::TrackTrajectory "
45 "objects, otherwise of recob::Trajectory objects.")};
48 Comment(
"Label of sim::MCTrack Collection to be used for initial momentum estimate. Used "
49 "only if momFromMC is set to true.")};
56 Comment(
"Flag used to get initial momentum estimate from "
57 "trkf::TrackMomentumCalculator::GetTrackMomentum().")};
60 Comment(
"Flag used to get initial momentum estimate from inputMCLabel collection.")};
62 Name(
"momentumInGeV"),
63 Comment(
"Fixed momentum estimate value, to be used when momFromCalo, momFromLength and "
64 "momFromMC are all false, or if the estimate is not available.")
68 Comment(
"Default particle id hypothesis in case no valid id is provided either via "
69 "PFParticle or in the ParticleId collection.")};
72 Comment(
"Assume track direction from as the one giving positive "
73 "dot product with vector specified by dirVec.")};
75 Comment(
"Fhicl sequence defining the vector used when "
76 "dirFromVec=true. It must have 3 elements.")};
78 Name(
"alwaysInvertDir"),
79 Comment(
"If true, fit all tracks from end to vertex assuming inverted direction.")};
81 Name(
"produceTrackFitHitInfo"),
82 Comment(
"Option to produce (or not) the detailed TrackFitHitInfo.")};
84 Name(
"produceSpacePoints"),
85 Comment(
"Option to produce (or not) the associated SpacePoints.")};
87 Name(
"keepInputTrajectoryPoints"),
88 Comment(
"Option to keep positions and directions from input trajectory. The fit will "
89 "provide only covariance matrices, chi2, ndof, particle Id and absolute momentum. "
90 "It may also modify the trajectory point flags. In order to avoid inconsistencies, "
91 "it has to be used with the following fitter options all set to false: "
92 "sortHitsByPlane, sortOutputHitsMinLength, skipNegProp.")};
97 fhicl::Table<KalmanFilterTrajectoryFitter::Inputs>
inputs{
100 fhicl::Table<KalmanFilterTrajectoryFitter::Options>
options{
Name(
"options")};
102 fhicl::Table<TrackKalmanFitter::Config>
fitter{
Name(
"fitter")};
115 void produce(art::Event&
e)
override;
142 , prop{p_().propagator}
143 , kalmanFitter{&prop, p_().fitter}
144 , trajectoryInputTag{p_().inputs().inputTrajectoryLabel()}
147 simTrackInputTag = art::InputTag{p_().inputs().inputMCLabel()};
149 isTT = p_().inputs().isTrackTrajectory();
151 produces<std::vector<recob::Track>>();
152 produces<art::Assns<recob::Track, recob::Hit>>();
153 produces<art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>>();
154 if (isTT) { produces<art::Assns<recob::TrackTrajectory, recob::Track>>(); }
156 produces<art::Assns<recob::Trajectory, recob::Track>>();
158 if (p_().options().produceTrackFitHitInfo()) {
159 produces<std::vector<std::vector<recob::TrackFitHitInfo>>>();
161 if (p_().options().produceSpacePoints()) {
162 produces<std::vector<recob::SpacePoint>>();
163 produces<art::Assns<recob::Hit, recob::SpacePoint>>();
168 unsigned int nDirs = 0;
169 if (p_().options().dirFromMC()) nDirs++;
170 if (p_().options().dirFromVec()) nDirs++;
171 if (p_().options().alwaysInvertDir()) nDirs++;
173 throw cet::exception(
"KalmanFilterTrajectoryFitter")
174 <<
"Incompatible configuration parameters: only at most one can be set to true among "
175 "dirFromMC, dirFromVec, and alwaysInvertDir."
179 unsigned int nPFroms = 0;
180 if (p_().
options().pFromLength()) nPFroms++;
181 if (p_().
options().pFromMC()) nPFroms++;
183 throw cet::exception(
"KalmanFilterTrajectoryFitter")
184 <<
"Incompatible configuration parameters: only at most one can be set to true among "
185 "pFromLength, and pFromMC."
189 if (p_().
options().keepInputTrajectoryPoints()) {
190 if (p_().fitter().sortHitsByPlane() || p_().fitter().sortOutputHitsMinLength() ||
191 p_().fitter().skipNegProp()) {
192 throw cet::exception(
"KalmanFilterTrajectoryFitter")
193 <<
"Incompatible configuration parameters: keepInputTrajectoryPoints needs the following "
194 "fitter options all set to false: sortHitsByPlane, sortOutputHitsMinLength, skipNegProp."
204 auto outputTracks = std::make_unique<std::vector<recob::Track>>();
205 auto outputHitsMeta =
206 std::make_unique<art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>>();
207 auto outputHits = std::make_unique<art::Assns<recob::Track, recob::Hit>>();
208 auto outputHitInfo = std::make_unique<std::vector<std::vector<recob::TrackFitHitInfo>>>();
211 auto outputTTjTAssn = std::make_unique<art::Assns<recob::TrackTrajectory, recob::Track>>();
212 auto outputTjTAssn = std::make_unique<art::Assns<recob::Trajectory, recob::Track>>();
214 auto const tid = e.getProductID<std::vector<recob::Track>>();
215 auto const tidgetter = e.productGetter(tid);
217 auto outputSpacePoints = std::make_unique<std::vector<recob::SpacePoint>>();
218 auto outputHitSpacePointAssn = std::make_unique<art::Assns<recob::Hit, recob::SpacePoint>>();
219 auto const spid = e.getProductID<std::vector<recob::SpacePoint>>();
220 auto const spidgetter = e.productGetter(spid);
226 art::ValidHandle<std::vector<sim::MCTrack>> simTracks =
227 e.getValidHandle<std::vector<sim::MCTrack>>(simTrackInputTag);
228 for (
unsigned int iMC = 0; iMC < simTracks->size(); ++iMC) {
231 if (mctrack.
PdgCode() != 13)
continue;
232 if (mctrack.
Process() !=
"primary")
continue;
234 mcdir = TVector3(mctrack.
Start().
Momentum().X() * 0.001 / pMC,
242 unsigned int nTrajs = 0;
244 art::Handle<std::vector<recob::TrackTrajectory>> inputTrackTrajectoryH;
245 art::Handle<std::vector<recob::Trajectory>> inputTrajectoryH;
246 const std::vector<recob::TrackTrajectory>* trackTrajectoryVec =
nullptr;
247 const std::vector<recob::Trajectory>* trajectoryVec =
nullptr;
248 const art::Assns<recob::TrackTrajectory, recob::Hit>* trackTrajectoryHitsAssn =
nullptr;
249 const art::Assns<recob::Trajectory, recob::Hit>* trajectoryHitsAssn =
nullptr;
251 bool ok = e.getByLabel(trajectoryInputTag, inputTrackTrajectoryH);
253 throw cet::exception(
"KalmanFilterTrajectoryFitter")
254 <<
"Cannot find recob::TrackTrajectory art::Handle with inputTag " << trajectoryInputTag;
255 trackTrajectoryVec = inputTrackTrajectoryH.product();
256 trackTrajectoryHitsAssn =
257 e.getValidHandle<art::Assns<recob::TrackTrajectory, recob::Hit>>(trajectoryInputTag)
259 nTrajs = trackTrajectoryVec->size();
262 bool ok = e.getByLabel(trajectoryInputTag, inputTrajectoryH);
264 throw cet::exception(
"KalmanFilterTrajectoryFitter")
265 <<
"Cannot find recob::Trajectory art::Handle with inputTag " << trajectoryInputTag;
266 trajectoryVec = inputTrajectoryH.product();
268 e.getValidHandle<art::Assns<recob::Trajectory, recob::Hit>>(trajectoryInputTag).product();
269 nTrajs = trajectoryVec->size();
272 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e);
274 for (
unsigned int iTraj = 0; iTraj < nTrajs; ++iTraj) {
277 (isTT ? trackTrajectoryVec->at(iTraj) :
279 std::vector<recob::TrajectoryPointFlags>()));
282 std::vector<art::Ptr<recob::Hit>> inHits;
284 for (
auto it = trackTrajectoryHitsAssn->begin(); it != trackTrajectoryHitsAssn->end(); ++it) {
285 if (it->first.key() == iTraj)
286 inHits.push_back(it->second);
287 else if (inHits.size() > 0)
292 for (
auto it = trajectoryHitsAssn->begin(); it != trajectoryHitsAssn->end(); ++it) {
293 if (it->first.key() == iTraj)
294 inHits.push_back(it->second);
295 else if (inHits.size() > 0)
299 const int pId = setPId();
300 const double mom = setMomValue(&inTraj, pMC, pId);
301 const bool flipDir = setDirFlip(&inTraj, mcdir);
304 std::vector<art::Ptr<recob::Hit>> outHits;
307 bool fitok = kalmanFitter.fitTrack(
detProp,
319 if (!fitok)
continue;
321 if (p_().
options().keepInputTrajectoryPoints()) {
322 restoreInputPoints(inTraj, inHits, outTrack, outHits);
325 outputTracks->emplace_back(std::move(outTrack));
326 art::Ptr<recob::Track> aptr(tid, outputTracks->size() - 1, tidgetter);
328 for (
auto const& trhit : outHits) {
331 outputHitsMeta->addSingle(aptr, trhit, metadata);
332 outputHits->addSingle(aptr, trhit);
333 if (p_().
options().produceSpacePoints() && outputTracks->back().HasValidPoint(ip)) {
334 auto& tp = outputTracks->back().Trajectory().LocationAtPoint(ip);
335 double fXYZ[3] = {tp.X(), tp.Y(), tp.Z()};
336 double fErrXYZ[6] = {0};
338 outputSpacePoints->emplace_back(std::move(sp));
339 art::Ptr<recob::SpacePoint> apsp(spid, outputSpacePoints->size() - 1, spidgetter);
340 outputHitSpacePointAssn->addSingle(trhit, apsp);
346 outputTTjTAssn->addSingle(art::Ptr<recob::TrackTrajectory>(inputTrackTrajectoryH, iTraj),
350 outputTjTAssn->addSingle(art::Ptr<recob::Trajectory>(inputTrajectoryH, iTraj), aptr);
353 e.put(std::move(outputTracks));
354 e.put(std::move(outputHitsMeta));
355 e.put(std::move(outputHits));
356 if (p_().
options().produceTrackFitHitInfo()) { e.put(std::move(outputHitInfo)); }
357 if (p_().
options().produceSpacePoints()) {
358 e.put(std::move(outputSpacePoints));
359 e.put(std::move(outputHitSpacePointAssn));
362 e.put(std::move(outputTTjTAssn));
364 e.put(std::move(outputTjTAssn));
375 std::vector<Point_t> positions(np);
376 std::vector<Vector_t> momenta(np);
377 std::vector<recob::TrajectoryPointFlags> outFlags(np);
379 for (
unsigned int p = 0;
p < np; ++
p) {
382 auto op =
flag.fromHit();
396 std::move(covs.first),
397 std::move(covs.second),
401 for (
auto h : inHits)
402 outHits.push_back(
h);
410 double result = p_().options().pval();
411 if (p_().
options().pFromLength()) { result = tmc.GetTrackMomentum(ptraj->
Length(), pId); }
412 else if (p_().options().pFromMC() && pMC > 0.) {
421 int result = p_().options().pdgId();
427 TVector3& mcdir)
const
430 if (p_().
options().alwaysInvertDir()) {
return true; }
431 else if (p_().
options().dirFromMC()) {
433 if ((mcdir.X() * tdir.X() + mcdir.Y() * tdir.Y() + mcdir.Z() * tdir.Z()) < 0.) result =
true;
435 else if (p_().options().dirFromVec()) {
436 std::array<float, 3>
dir = p_().options().dirVec();
438 if ((dir[0] * tdir.X() + dir[1] * tdir.Y() + dir[2] * tdir.Z()) < 0.) result =
true;
trkf::TrackKalmanFitter kalmanFitter
fhicl::Table< KalmanFilterTrajectoryFitter::Options > options
art::EDProducer::Table< Config > Parameters
void restoreInputPoints(const recob::TrackTrajectory &track, const std::vector< art::Ptr< recob::Hit >> &inHits, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits) const
fhicl::Table< TrackStatePropagator::Config > propagator
double VertexMomentum() const
Fit tracks using Kalman Filter fit+smooth.
void initTrackFitInfos()
initialize the output vector of TrackFitHitInfos
fhicl::Atom< bool > produceSpacePoints
static constexpr Flag_t NoPoint
The trajectory point is not defined.
T DirectionAtPoint(unsigned int p) const
Direction at point p. Use e.g. as:
fhicl::Atom< bool > pFromMC
then echo unknown compiler flag
fhicl::Atom< bool > dirFromVec
Declaration of signal hit object.
recob::tracking::SMatrixSym55 SMatrixSym55
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Class for propagation of a trkf::TrackState to a recob::tracking::Plane.
void produce(art::Event &e) override
art::InputTag simTrackInputTag
process_name use argoneut_mc_hitfinder track
std::pair< SMatrixSym55, SMatrixSym55 > Covariances() const
fhicl::Atom< bool > produceTrackFitHitInfo
fhicl::Atom< bool > alwaysInvertDir
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Vector_t VertexDirection() const
Returns the direction of the trajectory at the first point.
double Length(size_t startAt=0) const
Returns the approximate length of the trajectory.
trkf::TrackMomentumCalculator tmc
constexpr mask_t< EnumType > mask(EnumType bit, OtherBits...otherBits)
Returns a mask with all specified bits set.
TrackStatePropagator prop
A trajectory in space reconstructed from hits.
T LocationAtPoint(unsigned int p) const
Position at point p. Use e.g. as:
fhicl::Atom< double > pval
BEGIN_PROLOG vertical distance to the surface Name
double setMomValue(const recob::TrackTrajectory *ptraj, const double pMC, const int pId) const
fhicl::Atom< bool > keepInputTrajectoryPoints
Class def header for mctrack data container.
Provides recob::Track data product.
const TLorentzVector & Momentum() const
fhicl::Sequence< float, 3u > dirVec
std::vector< recob::TrackFitHitInfo > trackFitHitInfos()
get the output vector of TrackFitHitInfos by releasing and moving
const std::string & Process() const
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker options
PointFlags_t const & FlagsAtPoint(size_t i) const
const MCStep & Start() const
bool setDirFlip(const recob::TrackTrajectory *ptraj, TVector3 &mcdir) const
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
fhicl::Atom< bool > pFromLength
art::InputTag trajectoryInputTag
KalmanFilterTrajectoryFitter & operator=(KalmanFilterTrajectoryFitter const &)=delete
fhicl::Table< TrackKalmanFitter::Config > fitter
Struct holding optional TrackMaker outputs.
Set of flags pertaining a point of the track.
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
KalmanFilterTrajectoryFitter(Parameters const &p)
fhicl::Table< KalmanFilterTrajectoryFitter::Inputs > inputs
fhicl::Atom< bool > dirFromMC