CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Classes | Public Types | Public Member Functions | Protected Types | Protected Member Functions | Static Protected Attributes | Private Types | Private Attributes | Static Private Attributes
SteppingHelixPropagator Class Reference

#include <SteppingHelixPropagator.h>

Inheritance diagram for SteppingHelixPropagator:
Propagator

Classes

struct  Basis
 

Public Types

enum  DestType {
  RADIUS_DT =0, Z_DT, PLANE_DT, CONE_DT,
  CYLINDER_DT, PATHL_DT, POINT_PCA_DT, LINE_PCA_DT,
  UNDEFINED_DT
}
 
enum  Fancy {
  HEL_AS_F =0, HEL_ALL_F, POL_1_F, POL_2_F,
  POL_M_F
}
 
enum  Pars { RADIUS_P =0, Z_P = 0, PATHL_P = 0 }
 
typedef CLHEP::Hep3Vector Point
 
typedef
SteppingHelixStateInfo::Result 
Result
 
typedef SteppingHelixStateInfo StateInfo
 
typedef CLHEP::Hep3Vector Vector
 

Public Member Functions

void applyRadX0Correction (bool applyRadX0Correction)
 
virtual SteppingHelixPropagatorclone () const override
 
virtual const MagneticFieldmagneticField () const override
 
void propagate (const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
 Propagate to Plane given a starting point. More...
 
void propagate (const SteppingHelixStateInfo &ftsStart, const Plane &pDest, SteppingHelixStateInfo &out) const
 
void propagate (const SteppingHelixStateInfo &ftsStart, const Cylinder &cDest, SteppingHelixStateInfo &out) const
 Propagate to Cylinder given a starting point (a Cylinder is assumed to be positioned at 0,0,0) More...
 
void propagate (const SteppingHelixStateInfo &ftsStart, const GlobalPoint &pDest, SteppingHelixStateInfo &out) const
 Propagate to PCA to point given a starting point. More...
 
void propagate (const SteppingHelixStateInfo &ftsStart, const GlobalPoint &pDest1, const GlobalPoint &pDest2, SteppingHelixStateInfo &out) const
 Propagate to PCA to a line (given by 2 points) given a starting point. More...
 
virtual std::pair
< TrajectoryStateOnSurface,
double > 
propagateWithPath (const FreeTrajectoryState &ftsStart, const Plane &pDest) const override
 
virtual std::pair
< TrajectoryStateOnSurface,
double > 
propagateWithPath (const FreeTrajectoryState &ftsStart, const Cylinder &cDest) const override
 
virtual std::pair
< FreeTrajectoryState, double > 
propagateWithPath (const FreeTrajectoryState &ftsStart, const GlobalPoint &pDest) const override
 Propagate to PCA to point given a starting point. More...
 
virtual std::pair
< FreeTrajectoryState, double > 
propagateWithPath (const FreeTrajectoryState &ftsStart, const GlobalPoint &pDest1, const GlobalPoint &pDest2) const override
 Propagate to PCA to a line (given by 2 points) given a starting point. More...
 
virtual std::pair
< FreeTrajectoryState, double > 
propagateWithPath (const FreeTrajectoryState &ftsStart, const reco::BeamSpot &beamSpot) const override
 Propagate to PCA to a line (given by beamSpot position and slope) given a starting point. More...
 
void setDebug (bool debug)
 Switch debug printouts (to cout) .. very verbose. More...
 
void setEndcapShiftsInZPosNeg (double valPos, double valNeg)
 set shifts in Z for endcap pieces (includes EE, HE, ME, YE) More...
 
void setMaterialMode (bool noMaterial)
 Switch for material effects mode: no material effects if true. More...
 
void setNoErrorPropagation (bool noErrorPropagation)
 Force no error propagation. More...
 
void setReturnTangentPlane (bool val)
 flag to return tangent plane for non-plane input More...
 
void setSendLogWarning (bool val)
 flag to send LogWarning on failures More...
 
void setUseInTeslaFromMagField (bool val)
 force getting field value from MagneticField, not the geometric one More...
 
void setUseIsYokeFlag (bool val)
 
void setUseMagVolumes (bool val)
 Switch to using MagneticField Volumes .. as in VolumeBasedMagneticField. More...
 
void setUseMatVolumes (bool val)
 Switch to using Material Volumes .. internally defined for now. More...
 
void setUseTuningForL2Speed (bool val)
 
void setVBFPointer (const VolumeBasedMagneticField *val)
 
 SteppingHelixPropagator ()
 Constructors. More...
 
 SteppingHelixPropagator (const MagneticField *field, PropagationDirection dir=alongMomentum)
 
virtual ~SteppingHelixPropagator ()
 Destructor. More...
 
- Public Member Functions inherited from Propagator
virtual FreeTrajectoryState propagate (const FreeTrajectoryState &ftsStart, const GlobalPoint &pDest) const final
 
virtual FreeTrajectoryState propagate (const FreeTrajectoryState &ftsStart, const GlobalPoint &pDest1, const GlobalPoint &pDest2) const final
 
virtual FreeTrajectoryState propagate (const FreeTrajectoryState &ftsStart, const reco::BeamSpot &beamSpot) const final
 
virtual std::pair
< TrajectoryStateOnSurface,
double > 
propagateWithPath (const FreeTrajectoryState &, const Surface &) const final
 
virtual std::pair
< TrajectoryStateOnSurface,
double > 
propagateWithPath (const TrajectoryStateOnSurface &tsos, const Surface &sur) const final
 
virtual std::pair
< TrajectoryStateOnSurface,
double > 
propagateWithPath (const TrajectoryStateOnSurface &tsos, const Plane &sur) const
 
virtual std::pair
< TrajectoryStateOnSurface,
double > 
propagateWithPath (const TrajectoryStateOnSurface &tsos, const Cylinder &sur) const
 
virtual PropagationDirection propagationDirection () const
 
 Propagator (PropagationDirection dir=alongMomentum)
 
virtual bool setMaxDirectionChange (float phiMax)
 
virtual void setPropagationDirection (PropagationDirection dir)
 
virtual ~Propagator ()
 

Protected Types

typedef
SteppingHelixStateInfo::VolumeBounds 
MatBounds
 
typedef StateInfo StateArray [MAX_POINTS+1]
 

Protected Member Functions

int cIndex_ (int ind) const
 (Internals) circular index for array of transients More...
 
double getDeDx (const SteppingHelixPropagator::StateInfo &sv, double &dEdXPrime, double &radX0, MatBounds &rzLims) const
 estimate average (in fact smth. close to MPV and median) energy loss per unit path length More...
 
void getNextState (const SteppingHelixPropagator::StateInfo &svPrevious, SteppingHelixPropagator::StateInfo &svNext, double dP, const SteppingHelixPropagator::Vector &tau, const SteppingHelixPropagator::Vector &drVec, double dS, double dX0, const AlgebraicMatrix55 &dCovCurv) const
 
void initStateArraySHPSpecific (StateArray &svBuf, bool flagsOnly) const
 (Internals) set defaults needed for states used inside propagate methods More...
 
bool isYokeVolume (const MagVolume *vol) const
 check if it's a yoke/iron based on this MagVol internals More...
 
void loadState (SteppingHelixPropagator::StateInfo &svCurrent, const SteppingHelixPropagator::Vector &p3, const SteppingHelixPropagator::Point &r3, int charge, PropagationDirection dir, const AlgebraicSymMatrix55 &covCurv) const
 
bool makeAtomStep (SteppingHelixPropagator::StateInfo &svCurrent, SteppingHelixPropagator::StateInfo &svNext, double dS, PropagationDirection dir, SteppingHelixPropagator::Fancy fancy) const
 main stepping function: compute next state vector after a step of length dS More...
 
Result propagate (StateArray &svBuff, int &nPoints, SteppingHelixPropagator::DestType type, const double pars[6], double epsilon=1e-3) const
 
Result refToDest (DestType dest, const SteppingHelixPropagator::StateInfo &sv, const double pars[6], double &dist, double &tanDist, PropagationDirection &refDirection, double fastSkipDist=1e12) const
 (Internals) determine distance and direction from the current position to the plane More...
 
Result refToMagVolume (const SteppingHelixPropagator::StateInfo &sv, PropagationDirection dir, double &dist, double &tanDist, double fastSkipDist=1e12, bool expectNewMagVolume=false, double maxStep=1e12) const
 
Result refToMatVolume (const SteppingHelixPropagator::StateInfo &sv, PropagationDirection dir, double &dist, double &tanDist, double fastSkipDist=1e12) const
 
void setIState (const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
 (Internals) Init starting point More...
 
void setRep (SteppingHelixPropagator::Basis &rep, const SteppingHelixPropagator::Vector &tau) const
 Set/compute basis vectors for local coordinates at current step (called by incrementState) More...
 

Static Protected Attributes

static const int MAX_POINTS = 7
 

Private Types

typedef std::pair
< FreeTrajectoryState, double > 
FtsPP
 
typedef std::pair
< TrajectoryStateOnSurface,
double > 
TsosPP
 

Private Attributes

bool applyRadX0Correction_
 
bool debug_
 
double defaultStep_
 
double ecShiftNeg_
 
double ecShiftPos_
 
const MagneticFieldfield_
 
StateInfo invalidState_
 
bool noErrorPropagation_
 
bool noMaterialMode_
 
bool returnTangentPlane_
 
bool sendLogWarning_
 
const AlgebraicSymMatrix55 unit55_
 
bool useInTeslaFromMagField_
 
bool useIsYokeFlag_
 
bool useMagVolumes_
 
bool useMatVolumes_
 
bool useTuningForL2Speed_
 
const VolumeBasedMagneticFieldvbField_
 

Static Private Attributes

static const int MAX_STEPS = 10000
 

Detailed Description

Propagator implementation using steps along a helix. Minimal geometry navigation. Material effects (multiple scattering and energy loss) are based on tuning to MC and (eventually) data.

Author
Vyacheslav Krutelyov (slava77)

Propagator implementation using steps along a helix. Minimal geometry navigation. Material effects (multiple scattering and energy loss) are based on tuning to MC and (eventually) data. Implementation file contents follow.

Author
Vyacheslav Krutelyov (slava77)

Definition at line 41 of file SteppingHelixPropagator.h.

Member Typedef Documentation

typedef std::pair<FreeTrajectoryState, double> SteppingHelixPropagator::FtsPP
private

Definition at line 260 of file SteppingHelixPropagator.h.

Definition at line 185 of file SteppingHelixPropagator.h.

typedef CLHEP::Hep3Vector SteppingHelixPropagator::Point

Definition at line 44 of file SteppingHelixPropagator.h.

Definition at line 47 of file SteppingHelixPropagator.h.

typedef StateInfo SteppingHelixPropagator::StateArray[MAX_POINTS+1]
protected

Definition at line 187 of file SteppingHelixPropagator.h.

Definition at line 46 of file SteppingHelixPropagator.h.

typedef std::pair<TrajectoryStateOnSurface, double> SteppingHelixPropagator::TsosPP
private

Definition at line 259 of file SteppingHelixPropagator.h.

typedef CLHEP::Hep3Vector SteppingHelixPropagator::Vector

Definition at line 43 of file SteppingHelixPropagator.h.

Member Enumeration Documentation

Enumerator
HEL_AS_F 
HEL_ALL_F 
POL_1_F 
POL_2_F 
POL_M_F 

Definition at line 73 of file SteppingHelixPropagator.h.

73  {
74  HEL_AS_F=0, //simple analytical helix, eloss at end of step
75  HEL_ALL_F, //analytical helix with linear eloss
76  POL_1_F, //1st order approximation, straight line
77  POL_2_F,//2nd order
78  POL_M_F //highest available
79  };
Enumerator
RADIUS_P 
Z_P 
PATHL_P 

Definition at line 55 of file SteppingHelixPropagator.h.

Constructor & Destructor Documentation

SteppingHelixPropagator::SteppingHelixPropagator ( )

Constructors.

Definition at line 60 of file SteppingHelixPropagator.cc.

References field_.

Referenced by clone().

60  :
62 {
63  field_ = 0;
64 }
Propagator(PropagationDirection dir=alongMomentum)
Definition: Propagator.h:48
const MagneticField * field_
SteppingHelixPropagator::SteppingHelixPropagator ( const MagneticField field,
PropagationDirection  dir = alongMomentum 
)

Definition at line 66 of file SteppingHelixPropagator.cc.

References applyRadX0Correction_, debug_, defaultStep_, ecShiftNeg_, ecShiftPos_, field_, noErrorPropagation_, noMaterialMode_, returnTangentPlane_, sendLogWarning_, useInTeslaFromMagField_, useIsYokeFlag_, useMagVolumes_, useMatVolumes_, useTuningForL2Speed_, and vbField_.

67  :
68  Propagator(dir),
70 {
71  field_ = field;
72  vbField_ = dynamic_cast<const VolumeBasedMagneticField*>(field_);
73  debug_ = false;
74  noMaterialMode_ = false;
75  noErrorPropagation_ = false;
76  applyRadX0Correction_ = true;
77  useMagVolumes_ = true;
78  useIsYokeFlag_ = true;
79  useMatVolumes_ = true;
80  useInTeslaFromMagField_ = false; //overrides behavior only if true
81  returnTangentPlane_ = true;
82  sendLogWarning_ = false;
83  useTuningForL2Speed_ = false;
84  defaultStep_ = 5.;
85 
86  ecShiftPos_ = 0;
87  ecShiftNeg_ = 0;
88 
89 }
Propagator(PropagationDirection dir=alongMomentum)
Definition: Propagator.h:48
ROOT::Math::SMatrixIdentity AlgebraicMatrixID
const VolumeBasedMagneticField * vbField_
const AlgebraicSymMatrix55 unit55_
dbl *** dir
Definition: mlp_gen.cc:35
const MagneticField * field_
SteppingHelixPropagator::~SteppingHelixPropagator ( )
virtual

Destructor.

Definition at line 57 of file SteppingHelixPropagator.cc.

57 {}

Member Function Documentation

void SteppingHelixPropagator::applyRadX0Correction ( bool  applyRadX0Correction)
inline

Apply radLength correction (1+0.036*ln(radX0+1)) to covariance matrix +1 is added for IR-safety Should be done with care: it's easy to make the end-point result dependent on the intermediate stop points

Definition at line 149 of file SteppingHelixPropagator.h.

References applyRadX0Correction(), and applyRadX0Correction_.

Referenced by applyRadX0Correction(), TrackDetectorAssociator::init(), HTrackAssociator::init(), SteppingHelixPropagatorESProducer::produce(), and AlCaHOCalibProducer::produce().

int SteppingHelixPropagator::cIndex_ ( int  ind) const
protected

(Internals) circular index for array of transients

Definition at line 1658 of file SteppingHelixPropagator.cc.

References MAX_POINTS, and query::result.

Referenced by propagate(), and setIState().

1658  {
1659  int result = ind%MAX_POINTS;
1660  if (ind != 0 && result == 0){
1661  result = MAX_POINTS;
1662  }
1663  return result;
1664 }
tuple result
Definition: query.py:137
virtual SteppingHelixPropagator* SteppingHelixPropagator::clone ( void  ) const
inlineoverridevirtual

Implements Propagator.

Definition at line 85 of file SteppingHelixPropagator.h.

References SteppingHelixPropagator().

85 {return new SteppingHelixPropagator(*this);}
double SteppingHelixPropagator::getDeDx ( const SteppingHelixPropagator::StateInfo sv,
double &  dEdXPrime,
double &  radX0,
MatBounds rzLims 
) const
protected

estimate average (in fact smth. close to MPV and median) energy loss per unit path length

Definition at line 1298 of file SteppingHelixPropagator.cc.

References SteppingHelixStateInfo::bf, alignCSCRings::e, ecShiftNeg_, ecShiftPos_, SteppingHelixStateInfo::isYokeVol, log, SteppingHelixStateInfo::magVol, noMaterialMode_, SteppingHelixStateInfo::p3, SteppingHelixStateInfo::r3, mathSSE::sqrt(), useIsYokeFlag_, and useMagVolumes_.

Referenced by getNextState(), loadState(), and makeAtomStep().

1300  {
1301  radX0 = 1.e24;
1302  dEdXPrime = 0.;
1303  rzLims = MatBounds();
1304  if (noMaterialMode_) return 0;
1305 
1306  double dEdx = 0.;
1307 
1308  double lR = sv.r3.perp();
1309  double lZ = fabs(sv.r3.z());
1310 
1311  //assume "Iron" .. seems to be quite the same for brass/iron/PbW04
1312  //good for Fe within 3% for 0.2 GeV to 10PeV
1313 
1314  double dEdX_HCal = 0.95; //extracted from sim
1315  double dEdX_ECal = 0.45;
1316  double dEdX_coil = 0.35; //extracted from sim .. closer to 40% in fact
1317  double dEdX_Fe = 1;
1318  double dEdX_MCh = 0.053; //chambers on average
1319  double dEdX_Trk = 0.0114;
1320  double dEdX_Air = 2E-4;
1321  double dEdX_Vac = 0.0;
1322 
1323  double radX0_HCal = 1.44/0.8; //guessing
1324  double radX0_ECal = 0.89/0.7;
1325  double radX0_coil = 4.; //
1326  double radX0_Fe = 1.76;
1327  double radX0_MCh = 1e3; //
1328  double radX0_Trk = 320.;
1329  double radX0_Air = 3.e4;
1330  double radX0_Vac = 3.e9; //"big" number for vacuum
1331 
1332 
1333  //not all the boundaries are set below: this will be a default
1334  if (! (lR < 380 && lZ < 785)){
1335  if (lZ > 785 ) rzLims = MatBounds(0, 1e4, 785, 1e4);
1336  if (lZ < 785 ) rzLims = MatBounds(380, 1e4, 0, 785);
1337  }
1338 
1339  //this def makes sense assuming we don't jump into endcap volume from the other z-side in one step
1340  //also, it is a positive shift only (at least for now): can't move ec further into the detector
1341  double ecShift = sv.r3.z() > 0 ? fabs(ecShiftPos_) : fabs(ecShiftNeg_);
1342 
1343  //this should roughly figure out where things are
1344  //(numbers taken from Fig1.1.2 TDR and from geom xmls)
1345  if (lR < 2.9){ //inside beampipe
1346  dEdx = dEdX_Vac; radX0 = radX0_Vac;
1347  rzLims = MatBounds(0, 2.9, 0, 1E4);
1348  }
1349  else if (lR < 129){
1350  if (lZ < 294){
1351  rzLims = MatBounds(2.9, 129, 0, 294); //tracker boundaries
1352  dEdx = dEdX_Trk; radX0 = radX0_Trk;
1353  //somewhat empirical formula that ~ matches the average if going from 0,0,0
1354  //assuming "uniform" tracker material
1355  //doesn't really track material layer to layer
1356  double lEtaDet = fabs(sv.r3.eta());
1357  double scaleRadX = lEtaDet > 1.5 ? 0.7724 : 1./cosh(0.5*lEtaDet);//sin(2.*atan(exp(-0.5*lEtaDet)));
1358  scaleRadX *= scaleRadX;
1359  if (lEtaDet > 2 && lZ > 20) scaleRadX *= (lEtaDet-1.);
1360  if (lEtaDet > 2.5 && lZ > 20) scaleRadX *= (lEtaDet-1.);
1361  radX0 *= scaleRadX;
1362  }
1363  //endcap part begins here
1364  else if ( lZ < 294 + ecShift ){
1365  //gap in front of EE here, piece inside 2.9<R<129
1366  rzLims = MatBounds(2.9, 129, 294, 294 + ecShift);
1367  dEdx = dEdX_Air; radX0 = radX0_Air;
1368  }
1369  else if (lZ < 372 + ecShift){
1370  rzLims = MatBounds(2.9, 129, 294 + ecShift, 372 + ecShift); //EE here, piece inside 2.9<R<129
1371  dEdx = dEdX_ECal; radX0 = radX0_ECal;
1372  }//EE averaged out over a larger space
1373  else if (lZ < 398 + ecShift){
1374  rzLims = MatBounds(2.9, 129, 372 + ecShift, 398 + ecShift); //whatever goes behind EE 2.9<R<129 is air up to Z=398
1375  dEdx = dEdX_HCal*0.05; radX0 = radX0_Air;
1376  }//betw EE and HE
1377  else if (lZ < 555 + ecShift){
1378  rzLims = MatBounds(2.9, 129, 398 + ecShift, 555 + ecShift); //HE piece 2.9<R<129;
1379  dEdx = dEdX_HCal*0.96; radX0 = radX0_HCal/0.96;
1380  } //HE calor abit less dense
1381  else {
1382  // rzLims = MatBounds(2.9, 129, 555, 785);
1383  // set the boundaries first: they serve as stop-points here
1384  // the material is set below
1385  if (lZ < 568 + ecShift) rzLims = MatBounds(2.9, 129, 555 + ecShift, 568 + ecShift); //a piece of HE support R<129, 555<Z<568
1386  else if (lZ < 625 + ecShift){
1387  if (lR < 85 + ecShift) rzLims = MatBounds(2.9, 85, 568 + ecShift, 625 + ecShift);
1388  else rzLims = MatBounds(85, 129, 568 + ecShift, 625 + ecShift);
1389  } else if (lZ < 785 + ecShift) rzLims = MatBounds(2.9, 129, 625 + ecShift, 785 + ecShift);
1390  else if (lZ < 1500 + ecShift) rzLims = MatBounds(2.9, 129, 785 + ecShift, 1500 + ecShift);
1391  else rzLims = MatBounds(2.9, 129, 1500 + ecShift, 1E4);
1392 
1393  //iron .. don't care about no material in front of HF (too forward)
1394  if (! (lZ > 568 + ecShift && lZ < 625 + ecShift && lR > 85 ) // HE support
1395  && ! (lZ > 785 + ecShift && lZ < 850 + ecShift && lR > 118)) {dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1396  else { dEdx = dEdX_MCh; radX0 = radX0_MCh; } //ME at eta > 2.2
1397  }
1398  }
1399  else if (lR < 287){
1400  if (lZ < 372 + ecShift && lR < 177){ // 129<<R<177
1401  if (lZ < 304) rzLims = MatBounds(129, 177, 0, 304); //EB 129<<R<177 0<Z<304
1402  else if (lZ < 343){ // 129<<R<177 304<Z<343
1403  if (lR < 135 ) rzLims = MatBounds(129, 135, 304, 343);// tk piece 129<<R<135 304<Z<343
1404  else if (lR < 172 ){ //
1405  if (lZ < 311 ) rzLims = MatBounds(135, 172, 304, 311);
1406  else rzLims = MatBounds(135, 172, 311, 343);
1407  } else {
1408  if (lZ < 328) rzLims = MatBounds(172, 177, 304, 328);
1409  else rzLims = MatBounds(172, 177, 328, 343);
1410  }
1411  }
1412  else if ( lZ < 343 + ecShift){
1413  rzLims = MatBounds(129, 177, 343, 343 + ecShift); //gap
1414  }
1415  else {
1416  if (lR < 156 ) rzLims = MatBounds(129, 156, 343 + ecShift, 372 + ecShift);
1417  else if ( (lZ - 343 - ecShift) > (lR - 156)*1.38 )
1418  rzLims = MatBounds(156, 177, 127.72 + ecShift, 372 + ecShift, atan(1.38), 0);
1419  else rzLims = MatBounds(156, 177, 343 + ecShift, 127.72 + ecShift, 0, atan(1.38));
1420  }
1421 
1422  if (!(lR > 135 && lZ <343 + ecShift && lZ > 304 )
1423  && ! (lR > 156 && lZ < 372 + ecShift && lZ > 343 + ecShift && ((lZ-343. - ecShift )< (lR-156.)*1.38)))
1424  {
1425  //the crystals are the same length, but they are not 100% of material
1426  double cosThetaEquiv = 0.8/sqrt(1.+lZ*lZ/lR/lR) + 0.2;
1427  if (lZ > 343) cosThetaEquiv = 1.;
1428  dEdx = dEdX_ECal*cosThetaEquiv; radX0 = radX0_ECal/cosThetaEquiv;
1429  } //EB
1430  else {
1431  if ( (lZ > 304 && lZ < 328 && lR < 177 && lR > 135)
1432  && ! (lZ > 311 && lR < 172) ) {dEdx = dEdX_Fe; radX0 = radX0_Fe; } //Tk_Support
1433  else if ( lZ > 343 && lZ < 343 + ecShift) { dEdx = dEdX_Air; radX0 = radX0_Air; }
1434  else {dEdx = dEdX_ECal*0.2; radX0 = radX0_Air;} //cables go here <-- will be abit too dense for ecShift > 0
1435  }
1436  }
1437  else if (lZ < 554 + ecShift){ // 129<R<177 372<Z<554 AND 177<R<287 0<Z<554
1438  if (lR < 177){ // 129<R<177 372<Z<554
1439  if ( lZ > 372 + ecShift && lZ < 398 + ecShift )rzLims = MatBounds(129, 177, 372 + ecShift, 398 + ecShift); // EE 129<R<177 372<Z<398
1440  else if (lZ < 548 + ecShift) rzLims = MatBounds(129, 177, 398 + ecShift, 548 + ecShift); // HE 129<R<177 398<Z<548
1441  else rzLims = MatBounds(129, 177, 548 + ecShift, 554 + ecShift); // HE gap 129<R<177 548<Z<554
1442  }
1443  else if (lR < 193){ // 177<R<193 0<Z<554
1444  if ((lZ - 307) < (lR - 177.)*1.739) rzLims = MatBounds(177, 193, 0, -0.803, 0, atan(1.739));
1445  else if ( lZ < 389) rzLims = MatBounds(177, 193, -0.803, 389, atan(1.739), 0.);
1446  else if ( lZ < 389 + ecShift) rzLims = MatBounds(177, 193, 389, 389 + ecShift); // air insert
1447  else if ( lZ < 548 + ecShift ) rzLims = MatBounds(177, 193, 389 + ecShift, 548 + ecShift);// HE 177<R<193 389<Z<548
1448  else rzLims = MatBounds(177, 193, 548 + ecShift, 554 + ecShift); // HE gap 177<R<193 548<Z<554
1449  }
1450  else if (lR < 264){ // 193<R<264 0<Z<554
1451  double anApex = 375.7278 - 193./1.327; // 230.28695599096
1452  if ( (lZ - 375.7278) < (lR - 193.)/1.327) rzLims = MatBounds(193, 264, 0, anApex, 0, atan(1./1.327)); //HB
1453  else if ( (lZ - 392.7278 ) < (lR - 193.)/1.327)
1454  rzLims = MatBounds(193, 264, anApex, anApex+17., atan(1./1.327), atan(1./1.327)); // HB-HE gap
1455  else if ( (lZ - 392.7278 - ecShift ) < (lR - 193.)/1.327)
1456  rzLims = MatBounds(193, 264, anApex+17., anApex+17. + ecShift, atan(1./1.327), atan(1./1.327)); // HB-HE gap air insert
1457  // HE (372,193)-(517,193)-(517,264)-(417.8,264)
1458  else if ( lZ < 517 + ecShift ) rzLims = MatBounds(193, 264, anApex+17. + ecShift, 517 + ecShift, atan(1./1.327), 0);
1459  else if (lZ < 548 + ecShift){ // HE+gap 193<R<264 517<Z<548
1460  if (lR < 246 ) rzLims = MatBounds(193, 246, 517 + ecShift, 548 + ecShift); // HE 193<R<246 517<Z<548
1461  else rzLims = MatBounds(246, 264, 517 + ecShift, 548 + ecShift); // HE gap 246<R<264 517<Z<548
1462  }
1463  else rzLims = MatBounds(193, 264, 548 + ecShift, 554 + ecShift); // HE gap 193<R<246 548<Z<554
1464  }
1465  else if ( lR < 275){ // 264<R<275 0<Z<554
1466  if (lZ < 433) rzLims = MatBounds(264, 275, 0, 433); //HB
1467  else if (lZ < 554 ) rzLims = MatBounds(264, 275, 433, 554); // HE gap 264<R<275 433<Z<554
1468  else rzLims = MatBounds(264, 275, 554, 554 + ecShift); // HE gap 264<R<275 554<Z<554 air insert
1469  }
1470  else { // 275<R<287 0<Z<554
1471  if (lZ < 402) rzLims = MatBounds(275, 287, 0, 402);// HB 275<R<287 0<Z<402
1472  else if (lZ < 554) rzLims = MatBounds(275, 287, 402, 554);// //HE gap 275<R<287 402<Z<554
1473  else rzLims = MatBounds(275, 287, 554, 554 + ecShift); //HE gap 275<R<287 554<Z<554 air insert
1474  }
1475 
1476  if ((lZ < 433 || lR < 264) && (lZ < 402 || lR < 275) && (lZ < 517 + ecShift || lR < 246) //notches
1477  //I should've made HE and HF different .. now need to shorten HE to match
1478  && lZ < 548 + ecShift
1479  && ! (lZ < 389 + ecShift && lZ > 335 && lR < 193 ) //not a gap EB-EE 129<R<193
1480  && ! (lZ > 307 && lZ < 335 && lR < 193 && ((lZ - 307) > (lR - 177.)*1.739)) //not a gap
1481  && ! (lR < 177 && lZ < 398 + ecShift) //under the HE nose
1482  && ! (lR < 264 && lR > 193 && fabs(441.5+0.5*ecShift - lZ + (lR - 269.)/1.327) < (8.5 + ecShift*0.5)) ) //not a gap
1483  { dEdx = dEdX_HCal; radX0 = radX0_HCal; //hcal
1484  }
1485  else if( (lR < 193 && lZ > 389 && lZ < 389 + ecShift ) || (lR > 264 && lR < 287 && lZ > 554 && lZ < 554 + ecShift)
1486  ||(lR < 264 && lR > 193 && fabs(441.5+8.5+0.5*ecShift - lZ + (lR - 269.)/1.327) < ecShift*0.5) ) {
1487  dEdx = dEdX_Air; radX0 = radX0_Air;
1488  }
1489  else {dEdx = dEdX_HCal*0.05; radX0 = radX0_Air; }//endcap gap
1490  }
1491  //the rest is a tube of endcap volume 129<R<251 554<Z<largeValue
1492  else if (lZ < 564 + ecShift){ // 129<R<287 554<Z<564
1493  if (lR < 251) {
1494  rzLims = MatBounds(129, 251, 554 + ecShift, 564 + ecShift); // HE support 129<R<251 554<Z<564
1495  dEdx = dEdX_Fe; radX0 = radX0_Fe;
1496  }//HE support
1497  else {
1498  rzLims = MatBounds(251, 287, 554 + ecShift, 564 + ecShift); //HE/ME gap 251<R<287 554<Z<564
1499  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1500  }
1501  }
1502  else if (lZ < 625 + ecShift){ // ME/1/1 129<R<287 564<Z<625
1503  rzLims = MatBounds(129, 287, 564 + ecShift, 625 + ecShift);
1504  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1505  }
1506  else if (lZ < 785 + ecShift){ //129<R<287 625<Z<785
1507  if (lR < 275) rzLims = MatBounds(129, 275, 625 + ecShift, 785 + ecShift); //YE/1 129<R<275 625<Z<785
1508  else { // 275<R<287 625<Z<785
1509  if (lZ < 720 + ecShift) rzLims = MatBounds(275, 287, 625 + ecShift, 720 + ecShift); // ME/1/2 275<R<287 625<Z<720
1510  else rzLims = MatBounds(275, 287, 720 + ecShift, 785 + ecShift); // YE/1 275<R<287 720<Z<785
1511  }
1512  if (! (lR > 275 && lZ < 720 + ecShift)) { dEdx = dEdX_Fe; radX0 = radX0_Fe; }//iron
1513  else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1514  }
1515  else if (lZ < 850 + ecShift){
1516  rzLims = MatBounds(129, 287, 785 + ecShift, 850 + ecShift);
1517  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1518  }
1519  else if (lZ < 910 + ecShift){
1520  rzLims = MatBounds(129, 287, 850 + ecShift, 910 + ecShift);
1521  dEdx = dEdX_Fe; radX0 = radX0_Fe;
1522  }//iron
1523  else if (lZ < 975 + ecShift){
1524  rzLims = MatBounds(129, 287, 910 + ecShift, 975 + ecShift);
1525  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1526  }
1527  else if (lZ < 1000 + ecShift){
1528  rzLims = MatBounds(129, 287, 975 + ecShift, 1000 + ecShift);
1529  dEdx = dEdX_Fe; radX0 = radX0_Fe;
1530  }//iron
1531  else if (lZ < 1063 + ecShift){
1532  rzLims = MatBounds(129, 287, 1000 + ecShift, 1063 + ecShift);
1533  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1534  }
1535  else if ( lZ < 1073 + ecShift){
1536  rzLims = MatBounds(129, 287, 1063 + ecShift, 1073 + ecShift);
1537  dEdx = dEdX_Fe; radX0 = radX0_Fe;
1538  }
1539  else if (lZ < 1E4 ) {
1540  rzLims = MatBounds(129, 287, 1073 + ecShift, 1E4);
1541  dEdx = dEdX_Air; radX0 = radX0_Air;
1542  }
1543  else {
1544 
1545  dEdx = dEdX_Air; radX0 = radX0_Air;
1546  }
1547  }
1548  else if (lR <380 && lZ < 667){
1549  if (lZ < 630){
1550  if (lR < 315) rzLims = MatBounds(287, 315, 0, 630);
1551  else if (lR < 341 ) rzLims = MatBounds(315, 341, 0, 630); //b-field ~linear rapid fall here
1552  else rzLims = MatBounds(341, 380, 0, 630);
1553  } else rzLims = MatBounds(287, 380, 630, 667);
1554 
1555  if (lZ < 630) { dEdx = dEdX_coil; radX0 = radX0_coil; }//a guess for the solenoid average
1556  else {dEdx = dEdX_Air; radX0 = radX0_Air; }//endcap gap
1557  }
1558  else {
1559  if (lZ < 667) {
1560  if (lR < 850){
1561  bool isIron = false;
1562  //sanity check in addition to flags
1563  if (useIsYokeFlag_ && useMagVolumes_ && sv.magVol != 0){
1564  isIron = sv.isYokeVol;
1565  } else {
1566  double bMag = sv.bf.mag();
1567  isIron = (bMag > 0.75 && ! (lZ > 500 && lR <500 && bMag < 1.15)
1568  && ! (lZ < 450 && lR > 420 && bMag < 1.15 ) );
1569  }
1570  //tell the material stepper where mat bounds are
1571  rzLims = MatBounds(380, 850, 0, 667);
1572  if (isIron) { dEdx = dEdX_Fe; radX0 = radX0_Fe; }//iron
1573  else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1574  } else {
1575  rzLims = MatBounds(850, 1E4, 0, 667);
1576  dEdx = dEdX_Air; radX0 = radX0_Air;
1577  }
1578  }
1579  else if (lR > 750 ){
1580  rzLims = MatBounds(750, 1E4, 667, 1E4);
1581  dEdx = dEdX_Air; radX0 = radX0_Air;
1582  }
1583  else if (lZ < 667 + ecShift){
1584  rzLims = MatBounds(287, 750, 667, 667 + ecShift);
1585  dEdx = dEdX_Air; radX0 = radX0_Air;
1586  }
1587  //the rest is endcap piece with 287<R<750 Z>667
1588  else if (lZ < 724 + ecShift){
1589  if (lR < 380 ) rzLims = MatBounds(287, 380, 667 + ecShift, 724 + ecShift);
1590  else rzLims = MatBounds(380, 750, 667 + ecShift, 724 + ecShift);
1591  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1592  }
1593  else if (lZ < 785 + ecShift){
1594  if (lR < 380 ) rzLims = MatBounds(287, 380, 724 + ecShift, 785 + ecShift);
1595  else rzLims = MatBounds(380, 750, 724 + ecShift, 785 + ecShift);
1596  dEdx = dEdX_Fe; radX0 = radX0_Fe;
1597  }//iron
1598  else if (lZ < 850 + ecShift){
1599  rzLims = MatBounds(287, 750, 785 + ecShift, 850 + ecShift);
1600  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1601  }
1602  else if (lZ < 910 + ecShift){
1603  rzLims = MatBounds(287, 750, 850 + ecShift, 910 + ecShift);
1604  dEdx = dEdX_Fe; radX0 = radX0_Fe;
1605  }//iron
1606  else if (lZ < 975 + ecShift){
1607  rzLims = MatBounds(287, 750, 910 + ecShift, 975 + ecShift);
1608  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1609  }
1610  else if (lZ < 1000 + ecShift){
1611  rzLims = MatBounds(287, 750, 975 + ecShift, 1000 + ecShift);
1612  dEdx = dEdX_Fe; radX0 = radX0_Fe;
1613  }//iron
1614  else if (lZ < 1063 + ecShift){
1615  if (lR < 360){
1616  rzLims = MatBounds(287, 360, 1000 + ecShift, 1063 + ecShift);
1617  dEdx = dEdX_MCh; radX0 = radX0_MCh;
1618  }
1619  //put empty air where me4/2 should be (future)
1620  else {
1621  rzLims = MatBounds(360, 750, 1000 + ecShift, 1063 + ecShift);
1622  dEdx = dEdX_Air; radX0 = radX0_Air;
1623  }
1624  }
1625  else if ( lZ < 1073 + ecShift){
1626  rzLims = MatBounds(287, 750, 1063 + ecShift, 1073 + ecShift);
1627  //this plate does not exist: air
1628  dEdx = dEdX_Air; radX0 = radX0_Air;
1629  }
1630  else if (lZ < 1E4 ) {
1631  rzLims = MatBounds(287, 750, 1073 + ecShift, 1E4);
1632  dEdx = dEdX_Air; radX0 = radX0_Air;
1633  }
1634  else {dEdx = dEdX_Air; radX0 = radX0_Air; }//air
1635  }
1636 
1637  //dEdx so far is a relative number (relative to iron)
1638  //scale by what's expected for iron (the function was fit from pdg table)
1639  //0.065 (PDG) --> 0.044 to better match with MPV
1640  double p0 = sv.p3.mag();
1641  double logp0 = log(p0);
1642  double p0powN33 = 0;
1643  if (p0>3.) {
1644  // p0powN33 = exp(-0.33*logp0); //calculate for p>3GeV
1645  double xx=1./p0; xx=sqrt(sqrt(sqrt(sqrt(xx)))); xx=xx*xx*xx*xx*xx; // this is (p0)**(-5/16), close enough to -0.33
1646  p0powN33 = xx;
1647  }
1648  double dEdX_mat = -(11.4 + 0.96*fabs(logp0+log(2.8)) + 0.033*p0*(1.0 - p0powN33) )*1e-3;
1649  //in GeV/cm .. 0.8 to get closer to the median or MPV
1650 
1651  dEdXPrime = dEdx == 0 ? 0 : -dEdx*(0.96/p0 + 0.033 - 0.022*p0powN33)*1e-3; //== d(dEdX)/dp
1652  dEdx *= dEdX_mat;
1653 
1654  return dEdx;
1655 }
static std::vector< std::string > checklist log
SteppingHelixStateInfo::VolumeBounds MatBounds
T sqrt(T t)
Definition: SSEVec.h:48
void SteppingHelixPropagator::getNextState ( const SteppingHelixPropagator::StateInfo svPrevious,
SteppingHelixPropagator::StateInfo svNext,
double  dP,
const SteppingHelixPropagator::Vector tau,
const SteppingHelixPropagator::Vector drVec,
double  dS,
double  dX0,
const AlgebraicMatrix55 dCovCurv 
) const
protected

(Internals) compute transients for current point (increments step counter). Called by makeAtomStep

Definition at line 777 of file SteppingHelixPropagator.cc.

References SteppingHelixStateInfo::bf, SteppingHelixStateInfo::covCurv, debug_, SteppingHelixStateInfo::dEdx, SteppingHelixStateInfo::dEdXPrime, SteppingHelixStateInfo::dir, alignCSCRings::e, field_, VolumeBasedMagneticField::findVolume(), getDeDx(), SteppingHelixStateInfo::hasErrorPropagated_, MagneticField::inTesla(), MagVolume::inTesla(), SteppingHelixStateInfo::isYokeVol, isYokeVolume(), LogTrace, SteppingHelixStateInfo::magVol, SteppingHelixStateInfo::matDCovCurv, metname, SteppingHelixStateInfo::p3, SteppingHelixStateInfo::path(), SteppingHelixStateInfo::path_, SteppingHelixStateInfo::q, SteppingHelixStateInfo::r3, SteppingHelixStateInfo::radPath(), SteppingHelixStateInfo::radPath_, SteppingHelixStateInfo::radX0, SteppingHelixStateInfo::rzLims, AlCaHLTBitMon_QueryRunRegistry::string, metsig::tau, tmp, useInTeslaFromMagField_, useIsYokeFlag_, useMagVolumes_, and vbField_.

Referenced by makeAtomStep().

781  {
782  static const std::string metname = "SteppingHelixPropagator";
783  svNext.q = svPrevious.q;
784  svNext.dir = dS > 0.0 ? 1.: -1.;
785  svNext.p3 = tau; svNext.p3*=(svPrevious.p3.mag() - svNext.dir*fabs(dP));
786 
787  svNext.r3 = svPrevious.r3; svNext.r3 += drVec;
788 
789  svNext.path_ = svPrevious.path() + dS;
790  svNext.radPath_ = svPrevious.radPath() + dX0;
791 
792  GlobalPoint gPointNorZ(svNext.r3.x(), svNext.r3.y(), svNext.r3.z());
793 
794  GlobalVector bf(0,0,0);
795 
796  if (useMagVolumes_){
797  if (vbField_ != 0){
798  svNext.magVol = vbField_->findVolume(gPointNorZ);
799  if (useIsYokeFlag_){
800  double curRad = svNext.r3.perp();
801  if (curRad > 380 && curRad < 850 && fabs(svNext.r3.z()) < 667){
802  svNext.isYokeVol = isYokeVolume(svNext.magVol);
803  } else {
804  svNext.isYokeVol = false;
805  }
806  }
807  } else {
808  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Failed to cast into VolumeBasedMagneticField"<<std::endl;
809  svNext.magVol = 0;
810  }
811  if (debug_){
812  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Got volume at "<<svNext.magVol<<std::endl;
813  }
814  }
815 
816  if (useMagVolumes_ && svNext.magVol != 0 && ! useInTeslaFromMagField_){
817  bf = svNext.magVol->inTesla(gPointNorZ);
818  svNext.bf.set(bf.x(), bf.y(), bf.z());
819  } else {
820  GlobalPoint gPoint(svNext.r3.x(), svNext.r3.y(), svNext.r3.z());
821  bf = field_->inTesla(gPoint);
822  svNext.bf.set(bf.x(), bf.y(), bf.z());
823  }
824  if (svNext.bf.mag2() < 1e-32) svNext.bf.set(0., 0., 1e-16);
825 
826 
827  double dEdXPrime = 0;
828  double dEdx = 0;
829  double radX0 = 0;
830  MatBounds rzLims;
831  dEdx = getDeDx(svNext, dEdXPrime, radX0, rzLims);
832  svNext.dEdx = dEdx; svNext.dEdXPrime = dEdXPrime;
833  svNext.radX0 = radX0;
834  svNext.rzLims = rzLims;
835 
836  //update Emat only if it's valid
837  svNext.hasErrorPropagated_ = svPrevious.hasErrorPropagated_;
838  if (svPrevious.hasErrorPropagated_){
839  {
840  AlgebraicMatrix55 tmp = dCovCurvTransform*svPrevious.covCurv;
841  ROOT::Math::AssignSym::Evaluate(svNext.covCurv, tmp*ROOT::Math::Transpose(dCovCurvTransform));
842 
843  svNext.covCurv += svPrevious.matDCovCurv;
844  }
845  } else {
846  //could skip dragging along the unprop. cov later .. now
847  // svNext.cov = svPrevious.cov;
848  }
849 
850  if (debug_){
851  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Now at path: "<<svNext.path()<<" radPath: "<<svNext.radPath()
852  <<" p3 "<<" pt: "<<svNext.p3.perp()<<" phi: "<<svNext.p3.phi()
853  <<" eta: "<<svNext.p3.eta()
854  <<" "<<svNext.p3
855  <<" r3: "<<svNext.r3
856  <<" dPhi: "<<acos(svNext.p3.unit().dot(svPrevious.p3.unit()))
857  <<" bField: "<<svNext.bf.mag()
858  <<" dedx: "<<svNext.dEdx
859  <<std::endl;
860  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"New Covariance "<<svNext.covCurv<<std::endl;
861  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Transf by dCovTransform "<<dCovCurvTransform<<std::endl;
862  }
863 }
const std::string metname
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
bool isYokeVolume(const MagVolume *vol) const
check if it&#39;s a yoke/iron based on this MagVol internals
SteppingHelixStateInfo::VolumeBounds MatBounds
AlgebraicSymMatrix55 covCurv
const MagVolume * findVolume(const GlobalPoint &gp) const
double getDeDx(const SteppingHelixPropagator::StateInfo &sv, double &dEdXPrime, double &radX0, MatBounds &rzLims) const
estimate average (in fact smth. close to MPV and median) energy loss per unit path length ...
virtual ::GlobalVector inTesla(const ::GlobalPoint &gp) const
Definition: MagVolume.h:46
const VolumeBasedMagneticField * vbField_
AlgebraicSymMatrix55 matDCovCurv
#define LogTrace(id)
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
const MagneticField * field_
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepStd< double, 5, 5 > > AlgebraicMatrix55
void SteppingHelixPropagator::initStateArraySHPSpecific ( StateArray svBuf,
bool  flagsOnly 
) const
protected

(Internals) set defaults needed for states used inside propagate methods

Definition at line 41 of file SteppingHelixPropagator.cc.

References i, MAX_POINTS, and noErrorPropagation_.

Referenced by propagate(), and propagateWithPath().

41  {
42  for (int i = 0; i <= MAX_POINTS; i++){
43  svBuf[i].isComplete = true;
44  svBuf[i].isValid_ = true;
45  svBuf[i].hasErrorPropagated_ = !noErrorPropagation_;
46  if (!flagsOnly){
47  svBuf[i].p3 = Vector(0,0,0);
48  svBuf[i].r3 = Point(0,0,0);
49  svBuf[i].bf = Vector(0,0,0);
50  svBuf[i].bfGradLoc = Vector(0,0,0);
51  svBuf[i].covCurv = AlgebraicSymMatrix55();
52  svBuf[i].matDCovCurv = AlgebraicSymMatrix55();
53  }
54  }
55 }
int i
Definition: DBlmapReader.cc:9
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
bool SteppingHelixPropagator::isYokeVolume ( const MagVolume vol) const
protected

check if it's a yoke/iron based on this MagVol internals

Definition at line 2279 of file SteppingHelixPropagator.cc.

References debug_, MagVolume::isIron(), LogTrace, metname, GloballyPositioned< T >::position(), query::result, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by getNextState(), and loadState().

2279  {
2280  static const std::string metname = "SteppingHelixPropagator";
2281  if (vol == 0) return false;
2282  /*
2283  const MFGrid* mGrid = reinterpret_cast<const MFGrid*>(vol->provider());
2284  std::vector<int> dims(mGrid->dimensions());
2285 
2286  LocalVector lVCen(mGrid->nodeValue(dims[0]/2, dims[1]/2, dims[2]/2));
2287  LocalVector lVZLeft(mGrid->nodeValue(dims[0]/2, dims[1]/2, dims[2]/5));
2288  LocalVector lVZRight(mGrid->nodeValue(dims[0]/2, dims[1]/2, (dims[2]*4)/5));
2289 
2290  double mag2VCen = lVCen.mag2();
2291  double mag2VZLeft = lVZLeft.mag2();
2292  double mag2VZRight = lVZRight.mag2();
2293 
2294  bool result = false;
2295  if (mag2VCen > 0.6 && mag2VZLeft > 0.6 && mag2VZRight > 0.6){
2296  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Volume is magnetic, located at "<<vol->position()<<std::endl;
2297  result = true;
2298  } else {
2299  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Volume is not magnetic, located at "<<vol->position()<<std::endl;
2300  }
2301 
2302  */
2303  bool result = vol->isIron();
2304  if (result){
2305  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Volume is magnetic, located at "<<vol->position()<<std::endl;
2306  } else {
2307  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Volume is not magnetic, located at "<<vol->position()<<std::endl;
2308  }
2309 
2310  return result;
2311 }
const std::string metname
tuple result
Definition: query.py:137
#define LogTrace(id)
bool isIron() const
Temporary hack to pass information on material. Will eventually be replaced!
Definition: MagVolume.h:51
const PositionType & position() const
void SteppingHelixPropagator::loadState ( SteppingHelixPropagator::StateInfo svCurrent,
const SteppingHelixPropagator::Vector p3,
const SteppingHelixPropagator::Point r3,
int  charge,
PropagationDirection  dir,
const AlgebraicSymMatrix55 covCurv 
) const
protected

(Internals) compute transient values for initial point (resets step counter). Called by setIState

Definition at line 668 of file SteppingHelixPropagator.cc.

References alongMomentum, SteppingHelixStateInfo::bf, DeDxDiscriminatorTools::charge(), SteppingHelixStateInfo::covCurv, debug_, SteppingHelixStateInfo::dEdx, SteppingHelixStateInfo::dEdXPrime, SteppingHelixStateInfo::dir, alignCSCRings::e, field_, MagVolume::fieldInTesla(), VolumeBasedMagneticField::findVolume(), getDeDx(), MagneticField::inTesla(), MagVolume::inTesla(), SteppingHelixStateInfo::isComplete, SteppingHelixStateInfo::isValid_, SteppingHelixStateInfo::isYokeVol, isYokeVolume(), LogTrace, PV3DBase< T, PVType, FrameType >::mag2(), SteppingHelixStateInfo::magVol, metname, SteppingHelixStateInfo::p3, p3, SteppingHelixStateInfo::path(), SteppingHelixStateInfo::path_, SteppingHelixStateInfo::q, SteppingHelixStateInfo::r3, SteppingHelixStateInfo::radPath(), SteppingHelixStateInfo::radPath_, SteppingHelixStateInfo::radX0, SteppingHelixStateInfo::rzLims, AlCaHLTBitMon_QueryRunRegistry::string, GloballyPositioned< T >::toLocal(), useInTeslaFromMagField_, useIsYokeFlag_, useMagVolumes_, vbField_, PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().

Referenced by setIState().

672  {
673  static const std::string metname = "SteppingHelixPropagator";
674 
675  svCurrent.q = charge;
676  svCurrent.p3 = p3;
677  svCurrent.r3 = r3;
678  svCurrent.dir = dir == alongMomentum ? 1.: -1.;
679 
680  svCurrent.path_ = 0; // this could've held the initial path
681  svCurrent.radPath_ = 0;
682 
683  GlobalPoint gPointNorZ(svCurrent.r3.x(), svCurrent.r3.y(), svCurrent.r3.z());
684 
685  float gpmag = gPointNorZ.mag2();
686  float pmag2 = p3.mag2();
687  if (gpmag > 1e20f ) {
688  LogTrace(metname)<<"Initial point is too far";
689  svCurrent.isValid_ = false;
690  return;
691  }
692  if (! (gpmag == gpmag) ) {
693  LogTrace(metname)<<"Initial point is a nan";
694  edm::LogWarning("SteppingHelixPropagatorNAN")<<"Initial point is a nan";
695  svCurrent.isValid_ = false;
696  return;
697  }
698  if (! (pmag2 == pmag2) ) {
699  LogTrace(metname)<<"Initial momentum is a nan";
700  edm::LogWarning("SteppingHelixPropagatorNAN")<<"Initial momentum is a nan";
701  svCurrent.isValid_ = false;
702  return;
703  }
704 
705  GlobalVector bf(0,0,0);
706  // = field_->inTesla(gPoint);
707  if (useMagVolumes_){
708  if (vbField_ ){
709  svCurrent.magVol = vbField_->findVolume(gPointNorZ);
710  if (useIsYokeFlag_){
711  double curRad = svCurrent.r3.perp();
712  if (curRad > 380 && curRad < 850 && fabs(svCurrent.r3.z()) < 667){
713  svCurrent.isYokeVol = isYokeVolume(svCurrent.magVol);
714  } else {
715  svCurrent.isYokeVol = false;
716  }
717  }
718  } else {
719  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Failed to cast into VolumeBasedMagneticField: fall back to the default behavior"<<std::endl;
720  svCurrent.magVol = 0;
721  }
722  if (debug_){
723  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Got volume at "<<svCurrent.magVol<<std::endl;
724  }
725  }
726 
727  if (useMagVolumes_ && svCurrent.magVol != 0 && ! useInTeslaFromMagField_){
728  bf = svCurrent.magVol->inTesla(gPointNorZ);
729  if (debug_){
730  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Loaded bfield float: "<<bf
731  <<" at global float "<< gPointNorZ<<" double "<< svCurrent.r3<<std::endl;
732  LocalPoint lPoint(svCurrent.magVol->toLocal(gPointNorZ));
733  LocalVector lbf = svCurrent.magVol->fieldInTesla(lPoint);
734  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"\t cf in local locF: "<<lbf<<" at "<<lPoint<<std::endl;
735  }
736  svCurrent.bf.set(bf.x(), bf.y(), bf.z());
737  } else {
738  GlobalPoint gPoint(r3.x(), r3.y(), r3.z());
739  bf = field_->inTesla(gPoint);
740  svCurrent.bf.set(bf.x(), bf.y(), bf.z());
741  }
742  if (svCurrent.bf.mag2() < 1e-32) svCurrent.bf.set(0., 0., 1e-16);
743  if (debug_){
744  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific
745  <<"Loaded bfield double: "<<svCurrent.bf<<" from float: "<<bf
746  <<" at float "<< gPointNorZ<<" double "<< svCurrent.r3<<std::endl;
747  }
748 
749 
750 
751  double dEdXPrime = 0;
752  double dEdx = 0;
753  double radX0 = 0;
754  MatBounds rzLims;
755  dEdx = getDeDx(svCurrent, dEdXPrime, radX0, rzLims);
756  svCurrent.dEdx = dEdx; svCurrent.dEdXPrime = dEdXPrime;
757  svCurrent.radX0 = radX0;
758  svCurrent.rzLims = rzLims;
759 
760  svCurrent.covCurv =covCurv;
761 
762  svCurrent.isComplete = true;
763  svCurrent.isValid_ = true;
764 
765  if (debug_){
766  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Loaded at path: "<<svCurrent.path()<<" radPath: "<<svCurrent.radPath()
767  <<" p3 "<<" pt: "<<svCurrent.p3.perp()<<" phi: "<<svCurrent.p3.phi()
768  <<" eta: "<<svCurrent.p3.eta()
769  <<" "<<svCurrent.p3
770  <<" r3: "<<svCurrent.r3
771  <<" bField: "<<svCurrent.bf.mag()
772  <<std::endl;
773  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Input Covariance in Curvilinear RF "<<covCurv<<std::endl;
774  }
775 }
T mag2() const
Definition: PV3DBase.h:66
const std::string metname
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
bool isYokeVolume(const MagVolume *vol) const
check if it&#39;s a yoke/iron based on this MagVol internals
SteppingHelixStateInfo::VolumeBounds MatBounds
AlgebraicSymMatrix55 covCurv
const MagVolume * findVolume(const GlobalPoint &gp) const
double getDeDx(const SteppingHelixPropagator::StateInfo &sv, double &dEdXPrime, double &radX0, MatBounds &rzLims) const
estimate average (in fact smth. close to MPV and median) energy loss per unit path length ...
double charge(const std::vector< uint8_t > &Ampls)
virtual ::GlobalVector inTesla(const ::GlobalPoint &gp) const
Definition: MagVolume.h:46
LocalPoint toLocal(const GlobalPoint &gp) const
const VolumeBasedMagneticField * vbField_
#define LogTrace(id)
LocalVector fieldInTesla(const LocalPoint &lp) const
Definition: MagVolume.cc:11
dbl *** dir
Definition: mlp_gen.cc:35
const MagneticField * field_
double p3[4]
Definition: TauolaWrapper.h:91
virtual const MagneticField* SteppingHelixPropagator::magneticField ( ) const
inlineoverridevirtual

Implements Propagator.

Definition at line 90 of file SteppingHelixPropagator.h.

References field_.

90 { return field_;}
const MagneticField * field_
bool SteppingHelixPropagator::makeAtomStep ( SteppingHelixPropagator::StateInfo svCurrent,
SteppingHelixPropagator::StateInfo svNext,
double  dS,
PropagationDirection  dir,
SteppingHelixPropagator::Fancy  fancy 
) const
protected

main stepping function: compute next state vector after a step of length dS

Definition at line 873 of file SteppingHelixPropagator.cc.

References alongMomentum, applyRadX0Correction_, SteppingHelixStateInfo::bf, funct::cos(), prof2calltree::cost, debug_, SteppingHelixStateInfo::dEdx, SteppingHelixStateInfo::dEdXPrime, alignCSCRings::e, field_, getDeDx(), getNextState(), SteppingHelixStateInfo::hasErrorPropagated_, HEL_ALL_F, HEL_AS_F, MagneticField::inTesla(), MagVolume::inTesla(), SteppingHelixStateInfo::isYokeVol, log, LogTrace, SteppingHelixPropagator::Basis::lX, SteppingHelixPropagator::Basis::lY, SteppingHelixPropagator::Basis::lZ, PV3DBase< T, PVType, FrameType >::mag(), SteppingHelixStateInfo::magVol, SteppingHelixStateInfo::matDCovCurv, metname, oppositeToMomentum, SteppingHelixStateInfo::p3, SteppingHelixStateInfo::path(), phi, createTree::pp, SteppingHelixStateInfo::q, lumiQueryAPI::q, SteppingHelixStateInfo::r3, SteppingHelixStateInfo::radPath(), SteppingHelixStateInfo::radX0, cuy::rep, setRep(), funct::sin(), mathSSE::sqrt(), AlCaHLTBitMon_QueryRunRegistry::string, metsig::tau, unit55_, useInTeslaFromMagField_, useMagVolumes_, PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().

Referenced by propagate().

877  {
878  static const std::string metname = "SteppingHelixPropagator";
879  if (debug_){
880  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Make atom step "<<svCurrent.path()<<" with step "<<dS<<" in direction "<<dir<<std::endl;
881  }
882 
883  AlgebraicMatrix55 dCCurvTransform(unit55_);
884 
885  double dP = 0;
886  double curP = svCurrent.p3.mag();
887  Vector tau = svCurrent.p3; tau *= 1./curP;
888  Vector tauNext(tau);
889  Vector drVec(0,0,0);
890 
891  dS = dir == alongMomentum ? fabs(dS) : -fabs(dS);
892 
893 
894  double radX0 = 1e24;
895 
896  switch (fancy){
897  case HEL_AS_F:
898  case HEL_ALL_F:{
899  double p0 = curP;// see above = svCurrent.p3.mag();
900  double p0Inv = 1./p0;
901  double b0 = svCurrent.bf.mag();
902 
903  //get to the mid-point first
904  double phi = (2.99792458e-3*svCurrent.q*b0*p0Inv)*dS/2.;
905  bool phiSmall = fabs(phi) < 1e-4;
906 
907  double cosPhi = 0;
908  double sinPhi = 0;
909 
910  double oneLessCosPhi=0;
911  double oneLessCosPhiOPhi=0;
912  double sinPhiOPhi=0;
913  double phiLessSinPhiOPhi=0;
914 
915  if (phiSmall){
916  double phi2 = phi*phi;
917  double phi3 = phi2*phi;
918  double phi4 = phi3*phi;
919  sinPhi = phi - phi3/6. + phi4*phi/120.;
920  cosPhi = 1. -phi2/2. + phi4/24.;
921  oneLessCosPhi = phi2/2. - phi4/24. + phi2*phi4/720.; // 0.5*phi*phi;//*(1.- phi*phi/12.);
922  oneLessCosPhiOPhi = 0.5*phi - phi3/24. + phi2*phi3/720.;//*(1.- phi*phi/12.);
923  sinPhiOPhi = 1. - phi*phi/6. + phi4/120.;
924  phiLessSinPhiOPhi = phi*phi/6. - phi4/120. + phi4*phi2/5040.;//*(1. - phi*phi/20.);
925  } else {
926  cosPhi = cos(phi);
927  sinPhi = sin(phi);
928  oneLessCosPhi = 1.-cosPhi;
929  oneLessCosPhiOPhi = oneLessCosPhi/phi;
930  sinPhiOPhi = sinPhi/phi;
931  phiLessSinPhiOPhi = 1 - sinPhiOPhi;
932  }
933 
934  Vector bHat = svCurrent.bf; bHat *= 1./b0; //bHat.mag();
935  // bool bAlongZ = fabs(bHat.z()) > 0.9999;
936 
937  Vector btVec(bHat.cross(tau)); // for balong z btVec.z()==0
938  double tauB = tau.dot(bHat);
939  Vector bbtVec(bHat*tauB - tau); // (-tau.x(), -tau.y(), 0)
940 
941  //don't need it here tauNext = tau + bbtVec*oneLessCosPhi - btVec*sinPhi;
942  drVec = bbtVec*phiLessSinPhiOPhi; drVec -= btVec*oneLessCosPhiOPhi; drVec += tau;
943  drVec *= dS/2.;
944 
945  double dEdx = svCurrent.dEdx;
946  double dEdXPrime = svCurrent.dEdXPrime;
947  radX0 = svCurrent.radX0;
948  dP = dEdx*dS;
949 
950  //improve with above values:
951  drVec += svCurrent.r3;
952  GlobalVector bfGV(0,0,0);
953  Vector bf(0,0,0);
954  if (useMagVolumes_ && svCurrent.magVol != 0 && ! useInTeslaFromMagField_){
955  bfGV = svCurrent.magVol->inTesla(GlobalPoint(drVec.x(), drVec.y(), drVec.z()));
956  bf.set(bfGV.x(), bfGV.y(), bfGV.z());
957  } else {
958  bfGV = field_->inTesla(GlobalPoint(drVec.x(), drVec.y(), drVec.z()));
959  bf.set(bfGV.x(), bfGV.y(), bfGV.z());
960  }
961  double b0Init = b0;
962  b0 = bf.mag();
963  if (b0 < 1e-16) {
964  b0 = 1e-16;
965  bf.set(0., 0., 1e-16);
966  }
967  if (debug_){
968  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Improved b "<<b0
969  <<" at r3 "<<drVec<<std::endl;
970  }
971 
972  if (fabs((b0-b0Init)*dS) > 1){
973  //missed the mag volume boundary?
974  if (debug_){
975  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Large bf*dS change "<<fabs((b0-svCurrent.bf.mag())*dS)
976  <<" --> recalc dedx"<<std::endl;
977  }
978  svNext.r3 = drVec;
979  svNext.bf = bf;
980  svNext.p3 = svCurrent.p3;
981  svNext.isYokeVol = svCurrent.isYokeVol;
982  svNext.magVol = svCurrent.magVol;
983  MatBounds rzTmp;
984  dEdx = getDeDx(svNext, dEdXPrime, radX0, rzTmp);
985  dP = dEdx*dS;
986  if (debug_){
987  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"New dEdX= "<<dEdx
988  <<" dP= "<<dP
989  <<" for p0 "<<p0<<std::endl;
990  }
991  }
992  //p0 is mid-way and b0 from mid-point
993  p0 += dP/2.; if (p0 < 1e-2) p0 = 1e-2;
994  p0Inv = 1./p0;
995 
996  phi = (2.99792458e-3*svCurrent.q*b0*p0Inv)*dS;
997  phiSmall = fabs(phi) < 1e-4;
998 
999  if (phiSmall){
1000  double phi2 = phi*phi;
1001  double phi3 = phi2*phi;
1002  double phi4 = phi3*phi;
1003  sinPhi = phi - phi3/6. + phi4*phi/120.;
1004  cosPhi = 1. -phi2/2. + phi4/24.;
1005  oneLessCosPhi = phi2/2. - phi4/24. + phi2*phi4/720.; // 0.5*phi*phi;//*(1.- phi*phi/12.);
1006  oneLessCosPhiOPhi = 0.5*phi - phi3/24. + phi2*phi3/720.;//*(1.- phi*phi/12.);
1007  sinPhiOPhi = 1. - phi*phi/6. + phi4/120.;
1008  phiLessSinPhiOPhi = phi*phi/6. - phi4/120. + phi4*phi2/5040.;//*(1. - phi*phi/20.);
1009  }else {
1010  cosPhi = cos(phi);
1011  sinPhi = sin(phi);
1012  oneLessCosPhi = 1.-cosPhi;
1013  oneLessCosPhiOPhi = oneLessCosPhi/phi;
1014  sinPhiOPhi = sinPhi/phi;
1015  phiLessSinPhiOPhi = 1. - sinPhiOPhi;
1016  }
1017 
1018  bHat = bf; bHat *= 1./b0;// as above =1./bHat.mag();
1019  // bAlongZ = fabs(bHat.z()) > 0.9999;
1020  btVec = bHat.cross(tau); // for b||z (-tau.y(), tau.x() ,0)
1021  tauB = tau.dot(bHat);
1022  bbtVec = bHat*tauB - tau; //bHat.cross(btVec); for b||z: (-tau.x(), -tau.y(), 0)
1023 
1024  tauNext = bbtVec*oneLessCosPhi; tauNext -= btVec*sinPhi; tauNext += tau; //for b||z tauNext.z() == tau.z()
1025  double tauNextPerpInv = 1./tauNext.perp();
1026  drVec = bbtVec*phiLessSinPhiOPhi; drVec -= btVec*oneLessCosPhiOPhi; drVec += tau;
1027  drVec *= dS;
1028 
1029 
1030  if (svCurrent.hasErrorPropagated_){
1031  double theta02 = 0;
1032  double dX0 = fabs(dS)/radX0;
1033 
1034  if (applyRadX0Correction_){
1035  // this provides the integrand for theta^2
1036  // if summed up along the path, should result in
1037  // theta_total^2 = Int_0^x0{ f(x)dX} = (13.6/p0)^2*x0*(1+0.036*ln(x0+1))
1038  // x0+1 above is to make the result infrared safe.
1039  double x0 = fabs(svCurrent.radPath());
1040  double alphaX0 = 13.6e-3*p0Inv; alphaX0 *= alphaX0;
1041  double betaX0 = 0.038;
1042  double logx0p1 = log(x0+1);
1043  theta02 = dX0*alphaX0*(1+betaX0*logx0p1)*(1 + betaX0*logx0p1 + 2.*betaX0*x0/(x0+1) );
1044  } else {
1045  theta02 = 196e-6* p0Inv * p0Inv * dX0; //14.e-3/p0*sqrt(fabs(dS)/radX0); // .. drop log term (this is non-additive)
1046  }
1047 
1048  double epsilonP0 = 1.+ dP/(p0-0.5*dP);
1049  // double omegaP0 = -dP/(p0-0.5*dP) + dS*dEdXPrime;
1050  // double dsp = dS/(p0-0.5*dP); //use the initial p0 (not the mid-point) to keep the transport properly additive
1051 
1052  Vector tbtVec(bHat - tauB*tau); // for b||z tau.z()*(-tau.x(), -tau.y(), 1.-tau.z())
1053 
1054  {
1055  //Slightly modified copy of the curvilinear jacobian (don't use the original just because it's in float precision
1056  // and seems to have some assumptions about the field values
1057  // notation changes: p1--> tau, p2-->tauNext
1058  // theta --> phi
1059  // Vector p1 = tau;
1060  // Vector p2 = tauNext;
1061  Point xStart = svCurrent.r3;
1062  Vector dx = drVec;
1063  //GlobalVector h = MagneticField::inInverseGeV(xStart);
1064  // Martijn: field is now given as parameter.. GlobalVector h = globalParameters.magneticFieldInInverseGeV(xStart);
1065 
1066  //double qbp = fts.signedInverseMomentum();
1067  double qbp = svCurrent.q*p0Inv;
1068  // double absS = dS;
1069 
1070  // calculate transport matrix
1071  // Origin: TRPRFN
1072  double t11 = tau.x(); double t12 = tau.y(); double t13 = tau.z();
1073  double t21 = tauNext.x(); double t22 = tauNext.y(); double t23 = tauNext.z();
1074  double cosl0 = tau.perp();
1075  // double cosl1 = 1./tauNext.perp(); //not quite a cos .. it's a cosec--> change to cosecl1 below
1076  double cosecl1 = tauNextPerpInv;
1077  //AlgebraicMatrix a(5,5,1);
1078  // define average magnetic field and gradient
1079  // at initial point - inlike TRPRFN
1080  Vector hn = bHat;
1081  // double qp = -2.99792458e-3*b0;
1082  // double q = -h.mag()*qbp;
1083 
1084  double q = -phi/dS; //qp*qbp; // -phi/dS
1085  // double theta = -phi;
1086  double sint = -sinPhi; double cost = cosPhi;
1087  double hn1 = hn.x(); double hn2 = hn.y(); double hn3 = hn.z();
1088  double dx1 = dx.x(); double dx2 = dx.y(); double dx3 = dx.z();
1089  // double hnDt1 = hn1*t11 + hn2*t12 + hn3*t13;
1090 
1091  double gamma = hn1*t21 + hn2*t22 + hn3*t23;
1092  double an1 = hn2*t23 - hn3*t22;
1093  double an2 = hn3*t21 - hn1*t23;
1094  double an3 = hn1*t22 - hn2*t21;
1095  // double auInv = sqrt(1.- t13*t13); double au = auInv>0 ? 1./auInv : 1e24;
1096  double auInv = cosl0; double au = auInv>0 ? 1./auInv : 1e24;
1097  // double auInv = sqrt(t11*t11 + t12*t12); double au = auInv>0 ? 1./auInv : 1e24;
1098  double u11 = -au*t12; double u12 = au*t11;
1099  double v11 = -t13*u12; double v12 = t13*u11; double v13 = auInv;//t11*u12 - t12*u11;
1100  auInv = sqrt(1. - t23*t23); au = auInv>0 ? 1./auInv : 1e24;
1101  // auInv = sqrt(t21*t21 + t22*t22); au = auInv>0 ? 1./auInv : 1e24;
1102  double u21 = -au*t22; double u22 = au*t21;
1103  double v21 = -t23*u22; double v22 = t23*u21; double v23 = auInv;//t21*u22 - t22*u21;
1104  // now prepare the transport matrix
1105  // pp only needed in high-p case (WA)
1106  // double pp = 1./qbp;
1108  // moved up (where -h.mag() is needed()
1109  // double qp = q*pp;
1110  double anv = -(hn1*u21 + hn2*u22 );
1111  double anu = (hn1*v21 + hn2*v22 + hn3*v23);
1112  double omcost = oneLessCosPhi; double tmsint = -phi*phiLessSinPhiOPhi;
1113 
1114  double hu1 = - hn3*u12;
1115  double hu2 = hn3*u11;
1116  double hu3 = hn1*u12 - hn2*u11;
1117 
1118  double hv1 = hn2*v13 - hn3*v12;
1119  double hv2 = hn3*v11 - hn1*v13;
1120  double hv3 = hn1*v12 - hn2*v11;
1121 
1122  // 1/p - doesn't change since |tau| = |tauNext| ... not. It changes now
1123  dCCurvTransform(0,0) = 1./(epsilonP0*epsilonP0)*(1. + dS*dEdXPrime);
1124 
1125  // lambda
1126 
1127  dCCurvTransform(1,0) = phi*p0/svCurrent.q*cosecl1*
1128  (sinPhi*bbtVec.z() - cosPhi*btVec.z());
1129  //was dCCurvTransform(1,0) = -qp*anv*(t21*dx1 + t22*dx2 + t23*dx3); //NOTE (SK) this was found to have an opposite sign
1130  //from independent re-calculation ... in fact the tauNext.dot.dR piece isnt reproduced
1131 
1132  dCCurvTransform(1,1) = cost*(v11*v21 + v12*v22 + v13*v23) +
1133  sint*(hv1*v21 + hv2*v22 + hv3*v23) +
1134  omcost*(hn1*v11 + hn2*v12 + hn3*v13) * (hn1*v21 + hn2*v22 + hn3*v23) +
1135  anv*(-sint*(v11*t21 + v12*t22 + v13*t23) +
1136  omcost*(v11*an1 + v12*an2 + v13*an3) -
1137  tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
1138 
1139  dCCurvTransform(1,2) = cost*(u11*v21 + u12*v22 ) +
1140  sint*(hu1*v21 + hu2*v22 + hu3*v23) +
1141  omcost*(hn1*u11 + hn2*u12 ) * (hn1*v21 + hn2*v22 + hn3*v23) +
1142  anv*(-sint*(u11*t21 + u12*t22 ) +
1143  omcost*(u11*an1 + u12*an2 ) -
1144  tmsint*gamma*(hn1*u11 + hn2*u12 ) );
1145  dCCurvTransform(1,2) *= cosl0;
1146 
1147  // Commented out in part for reproducibility purposes: these terms are zero in cart->curv
1148  // dCCurvTransform(1,3) = -q*anv*(u11*t21 + u12*t22 ); //don't show up in cartesian setup-->curv
1149  //why would lambdaNext depend explicitely on initial position ? any arbitrary init point can be chosen not
1150  // affecting the final state's momentum direction ... is this the field gradient in curvilinear coord?
1151  // dCCurvTransform(1,4) = -q*anv*(v11*t21 + v12*t22 + v13*t23); //don't show up in cartesian setup-->curv
1152 
1153  // phi
1154 
1155  dCCurvTransform(2,0) = - phi*p0/svCurrent.q*cosecl1*cosecl1*
1156  (oneLessCosPhi*bHat.z()*btVec.mag2() + sinPhi*btVec.z() + cosPhi*tbtVec.z()) ;
1157  //was dCCurvTransform(2,0) = -qp*anu*(t21*dx1 + t22*dx2 + t23*dx3)*cosecl1;
1158 
1159  dCCurvTransform(2,1) = cost*(v11*u21 + v12*u22 ) +
1160  sint*(hv1*u21 + hv2*u22 ) +
1161  omcost*(hn1*v11 + hn2*v12 + hn3*v13) *
1162  (hn1*u21 + hn2*u22 ) +
1163  anu*(-sint*(v11*t21 + v12*t22 + v13*t23) +
1164  omcost*(v11*an1 + v12*an2 + v13*an3) -
1165  tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
1166  dCCurvTransform(2,1) *= cosecl1;
1167 
1168  dCCurvTransform(2,2) = cost*(u11*u21 + u12*u22 ) +
1169  sint*(hu1*u21 + hu2*u22 ) +
1170  omcost*(hn1*u11 + hn2*u12 ) *
1171  (hn1*u21 + hn2*u22 ) +
1172  anu*(-sint*(u11*t21 + u12*t22 ) +
1173  omcost*(u11*an1 + u12*an2 ) -
1174  tmsint*gamma*(hn1*u11 + hn2*u12 ) );
1175  dCCurvTransform(2,2) *= cosecl1*cosl0;
1176 
1177  // Commented out in part for reproducibility purposes: these terms are zero in cart->curv
1178  // dCCurvTransform(2,3) = -q*anu*(u11*t21 + u12*t22 )*cosecl1;
1179  //why would lambdaNext depend explicitely on initial position ? any arbitrary init point can be chosen not
1180  // affecting the final state's momentum direction ... is this the field gradient in curvilinear coord?
1181  // dCCurvTransform(2,4) = -q*anu*(v11*t21 + v12*t22 + v13*t23)*cosecl1;
1182 
1183  // yt
1184 
1185  double pp = 1./qbp;
1186  // (SK) these terms seem to consistently have a sign opp from private derivation
1187  dCCurvTransform(3,0) = - pp*(u21*dx1 + u22*dx2 ); //NB: modified from the original: changed the sign
1188  dCCurvTransform(4,0) = - pp*(v21*dx1 + v22*dx2 + v23*dx3);
1189 
1190 
1191  dCCurvTransform(3,1) = (sint*(v11*u21 + v12*u22 ) +
1192  omcost*(hv1*u21 + hv2*u22 ) +
1193  tmsint*(hn1*u21 + hn2*u22 ) *
1194  (hn1*v11 + hn2*v12 + hn3*v13))/q;
1195 
1196  dCCurvTransform(3,2) = (sint*(u11*u21 + u12*u22 ) +
1197  omcost*(hu1*u21 + hu2*u22 ) +
1198  tmsint*(hn1*u21 + hn2*u22 ) *
1199  (hn1*u11 + hn2*u12 ))*cosl0/q;
1200 
1201  dCCurvTransform(3,3) = (u11*u21 + u12*u22 );
1202 
1203  dCCurvTransform(3,4) = (v11*u21 + v12*u22 );
1204 
1205  // zt
1206 
1207  dCCurvTransform(4,1) = (sint*(v11*v21 + v12*v22 + v13*v23) +
1208  omcost*(hv1*v21 + hv2*v22 + hv3*v23) +
1209  tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
1210  (hn1*v11 + hn2*v12 + hn3*v13))/q;
1211 
1212  dCCurvTransform(4,2) = (sint*(u11*v21 + u12*v22 ) +
1213  omcost*(hu1*v21 + hu2*v22 + hu3*v23) +
1214  tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
1215  (hn1*u11 + hn2*u12 ))*cosl0/q;
1216 
1217  dCCurvTransform(4,3) = (u11*v21 + u12*v22 );
1218 
1219  dCCurvTransform(4,4) = (v11*v21 + v12*v22 + v13*v23);
1220  // end of TRPRFN
1221  }
1222 
1223  if (debug_){
1224  Basis rep; setRep(rep, tauNext);
1225  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"rep X: "<<rep.lX<<" "<<rep.lX.mag()
1226  <<"\t Y: "<<rep.lY<<" "<<rep.lY.mag()
1227  <<"\t Z: "<<rep.lZ<<" "<<rep.lZ.mag();
1228  }
1229  //mind the sign of dS and dP (dS*dP < 0 allways)
1230  //covariance should grow no matter which direction you propagate
1231  //==> take abs values.
1232  //reset not needed: fill all below svCurrent.matDCov *= 0.;
1233  double mulRR = theta02*dS*dS/3.;
1234  double mulRP = theta02*fabs(dS)*p0/2.;
1235  double mulPP = theta02*p0*p0;
1236  double losPP = dP*dP*1.6/fabs(dS)*(1.0 + p0*1e-3);
1237  //another guess .. makes sense for 1 cm steps 2./dS == 2 [cm] / dS [cm] at low pt
1238  //double it by 1TeV
1239  //not gaussian anyways
1240  // derived from the fact that sigma_p/eLoss ~ 0.08 after ~ 200 steps
1241 
1242  //curvilinear
1243  double sinThetaInv = tauNextPerpInv;
1244  double p0Mat = p0+ 0.5*dP; // FIXME change this to p0 after it's clear that there's agreement in everything else
1245  double p0Mat2 = p0Mat*p0Mat;
1246  // with 6x6 formulation
1247  svCurrent.matDCovCurv*=0;
1248 
1249  svCurrent.matDCovCurv(0,0) = losPP/(p0Mat2*p0Mat2);
1250  // svCurrent.matDCovCurv(0,1) = 0;
1251  // svCurrent.matDCovCurv(0,2) = 0;
1252  // svCurrent.matDCovCurv(0,3) = 0;
1253  // svCurrent.matDCovCurv(0,4) = 0;
1254 
1255  // svCurrent.matDCovCurv(1,0) = 0;
1256  svCurrent.matDCovCurv(1,1) = mulPP/p0Mat2;
1257  // svCurrent.matDCovCurv(1,2) = 0;
1258  // svCurrent.matDCovCurv(1,3) = 0;
1259  svCurrent.matDCovCurv(1,4) = mulRP/p0Mat;
1260 
1261  // svCurrent.matDCovCurv(2,0) = 0;
1262  // svCurrent.matDCovCurv(2,1) = 0;
1263  svCurrent.matDCovCurv(2,2) = mulPP/p0Mat2*(sinThetaInv*sinThetaInv);
1264  svCurrent.matDCovCurv(2,3) = mulRP/p0Mat*sinThetaInv;
1265  // svCurrent.matDCovCurv(2,4) = 0;
1266 
1267  // svCurrent.matDCovCurv(3,0) = 0;
1268  // svCurrent.matDCovCurv(3,1) = 0;
1269  svCurrent.matDCovCurv(3,2) = mulRP/p0Mat*sinThetaInv;
1270  // svCurrent.matDCovCurv(3,0) = 0;
1271  svCurrent.matDCovCurv(3,3) = mulRR;
1272  // svCurrent.matDCovCurv(3,4) = 0;
1273 
1274  // svCurrent.matDCovCurv(4,0) = 0;
1275  svCurrent.matDCovCurv(4,1) = mulRP/p0Mat;
1276  // svCurrent.matDCovCurv(4,2) = 0;
1277  // svCurrent.matDCovCurv(4,3) = 0;
1278  svCurrent.matDCovCurv(4,4) = mulRR;
1279  }
1280  break;
1281  }
1282  default:
1283  break;
1284  }
1285 
1286  double pMag = curP;//svCurrent.p3.mag();
1287 
1288  if (dir == oppositeToMomentum) dP = fabs(dP);
1289  else if( dP < 0) { //the case of negative dP
1290  dP = -dP > pMag ? -pMag+1e-5 : dP;
1291  }
1292 
1293  getNextState(svCurrent, svNext, dP, tauNext, drVec, dS, dS/radX0,
1294  dCCurvTransform);
1295  return true;
1296 }
string rep
Definition: cuy.py:1188
static std::vector< std::string > checklist log
tuple pp
Definition: createTree.py:15
const std::string metname
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
SteppingHelixStateInfo::VolumeBounds MatBounds
double getDeDx(const SteppingHelixPropagator::StateInfo &sv, double &dEdXPrime, double &radX0, MatBounds &rzLims) const
estimate average (in fact smth. close to MPV and median) energy loss per unit path length ...
virtual ::GlobalVector inTesla(const ::GlobalPoint &gp) const
Definition: MagVolume.h:46
T mag() const
Definition: PV3DBase.h:67
T sqrt(T t)
Definition: SSEVec.h:48
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
math::XYZPoint Point
AlgebraicSymMatrix55 matDCovCurv
#define LogTrace(id)
const AlgebraicSymMatrix55 unit55_
void setRep(SteppingHelixPropagator::Basis &rep, const SteppingHelixPropagator::Vector &tau) const
Set/compute basis vectors for local coordinates at current step (called by incrementState) ...
dbl *** dir
Definition: mlp_gen.cc:35
void getNextState(const SteppingHelixPropagator::StateInfo &svPrevious, SteppingHelixPropagator::StateInfo &svNext, double dP, const SteppingHelixPropagator::Vector &tau, const SteppingHelixPropagator::Vector &drVec, double dS, double dX0, const AlgebraicMatrix55 &dCovCurv) const
const MagneticField * field_
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepStd< double, 5, 5 > > AlgebraicMatrix55
Definition: DDAxes.h:10
void SteppingHelixPropagator::propagate ( const SteppingHelixStateInfo ftsStart,
const Surface sDest,
SteppingHelixStateInfo out 
) const

Propagate to Plane given a starting point.

Definition at line 173 of file SteppingHelixPropagator.cc.

References invalidState_, SteppingHelixStateInfo::isValid(), and sendLogWarning_.

Referenced by AlCaHOCalibProducer::produce(), propagate(), and propagateWithPath().

175  {
176 
177  if (! sStart.isValid()){
178  if (sendLogWarning_){
179  edm::LogWarning("SteppingHelixPropagator")<<"Can't propagate: invalid input state"
180  <<std::endl;
181  }
182  out=invalidState_;
183  return;
184  }
185 
186  const Plane* pDest = dynamic_cast<const Plane*>(&sDest);
187  if (pDest != 0) {
188  propagate(sStart, *pDest, out);
189  return;
190  }
191 
192  const Cylinder* cDest = dynamic_cast<const Cylinder*>(&sDest);
193  if (cDest != 0) {
194  propagate(sStart, *cDest, out);
195  return;
196  }
197 
198  throw PropagationException("The surface is neither Cylinder nor Plane");
199 
200 }
Definition: Plane.h:17
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
Common base class.
void SteppingHelixPropagator::propagate ( const SteppingHelixStateInfo ftsStart,
const Plane pDest,
SteppingHelixStateInfo out 
) const

Definition at line 203 of file SteppingHelixPropagator.cc.

References cIndex_(), initStateArraySHPSpecific(), invalidState_, SteppingHelixStateInfo::isValid(), SteppingHelixStateInfo::path(), PLANE_DT, GloballyPositioned< T >::position(), propagate(), mathSSE::return(), GloballyPositioned< T >::rotation(), sendLogWarning_, setIState(), PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), PV3DBase< T, PVType, FrameType >::z(), TkRotation< T >::zx(), TkRotation< T >::zy(), and TkRotation< T >::zz().

205  {
206 
207  if (! sStart.isValid()){
208  if (sendLogWarning_){
209  edm::LogWarning("SteppingHelixPropagator")<<"Can't propagate: invalid input state"
210  <<std::endl;
211  }
212  out = invalidState_;
213  return ;
214  }
215  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
216  int nPoints = 0;
217  setIState(sStart,svBuf,nPoints);
218 
219  Point rPlane(pDest.position().x(), pDest.position().y(), pDest.position().z());
220  Vector nPlane(pDest.rotation().zx(), pDest.rotation().zy(), pDest.rotation().zz()); nPlane /= nPlane.mag();
221 
222  double pars[6] = { rPlane.x(), rPlane.y(), rPlane.z(),
223  nPlane.x(), nPlane.y(), nPlane.z() };
224 
225  propagate(svBuf,nPoints,PLANE_DT, pars);
226 
227  //(re)set it before leaving: dir =1 (-1) if path increased (decreased) and 0 if it didn't change
228  //need to implement this somewhere else as a separate function
229  double lDir = 0;
230  if (sStart.path() < svBuf[cIndex_(nPoints-1)].path()) lDir = 1.;
231  if (sStart.path() > svBuf[cIndex_(nPoints-1)].path()) lDir = -1.;
232  svBuf[cIndex_(nPoints-1)].dir = lDir;
233 
234  out = svBuf[cIndex_(nPoints-1)];
235  return;
236 }
StateInfo StateArray[MAX_POINTS+1]
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
T y() const
Definition: PV3DBase.h:63
int cIndex_(int ind) const
(Internals) circular index for array of transients
return((rh^lh)&mask)
T zx() const
T zz() const
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
T z() const
Definition: PV3DBase.h:64
math::XYZPoint Point
T zy() const
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
const RotationType & rotation() const
T x() const
Definition: PV3DBase.h:62
const PositionType & position() const
void SteppingHelixPropagator::propagate ( const SteppingHelixStateInfo ftsStart,
const Cylinder cDest,
SteppingHelixStateInfo out 
) const

Propagate to Cylinder given a starting point (a Cylinder is assumed to be positioned at 0,0,0)

Definition at line 239 of file SteppingHelixPropagator.cc.

References cIndex_(), initStateArraySHPSpecific(), invalidState_, SteppingHelixStateInfo::isValid(), SteppingHelixStateInfo::path(), propagate(), Cylinder::radius(), RADIUS_DT, RADIUS_P, sendLogWarning_, and setIState().

241  {
242 
243  if (! sStart.isValid()){
244  if (sendLogWarning_){
245  edm::LogWarning("SteppingHelixPropagator")<<"Can't propagate: invalid input state"
246  <<std::endl;
247  }
248  out = invalidState_;
249  return;
250  }
251  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
252  int nPoints = 0;
253  setIState(sStart,svBuf,nPoints);
254 
255  double pars[6] = {0,0,0,0,0,0};
256  pars[RADIUS_P] = cDest.radius();
257 
258 
259  propagate(svBuf,nPoints,RADIUS_DT, pars);
260 
261  //(re)set it before leaving: dir =1 (-1) if path increased (decreased) and 0 if it didn't change
262  //need to implement this somewhere else as a separate function
263  double lDir = 0;
264  if (sStart.path() < svBuf[cIndex_(nPoints-1)].path()) lDir = 1.;
265  if (sStart.path() > svBuf[cIndex_(nPoints-1)].path()) lDir = -1.;
266  svBuf[cIndex_(nPoints-1)].dir = lDir;
267  out= svBuf[cIndex_(nPoints-1)];
268  return;
269 }
StateInfo StateArray[MAX_POINTS+1]
int cIndex_(int ind) const
(Internals) circular index for array of transients
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
Scalar radius() const
Radius of the cylinder.
Definition: Cylinder.h:67
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
void SteppingHelixPropagator::propagate ( const SteppingHelixStateInfo ftsStart,
const GlobalPoint pDest,
SteppingHelixStateInfo out 
) const

Propagate to PCA to point given a starting point.

Definition at line 272 of file SteppingHelixPropagator.cc.

References cIndex_(), initStateArraySHPSpecific(), invalidState_, SteppingHelixStateInfo::isValid(), POINT_PCA_DT, propagate(), sendLogWarning_, setIState(), PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().

274  {
275 
276  if (! sStart.isValid()){
277  if (sendLogWarning_){
278  edm::LogWarning("SteppingHelixPropagator")<<"Can't propagate: invalid input state"
279  <<std::endl;
280  }
281  out = invalidState_;
282  return;
283  }
284  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
285  int nPoints = 0;
286  setIState(sStart,svBuf,nPoints);
287 
288  double pars[6] = {pDest.x(), pDest.y(), pDest.z(), 0, 0, 0};
289 
290 
291  propagate(svBuf,nPoints,POINT_PCA_DT, pars);
292 
293  out = svBuf[cIndex_(nPoints-1)];
294  return;
295 }
StateInfo StateArray[MAX_POINTS+1]
T y() const
Definition: PV3DBase.h:63
int cIndex_(int ind) const
(Internals) circular index for array of transients
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
T z() const
Definition: PV3DBase.h:64
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
T x() const
Definition: PV3DBase.h:62
void SteppingHelixPropagator::propagate ( const SteppingHelixStateInfo ftsStart,
const GlobalPoint pDest1,
const GlobalPoint pDest2,
SteppingHelixStateInfo out 
) const

Propagate to PCA to a line (given by 2 points) given a starting point.

Definition at line 298 of file SteppingHelixPropagator.cc.

References cIndex_(), alignCSCRings::e, initStateArraySHPSpecific(), invalidState_, SteppingHelixStateInfo::isValid(), LINE_PCA_DT, mag(), propagate(), sendLogWarning_, setIState(), PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().

300  {
301 
302  if ((pDest1-pDest2).mag() < 1e-10 || !sStart.isValid()){
303  if (sendLogWarning_){
304  if ((pDest1-pDest2).mag() < 1e-10)
305  edm::LogWarning("SteppingHelixPropagator")<<"Can't propagate: points are too close"
306  <<std::endl;
307  if (!sStart.isValid())
308  edm::LogWarning("SteppingHelixPropagator")<<"Can't propagate: invalid input state"
309  <<std::endl;
310  }
311  out = invalidState_;
312  return;
313  }
314  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
315  int nPoints = 0;
316  setIState(sStart,svBuf,nPoints);
317 
318  double pars[6] = {pDest1.x(), pDest1.y(), pDest1.z(),
319  pDest2.x(), pDest2.y(), pDest2.z()};
320 
321  propagate(svBuf,nPoints,LINE_PCA_DT, pars);
322 
323  out = svBuf[cIndex_(nPoints-1)];
324  return;
325 }
StateInfo StateArray[MAX_POINTS+1]
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
T y() const
Definition: PV3DBase.h:63
int cIndex_(int ind) const
(Internals) circular index for array of transients
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
T z() const
Definition: PV3DBase.h:64
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
T x() const
Definition: PV3DBase.h:62
SteppingHelixPropagator::Result SteppingHelixPropagator::propagate ( StateArray svBuff,
int &  nPoints,
SteppingHelixPropagator::DestType  type,
const double  pars[6],
double  epsilon = 1e-3 
) const
protected

propagate: chose stop point by type argument propagate to fixed radius [ r = sqrt(x**2+y**2) ] with precision epsilon propagate to plane by [x0,y0,z0, n_x, n_y, n_z] parameters

define a fast-skip distance: should be the shortest of a possible step or distance

Definition at line 343 of file SteppingHelixPropagator.cc.

References alongMomentum, anyDirection, cIndex_(), debug_, SteppingHelixStateInfo::dEdx, defaultStep_, dir, alignCSCRings::e, SteppingHelixStateInfo::FAULT, SteppingHelixStateInfo::field, field_, HEL_AS_F, SteppingHelixStateInfo::INACC, SteppingHelixStateInfo::isValid_, LINE_PCA_DT, LogTrace, makeAtomStep(), MAX_STEPS, metname, SteppingHelixStateInfo::OK, oppositeToMomentum, SteppingHelixStateInfo::p3, PATHL_DT, PATHL_P, PLANE_DT, POINT_PCA_DT, Propagator::propagationDirection(), SteppingHelixStateInfo::r3, RADIUS_DT, RADIUS_P, SteppingHelixStateInfo::RANGEOUT, refToDest(), refToMagVolume(), refToMatVolume(), query::result, SteppingHelixStateInfo::ResultName, sendLogWarning_, SteppingHelixStateInfo::status_, AlCaHLTBitMon_QueryRunRegistry::string, SteppingHelixStateInfo::UNDEFINED, useIsYokeFlag_, useMagVolumes_, useMatVolumes_, useTuningForL2Speed_, SteppingHelixStateInfo::WRONG_VOLUME, Z_DT, and Z_P.

345  {
346 
347  static const std::string metname = "SteppingHelixPropagator";
348  StateInfo* svCurrent = &svBuf[cIndex_(nPoints-1)];
349 
350  //check if it's going to work at all
351  double tanDist = 0;
352  double dist = 0;
353  PropagationDirection refDirection = anyDirection;
354  Result result = refToDest(type, (*svCurrent), pars, dist, tanDist, refDirection);
355 
356  if (result != SteppingHelixStateInfo::OK || fabs(dist) > 1e6){
357  svCurrent->status_ = result;
358  if (fabs(dist) > 1e6) svCurrent->status_ = SteppingHelixStateInfo::INACC;
359  svCurrent->isValid_ = false;
360  svCurrent->field = field_;
361  if (sendLogWarning_){
362  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<" Failed after first refToDest check with status "
364  <<std::endl;
365  }
366  return result;
367  }
368 
370  bool makeNextStep = true;
371  double dStep = defaultStep_;
372  PropagationDirection dir,oldDir;
373  dir = propagationDirection();
374  oldDir = dir;
375  int nOsc = 0;
376 
377  double distMag = 1e12;
378  double tanDistMag = 1e12;
379 
380  double distMat = 1e12;
381  double tanDistMat = 1e12;
382 
383  double tanDistNextCheck = -0.1;//just need a negative start val
384  double tanDistMagNextCheck = -0.1;
385  double tanDistMatNextCheck = -0.1;
386  double oldDStep = 0;
387  PropagationDirection oldRefDirection = propagationDirection();
388 
391 
392  bool isFirstStep = true;
393  bool expectNewMagVolume = false;
394 
395  int loopCount = 0;
396  while (makeNextStep){
397  dStep = defaultStep_;
398  svCurrent = &svBuf[cIndex_(nPoints-1)];
399  double curZ = svCurrent->r3.z();
400  double curR = svCurrent->r3.perp();
401  if ( fabs(curZ) < 440 && curR < 260) dStep = defaultStep_*2;
402 
403  //more such ifs might be scattered around
404  //even though dStep is large, it will still make stops at each volume boundary
406  dStep = 100.;
407  if (! useIsYokeFlag_ && fabs(curZ) < 667 && curR > 380 && curR < 850){
408  dStep = 5*(1+0.2*svCurrent->p3.mag());
409  }
410  }
411 
412  // refDirection = propagationDirection();
413 
414  tanDistNextCheck -= oldDStep;
415  tanDistMagNextCheck -= oldDStep;
416  tanDistMatNextCheck -= oldDStep;
417 
418  if (tanDistNextCheck < 0){
419  //use pre-computed values if it's the first step
420  if (! isFirstStep) refToDest(type, (*svCurrent), pars, dist, tanDist, refDirection);
421  // constrain allowed path for a tangential approach
422  if (fabs(tanDist) > 4.*(fabs(dist)) ) tanDist *= tanDist == 0 ? 0 :fabs(dist/tanDist*4.);
423 
424  tanDistNextCheck = fabs(tanDist)*0.5 - 0.5; //need a better guess (to-do)
425  //reasonable limit
426  if (tanDistNextCheck > defaultStep_*20. ) tanDistNextCheck = defaultStep_*20.;
427  oldRefDirection = refDirection;
428  } else {
429  tanDist = tanDist > 0. ? tanDist - oldDStep : tanDist + oldDStep;
430  refDirection = oldRefDirection;
431  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Skipped refToDest: guess tanDist = "<<tanDist
432  <<" next check at "<<tanDistNextCheck<<std::endl;
433  }
435  double fastSkipDist = fabs(dist) > fabs(tanDist) ? tanDist : dist;
436 
438  dir = refDirection;
439  } else {
440  dir = propagationDirection();
441  if (fabs(tanDist)<0.1 && refDirection != dir ){
442  //how did it get here? nOsc++;
443  dir = refDirection;
444  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"NOTE: overstepped last time: switch direction (can do it if within 1 mm)"<<std::endl;
445  }
446  }
447 
448  if (useMagVolumes_ && ! (fabs(dist) < fabs(epsilon))){//need to know the general direction
449  if (tanDistMagNextCheck < 0){
450  resultToMag = refToMagVolume((*svCurrent), dir, distMag, tanDistMag, fabs(fastSkipDist), expectNewMagVolume, fabs(tanDist));
451  // constrain allowed path for a tangential approach
452  if (fabs(tanDistMag) > 4.*(fabs(distMag)) ) tanDistMag *= tanDistMag == 0 ? 0 : fabs(distMag/tanDistMag*4.);
453 
454  tanDistMagNextCheck = fabs(tanDistMag)*0.5-0.5; //need a better guess (to-do)
455  //reasonable limit; "turn off" checking if bounds are further than the destination
456  if (tanDistMagNextCheck > defaultStep_*20.
457  || fabs(dist) < fabs(distMag)
458  || resultToMag ==SteppingHelixStateInfo::INACC)
459  tanDistMagNextCheck = defaultStep_*20 > fabs(fastSkipDist) ? fabs(fastSkipDist) : defaultStep_*20;
460  if (resultToMag != SteppingHelixStateInfo::INACC
461  && resultToMag != SteppingHelixStateInfo::OK) tanDistMagNextCheck = -1;
462  } else {
463  // resultToMag = SteppingHelixStateInfo::OK;
464  tanDistMag = tanDistMag > 0. ? tanDistMag - oldDStep : tanDistMag + oldDStep;
465  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Skipped refToMag: guess tanDistMag = "<<tanDistMag
466  <<" next check at "<<tanDistMagNextCheck;
467  }
468  }
469 
470  if (useMatVolumes_ && ! (fabs(dist) < fabs(epsilon))){//need to know the general direction
471  if (tanDistMatNextCheck < 0){
472  resultToMat = refToMatVolume((*svCurrent), dir, distMat, tanDistMat, fabs(fastSkipDist));
473  // constrain allowed path for a tangential approach
474  if (fabs(tanDistMat) > 4.*(fabs(distMat)) ) tanDistMat *= tanDistMat == 0 ? 0 : fabs(distMat/tanDistMat*4.);
475 
476  tanDistMatNextCheck = fabs(tanDistMat)*0.5-0.5; //need a better guess (to-do)
477  //reasonable limit; "turn off" checking if bounds are further than the destination
478  if (tanDistMatNextCheck > defaultStep_*20.
479  || fabs(dist) < fabs(distMat)
480  || resultToMat ==SteppingHelixStateInfo::INACC )
481  tanDistMatNextCheck = defaultStep_*20 > fabs(fastSkipDist) ? fabs(fastSkipDist) : defaultStep_*20;
482  if (resultToMat != SteppingHelixStateInfo::INACC
483  && resultToMat != SteppingHelixStateInfo::OK) tanDistMatNextCheck = -1;
484  } else {
485  // resultToMat = SteppingHelixStateInfo::OK;
486  tanDistMat = tanDistMat > 0. ? tanDistMat - oldDStep : tanDistMat + oldDStep;
487  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Skipped refToMat: guess tanDistMat = "<<tanDistMat
488  <<" next check at "<<tanDistMatNextCheck;
489  }
490  }
491 
492  double rDotP = svCurrent->r3.dot(svCurrent->p3);
493  if ((fabs(curZ) > 1.5e3 || curR >800.)
494  && ((dir == alongMomentum && rDotP > 0)
495  || (dir == oppositeToMomentum && rDotP < 0) )
496  ){
497  dStep = fabs(tanDist) -1e-12;
498  }
499  double tanDistMin = fabs(tanDist);
500  if (tanDistMin > fabs(tanDistMag)+0.05 &&
501  (resultToMag == SteppingHelixStateInfo::OK || resultToMag == SteppingHelixStateInfo::WRONG_VOLUME)){
502  tanDistMin = fabs(tanDistMag)+0.05; //try to step into the next volume
503  expectNewMagVolume = true;
504  } else expectNewMagVolume = false;
505 
506  if (tanDistMin > fabs(tanDistMat)+0.05 && resultToMat == SteppingHelixStateInfo::OK){
507  tanDistMin = fabs(tanDistMat)+0.05; //try to step into the next volume
508  if (expectNewMagVolume) expectNewMagVolume = false;
509  }
510 
511  if (tanDistMin*fabs(svCurrent->dEdx) > 0.5*svCurrent->p3.mag()){
512  tanDistMin = 0.5*svCurrent->p3.mag()/fabs(svCurrent->dEdx);
513  if (expectNewMagVolume) expectNewMagVolume = false;
514  }
515 
516 
517 
518  double tanDistMinLazy = fabs(tanDistMin);
519  if ((type == POINT_PCA_DT || type == LINE_PCA_DT)
520  && fabs(tanDist) < 2.*fabs(tanDistMin) ){
521  //being lazy here; the best is to take into account the curvature
522  tanDistMinLazy = fabs(tanDistMin)*0.5;
523  }
524 
525  if (fabs(tanDistMinLazy) < dStep){
526  dStep = fabs(tanDistMinLazy);
527  }
528 
529  //keep this path length for the next step
530  oldDStep = dStep;
531 
532  if (dStep > 1e-10 && ! (fabs(dist) < fabs(epsilon))){
533  StateInfo* svNext = &svBuf[cIndex_(nPoints)];
534  makeAtomStep((*svCurrent), (*svNext), dStep, dir, HEL_AS_F);
535 // if (useMatVolumes_ && expectNewMagVolume
536 // && svCurrent->magVol == svNext->magVol){
537 // double tmpDist=0;
538 // double tmpDistMag = 0;
539 // if (refToMagVolume((*svNext), dir, tmpDist, tmpDistMag, fabs(dist)) != SteppingHelixStateInfo::OK){
540 // //the point appears to be outside, but findVolume claims the opposite
541 // dStep += 0.05*fabs(tanDistMag/distMag); oldDStep = dStep; //do it again with a bigger step
542 // if (debug_) LogTrace(metname)
543 // <<"Failed to get into new mag volume: will try with new bigger step "<<dStep<<std::endl;
544 // makeAtomStep((*svCurrent), (*svNext), dStep, dir, HEL_AS_F);
545 // }
546 // }
547  nPoints++; svCurrent = &svBuf[cIndex_(nPoints-1)];
548  if (oldDir != dir){
549  nOsc++;
550  tanDistNextCheck = -1;//check dist after osc
551  tanDistMagNextCheck = -1;
552  tanDistMatNextCheck = -1;
553  }
554  oldDir = dir;
555  }
556 
557  if (nOsc>1 && fabs(dStep)>epsilon){
558  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Ooops"<<std::endl;
559  }
560 
561  if (fabs(dist) < fabs(epsilon) ) result = SteppingHelixStateInfo::OK;
562 
563  if ((type == POINT_PCA_DT || type == LINE_PCA_DT )
564  && fabs(dStep) < fabs(epsilon) ){
565  //now check if it's not a branch point (peek ahead at 1 cm)
566  double nextDist = 0;
567  double nextTanDist = 0;
568  PropagationDirection nextRefDirection = anyDirection;
569  StateInfo* svNext = &svBuf[cIndex_(nPoints)];
570  makeAtomStep((*svCurrent), (*svNext), 1., dir, HEL_AS_F);
571  nPoints++; svCurrent = &svBuf[cIndex_(nPoints-1)];
572  refToDest(type, (*svCurrent), pars, nextDist, nextTanDist, nextRefDirection);
573  if ( fabs(nextDist) > fabs(dist)){
574  nPoints--; svCurrent = &svBuf[cIndex_(nPoints-1)];
576  if (debug_){
577  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Found real local minimum in PCA"<<std::endl;
578  }
579  } else {
580  //keep this trial point and continue
581  dStep = defaultStep_;
582  if (debug_){
583  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Found branch point in PCA"<<std::endl;
584  }
585  }
586  }
587 
588  if (nPoints > MAX_STEPS*1./defaultStep_ || loopCount > MAX_STEPS*100
589  || nOsc > 6 ) result = SteppingHelixStateInfo::FAULT;
590 
591  if (svCurrent->p3.mag() < 0.1 ) result = SteppingHelixStateInfo::RANGEOUT;
592 
593  curZ = svCurrent->r3.z();
594  curR = svCurrent->r3.perp();
595  if ( curR > 20000 || fabs(curZ) > 20000 ) result = SteppingHelixStateInfo::INACC;
596 
597  makeNextStep = result == SteppingHelixStateInfo::UNDEFINED;
598  svCurrent->status_ = result;
599  svCurrent->isValid_ = (result == SteppingHelixStateInfo::OK || makeNextStep );
600  svCurrent->field = field_;
601 
602  isFirstStep = false;
603  loopCount++;
604  }
605 
607  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<" Propagation failed with status "
609  <<std::endl;
610  if (result == SteppingHelixStateInfo::RANGEOUT)
611  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<" Momentum at last point is too low (<0.1) p_last = "
612  <<svCurrent->p3.mag()
613  <<std::endl;
614  if (result == SteppingHelixStateInfo::INACC)
615  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<" Went too far: the last point is at "<<svCurrent->r3
616  <<std::endl;
617  if (result == SteppingHelixStateInfo::FAULT && nOsc > 6)
618  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<" Infinite loop condidtion detected: going in cycles. Break after 6 cycles"
619  <<std::endl;
620  if (result == SteppingHelixStateInfo::FAULT && nPoints > MAX_STEPS*1./defaultStep_)
621  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<" Tired to go farther. Made too many steps: more than "
623  <<std::endl;
624 
625  }
626 
627  if (debug_){
628  switch (type) {
629  case RADIUS_DT:
630  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"going to radius "<<pars[RADIUS_P]<<std::endl;
631  break;
632  case Z_DT:
633  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"going to z "<<pars[Z_P]<<std::endl;
634  break;
635  case PATHL_DT:
636  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"going to pathL "<<pars[PATHL_P]<<std::endl;
637  break;
638  case PLANE_DT:
639  {
640  Point rPlane(pars[0], pars[1], pars[2]);
641  Vector nPlane(pars[3], pars[4], pars[5]);
642  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"going to plane r0:"<<rPlane<<" n:"<<nPlane<<std::endl;
643  }
644  break;
645  case POINT_PCA_DT:
646  {
647  Point rDest(pars[0], pars[1], pars[2]);
648  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"going to PCA to point "<<rDest<<std::endl;
649  }
650  break;
651  case LINE_PCA_DT:
652  {
653  Point rDest1(pars[0], pars[1], pars[2]);
654  Point rDest2(pars[3], pars[4], pars[5]);
655  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"going to PCA to line "<<rDest1<<" - "<<rDest2<<std::endl;
656  }
657  break;
658  default:
659  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"going to NOT IMPLEMENTED"<<std::endl;
660  break;
661  }
662  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Made "<<nPoints-1<<" steps and stopped at(cur step) "<<svCurrent->r3<<" nOsc "<<nOsc<<std::endl;
663  }
664 
665  return result;
666 }
type
Definition: HCALResponse.h:21
virtual PropagationDirection propagationDirection() const
Definition: Propagator.h:155
Result refToDest(DestType dest, const SteppingHelixPropagator::StateInfo &sv, const double pars[6], double &dist, double &tanDist, PropagationDirection &refDirection, double fastSkipDist=1e12) const
(Internals) determine distance and direction from the current position to the plane ...
const std::string metname
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
SteppingHelixStateInfo StateInfo
int cIndex_(int ind) const
(Internals) circular index for array of transients
PropagationDirection
Result refToMatVolume(const SteppingHelixPropagator::StateInfo &sv, PropagationDirection dir, double &dist, double &tanDist, double fastSkipDist=1e12) const
SteppingHelixStateInfo::Result Result
tuple result
Definition: query.py:137
math::XYZPoint Point
#define LogTrace(id)
bool makeAtomStep(SteppingHelixPropagator::StateInfo &svCurrent, SteppingHelixPropagator::StateInfo &svNext, double dS, PropagationDirection dir, SteppingHelixPropagator::Fancy fancy) const
main stepping function: compute next state vector after a step of length dS
Result refToMagVolume(const SteppingHelixPropagator::StateInfo &sv, PropagationDirection dir, double &dist, double &tanDist, double fastSkipDist=1e12, bool expectNewMagVolume=false, double maxStep=1e12) const
dbl *** dir
Definition: mlp_gen.cc:35
const double epsilon
const MagneticField * field_
static const std::string ResultName[MAX_RESULT]
std::pair< TrajectoryStateOnSurface, double > SteppingHelixPropagator::propagateWithPath ( const FreeTrajectoryState ftsStart,
const Plane pDest 
) const
overridevirtual

Propagate to Plane given a starting point: return final TrajectoryState and path length from start to this point

Implements Propagator.

Definition at line 93 of file SteppingHelixPropagator.cc.

References SteppingHelixStateInfo::getStateOnSurface(), initStateArraySHPSpecific(), SteppingHelixStateInfo::path(), propagate(), and setIState().

Referenced by PropagateToCal::propagate(), and propagateWithPath().

94  {
95 
96  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
97  int nPoints = 0;
98  setIState(SteppingHelixStateInfo(ftsStart),svBuf,nPoints);
99 
100  StateInfo svCurrent;
101  propagate(svBuf[0], pDest, svCurrent);
102 
103  return TsosPP(svCurrent.getStateOnSurface(pDest), svCurrent.path());
104 }
StateInfo StateArray[MAX_POINTS+1]
SteppingHelixStateInfo StateInfo
std::pair< TrajectoryStateOnSurface, double > TsosPP
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
std::pair< TrajectoryStateOnSurface, double > SteppingHelixPropagator::propagateWithPath ( const FreeTrajectoryState ftsStart,
const Cylinder cDest 
) const
overridevirtual

Propagate to Cylinder given a starting point: return final TrajectoryState and path length from start to this point

Implements Propagator.

Definition at line 107 of file SteppingHelixPropagator.cc.

References SteppingHelixStateInfo::getStateOnSurface(), initStateArraySHPSpecific(), SteppingHelixStateInfo::path(), propagate(), returnTangentPlane_, and setIState().

108  {
109 
110  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
111  int nPoints = 0;
112  setIState(SteppingHelixStateInfo(ftsStart),svBuf,nPoints);
113 
114  StateInfo svCurrent;
115  propagate(svBuf[0], cDest, svCurrent);
116 
117  return TsosPP(svCurrent.getStateOnSurface(cDest, returnTangentPlane_), svCurrent.path());
118 }
StateInfo StateArray[MAX_POINTS+1]
SteppingHelixStateInfo StateInfo
std::pair< TrajectoryStateOnSurface, double > TsosPP
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
std::pair< FreeTrajectoryState, double > SteppingHelixPropagator::propagateWithPath ( const FreeTrajectoryState ftsStart,
const GlobalPoint pDest 
) const
overridevirtual

Propagate to PCA to point given a starting point.

Reimplemented from Propagator.

Definition at line 122 of file SteppingHelixPropagator.cc.

References SteppingHelixStateInfo::getFreeState(), initStateArraySHPSpecific(), SteppingHelixStateInfo::path(), propagate(), and setIState().

123  {
124  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
125  int nPoints = 0;
126  setIState(SteppingHelixStateInfo(ftsStart),svBuf,nPoints);
127 
128  StateInfo svCurrent;
129  propagate(svBuf[0], pDest,svCurrent);
130 
131  FreeTrajectoryState ftsDest;
132  svCurrent.getFreeState(ftsDest);
133 
134  return FtsPP(ftsDest, svCurrent.path());
135 }
StateInfo StateArray[MAX_POINTS+1]
SteppingHelixStateInfo StateInfo
std::pair< FreeTrajectoryState, double > FtsPP
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
std::pair< FreeTrajectoryState, double > SteppingHelixPropagator::propagateWithPath ( const FreeTrajectoryState ftsStart,
const GlobalPoint pDest1,
const GlobalPoint pDest2 
) const
overridevirtual

Propagate to PCA to a line (given by 2 points) given a starting point.

Reimplemented from Propagator.

Definition at line 138 of file SteppingHelixPropagator.cc.

References alignCSCRings::e, SteppingHelixStateInfo::getFreeState(), initStateArraySHPSpecific(), mag(), SteppingHelixStateInfo::path(), propagate(), sendLogWarning_, and setIState().

139  {
140 
141  if ((pDest1-pDest2).mag() < 1e-10){
142  if (sendLogWarning_){
143  edm::LogWarning("SteppingHelixPropagator")<<"Can't propagate: the points should be at a bigger distance"
144  <<std::endl;
145  }
146  return FtsPP();
147  }
148  StateArray svBuf; initStateArraySHPSpecific(svBuf, true);
149  int nPoints = 0;
150  setIState(SteppingHelixStateInfo(ftsStart),svBuf,nPoints);
151 
152  StateInfo svCurrent;
153  propagate(svBuf[0], pDest1, pDest2,svCurrent);
154 
155  FreeTrajectoryState ftsDest;
156  svCurrent.getFreeState(ftsDest);
157 
158  return FtsPP(ftsDest, svCurrent.path());
159 }
StateInfo StateArray[MAX_POINTS+1]
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
SteppingHelixStateInfo StateInfo
std::pair< FreeTrajectoryState, double > FtsPP
void initStateArraySHPSpecific(StateArray &svBuf, bool flagsOnly) const
(Internals) set defaults needed for states used inside propagate methods
void propagate(const SteppingHelixStateInfo &ftsStart, const Surface &sDest, SteppingHelixStateInfo &out) const
Propagate to Plane given a starting point.
void setIState(const SteppingHelixStateInfo &sStart, StateArray &svBuff, int &nPoints) const
(Internals) Init starting point
std::pair< FreeTrajectoryState, double > SteppingHelixPropagator::propagateWithPath ( const FreeTrajectoryState ftsStart,
const reco::BeamSpot beamSpot 
) const
overridevirtual

Propagate to PCA to a line (given by beamSpot position and slope) given a starting point.

Reimplemented from Propagator.

Definition at line 163 of file SteppingHelixPropagator.cc.

References reco::BeamSpot::dxdz(), reco::BeamSpot::dydz(), propagateWithPath(), reco::BeamSpot::x0(), reco::BeamSpot::y0(), and reco::BeamSpot::z0().

164  {
165  GlobalPoint pDest1(beamSpot.x0(), beamSpot.y0(), beamSpot.z0());
166  GlobalPoint pDest2(pDest1.x() + beamSpot.dxdz()*1e3,
167  pDest1.y() + beamSpot.dydz()*1e3,
168  pDest1.z() + 1e3);
169  return propagateWithPath(ftsStart, pDest1, pDest2);
170 }
double z0() const
z coordinate
Definition: BeamSpot.h:68
double dydz() const
dydz slope
Definition: BeamSpot.h:84
double dxdz() const
dxdz slope
Definition: BeamSpot.h:82
double y0() const
y coordinate
Definition: BeamSpot.h:66
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &ftsStart, const Plane &pDest) const override
double x0() const
x coordinate
Definition: BeamSpot.h:64
SteppingHelixPropagator::Result SteppingHelixPropagator::refToDest ( SteppingHelixPropagator::DestType  dest,
const SteppingHelixPropagator::StateInfo sv,
const double  pars[6],
double &  dist,
double &  tanDist,
PropagationDirection refDirection,
double  fastSkipDist = 1e12 
) const
protected

(Internals) determine distance and direction from the current position to the plane

Definition at line 1667 of file SteppingHelixPropagator.cc.

References alongMomentum, anyDirection, SteppingHelixStateInfo::bf, CONE_DT, funct::cos(), debug_, PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi::dR, alignCSCRings::e, i, SteppingHelixStateInfo::INACC, LINE_PCA_DT, LogTrace, mag(), metname, SteppingHelixStateInfo::NOT_IMPLEMENTED, SteppingHelixStateInfo::OK, oppositeToMomentum, SteppingHelixStateInfo::p3, SteppingHelixStateInfo::path(), PATHL_DT, PATHL_P, Geom::pi(), PLANE_DT, POINT_PCA_DT, SteppingHelixStateInfo::q, SteppingHelixStateInfo::r3, RADIUS_DT, RADIUS_P, query::result, funct::sin(), mathSSE::sqrt(), AlCaHLTBitMon_QueryRunRegistry::string, metsig::tau, theta(), Z_DT, and Z_P.

Referenced by propagate(), refToMagVolume(), and refToMatVolume().

1672  {
1673  static const std::string metname = "SteppingHelixPropagator";
1675 
1676  switch (dest){
1677  case RADIUS_DT:
1678  {
1679  double curR = sv.r3.perp();
1680  dist = pars[RADIUS_P] - curR;
1681  if (fabs(dist) > fastSkipDist){
1683  break;
1684  }
1685  double curP2 = sv.p3.mag2();
1686  double curPtPos2 = sv.p3.perp2(); if(curPtPos2< 1e-16) curPtPos2=1e-16;
1687 
1688  double cosDPhiPR = (sv.r3.x()*sv.p3.x()+sv.r3.y()*sv.p3.y());//only the sign is needed cos((sv.r3.deltaPhi(sv.p3)));
1689  refDirection = dist*cosDPhiPR > 0 ?
1691  tanDist = dist*sqrt(curP2/curPtPos2);
1692  result = SteppingHelixStateInfo::OK;
1693  }
1694  break;
1695  case Z_DT:
1696  {
1697  double curZ = sv.r3.z();
1698  dist = pars[Z_P] - curZ;
1699  if (fabs(dist) > fastSkipDist){
1701  break;
1702  }
1703  double curP = sv.p3.mag();
1704  refDirection = sv.p3.z()*dist > 0. ?
1706  tanDist = dist/sv.p3.z()*curP;
1707  result = SteppingHelixStateInfo::OK;
1708  }
1709  break;
1710  case PLANE_DT:
1711  {
1712  Point rPlane(pars[0], pars[1], pars[2]);
1713  Vector nPlane(pars[3], pars[4], pars[5]);
1714 
1715 
1716  // unfortunately this doesn't work: the numbers are too large
1717  // bool pVertical = fabs(pars[5])>0.9999;
1718  // double dRDotN = pVertical? (sv.r3.z() - rPlane.z())*nPlane.z() :(sv.r3 - rPlane).dot(nPlane);
1719  double dRDotN = (sv.r3.x()-rPlane.x())*nPlane.x() + (sv.r3.y()-rPlane.y())*nPlane.y() + (sv.r3.z()-rPlane.z())*nPlane.z();//(sv.r3 - rPlane).dot(nPlane);
1720 
1721  dist = fabs(dRDotN);
1722  if (dist > fastSkipDist){
1724  break;
1725  }
1726  double curP = sv.p3.mag();
1727  double p0 = curP;
1728  double p0Inv = 1./p0;
1729  Vector tau(sv.p3); tau *=p0Inv;
1730  double tN = tau.dot(nPlane);
1731  refDirection = tN*dRDotN < 0. ?
1733  double b0 = sv.bf.mag();
1734  if (fabs(tN)>1e-24){
1735  tanDist = -dRDotN/tN;
1736  } else {
1737  tN = 1e-24;
1738  if (fabs(dRDotN)>1e-24) tanDist = 1e6;
1739  else tanDist = 1;
1740  }
1741  if (fabs(tanDist) > 1e4) tanDist = 1e4;
1742  if (b0>1.5e-6){
1743  double b0Inv = 1./b0;
1744  double tNInv = 1./tN;
1745  Vector bHat(sv.bf); bHat *=b0Inv;
1746  double bHatN = bHat.dot(nPlane);
1747  double cosPB = bHat.dot(tau);
1748  double kVal = 2.99792458e-3*sv.q*p0Inv*b0;
1749  double aVal = tanDist*kVal;
1750  Vector lVec = bHat.cross(tau);
1751  double bVal = lVec.dot(nPlane)*tNInv;
1752  if (fabs(aVal*bVal)< 0.3){
1753  double cVal = 1. - bHatN*cosPB*tNInv; // - sv.bf.cross(lVec).dot(nPlane)*b0Inv*tNInv; //1- bHat_n*bHat_tau/tau_n;
1754  double aacVal = cVal*aVal*aVal;
1755  if (fabs(aacVal)<1){
1756  double tanDCorr = bVal/2. + (bVal*bVal/2. + cVal/6)*aVal;
1757  tanDCorr *= aVal;
1758  //+ (-bVal/24. + 0.625*bVal*bVal*bVal + 5./12.*bVal*cVal)*aVal*aVal*aVal
1759  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<tanDist<<" vs "
1760  <<tanDist*(1.+tanDCorr)<<" corr "<<tanDist*tanDCorr<<std::endl;
1761  tanDist *= (1.+tanDCorr);
1762  } else {
1763  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"AACVal "<< fabs(aacVal)
1764  <<" = "<<aVal<<"**2 * "<<cVal<<" too large:: will not converge"<<std::endl;
1765  }
1766  } else {
1767  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"ABVal "<< fabs(aVal*bVal)
1768  <<" = "<<aVal<<" * "<<bVal<<" too large:: will not converge"<<std::endl;
1769  }
1770  }
1771  result = SteppingHelixStateInfo::OK;
1772  }
1773  break;
1774  case CONE_DT:
1775  {
1776  Point cVertex(pars[0], pars[1], pars[2]);
1777  if (cVertex.perp2() < 1e-10){
1778  //assumes the cone axis/vertex is along z
1779  Vector relV3 = sv.r3 - cVertex;
1780  double relV3mag = relV3.mag();
1781  // double relV3Theta = relV3.theta();
1782  double theta(pars[3]);
1783  // double dTheta = theta-relV3Theta;
1784  double sinTheta = sin(theta);
1785  double cosTheta = cos(theta);
1786  double cosV3Theta = relV3.z()/relV3mag;
1787  if (cosV3Theta>1) cosV3Theta=1;
1788  if (cosV3Theta<-1) cosV3Theta=-1;
1789  double sinV3Theta = sqrt(1.-cosV3Theta*cosV3Theta);
1790 
1791  double sinDTheta = sinTheta*cosV3Theta - cosTheta*sinV3Theta;//sin(dTheta);
1792  double cosDTheta = cosTheta*cosV3Theta + sinTheta*sinV3Theta;//cos(dTheta);
1793  bool isInside = sinTheta > sinV3Theta && cosTheta*cosV3Theta > 0;
1794  dist = isInside || cosDTheta > 0 ? relV3mag*sinDTheta : relV3mag;
1795  if (fabs(dist) > fastSkipDist){
1797  break;
1798  }
1799 
1800  double relV3phi=relV3.phi();
1801  double normPhi = isInside ?
1802  Geom::pi() + relV3phi : relV3phi;
1803  double normTheta = theta > Geom::pi()/2. ?
1804  ( isInside ? 1.5*Geom::pi() - theta : theta - Geom::pi()/2. )
1805  : ( isInside ? Geom::pi()/2. - theta : theta + Geom::pi()/2 );
1806  //this is a normVector from the cone to the point
1807  Vector norm; norm.setRThetaPhi(fabs(dist), normTheta, normPhi);
1808  double curP = sv.p3.mag(); double cosp3theta = sv.p3.z()/curP;
1809  if (cosp3theta>1) cosp3theta=1;
1810  if (cosp3theta<-1) cosp3theta=-1;
1811  double sineConeP = sinTheta*cosp3theta - cosTheta*sqrt(1.-cosp3theta*cosp3theta);
1812 
1813  double sinSolid = norm.dot(sv.p3)/(fabs(dist)*curP);
1814  tanDist = fabs(sinSolid) > fabs(sineConeP) ? dist/fabs(sinSolid) : dist/fabs(sineConeP);
1815 
1816 
1817  refDirection = sinSolid > 0 ?
1819  if (debug_){
1820  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Cone pars: theta "<<theta
1821  <<" normTheta "<<norm.theta()
1822  <<" p3Theta "<<sv.p3.theta()
1823  <<" sinD: "<< sineConeP
1824  <<" sinSolid "<<sinSolid;
1825  }
1826  if (debug_){
1827  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"refToDest:toCone the point is "
1828  <<(isInside? "in" : "out")<<"side the cone"
1829  <<std::endl;
1830  }
1831  }
1832  result = SteppingHelixStateInfo::OK;
1833  }
1834  break;
1835  // case CYLINDER_DT:
1836  // break;
1837  case PATHL_DT:
1838  {
1839  double curS = fabs(sv.path());
1840  dist = pars[PATHL_P] - curS;
1841  if (fabs(dist) > fastSkipDist){
1843  break;
1844  }
1845  refDirection = pars[PATHL_P] > 0 ?
1847  tanDist = dist;
1848  result = SteppingHelixStateInfo::OK;
1849  }
1850  break;
1851  case POINT_PCA_DT:
1852  {
1853  Point pDest(pars[0], pars[1], pars[2]);
1854  double curP = sv.p3.mag();
1855  dist = (sv.r3 - pDest).mag()+ 1e-24;//add a small number to avoid 1/0
1856  tanDist = (sv.r3.dot(sv.p3) - pDest.dot(sv.p3))/curP;
1857  //account for bending in magnetic field (quite approximate)
1858  double b0 = sv.bf.mag();
1859  if (b0>1.5e-6){
1860  double p0 = curP;
1861  double kVal = 2.99792458e-3*sv.q/p0*b0;
1862  double aVal = fabs(dist*kVal);
1863  tanDist *= 1./(1.+ aVal);
1864  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"corrected by aVal "<<aVal<<" to "<<tanDist;
1865  }
1866  refDirection = tanDist < 0 ?
1868  result = SteppingHelixStateInfo::OK;
1869  }
1870  break;
1871  case LINE_PCA_DT:
1872  {
1873  Point rLine(pars[0], pars[1], pars[2]);
1874  Vector dLine(pars[3], pars[4], pars[5]);
1875  dLine = (dLine - rLine);
1876  dLine *= 1./dLine.mag(); if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"dLine "<<dLine;
1877 
1878  Vector dR = sv.r3 - rLine;
1879  double curP = sv.p3.mag();
1880  Vector dRPerp = dR - dLine*(dR.dot(dLine));
1881  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"dRperp "<<dRPerp;
1882 
1883  dist = dRPerp.mag() + 1e-24;//add a small number to avoid 1/0
1884  tanDist = dRPerp.dot(sv.p3)/curP;
1885  //angle wrt line
1886  double cosAlpha2 = dLine.dot(sv.p3)/curP; cosAlpha2 *= cosAlpha2;
1887  tanDist *= 1./sqrt(fabs(1.-cosAlpha2)+1e-96);
1888  //correct for dPhi in magnetic field: this isn't made quite right here
1889  //(the angle between the line and the trajectory plane is neglected .. conservative)
1890  double b0 = sv.bf.mag();
1891  if (b0>1.5e-6){
1892  double p0 = curP;
1893  double kVal = 2.99792458e-3*sv.q/p0*b0;
1894  double aVal = fabs(dist*kVal);
1895  tanDist *= 1./(1.+ aVal);
1896  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"corrected by aVal "<<aVal<<" to "<<tanDist;
1897  }
1898  refDirection = tanDist < 0 ?
1900  result = SteppingHelixStateInfo::OK;
1901  }
1902  break;
1903  default:
1904  {
1905  //some large number
1906  dist = 1e12;
1907  tanDist = 1e12;
1908  refDirection = anyDirection;
1910  }
1911  break;
1912  }
1913 
1914  double tanDistConstrained = tanDist;
1915  if (fabs(tanDist) > 4.*fabs(dist) ) tanDistConstrained *= tanDist == 0 ? 0 : fabs(dist/tanDist*4.);
1916 
1917  if (debug_){
1918  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"refToDest input: dest"<<dest<<" pars[]: ";
1919  for (int i = 0; i < 6; i++){
1920  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<", "<<i<<" "<<pars[i];
1921  }
1922  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<std::endl;
1923  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"refToDest output: "
1924  <<"\t dist" << dist
1925  <<"\t tanDist "<< tanDist
1926  <<"\t tanDistConstr "<< tanDistConstrained
1927  <<"\t refDirection "<< refDirection
1928  <<std::endl;
1929  }
1930  tanDist = tanDistConstrained;
1931 
1932  return result;
1933 }
int i
Definition: DBlmapReader.cc:9
const std::string metname
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Theta< T > theta() const
SteppingHelixStateInfo::Result Result
T sqrt(T t)
Definition: SSEVec.h:48
tuple result
Definition: query.py:137
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
math::XYZPoint Point
#define LogTrace(id)
double pi()
Definition: Pi.h:31
SteppingHelixPropagator::Result SteppingHelixPropagator::refToMagVolume ( const SteppingHelixPropagator::StateInfo sv,
PropagationDirection  dir,
double &  dist,
double &  tanDist,
double  fastSkipDist = 1e12,
bool  expectNewMagVolume = false,
double  maxStep = 1e12 
) const
protected

(Internals) determine distance and direction from the current position to the boundary of current mag volume

Definition at line 1936 of file SteppingHelixPropagator.cc.

References alongMomentum, anyDirection, CONE_DT, debug_, alignCSCRings::e, MagVolume::faces(), i, SteppingHelixStateInfo::INACC, MagVolume::inside(), j, LogTrace, SteppingHelixStateInfo::magVol, metname, DDSolidShapesName::name(), SteppingHelixStateInfo::NOT_IMPLEMENTED, SteppingHelixStateInfo::OK, Cone::openingAngle(), SteppingHelixStateInfo::p3, PLANE_DT, GloballyPositioned< T >::position(), SteppingHelixStateInfo::r3, Cylinder::radius(), RADIUS_DT, RADIUS_P, refToDest(), query::result, GloballyPositioned< T >::rotation(), MagVolume::shapeType(), AlCaHLTBitMon_QueryRunRegistry::string, SteppingHelixStateInfo::UNDEFINED, UNDEFINED_DT, Cone::vertex(), SteppingHelixStateInfo::WRONG_VOLUME, PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), PV3DBase< T, PVType, FrameType >::z(), TkRotation< T >::zx(), TkRotation< T >::zy(), and TkRotation< T >::zz().

Referenced by propagate().

1939  {
1940 
1941  static const std::string metname = "SteppingHelixPropagator";
1943  const MagVolume* cVol = sv.magVol;
1944 
1945  if (cVol == 0) return result;
1946  const std::vector<VolumeSide>& cVolFaces(cVol->faces());
1947 
1948  double distToFace[6] = {0,0,0,0,0,0};
1949  double tanDistToFace[6] = {0,0,0,0,0,0};
1950  PropagationDirection refDirectionToFace[6] = {anyDirection, anyDirection, anyDirection, anyDirection, anyDirection, anyDirection};
1951  Result resultToFace[6] = {result, result, result, result, result, result};
1952  int iFDest = -1;
1953  int iDistMin = -1;
1954 
1955  unsigned int iFDestSorted[6] = {0,0,0,0,0,0};
1956  int nDestSorted =0;
1957  unsigned int nearParallels = 0;
1958 
1959  double curP = sv.p3.mag();
1960 
1961  if (debug_){
1962  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Trying volume "<<DDSolidShapesName::name(cVol->shapeType())
1963  <<" with "<<cVolFaces.size()<<" faces"<<std::endl;
1964  }
1965 
1966  unsigned int nFaces = cVolFaces.size();
1967  for (unsigned int iFace = 0; iFace < nFaces; ++iFace){
1968  if (iFace > 5){
1969  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Too many faces"<<std::endl;
1970  }
1971  if (debug_){
1972  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Start with face "<<iFace<<std::endl;
1973  }
1974 // const Plane* cPlane = dynamic_cast<const Plane*>(&cVolFaces[iFace].surface());
1975 // const Cylinder* cCyl = dynamic_cast<const Cylinder*>(&cVolFaces[iFace].surface());
1976 // const Cone* cCone = dynamic_cast<const Cone*>(&cVolFaces[iFace].surface());
1977  const Surface* cPlane = 0; //only need to know the loc->glob transform
1978  const Cylinder* cCyl = 0;
1979  const Cone* cCone = 0;
1980  if (typeid(cVolFaces[iFace].surface()) == typeid(const Plane&)){
1981  cPlane = &cVolFaces[iFace].surface();
1982  } else if (typeid(cVolFaces[iFace].surface()) == typeid(const Cylinder&)){
1983  cCyl = dynamic_cast<const Cylinder*>(&cVolFaces[iFace].surface());
1984  } else if (typeid(cVolFaces[iFace].surface()) == typeid(const Cone&)){
1985  cCone = dynamic_cast<const Cone*>(&cVolFaces[iFace].surface());
1986  } else {
1987  edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Could not cast a volume side surface to a known type"<<std::endl;
1988  }
1989 
1990  if (debug_){
1991  if (cPlane!=0) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"The face is a plane at "<<cPlane<<std::endl;
1992  if (cCyl!=0) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"The face is a cylinder at "<<cCyl<<std::endl;
1993  }
1994 
1995  double pars[6] = {0,0,0,0,0,0};
1996  DestType dType = UNDEFINED_DT;
1997  if (cPlane != 0){
1998  Point rPlane(cPlane->position().x(),cPlane->position().y(),cPlane->position().z());
1999  // = cPlane->toGlobal(LocalVector(0,0,1.)); nPlane = nPlane.unit();
2000  Vector nPlane(cPlane->rotation().zx(), cPlane->rotation().zy(), cPlane->rotation().zz()); nPlane /= nPlane.mag();
2001 
2002  pars[0] = rPlane.x(); pars[1] = rPlane.y(); pars[2] = rPlane.z();
2003  pars[3] = nPlane.x(); pars[4] = nPlane.y(); pars[5] = nPlane.z();
2004  dType = PLANE_DT;
2005  } else if (cCyl != 0){
2006  if (debug_){
2007  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Cylinder at "<<cCyl->position()
2008  <<" rorated by "<<cCyl->rotation()
2009  <<std::endl;
2010  }
2011  pars[RADIUS_P] = cCyl->radius();
2012  dType = RADIUS_DT;
2013  } else if (cCone != 0){
2014  if (debug_){
2015  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Cone at "<<cCone->position()
2016  <<" rorated by "<<cCone->rotation()
2017  <<" vertex at "<<cCone->vertex()
2018  <<" angle of "<<cCone->openingAngle()
2019  <<std::endl;
2020  }
2021  pars[0] = cCone->vertex().x(); pars[1] = cCone->vertex().y();
2022  pars[2] = cCone->vertex().z();
2023  pars[3] = cCone->openingAngle();
2024  dType = CONE_DT;
2025  } else {
2026  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Unknown surface"<<std::endl;
2027  resultToFace[iFace] = SteppingHelixStateInfo::UNDEFINED;
2028  continue;
2029  }
2030  resultToFace[iFace] =
2031  refToDest(dType, sv, pars,
2032  distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2033 
2034 
2035  if (resultToFace[iFace] != SteppingHelixStateInfo::OK){
2036  if (resultToFace[iFace] == SteppingHelixStateInfo::INACC) result = SteppingHelixStateInfo::INACC;
2037  }
2038 
2039 
2040 
2041  //keep those in right direction for later use
2042  if (resultToFace[iFace] == SteppingHelixStateInfo::OK){
2043  double invDTFPosiF = 1./(1e-32+fabs(tanDistToFace[iFace]));
2044  double dSlope = fabs(distToFace[iFace])*invDTFPosiF;
2045  double maxStepL = maxStep> 100 ? 100 : maxStep; if (maxStepL < 10) maxStepL = 10.;
2046  bool isNearParallel = fabs(tanDistToFace[iFace]) + 100.*curP*dSlope < maxStepL //
2047  //a better choice is to use distance to next check of mag volume instead of 100cm; the last is for ~1.5arcLength(4T)+tandistance< maxStep
2048  && dSlope < 0.15 ; //
2049  if (refDirectionToFace[iFace] == dir || isNearParallel){
2050  if (isNearParallel) nearParallels++;
2051  iFDestSorted[nDestSorted] = iFace;
2052  nDestSorted++;
2053  }
2054  }
2055 
2056  //pick a shortest distance here (right dir only for now)
2057  if (refDirectionToFace[iFace] == dir){
2058  if (iDistMin == -1) iDistMin = iFace;
2059  else if (fabs(distToFace[iFace]) < fabs(distToFace[iDistMin])) iDistMin = iFace;
2060  }
2061  if (debug_)
2062  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<cVol<<" "<<iFace<<" "
2063  <<tanDistToFace[iFace]<<" "<<distToFace[iFace]<<" "<<refDirectionToFace[iFace]<<" "<<dir<<std::endl;
2064 
2065  }
2066 
2067  for (int i = 0;i<nDestSorted; ++i){
2068  int iMax = nDestSorted-i-1;
2069  for (int j=0;j<nDestSorted-i; ++j){
2070  if (fabs(tanDistToFace[iFDestSorted[j]]) > fabs(tanDistToFace[iFDestSorted[iMax]]) ){
2071  iMax = j;
2072  }
2073  }
2074  int iTmp = iFDestSorted[nDestSorted-i-1];
2075  iFDestSorted[nDestSorted-i-1] = iFDestSorted[iMax];
2076  iFDestSorted[iMax] = iTmp;
2077  }
2078 
2079  if (debug_){
2080  for (int i=0;i<nDestSorted;++i){
2081  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<cVol<<" "<<i<<" "<<iFDestSorted[i]<<" "<<tanDistToFace[iFDestSorted[i]]<<std::endl;
2082  }
2083  }
2084 
2085  //now go from the shortest to the largest distance hoping to get a point in the volume.
2086  //other than in case of a near-parallel travel this should stop after the first try
2087 
2088  for (int i=0; i<nDestSorted;++i){
2089  iFDest = iFDestSorted[i];
2090 
2091  double sign = dir == alongMomentum ? 1. : -1.;
2092  Point gPointEst(sv.r3);
2093  Vector lDelta(sv.p3); lDelta *= sign/curP*fabs(distToFace[iFDest]);
2094  gPointEst += lDelta;
2095  if (debug_){
2096  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Linear est point "<<gPointEst
2097  <<" for iFace "<<iFDest<<std::endl;
2098  }
2099  GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z() );
2100  if ( cVol->inside(gPointEstNorZ) ){
2101  if (debug_){
2102  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"The point is inside the volume"<<std::endl;
2103  }
2104 
2105  result = SteppingHelixStateInfo::OK;
2106  dist = distToFace[iFDest];
2107  tanDist = tanDistToFace[iFDest];
2108  if (debug_){
2109  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Got a point near closest boundary -- face "<<iFDest<<std::endl;
2110  }
2111  break;
2112  }
2113  }
2114 
2115  if (result != SteppingHelixStateInfo::OK && expectNewMagVolume){
2116  double sign = dir == alongMomentum ? 1. : -1.;
2117 
2118  //check if it's a wrong volume situation
2119  if (nDestSorted-nearParallels > 0 ) result = SteppingHelixStateInfo::WRONG_VOLUME;
2120  else {
2121  //get here if all faces in the corr direction were skipped
2122  Point gPointEst(sv.r3);
2123  double lDist = iDistMin == -1 ? fastSkipDist : fabs(distToFace[iDistMin]);
2124  if (lDist > fastSkipDist) lDist = fastSkipDist;
2125  Vector lDelta(sv.p3); lDelta *= sign/curP*lDist;
2126  gPointEst += lDelta;
2127  if (debug_){
2128  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Linear est point to shortest dist "<<gPointEst
2129  <<" for iFace "<<iDistMin<<" at distance "<<lDist*sign<<std::endl;
2130  }
2131  GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z() );
2132  if ( cVol->inside(gPointEstNorZ) ){
2133  if (debug_){
2134  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"The point is inside the volume"<<std::endl;
2135  }
2136 
2137  }else {
2139  }
2140  }
2141 
2142  if (result == SteppingHelixStateInfo::WRONG_VOLUME){
2143  dist = sign*0.05;
2144  tanDist = dist*1.01;
2145  if( debug_){
2146  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Wrong volume located: return small dist, tandist"<<std::endl;
2147  }
2148  }
2149  }
2150 
2151  if (result == SteppingHelixStateInfo::INACC){
2152  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"All faces are too far"<<std::endl;
2153  } else if (result == SteppingHelixStateInfo::WRONG_VOLUME){
2154  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Appear to be in a wrong volume"<<std::endl;
2155  } else if (result != SteppingHelixStateInfo::OK){
2156  if (debug_) LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Something else went wrong"<<std::endl;
2157  }
2158 
2159 
2160  return result;
2161 }
int i
Definition: DBlmapReader.cc:9
Definition: Cone.h:17
DDSolidShape shapeType() const
Definition: MagVolume.h:31
Result refToDest(DestType dest, const SteppingHelixPropagator::StateInfo &sv, const double pars[6], double &dist, double &tanDist, PropagationDirection &refDirection, double fastSkipDist=1e12) const
(Internals) determine distance and direction from the current position to the plane ...
const std::string metname
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
T y() const
Definition: PV3DBase.h:63
PropagationDirection
Definition: Plane.h:17
T zx() const
GlobalPoint vertex() const
Global position of the cone vertex.
Definition: Cone.h:55
T zz() const
static const char *const name(DDSolidShape s)
Definition: DDSolidShapes.h:21
virtual bool inside(const GlobalPoint &gp, double tolerance=0.) const =0
SteppingHelixStateInfo::Result Result
Scalar radius() const
Radius of the cylinder.
Definition: Cylinder.h:67
T z() const
Definition: PV3DBase.h:64
tuple result
Definition: query.py:137
math::XYZPoint Point
T zy() const
int j
Definition: DBlmapReader.cc:9
#define LogTrace(id)
virtual const std::vector< VolumeSide > & faces() const =0
Access to volume faces.
const RotationType & rotation() const
dbl *** dir
Definition: mlp_gen.cc:35
T x() const
Definition: PV3DBase.h:62
const PositionType & position() const
Geom::Theta< float > openingAngle() const
Angle of the cone.
Definition: Cone.h:58
SteppingHelixPropagator::Result SteppingHelixPropagator::refToMatVolume ( const SteppingHelixPropagator::StateInfo sv,
PropagationDirection  dir,
double &  dist,
double &  tanDist,
double  fastSkipDist = 1e12 
) const
protected

Definition at line 2165 of file SteppingHelixPropagator.cc.

References alongMomentum, anyDirection, CONE_DT, debug_, alignCSCRings::e, SteppingHelixStateInfo::INACC, LogTrace, metname, SteppingHelixStateInfo::NOT_IMPLEMENTED, SteppingHelixStateInfo::OK, SteppingHelixStateInfo::p3, Geom::pi(), PLANE_DT, SteppingHelixStateInfo::r3, RADIUS_DT, RADIUS_P, refToDest(), query::result, SteppingHelixStateInfo::VolumeBounds::rMax, SteppingHelixStateInfo::VolumeBounds::rMin, SteppingHelixStateInfo::rzLims, AlCaHLTBitMon_QueryRunRegistry::string, funct::tan(), SteppingHelixStateInfo::VolumeBounds::th1, SteppingHelixStateInfo::VolumeBounds::th2, UNDEFINED_DT, SteppingHelixStateInfo::VolumeBounds::zMax, and SteppingHelixStateInfo::VolumeBounds::zMin.

Referenced by propagate().

2168  {
2169 
2170  static const std::string metname = "SteppingHelixPropagator";
2172 
2173  double parLim[6] = {sv.rzLims.rMin, sv.rzLims.rMax,
2174  sv.rzLims.zMin, sv.rzLims.zMax,
2175  sv.rzLims.th1, sv.rzLims.th2 };
2176 
2177  double distToFace[4] = {0,0,0,0};
2178  double tanDistToFace[4] = {0,0,0,0};
2179  PropagationDirection refDirectionToFace[4] = {anyDirection, anyDirection, anyDirection, anyDirection};
2180  Result resultToFace[4] = {result, result, result, result};
2181  int iFDest = -1;
2182 
2183  double curP = sv.p3.mag();
2184 
2185  for (unsigned int iFace = 0; iFace < 4; iFace++){
2186  if (debug_){
2187  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Start with mat face "<<iFace<<std::endl;
2188  }
2189 
2190  double pars[6] = {0,0,0,0,0,0};
2191  DestType dType = UNDEFINED_DT;
2192  if (iFace > 1){
2193  if (fabs(parLim[iFace+2])< 1e-6){//plane
2194  if (sv.r3.z() < 0){
2195  pars[0] = 0; pars[1] = 0; pars[2] = -parLim[iFace];
2196  pars[3] = 0; pars[4] = 0; pars[5] = 1;
2197  } else {
2198  pars[0] = 0; pars[1] = 0; pars[2] = parLim[iFace];
2199  pars[3] = 0; pars[4] = 0; pars[5] = 1;
2200  }
2201  dType = PLANE_DT;
2202  } else {
2203  if (sv.r3.z() > 0){
2204  pars[0] = 0; pars[1] = 0;
2205  pars[2] = parLim[iFace];
2206  pars[3] = Geom::pi()/2. - parLim[iFace+2];
2207  } else {
2208  pars[0] = 0; pars[1] = 0;
2209  pars[2] = - parLim[iFace];
2210  pars[3] = Geom::pi()/2. + parLim[iFace+2];
2211  }
2212  dType = CONE_DT;
2213  }
2214  } else {
2215  pars[RADIUS_P] = parLim[iFace];
2216  dType = RADIUS_DT;
2217  }
2218 
2219  resultToFace[iFace] =
2220  refToDest(dType, sv, pars,
2221  distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2222 
2223  if (resultToFace[iFace] != SteppingHelixStateInfo::OK){
2224  if (resultToFace[iFace] == SteppingHelixStateInfo::INACC) result = SteppingHelixStateInfo::INACC;
2225  continue;
2226  }
2227  if (refDirectionToFace[iFace] == dir || fabs(distToFace[iFace]) < 2e-2*fabs(tanDistToFace[iFace]) ){
2228  double sign = dir == alongMomentum ? 1. : -1.;
2229  Point gPointEst(sv.r3);
2230  Vector lDelta(sv.p3); lDelta *= sign*fabs(distToFace[iFace])/curP;
2231  gPointEst += lDelta;
2232  if (debug_){
2233  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Linear est point "<<gPointEst
2234  <<std::endl;
2235  }
2236  double lZ = fabs(gPointEst.z());
2237  double lR = gPointEst.perp();
2238  double tan4 = parLim[4] == 0 ? 0 : tan(parLim[4]);
2239  double tan5 = parLim[5] == 0 ? 0 : tan(parLim[5]);
2240  if ( (lZ - parLim[2]) > lR*tan4
2241  && (lZ - parLim[3]) < lR*tan5
2242  && lR > parLim[0] && lR < parLim[1]){
2243  if (debug_){
2244  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"The point is inside the volume"<<std::endl;
2245  }
2246  //OK, guessed a point still inside the volume
2247  if (iFDest == -1){
2248  iFDest = iFace;
2249  } else {
2250  if (fabs(tanDistToFace[iFDest]) > fabs(tanDistToFace[iFace])){
2251  iFDest = iFace;
2252  }
2253  }
2254  } else {
2255  if (debug_){
2256  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"The point is NOT inside the volume"<<std::endl;
2257  }
2258  }
2259  }
2260 
2261  }
2262  if (iFDest != -1){
2263  result = SteppingHelixStateInfo::OK;
2264  dist = distToFace[iFDest];
2265  tanDist = tanDistToFace[iFDest];
2266  if (debug_){
2267  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Got a point near closest boundary -- face "<<iFDest<<std::endl;
2268  }
2269  } else {
2270  if (debug_){
2271  LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<"Failed to find a dest point inside the volume"<<std::endl;
2272  }
2273  }
2274 
2275  return result;
2276 }
Result refToDest(DestType dest, const SteppingHelixPropagator::StateInfo &sv, const double pars[6], double &dist, double &tanDist, PropagationDirection &refDirection, double fastSkipDist=1e12) const
(Internals) determine distance and direction from the current position to the plane ...
const std::string metname
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
PropagationDirection
SteppingHelixStateInfo::Result Result
tuple result
Definition: query.py:137
math::XYZPoint Point
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
#define LogTrace(id)
double pi()
Definition: Pi.h:31
dbl *** dir
Definition: mlp_gen.cc:35
void SteppingHelixPropagator::setDebug ( bool  debug)
inline

Switch debug printouts (to cout) .. very verbose.

Definition at line 137 of file SteppingHelixPropagator.h.

References debug, and debug_.

Referenced by SteppingHelixPropagatorESProducer::produce().

137 { debug_ = debug;}
#define debug
Definition: HDRShower.cc:19
void SteppingHelixPropagator::setEndcapShiftsInZPosNeg ( double  valPos,
double  valNeg 
)
inline

set shifts in Z for endcap pieces (includes EE, HE, ME, YE)

Definition at line 180 of file SteppingHelixPropagator.h.

References ecShiftNeg_, and ecShiftPos_.

Referenced by SteppingHelixPropagatorESProducer::produce().

180  {
181  ecShiftPos_ = valPos; ecShiftNeg_ = valNeg;
182  }
void SteppingHelixPropagator::setIState ( const SteppingHelixStateInfo sStart,
StateArray svBuff,
int &  nPoints 
) const
protected

(Internals) Init starting point

Definition at line 327 of file SteppingHelixPropagator.cc.

References cIndex_(), SteppingHelixStateInfo::covCurv, SteppingHelixStateInfo::hasErrorPropagated_, SteppingHelixStateInfo::isComplete, loadState(), noErrorPropagation_, SteppingHelixStateInfo::p3, Propagator::propagationDirection(), SteppingHelixStateInfo::q, and SteppingHelixStateInfo::r3.

Referenced by propagate(), and propagateWithPath().

328  {
329  nPoints = 0;
330  svBuf[cIndex_(nPoints)] = sStart; //do this anyways to have a fresh start
331  if (sStart.isComplete ) {
332  svBuf[cIndex_(nPoints)] = sStart;
333  nPoints++;
334  } else {
335  loadState(svBuf[cIndex_(nPoints)], sStart.p3, sStart.r3, sStart.q,
336  propagationDirection(), sStart.covCurv);
337  nPoints++;
338  }
339  svBuf[cIndex_(0)].hasErrorPropagated_ = sStart.hasErrorPropagated_ & !noErrorPropagation_;
340 }
virtual PropagationDirection propagationDirection() const
Definition: Propagator.h:155
AlgebraicSymMatrix55 covCurv
int cIndex_(int ind) const
(Internals) circular index for array of transients
void loadState(SteppingHelixPropagator::StateInfo &svCurrent, const SteppingHelixPropagator::Vector &p3, const SteppingHelixPropagator::Point &r3, int charge, PropagationDirection dir, const AlgebraicSymMatrix55 &covCurv) const
void SteppingHelixPropagator::setMaterialMode ( bool  noMaterial)
inline
void SteppingHelixPropagator::setNoErrorPropagation ( bool  noErrorPropagation)
inline

Force no error propagation.

Definition at line 143 of file SteppingHelixPropagator.h.

References noErrorPropagation_.

Referenced by SteppingHelixPropagatorESProducer::produce(), and PropagateToCal::propagate().

143 { noErrorPropagation_ = noErrorPropagation;}
void SteppingHelixPropagator::setRep ( SteppingHelixPropagator::Basis rep,
const SteppingHelixPropagator::Vector tau 
) const
protected

Set/compute basis vectors for local coordinates at current step (called by incrementState)

Definition at line 865 of file SteppingHelixPropagator.cc.

References SteppingHelixPropagator::Basis::lX, SteppingHelixPropagator::Basis::lY, SteppingHelixPropagator::Basis::lZ, and metsig::tau.

Referenced by makeAtomStep().

866  {
867  Vector zRep(0., 0., 1.);
868  rep.lX = tau;
869  rep.lY = zRep.cross(tau); rep.lY *= 1./tau.perp();
870  rep.lZ = rep.lX.cross(rep.lY);
871 }
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
void SteppingHelixPropagator::setReturnTangentPlane ( bool  val)
inline

flag to return tangent plane for non-plane input

Definition at line 158 of file SteppingHelixPropagator.h.

References returnTangentPlane_.

Referenced by SteppingHelixPropagatorESProducer::produce().

void SteppingHelixPropagator::setSendLogWarning ( bool  val)
inline

flag to send LogWarning on failures

Definition at line 161 of file SteppingHelixPropagator.h.

References sendLogWarning_.

Referenced by SteppingHelixPropagatorESProducer::produce().

void SteppingHelixPropagator::setUseInTeslaFromMagField ( bool  val)
inline

force getting field value from MagneticField, not the geometric one

Definition at line 177 of file SteppingHelixPropagator.h.

References useInTeslaFromMagField_.

Referenced by SteppingHelixPropagatorESProducer::produce().

void SteppingHelixPropagator::setUseIsYokeFlag ( bool  val)
inline

(temporary?) flag to identify if the volume is yoke based on MagVolume internals works if useMatVolumes_ is also true

Definition at line 165 of file SteppingHelixPropagator.h.

References useIsYokeFlag_.

Referenced by SteppingHelixPropagatorESProducer::produce().

void SteppingHelixPropagator::setUseMagVolumes ( bool  val)
inline

Switch to using MagneticField Volumes .. as in VolumeBasedMagneticField.

Definition at line 152 of file SteppingHelixPropagator.h.

References useMagVolumes_.

Referenced by SteppingHelixPropagatorESProducer::produce().

void SteppingHelixPropagator::setUseMatVolumes ( bool  val)
inline

Switch to using Material Volumes .. internally defined for now.

Definition at line 155 of file SteppingHelixPropagator.h.

References useMatVolumes_.

Referenced by SteppingHelixPropagatorESProducer::produce().

void SteppingHelixPropagator::setUseTuningForL2Speed ( bool  val)
inline

will use bigger steps ~tuned for good-enough L2/Standalone reco use this in hope of a speed-up

Definition at line 169 of file SteppingHelixPropagator.h.

References useTuningForL2Speed_.

Referenced by SteppingHelixPropagatorESProducer::produce().

void SteppingHelixPropagator::setVBFPointer ( const VolumeBasedMagneticField val)
inline

set VolumBasedField pointer allows to have geometry description in uniformField scenario only important/relevant in the barrel region

Definition at line 174 of file SteppingHelixPropagator.h.

References vbField_.

Referenced by SteppingHelixPropagatorESProducer::produce().

174 { vbField_ = val;}
const VolumeBasedMagneticField * vbField_

Member Data Documentation

bool SteppingHelixPropagator::applyRadX0Correction_
private
bool SteppingHelixPropagator::debug_
private
double SteppingHelixPropagator::defaultStep_
private

Definition at line 282 of file SteppingHelixPropagator.h.

Referenced by propagate(), and SteppingHelixPropagator().

double SteppingHelixPropagator::ecShiftNeg_
private
double SteppingHelixPropagator::ecShiftPos_
private
const MagneticField* SteppingHelixPropagator::field_
private
StateInfo SteppingHelixPropagator::invalidState_
private

Definition at line 265 of file SteppingHelixPropagator.h.

Referenced by propagate().

const int SteppingHelixPropagator::MAX_POINTS = 7
staticprotected

Definition at line 186 of file SteppingHelixPropagator.h.

Referenced by cIndex_(), and initStateArraySHPSpecific().

const int SteppingHelixPropagator::MAX_STEPS = 10000
staticprivate

Definition at line 261 of file SteppingHelixPropagator.h.

Referenced by propagate().

bool SteppingHelixPropagator::noErrorPropagation_
private
bool SteppingHelixPropagator::noMaterialMode_
private

Definition at line 271 of file SteppingHelixPropagator.h.

Referenced by getDeDx(), setMaterialMode(), and SteppingHelixPropagator().

bool SteppingHelixPropagator::returnTangentPlane_
private
bool SteppingHelixPropagator::sendLogWarning_
private
const AlgebraicSymMatrix55 SteppingHelixPropagator::unit55_
private

Definition at line 269 of file SteppingHelixPropagator.h.

Referenced by makeAtomStep().

bool SteppingHelixPropagator::useInTeslaFromMagField_
private
bool SteppingHelixPropagator::useIsYokeFlag_
private
bool SteppingHelixPropagator::useMagVolumes_
private
bool SteppingHelixPropagator::useMatVolumes_
private

Definition at line 276 of file SteppingHelixPropagator.h.

Referenced by propagate(), setUseMatVolumes(), and SteppingHelixPropagator().

bool SteppingHelixPropagator::useTuningForL2Speed_
private
const VolumeBasedMagneticField* SteppingHelixPropagator::vbField_
private