00001
00002
00003
00004 #include "GaudiKernel/ToolFactory.h"
00005
00006 #include "GaudiKernel/IDataProviderSvc.h"
00007
00008
00009 #include "Event/State.h"
00010 #include "Event/TrackParameters.h"
00011
00012
00013 #include "TrackTools/TrueStateCreator.h"
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 static const ToolFactory<TrueStateCreator> s_factory;
00025 const IToolFactory& TrueStateCreatorFactory = s_factory;
00026
00027
00028
00029
00030 TrueStateCreator::TrueStateCreator( const std::string& type,
00031 const std::string& name,
00032 const IInterface* parent )
00033 : GaudiTool( type, name, parent )
00034 , m_velo(0)
00035 , m_p2VeloHitAsct(0)
00036 , m_p2ITHitAsct(0)
00037 , m_p2OTHitAsct(0)
00038 , m_extrapolator(0)
00039 , m_p2VeloHitAsctName("")
00040 , m_p2ITHitAsctName("")
00041 , m_p2OTHitAsctName("")
00042 , m_eX2(2.e-5*mm2)
00043 , m_eY2(2.e-5*mm2)
00044 , m_eTx2(1.e-7)
00045 , m_eTy2(1.e-7)
00046 , m_eP(0.005)
00047 {
00048
00049 declareInterface<IStateCreator>(this);
00050
00051
00052 declareProperty( "MCP2VeloMCHitAscName",
00053 m_p2VeloHitAsctName = "MCP2VeloMCHitAsc" );
00054 declareProperty( "MCP2ITMCHitAscName",
00055 m_p2ITHitAsctName = "MCP2ITMCHitAsc" );
00056 declareProperty( "MCP2OTMCHitAscName",
00057 m_p2OTHitAsctName = "MCP2OTMCHitAsc" );
00058 declareProperty( "extrapolatorName",
00059 m_extrapolatorName = "TrackHerabExtrapolator" );
00060 declareProperty( "eX2", m_eX2 );
00061 declareProperty( "eY2", m_eY2 );
00062 declareProperty( "eTx2", m_eTx2 );
00063 declareProperty( "eTy2", m_eTy2 );
00064 declareProperty( "eP", m_eP );
00065 }
00066
00067
00068
00069
00070 TrueStateCreator::~TrueStateCreator() {};
00071
00072
00073
00074
00075 StatusCode TrueStateCreator::initialize()
00076 {
00077 StatusCode sc;
00078
00079 debug() << "==> Initialize" << endreq;
00080
00081 std::string ascType = "Associator<MCParticle,MCHit>";
00082 std::string ascVeloType = "Associator<MCParticle,MCVeloHit>";
00083
00084
00085 sc = toolSvc() -> retrieveTool( ascVeloType,
00086 m_p2VeloHitAsctName, m_p2VeloHitAsct );
00087 if ( sc.isFailure() ) {
00088 error() << "Unable to retrieve the Velo MCHit Associator "
00089 << m_p2VeloHitAsctName << endreq;
00090 return sc;
00091 }
00092
00093
00094 sc = toolSvc() -> retrieveTool( ascType, m_p2OTHitAsctName, m_p2OTHitAsct );
00095 if ( sc.isFailure() ) {
00096 error() << "Unable to retrieve the OT MCHit Associator "
00097 << m_p2OTHitAsctName << endreq;
00098 return sc;
00099 }
00100
00101
00102 sc = toolSvc()->retrieveTool(ascType, m_p2ITHitAsctName, m_p2ITHitAsct);
00103 if ( sc.isFailure() ) {
00104 error() << "Unable to retrieve the IT MCHit Associator "
00105 << m_p2ITHitAsctName << endreq;
00106 return sc;
00107 }
00108
00109
00110 m_extrapolator = tool<ITrackExtrapolator>( m_extrapolatorName );
00111
00112 return StatusCode::SUCCESS;
00113 }
00114
00115
00116
00117
00118
00119 StatusCode TrueStateCreator::createState( const MCParticle* mcPart,
00120 double zRec,
00121 State*& state ) const {
00122
00123 HepSymMatrix stateCov = HepSymMatrix(5, 1);
00124 State* pState = new State();
00125 pState -> setZ( zRec );
00126 pState -> setCovariance( stateCov );
00127 state = pState;
00128
00129
00130 if ( mcPart == 0 ) return StatusCode::FAILURE;
00131
00132
00133 if ( !m_p2VeloHitAsct || !m_p2OTHitAsct || !m_p2ITHitAsct )
00134 return Error( "MCParticle 2 MCHit Associator missing." );
00135
00136 MCHit* closestHit = 0;
00137 MCHit* secondClosestHit = 0;
00138 double closestZ = 10000;
00139 double secondClosestZ = 10000;
00140
00141
00142 MCVeloHitAsct::ToRange mcVeloHitsRange = m_p2VeloHitAsct->rangeFrom(mcPart);
00143 MCVeloHitAsct::ToIterator vt;
00144 for ( vt = mcVeloHitsRange.begin(); vt != mcVeloHitsRange.end(); ++vt) {
00145
00146 MCVeloHit* mcVeloHit = vt->to();
00147 if ( !mcVeloHit )
00148 return Error( "Failed retrieving Velo MCHit" );
00149
00150
00151
00152 HepPoint3D midPointTmp = ( mcVeloHit->entry() + mcVeloHit->exit() ) / 2.0;
00153 Hep3Vector midPoint = ( midPointTmp.x(), midPointTmp.y(), midPointTmp.z() );
00154
00155
00156
00157 if ( fabs(midPoint.z() - zRec) < closestZ ) {
00158 secondClosestHit = closestHit;
00159 secondClosestZ = closestZ;
00160 closestHit = mcVeloHit;
00161 closestZ = fabs(midPoint.z()- zRec);
00162 }
00163 else if ( fabs(midPoint.z()- zRec) < secondClosestZ ) {
00164 secondClosestHit = mcVeloHit;
00165 secondClosestZ = fabs(midPoint.z()- zRec);
00166 }
00167 }
00168
00169
00170 MCHitAsct::ToRange mcOTHitsRange = m_p2OTHitAsct->rangeFrom(mcPart);
00171 MCHitAsct::ToIterator ot;
00172 for ( ot = mcOTHitsRange.begin(); ot != mcOTHitsRange.end(); ++ot) {
00173
00174 MCHit* mcHit = ot->to();
00175 if ( !mcHit )
00176 return Error( "Failed retrieving OT MCHit" );
00177
00178
00179
00180 HepPoint3D midPointTmp = ( mcHit->entry() + mcHit->exit() ) / 2.0;
00181 Hep3Vector midPoint = ( midPointTmp.x(), midPointTmp.y(), midPointTmp.z() );
00182
00183
00184
00185 if ( fabs(midPoint.z() - zRec) < closestZ ) {
00186 secondClosestHit = closestHit;
00187 secondClosestZ = closestZ;
00188 closestHit = mcHit;
00189 closestZ = fabs(midPoint.z()- zRec);
00190 }
00191 else if ( fabs(midPoint.z()- zRec) < secondClosestZ ) {
00192 secondClosestHit = mcHit;
00193 secondClosestZ = fabs(midPoint.z()- zRec);
00194 }
00195 }
00196
00197
00198 MCHitAsct::ToRange mcITHitsRange = m_p2ITHitAsct->rangeFrom(mcPart);
00199 MCHitAsct::ToIterator it;
00200 for ( it = mcITHitsRange.begin(); it != mcITHitsRange.end(); ++it) {
00201
00202 MCHit* mcHit = it->to();
00203 if ( !mcHit )
00204 return Error( "Failed retrieving IT MCHit" );
00205
00206
00207
00208 HepPoint3D midPointTmp = ( mcHit->entry() + mcHit->exit() ) / 2.0;
00209 Hep3Vector midPoint = ( midPointTmp.x(), midPointTmp.y(), midPointTmp.z() );
00210
00211
00212
00213 if ( fabs(midPoint.z()- zRec) < closestZ ) {
00214 secondClosestHit = closestHit;
00215 secondClosestZ = closestZ;
00216 closestHit = mcHit;
00217 closestZ = fabs(midPoint.z()- zRec);
00218 }
00219 else if ( fabs(midPoint.z()- zRec) < secondClosestZ ) {
00220 secondClosestHit = mcHit;
00221 secondClosestZ = fabs(midPoint.z()- zRec);
00222 }
00223
00224 }
00225
00226 if ( !closestHit || !secondClosestHit ) {
00227 warning() << "No two closest MCHits found!!" << endreq;
00228 return StatusCode::FAILURE;
00229 }
00230
00231
00232 Hep3Vector beginPoint = closestHit->entry();
00233 if ( beginPoint.z() > closestHit->exit().z() )
00234 beginPoint = closestHit->exit();
00235 if ( beginPoint.z() > secondClosestHit->entry().z() )
00236 beginPoint = secondClosestHit->entry();
00237 if ( beginPoint.z() > secondClosestHit->exit().z() )
00238 beginPoint = secondClosestHit->exit();
00239
00240
00241 Hep3Vector endPoint = secondClosestHit->exit();
00242 if ( endPoint.z() < secondClosestHit->entry().z() )
00243 endPoint = secondClosestHit->entry();
00244 if ( endPoint.z() < closestHit->entry().z() )
00245 endPoint = closestHit->entry();
00246 if ( endPoint.z() < closestHit->exit().z() )
00247 endPoint = closestHit->exit();
00248
00249 double dz = (beginPoint.z() - endPoint.z());
00250 if ( dz == 0. ) {
00251 warning() << "Delta z between two hits equals zero." << endreq;
00252 return StatusCode::FAILURE;
00253 }
00254 double slopeX = (beginPoint.x() - endPoint.x()) / dz;
00255 double slopeY = (beginPoint.y() - endPoint.y()) / dz;
00256 double x = (beginPoint.x());
00257 double y = (beginPoint.y());
00258 double z = (beginPoint.z());
00259
00260
00261 pState->setState( x, y, z, slopeX, slopeY, this->qOverP(mcPart) );
00262
00263
00264 HepSymMatrix cov = HepSymMatrix(5,0);
00265 cov.fast(1,1) = m_eX2;
00266 cov.fast(2,2) = m_eY2;
00267 cov.fast(3,3) = m_eTx2;
00268 cov.fast(4,4) = m_eTy2;
00269 cov.fast(5,5) = pow(m_eP * pState->qOverP(), 2.);
00270 pState -> setCovariance( cov );
00271
00272
00273 ParticleID partID = 211;
00274 StatusCode sc = m_extrapolator -> propagate( *pState, zRec, partID );
00275 if ( sc.isFailure() ) {
00276 debug() << "Extrapolation of True State from z = "
00277 << z << " to z = " << zRec << " failed!" << endreq;
00278 }
00279
00280 return sc;
00281 }
00282
00283
00284
00285
00286
00287 StatusCode TrueStateCreator::createStateVertex( const MCParticle* mcParticle,
00288 State*& state ) const
00289 {
00291 HepSymMatrix stateCov = HepSymMatrix(5, 1);
00292 State* trueState = new State();
00293 trueState -> setCovariance( stateCov );
00294 state = trueState;
00295
00296
00297 if ( mcParticle == 0 ) return StatusCode::FAILURE;
00298
00299
00300 const MCVertex* mcVertex = mcParticle -> originVertex();
00301 const HepPoint3D mcPos = mcVertex -> position();
00302 const HepLorentzVector mc4Mom = mcParticle -> momentum();
00303
00304
00305 double trueQdivP = this -> qOverP( mcParticle );
00306
00307
00308 double trueTx = 99999999;
00309 double trueTy = 99999999;
00310 double px = mc4Mom.px();
00311 double py = mc4Mom.py();
00312 double pz = mc4Mom.pz();
00313 if ( fabs(pz) > TrackParameters::lowTolerance ) {
00314 trueTx = px/pz;
00315 trueTy = py/pz;
00316 }
00317 else {
00318 warning() << "No momentum z component." << endreq;
00319 return StatusCode::FAILURE;
00320 }
00321
00322
00323 trueState->setState( mcPos.x(),
00324 mcPos.y(),
00325 mcPos.z(),
00326 trueTx,
00327 trueTy,
00328 trueQdivP );
00329
00330
00331 HepSymMatrix cov = HepSymMatrix(5,0);
00332 cov.fast(1,1) = m_eX2;
00333 cov.fast(2,2) = m_eY2;
00334 cov.fast(3,3) = m_eTx2;
00335 cov.fast(4,4) = m_eTy2;
00336 cov.fast(5,5) = pow(m_eP * trueState->qOverP(), 2.);
00337 trueState -> setCovariance( cov );
00338
00339 return StatusCode::SUCCESS;
00340 }
00341
00342
00343
00344
00345 double TrueStateCreator::qOverP( const MCParticle* mcPart ) const
00346 {
00348 double momentum = mcPart -> momentum().vect().mag();
00349 double charge = (mcPart -> particleID().threeCharge())/3.;
00350 if ( momentum > TrackParameters::lowTolerance) {
00351 return charge/momentum;
00352 }
00353 else {
00354 return 0.0;
00355 }
00356 }
00357
00358