From 6fc25e428f980c3cccfcf2da71b9119b6eb5bd4c Mon Sep 17 00:00:00 2001
From: Morfouace <pierre.morfouace@cea.fr>
Date: Thu, 29 Sep 2022 15:35:58 +0200
Subject: [PATCH] Updating GladField

---
 NPLib/Detectors/Sofia/GladFieldMap.cxx | 379 ++++++++++++++++---------
 NPLib/Detectors/Sofia/GladFieldMap.h   |  23 +-
 Projects/s455/Analysis.cxx             |   3 +-
 3 files changed, 266 insertions(+), 139 deletions(-)

diff --git a/NPLib/Detectors/Sofia/GladFieldMap.cxx b/NPLib/Detectors/Sofia/GladFieldMap.cxx
index 1e4c737e3..0126bebb8 100644
--- a/NPLib/Detectors/Sofia/GladFieldMap.cxx
+++ b/NPLib/Detectors/Sofia/GladFieldMap.cxx
@@ -30,41 +30,47 @@ using namespace NPUNITS;
 #include <string>
 using namespace std; 
 
-ClassImp(GladFieldMap)
-
-  //////////////////////////////////////////////////////////////////////
-  GladFieldMap::GladFieldMap() {
-
-    m_BrhoScan=NULL;
-    m_min = ROOT::Math::Factory::CreateMinimizer("Minuit2","Migrad");
-    m_func = ROOT::Math::Functor(this,&GladFieldMap::Delta,1);
-    m_min->SetFunction(m_func);
-    m_min->SetPrintLevel(-1);
-    m_bin = 50;
-    m_Scale = -2135./3583.81;
-    m_Z_Glad = 2724.;
-    m_Leff = 2.*m;
-    m_Tilt = 14.*deg;
-
-    m_Zmax = 8.5*m;
-    m_Limit = 1000;
-    m_dt = 0.1*nanosecond;
-    m_x_min=1e6;
-    m_x_max=-1e6;
-    m_y_min=1e6;
-    m_y_max=-1e6;
-    m_z_min=1e6;
-    m_z_max=-1e6;
-
-    m_CentralTheta = 20.*deg;
-    m_X_MWPC3 = -1436.;
-    m_Z_MWPC3 = 8380.;
-    m_Angle_MWPC3 = 20.*deg;
-    m_R_MWPC3 = 4199.; 
-
-    m_InitPos = TVector3(0,0,0);
-    m_InitDir = TVector3(0,0,1);
-  }
+
+ClassImp(GladFieldMap);
+
+//////////////////////////////////////////////////////////////////////
+GladFieldMap::GladFieldMap() {
+
+  m_BrhoScan=NULL;
+  m_Bx.clear();
+  m_By.clear();
+  m_Bz.clear();
+  m_min = ROOT::Math::Factory::CreateMinimizer("Minuit2","Migrad");
+  m_func = ROOT::Math::Functor(this,&GladFieldMap::Delta,1);
+  m_min->SetFunction(m_func);
+  m_min->SetPrintLevel(-1);
+  m_bin = 50;
+  m_Scale = -2135./3583.81;
+  m_Z_Glad = 2724.;
+  m_Leff = 2.*m;
+  m_Tilt = 14.*deg;
+
+  m_Zmax = 8.5*m;
+  m_Limit = 1000;
+  m_dt = 0.1*nanosecond;
+  m_x_min=1e6;
+  m_x_max=-1e6;
+  m_y_min=1e6;
+  m_y_max=-1e6;
+  m_z_min=1e6;
+  m_z_max=-1e6;
+  m_Nx= 0;
+  m_Ny= 0;
+  m_Nz= 0;
+  m_CentralTheta = 20.*deg;
+  m_X_MWPC3 = -1436.;
+  m_Z_MWPC3 = 8380.;
+  m_Angle_MWPC3 = 20.*deg;
+  m_R_MWPC3 = 4199.; 
+
+  m_InitPos = TVector3(0,0,0);
+  m_InitDir = TVector3(0,0,1);
+}
 
 
 
@@ -79,7 +85,7 @@ double GladFieldMap::Delta(const double* parameter){
 
   pos = Propagate(parameter[0], m_InitPos, m_InitDir, false);
   //pos.back().RotateY(-m_Angle_MWPC3+m_Tilt);
-  
+
   diff = pos.back() - m_FinalPos;
   //cout << pos.back().X() << " " << pos.back().Z() << endl;
   return diff.Mag2();
@@ -87,37 +93,37 @@ double GladFieldMap::Delta(const double* parameter){
 
 //////////////////////////////////////////////////////////////////////
 double GladFieldMap::FindBrho(TVector3 Pos_init, TVector3 Dir_init, TVector3 Pos_final){
-    
+
   if(!m_BrhoScan)
-    BrhoScan(6.,11,1);
+    BrhoScan(6.,11,1,TVector3(0,0,0), TVector3(0,0,1));
 
   m_InitPos  = Pos_init;
   m_InitDir  = Dir_init;
   m_FinalPos = Pos_final;
 
-  if(m_FinalPos.X()>-2000){
+  //if(m_FinalPos.X()>-2000){
     m_InitDir = m_InitDir.Unit();
-
-    double param[1];
+    //BrhoScan(6,12,3,m_InitPos, m_InitDir);
+    static double param[1];
     param[0] = m_BrhoScan->Eval(m_FinalPos.X());
-    
-    return param[0];
-    
+
+    //return param[0];
+
     m_min->Clear();
     m_min->SetPrecision(1e-6);
     m_min->SetMaxFunctionCalls(1000);
     m_min->SetLimitedVariable(0,"B",param[0],0.1,6,11);
     m_min->Minimize();
-    
+
     return m_min->X()[0];
-  }
+  //}
 
-  else
-    return -1;
+  //else
+    //return -1;
 }
 
 //////////////////////////////////////////////////////////////////////
-TGraph* GladFieldMap::BrhoScan(double Brho_min, double Brho_max, double Brho_step){
+TGraph* GladFieldMap::BrhoScan(double Brho_min, double Brho_max, double Brho_step, TVector3 pos, TVector3 dir){
   if(m_BrhoScan)
     delete m_BrhoScan;
 
@@ -126,8 +132,8 @@ TGraph* GladFieldMap::BrhoScan(double Brho_min, double Brho_max, double Brho_ste
   m_BrhoScan->Set(size);
 
   unsigned int i=0;
-  TVector3 pos = TVector3(0,0,0);
-  TVector3 dir = TVector3(0,0,1);
+  //TVector3 pos = TVector3(0,0,0);
+  //TVector3 dir = TVector3(0,0,1);
   //pos.RotateY(m_Tilt);
   //dir.RotateY(m_Tilt);
   for(double Brho=Brho_min; Brho<Brho_max; Brho+=Brho_step){
@@ -164,7 +170,7 @@ vector<TVector3> GladFieldMap::Propagate(double Brho, TVector3 Pos, TVector3 Dir
   //Dir.RotateY(m_Tilt);
   static NPL::Particle N("90Zr");
   N.SetBrho(Brho);
-  
+
   // track result
   static std::vector<TVector3> track;
   track.clear();
@@ -183,18 +189,18 @@ vector<TVector3> GladFieldMap::Propagate(double Brho, TVector3 Pos, TVector3 Dir
   /*while(r>m_R_max && count<m_Limit){
     Pos+=(r-m_R_max)/cos(Dir.Theta())*Dir.Unit();
     r = 1.01*sqrt(Pos.X()*Pos.X() + Pos.Z()*Pos.Z());
-  }
+    }
 
-  if(r<=m_R_max){ // success
+    if(r<=m_R_max){ // success
     if(store){
-      //Pos.RotateY(-m_Tilt);
-      track.push_back(Pos);
-      //Pos.RotateY(m_Tilt);
-    }
+  //Pos.RotateY(-m_Tilt);
+  track.push_back(Pos);
+  //Pos.RotateY(m_Tilt);
+  }
   }
   else{
-    cout << "Fail" << endl;
-    return track;
+  cout << "Fail" << endl;
+  return track;
   }*/
 
   static TVector3 xk1, xk2, xk3, xk4;
@@ -202,12 +208,12 @@ vector<TVector3> GladFieldMap::Propagate(double Brho, TVector3 Pos, TVector3 Dir
   static double T, M, E, P;
   static double px, py, pz;
   static TVector3 Imp;
-  
+
   T = N.GetEnergy();
   M = N.Mass();
   E = T + M;
   P = sqrt(T*T + 2*M*T)/c_light;
- 
+
   Dir = Dir.Unit();
 
   px = P*Dir.X();
@@ -267,11 +273,14 @@ void GladFieldMap::func(NPL::Particle& N, TVector3 Pos, TVector3 Imp, TVector3&
   xk.SetY(vy);
   xk.SetZ(vz);
 
-  //vector<double> position = {Pos.X(),Pos.Y(),Pos.Z()};
-  B = InterpolateB(Pos);
+  /*B = InterpolateB(Pos);
   Bx = B[0];
   By = B[1];
-  Bz = B[2];
+  Bz = B[2];*/
+
+  Bx = GetB(Pos,"X");
+  By = GetB(Pos,"Y");
+  Bz = GetB(Pos,"Z");
 
   q = N.GetZ()*eplus;
   pk.SetX(q*(vy*Bz - vz*By));
@@ -307,6 +316,7 @@ TVector3 GladFieldMap::CalculateIntersectionPoint(vector<TVector3> vPos){
 
 //////////////////////////////////////////////////////////////////////
 void GladFieldMap::LoadMap(string filename) {
+
   ifstream ifile(filename.c_str());
   if(!ifile.is_open()){
     cout << "Error: failed to load Glad field map: " << filename << endl;
@@ -315,51 +325,58 @@ void GladFieldMap::LoadMap(string filename) {
 
   cout << "///////// Loading ASCII Glad field map: " << filename << endl;
   double x,y,z,Bx,By,Bz;
+  ifile.precision(6);
+  string symmetry;
+  ifile >> symmetry;
+  ifile >> m_x_min >> m_x_max >> m_Nx;
+  ifile >> m_y_min >> m_y_max >> m_Ny;
+  ifile >> m_z_min >> m_z_max >> m_Nz;
 
   unsigned int count=0;
+  int index = 0;
   //while(!ifile.eof()){
-  for(unsigned int i=0; i<401841; i++){
-    ifile >> x >> y >> z >> Bx >> By >> Bz;
-    if(++count%10000==0)
-      cout << "\r - Loading " << count << " values " << flush;
-
-    x = x*10;
-    y = y*10;
-    z = z*10;
-
-    z = z + x*sin(m_Tilt);
-    z += m_Z_Glad;
-    
-    Bx *= m_Scale;
-    By *= m_Scale;
-    Bz *= m_Scale;
-
-    vector<double> p = {x,y,z};
-    Bx*=tesla;
-    By*=tesla;
-    Bz*=tesla;
-    vector<double> B = {Bx,By,Bz};
-    m_field[p] = B;
-
-    if(x<m_x_min)
-      m_x_min=x;
-    if(y<m_y_min)
-      m_y_min=y;
-    if(z<m_z_min)
-      m_z_min=z;
-    if(x>m_x_max)
-      m_x_max=x;
-    if(y>m_y_max)
-      m_y_max=y;
-    if(z>m_z_max)
-      m_z_max=z;
-
+  //for(unsigned int i=0; i<401841; i++){
+  for(int ix=0; ix<m_Nx; ix++){
+    for(int iy=0; iy<m_Ny; iy++){
+      for(int iz=0; iz<m_Nz; iz++){
+        ifile >> x >> y >> z >> Bx >> By >> Bz;
+        if(++count%10000==0)
+          cout << "\r - Loading " << count << " values " << flush;
+
+        index = ix*m_Ny*m_Nz + iy*m_Nz + iz;
+
+        //cout << x << " " << y << " " << z << " " << Bx << " " << By << " " << Bz << endl;
+          
+        x = x*10;
+        y = y*10;
+        z = z*10;
+
+        z = z + x*sin(m_Tilt);
+        z += m_Z_Glad;
+
+        Bx *= m_Scale;
+        By *= m_Scale;
+        Bz *= m_Scale;
+
+        m_Bx.push_back(Bx*tesla);
+        m_By.push_back(By*tesla);
+        m_Bz.push_back(Bz*tesla);
+
+
+        /*vector<double> p = {x,y,z};
+        Bx*=tesla;
+        By*=tesla;
+        Bz*=tesla;
+        vector<double> B = {Bx,By,Bz};
+        m_field[p] = B;*/
+      }
+    }
   }
 
   m_R_max = m_z_max;
   cout << endl;
   cout << "///////// ASCII file loaded"<< endl;
-  cout << "m_field size= " << m_field.size() << endl;
+  cout << "m_field size= " << m_By.size() << endl;
   cout << "m_x_min= " << m_x_min << endl;
   cout << "m_x_max= " << m_x_max << endl;
   cout << "m_y_min= " << m_y_min << endl;
@@ -367,7 +384,7 @@ void GladFieldMap::LoadMap(string filename) {
   cout << "m_z_min= " << m_z_min << endl;
   cout << "m_z_max= " << m_z_max << endl;
   cout << "/////////"<< endl;
-  
+
   ifile.close();
 }
 
@@ -376,7 +393,7 @@ vector<double> GladFieldMap::InterpolateB(const vector<double>& pos)
 {
   static vector<double> nullv = {0,0,0};
 
-  double x,y,z;
+  static double x,y,z;
   x=pos[0];
   y=pos[1];
   z=pos[2];
@@ -389,48 +406,49 @@ vector<double> GladFieldMap::InterpolateB(const vector<double>& pos)
   if(z<m_z_min || z>m_z_max)
     return nullv;
 
-  double x0 = (double)((int)(x)/m_bin)*m_bin;
+  static double x0,x1,y0,y1,z0,z1;
+  x0 = (double)((int)(x)/m_bin)*m_bin;
   if(x<=x0)
     x0=(double)((int)(x-m_bin)/m_bin)*m_bin; 
 
-  double x1 = (double)((int)(x)/m_bin)*m_bin;
+  x1 = (double)((int)(x)/m_bin)*m_bin;
   if(x>=x1)
     x1=(double)((int)(x+m_bin)/m_bin)*m_bin; 
 
-  double y0 = (double)((int)(y)/m_bin)*m_bin;
+  y0 = (double)((int)(y)/m_bin)*m_bin;
   if(y<=y0)
     y0=(double)((int)(y-m_bin)/m_bin)*m_bin; 
 
-  double y1 = (double)((int)(y)/m_bin)*m_bin;
+  y1 = (double)((int)(y)/m_bin)*m_bin;
   if(y>=y1)
     y1=(double)((int)(y+m_bin)/m_bin)*m_bin; 
 
-  double z0 = (double)((int)(z)/m_bin)*m_bin;
+  z0 = (double)((int)(z)/m_bin)*m_bin;
   if(z<=z0)
     z0=(double)((int)(z-m_bin)/m_bin)*m_bin; 
 
-  double z1 = (double)((int)(z)/m_bin)*m_bin;
+  z1 = (double)((int)(z)/m_bin)*m_bin;
   if(z>=z1)
     z1=(double)((int)(z+m_bin)/m_bin)*m_bin; 
 
   //vector<double> X={xm,ym,zm};
-  vector<double> X000={x0,y0,z0};
-  vector<double> X111={x1,y1,z1};
-  vector<double> X100={x1,y0,z0};
-  vector<double> X010={x0,y1,z0};
-  vector<double> X001={x0,y0,z1};
-  vector<double> X101={x1,y0,z1};
-  vector<double> X011={x0,y1,z1};
-  vector<double> X110={x1,y1,z0};
-
-  vector<double> C000;
-  vector<double> C111;
-  vector<double> C100;
-  vector<double> C010;
-  vector<double> C001;
-  vector<double> C101;
-  vector<double> C011;
-  vector<double> C110;
+  static vector<double> X000; X000={x0,y0,z0};
+  static vector<double> X111; X111={x1,y1,z1};
+  static vector<double> X100; X100={x1,y0,z0};
+  static vector<double> X010; X010={x0,y1,z0};
+  static vector<double> X001; X001={x0,y0,z1};
+  static vector<double> X101; X101={x1,y0,z1};
+  static vector<double> X011; X011={x0,y1,z1};
+  static vector<double> X110; X110={x1,y1,z0};
+
+  static vector<double> C000;
+  static vector<double> C111;
+  static vector<double> C100;
+  static vector<double> C010;
+  static vector<double> C001;
+  static vector<double> C101;
+  static vector<double> C011;
+  static vector<double> C110;
 
   if(m_field.lower_bound(X000)!=m_field.end())
     C000=m_field.lower_bound(X000)->second;
@@ -493,16 +511,109 @@ vector<double> GladFieldMap::InterpolateB(const vector<double>& pos)
 }
 
 //////////////////////////////////
-vector<double> GladFieldMap::GetB(const vector<double>& pos)
+double GladFieldMap::GetB(TVector3 localpoint, string field_component)
 {
-  static vector<double> nullv = {0,0,0};
+  TVector3 vtrans(0,0,-m_Z_Glad);
+
+  localpoint = localpoint + vtrans;
+
+  static int ix, iy, iz;
+  static double dx, dy, dz;
+  double val = 0;
+
+  if(IsInside(localpoint, ix, iy, iz, dx, dy, dz)){
+    // B component value at grid cell corner
+    if(field_component=="X"){
+      m_C0[0][0][0] = m_Bx.at(ix*m_Ny*m_Nz + iy*m_Nz + iz);
+      m_C0[1][0][0] = m_Bx.at((ix+1)*m_Ny*m_Nz + iy*m_Nz + iz);
+      m_C0[0][1][0] = m_Bx.at(ix*m_Ny*m_Nz + (iy+1)*m_Nz + iz);
+      m_C0[1][1][0] = m_Bx.at((ix+1)*m_Ny*m_Nz + (iy+1)*m_Nz + iz);
+      m_C0[0][0][1] = m_Bx.at(ix*m_Ny*m_Nz + iy*m_Nz + (iz+1));
+      m_C0[1][0][1] = m_Bx.at((ix+1)*m_Ny*m_Nz + iy*m_Nz + (iz+1));
+      m_C0[0][1][1] = m_Bx.at(ix*m_Ny*m_Nz + (iy+1)*m_Nz + (iz+1));
+      m_C0[1][1][1] = m_Bx.at((ix+1)*m_Ny*m_Nz + (iy+1)*m_Nz + (iz+1));
+
+      val = Interpolate(dx,dy,dz);
+    }
+    if(field_component=="Y"){
+      m_C0[0][0][0] = m_By.at(ix*m_Ny*m_Nz + iy*m_Nz + iz);
+      m_C0[1][0][0] = m_By.at((ix+1)*m_Ny*m_Nz + iy*m_Nz + iz);
+      m_C0[0][1][0] = m_By.at(ix*m_Ny*m_Nz + (iy+1)*m_Nz + iz);
+      m_C0[1][1][0] = m_By.at((ix+1)*m_Ny*m_Nz + (iy+1)*m_Nz + iz);
+      m_C0[0][0][1] = m_By.at(ix*m_Ny*m_Nz + iy*m_Nz + (iz+1));
+      m_C0[1][0][1] = m_By.at((ix+1)*m_Ny*m_Nz + iy*m_Nz + (iz+1));
+      m_C0[0][1][1] = m_By.at(ix*m_Ny*m_Nz + (iy+1)*m_Nz + (iz+1));
+      m_C0[1][1][1] = m_By.at((ix+1)*m_Ny*m_Nz + (iy+1)*m_Nz + (iz+1));
+
+      val = Interpolate(dx,dy,dz);
+    }
+    if(field_component=="Z"){
+      m_C0[0][0][0] = m_Bz.at(ix*m_Ny*m_Nz + iy*m_Nz + iz);
+      m_C0[1][0][0] = m_Bz.at((ix+1)*m_Ny*m_Nz + iy*m_Nz + iz);
+      m_C0[0][1][0] = m_Bz.at(ix*m_Ny*m_Nz + (iy+1)*m_Nz + iz);
+      m_C0[1][1][0] = m_Bz.at((ix+1)*m_Ny*m_Nz + (iy+1)*m_Nz + iz);
+      m_C0[0][0][1] = m_Bz.at(ix*m_Ny*m_Nz + iy*m_Nz + (iz+1));
+      m_C0[1][0][1] = m_Bz.at((ix+1)*m_Ny*m_Nz + iy*m_Nz + (iz+1));
+      m_C0[0][1][1] = m_Bz.at(ix*m_Ny*m_Nz + (iy+1)*m_Nz + (iz+1));
+      m_C0[1][1][1] = m_Bz.at((ix+1)*m_Ny*m_Nz + (iy+1)*m_Nz + (iz+1));
+
+      val = Interpolate(dx,dy,dz);
+    }
+
 
-  auto it = m_field.find(pos);
-  if(it!=m_field.end()){
-    return it->second;
   }
-  else
-    return nullv;
+
+  return val;
 
 }
 
+//////////////////////////////////
+bool GladFieldMap::IsInside(TVector3 localpoint, int& ix, int& iy, int& iz, double& dx, double& dy, double& dz)
+{
+  bool isIn=false;
+
+  double x = localpoint.X();
+  double y = localpoint.X();
+  double z = localpoint.X();
+
+  if(!(x>=m_x_min && x<=m_x_max && y>=m_y_min && y<=m_y_max && z>=m_z_min && z<=m_z_max)){
+    ix = iy = iz = 0;
+    dx = dy = dz = 0;
+
+    isIn = false;
+  }
+
+  else{
+    ix = int((x - m_x_min) / m_bin);
+    iy = int((y - m_y_min) / m_bin);
+    iz = int((z - m_z_min) / m_bin);
+
+    dx = (x - m_x_min) / m_bin - double(ix);
+    dy = (y - m_y_min) / m_bin - double(iy);
+    dz = (z - m_z_min) / m_bin - double(iz);
+
+    isIn = true;
+  }
+
+  return isIn;
+}
+
+//////////////////////////////////
+double GladFieldMap::Interpolate(double dx, double dy, double dz)
+{
+  m_C1[0][0] = m_C0[0][0][0] + (m_C0[1][0][0] - m_C0[0][0][0]) * dx;
+  m_C1[1][0] = m_C0[0][1][0] + (m_C0[1][1][0] - m_C0[0][1][0]) * dx;
+  m_C1[0][1] = m_C0[0][0][1] + (m_C0[1][0][1] - m_C0[0][0][1]) * dx;
+  m_C1[1][1] = m_C0[0][1][1] + (m_C0[1][1][1] - m_C0[0][1][1]) * dx;
+
+  m_C2[0] = m_C1[0][0] + (m_C1[1][0] - m_C1[0][0]) * dy;
+  m_C2[1] = m_C1[0][1] + (m_C1[1][1] - m_C1[0][1]) * dy;
+
+  double val = m_C2[0] + (m_C2[1] - m_C2[0]) * dz;
+
+  return val;
+}
+
+
+
+
diff --git a/NPLib/Detectors/Sofia/GladFieldMap.h b/NPLib/Detectors/Sofia/GladFieldMap.h
index a61251cae..155861800 100644
--- a/NPLib/Detectors/Sofia/GladFieldMap.h
+++ b/NPLib/Detectors/Sofia/GladFieldMap.h
@@ -36,6 +36,9 @@ using namespace std;
 
 #include "NPParticle.h"
 
+#define NX 80;
+#define NY 40;
+#define NZ 120;
 
 class GladFieldMap{
   public: 
@@ -45,9 +48,15 @@ class GladFieldMap{
   private:
     // GLAD parameters
     map<vector<double>, vector<double>> m_field;
+    vector<double> m_Bx;
+    vector<double> m_By;
+    vector<double> m_Bz;
     double m_Z_Glad;
     double m_Leff;
     double m_Tilt;
+    int m_Nx;
+    int m_Ny;
+    int m_Nz;
     double m_x_min;
     double m_y_min;
     double m_z_min;
@@ -57,22 +66,24 @@ class GladFieldMap{
     double m_R_max;
     double m_Scale;
     int m_bin;
+  private:
     // MWPC3 paramters
     double m_CentralTheta;
     double m_X_MWPC3;
     double m_Z_MWPC3;
     double m_R_MWPC3;
     double m_Angle_MWPC3;
+  private:
     // Runge-Kunta 4 paramaters
     double m_dt;
     int m_Limit;
     double m_Zmax;
 
+  private:
     TVector3 m_InitPos;
     TVector3 m_InitDir;
     TVector3 m_FinalPos;
 
-
   public:
     void SetZGlad(double val) {m_Z_Glad = val;}
     void SetLeff(double val) {m_Leff = val;}
@@ -97,8 +108,8 @@ class GladFieldMap{
       vector<double> position={(double)pos.X(),(double)pos.Y(),(double)pos.Z()};
       return InterpolateB(position);
     };
-    vector<double> GetB(const vector<double>& pos);
-    TGraph* BrhoScan(double Brho_min, double Brho_max, double Brho_step);
+    double GetB(TVector3 localpoint, string field_component);
+    TGraph* BrhoScan(double Brho_min, double Brho_max, double Brho_step, TVector3 pos, TVector3 dir);
     TVector3 CalculateIntersectionPoint(vector<TVector3> vPos);
     vector<TVector3> Propagate(double Brho, TVector3 Pos, TVector3 Dir, bool store);
     TVector3 PropagateToMWPC(TVector3 pos, TVector3 dir);
@@ -110,6 +121,12 @@ class GladFieldMap{
     ROOT::Math::Minimizer* m_min;
     ROOT::Math::Functor m_func;
     double Delta(const double* parameter);
+    bool IsInside(TVector3 localpoint, int& ix, int& iy, int& iz, double& dx, double& dy, double& dz);
+    double Interpolate(double dx, double dy, double dz);
+
+    double m_C0[2][2][2]; //!
+    double m_C1[2][2]; //!
+    double m_C2[2]; //!
 
   private:
 
diff --git a/Projects/s455/Analysis.cxx b/Projects/s455/Analysis.cxx
index ebf61cd27..133e5d5e8 100644
--- a/Projects/s455/Analysis.cxx
+++ b/Projects/s455/Analysis.cxx
@@ -80,14 +80,13 @@ void Analysis::Init(){
   
   m_GladField = new GladFieldMap();
   m_GladField->SetScale(-2135./3583.81);
-  //m_GladField->SetZGlad(4434.);
   m_GladField->SetZGlad(2724.);
   m_GladField->SetLeff(2.067*m);
   m_GladField->SetGladTiltAngle(14.*deg);
+  m_GladField->LoadMap("GladFieldMap.dat");
   m_GladField->SetCentralTheta(20.*deg);
   m_GladField->SetX_MWPC3(-1.436*m);
   m_GladField->SetZ_MWPC3(8.380*m);
-  m_GladField->LoadMap("GladFieldMap.dat");
   
   InitParameter();
   InitOutputBranch();
-- 
GitLab