File indexing completed on 2024-06-01 07:07:41
0001 #include "DDG4/Factories.h"
0002
0003
0004 #include "DD4hep/Printout.h"
0005 #include "DD4hep/InstanceCount.h"
0006 #include "DDG4/Geant4Random.h"
0007 #include "DDG4/Geant4Context.h"
0008 #include "DDG4/Geant4InputHandling.h"
0009 #include "npdet/EICInteractionVertexSmear.h"
0010
0011
0012 #include <cmath>
0013
0014 #include "Math/Vector3D.h"
0015 #include "Math/Vector4D.h"
0016 #include "Math/LorentzRotation.h"
0017 #include "Math/AxisAngle.h"
0018 #include "Math/Rotation3D.h"
0019 #include "Math/RotationX.h"
0020 #include "Math/RotationY.h"
0021 #include "Math/Boost.h"
0022 #include "Math/BoostX.h"
0023 #include "Math/BoostX.h"
0024 #include "Math/PxPyPzM4D.h"
0025
0026 namespace npdet::sim {
0027
0028 using namespace dd4hep::sim;
0029
0030
0031 EICInteractionVertexSmear::EICInteractionVertexSmear(Geant4Context* ctxt, const std::string& nam)
0032 : Geant4GeneratorAction(ctxt, nam)
0033 {
0034 dd4hep::InstanceCount::increment(this);
0035 declareProperty("Offset", m_offset);
0036 declareProperty("Sigma_ion", m_sigma_Ion);
0037 declareProperty("Sigma_e", m_sigma_Electron);
0038 declareProperty("Mask", m_mask = 0);
0039 m_needsControl = true;
0040 }
0041
0042
0043 EICInteractionVertexSmear::~EICInteractionVertexSmear() { dd4hep::InstanceCount::decrement(this); }
0044
0045
0046 void EICInteractionVertexSmear::smear(Interaction* inter) const {
0047 using namespace ROOT::Math;
0048 Geant4Random& rndm = context()->event().random();
0049 if (inter) {
0050 double dx = rndm.gauss(m_offset.x(), m_sigma_Ion.x());
0051 double dy = rndm.gauss(m_offset.y(), m_sigma_Ion.y());
0052
0053
0054
0055
0056
0057
0058 XYZVector ion_dir(0, 0, 1.0);
0059 RotationY rotx_ion(-dx);
0060 RotationX roty_ion(dy);
0061 auto new_ion_dir = rotx_ion(roty_ion(ion_dir));
0062
0063 Geant4PrimaryEvent::Interaction::VertexMap::iterator iv;
0064 Geant4PrimaryEvent::Interaction::ParticleMap::iterator ip;
0065
0066 double alpha = new_ion_dir.Theta();
0067 auto rotation_axis = ion_dir.Cross(new_ion_dir).Unit();
0068
0069 if (inter->locked) {
0070 this->abortRun("Locked interactions may not be boosted!",
0071 "Cannot boost interactions with a native G4 primary record!");
0072 } else if (alpha != 0.0) {
0073
0074 double tanalpha = std::tan(alpha/2.0);
0075 double gamma = std::sqrt(1 + tanalpha * tanalpha);
0076 double betagamma = tanalpha;
0077 double beta = betagamma / gamma;
0078
0079 Polar3D boost_vec(beta, M_PI / 2.0, new_ion_dir.Phi());
0080
0081 std::cout << " beta = " << beta << "\n";
0082
0083 Boost bst(boost_vec);
0084 LorentzRotation roty(AxisAngle(rotation_axis, alpha / 2.0));
0085
0086
0087 for (iv = inter->vertices.begin(); iv != inter->vertices.end(); ++iv) {
0088 for (Geant4Vertex* v : (*iv).second) {
0089 XYZTVector v0(v->x, v->y, v->z, v->time);
0090 auto v1 = roty(bst * v0);
0091 v->x = v1.x();
0092 v->y = v1.y();
0093 v->z = v1.z();
0094 v->time = v1.t();
0095 }
0096 }
0097
0098 for (ip = inter->particles.begin(); ip != inter->particles.end(); ++ip) {
0099 Geant4ParticleHandle p = (*ip).second;
0100 XYZTVector v0{p->vsx, p->vsy, p->vsz, p->time};
0101 auto v1 = roty(bst * v0);
0102
0103 PxPyPzMVector p0{p->psx, p->psy, p->psz, p->mass};
0104 auto p1 = roty(bst * p0);
0105
0106 p->vsx = v1.x();
0107 p->vsy = v1.y();
0108 p->vsz = v1.z();
0109 p->time = v1.t();
0110
0111 p->psx = p1.x();
0112 p->psy = p1.y();
0113 p->psz = p1.z();
0114 }
0115 }
0116
0117
0118 return;
0119 } else {
0120
0121
0122
0123 print("+++ No interaction of type %d present.", m_mask);
0124 }
0125 }
0126
0127
0128 void EICInteractionVertexSmear::operator()(G4Event*) {
0129 typedef std::vector<Geant4PrimaryInteraction*> _I;
0130 Geant4PrimaryEvent* evt = context()->event().extension<Geant4PrimaryEvent>();
0131
0132 if ( m_mask >= 0 ) {
0133 Interaction* inter = evt->get(m_mask);
0134 smear(inter);
0135 return;
0136 }
0137 _I interactions = evt->interactions();
0138 for(_I::iterator i=interactions.begin(); i != interactions.end(); ++i)
0139 smear(*i);
0140 }
0141 }
0142
0143 namespace dd4hep::sim {
0144 using EICInteractionVertexSmear = npdet::sim::EICInteractionVertexSmear;
0145 }
0146 DECLARE_GEANT4ACTION(EICInteractionVertexSmear)
0147