00001
00002
00003 #include "TrackPropagation/Geant4e/interface/Geant4ePropagator.h"
00004 #include "TrackPropagation/Geant4e/interface/ConvertFromToCLHEP.h"
00005 #include "TrackPropagation/Geant4e/interface/Geant4eSteppingAction.h"
00006
00007
00008 #include "MagneticField/Engine/interface/MagneticField.h"
00009 #include "DataFormats/TrajectorySeed/interface/PropagationDirection.h"
00010 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00011 #include "TrackingTools/TrajectoryState/interface/SurfaceSideDefinition.h"
00012 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00013 #include "DataFormats/GeometrySurface/interface/Plane.h"
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015
00016
00017 #include "G4ErrorFreeTrajState.hh"
00018 #include "G4ErrorPlaneSurfaceTarget.hh"
00019 #include "G4ErrorCylSurfaceTarget.hh"
00020 #include "G4ErrorPropagatorData.hh"
00021 #include "G4EventManager.hh"
00022 #include "G4SteppingControl.hh"
00023
00024
00025 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00026
00027
00030 Geant4ePropagator::Geant4ePropagator(const MagneticField* field,
00031 const char* particleName,
00032 PropagationDirection dir):
00033 Propagator(dir),
00034 theField(field),
00035 theParticleName(particleName),
00036 theG4eManager(G4ErrorPropagatorManager::GetErrorPropagatorManager()),
00037 theSteppingAction(0) {
00038
00039 G4ErrorPropagatorData::SetVerbose(0);
00040 }
00041
00044 Geant4ePropagator::~Geant4ePropagator() {
00045 }
00046
00047
00049
00050
00055 TrajectoryStateOnSurface
00056 Geant4ePropagator::propagate (const FreeTrajectoryState& ftsStart,
00057 const Plane& pDest) const {
00058
00059 if(theG4eManager->PrintG4ErrorState() == "G4ErrorState_PreInit")
00060 theG4eManager->InitGeant4e();
00061
00062 if (!theSteppingAction) {
00063 theSteppingAction = new Geant4eSteppingAction;
00064 theG4eManager->SetUserAction(theSteppingAction);
00065 }
00066
00068
00069
00070
00071
00072 GlobalPoint posPlane = pDest.toGlobal(LocalPoint(0,0,0));
00073 GlobalVector normalPlane = pDest.toGlobal(LocalVector(0,0,1.));
00074 normalPlane = normalPlane.unit();
00075
00076
00077
00078
00079 HepGeom::Point3D<double> surfPos =
00080 TrackPropagation::globalPointToHepPoint3D(posPlane);
00081 HepGeom::Normal3D<double> surfNorm =
00082 TrackPropagation::globalVectorToHepNormal3D(normalPlane);
00083
00084
00085 LogDebug("Geant4e") << "G4e - Destination CMS plane position:" << posPlane << "cm\n"
00086 << "G4e - (Ro, eta, phi): ("
00087 << posPlane.perp() << " cm, "
00088 << posPlane.eta() << ", "
00089 << posPlane.phi().degrees() << " deg)\n"
00090 << "G4e - Destination G4 plane position: " << surfPos
00091 << " mm, Ro = " << surfPos.perp() << " mm";
00092 LogDebug("Geant4e") << "G4e - Destination CMS plane normal : "
00093 << normalPlane << "\n"
00094 << "G4e - Destination G4 plane normal : "
00095 << normalPlane;
00096 LogDebug("Geant4e") << "G4e - Distance from plane position to plane: "
00097 << pDest.localZ(posPlane) << " cm";
00098
00099
00100
00101 G4ErrorSurfaceTarget* g4eTarget = new G4ErrorPlaneSurfaceTarget(surfNorm,
00102 surfPos);
00103
00104
00105
00107
00109
00110
00111
00112
00113
00114 GlobalPoint cmsInitPos = ftsStart.position();
00115 GlobalVector cmsInitMom = ftsStart.momentum();
00116
00117 CLHEP::Hep3Vector g4InitPos =
00118 TrackPropagation::globalPointToHep3Vector(cmsInitPos);
00119 CLHEP::Hep3Vector g4InitMom =
00120 TrackPropagation::globalVectorToHep3Vector(cmsInitMom*GeV);
00121
00122
00123 LogDebug("Geant4e") << "G4e - Initial CMS point position:" << cmsInitPos
00124 << "cm\n"
00125 << "G4e - (Ro, eta, phi): ("
00126 << cmsInitPos.perp() << " cm, "
00127 << cmsInitPos.eta() << ", "
00128 << cmsInitPos.phi().degrees() << " deg)\n"
00129 << "G4e - Initial G4 point position: " << g4InitPos
00130 << " mm, Ro = " << g4InitPos.perp() << " mm";
00131 LogDebug("Geant4e") << "G4e - Initial CMS momentum :" << cmsInitMom
00132 << "GeV\n"
00133 << "G4e - Initial G4 momentum : " << g4InitMom
00134 << " MeV";
00135 LogDebug("Geant4e") << "G4e - Distance from initial point to plane: "
00136 << pDest.localZ(cmsInitPos) << " cm";
00137
00138
00139
00141
00143
00144
00145 int charge = ftsStart.charge();
00146 std::string particleName = theParticleName;
00147
00148 if (charge > 0) {
00149 particleName += "+";
00150 } else {
00151 particleName += "-";
00152 }
00153
00154 LogDebug("Geant4e") << "G4e - Particle name: " << particleName;
00155
00156
00158
00160
00161
00162 G4ErrorTrajErr g4error( 5, 1 );
00163 if(ftsStart.hasError()) {
00164 const CurvilinearTrajectoryError initErr = ftsStart.curvilinearError();
00165 g4error = TrackPropagation::algebraicSymMatrix55ToG4ErrorTrajErr( initErr , charge);
00166 }
00167 LogDebug("Geant4e") << "G4e - Error matrix: " << g4error;
00168
00169 G4ErrorFreeTrajState* g4eTrajState =
00170 new G4ErrorFreeTrajState(particleName, g4InitPos, g4InitMom, g4error);
00171 LogDebug("Geant4e") << "G4e - Traj. State: " << (*g4eTrajState);
00172
00173
00174 G4ErrorMode mode = G4ErrorMode_PropForwards;
00175
00176 if (propagationDirection() == oppositeToMomentum) {
00177 mode = G4ErrorMode_PropBackwards;
00178 LogDebug("Geant4e") << "G4e - Propagator mode is \'backwards\'";
00179 } else if(propagationDirection() == alongMomentum) {
00180 LogDebug("Geant4e") << "G4e - Propagator mode is \'forwards\'";
00181 } else {
00182 std::cout << "Determining actual direction";
00183 if(pDest.localZ(cmsInitPos)*pDest.localZ(cmsInitMom) < 0) {
00184 LogDebug("Geant4e") << "G4e - Propagator mode is \'forwards\'";
00185 std::cout << ", got forwards" << std::endl;
00186 } else {
00187 mode = G4ErrorMode_PropBackwards;
00188 LogDebug("Geant4e") << "G4e - Propagator mode is \'backwards\'";
00189 std::cout << ", got backwards" << std::endl;
00190 }
00191 }
00192
00193
00195
00197
00198
00199 int ierr;
00200 if(mode == G4ErrorMode_PropBackwards) {
00201
00202
00203
00204 g4eTrajState->SetMomentum( -g4eTrajState->GetMomentum());
00205 ierr = theG4eManager->Propagate( g4eTrajState, g4eTarget, mode);
00206 g4eTrajState->SetMomentum( -g4eTrajState->GetMomentum());
00207 } else {
00208 ierr = theG4eManager->Propagate( g4eTrajState, g4eTarget, mode);
00209 }
00210 LogDebug("Geant4e") << "G4e - Return error from propagation: " << ierr;
00211
00212 if(ierr!=0) {
00213 LogDebug("Geant4e") << "G4e - Error is not 0, returning invalid trajectory";
00214 return TrajectoryStateOnSurface();
00215 }
00216
00217
00219
00221
00222
00223
00224
00225 HepGeom::Point3D<double> posEnd = g4eTrajState->GetPosition();
00226 HepGeom::Vector3D<double> momEnd = g4eTrajState->GetMomentum();
00227
00228 GlobalPoint posEndGV = TrackPropagation::hepPoint3DToGlobalPoint(posEnd);
00229 GlobalVector momEndGV = TrackPropagation::hep3VectorToGlobalVector(momEnd)/GeV;
00230
00231
00232 LogDebug("Geant4e") << "G4e - Final CMS point position:" << posEndGV
00233 << "cm\n"
00234 << "G4e - (Ro, eta, phi): ("
00235 << posEndGV.perp() << " cm, "
00236 << posEndGV.eta() << ", "
00237 << posEndGV.phi().degrees() << " deg)\n"
00238 << "G4e - Final G4 point position: " << posEnd
00239 << " mm,\tRo =" << posEnd.perp() << " mm";
00240 LogDebug("Geant4e") << "G4e - Final CMS momentum :" << momEndGV
00241 << "GeV\n"
00242 << "G4e - Final G4 momentum : " << momEnd
00243 << " MeV";
00244 LogDebug("Geant4e") << "G4e - Distance from final point to plane: "
00245 << pDest.localZ(posEndGV) << " cm";
00246
00247
00248 GlobalTrajectoryParameters tParsDest(posEndGV, momEndGV, charge, theField);
00249
00250
00251
00252
00253 G4ErrorTrajErr g4errorEnd = g4eTrajState->GetError();
00254 CurvilinearTrajectoryError
00255 curvError(TrackPropagation::g4ErrorTrajErrToAlgebraicSymMatrix55(g4errorEnd, charge));
00256 LogDebug("Geant4e") << "G4e - Error matrix after propagation: " << g4errorEnd;
00257
00259
00261 LogDebug("Geant4e") << "G4e - SurfaceSide is always atCenterOfSurface after propagation";
00262 SurfaceSideDefinition::SurfaceSide side = SurfaceSideDefinition::atCenterOfSurface;
00263
00265
00266 return TrajectoryStateOnSurface(tParsDest, curvError, pDest, side);
00267 }
00268
00269
00270
00271 TrajectoryStateOnSurface
00272 Geant4ePropagator::propagate (const TrajectoryStateOnSurface& tsos, const Plane& plane) const {
00273 const FreeTrajectoryState ftsStart = *tsos.freeState();
00274 return propagate(ftsStart,plane);
00275 }
00276
00277
00281 TrajectoryStateOnSurface
00282 Geant4ePropagator::propagate (const FreeTrajectoryState& ftsStart,
00283 const Cylinder& cDest) const {
00284
00285 if(theG4eManager->PrintG4ErrorState() == "G4ErrorState_PreInit")
00286 theG4eManager->InitGeant4e();
00287 if (!theSteppingAction) {
00288 theSteppingAction = new Geant4eSteppingAction;
00289 theG4eManager->SetUserAction(theSteppingAction);
00290 }
00291
00292
00293
00294
00295 G4float radCyl = cDest.radius()*cm;
00296
00297 G4ThreeVector posCyl =
00298 TrackPropagation::globalPointToHep3Vector(cDest.position());
00299
00300 G4RotationMatrix rotCyl =
00301 TrackPropagation::tkRotationFToHepRotation(cDest.rotation());
00302
00303
00304 TkRotation<float> rotation = cDest.rotation();
00305 LogDebug("Geant4e") << "G4e - TkRotation" << rotation;
00306 LogDebug("Geant4e") << "G4e - G4Rotation" << rotCyl << "mm";
00307
00308
00309
00310 G4ErrorSurfaceTarget* g4eTarget = new G4ErrorCylSurfaceTarget(radCyl, posCyl,
00311 rotCyl);
00312
00313
00314 LogDebug("Geant4e") << "G4e - Destination CMS cylinder position:" << cDest.position() << "cm\n"
00315 << "G4e - Destination CMS cylinder radius:" << cDest.radius() << "cm\n"
00316 << "G4e - Destination CMS cylinder rotation:" << cDest.rotation() << "\n";
00317 LogDebug("Geant4e") << "G4e - Destination G4 cylinder position: " << posCyl << "mm\n"
00318 << "G4e - Destination G4 cylinder radius:" << radCyl << "mm\n"
00319 << "G4e - Destination G4 cylinder rotation:" << rotCyl << "\n";
00320
00321
00322
00323
00324 GlobalPoint cmsInitPos = ftsStart.position();
00325 GlobalVector cmsInitMom = ftsStart.momentum();
00326
00327 CLHEP::Hep3Vector g4InitMom =
00328 TrackPropagation::globalVectorToHep3Vector(cmsInitMom*GeV);
00329 CLHEP::Hep3Vector g4InitPos =
00330 TrackPropagation::globalPointToHep3Vector(cmsInitPos);
00331
00332
00333 LogDebug("Geant4e") << "G4e - Initial CMS point position:" << cmsInitPos
00334 << "cm\n"
00335 << "G4e - (Ro, eta, phi): ("
00336 << cmsInitPos.perp() << " cm, "
00337 << cmsInitPos.eta() << ", "
00338 << cmsInitPos.phi().degrees() << " deg)\n"
00339 << "G4e - Initial G4 point position: " << g4InitPos
00340 << " mm, Ro = " << g4InitPos.perp() << " mm";
00341 LogDebug("Geant4e") << "G4e - Initial CMS momentum :" << cmsInitMom
00342 << "GeV\n"
00343 << "G4e - Initial G4 momentum : " << g4InitMom
00344 << " MeV";
00345
00346
00347 int charge = ftsStart.charge();
00348 std::string particleName = theParticleName;
00349 if (charge > 0)
00350 particleName += "+";
00351 else
00352 particleName += "-";
00353 LogDebug("Geant4e") << "G4e - Particle name: " << particleName;
00354
00355
00356 G4ErrorTrajErr g4error( 5, 1 );
00357 if(ftsStart.hasError()) {
00358 const CurvilinearTrajectoryError initErr = ftsStart.curvilinearError();
00359 g4error = TrackPropagation::algebraicSymMatrix55ToG4ErrorTrajErr( initErr , charge);
00360 }
00361 LogDebug("Geant4e") << "G4e - Error matrix: " << g4error;
00362
00363 G4ErrorFreeTrajState* g4eTrajState =
00364 new G4ErrorFreeTrajState(particleName, g4InitPos, g4InitMom, g4error);
00365 LogDebug("Geant4e") << "G4e - Traj. State: " << (*g4eTrajState);
00366
00367
00368 G4ErrorMode mode = G4ErrorMode_PropForwards;
00369
00370 if (propagationDirection() == oppositeToMomentum) {
00371 mode = G4ErrorMode_PropBackwards;
00372 LogDebug("Geant4e") << "G4e - Propagator mode is \'backwards\'";
00373 } else if(propagationDirection() == alongMomentum) {
00374 LogDebug("Geant4e") << "G4e - Propagator mode is \'forwards\'";
00375 } else {
00376
00377
00378
00379 LocalVector lmom = cDest.toLocal(cmsInitMom);
00380 LocalPoint lpos = cDest.toLocal(cmsInitPos);
00381 Surface::Side theSide = cDest.side(lpos,0);
00382 if(theSide==SurfaceOrientation::positiveSide){
00383 mode = G4ErrorMode_PropBackwards;
00384 LogDebug("Geant4e") << "G4e - Propagator mode is \'backwards\'";
00385 } else {
00386 LogDebug("Geant4e") << "G4e - Propagator mode is \'forwards\'";
00387 }
00388
00389 }
00390
00392
00393
00394 int ierr;
00395 if(mode == G4ErrorMode_PropBackwards) {
00396
00397
00398
00399 g4eTrajState->SetMomentum( -g4eTrajState->GetMomentum());
00400 ierr = theG4eManager->Propagate( g4eTrajState, g4eTarget, mode);
00401 g4eTrajState->SetMomentum( -g4eTrajState->GetMomentum());
00402 } else {
00403 ierr = theG4eManager->Propagate( g4eTrajState, g4eTarget, mode);
00404 }
00405 LogDebug("Geant4e") << "G4e - Return error from propagation: " << ierr;
00406
00407 if(ierr!=0) {
00408 LogDebug("Geant4e") << "G4e - Error is not 0, returning invalid trajectory";
00409 return TrajectoryStateOnSurface();
00410 }
00411
00412
00413
00414
00415 HepGeom::Point3D<double> posEnd = g4eTrajState->GetPosition();
00416 HepGeom::Vector3D<double> momEnd = g4eTrajState->GetMomentum();
00417
00418 GlobalPoint posEndGV = TrackPropagation::hepPoint3DToGlobalPoint(posEnd);
00419 GlobalVector momEndGV = TrackPropagation::hep3VectorToGlobalVector(momEnd)/GeV;
00420
00421
00422
00423 LogDebug("Geant4e") << "G4e - Final CMS point position:" << posEndGV
00424 << "cm\n"
00425 << "G4e - (Ro, eta, phi): ("
00426 << posEndGV.perp() << " cm, "
00427 << posEndGV.eta() << ", "
00428 << posEndGV.phi().degrees() << " deg)\n"
00429 << "G4e - Final G4 point position: " << posEnd
00430 << " mm,\tRo =" << posEnd.perp() << " mm";
00431 LogDebug("Geant4e") << "G4e - Final CMS momentum :" << momEndGV
00432 << "GeV\n"
00433 << "G4e - Final G4 momentum : " << momEnd
00434 << " MeV";
00435
00436 GlobalTrajectoryParameters tParsDest(posEndGV, momEndGV, charge, theField);
00437
00438
00439
00440
00441 G4ErrorTrajErr g4errorEnd = g4eTrajState->GetError();
00442 CurvilinearTrajectoryError
00443 curvError(TrackPropagation::g4ErrorTrajErrToAlgebraicSymMatrix55(g4errorEnd, charge));
00444 LogDebug("Geant4e") << "G4e - Error matrix after propagation: " << g4errorEnd;
00445
00447
00449
00450 SurfaceSideDefinition::SurfaceSide side = SurfaceSideDefinition::atCenterOfSurface;
00451
00452 return TrajectoryStateOnSurface(tParsDest, curvError, cDest, side);
00453 }
00454
00455
00456
00457
00458 TrajectoryStateOnSurface
00459 Geant4ePropagator::propagate (const TrajectoryStateOnSurface& tsos, const Cylinder& cyl) const {
00460 const FreeTrajectoryState ftsStart = *tsos.freeState();
00461 return propagate(ftsStart,cyl);
00462 }
00463
00464
00465
00467
00468
00475 std::pair< TrajectoryStateOnSurface, double>
00476 Geant4ePropagator::propagateWithPath (const FreeTrajectoryState& ftsStart,
00477 const Plane& pDest) const {
00478
00479 theSteppingAction->reset();
00480
00481
00482
00483
00484 return TsosPP(propagate(ftsStart,pDest), theSteppingAction->trackLength());
00485 }
00486
00487 std::pair< TrajectoryStateOnSurface, double>
00488 Geant4ePropagator::propagateWithPath (const FreeTrajectoryState& ftsStart,
00489 const Cylinder& cDest) const {
00490 theSteppingAction->reset();
00491
00492
00493
00494
00495 return TsosPP(propagate(ftsStart,cDest), theSteppingAction->trackLength());
00496 }
00497
00498 std::pair< TrajectoryStateOnSurface, double>
00499 Geant4ePropagator::propagateWithPath (const TrajectoryStateOnSurface& tsosStart,
00500 const Plane& pDest) const {
00501
00502 theSteppingAction->reset();
00503
00504
00505
00506
00507 return TsosPP(propagate(tsosStart,pDest), theSteppingAction->trackLength());
00508 }
00509
00510 std::pair< TrajectoryStateOnSurface, double>
00511 Geant4ePropagator::propagateWithPath (const TrajectoryStateOnSurface& tsosStart,
00512 const Cylinder& cDest) const {
00513 theSteppingAction->reset();
00514
00515
00516
00517
00518 return TsosPP(propagate(tsosStart,cDest), theSteppingAction->trackLength());
00519 }