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) +