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