#include "R3BNeutronTracker.h" #include "TClonesArray.h" #include "FairRootManager.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" // includes for modeling #include "TGeoManager.h" #include "TParticle.h" #include "TVirtualMC.h" #include "TGeoMatrix.h" #include "TGeoMaterial.h" #include "TGeoMedium.h" #include "TGeoBBox.h" #include "TGeoCompositeShape.h" #include "TGeoShapeAssembly.h" #include "TVector3.h" #include "TMath.h" #include "TRandom.h" #include "TH1F.h" #include "TH2F.h" #include #include #include "R3BLandPoint.h" #include "R3BLandDigi.h" #include "R3BMCTrack.h" #include "R3BNeutronTrack.h" #include "R3BLandFirstHits.h" using std::cout; using std::endl; R3BNeutronTracker::R3BNeutronTracker() : FairTask("R3B Land Digitization scheme ") { } R3BNeutronTracker::~R3BNeutronTracker() { } void R3BNeutronTracker::SetParContainers() { // Get run and runtime database FairRunAna* run = FairRunAna::Instance(); if ( ! run ) Fatal("SetParContainers", "No analysis run"); FairRuntimeDb* rtdb = run->GetRuntimeDb(); if ( ! rtdb ) Fatal("SetParContainers", "No runtime database"); fLandDigiPar = (R3BLandDigiPar*)(rtdb->getContainer("R3BLandDigiPar")); if ( fLandDigiPar ) { cout << "-I- R3BLandDigitizer::SetParContainers() "<< endl; cout << "-I- Container R3BLandDigiPar loaded " << endl; } } InitStatus R3BNeutronTracker::Init() { // Get input array FairRootManager* ioman = FairRootManager::Instance(); if ( ! ioman ) Fatal("Init", "No FairRootManager"); fLandPoints = (TClonesArray*) ioman->GetObject("LandPoint"); fLandMCTrack = (TClonesArray*) ioman->GetObject("MCTrack"); fLandDigi = (TClonesArray*) ioman->GetObject("LandDigi"); fLandFirstHits = (TClonesArray*) ioman->GetObject("LandFirstHits"); // New structure created by the Neutron Tracker fNeutronTracks = new TClonesArray("R3BNeutronTrack"); ioman->Register("LandNeTracks", "Neutron Tracks", fNeutronTracks, kTRUE); npaddles = fLandDigiPar->GetMaxPaddle()+1; nplanes = fLandDigiPar->GetMaxPlane(); cout<<"# paddles: "<GetXaxis()->SetTitle("Number of Neutrons"); hNeutmult->GetYaxis()->SetTitle("Counts"); hErel1 = new TH1F("Erel1","Erel for 1 neutron",400,0.,40.); hErel1->GetXaxis()->SetTitle("Erel (MeV)"); hErel1->GetYaxis()->SetTitle("Counts"); hErel2 = new TH1F("Erel2","Erel for 2 neutron",400,0.,40.); hErel2->GetXaxis()->SetTitle("Erel (MeV)"); hErel2->GetYaxis()->SetTitle("Counts"); hErel3 = new TH1F("Erel3","Erel for 3 neutron",400,0.,40.); hErel3->GetXaxis()->SetTitle("Erel (MeV)"); hErel3->GetYaxis()->SetTitle("Counts"); hErel4 = new TH1F("Erel4","Erel for 4 neutron",400,0.,40.); hErel4->GetXaxis()->SetTitle("Erel (MeV)"); hErel4->GetYaxis()->SetTitle("Counts"); hMinv = new TH1F("Minv","Minv for reconstructed hits",400,0.,40.); hMinv->GetXaxis()->SetTitle("Erel (MeV)"); hMinv->GetYaxis()->SetTitle("Counts"); hMinv1 = new TH1F("Minv1","Minv for first hits",400,0.,40.); hMinv1->GetXaxis()->SetTitle("Erel (MeV)"); hMinv1->GetYaxis()->SetTitle("Counts"); hMinv2 = new TH1F("Minv2","Minv for selected hits",400,0.,40.); hMinv2->GetXaxis()->SetTitle("Erel (MeV)"); hMinv2->GetYaxis()->SetTitle("Counts"); hMinv0 = new TH1F("Minv0","Minv for ideal hits",400,0.,40.); hMinv0->GetXaxis()->SetTitle("Erel (MeV)"); hMinv0->GetYaxis()->SetTitle("Counts"); hDeltaX = new TH1F("DeltaX","error in x determination",300,-150.,150.); hDeltaX->GetXaxis()->SetTitle("x position (cm)"); hDeltaX->GetYaxis()->SetTitle("Counts"); hDeltaY = new TH1F("DeltaY","error in y determination",300,-150.,150.); hDeltaY->GetXaxis()->SetTitle("y position (cm)"); hDeltaY->GetYaxis()->SetTitle("Counts"); hDeltaZ = new TH1F("DeltaZ","error in z determination",500,-250.,250.); hDeltaZ->GetXaxis()->SetTitle("z position (cm)"); hDeltaZ->GetYaxis()->SetTitle("Counts"); hDeltaT = new TH1F("DeltaT","error in time determination",2000,-10.,10.); hDeltaT->GetXaxis()->SetTitle("time (ns)"); hDeltaT->GetYaxis()->SetTitle("Counts"); hDeltaP1 = new TH1F("DeltaP1","difference in reconstucted momenta for 1st neutron)",1000,-150.,150.); hDeltaP1->GetXaxis()->SetTitle("Delta P (MeV/c)"); hDeltaP1->GetYaxis()->SetTitle("Counts"); hDeltaP2 = new TH1F("DeltaP2","difference in reconstucted momenta for 2nd neutron)",1000,-150.,150.); hDeltaP2->GetXaxis()->SetTitle("Delta P (MeV/c)"); hDeltaP2->GetYaxis()->SetTitle("Counts"); hDeltaP3 = new TH1F("DeltaP3","difference in reconstucted momenta for 3rd neutron)",1000,-150.,150.); hDeltaP3->GetXaxis()->SetTitle("Delta P (MeV/c)"); hDeltaP3->GetYaxis()->SetTitle("Counts"); hDeltaP4 = new TH1F("DeltaP4","difference in reconstucted momenta for 4th neutron)",1000,-150.,150.); hDeltaP4->GetXaxis()->SetTitle("Delta P (MeV/c)"); hDeltaP4->GetYaxis()->SetTitle("Counts"); hDeltaP5 = new TH1F("DeltaP5","difference in reconstucted momenta for 5th neutron)",1000,-150.,150.); hDeltaP5->GetXaxis()->SetTitle("Delta P (MeV/c)"); hDeltaP5->GetYaxis()->SetTitle("Counts"); hDeltaP6 = new TH1F("DeltaP6","difference in reconstucted momenta for 6th neutron)",1000,-150.,150.); hDeltaP6->GetXaxis()->SetTitle("Delta P (MeV/c)"); hDeltaP6->GetYaxis()->SetTitle("Counts"); hDeltaPx1 = new TH1F("DeltaPx1","difference in reconstucted momenta px (ideal case)",1000,-50.,50.); hDeltaPx1->GetXaxis()->SetTitle("Delta Px (MeV/c)"); hDeltaPx1->GetYaxis()->SetTitle("Counts"); hDeltaPy1 = new TH1F("DeltaPy1","difference in reconstucted momenta py (ideal case)",1000,-50.,50.); hDeltaPy1->GetXaxis()->SetTitle("Delta Py (MeV/c)"); hDeltaPy1->GetYaxis()->SetTitle("Counts"); hDeltaPz1 = new TH1F("DeltaPz1","difference in reconstucted momenta pz (ideal case)",1000,-150.,150.); hDeltaPz1->GetXaxis()->SetTitle("Delta Pz (MeV/c)"); hDeltaPz1->GetYaxis()->SetTitle("Counts"); hDeltaPx2 = new TH1F("DeltaPx2","difference in reconstucted momenta px (exp case)",1000,-50.,50.); hDeltaPx2->GetXaxis()->SetTitle("Delta Px (MeV/c)"); hDeltaPx2->GetYaxis()->SetTitle("Counts"); hDeltaPy2 = new TH1F("DeltaPy2","difference in reconstucted momenta py (exp case)",1000,-50.,50.); hDeltaPy2->GetXaxis()->SetTitle("Delta Py (MeV/c)"); hDeltaPy2->GetYaxis()->SetTitle("Counts"); hDeltaPz2 = new TH1F("DeltaPz2","difference in reconstucted momenta pz (exp case)",1000,-150.,150.); hDeltaPz2->GetXaxis()->SetTitle("Delta Pz (MeV/c)"); hDeltaPz2->GetYaxis()->SetTitle("Counts"); hClusterSize = new TH1F("ClusterSize","number of paddles in a cluster",500,0.,500); hClusterSize->GetXaxis()->SetTitle("Cluster Size"); hClusterSize->GetYaxis()->SetTitle("Counts"); hClusterEnergy = new TH1F("ClusterEnergy","Cluster energy",5000,0.,500); hClusterEnergy->GetXaxis()->SetTitle("Energy (MeV)"); hClusterEnergy->GetYaxis()->SetTitle("Counts"); hHits = new TH1F("Hits","Number of hits in one event",500,0.,500); hHits->GetXaxis()->SetTitle("number of hits"); hHits->GetYaxis()->SetTitle("Counts"); hClusters = new TH1F("Cluster","Number of clusters in one event",100,0.,100); hClusters->GetXaxis()->SetTitle("number of clusters"); hClusters->GetYaxis()->SetTitle("Counts"); hClusters1 = new TH1F("Cluster1","Number of clusters after eliminating elastic scattering",100,-0.5,99.5); hClusters1->GetXaxis()->SetTitle("number of clusters"); hClusters1->GetYaxis()->SetTitle("Counts"); hClusters2 = new TH1F("Cluster2","Number of clusters after deleting low energy and late events",100,-0.5,99.5); hClusters2->GetXaxis()->SetTitle("number of clusters"); hClusters2->GetYaxis()->SetTitle("Counts"); hClusterNo_vs_Size = new TH2F("hClusterNo_vs_Size","Cluster length vs. Size",100,0.,100,100,0.,100); hClusterNo_vs_Size->GetXaxis()->SetTitle("Total cluster length"); hClusterNo_vs_Size->GetYaxis()->SetTitle("No of clusters"); hDelta = new TH1F("Delta","distance between two primary interactions",300,-150.,150.); hDelta->GetXaxis()->SetTitle("distance (cm)"); hDelta->GetYaxis()->SetTitle("Counts"); hFirstHitZ = new TH1F("FirstHitZ","z positions of first hits",200,1000.,2000.); hFirstHitZ->GetXaxis()->SetTitle("z position (cm)"); hFirstHitZ->GetYaxis()->SetTitle("Counts"); return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- void R3BNeutronTracker::Exec(Option_t* opt) { //-Reset entries in output arrays //-Reset local arrays Reset(); eventNo+=1; if(eventNo/1000. == (int)eventNo/1000.) cout<<"Neutron #: "<GetEntries(); Double_t temp[npaddles][14]; Int_t nPrim=0; Int_t nPrimNeutrons=0; Double_t momentumT[10],momentumX[10],momentumY[10],momentumZ[10],energy[10]; Double_t beta[10], gamma[10],rr,s; Double_t sum_momentumX,sum_momentumY,sum_momentumZ,sum_masses,sum_energy; Double_t betaNeutron,E_lab,pnzcm; Double_t Egamma=0; Double_t gamma_px=0.; Double_t gamma_py=0.; Double_t gamma_pz=0.; Double_t m_proj=67.93187*amu; // Get parameter from original neutrons and fragment // Access to Monte Carlo Info // get object from the TclonesArray at index=TrackID R3BMCTrack *aTrack1 = (R3BMCTrack*) fLandMCTrack->At(0); Int_t prim = aTrack1->GetMotherId(); while (prim < 0 ) { Int_t particleID = aTrack1->GetPdgCode(); /* cout << "primary particle " << PRIM_part[nPrim].pdg<<" "<< endl; cout << "mass " << PRIM_part[nPrim].M<< endl; cout << "px, py, pz " << PRIM_part[nPrim].px << " " << PRIM_part[nPrim].py << " " << PRIM_part[nPrim].pz << endl; cout << "Ptransversal, P total " << PRIM_part[nPrim].pt << " " << PRIM_part[nPrim].p << endl; */ if(particleID==2112){ //neutron PRIM_part[nPrim].M = aTrack1->GetMass()*1000.; PRIM_part[nPrim].A=1.0086649; PRIM_part[nPrim].M=PRIM_part[nPrim].A*amu; PRIM_part[nPrim].pdg = aTrack1->GetPdgCode(); PRIM_part[nPrim].px = aTrack1->GetPx()*1000.; PRIM_part[nPrim].py = aTrack1->GetPy()*1000.; PRIM_part[nPrim].pz = aTrack1->GetPz()*1000.; PRIM_part[nPrim].pt = aTrack1->GetPt()*1000.; PRIM_part[nPrim].p = aTrack1->GetP()*1000.; PRIM_part[nPrim].x = aTrack1->GetStartX(); PRIM_part[nPrim].y = aTrack1->GetStartY(); PRIM_part[nPrim].z = aTrack1->GetStartZ(); PRIM_part[nPrim].t = aTrack1->GetStartT(); nPrimNeutrons=nPrimNeutrons+1; } else if(particleID==2212){ //proton PRIM_part[nPrim].M = aTrack1->GetMass()*1000.; PRIM_part[nPrim].A=1.0072765; PRIM_part[nPrim].M=PRIM_part[nPrim].A*amu; PRIM_part[nPrim].pdg = aTrack1->GetPdgCode(); PRIM_part[nPrim].px = aTrack1->GetPx()*1000.; PRIM_part[nPrim].py = aTrack1->GetPy()*1000.; PRIM_part[nPrim].pz = aTrack1->GetPz()*1000.; PRIM_part[nPrim].pt = aTrack1->GetPt()*1000.; PRIM_part[nPrim].p = aTrack1->GetP()*1000.; PRIM_part[nPrim].x = aTrack1->GetStartX(); PRIM_part[nPrim].y = aTrack1->GetStartY(); PRIM_part[nPrim].z = aTrack1->GetStartZ(); PRIM_part[nPrim].t = aTrack1->GetStartT(); } else if(particleID==22){ //gamma PRIM_gamma[0].M = aTrack1->GetMass(); // PRIM_gamma[0].A=0; // PRIM_gamma[0].M=PRIM_gamma[nPrim].A*amu; PRIM_gamma[0].pdg = aTrack1->GetPdgCode(); PRIM_gamma[0].px = aTrack1->GetPx()*1000.; PRIM_gamma[0].py = aTrack1->GetPy()*1000.; PRIM_gamma[0].pz = aTrack1->GetPz()*1000.; PRIM_gamma[0].pt = aTrack1->GetPt()*1000.; PRIM_gamma[0].p = aTrack1->GetP()*1000.; PRIM_gamma[0].x = aTrack1->GetStartX(); PRIM_gamma[0].y = aTrack1->GetStartY(); PRIM_gamma[0].z = aTrack1->GetStartZ(); PRIM_gamma[0].t = aTrack1->GetStartT(); cout<<"gamma "<< PRIM_gamma[0].px<< " " << PRIM_gamma[0].py<<" "<GetMass(); // cout<<"prim M "<GetPdgCode(); PRIM_frag[0].px = aTrack1->GetPx()*1000.; PRIM_frag[0].py = aTrack1->GetPy()*1000.; PRIM_frag[0].pz = aTrack1->GetPz()*1000.; PRIM_frag[0].pt = aTrack1->GetPt()*1000.; PRIM_frag[0].p = aTrack1->GetP()*1000.; PRIM_frag[0].x = aTrack1->GetStartX(); PRIM_frag[0].y = aTrack1->GetStartY(); PRIM_frag[0].z = aTrack1->GetStartZ(); PRIM_frag[0].t = aTrack1->GetStartT(); } nPrim=nPrim+1; aTrack1 = (R3BMCTrack*) fLandMCTrack->At(nPrim); if (aTrack1!=0) prim = aTrack1->GetMotherId(); else prim= 1; } Double_t sumTotalEnergy=0; for (Int_t l=0;lAt(l); temp[l][0] = int(land_obj->GetPaddleNr())-1; //note that paddle starts at 1 temp[l][1] = land_obj->GetTdcL(); temp[l][2] = land_obj->GetTdcR(); temp[l][3] = land_obj->GetTdc(); temp[l][4] = land_obj->GetQdcL(); temp[l][5] = land_obj->GetQdcR(); temp[l][6] = land_obj->GetQdc(); temp[l][7] = land_obj->GetXX(); temp[l][8] = land_obj->GetYY(); temp[l][9] = land_obj->GetZZ(); sumTotalEnergy += temp[l][6]; }//loop over entries // Get first hits for comparison later Double_t firstHitX[6],firstHitY[6],firstHitZ[6],firstT[6]; // Int_t nentr = fLandFirstHits->GetEntries(); // cout<<"entries: "<At(0); firstHitX[0] = land_obj1->GetX0(); firstHitY[0] = land_obj1->GetY0(); firstHitZ[0] = land_obj1->GetZ0(); firstT[0] = 1.E9*land_obj1->GetT0(); firstHitX[1] = land_obj1->GetX1(); firstHitY[1] = land_obj1->GetY1(); firstHitZ[1] = land_obj1->GetZ1(); firstT[1] = 1.E9*land_obj1->GetT1(); firstHitX[2] = land_obj1->GetX2(); firstHitY[2] = land_obj1->GetY2(); firstHitZ[2] = land_obj1->GetZ2(); firstT[2] = 1.E9*land_obj1->GetT2(); firstHitX[3] = land_obj1->GetX3(); firstHitY[3] = land_obj1->GetY3(); firstHitZ[3] = land_obj1->GetZ3(); firstT[3] = 1.E9*land_obj1->GetT3(); firstHitX[4] = land_obj1->GetX4(); firstHitY[4] = land_obj1->GetY4(); firstHitZ[4] = land_obj1->GetZ4(); firstT[4] = 1.E9*land_obj1->GetT4(); firstHitX[5] = land_obj1->GetX5(); firstHitY[5] = land_obj1->GetY5(); firstHitZ[5] = land_obj1->GetZ5(); firstT[5] = 1.E9*land_obj1->GetT5(); for (Int_t l=0;lFill(firstHitZ[l]); for (Int_t k=l+1;kFill(dist); } } if(printing){ for (Int_t l=0;l<6;l++){ cout<<"First Hits: "<< firstHitX[l]<<" "<Fill(nentries); if (nentries>0) { for (Int_t l=0;l=0.0 && delt<1.0){ // This is a neighbor // check if this cluster already exists if(temp[l][6]>0){ if(l!=k){ // inside cluster Int_t clusNo=(int)temp[l][6]; if(printing){ cout<<"Neighbor paddle "<< temp[k][5]<Cluster[clusNo-1].tStop){ Cluster[clusNo-1].tStop = temp[k][3]; Cluster[clusNo-1].xEnd = temp[k][0]; Cluster[clusNo-1].yEnd = temp[k][1]; Cluster[clusNo-1].zEnd = temp[k][2]; } } } else{ // new cluster Nclusters+=1; // cout<<"New cluster "<< Nclusters <Fill(Nclusters); Double_t MaxSize=0; Double_t MaxEnergy=0; for (Int_t i=0;iMaxSize) MaxSize=Cluster[i].size; if(Cluster[i].e>MaxEnergy) MaxEnergy=Cluster[i].e; // hClusterSize->Fill(Cluster[i].size); hClusterEnergy->Fill(Cluster[i].e); } hClusterSize->Fill(Nclusters/MaxSize); // hClusterEnergy->Fill(MaxEnergy); Double_t x0=0.; Double_t y0=0.; Double_t z0=0.; Double_t t0=0.; Double_t v1xmin,v1ymin,v1zmin,v1xmax,v1ymax,v1zmax; Double_t v4xmin,v4ymin,v4zmin,v4xmax,v4ymax,v4zmax; Double_t v3xmin,v3ymin,v3zmin,v3xmax,v3ymax,v3zmax; Double_t v6xmin,v6ymin,v6zmin,v6xmax,v6ymax,v6zmax; Int_t elastic[100],origin[100]; Int_t elasticCount=0; for(Int_t i=0;i<100;i++){ elastic[i]=0; origin[i]=-1; } // search for scattering // elastic scattering of particle 1 (neutron) on a particle 2 (proton) at rest. // Outgoing particles are 3 (scattered neutron) and 4 (recoil proton). // angle of particles after scattering is theta3 and theta4 // K is kinetic energy, p is momentum for (Int_t i=0;i0.99) beta1max=0.99; if (beta1min<0.) beta1min=0.; Double_t gamma1=1./sqrt(1.-beta1*beta1); Double_t gamma1min=1./sqrt(1.-beta1min*beta1min); Double_t gamma1max=1./sqrt(1.-beta1max*beta1max); Double_t p1=beta1*gamma1*1.*amu; Double_t p1min=beta1min*gamma1min*1.*amu; Double_t p1max=beta1max*gamma1max*1.*amu; Double_t En1=sqrt(p1*p1+amu*amu); Double_t En1min=sqrt(p1min*p1min+amu*amu); Double_t En1max=sqrt(p1max*p1max+amu*amu); Double_t K1=En1-amu; Double_t K1min=En1min-amu; Double_t K1max=En1max-amu; /* cout<<"incoming particle:"<theta4Measuredmax) theta4Measuredmax=tempAngle; if (tempAngle1.55) theta4Measuredmax=1.55; /* cout<<"Angle of proton measured: "<theta3max) theta3max=tempAngle; if (tempAngle1.55) theta3max=1.55; dt=Cluster[j].tStart-Cluster[i].tStart; dr=sqrt(v3x*v3x + v3y*v3y + v3z*v3z); Double_t beta3=dr/dt*1.E7/c; Double_t beta3max=(dr+dio)/dt*1.E7/c; Double_t beta3min=(dr-dio)/dt*1.E7/c; if (beta3>1.){ // cout<<"faster than speed of light!!!"<0.8) beta3max=0.8; if (beta3max>0.99) beta3max=0.99; if (beta3min<0.) beta3min=0.; Double_t gamma3=1./sqrt(1.-beta3*beta3); Double_t gamma3min=1./sqrt(1.-beta3min*beta3min); Double_t gamma3max=1./sqrt(1.-beta3max*beta3max); Double_t p3=beta3*gamma3*1.*amu; Double_t p3min=beta3min*gamma3min*1.*amu; Double_t p3max=beta3max*gamma3max*1.*amu; if (p3>p1) p3=p1; Double_t En3=sqrt(p3*p3+amu*amu); Double_t En3min=sqrt(p3min*p3min+amu*amu); Double_t En3max=sqrt(p3max*p3max+amu*amu); Double_t K3=En3-amu; Double_t K3min=En3min-amu; Double_t K3max=En3max-amu; Double_t Ma,Mb,Mc,Md,Ka,Thc,Ei,Pa,AA,BB,a,b,cc,Pc1,Pc2; Double_t Pd1,Thd1,Ec1,Ed1,Kc1,Kd1,Qsqr1; Double_t Pd2,Thd2,Ec2,Ed2,Kc2,Kd2,Qsqr2; Ma = 1.0087*amu; Mb = 1.0073*amu; Mc = Ma; Md = Mb; // calculate momentum of scattered proton and neutron Ka = K1; Thc = theta3; Ei=Ma +Mb +Ka; Pa = sqrt( Ka * Ka +2. * Ka * Ma ); AA = Ei * Ei - Md * Md +Mc * Mc - Pa * Pa; BB = AA * AA - 4. * Ei * Ei * Mc * Mc; a = 4. * Pa * Pa * cos(Thc) * cos(Thc) - 4. * Ei * Ei; b = 4. * AA * Pa * cos(Thc); cc = BB; Pc1 = -b/(2. * a)+sqrt( (b * b)/( 4. * a * a) - ( cc / a ) ); if(Pc1<0.) Pc1=0.; Pc2 = -b/(2. * a)-sqrt( (b * b)/( 4. * a * a) - ( cc / a ) ); Pd1 = sqrt( Pc1 * Pc1 +Pa * Pa - 2. * Pc1 * Pa * cos(Thc) ); Thd1 = acos( ( Pc1 * Pc1 - Pd1 * Pd1 - Pa * Pa) / ( -2. * Pd1 * Pa ) ) ; Ec1 = sqrt( Pc1 * Pc1 - -Ma * Ma ); Ed1 = sqrt( Pd1 * Pd1 - -Mb * Mb ); Kc1 = Ec1 - Ma; Kd1 = Ed1 - Mb; Qsqr1 = (- ( Ka - Kc1 ) * (Ka - Kc1 ) + ( Pa * Pa + Pc1 * Pc1 - 2. * Pa * Pc1 * cos(Thc) ))/197.327/197.327; Double_t p3b=Pc1; Double_t K3b=Kc1; Double_t E3b=Ec1; Double_t theta4=Thd1; Double_t p4b=Pd1; Double_t K4b=Kd1; Double_t E4b=Ed1; Double_t p3bmin=p3b; Double_t p3bmax=p3b; Double_t p4bmin=p4b; Double_t p4bmax=p4b; Double_t theta4min=theta4; Double_t theta4max=theta4; // calculate minimum and maximum(within errors) momentum of scattered proton and neutron for (Int_t m=1;m<5;m++){ if(m==1){ Ka = K1min; Thc = theta3min; } if(m==2){ Ka = K1min; Thc = theta3max; } if(m==3){ Ka = K1max; Thc = theta3min; } if(m==4){ Ka = K1max; Thc = theta3max; } Ei=Ma +Mb +Ka; Pa = sqrt( Ka * Ka +2. * Ka * Ma ); AA = Ei * Ei - Md * Md +Mc * Mc - Pa * Pa; BB = AA * AA - 4. * Ei * Ei * Mc * Mc; a = 4. * Pa * Pa * cos(Thc) * cos(Thc) - 4. * Ei * Ei; b = 4. * AA * Pa * cos(Thc); cc = BB; Pc1 = -b/(2. * a)+sqrt( (b * b)/( 4. * a * a) - ( cc / a ) ); if (((b * b)/( 4. * a * a) - ( cc / a ))<0.) Pc1=0.; if(Pc1<0.) Pc1=0.; Pc2 = -b/(2. * a)-sqrt( (b * b)/( 4. * a * a) - ( cc / a ) ); Pd1 = sqrt( Pc1 * Pc1 +Pa * Pa - 2. * Pc1 * Pa * cos(Thc) ); Thd1 = acos( ( Pc1 * Pc1 - Pd1 * Pd1 - Pa * Pa) / ( -2. * Pd1 * Pa ) ) ; if(Pc1p3bmax) p3bmax=Pc1; if(Pd1p4bmax) p4bmax=Pd1; if(Thd1theta4max) theta4max=Thd1; } Ec1 = sqrt( p3bmin * p3bmin - -Ma * Ma ); Kc1 = Ec1 - Ma; Ed1 = sqrt( p4bmin * p4bmin - -Mb * Mb ); Kd1 = Ed1 - Mb; Qsqr1 = (- ( Ka - Kc1 ) * (Ka - Kc1 ) + ( Pa * Pa + Pc1 * Pc1 - 2. * Pa * Pc1 * cos(Thc) ))/197.327/197.327; Double_t K3bmin=Kc1; Double_t E3bmin=Ec1; Double_t K4bmin=Kd1; Double_t E4bmin=Ed1; Ec1 = sqrt( p3bmax * p3bmax - -Ma * Ma ); Kc1 = Ec1 - Ma; Ed1 = sqrt( p4bmax * p4bmax - -Mb * Mb ); Kd1 = Ed1 - Mb; Qsqr1 = (- ( Ka - Kc1 ) * (Ka - Kc1 ) + ( Pa * Pa + Pc1 * Pc1 - 2. * Pa * Pc1 * cos(Thc) ))/197.327/197.327; Double_t K3bmax=Kc1; Double_t E3bmax=Ec1; Double_t K4bmax=Kd1; Double_t E4bmax=Ed1; /* cout<<"angle of proton calculated: "<p3min && p3bmintheta4Measuredmin && theta4minprotonEnergy && K4bmin120.){ // cout<<"Elastic scattering between "<=p3max) { cout<<"because of p3"<=theta4Measuredmax) { cout<<"because of theta4"<=protonEnergy) { cout<<"because of K4"<=0;i--){ // cout<<"elastic scattering: "<Fill(Nclusters); // determine how many neutrons from sum energy considerations Double_t neutmult=0.0098*sumTotalEnergy/beamEnergy*600.; // Double_t neutmult=0.0112*sumTotalEnergy/beamEnergy*600.; //200 MeV // cout<< "neutmult from energy: " << neutmult << endl; if(neutmult<0.5) neutmult=0.5; hNeutmult->Fill(neutmult); Int_t numneut=(int)(neutmult+0.5); for (Int_t i=0;i0.05*600./beamEnergy)){ deleteMe[k]=1; } if(Cluster[k].e<2.5 && k>0){ // delete this cluster because it is not inside beta window // But not first hit deleteMe[k]=1; // cout<<"delete cluster"<0;i--){ if (deleteMe[i]){ Nclusters -=1; for (Int_t k=i;kmaxEnergy){ maxEnergy=temp[k][4]; index=k; } } Cluster[i].xStart = temp[index][0]; Cluster[i].yStart = temp[index][1]; Cluster[i].zStart = temp[index][2]; Cluster[i].tStart = temp[index][3]; Cluster[i].e = temp[index][4]; Cluster[i].size = temp[index][5]; Cluster[i].tStop = temp[index][6]; Cluster[i].xEnd = temp[index][7]; Cluster[i].yEnd = temp[index][8]; Cluster[i].zEnd = temp[index][9]; temp[index][4] = 0.; } */ // now we sort according to closest beta compared to beam for (Int_t k=1;kmaxEnergy){ maxEnergy=temp[k][4]; index=k; } } Cluster[i].xStart = temp[index][0]; Cluster[i].yStart = temp[index][1]; Cluster[i].zStart = temp[index][2]; Cluster[i].tStart = temp[index][3]; Cluster[i].e = temp[index][4]; Cluster[i].size = temp[index][5]; Cluster[i].tStop = temp[index][6]; Cluster[i].xEnd = temp[index][7]; Cluster[i].yEnd = temp[index][8]; Cluster[i].zEnd = temp[index][9]; temp[index][4] = 0.; } */ for (Int_t i=0;iFill(Nclusters); Double_t totalLength=0.; for (Int_t i=0;iFill(firstHitX[i]-NEUT2_hit[closest].x,1.); hDeltaY->Fill(firstHitY[i]-NEUT2_hit[closest].y,1.); hDeltaZ->Fill(firstHitZ[i]-NEUT2_hit[closest].z,1.); hDeltaT->Fill(firstT[i]-NEUT2_hit[closest].t,1.); NEUT2_hit[closest].x=1000.; NEUT2_hit[closest].y=1000.; NEUT2_hit[closest].z=0.; minDis=1000.; closest=0; } } hClusterNo_vs_Size->Fill(nentries,totalLength); // Reconstruct neutron momentum with first hit. // First with the ideal values from simulations. sum_energy=0.; sum_momentumX=0.; sum_momentumY=0.; sum_momentumZ=0.; sum_masses=0.; for (Int_t i=0;iFill(xinv0); // if(printing){ cout<<"xinv0 "<=numneut){ // invariant mass calculation makes only sense if we have enough cluster sum_energy=0.; sum_momentumX=0.; sum_momentumY=0.; sum_momentumZ=0.; sum_masses=0.; for (Int_t i=0;iFill(momentumX[i]-PRIM_part[i].px,1.); hDeltaPy2 ->Fill(momentumY[i]-PRIM_part[i].py,1.); hDeltaPz2 ->Fill(pnzcm,1.); */ sum_energy+=energy[i]; sum_momentumX+=momentumX[i]; sum_momentumY+=momentumY[i]; sum_momentumZ+=momentumZ[i]; sum_masses+=mNeutron; /* cout<<"Sum energy " <Fill(xinv); if(numneut==1) hErel1->Fill(xinv); if(numneut==2) hErel2->Fill(xinv); if(numneut==3) hErel3->Fill(xinv); if(numneut==4) hErel4->Fill(xinv); if(numneut==(nPrimNeutrons) && Nclusters==(nPrimNeutrons)) hMinv2->Fill(xinv); // if(printing){ cout<<"numNeut "<Fill(momentumX[closest]-PRIM_part[i+1].px,1.); hDeltaPy2->Fill(momentumY[closest]-PRIM_part[i+1].py,1.); hDeltaPz2->Fill(momentumZ[closest]-PRIM_part[i+1].pz,1.); if(i==0) hDeltaP1->Fill(momentumT[closest]-PRIM_part[i+1].p); if(i==1) hDeltaP2->Fill(momentumT[closest]-PRIM_part[i+1].p); if(i==2) hDeltaP3->Fill(momentumT[closest]-PRIM_part[i+1].p); if(i==3) hDeltaP4->Fill(momentumT[closest]-PRIM_part[i+1].p); if(i==4) hDeltaP5->Fill(momentumT[closest]-PRIM_part[i+1].p); if(i==5) hDeltaP6->Fill(momentumT[closest]-PRIM_part[i+1].p); momentumX[closest]=0.; momentumY[closest]=0.; momentumZ[closest]=0.; min=100000.; closest=0; } } } //****************************************************************** // Now reconstruction of momenta with first hits numneut=nPrimNeutrons; for (Int_t i=0;iFill(xinv); if(printing){ cout<<"numNeut "<Fill(momentumX[closest]-PRIM_part[i+1].px); hDeltaPy1->Fill(momentumY[closest]-PRIM_part[i+1].py); hDeltaPz1->Fill(momentumZ[closest]-PRIM_part[i+1].pz); momentumX[closest]=0.; momentumY[closest]=0.; momentumZ[closest]=0.; min=100000.; closest=0; } } } // end if entries >0 /* // TrackId = land_obj->GetTrackID(); Int_t TrackId=0; Int_t VolumeID=0; for (Int_t i=0;iClear(); } void R3BNeutronTracker::Finish() { // here event. write histos // cout << " -I- Digit Finish() called " << endl; // Write control histograms hHits->Write(); hClusters->Write(); hClusters1->Write(); hClusters2->Write(); hNeutmult->Write(); hMinv->Write(); hMinv0->Write(); hMinv1->Write(); hMinv2->Write(); hErel1->Write(); hErel2->Write(); hErel3->Write(); hErel4->Write(); hDeltaPx1->Write(); hDeltaPy1->Write(); hDeltaPz1->Write(); hDeltaPx2->Write(); hDeltaPy2->Write(); hDeltaPz2->Write(); hDeltaX->Write(); hDeltaY->Write(); hDeltaZ->Write(); hDeltaT->Write(); hDeltaP1->Write(); hDeltaP2->Write(); hDeltaP3->Write(); hDeltaP4->Write(); hDeltaP5->Write(); hDeltaP6->Write(); hClusterSize->Write(); hClusterEnergy->Write(); hClusterNo_vs_Size->Write(); hDelta->Write(); hFirstHitZ->Write(); } R3BNeutronTrack* R3BNeutronTracker::AddHit(TVector3 posIn, TVector3 posOut, TVector3 momOut, Double_t time){ // It fills the R3BLandDigi array TClonesArray& clref = *fNeutronTracks; Int_t size = clref.GetEntriesFast(); return new(clref[size]) R3BNeutronTrack(posIn, posOut, momOut, time); } // ----- Public method UseBeam ---------------------------------- void R3BNeutronTracker::UseBeam(Double_t beam_energy, Double_t beam_beta) { beamEnergy = beam_energy; beamBeta = beam_beta; } ClassImp(R3BNeutronTracker)