LH2 target
Detector Material and Construction
Using GEANT4, the ExampleN02 file was edited to run for a LH2 target. The file ExN02DetectorConstruction.cc was edited with
//--------- Material definition --------- G4double a, z; G4double density, temperature, pressure; //Liquid Hydrogen G4Material* LH2 = new G4Material("Hydrogen", z=2., a=2.02*g/mole, density=0.07*g/cm3, kStateGas,3*kelvin,1.7e5*pascal);
//--------- Sizes of the principal geometrical components (solids) --------- NbOfChambers = 1; ChamberWidth = 1.5*cm; ChamberSpacing = 40*cm; fTrackerLength = (NbOfChambers+1)*ChamberSpacing; // Full length of Tracker fTargetLength = 1.0 * cm; // Full length of Target TargetMater = LH2; ChamberMater = BadVacuum; //fWorldLength= 1.2 *(fTargetLength+fTrackerLength); fWorldLength= 1.2 *(10+fTrackerLength)+100 *cm; G4double targetSize = 0.5*fTargetLength; // Half length of the Target G4double trackerSize = 0.5*fTrackerLength; // Half length of the Tracker
//------------------------------ // Target //------------------------------ G4ThreeVector positionTarget = G4ThreeVector(0,0,-(targetSize+trackerSize)-10*cm); solidTarget = new G4Box("target",20*cm,20*cm,targetSize); //logicTarget = new G4LogicalVolume(solidTarget,TargetMater,"Target",0,0,0); logicTarget = new G4LogicalVolume(solidTarget,TargetMater,"Target",0,0,0); physiTarget = new G4PVPlacement(0, // no rotation positionTarget, // at (x,y,z) logicTarget, // its logical volume "Target", // its name logicWorld, // its mother volume false, // no boolean operations 0); // copy number G4cout << "Target is " << fTargetLength/cm << " cm of " << TargetMater->GetName() << G4endl;
Recording Moller Events
Moller scattering does not have a GEANT4 specific setting, so the file ExN02SteppingVerbose.cc was edited to record only events that would correspond to Moller events. Since Moller scattering is simply electron-electron scattering, we can look for events where electron ionization is the process in the data stream. We will limit this to only particles with a parentID of 0 and 1 representing the parent and daughter (Moller) electrons. This eliminates second generation Moller scatterings, which only ocur about 2 times out of 1E6 incoming electrons. This method also eliminates Delta Rays or Knock-on-Electrons.
The file ExN02SteppingVerbose.cc is read for each step in the GEANT4 simulation, so recording the momentum, position, and energies of the electrons before and after the collision can be found in multiple loops.
On the first pass of SteppingVerbose, the data is recorded into a temporary variable set. The physical process of ionization occurs after the collision of the two electrons. This implies that the data could possible be the initial state of the incoming electron. This is read every time to be prepared for the subsequent pass where the process of ionization (scattering) is active.
void ExN02SteppingVerbose::StepInfo() { . . . if(fTrack->GetDefinition()->GetPDGEncoding()==11 && fStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName()!="eIoni" && fTrack->GetParentID()==0) { Temp_Energy=fTrack->GetKineticEnergy(); Temp_Mom_x=fTrack->GetMomentum().x(); Temp_Mom_y=fTrack->GetMomentum().y(); Temp_Mom_z=fTrack->GetMomentum().z(); Temp_Pos_x=fTrack->GetPosition().x(); Temp_Pos_y=fTrack->GetPosition().y(); Temp_Pos_z=fTrack->GetPosition().z(); }
On a pass afterwards, the data is read into a variable for the final state when the physical state is ionization, representing the Moller scattering. The the temporary variable is read into the initial state.
if( fTrack->GetDefinition()->GetPDGEncoding()==11 && fStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName()=="eIoni" && fTrack->GetParentID()==0) { Final_Energy= fTrack->GetKineticEnergy(); Final_Mom_x=fTrack->GetMomentum().x(); Final_Mom_y=fTrack->GetMomentum().y(); Final_Mom_z=fTrack->GetMomentum().z(); Final_Pos_x=fTrack->GetPosition().x(); Final_Pos_y=fTrack->GetPosition().y(); Final_Pos_z=fTrack->GetPosition().z(); Init_Energy=Temp_Energy; Init_Mom_x=Temp_Mom_x; Init_Mom_y=Temp_Mom_y; Init_Mom_z=Temp_Mom_z; Init_Pos_x=Temp_Pos_x; Init_Pos_y=Temp_Pos_y; Init_Pos_z=Temp_Pos_z; }
This will write the data to an external file only for a 1st generation daughter particle and an active trigger. Afterwards, the trigger is turned off so that the recording process can start again.
if(fTrack->GetDefinition()->GetPDGEncoding()==11 && fTrack->GetParentID()==1 && trigger==1 ) { outfile //G4cout << Init_Energy<< " " << Init_Mom_x << " " << Init_Mom_y << " " << Init_Mom_z << " " << Init_Pos_x << " " << Init_Pos_y << " " << Init_Pos_z << " " << Final_Energy << " " << Final_Mom_x << " " << Final_Mom_y << " " << Final_Mom_z << " " << Final_Pos_x << " " << Final_Pos_y << " " << Final_Pos_z << " " << Mol_Energy << " " << Mol_Mom_x << " " << Mol_Mom_y << " " << Mol_Mom_z << " " << Mol_Pos_x << " " << Mol_Pos_y << " " << Mol_Pos_z << " " << G4endl; trigger=0; } . . . }
On a later pass, the condition that the parentID no longer represents the parent. This implies that the particle a Moller electron and the data is recorded into the Moller final state. The trigger is activated, which on the next pass of the program will allow a printout of all Moller Scattering data.
void ExN02SteppingVerbose::TrackingStarted() { . . . if(fTrack->GetDefinition()->GetPDGEncoding()==11 && fTrack->GetParentID()>0) { Mol_Energy=fTrack->GetKineticEnergy(); Mol_Mom_x=fTrack->GetMomentum().x(); Mol_Mom_y=fTrack->GetMomentum().y(); Mol_Mom_z=fTrack->GetMomentum().z(); Mol_Pos_x=fTrack->GetPosition().x(); Mol_Pos_y=fTrack->GetPosition().y(); Mol_Pos_z=fTrack->GetPosition().z(); trigger=1; } . . . }
Running the simulation
cmake . make -f Makefile ./exampleN02 run4.mac>/dev/null
Where the run4.mac file is
/gun/particle e- /gun/energy 11 GeV /event/verbose 0 /tracking/verbose 1 /run/beamOn 40000000
Working with Moller Data
The event data from the GEANT4 simulation is written to a data file in the following format:
KEi | Pxi | Pyi | Pzi | xi | yi | z1 | KEf | Pxf | Pyf | Pzf | xf | yf | zf | KEm | Pxm | Pym | Pzm | xm | ym | zm |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
11000 | 0 | 0 | 11000.5 | 0 | 0 | -510 | 10999.1 | 0.433025 | -0.858867 | 10999.6 | 0 | 0 | -509.276 | 0.905324 | -0.433025 | 0.858867 | 0.905366 | 0 | 0 | -509.276 |
Where each line represents a Moller scattering with the kinematic variables of kinetic energy, momentum in the x, y, and z directions, as well as the x, y, and z position of the collision for the Incoming electron, the scattered state of the incoming electron, and the scattered Moller electron in that specific order.
Using a c++ macro, the variables are read into a Root tree, with branches for each variable. Specific histograms are also created for the total momentum and the scattering angle theta for the scattered and Moller electron, both in the Lab frame and Center of Mass frame.
tree->Branch("evt",&evt.event,"event/I:IntKE/F:IntPx:IntPy:IntPz:IntPosx:IntPosy:IntPosz:FnlKE:FnlPx:FnlPy:FnlPz:FnlPosx:FnlPosy:FnlPosz: MolKE:MolPx:MolPy:MolPz:MolPosx:MolPosy:MolPosz"); while(in.good()) { //Create Tree from GEANT4 simulation data evt.event=nlines; in >> evt.IntKE >> evt.IntMom[0] >> evt.IntMom[1] >> evt.IntMom[2] >> evt.IntPos[0] >> evt.IntPos[1] >> evt.IntPos[2] >> evt.FnlKE >> evt.FnlMom[0] >> evt.FnlMom[1] >> evt.FnlMom[2] >> evt.FnlPos[0] >> evt.FnlPos[1] >> evt.FnlPos[2] >> evt.MolKE >> evt.MolMom[0] >> evt.MolMom[1] >> evt.MolMom[2] >> evt.MolPos[0] >> evt.MolPos[1] >> evt.MolPos[2]; nlines++; tree->Fill(); FnlE=sqrt(evt.FnlMom[0]*evt.FnlMom[0]+evt.FnlMom[1]*evt.FnlMom[1]+evt.FnlMom[2]*evt.FnlMom[2]+0.511*0.511); IntE=sqrt(evt.IntMom[0]*evt.IntMom[0]+evt.IntMom[1]*evt.IntMom[1]+evt.IntMom[2]*evt.IntMom[2]+0.511*0.511); MolE=sqrt(evt.MolMom[0]*evt.MolMom[0]+evt.MolMom[1]*evt.MolMom[1]+evt.MolMom[2]*evt.MolMom[2]+0.511*0.511);//Define 4Vectors Fnl4Mom.SetPxPyPzE(evt.FnlMom[0],evt.FnlMom[1],evt.FnlMom[2],FnlE); Int4Mom.SetPxPyPzE(evt.IntMom[0],evt.IntMom[1],evt.IntMom[2],IntE); Mol4Mom.SetPxPyPzE(evt.MolMom[0],evt.MolMom[1],evt.MolMom[2],MolE); //Create Lab Frame Histograms FinalMomentum->Fill(Fnl4Mom.P()); MollerMomentum->Fill(Mol4Mom.P()); FinalTheta->Fill(Fnl4Mom.Theta()*180/3.14); MollerTheta->Fill(Mol4Mom.Theta()*180/3.14); //Boost to Center of Mass Frame CMS=Fnl4Mom+Mol4Mom; Fnl4Mom.Boost(-CMS.BoostVector()); Mol4Mom.Boost(-CMS.BoostVector()); //Create CM Histograms FinalMomentumCM->Fill(Fnl4Mom.P()); MollerMomentumCM->Fill(Mol4Mom.P()); FinalThetaCM->Fill(Fnl4Mom.Theta()*180/3.14); MollerThetaCM->Fill(Mol4Mom.Theta()*180/3.14); }