3 #include "Pandora/PdgTable.h" 10 #include "MCCheater/BackTracker.h" 15 namespace gar_pandora {
18 : m_settings(settings),
20 m_rotation(*pRotation),
39 PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->
CreateTracks());
41 return pandora::STATUS_CODE_SUCCESS;
48 PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->
ExtractKinks(pEvent));
50 PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->
ExtractV0s(pEvent));
52 return pandora::STATUS_CODE_SUCCESS;
59 return pandora::STATUS_CODE_SUCCESS;
66 return pandora::STATUS_CODE_SUCCESS;
73 return pandora::STATUS_CODE_SUCCESS;
85 const unsigned int nTrackHits(static_cast<int>(pTrack->
NHits()));
89 PandoraApi::Track::Parameters trackParameters;
92 const float omega = trackParams[2] /
CLHEP::cm;
93 const float d0 = std::sqrt(trackParams[0]*trackParams[0] + trackParams[1]*trackParams[1]) *
CLHEP::cm;
96 trackParameters.m_pParentAddress = (
void*)pTrack;
97 trackParameters.m_d0 = d0;
98 trackParameters.m_z0 = z0;
100 trackParameters.m_particleId = (omega > 0) ? pandora::MU_PLUS : pandora::MU_MINUS;
101 trackParameters.m_mass = pandora::PdgTable::GetParticleMass(pandora::MU_PLUS);
103 if (std::numeric_limits<float>::epsilon() < std::fabs(omega))
104 trackParameters.m_charge =
static_cast<int>(omega / std::fabs(omega));
113 <<
"Creating Track " << pTrack <<
"\n" 114 <<
" starting at " << trackParameters.m_trackStateAtStart.Get() <<
"\n" 115 <<
" ending at " << trackParameters.m_trackStateAtEnd.Get() <<
"\n" 116 <<
" state at calo " << trackParameters.m_trackStateAtCalorimeter.Get() <<
"\n" 117 <<
" with momentum " << trackParameters.m_momentumAtDca.Get() <<
"\n" 118 <<
" magnitude " << trackParameters.m_momentumAtDca.Get().GetMagnitude() <<
" GeV\n" 119 <<
" can form PFO " << trackParameters.m_canFormPfo.Get() <<
"\n" 120 <<
" can form clusterless PFO " << trackParameters.m_canFormClusterlessPfo.Get() <<
"\n" 121 <<
" time at calo " << trackParameters.m_timeAtCalorimeter.Get() <<
" ns";
123 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Track::Create(
m_pandora, trackParameters));
126 catch (pandora::StatusCodeException &statusCodeException)
129 <<
"Failed to extract a track: " << statusCodeException.ToString();
134 return pandora::STATUS_CODE_SUCCESS;
142 const float omega = trackParams[2] /
CLHEP::cm;
146 const pandora::CartesianVector
momentum = pandora::CartesianVector(std::cos(trackParams[3]), std::sin(trackParams[3]), std::tan(trackParams[4])) * pt;
148 trackParameters.m_momentumAtDca = newmomentum;
156 trackParameters.m_trackStateAtStart = pandora::TrackState(newstartPosition, momentum);
157 trackParameters.m_trackStateAtEnd = pandora::TrackState(newendPosition, momentum);
159 pandora::CartesianVector calorimeterPosition(0., 0., 0.);
160 float minGenericTime(0.);
165 trackParameters.m_trackStateAtCalorimeter = pandora::TrackState(newcalorimeterPosition, momentum);
166 trackParameters.m_isProjectedToEndCap = ((std::fabs(trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetX()) <
m_settings.
m_eCalEndCapInnerZ) ?
false :
true);
169 const float particleMass(trackParameters.m_mass.Get());
170 const float particleEnergy(std::sqrt(particleMass * particleMass + trackParameters.m_momentumAtDca.Get().GetMagnitudeSquared()));
171 trackParameters.m_timeAtCalorimeter = minGenericTime * particleEnergy / 299.792f;
184 <<
"Track has Omega = 0 ";
189 const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get());
195 <<
" Dropping track : " << momentumAtDca.GetMagnitude()
196 <<
" +- " << sigmaPOverP * (momentumAtDca.GetMagnitude())
208 trackParameters.m_reachesCalorimeter =
true;
218 bool canFormPfo(
false);
219 bool canFormClusterlessPfo(
false);
221 if (trackParameters.m_reachesCalorimeter.Get() && !this->
IsParent(pTrack))
224 const float d0(std::sqrt(trackParams[0]*trackParams[0] + trackParams[1]+trackParams[1]) *
CLHEP::cm);
225 const float z0(std::fabs(pTrack->
Vertex()[0]) * CLHEP::cm);
229 const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get());
230 const bool isV0(this->
IsV0(pTrack));
231 const bool isDaughter(this->
IsDaughter(pTrack));
238 else if (isV0 || isDaughter)
244 const float particleMass(trackParameters.m_mass.Get());
245 const float trackEnergy(std::sqrt(momentumAtDca.GetMagnitudeSquared() + particleMass * particleMass));
251 canFormClusterlessPfo =
true;
253 else if (isV0 || isDaughter)
255 canFormClusterlessPfo =
true;
262 <<
"Recovering daughter or v0 track " 263 << trackParameters.m_momentumAtDca.Get().GetMagnitude();
268 <<
" -- track canFormPfo = " << canFormPfo
269 <<
" - canFormClusterlessPfo = " << canFormClusterlessPfo;
273 trackParameters.m_canFormPfo = canFormPfo;
274 trackParameters.m_canFormClusterlessPfo = canFormClusterlessPfo;
282 pandora::CartesianVector bestECalProjection(0., 0., 0);
283 float fbestECalProjection[3] = {0., 0., 0.};
float otherECALProjection[3];
287 bestECalProjection.SetValues(fbestECalProjection[0] *
CLHEP::cm, fbestECalProjection[1] * CLHEP::cm, fbestECalProjection[2] * CLHEP::cm);
291 float endcapProjection[3] = {0., 0., 0.};
294 if(result_local == 0) {
295 bestECalProjection.SetValues(endcapProjection[0] * CLHEP::cm, endcapProjection[1] * CLHEP::cm, endcapProjection[2] * CLHEP::cm);
299 if (bestECalProjection.GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
300 throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED);
302 posAtCalo = bestECalProjection;
311 const float omega = trackParams[2] /
CLHEP::cm;
312 const float tanl = std::tan(trackParams[4]);
313 const float d0(std::sqrt(trackParams[0]*trackParams[0] + trackParams[1]+trackParams[1]) *
CLHEP::cm);
314 const float z0(std::fabs(pTrack->
Vertex()[0]) * CLHEP::cm);
322 pandora::CartesianVector bestECalProjection(0.
f, 0.
f, 0.
f);
323 const int signPx((helix.
GetMomentum().GetX() > 0.f) ? 1 : -1);
327 pandora::CartesianVector barrelProjection(0.
f, 0.
f, 0.
f);
340 if ((pandora::STATUS_CODE_SUCCESS == statusCode) && (genericTime < minGenericTime))
342 minGenericTime = genericTime;
343 bestECalProjection = barrelProjection;
353 if ((pandora::STATUS_CODE_SUCCESS == statusCode) && (genericTime < minGenericTime))
355 minGenericTime = genericTime;
356 bestECalProjection = barrelProjection;
360 if (bestECalProjection.GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
361 throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED);
363 timeAtCalo = minGenericTime;
376 return pandora::STATUS_CODE_NOT_FOUND;
379 MF_LOG_DEBUG(
"TrackCreator::CreateTracks") <<
" Found: " << theTrk->size() <<
" tracks " <<
std::endl;
381 for (
unsigned int i = 0; i < theTrk->size(); ++i)
384 trkVector.push_back(trk);
387 return pandora::STATUS_CODE_SUCCESS;
393 : m_trackCollection(
"" ),
394 m_V0Collection(
"" ),
396 m_maxTrackHits(5000.
f),
397 m_d0TrackCut(2500.
f),
398 m_z0TrackCut(3000.
f),
399 m_unmatchedVertexTrackMaxEnergy(0.1
f),
400 m_d0UnmatchedVertexTrackCut(2500.
f),
401 m_z0UnmatchedVertexTrackCut(3000.
f),
402 m_minTrackECalDistanceFromIp(100.
f),
403 m_maxTrackSigmaPOverP(0.15
f),
405 m_eCalBarrelInnerSymmetry(0),
406 m_eCalBarrelInnerPhi0(0.
f),
407 m_eCalBarrelInnerR(0.
f),
408 m_eCalEndCapInnerZ(0.
f),
static constexpr double cm
float m_eCalBarrelInnerR
ECal barrel inner radius.
pandora::StatusCode CollectTracks(const art::Event &pEvent, const std::string &label, TrackVector &trkVector)
pandora::StatusCode GetPointInX(const float xPlane, const pandora::CartesianVector &referencePoint, pandora::CartesianVector &intersectionPoint) const
Get helix intersection point with a plane perpendicular to x axis.
int m_eCalBarrelInnerSymmetry
ECal barrel inner symmetry order.
float m_eCalEndCapInnerZ
ECal endcap inner z.
const RotationTransformation & m_rotation
pandora::StatusCode CreateTracks()
const float * TrackParBeg() const
unsigned int m_maxTrackHits
Track quality cut: the maximum number of track hits.
Handle< PROD > getHandle(SelectorBase const &) const
float m_d0TrackCut
Track d0 cut used to determine whether track can be used to form pfo.
const Settings m_settings
float m_minTrackECalDistanceFromIp
Sanity check on separation between ip and track projected ecal position.
#define MF_LOG_ERROR(category)
std::set< const gar::rec::Track * > TrackList
float m_bField
The bfield.
float m_z0UnmatchedVertexTrackCut
TrackCreator(const Settings &settings, const pandora::Pandora *const pPandora, const RotationTransformation *const pRotation)
float m_z0TrackCut
Track z0 cut used to determine whether track can be used to form pfo.
pandora::StatusCode GetPointOnCircle(const float radius, const pandora::CartesianVector &referencePoint, pandora::CartesianVector &intersectionPoint) const
Get coordinates of helix intersection with cylinder, aligned along z-axis.
const pandora::CartesianVector & GetMomentum() const
Get momentum of particle at the point of closest approach to IP.
bool IsV0(const gar::rec::Track *const pTrack) const
pandora::StatusCode ExtractProngsAndSplits(const art::Event &pEvent)
pandora::StatusCode CreateTrackAssociations(const art::Event &pEvent)
pandora::StatusCode ExtractKinks(const art::Event &pEvent)
const float * Vertex() const
const pandora::Pandora & m_pandora
static int PropagateToX(const float *trackpar, const float *Xpoint, const float x, float *retXYZ, const float Rmax=0.0)
const pandora::CartesianVector & GetReferencePoint() const
Get reference point of track.
const float * TrackParEnd() const
static int PropagateToCylinder(const float *trackpar, const float *Xpoint, const float rCyl, const float yCyl, const float zCyl, float *retXYZ1, float *retXYZ2, const float Xmax=0.0, const float epsilon=2.0e-5)
bool IsParent(const gar::rec::Track *const pTrack) const
static int max(int a, int b)
float m_eCalBarrelInnerPhi0
ECal barrel inner phi 0.
float const & ChisqForward() const
const float * End() const
bool PassesQualityCuts(const gar::rec::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const
Interface to propagate a Track to the specific point.
pandora::StatusCode GetPointInZY(const float z0, const float y0, const float az, const float ay, const pandora::CartesianVector &referencePoint, pandora::CartesianVector &intersectionPoint) const
Get helix intersection point with a plane parallel to x axis. The plane is defined by two coordinates...
General GArSoft Utilities.
unsigned int m_minTrackHits
Track quality cut: the minimum number of track hits.
void GetTrackStates(const gar::rec::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const
float m_d0UnmatchedVertexTrackCut
std::string m_trackCollection
The reconstructed track collection.
pandora::StatusCode ExtractV0s(const art::Event &pEvent)
float m_unmatchedVertexTrackMaxEnergy
void CalculateTrackStateAtCalo(const gar::rec::Track *const pTrack, pandora::CartesianVector &posAtCalo) const
void TrackReachesECAL(const gar::rec::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const
std::vector< art::Ptr< gar::rec::Track > > TrackVector
size_t const & NHits() const
float m_maxTrackSigmaPOverP
Track fraction momentum error cut.
bool IsDaughter(const gar::rec::Track *const pTrack) const
#define MF_LOG_WARNING(category)
const float * CovMatEndPacked() const
def momentum(x1, x2, x3, scale=1.)
TrackVector m_trackVector
std::vector< gar::rec::Track > RawTrackVector
QTextStream & endl(QTextStream &s)
void CalculateTimeAtCalo(const gar::rec::Track *const pTrack, float &timeAtCalo) const
void DefineTrackPfoUsage(const gar::rec::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const