Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/error_propagation/src/G4ErrorFreeTrajState.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /error_propagation/src/G4ErrorFreeTrajState.cc (Version 11.3.0) and /error_propagation/src/G4ErrorFreeTrajState.cc (Version 11.0.p2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 // -------------------------------------------     27 // ------------------------------------------------------------
 28 //      GEANT 4 class implementation file          28 //      GEANT 4 class implementation file
 29 // -------------------------------------------     29 // ------------------------------------------------------------
 30 //                                                 30 //
 31                                                    31 
 32 #include <iomanip>                                 32 #include <iomanip>
 33                                                    33 
 34 #include "G4PhysicalConstants.hh"                  34 #include "G4PhysicalConstants.hh"
 35 #include "G4SystemOfUnits.hh"                      35 #include "G4SystemOfUnits.hh"
 36 #include "G4Field.hh"                              36 #include "G4Field.hh"
 37 #include "G4FieldManager.hh"                       37 #include "G4FieldManager.hh"
 38 #include "G4TransportationManager.hh"              38 #include "G4TransportationManager.hh"
 39 #include "G4GeometryTolerance.hh"                  39 #include "G4GeometryTolerance.hh"
 40 #include "G4Material.hh"                           40 #include "G4Material.hh"
 41 #include "G4ErrorPropagatorData.hh"                41 #include "G4ErrorPropagatorData.hh"
 42 #include "G4ErrorFreeTrajState.hh"                 42 #include "G4ErrorFreeTrajState.hh"
 43 #include "G4ErrorFreeTrajParam.hh"                 43 #include "G4ErrorFreeTrajParam.hh"
 44 #include "G4ErrorSurfaceTrajState.hh"              44 #include "G4ErrorSurfaceTrajState.hh"
 45 #include "G4ErrorMatrix.hh"                        45 #include "G4ErrorMatrix.hh"
 46                                                    46 
 47 //--------------------------------------------     47 //------------------------------------------------------------------------
 48 G4ErrorFreeTrajState::G4ErrorFreeTrajState(con     48 G4ErrorFreeTrajState::G4ErrorFreeTrajState(const G4String& partName,
 49                                            con     49                                            const G4Point3D& pos,
 50                                            con     50                                            const G4Vector3D& mom,
 51                                            con     51                                            const G4ErrorTrajErr& errmat)
 52   : G4ErrorTrajState(partName, pos, mom, errma     52   : G4ErrorTrajState(partName, pos, mom, errmat)
 53 {                                                  53 {
 54   fTrajParam = G4ErrorFreeTrajParam(pos, mom);     54   fTrajParam = G4ErrorFreeTrajParam(pos, mom);
 55   Init();                                          55   Init();
 56 }                                                  56 }
 57                                                    57 
 58 //--------------------------------------------     58 //------------------------------------------------------------------------
 59 G4ErrorFreeTrajState::G4ErrorFreeTrajState(con     59 G4ErrorFreeTrajState::G4ErrorFreeTrajState(const G4ErrorSurfaceTrajState& tpSD)
 60   : G4ErrorTrajState(tpSD.GetParticleType(), t     60   : G4ErrorTrajState(tpSD.GetParticleType(), tpSD.GetPosition(),
 61                      tpSD.GetMomentum())           61                      tpSD.GetMomentum())
 62 {                                                  62 {
 63   // G4ThreeVector planeNormal = tpSD.GetPlane     63   // G4ThreeVector planeNormal = tpSD.GetPlaneNormal();
 64   // G4double fPt = tpSD.GetMomentum()*planeNo     64   // G4double fPt = tpSD.GetMomentum()*planeNormal;//mom projected on normal to
 65   // plane G4ErrorSurfaceTrajParam tpSDparam =     65   // plane G4ErrorSurfaceTrajParam tpSDparam = tpSD.GetParameters();
 66   // G4ThreeVector Psc = fPt * planeNormal +       66   // G4ThreeVector Psc = fPt * planeNormal +
 67   // tpSDparam.GetPU()*tpSDparam.GetVectorU()      67   // tpSDparam.GetPU()*tpSDparam.GetVectorU() + tpSD.GetPV()*tpSD.GetVectorW();
 68                                                    68 
 69   fTrajParam = G4ErrorFreeTrajParam(fPosition,     69   fTrajParam = G4ErrorFreeTrajParam(fPosition, fMomentum);
 70   Init();                                          70   Init();
 71                                                    71 
 72   //----- Get the error matrix in SC coordinat     72   //----- Get the error matrix in SC coordinates
 73   G4ErrorSurfaceTrajParam tpSDparam = tpSD.Get     73   G4ErrorSurfaceTrajParam tpSDparam = tpSD.GetParameters();
 74   G4double mom                      = fMomentu     74   G4double mom                      = fMomentum.mag();
 75   G4double mom2                     = fMomentu     75   G4double mom2                     = fMomentum.mag2();
 76   G4double TVW1 =                                  76   G4double TVW1 =
 77     std::sqrt(mom2 / (mom2 + tpSDparam.GetPV()     77     std::sqrt(mom2 / (mom2 + tpSDparam.GetPV() * tpSDparam.GetPV() +
 78                       tpSDparam.GetPW() * tpSD     78                       tpSDparam.GetPW() * tpSDparam.GetPW()));
 79   G4ThreeVector vTVW(TVW1, tpSDparam.GetPV() /     79   G4ThreeVector vTVW(TVW1, tpSDparam.GetPV() / mom * TVW1,
 80                      tpSDparam.GetPW() / mom *     80                      tpSDparam.GetPW() / mom * TVW1);
 81   G4Vector3D vectorU = tpSDparam.GetVectorV().     81   G4Vector3D vectorU = tpSDparam.GetVectorV().cross(tpSDparam.GetVectorW());
 82   G4Vector3D vTN     = vTVW.x() * vectorU + vT     82   G4Vector3D vTN     = vTVW.x() * vectorU + vTVW.y() * tpSDparam.GetVectorV() +
 83                    vTVW.z() * tpSDparam.GetVec     83                    vTVW.z() * tpSDparam.GetVectorW();
 84                                                    84 
 85 #ifdef G4EVERBOSE                                  85 #ifdef G4EVERBOSE
 86   if(iverbose >= 5)                                86   if(iverbose >= 5)
 87   {                                                87   {
 88     G4double pc2 = std::asin(vTN.z());             88     G4double pc2 = std::asin(vTN.z());
 89     G4double pc3 = std::atan(vTN.y() / vTN.x()     89     G4double pc3 = std::atan(vTN.y() / vTN.x());
 90                                                    90 
 91     G4cout << " CHECK: pc2 " << pc2 << " = " <     91     G4cout << " CHECK: pc2 " << pc2 << " = " << GetParameters().GetLambda()
 92            << " diff " << pc2 - GetParameters(     92            << " diff " << pc2 - GetParameters().GetLambda() << G4endl;
 93     G4cout << " CHECK: pc3 " << pc3 << " = " <     93     G4cout << " CHECK: pc3 " << pc3 << " = " << GetParameters().GetPhi()
 94            << " diff " << pc3 - GetParameters(     94            << " diff " << pc3 - GetParameters().GetPhi() << G4endl;
 95   }                                                95   }
 96 #endif                                             96 #endif
 97                                                    97 
 98   //--- Get the unit vectors perp to P             98   //--- Get the unit vectors perp to P
 99   G4double cosl = std::cos(GetParameters().Get     99   G4double cosl = std::cos(GetParameters().GetLambda());
100   if(cosl < 1.E-30)                               100   if(cosl < 1.E-30)
101     cosl = 1.E-30;                                101     cosl = 1.E-30;
102   G4double cosl1 = 1. / cosl;                     102   G4double cosl1 = 1. / cosl;
103   G4Vector3D vUN(-vTN.y() * cosl1, vTN.x() * c    103   G4Vector3D vUN(-vTN.y() * cosl1, vTN.x() * cosl1, 0.);
104   G4Vector3D vVN(-vTN.z() * vUN.y(), vTN.z() *    104   G4Vector3D vVN(-vTN.z() * vUN.y(), vTN.z() * vUN.x(), cosl);
105                                                   105 
106   G4Vector3D vUperp = G4Vector3D(-fMomentum.y(    106   G4Vector3D vUperp = G4Vector3D(-fMomentum.y(), fMomentum.x(), 0.);
107   G4Vector3D vVperp = vUperp.cross(fMomentum);    107   G4Vector3D vVperp = vUperp.cross(fMomentum);
108   vUperp *= 1. / vUperp.mag();                    108   vUperp *= 1. / vUperp.mag();
109   vVperp *= 1. / vVperp.mag();                    109   vVperp *= 1. / vVperp.mag();
110                                                   110 
111 #ifdef G4EVERBOSE                                 111 #ifdef G4EVERBOSE
112   if(iverbose >= 5)                               112   if(iverbose >= 5)
113   {                                               113   {
114     G4cout << " CHECK: vUN " << vUN << " = " <    114     G4cout << " CHECK: vUN " << vUN << " = " << vUperp << " diff "
115            << (vUN - vUperp).mag() << G4endl;     115            << (vUN - vUperp).mag() << G4endl;
116     G4cout << " CHECK: vVN " << vVN << " = " <    116     G4cout << " CHECK: vVN " << vVN << " = " << vVperp << " diff "
117            << (vVN - vVperp).mag() << G4endl;     117            << (vVN - vVperp).mag() << G4endl;
118   }                                               118   }
119 #endif                                            119 #endif
120                                                   120 
121   // get the dot products of vectors perpendic    121   // get the dot products of vectors perpendicular to direction and vector
122   // defining SD plane                            122   // defining SD plane
123   G4double dUU = vUperp * tpSD.GetVectorV();      123   G4double dUU = vUperp * tpSD.GetVectorV();
124   G4double dUV = vUperp * tpSD.GetVectorW();      124   G4double dUV = vUperp * tpSD.GetVectorW();
125   G4double dVU = vVperp * tpSD.GetVectorV();      125   G4double dVU = vVperp * tpSD.GetVectorV();
126   G4double dVV = vVperp * tpSD.GetVectorW();      126   G4double dVV = vVperp * tpSD.GetVectorW();
127                                                   127 
128   //--- Get transformation first                  128   //--- Get transformation first
129   G4ErrorMatrix transfM(5, 5, 1);                 129   G4ErrorMatrix transfM(5, 5, 1);
130   //--- Get magnetic field                        130   //--- Get magnetic field
131   const G4Field* field = G4TransportationManag    131   const G4Field* field = G4TransportationManager::GetTransportationManager()
132                            ->GetFieldManager()    132                            ->GetFieldManager()
133                            ->GetDetectorField(    133                            ->GetDetectorField();
134   G4ThreeVector dir    = fTrajParam.GetDirecti    134   G4ThreeVector dir    = fTrajParam.GetDirection();
135   G4double invCosTheta = 1. / std::cos(dir.the    135   G4double invCosTheta = 1. / std::cos(dir.theta());
136   G4cout << " dir=" << dir << " invCosTheta "     136   G4cout << " dir=" << dir << " invCosTheta " << invCosTheta << G4endl;
137                                                   137 
138   if(fCharge != 0 && field)                       138   if(fCharge != 0 && field)
139   {                                               139   {
140     G4double pos1[3];                             140     G4double pos1[3];
141     pos1[0] = fPosition.x() * cm;                 141     pos1[0] = fPosition.x() * cm;
142     pos1[1] = fPosition.y() * cm;                 142     pos1[1] = fPosition.y() * cm;
143     pos1[2] = fPosition.z() * cm;                 143     pos1[2] = fPosition.z() * cm;
144     G4double h1[3];                               144     G4double h1[3];
145     field->GetFieldValue(pos1, h1);               145     field->GetFieldValue(pos1, h1);
146     G4ThreeVector HPre = G4ThreeVector(h1[0],     146     G4ThreeVector HPre = G4ThreeVector(h1[0], h1[1], h1[2]) / tesla * 10.;
147     G4double magHPre   = HPre.mag();              147     G4double magHPre   = HPre.mag();
148     G4double invP      = 1. / fMomentum.mag();    148     G4double invP      = 1. / fMomentum.mag();
149     G4double magHPreM  = magHPre * invP;          149     G4double magHPreM  = magHPre * invP;
150     if(magHPre != 0.)                             150     if(magHPre != 0.)
151     {                                             151     {
152       G4double magHPreM2 = fCharge / magHPre;     152       G4double magHPreM2 = fCharge / magHPre;
153                                                   153 
154       G4double Q    = -magHPreM * c_light;        154       G4double Q    = -magHPreM * c_light;
155       G4double sinz = -HPre * vUperp * magHPre    155       G4double sinz = -HPre * vUperp * magHPreM2;
156       G4double cosz = HPre * vVperp * magHPreM    156       G4double cosz = HPre * vVperp * magHPreM2;
157                                                   157 
158       transfM[1][3] = -Q * dir.y() * sinz;        158       transfM[1][3] = -Q * dir.y() * sinz;
159       transfM[1][4] = -Q * dir.z() * sinz;        159       transfM[1][4] = -Q * dir.z() * sinz;
160       transfM[2][3] = -Q * dir.y() * cosz * in    160       transfM[2][3] = -Q * dir.y() * cosz * invCosTheta;
161       transfM[2][4] = -Q * dir.z() * cosz * in    161       transfM[2][4] = -Q * dir.z() * cosz * invCosTheta;
162     }                                             162     }
163   }                                               163   }
164                                                   164 
165   transfM[0][0] = 1.;                             165   transfM[0][0] = 1.;
166   transfM[1][1] = dir.x() * dVU;                  166   transfM[1][1] = dir.x() * dVU;
167   transfM[1][2] = dir.x() * dVV;                  167   transfM[1][2] = dir.x() * dVV;
168   transfM[2][1] = dir.x() * dUU * invCosTheta;    168   transfM[2][1] = dir.x() * dUU * invCosTheta;
169   transfM[2][2] = dir.x() * dUV * invCosTheta;    169   transfM[2][2] = dir.x() * dUV * invCosTheta;
170   transfM[3][3] = dUU;                            170   transfM[3][3] = dUU;
171   transfM[3][4] = dUV;                            171   transfM[3][4] = dUV;
172   transfM[4][3] = dVU;                            172   transfM[4][3] = dVU;
173   transfM[4][4] = dVV;                            173   transfM[4][4] = dVV;
174                                                   174 
175   fError = G4ErrorTrajErr(tpSD.GetError().simi    175   fError = G4ErrorTrajErr(tpSD.GetError().similarity(transfM));
176                                                   176 
177 #ifdef G4EVERBOSE                                 177 #ifdef G4EVERBOSE
178   if(iverbose >= 1)                               178   if(iverbose >= 1)
179     G4cout << "error matrix SD2SC " << fError     179     G4cout << "error matrix SD2SC " << fError << G4endl;
180   if(iverbose >= 4)                               180   if(iverbose >= 4)
181     G4cout << "G4ErrorFreeTrajState from SD "     181     G4cout << "G4ErrorFreeTrajState from SD " << *this << G4endl;
182 #endif                                            182 #endif
183 }                                                 183 }
184                                                   184 
185 //--------------------------------------------    185 //------------------------------------------------------------------------
186 void G4ErrorFreeTrajState::Init()                 186 void G4ErrorFreeTrajState::Init()
187 {                                                 187 {
188   theTSType = G4eTS_FREE;                         188   theTSType = G4eTS_FREE;
189   BuildCharge();                                  189   BuildCharge();
190   theTransfMat = G4ErrorMatrix(5, 5, 0);          190   theTransfMat = G4ErrorMatrix(5, 5, 0);
191   theFirstStep = true;                            191   theFirstStep = true;
192 }                                                 192 }
193                                                   193 
194 //--------------------------------------------    194 //------------------------------------------------------------------------
195 void G4ErrorFreeTrajState::Dump(std::ostream&     195 void G4ErrorFreeTrajState::Dump(std::ostream& out) const { out << *this; }
196                                                   196 
197 //--------------------------------------------    197 //------------------------------------------------------------------------
198 G4int G4ErrorFreeTrajState::Update(const G4Tra    198 G4int G4ErrorFreeTrajState::Update(const G4Track* aTrack)
199 {                                                 199 {
200   G4int ierr = 0;                                 200   G4int ierr = 0;
201   fTrajParam.Update(aTrack);                      201   fTrajParam.Update(aTrack);
202   UpdatePosMom(aTrack->GetPosition(), aTrack->    202   UpdatePosMom(aTrack->GetPosition(), aTrack->GetMomentum());
203   return ierr;                                    203   return ierr;
204 }                                                 204 }
205                                                   205 
206 //--------------------------------------------    206 //------------------------------------------------------------------------
207 std::ostream& operator<<(std::ostream& out, co    207 std::ostream& operator<<(std::ostream& out, const G4ErrorFreeTrajState& ts)
208 {                                                 208 {
209   std::ios::fmtflags orig_flags = out.flags();    209   std::ios::fmtflags orig_flags = out.flags();
210                                                   210 
211   out.setf(std::ios::fixed, std::ios::floatfie    211   out.setf(std::ios::fixed, std::ios::floatfield);
212                                                   212 
213   ts.DumpPosMomError(out);                        213   ts.DumpPosMomError(out);
214                                                   214 
215   out << " G4ErrorFreeTrajState: Params: " <<     215   out << " G4ErrorFreeTrajState: Params: " << ts.fTrajParam << G4endl;
216                                                   216 
217   out.flags(orig_flags);                          217   out.flags(orig_flags);
218                                                   218 
219   return out;                                     219   return out;
220 }                                                 220 }
221                                                   221 
222 //--------------------------------------------    222 //------------------------------------------------------------------------
223 G4int G4ErrorFreeTrajState::PropagateError(con    223 G4int G4ErrorFreeTrajState::PropagateError(const G4Track* aTrack)
224 {                                                 224 {
225   G4double stepLengthCm = aTrack->GetStep()->G    225   G4double stepLengthCm = aTrack->GetStep()->GetStepLength() / cm;
226   if(G4ErrorPropagatorData::GetErrorPropagator    226   if(G4ErrorPropagatorData::GetErrorPropagatorData()->GetStage() ==
227      G4ErrorStage_Deflation)                      227      G4ErrorStage_Deflation)
228     stepLengthCm *= -1.;                          228     stepLengthCm *= -1.;
229                                                   229 
230   G4double kCarTolerance =                        230   G4double kCarTolerance =
231     G4GeometryTolerance::GetInstance()->GetSur    231     G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
232                                                   232 
233   if(std::fabs(stepLengthCm) <= kCarTolerance     233   if(std::fabs(stepLengthCm) <= kCarTolerance / cm)
234     return 0;                                     234     return 0;
235                                                   235 
236 #ifdef G4EVERBOSE                                 236 #ifdef G4EVERBOSE
237   if(iverbose >= 2)                               237   if(iverbose >= 2)
238     G4cout << "  G4ErrorFreeTrajState::Propaga    238     G4cout << "  G4ErrorFreeTrajState::PropagateError " << G4endl;
239   G4cout << "G4EP: iverbose=" << iverbose << G    239   G4cout << "G4EP: iverbose=" << iverbose << G4endl;
240 #endif                                            240 #endif
241                                                   241 
242   // * *** ERROR PROPAGATION ON A HELIX ASSUMI    242   // * *** ERROR PROPAGATION ON A HELIX ASSUMING SC VARIABLES
243   G4Point3D vposPost = aTrack->GetPosition() /    243   G4Point3D vposPost = aTrack->GetPosition() / cm;
244   G4Vector3D vpPost  = aTrack->GetMomentum() /    244   G4Vector3D vpPost  = aTrack->GetMomentum() / GeV;
245   //  G4Point3D vposPre = fPosition/cm;           245   //  G4Point3D vposPre = fPosition/cm;
246   //  G4Vector3D vpPre = fMomentum/GeV;           246   //  G4Vector3D vpPre = fMomentum/GeV;
247   G4Point3D vposPre = aTrack->GetStep()->GetPr    247   G4Point3D vposPre = aTrack->GetStep()->GetPreStepPoint()->GetPosition() / cm;
248   G4Vector3D vpPre  = aTrack->GetStep()->GetPr    248   G4Vector3D vpPre  = aTrack->GetStep()->GetPreStepPoint()->GetMomentum() / GeV;
249   // correct to avoid propagation along Z         249   // correct to avoid propagation along Z
250   if(vpPre.mag() == vpPre.z())                    250   if(vpPre.mag() == vpPre.z())
251     vpPre.setX(1.E-6 * MeV);                      251     vpPre.setX(1.E-6 * MeV);
252   if(vpPost.mag() == vpPost.z())                  252   if(vpPost.mag() == vpPost.z())
253     vpPost.setX(1.E-6 * MeV);                     253     vpPost.setX(1.E-6 * MeV);
254                                                   254 
255   G4double pPre  = vpPre.mag();                   255   G4double pPre  = vpPre.mag();
256   G4double pPost = vpPost.mag();                  256   G4double pPost = vpPost.mag();
257 #ifdef G4EVERBOSE                                 257 #ifdef G4EVERBOSE
258   if(iverbose >= 2)                               258   if(iverbose >= 2)
259   {                                               259   {
260     G4cout << "G4EP: vposPre " << vposPre << G    260     G4cout << "G4EP: vposPre " << vposPre << G4endl << "G4EP: vposPost "
261            << vposPost << G4endl;                 261            << vposPost << G4endl;
262     G4cout << "G4EP: vpPre " << vpPre << G4end    262     G4cout << "G4EP: vpPre " << vpPre << G4endl << "G4EP: vpPost " << vpPost
263            << G4endl;                             263            << G4endl;
264     G4cout << " err start step " << fError <<     264     G4cout << " err start step " << fError << G4endl;
265     G4cout << "G4EP: stepLengthCm " << stepLen    265     G4cout << "G4EP: stepLengthCm " << stepLengthCm << G4endl;
266   }                                               266   }
267 #endif                                            267 #endif
268                                                   268 
269   if(pPre == 0. || pPost == 0)                    269   if(pPre == 0. || pPost == 0)
270     return 2;                                     270     return 2;
271   G4double pInvPre   = 1. / pPre;                 271   G4double pInvPre   = 1. / pPre;
272   G4double pInvPost  = 1. / pPost;                272   G4double pInvPost  = 1. / pPost;
273   G4double deltaPInv = pInvPost - pInvPre;        273   G4double deltaPInv = pInvPost - pInvPre;
274   if(iverbose >= 2)                               274   if(iverbose >= 2)
275     G4cout << "G4EP:  pInvPre" << pInvPre << "    275     G4cout << "G4EP:  pInvPre" << pInvPre << "  pInvPost:" << pInvPost
276            << "  deltaPInv:" << deltaPInv << G    276            << "  deltaPInv:" << deltaPInv << G4endl;
277                                                   277 
278   G4Vector3D vpPreNorm  = vpPre * pInvPre;        278   G4Vector3D vpPreNorm  = vpPre * pInvPre;
279   G4Vector3D vpPostNorm = vpPost * pInvPost;      279   G4Vector3D vpPostNorm = vpPost * pInvPost;
280   if(iverbose >= 2)                               280   if(iverbose >= 2)
281     G4cout << "G4EP: vpPreNorm " << vpPreNorm     281     G4cout << "G4EP: vpPreNorm " << vpPreNorm << " vpPostNorm " << vpPostNorm
282            << G4endl;                             282            << G4endl;
283   // return if propagation along Z??              283   // return if propagation along Z??
284   if(1. - std::fabs(vpPreNorm.z()) < kCarToler    284   if(1. - std::fabs(vpPreNorm.z()) < kCarTolerance)
285     return 4;                                     285     return 4;
286   if(1. - std::fabs(vpPostNorm.z()) < kCarTole    286   if(1. - std::fabs(vpPostNorm.z()) < kCarTolerance)
287     return 4;                                     287     return 4;
288   G4double sinpPre =                              288   G4double sinpPre =
289     std::sin(vpPreNorm.theta());  // cosine pe    289     std::sin(vpPreNorm.theta());  // cosine perpendicular to pPre = sine pPre
290   G4double sinpPost =                             290   G4double sinpPost =
291     std::sin(vpPostNorm.theta());  // cosine p    291     std::sin(vpPostNorm.theta());  // cosine perpendicular to pPost = sine pPost
292   G4double sinpPostInv = 1. / std::sin(vpPostN    292   G4double sinpPostInv = 1. / std::sin(vpPostNorm.theta());
293                                                   293 
294 #ifdef G4EVERBOSE                                 294 #ifdef G4EVERBOSE
295   if(iverbose >= 2)                               295   if(iverbose >= 2)
296     G4cout << "G4EP: cosl " << sinpPre << " co    296     G4cout << "G4EP: cosl " << sinpPre << " cosl0 " << sinpPost << G4endl;
297 #endif                                            297 #endif
298   //* *** DEFINE TRANSFORMATION MATRIX BETWEEN    298   //* *** DEFINE TRANSFORMATION MATRIX BETWEEN X1 AND X2 FOR
299   //* *** NEUTRAL PARTICLE OR FIELDFREE REGION    299   //* *** NEUTRAL PARTICLE OR FIELDFREE REGION
300   G4ErrorMatrix transf(5, 5, 0);                  300   G4ErrorMatrix transf(5, 5, 0);
301                                                   301 
302   transf[3][2] = stepLengthCm * sinpPost;         302   transf[3][2] = stepLengthCm * sinpPost;
303   transf[4][1] = stepLengthCm;                    303   transf[4][1] = stepLengthCm;
304   for(auto ii = 0; ii < 5; ++ii)               << 304   for(size_t ii = 0; ii < 5; ii++)
305   {                                               305   {
306     transf[ii][ii] = 1.;                          306     transf[ii][ii] = 1.;
307   }                                               307   }
308 #ifdef G4EVERBOSE                                 308 #ifdef G4EVERBOSE
309   if(iverbose >= 2)                               309   if(iverbose >= 2)
310   {                                               310   {
311     G4cout << "G4EP: transf matrix neutral " <    311     G4cout << "G4EP: transf matrix neutral " << transf;
312   }                                               312   }
313 #endif                                            313 #endif
314                                                   314 
315   //  charge X propagation direction              315   //  charge X propagation direction
316   G4double charge = aTrack->GetDynamicParticle    316   G4double charge = aTrack->GetDynamicParticle()->GetCharge();
317   if(G4ErrorPropagatorData::GetErrorPropagator    317   if(G4ErrorPropagatorData::GetErrorPropagatorData()->GetMode() ==
318      G4ErrorMode_PropBackwards)                   318      G4ErrorMode_PropBackwards)
319   {                                               319   {
320     charge *= -1.;                                320     charge *= -1.;
321   }                                               321   }
322   //  G4cout << " charge " << charge << G4endl    322   //  G4cout << " charge " << charge << G4endl;
323   // t check if particle has charge               323   // t check if particle has charge
324   // t  if( charge == 0 ) goto 45;                324   // t  if( charge == 0 ) goto 45;
325   // check if the magnetic field is = 0.          325   // check if the magnetic field is = 0.
326                                                   326 
327   // position is from geant4, it is assumed to    327   // position is from geant4, it is assumed to be in mm (for debugging,
328   // eventually it will not be transformed) it    328   // eventually it will not be transformed) it is assumed vposPre[] is in cm and
329   // pos1[] is in mm.                             329   // pos1[] is in mm.
330   G4double pos1[3];                               330   G4double pos1[3];
331   pos1[0] = vposPre.x() * cm;                     331   pos1[0] = vposPre.x() * cm;
332   pos1[1] = vposPre.y() * cm;                     332   pos1[1] = vposPre.y() * cm;
333   pos1[2] = vposPre.z() * cm;                     333   pos1[2] = vposPre.z() * cm;
334   G4double pos2[3];                               334   G4double pos2[3];
335   pos2[0] = vposPost.x() * cm;                    335   pos2[0] = vposPost.x() * cm;
336   pos2[1] = vposPost.y() * cm;                    336   pos2[1] = vposPost.y() * cm;
337   pos2[2] = vposPost.z() * cm;                    337   pos2[2] = vposPost.z() * cm;
338   G4double h1[3], h2[3];                          338   G4double h1[3], h2[3];
339                                                   339 
340   const G4Field* field = G4TransportationManag    340   const G4Field* field = G4TransportationManager::GetTransportationManager()
341                            ->GetFieldManager()    341                            ->GetFieldManager()
342                            ->GetDetectorField(    342                            ->GetDetectorField();
343   if(!field)                                      343   if(!field)
344     return 0;  // goto 45                         344     return 0;  // goto 45
345                                                   345 
346   // calculate transformation except it NEUTRA    346   // calculate transformation except it NEUTRAL PARTICLE OR FIELDFREE REGION
347   if(charge != 0. && field)                       347   if(charge != 0. && field)
348   {                                               348   {
349     field->GetFieldValue(pos1,                    349     field->GetFieldValue(pos1,
350                          h1);  // here pos1[],    350                          h1);  // here pos1[], pos2[] are in mm, not changed
351     field->GetFieldValue(pos2, h2);               351     field->GetFieldValue(pos2, h2);
352     G4ThreeVector HPre =                          352     G4ThreeVector HPre =
353       G4ThreeVector(h1[0], h1[1], h1[2]) / tes    353       G4ThreeVector(h1[0], h1[1], h1[2]) / tesla *
354       10.;  // 10. is to get same dimensions a    354       10.;  // 10. is to get same dimensions as GEANT3 (kilogauss)
355     G4ThreeVector HPost = G4ThreeVector(h2[0],    355     G4ThreeVector HPost = G4ThreeVector(h2[0], h2[1], h2[2]) / tesla * 10.;
356     G4double magHPre    = HPre.mag();             356     G4double magHPre    = HPre.mag();
357     G4double magHPost   = HPost.mag();            357     G4double magHPost   = HPost.mag();
358 #ifdef G4EVERBOSE                                 358 #ifdef G4EVERBOSE
359     if(iverbose >= 2)                             359     if(iverbose >= 2)
360     {                                             360     {
361       G4cout << "G4EP: h1 = " << h1[0] << ", "    361       G4cout << "G4EP: h1 = " << h1[0] << ", " << h1[1] << ", " << h1[2]
362              << G4endl;                           362              << G4endl;
363       G4cout << "G4EP: pos1/mm = " << pos1[0]     363       G4cout << "G4EP: pos1/mm = " << pos1[0] << ", " << pos1[1] << ", "
364              << pos1[2] << G4endl;                364              << pos1[2] << G4endl;
365       G4cout << "G4EP: pos2/mm = " << pos2[0]     365       G4cout << "G4EP: pos2/mm = " << pos2[0] << ", " << pos2[1] << ", "
366              << pos2[2] << G4endl;                366              << pos2[2] << G4endl;
367       G4cout << "G4EP: B-filed in KGauss HPre     367       G4cout << "G4EP: B-filed in KGauss HPre " << HPre << G4endl
368              << "G4EP: in KGauss HPost " << HP    368              << "G4EP: in KGauss HPost " << HPost << G4endl;
369     }                                             369     }
370 #endif                                            370 #endif
371                                                   371 
372     if(magHPre + magHPost != 0.)                  372     if(magHPre + magHPost != 0.)
373     {                                             373     {
374       //* *** CHECK WHETHER H*ALFA/P IS TOO DI    374       //* *** CHECK WHETHER H*ALFA/P IS TOO DIFFERENT AT X1 AND X2
375       G4double gam;                               375       G4double gam;
376       if(magHPost != 0.)                          376       if(magHPost != 0.)
377       {                                           377       {
378         gam = HPost * vpPostNorm / magHPost;      378         gam = HPost * vpPostNorm / magHPost;
379       }                                           379       }
380       else                                        380       else
381       {                                           381       {
382         gam = HPre * vpPreNorm / magHPre;         382         gam = HPre * vpPreNorm / magHPre;
383       }                                           383       }
384                                                   384 
385       // G4eMagneticLimitsProcess will limit t    385       // G4eMagneticLimitsProcess will limit the step, but based on an straight
386       // line trajectory                          386       // line trajectory
387       G4double alphaSqr  = 1. - gam * gam;        387       G4double alphaSqr  = 1. - gam * gam;
388       G4double diffHSqr  = (HPre * pInvPre - H    388       G4double diffHSqr  = (HPre * pInvPre - HPost * pInvPost).mag2();
389       G4double delhp6Sqr = 300. * 300.;           389       G4double delhp6Sqr = 300. * 300.;
390 #ifdef G4EVERBOSE                                 390 #ifdef G4EVERBOSE
391       if(iverbose >= 2)                           391       if(iverbose >= 2)
392       {                                           392       {
393         G4cout << " G4EP: gam " << gam << " al    393         G4cout << " G4EP: gam " << gam << " alphaSqr " << alphaSqr
394                << " diffHSqr " << diffHSqr <<     394                << " diffHSqr " << diffHSqr << G4endl;
395         G4cout << " alpha= " << std::sqrt(alph    395         G4cout << " alpha= " << std::sqrt(alphaSqr) << G4endl;
396       }                                           396       }
397 #endif                                            397 #endif
398       if(diffHSqr * alphaSqr > delhp6Sqr)         398       if(diffHSqr * alphaSqr > delhp6Sqr)
399         return 3;                                 399         return 3;
400                                                   400 
401       //* *** DEFINE AVERAGE MAGNETIC FIELD AN    401       //* *** DEFINE AVERAGE MAGNETIC FIELD AND GRADIENT
402       G4double pInvAver = 1. / (pInvPre + pInv    402       G4double pInvAver = 1. / (pInvPre + pInvPost);
403       G4double CFACT8   = 2.997925E-4;            403       G4double CFACT8   = 2.997925E-4;
404       // G4double HAver                           404       // G4double HAver
405       G4ThreeVector vHAverNorm((HPre * pInvPre    405       G4ThreeVector vHAverNorm((HPre * pInvPre + HPost * pInvPost) * pInvAver *
406                                charge * CFACT8    406                                charge * CFACT8);
407       G4double HAver    = vHAverNorm.mag();       407       G4double HAver    = vHAverNorm.mag();
408       G4double invHAver = 1. / HAver;             408       G4double invHAver = 1. / HAver;
409       vHAverNorm *= invHAver;                     409       vHAverNorm *= invHAver;
410 #ifdef G4EVERBOSE                                 410 #ifdef G4EVERBOSE
411       if(iverbose >= 2)                           411       if(iverbose >= 2)
412         G4cout << " G4EP: HaverNorm " << vHAve    412         G4cout << " G4EP: HaverNorm " << vHAverNorm << " magHAver " << HAver
413                << " charge " << charge << G4en    413                << " charge " << charge << G4endl;
414 #endif                                            414 #endif
415                                                   415 
416       G4double pAver        = (pPre + pPost) *    416       G4double pAver        = (pPre + pPost) * 0.5;
417       G4double QAver        = -HAver / pAver;     417       G4double QAver        = -HAver / pAver;
418       G4double thetaAver    = QAver * stepLeng    418       G4double thetaAver    = QAver * stepLengthCm;
419       G4double sinThetaAver = std::sin(thetaAv    419       G4double sinThetaAver = std::sin(thetaAver);
420       G4double cosThetaAver = std::cos(thetaAv    420       G4double cosThetaAver = std::cos(thetaAver);
421       G4double gamma        = vHAverNorm * vpP    421       G4double gamma        = vHAverNorm * vpPostNorm;
422       G4ThreeVector AN2     = vHAverNorm.cross    422       G4ThreeVector AN2     = vHAverNorm.cross(vpPostNorm);
423                                                   423 
424 #ifdef G4EVERBOSE                                 424 #ifdef G4EVERBOSE
425       if(iverbose >= 2)                           425       if(iverbose >= 2)
426         G4cout << " G4EP: AN2 " << AN2 << "  g    426         G4cout << " G4EP: AN2 " << AN2 << "  gamma:" << gamma
427                << "  theta=" << thetaAver << G    427                << "  theta=" << thetaAver << G4endl;
428 #endif                                            428 #endif
429       G4double AU = 1. / vpPreNorm.perp();        429       G4double AU = 1. / vpPreNorm.perp();
430       // t  G4ThreeVector vU( vpPreNorm.cross(    430       // t  G4ThreeVector vU( vpPreNorm.cross( G4ThreeVector(0.,0.,1.) ) * AU );
431       G4ThreeVector vUPre(-AU * vpPreNorm.y(),    431       G4ThreeVector vUPre(-AU * vpPreNorm.y(), AU * vpPreNorm.x(), 0.);
432       G4ThreeVector vVPre(-vpPreNorm.z() * vUP    432       G4ThreeVector vVPre(-vpPreNorm.z() * vUPre.y(), vpPreNorm.z() * vUPre.x(),
433                           vpPreNorm.x() * vUPr    433                           vpPreNorm.x() * vUPre.y() -
434                             vpPreNorm.y() * vU    434                             vpPreNorm.y() * vUPre.x());
435                                                   435 
436       //                                          436       //
437       AU = 1. / vpPostNorm.perp();                437       AU = 1. / vpPostNorm.perp();
438       // t  G4ThreeVector vU( vpPostNorm.cross    438       // t  G4ThreeVector vU( vpPostNorm.cross( G4ThreeVector(0.,0.,1.) ) * AU
439       // );                                       439       // );
440       G4ThreeVector vUPost(-AU * vpPostNorm.y(    440       G4ThreeVector vUPost(-AU * vpPostNorm.y(), AU * vpPostNorm.x(), 0.);
441       G4ThreeVector vVPost(                       441       G4ThreeVector vVPost(
442         -vpPostNorm.z() * vUPost.y(), vpPostNo    442         -vpPostNorm.z() * vUPost.y(), vpPostNorm.z() * vUPost.x(),
443         vpPostNorm.x() * vUPost.y() - vpPostNo    443         vpPostNorm.x() * vUPost.y() - vpPostNorm.y() * vUPost.x());
444 #ifdef G4EVERBOSE                                 444 #ifdef G4EVERBOSE
445       G4cout << " vpPostNorm " << vpPostNorm <    445       G4cout << " vpPostNorm " << vpPostNorm << G4endl;
446       if(iverbose >= 2)                           446       if(iverbose >= 2)
447         G4cout << " G4EP: AU " << AU << " vUPr    447         G4cout << " G4EP: AU " << AU << " vUPre " << vUPre << " vVPre " << vVPre
448                << " vUPost " << vUPost << " vV    448                << " vUPost " << vUPost << " vVPost " << vVPost << G4endl;
449 #endif                                            449 #endif
450       G4Point3D deltaPos(vposPre - vposPost);     450       G4Point3D deltaPos(vposPre - vposPost);
451                                                   451 
452       // * *** COMPLETE TRANSFORMATION MATRIX     452       // * *** COMPLETE TRANSFORMATION MATRIX BETWEEN ERRORS AT X1 AND X2
453       // * *** FIELD GRADIENT PERPENDICULAR TO    453       // * *** FIELD GRADIENT PERPENDICULAR TO TRACK IS PRESENTLY NOT
454       // * *** TAKEN INTO ACCOUNT                 454       // * *** TAKEN INTO ACCOUNT
455                                                   455 
456       G4double QP = QAver * pAver;  // = -HAve    456       G4double QP = QAver * pAver;  // = -HAver
457 #ifdef G4EVERBOSE                                 457 #ifdef G4EVERBOSE
458       if(iverbose >= 2)                           458       if(iverbose >= 2)
459         G4cout << " G4EP: QP " << QP << " QAve    459         G4cout << " G4EP: QP " << QP << " QAver " << QAver << " pAver " << pAver
460                << G4endl;                         460                << G4endl;
461 #endif                                            461 #endif
462       G4double ANV =                              462       G4double ANV =
463         -(vHAverNorm.x() * vUPost.x() + vHAver    463         -(vHAverNorm.x() * vUPost.x() + vHAverNorm.y() * vUPost.y());
464       G4double ANU =                              464       G4double ANU =
465         (vHAverNorm.x() * vVPost.x() + vHAverN    465         (vHAverNorm.x() * vVPost.x() + vHAverNorm.y() * vVPost.y() +
466          vHAverNorm.z() * vVPost.z());            466          vHAverNorm.z() * vVPost.z());
467       G4double OMcosThetaAver = 1. - cosThetaA    467       G4double OMcosThetaAver = 1. - cosThetaAver;
468 #ifdef G4EVERBOSE                                 468 #ifdef G4EVERBOSE
469       if(iverbose >= 2)                           469       if(iverbose >= 2)
470         G4cout << "G4EP: OMcosThetaAver " << O    470         G4cout << "G4EP: OMcosThetaAver " << OMcosThetaAver << " cosThetaAver "
471                << cosThetaAver << " thetaAver     471                << cosThetaAver << " thetaAver " << thetaAver << " QAver "
472                << QAver << " stepLengthCm " <<    472                << QAver << " stepLengthCm " << stepLengthCm << G4endl;
473 #endif                                            473 #endif
474       G4double TMSINT = thetaAver - sinThetaAv    474       G4double TMSINT = thetaAver - sinThetaAver;
475 #ifdef G4EVERBOSE                                 475 #ifdef G4EVERBOSE
476       if(iverbose >= 2)                           476       if(iverbose >= 2)
477         G4cout << " G4EP: ANV " << ANV << " AN    477         G4cout << " G4EP: ANV " << ANV << " ANU " << ANU << G4endl;
478 #endif                                            478 #endif
479                                                   479 
480       G4ThreeVector vHUPre(                       480       G4ThreeVector vHUPre(
481         -vHAverNorm.z() * vUPre.y(), vHAverNor    481         -vHAverNorm.z() * vUPre.y(), vHAverNorm.z() * vUPre.x(),
482         vHAverNorm.x() * vUPre.y() - vHAverNor    482         vHAverNorm.x() * vUPre.y() - vHAverNorm.y() * vUPre.x());
483 #ifdef G4EVERBOSE                                 483 #ifdef G4EVERBOSE
484       //    if( iverbose >= 2 ) G4cout << "G4E    484       //    if( iverbose >= 2 ) G4cout << "G4EP: HUPre(1) " << vHUPre.x() << " "
485       //    << vHAverNorm.z() << " " << vUPre.    485       //    << vHAverNorm.z() << " " << vUPre.y() << G4endl;
486 #endif                                            486 #endif
487       G4ThreeVector vHVPre(                       487       G4ThreeVector vHVPre(
488         vHAverNorm.y() * vVPre.z() - vHAverNor    488         vHAverNorm.y() * vVPre.z() - vHAverNorm.z() * vVPre.y(),
489         vHAverNorm.z() * vVPre.x() - vHAverNor    489         vHAverNorm.z() * vVPre.x() - vHAverNorm.x() * vVPre.z(),
490         vHAverNorm.x() * vVPre.y() - vHAverNor    490         vHAverNorm.x() * vVPre.y() - vHAverNorm.y() * vVPre.x());
491 #ifdef G4EVERBOSE                                 491 #ifdef G4EVERBOSE
492       if(iverbose >= 2)                           492       if(iverbose >= 2)
493         G4cout << " G4EP: HUPre " << vHUPre <<    493         G4cout << " G4EP: HUPre " << vHUPre << " HVPre " << vHVPre << G4endl;
494 #endif                                            494 #endif
495                                                   495 
496       //------------------- COMPUTE MATRIX        496       //------------------- COMPUTE MATRIX
497       //---------- 1/P                            497       //---------- 1/P
498                                                   498 
499       transf[0][0] =                              499       transf[0][0] =
500         1. -                                      500         1. -
501         deltaPInv * pAver *                       501         deltaPInv * pAver *
502           (1. + (vpPostNorm.x() * deltaPos.x()    502           (1. + (vpPostNorm.x() * deltaPos.x() + vpPostNorm.y() * deltaPos.y() +
503                  vpPostNorm.z() * deltaPos.z()    503                  vpPostNorm.z() * deltaPos.z()) /
504                   stepLengthCm) +                 504                   stepLengthCm) +
505         2. * deltaPInv * pAver;                   505         2. * deltaPInv * pAver;
506                                                   506 
507       transf[0][1] =                              507       transf[0][1] =
508         -deltaPInv / thetaAver *                  508         -deltaPInv / thetaAver *
509         (TMSINT * gamma *                         509         (TMSINT * gamma *
510            (vHAverNorm.x() * vVPre.x() + vHAve    510            (vHAverNorm.x() * vVPre.x() + vHAverNorm.y() * vVPre.y() +
511             vHAverNorm.z() * vVPre.z()) +         511             vHAverNorm.z() * vVPre.z()) +
512          sinThetaAver *                           512          sinThetaAver *
513            (vVPre.x() * vpPostNorm.x() + vVPre    513            (vVPre.x() * vpPostNorm.x() + vVPre.y() * vpPostNorm.y() +
514             vVPre.z() * vpPostNorm.z()) +         514             vVPre.z() * vpPostNorm.z()) +
515          OMcosThetaAver *                         515          OMcosThetaAver *
516            (vHVPre.x() * vpPostNorm.x() + vHVP    516            (vHVPre.x() * vpPostNorm.x() + vHVPre.y() * vpPostNorm.y() +
517             vHVPre.z() * vpPostNorm.z()));        517             vHVPre.z() * vpPostNorm.z()));
518                                                   518 
519       transf[0][2] =                              519       transf[0][2] =
520         -sinpPre * deltaPInv / thetaAver *        520         -sinpPre * deltaPInv / thetaAver *
521         (TMSINT * gamma *                         521         (TMSINT * gamma *
522            (vHAverNorm.x() * vUPre.x() + vHAve    522            (vHAverNorm.x() * vUPre.x() + vHAverNorm.y() * vUPre.y()) +
523          sinThetaAver *                           523          sinThetaAver *
524            (vUPre.x() * vpPostNorm.x() + vUPre    524            (vUPre.x() * vpPostNorm.x() + vUPre.y() * vpPostNorm.y()) +
525          OMcosThetaAver *                         525          OMcosThetaAver *
526            (vHUPre.x() * vpPostNorm.x() + vHUP    526            (vHUPre.x() * vpPostNorm.x() + vHUPre.y() * vpPostNorm.y() +
527             vHUPre.z() * vpPostNorm.z()));        527             vHUPre.z() * vpPostNorm.z()));
528                                                   528 
529       transf[0][3] = -deltaPInv / stepLengthCm    529       transf[0][3] = -deltaPInv / stepLengthCm *
530                      (vUPre.x() * vpPostNorm.x    530                      (vUPre.x() * vpPostNorm.x() + vUPre.y() * vpPostNorm.y());
531                                                   531 
532       transf[0][4] = -deltaPInv / stepLengthCm    532       transf[0][4] = -deltaPInv / stepLengthCm *
533                      (vVPre.x() * vpPostNorm.x    533                      (vVPre.x() * vpPostNorm.x() + vVPre.y() * vpPostNorm.y() +
534                       vVPre.z() * vpPostNorm.z    534                       vVPre.z() * vpPostNorm.z());
535                                                   535 
536       // ***   Lambda                             536       // ***   Lambda
537       transf[1][0] =                              537       transf[1][0] =
538         -QP * ANV *                               538         -QP * ANV *
539         (vpPostNorm.x() * deltaPos.x() + vpPos    539         (vpPostNorm.x() * deltaPos.x() + vpPostNorm.y() * deltaPos.y() +
540          vpPostNorm.z() * deltaPos.z()) *         540          vpPostNorm.z() * deltaPos.z()) *
541         (1. + deltaPInv * pAver);                 541         (1. + deltaPInv * pAver);
542 #ifdef G4EVERBOSE                                 542 #ifdef G4EVERBOSE
543       if(iverbose >= 3)                           543       if(iverbose >= 3)
544         G4cout << "ctransf10= " << transf[1][0    544         G4cout << "ctransf10= " << transf[1][0] << " " << -QP << " " << ANV
545                << " " << vpPostNorm.x() << " "    545                << " " << vpPostNorm.x() << " " << deltaPos.x() << " "
546                << vpPostNorm.y() << " " << del    546                << vpPostNorm.y() << " " << deltaPos.y() << " " << vpPostNorm.z()
547                << " " << deltaPos.z() << " " <    547                << " " << deltaPos.z() << " " << deltaPInv << " " << pAver
548                << G4endl;                         548                << G4endl;
549 #endif                                            549 #endif
550                                                   550 
551       transf[1][1] =                              551       transf[1][1] =
552         cosThetaAver * (vVPre.x() * vVPost.x()    552         cosThetaAver * (vVPre.x() * vVPost.x() + vVPre.y() * vVPost.y() +
553                         vVPre.z() * vVPost.z()    553                         vVPre.z() * vVPost.z()) +
554         sinThetaAver * (vHVPre.x() * vVPost.x(    554         sinThetaAver * (vHVPre.x() * vVPost.x() + vHVPre.y() * vVPost.y() +
555                         vHVPre.z() * vVPost.z(    555                         vHVPre.z() * vVPost.z()) +
556         OMcosThetaAver *                          556         OMcosThetaAver *
557           (vHAverNorm.x() * vVPre.x() + vHAver    557           (vHAverNorm.x() * vVPre.x() + vHAverNorm.y() * vVPre.y() +
558            vHAverNorm.z() * vVPre.z()) *          558            vHAverNorm.z() * vVPre.z()) *
559           (vHAverNorm.x() * vVPost.x() + vHAve    559           (vHAverNorm.x() * vVPost.x() + vHAverNorm.y() * vVPost.y() +
560            vHAverNorm.z() * vVPost.z()) +         560            vHAverNorm.z() * vVPost.z()) +
561         ANV * (-sinThetaAver *                    561         ANV * (-sinThetaAver *
562                  (vVPre.x() * vpPostNorm.x() +    562                  (vVPre.x() * vpPostNorm.x() + vVPre.y() * vpPostNorm.y() +
563                   vVPre.z() * vpPostNorm.z())     563                   vVPre.z() * vpPostNorm.z()) +
564                OMcosThetaAver * (vVPre.x() * A    564                OMcosThetaAver * (vVPre.x() * AN2.x() + vVPre.y() * AN2.y() +
565                                  vVPre.z() * A    565                                  vVPre.z() * AN2.z()) -
566                TMSINT * gamma *                   566                TMSINT * gamma *
567                  (vHAverNorm.x() * vVPre.x() +    567                  (vHAverNorm.x() * vVPre.x() + vHAverNorm.y() * vVPre.y() +
568                   vHAverNorm.z() * vVPre.z()))    568                   vHAverNorm.z() * vVPre.z()));
569                                                   569 
570       transf[1][2] =                              570       transf[1][2] =
571         cosThetaAver * (vUPre.x() * vVPost.x()    571         cosThetaAver * (vUPre.x() * vVPost.x() + vUPre.y() * vVPost.y()) +
572         sinThetaAver * (vHUPre.x() * vVPost.x(    572         sinThetaAver * (vHUPre.x() * vVPost.x() + vHUPre.y() * vVPost.y() +
573                         vHUPre.z() * vVPost.z(    573                         vHUPre.z() * vVPost.z()) +
574         OMcosThetaAver *                          574         OMcosThetaAver *
575           (vHAverNorm.x() * vUPre.x() + vHAver    575           (vHAverNorm.x() * vUPre.x() + vHAverNorm.y() * vUPre.y()) *
576           (vHAverNorm.x() * vVPost.x() + vHAve    576           (vHAverNorm.x() * vVPost.x() + vHAverNorm.y() * vVPost.y() +
577            vHAverNorm.z() * vVPost.z()) +         577            vHAverNorm.z() * vVPost.z()) +
578         ANV * (-sinThetaAver *                    578         ANV * (-sinThetaAver *
579                  (vUPre.x() * vpPostNorm.x() +    579                  (vUPre.x() * vpPostNorm.x() + vUPre.y() * vpPostNorm.y()) +
580                OMcosThetaAver * (vUPre.x() * A    580                OMcosThetaAver * (vUPre.x() * AN2.x() + vUPre.y() * AN2.y()) -
581                TMSINT * gamma *                   581                TMSINT * gamma *
582                  (vHAverNorm.x() * vUPre.x() +    582                  (vHAverNorm.x() * vUPre.x() + vHAverNorm.y() * vUPre.y()));
583       transf[1][2] = sinpPre * transf[1][2];      583       transf[1][2] = sinpPre * transf[1][2];
584                                                   584 
585       transf[1][3] = -QAver * ANV *               585       transf[1][3] = -QAver * ANV *
586                      (vUPre.x() * vpPostNorm.x    586                      (vUPre.x() * vpPostNorm.x() + vUPre.y() * vpPostNorm.y());
587                                                   587 
588       transf[1][4] = -QAver * ANV *               588       transf[1][4] = -QAver * ANV *
589                      (vVPre.x() * vpPostNorm.x    589                      (vVPre.x() * vpPostNorm.x() + vVPre.y() * vpPostNorm.y() +
590                       vVPre.z() * vpPostNorm.z    590                       vVPre.z() * vpPostNorm.z());
591                                                   591 
592       // ***   Phi                                592       // ***   Phi
593                                                   593 
594       transf[2][0] =                              594       transf[2][0] =
595         -QP * ANU *                               595         -QP * ANU *
596         (vpPostNorm.x() * deltaPos.x() + vpPos    596         (vpPostNorm.x() * deltaPos.x() + vpPostNorm.y() * deltaPos.y() +
597          vpPostNorm.z() * deltaPos.z()) *         597          vpPostNorm.z() * deltaPos.z()) *
598         sinpPostInv * (1. + deltaPInv * pAver)    598         sinpPostInv * (1. + deltaPInv * pAver);
599 #ifdef G4EVERBOSE                                 599 #ifdef G4EVERBOSE
600       if(iverbose >= 3)                           600       if(iverbose >= 3)
601         G4cout << "ctransf20= " << transf[2][0    601         G4cout << "ctransf20= " << transf[2][0] << " " << -QP << " " << ANU
602                << " " << vpPostNorm.x() << " "    602                << " " << vpPostNorm.x() << " " << deltaPos.x() << " "
603                << vpPostNorm.y() << " " << del    603                << vpPostNorm.y() << " " << deltaPos.y() << " " << vpPostNorm.z()
604                << " " << deltaPos.z() << " " <    604                << " " << deltaPos.z() << " " << sinpPostInv << " " << deltaPInv
605                << " " << pAver << G4endl;         605                << " " << pAver << G4endl;
606 #endif                                            606 #endif
607       transf[2][1] =                              607       transf[2][1] =
608         cosThetaAver * (vVPre.x() * vUPost.x()    608         cosThetaAver * (vVPre.x() * vUPost.x() + vVPre.y() * vUPost.y()) +
609         sinThetaAver * (vHVPre.x() * vUPost.x(    609         sinThetaAver * (vHVPre.x() * vUPost.x() + vHVPre.y() * vUPost.y()) +
610         OMcosThetaAver *                          610         OMcosThetaAver *
611           (vHAverNorm.x() * vVPre.x() + vHAver    611           (vHAverNorm.x() * vVPre.x() + vHAverNorm.y() * vVPre.y() +
612            vHAverNorm.z() * vVPre.z()) *          612            vHAverNorm.z() * vVPre.z()) *
613           (vHAverNorm.x() * vUPost.x() + vHAve    613           (vHAverNorm.x() * vUPost.x() + vHAverNorm.y() * vUPost.y()) +
614         ANU * (-sinThetaAver *                    614         ANU * (-sinThetaAver *
615                  (vVPre.x() * vpPostNorm.x() +    615                  (vVPre.x() * vpPostNorm.x() + vVPre.y() * vpPostNorm.y() +
616                   vVPre.z() * vpPostNorm.z())     616                   vVPre.z() * vpPostNorm.z()) +
617                OMcosThetaAver * (vVPre.x() * A    617                OMcosThetaAver * (vVPre.x() * AN2.x() + vVPre.y() * AN2.y() +
618                                  vVPre.z() * A    618                                  vVPre.z() * AN2.z()) -
619                TMSINT * gamma *                   619                TMSINT * gamma *
620                  (vHAverNorm.x() * vVPre.x() +    620                  (vHAverNorm.x() * vVPre.x() + vHAverNorm.y() * vVPre.y() +
621                   vHAverNorm.z() * vVPre.z()))    621                   vHAverNorm.z() * vVPre.z()));
622       transf[2][1] = sinpPostInv * transf[2][1    622       transf[2][1] = sinpPostInv * transf[2][1];
623                                                   623 
624       transf[2][2] =                              624       transf[2][2] =
625         cosThetaAver * (vUPre.x() * vUPost.x()    625         cosThetaAver * (vUPre.x() * vUPost.x() + vUPre.y() * vUPost.y()) +
626         sinThetaAver * (vHUPre.x() * vUPost.x(    626         sinThetaAver * (vHUPre.x() * vUPost.x() + vHUPre.y() * vUPost.y()) +
627         OMcosThetaAver *                          627         OMcosThetaAver *
628           (vHAverNorm.x() * vUPre.x() + vHAver    628           (vHAverNorm.x() * vUPre.x() + vHAverNorm.y() * vUPre.y()) *
629           (vHAverNorm.x() * vUPost.x() + vHAve    629           (vHAverNorm.x() * vUPost.x() + vHAverNorm.y() * vUPost.y()) +
630         ANU * (-sinThetaAver *                    630         ANU * (-sinThetaAver *
631                  (vUPre.x() * vpPostNorm.x() +    631                  (vUPre.x() * vpPostNorm.x() + vUPre.y() * vpPostNorm.y()) +
632                OMcosThetaAver * (vUPre.x() * A    632                OMcosThetaAver * (vUPre.x() * AN2.x() + vUPre.y() * AN2.y()) -
633                TMSINT * gamma *                   633                TMSINT * gamma *
634                  (vHAverNorm.x() * vUPre.x() +    634                  (vHAverNorm.x() * vUPre.x() + vHAverNorm.y() * vUPre.y()));
635       transf[2][2] = sinpPostInv * sinpPre * t    635       transf[2][2] = sinpPostInv * sinpPre * transf[2][2];
636                                                   636 
637       transf[2][3] = -QAver * ANU *               637       transf[2][3] = -QAver * ANU *
638                      (vUPre.x() * vpPostNorm.x    638                      (vUPre.x() * vpPostNorm.x() + vUPre.y() * vpPostNorm.y()) *
639                      sinpPostInv;                 639                      sinpPostInv;
640 #ifdef G4EVERBOSE                                 640 #ifdef G4EVERBOSE
641       if(iverbose >= 3)                           641       if(iverbose >= 3)
642         G4cout << "ctransf23= " << transf[2][3    642         G4cout << "ctransf23= " << transf[2][3] << " " << -QAver << " " << ANU
643                << " " << vUPre.x() << " " << v    643                << " " << vUPre.x() << " " << vpPostNorm.x() << " " << vUPre.y()
644                << " " << vpPostNorm.y() << " "    644                << " " << vpPostNorm.y() << " " << sinpPostInv << G4endl;
645 #endif                                            645 #endif
646                                                   646 
647       transf[2][4] = -QAver * ANU *               647       transf[2][4] = -QAver * ANU *
648                      (vVPre.x() * vpPostNorm.x    648                      (vVPre.x() * vpPostNorm.x() + vVPre.y() * vpPostNorm.y() +
649                       vVPre.z() * vpPostNorm.z    649                       vVPre.z() * vpPostNorm.z()) *
650                      sinpPostInv;                 650                      sinpPostInv;
651                                                   651 
652       // ***   Yt                                 652       // ***   Yt
653                                                   653 
654       transf[3][0] = pAver *                      654       transf[3][0] = pAver *
655                      (vUPost.x() * deltaPos.x(    655                      (vUPost.x() * deltaPos.x() + vUPost.y() * deltaPos.y()) *
656                      (1. + deltaPInv * pAver);    656                      (1. + deltaPInv * pAver);
657 #ifdef G4EVERBOSE                                 657 #ifdef G4EVERBOSE
658       if(iverbose >= 3)                           658       if(iverbose >= 3)
659         G4cout << "ctransf30= " << transf[3][0    659         G4cout << "ctransf30= " << transf[3][0] << " " << pAver << " "
660                << vUPost.x() << " " << deltaPo    660                << vUPost.x() << " " << deltaPos.x() << " " << vUPost.y() << " "
661                << deltaPos.y() << " " << delta    661                << deltaPos.y() << " " << deltaPInv << " " << pAver << G4endl;
662 #endif                                            662 #endif
663                                                   663 
664       transf[3][1] =                              664       transf[3][1] =
665         (sinThetaAver * (vVPre.x() * vUPost.x(    665         (sinThetaAver * (vVPre.x() * vUPost.x() + vVPre.y() * vUPost.y()) +
666          OMcosThetaAver * (vHVPre.x() * vUPost    666          OMcosThetaAver * (vHVPre.x() * vUPost.x() + vHVPre.y() * vUPost.y()) +
667          TMSINT * (vHAverNorm.x() * vUPost.x()    667          TMSINT * (vHAverNorm.x() * vUPost.x() + vHAverNorm.y() * vUPost.y()) *
668            (vHAverNorm.x() * vVPre.x() + vHAve    668            (vHAverNorm.x() * vVPre.x() + vHAverNorm.y() * vVPre.y() +
669             vHAverNorm.z() * vVPre.z())) /        669             vHAverNorm.z() * vVPre.z())) /
670         QAver;                                    670         QAver;
671                                                   671 
672       transf[3][2] =                              672       transf[3][2] =
673         (sinThetaAver * (vUPre.x() * vUPost.x(    673         (sinThetaAver * (vUPre.x() * vUPost.x() + vUPre.y() * vUPost.y()) +
674          OMcosThetaAver * (vHUPre.x() * vUPost    674          OMcosThetaAver * (vHUPre.x() * vUPost.x() + vHUPre.y() * vUPost.y()) +
675          TMSINT * (vHAverNorm.x() * vUPost.x()    675          TMSINT * (vHAverNorm.x() * vUPost.x() + vHAverNorm.y() * vUPost.y()) *
676            (vHAverNorm.x() * vUPre.x() + vHAve    676            (vHAverNorm.x() * vUPre.x() + vHAverNorm.y() * vUPre.y())) *
677         sinpPre / QAver;                          677         sinpPre / QAver;
678 #ifdef G4EVERBOSE                                 678 #ifdef G4EVERBOSE
679       if(iverbose >= 3)                           679       if(iverbose >= 3)
680         G4cout << "ctransf32= " << transf[3][2    680         G4cout << "ctransf32= " << transf[3][2] << " " << sinThetaAver << " "
681                << vUPre.x() << " " << vUPost.x    681                << vUPre.x() << " " << vUPost.x() << " " << vUPre.y() << " "
682                << vUPost.y() << " " << OMcosTh    682                << vUPost.y() << " " << OMcosThetaAver << " " << vHUPre.x()
683                << " " << vUPost.x() << " " <<     683                << " " << vUPost.x() << " " << vHUPre.y() << " " << vUPost.y()
684                << " " << TMSINT << " " << vHAv    684                << " " << TMSINT << " " << vHAverNorm.x() << " " << vUPost.x()
685                << " " << vHAverNorm.y() << " "    685                << " " << vHAverNorm.y() << " " << vUPost.y() << " "
686                << vHAverNorm.x() << " " << vUP    686                << vHAverNorm.x() << " " << vUPre.x() << " " << vHAverNorm.y()
687                << " " << vUPre.y() << " " << s    687                << " " << vUPre.y() << " " << sinpPre << " " << QAver << G4endl;
688 #endif                                            688 #endif
689                                                   689 
690       transf[3][3] = (vUPre.x() * vUPost.x() +    690       transf[3][3] = (vUPre.x() * vUPost.x() + vUPre.y() * vUPost.y());
691                                                   691 
692       transf[3][4] = (vVPre.x() * vUPost.x() +    692       transf[3][4] = (vVPre.x() * vUPost.x() + vVPre.y() * vUPost.y());
693                                                   693 
694       // ***   Zt                                 694       // ***   Zt
695       transf[4][0] = pAver *                      695       transf[4][0] = pAver *
696                      (vVPost.x() * deltaPos.x(    696                      (vVPost.x() * deltaPos.x() + vVPost.y() * deltaPos.y() +
697                       vVPost.z() * deltaPos.z(    697                       vVPost.z() * deltaPos.z()) *
698                      (1. + deltaPInv * pAver);    698                      (1. + deltaPInv * pAver);
699                                                   699 
700       transf[4][1] =                              700       transf[4][1] =
701         (sinThetaAver * (vVPre.x() * vVPost.x(    701         (sinThetaAver * (vVPre.x() * vVPost.x() + vVPre.y() * vVPost.y() +
702                          vVPre.z() * vVPost.z(    702                          vVPre.z() * vVPost.z()) +
703          OMcosThetaAver * (vHVPre.x() * vVPost    703          OMcosThetaAver * (vHVPre.x() * vVPost.x() + vHVPre.y() * vVPost.y() +
704                            vHVPre.z() * vVPost    704                            vHVPre.z() * vVPost.z()) +
705          TMSINT *                                 705          TMSINT *
706            (vHAverNorm.x() * vVPost.x() + vHAv    706            (vHAverNorm.x() * vVPost.x() + vHAverNorm.y() * vVPost.y() +
707             vHAverNorm.z() * vVPost.z()) *        707             vHAverNorm.z() * vVPost.z()) *
708            (vHAverNorm.x() * vVPre.x() + vHAve    708            (vHAverNorm.x() * vVPre.x() + vHAverNorm.y() * vVPre.y() +
709             vHAverNorm.z() * vVPre.z())) /        709             vHAverNorm.z() * vVPre.z())) /
710         QAver;                                    710         QAver;
711 #ifdef G4EVERBOSE                                 711 #ifdef G4EVERBOSE
712       if(iverbose >= 3)                           712       if(iverbose >= 3)
713         G4cout << "ctransf41= " << transf[4][1    713         G4cout << "ctransf41= " << transf[4][1] << " " << sinThetaAver << " "
714                << OMcosThetaAver << " " << TMS    714                << OMcosThetaAver << " " << TMSINT << " " << vVPre << " "
715                << vVPost << " " << vHVPre << "    715                << vVPost << " " << vHVPre << " " << vHAverNorm << " " << QAver
716                << G4endl;                         716                << G4endl;
717 #endif                                            717 #endif
718                                                   718 
719       transf[4][2] =                              719       transf[4][2] =
720         (sinThetaAver * (vUPre.x() * vVPost.x(    720         (sinThetaAver * (vUPre.x() * vVPost.x() + vUPre.y() * vVPost.y()) +
721          OMcosThetaAver * (vHUPre.x() * vVPost    721          OMcosThetaAver * (vHUPre.x() * vVPost.x() + vHUPre.y() * vVPost.y() +
722                            vHUPre.z() * vVPost    722                            vHUPre.z() * vVPost.z()) +
723          TMSINT *                                 723          TMSINT *
724            (vHAverNorm.x() * vVPost.x() + vHAv    724            (vHAverNorm.x() * vVPost.x() + vHAverNorm.y() * vVPost.y() +
725             vHAverNorm.z() * vVPost.z()) *        725             vHAverNorm.z() * vVPost.z()) *
726            (vHAverNorm.x() * vUPre.x() + vHAve    726            (vHAverNorm.x() * vUPre.x() + vHAverNorm.y() * vUPre.y())) *
727         sinpPre / QAver;                          727         sinpPre / QAver;
728                                                   728 
729       transf[4][3] = (vUPre.x() * vVPost.x() +    729       transf[4][3] = (vUPre.x() * vVPost.x() + vUPre.y() * vVPost.y());
730                                                   730 
731       transf[4][4] = (vVPre.x() * vVPost.x() +    731       transf[4][4] = (vVPre.x() * vVPost.x() + vVPre.y() * vVPost.y() +
732                       vVPre.z() * vVPost.z());    732                       vVPre.z() * vVPost.z());
733       //   if(iverbose >= 3) G4cout <<"ctransf    733       //   if(iverbose >= 3) G4cout <<"ctransf44= " << transf[4][4] <<" "<<
734       //   vVPre.x()  <<" "<<vVPost.x() <<" "<    734       //   vVPre.x()  <<" "<<vVPost.x() <<" "<< vVPre.y() <<" "<< vVPost.y() <<"
735       //   "<< vVPre.z() <<" "<< vVPost.z() <<    735       //   "<< vVPre.z() <<" "<< vVPost.z() << G4endl;
736                                                   736 
737 #ifdef G4EVERBOSE                                 737 #ifdef G4EVERBOSE
738       if(iverbose >= 1)                           738       if(iverbose >= 1)
739         G4cout << "G4EP: transf matrix compute    739         G4cout << "G4EP: transf matrix computed " << transf << G4endl;
740 #endif                                            740 #endif
741       /*    for( G4int ii=0;ii<5;ii++){           741       /*    for( G4int ii=0;ii<5;ii++){
742         for( G4int jj=0;jj<5;jj++){               742         for( G4int jj=0;jj<5;jj++){
743           G4cout << transf[ii][jj] << " ";        743           G4cout << transf[ii][jj] << " ";
744         }                                         744         }
745         G4cout << G4endl;                         745         G4cout << G4endl;
746         } */                                      746         } */
747     }                                             747     }
748   }                                               748   }
749   // end of calculate transformation except it    749   // end of calculate transformation except it NEUTRAL PARTICLE OR FIELDFREE
750   // REGION                                       750   // REGION
751   /*  if( iverbose >= 1 ) G4cout << "G4EP: tra    751   /*  if( iverbose >= 1 ) G4cout << "G4EP: transf not updated but initialized "
752   << theFirstStep << G4endl; if( theFirstStep     752   << theFirstStep << G4endl; if( theFirstStep ) { theTransfMat = transf;
753     theFirstStep = false;                         753     theFirstStep = false;
754   }else{                                          754   }else{
755     theTransfMat = theTransfMat * transf;         755     theTransfMat = theTransfMat * transf;
756     if( iverbose >= 1 ) G4cout << "G4EP: trans    756     if( iverbose >= 1 ) G4cout << "G4EP: transf matrix accumulated" <<
757   theTransfMat << G4endl;                         757   theTransfMat << G4endl;
758   }                                               758   }
759   */                                              759   */
760   theTransfMat = std::move(transf);            << 760   theTransfMat = transf;
761 #ifdef G4EVERBOSE                                 761 #ifdef G4EVERBOSE
762   if(iverbose >= 1)                               762   if(iverbose >= 1)
763     G4cout << "G4EP: error matrix before trans    763     G4cout << "G4EP: error matrix before transformation " << fError << G4endl;
764   if(iverbose >= 2)                               764   if(iverbose >= 2)
765     G4cout << " tf * err " << theTransfMat * f    765     G4cout << " tf * err " << theTransfMat * fError << G4endl
766            << " transf matrix " << theTransfMa    766            << " transf matrix " << theTransfMat.T() << G4endl;
767 #endif                                            767 #endif
768                                                   768 
769   fError = fError.similarity(theTransfMat).T()    769   fError = fError.similarity(theTransfMat).T();
770   //-    fError = transf * fError * transf.T()    770   //-    fError = transf * fError * transf.T();
771 #ifdef G4EVERBOSE                                 771 #ifdef G4EVERBOSE
772   if(iverbose >= 1)                               772   if(iverbose >= 1)
773     G4cout << "G4EP: error matrix propagated "    773     G4cout << "G4EP: error matrix propagated " << fError << G4endl;
774 #endif                                            774 #endif
775                                                   775 
776   //? S = B*S*BT S.similarity(B)                  776   //? S = B*S*BT S.similarity(B)
777   //? R = S                                       777   //? R = S
778   // not needed * *** TRANSFORM ERROR MATRIX F    778   // not needed * *** TRANSFORM ERROR MATRIX FROM INTERNAL TO EXTERNAL
779   // VARIABLES;                                   779   // VARIABLES;
780                                                   780 
781   PropagateErrorMSC(aTrack);                      781   PropagateErrorMSC(aTrack);
782                                                   782 
783   PropagateErrorIoni(aTrack);                     783   PropagateErrorIoni(aTrack);
784                                                   784 
785   return 0;                                       785   return 0;
786 }                                                 786 }
787                                                   787 
788 //--------------------------------------------    788 //------------------------------------------------------------------------
789 G4int G4ErrorFreeTrajState::PropagateErrorMSC(    789 G4int G4ErrorFreeTrajState::PropagateErrorMSC(const G4Track* aTrack)
790 {                                                 790 {
791   G4ThreeVector vpPre   = aTrack->GetMomentum(    791   G4ThreeVector vpPre   = aTrack->GetMomentum() / GeV;
792   G4double pPre         = vpPre.mag();            792   G4double pPre         = vpPre.mag();
793   G4double pBeta        = pPre * pPre / (aTrac    793   G4double pBeta        = pPre * pPre / (aTrack->GetTotalEnergy() / GeV);
794   G4double stepLengthCm = aTrack->GetStep()->G    794   G4double stepLengthCm = aTrack->GetStep()->GetStepLength() / cm;
795                                                   795 
796   G4Material* mate = aTrack->GetVolume()->GetL    796   G4Material* mate = aTrack->GetVolume()->GetLogicalVolume()->GetMaterial();
797   G4double effZ, effA;                            797   G4double effZ, effA;
798   CalculateEffectiveZandA(mate, effZ, effA);      798   CalculateEffectiveZandA(mate, effZ, effA);
799                                                   799 
800 #ifdef G4EVERBOSE                                 800 #ifdef G4EVERBOSE
801   if(iverbose >= 4)                               801   if(iverbose >= 4)
802     G4cout << "material "                         802     G4cout << "material "
803            << mate->GetName()                     803            << mate->GetName()
804            //<< " " << mate->GetZ() << " "  <<    804            //<< " " << mate->GetZ() << " "  << mate->GetA()
805            << " effZ:" << effZ << " effA:" <<     805            << " effZ:" << effZ << " effA:" << effA
806            << " dens(g/mole):" << mate->GetDen    806            << " dens(g/mole):" << mate->GetDensity() / g * mole
807            << " Radlen/cm:" << mate->GetRadlen    807            << " Radlen/cm:" << mate->GetRadlen() / cm << " nuclLen/cm"
808            << mate->GetNuclearInterLength() /     808            << mate->GetNuclearInterLength() / cm << G4endl;
809 #endif                                            809 #endif
810                                                   810 
811   G4double RI = stepLengthCm / (mate->GetRadle    811   G4double RI = stepLengthCm / (mate->GetRadlen() / cm);
812 #ifdef G4EVERBOSE                                 812 #ifdef G4EVERBOSE
813   if(iverbose >= 4)                               813   if(iverbose >= 4)
814     G4cout << std::setprecision(6) << std::set    814     G4cout << std::setprecision(6) << std::setw(6) << "G4EP:MSC: RI=X/X0 " << RI
815            << " stepLengthCm " << stepLengthCm    815            << " stepLengthCm " << stepLengthCm << " radlen/cm "
816            << (mate->GetRadlen() / cm) << " RI    816            << (mate->GetRadlen() / cm) << " RI*1.e10:" << RI * 1.e10 << G4endl;
817 #endif                                            817 #endif
818   G4double charge = aTrack->GetDynamicParticle    818   G4double charge = aTrack->GetDynamicParticle()->GetCharge();
819   G4double DD     = 1.8496E-4 * RI * (charge /    819   G4double DD     = 1.8496E-4 * RI * (charge / pBeta * charge / pBeta);
820 #ifdef G4EVERBOSE                                 820 #ifdef G4EVERBOSE
821   if(iverbose >= 3)                               821   if(iverbose >= 3)
822     G4cout << "G4EP:MSC: D*1E6= " << DD * 1.E6    822     G4cout << "G4EP:MSC: D*1E6= " << DD * 1.E6 << " pBeta " << pBeta << G4endl;
823 #endif                                            823 #endif
824   G4double S1 = DD * stepLengthCm * stepLength    824   G4double S1 = DD * stepLengthCm * stepLengthCm / 3.;
825   G4double S2 = DD;                               825   G4double S2 = DD;
826   G4double S3 = DD * stepLengthCm / 2.;           826   G4double S3 = DD * stepLengthCm / 2.;
827                                                   827 
828   G4double CLA =                                  828   G4double CLA =
829     std::sqrt(vpPre.x() * vpPre.x() + vpPre.y(    829     std::sqrt(vpPre.x() * vpPre.x() + vpPre.y() * vpPre.y()) / pPre;
830 #ifdef G4EVERBOSE                                 830 #ifdef G4EVERBOSE
831   if(iverbose >= 2)                               831   if(iverbose >= 2)
832     G4cout << std::setw(6) << "G4EP:MSC: RI "     832     G4cout << std::setw(6) << "G4EP:MSC: RI " << RI << " S1 " << S1 << " S2 "
833            << S2 << " S3 " << S3 << " CLA " <<    833            << S2 << " S3 " << S3 << " CLA " << CLA << G4endl;
834 #endif                                            834 #endif
835   fError[1][1] += S2;                             835   fError[1][1] += S2;
836   fError[1][4] -= S3;                             836   fError[1][4] -= S3;
837   fError[2][2] += S2 / CLA / CLA;                 837   fError[2][2] += S2 / CLA / CLA;
838   fError[2][3] += S3 / CLA;                       838   fError[2][3] += S3 / CLA;
839   fError[3][3] += S1;                             839   fError[3][3] += S1;
840   fError[4][4] += S1;                             840   fError[4][4] += S1;
841                                                   841 
842 #ifdef G4EVERBOSE                                 842 #ifdef G4EVERBOSE
843   if(iverbose >= 2)                               843   if(iverbose >= 2)
844     G4cout << "G4EP:MSC: error matrix propagat    844     G4cout << "G4EP:MSC: error matrix propagated msc " << fError << G4endl;
845 #endif                                            845 #endif
846                                                   846 
847   return 0;                                       847   return 0;
848 }                                                 848 }
849                                                   849 
850 //--------------------------------------------    850 //------------------------------------------------------------------------
851 void G4ErrorFreeTrajState::CalculateEffectiveZ    851 void G4ErrorFreeTrajState::CalculateEffectiveZandA(const G4Material* mate,
852                                                   852                                                    G4double& effZ,
853                                                   853                                                    G4double& effA)
854 {                                                 854 {
855   effZ = 0.;                                      855   effZ = 0.;
856   effA = 0.;                                      856   effA = 0.;
857   auto nelem = mate->GetNumberOfElements();    << 857   G4int ii, nelem = mate->GetNumberOfElements();
858   const G4double* fracVec = mate->GetFractionV    858   const G4double* fracVec = mate->GetFractionVector();
859   for(G4int ii = 0; ii < (G4int)nelem; ++ii)   << 859   for(ii = 0; ii < nelem; ii++)
860   {                                               860   {
861     effZ += mate->GetElement(ii)->GetZ() * fra    861     effZ += mate->GetElement(ii)->GetZ() * fracVec[ii];
862     effA += mate->GetElement(ii)->GetA() * fra    862     effA += mate->GetElement(ii)->GetA() * fracVec[ii] / g * mole;
863   }                                               863   }
864 }                                                 864 }
865                                                   865 
866 //--------------------------------------------    866 //------------------------------------------------------------------------
867 G4int G4ErrorFreeTrajState::PropagateErrorIoni    867 G4int G4ErrorFreeTrajState::PropagateErrorIoni(const G4Track* aTrack)
868 {                                                 868 {
869   G4double stepLengthCm = aTrack->GetStep()->G    869   G4double stepLengthCm = aTrack->GetStep()->GetStepLength() / cm;
870 #ifdef G4EVERBOSE                                 870 #ifdef G4EVERBOSE
871   G4double DEDX2;                                 871   G4double DEDX2;
872   if(stepLengthCm < 1.E-7)                        872   if(stepLengthCm < 1.E-7)
873   {                                               873   {
874     DEDX2 = 0.;                                   874     DEDX2 = 0.;
875   }                                               875   }
876 #endif                                            876 #endif
877   //  *     Calculate xi factor (KeV).            877   //  *     Calculate xi factor (KeV).
878   G4Material* mate = aTrack->GetVolume()->GetL    878   G4Material* mate = aTrack->GetVolume()->GetLogicalVolume()->GetMaterial();
879   G4double effZ, effA;                            879   G4double effZ, effA;
880   CalculateEffectiveZandA(mate, effZ, effA);      880   CalculateEffectiveZandA(mate, effZ, effA);
881                                                   881 
882   G4double Etot  = aTrack->GetTotalEnergy() /     882   G4double Etot  = aTrack->GetTotalEnergy() / GeV;
883   G4double beta  = aTrack->GetMomentum().mag()    883   G4double beta  = aTrack->GetMomentum().mag() / GeV / Etot;
884   G4double mass  = aTrack->GetDynamicParticle(    884   G4double mass  = aTrack->GetDynamicParticle()->GetMass() / GeV;
885   G4double gamma = Etot / mass;                   885   G4double gamma = Etot / mass;
886                                                   886 
887   // *     Calculate xi factor (keV).             887   // *     Calculate xi factor (keV).
888   G4double XI = 153.5 * effZ * stepLengthCm *     888   G4double XI = 153.5 * effZ * stepLengthCm * (mate->GetDensity() / mg * mole) /
889                 (effA * beta * beta);             889                 (effA * beta * beta);
890                                                   890 
891 #ifdef G4EVERBOSE                                 891 #ifdef G4EVERBOSE
892   if(iverbose >= 2)                               892   if(iverbose >= 2)
893   {                                               893   {
894     G4cout << "G4EP:IONI: XI/keV " << XI << "     894     G4cout << "G4EP:IONI: XI/keV " << XI << " beta " << beta << " gamma "
895            << gamma << G4endl;                    895            << gamma << G4endl;
896     G4cout << " density " << (mate->GetDensity    896     G4cout << " density " << (mate->GetDensity() / mg * mole) << " effA "
897            << effA << " step " << stepLengthCm    897            << effA << " step " << stepLengthCm << G4endl;
898   }                                               898   }
899 #endif                                            899 #endif
900   // *     Maximum energy transfer to atomic e    900   // *     Maximum energy transfer to atomic electron (KeV).
901   G4double eta       = beta * gamma;              901   G4double eta       = beta * gamma;
902   G4double etasq     = eta * eta;                 902   G4double etasq     = eta * eta;
903   G4double eMass     = 0.51099906 / GeV;          903   G4double eMass     = 0.51099906 / GeV;
904   G4double massRatio = eMass / mass;              904   G4double massRatio = eMass / mass;
905   G4double F1        = 2 * eMass * etasq;         905   G4double F1        = 2 * eMass * etasq;
906   G4double F2        = 1. + 2. * massRatio * g    906   G4double F2        = 1. + 2. * massRatio * gamma + massRatio * massRatio;
907   G4double Emax      = 1.E+6 * F1 / F2;  // no    907   G4double Emax      = 1.E+6 * F1 / F2;  // now in keV
908                                                   908 
909   //  * *** and now sigma**2  in GeV              909   //  * *** and now sigma**2  in GeV
910   G4double dedxSq =                               910   G4double dedxSq =
911     XI * Emax * (1. - (beta * beta / 2.)) * 1.    911     XI * Emax * (1. - (beta * beta / 2.)) * 1.E-12;  // now in GeV^2
912   /*The above  formula for var(1/p) good for d    912   /*The above  formula for var(1/p) good for dens scatterers. However, for MIPS
913     passing through a gas it leads to overesti    913     passing through a gas it leads to overestimation. Further more for incident
914     electrons the Emax is almost equal to inci    914     electrons the Emax is almost equal to incident energy. This leads  to
915     k=Xi/Emax  as small as e-6  and gradually     915     k=Xi/Emax  as small as e-6  and gradually the cov matrix  explodes.
916                                                   916 
917     http://www2.pv.infn.it/~rotondi/kalman_1.p    917     http://www2.pv.infn.it/~rotondi/kalman_1.pdf
918                                                   918 
919     Since I do not have enough info at the mom    919     Since I do not have enough info at the moment to implement Landau &
920     sub-Landau models for k=Xi/Emax <0.01 I'll    920     sub-Landau models for k=Xi/Emax <0.01 I'll saturate k at this value for now
921   */                                              921   */
922                                                   922 
923   if(XI / Emax < 0.01)                            923   if(XI / Emax < 0.01)
924     dedxSq *=                                     924     dedxSq *=
925       XI / Emax * 100;  // Quench for low Elos    925       XI / Emax * 100;  // Quench for low Elos, see above: newVar=odVar *k/0.01
926                                                   926 
927 #ifdef G4EVERBOSE                                 927 #ifdef G4EVERBOSE
928   if(iverbose >= 2)                               928   if(iverbose >= 2)
929     G4cout << "G4EP:IONI: DEDX^2(GeV^2) " << d    929     G4cout << "G4EP:IONI: DEDX^2(GeV^2) " << dedxSq << " emass/GeV: " << eMass
930            << " Emax/keV: " << Emax << "  k=Xi    930            << " Emax/keV: " << Emax << "  k=Xi/Emax=" << XI / Emax << G4endl;
931                                                   931 
932 #endif                                            932 #endif
933                                                   933 
934   G4double pPre6 =                                934   G4double pPre6 =
935     (aTrack->GetStep()->GetPreStepPoint()->Get    935     (aTrack->GetStep()->GetPreStepPoint()->GetMomentum() / GeV).mag();
936   pPre6 = std::pow(pPre6, 6);                     936   pPre6 = std::pow(pPre6, 6);
937   // Apply it to error                            937   // Apply it to error
938   fError[0][0] += Etot * Etot * dedxSq / pPre6    938   fError[0][0] += Etot * Etot * dedxSq / pPre6;
939 #ifdef G4EVERBOSE                                 939 #ifdef G4EVERBOSE
940   if(iverbose >= 2)                               940   if(iverbose >= 2)
941     G4cout << "G4:IONI Etot/GeV: " << Etot <<     941     G4cout << "G4:IONI Etot/GeV: " << Etot << " err_dedx^2/GeV^2: " << dedxSq
942            << " p^6: " << pPre6 << G4endl;        942            << " p^6: " << pPre6 << G4endl;
943   if(iverbose >= 2)                               943   if(iverbose >= 2)
944     G4cout << "G4EP:IONI: error2_from_ionisati    944     G4cout << "G4EP:IONI: error2_from_ionisation "
945            << (Etot * Etot * dedxSq) / pPre6 <    945            << (Etot * Etot * dedxSq) / pPre6 << G4endl;
946 #endif                                            946 #endif
947                                                   947 
948   return 0;                                       948   return 0;
949 }                                                 949 }
950                                                   950