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 "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 debug() << "==> Initialize" << endreq;
00078
00079 StatusCode sc = GaudiTool::initialize();
00080 if ( sc.isFailure() ) return sc;
00081
00082 std::string ascType = "Associator<MCParticle,MCHit>";
00083 std::string ascVeloType = "Associator<MCParticle,MCVeloHit>";
00084
00085
00086 sc = toolSvc() -> retrieveTool( ascVeloType,
00087 m_p2VeloHitAsctName, m_p2VeloHitAsct );
00088 if ( sc.isFailure() ) {
00089 error() << "Unable to retrieve the Velo MCHit Associator "
00090 << m_p2VeloHitAsctName << endreq;
00091 return sc;
00092 }
00093
00094
00095 sc = toolSvc() -> retrieveTool( ascType, m_p2OTHitAsctName, m_p2OTHitAsct );
00096 if ( sc.isFailure() ) {
00097 error() << "Unable to retrieve the OT MCHit Associator "
00098 << m_p2OTHitAsctName << endreq;
00099 return sc;
00100 }
00101
00102
00103 sc = toolSvc()->retrieveTool(ascType, m_p2ITHitAsctName, m_p2ITHitAsct);
00104 if ( sc.isFailure() ) {
00105 error() << "Unable to retrieve the IT MCHit Associator "
00106 << m_p2ITHitAsctName << endreq;
00107 return sc;
00108 }
00109
00110
00111 m_extrapolator = tool<ITrackExtrapolator>( m_extrapolatorName );
00112
00113 return StatusCode::SUCCESS;
00114 }
00115
00116
00117
00118
00119
00120 StatusCode TrueStateCreator::createState( const MCParticle* mcPart,
00121 double zRec,
00122 State*& state ) const {
00123
00124 HepSymMatrix stateCov = HepSymMatrix(5, 1);
00125 State* pState = new State();
00126 pState -> setZ( zRec );
00127 pState -> setCovariance( stateCov );
00128 state = pState;
00129
00130
00131 if ( mcPart == 0 ) return StatusCode::FAILURE;
00132
00133
00134 if ( !m_p2VeloHitAsct || !m_p2OTHitAsct || !m_p2ITHitAsct )
00135 return Error( "MCParticle 2 MCHit Associator missing." );
00136
00137 MCHit* closestHit = 0;
00138 MCHit* secondClosestHit = 0;
00139 double closestZ = 10000;
00140 double secondClosestZ = 10000;
00141
00142
00143 MCVeloHitAsct::ToRange mcVeloHitsRange = m_p2VeloHitAsct->rangeFrom(mcPart);
00144 MCVeloHitAsct::ToIterator vt;
00145 for ( vt = mcVeloHitsRange.begin(); vt != mcVeloHitsRange.end(); ++vt) {
00146
00147 MCVeloHit* mcVeloHit = vt->to();
00148 if ( !mcVeloHit )
00149 return Error( "Failed retrieving Velo MCHit" );
00150
00151
00152
00153 HepPoint3D midPointTmp = ( mcVeloHit->entry() + mcVeloHit->exit() ) / 2.0;
00154 Hep3Vector midPoint = ( midPointTmp.x(), midPointTmp.y(), midPointTmp.z() );
00155
00156
00157
00158 if ( fabs(midPoint.z() - zRec) < closestZ ) {
00159 secondClosestHit = closestHit;
00160 secondClosestZ = closestZ;
00161 closestHit = mcVeloHit;
00162 closestZ = fabs(midPoint.z()- zRec);
00163 }
00164 else if ( fabs(midPoint.z()- zRec) < secondClosestZ ) {
00165 secondClosestHit = mcVeloHit;
00166 secondClosestZ = fabs(midPoint.z()- zRec);
00167 }
00168 }
00169
00170
00171 MCHitAsct::ToRange mcOTHitsRange = m_p2OTHitAsct->rangeFrom(mcPart);
00172 MCHitAsct::ToIterator ot;
00173 for ( ot = mcOTHitsRange.begin(); ot != mcOTHitsRange.end(); ++ot) {
00174
00175 MCHit* mcHit = ot->to();
00176 if ( !mcHit )
00177 return Error( "Failed retrieving OT MCHit" );
00178
00179
00180
00181 HepPoint3D midPointTmp = ( mcHit->entry() + mcHit->exit() ) / 2.0;
00182 Hep3Vector midPoint = ( midPointTmp.x(), midPointTmp.y(), midPointTmp.z() );
00183
00184
00185
00186 if ( fabs(midPoint.z() - zRec) < closestZ ) {
00187 secondClosestHit = closestHit;
00188 secondClosestZ = closestZ;
00189 closestHit = mcHit;
00190 closestZ = fabs(midPoint.z()- zRec);
00191 }
00192 else if ( fabs(midPoint.z()- zRec) < secondClosestZ ) {
00193 secondClosestHit = mcHit;
00194 secondClosestZ = fabs(midPoint.z()- zRec);
00195 }
00196 }
00197
00198
00199 MCHitAsct::ToRange mcITHitsRange = m_p2ITHitAsct->rangeFrom(mcPart);
00200 MCHitAsct::ToIterator it;
00201 for ( it = mcITHitsRange.begin(); it != mcITHitsRange.end(); ++it) {
00202
00203 MCHit* mcHit = it->to();
00204 if ( !mcHit )
00205 return Error( "Failed retrieving IT MCHit" );
00206
00207
00208
00209 HepPoint3D midPointTmp = ( mcHit->entry() + mcHit->exit() ) / 2.0;
00210 Hep3Vector midPoint = ( midPointTmp.x(), midPointTmp.y(), midPointTmp.z() );
00211
00212
00213
00214 if ( fabs(midPoint.z()- zRec) < closestZ ) {
00215 secondClosestHit = closestHit;
00216 secondClosestZ = closestZ;
00217 closestHit = mcHit;
00218 closestZ = fabs(midPoint.z()- zRec);
00219 }
00220 else if ( fabs(midPoint.z()- zRec) < secondClosestZ ) {
00221 secondClosestHit = mcHit;
00222 secondClosestZ = fabs(midPoint.z()- zRec);
00223 }
00224
00225 }
00226
00227 if ( !closestHit || !secondClosestHit ) {
00228 warning() << "No two closest MCHits found!!" << endreq;
00229 return StatusCode::FAILURE;
00230 }
00231
00232
00233 Hep3Vector beginPoint = closestHit->entry();
00234 if ( beginPoint.z() > closestHit->exit().z() )
00235 beginPoint = closestHit->exit();
00236 if ( beginPoint.z() > secondClosestHit->entry().z() )
00237 beginPoint = secondClosestHit->entry();
00238 if ( beginPoint.z() > secondClosestHit->exit().z() )
00239 beginPoint = secondClosestHit->exit();
00240
00241
00242 Hep3Vector endPoint = secondClosestHit->exit();
00243 if ( endPoint.z() < secondClosestHit->entry().z() )
00244 endPoint = secondClosestHit->entry();
00245 if ( endPoint.z() < closestHit->entry().z() )
00246 endPoint = closestHit->entry();
00247 if ( endPoint.z() < closestHit->exit().z() )
00248 endPoint = closestHit->exit();
00249
00250 double dz = (beginPoint.z() - endPoint.z());
00251 if ( dz == 0. ) {
00252 warning() << "Delta z between two hits equals zero." << endreq;
00253 return StatusCode::FAILURE;
00254 }
00255 double slopeX = (beginPoint.x() - endPoint.x()) / dz;
00256 double slopeY = (beginPoint.y() - endPoint.y()) / dz;
00257 double x = (beginPoint.x());
00258 double y = (beginPoint.y());
00259 double z = (beginPoint.z());
00260
00261
00262 pState->setState( x, y, z, slopeX, slopeY, this->qOverP(mcPart) );
00263
00264
00265 HepSymMatrix cov = HepSymMatrix(5,0);
00266 cov.fast(1,1) = m_eX2;
00267 cov.fast(2,2) = m_eY2;
00268 cov.fast(3,3) = m_eTx2;
00269 cov.fast(4,4) = m_eTy2;
00270 cov.fast(5,5) = pow(m_eP * pState->qOverP(), 2.);
00271 pState -> setCovariance( cov );
00272
00273
00274 ParticleID partID = 211;
00275 StatusCode sc = m_extrapolator -> propagate( *pState, zRec, partID );
00276 if ( sc.isFailure() ) {
00277 debug() << "Extrapolation of True State from z = "
00278 << z << " to z = " << zRec << " failed!" << endreq;
00279 }
00280
00281 return sc;
00282 }
00283
00284
00285
00286
00287
00288 StatusCode TrueStateCreator::createStateVertex( const MCParticle* mcParticle,
00289 State*& state ) const
00290 {
00292 HepSymMatrix stateCov = HepSymMatrix(5, 1);
00293 State* trueState = new State();
00294 trueState -> setCovariance( stateCov );
00295 state = trueState;
00296
00297
00298 if ( mcParticle == 0 ) return StatusCode::FAILURE;
00299
00300
00301 const MCVertex* mcVertex = mcParticle -> originVertex();
00302 const HepPoint3D mcPos = mcVertex -> position();
00303 const HepLorentzVector mc4Mom = mcParticle -> momentum();
00304
00305
00306 double trueQdivP = this -> qOverP( mcParticle );
00307
00308
00309 double trueTx = 99999999;
00310 double trueTy = 99999999;
00311 double px = mc4Mom.px();
00312 double py = mc4Mom.py();
00313 double pz = mc4Mom.pz();
00314 if ( fabs(pz) > TrackParameters::lowTolerance ) {
00315 trueTx = px/pz;
00316 trueTy = py/pz;
00317 }
00318 else {
00319 warning() << "No momentum z component." << endreq;
00320 return StatusCode::FAILURE;
00321 }
00322
00323
00324 trueState->setState( mcPos.x(),
00325 mcPos.y(),
00326 mcPos.z(),
00327 trueTx,
00328 trueTy,
00329 trueQdivP );
00330
00331
00332 HepSymMatrix cov = HepSymMatrix(5,0);
00333 cov.fast(1,1) = m_eX2;
00334 cov.fast(2,2) = m_eY2;
00335 cov.fast(3,3) = m_eTx2;
00336 cov.fast(4,4) = m_eTy2;
00337 cov.fast(5,5) = pow(m_eP * trueState->qOverP(), 2.);
00338 trueState -> setCovariance( cov );
00339
00340 return StatusCode::SUCCESS;
00341 }
00342
00343
00344
00345
00346 double TrueStateCreator::qOverP( const MCParticle* mcPart ) const
00347 {
00349 double momentum = mcPart -> momentum().vect().mag();
00350 double charge = (mcPart -> particleID().threeCharge())/3.;
00351 if ( momentum > TrackParameters::lowTolerance) {
00352 return charge/momentum;
00353 }
00354 else {
00355 return 0.0;
00356 }
00357 }
00358
00359