示例#1
0
FieldSetup::FieldSetup(lucretiaManager* lman)
 : fFieldManager(0),
   fChordFinder(0),
   fEquation(0),
   fElFieldValue(),
   fStepper(0),
   fIntgrDriver(0),
   fMinStep(lman->EMStepSize*m)
{
  fUniform=lman->EMisUniform;
  if (fUniform==1) {
    double magField[3]={0,0,0};
    lman->GetUniformField(magField);
    fMfield = new G4UniformMagField(G4ThreeVector(magField[0]*tesla,magField[1]*tesla,magField[2]*tesla));
    fEquation = new G4EqMagElectricField(fMfield);
  }
  else if (fUniform==2) {
    double eField[3]={0,0,0};
    lman->GetUniformField(eField);
    fEfield = new G4UniformElectricField(G4ThreeVector(eField[0]*kilovolt/m,eField[1]*kilovolt/m,eField[2]*kilovolt/m));
    fEquation = new G4EqMagElectricField(fEfield);
  }
  else {
    fEMfield = new GlobalField(lman); // Gets field data from LucretiaManager object
    fEquation = new G4EqMagElectricField(fEMfield);
  }
  fFieldManager = GetGlobalFieldManager();
  UpdateField(lman);
}
G4VPhysicalVolume* TargetDetectorConstruction::Construct() {
  G4NistManager* nist = G4NistManager::Instance();
  nist->SetVerbose(1);
  
  G4double rhoVacuum = CLHEP::universe_mean_density;
  G4double pVacuum   = 1.0e-19*pascal;
  G4double TVacuum   = 0.1*kelvin;
  G4Material* graphite = new G4Material("Graphite", 6., 12.*g/mole, 1.82*g/cm3);
  G4Material* vacuum   = new G4Material("Vacuum", 1., 1.01*g/mole, rhoVacuum, kStateGas, TVacuum, pVacuum);

  /****************************/
  // World
  /****************************/
  G4bool checkOverlaps = true;
  G4double earthRadius = 100*cm;
  G4Orb* worldSolid = new G4Orb("World", earthRadius);
  G4LogicalVolume*  logicWorld = new G4LogicalVolume(worldSolid, vacuum, "World");
  G4VPhysicalVolume* physWorld = new G4PVPlacement(0, G4ThreeVector(), logicWorld, "World", 0, false, 0, checkOverlaps);

  /****************************/
  // Target
  /****************************/
  G4VisAttributes* colorGraphite = new G4VisAttributes(G4Colour(0.8, 0.0, 0.0, 0.7));
  G4Tubs* targetSolid = new G4Tubs("Target", 0., 3*cm, 30.*cm, 0., 2*M_PI);
  G4LogicalVolume*  logicTarget = new G4LogicalVolume(targetSolid, graphite, "Target");
  G4VPhysicalVolume* physTarget = new G4PVPlacement(0, G4ThreeVector(), logicTarget, "Target", logicWorld, false, 0, checkOverlaps);
  logicTarget->SetVisAttributes(colorGraphite);
  
  return physWorld;
}
示例#3
0
TargetHits::TargetHits() : G4VHit() {
  fTrack    = -1;
  fPosition = G4ThreeVector();
  fEnergy   = 0.;
  fMomentum = G4ThreeVector();
  fTime     = 0.;
  fParticle = NULL;
}
示例#4
0
/*
 * ray fire test, distance to in 
 * points inside of a volume
 */
TEST_F(DagSolidTest,test_5) {

  G4ThreeVector position = G4ThreeVector(0.,0.,0.);
  G4ThreeVector direction = G4ThreeVector(1.,0.,0.);
  double distance = vol_1->DistanceToIn(position,direction);

  // distance should be set to infinity since there are no other volumes
  // to enter
  EXPECT_EQ(kInfinity,distance);

  return;
}
示例#5
0
GSMS::Geometry::Geometry()
{
	m_world = NULL;
	defineMaterials();

	G4Box* world_box = new G4Box(
		"world_box",
		2*m,
		2*m,
		2*m);

	G4LogicalVolume*	world_log  = new G4LogicalVolume(
		world_box,
		m_materials["Air"],
		"world_log");

	m_world = new G4PVPlacement(
		0,
		G4ThreeVector(0.	,0.	,0.),
		"world_phys",
		world_log,
		NULL,
		false,
		0);

	world_log->SetVisAttributes(G4VisAttributes::Invisible);
}
示例#6
0
/*
 * ray fire test, distance to out calc normal as well
 * point just outside of a volume, vnorm should be false
 */
TEST_F(DagSolidTest, test_8 ) {

  // point inside cell looking out
  G4ThreeVector position = G4ThreeVector(51.,0.,0.);
  G4ThreeVector direction = G4ThreeVector(1.,0.,0.);
  
  G4ThreeVector normal;
  bool v_norm = false;
  double distance = vol_1->DistanceToOut(position,direction,true,&v_norm,&normal);
 
  // when the point is outside the volume, v_norm should be false
  EXPECT_FALSE(v_norm);
  // distance should be set to infinity
  EXPECT_EQ(kInfinity,distance);
  return;
}
void BIPrimaryGeneratorAction::GeneratePrimaries(G4Event *event)
{
   //G4double coneTheta = 15.*deg;
   //G4ThreeVector particleVec = GetParVec(coneTheta);
   //fEnergy = fEneFnc->GetRandom() * MeV;

   G4ThreeVector particleVec = GetParVecEne();
   fProtonGun->SetParticleMomentumDirection(particleVec);

   fProtonGun->SetParticlePosition(G4ThreeVector(0., 0., fZPosition));
   fProtonGun->SetParticleEnergy(fEnergy);
   fProtonGun->GeneratePrimaryVertex(event);
/*
   G4AnalysisManager *anaMan = G4AnalysisManager::Instance();
   anaMan->FillNtupleIColumn(1, 0, 11);
   anaMan->FillNtupleDColumn(1, 1, fEnergy);
   anaMan->FillNtupleDColumn(1, 2, particleVec.x());
   anaMan->FillNtupleDColumn(1, 3, particleVec.y());
   anaMan->FillNtupleDColumn(1, 4, particleVec.z());
   anaMan->AddNtupleRow(1);
*/
   G4AutoLock lock(&mutexInPGA);
   if (nEveInPGA++ % 10000 == 0)
      G4cout << nEveInPGA - 1 << " events done" << G4endl;

}
示例#8
0
/*
 * ray fire test, distance to out calc normal as well
 * points inside of a volume, point on surface
 */
TEST_F(DagSolidTest,test_7) {

  // point inside cell looking out
  G4ThreeVector position = G4ThreeVector(50.,0.,0.);
  G4ThreeVector direction = G4ThreeVector(1.,0.,0.);
  
  G4ThreeVector normal;
  bool v_norm = false;
  double distance = vol_1->DistanceToOut(position,direction,true,&v_norm,&normal);

  // when the point is inside or on the surface of the volume, v_norm should be true
  EXPECT_TRUE(v_norm);
  // distance should be set to 0.0 in this case
  EXPECT_EQ(0.0,distance);
  return;
}
示例#9
0
/*
 * ray fire test, distance to out
 */
TEST_F(DagSolidTest,test_3) {

  G4ThreeVector position = G4ThreeVector(-100.,0.,0.);
  G4ThreeVector direction = G4ThreeVector(1.,0.,0.);
  double distance = vol_1->DistanceToOut(position,direction);

  // DistanceToOut normally only called from inside the volume
  // but in this case, we expect the ray to skip over the volume 
  // and give the distance to when we leave the volume instead

  // distance should be set to 50.0 mm since the point
  // is in the center of the box
  EXPECT_EQ(150.0,distance);

  return;
}
示例#10
0
//---------------------------------------------------------------------
TrackInformation::TrackInformation()
  : G4VUserTrackInformation()
{
    fOriginalTrackID = 0;
    fParticleDefinition = 0;
    fOriginalPosition = G4ThreeVector(0.,0.,0.);
    fOriginalMomentum = G4ThreeVector(0.,0.,0.);
    fOriginalEnergy = 0.;
    fOriginalTime = 0.;
    fTrackingStatus = 1;
    fSourceTrackID = -1;
    fSourceDefinition = 0;
    fSourcePosition = G4ThreeVector(0.,0.,0.);
    fSourceMomentum = G4ThreeVector(0.,0.,0.);
    fSourceEnergy = 0.;
    fSourceTime = 0.;
}
示例#11
0
//-------------------------------------------------------------------------
TrackInformation::TrackInformation(const G4Track* aTrack)
  : G4VUserTrackInformation()
{
    fOriginalTrackID = aTrack->GetTrackID();
    fParticleDefinition = aTrack->GetDefinition();
    fOriginalPosition = aTrack->GetPosition();
    fOriginalMomentum = aTrack->GetMomentum();
    fOriginalEnergy = aTrack->GetTotalEnergy();
    fOriginalTime = aTrack->GetGlobalTime();
    fTrackingStatus = 1;
    fSourceTrackID = -1;
    fSourceDefinition = 0;
    fSourcePosition = G4ThreeVector(0.,0.,0.);
    fSourceMomentum = G4ThreeVector(0.,0.,0.);
    fSourceEnergy = 0.;
    fSourceTime = 0.;
}
示例#12
0
/*
 * Point in volume test
 */
TEST_F(DagSolidTest,point_in_volume) {
  // sample position
  G4ThreeVector position = G4ThreeVector(0.,0.,0.);
  // point in volume test
  EInside inside = vol_1->Inside(position);
 
  EXPECT_EQ(kInside,inside);
 
  return;
}
void CollimationParticleGun::SetParticleDetails(double x, double y, double xp, double yp, double dp)
{
//UNITS MUST BE MeV, mm, rad!

	const G4double mp = particle->GetPDGMass();
/*
	G4double BeamMomentum = sqrt((ReferenceEnergy*ReferenceEnergy) - (mp*mp));
	G4double ParticleMomentum = BeamMomentum * (1.0 + dp);
	G4double ParticleKE = sqrt((ParticleMomentum*ParticleMomentum) + (mp*mp)) - mp;
	G4cout << ParticleKE << "\t" << ParticleMomentum << "\t" << BeamMomentum << "\t" << ReferenceEnergy << "\t" << dp << std::endl;
*/

	//The kinetic energy (Total energy - rest mass)
	ParticleGun->SetParticleEnergy(dp - mp);
	double p = sqrt(dp*dp - mp*mp);
	//How to deal with longitudinal coordinate?
	ParticleGun->SetParticlePosition(G4ThreeVector(x, y, 0));
	ParticleGun->SetParticleMomentumDirection(G4ThreeVector(xp,yp,p));
}
示例#14
0
/*
 * ray fire test, distance to in
 * only for points external to a volume
 */
TEST_F(DagSolidTest,test_2) {

  G4ThreeVector position = G4ThreeVector(-100.,0.,0.);
  double distance = vol_1->DistanceToIn(position);

  // DistanceToIn point external to volume should give distance
  // to entry, distance should be set to 50.0 mm 
  EXPECT_EQ(50.0,distance);

  return;
}
G4ThreeVector BIPrimaryGeneratorAction::GetParVec(G4double limit)
{
   G4double theta = acos(1. - G4UniformRand() * (1. - cos(limit)));
   G4double phi = G4UniformRand() * 2. * CLHEP::pi;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   G4ThreeVector particleVec = G4ThreeVector(vx, vy, vz);

   return particleVec;
}
示例#16
0
/*
 * Point on surface tolerance, kCarTolerance/2.0 = 5.0e-9 
 * of a surface should return outside
 */
TEST_F(DagSolidTest,point_out_surface_tolerance) {

  // sample position
  G4ThreeVector position = G4ThreeVector(50.+(9.99e-9/2.0),0.,0.);
  // point in volume test
  EInside inside = vol_1->Inside(position);

  EXPECT_EQ(kSurface,inside);

  return;
}
示例#17
0
/*
 * ray fire test, distance to out, called 
 *  when point is inside of volume
 */
TEST_F(DagSolidTest,test_4) {

  G4ThreeVector position = G4ThreeVector(0.,0.,0.);
  double distance = vol_1->DistanceToOut(position);

  // distance should be set to 50.0 mm since the point
  // is in the center of the box
  EXPECT_EQ(50.0,distance);

  return;
}
示例#18
0
G4VPhysicalVolume* DetectorConstruction::Construct()
{

  //------------------------------------------------------ materials

  G4double a;  // atomic mass
  G4double z;  // atomic number
  G4double density;

  G4Material* Ar = 
  new G4Material("ArgonGas", z= 18., a= 39.95*g/mole, density= 1.782*mg/cm3);

  G4Material* Pb = 
  new G4Material("Lead", z= 82., a= 207.19*g/mole, density= 11.35*g/cm3);

  //------------------------------------------------------ volumes

  //------------------------------ experimental hall (world volume)
  //------------------------------ beam line along x axis

  G4double expHall_x = 3.0*m;
  G4double expHall_y = 1.0*m;
  G4double expHall_z = 1.0*m;
  G4Box* experimentalHall_box = new G4Box("expHall_box",expHall_x,expHall_y,expHall_z);
  experimentalHall_log = new G4LogicalVolume(experimentalHall_box,Ar,"expHall_log",0,0,0);
  experimentalHall_phys = new G4PVPlacement(0,G4ThreeVector(),experimentalHall_log,"expHall",0,false,0);

  //------------------------------ a calorimeter block

  G4double block_x = 1.0*m;
  G4double block_y = 1.0*m;
  G4double block_z = 1.0*m;
  G4Box* calorimeterBlock_box = new G4Box("calBlock_box",block_x,block_y,block_z);
  calorimeterBlock_log = new G4LogicalVolume(calorimeterBlock_box,Pb,"caloBlock_log",0,0,0);
  G4double blockPos_x = 2*block_x+0.0*m;
  G4double blockPos_y = 0.0*m;
  G4double blockPos_z = 0.0*m;
  calorimeterBlock_phys = new G4PVPlacement(0,G4ThreeVector(blockPos_x,blockPos_y,blockPos_z),calorimeterBlock_log,"caloBlock",experimentalHall_log,false,0);

  return experimentalHall_phys;
}
/*
// For using ROOT classes.
// When using ROOT classes, it have to be thread local or mutex locked.
// I don't know _G4MT_TLS_ is truely needed or not.
// https://indico.cern.ch/event/226961/material-old/0/0?contribId=0
// In case without, this code looks like working well...
G4ThreadLocal TF1 *fEneFnc_G4MT_TLS_ = 0;
*/
BIPrimaryGeneratorAction::BIPrimaryGeneratorAction()
   : G4VUserPrimaryGeneratorAction(),
     fProtonGun(0),
     fEneFnc(NULL)
{
   G4AutoLock lock(&mutexInPGA);

   Int_t seed = time(NULL) + G4Threading::G4GetThreadId() * 100000;
   gRandom->SetSeed(seed);
/*
   if(!fEneFnc_G4MT_TLS_) fEneFnc_G4MT_TLS_ = new TF1("fEneFnc", "expo(0)+expo(2)+gaus(4)", 0., 30.);
   fEneFnc = fEneFnc_G4MT_TLS_;
*/
   fEneFnc = new TF1("fEneFnc", "expo(0)+expo(2)+gaus(4)", 0., 30.);
   fEneFnc->SetParameter(0, 2.67164e+01);
   fEneFnc->SetParameter(1, -8.35969e-01);
   fEneFnc->SetParameter(2, 2.15801e+01);
   fEneFnc->SetParameter(3, -7.66820e-02);
   fEneFnc->SetParameter(4, 3.79820e+09);
   fEneFnc->SetParameter(5, 8.94835e+00);
   fEneFnc->SetParameter(6, 3.04310e+00);
   fEnergy = fEneFnc->GetRandom() * MeV;   
   
   G4int nPar = 1;
   fProtonGun = new G4ParticleGun(nPar);

   fZPosition = -300.*mm;
   G4ParticleTable *parTable = G4ParticleTable::GetParticleTable();

   G4ParticleDefinition *proton = parTable->FindParticle("proton");
   fProtonGun->SetParticleDefinition(proton);
   fProtonGun->SetParticlePosition(G4ThreeVector(0., 0., fZPosition));
   fProtonGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
   fProtonGun->SetParticleEnergy(fEnergy);

   TFile *file = new TFile("randomSource.root", "OPEN");
   fHisSource = (TH2D*)file->Get("fHisMap");
   fHisSource->SetName("fHisSource");

   DefineCommands();
}
示例#20
0
void BIPrimaryGeneratorAction::FirstBeamGun()
{
   G4AutoLock lock(&mutexInPGA);
   fEnergy = fEneFnc->GetRandom() * MeV;
   lock.unlock();
   
   //G4double x = (G4UniformRand() * 12.5 - 6.25)*mm;
   G4double x = (G4UniformRand() * 12.5 - 6.25) * 1.41421356*mm;
   G4double y = (G4UniformRand() * 48.75 - 24.375)*mm;

   fParticleGun->SetParticlePosition(G4ThreeVector(x, y, fZPosition));
}
G4VPhysicalVolume * GeantDetectorConstruction::Construct()
{
    // World
    G4double worldSize = 5 * ( std::abs( gOptions->GetDetZ_cm() * cm ) + std::abs( gOptions->GetPartZ_cm() * cm ) ) ;
    G4Box * worldSolid = new G4Box("WorldS", worldSize, worldSize, worldSize);
    G4LogicalVolume * worldLV = new G4LogicalVolume( worldSolid, G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic"), "World");
    G4VPhysicalVolume * worldPV = new G4PVPlacement( 0, G4ThreeVector(0,0,0), worldLV, "WorldPV", 0, false, 0, true);

    // Scatterer plane
    G4Box * scatPlaneSolid = new G4Box("scatPlaneSolid", worldSize, worldSize, gOptions->GetScatThick_um() * um / 2  );
    G4Material * scatMat =  G4NistManager::Instance()->FindOrBuildMaterial("G4_Si");
    G4cout << "Scatterer material: " << scatMat->GetName() << " Radiation length = "<< scatMat->GetRadlen() / cm << " cm"<< G4endl;
    G4LogicalVolume * scatPlaneLV = new G4LogicalVolume( scatPlaneSolid, scatMat, "scatPlaneLV");
    new G4PVPlacement( 0, G4ThreeVector(0,0,0), scatPlaneLV, "scatPlanePV", worldLV, false, 0, true);

    // Detector plane
    G4Box * detPlaneSolid = new G4Box("detPlaneSolid", worldSize, worldSize, 1 * um );
    G4LogicalVolume * detPlaneLV = new G4LogicalVolume( detPlaneSolid, G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic"), "detPlaneLV");
    new G4PVPlacement( 0, G4ThreeVector( 0, 0, ( gOptions->GetDetZ_cm() + detPlaneSolid->GetZHalfLength() ) * cm ), detPlaneLV, "DetPlanePV", worldLV, false, 0, true);
    fDetPlaneSD = new GeantTrackerSD( 0 );
    SetSensitiveDetector( detPlaneLV, fDetPlaneSD );

    return worldPV;
}
示例#22
0
void BIPrimaryGeneratorAction::SecondBeamGun()
{
   G4double x, y;
   fHisSource->GetRandom2(x, y);

   fEnergy = pow(10., (y - 152.) / fDy) * 20 * MeV;

   G4double theta = CLHEP::pi * ((x - 78.) / fDx) / 180.;
   G4double phi = G4UniformRand() * fPhiLimit;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   fParVec = G4ThreeVector(vx, vy, vz);
   fParticleGun->SetParticleMomentumDirection(fParVec);
}
示例#23
0
//
// 24. Cylindrical Cut Section or Cut Tube:
//
// G4CutTubs(const G4String& pName,
//           G4double  pRMin,
//           G4double  pRMax,
//           G4double  pDz,
//           G4double  pSPhi,
//           G4double  pDPhi,
//           G4ThreeVector pLowNorm,
//           G4ThreeVector pHighNorm)
void doCutTubs(const std::string &name,
               double rIn,
               double rOut,
               double zhalf,
               double startPhi,
               double deltaPhi,
               std::array<double, 3> lowNorm,
               std::array<double, 3> highNorm) {
  G4CutTubs g4(name,
               rIn,
               rOut,
               zhalf,
               startPhi,
               deltaPhi,
               G4ThreeVector(lowNorm[0], lowNorm[1], lowNorm[2]),
               G4ThreeVector(highNorm[0], highNorm[1], highNorm[2]));
  DDI::CutTubs dd(
      zhalf, rIn, rOut, startPhi, deltaPhi, lowNorm[0], lowNorm[1], lowNorm[2], highNorm[0], highNorm[1], highNorm[2]);
  DDCutTubs dds = DDSolidFactory::cuttubs(name,
                                          zhalf,
                                          rIn,
                                          rOut,
                                          startPhi,
                                          deltaPhi,
                                          lowNorm[0],
                                          lowNorm[1],
                                          lowNorm[2],
                                          highNorm[0],
                                          highNorm[1],
                                          highNorm[2]);
  dd.stream(std::cout);
  std::cout << std::endl;
  std::cout << "\tg4 volume = " << g4.GetCubicVolume() / cm3 << " cm3" << std::endl;
  std::cout << "\tdd volume = " << dd.volume() / cm3 << " cm3" << std::endl;
  std::cout << "\tDD Information: " << dds << " vol= " << dds.volume() << std::endl;
}
示例#24
0
void	GSMS::Source::generate_G4(G4GeneralParticleSource*	dst, G4double	dAngle) {

    if (!dst) return;
    for(int i=0; i<m_gamma.size(); i++) {
        G4float	ene = m_gamma[i].first;
        G4float	act = m_gamma[i].second;

        dst->AddaSource(act);
        dst->SetParticleDefinition(G4Gamma::Gamma());
        G4SingleParticleSource*	src = dst->GetCurrentSource();
        src->GetEneDist()->SetMonoEnergy(ene);

        src->GetAngDist()->SetAngDistType("iso");
        src->GetPosDist()->SetPosDisType("Point");
        src->GetEneDist()->SetEnergyDisType("Mono");

        //src->GetPosDist()->SetCentreCoords(get_coords());
        //src->GetPosDist()->SetCentreCoords(G4ThreeVector(1., 0., 0.));
        src->GetPosDist()->SetCentreCoords(G4ThreeVector(m_x, m_y, m_z));

        G4double	basePhi = 0.0;
        m_x != 0.0 ? basePhi = std::atan(m_y/m_x) :
                               m_y > 0 ? basePhi = pi/2 : basePhi = -pi/2;

        if(m_x < 0.0 ) basePhi = -pi + basePhi;

        std::cerr << "X: " << m_x << " Y: " << m_y << " Phi: " << basePhi << std::endl;


        G4double	dPhi = GSMS::get_hull().get_delta_phi(get_coords());
        G4double	baseTheta = pi/2;//TODO

        G4double	dTheta = GSMS::get_hull().get_delta_theta(get_coords());
        std::cerr << "dPhi: " << dPhi*360/2/pi << "; dTheta" << dTheta*360/2/pi << std::endl;

        //dPhi = 3*pi/2/180;//2*pi/2/180;
        //dTheta = 16*pi/2/180;//6*pi/2/180;

        src->GetAngDist()->SetMinPhi(basePhi - dPhi);
        src->GetAngDist()->SetMaxPhi(basePhi + dPhi);
        src->GetAngDist()->SetMinTheta(baseTheta - dTheta);
        src->GetAngDist()->SetMaxTheta(baseTheta + dTheta);
        std::cerr << ene << std::endl;
        std::cerr << act << std::endl;
    }
}
// Primary event
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
   /*
   * To avoid dependence on Detector Construction we will get an envelope volume
   * from the G4LogicalVolumeStore
   *
   * Here we will be assuming our box is sitting in a world where the radiation flux
   * is coming from the -x direction. Thus we will have a uniform random start location
   * through the YZ plane
   */
  G4double envSizeX = 0.;
  G4double envSizeYZ  = 0.;

  if ( !EnvelopeBox )
  {
     G4LogicalVolume* envLV = G4LogicalVolumeStore::GetInstance() -> GetVolume("World");
     if ( envLV ) EnvelopeBox = dynamic_cast<G4Box*>( envLV -> GetSolid() );
  }

  if ( EnvelopeBox ) 
  {
     envSizeYZ = EnvelopeBox -> GetYHalfLength() *2.;
     envSizeX  = EnvelopeBox -> GetXHalfLength() *2.;
  }
  else
  {
     G4ExceptionDescription msg;
     msg << "World volume of box shape is not found.\n";
     msg << "Perhaps you have changed the geometry.\n";
     msg << "\nWhere has the world gone?";
     G4Exception("PrimaryGeneratorAction::GeneratePrimaries()","Mycode0001",JustWarning,msg);
  }

  // We won't use the outer 10% edge
  G4double size = 0.9;
  // Since we are starting in the -x direction and firing in the x direction we want the
  // particles to come uniformly out of the YZ plane
  G4double x0 = 0.5 * envSizeX; 
  G4double y0 = size * envSizeYZ * (G4UniformRand() - 0.5);
  G4double z0 = size * envSizeYZ  * (G4UniformRand() - 0.5);

  particleGun -> SetParticlePosition(G4ThreeVector(-x0,y0,z0));
  //particleGun -> SetParticleMomentumDirection(G4ThreeVector(1.0,0.,0.));  // Pure x momentum
 
  particleGun -> GeneratePrimaryVertex(anEvent);  // creates the initial momentum
}
G4ThreeVector BIPrimaryGeneratorAction::GetParVecEne()
{
   G4double x, y;
   while(1){// HisSource should be changed start with 0
      fHisSource->GetRandom2(x, y);
      if(x >= 78) break;
   }

   fEnergy = pow(10., (y - 152.) / fDy) * 20;

   G4double theta = CLHEP::pi * ((x - 78.) / fDx) / 180.;
   G4double phi = G4UniformRand() * 2. * CLHEP::pi;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   G4ThreeVector particleVec = G4ThreeVector(vx, vy, vz);

   return particleVec;
}
PrimaryGeneratorAction::PrimaryGeneratorAction()
  : G4VUserPrimaryGeneratorAction(),
    particleGun(0),
    EnvelopeBox(0)
{
  G4int n_particle = 1;   
  particleGun = new G4ParticleGun(n_particle); 

  // Here we'll load the whole particle table to be able to call a lookup
  G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
  G4String particleName;
  G4ParticleDefinition* particle = particleTable -> FindParticle(particleName="gamma");

  particleGun -> SetParticleDefinition(particle); 
  particleGun -> SetParticleEnergy(6.0 * MeV);  

  //particleGun -> SetParticlePosition(G4ThreeVector(-1.*m, 0.*m, 0.*m)); 
  particleGun -> SetParticleMomentumDirection(G4ThreeVector(1., 0., 0.));
}
示例#28
0
void BIPrimaryGeneratorAction::ThirdBeamGun()
{
   G4AutoLock lock(&mutexInPGA);
   fEnergy = fEneFnc->GetRandom() * MeV;
   lock.unlock();
   
   G4double theta;
   if(fEnergy > 30.*MeV){
      lock.lock();
      theta = fAngFnc->GetRandom() * deg;
      lock.unlock();
   }
   else
      theta = acos(1. - G4UniformRand() * (1. - cos(20.*deg)));
   G4double phi = G4UniformRand() * fPhiLimit;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   fParVec = G4ThreeVector(vx, vy, vz);
   fParticleGun->SetParticleMomentumDirection(fParVec);
}
示例#29
0
int AddSmallCons(G4double dist, G4double density, G4LogicalVolume* motherLogical, int level) {
	G4double dTheta = THETA_DIST_FACTOR * 2 * asin(SMALL_CONS_R / dist) * mm; /* Theta distance between adjacent cons */

		const G4double SMALL_CONS_R   = 25; /* Radius of the samll cons */
		
	int cnt = 0;
	for(G4double theta = dTheta; theta + dTheta < M_PI; theta += dTheta) { // theta is between [0, Pi] 

		G4double dPhi = PHI_DIST_FACTOR * 2 * asin(SMALL_CONS_R / (dist * sin(theta))); /* Phi distance between adjacent spheres */

		for (G4double phi = dPhi; 2 * phi + dPhi < M_PI; phi += dPhi ) // phi is between [0, Pi/2]
			if (density == 1.0 || G4UniformRand() <= density)
			{
				/* Cons from the outer layers will have bigger radius */
				G4Cons* smallCons = new G4Cons("", 0 * mm, SMALL_CONS_R * mm, 0 * mm, 0.1 * mm, 50 * level * mm, 0 * deg, 360 * deg);
					
				/* Calculate the new center of the cons */
				G4ThreeVector v(dist * sin(theta) * cos(phi) * mm, dist * sin(theta) * sin(phi) * mm, dist * cos(theta) * mm);

				G4RotationMatrix* rot = new G4RotationMatrix();								
				
			    G4double alfa = v.angle(G4ThreeVector(0, 0, 1));
				rot->rotateY(M_PI-v.theta()/*(M_PI-alfa) * rad*/);
				rot->rotateX(-v.phi());
	
				G4LogicalVolume* logicSmallCons = new G4LogicalVolume(smallCons, Air, "", 0, 0, 0);
					
				G4PVPlacement* physiSmallCons = new G4PVPlacement(0, v, logicSmallCons, "", motherLogical, false, 0, false);

				//assert(physiSmallCons->CheckOverlaps());
				cnt++; 
		    }
		}

	return cnt;
}
示例#30
0
/*
// For using ROOT classes.
// When using ROOT classes, it have to be thread local or mutex locked.
// I don't know _G4MT_TLS_ is truely needed or not.
// https://indico.cern.ch/event/226961/material-old/0/0?contribId=0
// In case without, this code looks like working well...
G4ThreadLocal TF1 *fEneFnc_G4MT_TLS_ = 0;
*/
BIPrimaryGeneratorAction::BIPrimaryGeneratorAction(BeamType beamType, G4bool gridFlag, G4bool quarterFlag)
   : G4VUserPrimaryGeneratorAction(),
     fParticleGun(nullptr),
     fInputFile(nullptr),
     fHisSource(nullptr),
     fEneFnc(nullptr),
     fAngFnc(nullptr)
{
   fBeamType = beamType;

   fForGrid = gridFlag;

   fUseQuarter = quarterFlag;
   if(fUseQuarter) fPhiLimit = 0.5 * CLHEP::pi;
   else fPhiLimit = 2. * CLHEP::pi;
   
   fDx = (458. - 78.) / 15.;
   fDy = (332 - 152) / (log10(60.) - log10(20.));

   G4AutoLock lock(&mutexInPGA);
   
   Int_t seed = G4UniformRand() * 1000000;
   G4cout << "Seed of PGA = " << seed << G4endl;
   gRandom->SetSeed(seed);
   
   G4int nPar = 1;
   fParticleGun = new G4ParticleGun(nPar);

   fZPosition = -300.*mm;
   //fZPosition = -160.*mm; // Minimum distance for new beam

   fParVec = G4ThreeVector(0., 0., 1.);
   
   G4ParticleTable *parTable = G4ParticleTable::GetParticleTable();
   G4ParticleDefinition *proton = parTable->FindParticle("proton");
   fParticleGun->SetParticleDefinition(proton);
   fParticleGun->SetParticlePosition(G4ThreeVector(0., 0., fZPosition));
   fParticleGun->SetParticleMomentumDirection(fParVec);
   fParticleGun->SetParticleEnergy(fEnergy);

   fInputFile = new TFile("randomSource.root", "OPEN");
   fHisSource = (TH2D*)fInputFile->Get("HisMap");
   fHisSource->SetName("fHisSource");
   
   DefineCommands();

// Pointer of Function is not good for readable code?
// And also, use if statement does not make program slow.
   if(fBeamType == kFirstBeam){
      fEneFnc = new TF1("fncEne", "exp([0]*x)", 0., 100.);
      fEneFnc->SetParameter(0, -4.77205e-02);
      
      GunFuncPointer = &BIPrimaryGeneratorAction::FirstBeamGun;
   }
   else if(fBeamType == kSecondBeam)
      GunFuncPointer = &BIPrimaryGeneratorAction::SecondBeamGun;
   
   else if(fBeamType == kThirdBeam){
      fEneFnc = new TF1("fncEne", "exp([0]*x)", 0., 100.);
      fEneFnc->SetParameter(0, -4.77205e-02);
      
      fAngFnc = new TF1("fAngFnc", "exp([0]*x)", 0., 20.);
      fAngFnc->SetParameter(0, -8.98131e-02);

      GunFuncPointer = &BIPrimaryGeneratorAction::ThirdBeamGun;
   }
   else{
      G4cout << "Beam type is wrong.  Please check it." << G4endl;
      exit(0);
   }
}