diff --git a/Examples/Example1/ShowResults.C b/Examples/Example1/ShowResults.C
index 4a6f99d23035e0e6c11d8635981fcf1c4d2dcaa4..9168863302ea8510128edcb2b9a27ed53e3affe8 100644
--- a/Examples/Example1/ShowResults.C
+++ b/Examples/Example1/ShowResults.C
@@ -7,69 +7,69 @@ TCanvas* c1 = NULL;
 
 ////////////////////////////////////////////////////////////////////////////////
 void LoadCuts(){
-TFile* File_ETOF = new TFile("cuts/ETOF.root","READ");
-ETOF = (TCutG*) File_ETOF->FindObjectAny("ETOF");
-
-TFile* File_EDE = new TFile("cuts/EDE.root","READ");
-EDE= (TCutG*) File_EDE->FindObjectAny("EDE");
+    TFile* File_ETOF = new TFile("cuts/ETOF.root","READ");
+    ETOF = (TCutG*) File_ETOF->FindObjectAny("ETOF");
+    
+    TFile* File_EDE = new TFile("cuts/EDE.root","READ");
+    EDE= (TCutG*) File_EDE->FindObjectAny("EDE");
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void LoadChain(){
-chain = new TChain("PhysicsTree");
-chain->Add("../../Outputs/Analysis/Example1.root");
+    chain = new TChain("PhysicsTree");
+    chain->Add("../../Outputs/Analysis/Example1.root");
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void ShowResults(){
-LoadChain();
-LoadCuts();
-
-c1 = new TCanvas("Example1","Example1",0,0,600,600);
-c1->Divide(2,2);
-
-// Light Particle ID //
-// E-DE
-c1->cd(1);
-chain->Draw("SSSD.Energy:MUST2.Si_E>>hIDE(1000,0,35,1000,0,5)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5","colz");
-EDE->Draw("same");
-
-// E-TOF
-c1->cd(2);
-chain->Draw("-MUST2.Si_T:SSSD.Energy+MUST2.Si_E>>hIDT(1000,0,35,1000,-15,0)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5","colz");
-ETOF->Draw("same");
-
-// Kinematical Line //
-c1->cd(3);
-//chain->Draw("ELab:ThetaLab>>hKine(500,0,45,400,0,40)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5 && EDE && ETOF","colz");
-chain->Draw("ELab:ThetaLab>>h(1000,0,90,1000,0,30)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5 && EDE && ETOF","colz");
-
-NPL::Reaction r("11Li(d,3He)10He@553");
-r.SetExcitationHeavy(1.4);
-TGraph* Kine = r.GetKinematicLine3(); 
-Kine->SetLineWidth(2);
-Kine->SetLineColor(kOrange-3);
-Kine->Draw("c");
-
-// Excitation Energy //
-c1->cd(4);
-int bin=50;
-double Emin = -5;
-double Emax = 5;
-
-chain->Draw(Form("Ex>>hEx(%d,%f,%f)",bin,Emin,Emax),"MUST2.CsI_E<0 && MUST2.TelescopeNumber<5 && EDE && ETOF");
-TH1F* hEx = (TH1F*) gDirectory->FindObjectAny("hEx");
-hEx->GetYaxis()->SetTitle(Form("counts / %d keV",(int) (1000*(Emax-Emin)/bin)));
-hEx->GetXaxis()->SetTitle("E_{10He}");
-hEx->SetFillStyle(1001);
-hEx->SetLineColor(kAzure+7);
-hEx->SetFillColor(kAzure+7);
-
-hEx->Fit("gaus");
-
-TF1* f = hEx->GetFunction("gaus");
-f->SetLineWidth(2);
-f->SetLineColor(kOrange-3);
-f->SetNpx(1000);
-
+    LoadChain();
+    LoadCuts();
+    
+    c1 = new TCanvas("Example1","Example1",0,0,600,600);
+    c1->Divide(2,2);
+    
+    // Light Particle ID //
+    // E-DE
+    c1->cd(1);
+    chain->Draw("SSSD.Energy:MUST2.Si_E>>hIDE(1000,0,35,1000,0,5)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5","colz");
+    EDE->Draw("same");
+    
+    // E-TOF
+    c1->cd(2);
+    chain->Draw("-MUST2.Si_T:SSSD.Energy+MUST2.Si_E>>hIDT(1000,0,35,1000,-15,0)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5","colz");
+    ETOF->Draw("same");
+    
+    // Kinematical Line //
+    c1->cd(3);
+    //chain->Draw("ELab:ThetaLab>>hKine(500,0,45,400,0,40)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5 && EDE && ETOF","colz");
+    chain->Draw("ELab:ThetaLab>>h(1000,0,90,1000,0,30)","MUST2.CsI_E<0 && MUST2.TelescopeNumber<5 && EDE && ETOF","colz");
+    
+    NPL::Reaction r("11Li(d,3He)10He@553");
+    r.SetExcitationHeavy(1.4);
+    TGraph* Kine = r.GetKinematicLine3();
+    Kine->SetLineWidth(2);
+    Kine->SetLineColor(kOrange-3);
+    Kine->Draw("c");
+    
+    // Excitation Energy //
+    c1->cd(4);
+    int bin=50;
+    double Emin = -5;
+    double Emax = 5;
+    
+    chain->Draw(Form("Ex>>hEx(%d,%f,%f)",bin,Emin,Emax),"MUST2.CsI_E<0 && MUST2.TelescopeNumber<5 && EDE && ETOF");
+    TH1F* hEx = (TH1F*) gDirectory->FindObjectAny("hEx");
+    hEx->GetYaxis()->SetTitle(Form("counts / %d keV",(int) (1000*(Emax-Emin)/bin)));
+    hEx->GetXaxis()->SetTitle("E_{10He}");
+    hEx->SetFillStyle(1001);
+    hEx->SetLineColor(kAzure+7);
+    hEx->SetFillColor(kAzure+7);
+    
+    hEx->Fit("gaus");
+    
+    TF1* f = hEx->GetFunction("gaus");
+    f->SetLineWidth(2);
+    f->SetLineColor(kOrange-3);
+    f->SetNpx(1000);
+    
 }
diff --git a/Inputs/DetectorConfiguration/ConfigMDM.dat b/Inputs/DetectorConfiguration/ConfigMDM.dat
new file mode 100644
index 0000000000000000000000000000000000000000..564e5a231bb0d95a15df7c4687c9234c90503a6b
--- /dev/null
+++ b/Inputs/DetectorConfiguration/ConfigMDM.dat
@@ -0,0 +1,15 @@
+ConfigMDM
+  X_THRESHOLD 1000
+  Y_THRESHOLD 1000
+  X_LOW	       -15
+  Y_LOW	       -15
+  X_HIGH       +15
+  Y_HIGH       +15
+  RECON_A       14
+  RECON_Z        8
+  RECON_Q        8
+  DO_MINIMIZATION     false
+  MINIMIZER_NAME      Minuit2
+  MINIMIZER_ALGORITHM Migrad
+  MINIMIZER_PLUGIN_FILE  ${NPTOOL}/Inputs/DetectorConfiguration/MDM_MinimizerPlugins.C
+  MINIMIZER_PLUGIN_CLASS MinimizerR2XYLight
diff --git a/Inputs/DetectorConfiguration/MDM_MinimizerPlugins.C b/Inputs/DetectorConfiguration/MDM_MinimizerPlugins.C
new file mode 100644
index 0000000000000000000000000000000000000000..c8f77c84e366ec095aba997af97ea53e8655da75
--- /dev/null
+++ b/Inputs/DetectorConfiguration/MDM_MinimizerPlugins.C
@@ -0,0 +1,514 @@
+// ROOT
+#include <TGraph.h>
+#include <TVector3.h>
+// NPTOOL
+#include "NPSystemOfUnits.h"
+// MDM
+#include "TMDMPhysicsMinimizer.h"
+#include "TMDMPhysics.h"
+
+
+// Helper functions
+// Check if xpos between limits for MDM
+bool check_good_x(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		if(m_MDM->Xpos[i] > m_MDM->GetXlow() &&
+			 m_MDM->Xpos[i] < m_MDM->GetXhigh()) {
+			++ngood;
+		}
+	}
+	return (ngood > 1);
+}
+
+bool check_good_y(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	for(size_t i=0; i< m_MDM->Ypos.size(); ++i) {
+		if(m_MDM->Ypos[i] > m_MDM->GetYlow() &&
+			 m_MDM->Ypos[i] < m_MDM->GetYhigh()) {
+			++ngood;
+		}
+	}
+	return (ngood > 1);
+}
+
+// Chi2 calculation (x-only) (used in many classes)
+double calc_chi2_xy(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	double chi2 = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		size_t iDet = m_MDM->DetectorNumber[i];
+		if(iDet > 3) { continue; }
+
+		double X = m_MDM->Xpos[i];
+		double F = m_MDM->Fit_Xpos[iDet];
+
+		double Y = m_MDM->Ypos[i];
+		double G = m_MDM->Fit_Ypos[iDet];
+		
+		if(X > m_MDM->GetXlow() && X < m_MDM->GetXhigh() &&
+			 Y > m_MDM->GetYlow() && Y < m_MDM->GetYhigh() ){
+			++ngood;
+			double w = 1.; // "weight"
+			double ch2;
+			ch2 = pow(X - F, 2) / w;   chi2 += ch2;
+			ch2 = pow(Y - G, 2) / w;   chi2 += ch2;
+		}
+	}
+	return chi2 / ngood;
+}
+
+// Chi2 calculation (x-only) (used in many classes)
+double calc_chi2_x(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	double chi2 = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		size_t iDet = m_MDM->DetectorNumber[i];
+		if(iDet > 3) { continue; }
+
+		double X = m_MDM->Xpos[i];
+		double F = m_MDM->Fit_Xpos[iDet];
+
+		if(X > m_MDM->GetXlow() && X < m_MDM->GetXhigh()){
+			++ngood;
+			double w = 1.; // "weight"
+			double ch2 = pow(X - F, 2) / w;
+			chi2 += ch2;
+		}
+	}
+	return chi2 / ngood;
+}
+
+// R2 calculation (x-only) (used in many classes)
+double calc_r2_x(TMDMPhysics* m_MDM){
+	int nnn = 0;
+	double ybar = 0;
+	for(const auto& x : m_MDM->Xpos) {
+		if(x > m_MDM->GetXlow() && x < m_MDM->GetXhigh()) {
+			++nnn;	ybar += x;
+		}
+	}
+	ybar /= nnn;
+
+	double SStot = 0, SSres = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		size_t iDet = m_MDM->DetectorNumber[i];
+		if(iDet > 3) { continue; }
+
+		double X = m_MDM->Xpos[i];				
+		double F = m_MDM->Fit_Xpos[iDet];
+		if(X > m_MDM->GetXlow() && X < m_MDM->GetXhigh()) {
+			SStot += pow(X - ybar, 2);
+			SSres += pow(X - F, 2);
+		}
+	}
+	double  r2 = 1 - (SSres/SStot);
+	return -r2; // negative (to minimize)
+}
+
+
+// Minimize over x, y angle and ekin, using unweighted chi2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerChi2XY : public TMDMPhysicsMinimizer{
+public:
+	MinimizerChi2XY(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(3, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerChi2XY* out = new MinimizerChi2XY(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = false;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double thetaY = x[1]; // deg
+		double Ekin   = x[2]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,thetaY,Ekin);
+		}
+
+		// calculate Chi2
+		return calc_chi2_xy(m_MDM);
+	}
+};
+
+// Minimize over x angle and ekin, using unweighted chi2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerChi2X : public TMDMPhysicsMinimizer{
+public:
+	MinimizerChi2X(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(2, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerChi2X* out = new MinimizerChi2X(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double Ekin   = x[2]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,m_InitialThetaY,Ekin);
+		}
+
+		// calculate Chi2
+		return calc_chi2_x(m_MDM);
+	}
+};
+
+
+// Minimize over x-angle and ekin, using linear R2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerR2X : public TMDMPhysicsMinimizer{
+public:
+	MinimizerR2X(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(2, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerR2X* out = new MinimizerR2X(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double Ekin   = x[1]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,m_InitialThetaY,Ekin);
+		}
+
+		// calculate R2
+		return calc_r2_x(m_MDM);
+	}
+};
+
+// Minimize over ekin only
+// Take x- and y- angle from the measured light particle angle
+// and reaction kinematics
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerR2XYLight : public TMDMPhysicsMinimizer{
+public:
+	MinimizerR2XYLight(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(1, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerR2XYLight* out = new MinimizerR2XYLight(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = true;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		
+		if(m_MDM->GetReaction() == 0) {
+			static bool warn = true;
+			if(warn) {
+				warn = false;
+				std::cerr << "WARNING in MinimizerR2XYLight::Initialize() :: " <<
+					"Reaction not set, defaulting to ZERO angle for Theta_X and Theta_Y at " <<
+					"the target...\n";
+			}
+			m_InitialThetaX = 0;
+			m_InitialThetaY = 0;
+		} else {
+			double ThetaLight, PhiLight;
+			m_MDM->GetLightParticleAngles(ThetaLight, PhiLight);
+			
+			std::unique_ptr<TGraph> kin (m_MDM->GetReaction()->GetTheta3VsTheta4(0.1));
+			double ThetaHeavy = kin->Eval(ThetaLight);
+			double PhiHeavy = PhiLight - 180;
+			if(PhiLight < 0) { PhiHeavy += 360; }
+
+			TVector3 v;
+			v.SetMagThetaPhi(1,ThetaHeavy*NPUNITS::deg, PhiHeavy*NPUNITS::deg);
+			m_InitialThetaX = atan(v.X()/v.Z())/NPUNITS::deg;
+			m_InitialThetaY = atan(v.Y()/v.Z())/NPUNITS::deg;
+		}
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double Ekin   = x[0]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(m_InitialThetaX,m_InitialThetaY,Ekin);
+		}
+		
+		// calculate R2 (from wires x)
+		return calc_r2_x(m_MDM);
+	}
+};
+
+
+
+# if 0
+
+void TMDMPhysics::CalculateAnalyticAngles(double& tx, double& ty){
+	// n.b. not sure if this is universal!!
+	// Taken from simulation of 14C(a,4n)14O @560 MeV
+	// detecting 14O in MDM
+	tx = -0.656*pow(Xang,2) + -0.414486*Xang; // RAD
+	ty = -3.97*Yang; // RAD
+}
+
+
+// Fit both x-angle and energy to the wire spectra
+// take y-angle from "analytic" evaluation of RAYTRACE
+// correlations
+void TMDMPhysics::MinimizeWithXangle(){
+	Target_Ekin = CalculateCentralEnergy();
+	CalculateAnalyticAngles(Target_Xang, Target_Yang);
+
+	std::unique_ptr<FitFunctor> f (nullptr);
+	if(m_FitMethod == 1) {
+		f.reset(new Chi2WireX(this));
+	}
+	else if(m_FitMethod == 2) {
+		f.reset(new R2WireX(this));
+	}
+	else {
+		assert(0 && "Shouldn't get here!!!");
+	}
+
+	ROOT::Minuit2::Minuit2Minimizer min (ROOT::Minuit2::kMigrad); 
+	InitializeMinimizerWithDefaults(&min);
+	min.SetFunction(*f);
+	// Set the free variables to be minimized!
+	min.SetVariable(0,"thetax",Target_Xang, 0.01 /*step*/);
+	min.SetVariable(1,"ekin"  ,Target_Ekin, 0.01 /*step*/);
+	min.Minimize();
+
+	Target_Xang = min.X()[0] * deg; // rad
+	Target_Ekin = min.X()[1] * MeV; // MeV
+	Fit_Chi2 = f->operator()(min.X());
+}
+
+// Fit only the energy to the wire spectra
+// Take angle from the LIGHT particle and reaction
+// Minimize over x-angle and ekin, using linear R2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerR2X : public TMDMPhysicsMinimizer{
+public:
+	MinimizerR2X(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(2, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerR2X* out = new MinimizerR2X(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double Ekin   = x[1]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,m_InitialThetaY,Ekin);
+		}
+
+		// calculate R2
+		return calc_r2_x(m_MDM);
+	}
+};
+
+// kinematics
+void TMDMPhysics::MinimizeUsingLightParticleAngle(){
+	Target_Ekin = CalculateCentralEnergy();
+	if(m_Reaction == 0) {
+		static bool warn = true;
+		if(warn) {
+			warn = false;
+			std::cerr << "WARNING in TMDMPhysics::MinimizeUsingLightParticleAngle() :: " <<
+				"m_Reaction not set, defaulting to ZERO angle for Theta_X and Theta_Y at " <<
+				"the target...\n";
+		}
+		Target_Xang = 0;
+		Target_Yang = 0;
+	} else {
+		std::unique_ptr<TGraph> kin (m_Reaction->GetTheta3VsTheta4(0.1));
+		double ThetaHeavy = kin->Eval(m_Light_ThetaLab);
+		double PhiHeavy = m_Light_PhiLab - 180;
+		if(m_Light_PhiLab < 0) { PhiHeavy += 360; }
+
+		TVector3 v;
+		v.SetMagThetaPhi(1,ThetaHeavy*deg,PhiHeavy*deg);
+		Target_Xang = atan(v.X()/v.Z())/deg;
+		Target_Yang = atan(v.Y()/v.Z())/deg;
+	}
+	
+	R2WireX1 f(this, Target_Xang, Target_Yang);
+	
+	ROOT::Minuit2::Minuit2Minimizer min (ROOT::Minuit2::kMigrad); 
+	InitializeMinimizerWithDefaults(&min);
+	min.SetFunction(f);
+	// Set the free variables to be minimized!
+	min.SetVariable(0,"ekin"  ,Target_Ekin, 0.01 /*step*/);
+	min.Minimize();
+
+	Target_Ekin = min.X()[0] * MeV; // MeV
+	Fit_Chi2 = f(min.X());
+}
+
+
+
+
+class Chi2WireX : public FitFunctor {
+public:
+	Chi2WireX(const TMDMPhysics* mdm):
+		FitFunctor(mdm) { }
+
+	double DoEval (const double* p) const{
+		double thetaX = p[0]; // deg
+		double Ekin   = p[1]; // MeV
+		m_MDM->SendRay(thetaX,m_MDM->Yang/deg,Ekin);
+
+		// calculate Chi2
+		double chi2 = 0;
+		assert(m_MDM->Xpos.size() == 4);
+
+		for(int i=0; i< m_MDM->Xpos.size(); ++i) {
+
+			size_t iDet = m_MDM->DetectorNumber[i];
+			if(iDet > 3) { continue; }
+
+			double X = m_MDM->Xpos[i];				
+			double F = m_MDM->Fit_Xpos[iDet];
+
+			if(X > -20 && X < 20) {
+				double w = 1.; // "weight"
+				double ch2 = pow(X - F, 2) / w;
+				chi2 += ch2;
+			}
+		}
+	
+		return chi2;
+	}
+1
+	unsigned int NDim() const { return 2; }
+};
+
+class R2WireX : public FitFunctor {
+public:
+	R2WireX(const TMDMPhysics* mdm):
+		FitFunctor(mdm) { }
+
+	double DoEval (const double* p) const{
+		double thetaX = p[0]; // deg
+		double Ekin   = p[1]; // MeV
+		m_MDM->SendRay(thetaX,0,Ekin);
+
+		// calculate R2
+		int nnn = 0;
+		double ybar = 0;
+		for(const auto& x : m_MDM->Xpos) {
+			if(x > -20 && x < 20) {
+				++nnn;	ybar += x;
+			}
+		}
+		ybar /= nnn;
+
+		double SStot = 0, SSres = 0;
+		for(int i=0; i< 4; ++i) {
+			size_t iDet = m_MDM->DetectorNumber[i];
+			if(iDet > 3) { continue; }
+
+			double X = m_MDM->Xpos[i];				
+			double F = m_MDM->Fit_Xpos[iDet];
+
+			if(X > -20 && X < 20) {
+				SStot += pow(X - ybar, 2);
+				SSres += pow(X - F, 2);
+			}
+		}
+
+		double r2 = 1 - (SSres/SStot);
+		return -r2;
+	}
+
+	unsigned int NDim() const { return 2; }
+};
+
+
+class R2WireX1 : public FitFunctor {
+public:
+	double thetaX,thetaY;
+	R2WireX1(const TMDMPhysics* mdm, double thetax, double thetay):
+		FitFunctor(mdm) {
+		thetaX = thetax;
+		thetaY = thetay;
+	}
+
+	double DoEval (const double* p) const{
+		double Ekin   = p[0]; // MeV
+		m_MDM->SendRay(thetaX,thetaY,Ekin);
+
+		// calculate R2
+		int nnn = 0;
+		double ybar = 0;
+		for(const auto& x : m_MDM->Xpos) {
+			if(x > -20 && x < 20) {
+				++nnn;	ybar += x;
+			}
+		}
+		ybar /= nnn;
+
+		double SStot = 0, SSres = 0;
+		for(int i=0; i< 4; ++i) {
+			size_t iDet = m_MDM->DetectorNumber[i];
+			if(iDet > 3) { continue; }
+
+			double X = m_MDM->Xpos[i];				
+			double F = m_MDM->Fit_Xpos[iDet];
+
+			if(X > -20 && X < 20) {
+				SStot += pow(X - ybar, 2);
+				SSres += pow(X - F, 2);
+			}
+		}
+
+		double r2 = 1 - (SSres/SStot);
+		return -r2;
+	}
+
+	unsigned int NDim() const { return 1; }
+};
+
+
+#endif
diff --git a/Inputs/DetectorConfiguration/actar_test.detector b/Inputs/DetectorConfiguration/actar_test.detector
new file mode 100644
index 0000000000000000000000000000000000000000..c46dd5f1d2c540b66ccdc643207035dff16ce266
--- /dev/null
+++ b/Inputs/DetectorConfiguration/actar_test.detector
@@ -0,0 +1,19 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Target
+ THICKNESS= 1 micrometer
+ ANGLE= 0 deg
+ RADIUS= 7.5 mm
+ MATERIAL= CH2
+ X= 0 mm
+ Y= 0 mm
+ Z= -110 mm
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Actar
+ POS= 0 0 0 mm
+ Shape= Square
+ Si= 1
+ CsI= 1
+ GasMaterial= iC4H10
+ GasFraction= 100
+ Temperature= 295 kelvin
+ Pressure= 0.4 bar
diff --git a/Inputs/DetectorConfiguration/rayin-t4t.dat b/Inputs/DetectorConfiguration/rayin-t4t.dat
new file mode 100644
index 0000000000000000000000000000000000000000..beeec1a2bb55829788fcc1d3db35a8cac6fc97df
--- /dev/null
+++ b/Inputs/DetectorConfiguration/rayin-t4t.dat
@@ -0,0 +1,41 @@
+MDM 6Li+12C @3.0 deg el scattering for test for RAYKIN1
+    1  206    1    2    3    0    0
+  71.09    2.0       0.       6.000      3.       
+DRIF
+ 57.0
+COLL
+0.0        0.0       0.0      3.         3.
+DRIF
+ 18.075
+POLE input multipole (use Bronson calibration of Bhall)
+ 1.        3.        1.
+ 1.925     113.2     26.      6.5
+-0.32269   0.02401   0.0176    -0.01416  -0.0119   Bq=      6015.3*1.034
+ 20.       -10.       -10.      20.
+ .1122      6.2671   -1.4982  3.5882     -2.1209  1.723                          
+ .1122      6.2671   -1.4982  3.5882     -2.1209  1.723
+ 1.        1.        1.        1.        1.       1.        1.        1.
+DIPO   (Bd=1.034*Bnmr  Bnmr=Bhall)
+ 1.        6.        1.        1.        3.       60.       0.
+ 26.       32.55     11.5      160.      0.6220
+ 100.      0.        0.
+ 0.191    -0.04     0.        0.
+ 46.       -33.      -23.      50.
+ .048      3.70      .0125     -.299     .016     .020       Jeffs frng 800amp
+ .048      3.70      .0125     -.299     .016     .020       Jeffs frng 800amp
+ 0.        0.        0.        0.        0.       0.
+ 0.        0.
+ 1.242     -3.11     4.142     -1.06     0.       0.        0.        Drawing ent
+ -1.579    1.719     -13.43   -24.58    779.35    821.26    -21410.   Drawing Exit
+MULT (L=35 cm 9/7/93)
+ 1.        2.        0.
+ 0.2        1.5      35.0      60.       9.6      1.0   
+ -32.5     32.5
+ 0.        0.         0.0      0.0       0.       0.
+ 0.        1.        1.
+COLL
+ 0.       -0.08      0.        29.61    20.21
+DRIF 
+ 88.4
+SENT  
+
diff --git a/Inputs/EventGenerator/18Opp.reaction b/Inputs/EventGenerator/18Opp.reaction
new file mode 100644
index 0000000000000000000000000000000000000000..488eed07eb95c1528e653d8bda9377052c44ecc1
--- /dev/null
+++ b/Inputs/EventGenerator/18Opp.reaction
@@ -0,0 +1,28 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%% Reaction file for 11Li(d,3He)10He reaction %%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%Beam energy given in MeV ; Excitation in MeV
+Beam
+  Particle= 18O
+  Energy= 137.88
+  SigmaEnergy= 0
+  SigmaThetaX= 0
+  SigmaPhiY= 0
+  SigmaX= 0
+  SigmaY= 0
+  MeanThetaX= 0
+  MeanPhiY= 0
+  MeanX= 0
+  MeanY= 0
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+TwoBodyReaction
+ Beam= 18O
+ Target= 1H
+ Light= 1H
+ Heavy= 18O
+ ExcitationEnergyLight= 0.0
+ ExcitationEnergyHeavy= 0.0
+ CrossSectionPath= flat.txt CS
+ ShootLight= 1
+ ShootHeavy= 1
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/Inputs/EventGenerator/alpha.source b/Inputs/EventGenerator/alpha.source
index 6cb81d2825f67c2a17088cd685af319ea22cd7a2..ea19e4bc82f69f9e898e26f1beadd9a70658a35b 100644
--- a/Inputs/EventGenerator/alpha.source
+++ b/Inputs/EventGenerator/alpha.source
@@ -4,13 +4,13 @@
 %      Energy are given in MeV , Position in mm      % 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 Isotropic
- EnergyLow= 30 MeV
- EnergyHigh= 30 MeV
+ EnergyLow= 5.5 MeV
+ EnergyHigh= 5.5 MeV
  HalfOpenAngleMin= 0 deg
- HalfOpenAngleMax= 180 deg
+ HalfOpenAngleMax= 90 deg
  x0= 0 mm
  y0= 0 mm
- z0= 0 mm
+ z0= -110 mm
  Particle= alpha
  ExcitationEnergy= 0 MeV
 
diff --git a/Inputs/EventGenerator/proton.source b/Inputs/EventGenerator/proton.source
index 59809fe9e40efbcfc60679c7961af628121436ba..7b62f807a43297d6ba4566711765a7c559e00578 100644
--- a/Inputs/EventGenerator/proton.source
+++ b/Inputs/EventGenerator/proton.source
@@ -4,16 +4,16 @@
 %      Energy are given in MeV , Position in mm      % 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 Isotropic
- EnergyLow=  0
- EnergyHigh= 200
+ EnergyLow=  30
+ EnergyHigh= 80
   HalfOpenAngleMin= 0
- HalfOpenAngleMax= 180
+ HalfOpenAngleMax= 1
  x0= 0 
  y0= 0 
  z0= 0 
   SigmaX= 0
   SigmaY= 0
-  Multiplicity= 4
+  Multiplicity= 1
  Particle= proton
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Supported particle type: proton, neutron, deuton, triton, He3 , alpha 
diff --git a/NPLib/Core/NPGlobalSystemOfUnits.h b/NPLib/Core/NPGlobalSystemOfUnits.h
index 3e53094b3b924d2d22d61250101af91455b42b08..3eed6c7b82185adccea7175599234e7c9a078f54 100644
--- a/NPLib/Core/NPGlobalSystemOfUnits.h
+++ b/NPLib/Core/NPGlobalSystemOfUnits.h
@@ -106,6 +106,7 @@ using NPUNITS::watt;
 using NPUNITS::newton;
 using NPUNITS::hep_pascal;
 using NPUNITS::bar;
+using NPUNITS::torr;
 using NPUNITS::atmosphere;
 using NPUNITS::ampere;
 using NPUNITS::milliampere;
diff --git a/NPLib/Core/NPOptionManager.cxx b/NPLib/Core/NPOptionManager.cxx
index c78716c934d460633de0c047c15ba2ca0561e513..eb522e198b87a011e66548e37a0e93749954f144 100644
--- a/NPLib/Core/NPOptionManager.cxx
+++ b/NPLib/Core/NPOptionManager.cxx
@@ -67,6 +67,7 @@ void NPOptionManager::ReadTheInputArgument(int argc, char** argv){
   fLastAnyFile = false;
   fVerboseLevel               = 1;
   fNumberOfEntryToAnalyse     = -1;
+	fFirstEntryToAnalyse        = 0;
   fDisableAllBranchOption = false;
   fInputPhysicalTreeOption = false;
   fGenerateHistoOption = false ;
@@ -140,6 +141,8 @@ void NPOptionManager::ReadTheInputArgument(int argc, char** argv){
 
     else if (argument == "-L")                                    fNumberOfEntryToAnalyse = atoi(argv[++i]) ;
 
+		else if (argument == "-F")                                    fFirstEntryToAnalyse = atoi(argv[++i]);
+
     else if (argument == "--last-sim")                            fLastSimFile = true ;
 
     else if (argument == "--last-phy")                            fLastPhyFile = true ;
@@ -366,7 +369,7 @@ void NPOptionManager::DisplayHelp(){
   cout << "\t--output -O <arg>\t\tSet arg as the Output File Name (output tree)" << endl ;
   cout << "\t--tree-name <arg>\t\tSet arg as the Output Tree Name " << endl ;
   cout << "\t--verbose -V <arg>\t\tSet the verbose level, 0 for nothing, 1 for normal printout."<<endl;
- cout  << "\t\t\t\t\tError and warning are not affected" << endl ;
+	cout  << "\t\t\t\t\tError and warning are not affected" << endl ;
   cout << endl << "NPAnalysis only:"<<endl;
   cout << "\t--run -R <arg>\t\t\tSet arg as the run to read file list" << endl  ;
   cout << "\t--cal -C <arg>\t\t\tSet arg as the calibration file list" << endl ;
@@ -375,6 +378,7 @@ void NPOptionManager::DisplayHelp(){
   cout << "\t--check-histo -CH\t\tCheck if the Histogram looks ok and change there color if not" << endl ;
   cout << "\t--input-physical -IP\t\tConsider the Input file is containing Physics Class." << endl  ;
   cout << "\t-L <arg>\t\t\tLimit the number of events to be analysed to arg" << endl ;
+  cout << "\t-F <arg>\t\t\tSet the first event to analyse to arg (analysis goes from F -> L+F)" << endl ;
   cout << "\t--last-sim\t\t\tIgnore the list of Run to treat if any and analysed the last simulated file" << endl ;
   cout << "\t--last-phy\t\t\tIgnore the list of Run to treat if any and analysed the last Physics file" << endl ;
   cout << "\t--last-res\t\t\tIgnore the list of Run to treat if any and analysed the last Result file" << endl ;
diff --git a/NPLib/Core/NPOptionManager.h b/NPLib/Core/NPOptionManager.h
index dc9941ceb5713793ee615f1a02f4ef7179de8e82..eaece873a6d061ccc5ac2b20214bc8350a5a2d1e 100644
--- a/NPLib/Core/NPOptionManager.h
+++ b/NPLib/Core/NPOptionManager.h
@@ -105,6 +105,7 @@ class NPOptionManager{
       bool   GetG4BatchMode()              {return fG4BatchMode;}
       int    GetVerboseLevel()             {return fVerboseLevel;}
       int    GetNumberOfEntryToAnalyse()   {return fNumberOfEntryToAnalyse;} 
+      int    GetFirstEntryToAnalyse()      {return fFirstEntryToAnalyse;} 
       string GetSharedLibExtension()       {return fSharedLibExtension;}     
       string GetLastFile();                 
       
@@ -143,6 +144,7 @@ class NPOptionManager{
       bool   fLastAnyFile;
       int    fVerboseLevel; // 0 for not talk, 1 for talking
       int    fNumberOfEntryToAnalyse; // use to limit the number of analysed in NPA
+      int    fFirstEntryToAnalyse; // use to set the first event analysed in NPA (total: fFirstEntryToAnalyse -> fFirstEntryToAnalyse + fNumberOfEntryToAnalyse)
       string fSharedLibExtension; // lib extension is platform dependent
       string fG4MacroPath; // Path to a geant4 macro to execute at start of nps
       bool fG4BatchMode; // Execute geant4 in batch mode, running the given macro
diff --git a/NPLib/Core/NPSystemOfUnits.h b/NPLib/Core/NPSystemOfUnits.h
index d6513b20982f7c315e2de09104b38929edf6a0f0..11feef095077ee3418546397fee2a5ad41aa54c0 100644
--- a/NPLib/Core/NPSystemOfUnits.h
+++ b/NPLib/Core/NPSystemOfUnits.h
@@ -25,246 +25,247 @@
 #define NP_SYSTEM_OF_UNITS_H
 
 namespace NPUNITS {
-
-  // 
-  // Length [L]
-  //
-  static const double millimeter  = 1.;                        
-  static const double millimeter2 = millimeter*millimeter;
-  static const double millimeter3 = millimeter*millimeter*millimeter;
-
-  static const double centimeter  = 10.*millimeter;   
-  static const double centimeter2 = centimeter*centimeter;
-  static const double centimeter3 = centimeter*centimeter*centimeter;
-
-  static const double meter  = 1000.*millimeter;                  
-  static const double meter2 = meter*meter;
-  static const double meter3 = meter*meter*meter;
-
-  static const double kilometer = 1000.*meter;                   
-  static const double kilometer2 = kilometer*kilometer;
-  static const double kilometer3 = kilometer*kilometer*kilometer;
-
-  static const double parsec = 3.0856775807e+16*meter;
-
-  static const double micrometer = 1.e-6 *meter;             
-  static const double  nanometer = 1.e-9 *meter;
-  static const double  angstrom  = 1.e-10*meter;
-  static const double  fermi     = 1.e-15*meter;
-
-  static const double      barn = 1.e-28*meter2;
-  static const double millibarn = 1.e-3 *barn;
-  static const double microbarn = 1.e-6 *barn;
-  static const double  nanobarn = 1.e-9 *barn;
-  static const double  picobarn = 1.e-12*barn;
-
-  // symbols
-  static const double nm  = nanometer;                        
-  static const double um  = micrometer;                        
-
-  static const double mm  = millimeter;                        
-  static const double mm2 = millimeter2;
-  static const double mm3 = millimeter3;
-
-  static const double cm  = centimeter;   
-  static const double cm2 = centimeter2;
-  static const double cm3 = centimeter3;
-
-  static const double m  = meter;                  
-  static const double m2 = meter2;
-  static const double m3 = meter3;
-
-  static const double km  = kilometer;                   
-  static const double km2 = kilometer2;
-  static const double km3 = kilometer3;
-
-  static const double pc = parsec;
-
-  //
-  // Angle
-  //
-  static const double radian      = 1.;                  
-  static const double milliradian = 1.e-3*radian;
-  static const double degree = (3.14159265358979323846/180.0)*radian;
-
-  static const double   steradian = 1.;
-  
-  // symbols
-  static const double rad  = radian;
-  static const double mrad = milliradian;
-  static const double sr   = steradian;
-  static const double deg  = degree;
-
-  //
-  // Time [T]
-  //
-  static const double nanosecond  = 1.;
-  static const double second      = 1.e+9 *nanosecond;
-  static const double millisecond = 1.e-3 *second;
-  static const double microsecond = 1.e-6 *second;
-  static const double  picosecond = 1.e-12*second;
-
-  static const double hertz = 1./second;
-  static const double kilohertz = 1.e+3*hertz;
-  static const double megahertz = 1.e+6*hertz;
-
-  // symbols
-  static const double ns = nanosecond;
-  static const double us = microsecond;
-  static const double  s = second;
-  static const double ms = millisecond;
-
-  //
-  // Electric charge [Q]
-  //
-  static const double eplus = 1. ;// positron charge
-  static const double e_SI  = 1.602176487e-19;// positron charge in coulomb
-  static const double coulomb = eplus/e_SI;// coulomb = 6.24150 e+18 * eplus
-
-  //
-  // Energy [E]
-  //
-  static const double megaelectronvolt = 1. ;
-  static const double     electronvolt = 1.e-6*megaelectronvolt;
-  static const double kiloelectronvolt = 1.e-3*megaelectronvolt;
-  static const double gigaelectronvolt = 1.e+3*megaelectronvolt;
-  static const double teraelectronvolt = 1.e+6*megaelectronvolt;
-  static const double petaelectronvolt = 1.e+9*megaelectronvolt;
-
-  static const double joule = electronvolt/e_SI;// joule = 6.24150 e+12 * MeV
-
-  // symbols
-  static const double MeV = megaelectronvolt;
-  static const double  eV = electronvolt;
-  static const double keV = kiloelectronvolt;
-  static const double GeV = gigaelectronvolt;
-  static const double TeV = teraelectronvolt;
-  static const double PeV = petaelectronvolt;
-
-  //
-  // Mass [E][T^2][L^-2]
-  //
-  static const double  kilogram = joule*second*second/(meter*meter);   
-  static const double      gram = 1.e-3*kilogram;
-  static const double milligram = 1.e-3*gram;
-
-  // symbols
-  static const double  kg = kilogram;
-  static const double   g = gram;
-  static const double  mg = milligram;
-
-  //
-  // Power [E][T^-1]
-  //
-  static const double watt = joule/second;// watt = 6.24150 e+3 * MeV/ns
-
-  //
-  // Force [E][L^-1]
-  //
-  static const double newton = joule/meter;// newton = 6.24150 e+9 * MeV/mm
-
-  //
-  // Pressure [E][L^-3]
-  //
-//#define pascal hep_pascal                          // a trick to avoid warnings 
-  static const double hep_pascal = newton/m2;   // pascal = 6.24150 e+3 * MeV/mm3
-  static const double pascal     = newton/m2;   // pascal = 6.24150 e+3 * MeV/mm3
-  static const double bar        = 100000*pascal; // bar    = 6.24150 e+8 * MeV/mm3
-  static const double atmosphere = 101325*pascal; // atm    = 6.32420 e+8 * MeV/mm3
-
-  //
-  // Electric current [Q][T^-1]
-  //
-  static const double      ampere = coulomb/second; // ampere = 6.24150 e+9 * eplus/ns
-  static const double milliampere = 1.e-3*ampere;
-  static const double microampere = 1.e-6*ampere;
-  static const double  nanoampere = 1.e-9*ampere;
-
-  //
-  // Electric potential [E][Q^-1]
-  //
-  static const double megavolt = megaelectronvolt/eplus;
-  static const double kilovolt = 1.e-3*megavolt;
-  static const double     volt = 1.e-6*megavolt;
-
-  //
-  // Electric resistance [E][T][Q^-2]
-  //
-  static const double ohm = volt/ampere;// ohm = 1.60217e-16*(MeV/eplus)/(eplus/ns)
-
-  //
-  // Electric capacitance [Q^2][E^-1]
-  //
-  static const double farad = coulomb/volt;// farad = 6.24150e+24 * eplus/Megavolt
-  static const double millifarad = 1.e-3*farad;
-  static const double microfarad = 1.e-6*farad;
-  static const double  nanofarad = 1.e-9*farad;
-  static const double  picofarad = 1.e-12*farad;
-
-  //
-  // Magnetic Flux [T][E][Q^-1]
-  //
-  static const double weber = volt*second;// weber = 1000*megavolt*ns
-
-  //
-  // Magnetic Field [T][E][Q^-1][L^-2]
-  //
-  static const double tesla     = volt*second/meter2;// tesla =0.001*megavolt*ns/mm2
-
-  static const double gauss     = 1.e-4*tesla;
-  static const double kilogauss = 1.e-1*tesla;
-
-  //
-  // Inductance [T^2][E][Q^-2]
-  //
-  static const double henry = weber/ampere;// henry = 1.60217e-7*MeV*(ns/eplus)**2
-
-  //
-  // Temperature
-  //
-  static const double kelvin = 1.;
-
-  //
-  // Amount of substance
-  //
-  static const double mole = 1.;
-
-  //
-  // Activity [T^-1]
-  //
-  static const double becquerel = 1./second ;
-  static const double curie = 3.7e+10 * becquerel;
-
-  //
-  // Absorbed dose [L^2][T^-2]
-  //
-  static const double      gray = joule/kilogram ;
-  static const double  kilogray = 1.e+3*gray;
-  static const double milligray = 1.e-3*gray;
-  static const double microgray = 1.e-6*gray;
-
-  //
-  // Luminous intensity [I]
-  //
-  static const double candela = 1.;
-
-  //
-  // Luminous flux [I]
-  //
-  static const double lumen = candela*steradian;
-
-  //
-  // Illuminance [I][L^-2]
-  //
-  static const double lux = lumen/meter2;
-
-  //
-  // Miscellaneous
-  //
-  static const double perCent     = 0.01 ;
-  static const double perThousand = 0.001;
-  static const double perMillion  = 0.000001;
-
+    
+    //
+    // Length [L]
+    //
+    static const double millimeter  = 1.;
+    static const double millimeter2 = millimeter*millimeter;
+    static const double millimeter3 = millimeter*millimeter*millimeter;
+    
+    static const double centimeter  = 10.*millimeter;
+    static const double centimeter2 = centimeter*centimeter;
+    static const double centimeter3 = centimeter*centimeter*centimeter;
+    
+    static const double meter  = 1000.*millimeter;
+    static const double meter2 = meter*meter;
+    static const double meter3 = meter*meter*meter;
+    
+    static const double kilometer = 1000.*meter;
+    static const double kilometer2 = kilometer*kilometer;
+    static const double kilometer3 = kilometer*kilometer*kilometer;
+    
+    static const double parsec = 3.0856775807e+16*meter;
+    
+    static const double micrometer = 1.e-6 *meter;
+    static const double  nanometer = 1.e-9 *meter;
+    static const double  angstrom  = 1.e-10*meter;
+    static const double  fermi     = 1.e-15*meter;
+    
+    static const double      barn = 1.e-28*meter2;
+    static const double millibarn = 1.e-3 *barn;
+    static const double microbarn = 1.e-6 *barn;
+    static const double  nanobarn = 1.e-9 *barn;
+    static const double  picobarn = 1.e-12*barn;
+    
+    // symbols
+    static const double nm  = nanometer;
+    static const double um  = micrometer;
+    
+    static const double mm  = millimeter;
+    static const double mm2 = millimeter2;
+    static const double mm3 = millimeter3;
+    
+    static const double cm  = centimeter;
+    static const double cm2 = centimeter2;
+    static const double cm3 = centimeter3;
+    
+    static const double m  = meter;
+    static const double m2 = meter2;
+    static const double m3 = meter3;
+    
+    static const double km  = kilometer;
+    static const double km2 = kilometer2;
+    static const double km3 = kilometer3;
+    
+    static const double pc = parsec;
+    
+    //
+    // Angle
+    //
+    static const double radian      = 1.;
+    static const double milliradian = 1.e-3*radian;
+    static const double degree = (3.14159265358979323846/180.0)*radian;
+    
+    static const double   steradian = 1.;
+    
+    // symbols
+    static const double rad  = radian;
+    static const double mrad = milliradian;
+    static const double sr   = steradian;
+    static const double deg  = degree;
+    
+    //
+    // Time [T]
+    //
+    static const double nanosecond  = 1.;
+    static const double second      = 1.e+9 *nanosecond;
+    static const double millisecond = 1.e-3 *second;
+    static const double microsecond = 1.e-6 *second;
+    static const double  picosecond = 1.e-12*second;
+    
+    static const double hertz = 1./second;
+    static const double kilohertz = 1.e+3*hertz;
+    static const double megahertz = 1.e+6*hertz;
+    
+    // symbols
+    static const double ns = nanosecond;
+    static const double us = microsecond;
+    static const double  s = second;
+    static const double ms = millisecond;
+    
+    //
+    // Electric charge [Q]
+    //
+    static const double eplus = 1. ;// positron charge
+    static const double e_SI  = 1.602176487e-19;// positron charge in coulomb
+    static const double coulomb = eplus/e_SI;// coulomb = 6.24150 e+18 * eplus
+    
+    //
+    // Energy [E]
+    //
+    static const double megaelectronvolt = 1. ;
+    static const double     electronvolt = 1.e-6*megaelectronvolt;
+    static const double kiloelectronvolt = 1.e-3*megaelectronvolt;
+    static const double gigaelectronvolt = 1.e+3*megaelectronvolt;
+    static const double teraelectronvolt = 1.e+6*megaelectronvolt;
+    static const double petaelectronvolt = 1.e+9*megaelectronvolt;
+    
+    static const double joule = electronvolt/e_SI;// joule = 6.24150 e+12 * MeV
+    
+    // symbols
+    static const double MeV = megaelectronvolt;
+    static const double  eV = electronvolt;
+    static const double keV = kiloelectronvolt;
+    static const double GeV = gigaelectronvolt;
+    static const double TeV = teraelectronvolt;
+    static const double PeV = petaelectronvolt;
+    
+    //
+    // Mass [E][T^2][L^-2]
+    //
+    static const double  kilogram = joule*second*second/(meter*meter);
+    static const double      gram = 1.e-3*kilogram;
+    static const double milligram = 1.e-3*gram;
+    
+    // symbols
+    static const double  kg = kilogram;
+    static const double   g = gram;
+    static const double  mg = milligram;
+    
+    //
+    // Power [E][T^-1]
+    //
+    static const double watt = joule/second;// watt = 6.24150 e+3 * MeV/ns
+    
+    //
+    // Force [E][L^-1]
+    //
+    static const double newton = joule/meter;// newton = 6.24150 e+9 * MeV/mm
+    
+    //
+    // Pressure [E][L^-3]
+    //
+    //#define pascal hep_pascal                          // a trick to avoid warnings
+    static const double hep_pascal  = newton/m2;   // pascal = 6.24150 e+3 * MeV/mm3
+    static const double pascal      = newton/m2;   // pascal = 6.24150 e+3 * MeV/mm3
+    static const double bar         = 100000*pascal; // bar    = 6.24150 e+8 * MeV/mm3
+    static const double atmosphere  = 101325*pascal; // atm    = 6.32420 e+8 * MeV/mm3
+    static const double torr        = 0.00133322*bar;
+    
+    //
+    // Electric current [Q][T^-1]
+    //
+    static const double      ampere = coulomb/second; // ampere = 6.24150 e+9 * eplus/ns
+    static const double milliampere = 1.e-3*ampere;
+    static const double microampere = 1.e-6*ampere;
+    static const double  nanoampere = 1.e-9*ampere;
+    
+    //
+    // Electric potential [E][Q^-1]
+    //
+    static const double megavolt = megaelectronvolt/eplus;
+    static const double kilovolt = 1.e-3*megavolt;
+    static const double     volt = 1.e-6*megavolt;
+    
+    //
+    // Electric resistance [E][T][Q^-2]
+    //
+    static const double ohm = volt/ampere;// ohm = 1.60217e-16*(MeV/eplus)/(eplus/ns)
+    
+    //
+    // Electric capacitance [Q^2][E^-1]
+    //
+    static const double farad = coulomb/volt;// farad = 6.24150e+24 * eplus/Megavolt
+    static const double millifarad = 1.e-3*farad;
+    static const double microfarad = 1.e-6*farad;
+    static const double  nanofarad = 1.e-9*farad;
+    static const double  picofarad = 1.e-12*farad;
+    
+    //
+    // Magnetic Flux [T][E][Q^-1]
+    //
+    static const double weber = volt*second;// weber = 1000*megavolt*ns
+    
+    //
+    // Magnetic Field [T][E][Q^-1][L^-2]
+    //
+    static const double tesla     = volt*second/meter2;// tesla =0.001*megavolt*ns/mm2
+    
+    static const double gauss     = 1.e-4*tesla;
+    static const double kilogauss = 1.e-1*tesla;
+    
+    //
+    // Inductance [T^2][E][Q^-2]
+    //
+    static const double henry = weber/ampere;// henry = 1.60217e-7*MeV*(ns/eplus)**2
+    
+    //
+    // Temperature
+    //
+    static const double kelvin = 1.;
+    
+    //
+    // Amount of substance
+    //
+    static const double mole = 1.;
+    
+    //
+    // Activity [T^-1]
+    //
+    static const double becquerel = 1./second ;
+    static const double curie = 3.7e+10 * becquerel;
+    
+    //
+    // Absorbed dose [L^2][T^-2]
+    //
+    static const double      gray = joule/kilogram ;
+    static const double  kilogray = 1.e+3*gray;
+    static const double milligray = 1.e-3*gray;
+    static const double microgray = 1.e-6*gray;
+    
+    //
+    // Luminous intensity [I]
+    //
+    static const double candela = 1.;
+    
+    //
+    // Luminous flux [I]
+    //
+    static const double lumen = candela*steradian;
+    
+    //
+    // Illuminance [I][L^-2]
+    //
+    static const double lux = lumen/meter2;
+    
+    //
+    // Miscellaneous
+    //
+    static const double perCent     = 0.01 ;
+    static const double perThousand = 0.001;
+    static const double perMillion  = 0.000001;
+    
 }  // namespace NPUNITS
 
 #endif
diff --git a/NPLib/Core/RootInput.cxx b/NPLib/Core/RootInput.cxx
index 30205cfcb0633bfaa17683243a8dbf442d1a24fc..e6393c049a0df1f022e2218ebfe9b6ec0bf63259 100644
--- a/NPLib/Core/RootInput.cxx
+++ b/NPLib/Core/RootInput.cxx
@@ -77,7 +77,7 @@ RootInput::RootInput(string configFileName){
   pRootChain = new TChain();
 
   if (!inputConfigFile.is_open()) {
-    cout << "\033[1;31mWarning : Run to Read file :" << configFileName << " not found\033[0m" << endl; 
+    cout << "\033[1;31mWarning : Run to Read file: " << configFileName << " not found\033[0m" << endl; 
     //exit(1);
   }
 
diff --git a/NPLib/Detectors/Actar/CMakeLists.txt b/NPLib/Detectors/Actar/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a1b027f6992044326fbeefd56d43a1e2c8150d56
--- /dev/null
+++ b/NPLib/Detectors/Actar/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_custom_command(OUTPUT TActarPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TActarPhysics.h TActarPhysicsDict.cxx TActarPhysics.rootmap libNPActar.dylib DEPENDS TActarPhysics.h)
+add_custom_command(OUTPUT TActarDataDict.cxx COMMAND ../../scripts/build_dict.sh TActarData.h TActarDataDict.cxx TActarData.rootmap libNPActar.dylib DEPENDS TActarData.h)
+add_library(NPActar SHARED TActarSpectra.cxx TActarData.cxx TActarPhysics.cxx TActarDataDict.cxx TActarPhysicsDict.cxx )
+target_link_libraries(NPActar ${ROOT_LIBRARIES} NPCore) 
+install(FILES TActarData.h TActarPhysics.h TActarSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY})
+
diff --git a/NPLib/Detectors/Actar/TActarData.cxx b/NPLib/Detectors/Actar/TActarData.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a9462d0ee2a68c4ca7dc012ee52835fb712e9d1d
--- /dev/null
+++ b/NPLib/Detectors/Actar/TActarData.cxx
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold Actar Raw data                                    *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+#include "TActarData.h"
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+using namespace std;
+
+ClassImp(TActarData)
+
+
+//////////////////////////////////////////////////////////////////////
+TActarData::TActarData() {
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+TActarData::~TActarData() {
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+void TActarData::Clear() {
+  // Charge
+    fActar_PadNumber.clear();
+    fActar_PadRow.clear();
+    fActar_PadColumn.clear();
+    fActar_PadCharge.clear();
+    fActar_PadTime.clear();
+    fActar_dig_Charge.clear();
+    fActar_dig_Time.clear();
+
+    fSilicon_Energy.clear();
+    fSilicon_Time.clear();
+    fSilicon_DetectorNumber.clear();
+
+    fCsI_Energy.clear();
+    fCsI_CrystalNumber.clear();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+TGraph* TActarData::GetChargeAsGraph(){
+    TGraph* res = new TGraph (fActar_dig_Charge.size(),&fActar_dig_Time[0],&fActar_dig_Charge[0]);
+    res->Sort();
+    return res;
+
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void TActarData::Dump() const {
+  // This method is very useful for debuging and worth the dev.
+  cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TActarData::Dump()] XXXXXXXXXXXXXXXXX" << endl;
+
+  // Charge
+  size_t mysize = fActar_PadNumber.size();
+  cout << "Actar_Mult: " << mysize << endl;
+
+  for (size_t i = 0 ; i < mysize ; i++){
+    cout << "Pad Number: " << fActar_PadNumber[i]
+         << " Charge: " << fActar_PadCharge[i]
+        << " Time: " << fActar_PadTime[i];
+  }
+
+}
diff --git a/NPLib/Detectors/Actar/TActarData.h b/NPLib/Detectors/Actar/TActarData.h
new file mode 100644
index 0000000000000000000000000000000000000000..385512cd1e87e73157fb9ea0fdcc3238cd4b4408
--- /dev/null
+++ b/NPLib/Detectors/Actar/TActarData.h
@@ -0,0 +1,166 @@
+#ifndef __ActarDATA__
+#define __ActarDATA__
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold Actar Raw data                                    *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+// STL
+#include <vector>
+using namespace std;
+
+// ROOT
+#include "TObject.h"
+#include "TGraph.h"
+
+class TActarData : public TObject {
+  //////////////////////////////////////////////////////////////
+  // data members are hold into vectors in order
+  // to allow multiplicity treatment
+  private:
+    // Charge
+    vector<int>  fActar_PadNumber;
+    vector<int>  fActar_PadTime;
+    vector<int>  fActar_PadRow;
+    vector<int>  fActar_PadColumn;
+    vector<double>  fActar_PadCharge;
+
+    vector<double> fActar_dig_Time;
+    vector<double> fActar_dig_Charge;
+
+    vector<double> fSilicon_Energy;
+    vector<int> fSilicon_DetectorNumber;
+    vector<double> fSilicon_Time;
+
+    vector<double> fCsI_Energy;
+    vector<int> fCsI_CrystalNumber;
+
+
+  //////////////////////////////////////////////////////////////
+  // Constructor and destructor
+  public:
+    TActarData();
+    ~TActarData();
+
+
+  //////////////////////////////////////////////////////////////
+  // Inherited from TObject and overriden to avoid warnings
+  public:
+    void Clear();
+    void Clear(const Option_t*) {};
+    void Dump() const;
+
+
+  //////////////////////////////////////////////////////////////
+  // Getters and Setters
+  // Prefer inline declaration to avoid unnecessary called of
+  // frequently used methods
+  // add //! to avoid ROOT creating dictionnary for the methods
+  public:
+    //////////////////////    SETTERS    ////////////////////////
+    // Charge
+    inline void SetCharge(const Double_t& Charge){
+        fActar_PadCharge.push_back(Charge);
+    };//!
+    // Pad
+    inline void SetPadNumber(const UShort_t& PadNbr){
+        fActar_PadNumber.push_back(PadNbr);
+    };//!
+    // Row
+    inline void SetRowNumber(const UShort_t& RowNbr){
+        fActar_PadRow.push_back(RowNbr);
+    }
+    // Column
+    inline void SetColumnNumber(const UShort_t& ColumnNbr){
+        fActar_PadColumn.push_back(ColumnNbr);
+    }
+    // Time
+    inline void SetTime(const Double_t& Time)	{
+      fActar_PadTime.push_back(Time);
+    };//!
+
+    // Digitizer
+    void AddEnergyPoint(double& E,double& T){
+        fActar_dig_Charge.push_back(E);
+        fActar_dig_Time.push_back(T);
+    }
+
+    //Silicon
+    inline void SetSiliconEnergy(const Double_t& Energy){
+      fSilicon_Energy.push_back(Energy);
+    }
+    inline void SetSiliconDetectorNumber(const Int_t& Det){
+      fSilicon_DetectorNumber.push_back(Det);
+    }
+    inline void SetSiliconTime(const Double_t& Time){
+      fSilicon_Time.push_back(Time);
+    }
+
+    //CsI
+    inline void SetCsIEnergy(const Double_t& Energy){
+      fCsI_Energy.push_back(Energy);
+    }
+    inline void SetCsICrystalNumber(const Int_t& Det){
+      fCsI_CrystalNumber.push_back(Det);
+    }
+
+
+    //////////////////////    GETTERS    ////////////////////////
+    // Charge
+    inline UShort_t GetMultCharge() const
+      {return fActar_PadNumber.size();}
+    inline UShort_t Get_PadNumber(const unsigned int &i) const
+      {return fActar_PadNumber[i];}//!
+    inline UShort_t Get_PadRow(const unsigned int &i) const
+      {return fActar_PadRow[i];}//!
+    inline UShort_t Get_PadColumn(const unsigned int &i) const
+      {return fActar_PadColumn[i];}//!
+    inline Double_t Get_Charge(const unsigned int &i) const
+      {return fActar_PadCharge[i];}//!
+
+    // Time
+    inline Double_t Get_Time(const unsigned int &i) const
+      {return fActar_PadTime[i];}//!
+
+    inline vector<double> Get_dig_Charge()   {return fActar_dig_Charge;}
+    TGraph* GetChargeAsGraph();
+
+    // Silicon
+    inline Double_t Get_SiliconEnergy(const unsigned int &i) const
+      {return fSilicon_Energy[i];}//!
+    inline Double_t Get_SiliconTime(const unsigned int &i) const
+      {return fSilicon_Time[i];}//!
+    inline Int_t Get_SiliconDetectorNumber(const unsigned int &i) const
+      {return fSilicon_DetectorNumber[i];}//!
+
+    // CsI
+    inline Double_t Get_CsIEnergy(const unsigned int &i) const
+      {return fCsI_Energy[i];}//!
+    inline Int_t Get_CsICrystalNumber(const unsigned int &i) const
+      {return fCsI_CrystalNumber[i];}//!
+
+
+
+  //////////////////////////////////////////////////////////////
+  // Required for ROOT dictionnary
+  ClassDef(TActarData,1)  // ActarData structure
+};
+
+#endif
diff --git a/NPLib/Detectors/Actar/TActarPhysics.cxx b/NPLib/Detectors/Actar/TActarPhysics.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c1b79c0d872d73695783ca9e8e88e67e239148ac
--- /dev/null
+++ b/NPLib/Detectors/Actar/TActarPhysics.cxx
@@ -0,0 +1,374 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold Actar Treated  data                               *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+#include "TActarPhysics.h"
+
+//   STL
+#include <sstream>
+#include <iostream>
+#include <cmath>
+#include <stdlib.h>
+#include <limits>
+using namespace std;
+
+//   NPLNPSystemOfUnits.h
+#include "RootInput.h"
+#include "RootOutput.h"
+#include "NPDetectorFactory.h"
+#include "NPOptionManager.h"
+#include "NPSystemOfUnits.h"
+
+//   ROOT
+#include "TChain.h"
+#include "TH2F.h"
+#include "TCanvas.h"
+
+ClassImp(TActarPhysics)
+
+
+///////////////////////////////////////////////////////////////////////////
+TActarPhysics::TActarPhysics()
+   : m_EventData(new TActarData),
+     m_PreTreatedData(new TActarData),
+     m_EventPhysics(this),
+     m_Spectra(0),
+     m_E_RAW_Threshold(0), // adc channels
+     m_E_Threshold(0),     // MeV
+     m_NumberOfDetectors(0) {
+}
+
+///////////////////////////////////////////////////////////////////////////
+/// A usefull method to bundle all operation to add a detector
+void TActarPhysics::AddDetector(TVector3 , string ){
+  // In That simple case nothing is done
+  // Typically for more complex detector one would calculate the relevant
+  // positions (stripped silicon) or angles (gamma array)
+  m_NumberOfDetectors++;
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::AddDetector(double R, double Theta, double Phi, string shape){
+  // Compute the TVector3 corresponding
+  TVector3 Pos(R*sin(Theta)*cos(Phi),R*sin(Theta)*sin(Phi),R*cos(Theta));
+  // Call the cartesian method
+  AddDetector(Pos,shape);
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::BuildSimplePhysicalEvent() {
+  BuildPhysicalEvent();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::BuildPhysicalEvent() {
+  // apply thresholds and calibration
+
+  PreTreat();
+
+  // match Charge and time together
+  unsigned int mysizeE = m_PreTreatedData->GetMultCharge();
+
+  for (UShort_t e = 0; e < mysizeE ; e++) {
+    PadNumber.push_back(m_PreTreatedData->Get_PadNumber(e));
+    PadRow.push_back(m_PreTreatedData->Get_PadRow(e));
+    PadColumn.push_back(m_PreTreatedData->Get_PadColumn(e));
+    PadCharge.push_back(m_PreTreatedData->Get_Charge(e));
+    PadTime.push_back(m_PreTreatedData->Get_Time(e));
+  }
+
+  HoughTransform(PadRow, PadColumn, PadTime);
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::PreTreat() {
+  // This method typically applies thresholds and calibrations
+  // Might test for disabled channels for more complex detector
+
+  // clear pre-treated object
+  ClearPreTreatedData();
+
+  // instantiate CalibrationManager
+  static CalibrationManager* Cal = CalibrationManager::getInstance();
+
+  // Charge
+  unsigned int mysize = m_EventData->GetMultCharge();
+
+  for (UShort_t i = 0; i < mysize ; ++i) {
+    if (m_EventData->Get_Charge(i) > m_E_RAW_Threshold) {
+      //Double_t Charge = Cal->ApplyCalibration("Actar/CHARGE"+NPL::itoa(m_EventData->Get_PadNumber(i)),m_EventData->Get_Charge(i));
+      //Double_t Time= Cal->ApplyCalibration("Actar/TIME"+NPL::itoa(m_EventData->Get_PadNumber(i)),m_EventData->Get_Time(i));
+      if (m_EventData->Get_Charge(i) > m_E_Threshold) {
+        m_PreTreatedData->SetCharge(m_EventData->Get_Charge(i));
+        m_PreTreatedData->SetPadNumber(m_EventData->Get_PadNumber(i));
+        m_PreTreatedData->SetRowNumber(m_EventData->Get_PadRow(i));
+        m_PreTreatedData->SetColumnNumber(m_EventData->Get_PadColumn(i));
+        m_PreTreatedData->SetTime(m_EventData->Get_Time(i));
+      }
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::HoughTransform(vector<int> v1, vector<int> v2, vector<int> v3){
+  for(unsigned int i=0; i<v1.size(); i++){
+    for(int itheta=0; itheta<180; itheta++){
+      HoughAngle.push_back(itheta);
+      double tmp= v1[i]*cos(itheta*NPUNITS::deg)+v2[i]*sin(itheta*NPUNITS::deg);
+      HoughRadius.push_back(tmp);
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::ReadAnalysisConfig() {
+  bool ReadingStatus = false;
+
+  // path to file
+  string FileName = "./configs/ConfigActar.dat";
+
+  // open analysis config file
+  ifstream AnalysisConfigFile;
+  AnalysisConfigFile.open(FileName.c_str());
+
+  if (!AnalysisConfigFile.is_open()) {
+    cout << " No ConfigActar.dat found: Default parameter loaded for Analayis " << FileName << endl;
+    return;
+  }
+  cout << " Loading user parameter for Analysis from ConfigActar.dat " << endl;
+
+  // Save it in a TAsciiFile
+  TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig();
+  asciiConfig->AppendLine("%%% ConfigActar.dat %%%");
+  asciiConfig->Append(FileName.c_str());
+  asciiConfig->AppendLine("");
+  // read analysis config file
+  string LineBuffer,DataBuffer,whatToDo;
+  while (!AnalysisConfigFile.eof()) {
+    // Pick-up next line
+    getline(AnalysisConfigFile, LineBuffer);
+
+    // search for "header"
+    string name = "ConfigActar";
+    if (LineBuffer.compare(0, name.length(), name) == 0)
+      ReadingStatus = true;
+
+    // loop on tokens and data
+    while (ReadingStatus ) {
+      whatToDo="";
+      AnalysisConfigFile >> whatToDo;
+
+      // Search for comment symbol (%)
+      if (whatToDo.compare(0, 1, "%") == 0) {
+        AnalysisConfigFile.ignore(numeric_limits<streamsize>::max(), '\n' );
+      }
+
+      else if (whatToDo=="E_RAW_THRESHOLD") {
+        AnalysisConfigFile >> DataBuffer;
+        m_E_RAW_Threshold = atof(DataBuffer.c_str());
+        cout << whatToDo << " " << m_E_RAW_Threshold << endl;
+      }
+
+      else if (whatToDo=="E_THRESHOLD") {
+        AnalysisConfigFile >> DataBuffer;
+        m_E_Threshold = atof(DataBuffer.c_str());
+        cout << whatToDo << " " << m_E_Threshold << endl;
+      }
+
+      else {
+        ReadingStatus = false;
+      }
+    }
+  }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::Clear() {
+  PadNumber.clear();
+  PadRow.clear();
+  PadColumn.clear();
+  PadCharge.clear();
+  PadTime.clear();
+
+  HoughRadius.clear();
+  HoughAngle.clear();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::ReadConfiguration(NPL::InputParser parser) {
+  vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Actar");
+  if(NPOptionManager::getInstance()->GetVerboseLevel())
+    cout << "//// " << blocks.size() << " detectors found " << endl;
+
+  vector<string> cart = {"POS","Shape"};
+  vector<string> sphe = {"R","Theta","Phi","Shape"};
+
+  for(unsigned int i = 0 ; i < blocks.size() ; i++){
+    if(blocks[i]->HasTokenList(cart)){
+      if(NPOptionManager::getInstance()->GetVerboseLevel())
+        cout << endl << "////  Actar " << i+1 <<  endl;
+
+      TVector3 Pos = blocks[i]->GetTVector3("POS","mm");
+      string Shape = blocks[i]->GetString("Shape");
+      AddDetector(Pos,Shape);
+    }
+    else if(blocks[i]->HasTokenList(sphe)){
+      if(NPOptionManager::getInstance()->GetVerboseLevel())
+        cout << endl << "////  Actar " << i+1 <<  endl;
+      double R = blocks[i]->GetDouble("R","mm");
+      double Theta = blocks[i]->GetDouble("Theta","deg");
+      double Phi = blocks[i]->GetDouble("Phi","deg");
+      string Shape = blocks[i]->GetString("Shape");
+      AddDetector(R,Theta,Phi,Shape);
+    }
+    else{
+      cout << "ERROR: check your input file formatting " << endl;
+      exit(1);
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::InitSpectra() {
+  m_Spectra = new TActarSpectra(m_NumberOfDetectors);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::FillSpectra() {
+  m_Spectra -> FillRawSpectra(m_EventData);
+  m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData);
+  m_Spectra -> FillPhysicsSpectra(m_EventPhysics);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::CheckSpectra() {
+  m_Spectra->CheckSpectra();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::ClearSpectra() {
+  // To be done
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+map< string , TH1*> TActarPhysics::GetSpectra() {
+  if(m_Spectra)
+    return m_Spectra->GetMapHisto();
+  else{
+    map< string , TH1*> empty;
+    return empty;
+  }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+vector<TCanvas*> TActarPhysics::GetCanvas() {
+  //if(m_Spectra)
+    //return m_Spectra->GetCanvas();
+  //else{
+    //vector<TCanvas*> empty;
+    //return empty;
+  //}
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::WriteSpectra() {
+  m_Spectra->WriteSpectra();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::AddParameterToCalibrationManager() {
+  CalibrationManager* Cal = CalibrationManager::getInstance();
+  for (int i = 0; i < m_NumberOfDetectors; ++i) {
+    Cal->AddParameter("Actar", "D"+ NPL::itoa(i+1)+"_CHARGE","Actar_D"+ NPL::itoa(i+1)+"_CHARGE");
+    Cal->AddParameter("Actar", "D"+ NPL::itoa(i+1)+"_TIME","Actar_D"+ NPL::itoa(i+1)+"_TIME");
+  }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::InitializeRootInputRaw() {
+  TChain* inputChain = RootInput::getInstance()->GetChain();
+  inputChain->SetBranchStatus("Actar",  true );
+  inputChain->SetBranchAddress("Actar", &m_EventData );
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::InitializeRootInputPhysics() {
+  TChain* inputChain = RootInput::getInstance()->GetChain();
+  inputChain->SetBranchAddress("Actar", &m_EventPhysics);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TActarPhysics::InitializeRootOutput() {
+  TTree* outputTree = RootOutput::getInstance()->GetTree();
+  outputTree->Branch("Actar", "TActarPhysics", &m_EventPhysics);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//            Construct Method to be pass to the DetectorFactory              //
+////////////////////////////////////////////////////////////////////////////////
+NPL::VDetector* TActarPhysics::Construct() {
+  return (NPL::VDetector*) new TActarPhysics();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//            Registering the construct method to the factory                 //
+////////////////////////////////////////////////////////////////////////////////
+extern "C"{
+class proxy_Actar{
+  public:
+    proxy_Actar(){
+      NPL::DetectorFactory::getInstance()->AddToken("Actar","Actar");
+      NPL::DetectorFactory::getInstance()->AddDetector("Actar",TActarPhysics::Construct);
+    }
+};
+
+proxy_Actar p_Actar;
+}
diff --git a/NPLib/Detectors/Actar/TActarPhysics.h b/NPLib/Detectors/Actar/TActarPhysics.h
new file mode 100644
index 0000000000000000000000000000000000000000..6240921b06ad69c29bafb88f883dc1e19a93ed25
--- /dev/null
+++ b/NPLib/Detectors/Actar/TActarPhysics.h
@@ -0,0 +1,189 @@
+#ifndef TActarPHYSICS_H
+#define TActarPHYSICS_H
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold Actar Treated data                                *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+// C++ headers
+#include <vector>
+#include <map>
+#include <string>
+using namespace std;
+
+// ROOT headers
+#include "TObject.h"
+#include "TH1.h"
+#include "TCanvas.h"
+#include "TVector3.h"
+// NPTool headers
+#include "TActarData.h"
+#include "TActarSpectra.h"
+#include "NPCalibrationManager.h"
+#include "NPVDetector.h"
+#include "NPInputParser.h"
+// forward declaration
+class TActarSpectra;
+
+
+
+class TActarPhysics : public TObject, public NPL::VDetector {
+  //////////////////////////////////////////////////////////////
+  // constructor and destructor
+  public:
+    TActarPhysics();
+    ~TActarPhysics() {};
+
+
+  //////////////////////////////////////////////////////////////
+  // Inherited from TObject and overriden to avoid warnings
+  public:
+    void Clear();
+    void Clear(const Option_t*) {};
+
+
+  //////////////////////////////////////////////////////////////
+  // data obtained after BuildPhysicalEvent() and stored in
+  // output ROOT file
+  public:
+    vector<int> PadNumber;
+    vector<int> PadRow;
+    vector<int> PadColumn;
+    vector<int> PadTime;
+    vector<double> PadCharge;
+
+    vector<double> HoughRadius;
+    vector<double> HoughAngle;
+
+  /// A usefull method to bundle all operation to add a detector
+  void AddDetector(TVector3 POS, string shape);
+  void AddDetector(double R, double Theta, double Phi, string shape);
+
+  //////////////////////////////////////////////////////////////
+  // methods inherited from the VDetector ABC class
+  public:
+    // read stream from ConfigFile to pick-up detector parameters
+    void ReadConfiguration(NPL::InputParser);
+
+    // add parameters to the CalibrationManger
+    void AddParameterToCalibrationManager();
+
+    // method called event by event, aiming at extracting the
+    // physical information from detector
+    void BuildPhysicalEvent();
+
+    // same as BuildPhysicalEvent() method but with a simpler
+    // treatment
+    void BuildSimplePhysicalEvent();
+
+    // same as above but for online analysis
+    void BuildOnlinePhysicalEvent()  {BuildPhysicalEvent();};
+
+    // activate raw data object and branches from input TChain
+    // in this method mother branches (Detector) AND daughter leaves
+    // (fDetector_parameter) have to be activated
+    void InitializeRootInputRaw();
+
+    // activate physics data object and branches from input TChain
+    // in this method mother branches (Detector) AND daughter leaves
+    // (fDetector_parameter) have to be activated
+    void InitializeRootInputPhysics();
+
+    // create branches of output ROOT file
+    void InitializeRootOutput();
+
+    // clear the raw and physical data objects event by event
+    void ClearEventPhysics() {Clear();}
+    void ClearEventData()    {m_EventData->Clear();}
+
+    // methods related to the TActarSpectra class
+    // instantiate the TActarSpectra class and
+    // declare list of histograms
+    void InitSpectra();
+
+    // fill the spectra
+    void FillSpectra();
+
+    // used for Online mainly, sanity check for histograms and
+    // change their color if issues are found, for example
+    void CheckSpectra();
+
+    // used for Online only, clear all the spectra
+    void ClearSpectra();
+
+    // write spectra to ROOT output file
+    void WriteSpectra();
+
+
+  //////////////////////////////////////////////////////////////
+  // specific methods to Actar array
+  public:
+    // remove bad channels, calibrate the data and apply thresholds
+    void PreTreat();
+
+    // clear the pre-treated object
+    void ClearPreTreatedData()   {m_PreTreatedData->Clear();}
+
+    // read the user configuration file. If no file is found, load standard one
+    void ReadAnalysisConfig();
+
+    // give and external TActarData object to TActarPhysics.
+    // needed for online analysis for example
+    void SetRawDataPointer(TActarData* rawDataPointer) {m_EventData = rawDataPointer;}
+
+    void HoughTransform(vector<int> v1, vector<int> v2, vector<int> v3);
+
+  // objects are not written in the TTree
+  private:
+    TActarData*         m_EventData;        //!
+    TActarData*         m_PreTreatedData;   //!
+    TActarPhysics*      m_EventPhysics;     //!
+
+  // getters for raw and pre-treated data object
+  public:
+    TActarData* GetRawData()        const {return m_EventData;}
+    TActarData* GetPreTreatedData() const {return m_PreTreatedData;}
+
+  // parameters used in the analysis
+  private:
+    // thresholds
+    double m_E_RAW_Threshold; //!
+    double m_E_Threshold;     //!
+
+  // number of detectors
+  private:
+    int m_NumberOfDetectors;  //!
+
+  // spectra class
+  private:
+    TActarSpectra* m_Spectra; // !
+
+  // spectra getter
+  public:
+    map<string, TH1*>   GetSpectra();
+    vector<TCanvas*>    GetCanvas();
+
+  // Static constructor to be passed to the Detector Factory
+  public:
+    static NPL::VDetector* Construct();
+
+    ClassDef(TActarPhysics,1)  // ActarPhysics structure
+};
+#endif
diff --git a/NPLib/Detectors/Actar/TActarSpectra.cxx b/NPLib/Detectors/Actar/TActarSpectra.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f37527d1a503c3e4e94b2baa6c3ca88ca01184b2
--- /dev/null
+++ b/NPLib/Detectors/Actar/TActarSpectra.cxx
@@ -0,0 +1,173 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold Actar Spectra                                     *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+// class header
+#include "TActarSpectra.h"
+
+// STL
+#include <iostream>
+#include <string>
+using namespace std;
+
+// NPTool header
+#include "NPOptionManager.h"
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+TActarSpectra::TActarSpectra()
+   : fNumberOfDetectors(0) {
+  SetName("Actar");
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+TActarSpectra::TActarSpectra(unsigned int NumberOfDetectors) {
+  if(NPOptionManager::getInstance()->GetVerboseLevel()>0)
+    cout << "************************************************" << endl
+      << "TActarSpectra : Initalizing control spectra for "
+      << NumberOfDetectors << " Detectors" << endl
+      << "************************************************" << endl ;
+  SetName("Actar");
+  fNumberOfDetectors = NumberOfDetectors;
+
+  InitRawSpectra();
+  InitPreTreatedSpectra();
+  InitPhysicsSpectra();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+TActarSpectra::~TActarSpectra() {
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TActarSpectra::InitRawSpectra() {
+  static string name;
+  for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
+    // Charge
+    name = "Actar"+NPL::itoa(i+1)+"_CHARGE_RAW";
+    AddHisto1D(name, name, 4096, 0, 16384, "Actar/RAW");
+    // Time
+    name = "Actar"+NPL::itoa(i+1)+"_TIME_RAW";
+    AddHisto1D(name, name, 4096, 0, 16384, "Actar/RAW");
+  } // end loop on number of detectors
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TActarSpectra::InitPreTreatedSpectra() {
+  static string name;
+  for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
+    // Energy
+    name = "Actar"+NPL::itoa(i+1)+"_CHARGE_CAL";
+    AddHisto1D(name, name, 500, 0, 25, "Actar/CAL");
+    // Time
+    name = "Actar"+NPL::itoa(i+1)+"_TIME_CAL";
+    AddHisto1D(name, name, 500, 0, 25, "Actar/CAL");
+
+
+  }  // end loop on number of detectors
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TActarSpectra::InitPhysicsSpectra() {
+  static string name;
+  // Kinematic Plot
+  name = "Actar_CHARGE_TIME";
+  AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "Actar/PHY");
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TActarSpectra::FillRawSpectra(TActarData* RawData) {
+  static string name;
+  static string family;
+
+  // Charge
+  unsigned int sizeE = RawData->GetMultCharge();
+  for (unsigned int i = 0; i < sizeE; i++) {
+    name = "Actar"+NPL::itoa(RawData->Get_PadNumber(i))+"_CHARGE_RAW";
+    family = "Actar/RAW";
+
+    //GetHisto(family,name) -> Fill(RawData->Get_Charge(i));
+  }
+
+  // Time
+  unsigned int sizeT = RawData->GetMultCharge();
+  for (unsigned int i = 0; i < sizeT; i++) {
+    name = "Actar"+NPL::itoa(RawData->Get_PadNumber(i))+"_TIME_RAW";
+    family = "Actar/RAW";
+
+    //GetHisto(family,name) -> Fill(RawData->Get_Time(i));
+  }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TActarSpectra::FillPreTreatedSpectra(TActarData* PreTreatedData) {
+  static string name;
+  static string family;
+
+  // Energy
+  unsigned int sizeE = PreTreatedData->GetMultCharge();
+  for (unsigned int i = 0; i < sizeE; i++) {
+    name = "Actar"+NPL::itoa(PreTreatedData->Get_PadNumber(i))+"_ENERGY_CAL";
+    family = "Actar/CAL";
+
+    //GetHisto(family,name) -> Fill(PreTreatedData->Get_Charge(i));
+  }
+
+  // Time
+  unsigned int sizeT = PreTreatedData->GetMultCharge();
+  for (unsigned int i = 0; i < sizeT; i++) {
+    name = "Actar"+NPL::itoa(PreTreatedData->Get_PadNumber(i))+"_TIME_CAL";
+    family = "Actar/CAL";
+
+    //GetHisto(family,name) -> Fill(PreTreatedData->Get_Time(i));
+  }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TActarSpectra::FillPhysicsSpectra(TActarPhysics* Physics) {
+  static string name;
+  static string family;
+  family= "Actar/PHY";
+
+  // Energy vs time
+  unsigned int sizeE = Physics->PadCharge.size();
+  for(unsigned int i = 0 ; i < sizeE ; i++){
+    name = "Actar_ENERGY_TIME";
+    //GetHisto(family,name) -> Fill(Physics->Charge[i],Physics->Time[i]);
+  }
+}
diff --git a/NPLib/Detectors/Actar/TActarSpectra.h b/NPLib/Detectors/Actar/TActarSpectra.h
new file mode 100644
index 0000000000000000000000000000000000000000..2534a52b9cddddff2f8a65390a48bd26f4c2ed95
--- /dev/null
+++ b/NPLib/Detectors/Actar/TActarSpectra.h
@@ -0,0 +1,62 @@
+#ifndef TActarSPECTRA_H
+#define TActarSPECTRA_H
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold Actar Spectra                                     *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+// NPLib headers
+#include "NPVSpectra.h"
+#include "TActarData.h"
+#include "TActarPhysics.h"
+
+// Forward Declaration
+class TActarPhysics;
+
+
+class TActarSpectra : public VSpectra {
+  //////////////////////////////////////////////////////////////
+  // constructor and destructor
+  public:
+    TActarSpectra();
+    TActarSpectra(unsigned int NumberOfDetectors);
+    ~TActarSpectra();
+
+  //////////////////////////////////////////////////////////////
+  // Initialization methods
+  private:
+    void InitRawSpectra();
+    void InitPreTreatedSpectra();
+    void InitPhysicsSpectra();
+
+  //////////////////////////////////////////////////////////////
+  // Filling methods
+  public:
+    void FillRawSpectra(TActarData*);
+    void FillPreTreatedSpectra(TActarData*);
+    void FillPhysicsSpectra(TActarPhysics*);
+
+  //////////////////////////////////////////////////////////////
+  // Detector parameters 
+  private:
+    unsigned int fNumberOfDetectors;
+};
+
+#endif
diff --git a/NPLib/Detectors/Hira/THiraPhysics.cxx b/NPLib/Detectors/Hira/THiraPhysics.cxx
index ccefeec09b206e6e32b2241520db22bff81fa57f..1ebaa897401b1f59c2fc7bc2e679eec420f4008e 100644
--- a/NPLib/Detectors/Hira/THiraPhysics.cxx
+++ b/NPLib/Detectors/Hira/THiraPhysics.cxx
@@ -758,9 +758,8 @@ int THiraPhysics::CheckEvent(){
         return 1 ; // Regular Event
     
     // INterstrip management is not coded, so waste of time to make this test
-    /*  else if(   m_PreTreatedData->GetMMStripXEMult() == m_PreTreatedData->GetMMStripYEMult()+1
-     || m_PreTreatedData->GetMMStripXEMult() == m_PreTreatedData->GetMMStripYEMult()-1  )
-     return 2 ; // Pseudo Event, potentially interstrip*/
+    else if(   fabs(m_PreTreatedData->GetHiraStripXEMult() - m_PreTreatedData->GetHiraStripYEMult() )< 3)
+        return 2 ; // Pseudo Event, potentially interstrip events
     
     else
         return -1 ; // Rejected Event
diff --git a/NPLib/Detectors/MDM/CMakeLists.txt b/NPLib/Detectors/MDM/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5bfc2205bdfbcec0fea4f25dfe5af053816eb968
--- /dev/null
+++ b/NPLib/Detectors/MDM/CMakeLists.txt
@@ -0,0 +1,29 @@
+include(CheckLanguage)
+
+add_custom_command(OUTPUT TMDMPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TMDMPhysics.h TMDMPhysicsDict.cxx TMDMPhysics.rootmap libNPMDM.dylib DEPENDS TMDMPhysics.h)
+add_custom_command(OUTPUT TMDMPhysicsMinimizerDict.cxx COMMAND ../../scripts/build_dict.sh TMDMPhysicsMinimizer.h TMDMPhysicsMinimizerDict.cxx TMDMPhysicsMinimizer.rootmap libNPMDM.dylib DEPENDS TMDMPhysicsMinimizer.h)
+add_custom_command(OUTPUT TMDMDataDict.cxx COMMAND ../../scripts/build_dict.sh TMDMData.h TMDMDataDict.cxx TMDMData.rootmap libNPMDM.dylib DEPENDS TMDMData.h)
+
+## Check for FORTRAN compiler, if so
+## compile RAYTRACE code
+if("${CMAKE_GENERATOR}" STREQUAL "Unix Makefiles")
+  check_language(Fortran)
+  if(CMAKE_Fortran_COMPILER)
+    message(STATUS "Compiling libMDM with RAYTRACE support included.")
+    add_definitions(-DUSE_RAYTRACE)
+    enable_language(Fortran)
+    set (CMAKE_Fortran_FLAGS "-O3 -finit-local-zero -falign-commons -fno-automatic")
+    add_library(NPMDM SHARED TMDMSpectra.cxx TMDMData.cxx TMDMPhysics.cxx TMDMPhysicsMinimizer TMDMDataDict.cxx TMDMPhysicsDict.cxx TMDMPhysicsMinimizerDict.cxx MDMTrace.cpp RAYTKIN1.F)
+  else()
+## No fortran support, compile "fake" c-version
+    message(STATUS "No Fortran support, disabling RAYTRACE in libMDM")
+    add_library(NPMDM SHARED TMDMSpectra.cxx TMDMData.cxx TMDMPhysics.cxx TMDMPhysicsMinimizer TMDMDataDict.cxx TMDMPhysicsDict.cxx TMDMPhysicsMinimizerDict.cxx MDMTrace.cpp)
+  endif()
+else()
+    message(STATUS "Fortran support only included with Unix Makefile generator, disabling RAYTRACE in libMDM.")
+    add_library(NPMDM SHARED TMDMSpectra.cxx TMDMData.cxx TMDMPhysics.cxx TMDMPhysicsMinimizer TMDMDataDict.cxx TMDMPhysicsDict.cxx TMDMPhysicsMinimizerDict.cxx MDMTrace.cpp)
+endif()      
+
+target_link_libraries(NPMDM ${ROOT_LIBRARIES} NPCore NPPhysics Minuit2) 
+install(FILES TMDMData.h TMDMPhysics.h TMDMPhysicsMinimizer.h TMDMSpectra.h MDMTrace.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY})
+
diff --git a/NPLib/Detectors/MDM/MDMTrace.cpp b/NPLib/Detectors/MDM/MDMTrace.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c375887cc87c20e040b259b70d69cbb78ed55da4
--- /dev/null
+++ b/NPLib/Detectors/MDM/MDMTrace.cpp
@@ -0,0 +1,350 @@
+#include "MDMTrace.h"
+#include <iostream>
+#include <math.h>
+#include <stdio.h>
+
+#include <cstdlib>
+#include <sstream>
+#include <fstream>
+#include <iostream>
+using namespace std;
+
+
+MDMTrace::Rayin::Rayin(const string& filename, bool check):
+  isOwner(true)
+{
+  if(check)
+	{
+		int length;
+		{
+			ifstream test_("rayin.dat");
+			test_.seekg(0, ios::end);
+			length = test_.tellg();
+		}
+		if(length > 0) {
+			string answer;
+			cerr << "\nWARNING: The file \"rayin.dat\" already exists in the current directory. "
+					 << "Enter 'y' to remove it and replace it with a link to \"" << filename << "\" "
+					 << "OR enter 'n' to continue with the existing \"rayin.dat\" file.\n"
+					 << "Or enter 'q' to abort the program...\n";
+			while(1) {
+				cin >> answer;
+				if     (answer == "y" || answer == "Y") { break;                  }
+				else if(answer == "n" || answer == "N") { isOwner = false; break; }
+				else if(answer == "q" || answer == "Q") { exit(1);                }
+				else {
+					cerr << "ERROR: invalid response: \"" << answer << "\". Please enter 'y', 'n', or 'q'\n";
+				}
+			}
+		}
+	}
+  if(isOwner) { 
+    cerr << "Creating link \"rayin.dat\" to the file \"" << filename << "\"...\n";
+    stringstream sstr;
+    sstr << "ln -fs " <<filename << " rayin.dat";
+    system(sstr.str().c_str());
+  }
+}
+
+MDMTrace::Rayin::~Rayin()
+{
+  if(isOwner) {
+    cerr << "Removing link \"rayin.dat\"...\n";
+    system("rm -f rayin.dat");
+  }
+}
+
+#ifdef USE_RAYTRACE
+#define EXT_ extern
+#else
+#define EXT_
+#endif
+
+extern "C" {
+  EXT_ struct {
+    double DATA[200][75];
+    double ITITLE[200];
+  } blck0_;
+
+  EXT_ struct {
+    double XI[1000];
+    double YI[1000];
+    double ZI[1000];
+    double VXI[1000];
+    double VYI[1000];
+    double VZI[1000];
+    double DELP[1000];
+  } blck1_;
+
+  EXT_ struct {
+    double XO[1000];
+    double YO[1000];
+    double ZO[1000];
+    double VXO[1000];
+    double VYO[1000];
+    double VZO[1000];
+    double RTL[1000];
+    double RLL[1000];
+  } blck2_;
+
+  EXT_ struct {
+    double ENERGY;
+    double VEL;
+    double PMASS;
+    double Q0;
+  } blck4_;
+
+  EXT_ struct {
+    double THTSPEC;
+    double TRGT1;
+    double AM[4];
+    double QVALUE;
+    double EEXC;
+    double THETACAL[10];
+    double EKINE;
+  } kineblck_;
+
+EXT_ void raytrace_(int*)
+#ifdef USE_RAYTRACE
+	;
+#else
+{
+	blck2_.XO[0]   = 1e10;
+	blck2_.YO[0]   = 1e10;
+	blck2_.ZO[0]   = 1e10;
+	blck2_.VXO[0]  = 1e10;
+	blck2_.VYO[0]  = 1e10;
+	blck2_.VZO[0]  = 1e10;
+	blck2_.RTL[0] = 1e10;
+	blck2_.RLL[0] = 1e10;
+	}
+#endif
+} // extern "C" {
+
+MDMTrace* MDMTrace::instance_ = 0;
+double MDMTrace::jeffParams_[6] = {-0.51927,0.038638,0.028404,-0.022797,-0.019275,0.755583};
+double MDMTrace::oxfordWireSpacing_[3] = {15.1,16.3,16.3};
+
+MDMTrace* MDMTrace::Instance() {
+  if(!instance_) {
+    instance_ = new MDMTrace;
+    int flag = 0;
+    raytrace_(&flag);
+    kineblck_.TRGT1 = 0.;
+    instance_->beamEnergy_ = 0;
+    instance_->scatteredEnergy_ = 0;
+    instance_->beamPositions_[0] = 0.;
+    instance_->beamPositions_[1] = 0.;
+    instance_->beamPositions_[2] = 0.;
+
+  }
+  return instance_;
+}
+
+void MDMTrace::SetBeamEnergy(double energy) {
+  beamEnergy_ = energy;
+}
+
+double MDMTrace::GetBeamEnergy() const {
+  return beamEnergy_;
+}
+
+void MDMTrace::SetMDMAngle(double angle) {
+  kineblck_.THTSPEC = angle;
+}
+
+double MDMTrace::GetMDMAngle() const {
+  return kineblck_.THTSPEC;
+}
+
+void MDMTrace::SetMDMBRho(double bRho) {
+  double field = bRho/160.*1000;
+  SetMDMDipoleField(field);
+}
+
+void MDMTrace::SetMDMDipoleField(double field) {
+  double hallProbe = field/1.034;
+  double multipoleHallProbe = hallProbe*0.71;
+  std::cout << "CONFIRM: Hall probe for dipole should be set to " << hallProbe << std::endl;
+  std::cout << "CONFIRM: Hall probe for multipole should be set to " << multipoleHallProbe << std::endl;
+  double BQR = -1.*multipoleHallProbe*1e-4*jeffParams_[5];
+  double BHR = BQR*jeffParams_[1]/jeffParams_[0];
+  double BOR = BQR*jeffParams_[2]/jeffParams_[0];
+  double BDR = BQR*jeffParams_[3]/jeffParams_[0];
+  double BDDR = BQR*jeffParams_[4]/jeffParams_[0];
+
+  blck0_.DATA[4][14] = field*1.e-4;
+  blck0_.DATA[3][13]=BQR;
+  blck0_.DATA[3][14]=BHR;
+  blck0_.DATA[3][15]=BOR;
+  blck0_.DATA[3][16]=BDR;
+  blck0_.DATA[3][17]=BDDR;
+}
+
+double MDMTrace::GetMDMDipoleField() const {
+  return blck0_.DATA[4][14]*1.e4;
+}
+
+void MDMTrace::SetScatteredAngle(double angle) { // degrees
+  kineblck_.THETACAL[0] = angle;
+  scatteredAngles_[0] = angle;
+  scatteredAngles_[1] = 0.;
+}
+
+void MDMTrace::SetScatteredAngle(double xAngle,double yAngle) { // degrees
+  kineblck_.THETACAL[0] = xAngle;
+  scatteredAngles_[0] = xAngle;
+  scatteredAngles_[1] = yAngle;
+}
+
+void MDMTrace::SetBeamPosition(double x, double y, double z) { // cm
+  beamPositions_[0] = x;
+  beamPositions_[1] = y;
+  beamPositions_[2] = z;
+}
+
+double MDMTrace::GetScatteredAngle() const {
+  return kineblck_.THETACAL[0];
+}
+
+void MDMTrace::SetQValue(double qValue) {
+  kineblck_.QVALUE =qValue;
+}
+
+double MDMTrace::GetQValue() const {
+  return kineblck_.QVALUE;
+}
+
+void MDMTrace::SetResidualEnergy(double energy) {
+  kineblck_.EEXC = energy;
+}
+
+double MDMTrace::GetResidualEnergy() const {
+  return kineblck_.EEXC;
+}
+
+void MDMTrace::SetScatteredEnergy(double energy) {
+  scatteredEnergy_ = energy;
+}
+
+double MDMTrace::GetScatteredEnergy() const {
+  return scatteredEnergy_;
+}
+
+void MDMTrace::SetTargetMass(double mass) {
+  kineblck_.AM[1] = mass;
+}
+
+double MDMTrace::GetTargetMass() const {
+  return kineblck_.AM[1];
+}
+
+void MDMTrace::SetProjectileMass(double mass) {
+  kineblck_.AM[0] = mass;
+}
+
+double MDMTrace::GetProjectileMass() const {
+  return kineblck_.AM[0];
+}
+
+void MDMTrace::SetScatteredMass(double mass) {
+  blck4_.PMASS = mass;
+}
+
+double MDMTrace::GetScatteredMass() const {
+  return blck4_.PMASS;
+}
+
+void MDMTrace::SetScatteredCharge(double charge) {
+  blck4_.Q0 = charge;
+}
+
+double MDMTrace::GetScatteredCharge() const {
+  return blck4_.Q0;
+}
+
+double MDMTrace::GetEnergyAfterKinematics() const {
+  return kineblck_.EKINE*(1.+blck1_.DELP[0]/100.);
+}
+
+void MDMTrace::SendRayWithKinematics() {
+  int flag = 1;
+  blck4_.ENERGY = beamEnergy_;
+  raytrace_(&flag);
+}
+
+void MDMTrace::SendRay() {
+  int flag = 2;
+  blck4_.ENERGY = scatteredEnergy_;
+  blck1_.XI[0]=beamPositions_[0];
+  blck1_.YI[0]=beamPositions_[1];
+  blck1_.ZI[0]=beamPositions_[2];
+  blck1_.VXI[0]=17.453*(scatteredAngles_[0]-kineblck_.THTSPEC);
+  blck1_.VYI[0]=17.453*(scatteredAngles_[1]);
+  blck1_.VZI[0]=0.;
+  blck1_.DELP[0]=0.;
+  raytrace_(&flag);
+}
+
+void MDMTrace::GetPositionAngleFirstWire(double& pos, double& ang) const {
+  pos  = blck2_.XO[0];
+  ang  = blck2_.VXO[0]/1000.*180./3.14159;
+}
+
+void MDMTrace::GetPositionAngleFirstWire(double& posX, double& posY, double& angX, double& angY) const {
+  posX  = blck2_.XO[0];
+  posY  = blck2_.YO[0];
+  angX  = blck2_.VXO[0]/1000.*180./3.14159;
+  angY  = blck2_.VYO[0]/1000.*180./3.14159;
+}
+
+void MDMTrace::GetOxfordWirePositions(double& x1,double& x2,double& x3,double& x4) {
+  double oxfordWire1Pos = blck2_.XO[0];
+  double oxfordWire1Ang = blck2_.VXO[0];
+  double tanAngle = tan(1e-3*oxfordWire1Ang);
+
+  x1 = oxfordWire1Pos;
+  x2 = oxfordWire1Pos+tanAngle*oxfordWireSpacing_[0];
+  x3 = oxfordWire1Pos+tanAngle*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]);
+  x4 = oxfordWire1Pos+tanAngle*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]+oxfordWireSpacing_[2]);
+}
+
+void MDMTrace::GetOxfordWirePositions(double& a1,double& x1,double& x2,double& x3,double& x4) {
+  double oxfordWire1Pos = blck2_.XO[0];
+  double oxfordWire1Ang = blck2_.VXO[0];
+  double tanAngle = tan(1e-3*oxfordWire1Ang);
+
+  a1 = oxfordWire1Ang;
+
+  x1 = oxfordWire1Pos;
+  x2 = oxfordWire1Pos+tanAngle*oxfordWireSpacing_[0];
+  x3 = oxfordWire1Pos+tanAngle*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]);
+  x4 = oxfordWire1Pos+tanAngle*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]+oxfordWireSpacing_[2]);
+} 
+
+void MDMTrace::GetOxfordWirePositions(double& a1,double& x1,double& x2,double& x3,double& x4,
+				      double& b1,double& y1,double& y2,double& y3,double& y4) {
+  double oxfordWire1PosX = blck2_.XO[0];
+  double oxfordWire1AngX = blck2_.VXO[0]; // mrad
+  double tanAngleX = tan(1e-3*oxfordWire1AngX);
+
+  double oxfordWire1PosY = blck2_.YO[0];
+  double oxfordWire1AngY = blck2_.VYO[0]; // mrad
+  double tanAngleY = tan(1e-3*oxfordWire1AngY);
+
+  // x - plane //
+  a1 = oxfordWire1AngX; // mrad
+
+  x1 = oxfordWire1PosX;
+  x2 = oxfordWire1PosX+tanAngleX*oxfordWireSpacing_[0];
+  x3 = oxfordWire1PosX+tanAngleX*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]);
+  x4 = oxfordWire1PosX+tanAngleX*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]+oxfordWireSpacing_[2]);
+
+  // y - plane //
+  b1 = oxfordWire1AngY; // mrad
+
+  y1 = oxfordWire1PosY;
+  y2 = oxfordWire1PosY+tanAngleY*oxfordWireSpacing_[0];
+  y3 = oxfordWire1PosY+tanAngleY*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]);
+  y4 = oxfordWire1PosY+tanAngleY*(oxfordWireSpacing_[0]+oxfordWireSpacing_[1]+oxfordWireSpacing_[2]);
+} 
diff --git a/NPLib/Detectors/MDM/MDMTrace.h b/NPLib/Detectors/MDM/MDMTrace.h
new file mode 100644
index 0000000000000000000000000000000000000000..cfe06cbc78dfc5c98f4802493ee6f3c25d1cb0a5
--- /dev/null
+++ b/NPLib/Detectors/MDM/MDMTrace.h
@@ -0,0 +1,65 @@
+#ifndef MDMTRACE_H
+#define MDMTRACE_H
+
+#include <string>
+
+
+
+class MDMTrace {
+public:
+	class Rayin {
+ public:
+		Rayin(const std::string& filename, bool check=true);
+		~Rayin();
+ private:
+		bool isOwner;
+	};
+	
+public:
+  static MDMTrace* Instance();
+  void SetBeamEnergy(double);
+  double GetBeamEnergy() const;
+  void SetMDMAngle(double);
+  double GetMDMAngle() const;
+  void SetMDMBRho(double);
+  void SetMDMDipoleField(double);
+  double GetMDMDipoleField() const;
+  void SetScatteredAngle(double);
+  void SetScatteredAngle(double,double);
+  double GetScatteredAngle() const;
+  void SetScatteredEnergy(double);
+  double GetScatteredEnergy() const;
+  void SetQValue(double);
+  double GetQValue() const;
+  void SetResidualEnergy(double);
+  double GetResidualEnergy() const;
+  void SetTargetMass(double);
+  double GetTargetMass() const;
+  void SetProjectileMass(double);	       
+  double GetProjectileMass() const;	       
+  void SetScatteredMass(double);
+  double GetScatteredMass() const;
+  void SetScatteredCharge(double);
+  void SetBeamPosition(double,double,double);
+  double GetScatteredCharge() const;
+  double GetEnergyAfterKinematics() const;
+  void SendRayWithKinematics();
+  void SendRay();
+  void GetPositionAngleFirstWire(double&,double&) const;
+  void GetPositionAngleFirstWire(double&,double&,double&,double&) const;
+  void GetOxfordWirePositions(double&,double&,double&,double&);
+  void GetOxfordWirePositions(double&,double&,double&,double&,double&);
+  void GetOxfordWirePositions(double&,double&,double&,double&,double&,
+															double&,double&,double&,double&,double&);
+private:
+  MDMTrace() {};
+  static MDMTrace* instance_;
+  static double jeffParams_[6];
+  static double oxfordWireSpacing_[3];
+  double beamEnergy_;
+  double scatteredEnergy_;
+  double scatteredAngles_[2];
+  double beamPositions_[3];
+};
+
+#endif
diff --git a/NPLib/Detectors/MDM/RAYTKIN1.F b/NPLib/Detectors/MDM/RAYTKIN1.F
new file mode 100644
index 0000000000000000000000000000000000000000..9fe03208345c30fee5dfd295674c3700080219d4
--- /dev/null
+++ b/NPLib/Detectors/MDM/RAYTKIN1.F
@@ -0,0 +1,5993 @@
+C****
+C**** RAY TRACE  -  MIT VERSION 1984   (11/25/84) dy MOD 3/16/93
+C****     add K=(1/p)dpdtheta to random rays 8/25/93  
+C****     add kinematics program  3/7/96
+C****  fix bug in random-kine (dele) 6/3/98, fix 2nd ray 6/4/98
+C**** DR. STANLEY KOWALSKI
+C**** MASS INST OF TECH
+C**** BLDG 26-427
+C**** CAMBRIDGE MASS 02139
+C**** PH 617+253-4288
+C****
+      SUBROUTINE raytrace(NCTL)
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8   K
+      LOGICAL LPLT   	
+c	character*24 ctemp
+
+C%%%% REAL*4 DAET, TYME
+      COMMON  /BLCK00/  LPLT
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 1/  XI, YI, ZI, VXI, VYI, VZI, DELP
+      COMMON  /BLCK 2/  XO, YO, ZO, VXO, VYO, VZO, RTL(1000), RLL(1000)
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK 6/  NP, JFOCAL
+      COMMON  /BLCK 7/ NCODE
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK11/  EX, EY, EZ, QMC, IVEC
+      COMMON  /DY1/ BDIPOLE
+      COMMON  /kineblck/ THTSPEC,TRGT1,AM,QVALUE,EEXC,THETACAL,EKINE
+
+c
+C
+C** xkine=K=(1/p)dp/dtheta
+C** added by DY for spectrometer calculations 8/25/93
+C
+      COMMON  /BLCK15/TMIN,PMIN,XMAX,TMAX,YMAX,PMAX,DMAX,xkine
+C
+C%%%% DIMENSION DAET(3), TYME(2)
+C*IBM DIMENSION DAET(5), TYME(2)
+      DIMENSION XO(1000),YO(1000),ZO(1000),VXO(1000),VYO(1000),VZO(1000)
+      DIMENSION XI(1000),YI(1000),ZI(1000),VXI(1000),VYI(1000),
+     1    VZI(1000), DELP(1000)
+      DIMENSION NWORD(15),DATA(75,200),IDATA(200),NTITLE(20),ITITLE(200)
+      DIMENSION TC(6), DTC(6), R(6,6), T2(5,6,6)
+      dimension am(4),theta(3),engy(3),rat(2),thetacal(10)
+      DATA NWORD/4HSENT, 4HDIPO, 4HQUAD, 4HHEXA, 4HOCTA, 4HDECA, 4HEDIP,
+     1   4HVELS, 4HPOLE, 4HMULT, 4HSHRT, 4HDRIF, 4HCOLL, 4HSOLE, 4HLENS/
+      DATA C /3.D10/
+C%%%% DATA TYME/4H    ,4H    /
+      DATA NT1, NT2 /4H RT8,4H2.0 /
+C****
+C****
+  100 FORMAT( 8F10.5 )
+  101 FORMAT( 20A4 )
+  102 FORMAT(10I5)
+  103 FORMAT(///10X,' KEY WORD DOES NOT MATCH STORED LIST - NWD=',A4)
+  104 FORMAT(//10X,' GO TO STATEMENT IN MAIN FELL THROUGH - I= ',I5,/)
+  105 FORMAT( 1H1, 10X, 20A4  )
+  106 FORMAT( 1H1 )
+  107 FORMAT( 5F10.5/ 5F10.5/3F10.5/4F10.5/ 4F10.5/ 6F10.5/ 6F10.5/
+     1        6F10.5/ 4F10.5/ 7F10.5/ 7F10.5                           )
+  108 FORMAT('1',62X, 'RAY ', I4, //  30X, 'ENERGY=',F8.3,' MEV ', 7X,
+     1   'PMOM=', F8.3, ' MEV/C', 6X, 'VELC=', 1PD11.3, ' CM/SEC'    /
+     2   30X, 'DELE/E=', 0PF8.3, ' (PC)', 5X, 'DELP/P=', F8.3,
+     3   ' (PC) ', 4X, 'DELV/V=', F7.3, '     (PC)'        /)
+  109 FORMAT( 3F10.5/ 5F10.5/ 4F10.5/ 6F10.5/ 6F10.5                   )
+  111 FORMAT( 2F10.5/ 6F10.5/ 2F10.5/ 6F10.5/ 3F10.5 )
+  112 FORMAT( 3F10.5/ 4F10.5/ 5F10.5/ 4F10.5/ 6F10.5/ 6F10.5 / 8F10.5 )
+  113 FORMAT( A4, 16X, A4  )
+  114 FORMAT( 1F10.5 / 5F10.5 / 2F10.5  )
+  115 FORMAT( 4F10.5/ 5F10.5/ 2F10.5/ 4F10.5/ 4F10.5/ 4F10.5/ 6F10.5/
+     1   6F10.5/ 6F10.5/ 6F10.5   )
+  116 FORMAT( /10X, '  PARTICLE ENERGY =', F10.4,  '  MEV'      /
+     1         10X, 'PARTICLE MOMENTUM =', F10.4,  '  MEV/C'    /
+     2         10X, 'PARTICLE VELOCITY =',1PD14.4, '  CM/SEC'  /
+     3         10X, '             MASS =',0PF10.4, '  AMU'     /
+     4         10X, '           CHARGE =', F10.4,  '  EQ'           )
+C%%%% 117   FORMAT( 10X, 3A4, 1X, 2A4, I12, ' CPU.SEC'   )
+C*IBM 117   FORMAT( 10X, 3A4, 1X, 2A4, 2A4 )
+  118   FORMAT(4F10.5/5F10.5/F10.5/4F10.5/4F10.5/6F10.5/6F10.5)
+  119   FORMAT( /// '  MAXIMUM NUMBER OF BEAM ELEMENTS EXCEEDED  ' /// )
+C****
+C%%%% CALL DATE(DAET)
+C%%%% CALL TIME(TYME)
+C*IBM CALL WHEN(DAET)
+C**** CALL ERRSET( NUMBER, CONT, COUNT, TYPE, LOG, MAXLIN     )
+C%%%% CALL ERRSET( 63, .TRUE., .FALSE., .FALSE., .FALSE., 2048)
+C%%%% CALL ERRSET( 72, .TRUE., .FALSE., .FALSE., .TRUE.,  2560)
+C%%%% CALL ERRSET( 74, .TRUE., .FALSE., .FALSE., .TRUE.,  2560)
+C%%%% CALL ERRSET( 88, .TRUE., .FALSE., .FALSE., .TRUE.,  2560)
+C%%%% CALL ERRSET( 89, .TRUE., .FALSE., .FALSE., .TRUE.,  2560)
+C*IBM CALL ERRSET( 207, 256, 1 )
+C*IBM CALL ERRSET( 208, 256, 1 )
+C*IBM CALL ERRSET( 209, 256, 1 )
+C*IBM CALL ERRSET( 210, 256, 1 )
+C****
+c      open(unit=6,file='output.dat',status='unknown')
+      open(unit=5,file='rayin.dat',status='unknown')		
+C****
+      IF(NCTL.EQ.1 .OR. NCTL.EQ.2) THEN
+        EMASS = PMASS*931.48
+        ETOT = EMASS + ENERGY
+        VEL = ( DSQRT( ( 2.*EMASS + ENERGY)*ENERGY) / ETOT ) * C
+        VEL0 = VEL
+        EN0 = ENERGY
+        PMOM0 = DSQRT( (2.*EMASS + EN0)*EN0)
+        IF(NCTL.EQ.1) GOTO 66
+        IF(NCTL.EQ.2) GOTO 52
+      ENDIF
+    5 LPLT = .FALSE.
+      IVEC = 0
+      LNEN = 0
+      NMAX = 200
+      DO 1  I=1,NMAX
+      IDATA(I)= 0
+      DO 1  J=1,75
+      DATA(J,I) = 0.
+    1 CONTINUE
+      READ ( 5,101,END=99) NTITLE
+      NTITLE(19) = NT1
+      NTITLE(20) = NT2
+      READ (5,*)NR, IP, NSKIP, JFOCAL, JMTRX, JNR, NPLT
+      READ (5,100) ENERGY, DEN, XNEN, PMASS, Q0
+      IF( NPLT .NE. 0 ) LPLT = .TRUE.
+      IF( NR .GT. 1000) NR=1000
+      IF( Q0 .EQ. 0. )  Q0 = 1.
+      EMASS = PMASS*931.48
+      QMC = EMASS/(9.D10*Q0)
+      ETOT = EMASS + ENERGY
+      VEL = ( DSQRT( ( 2.*EMASS + ENERGY)*ENERGY) / ETOT ) * C
+      VEL0 = VEL
+      EN0 = ENERGY
+      PMOM0 = DSQRT( (2.*EMASS + EN0)*EN0)
+      NEN = XNEN
+      IF( NEN  .EQ.  0 ) NEN = 1
+      NO = 1
+    2 IF( NO .LE. NMAX ) GO TO 6
+C      WRITE(6,119)
+      CALL EXIT
+    6 READ (5,113) NWD, ITITLE(NO)
+      DO 3  I=1,15
+      IF( NWD  .EQ. NWORD(I) ) GO TO 4
+    3 CONTINUE
+C      WRITE(6,103) NWD
+c   99 CALL EXIT
+   99 RETURN  
+    4 GO TO( 11, 12, 13, 13, 13, 13, 17, 18, 19, 20,21,22,23,24,25), I
+C****
+C****
+C****
+C****
+C      WRITE(6, 104)  I
+      CALL EXIT
+C****
+C**** DIPOLE  LENS           TYPE = 2
+C****
+   12 IDATA(NO) = 2
+      READ (5,107) ( DATA( J,NO ) , J=1,5 ), ( DATA( J,NO ), J=11,22 ),
+     1          ( DATA( J,NO ) , J=25,64)
+      BDIPOLE=DATA(15,NO)
+      NO = NO + 1
+      GO TO 2
+C****
+C**** PURE MULTIPOLES
+C**** QUADRUPOLE LENS        TYPE = 3
+C**** HEXAPOLE  LENS         TYPE = 4
+C**** OCTAPOLE  LENS         TYPE = 5
+C**** DECAPOLE  LENS         TYPE = 6
+C****
+   13 IDATA(NO) = I
+      READ (5,109)( DATA( J,NO ) , J=1,3 ), ( DATA( J,NO ), J=10,30 )
+      NO = NO + 1
+      GO TO 2
+C****
+C****   ELECTROSTATIC DEFLECTOR  TYPE=7
+C****
+   17 IDATA(NO) = 7
+      READ(5,118) (DATA(J, NO), J=1, 4), (DATA(J, NO), J=11,20),
+     1              (DATA(J, NO), J=25,40)
+        NO = NO + 1
+        GO TO 2
+C****
+C**** VELOCITY SELECTOR      TYPE = 8
+C****
+   18 IDATA(NO) = 8
+      READ (5,115) ( DATA(J,NO),J=1,4), (DATA(J,NO), J=7,11 ),
+     1             ( DATA(J,NO),J=12,13),(DATA(J,NO),J=16,51)
+      NO = NO + 1
+      GO TO 2
+C****
+C**** MULTIPOLE (POLES)      TYPE =  9
+C****
+   19 IDATA(NO) = 9
+      READ (5,112) ( DATA( J,NO ) , J=1,3 ), ( DATA( J,NO ), J=10,34 ),
+     1             ( DATA( J,NO ) , J=35,42)
+      NO = NO + 1
+      GO TO 2
+C****
+C**** MULTIPOLE LENS         TYPE = 10
+C****
+   20 IDATA(NO) = 10
+      READ (5,111) ( DATA( J,NO ) , J=1,2 ), ( DATA( J,NO ), J=10,17 ),
+     1          ( DATA( J,NO ) , J=20,28 )
+      NO = NO + 1
+      GO TO 2
+C****
+C**** SHIFT AND ROTATE       TYPE = 11
+C****
+   21 IDATA(NO) = 11
+      READ (5,100) ( DATA( J,NO ) , J=1,6 )
+      NO = NO + 1
+      GO TO 2
+C****
+C**** DRIFT                  TYPE = 12
+C****
+   22 IDATA(NO) = 12
+      READ (5,100) ( DATA( J,NO ) , J=1,1 )
+      NO = NO + 1
+      GO TO 2
+C****
+C**** COLLIMATOR             TYPE = 13
+C****
+   23 IDATA(NO) = 13
+      READ(5,100)  (DATA(J,NO),J=1,5)
+      NO = NO+1
+      GO TO 2
+C****
+C**** SOLENOID               TYPE = 14
+C****
+   24 IDATA(NO) = 14
+      READ (5,114) (DATA(J,NO),J=1,1), ( DATA(J,NO), J=10,16)
+      NO = NO+1
+      GO TO 2
+C****
+C**** LENS                   TYPE = 15
+C****
+   25 IDATA(NO) = 15
+      READ (5,100) (DATA(J,NO), J=1,9  )
+      NO = NO+1
+      GO TO 2
+C****
+C**** SYSTEM END             TYPE = 1
+C****
+   11 IDATA(NO) = 1
+C****
+C**** STANDARD RAYS AUTOMATIC SET-UP
+C**** IF( NR .GT. JNR ) APPEND ADDITIONAL RAYS FROM INPUT
+C****
+      RETURN
+      IF (JNR.EQ.0) GO TO 66
+C
+C** xkine=K=(1/p)dp/dtheta
+C** added by DY for spectrometer calculations 8/25/93
+C
+      READ (5,100) TMIN,PMIN,XMAX,TMAX,YMAX,PMAX,DMAX,xkine
+      CALL RAYS(JNR)
+      IF( JNR .GE. NR ) GO TO 52
+      JNRP = JNR+1
+C**********************************************************************
+C**********************************************************************
+      if(jmtrx.eq.1) then
+      read(5,100) xmax1,tmax1,ymax1,pmax1,dmax1
+         open (unit=10,file='RANDOM.NUM',
+     1    status='unknown')
+         do 4900 j=jnrp,nr
+         read(10,100) xi(j),vxi(j),yi(j),vyi(j),zi(i),vzi(i),delp(j)
+         xi(j)=(xi(j)-0.5)*xmax1
+         vxi(j)=(vxi(j)-0.5)*tmax1
+         yi(j)=(yi(j)-0.5)*ymax1
+         vyi(j)=(vyi(j)-0.5)*pmax1
+         zi(j)=0
+         vzi(j)=0
+         delp(j)=(delp(j)-0.5)*dmax1
+C
+C** add correlation of theta and energy for spectrometer
+C
+         delp(j)=delp(j)-xkine*vxi(j)*0.2
+C
+ 4900    continue
+      endif
+      close(unit=10)
+      if(jmtrx.eq.1) go to 52
+C**********************************************************************
+C***************************************************************  TMC *
+C****  Random rays with kinematics and angle offset              
+C**********************************************************************
+C***** toff1 is angle relative to central ray  *************
+      if(jmtrx.eq.2) then
+      read(5,100) xmax1,tmax1,ymax1,pmax1,dmax1
+         open (unit=10,file='RANDOM.NUM',
+     1    status='unknown')
+         do 4910 j=jnrp,nr
+         read(10,100) xi(j),vxi(j),yi(j),vyi(j),zi(i),vzi(i),delp(j)
+         xi(j)=(xi(j)-0.5)*xmax1
+         vxi(j)=(vxi(j)-0.5)*tmax1
+         yi(j)=(yi(j)-0.5)*ymax1
+         vyi(j)=(vyi(j)-0.5)*pmax1
+         zi(j)=0
+         vzi(j)=0
+         delp(j)=(delp(j)-0.5)*dmax1
+4910     continue
+C
+C** 
+C
+C
+      read (5,100) THTSPEC,THTSCAT,AM(1),AM(2),QVALUE,EEXC
+        ENGY(1)=QVALUE-EEXC 
+        ENGY(2)=ENERGY
+        AM(3)=PMASS
+        THETA(1)=THTSPEC 
+        CALL KINE (AM,THETA,ENGY,RAT,PATR,KB)
+        ENERGY=ENGY(3) 
+        ETOT = EMASS + ENERGY
+        VEL = ( DSQRT( ( 2.*EMASS + ENERGY)*ENERGY) / ETOT ) * C
+        VEL0 = VEL
+        EN0 = ENERGY
+        PMOM0 = DSQRT( (2.*EMASS + EN0)*EN0)
+        THTSPEC=THTSPEC*17.45329
+        THTSCAT=THTSCAT*17.45329
+        DO 4915 J=2,NR
+C****   DO 4915 J=JNRP,NR   ** THIS WAS CHANGED SO 2ND RAY HAS PROPER KINEMATICS
+C****                          to get focal plane position.  
+        VXI(J)=VXI(J)-THTSPEC+THTSCAT 
+        THETA(1)= SQRT((THTSCAT+VXI(J))**2+VYI(J)**2)
+        THETA(1)=THETA(1)/17.45329 
+        CALL KINE (AM,THETA,ENGY,RAT,PATR,KB)
+        DELE=100*(ENGY(3)-ENERGY)/(ENERGY)    
+        DELP(J)=DELP(J)+DELE
+ 4915   continue
+      endif
+      close(unit=10)
+      if(jmtrx.eq.2) go to 52
+C**********************************************************************
+C***************************************************************  TMC *
+      DO 49 J=JNRP,NR
+   49 READ(5,100,END=60) XI(J),VXI(J),YI(J),VYI(J),ZI(J),VZI(J),
+     1                    DELP(J)
+      GO TO 52
+C****
+C**** INPUT RAYS
+C****
+   66 IF (JMTRX.NE.3) GO TO 4940 
+C*   added 3/6/96 DHY to use KINE to get ray energies 
+c       read (5,100) THTSPEC,TRGT1,AM(1),AM(2),QVALUE,EEXC,FNANG
+C       write (6,100) THTSPEC,TRGT1,AM(1),AM(2),QVALUE,EEXC,FNANG
+C	read (*,*)
+        FNANG=1
+        EBEAM=ENERGY
+        ENGY(1)=QVALUE-EEXC 
+        ENGY(2)=EBEAM-TRGT1
+        AM(3)=PMASS
+        THETA(1)=THTSPEC 
+c 	write (6,100)am(1),am(2),
+c     1 		engy(1),engy(2),engy(3),pmass
+        CALL KINE (AM,THETA,ENGY,RAT,PATR,KB)
+C	write (6,1001) am(1),am(2),engy(1),engy(2),engy(3),pmass
+C	read (*,*)
+1001    format (' after kine', 6F10.4)
+        ENERGY=ENGY(3) 
+        ETOT = EMASS + ENERGY
+        VEL = ( DSQRT( ( 2.*EMASS + ENERGY)*ENERGY) / ETOT ) * C
+        VEL0 = VEL
+        EN0 = ENERGY
+        EKINE = ENERGY
+        PMOM0 = DSQRT( (2.*EMASS + EN0)*EN0)
+        NANG=FNANG
+        NCASE=NR/FNANG
+C        READ (5,4945) (THETACAL(J),J=1,NANG)
+C	write (*,*) nr,(thetacal(j),j=1,NANG)
+ 4945  format (10F7.3)
+      DO 4952 JJ=1,NCASE
+      JN=JJ*NANG-NANG+1
+      DO 4950 J=JN,JN+NANG-1
+      XI(J)=0.
+      YI(J)=0.
+      VYI(J)=0.
+      ZI(J)=0.
+      VZI(J)=0.
+      THETA(1)=THETACAL(J-JN+1)
+c 	write (6,100) am(1),am(2),engy(1),engy(2),engy(3)
+        CALL KINE (AM,THETA,ENGY,RAT,PATR,KB)
+c 	write (6,1001)am(1),am(2),engy(1),engy(2),engy(3)
+        DELP(J)=100*(ENGY(3)-ENERGY)/(ENERGY)   
+        VXI(J)=THETACAL(J-JN+1)-THTSPEC
+        VXI(J)=VXI(J)*17.45329 
+ 4950 CONTINUE         
+c	write (*,*) ' after 4950'
+c       read (5,100) THTSPEC,TRGT2,AM(1),AM(2),QVALUE,EEXC
+C       write (6,100) THTSPEC,TRGT2,AM(1),AM(2),QVALUE,EEXC
+C	read (*,*)
+        ENGY(1)=QVALUE-EEXC 
+        ENGY(2)=EBEAM-TRGT2
+ 4952  CONTINUE        
+      GO TO 52
+C  ***********
+C  *********** end of addition to use KINE to get RAY entries
+C  *******************
+ 4940 DO 56  J=1,NR
+      READ(5,100,END=60 )XI(J),VXI(J),YI(J),VYI(J),ZI(J),VZI(J),DELP(J)
+   56 CONTINUE
+      GO TO 52
+   60 NR = J-1
+   52 DO 53 JEN=1,NEN
+C****
+C****
+C****
+      NP = IP
+      IF( (NP .LE. 100)  .OR.  (NP .GE. 200)  ) GO TO 65
+      IF( JEN   .EQ.   (NEN/2+1)  )  NP = IP-100
+   65 CONTINUE
+      IF( (NP .GT. 100)  .AND.  (JEN .NE. 1) )  GO TO 55
+c      WRITE(6, 105) NTITLE
+C%%%% WRITE(6, 117) DAET, TYME
+c%%%%
+c     call dtime
+c	ctemp=ctime(time())	 
+c	write(6,*) ctemp
+
+c%%%%
+c      WRITE(6, 116) EN0, PMOM0, VEL0, PMASS, Q0
+      DO 54  NO = 1,200
+      ITYPE = IDATA(NO)
+      IF( ITYPE .EQ. 1 ) GO TO 55
+   54 CALL PRNT( ITYPE, NO )
+   55 CONTINUE
+C**** IF( ( NP .GT. 100) .AND. (JEN .EQ. 1 ) ) WRITE(6, 106)
+      DO 57  J=1,NR
+c%%%  ibm pc statements %%%%%%%%%%%%%%
+c      write(0,5710) j
+ 5710 format (i5)
+c%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+      ENERGY = (1.+DELP(J)/100. ) *EN0
+      ETOT = EMASS + ENERGY
+      VEL = ( DSQRT( (2.*EMASS + ENERGY) *ENERGY) /ETOT)*C
+      PMOM =  DSQRT( (2.*EMASS + ENERGY) *ENERGY)
+      K = (Q0/ETOT)*9.D10
+C****
+      T = 0.
+      NUM = 0
+      XA = XI(J)
+      YA = YI(J)
+      ZA = ZI(J)
+      VXA =VEL*DSIN( VXI(J)/1000. ) * DCOS( VYI(J)/1000. )
+      VYA =VEL*DSIN( VYI(J)/1000. )
+      VZA =VEL*DCOS( VXI(J)/1000. ) * DCOS( VYI(J)/1000. )
+      XDVEL = (VEL-VEL0)*100./VEL0
+      DELTP = (PMOM-PMOM0)*100./PMOM0
+c      IF( NP .LE. 100) WRITE(6,108)J,ENERGY,PMOM,VEL,DELP(J),DELTP,XDVEL
+      DO 50 NO =1,200
+      ITYPE = IDATA(NO )
+      GO TO( 31,32,33,33,33,33,37,38,39,40,41,42,46,44,45)      ,ITYPE
+      CALL EXIT
+C****
+C****
+   32 CALL DIPOLE ( NO, NP, T, TP ,NUM )
+      GO TO 51
+   33 NCODE = ITYPE-2
+      CALL MULTPL ( NO, NP, T, TP ,NUM )
+      GO TO 51
+   37 IVEC = 1
+      CALL EDIPL(NO, NP, T, TP, NUM)
+      IVEC = 0
+      GO TO 51
+   38 IVEC = 1
+      CALL VELS   ( NO, NP, T, TP ,NUM )
+      IVEC = 0
+      GO TO 51
+   39 CALL POLES  ( NO, NP, T, TP ,NUM )
+      GO TO 51
+   40 CALL MULT   ( NO, NP, T, TP ,NUM )
+      GO TO 51
+   41 CALL SHROT  ( NO, NP, T, TP ,NUM )
+      GO TO 50
+   42 CALL DRIFT  ( NO, NP, T, TP ,NUM )
+      GO TO 50
+   44 CALL SOLND  ( NO, NP, T, TP ,NUM )
+      GO TO 51
+   45 CALL LENS   ( NO, NP, T, TP ,NUM )
+      GO TO 50
+   46 CALL COLL   ( NO,  J, IFLAG      )
+      IF( IFLAG .NE. 0 ) GO TO 57
+      GO TO 50
+   51 XA = TC(1)
+      YA = TC(2)
+      ZA = TC(3)
+      VXA= TC(4)
+      VYA= TC(5)
+      VZA= TC(6)
+   50 CONTINUE
+   31 CONTINUE
+      CALL OPTIC( J, JFOCAL, NP, T, TP )
+      IF (LPLT ) CALL PLTOUT ( JEN, J, NUM )
+   57 CONTINUE
+      ENERGY = EN0
+      VEL = VEL0
+      IF( NP .GT. 100 ) GO TO 59
+C      WRITE(6, 105) NTITLE
+C%%%% WRITE(6, 117) DAET,TYME
+C%%%%
+C%%%% call dtime
+c%%%%
+C      WRITE(6, 116) EN0, PMOM0, VEL0, PMASS, Q0
+      DO 58 NO =1,200
+      ITYPE = IDATA(NO )
+      IF ( ITYPE  .EQ.  1 ) GO TO 59
+   58 CALL PRNT( ITYPE, NO )
+   59 CONTINUE
+      IF( NSKIP .NE. 0 ) GO TO 61
+      IF( NR  .GE.  46  )  GO TO 62
+      IF( NR  .GE.  14  )  GO TO 63
+      IF( NR  .GE.   6  )  GO TO 64
+      GO TO 61
+   62 CALL MATRIX(R,T2)
+      GO TO 61
+   63 CONTINUE
+c   63 WRITE(6, 105) NTITLE
+C%%%% ICPU = ITCPU( )/100
+C%%%% WRITE(6, 117) DAET, TYME, ICPU
+C%%%%
+C%%%% call dtime
+C%%%%
+      CALL MTRX1( 0, JEN, NR, ENERGY  )
+      LNEN = 1
+      GO TO 61
+   64 CONTINUE
+c   64 WRITE(6, 105) NTITLE
+C%%%% ICPU = ITCPU( )/100
+C%%%% WRITE(6, 117) DAET, TYME, ICPU
+C%%%%
+C%%%% call dtime
+C%%%%
+      CALL MTRX1( 1, JEN, NR, ENERGY )
+      LNEN = 1
+   61 CALL PRNT1 ( NR )
+      EN0 = EN0 + DEN
+      ENERGY = EN0
+      ETOT = EMASS + EN0
+      VEL0 = ( DSQRT( ( 2.*EMASS + EN0)*EN0 ) /ETOT)*C
+      PMOM0 = DSQRT( (2.*EMASS + EN0)*EN0)
+   53 CONTINUE
+c      IF(  (LNEN .EQ. 0 )  .OR.   (NEN .EQ. 1 )  )  GO TO 5
+      IF(  (LNEN .EQ. 0 )  .OR.   (NEN .EQ. 1 )  ) THEN
+      close(5) 
+      RETURN
+      ENDIF
+c      WRITE(6, 105) NTITLE
+C**** CALL TIME(TYME)
+C%%%% ICPU = ITCPU( )/100
+C%%%% WRITE(6, 117) DAET, TYME, ICPU
+C%%%%
+C%%%% call dtime
+C%%%%
+C*IBM CALL WHEN(DAET)
+      CALL MPRNT( NEN )
+c      WRITE(6, 106)
+      GO TO 5
+      END
+
+
+      SUBROUTINE MATRIX( R, T2  )
+C****
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 1/  XI, YI, ZI, VXI, VYI, VZI, DELP
+      COMMON  /BLCK 2/  XO, YO, ZO, VXO, VYO, VZO,RTL(1000),RLL(1000)
+      DIMENSION XI(1000),YI(1000),ZI(1000),VXI(1000),VYI(1000),
+     1        VZI(1000),DELP(1000)
+      DIMENSION XO(1000),YO(1000),ZO(1000),VXO(1000),VYO(1000),VZO(1000)
+      DIMENSION  R(6,6) , T2(5,6,6), TT(5,6,6)
+      DO 21  I1= 1,6
+      DO 21  I2= 1,6
+      R(I1,I2) = 0.
+      DO 21 I3= 1,5
+   21 T2(I3,I1,I2) = 0.
+C****
+C****
+C**** CALCULATE COEFFICIENTS
+C****
+      R(1,1) =  ( XO(3) -  XO(4) ) / ( XI(3) -  XI(4) )
+      R(1,2) =  ( XO(5) -  XO(6) ) / (VXI(5) - VXI(6) )
+      R(1,3) =  ( XO(7) -  XO(8) ) / ( YI(7) -  YI(8) )
+      R(1,4) =  ( XO(9) -  XO(10)) / (VYI(9) - VYI(10))
+      R(1,6) =  ( XO(11)-  XO(12) )/ (DELP(11) - DELP(12) )
+      R(2,1) =  (VXO(3) - VXO(4) ) / ( XI(3) -  XI(4) )
+      R(2,2) =  (VXO(5) - VXO(6) ) / (VXI(5) - VXI(6) )
+      R(2,3) =  (VXO(7) - VXO(8) ) / ( YI(7) -  YI(8) )
+      R(2,4) =  (VXO(9) - VXO(10)) / (VYI(9) - VYI(10))
+      R(2,6) =  (VXO(11)- VXO(12) )/ (DELP(11) - DELP(12) )
+      R(3,1) =  ( YO(3) -  YO(4) ) / ( XI(3) -  XI(4) )
+      R(3,2) =  ( YO(5) -  YO(6) ) / (VXI(5) - VXI(6) )
+      R(3,3) =  ( YO(7) -  YO(8) ) / ( YI(7) -  YI(8) )
+      R(3,4) =  ( YO(9) -  YO(10)) / (VYI(9) - VYI(10))
+      R(3,6) =  ( YO(11)-  YO(12) )/ (DELP(11) - DELP(12) )
+      R(4,1) =  (VYO(3) - VYO(4) ) / ( XI(3) -  XI(4) )
+      R(4,2) =  (VYO(5) - VYO(6) ) / (VXI(5) - VXI(6) )
+      R(4,3) =  (VYO(7) - VYO(8) ) / ( YI(7) -  YI(8) )
+      R(4,4) =  (VYO(9) - VYO(10)) / (VYI(9) - VYI(10))
+      R(4,6) =  (VYO(11)- VYO(12) )/ (DELP(11) - DELP(12) )
+      R( 5,5 )  =  1.
+      R( 6,6 )  =  1.
+      R(5,1) =  (RTL(3) - RTL(4) ) / ( XI(3) -  XI(4) )
+      R(5,2) =  (RTL(5) - RTL(6) ) / (VXI(5) - VXI(6) )
+      R(5,6) =  (RTL(11)- RTL(12) )/ (DELP(11) - DELP(12) )
+C****
+C****
+      T2(1,1,1)= ( XO(3) + XO(4) ) /(2.*XI(3)**2 )
+      T2(1,2,2)= ( XO(5) + XO(6) ) /(2.*VXI(5)**2)
+      T2(1,3,3)= ( XO(7) + XO(8) ) /(2.*YI(7)**2 )
+      T2(1,4,4)= ( XO(9) + XO(10) ) /(2.*VYI(9)**2 )
+      T2(1,6,6)= ( XO(11) + XO(12) ) /(2.*DELP(11)**2 )
+      T2(1,1,2)= ( XO(13)+XO(14)-2.*T2(1,1,1)*XI(13)**2-2.*T2(1,2,2)*
+     1   VXI(13)**2 ) /(2.*XI(13)*VXI(13) )
+      T2(1,1,6)= ( XO(15) + XO(16) -2.*T2(1,1,1)*XI(15)**2 -
+     1  2.*T2(1,6,6)*DELP(15)**2 ) /(2.*XI(15)*DELP(15) )
+      T2(1,2,6)= ( XO(17) + XO(18) -2.*T2(1,2,2)*VXI(17)**2 -
+     1  2.*T2(1,6,6)*DELP(17)**2 ) /(2.*VXI(17)*DELP(17) )
+      T2(1,3,4)= ( XO(19)- XO(20) ) /(2.*YI(19)*VYI(19) )
+      T2(2,1,1)= (VXO(3) +VXO(4) ) /(2.*XI(3)**2 )
+      T2(2,2,2)= (VXO(5) +VXO(6) ) /(2.*VXI(5)**2)
+      T2(2,3,3)= (VXO(7) +VXO(8) ) /(2.*YI(7)**2 )
+      T2(2,4,4)= (VXO(9) +VXO(10) ) /(2.*VYI(9)**2 )
+      T2(2,6,6)= (VXO(11) +VXO(12) ) /(2.*DELP(11)**2 )
+      T2(2,1,2)=(VXO(13)+VXO(14)-2.*T2(2,1,1)*XI(13)**2-2.*T2(2,2,2)*
+     1   VXI(13)**2 ) /(2.*XI(13)*VXI(13) )
+      T2(2,1,6)= (VXO(15) +VXO(16) -2.*T2(2,1,1)*XI(15)**2 -
+     1  2.*T2(2,6,6)*DELP(15)**2 ) /(2.*XI(15)*DELP(15) )
+      T2(2,2,6)= (VXO(17) +VXO(18) -2.*T2(2,2,2)*VXI(17)**2 -
+     1  2.*T2(2,6,6)*DELP(17)**2 ) /(2.*VXI(17)*DELP(17) )
+      T2(2,3,4)= (VXO(19)-VXO(20) ) /(2.*YI(19)*VYI(19) )
+      T2(3,1,3)= ( YO(21) - YO(22) ) /(2.*XI(21)*YI(21) )
+      T2(3,1,4)= ( YO(23) - YO(24) ) /(2.*XI(23)*VYI(23) )
+      T2(3,2,3)= ( YO(25) - YO(26) ) /(2. *VXI(25)*YI(25) )
+      T2(3,2,4)= ( YO(27) - YO(28) ) /(2.*VXI(27)*VYI(27) )
+      T2(3,3,6)= ( YO(29) - YO(30) ) /(2.*YI(29)*DELP(29) )
+      T2(3,4,6)= ( YO(31) - YO(32) ) /(2.*VYI(31)*DELP(31)  )
+      T2(4,1,3)= (VYO(21) -VYO(22) ) /(2.*XI(21)*YI(21) )
+      T2(4,1,4)= (VYO(23) -VYO(24) ) /(2.*XI(23)*VYI(23) )
+      T2(4,2,3)= (VYO(25) -VYO(26) ) /(2. *VXI(25)*YI(25) )
+      T2(4,2,4)= (VYO(27) -VYO(28) ) /(2.*VXI(27)*VYI(27) )
+      T2(4,3,6)= (VYO(29) -VYO(30) ) /(2.*YI(29)*DELP(29) )
+      T2(4,4,6)= (VYO(31) -VYO(32) ) /(2.*VYI(31)*DELP(31)  )
+C****
+C**** PATH LENGTH TERMS
+C****
+      T2(5,1,1) = ( RTL(3) + RTL(4) - 2*RTL(1) ) /( 2* XI(3)**2 )
+      T2(5,2,2) = ( RTL(5) + RTL(6) - 2*RTL(1) ) /( 2*VXI(5)**2 )
+      T2(5,3,3) = ( RTL(7) + RTL(8) - 2*RTL(1) ) /( 2* YI(7)**2 )
+      T2(5,4,4) = ( RTL(9) + RTL(10)- 2*RTL(1) ) /( 2*VYI(9)**2 )
+      T2(5,6,6) = ( RTL(11)+ RTL(12)- 2*RTL(1) ) /( 2*DELP(11)**2 )
+      T2(5,1,2) = ( RTL(13)+ RTL(14)- 2*RTL(1) - 2*T2(5,1,1)* XI(13)**2-
+     1            2*T2(5,2,2)*VXI(13)**2 ) / ( 2* XI(13)*VXI(13) )
+      T2(5,1,6) = ( RTL(15)+ RTL(16)- 2*RTL(1) - 2*T2(5,1,1)* XI(15)**2-
+     1            2*T2(5,6,6)*DELP(15)**2) / ( 2* XI(15)*DELP(15))
+      T2(5,2,6) = ( RTL(17)+ RTL(18)- 2*RTL(1) - 2*T2(5,2,2)*VXI(17)**2-
+     1            2*T2(5,6,6)*DELP(17)**2) / ( 2*VXI(17)*DELP(17))
+      T2(5,3,4) = ( RTL(19)- RTL(20)           ) /( 2* YI(19)*VYI(19) )
+C****
+C****
+c      write (6, 22)  ( ( R(IR, IJ), IJ=1,6), IR=1,6)
+   22 FORMAT(1H1, / 51X, 15H *TRANSFORM* 1  ,  / 6(25X, 6F10.5/)  )
+c      write (6, 120)
+  120 FORMAT(   /46X, 25H  *2ND ORDER TRANSFORM*           )
+      DO 24 I1= 1,5
+      DO 25 I2= 1,6
+c      write (6, 121) ( I1,I3,I2, T2(I1,I3,I2), I3=1,I2 )
+  121 FORMAT( 6(I4,I2,I1, 1PE11.3)  )
+   25 CONTINUE
+c      write (6, 122)
+  122 FORMAT( 1H  )
+   24 CONTINUE
+      XTTT=((XO(33)- XO(34) )/2. - R(1,2)*VXI(33) )/VXI(33)**3
+      XTPP  = (XO(27) - XO(28) + XO(6) -XO(5))/(2.*VXI(27)*VYI(27)**2)
+      XXTT  = (XO(37) - XO(36) + XO(35)-XO(38)- 2.*(XO( 3) - XO( 4) ) )/
+     1   (4.*XI(35) * VXI(35)**2 )
+      XXXT  = (XO(35) - XO(37) + XO(36)-XO(38)- 2.*(XO(33) - XO(34) ) )/
+     1   (4.*XI(35)**2*VXI(35))
+      XTTD  = (XO(39) - XO(40) + XO(41)-XO(42)- 2.*(XO(11) - XO(12) ) )/
+     1   (4.*VXI(39)**2*DELP(39))
+      XTDD  = (XO(39) - XO(41) + XO(40)-XO(42)- 2.*(XO(33) - XO(34) ) )/
+     1   (4.*VXI(39)*DELP(39)**2)
+      XXPP  = (XO(23) - XO(24) + XO( 4)-XO( 3))/(2.*XI(23)*VYI(23)**2  )
+      XPPD  = (XO(31) - XO(32) + XO(12)-XO(11))/(2.*VYI(31)**2*DELP(31))
+      XTTTT=((XO(33)+XO(34) )/2. - T2(1,2,2)*VXI(33)**2)/ VXI(33)**4
+      XTTPP = (XO(27) - XO( 5) + XO(28)-XO( 6) - 2.*XO( 9) ) /
+     1   ( 2.*VXI(27)**2*VYI(27)**2 )
+      XPPDD = (XO(31) - XO(11) + XO(32)-XO(12) - 2.*XO( 9) ) /
+     1   ( 2.*VYI(31)**2 * DELP(31)**2 )
+      XPPPP =(XO(43) -T2(1,4,4)*VYI(43)**2) / VYI(43)**4
+      ZDDD = ( (RTL(45) - RTL(46) )/2. - R(5,6)*DELP(45) )/DELP(45)**3
+      ZDDDD = ( (RTL(45)+RTL(46)-2*RTL(1) )/2. -T2(5,6,6)*DELP(45)**2)/
+     1   DELP(45)**4
+      XDDD = (( XO(45)- XO(46))/2. - R(1,6)*DELP(45) ) / DELP(45)**3
+      XDDDD= (( XO(45)+ XO(46))/2. - T2(1,6,6)*DELP(45)**2 )/DELP(45)**4
+      TDDD = ((VXO(45)-VXO(46))/2. - R(2,6)*DELP(45) ) / DELP(45)**3
+      TDDDD= ((VXO(45)+VXO(46))/2. - T2(2,6,6)*DELP(45)**2 )/DELP(45)**4
+c      write (6, 26) XTTT, XTPP, XXTT, XXXT, XTTD, XTDD, XXPP, XPPD,
+c     1   XTTTT, XTTPP, XPPDD, XPPPP,
+c     2   XDDD, XDDDD, TDDD, TDDDD,      ZDDD, ZDDDD
+   26 FORMAT('1',/15X, 'X/THETA**3       =',1PE11.3   /
+     1            15X, 'X/THETA.PHI**2   =',1PE11.3   /
+     2            15X, 'X/X.THETA**2     =',1PE11.3   /
+     3            15X, 'X/X**2.THETA     =',1PE11.3   /
+     4            15X, 'X/THETA**2.DELTA =',1PE11.3   /
+     5            15X, 'X/THETA.DELTA**2 =',1PE11.3   /
+     6            15X, 'X/X.PHI**2       =',1PE11.3   /
+     7            15X, 'X/PHI**2.DELTA   =',1PE11.3   //
+     8            15X, 'X/THETA**4       =',1PE11.3   /
+     9            15X, 'X/THETA**2.PHI**2=',1PE11.3   /
+     A            15X, 'X/PHI**2.DELTA**2=',1PE11.3   /
+     B            15X, 'X/PHI**4         =',1PE11.3   //
+     C            15X, 'X/DELTA*3        =',1PE11.3   /
+     D            15X, 'X/DELTA*4        =',1PE11.3   /
+     E            15X, 'THETA/DELTA*3    =',1PE11.3   /
+     F            15X, 'THETA/DELTA*4    =',1PE11.3   /
+     H            15X, 'Z/DELTA*3        =',1PE11.3   /
+     I            15X, 'Z/DELTA*4        =',1PE11.3   )
+C
+C***********************************************************************
+C THE NEXT LINE TURNS OFF EXTRA FOCAL PLANE CALC'S
+        RETURN
+C***********************************************************************
+      DO 1  I1=1,5
+      DO 1  I2=1,6
+      DO 1  I3=1,6
+    1 TT(I1,I2,I3) = T2(I1,I2,I3)
+      DO 2 I=1,12
+      PSI =  5. * FLOAT(I)
+      TPSI = .001*DTAN( PSI/57.29578 )
+      TT(1,1,1) = T2(1,1,1) + R(2,1) * R(1,1) * TPSI
+      TT(1,1,2) = T2(1,1,2) + ( R(2,1)*R(1,2) + R(2,2)*R(1,1) ) * TPSI
+      TT(1,2,2) = T2(1,2,2) + R(2,2) * R(1,2) * TPSI
+      TT(1,1,6) = T2(1,1,6) + ( R(2,1)*R(1,6) + R(2,6)*R(1,1) ) * TPSI
+      TT(1,2,6) = T2(1,2,6) + ( R(2,2)*R(1,6) + R(2,6)*R(1,2) ) * TPSI
+      TT(1,6,6) = T2(1,6,6) + R(2,6) * R(1,6) * TPSI
+      TT(3,1,3) = T2(3,1,3) + R(1,1) * R(4,3) * TPSI
+      TT(3,1,4) = T2(3,1,4) + R(1,1) * R(4,4) * TPSI
+      TT(3,2,3) = T2(3,2,3) + R(1,2) * R(4,3) * TPSI
+      TT(3,2,4) = T2(3,2,4) + R(1,2) * R(4,4) * TPSI
+      TT(3,3,6) = T2(3,3,6) + R(1,6) * R(4,3) * TPSI
+      TT(3,4,6) = T2(3,4,6) + R(1,6) * R(4,4) * TPSI
+      CTTT=XTTT+ ( R(1,2)*T2(2,2,2) + R(2,2)*T2(1,2,2) ) * TPSI
+      CTPP=XTPP+ ( R(1,2)*T2(2,4,4) + R(2,2)*T2(1,4,4) ) * TPSI
+      CXTT=XXTT+ ( R(1,1)*T2(2,2,2) + R(1,2)*T2(2,1,2) +
+     1             R(2,1)*T2(1,2,2) + R(2,2)*T2(1,1,2) ) * TPSI
+      CXXT=XXXT+ ( R(1,1)*T2(2,1,2) + R(1,2)*T2(2,1,1) +
+     1             R(2,1)*T2(1,1,2) + R(2,2)*T2(1,1,1) ) * TPSI
+      CTTD=XTTD+ ( R(1,2)*T2(2,2,6) + R(1,6)*T2(2,2,2) +
+     1             R(2,2)*T2(1,2,6) + R(2,6)*T2(1,2,2) ) * TPSI
+      CTDD=XTDD+ ( R(1,2)*T2(2,6,6) + R(1,6)*T2(2,2,6) +
+     1             R(2,2)*T2(1,6,6) + R(2,6)*T2(1,2,6) ) * TPSI
+      CXPP=XXPP+ ( R(1,1)*T2(2,4,4) + R(2,1)*T2(1,4,4) ) * TPSI
+      CPPD=XPPD+ ( R(1,6)*T2(2,4,4) + R(2,2)*T2(1,4,4) ) * TPSI
+c      write (6, 27) PSI
+   27 FORMAT(1H1, 35X,'FOCAL PLANE TILT ANGLE= ',F07.2, '   DEGREES '  )
+c      write (6, 28)  ( ( R(IR, IJ), IJ=1,6), IR=1,6)
+   28 FORMAT(     / 51X, 15H *TRANSFORM* 1  ,  / 6(25X, 6F10.5/)  )
+c      write (6, 120)
+      DO 29 I1= 1,5
+      DO 30 I2= 1,6
+c      write (6, 121) ( I1,I3,I2, TT(I1,I3,I2), I3=1,I2 )
+   30 CONTINUE
+c      write (6, 122)
+   29 CONTINUE
+c      write (6, 26) CTTT, CTPP, CXTT, CXXT, CTTD, CTDD, CXPP, CPPD,
+c     1   XTTTT, XTTPP, XPPDD, XPPPP,
+c     2   XDDD, XDDDD, TDDD, TDDDD,      ZDDD, ZDDDD
+    2 CONTINUE
+      RETURN
+      END
+
+
+
+      SUBROUTINE  MLTT ( BFLD, Z, X, Y )
+C****
+C****
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  K, L
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLK100/  W, L, D, DG, S, BF, BT
+      COMMON  /BLK101/  C0, C1, C2, C3, C4, C5, C6, C7, C8
+      DIMENSION TC(6), DTC(6)
+      U = 2.*X/W
+      S = 2.*Z/L
+      DL2 = (L/D)**2
+      W1 = C0 + C1*U + C2*U*U + C3*U**3 + C4*U**4 + C5*U**5
+      W2 = 1. + C7*( S**4 + DL2*C8*S**8 ) / ( 1. + DL2*C8 )
+      BFLD = BF*W1 / W2
+      RETURN
+      END
+
+
+      SUBROUTINE MTRX1( M, JEN, NR, ENERGY  )
+C****
+C****
+C**** M=0  14 RAYS ARE USED TO EVALUATE THE ABERRATION COEFFICIENTS FOR
+C**** A POINT SOURCE OBJECT THROUGH 4'TH ORDER
+C**** M=1   6 RAYS ARE USED TO EVALUATE THE ABERRATION COEFFICIENTS FOR
+C**** A POINT SOURCE OBJECT THROUGH 4'TH ORDER; MIDPLANE ONLY
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8 KT, LP
+      character*8 L(2,50), LX(2,12)
+      LOGICAL LPLT
+      COMMON  /BLCK00/ LPLT
+      COMMON  /BLCK 1/ XI, YI, ZI, VXI, VYI, VZI, DELP
+      COMMON  /BLCK 2/ XO, YO, ZO, VXO, VYO, VZO,RTL(1000),RLL(1000)
+      COMMON /BLCK 3/ XOR,  YOR,  ZOR , TH0, PH0, TL1
+      DIMENSION XI(1000),YI(1000),ZI(1000),VXI(1000),VYI(1000), 
+     1     VZI(1000),DELP(1000)
+      DIMENSION XO(1000),YO(1000),ZO(1000),VXO(1000),VYO(1000),VZO(1000)
+      DIMENSION CXX(12,10), IX(12), CD(6,4),   LFACT(50), C(50,10)
+      DIMENSION DXX(21,10), DXY(21,10)
+      DATA IX/ 1,2,5,7,11,13,19,22,29,32,35,36  /
+      DATA LFACT / 1,0,1,0,2*4,2*3,4,3,2*7,2*6,2*7,2*6,3*10,3*9,
+     1   2*10,2*9,3*13,12,4,7,4,7,14*0   /
+      DATA  L  / 'X/TH    ','       =','T/TH    ','       =',
+     1           'Y/PH    ','       =','P/PH    ','       =',
+     2           'X/TH**2 ','       =','X/PH**2 ','       =',
+     3           'T/TH**2 ','       =','T/PH**2 ','       =',
+     4           'Y/TH*PH ','       =','P/TH*PH ','       =',
+     5           'X/TH**3 ','       =','X/TH*PH*','*2     =',
+     6           'T/TH**3 ','       =','T/TH*PH*','*2     =',
+     7           'Y/PH**3 ','       =','Y/TH**2*','PH     =',
+     8           'P/PH**3 ','       =','P/TH**2*','PH     =',
+     9           'X/TH**4 ','       =','X/TH**2*','PH**2  =',
+     A           'X/PH**4 ','       =','T/TH**4 ','       =',
+     B           'T/TH**2*','PH**2  =','T/PH**4 ','       =',
+     C           'Y/TH**3*','PH     =','Y/TH*PH*','*3     =',
+     D           'P/TH**3*','PH     =','P/TH*PH*','*3     =',
+     E           'X/TH**5 ','       =','X/TH**3*','PH**2  =',
+     F           'X/TH*PH*','*4     =','T/TH**5 ','       =',
+     G           'X/PH**2(','TRUNC.)=','X/TH*PH*','*2(TR.)=',
+     H           'X/T**2 (','TRUNC.)=','X/T**3 (','TRUNC.)=',
+     i            28*'        '/
+      DATA  LX / 'ENERGY(M','EV)    =','XOR (CM)','       =',
+     1           'YOR (CM)','       =','ZOR (CM)','       =',
+     2           'TH  (MR)','       =','PHI (MR)','       =',
+     3           ']XMAX](C','M)     =','2]YMAX](','CM)    =',
+     4           ']X-WAIST','](CM)  =','X(X-WAIS','T)     =',
+     5           'Z(X-WAIS','T)     =','LENGTH(C','M)     ='  /
+C****
+      MM=M
+C****
+      I   = JEN
+      IF( I   .GT. 10 ) I   = 10
+C****
+C****
+      XMIN = XO(1)
+      XMAX = XO(1)
+      YMAX = DABS(YO(1))
+      DO 4 J=2,NR
+      IF( XO(J) .GT. XMAX )  XMAX = XO(J)
+      IF( XO(J) .LT. XMIN )  XMIN = XO(J)
+      IF( DABS(YO(J) ) .GT. YMAX ) YMAX = DABS(YO(J))
+    4 CONTINUE
+      CXX(1,I  ) = ENERGY
+      CXX(2,I  ) = XOR
+      CXX(3,I  ) = YOR
+      CXX(4,I  ) = ZOR
+      CXX(5,I  )=TH0
+      CXX(6,I  )=PH0
+      CXX(7,I  ) = DABS(XMAX-XMIN)
+      CXX(8,I  ) = 2.*YMAX
+C****
+C****   CALCULATE BEAM WIDTH AT TEN EQUALLY SPACED (5MM)
+C****   DISTANCES EACH SIDE OF ZOR
+C****
+      DO 20 JJ=1,21
+      XMIN = XO(1) + 0.00050 * VXO(1) * (JJ-11)
+      XMAX = XMIN
+      DO 21 J = 2, 6
+      XJJ = XO(J) + 0.00050 *VXO(J) * (JJ-11)
+      IF (XJJ.GT.XMAX) XMAX = XJJ
+      IF (XJJ.LT.XMIN) XMIN = XJJ
+   21 CONTINUE
+      DXX(JJ,I) = DABS( XMAX - XMIN)
+      DXY(JJ,I) = 0.
+      IF (NR.LE.6) GOTO 20
+      DO 22 J=7,NR
+      XJJ = XO(J) + 0.00050* VXO(J) * (JJ-11)
+      IF ( XJJ.GT.XMAX ) XMAX = XJJ
+      IF ( XJJ.LT.XMIN ) XMIN = XJJ
+   22 CONTINUE
+      DXY(JJ,I) = DABS( XMAX - XMIN)
+   20 CONTINUE
+C****
+C**** CALCULATE POSITION OF MINIMUM BEAM WIDTH
+C**** WITHIN 10.0 CM OF ZOR
+      XMX = 1.0D20
+      DO 25  JJ=1, 101
+      XMIN = XO(1) + 0.00020 * VXO(1) * (JJ-51)
+      XMAX = XMIN
+      DO 26  J=2,NR
+      XJJ = XO(J) + 0.00020 * VXO(J) * (JJ-51)
+      IF ( XJJ.GT.XMAX ) XMAX = XJJ
+      IF ( XJJ.LT.XMIN ) XMIN = XJJ
+   26 CONTINUE
+      DXMAX = DABS( XMAX - XMIN )
+      IF ( DXMAX.GE.XMX ) GO TO 25
+      XMX = DXMAX
+      ZMX = 0.20 * (JJ - 51)
+   25 CONTINUE
+      IF ( DABS( ZMX ).GT.9.9 ) ZMX = 1.0D20
+      CXX( 9, I) = XMX
+      CXX(10, I) = .001*TH0*ZMX + XOR
+      CXX(11, I) = ZMX+ZOR
+      CXX(12, I) = TL1
+C****
+C****
+      IF( VXI(2) .EQ. 0. )  VXI(2) = 1.D-30
+      IF( VXI(3) .EQ. 0. )  VXI(3) = 1.D-30
+      KT = VXI(5)/VXI(3)
+      DTH = VXI(3)
+      TMAX = VXI(5)
+      PMAX = VYI(12)
+      XT=XO(2)/VXI(2)
+      TT=(KT**3*(VXO(3)-VXO(4))- VXO(5)+VXO(6))/(2.* (KT**3-KT)*DTH)
+      XTT = ( KT**4*(XO(3) + XO(4)) - (XO(5)+XO(6) )) /
+     1   (2.*(KT**4-KT**2) *DTH*DTH)
+      TTT = ( KT**4*(VXO(3)+VXO(4)) -(VXO(5)+VXO(6))) /
+     1   (2.*(KT**4-KT**2) *DTH*DTH)
+      XTTT  = ( KT**5 * ( XO(3) - XO(4) - 2.*XT*DTH ) -
+     1 ( XO(5) - XO(6) -2.*KT*XT*DTH) ) / (2.*(KT**5 - KT**3) *DTH**3 )
+      TTTT  = (-KT    * (VXO(3) -VXO(4)) + (VXO(5) -VXO(6) )  ) /
+     1   (2.*(KT**3 - KT   ) *DTH**3 )
+      XTTTT = ( (XO(5)+XO(6))-KT*KT*(XO(3)+XO(4) ) ) /
+     1   (2.*(KT**4 - KT*KT)*DTH**4 )
+      TTTTT =((VXO(5)+VXO(6))-KT*KT*(VXO(3)+VXO(4))) /
+     1   (2.*(KT**4 - KT*KT)*DTH**4 )
+      XTTTTT= ( XO(5) - XO(6) - 2.*KT*XT*DTH - KT**3*( XO(3) - XO(4) -
+     1   2.*XT*DTH) ) / ( 2.*(KT**5 - KT**3) *DTH**5 )
+      TTTTTT= 0.
+C****
+C****
+      C( 1,I)      = XT*10.
+      C( 2,I)      = TT
+      C( 5,I)      = XTT*10.**4
+      C( 7,I)      = TTT*10.**3
+      C(11,I)      = XTTT*10.**7
+      C(13,I)      = TTTT*10.**6
+      C(19,I)      = XTTTT*10.**10
+      C(22,I)      = TTTTT*10.**09
+      C(29,I)      = XTTTTT*10.**13
+      C(32,I)      = TTTTTT*10.**12
+      C(35,I)      = (XTT + XTTTT*TMAX*TMAX)*10.**4
+      C(36,I)      = (XTTT+XTTTTT*TMAX*TMAX)*10.**7
+C****
+C****
+      IF( M .NE. 0 ) GO TO 1
+      LP = VYI(12)/VYI(7)
+      DPH = VYI(7)
+      XPP   = (LP**4*XO(7) - XO(12)) /((LP**4 - LP*LP)*DPH*DPH )
+      TPP   = (LP**4*VXO(7)-VXO(12)) /((LP**4 - LP*LP)*DPH*DPH )
+      XPPPP = (XO(12)-LP*LP*XO(7) ) /((LP**4-LP*LP)*DPH**4)
+      TPPPP =(VXO(12)-LP*LP*VXO(7)) /((LP**4-LP*LP)*DPH**4)
+      XTPP  = (LP**4*( XO(8) - XO(9)) - ( XO(13) - XO(14)) - (LP**4-1.)*
+     1   ( XO(3) - XO(4)) -(( XO(10) - XO(11)) - KT*( XO(8) - XO(9) ) -
+     2   ( XO(5) - XO(6) ) + KT*( XO(3) - XO(4) ) ) *
+     3   ( ( LP**4 - LP*LP) / (KT**3-KT) ))/(2.*(LP**4-LP*LP)*
+     4   DTH*DPH*DPH )
+      TTPP  = 0.
+      XTTPP = ( ( XO(8)+XO(9) ) - ( XO(3)+XO(4) ) - 2.*XO(7)) /
+     1   (2.*DTH*DTH*DPH*DPH)
+      TTTPP = ( (VXO(8)+VXO(9)) - (VXO(3)+VXO(4)) -2.*VXO(7)) /
+     1   (2.*DTH*DTH*DPH*DPH)
+      YP    = ( LP**3 * YO(7) - YO(12) ) / ( (LP**3 - LP)*DPH )
+      PP    = ( LP**3 *VYO(7) -VYO(12) ) / ( (LP**3 - LP)*DPH )
+      YPPP  = (YO(12) - LP*YO(7)) /((LP**3-LP)*DPH**3 )
+      PPPP  =(VYO(12) -LP*VYO(7)) /((LP**3-LP)*DPH**3 )
+      YTTP  = ( YO(8) + YO(9) - 2.*YO(7) ) / (2.*DTH*DTH*DPH )
+      PTTP  = (VYO(8) +VYO(9) - 2.*VYO(7)) / (2.*DTH*DTH*DPH )
+      YTPPP = ( YO(13) - LP*YO(8) - YO(12) + LP*YO(7) ) /
+     1   ((LP**3 - LP)*DTH*DPH**3 )
+      PTPPP = (VYO(13) - LP*VYO(8)-VYO(12) + LP*VYO(7)) /
+     1   ((LP**3 - LP)*DTH*DPH**3 )
+      YTTTP = ( YO(10) - YO(11) -KT*(YO(8)-YO(9) ) ) /
+     1   (2.*(KT**3-KT) * DTH**3*DPH )
+      PTTTP = (VYO(10) -VYO(11) -KT*(VYO(8)-VYO(9))) /
+     1   (2.*(KT**3-KT) * DTH**3*DPH )
+      YTP   = ( (YO(10)-YO(11) -KT**3*(YO(8)-YO(9) ) ) /(2.*(KT-KT**3))-
+     1   YTPPP*DTH*DPH**3 ) /(DTH*DPH)
+      PTP   = ((VYO(10)-VYO(11)-KT**3*(VYO(8)-VYO(9))) /(2.*(KT-KT**3))-
+     1   PTPPP*DTH*DPH**3 ) /(DTH*DPH)
+      XTTTPP= ( XO(10) - XO(11) - KT*( XO(8) - XO(9)) - ( XO(5) - XO(6))
+     1   +KT*( XO(3) - XO(4) ) ) / (2.*(KT**3-KT) * DTH**3*DPH*DPH )
+      TTTTPP= 0.
+      XTPPPP= ( XO(13) - XO(14) - LP*LP*( XO(8) - XO(9)) + (LP*LP-1.) *
+     1   ( XO(3) - XO(4) ) ) / (2.*(LP**4-LP*LP) * DTH*DPH**4 )
+      TTPPPP= 0.
+      C( 3,I)      = YP*10.
+      C( 4,I)      = PP
+      C( 6,I)      = XPP*10.**4
+      C( 8,I)      = TPP*10.**3
+      C( 9,I)      = YTP*10.**4
+      C(10,I)      = PTP*10.**3
+      C(12,I)      = XTPP*10.**7
+      C(14,I)      = TTPP*10.**6
+      C(15,I)      = YPPP*10.**7
+      C(16,I)      = YTTP*10.**7
+      C(17,I)      = PPPP*10.**6
+      C(18,I)      = PTTP*10.**6
+      C(20,I)      = XTTPP*10.**10
+      C(21,I)      = XPPPP*10.**10
+      C(23,I)      = TTTPP*10.**09
+      C(24,I)      = TPPPP*10.**09
+      C(25,I)      = YTTTP*10.**10
+      C(26,I)      = YTPPP*10.**10
+      C(27,I)      = PTTTP*10.**09
+      C(28,I)      = PTPPP*10.**09
+      C(30,I)      = XTTTPP*10.**13
+      C(31,I)      = XTPPPP*10.**13
+      C(33,I)      = (XPP + XPPPP*PMAX*PMAX)*10.**4
+      C(34,I)      = (XTPP + XTTTPP*TMAX*TMAX +XTPPPP*PMAX*PMAX)*10.**7
+C****
+C****
+   13 FORMAT( 2I5 )
+   14 FORMAT(   )
+   15 FORMAT( //  , 8( 15X, 2A8,  F9.4 /  ) /,3( 15X, 2A8, F8.3/))
+   16 FORMAT(    15X, 2A8, 1PE12.3, 0PF15.4   )
+c      write (6, 15) ( ( LX(J,K),J=1,2),  CXX(K,I), K=1,12)
+      DO 2 JJ=1,36
+      COEF = C(JJ,I)/ 10.**LFACT(JJ)
+c      IF((JJ.EQ.5).OR.(JJ.EQ.11).OR.(JJ.EQ.19).OR.(JJ.EQ.29))
+c     1 write(6,14)
+c****
+    2 CONTINUE
+c    2 write (6, 16) (L(J,JJ), J=1,2), COEF, C(JJ,I)
+      GO TO 23
+C****
+C****
+    1 CONTINUE
+c      write (6, 15) (( LX(J,K),J=1,2),  CXX(K,I), K=1,12)
+      DO 3 JJ=1,12
+      K = IX(JJ)
+      COEF = C(K,I)/10.**LFACT(K)
+    3 CONTINUE
+c    3 write (6, 16) ( L(J,K),J=1,2), COEF, C(K,I)
+C****
+C****   PRINT OUT BEAM WIDTH
+C****
+   23 CONTINUE
+C**     write (6, 29)
+C**     DO 24 JJ=1, 21
+C**     DZ = 0.50 * (JJ-11)
+C**     write (6, 30) DZ, DXX(JJ,I), DXY(JJ,I)
+C**24   CONTINUE
+C**29   FORMAT ('1', 3X, 'IMAGE SIZE ]XMAX](CM)', //2X, 'DZ (CM)',
+C**  1  2X, '  1-6  ', 2X, '  1-NR')
+C**30   FORMAT (F8.2, 2F9.3)
+      RETURN
+C****
+C****
+      ENTRY MPRNT( NEN )
+C****
+      IF( LPLT) WRITE(2,13) NEN, MM
+   18 FORMAT(   4X, 2A8, 10F11.3      )
+      IF( NEN .GT. 10 )  NEN = 10
+c      write (6, 14)
+      DO 8 K=1,8
+      IF( LPLT ) WRITE(2,18)(LX(J,K),J=1,2),(CXX(K,I),I=1,NEN)
+    8 CONTINUE
+c    8 write (6, 18)   ( LX(J,K),J=1,2),(CXX(K,I),I=1,NEN)
+c      write (6, 14 )
+C****
+      IF(MM .NE. 0 )  GO TO 5
+      DO 7 K=1,36
+c      IF( (K.EQ.5).OR.(K.EQ.11).OR.(K.EQ.19).OR.(K.EQ.29))
+c     1 write(6,14)
+      IF( LPLT ) WRITE(2,18) (L(J,K),J=1,2),(C(K,I),I=1,NEN )
+    7 CONTINUE
+c    7 write (6, 18) ( L(J,K),J=1,2),(C(K,I),I=1,NEN )
+      GO TO 19
+    5 DO 6 JJ=1,12
+      K = IX(JJ)
+      IF( LPLT ) WRITE(2,18) ( L(J,K),J=1,2), ( C(K,I), I=1,NEN)
+    6 CONTINUE
+c    6 write (6, 18) ( L(J,K),J=1,2),(C(K,I), I=1,NEN )
+C****
+C**** CHROMATIC ABERRATION COEFFICIENTS
+C**** CALCULATED ONLY FOR CASE OF NEN= 5 ENERGIES
+C****
+   19 CONTINUE
+      IF( NEN .NE. 5 ) RETURN
+      DEL = CXX(1,4)/CXX(1,3) - 1.
+      DO 9 I=1,6
+      IF( I .EQ. 1 ) K=2
+      IF( I .EQ. 2 ) GO TO 10
+      IF( I .EQ. 3 ) K=5
+      IF( I .EQ. 4 ) K=11
+      IF( I .EQ. 5 ) K=19
+      IF( I .EQ. 6 ) K=29
+      IF( I .GT. 2 ) GO TO 11
+      X1 =(CXX(K,1) - CXX(K,3))/100.
+      X2 =(CXX(K,2) - CXX(K,3))/100.
+      X4 =(CXX(K,4) - CXX(K,3))/100.
+      X5 =(CXX(K,5) - CXX(K,3))/100.
+      GO TO 12
+   11 X1 = C(K,1) - C(K,3)
+      X2 = C(K,2) - C(K,3)
+      X4 = C(K,4) - C(K,3)
+      X5 = C(K,5) - C(K,3)
+   12 CD(I,1) = (8. *(X4-X2) - (X5-X1) )/(12.  *DEL)
+      CD(I,2) = (16.* (X4+X2) - (X5+X1) )/(24.  *DEL*DEL)
+      CD(I,3) = ( (X5-X1) - 2.*(X4-X2) )/(12.  *DEL**3)
+      CD(I,4) = ( (X5+X1) - 4.*(X4+X2) )/(24.  *DEL**4)
+      GO TO 9
+   10 Z1 =(CXX(4,1) - CXX(4,3))/100.
+      Z2 =(CXX(4,2) - CXX(4,3))/100.
+      Z4 =(CXX(4,4) - CXX(4,3))/100.
+      Z5 =(CXX(4,5) - CXX(4,3))/100.
+      TPSI = (8.* (Z4-Z2) - (Z5-Z1) ) / (8.* (X4-X2) - (X5-X1) )
+      PSI = 57.29578D0 * DATAN(TPSI)
+      DZ1 = Z1 - X1*TPSI
+      DZ2 = Z2 - X2*TPSI
+      DZ4 = Z4 - X4*TPSI
+      DZ5 = Z5 - X5*TPSI
+      CD(I,1) = -C(2,3)*( 8.*(DZ4-DZ2) - (DZ5-DZ1) )/(12.  *DEL)
+      CD(I,2) = -C(2,3)*( 16.*(DZ4+DZ2) - (DZ5+DZ1) )/(24.  *DEL*DEL)
+      CD(I,3) = -C(2,3)*( (DZ5-DZ1) - 2.*(DZ4-DZ2) )/(12.  *DEL**3)
+      CD(I,4) = -C(2,3)*( (DZ5+DZ1) - 4.*(DZ4+DZ2) )/(24.  *DEL**4)
+    9 CONTINUE
+c      write (6, 14)
+c      write (6, 17) PSI, (I,I=1,4), ( (CD(K,I),I=1,4), K=1,6 )
+      IF( LPLT ) WRITE(2,17) PSI, (I,I=1,4), ( ( CD(K,I),I=1,4), K=1,6 )
+   17 FORMAT(4X,'PSI            =', F11.3,/4X,'N              =',4(I7,
+     1  4X),/4X,'X/D**N         =',4F11.3,/4X,'X/T*D**N       =',4F11.3,
+     2      /4X,'X/T**2*D**N    =',4X,1P4E11.3,
+     3      /4X,'X/T**3*D**N    =',4X,1P4E11.3,
+     4      /4X,'X/T**4*D**N    =',4X,1P4E11.3,
+     5      /4X,'X/T**5*D**N    =',4X,1P4E11.3             )
+      RETURN
+      END
+
+      SUBROUTINE MULT   ( NO, NP, T, TP ,NUM )
+C****
+C****
+C**** MULTIPOLE     RAY TRACING BY NUMERICAL INTEGRATION OF DIFFERENTIAL
+C**** EQUATIONS OF MOTION.
+C     T = TIME
+C     TC(1) TO TC(6) =  ( X, Y, Z, VX, VY, VZ )
+C     DTC(1) TO DTC(6) = ( VX, VY, VZ, VXDOT, VYDOT, VZDOT )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  LF, K, L
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLK100/  W, L, D, DG, S, BF, BT
+      COMMON  /BLK101/  C0, C1, C2, C3, C4, C5, C6, C7, C8
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+      DIMENSION TC(6), DTC(6), DS(6), ES(6)
+      EXTERNAL BMULT
+C**** DATA  C/ 3.D10/
+C****
+      LF   = DATA(  1,NO )
+      DG   = DATA(  2,NO )
+      A    = DATA( 10,NO )
+      B    = DATA( 11,NO )
+      L    = DATA( 12,NO )
+      W    = DATA( 13,NO )
+      D    = DATA( 14,NO )
+      BF   = DATA( 15,NO )
+      Z1   = DATA( 16,NO )
+      Z2   = DATA( 17,NO )
+      C0   = DATA( 20,NO )
+      C1   = DATA( 21,NO )
+      C2   = DATA( 22,NO )
+      C3   = DATA( 23,NO )
+      C4   = DATA( 24,NO )
+      C5   = DATA( 25,NO )
+      C6   = DATA( 26,NO )
+      C7   = DATA( 27,NO )
+      C8   = DATA( 28,NO )
+      DTF = LF/VEL
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S = 0.
+C****
+      IF( NP  .GT. 100 ) GO TO 5
+c      write (6, 100) ITITLE(NO)
+  100 FORMAT(  ' MULTIPOLE  ****  ', A4,'  *************************'/)
+c      write (6, 101)
+  101 FORMAT( 8H    T CM ,18X, 4HX CM , 7X, 2HBX, 8X, 4HY CM , 7X, 2HBY,
+     1   8X, 4HZ CM, 7X, 2HBZ, 8X, 6HVELZ/C , 6X, 8HTHETA MR , 5X,
+     2   6HPHI MR , 6X, 1HB             )
+      CALL PRNT2 ( T,S,XA   ,YA   ,ZA   ,BX,BY,BZ,BT,VXA  ,VYA  ,VZA   )
+c      write (6, 103)
+  103 FORMAT(   '0COORDINATE TRANSFORMATION TO CENTERED AXIS SYSTEM ' )
+  109 FORMAT(   '0COORDINATE TRANSFORMATION TO D AXIS SYSTEM '       )
+C**** TRANSFORM FROM INITIAL ENTRANCE COORDINATES TO VFB COORD.
+C****
+    5 TC(1) =  XA
+      TC(2) = YA
+      TC(3) = ZA - (A+L/2.)
+      TC(4) =  VXA
+      TC(5) =  VYA
+      TC(6) =  VZA
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** TRANSLATE PARTICLE TO START OF FIRST FRINGE FIELD
+C****
+      TDT = ( Z1 - TC(3)  ) /DABS( TC(6) )
+C****
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+c      IF( NP  .LE. 100) write (6, 104)
+  104 FORMAT( 24H0MULTIPOLE FIELD REGION  )
+      CALL FNMIRK( 6, T, DTF ,TC, DTC, DS, ES, BMULT, 0    )
+      NSTEP = 0
+    6 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 7 I = 1, NP
+      CALL FNMIRK( 6, T, DTF ,TC, DTC, DS, ES, BMULT, 1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( Z2  .LE. TC(3) ) GO TO 8
+    7 CONTINUE
+      GO TO 6
+    8 CONTINUE
+      XDTF  =-( TC(3) - Z2  ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF ,TC, DTC, DS, ES,BMULT,  0    )
+      CALL FNMIRK( 6, T,XDTF ,TC, DTC, DS, ES,BMULT,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+  105 FORMAT( 10H   NSTEPS= ,I5 )
+C****
+C**** TRANSFORM TO OUTPUT SYSTEM COORD.
+C****
+      TC(3) = TC(3) - (B+L/2.)
+c      IF( NP  .LE. 100) write (6, 109)
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+C****
+C**** TRANSLATE PARTICLE TO OUT SYSTEM COORD.
+C****
+      TDT = -TC(3) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      TP = T * VEL
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S  = 0.
+      VXF    = 1000. *DATAN2( TC(4), TC(6)  )
+      VYF    = 1000. *DASIN ( TC(5)/ VEL    )
+      VZF    = TC(6) / VEL
+c      IF(NP.LE.100) write (6,115) TP,TC(1),TC(2),TC(3),VZF,VXF,VYF
+  115 FORMAT( F10.4, 10X, F10.3, 11X, F10.3, 11X, F10.3, 11X,
+     1   F13.5, F13.2, F11.2                   )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** CALCULATE INTERCEPTS IN SYSTEM D
+C****
+C****
+C****
+      Z0X = -TC(1)/ ( TC(4) / TC(6)    + 1.E-10 )
+      Z0Y = -TC(2)/ ( TC(5) / TC(6)    + 1.E-10 )
+c      IF(NP.LE.100) write (6,111) VXF, VYF, Z0X, Z0Y
+  111 FORMAT( / ' INTERSECTIONS WITH VER. AND HOR. PLANES '          ,
+     X       /15X, 5H  XP=,F10.4, 10H MR    YP=,F10.4, 3H MR  /
+     1        15X, 5H Z0X=,F10.2, 10H CM   Z0Y=,F10.2, 3H CM  /        )
+      RETURN
+   99 CALL PRNT4(NO, IN)
+      RETURN
+      END
+
+
+      SUBROUTINE MULTPL ( NO, NP, T, TP ,NUM )
+C****
+C****
+C**** QUADRUPOLE    RAY TRACING BY NUMERICAL INTEGRATION OF DIFFERENTIAL
+C**** EQUATIONS OF MOTION.
+C     T = TIME
+C     TC(1) TO TC(6) =  ( X, Y, Z, VX, VY, VZ )
+C     DTC(1) TO DTC(6) = ( VX, VY, VZ, VXDOT, VYDOT, VZDOT )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  LF1, LF2, LU1, K, L
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK 7/ NCODE
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK50/  D,BGRAD, S, BT
+      COMMON  /BLCK51/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK52/  IN
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+      DIMENSION TC(6), DTC(6), DS(6), ES(6)
+      EXTERNAL  BFLD
+C**** DATA  C/ 3.D10/
+C****
+      LF1  = DATA(  1,NO )
+      LU1  = DATA(  2,NO )
+      LF2  = DATA(  3,NO )
+      A    = DATA( 10,NO )
+      B    = DATA( 11,NO )
+      L    = DATA( 12,NO )
+      RAD  = DATA( 13,NO )
+      BF   = DATA( 14,NO )
+      Z11  = DATA( 15,NO )
+      Z12  = DATA( 16,NO )
+      Z21  = DATA( 17,NO )
+      Z22  = DATA( 18,NO )
+      DTF1= LF1/ VEL
+      DTF2= LF2/ VEL
+      DTU = LU1/ VEL
+      D = 2. * RAD
+      BGRAD = (-1)**NCODE * BF/RAD**NCODE
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S = 0.
+C****
+      IF( NP  .GT. 100 ) GO TO 5
+  201 FORMAT(  ' QUADRUPOLE  ****  ', A4, '  ***********************'/)
+  202 FORMAT(  ' HEXAPOLE    ****  ', A4, '  ***********************'/)
+  203 FORMAT(  ' OCTAPOLE    ****  ', A4, '  ***********************'/)
+  204 FORMAT(  ' DECAPOLE    ****  ', A4, '  ***********************'/)
+      GO TO ( 21, 22, 23, 24 ) , NCODE
+   21 CONTINUE
+c   21 write (6, 201) ITITLE(NO)
+      GO TO 25
+   22 CONTINUE
+c   22 write (6, 202) ITITLE(NO)
+      GO TO 25
+   23 CONTINUE
+c   23 write (6, 203) ITITLE(NO)
+      GO TO 25
+   24 CONTINUE
+c   24 write (6, 204) ITITLE(NO)
+   25 CONTINUE
+c   25 write (6, 101)
+  101 FORMAT( 8H    T CM ,18X, 4HX CM , 7X, 2HBX, 8X, 4HY CM , 7X, 2HBY,
+     1   8X, 4HZ CM, 7X, 2HBZ, 8X, 6HVELZ/C , 6X, 8HTHETA MR , 5X,
+     2   6HPHI MR , 6X, 1HB             )
+      CALL PRNT2 ( T,S,XA   ,YA   ,ZA   ,BX,BY,BZ,BT,VXA  ,VYA  ,VZA   )
+c      write (6, 103)
+  103 FORMAT(   '0COORDINATE TRANSFORMATION TO B AXIS SYSTEM '       )
+  109 FORMAT(   '0COORDINATE TRANSFORMATION TO D AXIS SYSTEM '       )
+C**** TRANSFORM FROM INITIAL ENTRANCE COORDINATES TO VFB COORD.
+C****
+    5 TC(1) = -XA
+      TC(2) = YA
+      TC(3) = A - ZA
+      TC(4) = -VXA
+      TC(5) = VYA
+      TC(6) = -VZA
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** TRANSLATE PARTICLE TO START OF FIRST FRINGE FIELD
+C****
+      TDT = ( TC(3) - Z11 ) /DABS( TC(6) )
+C****
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** IN DESIGNATES FIELD REGIONS FOR QUADRUPOLE
+C****
+      IN = 1
+      C0   = DATA( 19,NO )
+      C1   = DATA( 20,NO )
+      C2   = DATA( 21,NO )
+      C3   = DATA( 22,NO )
+      C4   = DATA( 23,NO )
+      C5   = DATA( 24,NO )
+c      IF( NP  .LE. 100) write (6, 104)
+  104 FORMAT( 22H0FRINGING FIELD REGION    )
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BFLD , 0    )
+      NSTEP = 0
+    6 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 7 I = 1, NP
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BFLD , 1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( Z12 .GE. TC(3) ) GO TO 8
+    7 CONTINUE
+      GO TO 6
+    8 CONTINUE
+      XDTF1 =-( Z12 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES,BFLD ,  0    )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES,BFLD ,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+  105 FORMAT( 10H   NSTEPS=  ,I5 )
+C***
+C***  UNIFORM FIELD REGION
+C**** TRANSFORM TO SECOND VFB COORD SYSTEM
+C***
+      BGRAD = (-1)**NCODE *  BGRAD
+      TC(1) = -TC(1)
+      TC(3) = -TC(3) - L
+      TC(4) = -TC(4)
+      TC(6) = -TC(6)
+C****
+C****
+C**** UNIFORM FIELD INTEGRATION REGION
+C****
+C****
+      IN = 2
+c      IF( NP  .LE. 100) write (6, 106)
+  106 FORMAT(   '0UNIFORM FIELD REGION IN C AXIS SYSTEM '  )
+      IF( TC(3)  .LT.  Z21 ) GO TO 15
+C****
+C**** THIS SECTION CORRECTS FOR MAGNETS WHOSE FRINGING FIELDS INTERSECT
+C****
+c      IF( NP  .LE. 100) write (6, 102)
+  102 FORMAT( / '   INTEGRATE BACKWARDS    '  )
+      CALL FNMIRK( 6, T,-DTU ,TC, DTC, DS, ES, BFLD,  0    )
+      NSTEP = 0
+   16 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 17  I =1, NP
+      CALL FNMIRK( 6, T,-DTU, TC, DTC, DS, ES, BFLD,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3)  .LE.  Z21 )  GO TO 18
+   17 CONTINUE
+      GO TO 16
+   18 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, BFLD,  0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, BFLD,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+c      IF( NP  .LE. 100) write (6, 107)
+  107 FORMAT( / )
+C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+C%%%%
+      IF(TC(3).GE.Z21) GO TO 11
+      GO TO 9
+C%%%% GO TO 19    ...   REMOVED IN FAVOR OF ABOVE TWO STATEMENTS  T.M.C.
+C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+C****
+C****
+   15 CONTINUE
+      CALL FNMIRK( 6, T, DTU ,TC, DTC, DS, ES, BFLD , 0    )
+      NSTEP = 0
+    9 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 10  I =1, NP
+      CALL FNMIRK( 6, T, DTU ,TC, DTC, DS, ES, BFLD , 1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+   19 CONTINUE
+      IF( TC(3)  .GE.  Z21 )  GO TO 11
+   10 CONTINUE
+      GO TO 9
+   11 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES,BFLD ,  0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES,BFLD ,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+C***
+C***
+C**** SETUP FOR SECOND FRINGE FIELD AND INTEGRATION
+C****
+C****
+      C0   = DATA( 25,NO )
+      C1   = DATA( 26,NO )
+      C2   = DATA( 27,NO )
+      C3   = DATA( 28,NO )
+      C4   = DATA( 29,NO )
+      C5   = DATA( 30,NO )
+      IN = 3
+c      IF( NP  .LE. 100) write (6, 104)
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, BFLD , 0    )
+      NSTEP = 0
+   12 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 13  I =1, NP
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, BFLD , 1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3) .GE. Z22 )  GO TO 14
+   13 CONTINUE
+      GO TO 12
+   14 CONTINUE
+      XDTF2 = ( Z22 - TC(3) ) / TC(6)
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BFLD , 0    )
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BFLD , 1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+C****
+C**** TRANSFORM TO OUTPUT SYSTEM COORD.
+C****
+      TC(3) = TC(3) - B
+c      IF( NP  .LE. 100) write (6, 109)
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+C****
+C**** TRANSLATE PARTICLE TO OUT SYSTEM COORD.
+C****
+      TDT = -TC(3) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      TP = T * VEL
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S  = 0.
+      VXF    = 1000. *DATAN2( TC(4), TC(6)  )
+      VYF    = 1000. *DASIN ( TC(5)/ VEL    )
+      VZF    = TC(6) / VEL
+c      IF(NP.LE.100) write (6, 115)TP,TC(1),TC(2),TC(3),VZF,VXF,VYF
+  115 FORMAT( F10.4, 10X, F10.3, 11X, F10.3, 11X, F10.3, 11X,
+     1   F13.5, F13.2, F11.2                   )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 4
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** CALCULATE INTERCEPTS IN SYSTEM D
+C****
+C****
+C****
+      Z0X = -TC(1)/ ( TC(4) / TC(6)    + 1.E-10 )
+      Z0Y = -TC(2)/ ( TC(5) / TC(6)    + 1.E-10 )
+c      IF( NP  .LE. 100) write (6, 111) VXF, VYF, Z0X, Z0Y
+  111 FORMAT( / ' INTERSECTIONS WITH VER. AND HOR. PLANES '          ,
+     X       /15X, 5H  XP=,F10.4, 10H MR    YP=,F10.4, 3H MR  /
+     1        15X, 5H Z0X=,F10.2, 10H CM   Z0Y=,F10.2, 3H CM  /        )
+      RETURN
+   99 CALL PRNT4 (NO, IN)
+      RETURN
+      END
+
+
+      SUBROUTINE BDIP
+C****
+C****
+C**** MTYP=1  :    UNIFORM FIELD STANDARD APPROXIMATION
+C**** MTYP=2  :    UNIFORM FIELD MODIFIED ITERATIVE PROCEDURE
+C**** MTYP=3  :    NONUNIFORM FIELD STANDARD APPROXIMATION
+C**** MTYP=4  :    NONUNIFORM FIELD  B=BF/(1+N*DR/R)
+C**** MTYP=5  :    UNIFORM FIELD, CIRCULAR POLE OPTION
+C**** MTYP=6  :    PRETZEL MAGNET
+C****
+C**** THE RELATIONSHIP BETWEEN B0, ......... B12 AND B(I,J) RELATIVE TO
+C**** AXES (Z,X) IS GIVEN BY
+C****
+C****
+C****
+C**** B0  = B( 0, 0 )
+C**** B1  = B( 1, 0 )
+C**** B2  = B( 2, 0 )
+C**** B3  = B( 1, 1 )
+C**** B4  = B( 1,-1 )
+C**** B5  = B( 0, 1 )
+C**** B6  = B( 0, 2 )
+C**** B7  = B( 0,-1 )
+C**** B8  = B( 0,-2 )
+C**** B9  = B(-1, 0 )
+C**** B10 = B(-2, 0 )
+C**** B11 = B(-1, 1 )
+C**** B12 = B(-1,-1 )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  NDX, K
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK20/  NDX,BET1,GAMA,DELT,CSC
+      COMMON  /BLCK21/  RCA,DELS,BR,S2,S3,S4,S5,S6,S7,S8,SCOR
+      COMMON  /BLCK22/  D, DG, S, BF, BT
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION TC(6), DTC(6)
+      DIMENSION XX(11), ZZ(11), DD(11)
+      DATA PI2   / 1.570796325D0       /
+      DATA PI4   / .7853981625D0       /
+      DATA RT2   /  1.41421356D0       /
+C****
+C****
+      GO TO ( 10,10,6,6,10,21 )     ,MTYP
+      CALL EXIT
+      RETURN
+    6 CALL NDIP
+      RETURN
+   21 CALL BPRETZ
+      RETURN
+C****
+C**** MTYP = 1 , 2, 5
+C**** UNIFORM FIELD MAGNETS
+C****
+   10 CONTINUE
+      GO TO( 2, 1, 2, 4 ) , IN
+    7 CONTINUE
+c    7 write(6,8) IN
+    8 FORMAT(  35H0 ERROR -GO TO -  IN BFUN   IN=        ,I5  )
+    1 BX = 0.
+      BY = BF
+      BZ = 0.
+      BT = BF
+      RETURN
+    2 X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      IF( MTYP .NE. 2 ) GO TO 9
+C****
+C**** MTYP=2  :    UNIFORM FIELD MODIFIED ITERATIVE PROCEDURE
+C****
+      XP = X
+      XP2 = XP*XP
+      XP3 = XP2*XP
+      XP4 = XP3 * XP
+      ZP = -(S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+     1       S7*XP4*XP3 + S8*XP4*XP4 )
+      AZ = (Z-ZP)/5.D0
+      DO 11 I=1,11
+      XP    = X + AZ*(I-6)
+      XP2 = XP*XP
+      XP3 = XP2*XP
+      XP4 = XP3*XP
+      ZP = -(S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+     1       S7*XP4*XP3 + S8*XP4*XP4 )
+      XXP = X-XP
+      ZZP = Z-ZP
+      XX(I) = XP
+      ZZ(I) = ZP
+      DD(I) = ( XXP*XXP + ZZP*ZZP )
+   11 CONTINUE
+C****
+C**** SEARCH FOR SHORTEST OF THE 11 DISTANCES
+C****
+      XP = XX(1)
+      ZP = ZZ(1)
+      DP = DD(1)
+      DO 12 I=2,11
+      IF( DD(I) .GE. DP ) GO TO 12
+      XP = XX(I)
+      ZP = ZZ(I)
+      DP = DD(I)
+   12 CONTINUE
+C****
+C****  DIVIDE INTERVAL AND REPEAT FOR MORE EXACT
+C****  SHORTEST DISTANCE.
+C****
+      AZ = AZ/5.D0
+      X1 = XP
+      DO 13 I=1,11
+      XP    = X1+ AZ*(I-6)
+      XP2 = XP*XP
+      XP3 = XP2*XP
+      XP4 = XP3*XP
+      ZP = -(S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+     1       S7*XP4*XP3 + S8*XP4*XP4 )
+      XXP = X-XP
+      ZZP = Z-ZP
+      XX(I) = XP
+      ZZ(I) = ZP
+      DD(I) = ( XXP*XXP + ZZP*ZZP )
+   13 CONTINUE
+C****
+C**** SEARCH FOR SHORTEST OF THE 11 DISTANCES
+C****
+      XP = XX(1)
+      ZP = ZZ(1)
+      DP = DD(1)
+      DO 15 I=2,11
+      IF( DD(I) .GE. DP ) GO TO 15
+      XP = XX(I)
+      ZP = ZZ(I)
+      DP = DD(I)
+   15 CONTINUE
+C****
+C**** ITERATION LOOP FOR MORE EXACT SHORTEST DISTANCE
+C****
+C*    ZSIGN = Z-ZP
+C*    XP2 = XP*XP
+C*    XP3 = XP2*XP
+C*    XP4 = XP3*XP
+C*    DO 13 I=1,3
+C****
+C**** SLOPE OF CURVE AT XP, ZP
+C****
+C*    DZDXC = -(2.*S2*XP + 3.*S3*XP2+ 4.*S4*XP3 + 5.*S5*XP4 +
+C*   1   6.*S6*XP4*XP + 7.*S7*XP4*XP2 + 8.*S8*XP4*XP3 )
+C****
+C**** NEXT APPROXIMATION TO CLOSEST POINT IS
+C****
+C*    XP = ( DZDXC*(Z-ZP)  +  DZDXC*DZDXC*XP + X ) / (1.+DZDXC*DZDXC)
+C*    IF( I  .EQ.  1 )  XP = (3.*XP +  X ) / 4.
+C*    XP2 = XP*XP
+C*    XP3 = XP2*XP
+C*    XP4 = XP3*XP
+C*    ZP = -( S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+C*   1   S7*XP4*XP3 + S8*XP4*XP4 )
+C* 13 CONTINUE
+C*    XXP = X-XP
+C*    ZZP = Z-ZP
+C****
+C****
+      ZSIGN = Z-ZP
+      XP2 = XP*XP
+      XP3 = XP2*XP
+      XP4 = XP3*XP
+      S = DSIGN( 1.D0,ZSIGN) * DSQRT(DP)                 / D + DELS
+      SCON = S
+C****
+C**** TRIM CORRECTION FOR EFFECTIVE EDGE CURVATURE
+C****
+      DZDXC = -(2.*S2*XP + 3.*S3*XP2+ 4.*S4*XP3 + 5.*S5*XP4 +
+     1   6.*S6*XP4*XP + 7.*S7*XP4*XP2 + 8.*S8*XP4*XP3 )
+      DZDXC2= -(2.*S2+6.*S3*XP +12.*S4*XP2 +20.*S5*XP3 +30.*S6*XP4 +
+     1         42.*S7*XP4*XP +56.*S8*XP4*XP2 )
+      RCR = DZDXC2 / DSQRT( 1.D0 + DZDXC*DZDXC ) **3
+      S = S + SCOR*D*RCR
+      S0 = S
+      CALL BDPP( B0, Z, X, Y )
+      IF( Y .NE. 0. ) GO TO 14
+      BX = 0.
+      BY = B0
+      BZ = 0.
+      BT = B0
+      RETURN
+   14 GD = DG/D
+      DELTA = DATAN(DZDXC)
+      SCON = (1.D0 + SCON*D*RCR) *GD*DG*RCR/2.D0
+      DCS = DCOS( DELTA         )
+      S = S0-  SCON*( 1.D0 - DCS*DCS ) +      GD*DCS
+      CALL BDPP( B1 , Z, X, Y )
+      S =S0-4.*SCON*( 1.D0 - DCS*DCS ) +   2.*GD*DCS
+      CALL BDPP( B2 , Z, X, Y )
+      S = S0-  SCON*( 1.D0 - DCS*DCS ) -      GD*DCS
+      CALL BDPP( B9 , Z, X, Y )
+      S =S0-4.*SCON*( 1.D0 - DCS*DCS ) -   2.*GD*DCS
+      CALL BDPP( B10, Z, X, Y )
+      DCS = DCOS( DELTA + PI4   )
+      S =S0-2.*SCON*( 1.D0 - DCS*DCS ) +  RT2*GD*DCS
+      CALL BDPP( B3 , Z, X, Y )
+      S =S0-2.*SCON*( 1.D0 - DCS*DCS ) -  RT2*GD*DCS
+      CALL BDPP( B12, Z, X, Y )
+      DCS = DCOS( DELTA - PI4   )
+      S =S0-2.*SCON*( 1.D0 - DCS*DCS ) +  RT2*GD*DCS
+      CALL BDPP( B4 , Z, X, Y )
+      S =S0-2.*SCON*( 1.D0 - DCS*DCS ) -  RT2*GD*DCS
+      CALL BDPP( B11, Z, X, Y )
+      DCS = DCOS( DELTA + PI2   )
+      S = S0-  SCON*( 1.D0 - DCS*DCS ) +      GD*DCS
+      CALL BDPP( B5 , Z, X, Y )
+      S =S0-4.*SCON*( 1.D0 - DCS*DCS ) +   2.*GD*DCS
+      CALL BDPP( B6 , Z, X, Y )
+      S = S0-  SCON*( 1.D0 - DCS*DCS ) -      GD*DCS
+      CALL BDPP( B7 , Z, X, Y )
+      S =S0-4.*SCON*( 1.D0 - DCS*DCS ) -   2.*GD*DCS
+      CALL BDPP( B8 , Z, X, Y )
+      GO TO 5
+    9 CALL BDPP ( B0, Z, X, Y )
+      S0 = S
+      IF( Y .NE. 0. )   GO TO 3
+      BX = 0.
+      BY = B0
+      BZ = 0.
+      BT = B0
+      RETURN
+    3 CALL BDPP ( B1 , Z + DG, X , Y )
+      CALL BDPP ( B2 , Z + 2.*DG, X , Y )
+      CALL BDPP ( B3 , Z + DG, X + DG , Y )
+      CALL BDPP ( B4 , Z + DG, X - DG , Y )
+      CALL BDPP ( B5 , Z , X + DG , Y )
+      CALL BDPP ( B6 , Z , X + 2.*DG , Y )
+      CALL BDPP ( B7 , Z , X - DG , Y )
+      CALL BDPP ( B8 , Z , X - 2.*DG , Y )
+      CALL BDPP ( B9 , Z - DG, X , Y )
+      CALL BDPP ( B10, Z - 2.*DG, X , Y )
+      CALL BDPP ( B11, Z - DG, X + DG , Y )
+      CALL BDPP ( B12, Z - DG, X - DG , Y )
+    5 CONTINUE
+      S = S0
+      YG1 = Y/DG
+      YG2 = YG1**2
+      YG3 = YG1**3
+      YG4 = YG1**4
+      BX = YG1 * ( (B5-B7)*2./3. - (B6-B8)/12. )  +
+     1     YG3*( (B5-B7)/6. - (B6-B8)/12. -
+     2     (B3 + B11 - B4 - B12 - 2.*B5 + 2.*B7 ) / 12. )
+      BY = B0 - YG2*( ( B1 + B9 + B5 + B7 - 4.*B0 ) *2./3. -
+     1     ( B2 + B10 + B6 + B8 - 4.*B0 ) / 24. ) +
+     2     YG4* (-( B1 + B9 + B5 + B7 - 4.*B0 ) / 6. +
+     3     ( B2 + B10 + B6 + B8 - 4.*B0 ) / 24. +
+     4     ( B3 + B11 + B4 + B12 - 2.*B1 - 2.*B9 -
+     5     2.*B5 - 2.*B7 + 4.*B0 ) / 12. )
+      BZ = YG1*( (B1 - B9 ) *2./3. - ( B2 - B10 ) /12. ) +
+     1     YG3*( ( B1 - B9 ) / 6. - ( B2 - B10 ) / 12. -
+     2     ( B3 + B4 - B11 - B12 - 2.*B1 + 2.*B9 ) / 12.  )
+      BT = DSQRT(BX*BX + BY*BY + BZ*BZ)
+      RETURN
+    4 BX = 0.
+      BY = BR
+      BZ = 0.
+      BT = BR
+      RETURN
+      END
+
+
+      SUBROUTINE  BDPP ( BFLD, Z, X, Y )
+C****
+C****
+C****
+C**** MTYP=1  :    UNIFORM FIELD STANDARD APPROXIMATION
+C**** MTYP=2  :    UNIFORM FIELD MODIFIED ITERATIVE PROCEDURE
+C****              MORE ACCURATE 3'RD AND HIGHER ORDER CURVATURES
+C**** MTYP=5  :    UNIFORM FIELD, CIRCULAR POLE OPTION
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  NDX, K
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK20/  NDX,BET1,GAMA,DELT,CSC
+      COMMON  /BLCK21/  RCA,DELS,BR,S2,S3,S4,S5,S6,S7,S8,SCOR
+      COMMON  /BLCK22/  D, DG, S, BF, BT
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION TC(6), DTC(6)
+C****
+      GO TO (10,13,6,6,11 ) ,MTYP
+    6 CALL EXIT
+      RETURN
+C****
+C**** MTYP=1  :    UNIFORM FIELD STANDARD APPROXIMATION
+C****
+   10 X2=X*X
+      X3=X*X2
+      X4=X*X3
+      S = (    Z   +S2*X2 + S3*X3 + S4*X4 + S5*X*X4 + S6*X2*X4 +
+     1   S7*X3*X4 + S8*X4*X4  ) / D + DELS
+      GO TO 13
+C****
+C**** MTYP=5  :    UNIFORM FIELD, CIRCULAR POLE OPTION
+C****
+   11 IF( DABS(RCA)  .GE. 1.D-08  ) GO TO 12
+      S = Z/D + DELS
+      GO TO 13
+   12 A = 1./RCA
+      S = ( DSIGN(1.D0,A) * DSQRT( (Z+A)**2 + X*X ) - A ) / D + DELS
+   13 CS=C0+S*(C1+S*(C2+S*(C3+S*(C4+S*C5))))
+      IF( DABS(CS)  .GT.  70.  )  CS =DSIGN( 70.D0 ,CS  )
+      E=DEXP(CS)
+      P0 = 1.0 + E
+      DB=BF-BR
+      BFLD=BR + DB/P0
+C****
+C**** write (6, 100) X, Y, Z,  DR, S, BFLD
+C*100 FORMAT( 1P6D15.4 )
+C****
+      RETURN
+      END
+
+
+      SUBROUTINE BEFN (F,Z,X,Y,DR,IBEX)
+C****
+C****
+C****    CALCULATES S, THEN DETERMINES B (OR E) FIELD.
+C****
+C****
+C****
+C**** IBEX = 0   MAGNETIC FIELD COMPONENTS
+C****      = 1   ELECTRIC FIELD COMPONENTS
+C****
+      IMPLICIT  REAL*8 (A-H,O-Z)
+      REAL*8 NDX
+      COMMON /BLCK71/  CB0,CB1,CB2,CB3,CB4,CB5
+      COMMON /BLCK72/  CE0,CE1,CE2,CE3,CE4,CE5
+      COMMON /BLCK73/  IN,NFLAG
+      COMMON /BLCK74/  BF,EF,S,DG
+      COMMON /BLCK75/  BC2,BC4,EC2,EC4
+      COMMON /BLCK76/  DB,DE,WB,WE
+      COMMON /BLCK77/  RB,NDX
+C****
+      IF (IBEX .NE. 0 ) GO TO 10
+C****
+C**** MAGNETIC FIELD COMPONENTS
+C****
+      F1 = BF
+      D = DB
+      C02 = BC2
+      C04 = BC4
+      W2 = WB*WB
+      C0 = CB0
+      C1 = CB1
+      C2 = CB2
+      C3 = CB3
+      C4 = CB4
+      C5 = CB5
+      GO TO 20
+C****
+C**** ELECTRIC FIELD COMPONENTS
+C****
+   10 F1 = EF
+      IF( IN .EQ. 1 ) F1 = -EF
+      D = DE
+      C02 = EC2
+      C04 = EC4
+      W2 = WE*WE
+      C0 = CE0
+      C1 = CE1
+      C2 = CE2
+      C3 = CE3
+      C4 = CE4
+      C5 = CE5
+   20 ZD1 = Z/D
+      ZD2 = C02*ZD1*X*X/W2
+      W4 = W2*W2
+      ZD3 = C04*(X**4)/W4
+      S = ZD1+ZD2+ZD3
+      CS = C0+S*(C1+S*(C2+S*(C3+S*(C4+S*C5))))
+      IF ( DABS(CS) .GT. 70. ) CS = DSIGN ( 70.D0,CS )
+      E = DEXP(CS)
+      P0 = 1.0+E
+      F = F1/P0
+      IF( IBEX  .EQ.  1) RETURN
+      IF( NFLAG .EQ.  1) F=F*(1.D0 - (F/F1)*NDX*DR/RB)
+      RETURN
+      END
+
+
+      SUBROUTINE BEVC
+C****
+C****  CALCULATES B AND E FIELDS
+C****
+C****
+C****
+C**** NFLAG = 0      UNIFORM FIELD MAGNETIC DIPOLE
+C****       = 1  NON-UNIFORM FIELD MAGNETIC DIPOLE
+      IMPLICIT     REAL*8 (A-H,O-Z)
+      REAL*8 K,NDX
+      COMMON /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON /BLCK11/  EX, EY, EZ, QMC, IVEC
+      COMMON /BLCK71/  CB0,CB1,CB2,CB3,CB4,CB5
+      COMMON /BLCK72/  CE0,CE1,CE2,CE3,CE4,CE5
+      COMMON /BLCK73/  IN,NFLAG
+      COMMON /BLCK74/  BF,EF,S,DG
+      COMMON /BLCK77/  RB,NDX
+      DIMENSION TC(6),DTC(6),BEF(3)
+C****
+      GO TO (2,1,2) , IN
+c      write (6,  100) IN
+  100 FORMAT (  35H0 ERROR -GO TO -  IN BFUN   IN=     ,I5 )
+C****
+C**** UNIFORM FIELD REGION
+C****
+    1 BX = 0.
+      BY = BF
+      BZ = 0.
+      EX = EF
+      EY = 0.
+      EZ = 0.
+      IF( NFLAG .EQ. 0 ) RETURN
+      X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      DR =X
+      RP = X+RB
+      IF( RP .LE. 0. ) RP = 1.D-20
+      DRR1 = DR/RB
+      IF( Y .NE. 0. )  GO TO 14
+C****
+C**** MID-PLANE UNIFORM FIELD REGION
+C****
+      BY = BF* ( 1. - NDX*DRR1 )
+      RETURN
+C****
+C**** NON MID-PLANE UNIFORM FIELD REGION
+C****
+   14 YR1 = Y/RB
+      YR2 = YR1*YR1
+      YR3 = YR2*YR1
+      YR4 = YR3*YR1
+      RR1 = RB/RP
+      RR2 = RR1*RR1
+      RR3 = RR2*RR1
+      BX  = BF*( -NDX*YR1 - (NDX*RR2 )*YR3/6. )
+      BY  = BF* ( 1.-NDX*DRR1+.5*YR2*NDX*RR1 - YR4*NDX*RR3/24. )
+      RETURN
+C****
+C**** FRINGE FIELD REGIONS:  FIND B AND E FIELDS
+C****
+    2 X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      IF ( Y .EQ. 0. ) GO TO 3
+C****
+C**** MAGNETIC: NON-MIDPLANE REGION
+C****
+      CALL BEY( BEF,Z,X,Y,0 )
+      BX = BEF(1)
+      BY = BEF(2)
+      BZ = BEF(3)
+      GO TO 4
+C****
+C**** MAGNETIC:     MIDPLANE REGION
+C****
+    3 CONTINUE
+      IF( NFLAG .EQ. 0 ) GO TO 6
+      SINE = -1.
+      IF( IN .EQ. 3 ) SINE=1.
+      DR = X*SINE
+    6 CALL BEFN(B0,Z,X,Y,DR,0)
+      BX = 0.
+      BY = B0
+      BZ = 0.
+C****
+C**** NOW FIND E FIELD
+C****
+    4 IF ( X .EQ. 0 ) GO TO 5
+C****
+C**** ELECTRIC: NON-MIDPLANE REGION
+C****
+      CALL BEY( BEF,Z,Y,X,1 )
+      EX = BEF(2)
+      EY = BEF(1)
+      EZ = BEF(3)
+      RETURN
+C****
+C**** ELECTRIC:     MIDPLANE REGION
+C****
+    5 CALL BEFN ( B1,Z,Y,X,0.0d0,1 )
+      EX = B1
+      EY = 0.
+      EZ = 0.
+      RETURN
+      END
+
+      SUBROUTINE BEY (BEF,Z,X,Y,IBEX )
+C****
+C**** CALCULATE B OR E FIELD OFF THE MEDIAN PLANE
+C****
+C****
+C****
+C**** IBEX = 0   MAGNETIC FIELD COMPONENTS
+C****      = 1   ELECTRIC FIELD COMPONENTS
+C****
+      IMPLICIT  REAL*8 (A-H,O-Z)
+      REAL*8 NDX
+      COMMON /BLCK73/  IN,NFLAG
+      COMMON /BLCK74/  BF,EF,S,DG
+      COMMON /BLCK77/  RB,NDX
+      DIMENSION BEF(3)
+C****
+C****
+C**** NON MID-PLANE FRINGING FIELD REGION
+C****
+      IF( IBEX  .EQ. 1 ) GO TO 1
+      IF( NFLAG .EQ. 0 ) GO TO 1
+      SINE = -1.
+      IF( IN .EQ. 3 ) SINE=1.
+      DR0  = X*SINE
+      DR1  = SINE* X
+      DR2  = DR1
+      DR9  = DR1
+      DR10 = DR1
+      DR3  = SINE* ( X + DG )
+      DR5  = DR3
+      DR11 = DR3
+      DR4  = SINE*( X - DG )
+      DR7  = DR4
+      DR12 = DR4
+      DR6  = SINE* ( X + 2.*DG )
+      DR8  = SINE* ( X - 2.*DG )
+C****
+C****
+C****
+    1 CALL BEFN(F0,Z,X,Y,       DR0, IBEX )
+      CALL BEFN(F1,Z+DG,X,Y,    DR1, IBEX )
+      CALL BEFN(F2,Z+2.*DG,X,Y, DR2, IBEX )
+      CALL BEFN(F3,Z+DG,X+DG,Y, DR3, IBEX )
+      CALL BEFN(F4,Z+DG,X-DG,Y, DR4, IBEX )
+      CALL BEFN(F5,Z   ,X+DG,Y, DR5, IBEX )
+      CALL BEFN(F6,Z,X+2.*DG,Y, DR6, IBEX )
+      CALL BEFN(F7,Z,X-DG,Y,    DR7, IBEX )
+      CALL BEFN(F8,Z,X-2.*DG,Y, DR8, IBEX )
+      CALL BEFN(F9,Z-DG,X,Y,    DR9, IBEX )
+      CALL BEFN(F10,Z-2.*DG,X,Y,DR10,IBEX )
+      CALL BEFN(F11,Z-DG,X+DG,Y,DR11,IBEX )
+      CALL BEFN(F12,Z-DG,X-DG,Y,DR12,IBEX )
+C****
+      YG1 = Y/DG
+      YG2 = YG1**2
+      YG3 = YG1**3
+      YG4 = YG1**4
+C****
+      BEF(1) = YG1 * ( (F5-F7)*2./3. - (F6-F8)/12. ) +
+     1         YG3 * ( (F5-F7)/6. - (F6-F8)/12. -
+     2         ( F3 + F11 - F4 - F12 - 2.*F5 + 2.*F7 )/12. )
+      BEF(2) = F0 - YG2*( (F1 + F9 + F5 + F7 - 4.*F0) * 2./3. -
+     1         ( F2 + F10 + F6 + F8 - 4.*F0 )/24. ) +
+     2         YG4 * (-( F1 + F9 + F5 + F7 - 4.*F0 )/6. +
+     3         ( F2 + F10 +      F6 + F8 - 4.*F0 )/24. +
+     4         ( F3 + F11 + F4 + F12 - 2.*F1 - 2.*F9 -
+     5         2.*F5 - 2.*F7 + 4.*F0 )/12. )
+      BEF(3) = YG1 * ( (F1 - F9)*2./3. - (F2 - F10)/12. ) +
+     1         YG3 * ( (F1 - F9)/6. - (F2 - F10)/12. -
+     2         (F3 + F4 - F11 - F12 - 2.*F1 + 2.*F9)/12. )
+      RETURN
+      END
+
+
+      SUBROUTINE BFLD
+C****
+C**** CALCULATION OF FIELD COMPONENTS FOR EACH PURE MULTIPOLE
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8 K
+      COMMON  /BLCK 7/ NCODE
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK50/  D, GRAD, S, BT
+      COMMON  /BLCK51/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK52/  IN
+      DIMENSION TC(6), DTC(6)
+      X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      GO TO ( 11, 12, 13, 14 ) , NCODE
+C****
+C**** QUADRUPOLE
+C****
+   11 CONTINUE
+      GO TO ( 2, 1, 2 ) , IN
+c      write (6, 3) IN
+    3 FORMAT( '  ERROR IN BQUAD  IN= ',I5 ///)
+      CALL EXIT
+    1 BX = GRAD*Y
+      BY = GRAD*X
+      BZ = 0.
+      BT =   DSQRT( BX*BX + BY*BY )
+      RETURN
+    2 S = Z/D
+      CS = C0 + C1*S + C2*S**2 + C3*S**3 + C4*S**4 + C5*S**5
+      CSP = C1 + 2.*C2*S + 3.*C3*S**2 + 4.*C4*S**3 + 5.*C5*S**4
+      CSPP = 2.*C2 + 6.*C3*S + 12.*C4*S**2 + 20.*C5*S**3
+      IF( DABS(CS) .GT. 70. )  CS = DSIGN(70.D0, CS )
+      E = DEXP(CS)
+      RE = 1./(1. + E)
+      CB1 = GRAD*RE
+      CB2 = CB1*E*RE*( CSP**2 + CSPP - 2.*E*RE*CSP**2 )/(12.*D*D )
+      BX = CB1*Y + CB2*( 3.*X*X + Y*Y ) * Y
+      BY = CB1*X + CB2*( 3.*Y*Y + X*X ) * X
+      BZ = -CB1*E*CSP*RE*X*Y / D
+      BT =   DSQRT( BX*BX + BY*BY + BZ*BZ )
+      RETURN
+C****
+C**** HEXAPOLE
+C****
+   12 BA2 = GRAD
+      GO TO ( 22, 21, 22 ) , IN
+c      write (6, 23) IN
+   23 FORMAT( '  ERROR IN BHEX   IN= ',I5 ///)
+      CALL EXIT
+   21 BX = 2.*BA2*X*Y
+      BY = BA2*( X*X - Y*Y )
+      BZ = 0.
+      BT =   DSQRT( BX*BX + BY*BY )
+      RETURN
+   22 S = Z/D
+      IF( S .LT. 0. ) GO TO 21
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      RETURN
+C****
+C**** OCTAPOLE
+C****
+   13 BA3 = GRAD
+      GO TO ( 32, 31, 32 ) , IN
+c      write (6, 33) IN
+   33 FORMAT( '  ERROR IN BOCT   IN= ',I5 ///)
+      CALL EXIT
+   31 BX = BA3*( 3.*X*X*Y - Y**3 )
+      BY = BA3*( X**3 - 3.*X*Y*Y )
+      BZ = 0.
+      BT =   DSQRT( BX*BX + BY*BY )
+      RETURN
+   32 S = Z/D
+      IF( S .LT. 0. ) GO TO 31
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      RETURN
+C****
+C**** DECAPOLE
+   14 BA4 = GRAD
+      GO TO ( 42, 41, 42 ) , IN
+c      write (6, 43) IN
+   43 FORMAT( '  ERROR IN BDEC   IN= ',I5 ///)
+      CALL EXIT
+   41 BX = 4.D0*BA4*( X**3 *Y - X*(Y**3) )
+      BY = BA4*( X**4 - 6.D0* X*X*Y*Y + Y**4  )
+      BZ = 0.
+      BT =   DSQRT( BX*BX + BY*BY )
+      RETURN
+   42 S = Z/D
+      IF( S .LT. 0. ) GO TO 41
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      RETURN
+      END
+
+
+      SUBROUTINE BMULT
+C****
+C****
+C**** THE RELATIONSHIP BETWEEN B0, ......... B12 AND B(I,J) RELATIVE TO
+C**** AXES (Z,X) IS GIVEN BY
+C****
+C****
+C****
+C**** B0  = B( 0, 0 )
+C**** B1  = B( 1, 0 )
+C**** B2  = B( 2, 0 )
+C**** B3  = B( 1, 1 )
+C**** B4  = B( 1,-1 )
+C**** B5  = B( 0, 1 )
+C**** B6  = B( 0, 2 )
+C**** B7  = B( 0,-1 )
+C**** B8  = B( 0,-2 )
+C**** B9  = B(-1, 0 )
+C**** B10 = B(-2, 0 )
+C**** B11 = B(-1, 1 )
+C**** B12 = B(-1,-1 )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  K, L
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLK100/  W, L, D, DG, S, BF, BT
+      COMMON  /BLK101/  C0, C1, C2, C3, C4, C5, C6, C7, C8
+      DIMENSION TC(6), DTC(6)
+      X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      CALL MLTT ( B0, Z, X, Y )
+      CALL MLTT ( B1 , Z + DG, X , Y )
+      CALL MLTT ( B2 , Z + 2.*DG, X , Y )
+      CALL MLTT ( B3 , Z + DG, X + DG , Y )
+      CALL MLTT ( B4 , Z + DG, X - DG , Y )
+      CALL MLTT ( B5 , Z , X + DG , Y )
+      CALL MLTT ( B6 , Z , X + 2.*DG , Y )
+      CALL MLTT ( B7 , Z , X - DG , Y )
+      CALL MLTT ( B8 , Z , X - 2.*DG , Y )
+      CALL MLTT ( B9 , Z - DG, X , Y )
+      CALL MLTT ( B10, Z - 2.*DG, X , Y )
+      CALL MLTT ( B11, Z - DG, X + DG , Y )
+      CALL MLTT ( B12, Z - DG, X - DG , Y )
+      YG1 = Y/DG
+      YG2 = YG1**2
+      YG3 = YG1**3
+      YG4 = YG1**4
+      BX = YG1 * ( (B5-B7)*2./3. - (B6-B8)/12. )  +
+     1     YG3*( (B5-B7)/6. - (B6-B8)/12. -
+     2     (B3 + B11 - B4 - B12 - 2.*B5 + 2.*B7 ) / 12. )
+      BY = B0 - YG2*( ( B1 + B9 + B5 + B7 - 4.*B0 ) *2./3. -
+     1     ( B2 + B10 + B6 + B8 - 4.*B0 ) / 24. ) +
+     2     YG4* (-( B1 + B9 + B5 + B7 - 4.*B0 ) / 6. +
+     3     ( B2 + B10 + B6 + B8 - 4.*B0 ) / 24. +
+     4     ( B3 + B11 + B4 + B12 - 2.*B1 - 2.*B9 -
+     5     2.*B5 - 2.*B7 + 4.*B0 ) / 12. )
+      BZ = YG1*( (B1 - B9 ) *2./3. - ( B2 - B10 ) /12. ) +
+     1     YG3*( ( B1 - B9 ) / 6. - ( B2 - B10 ) / 12. -
+     2     ( B3 + B4 - B11 - B12 - 2.*B1 + 2.*B9 ) / 12.  )
+      BT  =DSQRT(BX*BX + BY*BY + BZ*BZ)
+      RETURN
+      END
+
+
+      SUBROUTINE BPLS ( IGP, D, S, RE, G1, G2, G3, G4, G5, G6 )
+C****
+C****
+C****
+      IMPLICIT REAL*8 (A-H,O-Z)
+C****
+C****
+      COMMON  /BLCK91/  C0, C1, C2, C3, C4, C5
+C****
+C****
+      S2 = S*S
+      S3 = S2*S
+      S4 = S2*S2
+      S5 = S4*S
+      CS = C0 + C1*S + C2*S2 + C3*S3 + C4*S4 + C5*S5
+      CP1 =(C1 + 2.*C2*S + 3.*C3*S2 + 4.*C4*S3 + 5.*C5*S4) / D
+      CP2 = (2.*C2 + 6.*C3*S + 12.*C4*S2 + 20.*C5*S3  ) / (D*D)
+      CP3 = ( 6.*C3 + 24.*C4*S + 60.*C5*S2 ) / (D**3)
+      CP4 = ( 24.*C4 + 120.*C5*S ) / (D**4)
+C****
+      CP5 = 120.*C5/(D**5)
+C****
+C****
+C****
+      IF( DABS(CS) .GT. 70. )  CS = DSIGN(70.D0, CS )
+      E = DEXP(CS)
+      RE = 1./(1. + E)
+      ERE = E*RE
+      ERE1= ERE*RE
+      ERE2= ERE*ERE1
+      ERE3= ERE*ERE2
+      ERE4= ERE*ERE3
+C****
+      ERE5= ERE*ERE4
+      ERE6= ERE*ERE5
+C****
+C****
+      CP12 = CP1*CP1
+      CP13 = CP1*CP12
+      CP14 = CP12*CP12
+      CP22 = CP2*CP2
+C****
+      CP15 = CP12*CP13
+      CP16 = CP13*CP13
+      CP23 = CP2*CP22
+      CP32 = CP3*CP3
+C****
+C****
+      IF( IGP .EQ. 6 ) RETURN
+      G1 = -CP1*ERE1
+C****
+C****
+      IF( IGP .EQ. 5 ) RETURN
+      IF( IGP .EQ. 4 ) GO TO 1
+      G2 =-( CP2+CP12   )*ERE1    + 2.*CP12 * ERE2
+      G3 =-(CP3 + 3.*CP1*CP2 + CP13  ) * ERE1      +
+     1   6.*(CP1*CP2 + CP13)*ERE2 - 6.*CP13*ERE3
+C****
+C****
+      IF( IGP .EQ. 3 ) RETURN
+1     G4 = -(CP4 + 4.*CP1*CP3 + 3.*CP22 + 6.*CP12*CP2 + CP14)*ERE1  +
+     1   (8.*CP1*CP3 + 36.*CP12*CP2 + 6.*CP22 + 14.*CP14)*ERE2    -
+     2   36.*(CP12*CP2 + CP14)*ERE3       + 24.*CP14*ERE4
+C****
+C****
+      IF( IGP .NE. 2 ) RETURN
+      G5 = (-CP5 - 5.*CP1*CP14 - 10.*CP2*CP3 - 10.*CP12*CP3 -
+     1     15.*CP1*CP22 - 10.*CP13*CP2 - CP15)*ERE1 +
+     2     (10.*CP1*CP4 +20.*CP2*CP3 +60.*CP12*CP3 + 90.*CP1*CP22 +
+     3     140.*CP13*CP2 +30.*CP15)*ERE2 + (-60.*CP12*CP3 -
+     4     90.*CP1*CP22 - 360.*CP13*CP2 - 150.*CP15)*ERE3 +
+     5     (240.*CP13*CP2 +240.*CP15)*ERE4 + (-120.*CP15)*ERE5
+      G6 = (-6.*CP1*CP5 - 15.*CP2*CP4 - 15.*CP12*CP4 - 10.*CP32 -
+     1     60.*CP1*CP2*CP3 - 20.*CP13*CP3 - 15.*CP23 - 45.*CP12*CP22 -
+     2     15.*CP14*CP2 - CP16)*ERE1 + (12.*CP1*CP5 + 30.*CP2*CP4 +
+     3     90.*CP12*CP4 +20.*CP32 + 360.*CP1*CP2*CP3 +280.*CP13*CP3 +
+     4     90.*CP23 + 630.*CP12*CP22 + 450.*CP14*CP2 + 62.*CP16)*ERE2 +
+     5     (-90.*CP12*CP4 - 360.*CP1*CP2*CP3 -720.*CP13*CP3 -90.*CP23 -
+     6     1620.*CP12*CP22 -2250.*CP14*CP2 - 540.*CP16)*ERE3 +
+     7     (480.*CP13*CP3 + 1080.*CP12*CP22 + 3600.*CP14*CP2 +
+     8     1560.*CP16)*ERE4 + (-1800.*CP14*CP2 - 1800.*CP16)*ERE5 +
+     9     720.*CP16*ERE6
+C****
+      RETURN
+      END
+
+
+      SUBROUTINE BPOLES
+C****
+C**** CALCULATION OF MULTIPOLE(POLES) FIELD COMPONENTS
+C****
+C****
+C****
+C**** 2 - QUADRUPOLE  (GRAD1)
+C**** 3 - HEXAPOLE    (GRAD2)
+C**** 4 - OCTAPOLE    (GRAD3)
+C**** 5 - DECAPOLE    (GRAD4)
+C**** 6 - DODECAPOLE  (GRAD5)
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8 K
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK90/  D, S, BT, GRAD1,GRAD2,GRAD3,GRAD4,GRAD5
+      COMMON  /BLCK91/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK92/  IN
+      COMMON  /BLCK93/  DH, DO, DD, DDD, DSH, DSO, DSD, DSDD
+      DIMENSION TC(6), DTC(6)
+      X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      X2 = X*X
+      X3 = X2*X
+      X4 = X3*X
+      X5 = X4*X
+      X6 = X5*X
+      X7 = X6*X
+      Y2 = Y*Y
+      Y3 = Y2*Y
+      Y4 = Y3*Y
+      Y5 = Y4*Y
+      Y6 = Y5*Y
+      Y7 = Y6*Y
+      GO TO ( 2, 1, 2 ) , IN
+c      write(6,3) IN
+    3 FORMAT( '  ERROR IN BPOLES IN= ',I5,///)
+      CALL EXIT
+    1 CONTINUE
+      B2X = GRAD1*Y
+      B2Y = GRAD1*X
+      B3X = GRAD2*2.*X*Y
+      B3Y = GRAD2*(X2-Y2)
+      B4X = GRAD3*(3.*X2*Y-Y3)
+      B4Y = GRAD3*(X3-3.*X*Y2)
+      B5X = GRAD4*4.*(X3*Y-X*Y3)
+      B5Y = GRAD4*(X4-6.*X2*Y2+Y4)
+      B6X = GRAD5*(5.*X4*Y-10.*X2*Y3+Y5)
+      B6Y = GRAD5*(X5-10.*X3*Y2+5.*X*Y4)
+      BX = B2X + B3X + B4X + B5X + B6X
+      BY = B2Y + B3Y + B4Y + B5Y + B6Y
+      BZ = 0.
+      BT =   DSQRT( BX*BX + BY*BY )
+      RETURN
+C****
+C****
+C****
+    2 S = Z/D
+      CALL BPLS( 2, D, S, RE, G1, G2, G3, G4, G5, G6 )
+      B2X = GRAD1*( RE*Y - (G2/12.)*(3.*X2*Y + Y3) +
+     1   (G4/384.)*(5.*X4*Y + 6.*X2*Y3 + Y5 ) -
+     2   (G6/23040.)*(7.*X6*Y + 15.*X4*Y3 + 9.*X2*Y5 + Y7)  )
+      B2Y = GRAD1*( RE*X - (G2/12.)*(X3 + 3.*X*Y2) +
+     1   (G4/384.)*(X5 + 6.*X3*Y2 + 5.*X*Y4 ) -
+     2   (G6/23040.)*(X7 + 9.*X5*Y2 + 15.*X3*Y4 + 7.*X*Y6) )
+      B2Z = GRAD1*( G1*X*Y - (G3/12.)*(X3*Y + X*Y3 ) +
+     1   (G5/384.)*(X5*Y +2.*X3*Y3 + X*Y5)  )
+C****
+C****
+      SS = Z/DH  + DSH
+      CALL BPLS( 3, DH, SS, RE, G1, G2, G3, G4, G5, G6 )
+      B3X = GRAD2*( RE*2.*X*Y - (G2/48.)*(12.*X3*Y + 4.*X*Y3 ) )
+      B3Y = GRAD2*( RE*(X2-Y2) - (G2/48.)*(3.*X4 + 6.*X2*Y2 - 5.*Y4 ) )
+      B3Z = GRAD2*( G1*(X2*Y - Y3/3.) - (G3/48.)*(3.*X4*Y+2.*X2*Y3-Y5))
+C****
+C****
+      SS = Z/DO  + DSO
+      CALL BPLS( 4, DO, SS, RE, G1, G2, G3, G4, G5, G6 )
+      B4X = GRAD3*( RE*(3.*X2*Y - Y3) - (G4/80.)*(20.*X4*Y - 4.*Y5 ) )
+      B4Y = GRAD3*( RE*(X3 - 3.*X*Y2) - (G4/80.)*(4.*X5-20.*X*Y4 ) )
+      B4Z = GRAD3*G1*(X3*Y - X*Y3 )
+C****
+C****
+      SS = Z/DD  + DSD
+      CALL BPLS( 5, DD, SS, RE, G1, G2, G3, G4, G5, G6 )
+      B5X = GRAD4*RE*(4.*X3*Y - 4.*X*Y3)
+      B5Y = GRAD4*RE*(X4 - 6.*X2*Y2 + Y4 )
+      B5Z = GRAD4*G1*(X4*Y - 2.*X2*Y3 + Y5/5. )
+C****
+C****
+      SS = Z/DDD + DSDD
+      CALL BPLS( 6, DDD,SS, RE, G1, G2, G3, G4, G5, G6 )
+      B6X = GRAD5*RE*(5.*X4*Y - 10.*X2*Y3 + Y5 )
+      B6Y = GRAD5*RE*(X5 - 10.*X3*Y2 + 5.*X*Y4 )
+      B6Z = 0.
+C****
+C****
+      BX = B2X + B3X + B4X + B5X + B6X
+      BY = B2Y + B3Y + B4Y + B5Y + B6Y
+      BZ = B2Z + B3Z + B4Z + B5Z + B6Z
+      BT =   DSQRT( BX*BX + BY*BY + BZ*BZ )
+      RETURN
+      END
+
+
+      SUBROUTINE BPRETZ
+C****
+C****
+C**** MTYP=6
+C****
+C****
+C**** PRETZEL MAGNET FIELD COMPONENTS
+C**** DG = SMALL NEGATIVE NUMBER
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  NDX, K
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK20/  NDX,BET1,GAMA,DELT,CSC
+      COMMON  /BLCK21/  RCA,DELS,BR,S2,S3,S4,S5,S6,S7,S8,SCOR
+      COMMON  /BLCK22/  D, DG, S, BF, BT
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION TC(6), DTC(6)
+C****
+C****
+      G1 = BF/D
+      Y = TC(2)
+      Z = TC(3)
+      IF( Z .LE. DG ) GO TO 1
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      RETURN
+    1 BY0 = G1*DABS(Z)**NDX
+      BY1 = BY0*NDX/Z
+      BY2 = BY1*(NDX-1.)/Z
+      BY3 = BY2*(NDX-2.)/Z
+      BY4 = BY3*(NDX-3.)/Z
+      BX = 0.
+      BY = BY0 - Y*Y*BY2/2. + Y**4*BY4/24.
+      BZ = Y*BY1 - Y**3*BY3/6.
+      BT = DSQRT(BX*BX + BY*BY + BZ*BZ)
+      RETURN
+      END
+
+
+      SUBROUTINE BSOL
+C****
+C****
+C**** ROUTINE VALID FOR FIELDS OUTSIDE CENTRAL ZONE OF ELEMENTAL
+C**** SOLENOID
+C**** BF    = FIELD AT CENTER OF INFINITE SOLENOID; CURR. DEN. (NI/M)
+C**** M.W.GARRETTT  JOURNAL OF APP. PHYS. 34,(1963),P2567
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8 K
+      DIMENSION  TC(6), DTC(6)
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK30/  BF ,      AL, RAD
+      COMMON  /BLCK31/  S, BT
+      COMMON  /BLCK32/  IN
+C****
+C****
+      DATA PI4/12.566370616D0 /
+C****
+C****
+C****
+      X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      R =DSQRT( X **2 + Y**2 )
+      IF( R  .LT.  (RAD/1.D4)  )  GO TO 5
+      RADR = RAD+R
+      AAPR = 4.D0*RAD/RADR
+      AAMR = (RAD-R)/(2.D0*RAD)
+      RCSQ = 4.D0*RAD*R/(RADR*RADR)
+C****
+C**** SOLENOID LEFT  HAND SOURCE
+C****
+      ZZ = -(AL+Z)
+      R1SQ = RADR*RADR  + ZZ*ZZ
+      R1 = DSQRT(R1SQ)
+      RKSQ = 4.D0*RAD*R/R1SQ
+      CALL FB01AD(RKSQ,       VKS, VES )
+      CALL FB03AD(RCSQ, RKSQ, P )
+      BZS1 = AAPR*ZZ*(VKS+AAMR*(P-VKS) ) /R1
+      BRS1 = R1*(2.D0*(VKS-VES) - RKSQ*VKS)
+C****
+C**** SOLENOID RIGHT HAND SOURCE
+C****
+      ZZ = AL-Z
+      R1SQ = RADR*RADR  + ZZ*ZZ
+      R1 = DSQRT(R1SQ)
+      RKSQ = 4.D0*RAD*R/R1SQ
+      CALL FB01AD(RKSQ,       VKS, VES )
+      CALL FB03AD(RCSQ, RKSQ, P )
+      BZS2 = AAPR*ZZ*(VKS+AAMR*(P-VKS) ) /R1
+      BRS2 = R1*(2.D0*(VKS-VES) - RKSQ*VKS)
+      BZ = BF*( BZS2-BZS1 )/PI4
+      BR = BF*( BRS2-BRS1 )/(R*PI4)
+      BX = BR * X /R
+      BY = BR *  Y/R
+      BT =DSQRT( BX**2 + BY**2 + BZ**2 )
+      RETURN
+    5 CONTINUE
+C****
+C****
+C****
+      COSA = (AL-Z) / DSQRT( RAD*RAD + (AL-Z)**2  )
+      COSB =-(AL+Z) / DSQRT( RAD*RAD + (AL+Z)**2  )
+      BX = 0.
+      BY = 0.
+      BZ = BF*(COSA-COSB)/2.D0
+      BT = DABS(BZ)
+      RETURN
+      END
+
+
+      SUBROUTINE COLL ( NO, J, IFLAG  )
+C****
+C****
+C**** TEST AND SET FLAG IF RAY EXCEEDS RECTANGULAR OR ELLIPTICAL
+C**** COLLIMATOR CUT-OFF DIMENSIONS
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 2/  XO, YO, ZO, VXO, VYO, VZO,RTL(1000),RLL(1000)
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      DIMENSION XO(1000),YO(1000),ZO(1000),VXO(1000),VYO(1000),VZO(1000)
+      DIMENSION DATA(75,200),ITITLE(200)
+C****
+C****
+  100 FORMAT( // 5X, 'RAY=', I5, 5X, 'ELEMENT=', I3,
+     1   '   STOPPED - EXCEEDS RECTANGULAR COLLIMATOR DIMENSIONS ' // )
+  101 FORMAT( // 5X, 'RAY=', I5, 5X, 'ELEMENT=', I3,
+     1   '   STOPPED - EXCEEDS ELLIPTICAL  COLLIMATOR DIMENSIONS ' // )
+C****
+C****
+      IFLAG = 0
+      ICOLL = DATA(1,NO)
+      XCEN  = DATA(2,NO)
+      YCEN  = DATA(3,NO)
+      XMAX  = DATA(4,NO)
+      YMAX  = DATA(5,NO)
+      IF ( ICOLL .NE. 0 ) GO TO 1
+      IF ( (DABS(XA-XCEN) .GT. XMAX) .OR. (DABS(YA-YCEN) .GT. YMAX) )
+     1      GO TO 2
+      RETURN
+    2 CONTINUE
+c    2 write (6, 100) J, NO
+      GO TO 3
+    1 XC = (XA-XCEN)/XMAX
+      YC = (YA-YCEN)/YMAX
+      IF ( (XC*XC+YC*YC) .GT. 1. ) GO TO 4
+      RETURN
+    4 CONTINUE
+c    4 write (6, 101) J, NO
+    3 XO(J)  = 1.D10
+      YO(J)  = 1.D10
+      VXO(J) = 0.
+      VYO(J) = 0.
+      IFLAG  = 1
+      RETURN
+      END
+
+      SUBROUTINE  DERIV( BFUN )
+C****
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  K
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK11/  EX, EY, EZ, QMC, IVEC
+      DIMENSION TC(6), DTC(6)
+      DATA  C /3.D10 /
+C****
+C****
+      CALL BFUN
+      DTC(1) = TC(4)
+      DTC(2) = TC(5)
+      DTC(3) = TC(6)
+      IF( IVEC .NE. 0 )  GO TO 4
+      DTC(4) = K * ( TC(5) * BZ - TC(6) * BY )
+      DTC(5) = K * ( TC(6) * BX - TC(4) * BZ )
+      DTC(6) = K * ( TC(4) * BY - TC(5) * BX )
+      RETURN
+    4 VEL = DSQRT( TC(4)**2 + TC(5)**2 + TC(6)**2 )
+C****
+C**** SK 12/02/83
+C**** GAMMA CORRECTION FOR HIGH ENERGY ELECTRONS
+C**** NOT EXACT
+C****
+      GAMMA = 1.D0 + ENERGY/(PMASS*931.48D0)
+      IF( GAMMA .LT. 100. ) GAMMA = 1./DSQRT( 1.-VEL*VEL/(C*C) )
+C****
+C****
+      K = 1./(QMC*GAMMA)
+      AK = K/(9.D13)
+      ETERM = (EX*TC(4)+EY*TC(5)+EZ*TC(6) )*AK
+      DTC(4) = K*( TC(5)*BZ - TC(6)*BY + EX*1.D7 ) - TC(4)*ETERM
+      DTC(5) = K*( TC(6)*BX - TC(4)*BZ + EY*1.D7 ) - TC(5)*ETERM
+      DTC(6) = K*( TC(4)*BY - TC(5)*BX + EZ*1.D7 ) - TC(6)*ETERM
+      RETURN
+      END
+
+
+      SUBROUTINE DIPOLE ( NO, NP, T, TP ,NUM )
+C****
+C****
+C**** SINGLE MAGNET RAY TRACING BY NUMERICAL INTEGRATION OF DIFFERENTIAL
+C**** EQUATIONS OF MOTION.
+C     T = TIME
+C     TC(1) TO TC(6) =  ( X, Y, Z, VX, VY, VZ )
+C     DTC(1) TO DTC(6) = ( VX, VY, VZ, VXDOT, VYDOT, VZDOT )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  LF1, LF2, LU1, K, NDX
+      EXTERNAL BDIP
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK20/  NDX,BET1,GAMA,DELT,CSC
+      COMMON  /BLCK21/  RCA,DELS,BR,S2,S3,S4,S5,S6,S7,S8,SCOR
+      COMMON  /BLCK22/  D, DG, S, BF, BT
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION DATA(  75,200 ) ,ITITLE(200)
+      DIMENSION TC(6), DTC(6), DS(6), ES(6)
+C**** DATA  C/ 3.D10/
+C****
+      LF1  = DATA(  1,NO )
+      LU1  = DATA(  2,NO )
+      LF2  = DATA(  3,NO )
+      DG   = DATA(  4,NO )
+      MTYP = DATA(  5,NO )
+      A    = DATA( 11,NO )
+      B    = DATA( 12,NO )
+      D    = DATA( 13,NO )
+      RB   = DATA( 14,NO )
+      BF   = DATA( 15,NO )
+      PHI  = DATA( 16,NO )
+      ALPHA= DATA( 17,NO )
+      BETA = DATA( 18,NO )
+      NDX  = DATA( 19,NO )
+      BET1 = DATA( 20,NO )
+      GAMA = DATA( 21,NO )
+      DELT = DATA( 22,NO )
+      Z11  = DATA( 25,NO )
+      Z12  = DATA( 26,NO )
+      Z21  = DATA( 27,NO )
+      Z22  = DATA( 28,NO )
+      BR1  = DATA( 41,NO )
+      BR2  = DATA( 42,NO )
+      XCR1 = DATA( 43,NO )
+      XCR2 = DATA( 44,NO )
+      IF( MTYP .EQ. 0  )  MTYP = 1
+      DTF1= LF1/ VEL
+      DTF2= LF2/ VEL
+      DTU = LU1/ VEL
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S = 0.
+      BR = BR1
+      IF( NP  .GT. 100 ) GO TO 5
+c      write (6, 100) ITITLE(NO)
+  100 FORMAT(  ' DIPOLE  ****  ', A4,'  ****************************'/)
+c      write (6, 101)
+  101 FORMAT( 8H    T CM ,18X, 4HX CM , 7X, 2HBX, 8X, 4HY CM , 7X, 2HBY,
+     1   8X, 4HZ CM, 7X, 2HBZ, 8X, 6HVELZ/C , 6X, 8HTHETA MR , 5X,
+     2   6HPHI MR , 6X, 1HB             )
+      CALL PRNT2 ( T,S,XA   ,YA   ,ZA   ,BX,BY,BZ,BT,VXA  ,VYA  ,VZA   )
+c      write (6, 103)
+  103 FORMAT(   '0COORDINATE TRANSFORMATION TO B AXIS SYSTEM '       )
+  109 FORMAT(   '0COORDINATE TRANSFORMATION TO D AXIS SYSTEM '       )
+C**** TRANSFORM FROM INITIAL ENTRANCE COORDINATES TO VFB COORD.
+C****
+    5 COSA =DCOS( ALPHA/57.29578)
+      SINA =DSIN( ALPHA/57.29578)
+      TC(1) = ( A-ZA ) * SINA - ( XA + XCR1 ) * COSA
+      TC(2) = YA
+      TC(3) = ( A-ZA ) * COSA + ( XA + XCR1 ) * SINA
+      TC(4) = -VZA * SINA - VXA * COSA
+      TC(5) = VYA
+      TC(6) = -VZA * COSA + VXA * SINA
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** TRANSLATE PARTICLE TO START OF FIRST FRINGE FIELD
+C****
+C****
+      IF(  BR1  .EQ.  0. ) GO TO 20
+      IN = 4
+      XDTF1 = DTF1
+      IF(  Z11  .GT.  TC(3) )  XDTF1 = -DTF1
+c      IF( NP  .LE. 100) write (6, 108)
+  108 FORMAT(/ ' CONSTANT FIELD CORRECTION IN FRINGE FIELD REGION    ' )
+      NSTEP = 0
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, BDIP,  0    )
+   21 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 22  I=1,NP
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, BDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF(  XDTF1  .LT.  0. )  GO TO 23
+      IF(  Z11  .GE.  TC(3) )  GO TO 24
+      GO TO 22
+   23 IF(  Z11  .LE.  TC(3) )  GO TO 24
+   22 CONTINUE
+      GO TO 21
+   24 DO 2 I=1,2
+      XDTF1 = (TC(3) - Z11) / DABS(TC(6))
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, BDIP,  0    )
+    2 CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, BDIP,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+C****
+C****
+C****
+   20 TDT = ( TC(3) - Z11 ) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** IN DESIGNATES MAGNET REGIONS FOR BFUN
+C****
+      IN = 1
+      XC= RB*DCOS( ALPHA/ 57.29578 )
+      ZC=-RB*DSIN( ALPHA/ 57.29578 )
+C****
+      C0   = DATA( 29,NO )
+      C1   = DATA( 30,NO )
+      C2   = DATA( 31,NO )
+      C3   = DATA( 32,NO )
+      C4   = DATA( 33,NO )
+      C5   = DATA( 34,NO )
+      DELS = DATA( 45,NO )
+      RCA  = DATA( 47,NO )
+      CSC = DCOS( ALPHA/57.29578 )
+      SCOR = DATA(49,NO)
+      S2   = DATA( 51,NO ) / RB    + RCA/2.D0
+      S3   = DATA( 52,NO ) / RB**2
+      S4   = DATA( 53,NO ) / RB**3 + RCA**3/8.D0
+      S5   = DATA( 54,NO ) / RB**4
+      S6   = DATA( 55,NO ) / RB**5 + RCA**5/16.D0
+      S7   = DATA( 56,NO ) / RB**6
+      S8   = DATA( 57,NO ) / RB**7 + RCA**7/25.6D0
+c      IF( NP  .LE. 100) write (6, 104)
+  104 FORMAT( 22H0FRINGING FIELD REGION    )
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BDIP,  0    )
+      NSTEP = 0
+    6 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 7 I = 1, NP
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( Z12 .GE. TC(3) ) GO TO 8
+    7 CONTINUE
+      GO TO 6
+    8 CONTINUE
+      XDTF1 =-( Z12 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, BDIP,  0    )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, BDIP,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+  105 FORMAT( 10H   NSTEPS= ,I5 )
+C***
+C***  UNIFORM FIELD REGION
+C**** TRANSFORM TO SECOND VFB COORD SYSTEM
+C***
+      COPAB =DCOS( (PHI-ALPHA-BETA)/57.29578)
+      SIPAB =DSIN( (PHI-ALPHA-BETA)/57.29578)
+      COSPB =DCOS( (PHI/2.-BETA)/57.29578 )
+      SINPB =DSIN( (PHI/2.-BETA)/57.29578 )
+      SIP2 =DSIN( (PHI/2.)/57.29578 )
+      XT = TC(1)
+      ZT = TC(3)
+      VXT = TC(4)
+      VZT = TC(6)
+      TC(3) = - ZT  *COPAB +  XT  *SIPAB -2.*RB*SIP2*COSPB
+      TC(1) = - ZT  *SIPAB -  XT  *COPAB -2.*RB*SIP2*SINPB
+      TC(6) = - VZT *COPAB +  VXT *SIPAB
+      TC(4) = - VZT *SIPAB -  VXT *COPAB
+C****
+C****
+C**** UNIFORM FIELD INTEGRATION REGION
+C****
+C****
+      IN = 2
+      XC=-RB*DCOS( BETA / 57.29578 )
+      ZC=-RB*DSIN( BETA / 57.29578 )
+c      IF( NP  .LE. 100) write (6, 106)
+  106 FORMAT(   '0UNIFORM FIELD REGION IN C AXIS SYSTEM '  )
+      IF( TC(3)  .LT.  Z21 ) GO TO 15
+C****
+C**** THIS SECTION CORRECTS FOR MAGNETS WHOSE FRINGING FIELDS INTERSECT
+C****
+c      IF( NP  .LE. 100) write (6, 102)
+  102 FORMAT( / '   INTEGRATE BACKWARDS    '  )
+      CALL FNMIRK( 6, T,-DTU ,TC, DTC, DS, ES, BDIP,  0    )
+      NSTEP = 0
+   16 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 17  I =1, NP
+      CALL FNMIRK( 6, T,-DTU, TC, DTC, DS, ES, BDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3)  .LE.  Z21 )  GO TO 18
+   17 CONTINUE
+      GO TO 16
+   18 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, BDIP,  0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, BDIP,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+c      IF( NP  .LE. 100) write (6, 107)
+  107 FORMAT( / )
+      GO TO 19
+C****
+C****
+   15 CONTINUE
+      CALL FNMIRK( 6, T, DTU ,TC, DTC, DS, ES, BDIP,  0    )
+      NSTEP = 0
+    9 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 10  I =1, NP
+      CALL FNMIRK( 6, T, DTU, TC, DTC, DS, ES, BDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3)  .GE.  Z21 )  GO TO 11
+   10 CONTINUE
+      GO TO 9
+   11 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, BDIP,  0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, BDIP,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+   19 CONTINUE
+C***
+C***
+C**** SETUP FOR SECOND FRINGE FIELD AND INTEGRATION
+C****
+C****
+      BR   = BR2
+      C0   = DATA( 35,NO )
+      C1   = DATA( 36,NO )
+      C2   = DATA( 37,NO )
+      C3   = DATA( 38,NO )
+      C4   = DATA( 39,NO )
+      C5   = DATA( 40,NO )
+      DELS = DATA( 46,NO )
+      RCA  = DATA( 48,NO )
+      SCOR = DATA(50,NO)
+      CSC = DCOS( BETA /57.29578 )
+      S2   = DATA( 58,NO ) / RB    + RCA/2.D0
+      S3   = DATA( 59,NO ) / RB**2
+      S4   = DATA( 60,NO ) / RB**3 + RCA**3/8.D0
+      S5   = DATA( 61,NO ) / RB**4
+      S6   = DATA( 62,NO ) / RB**5 + RCA**5/16.D0
+      S7   = DATA( 63,NO ) / RB**6
+      S8   = DATA( 64,NO ) / RB**7 + RCA**7/25.6D0
+      IN = 3
+c      IF( NP  .LE. 100) write (6, 104)
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, BDIP,  0    )
+      NSTEP = 0
+   12 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 13  I =1, NP
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, BDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3) .GE. Z22 )  GO TO 14
+   13 CONTINUE
+      GO TO 12
+   14 CONTINUE
+      XDTF2 = ( Z22 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BDIP,  0    )
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BDIP,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+C****
+C**** TRANSFORM TO OUTPUT SYSTEM COORD.
+C****
+      COSB =DCOS( BETA/57.29578 )
+      SINB =DSIN( BETA/57.29578 )
+      XT = TC(1)
+      ZT = TC(3)
+      VXT = TC(4)
+      VZT = TC(6)
+      TC(3) = ZT*COSB - XT*SINB - B
+      TC(1) = ZT*SINB + XT*COSB - XCR2
+      TC(6) = VZT*COSB - VXT*SINB
+      TC(4) = VZT*SINB + VXT*COSB
+c      IF( NP  .LE. 100) write (6, 109)
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+C****
+C**** TRANSLATE PARTICLE TO OUT SYSTEM COORD.
+C****
+      IF(  BR2  .EQ.  0. ) GO TO 30
+      IN = 4
+      XDTF2 = DTF2
+      IF( TC(3)  .GT. 0. ) XDTF2 = -DTF2
+c      IF( NP  .LE. 100) write (6, 108)
+      NSTEP = 0
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BDIP,  0    )
+   31 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 32  I=1,NP
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 4
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( XDTF2  .LT. 0. ) GO TO 33
+      IF( TC(3)  .GE. 0. ) GO TO 34
+      GO TO 32
+   33 IF( TC(3)  .LE. 0. ) GO TO 34
+   32 CONTINUE
+      GO TO 31
+   34 DO 3 I=1,2
+      XDTF2 = -TC(3) / DABS(TC(6))
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BDIP,  0    )
+    3 CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BDIP,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 4
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+C****
+C****
+C****
+   30 TDT = -TC(3) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      TP = T * VEL
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S  = 0.
+      VXF    = 1000. *DATAN2( TC(4), TC(6)  )
+      VYF    = 1000. *DASIN ( TC(5)/ VEL    )
+      VZF    = TC(6) / VEL
+c      IF(NP.LE.100) write (6,115)TP,TC(1),TC(2),TC(3),VZF,VXF,VYF
+  115 FORMAT( F10.4, 10X, F10.3, 11X, F10.3, 11X, F10.3, 11X,
+     1   F13.5, F13.2, F11.2                   )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 4
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** CALCULATE INTERCEPTS IN SYSTEM D
+C****
+      Z0X = -TC(1)/ ( TC(4) / TC(6)    + 1.E-10 )
+      Z0Y = -TC(2)/ ( TC(5) / TC(6)    + 1.E-10 )
+c      IF( NP .LE. 100) write (6, 111) VXF, VYF, Z0X, Z0Y
+  111 FORMAT( / ' INTERSECTIONS WITH VER. AND HOR. PLANES '          ,
+     X       /15X, 5H  XP=,F10.4, 10H MR    YP=,F10.4, 3H MR   /
+     1        15X, 5H Z0X=,F10.2, 10H CM   Z0Y=,F10.2, 3H CM   /       )
+      RETURN
+   99 CALL PRNT4(NO, IN)
+      RETURN
+      END
+
+
+      SUBROUTINE  DRIFT( NO,  NP,T, TP ,NUM )
+C****
+C****
+C**** Z-AXIS DRIFT ROUTINE
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+C**** DATA  C/ 3.D10/
+  100 FORMAT( /  '   Z-AXIS DRIFT  ****  ', A4, '****************',//
+     1'      T CM', 18X, 'X CM', 7X, 'Y CM', 7X, 'Z CM' , '      VELZ/C'
+     2   , '    THETA MR      PHI MR'  /  )
+  103 FORMAT( F10.4, 11X, 3F11.3, F12.5, 2F12.3  )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 1
+      CALL PLT2 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 100) ITITLE(NO)
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. *DASIN ( VYA/VEL )
+      VZP =  VZA  / VEL
+      TP = T*VEL
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+      TDT =(DATA(1,NO) - ZA) / DABS(VZA)
+      T = T + TDT
+      TP = T*VEL
+      XA = XA + TDT*VXA
+      YA = YA + TDT*VYA
+      ZA = 0.
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT2 ( NUM, NO, NBR, TPAR )
+      RETURN
+      END
+C
+C         SUBROUTINE DTIME
+C         INTEGER *2 H,MI,S,Y,MO,D,X
+C         CHARACTER COL,PNT,SL
+C         DATA COL/':'/,PNT/'.'/,SL/'/'/
+C         CALL GETTIM(H,MI,S,X)
+C         CALL GETDAT(Y,MO,D)
+C         WRITE (6,100) H,COL,MI,COL,S,PNT,X,MO,SL,D,SL,Y
+C 100     FORMAT(5X,I2,A1,I2,A1,I2,A1,I2,5X,I2,A1,I2,A1,I4)
+C         RETURN
+C         END
+
+
+      SUBROUTINE EDIP
+C****
+C****   CALCULATES E-FIELD COMPONENTS FOR A CYLINDRICAL
+C****   ELECTROSTATIC DEFLECTOR
+C****
+      IMPLICIT REAL*8 (A-H, O-Z)
+      REAL*8 K
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK11/  EX, EY, EZ, QMC, IVEC
+      COMMON  /BLCK20/ EC2, EC4, WE, WC
+      COMMON  /BLCK22/  D, DG, S, EF, ET
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION TC(6), DTC(6)
+C****
+C****
+      X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      DX = X - XC
+      DZ = Z
+      RP2 = DX * DX + Z * Z
+      RP = DSQRT(RP2)
+      GO TO (1, 2, 3) , IN
+  100 FORMAT( ' ERROR -GO TO-  IN EDIP IN = ', I5)
+c      write (6, 100) IN
+C****
+C**** UNIFORM FIELD REGION
+C****
+2     EX = - EF * RB * DX / RP2
+      EY = 0.
+      EZ = - EF * RB * Z / RP2
+      ET = DSQRT(EX * EX + EZ * EZ)
+      RETURN
+C****
+C**** FRINGE FIELD REGION
+C****
+1     CONTINUE
+3     CONTINUE
+      ZP1 = DZ + DG
+      ZP2 = DZ + 2. * DG
+      ZM1 = DZ - DG
+      ZM2 = DZ - 2. * DG
+      DRP1 = DSQRT( DX * DX + ZP1 * ZP1 )
+      DRP2 = DSQRT( DX * DX + ZP2 * ZP2 )
+      DRM1 = DSQRT( DX * DX + ZM1 * ZM1 )
+      DRM2 = DSQRT( DX * DX + ZM2 * ZM2 )
+      CALL EDPP (F0,   Z  ,  X, Y      , RP   )
+      S0 = S
+      CALL EDPP (F1,  ZP1 ,  X, Y      , DRP1 )
+      CALL EDPP (F2,  ZP2 ,  X, Y      , DRP2 )
+      CALL EDPP (F3,  ZP1 ,  X, Y+DG   , DRP1 )
+      CALL EDPP (F4,  ZP1 ,  X, Y-DG   , DRP1 )
+      CALL EDPP (F5,   Z  ,  X, Y+DG   , RP   )
+      CALL EDPP (F6,   Z  ,  X, Y+2.*DG, RP   )
+      CALL EDPP (F7,   Z  ,  X, Y-DG   , RP   )
+      CALL EDPP (F8,   Z  ,  X, Y-2.*DG, RP   )
+      CALL EDPP (F9,  ZM1 ,  X, Y      , DRM1 )
+      CALL EDPP (F10, ZM2 ,  X, Y      , DRM2 )
+      CALL EDPP (F11, ZM1 ,  X, Y+DG   , DRM1 )
+      CALL EDPP (F12, ZM1 ,  X, Y-DG   , DRM1 )
+      S = S0
+      XG1 = X/DG
+      XG2 = XG1*XG1
+      XG3 = XG2*XG1
+      XG4 = XG3*XG1
+C****
+      EY = XG1 * ( (F5-F7)*2./3. - (F6-F8)/12. ) +
+     1         XG3 * ( (F5-F7)/6. - (F6-F8)/12. -
+     2         ( F3 + F11 - F4 - F12 - 2.*F5 + 2.*F7 )/12. )
+      EX = F0 - XG2*( (F1 + F9 + F5 + F7 - 4.*F0) * 2./3. -
+     1         ( F2 + F10 + F6 + F8 - 4.*F0 )/24. ) +
+     2         XG4 * (-( F1 + F9 + F5 + F7 - 4.*F0 )/6. +
+     3         ( F2 + F10 +      F6 + F8 - 4.*F0 )/24. +
+     4         ( F3 + F11 + F4 + F12 - 2.*F1 - 2.*F9 -
+     5         2.*F5 - 2.*F7 + 4.*F0 )/12. )
+      EZ = XG1 * ( (F1 - F9)*2./3. - (F2 - F10)/12. ) +
+     1         XG3 * ( (F1 - F9)/6. - (F2 - F10)/12. -
+     2         (F3 + F4 - F11 - F12 - 2.*F1 + 2.*F9)/12. )
+      ET = DSQRT( EX * EX + EY * EY + EZ * EZ)
+      RETURN
+      END
+
+
+      SUBROUTINE EDIPL( NO, NP, T, TP ,NUM )
+C****
+C****
+C**** SINGLE MAGNET RAY TRACING BY NUMERICAL INTEGRATION OF DIFFERENTIAL
+C**** EQUATIONS OF MOTION.
+C     T = TIME
+C     TC(1) TO TC(6) =  ( X, Y, Z, VX, VY, VZ )
+C     DTC(1) TO DTC(6) = ( VX, VY, VZ, VXDOT, VYDOT, VZDOT )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  LF1, LF2, LU1, K
+      EXTERNAL EDIP
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK11/  EX, EY, EZ, QMC, IVEC
+      COMMON  /BLCK20/ EC2, EC4, WE, WC
+      COMMON  /BLCK22/  D, DG, S, EF, ET
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION DATA(  75,200 ) ,ITITLE(200)
+      DIMENSION TC(6), DTC(6), DS(6), ES(6)
+C**** DATA  C/ 3.D10/
+C****
+      LF1  = DATA(  1,NO )
+      LU1  = DATA(  2,NO )
+      LF2  = DATA(  3,NO )
+      DG   = DATA(  4,NO )
+      A    = DATA( 11,NO )
+      B    = DATA( 12,NO )
+      D    = DATA( 13,NO )
+      RB   = DATA( 14,NO )
+      EF   = DATA( 15,NO )
+      PHI  = DATA( 16,NO )
+      EC2  = DATA( 17,NO )
+      EC4  = DATA( 18,NO )
+      WE   = DATA( 19,NO )
+      WC   = DATA( 20,NO )
+      Z11  = DATA( 25,NO )
+      Z12  = DATA( 26,NO )
+      Z21  = DATA( 27,NO )
+      Z22  = DATA( 28,NO )
+      DTF1= LF1/ VEL
+      DTF2= LF2/ VEL
+      DTU = LU1/ VEL
+      IF (WE .EQ. 0.) WE = 1000. * RB
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      EX = 0.
+      EY = 0.
+      EZ = 0.
+      ET = 0.
+      S = 0.
+      IF( NP  .GT. 100 ) GO TO 5
+c      write (6,100) ITITLE(NO)
+  100 FORMAT(  ' E.S.-DIPOLE ****', A4,'  ***************************'/)
+c      write(6,101)
+  101 FORMAT( 8H    T CM ,18X, 4HX CM , 7X, 2HEX, 8X, 4HY CM , 7X, 2HEY,
+     1   8X, 4HZ CM, 7X, 2HEZ, 8X, 6HVELZ/C , 6X, 8HTHETA MR , 5X,
+     2   6HPHI MR , 6X, 1HE             )
+      CALL PRNT5 ( T,S,XA   ,YA   ,ZA   ,EX,EY,EZ,ET,VXA  ,VYA  ,VZA   )
+c      write(6,103)
+  103 FORMAT(   '0COORDINATE TRANSFORMATION TO B AXIS SYSTEM '       )
+  109 FORMAT(   '0COORDINATE TRANSFORMATION TO D AXIS SYSTEM '       )
+C**** TRANSFORM FROM INITIAL ENTRANCE COORDINATES TO EFB COORD.
+C****
+    5 CONTINUE
+      TC(1) =  -  XA
+      TC(2) = YA
+      TC(3) = ( A-ZA )
+      TC(4) = - VXA
+      TC(5) = VYA
+      TC(6) = -VZA
+      CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C****
+C****
+   20 TDT = ( TC(3) - Z11 ) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** IN DESIGNATES MAGNET REGIONS FOR BFUN
+C****
+      IN = 1
+      XC = RB
+      ZC = 0.0
+C****
+      C0   = DATA( 29,NO )
+      C1   = DATA( 30,NO )
+      C2   = DATA( 31,NO )
+      C3   = DATA( 32,NO )
+      C4   = DATA( 33,NO )
+      C5   = DATA( 34,NO )
+c      IF( NP  .LE. 100) write(6,104)
+  104 FORMAT( 22H0FRINGING FIELD REGION    )
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, EDIP,  0    )
+      NSTEP = 0
+    6 CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      DO 7 I = 1, NP
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, EDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+        IF (NSTEP  .GT.  200)  GO TO 99
+      IF( Z12 .GE. TC(3) ) GO TO 8
+    7 CONTINUE
+      GO TO 6
+    8 CONTINUE
+      XDTF1 =-( Z12 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, EDIP,  0    )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES, EDIP,  1    )
+      CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      NUM = NUM + 1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write(6,105) NSTEP
+  105 FORMAT( 10H   NSTEPS=,I5 )
+C***
+C***  UNIFORM FIELD REGION
+C**** TRANSFORM TO SECOND EFB COORD SYSTEM
+C***
+      COPAB =DCOS( (PHI)/57.29578)
+      SIPAB =DSIN( (PHI)/57.29578)
+      COSPB =DCOS( (PHI/2.)/57.29578 )
+      SINPB =DSIN( (PHI/2.)/57.29578 )
+      SIP2 =DSIN( (PHI/2.)/57.29578 )
+      XT = TC(1)
+      ZT = TC(3)
+      VXT = TC(4)
+      VZT = TC(6)
+      TC(3) = - ZT  *COPAB +  XT  *SIPAB -2.*RB*SIP2*COSPB
+      TC(1) = - ZT  *SIPAB -  XT  *COPAB -2.*RB*SIP2*SINPB
+      TC(6) = - VZT *COPAB +  VXT *SIPAB
+      TC(4) = - VZT *SIPAB -  VXT *COPAB
+C****
+C****
+C**** UNIFORM FIELD INTEGRATION REGION
+C****
+C****
+      IN = 2
+      XC = -RB
+      ZC = 0.0
+c      IF( NP  .LE. 100) write(6,106)
+  106 FORMAT(   '0UNIFORM FIELD REGION IN C AXIS SYSTEM '  )
+      IF( TC(3)  .LT.  Z21 ) GO TO 15
+C****
+C**** THIS SECTION CORRECTS FOR MAGNETS WHOSE FRINGING FIELDS INTERSECT
+C****
+c      IF( NP  .LE. 100) write(6,102)
+  102 FORMAT( / '   INTEGRATE BACKWARDS    '  )
+      CALL FNMIRK( 6, T,-DTU ,TC, DTC, DS, ES, EDIP,  0    )
+      NSTEP = 0
+   16 CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      DO 17  I =1, NP
+      CALL FNMIRK( 6, T,-DTU, TC, DTC, DS, ES, EDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3)  .LE.  Z21 )  GO TO 18
+   17 CONTINUE
+      GO TO 16
+   18 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, EDIP,  0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, EDIP,  1    )
+      CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write(6,105) NSTEP
+c      IF( NP  .LE. 100) write(6,107)
+  107 FORMAT( / )
+      GO TO 19
+C****
+C****
+   15 CONTINUE
+      CALL FNMIRK( 6, T, DTU ,TC, DTC, DS, ES, EDIP,  0    )
+      NSTEP = 0
+    9 CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      DO 10  I =1, NP
+      CALL FNMIRK( 6, T, DTU, TC, DTC, DS, ES, EDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3)  .GE.  Z21 )  GO TO 11
+   10 CONTINUE
+      GO TO 9
+   11 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, EDIP,  0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES, EDIP,  1    )
+      CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write(6,105) NSTEP
+   19 CONTINUE
+C***
+C***
+C**** SETUP FOR SECOND FRINGE FIELD AND INTEGRATION
+C****
+C****
+      C0   = DATA( 35,NO )
+      C1   = DATA( 36,NO )
+      C2   = DATA( 37,NO )
+      C3   = DATA( 38,NO )
+      C4   = DATA( 39,NO )
+      C5   = DATA( 40,NO )
+      IN = 3
+c      IF( NP  .LE. 100) write(6,104)
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, EDIP,  0    )
+      NSTEP = 0
+   12 CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      DO 13  I =1, NP
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, EDIP,  1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3) .GE. Z22 )  GO TO 14
+   13 CONTINUE
+      GO TO 12
+   14 CONTINUE
+      XDTF2 = ( Z22 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, EDIP,  0    )
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, EDIP,  1    )
+      CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write(6,105) NSTEP
+C****
+C**** TRANSFORM TO OUTPUT SYSTEM COORD.
+C****
+      XT = TC(1)
+      ZT = TC(3)
+      VXT = TC(4)
+      VZT = TC(6)
+      TC(3) = ZT - B
+      TC(1) = XT
+      TC(6) = VZT
+      TC(4) = VXT
+c      IF( NP  .LE. 100) write(6,109)
+      CALL PRNT5 ( T,S,TC(1),TC(2),TC(3),EX,EY,EZ,ET,TC(4),TC(5),TC(6) )
+C****
+C**** TRANSLATE PARTICLE TO OUT SYSTEM COORD.
+C****
+C****
+C****
+C****
+   30 TDT = -TC(3) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      TP = T * VEL
+      EX = 0.
+      EY = 0.
+      EZ = 0.
+      ET = 0.
+      S  = 0.
+      VXF    = 1000. *DATAN2( TC(4), TC(6)  )
+      VYF    = 1000. *DASIN ( TC(5)/ VEL    )
+      VZF    = TC(6) / VEL
+c      IF( NP.LE.100) write(6,115) TP,TC(1),TC(2),TC(3),VZF,VXF,VYF
+  115 FORMAT( F10.4, 10X, F10.3, 11X, F10.3, 11X, F10.3, 11X,
+     1   F13.5, F13.2, F11.2                   )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 4
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** CALCULATE INTERCEPTS IN SYSTEM D
+C****
+      Z0X = -TC(1)/ ( TC(4) / TC(6)    + 1.E-10 )
+      Z0Y = -TC(2)/ ( TC(5) / TC(6)    + 1.E-10 )
+c      IF( NP  .LE. 100) write(6,111) VXF, VYF, Z0X, Z0Y
+  111 FORMAT( / ' INTERSECTIONS WITH VER. AND HOR. PLANES '          ,
+     X       /15X, 5H  XP=,F10.4, 10H MR    YP=,F10.4, 3H MR   /
+     1        15X, 5H Z0X=,F10.2, 10H CM   Z0Y=,F10.2, 3H CM   /     )
+      RETURN
+   99 CALL PRNT4(NO, IN)
+      RETURN
+      END
+
+
+      SUBROUTINE EDPP( EFLD, Z, X, Y, DRP )
+C****
+C**** CALCULATE S; DETERMINE E-FIELD IN FRINGE REGIONS
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8 K
+      COMMON  /BLCK20/ EC2, EC4, WE, WC
+      COMMON  /BLCK22/  D, DG, S, EF, ET
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      FEF = -EF
+      IF ( IN .EQ. 1 ) FEF = +EF
+      W2 = WE * WE
+      ZD1 = Z / D
+      ZD2 = EC2 * ZD1 * Y * Y / W2
+      W4 = W2 * W2
+      ZD3 = EC4 * (Y**4) / W4
+      S = ZD1 + ZD2 + ZD3
+      CS = C0 + S * (C1 + S * (C2 + (S * (C3 + S * (C4 +S * C5)))))
+      IF (DABS(CS) .GT. 70.) CS = DSIGN(70.D0, CS)
+      E = DEXP(CS)
+      P0 = 1.0 + E
+      EFLD = (FEF / P0) * (RB / DRP)
+      RETURN
+      END
+        SUBROUTINE EXIT
+c       CALL DTIME
+c	    ctemp=ctime(time())
+c		write(6,*)ctemp
+        STOP
+        END
+
+
+      SUBROUTINE FB01AD(C,  VK,VE)
+      IMPLICIT REAL*8(A-H,O-Z)
+      DATA XLG/1.0D300/
+C**NON-IBM......REAL * 8 XLG/'7FFFFFFFFFFFFFFF'X/
+      D=1D0-C
+      IF(D .GT. 0D0)E=-DLOG(D)
+C**** HARWELL VERSION OF FB01AD
+      IF(C .GE. 1D0)GO TO 2
+      VE=E*((((((((((
+     A     3.18591956555015718D-5*D  +.989833284622538479D-3)*D
+     B    +.643214658643830177D-2)*D +.16804023346363385D-1)*D
+     C    +.261450147003138789D-1)*D +.334789436657616262D-1)*D
+     D    +.427178905473830956D-1)*D +.585936612555314917D-1)*D
+     E    +.937499997212031407D-1)*D +.249999999999901772D0)*D)
+     F    +(((((((((
+     G     .149466217571813268D-3*D  +.246850333046072273D-2)*D
+     H    +.863844217360407443D-2)*D+.107706350398664555D-1)*D
+     I    +.782040406095955417D-2)*D +.759509342255943228D-2)*D
+     J    +.115695957452954022D-1)*D +.218318116761304816D-1)*D
+     K    +.568051945675591566D-1)*D +.443147180560889526D0)*D
+     L    +1D0
+C****
+C**** ROUTINE MODIFIED TO CALCULATE VK AND VE ALWAYS
+C****
+C****
+      VK=E*((((((((((
+     A     .297002809665556121D-4*D   +.921554634963249846D-3)*D
+     B    +.597390429915542916D-2)*D  +.155309416319772039D-1)*D
+     C    +.239319133231107901D-1)*D  +.301248490128989303D-1)*D
+     D    +.373777397586236041D-1)*D  +.48828041906862398D-1)*D
+     E    +.703124997390383521D-1)*D  +.124999999999908081D0)*D
+     F    +.5D0)+(((((((((
+     G     .139308785700664673D-3*D   +.229663489839695869D-2)*D
+     H    +.800300398064998537D-2)*D  +.984892932217689377D-2)*D
+     I    +.684790928262450512D-2)*D  +.617962744605331761D-2)*D
+     J    +.878980187455506468D-2)*D  +.149380135326871652D-1)*D
+     K    +.308851462713051899D-1)*D  +.965735902808562554D-1)*D
+     L    +1.38629436111989062D0
+      RETURN
+    2 VE=1D0
+      VK=XLG
+      RETURN
+      END
+
+
+      SUBROUTINE FB02AD(CAYSQ,SINP,COSP,E,F)
+C
+      IMPLICITREAL*8(A-H,O-Z)
+      PHI=DATAN(SINP/COSP)
+      IF(CAYSQ*SINP*SINP-0.5D0)1,1,5
+    1 H=1.0D0
+      A=PHI
+      N=0
+      SIG1=0.D0
+      SIG2=0.D0
+      SIN2=SINP*SINP
+      TERM=SINP*COSP*0.5D0
+      CRIT=PHI
+    2 N=N+1
+      RECIP=1.0D0/N
+      FACT=(N-.5D0)*RECIP
+      H1=H
+      H=FACT*CAYSQ*H
+      A=FACT*A-TERM*RECIP
+      TERM=TERM*SIN2
+      CRIT=CRIT*SIN2
+      DEL1=H*A
+      DEL2=-.5D0*RECIP*CAYSQ*H1*A
+      SIG1=SIG1+DEL1
+      SIG2=SIG2+DEL2
+      IF(DABS(DEL1)-4.0D-16)4,3,3
+   3  IF(DABS(CRIT)-DABS(A))4,2,2
+    4 F=PHI+SIG1
+      E=PHI+SIG2
+      GO TO 8
+    5 CFI=1.D0
+      CFJ=1.D0
+      CFL=0.D0
+      CFM=0.D0
+      CFN=0.D0
+      SIG1=0.D0
+      SIG2=0.D0
+      SIG3=0.D0
+      SIG4=0.D0
+      N=0
+      FACT1=1.0D0-CAYSQ*SINP*SINP
+      FACTOR=.5D0*COSP*DSQRT(CAYSQ/FACT1)
+      FACTRO=FACTOR+FACTOR
+      CAYDSQ=1.0D0-CAYSQ
+    6 N=N+1
+      RECIP=1.0D0/N
+      FACTN=RECIP*(N-.5D0)
+      FACTM=(N+.5D0)/(N+1.0D0)
+      FACTOR=FACTOR*FACT1
+      CFI1=CFI
+      CFJ1=CFJ
+      CFI=CFI*FACTN
+      CFJ=CFJ*FACTN*FACTN*CAYDSQ
+      CFL=CFL+.5D0/(N*(N-.5D0))
+      CFM=(CFM-FACTOR*RECIP*CFI)*FACTM*FACTM*CAYDSQ
+      CFN=(CFN-FACTOR*RECIP*CFI1)*FACTN*FACTM*CAYDSQ
+      DEL1=CFM-CFJ*CFL
+      DEL2=CFN-(FACTN*CFL-.25D0*RECIP*RECIP)*CAYDSQ     *CFJ1
+      DEL3=CFJ
+      DEL4=FACTM*CFJ
+      SIG1=SIG1+DEL1
+      SIG2=SIG2+DEL2
+      SIG3=SIG3+DEL3
+      SIG4=SIG4+DEL4
+      IF(DABS (DEL1)-4.0D-16)7,6,6
+    7 CAYMOD=DSQRT(CAYSQ)
+      FLOG1=DLOG(4.0D0/(DSQRT(FACT1)+CAYMOD*COSP))
+      T1=(1.0D0+SIG3)*FLOG1+FACTRO*DLOG(.5D0+.5D0*CAYMOD*DABS (SINP))
+      T2=(.5D0+SIG4)*CAYDSQ*FLOG1+1.0D0-FACTRO*(1.0D0-CAYMOD*DABS(SINP))
+      F=T1+SIG1
+      E=T2+SIG2
+    8 RETURN
+      END
+
+
+      SUBROUTINE FB03AD( GN,CACA,P )
+C====== 23/03/72 LAST LIBRARY UPDATE
+      IMPLICITREAL*8(A-H,O-Z)
+      IF(GN)1,2,2
+    1 IF(CACA)3,3,4
+    3 P=1.5707963268/DSQRT(1.D0-GN)
+      RETURN
+    4 STH=DSQRT(-GN/(CACA-GN))
+      CTH=DSQRT(1.D0-STH*STH)
+      CADA=1.D0-CACA
+      CALLFB01AD(CACA,     CAPK,CAPE)
+      CALLFB02AD(CADA,STH,CTH,E,F)
+      BR=CAPE*F-CAPK*(F-E)
+      P=CAPK*CTH*CTH+STH*BR/DSQRT(1.D0-GN)
+      RETURN
+    2 IF(GN-CACA)10,30,20
+   10 STH=DSQRT(GN/CACA)
+      CTH=DSQRT(1.D0-STH*STH)
+      CALLFB01AD(CACA,     CAPK,CAPE)
+      CALLFB02AD(CACA,STH,CTH,E,F)
+      BR=CAPK*E-CAPE*F
+      P=CAPK+BR*STH/(CTH*DSQRT(1.D0-GN))
+      RETURN
+   30 CALLFB01AD(CACA,     CAPK,CAPE)
+      P=CAPE/(1.D0-CACA)
+      RETURN
+   20 CADA=1.D0-CACA
+      PI=3.1415926536
+      STH=DSQRT((1.D0-GN)/CADA)
+      CTH=DSQRT(1.D0-STH*STH)
+      CALLFB01AD(CACA,     CAPK,CAPE)
+      CALLFB02AD(CADA,STH,CTH,E,F)
+      BR=PI/2.+CAPK*(F-E)-CAPE*F
+      P=CAPK+BR*DSQRT(GN)/(CADA*STH*CTH)
+      RETURN
+      END
+      SUBROUTINE FNMIRK(N,X,H,Y,DY,D,E,BFUN,  NDEX)
+      IMPLICIT REAL*8(A-H,O-Z)
+      EXTERNAL BFUN
+      DIMENSION Y(1),DY(1),D(1),E(1)
+      IF( NDEX.NE.0) GO TO 20
+      DO 10 I=1,N
+      D(I)=Y(I)
+   10 CONTINUE
+      CALL DERIV ( BFUN )
+      HALFH=0.5*H
+      RETURN
+   20 DO 30 I=1,N
+      T=HALFH*DY(I)
+      Y(I)=D(I)+T
+      E(I)=T
+   30 CONTINUE
+      XZERO=X
+      X=X+HALFH
+      CALL DERIV ( BFUN )
+      DO 40 I=1,N
+      T=HALFH*DY(I)
+      Y(I)=D(I)+T
+      E(I)=E(I)+2.0*T
+   40 CONTINUE
+      CALL DERIV ( BFUN )
+      DO 50 I=1,N
+      T=H*DY(I)
+      Y(I)=D(I)+T
+      E(I)=E(I)+T
+   50 CONTINUE
+      X=XZERO+H
+      CALL DERIV ( BFUN )
+      DO 60 I=1,N
+      Y(I)=D(I)+(E(I)+HALFH*DY(I))*.333333333
+      D(I)=Y(I)
+   60 CONTINUE
+      CALL DERIV ( BFUN )
+      RETURN
+      END
+C
+
+
+C*IBM FUNCTION DASIN(X)
+C****
+C**** ROUTINE TO PASS CALL TO IBM DOUBLE PRECISION ARC-SINE
+C****
+C*IBM IMPLICIT REAL*8(A-H,O-Z)
+C*IBM DASIN = DARSIN(X)
+C*IBM RETURN
+C*IBM END
+
+
+      SUBROUTINE  LENS ( NO,  NP,T, TP ,NUM )
+C****
+C****
+C**** THIN LENS ROUTINE
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+C**** DATA  C/ 3.D10/
+C****
+  100 FORMAT( /  '   THIN LENS     ****  ', A4, '****************',//
+     1'      T CM', 18X, 'X CM', 7X, 'Y CM', 7X, 'Z CM' , '      VELZ/C'
+     2   , '    THETA MR      PHI MR'  /  )
+  103 FORMAT( F10.4, 11X, 3F11.3, F12.5, 2F12.3  )
+C****
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 1
+      CALL PLT2 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 100) ITITLE(NO)
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. *DASIN ( VYA/VEL )
+      VZP =  VZA  / VEL
+      TP = T*VEL
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+      XXA = XA
+      YYA = YA
+      CS = DATA(9,NO)
+      XA =XXA*DATA(1,NO) + VXP*DATA(2,NO)
+      VXP =XXA*DATA(3,NO) + VXP*DATA(4,NO) -
+     1     CS*DATA(3,NO)**4 * ( XXA*XXA + YYA*YYA )*XXA/10**9
+      YA =YYA*DATA(5,NO) + VYP*DATA(6,NO)
+      VYP =YYA*DATA(7,NO) + VYP*DATA(8,NO) -
+     1     CS*DATA(7,NO)**4 * ( XXA*XXA + YYA*YYA )*YYA/10**9
+      VXA = VEL*DSIN( VXP/1000.D0 )
+      VYA = VEL*DSIN( VYP/1000.D0 )
+      VZA = DSQRT(VEL*VEL -VXA*VXA-VYA*VYA)
+      VZP = VZA/VEL
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT2 ( NUM, NO, NBR, TPAR )
+      RETURN
+      END
+
+
+      SUBROUTINE NDIP
+C****
+C****
+C**** MTYP = 3 OR 4
+C**** THIS VERSION OF BFUN IS MAINLY FOR NONUNIFORM FIELD MAGNETS
+C**** THE CENTRAL FIELD REGION IS REPRESENTED TO 3'RD ORDER ON-AND-
+C**** OFF THE MIDPLANE BY ANALYTIC EXPRESSIONS. SEE SLAC NO. 75
+C**** FRINGE FIELD REGIONS REPRESENTED BY FERMI TYPE FALL-OFF
+C**** ALONG WITH RADIAL FALL-OFF
+C**** COMPONENTS OF 'B' IN FRINGE REGION EVALUATED BY NUMERICAL METHODS
+C****
+C****
+C**** THE RELATIONSHIP BETWEEN B0, ......... B12 AND B(I,J) RELATIVE TO
+C**** AXES (Z,X) IS GIVEN BY
+C****
+C****
+C**** B0  = B( 0, 0 )
+C**** B1  = B( 1, 0 )
+C**** B2  = B( 2, 0 )
+C**** B3  = B( 1, 1 )
+C**** B4  = B( 1,-1 )
+C**** B5  = B( 0, 1 )
+C**** B6  = B( 0, 2 )
+C**** B7  = B( 0,-1 )
+C**** B8  = B( 0,-2 )
+C**** B9  = B(-1, 0 )
+C**** B10 = B(-2, 0 )
+C**** B11 = B(-1, 1 )
+C**** B12 = B(-1,-1 )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  NDX, K
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK20/  NDX,BET1,GAMA,DELT,CSC
+      COMMON  /BLCK21/  RCA,DELS,BR,S2,S3,S4,S5,S6,S7,S8,SCOR
+      COMMON  /BLCK22/  D, DG, S, BF, BT
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION TC(6), DTC(6)
+      X = TC(1)
+      Y = TC(2)
+      Z = TC(3)
+      DX = X - XC
+      DZ = Z - ZC
+      RP =DSQRT( DX**2 + DZ**2 )
+      DR = RP - RB
+      GO TO ( 1, 2, 3, 14 ), IN
+    7 CONTINUE
+c    7 write (6, 8) IN, MTYP
+      CALL EXIT
+    8 FORMAT (    '0 ERROR -GO TO -  IN BFUN   IN=', I3, '   MTYP=',I4 )
+    2 DRR1 = DR/RB
+      DRR2 = DRR1*DRR1
+      DRR3 = DRR2*DRR1
+      DRR4 = DRR3*DRR1
+      IF( Y .NE. 0. )  GO TO 4
+C****
+C**** MID-PLANE UNIFORM FIELD REGION
+C****
+      BX = 0.
+      BY = 0.
+      IF( MTYP .EQ. 3) BY=
+     1     BF* ( 1. - NDX*DRR1 + BET1*DRR2 + GAMA*DRR3 + DELT*DRR4 )
+      IF( MTYP .EQ. 4) BY= BF/ (1. + NDX*DRR1 )
+      BZ = 0.
+      BT = BY
+      RETURN
+C****
+C**** NON MID-PLANE UNIFORM FIELD REGION
+C****
+    4 YR1 = Y/RB
+      YR2 = YR1*YR1
+      YR3 = YR2*YR1
+      YR4 = YR3*YR1
+      RR1 = RB/RP
+      RR2 = RR1*RR1
+      RR3 = RR2*RR1
+      IF( MTYP .EQ. 3 ) GO TO 11
+      IF( MTYP .EQ. 4 ) GO TO 12
+      GO TO 7
+C****
+C**** MTYP = 3
+C****
+   11 BRR = BF*( ( -NDX + 2.*BET1*DRR1 + 3.*GAMA*DRR2 + 4.*DELT*DRR3 )
+     1   *YR1 - (NDX*RR2 + 2.*BET1*RR1*(1.-RR1*DRR1) +
+     2   3.*GAMA*( 2. + 2.*RR1*DRR1 - RR2*DRR2 ) +
+     3   4.*DELT*( 6.*DRR1 + 3.*RR1*DRR2 - RR2*DRR3 ))*YR3/6. )
+      BY = BF* ( 1. - NDX*DRR1 + BET1*DRR2 + GAMA*DRR3 + DELT*DRR4 -
+     1   .5*YR2*( -NDX*RR1 + 2.*BET1*( 1. + RR1*DRR1) +
+     2   3.*GAMA*DRR1*( 2. + RR1*DRR1) + 4.*DELT*DRR2*(3. + RR1*DRR1) )
+     3   + YR4*( -NDX*RR3 + 2.*BET1*( RR3*DRR1 - RR2) +
+     4   3.*GAMA*( 4.*RR1 - 2.*RR2*DRR1 + RR3*DRR2 ) +
+     5   4.*DELT*( 6. + 12.*RR1*DRR1 - 3.*RR2*DRR2 + RR3*DRR3 ) )/24. )
+      GO TO 13
+C****
+C**** MTYP = 4
+C****
+   12 DNR1 = 1. + NDX*DRR1
+      DNR2 = DNR1*DNR1
+      DNR3 = DNR2*DNR1
+      DNR4 = DNR3*DNR1
+      DNR5 = DNR4*DNR1
+      BRR = BF*NDX*( -YR1/DNR2 + YR3*( 6.*NDX*NDX/DNR4 -
+     1   2.*NDX*RR1/DNR3 - RR2/DNR2 ) /6.  )
+      BY = BF*( 1./DNR1 + .5*YR2*NDX*( -2.*NDX/DNR3 + RR1/DNR2) +
+     2   YR4*NDX*( 24.*NDX**3 /DNR5 - 12.*NDX*NDX*RR1/DNR4 -
+     3   2.*NDX*RR2/DNR3 - RR3/DNR2 ) /24.  )
+C****
+C****
+   13 BX = BRR*DX/RP
+      BZ = BRR*DZ/RP
+      BT  =DSQRT(BX*BX + BY*BY + BZ*BZ)
+      RETURN
+C****
+C****
+    1 SINE = -1.
+      GO TO 5
+    3 SINE = 1.
+    5 IF( Z  .GT. 0. ) DR = X * SINE*CSC
+      CALL NDPP( B0, Z, X, Y, DR      )
+      IF( Y  .NE. 0. )  GO TO 6
+C****
+C**** MID-PLANE FRINGING FIELD REGION
+C****
+      BX = 0.
+      BY = B0
+      BZ = 0.
+      BT   = B0
+      RETURN
+C****
+C**** NON MID-PLANE FRINGING FIELD REGION
+C****
+    6 IF( Z .GT. 0. )  GO TO 9
+      DR1  =       (DSQRT( DX**2 + (DZ+DG)**2 ) - RB )
+      DR2  =       (DSQRT( DX**2 + (DZ+2.*DG)**2 ) - RB )
+      DR3  =       (DSQRT( (DX+DG)**2 + (DZ+DG)**2 )  - RB )
+      DR4  =       (DSQRT( (DX-DG)**2 + (DZ+DG)**2 )  - RB )
+      DR5  =       (DSQRT( (DX+DG)**2 + DZ**2 ) - RB )
+      DR6  =       (DSQRT( (DX+ 2.*DG)**2 + DZ**2 ) - RB )
+      DR7  =       (DSQRT( (DX-DG)**2 + DZ**2 ) - RB )
+      DR8  =       (DSQRT( (DX- 2.*DG)**2 + DZ**2 ) - RB )
+      DR9  =       (DSQRT( DX**2 + (DZ-DG)**2 ) - RB )
+      DR10 =       (DSQRT( DX**2 + (DZ-2.*DG)**2 ) - RB )
+      DR11 =       (DSQRT( (DX+DG)**2 + (DZ-DG)**2 )  - RB )
+      DR12 =       (DSQRT( (DX-DG)**2 + (DZ-DG)**2 )  - RB )
+      GO TO 10
+    9 DR1  = SINE* X*CSC
+      DR2  = DR1
+      DR9  = DR1
+      DR10 = DR1
+      DR3  = SINE* ( X + DG )*CSC
+      DR5  = DR3
+      DR11 = DR3
+      DR4  = SINE*( X - DG )*CSC
+      DR7  = DR4
+      DR12 = DR4
+      DR6  = SINE* ( X + 2.*DG )*CSC
+      DR8  = SINE* ( X - 2.*DG )*CSC
+C****
+C****
+   10 CALL NDPP ( B1 , Z + DG, X , Y , DR1 )
+      CALL NDPP ( B2 , Z + 2.*DG, X , Y , DR2 )
+      CALL NDPP ( B3 , Z + DG, X + DG , Y , DR3 )
+      CALL NDPP ( B4 , Z + DG, X - DG , Y , DR4 )
+      CALL NDPP ( B5 , Z , X + DG , Y, DR5 )
+      CALL NDPP ( B6 , Z , X + 2.*DG , Y , DR6 )
+      CALL NDPP ( B7 , Z , X - DG , Y, DR7 )
+      CALL NDPP ( B8 , Z , X - 2.*DG , Y , DR8 )
+      CALL NDPP ( B9 , Z - DG, X , Y , DR9 )
+      CALL NDPP ( B10, Z - 2.*DG, X, Y, DR10 )
+      CALL NDPP ( B11, Z - DG, X + DG , Y , DR11 )
+      CALL NDPP ( B12, Z - DG, X - DG , Y , DR12 )
+      YG1 = Y/DG
+      YG2 = YG1**2
+      YG3 = YG1**3
+      YG4 = YG1**4
+      BX = YG1 * ( (B5-B7)*2./3. - (B6-B8)/12. )  +
+     1     YG3*( (B5-B7)/6. - (B6-B8)/12. -
+     2     (B3 + B11 - B4 - B12 - 2.*B5 + 2.*B7 ) / 12. )
+      BY = B0 - YG2*( ( B1 + B9 + B5 + B7 - 4.*B0 ) *2./3. -
+     1     ( B2 + B10 + B6 + B8 - 4.*B0 ) / 24. ) +
+     2     YG4* (-( B1 + B9 + B5 + B7 - 4.*B0 ) / 6. +
+     3     ( B2 + B10 + B6 + B8 - 4.*B0 ) / 24. +
+     4     ( B3 + B11 + B4 + B12 - 2.*B1 - 2.*B9 -
+     5     2.*B5 - 2.*B7 + 4.*B0 ) / 12. )
+      BZ = YG1*( (B1 - B9 ) *2./3. - ( B2 - B10 ) /12. ) +
+     1     YG3*( ( B1 - B9 ) / 6. - ( B2 - B10 ) / 12. -
+     2     ( B3 + B4 - B11 - B12 - 2.*B1 + 2.*B9 ) / 12.  )
+      BT  =DSQRT(BX*BX + BY*BY + BZ*BZ)
+      RETURN
+   14 BX = 0.
+      BY = BR
+      BZ = 0.
+      BT = BR
+      RETURN
+      END
+
+
+      SUBROUTINE  NDPP ( BFLD, Z, X, Y , DR )
+C****
+C****
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  NDX, K
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK20/  NDX,BET1,GAMA,DELT,CSC
+      COMMON  /BLCK21/  RCA,DELS,BR,S2,S3,S4,S5,S6,S7,S8,SCOR
+      COMMON  /BLCK22/  D, DG, S, BF, BT
+      COMMON  /BLCK23/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK24/  RB, XC, ZC
+      COMMON  /BLCK25/  IN, MTYP
+      DIMENSION TC(6), DTC(6)
+      DRR1 = DR/RB
+      DRR2 = DRR1*DRR1
+      DRR3 = DRR2*DRR1
+      DRR4 = DRR3*DRR1
+C****
+C**** MTYP    :                  MODIFIED ITERATIVE PROCEDURE
+C****
+      XP = X
+      XP2 = XP*XP
+      XP3 = XP2*XP
+      XP4 = XP3 * XP
+      ZP = -(S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+     1       S7*XP4*XP3 + S8*XP4*XP4 )
+      AZ = (Z-ZP)/10.D0
+      AZMAX = DSQRT(  X*X + Z*Z  )
+      IF( AZ  .GT.  AZMAX  )  AZ = AZMAX
+      ZSIGN = Z-ZP
+      RINV4 = 0.
+      DO 11 I=1,21
+      XP   = X + AZ*(I-11)
+      XP2 = XP*XP
+      XP3 = XP2*XP
+      XP4 = XP3*XP
+      ZP = -(S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+     1       S7*XP4*XP3 + S8*XP4*XP4 )
+      XXP = X-XP
+      ZZP = Z-ZP
+      DD =            XXP*XXP + ZZP*ZZP
+      IF( DD  .LT.  1.D-15 )  DD = 1.D-15
+      IF( DD  .GT.  1.D15  )  DD = 1.D15
+      RINV4 = RINV4 + 1.0D0 / (DD*DD )
+   11 CONTINUE
+      DP = DSQRT( 1.D0/RINV4 )
+      DP = DSQRT( DP )
+      S = 1.9023D0* DSIGN( 1.D0, ZSIGN ) * DP/D + DELS
+C****
+C**** FIRST GUESS FOR CLOSEST POINT IS
+C****
+C*    XP = X
+C*    XP2 = XP*XP
+C*    XP3 = XP2*XP
+C*    XP4 = XP3*XP
+C****
+C**** CALCULATE ZP ON CURVE FOR CORRESPONDING XP
+C****
+C*    ZP = -( S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+C*   1   S7*XP4*XP3 + S8*XP4*XP4 )
+C*    ZSIGN = Z-ZP
+C****
+C**** SLOPE OF CURVE AT XP, ZP
+C****
+C*    DO 4 I=1,3
+C*    DZDXC = -(2.*S2*XP + 3.*S3*XP2+ 4.*S4*XP3 + 5.*S5*XP4 +
+C*   1   6.*S6*XP4*XP + 7.*S7*XP4*XP2 + 8.*S8*XP4*XP3 )
+C****
+C**** NEXT APPROXIMATION TO CLOSEST POINT IS
+C****
+C*    XP = ( DZDXC*(Z-ZP)  +  DZDXC*DZDXC*XP + X ) / (1.+DZDXC*DZDXC)
+C*    IF( I  .EQ.  1 )  XP = (3.*XP +  X ) / 4.
+C*    XP2 = XP*XP
+C*    XP3 = XP2*XP
+C*    XP4 = XP3*XP
+C*    ZP = -( S2*XP2 + S3*XP3 + S4*XP4 + S5*XP4*XP + S6*XP4*XP2 +
+C*   1   S7*XP4*XP3 + S8*XP4*XP4 )
+C*  4 CONTINUE
+C*    XXP = X-XP
+C*    ZZP = Z-ZP
+C*    S = DSIGN( 1.D0,ZSIGN) * DSQRT( XXP*XXP + ZZP*ZZP) / D + DELS
+C****
+C****
+C****
+C****
+      CS=C0+S*(C1+S*(C2+S*(C3+S*(C4+S*C5))))
+      IF( DABS(CS)  .GT.  70.  )  CS =DSIGN( 70.D0 ,CS  )
+      E=DEXP(CS)
+      P0 = 1.0 + E
+      DB=BF-BR
+      BFLD = 0.
+      IF( MTYP .EQ. 3 ) BFLD =
+     1       BR +( 1. - NDX*DRR1 + BET1*DRR2+GAMA*DRR3+DELT*DRR4)*DB/P0
+      IF( MTYP .EQ. 4 ) BFLD = BR + ( 1./(1. +NDX*DRR1) )*DB/P0
+C****
+C**** write(6,100) X, Y, Z,  DR, S, BFLD
+C*100 FORMAT( 1P6D15.4 )
+C****
+      RETURN
+      END
+      SUBROUTINE OPTIC( J, JFOCAL, NP, T, TP )
+C****
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 2/  XO, YO, ZO, VXO, VYO, VZO, RTL(1000), RLL(1000)
+      COMMON /BLCK 3/ XOR , YOR , ZOR , TH0, PH0, TL1
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      DIMENSION XO(1000),YO(1000),ZO(1000),VXO(1000),VYO(1000),VZO(1000)
+C**** DATA  C/ 3.D10/
+C****
+C****
+  100 FORMAT( /  ' INTERSECTION POINT IN XZ-PLANE OF CENTRAL RAY AND THI
+     1S RAY '      )
+  101 FORMAT(  ' (IN D AXIS SYSTEM                 )       '         )
+  102 FORMAT(  ' (IN OPTIC AXIS SYSTEM             )        '        )
+  103 FORMAT( / ' RAY PARAMETERS AT THE FOCAL AXIS SYSTEM  '         )
+  104 FORMAT( / ' COORDINATE TRANSFORMATION TO OPTIC AXIS SYSTEM  '  )
+C****
+C****
+C****
+  105 FORMAT( / '  *****************************************************
+     1************************************************************'/  )
+c      IF( NP  .LE. 100) write (6, 105)
+      IF( J  .GT.  2  )  GO TO 19
+      IF( J  .EQ.  1 )  GO TO 15
+      IF( J  .EQ. 2)  GO TO 18
+      CALL EXIT
+   15 B1X = XA
+      B1Y = YA
+      S1X = VXA/VZA
+      S1Y = VYA/VZA
+      TT = T
+      VEL1 = VEL
+      VZA1 = VZA
+      S1XP = DATAN2( VXA,VZA )
+      COS1 =DCOS(S1XP)
+      SIN1 =DSIN(S1XP)
+      ZZZZ = 0.
+      TT1 = TT*1.0D+09
+      TL1 = TT*VEL
+      TH0 = 1000. * S1XP
+      PH0 = 1000. * DASIN (VYA/VEL)
+      GO TO 17
+   18 B2X = XA
+      B2Y = YA
+      S2X = VXA/VZA
+      S2Y = VYA/VZA
+C****
+C**** CALCULATE CENTRAL AND PARAXIAL RAY INTERCEPTS IN SYSTEM - D
+C****
+      DSX = S1X-S2X
+      IF( DSX .EQ. 0. )   DSX = 1.D-30
+      ZINT =  ( B2X-B1X) /  DSX
+      XINT = ( B2X*S1X - B1X*S2X ) /  DSX
+      YINT = S2Y*ZINT + B2Y
+      XOR  = XINT
+      YOR  = 0.
+      ZOR  = ZINT
+      IF( JFOCAL .EQ. 0 ) GO TO 14
+      XOR  = B1X
+      ZOR  = 0.
+   14 CONTINUE
+C
+C      always print intersection 
+C
+C      IF( NP  .GT. 100 ) GO TO 5
+c      write (6, 100)
+c      write (6, 101)
+c      write (6, 114) XINT, YINT, ZINT
+  114 FORMAT(  14X, 6HXXINT= , F11.4,  3H CM ,  /
+     1         14X, 6HYYINT= , F11.4,  3H CM ,  /
+     2         14X, 6HZZINT= , F11.4,  3H CM ,  /          )
+  115 FORMAT( F10.4, 10X, F10.3, 11X, F10.3, 11X, F10.3, 11X,
+     1   F13.5, F13.2, F11.2                   )
+C****
+C**** ALTERATION OF INTERCEPTS TO OPTIC AXIS SYSTEM
+C****
+    5 ZINTZ = ZINT*COS1 + (XINT-B1X) *SIN1
+      XINTX =-ZINT*SIN1 + (XINT-B1X) *COS1
+      ZZZZ = ZINTZ
+      IF( JFOCAL  .NE.  0 )  ZZZZ = 0.
+C****
+C**** FLIGHT PATH AND TIME FOR RAY-1 IN FOCAL AXIS SYSTEM
+C****
+      TT = TT + ZZZZ/DABS(VZA1)
+      TT1 = TT*1.0D+09
+      TL1 = TT*VEL1
+C
+C      always print intersection 
+C
+C      IF( NP  .GT. 100 ) GO TO 17
+c      write (6, 102)
+c      write (6, 114) XINTX, YINT, ZINTZ
+      GO TO 17
+C****
+C**** GENERAL RAY INTERCEPTS IN D-AXIS SYSTEM
+C****
+   19 BJX = XA
+      BJY = YA
+      SJX = VXA/VZA
+      SJY = VYA/VZA
+      DSX = S1X-SJX
+      IF( DSX .EQ. 0. )   DSX = 1.D-30
+      XINT1 = ( BJX*S1X - B1X*SJX ) /  DSX
+      ZINT1 = ( BJX - B1X ) /  DSX
+      YINT1 = SJY*ZINT1 + BJY
+      IF( NP  .GT. 100 ) GO TO 17
+c      write (6, 100)
+c      write (6, 101)
+c      write (6, 114) XINT1, YINT1, ZINT1
+C****
+C**** TRANSFORM SYSTEM-D TO OPTIC AXIS SYSTEM
+C**** TRANSLATE TO (B1X,0) AND ROTATE BY (S1X,0)
+C****
+   17 IF( JFOCAL .EQ. 2 ) GO TO 13
+      XT = XA
+      ZT = ZA
+      VXT = VXA
+      VZT = VZA
+      ZA    = ZT*COS1 + ( XT-B1X ) *SIN1
+      XA    =-ZT*SIN1 + ( XT-B1X ) *COS1
+      VZA   = VZT*COS1 + VXT*SIN1
+      VXA   =-VZT*SIN1 + VXT*COS1
+   13 CONTINUE
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. * DASIN( VYA/VEL )
+      VZP = VZA   / VEL
+      TP = T * VEL
+      IF( NP  .GT. 100 ) GO TO 16
+c      write (6, 104)
+C****
+c      write (6, 115) TP, XA,  YA,  ZA,        VZP, VXP, VYP
+   16 TDT = -ZA    /DABS( VZA   )
+      XA = XA       + TDT * VXA
+      YA = YA       + TDT * VYA
+      ZA = ZA       + TDT * VZA
+      T = T + TDT
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. * DASIN( VYA/VEL )
+      VZP = VZA   / VEL
+      TP = T * VEL
+C****
+C**** TRANSLATE PARTICLE TO FOCAL AXIS SYSTEM
+C****
+      XINT2= XA    + ZZZZ* VXA/VZA
+      YINT2= YA    + ZZZZ* VYA/VZA
+      ZINT2 = 0.
+C****
+C****
+      TT = T + ZZZZ/DABS(VZA)
+      TTJ = TT*1.0D+09
+      TLJ = TT*VEL
+C****
+C**** PATH LENGTHS AND TIMES RELATIVE TO RAY-1
+C****
+      TTJ1 = TTJ - TT1
+      TLJ1 = TLJ - TL1
+C****
+C****
+      XO(J) = XINT2
+      YO(J) = YINT2
+      ZO(J) = ZA
+      VXO(J) = VXP
+      VYO(J) = VYP
+      VZO(J) = VZP
+C****
+C**** SAVE TIME DIFFERENCES IN UNITS OF VELOCITY OF RAY-1
+C****
+      RTL(J) = TTJ1*VEL1*1.0D-09
+      RLL(J) = TLJ1
+      IF( NP  .GT. 100 ) RETURN
+c      write (6, 115) TP, XA,  YA,  ZA,        VZP, VXP, VYP
+c      write (6, 103)
+c      write (6, 116) XINT2,VXP, YINT2,VYP,ZINT2,TLJ,TLJ1,TTJ,TTJ1
+  116 FORMAT( / 20X, 'X=', F10.4, ' CM', 5X, 'VX=',F10.4,' MR',    /
+     1          20X, 'Y=', F10.4, ' CM', 5X, 'VY=',F10.4,' MR',    /
+     2          20X, 'Z=', F10.4, ' CM'          /
+     3          20X, 'L=', F10.4, ' CM', 5X,'DL=',F10.4, ' CM' /
+     4          20X, 'T=', F10.4, ' NS', 5X,'DT=',F10.4, ' NS' )
+c      IF( JFOCAL  .NE.  0 )  write (6, 99)
+   99 FORMAT( / '   FOCAL POS FIXED BY INPUT DATA = IMAGE DISTANCE  '/ )
+      RETURN
+      END
+
+
+      SUBROUTINE PLTOUT ( JEN, J, NUM )
+C
+C THIS ROUTINE STORES STEP-BY-STEP POSITION INFORMATION FOR EACH
+C RAY FOR USE BY PLOTTING ROUTINES.
+C
+C   MODIFIED BY E.A.S.E. TO PRODUCE ASCII OUTPUT FILE IN
+C FORMATTED FORM.  THIS ALLOWS EASIER COMPATIBILITY WITH
+C RPLOT, REGARDLESS OF WHETHER OUTPUT IS FROM SINGLE OR
+C DOUBLE PRECISION VERSION OF RAYTRACE.
+C
+      IMPLICIT REAL*8 (A-H,O-Z)
+      REAL*8 K
+      LOGICAL LPLT
+      COMMON  /BLCK00/ LPLT
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      DIMENSION TC(6), DTC(6)
+      DIMENSION GRAPH(4,512), ICOR(512,2)
+C
+      IF( NUM .GT. 512 ) NUM = 512
+      WRITE (1, 811)   JEN, J, NUM
+  811 FORMAT(1X, 3I4)
+      DO 100 I = 1, NUM
+      WRITE (1,812) GRAPH(1,I), GRAPH(2,I),
+     1GRAPH(3,I), GRAPH(4,I), ICOR(I,1), ICOR(I,2)
+  812 FORMAT(4(1X, F9.3), 2(1X, I3))
+  100 CONTINUE
+      RETURN
+C
+      ENTRY   PLT1( NUM, NO, NBR, TPAR )
+C
+      IF( .NOT. LPLT ) RETURN
+      IF( NUM .GT. 512 ) RETURN
+      GRAPH( 1,NUM) = TC(1)
+      GRAPH( 2,NUM) = TC(2)
+      GRAPH( 3,NUM) = TC(3)
+      GRAPH( 4,NUM) = TPAR
+      ICOR ( NUM,1) = NO
+      ICOR ( NUM,2) = NBR
+      RETURN
+C
+      ENTRY   PLT2( NUM, NO, NBR, TPAR )
+C
+      IF( .NOT. LPLT ) RETURN
+      IF( NUM .GT. 512 ) RETURN
+      GRAPH( 1,NUM) = XA
+      GRAPH( 2,NUM) = YA
+      GRAPH( 3,NUM) = ZA
+      GRAPH( 4,NUM) = TPAR
+      ICOR ( NUM,1) = NO
+      ICOR ( NUM,2) = NBR
+      RETURN
+      END
+
+
+      SUBROUTINE POLES  ( NO, NP, T, TP ,NUM )
+C****
+C****
+C**** MULTIPOLE     RAY TRACING BY NUMERICAL INTEGRATION OF DIFFERENTIAL
+C**** EQUATIONS OF MOTION.
+C     T = TIME
+C     TC(1) TO TC(6) =  ( X, Y, Z, VX, VY, VZ )
+C     DTC(1) TO DTC(6) = ( VX, VY, VZ, VXDOT, VYDOT, VZDOT )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  LF1, LF2, LU1, K, L
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK90/  D, S, BT, GRAD1,GRAD2,GRAD3,GRAD4,GRAD5
+      COMMON  /BLCK91/  C0, C1, C2, C3, C4, C5
+      COMMON  /BLCK92/  IN
+      COMMON  /BLCK93/  DH, DO, DD, DDD, DSH, DSO, DSD, DSDD
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+      DIMENSION TC(6), DTC(6), DS(6), ES(6)
+      EXTERNAL  BPOLES
+C**** DATA  C/ 3.D10/
+C****
+      LF1  = DATA(  1,NO )
+      LU1  = DATA(  2,NO )
+      LF2  = DATA(  3,NO )
+      A    = DATA( 10,NO )
+      B    = DATA( 11,NO )
+      L    = DATA( 12,NO )
+      RAD  = DATA( 13,NO )
+      BQD  = DATA( 14,NO )
+      BHX  = DATA( 15,NO )
+      BOC  = DATA( 16,NO )
+      BDC  = DATA( 17,NO )
+      BDD  = DATA( 18,NO )
+      Z11  = DATA( 19,NO )
+      Z12  = DATA( 20,NO )
+      Z21  = DATA( 21,NO )
+      Z22  = DATA( 22,NO )
+      FRH  = DATA( 35,NO )
+      FRO  = DATA( 36,NO )
+      FRD  = DATA( 37,NO )
+      FRDD = DATA( 38,NO )
+      DSH  = DATA( 39,NO )
+      DSO  = DATA( 40,NO )
+      DSD  = DATA( 41,NO )
+      DSDD = DATA( 42,NO )
+      DTF1= LF1/ VEL
+      DTF2= LF2/ VEL
+      DTU = LU1/ VEL
+      D = 2. * RAD
+      IF( FRH  .EQ. 0. ) FRH  = 1.D0
+      IF( FRO  .EQ. 0. ) FRO  = 1.D0
+      IF( FRD  .EQ. 0. ) FRD  = 1.D0
+      IF( FRDD .EQ. 0. ) FRDD = 1.D0
+      DH  = FRH *D
+      DO  = FRO *D
+      DD  = FRD *D
+      DDD = FRDD*D
+      GRAD1 = -BQD/RAD
+      GRAD2 =  BHX/RAD**2
+      GRAD3 = -BOC/RAD**3
+      GRAD4 =  BDC/RAD**4
+      GRAD5 = -BDD/RAD**5
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S = 0.
+C****
+      IF( NP  .GT. 100 ) GO TO 5
+c      write (6, 100) ITITLE(NO)
+  100 FORMAT(  ' MULTIPOLE(POLES)  ****  ', A4,'  ******************'/)
+C****
+c      write (6, 101)
+  101 FORMAT( 8H    T CM ,18X, 4HX CM , 7X, 2HBX, 8X, 4HY CM , 7X, 2HBY,
+     1   8X, 4HZ CM, 7X, 2HBZ, 8X, 6HVELZ/C , 6X, 8HTHETA MR , 5X,
+     2   6HPHI MR , 6X, 1HB             )
+      CALL PRNT2 ( T,S,XA   ,YA   ,ZA   ,BX,BY,BZ,BT,VXA  ,VYA  ,VZA   )
+c      write (6, 103)
+  103 FORMAT(   '0COORDINATE TRANSFORMATION TO B AXIS SYSTEM '       )
+  109 FORMAT(   '0COORDINATE TRANSFORMATION TO D AXIS SYSTEM '       )
+C**** TRANSFORM FROM INITIAL ENTRANCE COORDINATES TO VFB COORD.
+C****
+    5 TC(1) = -XA
+      TC(2) = YA
+      TC(3) = A - ZA
+      TC(4) = -VXA
+      TC(5) = VYA
+      TC(6) = -VZA
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** TRANSLATE PARTICLE TO START OF FIRST FRINGE FIELD
+C****
+      TDT = ( TC(3) - Z11 ) /DABS( TC(6) )
+C****
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** IN DESIGNATES FIELD REGIONS FOR MULTIPOLE
+C****
+      IN = 1
+      C0   = DATA( 23,NO )
+      C1   = DATA( 24,NO )
+      C2   = DATA( 25,NO )
+      C3   = DATA( 26,NO )
+      C4   = DATA( 27,NO )
+      C5   = DATA( 28,NO )
+c      IF( NP  .LE. 100) write (6, 104)
+  104 FORMAT( 22H0FRINGING FIELD REGION    )
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BPOLES,0    )
+      NSTEP = 0
+    6 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 7 I = 1, NP
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BPOLES,1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( Z12 .GE. TC(3) ) GO TO 8
+    7 CONTINUE
+      GO TO 6
+    8 CONTINUE
+      XDTF1 =-( Z12 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES,BPOLES, 0    )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES,BPOLES, 1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+  105 FORMAT( 10H   NSTEPS= ,I5 )
+C***
+C***  UNIFORM FIELD REGION
+C**** TRANSFORM TO SECOND VFB COORD SYSTEM
+C***
+      GRAD1 = -GRAD1
+      GRAD2 =  GRAD2
+      GRAD3 = -GRAD3
+      GRAD4 =  GRAD4
+      GRAD5 = -GRAD5
+      TC(1) = -TC(1)
+      TC(3) = -TC(3) - L
+      TC(4) = -TC(4)
+      TC(6) = -TC(6)
+C****
+C****
+C**** UNIFORM FIELD INTEGRATION REGION
+C****
+C****
+      IN = 2
+c      IF( NP  .LE. 100) write (6, 106)
+  106 FORMAT(   '0UNIFORM FIELD REGION IN C AXIS SYSTEM '  )
+      IF( TC(3)  .LT.  Z21 ) GO TO 15
+C****
+C**** THIS SECTION CORRECTS FOR MAGNETS WHOSE FRINGING FIELDS INTERSECT
+C****
+c      IF( NP  .LE. 100) write (6, 102)
+  102 FORMAT( / '   INTEGRATE BACKWARDS    '  )
+      CALL FNMIRK( 6, T,-DTU ,TC, DTC, DS, ES,BPOLES, 0    )
+      NSTEP = 0
+   16 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 17  I =1, NP
+      CALL FNMIRK( 6, T,-DTU, TC, DTC, DS, ES,BPOLES, 1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3)  .LE.  Z21 )  GO TO 18
+   17 CONTINUE
+      GO TO 16
+   18 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES,BPOLES, 0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES,BPOLES, 1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+c      IF( NP  .LE. 100) write (6, 107)
+  107 FORMAT( / )
+      GO TO 19
+C****
+C****
+   15 CONTINUE
+      CALL FNMIRK( 6, T, DTU ,TC, DTC, DS, ES, BPOLES,0    )
+      NSTEP = 0
+    9 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 10  I =1, NP
+      CALL FNMIRK( 6, T, DTU ,TC, DTC, DS, ES, BPOLES,1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3)  .GE.  Z21 )  GO TO 11
+   10 CONTINUE
+      GO TO 9
+   11 CONTINUE
+      XDTU  = ( Z21 - TC(3) ) /DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES,BPOLES, 0    )
+      CALL FNMIRK( 6, T,XDTU ,TC, DTC, DS, ES,BPOLES, 1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+   19 CONTINUE
+C***
+C***
+C**** SETUP FOR SECOND FRINGE FIELD AND INTEGRATION
+C****
+C****
+      C0   = DATA( 29,NO )
+      C1   = DATA( 30,NO )
+      C2   = DATA( 31,NO )
+      C3   = DATA( 32,NO )
+      C4   = DATA( 33,NO )
+      C5   = DATA( 34,NO )
+      IN = 3
+c      IF( NP  .LE. 100) write (6, 104)
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, BPOLES,0    )
+      NSTEP = 0
+   12 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 13  I =1, NP
+      CALL FNMIRK( 6, T, DTF2,TC, DTC, DS, ES, BPOLES,1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( TC(3) .GE. Z22 )  GO TO 14
+   13 CONTINUE
+      GO TO 12
+   14 CONTINUE
+      XDTF2 = ( Z22 - TC(3) ) / TC(6)
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BPOLES,0    )
+      CALL FNMIRK( 6, T,XDTF2,TC, DTC, DS, ES, BPOLES,1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+C****
+C**** TRANSFORM TO OUTPUT SYSTEM COORD.
+C****
+      TC(3) = TC(3) - B
+c      IF( NP  .LE. 100) write (6, 109)
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+C****
+C**** TRANSLATE PARTICLE TO OUT SYSTEM COORD.
+C****
+      TDT = -TC(3) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      TP = T * VEL
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S  = 0.
+      VXF    = 1000. *DATAN2( TC(4), TC(6)  )
+      VYF    = 1000. *DASIN ( TC(5)/ VEL    )
+      VZF    = TC(6) / VEL
+c      IF(NP.LE.100) write (6,115)TP,TC(1),TC(2),TC(3),VZF,VXF,VYF
+  115 FORMAT( F10.4, 10X, F10.3, 11X, F10.3, 11X, F10.3, 11X,
+     1   F13.5, F13.2, F11.2                   )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 4
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C**
+C**** CALCULATE INTERCEPTS IN SYSTEM D
+C****
+C****
+C****
+C****
+      Z0X = -TC(1)/ ( TC(4) / TC(6)    + 1.E-10 )
+      Z0Y = -TC(2)/ ( TC(5) / TC(6)    + 1.E-10 )
+c      IF( NP  .LE. 100) write (6, 111) VXF, VYF, Z0X, Z0Y
+  111 FORMAT( / ' INTERSECTIONS WITH VER. AND HOR. PLANES '          ,
+     X       /15X, 5H  XP=,F10.4, 10H MR    YP=, F10.4, 3H MR   /
+     1        15X, 5H Z0X=,F10.2, 10H CM   Z0Y= ,F10.2, 3H CM   /   )
+      RETURN
+   99 CALL PRNT4 (NO, IN)
+      RETURN
+      END
+
+
+      SUBROUTINE  PRNT( J,NO )
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 0/  DATA, ITITLE
+      COMMON  /BLCK 1/  XI, YI, ZI, VXI, VYI, VZI, DELP
+      COMMON  /BLCK 2/  XO, YO, ZO, VXO, VYO, VZO,RTL(1000),RLL(1000)
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 6/  NP, JFOCAL
+      COMMON  /DY1/  BDIPOLE
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+      DIMENSION XO(1000),YO(1000),ZO(1000),VXO(1000),VYO(1000),VZO(1000)
+      DIMENSION XI(1000),YI(1000),ZI(1000),VXI(1000),VYI(1000),
+     1      VZI(1000),DELP(1000)
+      CHARACTER*8 LX(14)
+      CHARACTER*8 LCM
+      INTEGER ID2(52), ID3(21), ID4(43), ID5(33), ID6(17),ID7(7),ID8(26)
+      DATA ID2 / 11, 19, 29, 41, 51, 12, 20, 30, 42, 52, 13, 21, 31,
+     1   43, 53, 14, 22, 32, 44, 54, 15, 25, 33, 45, 55, 16, 26, 34,
+     2   46, 56, 17, 27, 35, 47, 57, 18, 28, 36, 48, 58, 37, 49, 59, 38,
+     3 50,60,39, 61, 40, 62, 63, 64                                  /
+      DATA ID3 / 10, 15, 19, 25, 11, 16, 20, 26, 12, 17, 21, 27, 13,
+     1   18, 22, 28, 14, 23, 29, 24, 30                              /
+      DATA ID4 /  7, 20, 28, 34,  8, 21, 29, 35,  9, 22, 30, 36, 10,
+     1   23, 31, 37, 11, 24, 32, 38, 12, 25, 33, 39, 13, 26, 40, 46,
+     2   16, 27, 41, 47, 17, 42, 48, 18, 43, 49, 19, 44, 50, 45, 51  /
+      DATA ID5 / 10, 14, 19, 23, 29, 11, 15, 20, 24, 30, 12, 16, 21,
+     1   25, 31, 13, 17, 22, 26, 32, 18, 27, 33, 28, 34, 35, 39, 36,
+     2   40, 37, 41, 38, 42  /
+      DATA ID6 / 10, 16, 20, 26, 11, 17, 21, 27, 12, 22, 28, 13, 23,
+     1   14, 24, 15, 25                                              /
+      DATA ID7 / 10, 15, 11, 16, 12, 13, 14                          /
+      DATA ID8 / 11, 16, 25, 29, 35, 12, 17, 26, 30, 36, 13, 18, 27,
+     1   31, 37, 14, 19, 28, 32, 38, 15, 20, 33, 39, 34, 40          /
+      DATA LCM / ' CM ' /
+      DATA LX/ ' ENTR FL','D STEP =',' UNIF FL','D STEP =',
+     1         ' EXIT FL','D STEP =',' DIFF/MI','D STEP =',
+     2         '        ','   RHO =','        ','  MTYP =',
+     3         '   FIELD','  STEP ='                                 /
+C****
+C****
+      GO TO ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ), J
+c      write (6, 109) J
+  109 FORMAT(// ' GO TO FELL THROUGH IN ROUTINE PRNT  J= ',I5, ///   )
+      CALL EXIT
+C****
+    1 RETURN
+C****
+C**** COLLIMATOR DATA
+C****
+  103 FORMAT( // 20X, '*** COLLIMATOR       ***',   A4  /  )
+  104 FORMAT(
+     1   5X,'ELPS=',  F9.1, 5X,'XCEN=',  F9.4, 5X,'YCEN=',  F9.4,
+     2   5X,'XMAX=',  F9.4, 5X,'YMAX=',  F9.4                       )
+   13 CONTINUE
+c   13 write (6, 103) ITITLE(NO)
+c      write (6, 104) (DATA(I,NO),I=1,5)
+      RETURN
+C****
+C**** DIPOLE DATA
+C****
+  100 FORMAT( // 20X, '*** DIPOLE MAGNET    ***',   A4  /  )
+  101 FORMAT(
+     1   5X,'  A =',  F9.4, 5X,'NDX =',  F9.4, 5X,'C01 =',  F9.4,
+     2   5X,'BR1 =',  F9.4, 5X,'S02 =',1PE12.3,5X,       2A8,0PF8.3,A4,/
+     3   5X,'  B =',  F9.4, 5X,'BET1=',  F9.4, 5X,'C02 =',  F9.4,
+     4   5X,'BR2 =',  F9.4, 5X,'S03 =',1PE12.3,5X,       2A8,0PF8.3,A4,/
+     5   5X,'  D =',  F9.4, 5X,'GAMA=',  F9.4, 5X,'C03 =',  F9.4,
+     6   5X,'XCR1=',  F9.4, 5X,'S04 =',1PE12.3,5X,       2A8,0PF8.3,A4,/
+     7   5X,'  R =',  F9.4, 5X,'DELT=',  F9.4, 5X,'C04 =',  F9.4,
+     8   5X,'XCR2=',  F9.4, 5X,'S05 =',1PE12.3,5X,       2A8,0PF8.3,A4,/
+     9   5X,' BF =',  F9.4, 5X,'Z11 =',  F9.4, 5X,'C05 =',  F9.4,
+     A   5X,'DLS1=',  F9.4, 5X,'S06 =',1PE12.3,5X,       2A8,  I4     ,/
+     B   5X,'PHI =',0PF9.4, 5X,'Z12 =',  F9.4, 5X,'C06 =',  F9.4,
+     C   5X,'DLS2=',  F9.4, 5X,'S07 =',1PE12.3,5X,       2A8,0PF8.3,A4 )
+  102 FORMAT(
+     1   5X,'ALPH=',  F9.4,   5X,'Z21 =',  F9.4,  5X,'C11 =',  F9.4,
+     2   5X,'RAP1=',  F9.4,   5X,'S08 =',1PE12.3,/, 5X,'BETA=',0PF9.4,
+     3   5X,'Z22 =',  F9.4,   5X,'C12 =',  F9.4,  5X,'RAP2=',  F9.4,
+     4   5X,'S12 =',1PE12.3,/,43X,'C13 =',0PF9.4,
+     X                        5X,'SCR1=',  F9.4,  5X,'S13 =', 1PE12.3
+     5   ,/,43X,'C14 =',0PF9.4,   5X,'SCR2=',  F9.4,
+     Y                        5X,'S14 =',1PE12.3,/,43X,'C15 =',0PF9.4,
+     6   24X,'S15 =',1PE12.3,/,43X,'C16 =',0PF9.4,24X,'S16 =',1PE12.3
+     7  ,/,81X,'S17 =',1PE12.3,/,81X,'S18 =',1PE12.3                )
+C****
+C****
+    2 RHO = 1.D30
+      IF( DATA(15,NO) .NE. 0 )
+     1RHO = DSQRT( (2.*931.48*PMASS+ENERGY)*ENERGY)/(3.*DATA(15,NO)*Q0)
+      MTYP = DATA(5,NO)
+c      write (6, 100) ITITLE(NO)
+c      write (6,101) (DATA(ID2(I),NO),I=1,5),LX(1),LX(2),DATA(1,NO),LCM,
+c     1          (DATA(ID2(I),NO),I= 6,10),LX( 3),LX( 4),DATA(2,NO),LCM,
+c     2          (DATA(ID2(I),NO),I=11,15),LX( 5),LX( 6),DATA(3,NO),LCM,
+c     3          (DATA(ID2(I),NO),I=16,20),LX( 7),LX( 8),DATA(4,NO),LCM,
+c     4          (DATA(ID2(I),NO),I=21,25),LX(11),LX(12),MTYP      ,
+c     5          (DATA(ID2(I),NO),I=26,30),LX( 9),LX(10),RHO,       LCM
+c      write (6, 102) (DATA(ID2(I),NO),I=31,52)
+      RETURN
+C****
+C**** QUADRUPOLE, HEXAPOLE, OCTAPOLE, DECAPOLE DATA
+C****
+  200 FORMAT( // 20X, '*** QUADRUPOLE       ***',   A4  /  )
+  400 FORMAT( // 20X, '*** SEXTUPOLE        ***',   A4  /  )
+  500 FORMAT( // 20X, '*** OCTUPOLE         ***',   A4  /  )
+  600 FORMAT( // 20X, '*** DECAPOLE         ***',   A4  /  )
+  120 FORMAT(
+     1   5X,'  A =',  F9.4, 5X,'Z11 =',  F9.4, 5X,'C01 =',  F9.4,
+     2   5X,'C11 =',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     3   5X,'  B =',  F9.4, 5X,'Z12 =',  F9.4, 5X,'C02 =',  F9.4,
+     4   5X,'C12 =',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     5   5X,'  L =',  F9.4, 5X,'Z21 =',  F9.4, 5X,'C03 =',  F9.4,
+     6   5X,'C13 =',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     7   5X,'RAD =',  F9.4, 5X,'Z22 =',  F9.4, 5X,'C04 =',  F9.4,
+     8   5X,'C14 =',  F9.4,/5X,' BF =',  F9.4,24X,'C05 =',  F9.4,
+     9   5X,'C15 =',  F9.4,/                  43X,'C06 =',  F9.4,
+     A   5X,'C16 =',  F9.4                                           )
+C****
+C****
+    3 CONTINUE
+c    3 write (6, 200) ITITLE(NO)
+      GO TO 21
+    4 CONTINUE
+c    4 write (6, 400) ITITLE(NO)
+      GO TO 21
+    5 CONTINUE
+c    5 write (6, 500) ITITLE(NO)
+      GO TO 21
+    6 CONTINUE
+c    6 write (6, 600) ITITLE(NO)
+   21 CONTINUE
+c   21 write (6,120)(DATA(ID3(I),NO),I=1,4),LX(1),LX(2),DATA(1,NO),LCM,
+c     1          (DATA(ID3(I),NO),I= 5,8 ),LX( 3),LX( 4),DATA(2,NO),LCM,
+c     2          (DATA(ID3(I),NO),I= 9,12),LX( 5),LX( 6),DATA(3,NO),LCM,
+c     3          (DATA(ID3(I),NO),I=13,21)
+      RETURN
+C****
+C**** ELECTROSTATIC DEFLECTOR DATA
+C****
+  190 FORMAT( // 20X, '*** ELECTROSTATIC DEF.***',   A4  /  )
+  191 FORMAT(
+     1   5X,'  A =',  F9.4, 5X,'PHI =',  F9.4, 5X,'Z11 =',  F9.4,
+     2   5X,'C01 =',  F9.4, 5X,'C11 =',  F9.4, 5X,       2A8,0PF8.3,A4,/
+     3   5X,'  B =',  F9.4, 5X,'EC2 =',  F9.4, 5X,'Z12 =',  F9.4,
+     4   5X,'C02 =',  F9.4, 5X,'C12 =',  F9.4, 5X,       2A8,0PF8.3,A4,/
+     5   5X,'  D =',  F9.4, 5X,'EC4 =',  F9.4, 5X,'Z21 =',  F9.4,
+     6   5X,'C03 =',  F9.4, 5X,'C13 =',  F9.4, 5X,       2A8,0PF8.3,A4,/
+     7   5X,'  R =',  F9.4, 5X,'WE  =',  F9.4, 5X,'Z22 =',  F9.4,
+     8   5X,'C04 =',  F9.4, 5X,'C14 =',  F9.4, 5X,       2A8,0PF8.3,A4,/
+     9   5X,' EF =',  F9.4, 5X,'WC  =',  F9.4,24X,'C05 =',  F9.4,
+     A   5X,'C15 =',  F9.4,                    5X,       2A8,0PF8.3,A4,/
+     B  62X,'C06 =',0PF9.4, 5X,'C16 =',  F9.4                   )
+C****
+C****
+    7 RHO = 1.D30
+      EMASS = PMASS * 931.48
+      ETOT = EMASS + ENERGY
+      VC2 = (2.*EMASS + ENERGY)*ENERGY / (ETOT*ETOT)
+      GAMMA = 1. / DSQRT(1. - VC2)
+      IF( DATA(15,NO) .NE. 0 )
+     1RHO = GAMMA * EMASS * VC2 * 1000. / (DATA(15,NO) * Q0)
+c      write (6, 190) ITITLE(NO)
+c      write (6,191)(DATA(ID8(I),NO),I=1,5),LX(1),LX(2),DATA(1,NO),LCM,
+c     1          (DATA(ID8(I),NO),I= 6,10),LX( 3),LX( 4),DATA(2,NO),LCM,
+c     2          (DATA(ID8(I),NO),I=11,15),LX( 5),LX( 6),DATA(3,NO),LCM,
+c     3          (DATA(ID8(I),NO),I=16,20),LX( 7),LX( 8),DATA(4,NO),LCM,
+c     4          (DATA(ID8(I),NO),I=21,24),LX( 9),LX(10),RHO,LCM   ,
+c     5          (DATA(ID8(I),NO),I=25,26)
+      RETURN
+C****
+C****    VELOCITY SELECTOR DATA
+C****
+  132 FORMAT( // 20X, '*** VELOCITY SELECTOR***',   A4  /  )
+  130 FORMAT(
+     1   5X,'  A =',  F9.4, 5X,'Z11 =',  F9.4, 5X,'CB00=',  F9.4,
+     2   5X,'CE00=',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     3   5X,'  B =',  F9.4, 5X,'Z12 =',  F9.4, 5X,'CB01=',  F9.4,
+     4   5X,'CE01=',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     5   5X,'  L =',  F9.4, 5X,'Z21 =',  F9.4, 5X,'CB02=',  F9.4,
+     6   5X,'CE02=',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     7   5X,' BF =',  F9.4, 5X,'Z22 =',  F9.4, 5X,'CB03=',  F9.4,
+     8   5X,'CE03=',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     9   5X,' BE =',  F9.4, 5X,'CB2 =',  F9.4, 5X,'CB04=',  F9.4,
+     A   5X,'CE04=',  F9.4, 5X, 2A8,0PF8.3,A4                        )
+  131 FORMAT(
+     1   5X,' RB =',  F9.4, 5X,'CB4 =',  F9.4, 5X,'CB05=',  F9.4,
+     2   5X,'CE05=',  F9.4,/5X,'NDX =',  F9.4, 5X,'CE2 =',  F9.4,
+     3   5X,'CB10=',  F9.4, 5X,'CE10=',  F9.4,/5X,' DB =',  F9.4,
+     4   5X,'CE4 =',  F9.4, 5X,'CB11=',  F9.4, 5X,'CE11=',  F9.4,/
+     5   5X,' DE =',  F9.4,24X,'CB12=',  F9.4, 5X,'CE12=',  F9.4,/
+     6   5X,' WB =',  F9.4,24X,'CB13=',  F9.4, 5X,'CE13=',  F9.4,/
+     7   5X,' WE =',  F9.4,24X,'CB14=',  F9.4, 5X,'CE14=',  F9.4,/
+     8  43X,'CB15=',  F9.4, 5X,'CE15=',  F9.4                        )
+C****
+C****
+    8 RHO = 1.D30
+      IF( DATA(10,NO)  .NE.  0.   )
+     1RHO = DSQRT( (2.*931.48*PMASS+ENERGY)*ENERGY)/(3.*DATA(10,NO)*Q0)
+c      write (6, 132)ITITLE(NO)
+c      write (6,130)(DATA(ID4(I),NO),I=1,4),LX(1),LX(2),DATA(1,NO),LCM,
+c     1          (DATA(ID4(I),NO),I= 5,8 ),LX( 3),LX( 4),DATA(2,NO),LCM,
+c     2          (DATA(ID4(I),NO),I= 9,12),LX( 5),LX( 6),DATA(3,NO),LCM,
+c     3          (DATA(ID4(I),NO),I=13,16),LX( 7),LX( 8),DATA(4,NO),LCM,
+c     4          (DATA(ID4(I),NO),I=17,20),LX( 9),LX(10),RHO,LCM
+c      write (6, 131) (DATA(ID4(I),NO),I=21,43)
+      RETURN
+C****
+C**** MULTIPOLE (POLES)      DATA
+C****
+  141 FORMAT( // 20X, '*** MULTIPOLES       ***',   A4  /  )
+  140 FORMAT(
+     1   5X,'  A =',  F9.4, 3X,'BQUAD =',F9.4, 5X,'Z11 =',  F9.4,
+     2   5X,'C01 =',  F9.4, 5X,'C11 =',  F9.4, 8X, 2A8,0PF8.3,A4,/
+     3   5X,'  B =',  F9.4, 3X,'BHEX  =',F9.4, 5X,'Z12 =',  F9.4,
+     4   5X,'C02 =',  F9.4, 5X,'C12 =',  F9.4, 8X, 2A8,0PF8.3,A4,/
+     5   5X,'  L =',  F9.4, 3X,'BOCT  =',F9.4, 5X,'Z21 =',  F9.4,
+     6   5X,'C03 =',  F9.4, 5X,'C13 =',  F9.4, 8X, 2A8,0PF8.3,A4,/
+     7   5X,'RAD =',  F9.4, 3X,'BDEC  =',F9.4, 5X,'Z22 =',  F9.4,
+     8   5X,'C04 =',  F9.4, 5X,'C14 =',  F9.4,/
+     9                     22X,'BDDEC =',F9.4,24X,'C05 =',  F9.4,
+     A   5X,'C15 =',  F9.4/62X,'C06 =',  F9.4, 5X,'C16 =',  F9.4
+     B                    /62X,'FRH =',  F9.4, 5X,'DSH =',  F9.4
+     C                    /62X,'FRO =',  F9.4, 5X,'DSO =',  F9.4
+     D                    /62X,'FRD =',  F9.4, 5X,'DSD =',  F9.4
+     E                    /62X,'FRDD=',  F9.4, 5X,'DSDD=',  F9.4     )
+C****
+C****
+    9 CONTINUE
+c    9 write (6, 141) ITITLE(NO)
+c      write (6,140)(DATA(ID5(I),NO),I=1,5),LX(1),LX(2),DATA(1,NO),LCM,
+c     1          (DATA(ID5(I),NO),I= 6,10),LX( 3),LX( 4),DATA(2,NO),LCM,
+c     2          (DATA(ID5(I),NO),I=11,15),LX( 5),LX( 6),DATA(3,NO),LCM,
+c     3          (DATA(ID5(I),NO),I=16,33)
+      RETURN
+C****
+C**** MULTIPOLE DATA
+C****
+  151 FORMAT( // 20X,  '***MULTIPOLE(HE)    ***',   A4  /  )
+  150 FORMAT(
+     1   5X,'  A =',  F9.4, 5X,' Z1 =',  F9.4, 5X,' C0 =',  F9.4,
+     2   5X,' C6 =',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     3   5X,'  B =',  F9.4, 5X,' Z2 =',  F9.4, 5X,' C1 =',  F9.4,
+     4   5X,' C7 =',  F9.4, 5X, 2A8,0PF8.3,A4,/
+     5   5X,'  L =',  F9.4,24X,' C2 =',  F9.4, 5X,' C8 =',  F9.4/
+     6   5X,'  W =',  F9.4,24X,' C3 =',  F9.4,/
+     7   5X,'  D =',  F9.4,24X,' C4 =',  F9.4,/
+     8   5X,' BF =',  F9.4,24X,' C5 =',  F9.4                        )
+C****
+C****
+   10 CONTINUE
+c   10 write (6, 151) ITITLE(NO)
+c      write (6,150)(DATA(ID6(I),NO),I=1,4),LX(1),LX(2),DATA(1,NO),LCM,
+c     1          (DATA(ID6(I),NO),I= 5,8 ),LX( 7),LX( 8),DATA(2,NO),LCM,
+c     2          (DATA(ID6(I),NO),I= 9,17)
+      RETURN
+C****
+C**** TRANSLATE - ROTATE DATA
+C****
+  170 FORMAT( // 20X, '*** TRANSLATE-ROTATE ***',   A4  /  )
+  171 FORMAT(   5X, 5H X0 =,F9.4,        5X,5H Y0 =,F9.4,
+     1          5X, 5H Z0 =,F9.4,     /,1X,9HTHETA X =,F9.4,
+     2        1X,9HTHETA Y =,F9.4,       1X,9HTHETA Z =,F9.4 )
+C****
+C****
+   11 CONTINUE
+c   11 write (6, 170) ITITLE(NO)
+c      write (6, 171) ( DATA(I,NO) , I=1,6 )
+      RETURN
+C****
+C**** DRIFT SECTION DATA
+C****
+   12 CONTINUE
+c   12 write (6, 175) ITITLE(NO)
+c      write (6, 176) ( DATA(I,NO) , I=1,1 )
+  175 FORMAT( // 20X, '*** DRIFT            ***',   A4  /  )
+  176 FORMAT(  19X,  ' Z-DRIFT ='  , F9.4,  ' CM'        )
+      RETURN
+C****
+C**** SOLENOID DATA
+C****
+  161 FORMAT( // 20X, '*** SOLENOID         ***',   A4  /  )
+  160 FORMAT(
+     1   5X,'  A =',  F9.4, 5X,'Z11 =',  F9.4, 5X,2A8,0PF8.3,A4,/
+     2   5X,'  B =',  F9.4, 5X,'Z22 =',  F9.4,/5X,'  L =',  F9.4,/
+     3   5X,'DIA =',  F9.4,/5X,' BF =',  F9.4                        )
+C****
+C****
+   14 CONTINUE
+c   14 write (6, 161) ITITLE(NO)
+c      write (6,160)(DATA(ID7(I),NO),I=1,2),LX(13),LX(14),DATA(1,NO),
+c     1         LCM, (DATA(ID7(I),NO),I= 3, 7)
+      RETURN
+C****
+C**** LENS DATA
+C****
+  180 FORMAT( // 20X, '*** LENS             ***',   A4  /  )
+  181 FORMAT(  3X, 7H(X/X) =  ,F9.4,   6H CM/CM,
+     1        16X, 7H(X/T) =  ,F9.4,   6H CM/MR, /,
+     2         3X, 7H(T/X) =  ,F9.4,   6H MR/CM,
+     3        16X, 7H(T/T) =  ,F9.4,   6H MR/MR, /,
+     4         3X, 7H(Y/Y) =  ,F9.4,   6H CM/CM,
+     5        16X, 7H(Y/P) =  ,F9.4,   6H CM/MR, /,
+     6         3X, 7H(P/Y) =  ,F9.4,   6H MR/CM,
+     7        16X, 7H(P/P) =  ,F9.4,   6H MR/MR, //,
+     8         3X, 7H   CS =  ,F9.4,   6H CM   , /         )
+C****
+C****
+   15 CONTINUE
+c   15 write (6, 180) ITITLE(NO)
+c      write (6, 181) ( DATA(I,NO) , I=1,9 )
+      RETURN
+C****
+C****
+      ENTRY PRNT1 ( N )
+C****
+C****
+c      IF( JFOCAL .EQ. 0 ) write (6, 105)
+c      IF( JFOCAL .EQ. 1 ) write (6, 106)
+c      IF( JFOCAL .EQ. 2 ) write (6, 107)
+c      IF( JFOCAL .GT. 2 ) write (6, 108)
+c      write (6, 110)
+  105 FORMAT( 1H1, 15X, '****COORDINATES OPTIC AXIS SYSTEM****
+     1  ( ORIGIN AT RAY 1-2 INTERSECTION ) '    // )
+  106 FORMAT( 1H1, 15X, '****COORDINATES OPTIC AXIS SYSTEM****
+     1  ( ORIGIN AT ZD=0.0  ) '    // )
+  107 FORMAT( 1H1, 15X, '****COORDINATES D-AXIS SYSTEM****' // )
+  108 FORMAT( 1H1, 15X, '****COORDINATES OPTIC AXIS SYSTEM****' // )
+  110 FORMAT(
+     1   10X, 45HX     THETA     Y      PHI      ZI    DELE     ,5X,
+     2   12HXO        XS  , 11X, 12HYO        YS , 6X, 'L(CM)', 5X,
+     3   'T(NS)'                         /)
+      DO 20  I=1,N
+C****
+C**** CALCULATE TIME IN (NS)
+C****
+      TLJ1 = RTL(I)*1.0D+09 / VEL
+C      write (6, 111)  I, XI(I), VXI(I), YI(I), VYI(I), ZI(I), DELP(I),
+C     1    XO(I), VXO(I), YO(I), VYO(I), RLL(I), TLJ1
+  111 FORMAT(       I5,    6F8.2, 2X,  F10.4,   F10.4, 2X,   F10.4,
+     1     F10.4 ,   F10.3, F10.3               /)
+   20 CONTINUE
+c      open(38,file='rayout.plt',status='unknown')
+c      do 2100  i=1,n
+c      write (38, 582)  I, XI(I), VXI(I), YI(I), VYI(I), ZI(I), DELP(I),
+c     1    XO(I), VXO(I), YO(I), VYO(I), RLL(I), TLJ1, BDIPOLE
+  582 format(i3,3x,13(f10.5,1x))
+ 2100 continue
+c      write(38,583)
+  583 format(1x,'/')
+c      close(38)
+      RETURN
+C****
+C****
+      ENTRY PRNT2 ( T, S, X, Y, Z, BX, BY, BZ, BT, VX, VY, VZ          )
+C****
+      IF( NP  .GT. 100 ) RETURN
+      VXP = 1000. *DATAN2( VX ,VZ  )
+      VYP = 1000. * DASIN( VY /VEL )
+      VZP = VZ  / VEL
+      TP = T * VEL
+c      write (6, 112)TP,S,X, BX, Y, BY, Z, BZ, VZP, VXP, VYP, BT
+  112 FORMAT(2F10.4,     F10.3, F11.4, F10.3, F11.4, F10.3, F11.4,
+     1        F13.5, F13.2, F11.2, F10.4         )
+      RETURN
+C****
+      ENTRY PRNT3 (TDIST,X,Y,Z,BX,BY,BZ,EX,EY,EZ,VX,VY,VZ)
+C****
+  114 FORMAT( 2F9.3, 2F10.4,F9.3, 2F10.4,F9.3, 2F10.4,2F11.3, -9PF9.5 )
+C****
+C****
+      IF( NP  .GT. 100 ) RETURN
+      VXP = 1000. *DATAN2( VX ,VZ  )
+      VYP = 1000. * DASIN( VY /VEL )
+      VZP = VZ  / VEL
+      TP = T * VEL
+c      write (6, 114) TDIST,X,BX,EX,Y,BY,EY,Z,BZ,EZ,VXP,VYP,VEL
+      RETURN
+C****
+C****
+C****
+        ENTRY  PRNT4(NO, IN)
+C****
+115     FORMAT (///, 10X, 'MAXIMUM STEPS EXCEEDED', /10X,
+     1   'ELEMENT = ', I4, /10X, 'REGION = ', I4 ///)
+c        write (6, 115) NO, IN
+        RETURN
+C****
+C****
+      ENTRY PRNT5 ( T, S, X, Y, Z, EX, EY, EZ, ET, VX, VY, VZ          )
+C****
+      IF( NP  .GT. 100 ) RETURN
+      VXP = 1000. *DATAN2( VX ,VZ  )
+      VYP = 1000. * DASIN( VY /VEL )
+      VZP = VZ  / VEL
+      TP = T * VEL
+c      write (6, 112)TP,S,X, EX, Y, EY, Z, EZ, VZP, VXP, VYP, ET
+      RETURN
+      END
+
+
+      SUBROUTINE SHROT  ( NO, NP, T, TP ,NUM )
+C****
+C****
+C**** SUBROUTINE DOES TRANSLATIONS FIRST ALONG AXES X, Y, Z IN ORDER,
+C**** FOLLOWED BY ROTATIONS ABOUT X, Y, Z   .
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+C**** DATA  C/ 3.D10/
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 1
+      CALL PLT2 ( NUM, NO, NBR, TPAR )
+      X0 = DATA( 1,NO )
+      Y0 = DATA( 2,NO )
+      Z0 = DATA( 3,NO )
+      CX = DCOS( DATA(4,NO)/57.29578 )
+      SX = DSIN( DATA(4,NO)/57.29578 )
+      CY = DCOS( DATA(5,NO)/57.29578 )
+      SY = DSIN( DATA(5,NO)/57.29578 )
+      CZ = DCOS( DATA(6,NO)/57.29578 )
+      SZ = DSIN( DATA(6,NO)/57.29578 )
+  100 FORMAT( / '   TRANSLATE-ROTATE  ****  ', A4,'  ***************'//
+     1'      T CM', 18X, 'X CM', 7X, 'Y CM', 7X, 'Z CM' , '      VELZ/C'
+     2   , '    THETA MR      PHI MR'  /  )
+  101 FORMAT( '  TRANSLATE  ' )
+  102 FORMAT( '  ROTATE  '  )
+  103 FORMAT( F10.4, 11X, 3F11.3, F12.5, 2F12.3  )
+c      IF( NP  .LE. 100) write (6, 100)
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. *DASIN ( VYA/VEL )
+      VZP =  VZA  / VEL
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+      IF( (X0 .EQ. 0.) .AND. (Y0 .EQ. 0.) .AND. (Z0 .EQ. 0.) ) GO TO 1
+c      IF( NP  .LE. 100) write (6, 101)
+      XA = XA-X0
+      YA = YA-Y0
+      ZA = ZA-Z0
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+    1 IF( DATA( 4,NO ) .EQ. 0. ) GO TO 2
+c      IF( NP  .LE. 100) write (6, 102)
+      YR =  YA*CX +  ZA*SX
+      ZR = -YA*SX +  ZA*CX
+      VYR= VYA*CX + VZA*SX
+      VZR=-VYA*SX + VZA*CX
+      YA = YR
+      ZA = ZR
+      VYA = VYR
+      VZA = VZR
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. *DASIN ( VYA/VEL )
+      VZP =  VZA  / VEL
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+    2 IF( DATA( 5,NO ) .EQ. 0. ) GO TO 3
+c      IF( NP  .LE. 100) write (6, 102)
+      XR = -ZA*SY +  XA*CY
+      ZR =  ZA*CY +  XA*SY
+      VXR=-VZA*SY + VXA*CY
+      VZR= VZA*CY + VXA*SY
+      XA = XR
+      ZA = ZR
+      VXA = VXR
+      VZA = VZR
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. *DASIN ( VYA/VEL )
+      VZP =  VZA  / VEL
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+    3 IF( DATA( 6,NO ) .EQ. 0. ) RETURN
+c      IF( NP  .LE. 100) write (6, 102)
+      XR =  XA*CZ +  YA*SZ
+      YR = -XA*SZ +  YA*CZ
+      VXR= VXA*CZ + VYA*SZ
+      VYR=-VXA*SZ + VYA*CZ
+      XA = XR
+      YA = YR
+      VXA = VXR
+      VYA = VYR
+      VXP = 1000. *DATAN2( VXA,VZA )
+      VYP = 1000. *DASIN ( VYA/VEL )
+c      IF( NP  .LE. 100) write (6, 103) TP, XA, YA, ZA, VZP, VXP, VYP
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT2 ( NUM, NO, NBR, TPAR )
+      RETURN
+      END
+
+
+      SUBROUTINE SOLND  ( NO, NP, T, TP ,NUM )
+C****
+C****
+C**** SOLENOID      RAY TRACING BY NUMERICAL INTEGRATION OF DIFFERENTIAL
+C**** EQUATIONS OF MOTION.
+C     T = TIME
+C     TC(1) TO TC(6) =  ( X, Y, Z, VX, VY, VZ )
+C     DTC(1) TO DTC(6) = ( VX, VY, VZ, VXDOT, VYDOT, VZDOT )
+C**** BF (POSITIVE) : SOLENOID FIELD IN BEAM DIRECTION
+C**** CBF - USED IN BSOL TO DISTINGUISH BETWEEN COORD. SYSTEMS
+C****
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      REAL*8  LF           , K, L
+      COMMON  /BLCK 0/  DATA , ITITLE
+      COMMON  /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON  /BLCK 5/  XA, YA, ZA, VXA, VYA, VZA
+      COMMON  /BLCK 7/ NCODE
+      COMMON  /BLCK10/  BX, BY, BZ, K, TC, DTC
+      COMMON  /BLCK30/  BF ,      AL, RAD
+      COMMON  /BLCK31/  S, BT
+      COMMON  /BLCK32/  IN
+      DIMENSION DATA(  75,200 ), ITITLE(200)
+      DIMENSION TC(6), DTC(6), DS(6), ES(6)
+      EXTERNAL  BSOL
+C**** DATA  C/ 3.D10/
+C****
+C****
+      LF   = DATA(  1,NO )
+      A    = DATA( 10,NO )
+      B    = DATA( 11,NO )
+      L    = DATA( 12,NO )
+      D    = DATA( 13,NO )
+      BF   = DATA( 14,NO )
+      Z11  = DATA( 15,NO )
+      Z22  = DATA( 16,NO )
+      DTF1= LF/VEL
+      AL  = L/2.
+      RAD = D/2.
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S = 0.
+C****
+C****
+      IF( NP  .GT. 100 ) GO TO 5
+  201 FORMAT(  ' SOLENOID    ****  ', A4, '  ***********************'/)
+c      write (6, 201) ITITLE(NO)
+  101 FORMAT( 8H    T CM ,18X, 4HX CM , 7X, 2HBX, 8X, 4HY CM , 7X, 2HBY,
+     1   8X, 4HZ CM, 7X, 2HBZ, 8X, 6HVELZ/C , 6X, 8HTHETA MR , 5X,
+     2   6HPHI MR , 6X, 1HB             )
+      CALL PRNT2 ( T,S,XA   ,YA   ,ZA   ,BX,BY,BZ,BT,VXA  ,VYA  ,VZA   )
+c      write (6, 101)
+c      write (6, 103)
+  103 FORMAT(   '0COORDINATE TRANSFORMATION TO CENTERED AXIS SYSTEM ' )
+  109 FORMAT(   '0COORDINATE TRANSFORMATION TO D AXIS SYSTEM '       )
+C**** TRANSFORM FROM INITIAL ENTRANCE COORDINATES TO VFB COORD.
+C****
+    5 TC(1) =  XA
+      TC(2) = YA
+      TC(3) = ZA-A-AL
+      TC(4) =  VXA
+      TC(5) = VYA
+      TC(6) =  VZA
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** TRANSLATE PARTICLE TO START OF FIRST FRINGE FIELD
+C****
+      TDT = (-TC(3) -Z11 -AL ) /DABS( TC(6) )
+C****
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 104)
+  104 FORMAT( 22H0FRINGING FIELD REGION    )
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BSOL , 0    )
+      NSTEP = 0
+    6 CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      DO 7 I = 1, NP
+      CALL FNMIRK( 6, T, DTF1,TC, DTC, DS, ES, BSOL , 1    )
+      NSTEP = NSTEP + 1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      IF( (Z22+AL) .LE. TC(3) ) GO TO 8
+    7 CONTINUE
+      GO TO 6
+    8 CONTINUE
+      XDTF1 =-( TC(3) -(Z22+AL)  ) / DABS( TC(6) )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES,BSOL ,  0    )
+      CALL FNMIRK( 6, T,XDTF1,TC, DTC, DS, ES,BSOL ,  1    )
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+c      IF( NP  .LE. 100) write (6, 105) NSTEP
+  105 FORMAT( 10H   NSTEPS= , I5 )
+C****
+C**** TRANSFORM TO OUTPUT SYSTEM COORD.
+C****
+      TC(3) = TC(3) - B - AL
+c      IF( NP  .LE. 100) write (6, 109)
+      CALL PRNT2 ( T,S,TC(1),TC(2),TC(3),BX,BY,BZ,BT,TC(4),TC(5),TC(6) )
+C****
+C**** TRANSLATE PARTICLE TO OUT SYSTEM COORD.
+C****
+      TDT = -TC(3) /DABS( TC(6) )
+      TC(1) = TC(1) + TDT * TC(4)
+      TC(2) = TC(2) + TDT * TC(5)
+      TC(3) = TC(3) + TDT * TC(6)
+      T = T + TDT
+      TP = T * VEL
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      BT = 0.
+      S  = 0.
+      VXF    = 1000. *DATAN2( TC(4), TC(6)  )
+      VYF    = 1000. *DASIN ( TC(5)/ VEL    )
+      VZF    = TC(6) / VEL
+c      IF(NP.LE.100) write (6,115) TP,TC(1),TC(2),TC(3),VZF,VXF,VYF
+  115 FORMAT( F10.4, 10X, F10.3, 11X, F10.3, 11X, F10.3, 11X,
+     1   F13.5, F13.2, F11.2                   )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** CALCULATE INTERCEPTS IN SYSTEM D
+C****
+      Z0X = -TC(1)/ ( TC(4) / TC(6)    + 1.E-10 )
+      Z0Y = -TC(2)/ ( TC(5) / TC(6)    + 1.E-10 )
+c      IF(NP.LE.100) write (6,111) VXF, VYF, Z0X, Z0Y
+  111 FORMAT( / ' INTERSECTIONS WITH VER. AND HOR. PLANES '          ,
+     X       /15X, 5H  XP=,F10.4, 10H MR    YP=, F10.4, 3H MR   /
+     1        15X, 5H Z0X=,F10.2, 10H CM   Z0Y=,F10.2, 3H CM   /     )
+      RETURN
+   99 CALL PRNT4(NO, IN )
+      RETURN
+      END
+
+
+      SUBROUTINE VELS ( NO,NP,T,TP ,NUM )
+C****
+C****
+C     VELOCITY SELECTOR......ADDED JAN. 1976 BY W. R. BERNECKY
+C****
+C****
+      IMPLICIT  REAL*8 (A-H,O-Z)
+      REAL*8  K,LF1,LU1,LF2,L
+      REAL*8  NDX
+      EXTERNAL BEVC
+      COMMON /BLCK 0/  DATA, ITITLE
+      COMMON /BLCK 4/  ENERGY, VEL, PMASS, Q0
+      COMMON /BLCK 5/  XA,YA,ZA,VXA,VYA,VZA
+      COMMON /BLCK10/  BX,BY,BZ,K,TC,DTC
+      COMMON /BLCK11/  EX, EY, EZ, QMC, IVEC
+      COMMON /BLCK71/  CB0,CB1,CB2,CB3,CB4,CB5
+      COMMON /BLCK72/  CE0,CE1,CE2,CE3,CE4,CE5
+      COMMON /BLCK73/  IN,NFLAG
+      COMMON /BLCK74/  BF,EF,S,DG
+      COMMON /BLCK75/  BC2,BC4,EC2,EC4
+      COMMON /BLCK76/  DB,DE,WB,WE
+      COMMON /BLCK77/  RB,NDX
+C****
+      DIMENSION  DATA(75,200) , ITITLE(200)
+      DIMENSION  TC(6),DTC(6),DS(6),ES(6)
+C**** DATA  C/3.D10/
+C****
+      LF1=DATA( 1,NO)
+      LU1=DATA( 2,NO)
+      LF2=DATA( 3,NO)
+      DG =DATA( 4,NO)
+      A  =DATA( 7,NO)
+      B  =DATA( 8,NO)
+      L  =DATA( 9,NO)
+      BF =DATA(10,NO)
+      EF =DATA(11,NO)
+      RB =DATA(12,NO)
+      NDX=DATA(13,NO)
+      DB =DATA(16,NO)
+      DE =DATA(17,NO)
+      WB =DATA(18,NO)
+      WE =DATA(19,NO)
+      Z11=DATA(20,NO)
+      Z12=DATA(21,NO)
+      Z21=DATA(22,NO)
+      Z22=DATA(23,NO)
+      BC2=DATA(24,NO)
+      BC4=DATA(25,NO)
+      EC2=DATA(26,NO)
+      EC4=DATA(27,NO)
+      NFLAG = 0
+      IF( NDX .NE. 0. ) NFLAG=1
+      IF( RB  .EQ. 0. ) RB=1.D30
+      EX = 0.
+      EY = 0.
+      EZ = 0.
+      S  = 0.
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      IF ( NP .GT. 100 ) GO TO 5
+c      write (6, 100) ITITLE(NO)
+  100 FORMAT ('0VELOCITY SELECTOR****  ',A4,'  ******************'/ )
+c      write (6, 101)
+  101 FORMAT (8H    T CM,6X,4HX CM,5X,2HBX,8X,2HEX,8X,4HY CM,5X,2HBY,8X,
+     1       2HEY,7X,4HZ CM,6X,2HBZ,8X,2HEZ,6X,8HTHETA MR,5X,6HPHI MR,
+     2   2X, 'VEL/E9'   )
+      TDIST = T*VEL
+      CALL PRNT3( TDIST,XA,YA,ZA,BX,BY,BZ,EX,EY,EZ,VXA,VYA,VZA )
+c      write (6, 103)
+  103 FORMAT ( '0COORDINATE TRANSFORMATION TO B AXIS SYSTEM' )
+  109 FORMAT ( '0COORDINATE TRANSFORMATION TO D AXIS SYSTEM' )
+C****
+C**** TRANSFORM FROM INITIAL ENTRANCE COORDINATES
+C****
+    5 TC(1) = -XA
+      TC(2) =  YA
+      TC(3) = A-ZA
+      TC(4) = -VXA
+      TC(5) =  VYA
+      TC(6) = -VZA
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** TRANSLATE PARTICLE TO START OF FRINGE FIELD
+C****
+      TDT = ( TC(3)-Z11 )/DABS( TC(6) )
+      TC(1) = TC(1)+TDT*TC(4)
+      TC(2) = TC(2)+TDT*TC(5)
+      TC(3) = TC(3)+TDT*TC(6)
+      T = T+TDT
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** IN DESIGNATES MAGNET REGIONS FOR BFUN
+C****
+      IN = 1
+      CB0=DATA(28,NO)
+      CB1=DATA(29,NO)
+      CB2=DATA(30,NO)
+      CB3=DATA(31,NO)
+      CB4=DATA(32,NO)
+      CB5=DATA(33,NO)
+      CE0=DATA(34,NO)
+      CE1=DATA(35,NO)
+      CE2=DATA(36,NO)
+      CE3=DATA(37,NO)
+      CE4=DATA(38,NO)
+      CE5=DATA(39,NO)
+      DTF1 = LF1/VEL
+c      IF ( NP .LE. 100 ) write (6, 104)
+  104 FORMAT ( 22H0FRINGING FIELD REGION)
+      CALL FNMIRK (6,T,DTF1,TC,DTC,DS,ES,BEVC,0 )
+      NSTEP = 0
+      TDIST = T*VEL
+    6 CONTINUE
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+      DO 7 I=1,NP
+      CALL FNMIRK (6,T,DTF1,TC,DTC,DS,ES,BEVC,1 )
+      NSTEP = NSTEP+1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 2
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      TDIST = TDIST + DTF1*VEL
+      IF ( Z12 .GE. TC(3) ) GO TO 8
+    7 CONTINUE
+      GO TO 6
+    8 CONTINUE
+      XDTF1 = -( Z12-TC(3) )*DABS( TC(6) )/VEL**2
+      CALL FNMIRK (6,T,XDTF1,TC,DTC,DS,ES,BEVC,0 )
+      CALL FNMIRK (6,T,XDTF1,TC,DTC,DS,ES,BEVC,1 )
+      TDIST = TDIST + XDTF1*VEL
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+c      IF ( NP .LE. 100 ) write (6, 105) NSTEP
+  105 FORMAT ( 10H   NSTEPS= ,I5 )
+C****
+C****    TRANSLATE TO 2ND VFB COORDINATE SYSTEM
+C****
+      TC(1) = -TC(1)
+      TC(3) = -(TC(3)+L)
+      TC(4) = -TC(4)
+      TC(6) = -TC(6)
+C****
+C**** UNIFORM FIELD REGION
+C****
+      IN = 2
+      DTU = LU1/VEL
+c      IF ( NP .LE. 100 ) write (6, 106)
+  106 FORMAT ( '0UNIFORM FIELD REGION IN C AXIS SYSTEM' )
+      CALL FNMIRK (6,T,DTU,TC,DTC,DS,ES,BEVC,0 )
+      NSTEP = 0
+    9 CONTINUE
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+      DO 10 I = 1,NP
+      CALL FNMIRK (6,T,DTU,TC,DTC,DS,ES,BEVC,1 )
+      NSTEP = NSTEP+1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      TDIST = TDIST + DTU*VEL
+      IF ( TC(3) .GE. Z21 ) GO TO 11
+   10 CONTINUE
+      GO TO 9
+   11 CONTINUE
+      XDTU = (Z21-TC(3) )*DABS( TC(6) )/VEL**2
+      CALL FNMIRK (6,T,XDTU,TC,DTC,DS,ES,BEVC,0)
+      CALL FNMIRK (6,T,XDTU,TC,DTC,DS,ES,BEVC,1 )
+      TDIST = TDIST + XDTU*VEL
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+c      IF ( NP .LE. 100 ) write (6, 105) NSTEP
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** SET UP FOR SECOND FRINGE FIELD INTEGRATION
+C****
+      CB0=DATA(40,NO)
+      CB1=DATA(41,NO)
+      CB2=DATA(42,NO)
+      CB3=DATA(43,NO)
+      CB4=DATA(44,NO)
+      CB5=DATA(45,NO)
+      CE0=DATA(46,NO)
+      CE1=DATA(47,NO)
+      CE2=DATA(48,NO)
+      CE3=DATA(49,NO)
+      CE4=DATA(50,NO)
+      CE5=DATA(51,NO)
+      IN = 3
+      DTF2 = LF2/VEL
+c      IF ( NP .LE. 100 ) write (6, 104)
+      CALL FNMIRK (6,T,DTF2,TC,DTC,DS,ES,BEVC,0 )
+      NSTEP=0
+   12 CONTINUE
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+      DO 13  I=1,NP
+      CALL FNMIRK (6,T,DTF2,TC,DTC,DS,ES,BEVC,1 )
+      NSTEP = NSTEP+1
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF (NSTEP  .GT.  200)  GO TO 99
+      TDIST = TDIST + DTF2*VEL
+      IF ( TC(3) .GE. Z22 ) GO TO 14
+   13 CONTINUE
+      GO TO 12
+   14 CONTINUE
+      XDTF2 = ( Z22-TC(3) )*TC(6)/VEL**2
+      CALL FNMIRK (6,T,XDTF2,TC,DTC,DS,ES,BEVC,0 )
+      CALL FNMIRK (6,T,XDTF2,TC,DTC,DS,ES,BEVC,1 )
+      TDIST = TDIST + XDTF2*VEL
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+c      IF (NP .LE. 100) write (6, 105) NSTEP
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 3
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+C****
+C**** TRANSLATE TO OUTPUT COORDINATES
+C****
+      TC(3) = TC(3)-B
+c      IF ( NP .LE. 100 ) write (6, 109)
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+      T = TDIST/VEL
+      TDT =-TC(3)/DABS( TC(6) )
+      TC(1) = TC(1)+TDT*TC(4)
+      TC(2) = TC(2)+TDT*TC(5)
+      TC(3) = TC(3)+TDT*TC(6)
+      T = T+TDT
+      BX = 0.
+      BY = 0.
+      BZ = 0.
+      EX = 0.
+      EY = 0.
+      EZ = 0.
+      S  = 0.
+      VXF    = 1000. *DATAN2( TC(4), TC(6)  )
+      VYF    = 1000. *DASIN ( TC(5)/ VEL    )
+      TDIST = T*VEL
+      NUM = NUM+1
+      TPAR = T*VEL
+      NBR = 4
+      CALL PLT1 ( NUM, NO, NBR, TPAR )
+      IF ( NP .GT. 100 ) GO TO 15
+      CALL PRNT3 (TDIST,TC(1),TC(2),TC(3),BX,BY,BZ,
+     1            EX,EY,EZ,TC(4),TC(5),TC(6)  )
+   15 CONTINUE
+      ZDX = -TC(1)/( TC(4)/TC(6)+1.E-10 )
+      ZDY = -TC(2)/( TC(5)/TC(6)+1.E-10 )
+c      IF (NP .LE. 100 ) write (6, 111) VXF,VYF,ZDX,ZDY
+  111 FORMAT (/'0INTERSECTIONS WITH VER. AND HOR. PLANES '
+     X       /15X,5H  XP=,F10.4,10H MR    YP=,F10.4,3H MR / ,
+     1    15X,5H Z0X=,F10.2,10H CM   Z0Y=,F10.2,3H CM   /   )
+      RETURN
+   99 CALL PRNT4(NO, IN)
+      RETURN
+      END
+
+
+      SUBROUTINE  RAYS(NR)
+C****
+      IMPLICIT REAL*8(A-H,O-Z)
+      COMMON  /BLCK 1/  XI, YI, ZI, VXI, VYI, VZI, DELP
+C
+C** xkine=K=(1/p)dp/dtheta
+C** added by DY for spectrometer calculations 8/25/93
+C
+      COMMON  /BLCK15/  TMIN, PMIN, XMAX, TMAX, YMAX, PMAX, DMAX, xkine
+C
+      DIMENSION XI(1000),YI(1000),ZI(1000),VXI(1000),VYI(1000),
+     1      VZI(1000), DELP(1000)
+  100 FORMAT (///10X, 'JNR = ', I10 ///)
+C****
+C****
+      DO 1 I=1,1000
+      XI(I)=0.
+      YI(I)=0.
+      ZI(I)=0.
+      VXI(I)=0.
+      VYI(I)=0.
+      VZI(I)=0.
+      DELP(I)=0.
+    1 CONTINUE
+      IF (TMIN.EQ.0.) TMIN=1.0
+      IF (PMIN.EQ.0.) PMIN=1.0
+      TMAX2 = TMAX/2.0
+      TMAX3 = TMAX/3.0
+      PMAX2 = PMAX/2.0
+      PMAX3 = 2.*PMAX/3.0
+      IF (NR.EQ.2) GO TO 2
+      IF (NR.EQ.6) GO TO 2
+      IF (NR.EQ.14) GO TO 2
+      IF (NR.EQ.46) GO TO 3
+c      write (6,100) NR
+      CALL EXIT
+    2 VXI(2)=TMIN
+      VYI(2)=PMIN
+      IF (NR.EQ.2) GO TO 5
+      VXI(3)=TMAX2
+      VXI(4)=-TMAX2
+      VXI(5)=TMAX
+      VXI(6)=-TMAX
+      IF (NR.EQ.6) GO TO 5
+      VYI(7)=PMAX2
+      VXI(8)=TMAX2
+      VYI(8)=PMAX2
+      VXI(9)=-TMAX2
+      VYI(9)=PMAX2
+      VXI(10)=TMAX
+      VYI(10)=PMAX2
+      VXI(11)=-TMAX
+      VYI(11)=PMAX2
+      VYI(12)=PMAX
+      VXI(13)=TMAX2
+      VYI(13)=PMAX
+      VXI(14)=-TMAX2
+      VYI(14)=PMAX
+C****
+C****
+C****
+    5 DO 4 I=1,NR
+      XI(I) = XMAX
+      YI(I) = YMAX
+    4 DELP(I) = DMAX
+C   
+C   change DELP for RAY 2 for kinematic focusing DY 8/93
+C
+      if (xkine.ne.0.0) DELP(2)=-xkine*vxi(2)*.20
+C
+      RETURN
+C****
+C****
+C****
+    3 VXI(2)=TMIN
+      VYI(2)=PMIN
+C   
+C   change DELP for RAY 2 for kinematic focusing DY 8/93
+C
+      if (xkine.ne.0.0) DELP(2)=-xkine*vxi(2)*.2
+C
+      XI(3)=XMAX
+      XI(4)=-XMAX
+      VXI(5)=TMAX3
+      VXI(6)=-TMAX3
+      YI(7)=YMAX
+      YI(8)=-YMAX
+      VYI(9)=PMAX3
+      VYI(10)=-PMAX3
+      DELP(11)=DMAX
+      DELP(12)=-DMAX
+      XI(13)=XMAX
+      VXI(13)=TMAX3
+      XI(14)=-XMAX
+      VXI(14)=-TMAX3
+      XI(15)=XMAX
+      DELP(15)=DMAX
+      XI(16)=-XMAX
+      DELP(16)=-DMAX
+      VXI(17)=TMAX3
+      DELP(17)=DMAX
+      VXI(18)=-TMAX3
+      DELP(18)=-DMAX
+      YI(19)=YMAX
+      VYI(19)=PMAX3
+      YI(20)=-YMAX
+      VYI(20)=PMAX3
+      XI(21)=XMAX
+      YI(21)=YMAX
+      XI(22)=-XMAX
+      YI(22)=YMAX
+      XI(23)=XMAX
+      VYI(23)=PMAX3
+      XI(24)=-XMAX
+      VYI(24)=PMAX3
+      VXI(25)=TMAX3
+      YI(25)=YMAX
+      YI(26)=YMAX
+      VXI(27)=TMAX3
+      VYI(27)=PMAX3
+      VXI(28)=-TMAX3
+      VYI(28)=PMAX3
+      YI(29)=YMAX
+      DELP(29)=DMAX
+      YI(30)=YMAX
+      DELP(30)=-DMAX
+      VYI(31)=PMAX3
+      DELP(31)=DMAX
+      VYI(32)=PMAX3
+      DELP(32)=-DMAX
+      VXI(33)=TMAX
+      VXI(34)=-TMAX
+      XI(35)=XMAX
+      VXI(35)=TMAX
+      XI(36)=-XMAX
+      VXI(36)=TMAX
+      XI(37)=XMAX
+      VXI(37)=-TMAX
+      XI(38)=-XMAX
+      VXI(38)=-TMAX
+      VXI(39)=TMAX
+      DELP(39)=DMAX
+      VXI(40)=TMAX
+      DELP(40)=-DMAX
+      VXI(41)=-TMAX
+      DELP(41)=DMAX
+      VXI(42)=-TMAX
+      DELP(42)=-DMAX
+      VYI(43)=PMAX
+      VXI(44)=TMAX
+      VYI(44)=PMAX
+      DELP(45)=3.*DMAX
+      DELP(46)=-3.*DMAX
+      RETURN
+      END
+C******************************
+C                             *
+C  FILE:  DATIME.F            *
+C                             *
+C******************************
+C
+C  THIS FILE CONTAINS SUBROUTINES THAT INTERFACE THE GETDAT AND GETTIM
+C   CALLS OF MICROSOFT FORTRAN, ETC., TO THE APPROPRIATE CALLS FOR
+C   THE MICROWAY NDP-FORTRAN 386 COMPILER.
+C
+C  THE CALLING SEQUENCES ARE OBVIOUS.  NOTE THAT THE SUBROUTINE
+C   ARGUMENTS ARE INT*2 TO BE COMPATIBLE WITH OTHER PC COMPILERS.
+C   THIS MAY BE A PROBLEM FOR PROGRAMS PORTED FROM THE VAX.
+C
+ 
+c******
+c        SUBROUTINE GETDAT(IYEAR,IMON,IDAY)
+c        INTEGER*2 IYEAR,IMON,IDAY
+C
+c        INTEGER*4 IMO,IDA,IYR,IDUMMY
+c        CALL DOSDAT(IMO,IDA,IYR,IDUMMY)
+c        IYEAR=IYR
+c        IMON=IMO
+c        IDAY=IDA
+c        RETURN
+c        END
+C
+C
+
+c        SUBROUTINE GETTIM(IHOUR,IMIN,ISEC,IHUND)
+c        INTEGER*2 IHOUR,IMIN,ISEC,IHUND
+c
+c        INTEGER*4 IHR,IMN,ISC,IHU
+c        CALL DOSTIM(IHR,IMN,ISC,IHU)
+c        IHOUR=IHR
+c        IMIN=IMN
+c        ISEC=ISC
+c        IHUND=IHU
+c        RETURN
+c        END
+c******
+
+
+       SUBROUTINE KINE(AM,THETA,ENGY,RAT,PCTR,KB)
+CC     THIS ROUTINE PERFORMS CALCULATIONS FOR FOUR BODY RELATIVISTIC
+CC     SCATTERING, IF THE INPUT DATA HAS NO SOLUTION, THE VALUE OF KB
+CC     ON RETURN IS ONE (1). OTHERWISE, KB = 2.
+C
+CC     INPUT.....
+CC     AM(1) TO AM(3) ARE THE MASSES (IN C12 SCALE AMU) OF THE INCIDENT 
+CC     TARGET, AND SCATTERED PARTICLES, RESPECTIVELY.
+CC     THETA(1) IS THE LAB SCATTERING ANGLE (IN DEGREES).
+CC     ENGY(1) IS THE Q-VALUE (IN MEV) OF THE REACTION
+CC     ENGY(2) IS THE BEAM ENERGY (IN MEV).
+C
+CC     OUTPUT.....
+CC     AM(4) IS THE MASS (IN C12 SCALE AMU) OF THE RESIDUAL NUCLEUS.
+CC     THETA(2) IS THE RECOIL ANGLE (IN DEGREES) OF MASS FOUR (4).
+CC     THETA (3) IS THE CENTER-OF-MOMENTUM ANGLE (IN DEGREES) OF SCATTER
+CC     ENGY(3) IS THE KINETIC ENERGY (IN MEV) OF THE SCATTERED PARTICLE.
+CC     RAT(1) IS THE KINEMATIC BROADENING (IN KEV/DEGREE) OF THE PRODUCT
+CC     RAT(2) IS THE CROSS-SECTION RATIO -- SIGC/SIGL.
+C
+CC     PCTR IS THE MOMENTUM TRANSFER
+C
+CC     PROGRAM CALCULATES SECOND SOLUTION IF AM(4) IS SET NEGATIVE
+CC     FUNCTION =1 IF NO SOLUTION AND ENGY(3) .LT. 0.0
+C
+	IMPLICIT REAL*8 (A-H,P-Z)
+C	DIMENSION EM(3)
+C	REAL*4 AM(4),THETA(3),ENGY(3),RAT(2),PCTR
+        DIMENSION AM(4), THETA(3), ENGY(3), RAT(2), EM(3)
+C
+C	WRITE (*,31) (AM(I),I=1,4),(THETA(I),I=1,3),(ENGY(I),I=1,3)
+C31	FORMAT (10F8.2)
+C	
+	KDEL = 1
+	ISOLU=0
+	IF(AM(4).LT.0.0) ISOLU=1
+	KB = 1
+        ENGY(3)=-0.001
+C	write (*,*) ' in kine am(4) ',am(1),am(2),am(3),am(4)
+ 	IF((AM(4).LT.0.0).AND.(AM( 1).LE.AM(2))) GO TO 24
+	IF((AM(1).GT.AM(2)).AND.(THETA(1).GT.90.0)) GO TO 24
+C  set theta to 0.01 for 0 deg. elastic scattering
+	IF (THETA(1) .EQ. 0.0 ) THETA(1) = 0.01
+	Q = ENGY(1)
+	TA = ENGY(2)
+	THL= .01745329*THETA(1)
+	DO 10 I=1,3
+ 10	EM(I)= 931.502*AM(I)
+  	EMI= EM(1)+EM(2)
+ 	AM(4)= (EMI-EM(3)-Q)/931.502
+C	write (*,*) ' em',em(1),em(2),em(3),emi,am(1),am(2),am(3)
+ 	COSL= COS (THL)
+  	SINL= SIN (THL)
+  	ETOT=EMI+TA
+  	PA= SQRT (TA*(2.*EM(1)+TA))
+  	BETA= PA/ETOT
+ 	GAMMA=ETOT/SQRT(EMI*EMI+2.*TA*EM(2))
+C	write (*,*) ' in kine 1.5',pa,ta,eps,beta,cosl,etot,emi
+  	EPS= BETA*COSL
+	EPSQ= EPS*EPS
+ 	OMES= 1.-EPSQ
+ 	EPSMC= EPS*EM(3)
+ 	B= (Q*(EMI-EM(3)-(Q/2.))+TA*(EM(2)-EM(3)))/ETOT
+ 	BP= B+EM(3)*EPSQ
+ 	DEL= B*B+EM(3)*(B+BP)
+C	write (*,*) ' in kine2', del
+ 	IF (DEL) 24, 12, 13
+12	KDEL = 2
+  	RAT(1)= 0.
+  	GO TO 14
+13	DEL= SQRT (DEL) 
+14	TC=(BP+(-1.)**ISOLU*EPS*DEL)/OMES
+C	write (*,*) ' in kine3',eps,del,omes,bp
+ 	 IF (TC-.001) 24,16,16
+16	KB=2
+	ENGY(3)=TC
+  	GO TO (18,20), KDEL
+18	ZZ=2.*(-1.)**ISOLU
+ 	RAT(1)=ABS((ZZ*EPS*TC+EPSMC*(2.+EPSMC/DEL)+DEL)*BETA*SINL*
+     1		17.45329/OMES)
+20	PC=SQRT(TC*(2.*EM(3)+TC))
+ 	PD=SQRT(ABS(PA*PA+PC*(PC-2.*PA*COSL)))
+C
+	TPC = PC*SINL
+C	WRITE (*,30) PC,SINL,PD,PA,TC,TPC
+C30	FORMAT (6F15.8)
+	PHI=ASIN(PC*(SINL/PD))
+ 	IF (PA-PC*COSL) 25,27,27
+25	PHI= 3.1415926-PHI
+27	CONTINUE
+	THETA(2)=PHI*57.295779
+ 	PCPX=GAMMA*(PC*COSL-BETA*(EM(3)+TC))
+ 	PCP= SQRT (PCPX*PCPX+(PC*SINL)**2)
+ 	THC= ASIN (PC*SINL/PCP)
+ 	COSC= COS (THC)
+	IF (PCPX) 26,28,28
+26 	THC= 3.1415926-THC
+ 	COSC= -COSC
+28	THETA(3)= THC*57.295779
+ 	RAT(2)= GAMMA*(1.+COSC*BETA*SQRT(1.+(EM(3)/PCP)**2))*(PCP/PC)**3
+ 	RAT(2)=ABS(RAT(2))
+ 	COSTH=COS(THC)
+ 	ECM=SQRT(EMI*EMI+2.*TA*EM(2))
+ 	ECM1=(EM(1)*EMI+TA*EM(2))/ECM
+	TCM1=ECM1-EM(1)
+	PCM1=SQRT(TCM1*(TCM1+2.*EM(1)))
+  	PCTR=0.005067*SQRT(PCM1*PCM1+PCP*(PCP-2.*PCM1*COSTH))
+24 	AM(4)=ABS(AM(4))
+	RETURN
+ 	END
diff --git a/NPLib/Detectors/MDM/Resources/MinimizerPlugins.C b/NPLib/Detectors/MDM/Resources/MinimizerPlugins.C
new file mode 100644
index 0000000000000000000000000000000000000000..c8f77c84e366ec095aba997af97ea53e8655da75
--- /dev/null
+++ b/NPLib/Detectors/MDM/Resources/MinimizerPlugins.C
@@ -0,0 +1,514 @@
+// ROOT
+#include <TGraph.h>
+#include <TVector3.h>
+// NPTOOL
+#include "NPSystemOfUnits.h"
+// MDM
+#include "TMDMPhysicsMinimizer.h"
+#include "TMDMPhysics.h"
+
+
+// Helper functions
+// Check if xpos between limits for MDM
+bool check_good_x(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		if(m_MDM->Xpos[i] > m_MDM->GetXlow() &&
+			 m_MDM->Xpos[i] < m_MDM->GetXhigh()) {
+			++ngood;
+		}
+	}
+	return (ngood > 1);
+}
+
+bool check_good_y(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	for(size_t i=0; i< m_MDM->Ypos.size(); ++i) {
+		if(m_MDM->Ypos[i] > m_MDM->GetYlow() &&
+			 m_MDM->Ypos[i] < m_MDM->GetYhigh()) {
+			++ngood;
+		}
+	}
+	return (ngood > 1);
+}
+
+// Chi2 calculation (x-only) (used in many classes)
+double calc_chi2_xy(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	double chi2 = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		size_t iDet = m_MDM->DetectorNumber[i];
+		if(iDet > 3) { continue; }
+
+		double X = m_MDM->Xpos[i];
+		double F = m_MDM->Fit_Xpos[iDet];
+
+		double Y = m_MDM->Ypos[i];
+		double G = m_MDM->Fit_Ypos[iDet];
+		
+		if(X > m_MDM->GetXlow() && X < m_MDM->GetXhigh() &&
+			 Y > m_MDM->GetYlow() && Y < m_MDM->GetYhigh() ){
+			++ngood;
+			double w = 1.; // "weight"
+			double ch2;
+			ch2 = pow(X - F, 2) / w;   chi2 += ch2;
+			ch2 = pow(Y - G, 2) / w;   chi2 += ch2;
+		}
+	}
+	return chi2 / ngood;
+}
+
+// Chi2 calculation (x-only) (used in many classes)
+double calc_chi2_x(TMDMPhysics* m_MDM){
+	int ngood = 0;
+	double chi2 = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		size_t iDet = m_MDM->DetectorNumber[i];
+		if(iDet > 3) { continue; }
+
+		double X = m_MDM->Xpos[i];
+		double F = m_MDM->Fit_Xpos[iDet];
+
+		if(X > m_MDM->GetXlow() && X < m_MDM->GetXhigh()){
+			++ngood;
+			double w = 1.; // "weight"
+			double ch2 = pow(X - F, 2) / w;
+			chi2 += ch2;
+		}
+	}
+	return chi2 / ngood;
+}
+
+// R2 calculation (x-only) (used in many classes)
+double calc_r2_x(TMDMPhysics* m_MDM){
+	int nnn = 0;
+	double ybar = 0;
+	for(const auto& x : m_MDM->Xpos) {
+		if(x > m_MDM->GetXlow() && x < m_MDM->GetXhigh()) {
+			++nnn;	ybar += x;
+		}
+	}
+	ybar /= nnn;
+
+	double SStot = 0, SSres = 0;
+	for(size_t i=0; i< m_MDM->Xpos.size(); ++i) {
+		size_t iDet = m_MDM->DetectorNumber[i];
+		if(iDet > 3) { continue; }
+
+		double X = m_MDM->Xpos[i];				
+		double F = m_MDM->Fit_Xpos[iDet];
+		if(X > m_MDM->GetXlow() && X < m_MDM->GetXhigh()) {
+			SStot += pow(X - ybar, 2);
+			SSres += pow(X - F, 2);
+		}
+	}
+	double  r2 = 1 - (SSres/SStot);
+	return -r2; // negative (to minimize)
+}
+
+
+// Minimize over x, y angle and ekin, using unweighted chi2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerChi2XY : public TMDMPhysicsMinimizer{
+public:
+	MinimizerChi2XY(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(3, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerChi2XY* out = new MinimizerChi2XY(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = false;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double thetaY = x[1]; // deg
+		double Ekin   = x[2]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,thetaY,Ekin);
+		}
+
+		// calculate Chi2
+		return calc_chi2_xy(m_MDM);
+	}
+};
+
+// Minimize over x angle and ekin, using unweighted chi2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerChi2X : public TMDMPhysicsMinimizer{
+public:
+	MinimizerChi2X(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(2, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerChi2X* out = new MinimizerChi2X(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double Ekin   = x[2]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,m_InitialThetaY,Ekin);
+		}
+
+		// calculate Chi2
+		return calc_chi2_x(m_MDM);
+	}
+};
+
+
+// Minimize over x-angle and ekin, using linear R2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerR2X : public TMDMPhysicsMinimizer{
+public:
+	MinimizerR2X(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(2, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerR2X* out = new MinimizerR2X(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double Ekin   = x[1]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,m_InitialThetaY,Ekin);
+		}
+
+		// calculate R2
+		return calc_r2_x(m_MDM);
+	}
+};
+
+// Minimize over ekin only
+// Take x- and y- angle from the measured light particle angle
+// and reaction kinematics
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerR2XYLight : public TMDMPhysicsMinimizer{
+public:
+	MinimizerR2XYLight(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(1, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerR2XYLight* out = new MinimizerR2XYLight(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = true;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		
+		if(m_MDM->GetReaction() == 0) {
+			static bool warn = true;
+			if(warn) {
+				warn = false;
+				std::cerr << "WARNING in MinimizerR2XYLight::Initialize() :: " <<
+					"Reaction not set, defaulting to ZERO angle for Theta_X and Theta_Y at " <<
+					"the target...\n";
+			}
+			m_InitialThetaX = 0;
+			m_InitialThetaY = 0;
+		} else {
+			double ThetaLight, PhiLight;
+			m_MDM->GetLightParticleAngles(ThetaLight, PhiLight);
+			
+			std::unique_ptr<TGraph> kin (m_MDM->GetReaction()->GetTheta3VsTheta4(0.1));
+			double ThetaHeavy = kin->Eval(ThetaLight);
+			double PhiHeavy = PhiLight - 180;
+			if(PhiLight < 0) { PhiHeavy += 360; }
+
+			TVector3 v;
+			v.SetMagThetaPhi(1,ThetaHeavy*NPUNITS::deg, PhiHeavy*NPUNITS::deg);
+			m_InitialThetaX = atan(v.X()/v.Z())/NPUNITS::deg;
+			m_InitialThetaY = atan(v.Y()/v.Z())/NPUNITS::deg;
+		}
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double Ekin   = x[0]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(m_InitialThetaX,m_InitialThetaY,Ekin);
+		}
+		
+		// calculate R2 (from wires x)
+		return calc_r2_x(m_MDM);
+	}
+};
+
+
+
+# if 0
+
+void TMDMPhysics::CalculateAnalyticAngles(double& tx, double& ty){
+	// n.b. not sure if this is universal!!
+	// Taken from simulation of 14C(a,4n)14O @560 MeV
+	// detecting 14O in MDM
+	tx = -0.656*pow(Xang,2) + -0.414486*Xang; // RAD
+	ty = -3.97*Yang; // RAD
+}
+
+
+// Fit both x-angle and energy to the wire spectra
+// take y-angle from "analytic" evaluation of RAYTRACE
+// correlations
+void TMDMPhysics::MinimizeWithXangle(){
+	Target_Ekin = CalculateCentralEnergy();
+	CalculateAnalyticAngles(Target_Xang, Target_Yang);
+
+	std::unique_ptr<FitFunctor> f (nullptr);
+	if(m_FitMethod == 1) {
+		f.reset(new Chi2WireX(this));
+	}
+	else if(m_FitMethod == 2) {
+		f.reset(new R2WireX(this));
+	}
+	else {
+		assert(0 && "Shouldn't get here!!!");
+	}
+
+	ROOT::Minuit2::Minuit2Minimizer min (ROOT::Minuit2::kMigrad); 
+	InitializeMinimizerWithDefaults(&min);
+	min.SetFunction(*f);
+	// Set the free variables to be minimized!
+	min.SetVariable(0,"thetax",Target_Xang, 0.01 /*step*/);
+	min.SetVariable(1,"ekin"  ,Target_Ekin, 0.01 /*step*/);
+	min.Minimize();
+
+	Target_Xang = min.X()[0] * deg; // rad
+	Target_Ekin = min.X()[1] * MeV; // MeV
+	Fit_Chi2 = f->operator()(min.X());
+}
+
+// Fit only the energy to the wire spectra
+// Take angle from the LIGHT particle and reaction
+// Minimize over x-angle and ekin, using linear R2
+// Initial starting point for angles taken as zero (change as needed)
+// Initial starting point for ekin taken as central brho of magnet
+class MinimizerR2X : public TMDMPhysicsMinimizer{
+public:
+	MinimizerR2X(TMDMPhysics* mdm = 0):
+		TMDMPhysicsMinimizer(2, mdm){
+	}
+	ROOT::Math::IMultiGenFunction* Clone() const{
+		MinimizerR2X* out = new MinimizerR2X(m_MDM);
+		return out;
+	}
+	void Initialize(){
+		m_FixedThetaX = false;
+		m_FixedThetaY = true;
+		m_FixedEkin   = false;
+
+		m_InitialThetaX = 0.;
+		m_InitialThetaY = 0.;
+		m_InitialEkin = m_MDM->CalculateCentralEnergy();
+	}
+private:
+	double DoEval(const double* x) const{
+		double thetaX = x[0]; // deg
+		double Ekin   = x[1]; // MeV
+		if(check_good_x(m_MDM)){
+			m_MDM->SendRay(thetaX,m_InitialThetaY,Ekin);
+		}
+
+		// calculate R2
+		return calc_r2_x(m_MDM);
+	}
+};
+
+// kinematics
+void TMDMPhysics::MinimizeUsingLightParticleAngle(){
+	Target_Ekin = CalculateCentralEnergy();
+	if(m_Reaction == 0) {
+		static bool warn = true;
+		if(warn) {
+			warn = false;
+			std::cerr << "WARNING in TMDMPhysics::MinimizeUsingLightParticleAngle() :: " <<
+				"m_Reaction not set, defaulting to ZERO angle for Theta_X and Theta_Y at " <<
+				"the target...\n";
+		}
+		Target_Xang = 0;
+		Target_Yang = 0;
+	} else {
+		std::unique_ptr<TGraph> kin (m_Reaction->GetTheta3VsTheta4(0.1));
+		double ThetaHeavy = kin->Eval(m_Light_ThetaLab);
+		double PhiHeavy = m_Light_PhiLab - 180;
+		if(m_Light_PhiLab < 0) { PhiHeavy += 360; }
+
+		TVector3 v;
+		v.SetMagThetaPhi(1,ThetaHeavy*deg,PhiHeavy*deg);
+		Target_Xang = atan(v.X()/v.Z())/deg;
+		Target_Yang = atan(v.Y()/v.Z())/deg;
+	}
+	
+	R2WireX1 f(this, Target_Xang, Target_Yang);
+	
+	ROOT::Minuit2::Minuit2Minimizer min (ROOT::Minuit2::kMigrad); 
+	InitializeMinimizerWithDefaults(&min);
+	min.SetFunction(f);
+	// Set the free variables to be minimized!
+	min.SetVariable(0,"ekin"  ,Target_Ekin, 0.01 /*step*/);
+	min.Minimize();
+
+	Target_Ekin = min.X()[0] * MeV; // MeV
+	Fit_Chi2 = f(min.X());
+}
+
+
+
+
+class Chi2WireX : public FitFunctor {
+public:
+	Chi2WireX(const TMDMPhysics* mdm):
+		FitFunctor(mdm) { }
+
+	double DoEval (const double* p) const{
+		double thetaX = p[0]; // deg
+		double Ekin   = p[1]; // MeV
+		m_MDM->SendRay(thetaX,m_MDM->Yang/deg,Ekin);
+
+		// calculate Chi2
+		double chi2 = 0;
+		assert(m_MDM->Xpos.size() == 4);
+
+		for(int i=0; i< m_MDM->Xpos.size(); ++i) {
+
+			size_t iDet = m_MDM->DetectorNumber[i];
+			if(iDet > 3) { continue; }
+
+			double X = m_MDM->Xpos[i];				
+			double F = m_MDM->Fit_Xpos[iDet];
+
+			if(X > -20 && X < 20) {
+				double w = 1.; // "weight"
+				double ch2 = pow(X - F, 2) / w;
+				chi2 += ch2;
+			}
+		}
+	
+		return chi2;
+	}
+1
+	unsigned int NDim() const { return 2; }
+};
+
+class R2WireX : public FitFunctor {
+public:
+	R2WireX(const TMDMPhysics* mdm):
+		FitFunctor(mdm) { }
+
+	double DoEval (const double* p) const{
+		double thetaX = p[0]; // deg
+		double Ekin   = p[1]; // MeV
+		m_MDM->SendRay(thetaX,0,Ekin);
+
+		// calculate R2
+		int nnn = 0;
+		double ybar = 0;
+		for(const auto& x : m_MDM->Xpos) {
+			if(x > -20 && x < 20) {
+				++nnn;	ybar += x;
+			}
+		}
+		ybar /= nnn;
+
+		double SStot = 0, SSres = 0;
+		for(int i=0; i< 4; ++i) {
+			size_t iDet = m_MDM->DetectorNumber[i];
+			if(iDet > 3) { continue; }
+
+			double X = m_MDM->Xpos[i];				
+			double F = m_MDM->Fit_Xpos[iDet];
+
+			if(X > -20 && X < 20) {
+				SStot += pow(X - ybar, 2);
+				SSres += pow(X - F, 2);
+			}
+		}
+
+		double r2 = 1 - (SSres/SStot);
+		return -r2;
+	}
+
+	unsigned int NDim() const { return 2; }
+};
+
+
+class R2WireX1 : public FitFunctor {
+public:
+	double thetaX,thetaY;
+	R2WireX1(const TMDMPhysics* mdm, double thetax, double thetay):
+		FitFunctor(mdm) {
+		thetaX = thetax;
+		thetaY = thetay;
+	}
+
+	double DoEval (const double* p) const{
+		double Ekin   = p[0]; // MeV
+		m_MDM->SendRay(thetaX,thetaY,Ekin);
+
+		// calculate R2
+		int nnn = 0;
+		double ybar = 0;
+		for(const auto& x : m_MDM->Xpos) {
+			if(x > -20 && x < 20) {
+				++nnn;	ybar += x;
+			}
+		}
+		ybar /= nnn;
+
+		double SStot = 0, SSres = 0;
+		for(int i=0; i< 4; ++i) {
+			size_t iDet = m_MDM->DetectorNumber[i];
+			if(iDet > 3) { continue; }
+
+			double X = m_MDM->Xpos[i];				
+			double F = m_MDM->Fit_Xpos[iDet];
+
+			if(X > -20 && X < 20) {
+				SStot += pow(X - ybar, 2);
+				SSres += pow(X - F, 2);
+			}
+		}
+
+		double r2 = 1 - (SSres/SStot);
+		return -r2;
+	}
+
+	unsigned int NDim() const { return 1; }
+};
+
+
+#endif
diff --git a/NPLib/Detectors/MDM/TMDMData.cxx b/NPLib/Detectors/MDM/TMDMData.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b43984f745806780e502624907ddbdb90065eb0b
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMData.cxx
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu                        *
+ *                                                                           *
+ * Creation Date  : October 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold MDM Raw data                                    *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+#include "TMDMData.h"
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+using namespace std; 
+
+ClassImp(TMDMData)
+
+
+//////////////////////////////////////////////////////////////////////
+TMDMData::TMDMData() {
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+TMDMData::~TMDMData() {
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+void TMDMData::Clear() {
+  fMDM_DetectorNbr.clear();
+  // X
+  fMDM_Xpos.clear();
+  // Y
+  fMDM_Ypos.clear();
+	// ID
+	fMDM_Particle_Mass.clear();
+	fMDM_Particle_Charge.clear();
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+void TMDMData::Dump() const {
+  // This method is very useful for debuging and worth the dev.
+  cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TMDMData::Dump()] XXXXXXXXXXXXXXXXX" << endl;
+
+  // X - position
+  size_t mysize = fMDM_DetectorNbr.size();
+  cout << "MDM_Mult: " << mysize << endl;
+ 
+  for (size_t i = 0 ; i < mysize ; i++){
+    cout << "DetNbr: " << fMDM_DetectorNbr[i]
+         << ", X position: " << fMDM_Xpos[i]
+         << ", Y position: " << fMDM_Ypos[i]
+				 << ", Particle Mass: " << fMDM_Particle_Mass[i]
+				 << ", Particle Charge: " << fMDM_Particle_Charge[i] << endl;
+	}
+}
diff --git a/NPLib/Detectors/MDM/TMDMData.h b/NPLib/Detectors/MDM/TMDMData.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3669fc829a9df1a853bb60c9f0ea5a0b37c14ee
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMData.h
@@ -0,0 +1,105 @@
+#ifndef __MDMDATA__
+#define __MDMDATA__
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu                        *
+ *                                                                           *
+ * Creation Date  : October 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold MDM Raw data                                    *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+// STL
+#include <vector>
+using namespace std;
+
+// ROOT
+#include "TObject.h"
+
+class TMDMData : public TObject {
+  //////////////////////////////////////////////////////////////
+  // data members are hold into vectors in order 
+  // to allow multiplicity treatment
+  private:
+	  // Detector Number
+    vector<UShort_t>   fMDM_DetectorNbr;
+
+    // X - position
+    vector<Double_t>   fMDM_Xpos;
+
+    // Y - position
+    vector<Double_t>   fMDM_Ypos;
+
+		// Particle ID
+		vector<UShort_t>   fMDM_Particle_Charge;
+		vector<Double_t>   fMDM_Particle_Mass;
+		
+
+  //////////////////////////////////////////////////////////////
+  // Constructor and destructor
+  public: 
+    TMDMData();
+    ~TMDMData();
+    
+
+  //////////////////////////////////////////////////////////////
+  // Inherited from TObject and overriden to avoid warnings
+  public:
+    void Clear();
+    void Clear(const Option_t*) {};
+    void Dump() const;
+
+
+  //////////////////////////////////////////////////////////////
+  // Getters and Setters
+  // Prefer inline declaration to avoid unnecessary called of 
+  // frequently used methods
+  // add //! to avoid ROOT creating dictionnary for the methods
+  public:
+    //////////////////////    SETTERS    ////////////////////////
+    //
+		inline void SetHit(UShort_t DetNbr, Double_t x, Double_t y, UShort_t charge, Double_t mass){
+      fMDM_DetectorNbr.push_back(DetNbr);
+      fMDM_Xpos.push_back(x);
+      fMDM_Ypos.push_back(y);
+			fMDM_Particle_Mass.push_back(mass);
+			fMDM_Particle_Charge.push_back(charge);
+    };//!
+
+
+    //////////////////////    GETTERS    ////////////////////////
+    inline UShort_t GetMult() const
+      {return fMDM_DetectorNbr.size();}
+    inline UShort_t GetDetectorNbr(const unsigned int &i) const 
+      {return fMDM_DetectorNbr[i];}//!
+    // X - position
+    inline Double_t Get_Xpos(const unsigned int &i) const 
+      {return fMDM_Xpos[i];}//!
+		// Y - position
+    inline Double_t Get_Ypos(const unsigned int &i) const 
+      {return fMDM_Ypos[i];}//!
+		// Particle ID
+		inline Double_t GetParticleMass(const unsigned int& i) const
+		  {return fMDM_Particle_Mass[i];}//!
+		inline UShort_t GetParticleCharge(const unsigned int& i) const
+		  {return fMDM_Particle_Charge[i];}//!
+		
+  //////////////////////////////////////////////////////////////
+  // Required for ROOT dictionnary
+  ClassDef(TMDMData,2)  // MDMData structure
+};
+
+#endif
diff --git a/NPLib/Detectors/MDM/TMDMPhysics.cxx b/NPLib/Detectors/MDM/TMDMPhysics.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1e21b623c457f3835e8dda9897e9d26e18cb92dd
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMPhysics.cxx
@@ -0,0 +1,600 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu     *
+ *                                                                           *
+ * Creation Date  : October 2017                                             *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold MDM Treated  data                                        *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+#include "TMDMPhysics.h"
+
+//   STL
+#include <sstream>
+#include <iostream>
+#include <cmath>
+#include <stdlib.h>
+#include <limits>
+#include <cassert>
+#include <memory>
+using namespace std;
+
+//   NPL
+#include "RootInput.h"
+#include "RootOutput.h"
+#include "NPDetectorFactory.h"
+#include "NPOptionManager.h"
+#include "NPSystemOfUnits.h"
+
+//   ROOT
+#include "TF1.h"
+#include "TMath.h"
+#include "TChain.h"
+#include "TGraph.h"
+#include "TROOT.h"
+#include "TVector3.h"
+#include "Math/Minimizer.h"
+#include "Math/Factory.h"
+#include "Math/Functor.h"
+
+
+ClassImp(TMDMPhysics)
+
+namespace {
+
+const double ZPOS_[4] = { 2.0, 17.1, 33.4, 49.7 }; // cm
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+TMDMPhysics::TMDMPhysics()
+: m_EventData(new TMDMData),
+	m_PreTreatedData(new TMDMData),
+	m_EventPhysics(this),
+	m_Spectra(0),
+	m_X_Threshold(1000000), // junk value
+	m_Y_Threshold(1000000), // junk value
+	m_NumberOfDetectors(0) {
+
+	m_Rayin = 0;
+	m_ParticleA = 0;
+	m_ParticleZ = 0;
+	m_ParticleQ = 0;
+	m_Particle = 0;
+	m_Reaction = 0;
+	m_Ex4 = 0;
+	m_Ex3 = 0;
+	SetLightParticleAngles(0,0);
+
+	m_DoMinimization       = false;
+	m_MinimizerName        = "Minuit";
+	m_MinimizerAlgorithm   = "";
+	m_MinimizerPluginFile  = "";
+	m_MinimizerPluginClass = "";
+	m_MinimizerFunction    =  0;
+
+	double m_Xlow  = -15;
+	double m_Ylow  = -15;
+	double m_Xhigh = +15;
+	double m_Yhigh = +15;
+}
+
+///////////////////////////////////////////////////////////////////////////
+TMDMPhysics::~TMDMPhysics(){
+//	if(m_Rayin) { delete m_Rayin; m_Rayin = 0; }
+	if(m_Particle) { delete m_Particle; m_Particle = 0; }
+	if(m_Reaction) { delete m_Reaction; m_Reaction = 0; }
+}
+
+///////////////////////////////////////////////////////////////////////////
+/// A usefull method to bundle all operation to add a detector
+void TMDMPhysics::AddDetector(double angle, double field, const std::string& rayin){
+  // In That simple case nothing is done
+  // Typically for more complex detector one would calculate the relevant 
+  // positions (stripped silicon) or angles (gamma array)
+
+	m_Angle = angle;
+	m_Field = field;
+	m_Rayin = new MDMTrace::Rayin(rayin, false);
+	m_Trace = MDMTrace::Instance();
+	m_Trace->SetMDMAngle(angle/NPUNITS::mrad);  // mrad
+  m_Trace->SetMDMDipoleField(field/NPUNITS::gauss); // gauss
+	
+  m_NumberOfDetectors++;
+} 
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::BuildSimplePhysicalEvent() {
+  BuildPhysicalEvent();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::BuildPhysicalEvent() {
+  // apply thresholds and calibration
+  PreTreat();
+
+  // match x and y
+  UInt_t mysize = m_PreTreatedData->GetMult();
+	UInt_t i0=-1, i1=-1;
+  for (UShort_t ix = 0; ix < mysize ; ix++) {
+    for (UShort_t iy = 0; iy < mysize ; iy++) {
+      if (m_PreTreatedData->GetDetectorNbr(ix) == m_PreTreatedData->GetDetectorNbr(iy)) {
+				int detno = m_PreTreatedData->GetDetectorNbr(ix);
+
+				if(detno >= 0 && detno < 4) {
+					DetectorNumber.push_back(detno);
+					Xpos.push_back(m_PreTreatedData->Get_Xpos(ix));
+					Ypos.push_back(m_PreTreatedData->Get_Ypos(iy));
+					Zpos.push_back(ZPOS_[detno]);
+				}
+						
+				if(detno == 0) { i0 = ix; }
+				if(detno == 1) { i1 = ix; }
+      }
+    }
+  }
+
+	// calculate angles from first 2 wires
+	if(i0!=-1 && i1!=-1) {
+		Xang = atan((Xpos[i1] - Xpos[i0]) / (Zpos[i1] - Zpos[i0]));
+		Yang = atan((Ypos[i1] - Ypos[i0]) / (Zpos[i1] - Zpos[i0]));
+	}
+
+	// do minimization
+	MinimizeTarget();
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::PreTreat() {
+  // This method typically applies thresholds and calibrations
+  // Might test for disabled channels for more complex detector
+
+  // clear pre-treated object
+  ClearPreTreatedData();
+
+  // instantiate CalibrationManager
+  static CalibrationManager* Cal = CalibrationManager::getInstance();
+
+  UInt_t mysize = m_EventData->GetMult();
+  for (UShort_t i = 0; i < mysize ; ++i) {
+    if (m_EventData->Get_Xpos(i) < m_X_Threshold && m_EventData->Get_Ypos(i) < m_Y_Threshold) {
+      Double_t Xpos = Cal->ApplyCalibration("MDM/XPOS"+NPL::itoa(m_EventData->GetDetectorNbr(i)),m_EventData->Get_Xpos(i));
+      Double_t Ypos = Cal->ApplyCalibration("MDM/YPOS"+NPL::itoa(m_EventData->GetDetectorNbr(i)),m_EventData->Get_Ypos(i));
+			Double_t Mass = m_EventData->GetParticleMass(i);
+			UShort_t Charge = m_EventData->GetParticleCharge(i);
+      if (true) {
+				m_PreTreatedData->SetHit(m_EventData->GetDetectorNbr(i), Xpos, Ypos, Charge, Mass);
+      }
+		}
+  }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::ReadAnalysisConfig() {
+  bool ReadingStatus = false;
+
+  // path to file
+  string FileName = "./configs/ConfigMDM.dat";
+
+  // open analysis config file
+  ifstream AnalysisConfigFile;
+  AnalysisConfigFile.open(FileName.c_str());
+
+  if (!AnalysisConfigFile.is_open()) {
+    cout << " No ConfigMDM.dat found: Default parameter loaded for Analayis " << FileName << endl;
+    return;
+  }
+  cout << " Loading user parameter for Analysis from ConfigMDM.dat " << endl;
+
+  // Save it in a TAsciiFile
+  TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig();
+  asciiConfig->AppendLine("%%% ConfigMDM.dat %%%");
+  asciiConfig->Append(FileName.c_str());
+  asciiConfig->AppendLine("");
+  // read analysis config file
+  string LineBuffer,DataBuffer,whatToDo;
+	bool haveQ = false;
+  while (!AnalysisConfigFile.eof()) {
+    // Pick-up next line
+    getline(AnalysisConfigFile, LineBuffer);
+
+    // search for "header"
+    string name = "ConfigMDM";
+    if (LineBuffer.compare(0, name.length(), name) == 0) 
+      ReadingStatus = true;
+
+		cout << "Reading " << FileName << "...\n";
+    // loop on tokens and data
+    while (ReadingStatus ) {
+      whatToDo="";
+      AnalysisConfigFile >> whatToDo;
+
+      // Search for comment symbol (%)
+      if (whatToDo.compare(0, 1, "%") == 0) {
+        AnalysisConfigFile.ignore(numeric_limits<streamsize>::max(), '\n' );
+      }
+
+      else if (whatToDo=="X_THRESHOLD") {
+        AnalysisConfigFile >> DataBuffer;
+        m_X_Threshold = atof(DataBuffer.c_str());
+        cout << "\t" << whatToDo << " " << m_X_Threshold << endl;
+      }
+
+      else if (whatToDo=="Y_THRESHOLD") {
+        AnalysisConfigFile >> DataBuffer;
+        m_Y_Threshold = atof(DataBuffer.c_str());
+        cout << "\t" << whatToDo << " " << m_Y_Threshold << endl;
+      }
+
+			else if (whatToDo=="X_LOW") {
+        AnalysisConfigFile >> DataBuffer;
+        m_Xlow = atof(DataBuffer.c_str());
+        cout << "\t" << whatToDo << " " << m_Xlow << endl;
+      }
+
+			else if (whatToDo=="X_HIGH") {
+        AnalysisConfigFile >> DataBuffer;
+        m_Xhigh = atof(DataBuffer.c_str());
+        cout << "\t" << whatToDo << " " << m_Xhigh << endl;
+      }
+
+			else if (whatToDo=="Y_LOW") {
+        AnalysisConfigFile >> DataBuffer;
+        m_Ylow = atof(DataBuffer.c_str());
+        cout << "\t" << whatToDo << " " << m_Ylow << endl;
+      }
+
+			else if (whatToDo=="Y_HIGH") {
+        AnalysisConfigFile >> DataBuffer;
+        m_Yhigh = atof(DataBuffer.c_str());
+        cout << "\t" << whatToDo << " " << m_Yhigh << endl;
+      }
+
+			else if (whatToDo=="MINIMIZER_PLUGIN_FILE") {
+				AnalysisConfigFile >> DataBuffer;
+				m_MinimizerPluginFile  = DataBuffer;
+				cout << "\t" << whatToDo << " " << m_MinimizerPluginFile << endl;
+			}
+
+			else if (whatToDo=="MINIMIZER_PLUGIN_CLASS") {
+				AnalysisConfigFile >> DataBuffer;
+				m_MinimizerPluginClass  = DataBuffer;
+				cout << "\t" << whatToDo << " " << m_MinimizerPluginClass << endl;
+			}
+
+			else if (whatToDo=="DO_MINIMIZATION") {
+				AnalysisConfigFile >> DataBuffer;
+				m_DoMinimization = DataBuffer == "true" ? true :
+					DataBuffer == "false" ? false : atoi(DataBuffer.c_str());
+				cout << "\t" << whatToDo << " " << m_DoMinimization << endl;
+			}
+
+			else if (whatToDo=="MINIMIZER_NAME") {
+				AnalysisConfigFile >> DataBuffer;
+				m_MinimizerName  = DataBuffer;
+				cout << "\t" << whatToDo << " " << m_MinimizerName << endl;
+			}
+
+			else if (whatToDo=="MINIMIZER_ALGORITHM") {
+				AnalysisConfigFile >> DataBuffer;
+				m_MinimizerAlgorithm  = DataBuffer;
+				cout << "\t" << whatToDo << " " << m_MinimizerAlgorithm << endl;
+			}
+
+			else if (whatToDo=="RECON_A") {
+				AnalysisConfigFile >> DataBuffer;
+				m_ParticleA = atoi(DataBuffer.c_str());
+				cout << "\t" << whatToDo << " " << m_ParticleA << endl;
+			}
+
+			else if (whatToDo=="RECON_Z") {
+				AnalysisConfigFile >> DataBuffer;
+				m_ParticleZ = atoi(DataBuffer.c_str());
+				cout << "\t" << whatToDo << " " << m_ParticleZ << endl;
+			}
+
+			else if (whatToDo=="RECON_Q") {
+				AnalysisConfigFile >> DataBuffer;
+				m_ParticleQ = atoi(DataBuffer.c_str());
+				haveQ = true;
+				cout << "\t" << whatToDo << " " << m_ParticleZ << endl;
+			}
+
+      else {
+        ReadingStatus = false;
+      }
+    }
+  }
+	if(!haveQ) { 
+		m_ParticleQ = m_ParticleZ;
+		cout << "\t" << "No RECON_Q found, setting particle Q = Z (fully stripped)\n";
+	}
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::Clear() {
+  DetectorNumber.clear();
+  Xpos.clear();
+  Ypos.clear();
+	Zpos.clear();
+	Xang = -1000;
+	Yang = -1000;
+	Target_Xang = -1000;
+	Target_Yang = -1000;
+	Target_Ekin = -1000;
+	Fit_Chi2    = -1000;
+	for(int i=0; i< 4; ++i) {
+		Fit_Xpos[i] = -1000;
+	}
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::ReadConfiguration(NPL::InputParser parser) {
+  vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("MDM");
+  if(NPOptionManager::getInstance()->GetVerboseLevel())
+    cout << "//// " << blocks.size() << " detectors found " << endl; 
+
+  vector<string> tokens = {"Angle","Field","Xaccept","Yaccept","Rayin"};
+
+  for(UInt_t i = 0 ; i < blocks.size() ; i++){
+		if(blocks[i]->HasTokenList(tokens)){
+      if(NPOptionManager::getInstance()->GetVerboseLevel())
+        cout << endl << "////  MDM " << i+1 <<  endl;
+      double Angle = blocks[i]->GetDouble("Angle","deg");
+			double Field = blocks[i]->GetDouble("Field","gauss");
+      double XA    = blocks[i]->GetDouble("XAccept","deg");
+      double YA    = blocks[i]->GetDouble("YAccept","deg");
+      string Rayin = blocks[i]->GetString("Rayin");
+      AddDetector(Angle,Field,Rayin);
+    }
+    else{
+      cout << "ERROR: check your input file formatting " << endl;
+      exit(1);
+    }
+  }
+
+	// Read analysis config file & initialize relavant variables
+  ReadAnalysisConfig();
+	
+	m_Particle = new NPL::Nucleus(m_ParticleZ, m_ParticleA);
+
+	if(DoMinimization()) {
+		gROOT->ProcessLine(Form(".L %s+", m_MinimizerPluginFile.c_str()));
+		m_MinimizerFunction = reinterpret_cast<TMDMPhysicsMinimizer*>(
+			gROOT->ProcessLineFast( 
+				Form("new %s((TMDMPhysics*)%p);",
+						 m_MinimizerPluginClass.c_str(),
+						 this)
+				));
+		if(!m_MinimizerFunction) {
+			cerr << "ERROR: Invalid minimizer plugin file or class name.\n" <<
+				"\tFile: "  << m_MinimizerPluginFile << "\n" <<
+				"\tClass: " << m_MinimizerPluginClass << "\n";
+			exit(1);
+		}
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::InitSpectra() {
+  m_Spectra = new TMDMSpectra(m_NumberOfDetectors);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::FillSpectra() {
+  m_Spectra -> FillRawSpectra(m_EventData);
+  m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData);
+  m_Spectra -> FillPhysicsSpectra(m_EventPhysics);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::CheckSpectra() {
+  m_Spectra->CheckSpectra();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::ClearSpectra() {
+  // To be done
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+map< string , TH1*> TMDMPhysics::GetSpectra() {
+  if(m_Spectra)
+    return m_Spectra->GetMapHisto();
+  else{
+    map< string , TH1*> empty;
+    return empty;
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::WriteSpectra() {
+  m_Spectra->WriteSpectra();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::AddParameterToCalibrationManager() {
+  CalibrationManager* Cal = CalibrationManager::getInstance();
+  for (int i = 0; i < m_NumberOfDetectors; ++i) {
+    Cal->AddParameter("MDM", "D"+ NPL::itoa(i+1)+"_ENERGY","MDM_D"+ NPL::itoa(i+1)+"_ENERGY");
+    Cal->AddParameter("MDM", "D"+ NPL::itoa(i+1)+"_TIME","MDM_D"+ NPL::itoa(i+1)+"_TIME");
+  }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::InitializeRootInputRaw() {
+  TChain* inputChain = RootInput::getInstance()->GetChain();
+  inputChain->SetBranchStatus("MDM",  true );
+  inputChain->SetBranchAddress("MDM", &m_EventData );
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::InitializeRootInputPhysics() {
+  TChain* inputChain = RootInput::getInstance()->GetChain();
+  inputChain->SetBranchAddress("MDM", &m_EventPhysics);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::InitializeRootOutput() {
+  TTree* outputTree = RootOutput::getInstance()->GetTree();
+  outputTree->Branch("MDM", "TMDMPhysics", &m_EventPhysics);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+void TMDMPhysics::SendRay(double thetaX,double thetaY,double Ekin) const {
+  // send ray through mdm and read wires x, y, and theta_x, theta_y
+	// n.b. const due to requirements of ROOT::Math::IMultiGenFinction
+	// but it needs to change internal variables (Fit_***), so these are
+	// made muitable in their definition
+	//
+	// Note:: All inputs/outputs in RADIANS. Converted to degrees here
+	// as required by MDMTrace, and then back to radians for the outputs
+	//
+	m_Trace->SetScatteredMass(GetParticle()->Mass()/amu_c2); // AMU
+	m_Trace->SetScatteredCharge(GetParticleQ());
+	m_Trace->SetScatteredAngle(thetaX/deg, thetaY/deg); // deg (converted)
+	m_Trace->SetScatteredEnergy(Ekin/MeV); // MeV
+			
+	m_Trace->SendRay();
+	m_Trace-> // angles in degrees here
+		GetOxfordWirePositions(Fit_AngleX,Fit_Xpos[0],Fit_Xpos[1],Fit_Xpos[2],Fit_Xpos[3],
+													 Fit_AngleY,Fit_Ypos[0],Fit_Ypos[1],Fit_Ypos[2],Fit_Ypos[3]);
+	// convert to radians
+	Fit_AngleX = Fit_AngleX*deg;
+	Fit_AngleY = Fit_AngleY*deg;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//            Construct Method to be pass to the DetectorFactory              //
+////////////////////////////////////////////////////////////////////////////////
+NPL::VDetector* TMDMPhysics::Construct() {
+  return (NPL::VDetector*) new TMDMPhysics();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//            Registering the construct method to the factory                 //
+////////////////////////////////////////////////////////////////////////////////
+extern "C"{
+class proxy_MDM{
+public:
+	proxy_MDM(){
+		NPL::DetectorFactory::getInstance()->AddToken("MDM","MDM");
+		NPL::DetectorFactory::getInstance()->AddDetector("MDM",TMDMPhysics::Construct);
+	}
+};
+
+proxy_MDM p_MDM;
+}
+
+
+void TMDMPhysics::MinimizeTarget(){
+	//
+	// check if we do the minimization
+	if(DoMinimization() == false) { 
+		return; 
+	}
+	// Set up minimizer
+	std::unique_ptr<ROOT::Math::Minimizer> min(
+		ROOT::Math::Factory::CreateMinimizer(
+			m_MinimizerName, m_MinimizerAlgorithm.c_str()
+			)
+		);
+	InitializeMinimizerWithDefaults(*min);
+	min->SetFunction(*m_MinimizerFunction);
+
+	// Set Initial parameters
+	// Note: everything in RADIANS, conversion to deg for MDMTrace
+	// happens in SendRay()
+	int ivar = 0;
+	m_MinimizerFunction->Initialize();
+	if(m_MinimizerFunction->GetFixedThetaX() == false) {
+		min->SetVariable(ivar++, "thetax", m_MinimizerFunction->GetInitialThetaX(), 0.01);
+	}
+	if(m_MinimizerFunction->GetFixedThetaY() == false) {
+		min->SetVariable(ivar++, "thetay", m_MinimizerFunction->GetInitialThetaY(), 0.01);
+	}
+	if(m_MinimizerFunction->GetFixedEkin() == false) {
+		min->SetVariable(ivar++, "ekin",   m_MinimizerFunction->GetInitialEkin(),   0.01);
+	}
+
+	// Do minimization
+	min->Minimize();
+
+	// Set outputs
+	// Output angles are in radians
+	// If using the initial angle, it's radians already
+	// If using the minimized angle, it's 
+	ivar = 0;
+	if(m_MinimizerFunction->GetFixedThetaX()) {
+		Target_Xang = m_MinimizerFunction->GetInitialThetaX();
+	}	else {
+		Target_Xang = min->X()[ivar++];
+	}
+	if(m_MinimizerFunction->GetFixedThetaY()) {
+		Target_Yang = m_MinimizerFunction->GetInitialThetaY();
+	}	else {
+		Target_Yang = min->X()[ivar++];
+	}
+	if(m_MinimizerFunction->GetFixedEkin()) {
+		Target_Ekin = m_MinimizerFunction->GetInitialEkin();
+	}	else {
+		Target_Ekin = min->X()[ivar++];
+	}
+
+	Fit_Chi2 = m_MinimizerFunction->operator()(min->X());
+}
+
+
+void TMDMPhysics::InitializeMinimizerWithDefaults(ROOT::Math::Minimizer& min){
+	min.SetMaxFunctionCalls(1000);
+	min.SetMaxIterations(1000);
+	min.SetTolerance(0.001);
+}
+
+double TMDMPhysics::CalculateCentralEnergy(){
+	double brho = (m_Field/tesla)*1.6; // tesla*meter
+	m_Particle->SetBrho(brho);
+	m_Particle->BrhoToEnergy(m_ParticleQ); // charge state
+	return m_Particle->GetEnergy()/MeV;
+}
diff --git a/NPLib/Detectors/MDM/TMDMPhysics.h b/NPLib/Detectors/MDM/TMDMPhysics.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c8d92545123a1a19a605695742c7cb5f5dd7e5a
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMPhysics.h
@@ -0,0 +1,272 @@
+#ifndef TMDMPHYSICS_H
+#define TMDMPHYSICS_H
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu                        *
+ *                                                                           *
+ * Creation Date  : October 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold MDM Treated data                                *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+// C++ headers 
+#include <vector>
+#include <map>
+#include <string>
+
+// ROOT headers
+#include "TObject.h"
+#include "TH1.h"
+#include "TVector3.h"
+// NPTool headers
+#include "TMDMData.h"
+#include "TMDMSpectra.h"
+#include "NPCalibrationManager.h"
+#include "NPVDetector.h"
+#include "NPInputParser.h"
+#include "NPNucleus.h"
+#include "NPReaction.h"
+// MDM Trace
+#include "MDMTrace.h"
+#include "TMDMPhysicsMinimizer.h"
+
+// forward declaration
+class TMDMSpectra;
+namespace ROOT { namespace Math { class Minimizer; } }
+
+class TMDMPhysics : public TObject, public NPL::VDetector {
+  //////////////////////////////////////////////////////////////
+  // constructor and destructor
+public:
+	TMDMPhysics();
+	~TMDMPhysics();
+
+
+  //////////////////////////////////////////////////////////////
+  // Inherited from TObject and overriden to avoid warnings
+public: 
+	void Clear();   
+	void Clear(const Option_t*) {};
+
+
+  //////////////////////////////////////////////////////////////
+  // data obtained after BuildPhysicalEvent() and stored in
+  // output ROOT file
+public:
+	std::vector<int>      DetectorNumber;
+	std::vector<double>   Xpos; // cm
+	std::vector<double>   Ypos; // cm
+	std::vector<double>   Zpos; // cm
+	double                Xang; // deg
+	double                Yang; // deg
+	double                Target_Xang;
+	double                Target_Yang;
+	double                Target_Ekin;
+	double                Fit_Chi2;
+	mutable double        Fit_Xpos[4];
+	mutable double        Fit_Ypos[4];
+	mutable double        Fit_AngleX;
+	mutable double        Fit_AngleY;
+	
+private:
+	int m_ParticleA; //!
+	int m_ParticleZ; //!
+	int m_ParticleQ; //!
+	NPL::Nucleus* m_Particle; //!
+	double m_Angle; //!
+	double m_Field; //!
+	MDMTrace::Rayin* m_Rayin; //!
+	MDMTrace* m_Trace; //!
+
+	// reaction / light particle stuff
+	double m_Light_ThetaLab;   //!
+	double m_Light_PhiLab;     //!
+	NPL::Reaction* m_Reaction; //!
+	Double_t m_Ex4; //!
+	Double_t m_Ex3; //!
+	
+public:
+
+	double GetAngle() { return m_Angle; }
+	double GetField() { return m_Field; }
+	double GetParticleQ()  const { return m_ParticleQ; }
+	NPL::Nucleus* GetParticle() const { return m_Particle;  } 
+	MDMTrace* GetTrace() { return m_Trace; }
+	NPL::Reaction* GetReaction() const { return m_Reaction; }
+	double GetEx4()  const { return m_Ex4; }
+	double GetEx3()  const { return m_Ex3; }
+	void   SetEx4(double ex) { m_Ex4 = ex; }
+	void   SetEx3(double ex) { m_Ex3 = ex; }
+	
+	void SetReaction(NPL::Reaction* r) {m_Reaction= new NPL::Reaction(*r);}
+	void SetLightParticleAngles(double theta,double phi)
+		{ m_Light_ThetaLab=theta; m_Light_PhiLab=phi; }
+	void GetLightParticleAngles(double& t, double& p)
+		{ t = m_Light_ThetaLab; p = m_Light_PhiLab; }
+	
+  /// A usefull method to bundle all operation to add a detector
+	void AddDetector(double angle, double field, const std::string& rayin);
+  
+  //////////////////////////////////////////////////////////////
+  // methods inherited from the VDetector ABC class
+public:
+	// read stream from ConfigFile to pick-up detector parameters
+	void ReadConfiguration(NPL::InputParser);
+
+	// add parameters to the CalibrationManger
+	void AddParameterToCalibrationManager();
+
+	// method called event by event, aiming at extracting the 
+	// physical information from detector
+	void BuildPhysicalEvent();
+
+	// same as BuildPhysicalEvent() method but with a simpler
+	// treatment
+	void BuildSimplePhysicalEvent();
+
+	// same as above but for online analysis
+	void BuildOnlinePhysicalEvent()  {BuildPhysicalEvent();};
+
+	// activate raw data object and branches from input TChain
+	// in this method mother branches (Detector) AND daughter leaves 
+	// (fDetector_parameter) have to be activated
+	void InitializeRootInputRaw();
+
+	// activate physics data object and branches from input TChain
+	// in this method mother branches (Detector) AND daughter leaves 
+	// (fDetector_parameter) have to be activated
+	void InitializeRootInputPhysics();
+
+	// create branches of output ROOT file
+	void InitializeRootOutput();
+
+	// clear the raw and physical data objects event by event
+	void ClearEventPhysics() {Clear();}      
+	void ClearEventData()    {m_EventData->Clear();}   
+
+	// methods related to the TMDMSpectra class
+	// instantiate the TMDMSpectra class and 
+	// declare list of histograms
+	void InitSpectra();
+
+	// fill the spectra
+	void FillSpectra();
+
+	// used for Online mainly, sanity check for histograms and 
+	// change their color if issues are found, for example
+	void CheckSpectra();
+
+	// used for Online only, clear all the spectra
+	void ClearSpectra();
+
+	// write spectra to ROOT output file
+	void WriteSpectra();
+
+
+  //////////////////////////////////////////////////////////////
+  // specific methods to MDM array
+public:
+	// remove bad channels, calibrate the data and apply thresholds
+	void PreTreat();
+
+	// clear the pre-treated object
+	void ClearPreTreatedData()   {m_PreTreatedData->Clear();}
+
+	// read the user configuration file. If no file is found, load standard one
+	void ReadAnalysisConfig();
+
+	// give and external TMDMData object to TMDMPhysics. 
+	// needed for online analysis for example
+	void SetRawDataPointer(void* rawDataPointer) {m_EventData = (TMDMData*)rawDataPointer;}
+
+	// do chi2 minimization to find most likely energy, angle parameters @target
+	void MinimizeTarget();
+
+	// send ray through MDM using RAYTRACE
+	// UNITS: deg, MeV
+	void SendRay(double thetaX, double thetaY, double Ekin) const;
+
+// Minimization options & helpers
+	double CalculateCentralEnergy();
+	void   InitializeMinimizerWithDefaults(ROOT::Math::Minimizer& min);
+
+private:
+	TMDMPhysicsMinimizer* m_MinimizerFunction; //!
+	std::string m_MinimizerPluginFile;  //!
+	std::string m_MinimizerPluginClass; //!
+	std::string m_MinimizerName; //!
+	std::string m_MinimizerAlgorithm; //!
+	bool m_DoMinimization; //!
+
+public:
+	TMDMPhysicsMinimizer* GetMinimizerFunction() const { return m_MinimizerFunction;    }
+	std::string GetMinimizerPluginFile()  const        { return m_MinimizerPluginFile;  }
+	std::string GetMinimizerPluginClass() const        { return m_MinimizerPluginClass; }
+	std::string GetMinimizerName() const               { return m_MinimizerName;        }
+	std::string GetAlgorithmName() const               { return m_MinimizerAlgorithm;   }
+	bool DoMinimization() const                        { return m_DoMinimization;       }		
+	
+  // objects are not written in the TTree
+private:
+	TMDMData*         m_EventData;        //!
+	TMDMData*         m_PreTreatedData;   //!
+	TMDMPhysics*      m_EventPhysics;     //!
+
+  // getters for raw and pre-treated data object
+public:
+	TMDMData* GetRawData()        const {return m_EventData;}
+	TMDMData* GetPreTreatedData() const {return m_PreTreatedData;}
+
+  // parameters used in the analysis
+private:
+	// thresholds
+	double m_X_Threshold;     //!
+	double m_Y_Threshold;     //!
+	double m_Xlow;  //!
+	double m_Ylow;  //!
+	double m_Xhigh; //!
+	double m_Yhigh; //!
+
+public:
+	double GetXlow()  const { return m_Xlow;  }
+	double GetYlow()  const { return m_Ylow;  }
+	double GetXhigh() const { return m_Xhigh; }
+	double GetYhigh() const { return m_Yhigh; }
+	
+  // number of detectors
+private:
+	int m_NumberOfDetectors;  //!
+
+  // spectra class
+private:
+	TMDMSpectra* m_Spectra; // !
+
+  // spectra getter
+public:
+	std::map<std::string, TH1*>   GetSpectra(); 
+
+  // Static constructor to be passed to the Detector Factory
+public:
+	static NPL::VDetector* Construct();
+
+	ClassDef(TMDMPhysics,2)  // MDMPhysics structure
+};
+#endif
+
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/NPLib/Detectors/MDM/TMDMPhysicsMinimizer.cxx b/NPLib/Detectors/MDM/TMDMPhysicsMinimizer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3e8d720e629ef7bc6e16ac92deccf33fcf22a75d
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMPhysicsMinimizer.cxx
@@ -0,0 +1,19 @@
+#include "TMDMPhysicsMinimizer.h"
+
+
+TMDMPhysicsMinimizer::TMDMPhysicsMinimizer(unsigned int ndim, 
+																					 TMDMPhysics* mdm):
+	m_NDim(ndim), 
+	m_MDM(mdm),
+	m_FixedThetaX(true),
+	m_FixedThetaY(true),
+	m_FixedEkin(true),
+	m_InitialThetaX(0.),
+	m_InitialThetaY(0.),
+	m_InitialEkin(0.){
+}
+
+TMDMPhysicsMinimizer::~TMDMPhysicsMinimizer(){
+}
+
+
diff --git a/NPLib/Detectors/MDM/TMDMPhysicsMinimizer.h b/NPLib/Detectors/MDM/TMDMPhysicsMinimizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..12d8c8b0a615c899d84d5b5edc4e2f61a41d0e05
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMPhysicsMinimizer.h
@@ -0,0 +1,64 @@
+#ifndef HAVE_MDM_PHYS_MIN
+#define HAVE_MDM_PHYS_MIN
+
+// ROOT includes
+#include <vector>
+#include <utility>
+#include "Math/Functor.h"
+
+
+class TMDMPhysics;
+
+class TMDMPhysicsMinimizer : public ROOT::Math::IMultiGenFunction {
+protected:
+	TMDMPhysicsMinimizer(unsigned int ndim, TMDMPhysics* mdm);
+	
+public:
+	virtual unsigned int NDim() const { return m_NDim; }
+	virtual ~TMDMPhysicsMinimizer();	
+
+// Need to implement these	
+public:
+	// Clone the current class
+	virtual ROOT::Math::IMultiGenFunction* Clone() const = 0;
+	// Initialize input parameters to RAYTRACE
+	// Should set the m_Fixed<...> and m_Initial<...> values
+	// for each of theta x, theta y, ekin (at target location)
+	virtual void Initialize() = 0;
+// End to implement
+public:
+	bool   GetFixedThetaX()   { return m_FixedThetaX   ;}
+	bool   GetFixedThetaY()   { return m_FixedThetaY   ;}
+	bool   GetFixedEkin()     { return m_FixedEkin     ;}
+	double GetInitialThetaX() { return m_InitialThetaX ;}
+	double GetInitialThetaY() { return m_InitialThetaY ;}
+	double GetInitialEkin()   { return m_InitialEkin   ;}
+private:
+	// Define the function to minimize
+	// Parameters are length n input, where n is the number
+	// of free parameters, in the following order:
+	// [0] target x
+	// [1] target y
+	// [2] target ekin
+	//   Note this is a _rank ordering_ of non-fixed parameters.
+	//   For example if target y is fixed, then the order is:
+	//      x[0] = target x
+	//      x[1] = ekin
+	virtual double DoEval(const double* x) const = 0;
+	
+protected:
+	TMDMPhysics* m_MDM;
+	unsigned int m_NDim;
+	bool   m_FixedThetaX;
+	bool   m_FixedThetaY;
+	bool   m_FixedEkin;
+	double m_InitialThetaX;
+	double m_InitialThetaY;
+	double m_InitialEkin;
+};
+
+#endif
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/NPLib/Detectors/MDM/TMDMSpectra.cxx b/NPLib/Detectors/MDM/TMDMSpectra.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..872811a6d1c4e8174cafa94f4790c29ca032a58f
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMSpectra.cxx
@@ -0,0 +1,180 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu                        *
+ *                                                                           *
+ * Creation Date  : October 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold MDM Spectra                                     *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+// class header 
+#include "TMDMSpectra.h"
+
+// STL
+#include <iostream>  
+#include <string>
+using namespace std;
+
+// NPTool header
+#include "NPOptionManager.h"
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+TMDMSpectra::TMDMSpectra() 
+   : fNumberOfDetectors(0) {
+  SetName("MDM");
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+TMDMSpectra::TMDMSpectra(unsigned int NumberOfDetectors) {
+  if(NPOptionManager::getInstance()->GetVerboseLevel()>0)
+    cout << "************************************************" << endl
+      << "TMDMSpectra : Initalizing control spectra for " 
+      << NumberOfDetectors << " Detectors" << endl
+      << "************************************************" << endl ;
+  SetName("MDM");
+  fNumberOfDetectors = NumberOfDetectors;
+
+  InitRawSpectra();
+  InitPreTreatedSpectra();
+  InitPhysicsSpectra();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+TMDMSpectra::~TMDMSpectra() {
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TMDMSpectra::InitRawSpectra() {
+  static string name;
+  for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
+    // Energy 
+    name = "MDM"+NPL::itoa(i+1)+"_ENERGY_RAW";
+    AddHisto1D(name, name, 4096, 0, 16384, "MDM/RAW");
+    // Time 
+    name = "MDM"+NPL::itoa(i+1)+"_TIME_RAW";
+    AddHisto1D(name, name, 4096, 0, 16384, "MDM/RAW");
+  } // end loop on number of detectors
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TMDMSpectra::InitPreTreatedSpectra() {
+  static string name;
+  for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
+    // Energy 
+    name = "MDM"+NPL::itoa(i+1)+"_ENERGY_CAL";
+    AddHisto1D(name, name, 500, 0, 25, "MDM/CAL");
+    // Time
+    name = "MDM"+NPL::itoa(i+1)+"_TIME_CAL";
+    AddHisto1D(name, name, 500, 0, 25, "MDM/CAL");
+
+  
+  }  // end loop on number of detectors
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TMDMSpectra::InitPhysicsSpectra() {
+  static string name;
+  // Kinematic Plot 
+  name = "MDM_ENERGY_TIME";
+  AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "MDM/PHY");
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TMDMSpectra::FillRawSpectra(void* RawData) {
+# if 0
+  static string name;
+  static string family;
+
+  // Energy 
+  unsigned int sizeE = RawData->GetMultEnergy();
+  for (unsigned int i = 0; i < sizeE; i++) {
+    name = "MDM"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW";
+    family = "MDM/RAW";
+
+    FillSpectra(family,name,RawData->Get_Energy(i));
+  }
+
+  // Time
+  unsigned int sizeT = RawData->GetMultTime();
+  for (unsigned int i = 0; i < sizeT; i++) {
+    name = "MDM"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW";
+    family = "MDM/RAW";
+
+    FillSpectra(family,name,RawData->Get_Time(i));
+  }
+#endif
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TMDMSpectra::FillPreTreatedSpectra(void* PreTreatedData) {
+#if 0
+  static string name;
+  static string family;
+  
+  // Energy 
+  unsigned int sizeE = PreTreatedData->GetMultEnergy();
+  for (unsigned int i = 0; i < sizeE; i++) {
+    name = "MDM"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL";
+    family = "MDM/CAL";
+
+    FillSpectra(family,name,PreTreatedData->Get_Energy(i));
+  }
+
+  // Time
+  unsigned int sizeT = PreTreatedData->GetMultTime();
+  for (unsigned int i = 0; i < sizeT; i++) {
+    name = "MDM"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL";
+    family = "MDM/CAL";
+
+    FillSpectra(family,name,PreTreatedData->Get_Time(i));
+  }
+#endif
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void TMDMSpectra::FillPhysicsSpectra(void* Physics) {
+#if 0
+  static string name;
+  static string family;
+  family= "MDM/PHY";
+
+  // Energy vs time
+  unsigned int sizeE = Physics->Energy.size();
+  for(unsigned int i = 0 ; i < sizeE ; i++){
+    name = "MDM_ENERGY_TIME";
+    FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]);
+  }
+#endif
+}
+
diff --git a/NPLib/Detectors/MDM/TMDMSpectra.h b/NPLib/Detectors/MDM/TMDMSpectra.h
new file mode 100644
index 0000000000000000000000000000000000000000..4898de61c08030c630f99c7f739266da5a323c23
--- /dev/null
+++ b/NPLib/Detectors/MDM/TMDMSpectra.h
@@ -0,0 +1,62 @@
+#ifndef TMDMSPECTRA_H
+#define TMDMSPECTRA_H
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu                        *
+ *                                                                           *
+ * Creation Date  : October 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold MDM Spectra                                     *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+// NPLib headers
+#include "NPVSpectra.h"
+#include "TMDMData.h"
+#include "TMDMPhysics.h"
+
+// Forward Declaration
+class TMDMPhysics;
+
+
+class TMDMSpectra : public VSpectra {
+  //////////////////////////////////////////////////////////////
+  // constructor and destructor
+  public:
+    TMDMSpectra();
+    TMDMSpectra(unsigned int NumberOfDetectors);
+    ~TMDMSpectra();
+
+  //////////////////////////////////////////////////////////////
+  // Initialization methods
+  private:
+    void InitRawSpectra();
+    void InitPreTreatedSpectra();
+    void InitPhysicsSpectra();
+
+  //////////////////////////////////////////////////////////////
+  // Filling methods
+  public:
+    void FillRawSpectra(void*);
+    void FillPreTreatedSpectra(void*);
+    void FillPhysicsSpectra(void*);
+
+  //////////////////////////////////////////////////////////////
+  // Detector parameters 
+  private:
+    unsigned int fNumberOfDetectors;
+};
+
+#endif
diff --git a/NPLib/Detectors/ModularLeaf/CMakeLists.txt b/NPLib/Detectors/ModularLeaf/CMakeLists.txt
index 89ce7b70c9fa953accffc9695c6aaa0dcdab3f32..6a32ba0c2d498087542b9e429c5047ddb1fec192 100644
--- a/NPLib/Detectors/ModularLeaf/CMakeLists.txt
+++ b/NPLib/Detectors/ModularLeaf/CMakeLists.txt
@@ -1,4 +1,5 @@
-add_library(NPModularLeaf SHARED TModularLeafPhysics.cxx)
+add_custom_command(OUTPUT TModularLeafPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TModularLeafPhysics.h TModularLeafPhysicsDict.cxx TModularLeafPhysics.rootmap libNPModularLeaf.dylib DEPENDS TModularLeafPhysics.h)
+add_library(NPModularLeaf SHARED TModularLeafPhysics.cxx TModularLeafPhysicsDict.cxx)
 target_link_libraries(NPModularLeaf ${ROOT_LIBRARIES} NPCore) 
 install(FILES  TModularLeafPhysics.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY})
 
diff --git a/NPLib/Detectors/ModularLeaf/TModularLeafPhysics.cxx b/NPLib/Detectors/ModularLeaf/TModularLeafPhysics.cxx
index a482a896262b1e95e30c1ff4651ecbb6981c30e6..67d19448a310d0ba09523250b60186b009683c4d 100644
--- a/NPLib/Detectors/ModularLeaf/TModularLeafPhysics.cxx
+++ b/NPLib/Detectors/ModularLeaf/TModularLeafPhysics.cxx
@@ -176,6 +176,6 @@ class proxy_modularleaf{
     }
 };
 
-proxy_modularleaf p;
+proxy_modularleaf p_modularleaf;
 }
 
diff --git a/NPLib/Detectors/Tiara/TTiaraHyballPhysics.h b/NPLib/Detectors/Tiara/TTiaraHyballPhysics.h
index abcf2c1a6b88c306111910db48eb9a05dd466915..819a08b2e83dec6924f3c3676241fa5461894596 100644
--- a/NPLib/Detectors/Tiara/TTiaraHyballPhysics.h
+++ b/NPLib/Detectors/Tiara/TTiaraHyballPhysics.h
@@ -207,7 +207,7 @@ class TTiaraHyballPhysics : public TObject, public NPL::VDetector{
 
     public: // Static constructor to be passed to the Detector Factory
      static NPL::VDetector* Construct();
-     ClassDef(TTiaraHyballPhysics,1)  // SharcPhysics structure
+     ClassDef(TTiaraHyballPhysics,2)  // SharcPhysics structure
 };
 
 namespace TiaraHyball_LOCAL{
diff --git a/NPLib/Online/NPOnlineGUI.cxx b/NPLib/Online/NPOnlineGUI.cxx
index fe637c2419b2f541972759fc043069aff8a513b6..cbf86f7061c4961ec8d367b1348cb5fe9fa01f41 100644
--- a/NPLib/Online/NPOnlineGUI.cxx
+++ b/NPLib/Online/NPOnlineGUI.cxx
@@ -732,7 +732,7 @@ NPL::OnlineGUI::~OnlineGUI(){
 
 ////////////////////////////////////////////////////////////////////////////////
 void NPL::OnlineGUI::Connect(){
-  m_Client->SetAddressAndPort((string) m_Address->GetDisplayText(),(int) m_Port->GetNumber());
+  m_Client->SetAddressAndPort((string) m_Address->GetDisplayText().Data(),(int) m_Port->GetNumber());
   m_Client->Connect();
   m_CanvasListTree->LoadCanvasList(m_Client->GetSpectra());
 }
diff --git a/NPLib/Utility/npanalysis.cxx b/NPLib/Utility/npanalysis.cxx
index 061bfbb413cd0a1f3d65b64befe6c8deee6f8ae0..3863a46d53d44cf0973215ed2f9291a5dcdc8f71 100644
--- a/NPLib/Utility/npanalysis.cxx
+++ b/NPLib/Utility/npanalysis.cxx
@@ -102,10 +102,13 @@ int main(int argc , char** argv){
   std::cout << std::endl << "///////// Starting Analysis ///////// "<< std::endl;
   TChain* Chain = RootInput:: getInstance()->GetChain();
   myOptionManager->GetNumberOfEntryToAnalyse();
- 
+
+	unsigned long first_entry = myOptionManager->GetFirstEntryToAnalyse(); // defaults to zero
   unsigned long nentries = Chain->GetEntries();
   if(nentries> myOptionManager->GetNumberOfEntryToAnalyse() && myOptionManager->GetNumberOfEntryToAnalyse()>0)
-    nentries = myOptionManager->GetNumberOfEntryToAnalyse() ; 
+    nentries = myOptionManager->GetNumberOfEntryToAnalyse() ;
+	if(nentries + first_entry > Chain->GetEntries()) {nentries = first_entry+Chain->GetEntries();}
+	
 
   TString ChainName = Chain->GetName();
   std::cout << " Number of Event to be treated : " << nentries << " on chain " << ChainName << std::endl;
@@ -124,7 +127,7 @@ int main(int argc , char** argv){
 
   if(UserAnalysis==NULL){ 
     if(!IsPhysics){
-      for (unsigned int i = 0 ; i < nentries; i++) { 
+      for (unsigned long i = first_entry ; i < nentries + first_entry; i++) { 
         // Get the raw Data
         Chain -> GetEntry(i);
         // Build the current event
@@ -166,7 +169,7 @@ int main(int argc , char** argv){
 
   else{
     if(!IsPhysics){ 
-      for (unsigned int i = 0 ; i < nentries; i++) { 
+      for (unsigned long i = first_entry ; i < nentries + first_entry; i++) { 
         // Get the raw Data
 	//cout << "!" << endl;
         Chain -> GetEntry(i);
@@ -207,7 +210,7 @@ int main(int argc , char** argv){
     }
 
     else{
-      for (unsigned int i = 0 ; i < nentries; i++) { 
+			for (unsigned long i = first_entry ; i < nentries + first_entry; i++) { 
         // Get the Physics Data
         Chain -> GetEntry(i);
         // User Analysis
diff --git a/NPSimulation/Core/MaterialManager.cc b/NPSimulation/Core/MaterialManager.cc
index 18001280e75ca7c73b44deb8606f8e91d71ee02f..29bdcad13612925cf79e1a5af4412854b96b4ed7 100644
--- a/NPSimulation/Core/MaterialManager.cc
+++ b/NPSimulation/Core/MaterialManager.cc
@@ -295,30 +295,6 @@ G4Material* MaterialManager::GetMaterialFromLibrary(string Name,double density){
             m_Material[Name]=material;
             return material;
         }
-				else  if(Name == "He_gas"){
-            if(!density)
-							density = 0.0001665*g/cm3; // room temp, 1 atm
-            G4Material* material = new G4Material("NPS_"+Name, density,1);
-            material->AddElement(GetElementFromLibrary("He"),1);
-            m_Material[Name]=material;
-            return material;
-				}
-				else  if(Name == "O2_gas"){
-            if(!density)
-							density = 0.001331*g/cm3; // room temp, 1 atm
-            G4Material* material = new G4Material("NPS_"+Name, density,1);
-            material->AddElement(GetElementFromLibrary("O"),2);
-            m_Material[Name]=material;
-            return material;
-				}
-				else  if(Name == "Ti"){
-            if(!density)
-							density = 4.5189*g/cm3;
-            G4Material* material = new G4Material("NPS_"+Name, density,1);
-            material->AddElement(GetElementFromLibrary("Ti"),1);
-            m_Material[Name]=material;
-            return material;
-				}
          
         // Usual detector material
         else  if(Name == "Si"){
@@ -766,7 +742,10 @@ G4Material* MaterialManager::GetGasFromLibrary(string Name, double Pressure, dou
     string newName= oss.str();
     map<string,G4Material*>::iterator it;
     it = m_Material.find(Name);
-    double density = 0 ; 
+    double density = 0 ;
+    
+    G4double Vm=0.08206*Temperature*atmosphere/(Pressure*kelvin);
+    
     // The element is not found
     if(it==m_Material.end()){
         if(Name == "CF4"){ // 52 torr
@@ -780,7 +759,61 @@ G4Material* MaterialManager::GetGasFromLibrary(string Name, double Pressure, dou
             m_Material[Name]=material;
             return material;
         }
+
+        if(Name == "He"){
+            density =  (4.0026/Vm)*mg/cm3;
+            G4Material* material = new G4Material("NPS_"+newName,density,1,kStateGas,Temperature,Pressure);
+            material->AddElement(GetElementFromLibrary("He"), 1);
+            m_Material[Name]=material;
+            return material;
+        }
+        
+        if(Name == "iC4H10" || Name == "Isobutane" || Name == "isobutane"){
+            density	= ((4*12.0107+10*1.00794)/Vm)*mg/cm3;
+            G4Material* material = new G4Material("NPS_"+newName,density,2,kStateGas,Temperature,Pressure);
+            material->AddElement(GetElementFromLibrary("C"), 4);
+            material->AddElement(GetElementFromLibrary("H"), 10);
+            m_Material[Name]=material;
+            return material;
+        }
         
+        if(Name == "CH4"){
+            density	= ((12.0107+4*1.00794)/Vm)*mg/cm3;
+            G4Material* material = new G4Material("NPS_"+newName,density,2,kStateGas,Temperature,Pressure);
+            material->AddElement(GetElementFromLibrary("C"), 1);
+            material->AddElement(GetElementFromLibrary("H"), 4);
+            m_Material[Name]=material;
+            return material;
+        }
+
+        if(Name == "CO2"){
+            density	= ((12.0107+2*16)/Vm)*mg/cm3;
+            G4Material* material = new G4Material("NPS_"+newName,density,2,kStateGas,Temperature,Pressure);
+            material->AddElement(GetElementFromLibrary("C"), 1);
+            material->AddElement(GetElementFromLibrary("O"), 2);
+            m_Material[Name]=material;
+            return material;
+        }
+
+        if(Name == "H2"){
+            density	= (2*1.00794/Vm)*mg/cm3;
+            G4Material* material = new G4Material("NPS_"+newName,density,2,kStateGas,Temperature,Pressure);
+            material->AddElement(GetElementFromLibrary("H"), 1);
+            material->AddElement(GetElementFromLibrary("H"), 1);
+            m_Material[Name]=material;
+            return material;
+        }
+        
+        if(Name == "D2"){
+            density	= (2*2.0140/Vm)*mg/cm3;
+            G4Material* material = new G4Material("NPS_"+newName,density,2,kStateGas,Temperature,Pressure);
+            material->AddElement(GetElementFromLibrary("D"), 1);
+            material->AddElement(GetElementFromLibrary("D"), 1);
+            m_Material[Name]=material;
+            return material;
+        }
+        
+
         else{
           exit(1);
         }
diff --git a/NPSimulation/Detectors/Actar/Actar.cc b/NPSimulation/Detectors/Actar/Actar.cc
new file mode 100644
index 0000000000000000000000000000000000000000..741f247d34fc5ee8a031fd414568268824864a6c
--- /dev/null
+++ b/NPSimulation/Detectors/Actar/Actar.cc
@@ -0,0 +1,691 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class describe  Actar simulation                             *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *****************************************************************************/
+
+// C++ headers
+#include <sstream>
+#include <cmath>
+#include <limits>
+//G4 Geometry object
+#include "G4Tubs.hh"
+#include "G4Box.hh"
+
+//G4 sensitive
+#include "G4SDManager.hh"
+#include "G4MultiFunctionalDetector.hh"
+
+//G4 various object
+#include "G4Material.hh"
+#include "G4Transform3D.hh"
+#include "G4PVPlacement.hh"
+#include "G4VisAttributes.hh"
+#include "G4Colour.hh"
+
+// G4 Field
+#include "G4FieldManager.hh"
+#include "G4ElectricField.hh"
+#include "G4UniformElectricField.hh"
+#include "G4TransportationManager.hh"
+#include "G4EqMagElectricField.hh"
+#include "G4MagIntegratorStepper.hh"
+#include "G4ClassicalRK4.hh"
+#include "G4MagIntegratorDriver.hh"
+#include "G4ChordFinder.hh"
+#include "G4MaterialPropertiesTable.hh"
+
+// NPTool header
+#include "Actar.hh"
+#include "SiliconScorers.hh"
+#include "DriftElectronScorers.hh"
+#include "RootOutput.h"
+#include "MaterialManager.hh"
+#include "NPSDetectorFactory.hh"
+#include "NPOptionManager.h"
+#include "FastDriftElectron.hh"
+#include "NPSHitsMap.hh"
+#include "CalorimeterScorers.hh"
+
+
+// CLHEP header
+#include "CLHEP/Random/RandGauss.h"
+
+// ROOT
+#include "TH1D.h"
+#include "TF1.h"
+
+using namespace std;
+using namespace CLHEP;
+
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+namespace Actar_NS{
+    // Energy and time Resolution
+    const double ChargeThreshold = 0;
+    const double ResoTime = 0.1*ns ;
+    //const double ResoEnergy = 1.0*MeV ;
+    const double ChamberThickness = 55*cm ;
+    const double ChamberWidth = 50*cm ;
+    const double ChamberHeight = 40*cm ;
+    //const int NumberOfPads = 16384;
+    const int PadX = 128;
+    const int PadZ = 128;
+
+    const double Nose_Rmin = 2.5*cm;
+    const double Nose_Rmax = 3.5*cm;
+    const double Nose_Length = 12*cm;
+
+    const double Mylar_Rmax = 3.5*cm;
+    const double Mylar_Thickness = 7*micrometer;
+
+    const double XGazVolume = 256.*mm;
+    const double YGazVolume = 256.*mm;
+    const double ZGazVolume = 256.*mm;
+
+    const double SiliconHeight = 53.*mm;
+    const double SiliconWidth = 53.*mm;
+    const double SiliconThickness = 0.7*mm;
+    const double DistInterSi = 1.*mm;
+    const double Si_PosZ=15.*cm;
+    const double ResoSilicon = 0.80/2.35;
+    const double EnergyThreshold = 0.1;
+
+    const double CsIThickness = 1.*cm;
+    const double CsIHeight = 2.5*cm;
+    const double CsIWidth = 2.5*cm;
+    const double DistInterCsI = 1.*mm;
+    const double CsI_PosZ = 16.*cm;
+    const double ResoCsI = 0.200/2.35;
+}
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// Actar Specific Method
+Actar::Actar(){
+    m_Event = new TActarData() ;
+    m_ActarScorer = 0;
+    m_SquareDetector = 0;
+
+    // RGB Color + Transparency
+    m_VisChamber    = new G4VisAttributes(G4Colour(0.7, 0.7, 0.7, 0.3));
+    m_VisWindows    = new G4VisAttributes(G4Colour(1, 0, 0, 0.25));
+    m_VisGas        = new G4VisAttributes(G4Colour(0, 0.5, 0.5, 0.3));
+    m_VisPads       = new G4VisAttributes(G4Colour(255, 223, 50, 0.8));
+    m_SiliconVisAtt = new G4VisAttributes(G4Colour(0.529412, 0.807843, 0.980392, 0.95)) ;
+    m_CsIVisAtt     = new G4VisAttributes(G4Colour(0.429412, 0.607843, 0.780392, 0.95));
+    m_VisPads->SetForceWireframe(true);
+
+    m_build_Silicon=1;
+    m_build_CsI=1;
+}
+
+Actar::~Actar(){
+}
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+void Actar::AddDetector(G4ThreeVector POS, string  Shape){
+    // Convert the POS value to R theta Phi as Spherical coordinate is easier in G4
+    m_R.push_back(POS.mag());
+    m_Theta.push_back(POS.theta());
+    m_Phi.push_back(POS.phi());
+    m_Shape.push_back(Shape);
+}
+
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+void Actar::AddDetector(double  R, double  Theta, double  Phi, string  Shape){
+    m_R.push_back(R);
+    m_Theta.push_back(Theta);
+    m_Phi.push_back(Phi);
+    m_Shape.push_back(Shape);
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+G4LogicalVolume* Actar::BuildDetector(){
+
+  G4Material* Cu= MaterialManager::getInstance()->GetMaterialFromLibrary("Cu");
+  G4Material* Si= MaterialManager::getInstance()->GetMaterialFromLibrary("Si");
+  G4Material* Al= MaterialManager::getInstance()->GetMaterialFromLibrary("Al");
+  G4Material* Mylar= MaterialManager::getInstance()->GetMaterialFromLibrary("Mylar");
+  G4Material* MaterialCsI = MaterialManager::getInstance()->GetMaterialFromLibrary("CsI");
+
+  if(!m_SquareDetector){
+        // Main volume
+        G4Box* sChamber = new G4Box("Actar_Box",Actar_NS::ChamberWidth*0.5,
+                                    Actar_NS::ChamberHeight*0.5,Actar_NS::ChamberThickness*0.5);
+
+        //Nose volume
+        G4Tubs* sNose = new G4Tubs("Actar_Nose",Actar_NS::Nose_Rmin, Actar_NS::Nose_Rmax,Actar_NS::Nose_Length*0.5,
+                                    0*deg, 360*deg);
+
+        //Mylar volume
+        G4Tubs* sWindows = new G4Tubs("Actar_Windows",0, Actar_NS::Mylar_Rmax,Actar_NS::Mylar_Thickness*0.5,
+                                    0*deg, 360*deg);
+
+        // Cage volume
+        G4Box* sCage = new G4Box("Actar_Gas",Actar_NS::XGazVolume*0.5,
+                                Actar_NS::YGazVolume*0.5,Actar_NS::ZGazVolume*0.5);
+
+        // Pad
+        G4Box* sPad = new G4Box("Actar_Pad",2*mm*0.5,
+                                 1*um*0.5,2*mm*0.5);
+
+        // Cathode
+        G4Box* sCathode = new G4Box("Actar_Cathode",26.5*cm*0.5,
+                                    1*um*0.5,25.6*cm*0.5);
+
+
+
+        unsigned const int NumberOfGasMix = m_GasMaterial.size();
+
+        double density=0;
+        double density_sum=0;
+        vector<G4Material*> GasComponent;
+        vector<double> FractionMass;
+
+        for(unsigned int i=0; i<NumberOfGasMix; i++){
+            GasComponent.push_back(MaterialManager::getInstance()->GetGasFromLibrary(m_GasMaterial[i],m_Pressure,m_Temperature) );
+        }
+        for(unsigned int i=0; i<NumberOfGasMix; i++){
+            density     += ((double)m_GasFraction[i]/100)*GasComponent[i]->GetDensity();
+            density_sum += GasComponent[i]->GetDensity();
+        }
+        //cout << "density = " << density*cm3/g << endl;
+
+        for(unsigned int i=0; i<NumberOfGasMix; i++){
+            FractionMass.push_back(GasComponent[i]->GetDensity()/density_sum);
+        }
+
+        G4Material* GasMaterial = new G4Material("GasMix", density, NumberOfGasMix, kStateGas, m_Temperature, m_Pressure);
+        G4Material* DriftGasMaterial = new G4Material("GasMix", density, NumberOfGasMix, kStateGas, m_Temperature, m_Pressure);
+
+        for(unsigned int i=0; i<NumberOfGasMix; i++){
+            GasMaterial->AddMaterial(GasComponent[i], FractionMass[i]);
+            DriftGasMaterial->AddMaterial(GasComponent[i], FractionMass[i]);
+        }
+
+        G4MaterialPropertiesTable* MPT = new G4MaterialPropertiesTable();
+        MPT->AddConstProperty("DE_PAIRENERGY",20*eV);
+        MPT->AddConstProperty("DE_YIELD",1e-2);
+        //MPT->AddConstProperty("DE_YIELD",1e-1);
+        //MPT->AddConstProperty("DE_AMPLIFICATION",5);
+        MPT->AddConstProperty("DE_ABSLENGTH",1*pc);
+        MPT->AddConstProperty("DE_DRIFTSPEED",5.*cm/microsecond);
+        //MPT->AddConstProperty("DE_TRANSVERSALSPREAD",5e-5*mm2/ns);
+        //MPT->AddConstProperty("DE_LONGITUDINALSPREAD",5e-5*mm2/ns);
+        MPT->AddConstProperty("DE_TRANSVERSALSPREAD",7e-6*mm2/ns);
+        MPT->AddConstProperty("DE_LONGITUDINALSPREAD",7e-6*mm2/ns);
+
+        DriftGasMaterial->SetMaterialPropertiesTable(MPT);
+
+        G4MaterialPropertiesTable* MPT2 = new G4MaterialPropertiesTable();
+        MPT2->AddConstProperty("DE_YIELD",1);
+        MPT2->AddConstProperty("DE_AMPLIFICATION",2);
+        MPT2->AddConstProperty("DE_ABSLENGTH",1*pc);
+
+        Al->SetMaterialPropertiesTable(MPT2);
+
+        m_SquareDetector = new G4LogicalVolume(sChamber,GasMaterial,"logic_Actar_Box",0,0,0);
+        G4LogicalVolume* logicGas = new G4LogicalVolume(sCage,DriftGasMaterial,"logic_Gas",0,0,0);
+        G4LogicalVolume* logicNose = new G4LogicalVolume(sNose,Al,"logic_Nose",0,0,0);
+        G4LogicalVolume* logicPad = new G4LogicalVolume(sPad,Cu,"logic_Pad",0,0,0);
+        G4LogicalVolume* logicCathode = new G4LogicalVolume(sCathode,Cu,"logic_Cathode",0,0,0);
+        G4LogicalVolume* logicWindows = new G4LogicalVolume(sWindows,Mylar,"logic_Windows",0,0,0);
+
+        G4RotationMatrix* Rot = new G4RotationMatrix();
+        new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-Actar_NS::ChamberThickness*0.5+Actar_NS::Nose_Length*0.5)),
+                          logicNose,
+                          "ActarNose",m_SquareDetector,false,0);
+
+        new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-Actar_NS::ChamberThickness*0.5+Actar_NS::Mylar_Thickness*0.5+Actar_NS::Nose_Length)),
+                          logicWindows,
+                          "ActarEntranceWindows",m_SquareDetector,false,0);
+
+        new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,0)),
+                          logicGas,
+                          "ActarGas",m_SquareDetector,false,0);
+
+        int pad=0;
+        m_PadToXRow.clear();
+        m_PadToZColumn.clear();
+        for(int i=0; i<Actar_NS::PadX; i++){
+            for(int j=0; j<Actar_NS::PadZ; j++){
+                m_PadToXRow[pad] = i;
+                m_PadToZColumn[pad] = j;
+                double X=(i-64)*2*mm;
+                double Z=(j-64)*2*mm;
+                new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(X,Actar_NS::YGazVolume*0.5,Z)),
+                                  logicPad,
+                                  "ActarPad",logicGas,false,pad+1);
+
+                pad++;
+            }
+        }
+
+        /*new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(3*cm-0.5*1*um,0,0)),
+                          logicCathode,
+                          "ActarCathode",logicGas,false,0);
+
+
+
+        new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-6*cm+6*micrometer)),
+                          logicWindows,
+                          "ActarEntranceWindows",m_SquareDetector,false,0);*/
+
+        G4ElectricField* field = new G4UniformElectricField(G4ThreeVector(0.0,-100*volt/cm,0.0));
+        // Create an equation of motion for this field
+        G4EqMagElectricField*  Equation = new G4EqMagElectricField(field);
+        G4MagIntegratorStepper* Stepper = new G4ClassicalRK4( Equation, 8 );
+
+        // Get the global field manager
+        G4FieldManager* FieldManager= new G4FieldManager();
+        // Set this field to the global field manager
+        FieldManager->SetDetectorField(field);
+        logicGas->SetFieldManager(FieldManager,true);
+
+        G4MagInt_Driver* IntgrDriver = new G4MagInt_Driver(0.1*mm,
+                                                           Stepper,
+                                                           Stepper->GetNumberOfVariables() );
+
+        G4ChordFinder* ChordFinder = new G4ChordFinder(IntgrDriver);
+        FieldManager->SetChordFinder( ChordFinder );
+
+
+        logicPad->SetSensitiveDetector(m_ActarScorer);
+        logicNose->SetVisAttributes(m_VisChamber);
+        m_SquareDetector->SetVisAttributes(m_VisChamber);
+        logicGas->SetVisAttributes(m_VisGas);
+        logicWindows->SetVisAttributes(m_VisWindows);
+        logicPad->SetVisAttributes(m_VisPads);
+        //m_SquareDetector->SetSensitiveDetector(m_ActarScorer);
+    }
+
+
+    ///////////////////////////////////////////////////
+    ///////////////////// Thin Si /////////////////////
+    ///////////////////////////////////////////////////
+    if(m_build_Silicon){
+        G4Box* solidSi = new G4Box("Si", 0.5*Actar_NS::SiliconWidth, 0.5*Actar_NS::SiliconHeight, 0.5*Actar_NS::SiliconThickness);	;
+        m_LogicSilicon = new G4LogicalVolume(solidSi, Si, "logicSi", 0, 0, 0);
+
+        int SiliconNumber=0;
+        for(int k=0;k<4; k++){
+          for(int p=0; p<5; p++){
+            double PosX;
+            double PosY;
+            if(k==0) PosY= -1.5*Actar_NS::SiliconHeight-2*Actar_NS::DistInterSi;
+            if(k==1) PosY= -0.5*Actar_NS::SiliconHeight-1*Actar_NS::DistInterSi;
+            if(k==2) PosY= 0.5*Actar_NS::SiliconHeight+1*Actar_NS::DistInterSi;
+            if(k==3) PosY= 1.5*Actar_NS::SiliconHeight+2*Actar_NS::DistInterSi;
+            if(p==0) PosX= -2*Actar_NS::SiliconWidth-2*Actar_NS::DistInterSi;
+            if(p==1) PosX= -1*Actar_NS::SiliconWidth-1*Actar_NS::DistInterSi;
+            if(p==2) PosX= 0;
+            if(p==3) PosX= 1*Actar_NS::SiliconWidth+2*Actar_NS::DistInterSi;
+            if(p==4) PosX= 2*Actar_NS::SiliconWidth+1*Actar_NS::DistInterSi;
+
+            G4ThreeVector positionSi = G4ThreeVector(PosX, PosY, Actar_NS::Si_PosZ);
+            new G4PVPlacement(new G4RotationMatrix(0,0,0),
+                              positionSi,
+                              m_LogicSilicon,"Si",
+                              m_SquareDetector,false,SiliconNumber);
+            SiliconNumber++;
+            }
+          }
+
+        // Set Si sensible
+        m_LogicSilicon->SetSensitiveDetector(m_SiliconScorer);
+
+        // Visualisation of ThinSi
+        m_LogicSilicon->SetVisAttributes(m_SiliconVisAtt) ;
+    }
+
+    ///////////////////////////////////////////////
+    ///////////////////// CsI /////////////////////
+    ///////////////////////////////////////////////
+    if(m_build_CsI){
+        G4Box* solidCsI = new G4Box("Si", 0.5*Actar_NS::CsIWidth, 0.5*Actar_NS::CsIHeight, 0.5*Actar_NS::CsIThickness);	;
+        m_LogicCsICrystal = new G4LogicalVolume(solidCsI, MaterialCsI, "logicCsI", 0, 0, 0);
+
+        int CsINumber=0;
+        for(int k=0;k<8; k++){
+          for(int p=0; p<10; p++){
+            double PosX;
+            double PosY;
+            if(k<4) PosY= -0.5*Actar_NS::CsIHeight-0.5*Actar_NS::DistInterCsI+(k-3)*(Actar_NS::CsIHeight+Actar_NS::DistInterCsI);
+            if(k>3) PosY= 0.5*Actar_NS::CsIHeight+0.5*Actar_NS::DistInterCsI+(k-4)*(Actar_NS::CsIHeight+Actar_NS::DistInterCsI);
+
+            if(p<5) PosX= 0.5*Actar_NS::CsIWidth+0.5*Actar_NS::DistInterCsI+(4-p)*(Actar_NS::CsIWidth+Actar_NS::DistInterCsI);
+            if(p>4) PosX= -0.5*Actar_NS::CsIWidth-0.5*Actar_NS::DistInterCsI+(5-p)*(Actar_NS::CsIWidth+Actar_NS::DistInterCsI);
+
+            G4ThreeVector positionCsI = G4ThreeVector(PosX, PosY, Actar_NS::CsI_PosZ);
+            new G4PVPlacement(new G4RotationMatrix(0,0,0),
+                              positionCsI,
+                              m_LogicCsICrystal,"CsI",
+                              m_SquareDetector,false,CsINumber);
+            CsINumber++;
+            }
+          }
+
+        // Set Si sensible
+        m_LogicCsICrystal->SetSensitiveDetector(m_CsIScorer);
+
+        // Visualisation of ThinSi
+        m_LogicCsICrystal->SetVisAttributes(m_CsIVisAtt) ;
+    }
+
+    return m_SquareDetector;
+}
+
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// Virtual Method of NPS::VDetector class
+
+// Read stream at Configfile to pick-up parameters of detector (Position,...)
+// Called in DetecorConstruction::ReadDetextorConfiguration Method
+void Actar::ReadConfiguration(NPL::InputParser parser){
+    vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Actar");
+    if(NPOptionManager::getInstance()->GetVerboseLevel())
+        cout << "//// " << blocks.size() << " detectors found " << endl;
+
+    vector<string> cart = {"POS","Shape","GasMaterial","GasFraction","Temperature","Pressure","Si","CsI"};
+    vector<string> sphe = {"R","Theta","Phi","Shape","GasMaterial","GasFraction","Temperature","Pressure","Si","CsI"};
+
+    for(unsigned int i = 0 ; i < blocks.size() ; i++){
+        if(blocks[i]->HasTokenList(cart)){
+            if(NPOptionManager::getInstance()->GetVerboseLevel())
+                cout << endl << "////  Actar " << i+1 <<  endl;
+
+            G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm"));
+            string Shape = blocks[i]->GetString("Shape");
+            vector<string> GasName = blocks[i]->GetVectorString("GasMaterial");
+            vector<int> GasFraction = blocks[i]->GetVectorInt("GasFraction");
+            for(unsigned int j=0; j<GasName.size(); j++){
+                m_GasMaterial.push_back(GasName[j]);
+                m_GasFraction.push_back(GasFraction[j]);
+            }
+            m_Temperature = blocks[i]->GetDouble("Temperature","kelvin");
+            m_Pressure = blocks[i]->GetDouble("Pressure","bar");
+            m_build_Silicon =  blocks[i]->GetInt("Si");
+            m_build_CsI     =  blocks[i]->GetInt("CsI");
+
+            AddDetector(Pos,Shape);
+        }
+        else if(blocks[i]->HasTokenList(sphe)){
+            if(NPOptionManager::getInstance()->GetVerboseLevel())
+                cout << endl << "////  Actar " << i+1 <<  endl;
+            double R = blocks[i]->GetDouble("R","mm");
+            double Theta = blocks[i]->GetDouble("Theta","deg");
+            double Phi = blocks[i]->GetDouble("Phi","deg");
+            string Shape = blocks[i]->GetString("Shape");
+            vector<string> GasName = blocks[i]->GetVectorString("GasMaterial");
+            vector<int> GasFraction = blocks[i]->GetVectorInt("GasFraction");
+            for(unsigned int j=0; j<GasName.size(); j++){
+                m_GasMaterial.push_back(GasName[j]);
+                m_GasFraction.push_back(GasFraction[j]);
+            }
+            m_Temperature = blocks[i]->GetDouble("Temperature","kelvin");
+            m_Pressure = blocks[i]->GetDouble("Pressure","bar");
+            m_build_Silicon =  blocks[i]->GetInt("Si");
+            m_build_CsI     =  blocks[i]->GetInt("CsI");
+
+            AddDetector(R,Theta,Phi,Shape);
+        }
+        else{
+            cout << "ERROR: check your input file formatting " << endl;
+            exit(1);
+        }
+    }
+}
+
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+// Construct detector and inialise sensitive part.
+// Called After DetecorConstruction::AddDetector Method
+void Actar::ConstructDetector(G4LogicalVolume* world){
+    for (unsigned short i = 0 ; i < m_R.size() ; i++) {
+
+        G4double wX = m_R[i] * sin(m_Theta[i] ) * cos(m_Phi[i] ) ;
+        G4double wY = m_R[i] * sin(m_Theta[i] ) * sin(m_Phi[i] ) ;
+        G4double wZ = m_R[i] * cos(m_Theta[i] ) ;
+        G4ThreeVector Det_pos = G4ThreeVector(wX, wY, wZ) ;
+        // So the face of the detector is at R instead of the middle
+        Det_pos+=Det_pos.unit()*Actar_NS::ChamberThickness*0.5;
+        // Building Detector reference frame
+        G4double ii = cos(m_Theta[i]) * cos(m_Phi[i]);
+        G4double jj = cos(m_Theta[i]) * sin(m_Phi[i]);
+        G4double kk = -sin(m_Theta[i]);
+        G4ThreeVector Y(ii,jj,kk);
+        G4ThreeVector w = Det_pos.unit();
+        G4ThreeVector u = w.cross(Y);
+        G4ThreeVector v = w.cross(u);
+        v = v.unit();
+        u = u.unit();
+
+        G4RotationMatrix* Rot = new G4RotationMatrix(u,v,w);
+
+        new G4PVPlacement(G4Transform3D(*Rot,Det_pos),
+                              BuildDetector(),
+                              "Actar",world,false,i+1);
+    }
+}
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// Add Detector branch to the EventTree.
+// Called After DetecorConstruction::AddDetector Method
+void Actar::InitializeRootOutput(){
+    RootOutput *pAnalysis = RootOutput::getInstance();
+    TTree *pTree = pAnalysis->GetTree();
+    if(!pTree->FindBranch("Actar")){
+        pTree->Branch("Actar", "TActarData", &m_Event) ;
+    }
+    pTree->SetBranchAddress("Actar", &m_Event) ;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// Read sensitive part and fill the Root tree.
+// Called at in the EventAction::EndOfEventAvtion
+void Actar::ReadSensitive(const G4Event* event){
+    m_Event->Clear();
+
+    //////////////
+    // Pad scorer
+    NPS::HitsMap<G4double*>* PadHitMap;
+    std::map<G4int, G4double**>::iterator Pad_itr;
+
+    G4int PadCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("ActarScorer/Actar_dig");
+    PadHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(PadCollectionID));
+
+    // Loop on the Pad map
+    TH1D* h = new TH1D("h","h",25000,0,25000);
+    for (Pad_itr = PadHitMap->GetMap()->begin() ; Pad_itr != PadHitMap->GetMap()->end() ; Pad_itr++){
+        G4double* Info = *(Pad_itr->second);
+        // Interraction Coordinates
+        ms_InterCoord->SetDetectedPositionX(Info[2]) ;
+        ms_InterCoord->SetDetectedPositionY(Info[3]) ;
+        ms_InterCoord->SetDetectedPositionZ(Info[4]) ;
+        ms_InterCoord->SetDetectedAngleTheta(Info[5]/deg) ;
+        ms_InterCoord->SetDetectedAnglePhi(Info[6]/deg) ;
+
+        double Count = Info[0];
+        double Time =  RandGauss::shoot(Info[1],Actar_NS::ResoTime);
+        //int iTime = ((int) Time*20/512)+1;
+        int PadNbr = Info[7];
+        if(Count>Actar_NS::ChargeThreshold){
+            m_Event->SetTime(Time);
+            m_Event->SetPadNumber(PadNbr);
+            m_Event->SetCharge(Count);
+            m_Event->SetRowNumber(m_PadToXRow[PadNbr]);
+            m_Event->SetColumnNumber(m_PadToZColumn[PadNbr]);
+        }
+
+        if(Count){
+            h->Fill(Info[1],Info[0]);
+        }
+    }
+
+    vector<double> Q, T;
+    for(int i=0; i<h->GetNbinsX(); i++){
+        double count = h->GetBinContent(i);
+        double time = h->GetBinCenter(i);
+        if(count){
+            Q.push_back(count);
+            T.push_back(time+500);
+
+        }
+    }
+    // clear map for next event
+    //SimulateDigitizer(Q,T,1.40*microsecond,0,8750,25,5);
+    delete h;
+    PadHitMap->clear();
+
+    // Silicon //
+    if(m_build_Silicon){
+        NPS::HitsMap<G4double*>* SiHitMap;
+        std::map<G4int, G4double**>::iterator Si_itr;
+
+        G4int SiCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("SiliconScorer/SiliconScorer");
+        SiHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(SiCollectionID));
+
+        // Loop on the ThinSi map
+        for (Si_itr = SiHitMap->GetMap()->begin() ; Si_itr != SiHitMap->GetMap()->end() ; Si_itr++){
+            G4double* Info = *(Si_itr->second);
+            double E_Si = RandGauss::shoot(Info[0],Actar_NS::ResoSilicon);
+
+            if(E_Si>Actar_NS::EnergyThreshold){
+                m_Event->SetSiliconEnergy(E_Si);
+                m_Event->SetSiliconDetectorNumber(Info[7]);
+                m_Event->SetSiliconTime(Info[1]);
+            }
+        }
+
+        // Clear Map for next event
+        SiHitMap->clear();
+    }
+
+    // CsI //
+    if(m_build_CsI){
+        NPS::HitsMap<G4double*>* CsIHitMap;
+        std::map<G4int, G4double**>::iterator CsI_itr;
+
+        G4int CsICollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("CsIScorer/CsI");
+        CsIHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(CsICollectionID));
+
+        // Loop on the CsI map
+        for (CsI_itr = CsIHitMap->GetMap()->begin() ; CsI_itr !=CsIHitMap->GetMap()->end() ; CsI_itr++){
+            G4double* Info = *(CsI_itr->second);
+            double E_CsI = RandGauss::shoot(Info[0],Actar_NS::ResoCsI);
+
+            if(E_CsI>Actar_NS::EnergyThreshold){
+                m_Event->SetCsIEnergy(E_CsI);
+                m_Event->SetCsICrystalNumber(Info[2]);
+            }
+        }
+        // Clear Map for next event
+        CsIHitMap->clear();
+    }
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+void Actar::SimulateDigitizer(vector<double> E, vector<double> T, double fallTime,double start,double stop, double step,double noise){
+
+    static string formula;
+    formula= "";
+    static string Es,Ts,var,cond;
+    static string fall;
+    fall=std::to_string(fallTime);
+
+    for(unsigned int i = 0 ; i < E.size() ; i++){
+        if(E[i]!=0 && T[i]!=0){
+            Es = std::to_string(E[i]);
+            Ts = std::to_string(T[i]);
+            cond = ")*(x>"+Ts+")+";
+            var = "(x-"+Ts+")";
+            formula += Es+"*-1*exp(-"+var+"/"+fall+cond;
+        }
+    }
+    formula+="0";
+    //cout << formula << endl;
+    TF1* f = new TF1("f",formula.c_str(),start,stop);
+    unsigned int size = (stop-start)/step;
+    for(unsigned int i = 0 ; i < size ; i++){
+        double time = start+i*step;
+        double energy = f->Eval(time)+noise*(1-2*G4UniformRand());
+        m_Event->AddEnergyPoint(energy,time);
+    }
+
+    delete f;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+////////////////////////////////////////////////////////////////
+void Actar::InitializeScorers() {
+    // This check is necessary in case the geometry is reloaded
+
+    bool already_exist = false;
+    vector<G4int> NestingLevel;
+    NestingLevel.push_back(0);
+    NestingLevel.push_back(2);
+
+    m_ActarScorer   = CheckScorer("ActarScorer",already_exist) ;
+    m_SiliconScorer = CheckScorer("SiliconScorer",already_exist);
+    m_CsIScorer     = CheckScorer("CsIScorer",already_exist);
+
+    if(already_exist) return;
+
+    G4VPrimitiveScorer *SiScorer = new SILICONSCORERS::PS_Silicon_Rectangle("SiliconScorer",0,Actar_NS::SiliconHeight,Actar_NS::SiliconWidth,1,1);
+    m_SiliconScorer->RegisterPrimitive(SiScorer);
+
+    G4VPrimitiveScorer* CsIScorer= new CALORIMETERSCORERS::PS_Calorimeter("CsI",NestingLevel);
+    m_CsIScorer->RegisterPrimitive(CsIScorer);
+
+    vector<int> level; level.push_back(0);
+    G4VPrimitiveScorer* Actar_dig= new DRIFTELECTRONSCORERS::PS_DECathode("Actar_dig",0) ;
+    m_ActarScorer->RegisterPrimitive(Actar_dig);
+
+    G4SDManager::GetSDMpointer()->AddNewDetector(m_ActarScorer);
+    G4SDManager::GetSDMpointer()->AddNewDetector(m_SiliconScorer);
+    G4SDManager::GetSDMpointer()->AddNewDetector(m_CsIScorer) ;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+////////////////////////////////////////////////////////////////////////////////
+//            Construct Method to be pass to the DetectorFactory              //
+////////////////////////////////////////////////////////////////////////////////
+NPS::VDetector* Actar::Construct(){
+    return  (NPS::VDetector*) new Actar();
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+////////////////////////////////////////////////////////////////////////////////
+//            Registering the construct method to the factory                 //
+////////////////////////////////////////////////////////////////////////////////
+extern"C" {
+    class proxy_nps_Actar{
+    public:
+        proxy_nps_Actar(){
+            NPS::DetectorFactory::getInstance()->AddToken("Actar","Actar");
+            NPS::DetectorFactory::getInstance()->AddDetector("Actar",Actar::Construct);
+        }
+    };
+
+    proxy_nps_Actar p_nps_Actar;
+}
diff --git a/NPSimulation/Detectors/Actar/Actar.hh b/NPSimulation/Detectors/Actar/Actar.hh
new file mode 100644
index 0000000000000000000000000000000000000000..43aecfd54d1a928425bb60f9c4be53edc3825a04
--- /dev/null
+++ b/NPSimulation/Detectors/Actar/Actar.hh
@@ -0,0 +1,136 @@
+#ifndef Actar_h
+#define Actar_h 1
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ *                                                                           *
+ * Creation Date  : September 2017                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class describe  Actar simulation                             *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *****************************************************************************/
+
+// C++ header
+#include <string>
+#include <vector>
+#include <map>
+using namespace std;
+
+// G4 headers
+#include "G4ThreeVector.hh"
+#include "G4RotationMatrix.hh"
+#include "G4LogicalVolume.hh"
+#include "G4MultiFunctionalDetector.hh"
+
+// NPTool header
+#include "NPSVDetector.hh"
+#include "TActarData.h"
+#include "NPInputParser.h"
+
+class Actar : public NPS::VDetector{
+    ////////////////////////////////////////////////////
+    /////// Default Constructor and Destructor /////////
+    ////////////////////////////////////////////////////
+public:
+    Actar() ;
+    virtual ~Actar() ;
+
+    ////////////////////////////////////////////////////
+    /////// Specific Function of this Class ///////////
+    ////////////////////////////////////////////////////
+public:
+    // Cartesian
+    void AddDetector(G4ThreeVector POS, string Shape);
+    // Spherical
+    void AddDetector(double R,double Theta,double Phi,string Shape);
+
+
+    G4LogicalVolume* BuildDetector();
+
+private:
+    G4LogicalVolume* m_SquareDetector;
+    bool m_build_Silicon;
+    bool m_build_CsI;
+    G4LogicalVolume* m_LogicSilicon;
+    G4LogicalVolume* m_LogicCsICrystal;
+
+    ////////////////////////////////////////////////////
+    //////  Inherite from NPS::VDetector class /////////
+    ////////////////////////////////////////////////////
+public:
+    // Read stream at Configfile to pick-up parameters of detector (Position,...)
+    // Called in DetecorConstruction::ReadDetextorConfiguration Method
+    void ReadConfiguration(NPL::InputParser) ;
+
+    // Construct detector and inialise sensitive part.
+    // Called After DetecorConstruction::AddDetector Method
+    void ConstructDetector(G4LogicalVolume* world) ;
+
+    // Add Detector branch to the EventTree.
+    // Called After DetecorConstruction::AddDetector Method
+    void InitializeRootOutput() ;
+
+    // Read sensitive part and fill the Root tree.
+    // Called at in the EventAction::EndOfEventAvtion
+    void ReadSensitive(const G4Event* event) ;
+
+public:   // Scorer
+    //   Initialize all Scorer
+    void InitializeScorers() ;
+     void SimulateDigitizer(vector<double> E, vector<double> T, double fallTime,double start,double stop,double step,double noise);
+
+    //   Associated Scorer
+    G4MultiFunctionalDetector* m_ActarScorer ;
+    G4MultiFunctionalDetector* m_CsIScorer ;
+    G4MultiFunctionalDetector* m_SiliconScorer ;
+    ////////////////////////////////////////////////////
+    ///////////Event class to store Data////////////////
+    ////////////////////////////////////////////////////
+private:
+    TActarData* m_Event ;
+
+    ////////////////////////////////////////////////////
+    ///////////////Private intern Data//////////////////
+    ////////////////////////////////////////////////////
+private: // Geometry
+    // Detector Coordinate
+    vector<double>  m_R;
+    vector<double>  m_Theta;
+    vector<double>  m_Phi;
+
+    //   Shape type
+    vector<string> m_Shape ;
+
+    // map
+    map<int, int> m_PadToXRow;
+    map<int, int> m_PadToZColumn;
+
+    // token
+    vector<string> m_GasMaterial;
+    vector<int> m_GasFraction;
+    double m_Pressure; // bar
+    double m_Temperature; // kelvin
+
+    // Visualisation Attribute
+    G4VisAttributes* m_VisChamber;
+    G4VisAttributes* m_VisWindows;
+    G4VisAttributes* m_VisGas;
+    G4VisAttributes* m_VisPads;
+    G4VisAttributes* m_SiliconVisAtt;
+    G4VisAttributes* m_CsIVisAtt;
+    // Needed for dynamic loading of the library
+public:
+    static NPS::VDetector* Construct();
+};
+#endif
diff --git a/NPSimulation/Detectors/Actar/CMakeLists.txt b/NPSimulation/Detectors/Actar/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2e1163d4fb99272a3e21fc19e495963c0a482ff6
--- /dev/null
+++ b/NPSimulation/Detectors/Actar/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(NPSActar SHARED  Actar.cc)
+target_link_libraries(NPSActar NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPActar)
diff --git a/NPSimulation/Detectors/ForwardArray/ForwardArray.cc b/NPSimulation/Detectors/ForwardArray/ForwardArray.cc
index 8bb623e61991d72a8c221f88bc9dd21974d91dae..71385a978517517895c473667e28b38887d53430 100644
--- a/NPSimulation/Detectors/ForwardArray/ForwardArray.cc
+++ b/NPSimulation/Detectors/ForwardArray/ForwardArray.cc
@@ -1,14 +1,14 @@
 /*****************************************************************************
- * Copyright (C) 2009-2017   this file is part of the NPTool Project       *
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project         *
  *                                                                           *
  * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
  * For the list of contributors see $NPTOOL/Licence/Contributors             *
  *****************************************************************************/
 
 /*****************************************************************************
- * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu                        *
+ * Original Author: Pierre Morfouace  contact address: morfouac@nscl.msu.edu *
  *                                                                           *
- * Creation Date  : May 2017                                           *
+ * Creation Date  : May 2017                                                 *
  * Last update    :                                                          *
  *---------------------------------------------------------------------------*
  * Decription:                                                               *
@@ -57,7 +57,7 @@ using namespace CLHEP;
 namespace ForwardArray_NS{
     // Energy and time Resolution
     const double EnergyThreshold = 0.1*MeV;
-    const double ResoTime = 4.5*ns ;
+    const double ResoTime = 0.3*ns ;
     const double ResoEnergy = 1.0*MeV ;
     //const double Width = 100*mm ;
     
diff --git a/NPSimulation/Detectors/MDM/CMakeLists.txt b/NPSimulation/Detectors/MDM/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2b2d15004670e3c49b295805fbf68138e9e6368e
--- /dev/null
+++ b/NPSimulation/Detectors/MDM/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(NPSMDM SHARED  MDM.cc)
+target_link_libraries(NPSMDM NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPMDM)
diff --git a/NPSimulation/Detectors/MDM/MDM.cc b/NPSimulation/Detectors/MDM/MDM.cc
new file mode 100644
index 0000000000000000000000000000000000000000..22d6b50b2018c809ff8be181f4c61318fc919e84
--- /dev/null
+++ b/NPSimulation/Detectors/MDM/MDM.cc
@@ -0,0 +1,278 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu     *
+ *                                                                           *
+ * Creation Date  : October 2017                                             *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class describe  MDM simulation                                      *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *****************************************************************************/
+
+// C++ headers
+#include <sstream>
+#include <cmath>
+#include <limits>
+//G4 Geometry object
+#include "G4Tubs.hh"
+#include "G4Box.hh"
+
+//G4 sensitive
+#include "G4SDManager.hh"
+#include "G4MultiFunctionalDetector.hh"
+
+//G4 various object
+#include "G4Material.hh"
+#include "G4Transform3D.hh"
+#include "G4PVPlacement.hh"
+#include "G4VisAttributes.hh"
+#include "G4Colour.hh"
+
+// NPTool header
+#include "MDM.hh"
+#include "MDMScorer.hh"
+#include "RootOutput.h"
+#include "MaterialManager.hh"
+#include "NPSDetectorFactory.hh"
+#include "NPOptionManager.h"
+#include "NPSHitsMap.hh"
+
+// ROOT
+#include "TSystem.h"
+
+// CLHEP header
+#include "CLHEP/Random/RandGauss.h"
+
+
+using namespace std;
+using namespace CLHEP;
+
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+namespace MDM_NS{
+  // Energy and time Resolution
+const double Width     = 250*mm ;
+const double Thickness = 10*mm;
+const double Zpos      = 40*cm;
+const string Material  = "BC400"; // fake!!
+}
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// MDM Specific Method
+MDM::MDM(){
+  m_Event = new TMDMData() ;
+  m_MDMScorer = 0;
+  m_SquareDetector = 0;
+  m_Angle = 0;
+  m_Field = 0;
+  m_Rayin = 0;
+}
+
+MDM::~MDM(){
+  if(m_Rayin) { delete m_Rayin; m_Rayin = 0; }
+}
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+void MDM::AddDetector(double angle, double field, double xaccept, double yaccept, const string& rayin){
+  m_Angle = angle;
+  m_Field = field;
+	m_Xaccept = xaccept;
+	m_Yaccept = yaccept;
+  m_Rayin_file = rayin;
+  
+  m_Rayin = new MDMTrace::Rayin(m_Rayin_file, false);
+  m_Trace = MDMTrace::Instance();
+
+  m_Trace->SetMDMAngle(angle/mrad);  // mrad
+  m_Trace->SetMDMDipoleField(field/gauss); // gauss
+
+  cout << "MDM::AddDetector :: Angle [mrad], Angle [deg], Field [G], Rayin File :: " 
+       << angle/mrad << ", " << angle/deg << ", " << field/gauss << ", " << m_Rayin_file << "\n";
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+G4LogicalVolume* MDM::BuildSquareDetector(){
+  if(!m_SquareDetector){
+    G4Box* box = new G4Box("MDM_Box",MDM_NS::Width*0.5,
+			   MDM_NS::Width*0.5,MDM_NS::Thickness*0.5);
+
+    G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(MDM_NS::Material);
+    m_SquareDetector = new G4LogicalVolume(box,DetectorMaterial,"logic_MDM_Box",0,0,0);
+    m_SquareDetector->SetVisAttributes(m_VisSquare);
+    m_SquareDetector->SetSensitiveDetector(m_MDMScorer);
+  }
+  return m_SquareDetector;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// Virtual Method of NPS::VDetector class
+
+// Read stream at Configfile to pick-up parameters of detector (Position,...)
+// Called in DetecorConstruction::ReadDetextorConfiguration Method
+void MDM::ReadConfiguration(NPL::InputParser parser){
+  vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("MDM");
+  if(NPOptionManager::getInstance()->GetVerboseLevel())
+    cout << "//// " << blocks.size() << " detectors found " << endl; 
+
+  vector<string> sphe = {"Angle","Field","Rayin"};
+
+  for(unsigned int i = 0 ; i < blocks.size() ; i++){
+    if(blocks[i]->HasTokenList(sphe)){
+      if(NPOptionManager::getInstance()->GetVerboseLevel())
+        cout << endl << "////  MDM " << i+1 <<  endl;
+      double Angle = blocks[i]->GetDouble("Angle","deg");
+      double Field = blocks[i]->GetDouble("Field","gauss");
+			double XA    = blocks[i]->GetDouble("XAccept","deg");
+			double YA    = blocks[i]->GetDouble("YAccept","deg");
+      string Rayin = blocks[i]->GetString("Rayin");
+      AddDetector(Angle, Field, XA, YA, Rayin);
+    }
+    else{
+      cout << "ERROR: check your input file formatting " << endl;
+      exit(1);
+    }
+  }
+}
+
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+// Construct detector and inialise sensitive part.
+// Called After DetecorConstruction::AddDetector Method
+void MDM::ConstructDetector(G4LogicalVolume* world){
+  G4double wX = 0;
+  G4double wY = 0;
+  G4double wZ = MDM_NS::Zpos;
+  G4ThreeVector Det_pos = G4ThreeVector(wX, wY, wZ) ;
+
+  new G4PVPlacement(0, Det_pos, BuildSquareDetector(), 
+		    "MDM0_Spectrometer", world, false, 0);
+}
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// Add Detector branch to the EventTree.
+// Called After DetecorConstruction::AddDetector Method
+void MDM::InitializeRootOutput(){
+  RootOutput *pAnalysis = RootOutput::getInstance();
+  TTree *pTree = pAnalysis->GetTree();
+  if(!pTree->FindBranch("MDM")){
+    pTree->Branch("MDM", "TMDMData", &m_Event) ;
+  }
+  pTree->SetBranchAddress("MDM", &m_Event) ;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+// Read sensitive part and fill the Root tree.
+// Called at in the EventAction::EndOfEventAvtion
+void MDM::ReadSensitive(const G4Event* event){
+  m_Event->Clear();
+
+  G4int ID = G4SDManager::GetSDMpointer()->GetCollectionID("MDMScorer/ScorerMDM");
+  NPS::HitsMap<MDMScorer::Infos>* Hits =
+    static_cast<NPS::HitsMap<MDMScorer::Infos>*> (event->GetHCofThisEvent()->GetHC(ID));
+
+  size_t indx = 0;
+  for(auto& Iter : *(Hits->GetMap())) {
+    // Read energy, position, momentum
+    double Ekin              = Iter.second->Edep;  // MeV
+    double Mass              = Iter.second->Mass;  // MeV/c^2
+    unsigned short Charge    = Iter.second->Charge;// e
+    const G4ThreeVector& Pos = Iter.second->Pos;   // mm
+    const G4ThreeVector& Mom = Iter.second->Mom;   // rad
+		
+    // Calculate dispersive & non-dispersive angles
+    double thetaX = atan(Mom.x() / Mom.z());
+    double thetaY = atan(Mom.y() / Mom.z());
+
+		double x[4] = {1e10,1e10,1e10,1e10};
+		double y[4] = {1e10,1e10,1e10,1e10};
+		double a = 1e10;
+		double b = 1e10;
+
+		// check if within acceptance
+		// saves lots of time not tracking events outside of the
+		// acceptance
+		if(fabs(thetaX) < m_Xaccept && fabs(thetaY) < m_Yaccept)
+		{
+			// Calculate positions at TARGET
+			double xTrgt = Pos.x()/mm - (MDM_NS::Zpos/mm - MDM_NS::Thickness*0.5/mm)*tan(thetaX);
+			double yTrgt = Pos.y()/mm - (MDM_NS::Zpos/mm - MDM_NS::Thickness*0.5/mm)*tan(thetaY);
+			double zTrgt = 0.*mm;
+			
+			// Send Through MDM
+			m_Trace->SetScatteredMass(Mass/amu_c2);
+			m_Trace->SetScatteredCharge(Charge);
+			m_Trace->SetScatteredAngle(thetaX/deg, thetaY/deg);
+			m_Trace->SetScatteredEnergy(Ekin/MeV);
+			m_Trace->SetBeamPosition(xTrgt/cm, yTrgt/cm, zTrgt/cm);
+			m_Trace->SendRay();
+
+			// Read wire1 position, angle
+			m_Trace->GetOxfordWirePositions(a,x[0],x[1],x[2],x[3],b,y[0],y[1],y[2],y[3]);
+		}
+		
+    // Set X, Y positions in TMDMData class
+    for(int i=0; i< 4; ++i) {
+			m_Event->SetHit(i, x[i], y[i], Charge, Mass/amu_c2);
+    }
+  
+    ++indx;
+  }
+
+  Hits->clear() ;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+////////////////////////////////////////////////////////////////   
+void MDM::InitializeScorers() { 
+  // This check is necessary in case the geometry is reloaded
+  bool already_exist = false; 
+  m_MDMScorer = CheckScorer("MDMScorer",already_exist) ;
+
+  if(already_exist) { return ; }
+
+  G4VPrimitiveScorer* ScorerMDM =
+    new MDMScorer("ScorerMDM", "MDM", 0);
+
+  //and register it to the multifunctionnal detector
+  m_MDMScorer->RegisterPrimitive(ScorerMDM);
+
+  G4SDManager::GetSDMpointer()->AddNewDetector(m_MDMScorer) ;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+////////////////////////////////////////////////////////////////////////////////
+//            Construct Method to be pass to the DetectorFactory              //
+////////////////////////////////////////////////////////////////////////////////
+NPS::VDetector* MDM::Construct(){
+  return  (NPS::VDetector*) new MDM();
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+////////////////////////////////////////////////////////////////////////////////
+//            Registering the construct method to the factory                 //
+////////////////////////////////////////////////////////////////////////////////
+extern"C" {
+  class proxy_nps_MDM{
+  public:
+    proxy_nps_MDM(){
+      NPS::DetectorFactory::getInstance()->AddToken("MDM","MDM");
+      NPS::DetectorFactory::getInstance()->AddDetector("MDM",MDM::Construct);
+    }
+  };
+
+  proxy_nps_MDM p_nps_MDM;
+}
diff --git a/NPSimulation/Detectors/MDM/MDM.hh b/NPSimulation/Detectors/MDM/MDM.hh
new file mode 100644
index 0000000000000000000000000000000000000000..9eb576bf869646d95878213d05264e6b1411a809
--- /dev/null
+++ b/NPSimulation/Detectors/MDM/MDM.hh
@@ -0,0 +1,111 @@
+#ifndef MDM_h
+#define MDM_h 1
+/*****************************************************************************
+ * Copyright (C) 2009-2017   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu                        *
+ *                                                                           *
+ * Creation Date  : October 2017                                             *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class describe  MDM simulation                                      *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *****************************************************************************/
+
+// G4 headers
+#include "G4ThreeVector.hh"
+#include "G4RotationMatrix.hh"
+#include "G4LogicalVolume.hh"
+#include "G4MultiFunctionalDetector.hh"
+
+// NPTool header
+#include "NPSVDetector.hh"
+#include "TMDMData.h"
+#include "NPInputParser.h"
+#include "MDMTrace.h"
+
+
+class MDM : public NPS::VDetector{
+  ////////////////////////////////////////////////////
+  /////// Default Constructor and Destructor /////////
+  ////////////////////////////////////////////////////
+public:
+  MDM() ;
+  virtual ~MDM() ;
+
+  ////////////////////////////////////////////////////
+  /////// Specific Function of this Class ///////////
+  ////////////////////////////////////////////////////
+public:
+  void AddDetector(double angle /*deg*/, double field /*Gauss*/, 
+									 double xaccept /*+/- deg*/, double yaccept /*+/- deg*/,
+									 const std::string& rayin);
+
+  G4LogicalVolume* BuildSquareDetector();
+  
+private:
+  G4LogicalVolume* m_SquareDetector;
+    
+  ////////////////////////////////////////////////////
+  //////  Inherite from NPS::VDetector class /////////
+  ////////////////////////////////////////////////////
+public:
+  // Read stream at Configfile to pick-up parameters of detector (Position,...)
+  // Called in DetecorConstruction::ReadDetextorConfiguration Method
+  void ReadConfiguration(NPL::InputParser) ;
+
+  // Construct detector and inialise sensitive part.
+  // Called After DetecorConstruction::AddDetector Method
+  void ConstructDetector(G4LogicalVolume* world) ;
+
+  // Add Detector branch to the EventTree.
+  // Called After DetecorConstruction::AddDetector Method
+  void InitializeRootOutput() ;
+
+  // Read sensitive part and fill the Root tree.
+  // Called at in the EventAction::EndOfEventAvtion
+  void ReadSensitive(const G4Event* event) ;
+
+public:   // Scorer
+  //   Initialize all Scorer used by the MUST2Array
+  void InitializeScorers() ;
+
+  //   Associated Scorer
+  G4MultiFunctionalDetector* m_MDMScorer ;
+  ////////////////////////////////////////////////////
+  ///////////Event class to store Data////////////////
+  ////////////////////////////////////////////////////
+private:
+  TMDMData* m_Event ;
+
+  ////////////////////////////////////////////////////
+  ///////////////Private intern Data//////////////////
+  ////////////////////////////////////////////////////
+private: // Geometry
+  // Detector Coordinate 
+  double  m_Angle;
+  double  m_Field;
+	double  m_Xaccept;
+	double  m_Yaccept;
+  std::string m_Rayin_file;
+
+  MDMTrace* m_Trace;
+	MDMTrace::Rayin* m_Rayin;
+
+  G4VisAttributes* m_VisSquare;
+	
+  // Needed for dynamic loading of the library
+public:
+  static NPS::VDetector* Construct();
+};
+#endif
+
diff --git a/NPSimulation/Scorers/CMakeLists.txt b/NPSimulation/Scorers/CMakeLists.txt
index f54c2bdbf5d8e506ce9ab80ed3998e087a52f42a..de493f8a6ad743470eff3e804a30811fe6ba532f 100644
--- a/NPSimulation/Scorers/CMakeLists.txt
+++ b/NPSimulation/Scorers/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_library(NPSScorers SHARED NPSHitsMap.hh CalorimeterScorers.cc  SiliconScorers.cc PhotoDiodeScorers.cc ObsoleteGeneralScorers.cc DriftElectronScorers.cc )
+add_library(NPSScorers SHARED NPSHitsMap.hh CalorimeterScorers.cc  SiliconScorers.cc PhotoDiodeScorers.cc ObsoleteGeneralScorers.cc DriftElectronScorers.cc MDMScorer.cc )
 target_link_libraries(NPSScorers ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPInitialConditions -lNPInteractionCoordinates)
diff --git a/NPSimulation/Scorers/DriftElectronScorers.cc b/NPSimulation/Scorers/DriftElectronScorers.cc
index 4c0548f425673d72e9cd3bbfe81496dfd4905aa3..2f66eaeece89e23770406a042565ed8307199fdf 100644
--- a/NPSimulation/Scorers/DriftElectronScorers.cc
+++ b/NPSimulation/Scorers/DriftElectronScorers.cc
@@ -40,11 +40,11 @@ G4bool PS_DECathode::ProcessHits(G4Step* aStep, G4TouchableHistory*){
   // contain Energy Time, DetNbr, StripFront and StripBack
   G4double* Infos = new G4double[9];
   Infos[0] = 0;
-  Infos[1] = aStep->GetPreStepPoint()->GetGlobalTime();
-  
+  Infos[1] = aStep->GetPreStepPoint()->GetProperTime();
+
   m_DetectorNumber = aStep->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(m_Level);
   m_Position  = aStep->GetPreStepPoint()->GetPosition();
-  
+
   // Interaction coordinates (used to fill the InteractionCoordinates branch)
   Infos[2] = m_Position.x();
   Infos[3] = m_Position.y();
@@ -52,10 +52,10 @@ G4bool PS_DECathode::ProcessHits(G4Step* aStep, G4TouchableHistory*){
   Infos[5] = m_Position.theta();
   Infos[6] = m_Position.phi();
   Infos[7] = m_DetectorNumber;
- 
+
   m_Index = m_DetectorNumber * 1e3 ;
   G4String PID = aStep->GetTrack()->GetDefinition()->GetParticleName();
-    
+
     if(PID=="driftelectron"){
         Infos[0] = 1;
     }
@@ -68,7 +68,7 @@ G4bool PS_DECathode::ProcessHits(G4Step* aStep, G4TouchableHistory*){
       Infos[0]+=dummy[0];
       Infos[1]=dummy[1];
     }
-  
+
   EvtMap->set(m_Index, Infos);
   return TRUE;
 }
@@ -92,13 +92,13 @@ void PS_DECathode::clear(){
   for (MapIterator = EvtMap->GetMap()->begin() ; MapIterator != EvtMap->GetMap()->end() ; MapIterator++){
     delete *(MapIterator->second);
   }
-  
+
   EvtMap->clear();
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 void PS_DECathode::DrawAll(){
-  
+
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -126,11 +126,11 @@ G4bool PS_DEDigitizer::ProcessHits(G4Step* aStep, G4TouchableHistory*){
   // contain Energy Time, DetNbr, StripFront and StripBack
   G4double* Infos = new G4double[9];
   Infos[0] = 0;
-  Infos[1] = aStep->GetPreStepPoint()->GetGlobalTime();
-  
+  Infos[1] = aStep->GetPreStepPoint()->GetProperTime();
+
   m_DetectorNumber = aStep->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(m_Level);
   m_Position  = aStep->GetPreStepPoint()->GetPosition();
-  
+
   // Interaction coordinates (used to fill the InteractionCoordinates branch)
   Infos[2] = m_Position.x();
   Infos[3] = m_Position.y();
@@ -138,10 +138,10 @@ G4bool PS_DEDigitizer::ProcessHits(G4Step* aStep, G4TouchableHistory*){
   Infos[5] = m_Position.theta();
   Infos[6] = m_Position.phi();
   Infos[7] = m_DetectorNumber;
- 
+
   m_Index =  aStep->GetTrack()->GetTrackID()  +  m_DetectorNumber*1e6 ;
   G4String PID = aStep->GetTrack()->GetDefinition()->GetParticleName();
-    
+
     if(PID=="driftelectron"){
         Infos[0] = 1;
     }
@@ -154,7 +154,7 @@ G4bool PS_DEDigitizer::ProcessHits(G4Step* aStep, G4TouchableHistory*){
       Infos[0]+=dummy[0];
       Infos[1]=dummy[1];
     }
-  
+
   EvtMap->set(m_Index, Infos);
   return TRUE;
 }
@@ -178,13 +178,13 @@ void PS_DEDigitizer::clear(){
   for (MapIterator = EvtMap->GetMap()->begin() ; MapIterator != EvtMap->GetMap()->end() ; MapIterator++){
     delete *(MapIterator->second);
   }
-  
+
   EvtMap->clear();
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 void PS_DEDigitizer::DrawAll(){
-  
+
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -194,5 +194,3 @@ void PS_DEDigitizer::PrintAll(){
   G4cout << " Number of entries " << EvtMap->entries() << G4endl     ;
 }
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-
-
diff --git a/NPSimulation/Scorers/MDMScorer.cc b/NPSimulation/Scorers/MDMScorer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..223f1f1b91148130660568a00a4e9695e7f8c896
--- /dev/null
+++ b/NPSimulation/Scorers/MDMScorer.cc
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2016   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Adrien MATTA  contact address: matta@lpccaen.in2p3.fr    *
+ *                                                                           *
+ * Creation Date  : January 2009                                             *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold some of the General Scorer, shared by different detector.*
+ *  Those scorer could be a could basis for your own scorer                  *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ * Those Scorer use TrackID as map index. This way ones can rebuild energy   *
+ *  deposit, time of flight or position,... particle by particle for each    *
+ *  event.Because standard scorer provide by G4 don't work this way but using*
+ *  a global ID for each event you should not use those scorer with some G4  *
+ *  provided ones or being very carefull doing so.                           *
+ *****************************************************************************/
+#include "MDMScorer.hh"
+#include "G4UnitsTable.hh"
+using namespace CLHEP;
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+//   The following function is used in many scorer. following the Detector Volume Nomenclature
+//   DetectorNameX_SubPart_SubPart
+//   where X stand for the detector number.
+
+namespace {
+  int PickUpDetectorNumber(G4Step* aStep, std::string DetName)
+  {
+    std::string name = aStep->GetTrack()->GetVolume()->GetName();
+    std::string nbr;
+    size_t start, end;
+    
+    start = name.find(DetName) + DetName.length();
+    end   = name.find("_");
+    
+    int numberOfCharacterInDetectorNumber = (int)end - (int)start;
+    
+    for (unsigned int i = start; i < start + numberOfCharacterInDetectorNumber; i++)
+      nbr += name[i];
+    
+    return atoi(nbr.c_str());
+  } }
+
+
+MDMScorer::MDMScorer(G4String name, G4String VolumeName, G4int depth)
+  : G4VPrimitiveScorer(name, depth), HCID(-1)
+{
+  m_VolumeName = VolumeName;
+}
+
+MDMScorer::~MDMScorer()
+{
+}
+
+G4bool MDMScorer::ProcessHits(G4Step* aStep, G4TouchableHistory*)
+{
+  int DetNumber = PickUpDetectorNumber(aStep, m_VolumeName) ;
+  G4int  index  = aStep->GetTrack()->GetTrackID();
+    
+  G4double edep = aStep->GetTotalEnergyDeposit();
+  G4double M = aStep->GetPreStepPoint()->GetMass();
+  G4double Q = aStep->GetPreStepPoint()->GetCharge();
+  G4ThreeVector POS  = aStep->GetPreStepPoint()->GetPosition();
+  G4ThreeVector MOM  = aStep->GetPreStepPoint()->GetMomentumDirection();
+  
+  MDMScorer::Infos info;
+  info.Edep   = edep/MeV;
+  info.Mass   = M;
+  info.Charge = Q;
+  info.Pos    = POS;
+  info.Mom    = MOM;
+  
+  EvtMap->add(index+DetNumber, info);
+  return TRUE;
+}
+
+void MDMScorer::Initialize(G4HCofThisEvent* HCE)
+{
+  EvtMap = new NPS::HitsMap<MDMScorer::Infos>
+    (GetMultiFunctionalDetector()->GetName(), GetName());
+  if (HCID < 0) {
+    HCID = GetCollectionID(0);
+  }
+  HCE->AddHitsCollection(HCID, (G4VHitsCollection*)EvtMap);
+}
+
+void MDMScorer::EndOfEvent(G4HCofThisEvent*)
+{
+  ;
+}
+
+void MDMScorer::clear()
+{
+  EvtMap->clear();
+}
+
+void MDMScorer::DrawAll()
+{
+  ;
+}
+
+void MDMScorer::PrintAll()
+{
+  // G4cout << " MultiFunctionalDet  " << detector->GetName() << G4endl;
+  // G4cout << " PrimitiveScorer " << GetName() << G4endl;
+  // G4cout << " Number of entries " << EvtMap->entries() << G4endl;
+  // std::map<G4int, G4double*>::iterator itr = EvtMap->GetMap()->begin();
+  // for (; itr != EvtMap->GetMap()->end(); itr++) {
+  //     G4cout << "  copy no.: " << itr->first
+  //     << "  energy deposit: " << G4BestUnit(*(itr->second), "Energy")
+  //     << G4endl;
+  // }
+}
diff --git a/NPSimulation/Scorers/MDMScorer.hh b/NPSimulation/Scorers/MDMScorer.hh
new file mode 100644
index 0000000000000000000000000000000000000000..683c820b191af3258ff986a47642df761b76f29f
--- /dev/null
+++ b/NPSimulation/Scorers/MDMScorer.hh
@@ -0,0 +1,51 @@
+#ifndef MDMScorer_h
+#define MDMScorer_h 1
+#include "G4VPrimitiveScorer.hh"
+#include "G4ThreeVector.hh"
+#include "NPSHitsMap.hh"
+using namespace CLHEP;
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......         
+class MDMScorer : public G4VPrimitiveScorer
+{
+
+public: // with description
+  MDMScorer(G4String name, G4String VolumeName, G4int depth);
+  virtual ~MDMScorer();
+
+protected: // with description
+  virtual G4bool ProcessHits(G4Step*, G4TouchableHistory*);
+
+public:
+  virtual void Initialize(G4HCofThisEvent*);
+  virtual void EndOfEvent(G4HCofThisEvent*);
+  virtual void clear();
+  virtual void DrawAll();
+  virtual void PrintAll();
+
+public:
+  struct Infos {
+    double Edep;
+    double Mass;
+    double Charge;
+    G4ThreeVector Pos;
+    G4ThreeVector Mom;
+    Infos& operator+=(const Infos& rhs)
+    {
+      // Only sum edep - leave others the same
+      // (want to be same as beginning of track)
+      Edep = Edep + rhs.Edep;
+      return *this;
+    }
+  };
+  
+private:
+  G4String m_VolumeName;
+  G4int HCID;
+  NPS::HitsMap<Infos>* EvtMap;
+};       
+
+
+
+
+#endif
diff --git a/Projects/Actar/Analysis.cxx b/Projects/Actar/Analysis.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..23c45664f868629cba52cf075ca4231dab73cd85
--- /dev/null
+++ b/Projects/Actar/Analysis.cxx
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2016    this file is part of the NPTool Project        *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: XAUTHORX  contact address: XMAILX                        *
+ *                                                                           *
+ * Creation Date  : XMONTHX XYEARX                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class describe  Actar analysis project                       *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *****************************************************************************/
+
+#include<iostream>
+using namespace std;
+#include"Analysis.h"
+#include"NPAnalysisFactory.h"
+#include"NPDetectorManager.h"
+////////////////////////////////////////////////////////////////////////////////
+Analysis::Analysis(){
+}
+////////////////////////////////////////////////////////////////////////////////
+Analysis::~Analysis(){
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Analysis::Init(){
+   Actar= (TActarPhysics*) m_DetectorManager->GetDetector("Actar");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Analysis::TreatEvent(){
+  //cout << "/// Size=" << Actar->PadRow.size() << endl;
+  for(unsigned int i=0; i<Actar->PadRow.size(); i++){
+    //cout << "Row= " << Actar->PadRow[i] << endl;
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Analysis::End(){
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//            Construct Method to be pass to the DetectorFactory              //
+////////////////////////////////////////////////////////////////////////////////
+NPL::VAnalysis* Analysis::Construct(){
+  return (NPL::VAnalysis*) new Analysis();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//            Registering the construct method to the factory                 //
+////////////////////////////////////////////////////////////////////////////////
+extern "C"{
+class proxy{
+  public:
+    proxy(){
+      NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct);
+    }
+};
+
+proxy p;
+}
diff --git a/Projects/Actar/Analysis.h b/Projects/Actar/Analysis.h
new file mode 100644
index 0000000000000000000000000000000000000000..075b9abe68fd6c3255f58bd01f22acbddee18ffd
--- /dev/null
+++ b/Projects/Actar/Analysis.h
@@ -0,0 +1,42 @@
+#ifndef Analysis_h 
+#define Analysis_h
+/*****************************************************************************
+ * Copyright (C) 2009-2016    this file is part of the NPTool Project        *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: XAUTHORX  contact address: XMAILX                        *
+ *                                                                           *
+ * Creation Date  : XMONTHX XYEARX                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class describe  Actar analysis project                       *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *****************************************************************************/
+
+#include"NPVAnalysis.h"
+#include"TActarPhysics.h"
+class Analysis: public NPL::VAnalysis{
+  public:
+    Analysis();
+    ~Analysis();
+
+  public: 
+    void Init();
+    void TreatEvent();
+    void End();
+
+   static NPL::VAnalysis* Construct();
+
+  private:
+   TActarPhysics* Actar;
+
+};
+#endif
diff --git a/Projects/Actar/CMakeLists.txt b/Projects/Actar/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..22c74affdfc45019bdda2594f8439c52d4ab97ec
--- /dev/null
+++ b/Projects/Actar/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required (VERSION 2.8) 
+# Setting the policy to match Cmake version
+cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
+# include the default NPAnalysis cmake file
+include("../../NPLib/ressources/CMake/NPAnalysis.cmake")
diff --git a/Projects/HiraU_experiment/.ls_return b/Projects/HiraU_experiment/.ls_return
index 6eb02b2613bfaf2946d0742a93989fef82426bc5..c40ba7451e09136b0f2db068aa7b0e9fb4d8552e 100644
--- a/Projects/HiraU_experiment/.ls_return
+++ b/Projects/HiraU_experiment/.ls_return
@@ -1 +1 @@
-../../Outputs/Simulation/ca40ni58_e140_b2.root
+../../Outputs/Simulation/ca40ni58_e50_b2.root
diff --git a/Projects/HiraU_experiment/Analysis.cxx b/Projects/HiraU_experiment/Analysis.cxx
index 8b49c4d2cfb6fdcc84c99ee7a5b01c087ba663fe..a09b52fa18bab8b31e52ae506000ffe16e5bfe2f 100644
--- a/Projects/HiraU_experiment/Analysis.cxx
+++ b/Projects/HiraU_experiment/Analysis.cxx
@@ -130,6 +130,7 @@ void Analysis::TreatEvent(){
     for(int i=0; i<FA->Energy.size(); i++){
         ThetaLabFA = InteractionCoordinates->GetDetectedAngleTheta(i);
         PhiLabFA = InteractionCoordinates->GetDetectedAnglePhi(i);
+        StartTimeFA = FA->Time[0];
     }
     
     FAMultiplicity = FA->DetectorNumber.size();
@@ -163,6 +164,7 @@ void Analysis::InitOutputBranch() {
     
     RootOutput::getInstance()->GetTree()->Branch("ThetaLabFA",&ThetaLabFA,"ThetaLabFA/D");
     RootOutput::getInstance()->GetTree()->Branch("PhiLabFA",&PhiLabFA,"PhiLabFA/D");
+    RootOutput::getInstance()->GetTree()->Branch("StartTimeFA",&StartTimeFA,"StartTimeFA/D");
     
     RootOutput::getInstance()->GetTree()->Branch("MBMultiplicity",&MBMultiplicity,"MBMultiplicity/I");
     RootOutput::getInstance()->GetTree()->Branch("NWMultiplicity",&NWMultiplicity,"NWMultiplicity/I");
@@ -200,6 +202,7 @@ void Analysis::ReInitValue(){
     EF              = -100;
     HiraELab        = -100;
     E_CsI           = -100;
+    StartTimeFA     = -100;
     
     FAMultiplicity  = -1;
     NWMultiplicity  = -1;
diff --git a/Projects/HiraU_experiment/Analysis.h b/Projects/HiraU_experiment/Analysis.h
index 545dc165f32a138a4d1472e3904e615377db45b2..67544bd735501b35944dcc7362c2756a1a78342b 100644
--- a/Projects/HiraU_experiment/Analysis.h
+++ b/Projects/HiraU_experiment/Analysis.h
@@ -59,6 +59,7 @@ private:
     int MBMultiplicity;
     int NWMultiplicity;
     int FAMultiplicity;
+    double StartTimeFA;
     double X_Hira;
     double Y_Hira;
     double Z_Hira;
diff --git a/Projects/HiraU_experiment/RunToTreat.txt b/Projects/HiraU_experiment/RunToTreat.txt
index 9a91e98a01774ba6e72dc27229314702cf7f85b8..40acab93914e12c670b25c79f80104d3d55b4be3 100755
--- a/Projects/HiraU_experiment/RunToTreat.txt
+++ b/Projects/HiraU_experiment/RunToTreat.txt
@@ -1,6 +1,6 @@
 TTreeName 
 	SimulatedTree
 RootFileName 
-  ../../Outputs/Simulation/ca40ni58_e140_b2.root
+  ../../Outputs/Simulation/ca40ni58_e50_b2.root
   %../../Outputs/Simulation/hiraU_12Cpp.root
   %../../Outputs/Simulation/hiraU_1Hpp.root
diff --git a/Projects/T40/Analysis.cxx b/Projects/T40/Analysis.cxx
index 2201d470a8ad77a986062657d2a17191f55463d4..b300a0f589a63c29a9f7483a0e7808aa657ab94e 100644
--- a/Projects/T40/Analysis.cxx
+++ b/Projects/T40/Analysis.cxx
@@ -120,7 +120,7 @@ void Analysis::Init(){
   //LightSi = NPL::EnergyLoss("He4_Si.SRIM","SRIM",10);
 
 //by Shuya 170530
-  LightCBacking = NPL::EnergyLoss(light+"_C.SRIM","SRIM",10);
+  //LightCBacking = NPL::EnergyLoss(light+"_C.SRIM","SRIM",10);
 
   BeamTarget = NPL::EnergyLoss(beam+"_"+TargetMaterial+".SRIM","SRIM",10);
   FinalBeamEnergy = BeamTarget.Slow(OriginalBeamEnergy, TargetThickness*0.5, 0);
@@ -141,8 +141,8 @@ void Analysis::Init(){
 
   //Original_ELab=0;
   //Original_ThetaLab=0;
-  XTarget =0;
-  YTarget =0;
+  XTarget =-1.026126;
+  YTarget =-2.3589;
   BeamDirection = TVector3(0,0,1);
   InitOutputBranch();
   InitInputBranch();
@@ -157,6 +157,7 @@ void Analysis::Init(){
 	Micro2_E_row1_2 = 0; // Energy from micromega rows 1-2  ("E in stopping mode")
   Micro1_E_row1 = 0 ;// Energy from micromega row 1
 //by Shuya 170912
+  //Micro1_E_col4 = 0 ;// energy from micromega col 4
   Micro1_E_col4_sum = 0 ;// energy from micromega col 4
   Plast_E = 0; // Energy Plastic
 	for(int i=0; i< kNumAw; ++i) {
@@ -195,7 +196,7 @@ void Analysis::Init(){
   Micro2_E_col4_mult = 0. ;// energy from micromega2 col 3
   Micro2_E_col5_mult = 0. ;// energy from micromega2 col 5
   Micro2_E_col6_mult = 0. ;// energy from micromega2 col 6
-  Micro2_E_col7_mult = 0. ;// energy from micromega2 col 6
+  Micro2_E_col7_mult = 0. ;// energy from micromega2 col 7
 
   //TAC
   TacSiGeOR     = -1000;
@@ -228,14 +229,14 @@ void Analysis::TreatEvent(){
     ThetaNormalTarget = 0;
     if(XTarget>-1000 && YTarget>-1000){
       //TVector3 BeamImpact(XTarget,YTarget,0);
-	//by Shuya 170807 (from 22Ne(d,d))
-      //TVector3 BeamImpact(-0.0781531, 3.12639, 4.27667);
 	//by Shuya 171020 from 22Ne(d,d) IB7,8 5 degrees adjustment
       //TVector3 BeamImpact(0.173098, 2.67341, 4.07383);
 	//by Shuya 171020 from 22Ne(d,d) IB7,8 5 degrees adjustment, but X, Y=0
       TVector3 BeamImpact(XTarget, YTarget, 4.07383);
 
-      TVector3 HitDirection = TH -> GetRandomisedPositionOfInteraction(countTiaraHyball) - BeamImpact ;
+	//by Shuya 171218 (because of T40 meeting's discussion)
+      //TVector3 HitDirection = TH -> GetRandomisedPositionOfInteraction(countTiaraHyball) - BeamImpact ;
+      TVector3 HitDirection = TH -> GetPositionOfInteraction(countTiaraHyball) - BeamImpact ;
 
       ThetaLab = HitDirection.Angle( BeamDirection );
       ThetaTHSurface = HitDirection.Angle(TVector3(0,0,-1)); // vector Normal on Hyball
@@ -244,6 +245,8 @@ void Analysis::TreatEvent(){
 	//by Shuya 171019
       PhiLab = HitDirection.Phi();
       PhiLab = PhiLab/(TMath::Pi())*180.0;
+	//by Shuya 171208
+      PhiLab_Hyball = PhiLab;
     }
     else{
       BeamDirection = TVector3(-1000,-1000,-1000);
@@ -254,10 +257,15 @@ void Analysis::TreatEvent(){
     /////////////////////////////
     // Part 2 : Impact Energy
     Energy = ELab = 0;
+//by Shuya 171206
+    ELab_Hyball = 0;
+
     Si_E_TH = TH->Strip_E[countTiaraHyball];
     Energy = Si_E_TH; // calibration for hyball is in MeV
     // Correct for energy loss using the thickness of the target and the dead layer
     ELab = LightSi.EvaluateInitialEnergy( Energy ,0.61*micrometer , ThetaTHSurface); // equivalent to 0.1 um of Aluminum
+//by Shuya 170530
+    //if(ThetaNormalTarget < halfpi)	ELab = LightCBacking.EvaluateInitialEnergy( ELab ,0.044*micrometer , ThetaNormalTarget); //10 ug/cm2 carbon
     ELab = LightTarget.EvaluateInitialEnergy( ELab ,TargetThickness/2., ThetaNormalTarget);
 
    /////////////////////////////
@@ -267,6 +275,9 @@ void Analysis::TreatEvent(){
     ThetaCM  = myReaction -> EnergyLabToThetaCM( ELab , ThetaLab)/deg;
     ThetaLab=ThetaLab/deg;
 
+//by Shuya 171206
+    ELab_Hyball = ELab;
+    ThetaLab_Hyball = ThetaLab;
 //by Shuya 170703
     Ex_Hyball = Ex;
 
@@ -287,14 +298,15 @@ void Analysis::TreatEvent(){
     ThetaNormalTarget = 0;
     if(XTarget>-1000 && YTarget>-1000){
       //TVector3 BeamImpact(XTarget,YTarget,0);
-	//by Shuya 170807 (from 22Ne(d,d))
-      //TVector3 BeamImpact(-0.0781531, 3.12639, 4.27667);
 	//by Shuya 171020 from 22Ne(d,d) IB7,8 5 degrees adjustment
       //TVector3 BeamImpact(0.173098, 2.67341, 4.07383);
 	//by Shuya 171020 from 22Ne(d,d) IB7,8 5 degrees adjustment, but X, Y=0
       TVector3 BeamImpact(XTarget, YTarget, 4.07383);
 
-      TVector3 HitDirection = TB -> GetRandomisedPositionOfInteraction(countTiaraBarrel) - BeamImpact ;
+	//by Shuya 171218 (because of T40 meeting's discussion)
+      //TVector3 HitDirection = TB -> GetRandomisedPositionOfInteraction(countTiaraBarrel) - BeamImpact ;
+      TVector3 HitDirection = TB -> GetPositionOfInteraction(countTiaraBarrel) - BeamImpact ;
+
       //Angle of emission wrt to beam
       ThetaLab = HitDirection.Angle( BeamDirection );
       ThetaNormalTarget = HitDirection.Angle( TVector3(0,0,1) ) ;
@@ -307,6 +319,8 @@ void Analysis::TreatEvent(){
 	//by Shuya 171019
       PhiLab = HitDirection.Phi();
       PhiLab = PhiLab/(TMath::Pi())*180.0;
+	//by Shuya 171208
+      PhiLab_Barrel = PhiLab;
     }
     else{
       BeamDirection = TVector3(-1000,-1000,-1000);
@@ -317,6 +331,9 @@ void Analysis::TreatEvent(){
     /////////////////////////////
     // Part 2 : Impact Energy
     Energy = ELab = 0;
+//by Shuya 171206
+    ELab_Barrel = 0;
+
     Si_E_InnerTB = TB->Strip_E[countTiaraBarrel];
     Energy = Si_E_InnerTB*keV;// calibration for barrel is in keV
     
@@ -327,10 +344,16 @@ void Analysis::TreatEvent(){
 	      Energy = Si_E_InnerTB*keV + Si_E_OuterTB*keV;
 	    }
 
+	//by Shuya 171208. If you need E+dE for Barrel.
+    for(unsigned int countTiaraOuterBarrel = 0 ; countTiaraOuterBarrel < TB->Outer_Strip_E.size() ; countTiaraOuterBarrel++){
+	    if(TB->Outer_Detector_N[countTiaraOuterBarrel]==TB->Detector_N[countTiaraBarrel] && TB->Outer_Strip_E[countTiaraOuterBarrel]>0){
+	      	Si_E_OuterTB = TB->Outer_Strip_E[countTiaraOuterBarrel];
+	        Energy = Si_E_InnerTB*keV + Si_E_OuterTB*keV;
+		}
+	}
+
     // Evaluate energy using the thickness, Target and Si dead layer Correction
     ELab = LightSi.EvaluateInitialEnergy( Energy ,0.3*micrometer, ThetaTBSurface);
-//by Shuya 170530
-    if(ThetaNormalTarget < halfpi)	ELab = LightCBacking.EvaluateInitialEnergy( ELab ,0.044*micrometer , ThetaNormalTarget); //10 ug/cm2 carbon
     ELab = LightTarget.EvaluateInitialEnergy( ELab ,TargetThickness/2., ThetaNormalTarget);
 
     /////////////////////////////
@@ -344,6 +367,10 @@ void Analysis::TreatEvent(){
     ThetaCM  = myReaction -> EnergyLabToThetaCM( ELab , ThetaLab)/deg;
     ThetaLab=ThetaLab/deg;
 
+//by Shuya 171206
+    ELab_Barrel = ELab;
+    ThetaLab_Barrel = ThetaLab;
+
     /////////////////////////////
     // Part 5 : Implementing randomised position impact matrix for both the entire Barrel (all 8 strips) and each strip making up the octagonal Barrel individually
     TVector3 BarrelRandomImpactPosition = TB -> GetRandomisedPositionOfInteraction(countTiaraBarrel);
@@ -493,9 +520,10 @@ void Analysis::TreatEvent(){
 	for(int i=0; i< kNumAw; ++i) {
 		if(Aw_X[i] != -1000) { ++numValid; }
 		if(numValid == 2) {  // at least 2 points to calculate an angle
-			Aw_ThetaFit = TF->AWireAngle*(180/TMath::Pi());
-			Aw_ThetaFit_R2 = TF->AWireFitR2;
+ 			Aw_ThetaFit = TF->AWireAngle*(180/TMath::Pi());
+ 			Aw_ThetaFit_R2 = TF->AWireFitR2;
 			break;
+
 		}
 	}
 
@@ -580,6 +608,12 @@ void Analysis::ReInitValue(){
   //Silicon
   Ex = -1000 ;
   ELab = -1000;
+//by Shuya 171206
+  ELab_Hyball = -1000;
+  ELab_Barrel = -1000;
+  ThetaLab_Hyball = -1000;
+  ThetaLab_Barrel = -1000;
+
   ThetaLab = -1000;
   ThetaCM = -1000;
   LightParticleDetected = false ;
@@ -587,7 +621,10 @@ void Analysis::ReInitValue(){
   Ex_Hyball = -1000 ;
   Ex_Barrel = -1000 ;
 //by Shuya 171019
-  PhiLab = -1000 ;
+  PhiLab = -1000;
+//by Shuya 171208
+  PhiLab_Hyball = -1000;
+  PhiLab_Barrel = -1000;
 
   //Simu
   //Original_ELab = -1000;
@@ -633,6 +670,7 @@ void Analysis::ReInitValue(){
   Micro2_E_col6_mult = -1000;
   Micro2_E_col7_mult = -1000;
 
+
 	for(int i=0; i< kNumAw; ++i) {
 		Aw_X[i] = -1000;
 		Aw_X[i] = -1000;
@@ -664,10 +702,20 @@ void Analysis::InitOutputBranch() {
   RootOutput::getInstance()->GetTree()->Branch("Ex_Barrel",&Ex_Barrel,"Ex_Barrel/D");
 
   RootOutput::getInstance()->GetTree()->Branch("ELab",&ELab,"ELab/D");
+//by Shuya 171206
+  RootOutput::getInstance()->GetTree()->Branch("ELab_Hyball",&ELab_Hyball,"ELab_Hyball/D");
+  RootOutput::getInstance()->GetTree()->Branch("ELab_Barrel",&ELab_Barrel,"ELab_Barrel/D");
+
   RootOutput::getInstance()->GetTree()->Branch("ThetaLab",&ThetaLab,"ThetaLab/D");
+//by Shuya 171206
+  RootOutput::getInstance()->GetTree()->Branch("ThetaLab_Hyball",&ThetaLab_Hyball,"ThetaLab_Hyball/D");
+  RootOutput::getInstance()->GetTree()->Branch("ThetaLab_Barrel",&ThetaLab_Barrel,"ThetaLab_Barrel/D");
+
   RootOutput::getInstance()->GetTree()->Branch("ThetaCM",&ThetaCM,"ThetaCM/D");
 //by Shuya 171019
   RootOutput::getInstance()->GetTree()->Branch("PhiLab",&PhiLab,"PhiLab/D");
+  RootOutput::getInstance()->GetTree()->Branch("PhiLab_Hyball",&PhiLab_Hyball,"PhiLab_Hyball/D");
+  RootOutput::getInstance()->GetTree()->Branch("PhiLab_Barrel",&PhiLab_Barrel,"PhiLab_Barrel/D");
 
   RootOutput::getInstance()->GetTree()->Branch("TiaraImpactMatrixX",&TiaraIMX,"TiaraImpactMatrixX/D");
   RootOutput::getInstance()->GetTree()->Branch("TiaraImpactMatrixY",&TiaraIMY,"TiaraImpactMatrixY/D");
@@ -723,7 +771,6 @@ void Analysis::InitOutputBranch() {
   RootOutput::getInstance()->GetTree()->Branch("Micro2_E_col6_mult",&Micro2_E_col6_mult,"Micro2_E_col6_mult/D");
   RootOutput::getInstance()->GetTree()->Branch("Micro2_E_col7_mult",&Micro2_E_col7_mult,"Micro2_E_col7_mult/D");
 
-
 //TACS
   RootOutput::getInstance()->GetTree()->Branch("TacSiGeOR",&TacSiGeOR,"TacSiGeOR/D");
 	RootOutput::getInstance()->GetTree()->Branch("TacSiMicro",&TacSiMicro,"TacSiMicro/D");
diff --git a/Projects/T40/Analysis.h b/Projects/T40/Analysis.h
index 5d31cd9146bff1fe524cb17e2c0ffd814be3510e..938e3fffcaf5d740e2ebfe36e8a2d2f1334d30a0 100644
--- a/Projects/T40/Analysis.h
+++ b/Projects/T40/Analysis.h
@@ -27,6 +27,7 @@
 #include "TTiaraBarrelPhysics.h"
 #include "TFPDTamuPhysics.h"
 #include "TGeTAMUPhysics.h"
+#include "TMDMPhysics.h"
 #include "TInitialConditions.h"
 #include "NPEnergyLoss.h"
 #include "NPReaction.h"
@@ -36,6 +37,8 @@
 #include <TMath.h>
 #include <TObject.h>
 
+namespace NPL { class VDetector; }
+
 
 class Analysis: public NPL::VAnalysis{
   public:
@@ -50,7 +53,7 @@ class Analysis: public NPL::VAnalysis{
     void InitOutputBranch();
     void InitInputBranch();
     static NPL::VAnalysis* Construct();
-    
+
   private:
   double Ex;
 //by Shuya 170703
@@ -68,6 +71,9 @@ class Analysis: public NPL::VAnalysis{
   bool LightParticleDetected;
 //by Shuya 171019
   double PhiLab;
+// GAC 171020
+	double ThetaXLab;
+	double ThetaYLab;
 
  
   //	Energy loss table: the G4Table are generated by the simulation
@@ -85,6 +91,8 @@ class Analysis: public NPL::VAnalysis{
   TTiaraBarrelPhysics* TB;  
   TFPDTamuPhysics* TF;
   TGeTAMUPhysics* TG;
+	TMDMPhysics* MDM;
+	bool MDM_in_file; //!
 
   TRandom *Rand ;
 	double ThetaNormalTarget  ;
diff --git a/Projects/T40/T40.detector b/Projects/T40/T40.detector
index 0b45e7a46bc9b9765ec61c49b816108165e67c21..61418ca7d8fc99d4beb4b8b1d0aa493e8fc498b8 100644
--- a/Projects/T40/T40.detector
+++ b/Projects/T40/T40.detector
@@ -4,12 +4,18 @@ GeneralTarget
 %0.03mg/cm2
 Target
  THICKNESS= 0.1132 micrometer 
- RADIUS=	5 mm
- MATERIAL= 6LiF
+ RADIUS=10 mm
+ MATERIAL= CD2
  ANGLE= 0 deg
  X= 0 mm
  Y= 0 mm
  Z= 0 mm
+MDM
+ Angle= 0 deg
+ Field= 6248.26 gauss
+ XAccept= 2.0 deg
+ YAccept= 2.0 deg
+ Rayin= ../../Inputs/DetectorConfiguration/rayin-t4t.dat
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 Tiara Barrel
  InnerBarrel= 1
diff --git a/Projects/T40/npanalysis-parallel b/Projects/T40/npanalysis-parallel
new file mode 100755
index 0000000000000000000000000000000000000000..f3d6b923199e0eecda8d52b61300d7627223c7d2
--- /dev/null
+++ b/Projects/T40/npanalysis-parallel
@@ -0,0 +1,176 @@
+#!/usr/bin/env python
+import os
+from sys import argv
+import ROOT as r
+from multiprocessing import Process
+from subprocess import call, check_output, STDOUT
+
+
+def merge_files(nthreads, fname):
+    fname = os.environ['NPTOOL'] + '/Outputs/Analysis/' + fname
+    chain = r.TChain("PhysicsTree")
+    for i in range(0, nthreads):
+        foutcmd = fname + '_' + str(i) + '.root'
+        chain.AddFile(foutcmd)
+    fout = r.TFile(fname + '.root', "recreate")
+    tout = chain.CopyTree("")
+    tout.Write()
+
+    # Global stuff
+    f0 = r.TFile.Open(fname + '_0.root')
+    fout.cd()
+    for k in f0.GetListOfKeys():
+        obj = f0.Get(k.GetName())
+        if obj.InheritsFrom("TTree") == False:
+            obj.Write(obj.GetName())
+    fout.Close()
+    f0.Close()
+
+    for i in range(0, nthreads):
+        foutcmd = fname + '_' + str(i) + '.root'
+        call(['rm', '-f', foutcmd])
+
+def run_npanalysis(args, redirect):
+    cmd = ['npanalysis']
+    f = open(os.devnull, 'w')
+    for a in args:
+        cmd.append(a)
+    if(redirect):
+        call(cmd, stdout=f, stderr=f)
+    else:
+        call(cmd)
+    f.close()
+
+
+def compile_num_entries():
+    f=open('/tmp/numEntries.cxx','w')
+    f.write('#include <iostream>\n')
+    f.write('#include \"RootInput.h\"\n')
+    f.write('int main(int argc , char** argv){std::cerr << RootInput::getInstance(argv[1])->GetChain()->GetEntries() << std::endl;}\n')
+    f.close()
+
+    rflags = check_output(['root-config', '--cflags', '--libs'])
+    callflags = ['c++', '/tmp/numEntries.cxx', '-o', '/tmp/numEntries', '-L' + os.environ['NPTOOL'] + '/NPLib/lib/', '-l' + 'NPCore', '-I' + os.environ['NPTOOL'] + '/NPLib/include']
+    call(callflags + rflags.split()) # compile
+
+    
+def get_num_entries(argv_):
+    compile_num_entries()
+    runF = 'defaultRunToTreat.txt'
+    for i in range(0, len(argv_)):
+        if argv_[i] == '-R':
+            runF = argv_[i+1]
+            
+    out=check_output(['/tmp/numEntries', runF], stderr=STDOUT)
+    out=out[0:out.rfind('\n')]
+    out=out[out.rfind('\n')+1:]
+    call(['rm', '-f', '/tmp/numEntries.cxx', '/tmp/numEntries'])
+    return long(out)
+
+    
+def run_npanalysis_parallel(nthreads, argv_):
+    nentries = get_num_entries(argv_)
+    nPerThread = nentries / nthreads
+    
+    oPos = 0
+    fout = ''
+    for i in range(0,len(argv_)):
+        if(argv_[i] == '-O'):
+            oPos = i+1
+            fout = argv_[i+1]
+            if(fout[-5:] == '.root'):
+                fout = fout[0:-5]
+    if oPos == 0:
+        fout = 'PhysicsTree'
+        argv_.append("-O")
+        argv_.append("PhysicsTree.root")
+        oPos = len(argv) - 1
+            
+    processes = []
+    for i in range(0, nthreads):
+        these_args = argv_
+        these_args[oPos] = fout + '_' + str(i) + '.root'
+        these_args = these_args[1:]
+
+        start = i*nPerThread
+        stop = (i+1)*nPerThread
+        if stop > nentries:
+            stop=nentries
+        these_args.append('-F')
+        these_args.append(str(start))
+        these_args.append('-L')
+        these_args.append(str(nPerThread))
+        
+        if( i > 0):
+            p = Process(target=run_npanalysis, args=(these_args,True,))
+        else:
+            p = Process(target=run_npanalysis, args=(these_args,False,))
+        processes.append(p)
+    for p in processes:
+        p.start()
+    for p in processes:
+        p.join()
+
+    merge_files(nthreads, fout)
+
+
+def help():
+    print '********************************************************************************'
+    print '***********************************  NPTool  ***********************************'
+    print '********************************************************************************'
+    print 'NPLib version: nplib-2-2-45\nCopyright: NPTool Collaboration\nGitHub: http://github.com/adrien-matta/nptool'
+    print '********************************************************************************'
+    print ''
+    print '----NPOptionManager Help----'
+    print ''
+    print 'List of Option'
+    print '--help -H -h                    Display this help message'
+    print '--detector  -D <arg>            Set arg as the detector configuration file'
+    print '--event-generator  -E <arg>     Set arg as the event generator file'
+    print '--output  -O <arg>              Set arg as the Output File Name (output tree)'
+    print '--tree-name <arg>               Set arg as the Output Tree Name'
+    print '--verbose -V <arg>              Set the verbose level, 0 for nothing, 1 for normal printout.'
+    print '                                Error and warning are not affected'
+    print ''
+    print 'NPAnalysis only:'
+    print '--nthreads -N <arg>             Set arg as the number of parallel jobs (default is 1)'
+    print '--run -R <arg>                  Set arg as the run to read file list'
+    print '--cal -C <arg>                  Set arg as the calibration file list'
+    print '--disable-branch                Disable of branch of Input tree except the one of the detector (faster)'
+    print '--generate-histo -GH            Instantiate the T*Spectra class of each detector'
+    print '--check-histo -CH               Check if the Histogram looks ok and change there color if not'
+    print '--input-physical -IP            Consider the Input file is containing Physics Class.'
+    print '-L <arg>                        Limit the number of events to be analysed to arg'
+    print '-F <arg>                        Set the first event to analyse to arg (analysis goes from F -> L+F)'
+    print '--last-sim                      Ignore the list of Run to treat if any and analysed the last simulated file'
+    print '--last-phy                      Ignore the list of Run to treat if any and analysed the last Physics file'
+    print '--last-res                      Ignore the list of Run to treat if any and analysed the last Result file'
+    print '--last-any                      Ignore the list of Run to treat if any and analysed the last generated root file'
+    print '--online                        Start the spectra server'
+    print ''
+    print 'NPSimulation only:'
+    print '-M <arg>                        Execute Geant4 macro <arg> at startup'
+    print '-B <arg>                        Execute in batch mode (no ui) with Geant4 macro <arg> at startup'
+    
+
+
+if __name__ == '__main__':
+    nthreads = 1
+    argv1 = []
+
+    iGen = (i for i in range(0,len(argv)))
+    for i in iGen:
+        if argv[i] == '-N' or argv[i] == '--nthreads':
+            iGen.next()
+            nthreads = int(argv[i+1])
+        elif argv[i] == '--help' or argv[i] == '-h' or argv[i] == '-H':
+            help()
+            exit()
+        else:
+            argv1.append(argv[i])
+            
+    if nthreads == 1:
+        run_npanalysis(argv1, True)
+    else:
+        run_npanalysis_parallel(nthreads, argv1)
+