Import Geant4 10.5.0 source tree

This commit is contained in:
Gabriele Cosmo
2018-12-07 15:15:39 +01:00
parent 6aa23be517
commit db49709b53
11370 changed files with 187480 additions and 160142 deletions
File diff suppressed because it is too large Load Diff
@@ -43,6 +43,8 @@
#include "ML2Acc1Messenger.hh"
#include "ML2Acc1.hh"
#include "ML2Accelerator.hh"
#include "G4SystemOfUnits.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
@@ -0,0 +1,951 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2Acc2.hh"
#include "ML2Acc2Messenger.hh"
#include "ML2Accelerator.hh"
#include "G4SystemOfUnits.hh"
#include "G4ios.hh"
using namespace std;
CML2Acc2::CML2Acc2()
{
PVWorld = 0;
acc2Messenger = new CML2Acc2Messenger(this);
}
CML2Acc2::~CML2Acc2(void)
{
}
CML2Acc2* CML2Acc2::instance = 0;
CML2Acc2* CML2Acc2::GetInstance(void)
{
if (instance == 0)
{
instance = new CML2Acc2();
}
return instance;
}
void CML2Acc2::writeInfo()
{
G4cout << "----------------------------------------------------------------" << G4endl;;
G4cout << "Accelerator VARIAN LINAC 2100 " << G4endl;
G4cout <<"\n\n\tnominal beam energy: "<<idEnergy << G4endl;
G4cout << "\tdistance isocentre [mm]:"<< isoCentre/mm << G4endl;
G4cout <<"\tJaw X aperture: 1) "<< jaw1XAperture/mm<<"[mm]\t2) " << jaw2XAperture/mm<< " [mm]"<< G4endl;
G4cout <<"\tJaw Y aperture: 1) "<< jaw1YAperture/mm<<"[mm]\t2) " << jaw2YAperture/mm<< " [mm]\n"<< G4endl;
if (vec_leavesA.size()>0)
{
G4cout << "\tvec_leaves A aperture [mm]" << G4endl;;
for (int i=0; i< (int)vec_leavesA.size(); i++)
{
G4cout<<"\t" <<i <<") "<< vec_leavesA[i]/mm << G4endl;
}
}
else
{
G4cout << "\tNo vec_leaves A" << G4endl;
}
if (vec_leavesB.size()>0)
{
G4cout << "\tvec_leaves B aperture [mm]" << G4endl;
for (int i=0; i< (int)vec_leavesB.size(); i++)
{
G4cout<<"\t" <<i <<") "<< vec_leavesB[i]/mm << G4endl;
}
}
else
{
G4cout << "\tNo vec_leaves B" << G4endl;
}
G4cout << "______________________________________________________________" << G4endl;
}
void CML2Acc2::Construct(G4VPhysicalVolume *PWorld, G4double iso)
{
setIsoCentre(iso);
PVWorld = PWorld;
target();
vacuumWindow();
ionizationChamber();
flatteningFilter();
mirror();
primaryCollimator();
MLC();
Jaw1X();
Jaw2X();
Jaw1Y();
Jaw2Y();
}
void CML2Acc2::SetJawAperture(G4int idJaw, G4ThreeVector &centre, G4ThreeVector halfSize, G4RotationMatrix *cRotation)
{
using namespace std;
G4double theta, x, y, z, dx, dy; //, dz, top;
// G4double beta, R;
x=centre.getX();
y=centre.getY();
z=centre.getZ();
// top=z-78./2.;
dx=halfSize.getX();
dy=halfSize.getY();
// dz=halfSize.getZ();
// G4double p1x, p1y, p2x, p2y, dist;
switch (idJaw)
{
case 1: //idJaw1XV2100:
theta=fabs(atan(jaw1XAperture/isoCentre));
centre.set(z*sin(theta)+dx*cos(theta), y, z*cos(theta)-dx*sin(theta));
cRotation->rotateY(-theta);
break;
case 2: //idJaw2XV2100:
theta=fabs(atan(jaw2XAperture/isoCentre));
centre.set(-(z*sin(theta)+dx*cos(theta)), y, z*cos(theta)-dx*sin(theta));
cRotation->rotateY(theta);
break;
case 3: //idJaw1YV2100:
theta=fabs(atan(jaw1YAperture/isoCentre));
centre.set(x, z*sin(theta)+dy*cos(theta), z*cos(theta)-dy*sin(theta));
cRotation->rotateX(theta);
break;
case 4: //idJaw2YV2100:
theta=fabs(atan(jaw2YAperture/isoCentre));
centre.set(x, -(z*sin(theta)+dy*cos(theta)), z*cos(theta)-dy*sin(theta));
cRotation->rotateX(-theta);
break;
}
}
bool CML2Acc2::target()
{
bool bCreated = false;
switch (idEnergy)
{
case 6:
{
// Physical and logical volumes
G4Material *W = G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
G4Box *targetABox = new G4Box("targetABox", 5.*mm, 5.*mm, (.035*25.4/2.)*mm);
G4LogicalVolume *targetALV = new G4LogicalVolume(targetABox, W, "targetALV", 0, 0, 0);
G4Material *Cu = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu");
G4Box *targetBBox = new G4Box("targetABox", 5.*mm, 5.*mm, (0.062*25.4/2.)*mm);
G4LogicalVolume *targetBLV = new G4LogicalVolume(targetBBox, Cu, "targetBLV", 0, 0, 0);
// specific translations for the various parts of the component
new G4PVPlacement(
0,
G4ThreeVector(0.,0.,targetABox->GetZHalfLength()),
"targetAPV",
targetALV,
PVWorld,
false,
0);
new G4PVPlacement(
0,
G4ThreeVector(0.,0.,targetABox->GetZHalfLength()*2.+targetBBox->GetZHalfLength()),
"targetBPV",
targetBLV,
PVWorld,
false,
0);
// Region for cuts
G4Region *regVol= new G4Region("targetR");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.2*cm);
regVol->SetProductionCuts(cuts);
targetALV->SetRegion(regVol);
regVol->AddRootLogicalVolume(targetALV);
targetBLV->SetRegion(regVol);
regVol->AddRootLogicalVolume(targetBLV);
// Visibility
G4VisAttributes* simpleAlSVisAtt= new G4VisAttributes(G4Colour::Red());
simpleAlSVisAtt->SetVisibility(true);
targetALV->SetVisAttributes(simpleAlSVisAtt);
G4VisAttributes* simpleBlSVisAtt= new G4VisAttributes(G4Colour::Yellow());
simpleBlSVisAtt->SetVisibility(true);
targetBLV->SetVisAttributes(simpleBlSVisAtt);
bCreated = true;
break;
}
case 15:
{
// Physical and logical volumes
G4Material *W = G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
G4Box *targetABox = new G4Box("targetABox", 5.*mm, 5.*mm, (.025*25.4/2.)*mm);
G4LogicalVolume *targetALV = new G4LogicalVolume(targetABox, W, "targetALV", 0, 0, 0);
G4Material *Cu = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu");
G4Box *targetBBox = new G4Box("targetABox", 5.*mm, 5.*mm, (0.312*25.4/2.)*mm);
G4LogicalVolume *targetBLV = new G4LogicalVolume(targetBBox, Cu, "targetBLV", 0, 0, 0);
// specific translations for the various parts of the component
new G4PVPlacement(
0,
G4ThreeVector(0.,0.,targetABox->GetZHalfLength()),
"targetAPV",
targetALV,
PVWorld,
false,
0);
new G4PVPlacement(
0,
G4ThreeVector(0.,0.,targetABox->GetZHalfLength()*2.+targetBBox->GetZHalfLength()),
"targetBPV",
targetBLV,
PVWorld,
false,
0);
// Region for cuts
G4Region *regVol= new G4Region("targetR");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.2*cm);
regVol->SetProductionCuts(cuts);
targetALV->SetRegion(regVol);
regVol->AddRootLogicalVolume(targetALV);
targetBLV->SetRegion(regVol);
regVol->AddRootLogicalVolume(targetBLV);
// Visibility
G4VisAttributes* simpleAlSVisAtt= new G4VisAttributes(G4Colour::Red());
simpleAlSVisAtt->SetVisibility(true);
targetALV->SetVisAttributes(simpleAlSVisAtt);
G4VisAttributes* simpleBlSVisAtt= new G4VisAttributes(G4Colour::Yellow());
simpleBlSVisAtt->SetVisibility(true);
targetBLV->SetVisAttributes(simpleBlSVisAtt);
bCreated=true;
break;
}
}
return bCreated;
}
bool CML2Acc2::primaryCollimator()
{
bool bCreated = false;
// the component as a whole
G4double totalHeight = 80.0*mm;
G4Material *Pb = G4NistManager::Instance()->FindOrBuildMaterial("G4_Pb");
G4Material *Vacuum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
// Region for cuts
G4Region *regVol = new G4Region("primaryCollimator");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(1.*cm);
regVol->SetProductionCuts(cuts);
// //-------------------- upper part----------------
G4ThreeVector centre=G4ThreeVector(0.,0.,16.)-G4ThreeVector(0.,0.,(16. + totalHeight-76.)/2.);
G4Tubs *PCUTube = new G4Tubs("PrimaryCollimatorUTube", 10.*mm, 40.0*mm, 10.*mm, 0.*deg, 360.*deg);
G4LogicalVolume *PCUTubeLV = new G4LogicalVolume(PCUTube, Pb, "PrimaryCollimatorUTubeLV", 0, 0, 0);
new G4PVPlacement(0, centre, "PrimaryCollimatorUTubePV", PCUTubeLV, PVWorld, false, 0);
G4VisAttributes* simpleAlSVisAtt= new G4VisAttributes(G4Colour::White());
simpleAlSVisAtt->SetVisibility(true);
PCUTubeLV->SetVisAttributes(simpleAlSVisAtt);
PCUTubeLV->SetRegion(regVol);
regVol->AddRootLogicalVolume(PCUTubeLV);
// //-------------------- lower part----------------
// Tube
G4Tubs* PCLTube = new G4Tubs("PrimaryCollimatorLTube", 0., 40.*mm, 60./2.*mm, 0.*deg, 360.*deg);
// Cone
G4double coneAperture = 14.*deg;
G4Cons* collimCone = new G4Cons("PrimaryCollimatorLCone", 0., (16.*std::tan(coneAperture))*mm, 0., (76.*std::tan(coneAperture))*mm, 30.*mm, 0.*deg, 360.*deg);
G4LogicalVolume* PCLTubeLV = new G4LogicalVolume(PCLTube, Pb, "PCLTubeLV",0,0,0);
G4LogicalVolume* collimConeLV = new G4LogicalVolume(collimCone, Vacuum, "collimConeLV",0,0,0);
centre = G4ThreeVector(0.,0.,16.+60./2.);
G4VPhysicalVolume *PCLTubePV = new G4PVPlacement(0, centre, "PCLTubePV", PCLTubeLV, PVWorld, false, 0);
centre = G4ThreeVector(0.,0.,0.);
new G4PVPlacement(0, centre, "TubeMinusConeLPV", collimConeLV, PCLTubePV, false, 0);
// Visualization
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Green());
simpleAlSVisAtt->SetVisibility(true);
simpleAlSVisAtt->SetForceSolid(true);
PCLTubeLV->SetVisAttributes(simpleAlSVisAtt);
// Region for cuts
PCLTubeLV->SetRegion(regVol);
regVol->AddRootLogicalVolume(PCLTubeLV);
bCreated = true;
return bCreated;
}
bool CML2Acc2::vacuumWindow()
{
bool bCreated = false;
G4Material *Be=G4NistManager::Instance()->FindOrBuildMaterial("G4_Be");
// Region for cuts
G4Region *regVol = new G4Region("BeWindow");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.1*cm);
regVol->SetProductionCuts(cuts);
G4Tubs* BeWTube = new G4Tubs("BeWindowTube", 0., 50.*mm, 0.12*mm, 0.*deg, 360.*deg);
G4LogicalVolume *BeWTubeLV = new G4LogicalVolume(BeWTube, Be, "BeWTubeLV", 0, 0, 0);
new G4PVPlacement(0, G4ThreeVector(0.,0.,90.*mm), "BeWTubePV", BeWTubeLV, PVWorld, false, 0);
G4VisAttributes* simpleAlSVisAtt= new G4VisAttributes(G4Colour::Yellow());
simpleAlSVisAtt->SetVisibility(true);
BeWTubeLV->SetVisAttributes(simpleAlSVisAtt);
BeWTubeLV->SetRegion(regVol);
regVol->AddRootLogicalVolume(BeWTubeLV);
bCreated = true;
return bCreated;
}
bool CML2Acc2::flatteningFilter()
{
G4String iName;
char a[10];
bool bCreated = false;
switch (idEnergy)
{
case 6:
{
G4double distanceLast = 116.3386 - 0.932*25.4/2.*mm;
G4Material *Cu = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu");
const int PointsNumber=22;
// Coordinates of flattening filter in inches
G4double xRadius[PointsNumber]={0.0000000001, .025, .050, .075, .1, .15, .2, .25, .3, .35, .4, .5, .6, .7, .8, .9, 1., 1.1, 1.205, 1.3, 1.325, 1.5};
G4double yHeight[PointsNumber]={.932, .92, .907, .892, .874, .83, .782, .736, .69, .645, .601, .516, .437, .361, .294, .22, .173, .118, .08, .08, .125, .125};
int i;
// From inches to millimeters
for (i = 0; i<PointsNumber; i++)
{
xRadius[i]*=25.4*mm;
yHeight[i]*=25.4*mm;
}
G4double angleStart=0.;
G4double angleStop=360.0;
G4double halfHeigth, rMaxInf, rMaxSup, rMinInf, rMinSup;
G4String name;
G4ThreeVector centre;
G4LogicalVolume *logVol;
G4Cons *cone;
// G4VPhysicalVolume *phVol;
G4VisAttributes* simpleAlSVisAtt;
G4Region *regVol= new G4Region("flatfilterR");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.2*cm);
regVol->SetProductionCuts(cuts);
for (i = 0 ; i < 19; i++)
{
sprintf(a,"%d", i);
iName = (G4String)a;
halfHeigth = (yHeight[i]-yHeight[i+1])/2. ;
if (i == 18)
{
halfHeigth = yHeight[i]/2.;
}
rMaxInf = xRadius[i];
rMaxSup = xRadius[i+1];
rMinInf = 0.;
rMinSup = 0.;
centre.set(0.,0.,distanceLast+halfHeigth); distanceLast+=halfHeigth*2.;
name = "ffConeG"+iName;
cone = new G4Cons(name, rMinInf, rMaxInf, rMinSup, rMaxSup, halfHeigth, angleStart, angleStop);
name = "ffConeLV"+iName;
logVol = new G4LogicalVolume(cone, Cu, name, 0, 0, 0);
name = "ffConePV"+iName;
new G4PVPlacement(0, centre, name, logVol, PVWorld, false, 0);
// Region for cuts
logVol->SetRegion(regVol);
regVol->AddRootLogicalVolume(logVol);
// Visualization
simpleAlSVisAtt= new G4VisAttributes(G4Colour::Cyan());
simpleAlSVisAtt->SetVisibility(true);
logVol->SetVisAttributes(simpleAlSVisAtt);
}
halfHeigth = yHeight[19]/2. ;
rMaxInf = xRadius[21];
rMaxSup = xRadius[21];
rMinInf = 0.;
rMinSup = 0.;
centre.set(0.,0., distanceLast+halfHeigth);
sprintf(a,"%d", i);
iName = (G4String)a;
name = "ffConeG"+iName;
cone = new G4Cons(name, rMinInf, rMaxInf, rMinSup, rMaxSup, halfHeigth, angleStart, angleStop);
name = "ffConeLV"+iName;
logVol = new G4LogicalVolume(cone, Cu, name, 0, 0, 0);
name = "ffConePV"+iName;
new G4PVPlacement(0, centre, name, logVol, PVWorld, false, 0);
// Region for cuts
logVol->SetRegion(regVol);
regVol->AddRootLogicalVolume(logVol);
// Visualization
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Cyan());
simpleAlSVisAtt -> SetVisibility(true);
logVol -> SetVisAttributes(simpleAlSVisAtt);
halfHeigth = (yHeight[20]-yHeight[19])/2. ;
rMaxInf = xRadius[21];
rMaxSup = xRadius[21];
rMinInf = xRadius[20];
rMinSup = xRadius[19];
centre.set(0.,0., distanceLast-halfHeigth);
sprintf(a,"%d", ++i);
iName = (G4String)a;
name = "ffConeG"+iName;
cone = new G4Cons(name, rMinInf, rMaxInf, rMinSup, rMaxSup, halfHeigth, angleStart, angleStop);
name = "ffConeLV"+iName;
logVol = new G4LogicalVolume(cone, Cu, name, 0, 0, 0);
name = "ffConePV"+iName;
new G4PVPlacement(0, centre, name, logVol,PVWorld, false, 0);
// Region for cuts
logVol->SetRegion(regVol);
regVol->AddRootLogicalVolume(logVol);
// Visualization
simpleAlSVisAtt= new G4VisAttributes(G4Colour::Cyan());
simpleAlSVisAtt->SetVisibility(true);
logVol->SetVisAttributes(simpleAlSVisAtt);
bCreated = true;
break;
}
case 15:
{
G4double distanceLast = 125.+.125*25.4 - 0.744*25.4/2.- 0.744*25.4/2.*mm;
G4Material *Cu = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu");
const int PointsNumber = 21;
// Coordinate in pollici del flattening filter come da disegno
G4double xRadius[PointsNumber] = {0.0000000001, 0.040, 0.078,
0.105, 0.131, 0.160, 0.205, 0.248, 0.343, 0.436, 0.531,
0.628, 0.727, 0.829, 0.880, 0.932, 0.983, 1.037, 1.250,
1.350, 1.5};
G4double yHeight[PointsNumber] = {0.744, 0.718, 0.682, 0.653,
0.622, 0.593, 0.547, 0.506, 0.427, 0.354, 0.287, 0.225,
0.168, 0.119, 0.090, 0.067, 0.047, 0.030, 0.030, 0.125,
0.125};
// From inches to millimeters
int i;
for (i = 0; i < PointsNumber; i++)
{
xRadius[i]*=25.4*mm;
yHeight[i]*=25.4*mm;
}
G4double angleStart = 0.;
G4double angleStop = 360.0;
G4double halfHeigth, rMaxInf, rMaxSup, rMinInf, rMinSup;
G4String name;
G4ThreeVector centre;
G4Cons *cone;
G4LogicalVolume *logVol;
// G4VPhysicalVolume *phVol;
G4VisAttributes* simpleAlSVisAtt;
G4Region *regVol= new G4Region("flatfilterR");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.2*cm);
regVol->SetProductionCuts(cuts);
for (i=0;i<18;i++)
{
sprintf(a,"%d", i);
iName = (G4String)a;
halfHeigth = (yHeight[i]-yHeight[i+1])/2. ;
if (i == 17)
{
halfHeigth = yHeight[i]/2.;
}
rMaxInf = xRadius[i];
rMaxSup = xRadius[i+1];
rMinInf = 0.;
rMinSup = 0.;
centre.set(0.,0.,distanceLast+halfHeigth); distanceLast+=halfHeigth*2.;
name = "ffConeG"+iName;
cone = new G4Cons(name, rMinInf, rMaxInf, rMinSup, rMaxSup, halfHeigth, angleStart, angleStop);
name = "ffConeLV"+iName;
logVol = new G4LogicalVolume(cone, Cu, name, 0, 0, 0);
name = "ffConePV"+iName;
new G4PVPlacement(0, centre, name, logVol, PVWorld, false, 0);
// Region for cuts
logVol -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(logVol);
// Visualization
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Cyan());
simpleAlSVisAtt -> SetVisibility(true);
logVol -> SetVisAttributes(simpleAlSVisAtt);
}
halfHeigth = yHeight[18]/2. ;
rMaxInf = xRadius[20];
rMaxSup = xRadius[20];
rMinInf = 0.;
rMinSup = 0.;
centre.set(0.,0., distanceLast+halfHeigth);
sprintf(a,"%d", i);
iName = (G4String)a;
name = "ffConeG"+iName;
cone = new G4Cons(name, rMinInf, rMaxInf, rMinSup, rMaxSup, halfHeigth, angleStart, angleStop);
name = "ffConeLV"+iName;
logVol = new G4LogicalVolume(cone, Cu, name, 0, 0, 0);
name = "ffConePV"+iName;
new G4PVPlacement(0, centre, name, logVol, PVWorld, false, 0);
// Region for cuts
logVol -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(logVol);
// Visualization
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Cyan());
simpleAlSVisAtt -> SetVisibility(true);
logVol -> SetVisAttributes(simpleAlSVisAtt);
halfHeigth = (yHeight[19]-yHeight[18])/2. ;
rMaxInf = xRadius[20];
rMaxSup = xRadius[20];
rMinInf = xRadius[19];
rMinSup = xRadius[18];
centre.set(0.,0., distanceLast-halfHeigth);
sprintf(a,"%d", ++i);
iName = (G4String)a;
name = "ffConeG"+iName;
cone = new G4Cons(name, rMinInf, rMaxInf, rMinSup, rMaxSup, halfHeigth, angleStart, angleStop);
name = "ffConeLV"+iName;
logVol = new G4LogicalVolume(cone, Cu, name, 0, 0, 0);
name = "ffConePV"+iName;
new G4PVPlacement(0, centre, name, logVol,PVWorld, false, 0);
// Region for cuts
logVol -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(logVol);
// Visualization
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Cyan());
simpleAlSVisAtt -> SetVisibility(true);
logVol -> SetVisAttributes(simpleAlSVisAtt);
bCreated = true;
break;
}
}
return bCreated;
}
bool CML2Acc2::ionizationChamber()
{
bool bCreated = false;
G4Material *KAPTON = G4NistManager::Instance()->FindOrBuildMaterial("G4_KAPTON");
G4Region *regVol = new G4Region("ionizationChamber");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts -> SetProductionCut(0.1*cm);
regVol -> SetProductionCuts(cuts);
G4VisAttributes* simpleAlSVisAtt;
// Region for cuts
G4Tubs* ICTubeW = new G4Tubs("ionizationChamberTube", 0., 3.75*2.54*10.*mm, 0.005*25.4*mm, 0.*deg, 360.*deg);
G4Tubs* ICTubeP = new G4Tubs("ionizationChamberTube", 0., 3.75*2.54*10.*mm, 0.002*25.4*mm, 0.*deg, 360.*deg);
G4ThreeVector centre;
// W1
centre.set(0.,0.,148.35*mm);
G4LogicalVolume *PCUTubeW1LV = new G4LogicalVolume(ICTubeW, KAPTON, "ionizationChamberTubeW1LV", 0, 0, 0);
new G4PVPlacement(0, centre, "ionizationChamberTubeW1PV", PCUTubeW1LV, PVWorld, false, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Blue());
simpleAlSVisAtt -> SetVisibility(true);
PCUTubeW1LV -> SetVisAttributes(simpleAlSVisAtt);
PCUTubeW1LV -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(PCUTubeW1LV);
// P1
centre.set(0.,0.,150.73*mm);
G4LogicalVolume *PCUTubeP1LV = new G4LogicalVolume(ICTubeP, KAPTON, "ionizationChamberTubeP1LV", 0, 0, 0);
new G4PVPlacement(0, centre, "ionizationChamberTubeP1PV", PCUTubeP1LV, PVWorld, false, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Yellow());
simpleAlSVisAtt -> SetVisibility(true);
PCUTubeP1LV -> SetVisAttributes(simpleAlSVisAtt);
PCUTubeP1LV -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(PCUTubeP1LV);
// W2
centre.set(0.,0.,155.5*mm);
G4LogicalVolume *PCUTubeW2LV = new G4LogicalVolume(ICTubeW, KAPTON, "ionizationChamberTubeW2LV", 0, 0, 0);
new G4PVPlacement(0, centre, "ionizationChamberTubeW2PV", PCUTubeW2LV, PVWorld, false, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Blue());
simpleAlSVisAtt -> SetVisibility(true);
PCUTubeW2LV -> SetVisAttributes(simpleAlSVisAtt);
PCUTubeW2LV -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(PCUTubeW2LV);
// P2
centre.set(0.,0.,153.12*mm);
G4LogicalVolume *PCUTubeP2LV = new G4LogicalVolume(ICTubeP, KAPTON, "ionizationChamberTubeP2LV", 0, 0, 0);
new G4PVPlacement(0, centre, "ionizationChamberTubeP2PV", PCUTubeP2LV, PVWorld, false, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Yellow());
simpleAlSVisAtt->SetVisibility(true);
PCUTubeP2LV->SetVisAttributes(simpleAlSVisAtt);
PCUTubeP2LV->SetRegion(regVol);
regVol->AddRootLogicalVolume(PCUTubeP2LV);
// W3
centre.set(0.,0.,162.65*mm);
G4LogicalVolume *PCUTubeW3LV = new G4LogicalVolume(ICTubeW, KAPTON, "ionizationChamberTubeW3LV", 0, 0, 0);
new G4PVPlacement(0, centre, "ionizationChamberTubeW3PV", PCUTubeW3LV, PVWorld, false, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Blue());
simpleAlSVisAtt -> SetVisibility(true);
PCUTubeW3LV -> SetVisAttributes(simpleAlSVisAtt);
PCUTubeW3LV -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(PCUTubeW3LV);
// P3
centre.set(0.,0.,157.88*mm);
G4LogicalVolume *PCUTubeP3LV = new G4LogicalVolume(ICTubeP, KAPTON, "ionizationChamberTubeP3LV", 0, 0, 0);
new G4PVPlacement(0, centre, "ionizationChamberTubeP3PV", PCUTubeP3LV, PVWorld, false, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Yellow());
simpleAlSVisAtt -> SetVisibility(true);
PCUTubeP3LV -> SetVisAttributes(simpleAlSVisAtt);
PCUTubeP3LV -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(PCUTubeP3LV);
// P4
centre.set(0.,0.,160.27*mm);
G4LogicalVolume *PCUTubeP4LV = new G4LogicalVolume(ICTubeP, KAPTON, "ionizationChamberTubeP4LV", 0, 0, 0);
new G4PVPlacement(0, centre, "ionizationChamberTubeP4PV", PCUTubeP4LV, PVWorld, false, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Yellow());
simpleAlSVisAtt->SetVisibility(true);
PCUTubeP4LV->SetVisAttributes(simpleAlSVisAtt);
PCUTubeP4LV->SetRegion(regVol);
regVol->AddRootLogicalVolume(PCUTubeP4LV);
bCreated = true;
return bCreated;
}
bool CML2Acc2::mirror()
{
bool bCreated = false;
G4Material *MYLAR = G4NistManager::Instance()->FindOrBuildMaterial("G4_MYLAR");
// Region for cuts
G4Region *regVol = new G4Region("Mirror");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts -> SetProductionCut(0.1*cm);
regVol -> SetProductionCuts(cuts);
G4Tubs* MirrorTube = new G4Tubs("MirrorTube", 0., 86.*mm, 1.*mm, 0.*deg, 360.*deg);
G4LogicalVolume *MirrorTubeLV = new G4LogicalVolume(MirrorTube, MYLAR, "MirrorTubeLV", 0, 0, 0);
G4RotationMatrix *cRotation = new G4RotationMatrix();
cRotation -> rotateY(35.0*deg);
new G4PVPlacement(cRotation, G4ThreeVector(0., 0., 220.*mm), "MirrorTubePV", MirrorTubeLV,PVWorld, false, 0);
G4VisAttributes* simpleAlSVisAtt = new G4VisAttributes(G4Colour::Green());
simpleAlSVisAtt -> SetVisibility(true);
MirrorTubeLV -> SetVisAttributes(simpleAlSVisAtt);
MirrorTubeLV -> SetRegion(regVol);
regVol -> AddRootLogicalVolume(MirrorTubeLV);
bCreated = true;
return bCreated;
}
bool CML2Acc2::Jaw1X()
{
bool bCreated = false;
G4Material *W = G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
G4String name = "Jaws1X";
G4Region *regVol= new G4Region(name+"R");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(1.*cm);
regVol->SetProductionCuts(cuts);
G4VisAttributes* simpleAlSVisAtt;
G4ThreeVector centre, halfSize;
G4RotationMatrix *cRotation = new G4RotationMatrix();
centre.set(0.,0.,(367.+78./2.)*mm);
halfSize.set(50.*mm, 90.*mm, 78./2.*mm);
G4Box *box = new G4Box(name+"Box", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *logVol = new G4LogicalVolume(box, W, name+"LV", 0, 0, 0);
SetJawAperture(1, centre, halfSize,cRotation);
new G4PVPlacement(cRotation, centre, name+"PV", logVol, PVWorld, false, 0);
// Region for cuts
logVol->SetRegion(regVol);
regVol->AddRootLogicalVolume(logVol);
// Visibility
simpleAlSVisAtt= new G4VisAttributes(G4Colour::Blue());
simpleAlSVisAtt->SetVisibility(true);
logVol->SetVisAttributes(simpleAlSVisAtt);
bCreated = true;
return bCreated;
}
bool CML2Acc2::Jaw2X()
{
bool bCreated=false;
G4Material *W=G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
G4String name="Jaws2X";
G4Region *regVol= new G4Region(name+"R");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(1.*cm);
regVol->SetProductionCuts(cuts);
G4VisAttributes* simpleAlSVisAtt;
G4ThreeVector centre, halfSize;
G4RotationMatrix *cRotation = new G4RotationMatrix();
centre.set(0.,0.,(367.+78./2.)*mm);
halfSize.set(50.*mm, 90.*mm, 78./2.*mm);
G4Box *box = new G4Box(name+"Box", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *logVol = new G4LogicalVolume(box, W, name+"LV", 0, 0, 0);
SetJawAperture(2, centre, halfSize, cRotation);
new G4PVPlacement(cRotation, centre, name+"PV", logVol, PVWorld, false, 0);
// Region for cuts
logVol->SetRegion(regVol);
regVol->AddRootLogicalVolume(logVol);
// Visibility
simpleAlSVisAtt= new G4VisAttributes(G4Colour::Blue());
simpleAlSVisAtt->SetVisibility(true);
logVol->SetVisAttributes(simpleAlSVisAtt);
bCreated = true;
return bCreated;
}
bool CML2Acc2::Jaw1Y()
{
bool bCreated = false;
G4Material *W = G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
G4String name="Jaws1Y";
G4Region *regVol= new G4Region(name+"R");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(1.*cm);
regVol->SetProductionCuts(cuts);
G4VisAttributes* simpleAlSVisAtt;
G4ThreeVector centre, halfSize;
G4RotationMatrix *cRotation=new G4RotationMatrix();
centre.set(0.,0.,(280.+78./2.)*mm);
halfSize.set(90.*mm, 50.*mm, 78./2.*mm);
G4Box *box = new G4Box(name+"Box", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *logVol = new G4LogicalVolume(box, W, name+"LV", 0, 0, 0);
SetJawAperture(3, centre, halfSize, cRotation);
new G4PVPlacement(cRotation, centre, name+"PV", logVol, PVWorld, false, 0);
// Region for cuts
logVol->SetRegion(regVol);
regVol->AddRootLogicalVolume(logVol);
// Visibility
simpleAlSVisAtt= new G4VisAttributes(G4Colour::Red());
simpleAlSVisAtt->SetVisibility(true);
logVol->SetVisAttributes(simpleAlSVisAtt);
bCreated = true;
return bCreated;
}
bool CML2Acc2::Jaw2Y()
{
bool bCreated = false;
G4Material *W = G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
G4String name = "Jaws2Y";
G4Region *regVol = new G4Region(name+"R");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(1.*cm);
regVol->SetProductionCuts(cuts);
G4ThreeVector centre, halfSize;
G4RotationMatrix *cRotation=new G4RotationMatrix();
centre.set(0.,0.,(280.+78./2.)*mm);
halfSize.set(90.*mm, 50.*mm, 78./2.*mm);
G4Box *box = new G4Box(name+"Box", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *logVol = new G4LogicalVolume(box, W, name+"LV", 0, 0, 0);
SetJawAperture(4, centre, halfSize, cRotation);
new G4PVPlacement(cRotation, centre, name+"PV", logVol, PVWorld, false, 0);
// Region for cuts
logVol->SetRegion(regVol);
regVol->AddRootLogicalVolume(logVol);
// Visibility
G4VisAttributes* simpleAlSVisAtt = new G4VisAttributes(G4Colour::Red());
simpleAlSVisAtt -> SetVisibility(true);
logVol -> SetVisAttributes(simpleAlSVisAtt);
bCreated = true;
return bCreated;
}
bool CML2Acc2::MLC()
{
G4String iName;
char a[12];
bool bCreated = false;
// material
G4Material *W = G4NistManager::Instance()->FindOrBuildMaterial("G4_W");
G4VisAttributes* simpleAlSVisAtt;
// Region for cuts
G4Region *regVol = new G4Region("MLCR");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.5*cm);
regVol->SetProductionCuts(cuts);
G4ThreeVector box1Size, box2Size;
G4ThreeVector centreStart;
centreStart.set(0.,0.,(482.5+535.5)/2.*mm);
box1Size.set(5.2883/2.*mm, 167.488/2.*mm, 61.2953/2.*mm);
G4double circleRadiuos=80.0*mm;
G4double alfa=std::asin(box1Size.getZ()/circleRadiuos);
G4double externalYPartSize=circleRadiuos*(1-std::cos(alfa));
box2Size.set(box1Size.getX(), externalYPartSize/2., box1Size.getZ());
// single leaf
G4Box *box1Leaf = new G4Box("LeafBox1", box1Size.getX(), box1Size.getY(), box1Size.getZ());
G4Box *box2leaf = new G4Box("LeafBox2", box2Size.getX(), box2Size.getY(), box2Size.getZ());
G4Tubs *cyLeaf = new G4Tubs("LeafCylinder", 0, circleRadiuos, box1Size.getX(),0,CLHEP::twopi);
G4RotationMatrix *rm=new G4RotationMatrix();
rm->rotateY(90.*deg);
G4DisplacedSolid *cyLeaf90Y=new G4DisplacedSolid("LeafCylinder90Y",cyLeaf,rm,G4ThreeVector(0,0,0));
G4DisplacedSolid *cyLeafTr=new G4DisplacedSolid("LeafCylinderTr",cyLeaf90Y,0,G4ThreeVector(0., -(circleRadiuos-box2Size.getY()), 0.));
G4IntersectionSolid* bx2CyleafTr =new G4IntersectionSolid("bx2CyleafTr", box2leaf, cyLeafTr);
G4DisplacedSolid *bx2CyleafTrTr=new G4DisplacedSolid("bx2CyleafTrTr",bx2CyleafTr,0,G4ThreeVector(0., +(box1Size.getY()+box2Size.getY()-.1), 0.)); // -.1 to guarantee the volumes touch each other
G4UnionSolid *leafSolidA = new G4UnionSolid("SingleLeafA", bx2CyleafTrTr, box1Leaf);
rm = new G4RotationMatrix();
rm -> rotateZ(180.*deg);
G4DisplacedSolid *leafSolidB = new G4DisplacedSolid("SingleLeafB", leafSolidA, rm, G4ThreeVector(0,0,0));
G4ThreeVector halfSize;
halfSize.set(0., box2Size.getY()*2.-.1,0.);
halfSize+=box1Size;
G4LogicalVolume *leafLVA = new G4LogicalVolume(leafSolidA, W, "leafSolidALV", 0, 0, 0);
G4LogicalVolume *leafLVB = new G4LogicalVolume(leafSolidB, W, "leafSolidBLV", 0, 0, 0);
simpleAlSVisAtt = new G4VisAttributes(G4Colour::Green());
simpleAlSVisAtt->SetVisibility(true);
leafLVA->SetVisAttributes(simpleAlSVisAtt);
leafLVA->SetRegion(regVol);
regVol->AddRootLogicalVolume(leafLVA);
simpleAlSVisAtt= new G4VisAttributes(G4Colour::Green());
simpleAlSVisAtt->SetVisibility(true);
leafLVB->SetVisAttributes(simpleAlSVisAtt);
leafLVB->SetRegion(regVol);
regVol->AddRootLogicalVolume(leafLVB);
G4String PVname;
// G4VPhysicalVolume *leafPhys;
int i;
int j = 0;
G4ThreeVector centre;
centre= centreStart + G4ThreeVector(-38.*halfSize.getX(), 0.,0.);
for (i = 1; i < (int)vec_leavesA.size(); i++)
{
sprintf(a,"%d", i);
iName = (G4String)a;
PVname = "leafA"+iName;
centre.setX(centre.getX()+halfSize.getX()*2.);
centre.setY(-halfSize.getY()-vec_leavesA[i]);
new G4PVPlacement(0, centre, PVname, leafLVA, PVWorld, false, i);
j++;
}
centre=centreStart+G4ThreeVector(-38.*halfSize.getX(), 0.,0.);
for (i = 1; i < (int)vec_leavesB.size(); i++)
{
sprintf(a,"%d", i);
iName = (G4String)a;
PVname = "leafB"+iName;
centre.setX(centre.getX()+halfSize.getX()*2.);
centre.setY(+halfSize.getY()+vec_leavesB[i]);
new G4PVPlacement(0, centre, PVname, leafLVB, PVWorld, false, i);
j++;
}
bCreated = true;
return bCreated;
}
@@ -0,0 +1,141 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2Accelerator.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4SystemOfUnits.hh"
#include "../include/ML2Acc2.hh"
#include "../include/ML2Acc2Messenger.hh"
CML2Acc2Messenger::CML2Acc2Messenger(CML2Acc2 *acc2) : pAcc2(acc2)
{
idEnergy=new G4UIcmdWithAnInteger("/accelerator/idEnergy",this);
idEnergy->SetDefaultValue(6);
pAcc2->setidEnergy(6);
leavesA=new G4UIcmdWithADoubleAndUnit("/accelerator/leavesA", this);
leavesA->SetDefaultUnit("mm");
leavesA->SetDefaultValue(300.);
pAcc2->setLeavesAx(300.*mm);
leavesB=new G4UIcmdWithADoubleAndUnit("/accelerator/leavesB", this);
leavesB->SetDefaultUnit("mm");
leavesB->SetDefaultValue(300.);
pAcc2->setLeavesBx(300.*mm);
aperture1X=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture1X", this);
aperture1X->SetDefaultUnit("mm");
aperture1X->SetDefaultValue(100.);
pAcc2->setJaw1X(100.*mm);
aperture1Y=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture1Y", this);
aperture1Y->SetDefaultUnit("mm");
aperture1Y->SetDefaultValue(100.);
pAcc2->setJaw1Y(100.*mm);
aperture2X=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture2X", this);
aperture2X->SetDefaultUnit("mm");
aperture2X->SetDefaultValue(-100.);
pAcc2->setJaw2X(-100.*mm);
aperture2Y=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture2Y", this);
aperture2Y->SetDefaultUnit("mm");
aperture2Y->SetDefaultValue(-100.);
pAcc2->setJaw2Y(-100.*mm);
}
CML2Acc2Messenger::~CML2Acc2Messenger(void)
{
delete idEnergy;
delete aperture1X;
delete aperture2X;
delete aperture1Y;
delete aperture2Y;
delete leavesA;
delete leavesB;
}
void CML2Acc2Messenger::SetNewValue(G4UIcommand* cmd, G4String newValue)
{
if (cmd==idEnergy)
{
pAcc2->setidEnergy(idEnergy->GetNewIntValue(newValue));
}
if (cmd==aperture1X)
{
aperture1X->GetNewUnitValue(newValue);
pAcc2->setJaw1X(aperture1X->GetNewDoubleValue(newValue));
}
if (cmd==aperture1Y)
{
aperture1Y->GetNewUnitValue(newValue);
pAcc2->setJaw1Y(aperture1Y->GetNewDoubleValue(newValue));
}
if (cmd==aperture2X)
{
aperture2X->GetNewUnitValue(newValue);
pAcc2->setJaw2X(aperture2X->GetNewDoubleValue(newValue));
}
if (cmd==aperture2Y)
{
aperture2Y->GetNewUnitValue(newValue);
pAcc2->setJaw2Y(aperture2Y->GetNewDoubleValue(newValue));
}
if (cmd==leavesA)
{pAcc2->setLeavesAx(leavesA->GetNewDoubleValue(newValue));}
if (cmd==leavesB)
{pAcc2->setLeavesBx(leavesA->GetNewDoubleValue(newValue));}
if (cmd==idEnergy)
{pAcc2->setidEnergy(idEnergy->GetNewIntValue(newValue));}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,136 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2Accelerator.hh"
#include "ML2AccSaturn.hh"
#include "ML2AccSaturnMessenger.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4SystemOfUnits.hh"
CML2AccSaturnMessenger::CML2AccSaturnMessenger(CML2AccSaturn *accSaturn ) : pAccSaturn(accSaturn)
{
idEnergy=new G4UIcmdWithAnInteger("/accelerator/idEnergy", this);
idEnergy->SetDefaultValue(6);
pAccSaturn->setidEnergy(6);
leavesA=new G4UIcmdWithADoubleAndUnit("/accelerator/leavesA", this);
leavesA->SetDefaultUnit("mm");
leavesA->SetDefaultValue(300.);
pAccSaturn->setLeavesAx(300.*mm);
leavesB=new G4UIcmdWithADoubleAndUnit("/accelerator/leavesB", this);
leavesB->SetDefaultUnit("mm");
leavesB->SetDefaultValue(300.);
pAccSaturn->setLeavesBx(300.*mm);
aperture1X=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture1X", this);
aperture1X->SetDefaultUnit("mm");
aperture1X->SetDefaultValue(100.);
pAccSaturn->setJaw1X(100.*mm);
aperture1Y=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture1Y", this);
aperture1Y->SetDefaultUnit("mm");
aperture1Y->SetDefaultValue(100.);
pAccSaturn->setJaw1Y(100.*mm);
aperture2X=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture2X", this);
aperture2X->SetDefaultUnit("mm");
aperture2X->SetDefaultValue(-100.);
pAccSaturn->setJaw2X(-100.*mm);
aperture2Y=new G4UIcmdWithADoubleAndUnit("/accelerator/aperture2Y", this);
aperture2Y->SetDefaultUnit("mm");
aperture2Y->SetDefaultValue(-100.);
pAccSaturn->setJaw2Y(-100.*mm);
}
CML2AccSaturnMessenger::~CML2AccSaturnMessenger(void)
{
delete idEnergy;
delete aperture1X;
delete aperture2X;
delete aperture1Y;
delete aperture2Y;
delete leavesA;
delete leavesB;
}
void CML2AccSaturnMessenger::SetNewValue(G4UIcommand* cmd, G4String newValue)
{
if (cmd==aperture1X)
{
aperture1X->GetNewUnitValue(newValue);
pAccSaturn->setJaw1X(aperture1X->GetNewDoubleValue(newValue));
}
if (cmd==aperture1Y)
{
aperture1Y->GetNewUnitValue(newValue);
pAccSaturn->setJaw1Y(aperture1Y->GetNewDoubleValue(newValue));
}
if (cmd==aperture2X)
{
aperture2X->GetNewUnitValue(newValue);
pAccSaturn->setJaw2X(aperture2X->GetNewDoubleValue(newValue));
}
if (cmd==aperture2Y)
{
aperture2Y->GetNewUnitValue(newValue);
pAccSaturn->setJaw2Y(aperture2Y->GetNewDoubleValue(newValue));
}
if (cmd==leavesA)
{pAccSaturn->setLeavesAx(leavesA->GetNewDoubleValue(newValue));}
if (cmd==leavesB)
{pAccSaturn->setLeavesBx(leavesA->GetNewDoubleValue(newValue));}
if (cmd==idEnergy)
{pAccSaturn->setidEnergy(idEnergy->GetNewIntValue(newValue));}
}
@@ -0,0 +1,125 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2Accelerator.hh"
#include "G4SystemOfUnits.hh"
CML2Accelerator::CML2Accelerator()
{
jaw1XAperture = 0;
jaw2XAperture = 0;
jaw1YAperture = 0;
jaw2YAperture = 0;
idEnergy = 0;
isoCentre = 0;
}
CML2Accelerator::~CML2Accelerator(void)
{
}
void CML2Accelerator::Construct(G4VPhysicalVolume *, G4double)
{
}
void CML2Accelerator::reset()
{
vec_leavesA.clear();
vec_leavesB.clear();
}
void CML2Accelerator::setJaw1X(G4double val)
{
jaw1XAperture = val;
}
void CML2Accelerator::setJaw2X(G4double val)
{
jaw2XAperture = val;
}
void CML2Accelerator::setJaw1Y(G4double val)
{
jaw1YAperture = val;
}
void CML2Accelerator::setJaw2Y(G4double val)
{
jaw2YAperture = val;
}
void CML2Accelerator::setIsoCentre(G4double val)
{
isoCentre=val;
}
void CML2Accelerator::setidEnergy(G4int val)
{
idEnergy=val;
}
void CML2Accelerator::setLeavesAx(G4double val)
{
vec_leavesA.push_back(val);
}
void CML2Accelerator::setLeavesBx(G4double val)
{
vec_leavesB.push_back(val);
}
int CML2Accelerator::getidEnergy()
{
return idEnergy;
}
@@ -40,22 +40,22 @@
//
//*******************************************************//
#include "ML2AcceleratorConstruction.hh"
#include "ML2AcceleratorConstructionMessenger.hh"
#include "G4ios.hh"
#include "G4SystemOfUnits.hh"
using namespace std;
CML2AcceleratorConstruction::CML2AcceleratorConstruction(void)
{
acceleratorConstructionMessenger=new CML2AcceleratorConstructionMessenger(this);
idCurrentRotationX=0;
acceleratorConstructionMessenger = new CML2AcceleratorConstructionMessenger(this);
idCurrentRotationX = 0;
}
CML2AcceleratorConstruction::~CML2AcceleratorConstruction(void)
{
if (AcceleratorName=="acc1")
{delete accelerator1;}
delete PVAccWorld;
delete acceleratorConstructionMessenger;
}
CML2AcceleratorConstruction* CML2AcceleratorConstruction::instance = 0;
@@ -71,62 +71,71 @@ CML2AcceleratorConstruction* CML2AcceleratorConstruction::GetInstance(void)
void CML2AcceleratorConstruction::resetAccelerator()
{
if (AcceleratorName=="acc1")
{
accelerator1->reset();
}
accelerator -> reset();
}
bool CML2AcceleratorConstruction::design(void)
{
// switch between different accelerators according to the main macro selection (actually only one accelerator is available)
std::cout << "I'm building "<< AcceleratorName<<" accelerator"<< G4endl;
bool bAccExists=false;
if (AcceleratorName=="acc1")
{accelerator1=CML2Acc1::GetInstance();bAccExists=true;}
G4cout << "I'm building " << AcceleratorName << " accelerator" << G4endl;
bool bAccExists = false;
if (AcceleratorName == "acc1")
{
accelerator = CML2Acc1::GetInstance();
bAccExists = true;
}
else if (AcceleratorName == "acc2")
{
accelerator = CML2Acc2::GetInstance();
bAccExists = true;
}
else if (AcceleratorName == "accSaturn")
{
accelerator = CML2AccSaturn::GetInstance();
bAccExists = true;
}
if (bAccExists && AcceleratorMacFileName!="")
{
// read the messenger data related to the accelerator selected
// read the messenger data related to the selected accelerator
G4UImanager* UI = G4UImanager::GetUIpointer();
G4String command = "/control/execute ";
UI->ApplyCommand(command+AcceleratorMacFileName);
}
if (rotationsX.size()<1)
{addAcceleratorRotationsX(0.);}
if (rotationsX.size() < 1)
{
addAcceleratorRotationsX(0.);
}
return bAccExists;
}
bool CML2AcceleratorConstruction::Construct(G4VPhysicalVolume *PVWorld, G4bool bOV)
{
// a call to select the right accelerator
bOnlyVisio=bOV;
// a call to select the right accelerator
bOnlyVisio = bOV;
if (design())
{
// G4cout << "*** debug *** AcceleratorConstruction::Construct" << G4endl;
acceleratorConstructionMessenger->SetReferenceWorld(bOnlyVisio);
// create the accelerator-world box
G4Material *Vacuum=G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4Material *Vacuum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4ThreeVector halfSize;
initialCentre.set(0.*mm, 0.*mm, -isoCentre);
halfSize.set(600.*mm, 600.*mm, 600.*mm);
G4Box *accWorldB = new G4Box("accWorldG", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *accWorldLV = new G4LogicalVolume(accWorldB, Vacuum, "accWorldL", 0, 0, 0);
G4VisAttributes* simpleAlSVisAtt= new G4VisAttributes(G4Colour::White());
simpleAlSVisAtt->SetVisibility(false);
// simpleAlSVisAtt->SetForceWireframe(false);
accWorldLV->SetVisAttributes(simpleAlSVisAtt);
G4VisAttributes* simpleAlSVisAtt = new G4VisAttributes(G4Colour::White());
simpleAlSVisAtt -> SetVisibility(false);
accWorldLV -> SetVisAttributes(simpleAlSVisAtt);
PVAccWorld= new G4PVPlacement(0, initialCentre, "acceleratorBox", accWorldLV, PVWorld, false, 0);
// create the actual accelerator
if (AcceleratorName=="acc1")
{
accelerator1->Construct(PVAccWorld, isoCentre);
Z_Value_PhaseSpaceBeforeJaws=accelerator1->getBeforeJaws_Z_PhaseSpacePosition();
accelerator1->writeInfo();
}
// create the actual accelerator
accelerator -> Construct(PVAccWorld, isoCentre);
Z_Value_PhaseSpaceBeforeJaws = accelerator -> getBeforeJaws_Z_PhaseSpacePosition();
accelerator -> writeInfo();
}
else
{
@@ -138,8 +147,10 @@ bool CML2AcceleratorConstruction::Construct(G4VPhysicalVolume *PVWorld, G4bool b
void CML2AcceleratorConstruction::writeInfo()
{
if (!bOnlyVisio)
{std::cout <<"Actual rotation: "<<idCurrentRotationX<<"/"<<rotationsX.size() <<" "<< G4endl;}
std::cout <<"Accelerator angle: "<< currentRotationX/deg << " [deg]"<< G4endl;
{
G4cout << "Actual rotation: " << idCurrentRotationX << "/" << rotationsX.size() << " " << G4endl;
}
G4cout << "Accelerator angle: " << currentRotationX/deg << " [deg]" << G4endl;
}
G4RotationMatrix * CML2AcceleratorConstruction::rotateAccelerator()
@@ -147,24 +158,29 @@ G4RotationMatrix * CML2AcceleratorConstruction::rotateAccelerator()
G4RotationMatrix *rmInv=new G4RotationMatrix();
if (idCurrentRotationX <(int) rotationsX.size())
{
currentRotationX=rotationsX[idCurrentRotationX];
rmInv=rotateAccelerator(currentRotationX);
currentRotationX = rotationsX[idCurrentRotationX];
rmInv = rotateAccelerator(currentRotationX);
idCurrentRotationX++;
}
else
{rmInv=0;}
{
rmInv = 0;
}
return rmInv;
}
G4RotationMatrix * CML2AcceleratorConstruction::rotateAccelerator(G4double angleX)
{
currentRotationX=angleX;
currentRotationX = angleX;
G4GeometryManager::GetInstance()->OpenGeometry();
G4ThreeVector NewCentre;
G4RotationMatrix *rm=new G4RotationMatrix();
G4RotationMatrix *rmInv=new G4RotationMatrix();
G4RotationMatrix *rm = new G4RotationMatrix();
G4RotationMatrix *rmInv = new G4RotationMatrix();
PVAccWorld->SetTranslation(initialCentre);
PVAccWorld->SetRotation(rm);
if (bRotate90Y) {rm->rotateY(90.*deg);}
if (bRotate90Y)
{
rm->rotateY(90.*deg);
}
rm->rotateX(-angleX);
PVAccWorld->SetRotation(rm);
*rmInv=CLHEP::inverseOf(*rm);
@@ -40,8 +40,11 @@
//
//*******************************************************//
#include "ML2AcceleratorConstructionMessenger.hh"
#include "ML2AcceleratorConstruction.hh"
#include "G4ios.hh"
#include "G4SystemOfUnits.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
@@ -50,34 +53,35 @@
CML2AcceleratorConstructionMessenger::CML2AcceleratorConstructionMessenger(CML2AcceleratorConstruction *acceleratorConstructor) : pAcceleratorConstructor (acceleratorConstructor)
{
bOnlyVisio=false;
AcceleratorName=new G4UIcmdWithAString("/accelerator/AcceleratorName",this);
AcceleratorName->SetDefaultValue("acc1");
AcceleratorName->SetGuidance("accelerator name to select among those implemented (acc1)");
pAcceleratorConstructor->setAcceleratorName("acc1");
bOnlyVisio = false;
acceleratorMacFileName=new G4UIcmdWithAString("/accelerator/AcceleratorMacFileName",this);
acceleratorMacFileName->SetDefaultValue("");
acceleratorMacFileName->SetGuidance("full path and macro file name containing specific setup data for the accelerator chosen");
pAcceleratorConstructor->setAcceleratorMacFileName("");
AcceleratorName = new G4UIcmdWithAString("/accelerator/AcceleratorName",this);
AcceleratorName -> SetDefaultValue("acc1");
AcceleratorName -> SetGuidance("accelerator name to select among those implemented (acc1, acc2, saturnAcc)");
pAcceleratorConstructor -> setAcceleratorName("acc1");
acceleratorMacFileName = new G4UIcmdWithAString("/accelerator/AcceleratorMacFileName",this);
acceleratorMacFileName -> SetDefaultValue("");
acceleratorMacFileName -> SetGuidance("full path and macro file name containing specific setup data for the accelerator chosen");
pAcceleratorConstructor -> setAcceleratorMacFileName("");
rotationX =new G4UIcmdWithADoubleAndUnit("/accelerator/rotationX", this);
rotationX ->SetDefaultUnit("deg");
rotationX ->SetDefaultValue(0.);
rotationX->SetGuidance("angles of rotation along X [deg]");
rotationX = new G4UIcmdWithADoubleAndUnit("/accelerator/rotationX", this);
rotationX ->SetDefaultUnit("deg");
rotationX ->SetDefaultValue(0.);
rotationX -> SetGuidance("rotation around X [deg]");
isoCentre=new G4UIcmdWithADoubleAndUnit("/accelerator/isoCentre", this);
isoCentre->SetDefaultUnit("mm");
isoCentre->SetDefaultValue(1000.);
isoCentre->SetGuidance("distance between the isocentre and the target of the accelerator");
pAcceleratorConstructor->setIsoCentre(1000.*mm);
isoCentre = new G4UIcmdWithADoubleAndUnit("/accelerator/isoCentre", this);
isoCentre -> SetDefaultUnit("mm");
isoCentre -> SetDefaultValue(1000.);
isoCentre -> SetGuidance("distance between the isocentre and the target of the accelerator");
pAcceleratorConstructor -> setIsoCentre(1000.*mm);
bRotate90Y =new G4UIcmdWithABool("/accelerator/rotation90Y", this);
bRotate90Y ->SetDefaultValue(false);
bRotate90Y->SetGuidance("to rotate the accelerator of 90 deg around the Y axis (true)");
pAcceleratorConstructor->setRotation90Y(false);
bRotate90Y = new G4UIcmdWithABool("/accelerator/rotation90Y", this);
bRotate90Y -> SetDefaultValue(false);
bRotate90Y -> SetGuidance("rotate the accelerator of 90 deg around the Y axis");
pAcceleratorConstructor -> setRotation90Y(false);
}
CML2AcceleratorConstructionMessenger::~CML2AcceleratorConstructionMessenger(void)
@@ -91,39 +95,29 @@ CML2AcceleratorConstructionMessenger::~CML2AcceleratorConstructionMessenger(void
void CML2AcceleratorConstructionMessenger::SetNewValue(G4UIcommand* cmd, G4String newValue)
{
if (cmd==AcceleratorName)
{pAcceleratorConstructor->setAcceleratorName(newValue);}
if (cmd==acceleratorMacFileName)
{pAcceleratorConstructor->setAcceleratorMacFileName(newValue);}
if (cmd==rotationX)
if (cmd == AcceleratorName)
{
if (bOnlyVisio)
{
G4RotationMatrix *rm=pAcceleratorConstructor->rotateAccelerator(rotationX ->GetNewDoubleValue(newValue));
CML2PrimaryGenerationAction::GetInstance()->setRotation(rm);
CML2PhantomConstruction::GetInstance()->resetSensDet();
// what follows seems to be necessary to have a good refresh
G4UImanager* UI = G4UImanager::GetUIpointer();
G4String command;
command = "/run/beamOn 0";
UI->ApplyCommand(command);
command = "/vis/viewer/flush";
UI->ApplyCommand(command);
}
else
{
pAcceleratorConstructor->addAcceleratorRotationsX(rotationX ->GetNewDoubleValue(newValue));
}
pAcceleratorConstructor -> setAcceleratorName(newValue);
}
if (cmd==isoCentre)
if (cmd == acceleratorMacFileName)
{
isoCentre->GetNewUnitValue(newValue);
pAcceleratorConstructor->setIsoCentre(isoCentre->GetNewDoubleValue(newValue));
pAcceleratorConstructor -> setAcceleratorMacFileName(newValue);
}
if (cmd == rotationX)
{
pAcceleratorConstructor -> addAcceleratorRotationsX(rotationX -> GetNewDoubleValue(newValue));
}
if (cmd == isoCentre)
{
isoCentre -> GetNewUnitValue(newValue);
pAcceleratorConstructor -> setIsoCentre(isoCentre -> GetNewDoubleValue(newValue));
}
if (cmd == bRotate90Y)
{
pAcceleratorConstructor -> setRotation90Y(bRotate90Y -> GetNewBoolValue(newValue));
}
if (cmd==bRotate90Y)
{pAcceleratorConstructor->setRotation90Y(bRotate90Y->GetNewBoolValue(newValue));}
}
@@ -45,10 +45,10 @@
CML2CInputData::CML2CInputData(void)
{
bOnlyVisio=false;
bOnlyVisio = false;
// instantiate the messenger for the general and convergence data
ML2MainMessenger=new CML2MainMessenger(this);
// instantiate the messenger for the general and convergence data
ML2MainMessenger = new CML2MainMessenger(this);
}
CML2CInputData::~CML2CInputData(void)
@@ -51,22 +51,23 @@ CML2Convergence::CML2Convergence(G4int seed, G4int saveEvents,
G4bool bComp, G4int maxNumEvents, G4int nRecycling, G4int maxLoops)
:ML2ExpVoxels(0)
{
nGeometry=0;
nMaxLoops=maxLoops;
idCurrentLoop=nMaxLoops;
bCompareExp=bComp;
nAccumulatedEvents=0;
if (bCompareExp){nMaxLoops=-1;};
fileExperimentalData=FileExperimentalData;
nGeometry = 0;
nMaxLoops = maxLoops;
idCurrentLoop = nMaxLoops;
bCompareExp = bComp;
nAccumulatedEvents = 0;
if (bCompareExp){nMaxLoops =-1;};
fileExperimentalData = FileExperimentalData;
// if the flag compareExp if true and the experimental data is given create the class CML2ExpVoxels
// if the flag compareExp if true and the experimental data is given, create the class CML2ExpVoxels
if (bCompareExp && fileExperimentalData!="")
{
ML2ExpVoxels=new CML2ExpVoxels(bCompareExp, saveEvents, seed, FileExperimentalData, FileExperimentalDataOut);
ML2ExpVoxels = new CML2ExpVoxels(bCompareExp, saveEvents, seed, FileExperimentalData, FileExperimentalDataOut);
if (!ML2ExpVoxels->loadData())
{
nMaxLoops =10;
ML2ExpVoxels=0;
std::cout <<"I don't have any convergence criteria set, I'll do " << nMaxLoops << " loop(s) for each rotation"<< G4endl;
G4cout << "I don't have any convergence criteria set, I'll do " << nMaxLoops << " loop(s) for each rotation" << G4endl;
}
else
{
@@ -122,10 +123,10 @@ G4bool CML2Convergence::convergenceCriteria()
else
{bStopRun = false;}
}
std::cout <<"\n ++++++++++++++++++++ \n";
std::cout <<"current geometry: " << nGeometry;
std::cout << "\nNumber of events accumulated in the current geometry:"<<
G4cout <<"\n ++++++++++++++++++++ " << G4endl;
G4cout <<"current geometry: " << nGeometry;
G4cout << "\nNumber of events accumulated in the current geometry:"<<
nEventsAccumulated<<"\nNumber of events to be accumulated:" <<
maxNumberOfEvents<< "\n -------------------------\n";
maxNumberOfEvents<< "\n -------------------------\n" << G4endl;
return bStopRun;
}
@@ -51,20 +51,20 @@ CML2ExpVoxels::CML2ExpVoxels(G4bool bData, G4int saveEvents, G4int seed,
{
char a[10];
sprintf(a,"%d", seed);
seedName=(G4String)a;
saving_in_Selected_Voxels_every_events=saveEvents;
nRecycling=1;
seedName = (G4String)a;
saving_in_Selected_Voxels_every_events = saveEvents;
nRecycling = 1;
fullFileOut=FileExperimentalDataOut+seedName+".m";
fullFileIn=FileExperimentalData;
nParticle=nTotalEvents=0;
fullFileOut = FileExperimentalDataOut+seedName+".m";
fullFileIn = FileExperimentalData;
nParticle = nTotalEvents = 0;
// define the extremes of global-volume containing all experimental voxels
G4double extr=100000000000.;
G4double extr = 100000000000.;
minZone.set(extr, extr, extr);
maxZone.set(-extr, -extr, -extr);
bHasExperimentalData=bData;
bHasExperimentalData = bData;
}
CML2ExpVoxels::~CML2ExpVoxels(void)
@@ -72,14 +72,15 @@ CML2ExpVoxels::~CML2ExpVoxels(void)
delete [] startCurve;
delete [] stopCurve;
delete [] chi2Factor;
delete [] nVoxelsgeometry;
delete [] nVoxelsgeometry;
}
G4bool CML2ExpVoxels::loadData(void)
{
bHasExperimentalData=true;
bHasExperimentalData = true;
std::ifstream in;
Svoxel voxel; voxel.volumeId=0;
Svoxel voxel;
voxel.volumeId = 0;
G4ThreeVector pos, halfSize;
G4double expDose;
@@ -88,78 +89,81 @@ G4bool CML2ExpVoxels::loadData(void)
{
G4String appo;
char a[1000];
in.getline(a,1000,'\n'); headerText1=(G4String)a;
in.getline(a,1000,'\n');
headerText1 = (G4String)a;
in.getline(a,1000,'\n');
in >> nCurves;
startCurve=new G4int[nCurves];
stopCurve=new G4int[nCurves];
chi2Factor=new G4double[nCurves];
for (int i=0; i< nCurves; i++)
startCurve = new G4int[nCurves];
stopCurve = new G4int[nCurves];
chi2Factor = new G4double[nCurves];
for (int i = 0; i < nCurves; i++)
{
chi2Factor[i]=0.;
chi2Factor[i] = 0.;
in >> startCurve[i];
in >> stopCurve[i];
in >> chi2Factor[i];
}
in.getline(a,1000,'\n');
in.getline(a,1000,'\n'); headerText2=(G4String)a;
in.getline(a,1000,'\n');
headerText2 = (G4String)a;
std::string line;
while (!in.eof())
while ( !in.eof() )
{
in >> pos;
in >> halfSize;
in >> halfSize;
if (bHasExperimentalData)
{
in >> expDose;
voxel.expDose=expDose/100.*(joule/kg); // input data in cGy
voxel.expDose = expDose/100.*(joule/kg); // input data in cGy
}
else
{
voxel.expDose=0.;
voxel.expDose = 0.;
}
voxel.pos=pos;
voxel.halfSize=halfSize;
voxel.depEnergy=0.;
voxel.depEnergy2=0.;
voxel.nEvents=0;
voxel.depEnergyNorm=0.;
voxel.depEnergyNormError=0.;
voxels.push_back(voxel);
voxel.halfSize = halfSize;
voxel.depEnergy = 0.;
voxel.depEnergy2 = 0.;
voxel.nEvents = 0;
voxel.depEnergyNorm = 0.;
voxel.depEnergyNormError = 0.;
vec_voxels.push_back(voxel);
// calculate the actual extremes of the global-volume containing all the experimental data
if (minZone.getX()>pos.getX()-halfSize.getX())
{minZone.setX(pos.getX()-halfSize.getX());}
if (maxZone.getX()<pos.getX()+halfSize.getX())
{maxZone.setX(pos.getX()+halfSize.getX());}
// calculate the actual extremes of the global-volume containing all the experimental data
if ( minZone.getX()>pos.getX()-halfSize.getX() )
{ minZone.setX(pos.getX()-halfSize.getX()); }
if ( maxZone.getX()<pos.getX()+halfSize.getX() )
{ maxZone.setX(pos.getX()+halfSize.getX()); }
if (minZone.getY()>pos.getY()-halfSize.getY())
{minZone.setY(pos.getY()-halfSize.getY());}
if (maxZone.getY()<pos.getY()+halfSize.getY())
{maxZone.setY(pos.getY()+halfSize.getY());}
if (minZone.getZ()>pos.getZ()-halfSize.getZ())
{minZone.setZ(pos.getZ()-halfSize.getZ());}
if (maxZone.getZ()<pos.getZ()+halfSize.getZ())
{maxZone.setZ(pos.getZ()+halfSize.getZ());}
if ( minZone.getY()>pos.getY()-halfSize.getY() )
{ minZone.setY(pos.getY()-halfSize.getY()); }
if ( maxZone.getY()<pos.getY()+halfSize.getY() )
{ maxZone.setY(pos.getY()+halfSize.getY()); }
if ( minZone.getZ()>pos.getZ()-halfSize.getZ() )
{ minZone.setZ(pos.getZ()-halfSize.getZ()); }
if ( maxZone.getZ()<pos.getZ()+halfSize.getZ() )
{ maxZone.setZ(pos.getZ()+halfSize.getZ()); }
}
}
else
{
std::cout << "ERROR I can't find the experimental data file" << G4endl;
G4cout << "ERROR I can't find the experimental data file" << G4endl;
return false;
}
in.close();
nVoxelsgeometry=new G4int[(G4int) voxels.size()];
nVoxelsgeometry = new G4int[(G4int) vec_voxels.size()];
resetNEventsInVoxels();
return true;
}
void CML2ExpVoxels::resetNEventsInVoxels()
{
for (int i=0; i<(int) voxels.size(); i++ )
{nVoxelsgeometry[i]=0;}
for (int i=0; i<(int) vec_voxels.size(); i++ )
{nVoxelsgeometry[i] = 0;}
}
void CML2ExpVoxels::add(const G4Step* aStep)
@@ -167,54 +171,54 @@ void CML2ExpVoxels::add(const G4Step* aStep)
G4ThreeVector pos;
G4double depEnergy, density, voxelVolume;
pos=aStep->GetPreStepPoint()->GetPosition();
depEnergy=aStep->GetTotalEnergyDeposit();
density=aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial()->GetDensity();
pos = aStep->GetPreStepPoint()->GetPosition();
depEnergy = aStep->GetTotalEnergyDeposit();
density = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial()->GetDensity();
G4ThreeVector minPos, maxPos;
G4bool newEvent=false;
G4double voxelMass, dose;
// check if the event is inside the global-volume
if (minZone.getX()<= pos.getX() && pos.getX()<maxZone.getX() &&
minZone.getY()<= pos.getY() && pos.getY()<maxZone.getY() &&
minZone.getZ()<= pos.getZ() && pos.getZ()<maxZone.getZ())
// check if the event is inside the global-volume
if (minZone.getX() <= pos.getX() && pos.getX() < maxZone.getX() &&
minZone.getY() <= pos.getY() && pos.getY() < maxZone.getY() &&
minZone.getZ() <= pos.getZ() && pos.getZ() < maxZone.getZ())
{
// look for the voxel containing the event
for (int i=0; i<(int)voxels.size(); i++)
// look for the voxel containing the event
for (int i = 0; i < (int)vec_voxels.size(); i++)
{
minPos=voxels[i].pos-voxels[i].halfSize;
maxPos=voxels[i].pos+voxels[i].halfSize;
if (minPos.getX()<= pos.getX() && pos.getX()<maxPos.getX() &&
minPos.getY()<= pos.getY() && pos.getY()<maxPos.getY() &&
minPos.getZ()<= pos.getZ() && pos.getZ()<maxPos.getZ())
minPos = vec_voxels[i].pos-vec_voxels[i].halfSize;
maxPos = vec_voxels[i].pos+vec_voxels[i].halfSize;
if ( minPos.getX() <= pos.getX() && pos.getX() < maxPos.getX() &&
minPos.getY() <= pos.getY() && pos.getY() < maxPos.getY() &&
minPos.getZ() <= pos.getZ() && pos.getZ() < maxPos.getZ() )
{
voxelVolume=voxels[i].halfSize.getX()*voxels[i].halfSize.getY()*voxels[i].halfSize.getZ()*8.;
voxelMass=density*voxelVolume;
// calculate the dose
voxelVolume = vec_voxels[i].halfSize.getX()*vec_voxels[i].halfSize.getY()*vec_voxels[i].halfSize.getZ()*8.;
voxelMass = density*voxelVolume;
// calculate the dose
dose=depEnergy/(voxelMass*nRecycling);
voxels[i].nEvents++;
nVoxelsgeometry[i]++;
voxels[i].depEnergy+=dose;
voxels[i].depEnergy2+=dose*dose;
newEvent=true;
vec_voxels[i].nEvents++;
nVoxelsgeometry[i]++;
vec_voxels[i].depEnergy += dose;
vec_voxels[i].depEnergy2 += dose*dose;
newEvent = true;
Sparticle *particle=new Sparticle;
particle->dir=aStep->GetPreStepPoint()->GetMomentumDirection();
particle->pos=aStep->GetPreStepPoint()->GetPosition();
particle->kinEnergy=dose; // I use the same kinEnergy name to store the dose
particle->nPrimaryPart=-1;
particle->partPDGE=aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
particle->primaryParticlePDGE=-1;
particle->volumeId=i; // voxel index where the dose is accumulating
particle->volumeName="-1";
Sparticle *particle = new Sparticle;
particle -> dir = aStep -> GetPreStepPoint() -> GetMomentumDirection();
particle -> pos = aStep -> GetPreStepPoint() -> GetPosition();
particle -> kinEnergy = dose; // I use the same kinEnergy name to store the dose
particle -> nPrimaryPart = -1;
particle -> partPDGE = aStep -> GetTrack() -> GetDefinition() -> GetPDGEncoding();
particle -> primaryParticlePDGE = -1;
particle -> volumeId = i; // voxel index where the dose is accumulating
particle -> volumeName = "-1";
}
}
if (newEvent)
if ( newEvent )
{
// save data
// save data
nTotalEvents++;
if (nTotalEvents%saving_in_Selected_Voxels_every_events==0 && nTotalEvents>0)
if ( nTotalEvents%saving_in_Selected_Voxels_every_events == 0 && nTotalEvents > 0 )
{
saveResults();
}
@@ -224,19 +228,21 @@ void CML2ExpVoxels::add(const G4Step* aStep)
G4int CML2ExpVoxels::getMinNumberOfEvents()
{
int n=voxels[0].nEvents;
for (int i=0;i<(int)voxels.size();i++)
int n = vec_voxels[0].nEvents;
for (int i = 0; i < (int)vec_voxels.size(); i++)
{
if (n>voxels[i].nEvents){n = voxels[i].nEvents;}
if ( n > vec_voxels[i].nEvents )
{ n = vec_voxels[i].nEvents; }
}
return n;
}
G4int CML2ExpVoxels::getMaxNumberOfEvents()
{
int n=nVoxelsgeometry[0];
for (int i=0;i<(int)voxels.size();i++)
int n = nVoxelsgeometry[0];
for ( int i = 0; i < (int)vec_voxels.size(); i++)
{
if (n<nVoxelsgeometry[i]){n = nVoxelsgeometry[i];}
if ( n < nVoxelsgeometry[i] )
{ n = nVoxelsgeometry[i]; }
}
return n;
}
@@ -244,39 +250,39 @@ void CML2ExpVoxels::saveHeader()
{
std::ofstream out;
out.open(fullFileOut, std::ios::out);
out <<"% "<< headerText1 << G4endl;
out <<"n"<< seedName<<"="<< nCurves<<";" << G4endl;
out <<"fh"<< seedName<<"=["<< G4endl;
for (int i=0; i< nCurves; i++)
out << "% " << headerText1 << G4endl;
out << "n" << seedName << "=" << nCurves << ";" << G4endl;
out << "fh" << seedName << "=[" << G4endl;
for (int i = 0; i< nCurves; i++)
{
out << startCurve[i] << '\t';
out << stopCurve[i] << '\t';
out << chi2Factor[i]<< G4endl;
out << chi2Factor[i] << G4endl;
}
out << "];"<<G4endl;
out <<"% x [mm], y [mm], z [mm], Dx [mm], Dy [mm], Dz [mm], expDose [Gy], Calculated dose [Gy], Calculated dose2 [Gy^2], nEvents, normDose [Gy], normDoseError [Gy]";
out << "];" << G4endl;
out << "% x [mm], y [mm], z [mm], Dx [mm], Dy [mm], Dz [mm], expDose [Gy], Calculated dose [Gy], Calculated dose2 [Gy^2], nEvents, normDose [Gy], normDoseError [Gy]";
out << G4endl;
out.close();
}
void CML2ExpVoxels::saveResults()
{
if (nTotalEvents>0)
if (nTotalEvents > 0)
{
calculateNormalizedEd(voxels);
calculateNormalizedEd(vec_voxels);
saveHeader();
std::ofstream out;
out.open(fullFileOut, std::ios::app);
out <<"d"<< seedName<<"=["<< G4endl;
for (int i=0; i<(int)voxels.size(); i++)
out << "d" << seedName << "=[" << G4endl;
for (int i=0; i<(int)vec_voxels.size(); i++)
{
out <<voxels[i].pos.getX()/mm<<'\t'<<voxels[i].pos.getY()/mm<<'\t'<<voxels[i].pos.getZ()/mm<<'\t';
out <<voxels[i].halfSize.getX()/mm<<'\t'<<voxels[i].halfSize.getY()/mm<<'\t'<<voxels[i].halfSize.getZ()/mm<<'\t';
out <<voxels[i].expDose/(joule/kg)<<'\t'<<voxels[i].depEnergy/(joule/kg)<<'\t'<<voxels[i].depEnergy2/((joule/kg)*(joule/kg))<<'\t'<<voxels[i].nEvents<< '\t';
out <<voxels[i].depEnergyNorm/(joule/kg)<<'\t'<<voxels[i].depEnergyNormError/(joule/kg);
out << vec_voxels[i].pos.getX()/mm << '\t' << vec_voxels[i].pos.getY()/mm << '\t' << vec_voxels[i].pos.getZ()/mm << '\t';
out << vec_voxels[i].halfSize.getX()/mm << '\t' << vec_voxels[i].halfSize.getY()/mm << '\t' << vec_voxels[i].halfSize.getZ()/mm << '\t';
out << vec_voxels[i].expDose/(joule/kg) << '\t' << vec_voxels[i].depEnergy/(joule/kg) << '\t' << vec_voxels[i].depEnergy2/((joule/kg)*(joule/kg)) << '\t' << vec_voxels[i].nEvents << '\t';
out << vec_voxels[i].depEnergyNorm/(joule/kg) << '\t' << vec_voxels[i].depEnergyNormError/(joule/kg);
out << G4endl;
}
out << "];"<<G4endl;
out << "];" << G4endl;
out.close();
}
}
@@ -288,28 +294,28 @@ void CML2ExpVoxels::calculateNormalizedEd(std::vector <Svoxel> &vox)
int n;
G4double d2, dd;
G4double v;
for (j=0;j<nCurves;j++)
for (j = 0; j < nCurves; j++)
{
cs=cc=0.;
for (i=startCurve[j]-1;i<stopCurve[j];i++)
cs = cc = 0.;
for (i = startCurve[j]-1;i<stopCurve[j];i++)
{
cs+=vox[i].depEnergy*vox[i].expDose;
cc+=vox[i].depEnergy*vox[i].depEnergy;
cs += vox[i].depEnergy*vox[i].expDose;
cc += vox[i].depEnergy*vox[i].depEnergy;
}
if (cc>0.)
{
chi2Factor[j]=cs/cc;
chi2Factor[j] = cs/cc;
}
for (i=startCurve[j]-1;i<stopCurve[j];i++)
for (i = startCurve[j]-1; i < stopCurve[j]; i++)
{
dd=vox[i].depEnergy*vox[i].depEnergy;
d2=vox[i].depEnergy2;
n=vox[i].nEvents;
vox[i].depEnergyNorm=chi2Factor[j]*vox[i].depEnergy;
v=n*d2-dd;
if (v<0.){v=0;}
if (n>1){vox[i].depEnergyNormError=chi2Factor[j]*std::sqrt(v/(n-1));}
if (n==1){vox[i].depEnergyNormError=vox[i].depEnergyNorm;}
dd = vox[i].depEnergy*vox[i].depEnergy;
d2 = vox[i].depEnergy2;
n = vox[i].nEvents;
vox[i].depEnergyNorm = chi2Factor[j]*vox[i].depEnergy;
v = n*d2-dd;
if (v < 0.) { v=0; }
if (n > 1) { vox[i].depEnergyNormError = chi2Factor[j]*std::sqrt(v/(n-1)); }
if (n == 1) { vox[i].depEnergyNormError = vox[i].depEnergyNorm; }
}
}
}
@@ -40,113 +40,135 @@
//
//*******************************************************//
#include "ML2MainMessenger.hh"
#include "G4ios.hh"
#include "G4SystemOfUnits.hh"
CML2MainMessenger::CML2MainMessenger(CML2CInputData *InData)
{
CInputData = InData;
phaseSpaceCentre = new G4UIcmdWith3VectorAndUnit("/general/centrePhaseSpace", this);
phaseSpaceCentre -> SetDefaultUnit("mm");
phaseSpaceCentre -> SetDefaultValue(G4ThreeVector(0.,0.,164.));
phaseSpaceCentre -> SetGuidance("position of the centre of the phase space plane");
CInputData -> setPhaseSpaceCentre(G4ThreeVector(0.*mm,0.*mm,164.*mm));
CInputData=InData;
phaseSpaceCentre=new G4UIcmdWith3VectorAndUnit("/general/centrePhaseSpace", this);
phaseSpaceCentre->SetDefaultUnit("mm");
phaseSpaceCentre->SetDefaultValue(G4ThreeVector(0.,0.,164.));
phaseSpaceCentre->SetGuidance("position of the centre of the plane phase space");
CInputData->setPhaseSpaceCentre(G4ThreeVector(0.*mm,0.*mm,164.*mm));
phaseSpaceHalfSize = new G4UIcmdWith3VectorAndUnit("/general/halfSizePhaseSpace", this);
phaseSpaceHalfSize -> SetDefaultUnit("mm");
phaseSpaceHalfSize -> SetDefaultValue(G4ThreeVector(100.,100.,1.));
phaseSpaceHalfSize -> SetGuidance("half size of the phase space plane");
CInputData -> setPhaseSpaceHalfSize(G4ThreeVector(100.*mm,100.*mm,1.*mm));
phaseSpaceHalfSize=new G4UIcmdWith3VectorAndUnit("/general/halfSizePhaseSpace", this);
phaseSpaceHalfSize->SetDefaultUnit("mm");
phaseSpaceHalfSize->SetDefaultValue(G4ThreeVector(100.,100.,1.));
phaseSpaceHalfSize->SetGuidance("half size of the plane phase space");
CInputData->setPhaseSpaceHalfSize(G4ThreeVector(100.*mm,100.*mm,1.*mm));
bSavePhaseSpace = new G4UIcmdWithABool("/general/bSavePhaseSpace",this);
bSavePhaseSpace -> SetDefaultValue(false);
bSavePhaseSpace -> SetGuidance("save the phase space");
CInputData -> setbSavePhaseSPace(false);
bSavePhaseSpace=new G4UIcmdWithABool("/general/bSavePhaseSpace",this);
bSavePhaseSpace->SetDefaultValue(false);
bSavePhaseSpace->SetGuidance("true if to save the phase space");
CInputData->setbSavePhaseSPace(false);
bForcePhaseSpaceBeforeJaws = new G4UIcmdWithABool("/general/bForcePhaseSpaceBeforeJaws",this);
bForcePhaseSpaceBeforeJaws -> SetDefaultValue(false);
bForcePhaseSpaceBeforeJaws -> SetGuidance("automatically put the phase plane before the jaws");
CInputData -> setbForcePhaseSpaceBeforeJaws(false);
bForcePhaseSpaceBeforeJaws=new G4UIcmdWithABool("/general/bForcePhaseSpaceBeforeJaws",this);
bForcePhaseSpaceBeforeJaws->SetDefaultValue(false);
bForcePhaseSpaceBeforeJaws->SetGuidance("to automatically put the phase plane before the jaws");
CInputData->setbForcePhaseSpaceBeforeJaws(false);
bStopAtPhaseSpace = new G4UIcmdWithABool("/general/bStopAtPhaseSpace",this);
bStopAtPhaseSpace -> SetDefaultValue(false);
bStopAtPhaseSpace -> SetGuidance("kill the particle at the phase space");
CInputData-> setbStopAtPhaseSpace(false);
bStopAtPhaseSpace=new G4UIcmdWithABool("/general/bStopAtPhaseSpace",this);
bStopAtPhaseSpace->SetDefaultValue(false);
bStopAtPhaseSpace->SetGuidance("true if to kill the particle at the phase space");
CInputData->setbStopAtPhaseSpace(false);
bSaveROG = new G4UIcmdWithABool("/general/bSaveROG",this);
bSaveROG -> SetDefaultValue(true);
bSaveROG -> SetGuidance("save the ROG volume");
CInputData -> setbSaveROG(true);
bSaveROG=new G4UIcmdWithABool("/general/bSaveROG",this);
bSaveROG->SetDefaultValue(true);
bSaveROG->SetGuidance("true if save the ROG volume");
CInputData->setbSaveROG(true);
bOnlyVisio = new G4UIcmdWithABool("/OnlyVisio",this);
bOnlyVisio -> SetDefaultValue(false);
bOnlyVisio -> SetGuidance("switch the visualization mode");
CInputData -> setbOnlyVisio(false);
bOnlyVisio=new G4UIcmdWithABool("/OnlyVisio",this);
bOnlyVisio->SetDefaultValue(false);
bOnlyVisio->SetGuidance("switch the visualization mode");
CInputData->setbOnlyVisio(false);
ROGOutFile = new G4UIcmdWithAString("/general/ROGOutFile",this);
ROGOutFile -> SetDefaultValue("");
ROGOutFile -> SetGuidance("full path and name of the ROG file");
CInputData -> setROGOutFile("defaultROGFile.txt");
ROGOutFile=new G4UIcmdWithAString("/general/ROGOutFile",this);
ROGOutFile->SetDefaultValue("");
ROGOutFile->SetGuidance("full path of the ROG file name");
CInputData->setROGOutFile("defaultROGFile.txt");
phaseSPaceOutFile=new G4UIcmdWithAString("/general/PhaseSpaceOutFile",this);
phaseSPaceOutFile->SetDefaultValue("");
phaseSPaceOutFile->SetGuidance("full file name of the phase space");
CInputData->setPhaseSpaceOutFile("");
phaseSPaceOutFile = new G4UIcmdWithAString("/general/PhaseSpaceOutFile",this);
phaseSPaceOutFile -> SetDefaultValue("");
phaseSPaceOutFile -> SetGuidance("full path and name of the phase space file");
CInputData -> setPhaseSpaceOutFile("");
maxNumberOfEvents=new G4UIcmdWithAnInteger("/convergence/maxNumberOfEvents", this);
maxNumberOfEvents->SetDefaultValue(10);
maxNumberOfEvents->SetGuidance(" maximum number of events at least in one experimental voxel");
maxNumberOfEvents->SetGuidance("number of events to be reached in one experimental voxel");
CInputData->setMaxNumberOfEvents(10);
nMaxLoop=new G4UIcmdWithAnInteger("/convergence/nMaxLoop", this);
nMaxLoop->SetDefaultValue(1);
nMaxLoop->SetGuidance("it is used if /convergence/bCompareExp is false");
CInputData->setNmaxLoop(1);
nMaxLoop = new G4UIcmdWithAnInteger("/convergence/nMaxLoop", this);
nMaxLoop -> SetDefaultValue(1);
nMaxLoop -> SetGuidance("used if /convergence/bCompareExp is false");
CInputData -> setNmaxLoop(1);
bCompareExp=new G4UIcmdWithABool("/convergence/bCompareExp",this);
bCompareExp->SetDefaultValue(false);
bCompareExp->SetGuidance("to compare the data with an experimental file data");
CInputData->setBCompareExp(false);
bCompareExp = new G4UIcmdWithABool("/convergence/bCompareExp", this);
bCompareExp -> SetDefaultValue(false);
bCompareExp -> SetGuidance("compare the data with an experimental data file");
CInputData -> setBCompareExp(false);
fileExperimentalData=new G4UIcmdWithAString("/convergence/fileExperimentalData",this);
fileExperimentalData->SetDefaultValue("");
fileExperimentalData->SetGuidance("full path and name of the experimental file results");
CInputData->setFileExperimentalData("");
fileExperimentalData = new G4UIcmdWithAString("/convergence/fileExperimentalData", this);
fileExperimentalData -> SetDefaultValue("");
fileExperimentalData -> SetGuidance("full path and name of the experimental data file");
CInputData -> setFileExperimentalData("");
fileExperimentalDataOut=new G4UIcmdWithAString("/convergence/fileExperimentalDataOut",this);
fileExperimentalDataOut->SetDefaultValue("");
fileExperimentalDataOut->SetGuidance("full path and name of the experimental file results");
CInputData->setFileExperimentalDataOut("");
fileExperimentalDataOut = new G4UIcmdWithAString("/convergence/fileExperimentalDataOut", this);
fileExperimentalDataOut -> SetDefaultValue("");
fileExperimentalDataOut -> SetGuidance("full path and name of the experimental data out file");
CInputData -> setFileExperimentalDataOut("");
nBeam=new G4UIcmdWithAnInteger("/general/nBeam",this);
nBeam->SetDefaultValue(100);
nBeam->SetGuidance("number of events to run");
CInputData->setNBeams(100);
nBeam = new G4UIcmdWithAnInteger("/general/nBeam", this);
nBeam -> SetDefaultValue(100);
nBeam -> SetGuidance("number of events to run");
CInputData -> setNBeams(100);
nMaxParticlesInRamPlanePhaseSpace=new G4UIcmdWithAnInteger("/general/nMaxParticlesInRamPlanePhaseSpace",this);
nMaxParticlesInRamPlanePhaseSpace->SetDefaultValue(10000);
nMaxParticlesInRamPlanePhaseSpace->SetGuidance("maximum particle number stored in RAM before saving - for phase space");
CInputData->setNMaxParticlesInRamPlanePhaseSpace(10000);
nMaxParticlesInRamPlanePhaseSpace = new G4UIcmdWithAnInteger("/general/nMaxParticlesInRamPlanePhaseSpace",this);
nMaxParticlesInRamPlanePhaseSpace -> SetDefaultValue(10000);
nMaxParticlesInRamPlanePhaseSpace -> SetGuidance("maximum number of particles stored in RAM before saving phase space file");
CInputData -> setNMaxParticlesInRamPlanePhaseSpace(10000);
saving_in_Selected_Voxels_every_events=new G4UIcmdWithAnInteger("/general/saving_in_Selected_Voxels_every_events",this);
saving_in_Selected_Voxels_every_events->SetDefaultValue(10000);
saving_in_Selected_Voxels_every_events->SetGuidance("maximum particle number stored before saving - for experiemntal data comparison");
CInputData->setSaving_in_Selected_Voxels_every_events(10000);
saving_in_Selected_Voxels_every_events = new G4UIcmdWithAnInteger("/general/saving_in_Selected_Voxels_every_events",this);
saving_in_Selected_Voxels_every_events -> SetDefaultValue(10000);
saving_in_Selected_Voxels_every_events -> SetGuidance("maximum number of particles stored before saving experimental data out file");
CInputData -> setSaving_in_Selected_Voxels_every_events(10000);
saving_in_ROG_Voxels_every_events=new G4UIcmdWithAnInteger("/general/saving_in_ROG_Voxels_every_events",this);
saving_in_ROG_Voxels_every_events->SetDefaultValue(1000);
saving_in_ROG_Voxels_every_events->SetGuidance("maximum particle number stored before saving - for ROG");
CInputData->setSaving_in_ROG_Voxels_every_events(1000);
saving_in_ROG_Voxels_every_events = new G4UIcmdWithAnInteger("/general/saving_in_ROG_Voxels_every_events",this);
saving_in_ROG_Voxels_every_events -> SetDefaultValue(1000);
saving_in_ROG_Voxels_every_events -> SetGuidance("maximum number of particles stored before saving ROG file");
CInputData -> setSaving_in_ROG_Voxels_every_events(1000);
max_N_particles_in_PhSp_File=new G4UIcmdWithAnInteger("/general/max_N_particles_in_PhSp_File",this);
max_N_particles_in_PhSp_File->SetDefaultValue(1000);
max_N_particles_in_PhSp_File->SetGuidance("maximum particle number stored in the phase space file");
CInputData->setMax_N_particles_in_PhSp_File(1000);
max_N_particles_in_PhSp_File = new G4UIcmdWithAnInteger("/general/max_N_particles_in_PhSp_File",this);
max_N_particles_in_PhSp_File -> SetDefaultValue(1000);
max_N_particles_in_PhSp_File -> SetGuidance("maximum number of particles stored in the phase space file");
CInputData -> setMax_N_particles_in_PhSp_File(1000);
// SUSANNA: command to fix the number of voxels in the phantom segmentation
fVoxelsXCmd = new G4UIcmdWithAnInteger("/general/numberVoxelsX",this);
fVoxelsXCmd -> SetDefaultValue(30);
fVoxelsXCmd -> SetGuidance("number of voxels along X axis");
CInputData->setVoxelsX(30);
fVoxelsYCmd = new G4UIcmdWithAnInteger("/general/numberVoxelsY",this);
fVoxelsYCmd -> SetDefaultValue(30);
fVoxelsYCmd -> SetGuidance("number of voxels along Y axis");
CInputData->setVoxelsY(30);
fVoxelsZCmd = new G4UIcmdWithAnInteger("/general/numberVoxelsZ",this);
fVoxelsZCmd -> SetDefaultValue(30);
fVoxelsZCmd -> SetGuidance("number of voxels along Z axis");
CInputData->setVoxelsZ(30);
}
CML2MainMessenger::~CML2MainMessenger(void)
{
delete fVoxelsXCmd;
delete fVoxelsYCmd;
delete fVoxelsZCmd;
delete saving_in_Selected_Voxels_every_events;
delete saving_in_ROG_Voxels_every_events;
delete max_N_particles_in_PhSp_File;
@@ -229,5 +251,10 @@ void CML2MainMessenger::SetNewValue(G4UIcommand* cmd, G4String newValue)
{CInputData->setFileExperimentalData(newValue);}
if (cmd==fileExperimentalDataOut)
{CInputData->setFileExperimentalDataOut(newValue);}
{CInputData->setFileExperimentalDataOut(newValue);}
if (cmd==fVoxelsXCmd) {CInputData->setVoxelsX(fVoxelsXCmd->GetNewIntValue(newValue));}
if (cmd==fVoxelsYCmd) {CInputData->setVoxelsY(fVoxelsYCmd->GetNewIntValue(newValue));}
if (cmd==fVoxelsZCmd) {CInputData->setVoxelsZ(fVoxelsZCmd->GetNewIntValue(newValue));}
}
@@ -55,12 +55,12 @@ CML2Ph_BoxInBox::~CML2Ph_BoxInBox(void)
}
void CML2Ph_BoxInBox::writeInfo()
{
std::cout<<"\n\n\tcentre of the inside box: " <<centreBoxInside/mm<<" [mm]"<< G4endl;
std::cout<<"\thalf thickness of the inside box: " <<halfBoxInside_Thickness/mm<<" [mm]\n"<< G4endl;
G4cout<<"\n\n\tcentre of the inside box: " <<centreBoxInside/mm<<" [mm]"<< G4endl;
G4cout<<"\thalf thickness of the inside box: " <<halfBoxInside_Thickness/mm<<" [mm]\n"<< G4endl;
}
bool CML2Ph_BoxInBox::Construct(G4VPhysicalVolume *PWorld, G4int saving_in_ROG_Voxels_every_events, G4int seed, G4String ROGOutFile, G4bool bSaveROG)
bool CML2Ph_BoxInBox::Construct(G4VPhysicalVolume *PWorld)
{
PVWorld=PWorld;
PVWorld = PWorld;
G4double A, Z;
@@ -91,7 +91,7 @@ bool CML2Ph_BoxInBox::Construct(G4VPhysicalVolume *PWorld, G4int saving_in_ROG_V
G4Material *boxInSideMaterial;
boxInSideMaterial=PMMA;
std::cout <<"boxInSideMaterial name "<<boxInSideMaterial->GetName() <<" density "<< boxInSideMaterial->GetDensity()/(g/cm3) <<" g/cm3"<< G4endl;
G4cout <<"boxInSideMaterial name "<<boxInSideMaterial->GetName() <<" density "<< boxInSideMaterial->GetDensity()/(g/cm3) <<" g/cm3"<< G4endl;
centreBoxInside.set(0,0,-50); // the centre of the inside box
halfBoxInside_Thickness=3.*cm; // the half thickness of the inside box
@@ -107,7 +107,7 @@ bool CML2Ph_BoxInBox::Construct(G4VPhysicalVolume *PWorld, G4int saving_in_ROG_V
G4LogicalVolume *layerLV = new G4LogicalVolume(layer, layerMaterial, "layerLV");
layerPV = new G4PVPlacement(0, centre+G4ThreeVector(0,0,-halfSize.getZ()+halfPMMA_Z_Thickness),"layerPV", layerLV,PVWorld,false,0,0);
std::cout <<"layerMaterial name "<<layerMaterial->GetName() <<" density " << layerMaterial->GetDensity()/(g/cm3) <<" g/cm3"<< G4endl;
G4cout <<"layerMaterial name "<<layerMaterial->GetName() <<" density " << layerMaterial->GetDensity()/(g/cm3) <<" g/cm3"<< G4endl;
// BOX OUTSIDE
G4Material *boxOutSideMaterial=G4NistManager::Instance()->FindOrBuildMaterial("G4_LUNG_ICRP"); // changable
@@ -122,7 +122,7 @@ bool CML2Ph_BoxInBox::Construct(G4VPhysicalVolume *PWorld, G4int saving_in_ROG_V
OutMinusInBoxPV = new G4PVPlacement(0, centre+G4ThreeVector(0,0,-halfSize.getZ()+2*halfPMMA_Z_Thickness+halfBoxOutSide_Thickness),
"OutMinusInBoxPV",OutMinusInBoxLV,PVWorld,false,0);
std::cout <<"boxOutSideMaterial name "<<boxOutSideMaterial->GetName() <<" density "<<boxOutSideMaterial->GetDensity()/(g/cm3) <<" g/cm3"<< G4endl;
G4cout <<"boxOutSideMaterial name "<<boxOutSideMaterial->GetName() <<" density "<<boxOutSideMaterial->GetDensity()/(g/cm3) <<" g/cm3"<< G4endl;
// Region for cuts
G4Region *regVol= new G4Region("BoxInBoxR");
@@ -160,24 +160,10 @@ bool CML2Ph_BoxInBox::Construct(G4VPhysicalVolume *PWorld, G4int saving_in_ROG_V
simple_InBox_VisAttWalls->SetVisibility(true);
// simple_InBox_VisAttWalls->SetForceSolid(true);
OutMinusInBoxLV->SetVisAttributes(simple_OutBox_VisAttWalls);
boxInSideLV->SetVisAttributes(simple_InBox_VisAttWalls);
layerLV->SetVisAttributes(simple_PMMA_VisAttWalls);
// Sensitive detector
sensDet=new CML2SDWithVoxels("BoxInBoxPhantom", saving_in_ROG_Voxels_every_events, seed, ROGOutFile, bSaveROG, centre, halfSize, 100, 100, 100);
G4SDManager *SDManager=G4SDManager::GetSDMpointer();
SDManager->AddNewDetector(sensDet);
// Read Out Geometry
CML2ReadOutGeometry *ROG = new CML2ReadOutGeometry();
ROG->setBuildData(PVWorld->GetFrameTranslation(), halfSize, 100, 100, 100);
ROG->BuildROGeometry();
sensDet->SetROgeometry(ROG);
OutMinusInBoxLV->SetSensitiveDetector(sensDet);
layerLV->SetSensitiveDetector(sensDet);
boxInSideLV->SetSensitiveDetector(sensDet);
return true;
}
@@ -41,39 +41,97 @@
//*******************************************************//
#include "ML2Ph_FullWater.hh"
#include "ML2Ph_FullWaterMessenger.hh"
#include "G4SystemOfUnits.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4SDManager.hh"
#include "G4PVReplica.hh"
CML2Ph_FullWater::CML2Ph_FullWater()
{
// phantom size and position
halfSize.set(150.*mm,150.*mm,150.*mm);
// phantom position
centre.set(0.,0.,0.);
// phantom size and position
halfSize.set(150.*mm,150.*mm,150.*mm);
// phantom position
centre.set(0.,0.,0.);
fPhantomSize.setX(300.*mm);
fPhantomSize.setY(300.*mm);
fPhantomSize.setZ(300.*mm);
fullWaterMessenger = new CML2Ph_FullWaterMessenger(this);
}
CML2Ph_FullWater::~CML2Ph_FullWater(void)
{
}
void CML2Ph_FullWater::writeInfo()
{
std::cout<<"\n\n\tcentre of the phantom: " <<centre/mm<<" [mm]"<< G4endl;
std::cout<<"\thalf thickness of the phantom: " <<halfSize/mm<<" [mm]\n"<< G4endl;
G4cout<<"\n\n\tcentre of the phantom: " <<centre/mm<<" [mm]"<< G4endl;
G4cout<<"\thalf thickness of the phantom: " <<halfSize/mm<<" [mm]\n"<< G4endl;
}
bool CML2Ph_FullWater::Construct(G4VPhysicalVolume *PWorld, G4int saving_in_ROG_Voxels_every_events, G4int seed, G4String ROGOutFile, G4bool bSaveROG)
bool CML2Ph_FullWater::Construct(G4VPhysicalVolume *PWorld, G4int nx, G4int ny, G4int nz)
{
PVWorld=PWorld;
bool bCreated=false;
G4Material *WATER=G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER");
G4Box *fullWaterPhantomBox = new G4Box("fullWaterPhantomBox", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *fullWaterPhantomLV = new G4LogicalVolume(fullWaterPhantomBox, WATER, "fullWaterPhantomLV", 0, 0, 0);
fullWaterPhantomPV = new G4PVPlacement(0, centre, "fullWaterPhantomPV", fullWaterPhantomLV, PVWorld, false, 0);
PVWorld=PWorld;
// Region for cuts
G4Region *regVol= new G4Region("fullWaterPhantomR");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.1*mm);
regVol->SetProductionCuts(cuts);
bool bCreated=false;
G4Material *WATER=G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER");
G4Box *fullWaterPhantomBox = new G4Box("fullWaterPhantomBox", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *fullWaterPhantomLV = new G4LogicalVolume(fullWaterPhantomBox, WATER, "fullWaterPhantomLV", 0, 0, 0);
fullWaterPhantomPV = new G4PVPlacement(0, centre, "fullWaterPhantomPV", fullWaterPhantomLV, PVWorld, false, 0);
G4int nxCells = nx;
G4int nyCells = ny;
G4int nzCells = nz;
G4cout << "VoxelX, voxelY, Voxelz = " << nx << ", " << ny << ", " << nz << "; " << G4endl;
G4ThreeVector sensSize;
sensSize.setX(fPhantomSize.x()/(G4double)nxCells);
sensSize.setY(fPhantomSize.y()/(G4double)nyCells);
sensSize.setZ(fPhantomSize.z()/(G4double)nzCells);
// The phantom is voxelised in 3D
G4String yRepName("RepY");
G4VSolid* solYRep = new G4Box(yRepName,fPhantomSize.x()/2.,sensSize.y()/2.,fPhantomSize.z()/2.);
G4LogicalVolume* logYRep = new G4LogicalVolume(solYRep,WATER,yRepName);
new G4PVReplica(yRepName,logYRep,fullWaterPhantomLV,kYAxis,ny,sensSize.y());
G4String xRepName("RepX");
G4VSolid* solXRep = new G4Box(xRepName,sensSize.x()/2.,sensSize.y()/2.,fPhantomSize.z()/2.);
G4LogicalVolume* logXRep = new G4LogicalVolume(solXRep,WATER,xRepName);
new G4PVReplica(xRepName,logXRep,logYRep,kXAxis,nx,sensSize.x());
G4String zVoxName("phantomSens");
G4VSolid* solVoxel = new G4Box(zVoxName,sensSize.x()/2.,sensSize.y()/2.,sensSize.z()/2.);
G4LogicalVolume* LVPhantomSens = new G4LogicalVolume(solVoxel,WATER,zVoxName); // This is the Sensitive Volume
new G4PVReplica(zVoxName,LVPhantomSens,logXRep,kZAxis,nz,sensSize.z());
//..............................................
// Phantom segmentation using Parameterisation
//..............................................
G4cout << " Water Phantom Size " << fPhantomSize/mm << G4endl;
G4cout << " Segmentation ("<< nx<<","<<ny<<","<<nz<<")"<< G4endl;
// Region for cuts
G4Region *regVol= new G4Region("fullWaterPhantomR");
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(0.1*mm);
regVol->SetProductionCuts(cuts);
fullWaterPhantomLV->SetRegion(regVol);
regVol->AddRootLogicalVolume(fullWaterPhantomLV);
@@ -84,20 +142,15 @@ bool CML2Ph_FullWater::Construct(G4VPhysicalVolume *PWorld, G4int saving_in_ROG_
// simpleAlSVisAtt->SetForceSolid(true);
fullWaterPhantomLV->SetVisAttributes(simpleAlSVisAtt);
// Sensitive detector
sensDet=new CML2SDWithVoxels("Water phantom", saving_in_ROG_Voxels_every_events, seed, ROGOutFile, bSaveROG, G4ThreeVector(0.,0.,0.), halfSize, 100, 100, 100);
G4SDManager *SDManager=G4SDManager::GetSDMpointer();
SDManager->AddNewDetector(sensDet);
// Read Out Geometry
CML2ReadOutGeometry *ROG = new CML2ReadOutGeometry();
ROG->setBuildData(PVWorld->GetFrameTranslation(), halfSize, 100, 100, 100);
ROG->BuildROGeometry();
sensDet->SetROgeometry(ROG);
fullWaterPhantomLV->SetSensitiveDetector(sensDet);
G4MultiFunctionalDetector* myScorer = new G4MultiFunctionalDetector("PhantomSD");
G4SDManager::GetSDMpointer()->AddNewDetector(myScorer);
LVPhantomSens->SetSensitiveDetector(myScorer);
G4VPrimitiveScorer * totalDose = new G4PSDoseDeposit3D("TotalDose", nx,ny,nz);
myScorer->RegisterPrimitive(totalDose);
G4cout << "scorer registered: totalDose" << G4endl;
bCreated=true;
return bCreated;
}
@@ -40,15 +40,26 @@
//
//*******************************************************//
#include "ML2Ph_FullWater.hh"
#include "ML2Ph_FullWaterMessenger.hh"
#include "ML2DummySD.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4SystemOfUnits.hh"
CML2DummySD::CML2DummySD(G4String name) : G4VSensitiveDetector(name)
CML2Ph_FullWaterMessenger::CML2Ph_FullWaterMessenger(CML2Ph_FullWater *) //: pPh_FullWater(ph_FullWater)
{
// Not used at that moment.
}
CML2Ph_FullWaterMessenger::~CML2Ph_FullWaterMessenger(void)
{
}
CML2DummySD::~CML2DummySD(void)
void CML2Ph_FullWaterMessenger::SetNewValue(G4UIcommand* , G4String )
{
}
G4bool CML2DummySD::ProcessHits(G4Step *, G4TouchableHistory *)
{return true;}
@@ -40,27 +40,21 @@
//
//*******************************************************//
#include "ML2PhantomConstruction.hh"
#include "ML2PhantomConstructionMessenger.hh"
#include "G4ios.hh"
#include "G4SystemOfUnits.hh"
CML2PhantomConstruction::CML2PhantomConstruction(void): PVPhmWorld(0), sensDet(0)
CML2PhantomConstruction::CML2PhantomConstruction(void): PVPhmWorld(0)
{
phantomContstructionMessenger=new CML2PhantomConstructionMessenger(this);
idCurrentCentre=0;
phantomContstructionMessenger = new CML2PhantomConstructionMessenger(this);
idCurrentCentre = 0;
}
CML2PhantomConstruction::~CML2PhantomConstruction(void)
{
if (phantomName=="fullWater")
{
delete Ph_fullWater;
}
else if (phantomName=="boxInBox")
{
delete Ph_BoxInBox;
}
}
{}
CML2PhantomConstruction* CML2PhantomConstruction::instance = 0;
@@ -75,75 +69,84 @@ CML2PhantomConstruction* CML2PhantomConstruction::GetInstance(void)
}
bool CML2PhantomConstruction::design(void)
{
// switch between two different phantoms according to the main macro selection
bool bPhanExists=false;
// switch between two different phantoms according to the macro ml2.mac
bool bPhanExists = false;
std::cout << "I'm building "<< phantomName<<" phantom"<< G4endl;
G4cout << "I'm building "<< phantomName<<" phantom"<< G4endl;
if (phantomName=="fullWater")
if (phantomName == "fullWater")
{
Ph_fullWater=new CML2Ph_FullWater();bPhanExists=true;
halfPhantomInsideSize=Ph_fullWater->getHalfContainerSize();
Ph_fullWater = new CML2Ph_FullWater();
bPhanExists=true;
halfPhantomInsideSize = Ph_fullWater->getHalfContainerSize();
}
else if (phantomName=="boxInBox")
else if (phantomName == "boxInBox")
{
Ph_BoxInBox=new CML2Ph_BoxInBox();bPhanExists=true;
halfPhantomInsideSize=Ph_BoxInBox->getHalfContainerSize();
Ph_BoxInBox = new CML2Ph_BoxInBox();
bPhanExists=true;
halfPhantomInsideSize = Ph_BoxInBox->getHalfContainerSize();
}
if (centre.size()<1)
{addNewCentre(G4ThreeVector(0.,0.,0.));}
if (centre.size() < 1)
{
addNewCentre(G4ThreeVector(0.,0.,0.));
}
return bPhanExists;
}
G4int CML2PhantomConstruction::getTotalNumberOfEvents()
{
if (phantomName=="fullWater")
{return Ph_fullWater->getTotalNumberOfEvents();}
else if (phantomName=="boxInBox")
{return Ph_BoxInBox->getTotalNumberOfEvents();}
return 0;
G4cout << "Not implemented at the moment " << G4endl;
/*if (phantomName == "fullWater")
{
return Ph_fullWater->getTotalNumberOfEvents();
}
else if (phantomName == "boxInBox")
{
return Ph_BoxInBox->getTotalNumberOfEvents();
}
*/
return 0;
}
bool CML2PhantomConstruction::Construct(G4VPhysicalVolume *PVWorld,
G4int saving_in_ROG_Voxels_every_events, G4int seed,
G4String ROGOutFile, G4bool bSaveROG, G4bool bOV)
G4int voxelX, G4int voxelY, G4int voxelZ, G4bool bOV)
{
idVolumeName=0;
bOnlyVisio=bOV;
// a call to select the right phantom
idVolumeName = 0;
bOnlyVisio = bOV;
// a call to select the right phantom
if(design())
{
phantomContstructionMessenger->SetReferenceWorld(bOV); // create the phantom-world box
G4Material *Vacuum=G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4Box *phmWorldB = new G4Box("phmWorldG", halfPhantomInsideSize.getX(), halfPhantomInsideSize.getY(), halfPhantomInsideSize.getZ());
G4Box *phmWorldB = new G4Box("phmWorldG", halfPhantomInsideSize.getX(),
halfPhantomInsideSize.getY(), halfPhantomInsideSize.getZ());
G4LogicalVolume *phmWorldLV = new G4LogicalVolume(phmWorldB, Vacuum, "phmWorldL", 0, 0, 0);
G4VisAttributes* simpleAlSVisAtt= new G4VisAttributes(G4Colour::White());
simpleAlSVisAtt->SetVisibility(false);
// simpleAlSVisAtt->SetForceWireframe(false);
phmWorldLV->SetVisAttributes(simpleAlSVisAtt);
PVPhmWorld= new G4PVPlacement(0, G4ThreeVector(0.,0.,0.), "phmWorldPV", phmWorldLV, PVWorld, false, 0);
PVPhmWorld = new G4PVPlacement(0, G4ThreeVector(0.,0.,0.), "phmWorldPV", phmWorldLV, PVWorld, false, 0);
// create the actual phantom
// create the actual phantom
if (phantomName=="fullWater")
{
Ph_fullWater->Construct(PVPhmWorld, saving_in_ROG_Voxels_every_events, seed, ROGOutFile, bSaveROG);
sensDet=Ph_fullWater->getSensDet();
Ph_fullWater->Construct(PVPhmWorld, voxelX, voxelY, voxelZ); // provide the voxelisation to the phantom
//sensDet=Ph_fullWater->getSensDet();
createPhysicalVolumeNamesList(Ph_fullWater->getPhysicalVolume());
Ph_fullWater->writeInfo();
}
else if (phantomName=="boxInBox")
{
Ph_BoxInBox->Construct(PVPhmWorld, saving_in_ROG_Voxels_every_events, seed, ROGOutFile, bSaveROG);
sensDet=Ph_BoxInBox->getSensDet();
Ph_BoxInBox->Construct(PVPhmWorld);
//sensDet=Ph_BoxInBox->getSensDet();
createPhysicalVolumeNamesList(Ph_BoxInBox->getPhysicalVolume());
Ph_BoxInBox->writeInfo();
}
// I create the data base volumeName-volumeID in the sensitive detector
sensDet->setVolumeNameIdLink(volumeNameIdLink);
}
else
{
@@ -166,7 +169,7 @@ void CML2PhantomConstruction::createPhysicalVolumeNamesList(G4VPhysicalVolume *
int nLVD1;
nLVD1=(int) PV->GetLogicalVolume()->GetNoDaughters();
SvolumeNameId svnid;
std::cout << "PV in name: " <<PV->GetName() << G4endl;
G4cout << "PV in name: " <<PV->GetName() << G4endl;
if (nLVD1>0)
{
for (int i=0; i <nLVD1; i++)
@@ -177,7 +180,7 @@ void CML2PhantomConstruction::createPhysicalVolumeNamesList(G4VPhysicalVolume *
svnid.volumeId=idVolumeName;
svnid.volumeName=PV->GetLogicalVolume()->GetMaterial()->GetName();
volumeNameIdLink.push_back(svnid);
std::cout << "physical volume name: " <<svnid.volumeName << G4endl;
G4cout << "physical volume name: " <<svnid.volumeName << G4endl;
}
else
{
@@ -185,14 +188,14 @@ void CML2PhantomConstruction::createPhysicalVolumeNamesList(G4VPhysicalVolume *
svnid.volumeId=idVolumeName;
svnid.volumeName=PV->GetLogicalVolume()->GetMaterial()->GetName();
volumeNameIdLink.push_back(svnid);
std::cout << "physical volume name: " <<svnid.volumeName << G4endl;
G4cout << "physical volume name: " <<svnid.volumeName << G4endl;
}
}
bool CML2PhantomConstruction::applyNewCentre()
{
if (idCurrentCentre <(int) centre.size())
{
currentCentre=centre[idCurrentCentre];
currentCentre = centre[idCurrentCentre];
applyNewCentre(currentCentre);
idCurrentCentre++;
return true;
@@ -202,21 +205,21 @@ bool CML2PhantomConstruction::applyNewCentre()
void CML2PhantomConstruction::writeInfo()
{
if (!bOnlyVisio)
{std::cout <<"Actual centre: "<<idCurrentCentre<<"/"<<centre.size() <<" "<< G4endl;}
std::cout <<"Phantom and its ROG centre: " << currentCentre<< G4endl;
{
G4cout << "Actual centre: "<<idCurrentCentre << "/" << centre.size() << " " << G4endl;
}
G4cout <<"Phantom and its ROG centre: " << currentCentre<< G4endl;
}
void CML2PhantomConstruction::applyNewCentre(G4ThreeVector ctr)
{
if (sensDet!=0)
{
currentCentre=ctr;
G4GeometryManager::GetInstance()->OpenGeometry();
PVPhmWorld->SetTranslation(ctr);
sensDet->GetROgeometry()->GetROWorld()->GetLogicalVolume()->GetDaughter(0)->SetTranslation(ctr);
sensDet->resetVoxelsSingle();
G4GeometryManager::GetInstance()->CloseGeometry();
G4RunManager::GetRunManager()->GeometryHasBeenModified();
}
if (PVPhmWorld)
{
currentCentre=ctr;
G4GeometryManager::GetInstance()->OpenGeometry();
PVPhmWorld->SetTranslation(ctr);
G4GeometryManager::GetInstance()->CloseGeometry();
G4RunManager::GetRunManager()->GeometryHasBeenModified();
}
}
G4String CML2PhantomConstruction::getCurrentTranslationString()
{
@@ -44,6 +44,7 @@
#include "ML2PhantomConstructionMessenger.hh"
#include "ML2PhantomConstruction.hh"
#include "G4ios.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
@@ -52,20 +53,15 @@
CML2PhantomConstructionMessenger::CML2PhantomConstructionMessenger(CML2PhantomConstruction *phantomConstructor) : pPhantomConstructor (phantomConstructor)
{
PhantomName=new G4UIcmdWithAString("/phantom/PhantomName",this);
PhantomName->SetDefaultValue("fullWater");
PhantomName->SetGuidance("phantom name to select among those implemented fullWater, boxInBox, Dicom1");
pPhantomConstructor->setPhantomName("fullWater");
PhantomName = new G4UIcmdWithAString("/phantom/PhantomName",this);
PhantomName -> SetDefaultValue("fullWater");
PhantomName -> SetGuidance("phantom name to select among those implemented (fullWater, boxInBox)");
pPhantomConstructor -> setPhantomName("fullWater");
PhantomFileName =new G4UIcmdWithAString("/phantom/PhantomFileName",this);
PhantomFileName ->SetDefaultValue("");
PhantomFileName->SetGuidance("full path and macro file name containing specific setup data for the phantom chosen");
pPhantomConstructor->setPhantomFileName ("");
phantomCentre=new G4UIcmdWith3VectorAndUnit("/phantom/centre", this);
phantomCentre->SetDefaultUnit("mm");
phantomCentre->SetGuidance("phantom centre coordinates in the world [mm]");
phantomCentre->SetDefaultValue(G4ThreeVector(0.,0.,0.));
phantomCentre = new G4UIcmdWith3VectorAndUnit("/phantom/centre", this);
phantomCentre -> SetDefaultUnit("mm");
phantomCentre -> SetGuidance("phantom centre coordinates in the world [mm]");
phantomCentre -> SetDefaultValue(G4ThreeVector(0.,0.,0.));
}
CML2PhantomConstructionMessenger::~CML2PhantomConstructionMessenger(void)
@@ -75,29 +71,19 @@ CML2PhantomConstructionMessenger::~CML2PhantomConstructionMessenger(void)
}
void CML2PhantomConstructionMessenger::SetNewValue(G4UIcommand* cmd, G4String newValue)
{
if (cmd==PhantomName)
{pPhantomConstructor->setPhantomName(newValue);}
if (cmd==PhantomFileName )
{pPhantomConstructor->setPhantomFileName (newValue);}
if (cmd==phantomCentre )
if (cmd == PhantomName)
{
if (bOnlyVisio)
{
pPhantomConstructor->applyNewCentre(phantomCentre->GetNew3VectorRawValue(newValue));
// what follows seems to be necessary to have a good refresh
G4UImanager* UI = G4UImanager::GetUIpointer();
G4String command;
command = "/run/beamOn 0";
UI->ApplyCommand(command);
command = "/vis/viewer/flush";
UI->ApplyCommand(command);
}
else
{
pPhantomConstructor->addNewCentre(phantomCentre->GetNew3VectorRawValue(newValue));
}
pPhantomConstructor->setPhantomName(newValue);
}
if (cmd == PhantomFileName )
{
pPhantomConstructor -> setPhantomFileName (newValue);
}
if (cmd == phantomCentre )
{
pPhantomConstructor -> addNewCentre(phantomCentre->GetNew3VectorRawValue(newValue));
}
}
@@ -42,61 +42,63 @@
#include "ML2PhaseSpaces.hh"
#include "ML2ReadOutGeometry.hh"
CML2PhaseSpaces::CML2PhaseSpaces():sensDetParticle(0)
CML2PhaseSpaces::CML2PhaseSpaces()
{}
CML2PhaseSpaces::~CML2PhaseSpaces(void)
{}
bool CML2PhaseSpaces::createPlane(G4VPhysicalVolume *PVWorld, G4String name, G4ThreeVector centre, G4ThreeVector halfSize)
/* NOT implemented at the moment
bool CML2PhaseSpaces::createPlane(G4VPhysicalVolume *, G4String , G4ThreeVector , G4ThreeVector )
{
G4cout << " Not implemented at the moment" << G4endl;
// constructor for killer plane
bool bCreated=false;
G4Material *Vacum=G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
bool bCreated = false;
G4Material *Vacum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4Box *box;
G4LogicalVolume *logVol;
box = new G4Box("KBox", halfSize.getX(), halfSize.getY(), halfSize.getZ());
logVol = new G4LogicalVolume(box, Vacum, name+"KLV", 0, 0, 0);
phVol= new G4PVPlacement(0, centre, name+"KPV", logVol, PVWorld, false, 0);
phVol = new G4PVPlacement(0, centre, name+"KPV", logVol, PVWorld, false, 0);
G4Colour color(0.,1.,1.,0.5);
G4VisAttributes* simplePhSpVisAtt= new G4VisAttributes(color);
G4VisAttributes* simplePhSpVisAtt = new G4VisAttributes(G4Colour::Cyan());
simplePhSpVisAtt->SetVisibility(true);
simplePhSpVisAtt->SetForceSolid(true);
logVol->SetVisAttributes(simplePhSpVisAtt);
sensDetParticle=new CML2SDWithParticle();
G4SDManager *SDManager=G4SDManager::GetSDMpointer();
SDManager->AddNewDetector(sensDetParticle);
logVol->SetSensitiveDetector(sensDetParticle);
bCreated=true;
bCreated = true;
return bCreated;
}
bool CML2PhaseSpaces::createPlane(G4int idSD_Type, G4int max_N_particles_in_PhSp_File, G4int seed, G4int nMaxParticlesInRamPhaseSpace, G4VPhysicalVolume *PVWorld, G4String name, G4String PhaseSpaceOutFile, G4bool bSavePhaseSpace, G4bool bStopAtPhaseSpace, G4ThreeVector centre, G4ThreeVector halfSize, SPrimaryParticle *primaryParticleData, G4double accTargetZPosition)
bool CML2PhaseSpaces::createPlane(G4int, //idSD_Type,
G4int,//max_N_particles_in_PhSp_File,
G4int, //seed,
G4int,// nMaxParticlesInRamPhaseSpace,
G4VPhysicalVolume*,// *PVWorld,
G4String, //name, G4String PhaseSpaceOutFile, G4bool bSavePhaseSpace, G4bool bStopAtPhaseSpace, G4ThreeVector centre, G4ThreeVector halfSize, SPrimaryParticle *primaryParticleData, G4double accTargetZPosition)
{
// constructor for phase space plane
bool bCreated=false;
G4Material *Vacum=G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
bool bCreated = false;
G4Material *Vacum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4Box *box;
G4LogicalVolume *logVol;
box = new G4Box(name+"Box", halfSize.getX(), halfSize.getY(), halfSize.getZ());
logVol = new G4LogicalVolume(box, Vacum, name+"LV", 0, 0, 0);
phVol= new G4PVPlacement(0, centre, name+"PV", logVol, PVWorld, false, 0);
G4VisAttributes* simplePhSpVisAtt= new G4VisAttributes(G4Colour::Yellow());
simplePhSpVisAtt->SetVisibility(true);
simplePhSpVisAtt->SetForceSolid(true);
logVol->SetVisAttributes(simplePhSpVisAtt);
G4VisAttributes* simplePhSpVisAtt = new G4VisAttributes(G4Colour::Yellow());
simplePhSpVisAtt -> SetVisibility(true);
simplePhSpVisAtt -> SetForceSolid(true);
logVol -> SetVisAttributes(simplePhSpVisAtt);
sensDetParticle=new CML2SDWithParticle(idSD_Type, max_N_particles_in_PhSp_File, seed, nMaxParticlesInRamPhaseSpace, name, PhaseSpaceOutFile, bSavePhaseSpace, bStopAtPhaseSpace, primaryParticleData, accTargetZPosition);
G4SDManager *SDManager=G4SDManager::GetSDMpointer();
SDManager->AddNewDetector(sensDetParticle);
logVol->SetSensitiveDetector(sensDetParticle);
bCreated=true;
sensDetParticle = new CML2SDWithParticle(idSD_Type, max_N_particles_in_PhSp_File, seed, nMaxParticlesInRamPhaseSpace, name, PhaseSpaceOutFile, bSavePhaseSpace, bStopAtPhaseSpace, primaryParticleData, accTargetZPosition);
G4SDManager *SDManager = G4SDManager::GetSDMpointer();
SDManager -> AddNewDetector(sensDetParticle);
logVol -> SetSensitiveDetector(sensDetParticle);
bCreated = true;
return bCreated;
}
}
*/
@@ -76,10 +76,10 @@
#include "ML2PhysicsListMessenger.hh"
#include "ML2StepMax.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysListFactory.hh"
#include "G4VPhysicsConstructor.hh"
// Physic lists (contained inside the Geant4 distribution)
// Physics lists
#include "G4EmStandardPhysics_option4.hh"
#include "G4EmStandardPhysics_option3.hh"
#include "G4EmLivermorePhysics.hh"
#include "G4EmPenelopePhysics.hh"
@@ -89,29 +89,19 @@
#include "G4IonBinaryCascadePhysics.hh"
#include "G4Decay.hh"
#include "G4LossTableManager.hh"
#include "G4UnitsTable.hh"
#include "G4ProcessManager.hh"
#include "G4IonFluctuations.hh"
#include "G4IonParametrisedLossModel.hh"
#include "G4EmProcessOptions.hh"
/////////////////////////////////////////////////////////////////////////////
ML2PhysicsList::ML2PhysicsList() : G4VModularPhysicsList()
{
G4LossTableManager::Instance();
defaultCutValue = 1.*mm;
cutForGamma = defaultCutValue;
cutForElectron = defaultCutValue;
cutForPositron = defaultCutValue;
helIsRegisted = false;
bicIsRegisted = false;
biciIsRegisted = false;
locIonIonInelasticIsRegistered = false;
stepMaxProcess = 0;
stepMaxProcess = nullptr;
pMessenger = new ML2PhysicsListMessenger(this);
@@ -121,10 +111,10 @@ ML2PhysicsList::ML2PhysicsList() : G4VModularPhysicsList()
emPhysicsList = new G4EmStandardPhysics_option3(1);
emName = G4String("emstandard_opt3");
// emPhysicsList = new G4EmLivermorePhysics();
// emName = G4String("LowE_Livermore");
// emPhysicsList = new G4EmLivermorePhysics();
// emName = G4String("LowE_Livermore");
// Deacy physics and all particles
// Decay physics and all particles
decPhysicsList = new G4DecayPhysics();
}
@@ -137,23 +127,6 @@ ML2PhysicsList::~ML2PhysicsList()
for(size_t i=0; i<hadronPhys.size(); i++) {delete hadronPhys[i];}
}
/////////////////////////////////////////////////////////////////////////////
void ML2PhysicsList::AddPackage(const G4String& name)
{
G4PhysListFactory factory;
G4VModularPhysicsList* phys =factory.GetReferencePhysList(name);
G4int i=0;
const G4VPhysicsConstructor* elem= phys->GetPhysics(i);
G4VPhysicsConstructor* tmp = const_cast<G4VPhysicsConstructor*> (elem);
while (elem !=0)
{
RegisterPhysics(tmp);
elem= phys->GetPhysics(++i) ;
tmp = const_cast<G4VPhysicsConstructor*> (elem);
}
G4cout << "THE FOLLOWING PHYSICS PACKEGE LIST HAS BEEN ACTIVATED: "<<name<< G4endl;
}
/////////////////////////////////////////////////////////////////////////////
void ML2PhysicsList::ConstructParticle()
{
@@ -170,7 +143,6 @@ void ML2PhysicsList::ConstructProcess()
// electromagnetic physics list
//
emPhysicsList->ConstructProcess();
em_config.AddModels();
// decay physics list
//
@@ -205,21 +177,27 @@ void ML2PhysicsList::AddPhysicsList(const G4String& name)
emPhysicsList = new G4EmStandardPhysics_option3();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmStandardPhysics_option3" << G4endl;
} else if (name == "LowE_Livermore") {
} else if (name == "standard_opt4") {
emName = name;
delete emPhysicsList;
emPhysicsList = new G4EmStandardPhysics_option4();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmStandardPhysics_option4" << G4endl;
} else if (name == "LowE_Livermore") {
emName = name;
delete emPhysicsList;
emPhysicsList = new G4EmLivermorePhysics();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmLivermorePhysics" << G4endl;
} else if (name == "LowE_Penelope") {
} else if (name == "LowE_Penelope") {
emName = name;
delete emPhysicsList;
emPhysicsList = new G4EmPenelopePhysics();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmLivermorePhysics" << G4endl;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// HADRONIC MODELS
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
} else if (name == "elastic" && !helIsRegisted) {
G4cout << "THE FOLLOWING HADRONIC ELASTIC PHYSICS LIST HAS BEEN ACTIVATED: G4HadronElasticPhysics()" << G4endl;
hadronPhys.push_back( new G4HadronElasticPhysics());
@@ -261,43 +239,5 @@ void ML2PhysicsList::AddStepMax()
}
}
/////////////////////////////////////////////////////////////////////////////
void ML2PhysicsList::SetCuts()
{
if (verboseLevel >0){
G4cout << "PhysicsList::SetCuts:";
G4cout << "CutLength : " << G4BestUnit(defaultCutValue,"Length") << G4endl;
}
// set cut values for gamma at first and for e- second and next for e+,
// because some processes for e+/e- need cut values for gamma
SetCutValue(cutForGamma, "gamma");
SetCutValue(cutForElectron, "e-");
SetCutValue(cutForPositron, "e+");
if (verboseLevel>0) DumpCutValuesTable();
}
/////////////////////////////////////////////////////////////////////////////
void ML2PhysicsList::SetCutForGamma(G4double cut)
{
cutForGamma = cut;
SetParticleCuts(cutForGamma, G4Gamma::Gamma());
}
/////////////////////////////////////////////////////////////////////////////
void ML2PhysicsList::SetCutForElectron(G4double cut)
{
cutForElectron = cut;
SetParticleCuts(cutForElectron, G4Electron::Electron());
}
/////////////////////////////////////////////////////////////////////////////
void ML2PhysicsList::SetCutForPositron(G4double cut)
{
cutForPositron = cut;
SetParticleCuts(cutForPositron, G4Positron::Positron());
}
@@ -39,7 +39,6 @@
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
#include "ML2PhysicsListMessenger.hh"
#include "ML2PhysicsList.hh"
@@ -51,58 +50,20 @@
ML2PhysicsListMessenger::ML2PhysicsListMessenger(ML2PhysicsList* pPhys)
:pPhysicsList(pPhys)
{
physDir = new G4UIdirectory("/physic/");
physDir = new G4UIdirectory("/physics/");
physDir->SetGuidance("Commands to activate physics models and set cuts");
gammaCutCmd = new G4UIcmdWithADoubleAndUnit("/physic/setGCut",this);
gammaCutCmd->SetGuidance("Set gamma cut.");
gammaCutCmd->SetParameterName("Gcut",false);
gammaCutCmd->SetUnitCategory("Length");
gammaCutCmd->SetRange("Gcut>0.0");
gammaCutCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
electCutCmd = new G4UIcmdWithADoubleAndUnit("/physic/setECut",this);
electCutCmd->SetGuidance("Set electron cut.");
electCutCmd->SetParameterName("Ecut",false);
electCutCmd->SetUnitCategory("Length");
electCutCmd->SetRange("Ecut>0.0");
electCutCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
protoCutCmd = new G4UIcmdWithADoubleAndUnit("/physic/setPCut",this);
protoCutCmd->SetGuidance("Set positron cut.");
protoCutCmd->SetParameterName("Pcut",false);
protoCutCmd->SetUnitCategory("Length");
protoCutCmd->SetRange("Pcut>0.0");
protoCutCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
allCutCmd = new G4UIcmdWithADoubleAndUnit("/physic/setCuts",this);
allCutCmd->SetGuidance("Set cut for all.");
allCutCmd->SetParameterName("cut",false);
allCutCmd->SetUnitCategory("Length");
allCutCmd->SetRange("cut>0.0");
allCutCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
pListCmd = new G4UIcmdWithAString("/physic/addPhysics",this);
pListCmd = new G4UIcmdWithAString("/physics/addPhysics",this);
pListCmd->SetGuidance("Add physics list.");
pListCmd->SetParameterName("PList",false);
pListCmd->AvailableForStates(G4State_PreInit);
packageListCmd = new G4UIcmdWithAString("/physic/addPackage",this);
packageListCmd->SetGuidance("Add physics package.");
packageListCmd->SetParameterName("package",false);
packageListCmd->AvailableForStates(G4State_PreInit);
}
/////////////////////////////////////////////////////////////////////////////
ML2PhysicsListMessenger::~ML2PhysicsListMessenger()
{
delete gammaCutCmd;
delete electCutCmd;
delete protoCutCmd;
delete allCutCmd;
delete pListCmd;
delete physDir;
delete packageListCmd;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -110,28 +71,8 @@ ML2PhysicsListMessenger::~ML2PhysicsListMessenger()
void ML2PhysicsListMessenger::SetNewValue(G4UIcommand* command,
G4String newValue)
{
if( command == gammaCutCmd )
{ pPhysicsList->SetCutForGamma(gammaCutCmd->GetNewDoubleValue(newValue));}
if( command == electCutCmd )
{ pPhysicsList->SetCutForElectron(electCutCmd->GetNewDoubleValue(newValue));}
if( command == protoCutCmd )
{ pPhysicsList->SetCutForPositron(protoCutCmd->GetNewDoubleValue(newValue));}
if( command == allCutCmd )
{
G4double cut = allCutCmd->GetNewDoubleValue(newValue);
pPhysicsList->SetCutForGamma(cut);
pPhysicsList->SetCutForElectron(cut);
pPhysicsList->SetCutForPositron(cut);
}
if( command == pListCmd )
{ pPhysicsList->AddPhysicsList(newValue);}
if( command == packageListCmd )
{ pPhysicsList->AddPackage(newValue);}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -40,6 +40,7 @@
//
//*******************************************************//
#include "ML2PrimaryGenerationAction.hh"
using namespace CLHEP;
@@ -60,21 +61,21 @@ CML2PrimaryGenerationAction* CML2PrimaryGenerationAction::GetInstance(void)
}
void CML2PrimaryGenerationAction::inizialize(SPrimaryParticle *pData)
{
rm=new G4RotationMatrix();
PrimaryGenerationActionMessenger=new CML2PrimaryGenerationActionMessenger(this);
particle=new Sparticle;
nParticle=nPhSpParticles=nRandomParticles=0;
rm = new G4RotationMatrix();
PrimaryGenerationActionMessenger = new CML2PrimaryGenerationActionMessenger(this);
particle = new Sparticle;
nParticle = nPhSpParticles = nRandomParticles = 0;
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
gamma=particleTable->FindParticle("gamma");
electron=particleTable->FindParticle("e-");
positron=particleTable->FindParticle("e+");
particleGun=new G4ParticleGun();
gamma = particleTable->FindParticle("gamma");
electron = particleTable->FindParticle("e-");
positron = particleTable->FindParticle("e+");
particleGun = new G4ParticleGun();
primaryParticleData=pData;
primaryParticleData->nPrimaryParticle=0;
primaryParticleData->partPDGE=0;
primaryParticleData = pData;
primaryParticleData -> nPrimaryParticle = 0;
primaryParticleData -> partPDGE = 0;
}
void CML2PrimaryGenerationAction::design(G4double aTZ)
@@ -127,15 +128,15 @@ void CML2PrimaryGenerationAction::GeneratePrimaries(G4Event *anEvent)
GenerateFromCalculatedPhaseSpace();
break;
}
pos0=pos;
dir0=dir;
pos0 = pos;
dir0 = dir;
}
currentRecycle++;
pos=pos0;
dir=dir0;
pos = pos0;
dir = dir0;
applySourceRotation(); // to follow the accelerator rotation
primaryParticleData->partPDGE=particleGun->GetParticleDefinition()->GetPDGEncoding();
primaryParticleData->partPDGE = particleGun->GetParticleDefinition()->GetPDGEncoding();
primaryParticleData->nPrimaryParticle++;
particleGun->SetParticleEnergy(ek*MeV);
@@ -145,18 +146,18 @@ void CML2PrimaryGenerationAction::GeneratePrimaries(G4Event *anEvent)
}
void CML2PrimaryGenerationAction::GenerateFromRandom()
{
sinTheta=RandGauss::shoot(0., 0.003);
cosTheta=std::sqrt(1 - sinTheta*sinTheta);
phi=twopi*G4UniformRand();
sinTheta = RandGauss::shoot(0., 0.003);
cosTheta = std::sqrt(1 - sinTheta*sinTheta);
phi = twopi*G4UniformRand();
dir.set(sinTheta*std::cos(phi), sinTheta*std::sin(phi), cosTheta);
ro=G4UniformRand()*GunRadious;
alfa=G4UniformRand()*twopi;
rho = G4UniformRand()*GunRadius;
alpha = G4UniformRand()*twopi;
pos.setX(ro*std::sin(alfa));
pos.setY(ro*std::cos(alfa));
pos.setX(rho*std::sin(alpha));
pos.setY(rho*std::cos(alpha));
pos.setZ(-(accTargetZPosition +5.)*mm); // the primary electrons are generated 5 mm before the target
ek=RandGauss::shoot(GunMeanEnegy, GunStdEnegy);
ek=RandGauss::shoot(GunMeanEnergy, GunStdEnergy);
nRandomParticles++;
}
void CML2PrimaryGenerationAction::GenerateFromCalculatedPhaseSpace()
@@ -202,7 +203,7 @@ void CML2PrimaryGenerationAction::fillParticlesContainer()
in.open(calculatedPhaseSpaceFileIN, std::ios::in);
if (in)
{
std::cout <<"ERROR phase space file: "<< calculatedPhaseSpaceFileIN << " NOT found. Run abort "<< G4endl;
G4cout << "ERROR phase space file: " << calculatedPhaseSpaceFileIN << " NOT found. Run abort " << G4endl;
G4RunManager::GetRunManager()->AbortRun(true);
}
@@ -238,14 +239,14 @@ void CML2PrimaryGenerationAction::fillParticlesContainer()
in.seekg(startDataFilePosition, std::ios::beg);
checkFileRewind=true;
bRewindTheFile=false;
std::cout<<"\n################\nI have reached the end of the phase space file "<<++nPhSpFileRewind <<" times, I rewind the file\n" << G4endl;
std::cout <<"loaded " <<i <<"/"<< nMaxParticlesInRamPhaseSpace<<" particles" << G4endl;
G4cout<<"\n################\nI have reached the end of the phase space file "<<++nPhSpFileRewind <<" times, I rewind the file\n" << G4endl;
G4cout <<"loaded " <<i <<"/"<< nMaxParticlesInRamPhaseSpace<<" particles" << G4endl;
}
in >> d;
in >> x; in >>y; in >> z;
/* std::cout <<"x:" <<x << G4endl;
std::cout <<"y:" <<y << G4endl;
std::cout <<"z:" <<z << G4endl;*/
/* G4cout <<"x:" <<x << G4endl;
G4cout <<"y:" <<y << G4endl;
G4cout <<"z:" <<z << G4endl;*/
particles[i].pos.set(x,y,z-accTargetZPosition);
in >> x; in >>y; in >> z;
particles[i].dir.set(x,y,z);
@@ -257,7 +258,7 @@ void CML2PrimaryGenerationAction::fillParticlesContainer()
if (in.eof()) {bRewindTheFile=true;}
if (checkFileRewind) {checkFileRewind=false;}
}
std::cout <<"loaded " <<i <<"/"<< nMaxParticlesInRamPhaseSpace<<" particles" << G4endl;
G4cout <<"loaded " <<i <<"/"<< nMaxParticlesInRamPhaseSpace<<" particles" << G4endl;
currentFilePosition=in.tellg(); // to remind the actual position in the phase space file
if (currentFilePosition>=currentFileSize) // to read the phase space file again
{currentFilePosition=startDataFilePosition;}
@@ -55,77 +55,81 @@ CML2PrimaryGenerationActionMessenger::CML2PrimaryGenerationActionMessenger(CML2P
calculatedPhaseSpaceFileIN=new G4UIcmdWithAString("/primaryParticleData/calculatedPhaseSpaceFileIN",this);
calculatedPhaseSpaceFileIN->SetDefaultValue("");
calculatedPhaseSpaceFileIN->SetGuidance("full path and file name of the phase space file to be used as particle generator");
calculatedPhaseSpaceFileIN->SetGuidance("full path and name of the phase space file to be used as particle generator");
sourceTypeName=new G4UIcmdWithAString("/primaryParticleData/sourceTypeName",this);
sourceTypeName->SetDefaultValue("");
sourceTypeName->SetGuidance("type of particle generator source (randomTarget, phaseSpace)");
sourceTypeName->SetGuidance("type of particle generator source (randomTarget, phaseSpace)");
nMaxParticlesInRamPhaseSpace=new G4UIcmdWithAnInteger("/primaryParticleData/nMaxParticlesInRamPhaseSpace",this);
nMaxParticlesInRamPhaseSpace->SetDefaultValue(10000);
nMaxParticlesInRamPhaseSpace->SetGuidance("maximum particle number loaded from the phase space file each time");
nMaxParticlesInRamPhaseSpace->SetGuidance("maximum number of particle loaded from the phase space file each time");
GunMeanEnegy=new G4UIcmdWithADoubleAndUnit("/primaryParticleData/GunMeanEnegy", this);
GunMeanEnegy->SetDefaultUnit("MeV");
GunMeanEnegy->SetDefaultValue(6.);
GunMeanEnegy->SetGuidance("mean energy of the primary particles");
GunMeanEnergy=new G4UIcmdWithADoubleAndUnit("/primaryParticleData/GunMeanEnergy", this);
GunMeanEnergy->SetDefaultUnit("MeV");
GunMeanEnergy->SetDefaultValue(6.);
GunMeanEnergy->SetGuidance("mean energy of the beam");
GunStdEnegy=new G4UIcmdWithADoubleAndUnit("/primaryParticleData/GunStdEnegy", this);
GunStdEnegy->SetDefaultUnit("MeV");
GunStdEnegy->SetDefaultValue(0.127);
GunStdEnegy->SetGuidance("std energy of the primary particles");
GunStdEnergy=new G4UIcmdWithADoubleAndUnit("/primaryParticleData/GunStdEnergy", this);
GunStdEnergy->SetDefaultUnit("MeV");
GunStdEnergy->SetDefaultValue(0.127);
GunStdEnergy->SetGuidance("std deviation of energy of the beam");
GunRadious=new G4UIcmdWithADoubleAndUnit("/primaryParticleData/GunRadious", this);
GunRadious->SetDefaultUnit("mm");
GunRadious->SetDefaultValue(10.);
GunRadious->SetGuidance("radious primary particles beam");
GunRadius=new G4UIcmdWithADoubleAndUnit("/primaryParticleData/GunRadius", this);
GunRadius->SetDefaultUnit("mm");
GunRadius->SetDefaultValue(10.);
GunRadius->SetGuidance("radius of the beam");
}
CML2PrimaryGenerationActionMessenger::~CML2PrimaryGenerationActionMessenger(void)
{
delete nRecycling;
delete nMaxParticlesInRamPhaseSpace;
delete GunMeanEnegy;
delete GunStdEnegy;
delete GunRadious;
delete GunMeanEnergy;
delete GunStdEnergy;
delete GunRadius;
delete calculatedPhaseSpaceFileIN;
delete sourceTypeName;
}
void CML2PrimaryGenerationActionMessenger::SetNewValue(G4UIcommand* cmd, G4String newValue)
{
if (cmd==GunMeanEnegy)
if (cmd == GunMeanEnergy)
{
GunMeanEnegy->GetNewUnitValue(newValue);
pML2PrimaryGenerationAction->setGunMeanEnergy(GunMeanEnegy->GetNewDoubleValue(newValue));
GunMeanEnergy -> GetNewUnitValue(newValue);
pML2PrimaryGenerationAction -> setGunMeanEnergy(GunMeanEnergy->GetNewDoubleValue(newValue));
}
if (cmd==GunStdEnegy)
if (cmd == GunStdEnergy)
{
GunStdEnegy->GetNewUnitValue(newValue);
pML2PrimaryGenerationAction->setGunStdEnergy(GunStdEnegy->GetNewDoubleValue(newValue));
GunStdEnergy -> GetNewUnitValue(newValue);
pML2PrimaryGenerationAction -> setGunStdEnergy(GunStdEnergy->GetNewDoubleValue(newValue));
}
if (cmd==GunRadious)
if (cmd == GunRadius)
{
GunRadious->GetNewUnitValue(newValue);
pML2PrimaryGenerationAction->setGunRadious(GunRadious->GetNewDoubleValue(newValue));
GunRadius -> GetNewUnitValue(newValue);
pML2PrimaryGenerationAction -> setGunRadius(GunRadius->GetNewDoubleValue(newValue));
}
if (cmd==nMaxParticlesInRamPhaseSpace)
if (cmd == nMaxParticlesInRamPhaseSpace)
{
pML2PrimaryGenerationAction->setNMaxParticlesInRamPhaseSpace(nMaxParticlesInRamPhaseSpace->GetNewIntValue(newValue));
pML2PrimaryGenerationAction -> setNMaxParticlesInRamPhaseSpace(nMaxParticlesInRamPhaseSpace->GetNewIntValue(newValue));
}
if (cmd == nRecycling)
{
pML2PrimaryGenerationAction -> setNRecycling(nRecycling->GetNewIntValue(newValue));
}
if (cmd==nRecycling)
{pML2PrimaryGenerationAction->setNRecycling(nRecycling->GetNewIntValue(newValue));}
if (cmd == calculatedPhaseSpaceFileIN)
{
pML2PrimaryGenerationAction -> setCalculatedPhaseSpaceFileIN(newValue);
}
if (cmd==calculatedPhaseSpaceFileIN)
{pML2PrimaryGenerationAction->setCalculatedPhaseSpaceFileIN(newValue);}
if (cmd==sourceTypeName)
{pML2PrimaryGenerationAction->setSourceTypeName(newValue);}
if (cmd == sourceTypeName)
{
pML2PrimaryGenerationAction -> setSourceTypeName(newValue);
}
}
@@ -1,163 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2ReadOutGeometry.hh"
#include "G4SystemOfUnits.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
#include "G4Box.hh"
#include "G4PVPlacement.hh"
#include "G4NistManager.hh"
#include "ML2DummySD.hh"
#include "G4PVReplica.hh"
CML2ReadOutGeometry::CML2ReadOutGeometry() : ROPhyVol(0)
{
// Build the world volume
G4Material *Vacuum=G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4ThreeVector halfSizeWorld, ctr;
ctr.set(0.*mm, 0.*mm, 0.*mm);
halfSizeWorld.set(3000.*mm, 3000*mm, 3000*mm);
G4Box *ROphmWorldB = new G4Box("ROphmWorldG", halfSizeWorld.getX(), halfSizeWorld.getY(), halfSizeWorld.getZ());
G4LogicalVolume *ROphmWorldLV = new G4LogicalVolume(ROphmWorldB, Vacuum, "ROphmWorldL", 0, 0, 0);
ROPhyVol= new G4PVPlacement(0, ctr, "ROphmWorldPV", ROphmWorldLV, 0, false, 0);
}
CML2ReadOutGeometry::~CML2ReadOutGeometry(void)
{
delete ROPhyVol;
}
void CML2ReadOutGeometry::setBuildData(G4ThreeVector ctr, G4ThreeVector hSiz, G4int NVX, G4int NVY, G4int NVZ)
{
centre=ctr;
halfSize=hSiz;
NumberOfVoxelsAlongX=NVX;
NumberOfVoxelsAlongY=NVY;
NumberOfVoxelsAlongZ=NVZ;
}
G4VPhysicalVolume* CML2ReadOutGeometry::Build()
{
// Build RO Zone
G4Material *Vacuum=G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4Box *ROBox = new G4Box("ROBox", halfSize.getX(), halfSize.getY(), halfSize.getZ());
G4LogicalVolume *ROLV = new G4LogicalVolume(ROBox, Vacuum, "ROLV", 0, 0, 0);
G4VPhysicalVolume *ROPV;
ROPV = new G4PVPlacement(0, centre, "ROPV", ROLV, ROPhyVol, false, 0);
// ROGeomtry: Voxel division
G4double halfXVoxelDimensionX, halfXVoxelDimensionY, halfXVoxelDimensionZ;
halfXVoxelDimensionX=halfSize.getX()/NumberOfVoxelsAlongX;
halfXVoxelDimensionY=halfSize.getY()/NumberOfVoxelsAlongY;
halfXVoxelDimensionZ=halfSize.getZ()/NumberOfVoxelsAlongZ;
G4double voxelXThicknessX = 2*halfXVoxelDimensionX;
G4double voxelXThicknessY = 2*halfXVoxelDimensionY;
G4double voxelXThicknessZ = 2*halfXVoxelDimensionZ;
// X division first... slice along X axis
G4Box *ROPhantomXDivision = new G4Box("ROPhantomXDivision",
halfXVoxelDimensionX,
halfSize.getY(),
halfSize.getZ());
G4LogicalVolume *ROPhantomXDivisionLog = new G4LogicalVolume(ROPhantomXDivision,
Vacuum,
"ROPhantomXDivisionLog",
0,0,0);
G4VPhysicalVolume *ROPhantomXDivisionPhys;
ROPhantomXDivisionPhys = new G4PVReplica("ROPhantomXDivisionPhys",
ROPhantomXDivisionLog,
ROPV,
kXAxis,
NumberOfVoxelsAlongX,
voxelXThicknessX,
-halfSize.getX());
// ...then Z division
G4Box *ROPhantomZDivision = new G4Box("ROPhantomZDivision",
halfXVoxelDimensionX,
halfSize.getY(),
halfXVoxelDimensionZ);
G4LogicalVolume *ROPhantomZDivisionLog = new G4LogicalVolume(ROPhantomZDivision,
Vacuum,
"ROPhantomZDivisionLog",
0,0,0);
G4VPhysicalVolume *ROPhantomZDivisionPhys;
ROPhantomZDivisionPhys = new G4PVReplica("ROPhantomZDivisionPhys",
ROPhantomZDivisionLog,
ROPhantomXDivisionPhys,
kZAxis,
NumberOfVoxelsAlongZ,
voxelXThicknessZ,
-halfSize.getZ());
// ...then Y division
G4Box *ROPhantomYDivision = new G4Box("ROPhantomYDivision",
halfXVoxelDimensionX,
halfXVoxelDimensionY,
halfXVoxelDimensionZ);
G4LogicalVolume *ROPhantomYDivisionLog = new G4LogicalVolume(ROPhantomYDivision,
Vacuum,
"ROPhantomYDivisionLog",
0,0,0);
ROPhantomYDivisionPhys = new G4PVReplica("ROPhantomYDivisionPhys",
ROPhantomYDivisionLog,
ROPhantomZDivisionPhys,
kYAxis,
NumberOfVoxelsAlongY,
voxelXThicknessY,
-halfSize.getY());
// Sensitive detector doesn't matter which logical volume is used
G4VSensitiveDetector *sensDet=new CML2DummySD("Dummy ROG phantom");
ROPhantomYDivisionLog->SetSensitiveDetector(sensDet);
return ROPhyVol;
}
@@ -0,0 +1,181 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// SUSANNA: This class is based on the RE02 extended example
//
#include "ML2Run.hh"
#include "G4SDManager.hh"
#include "G4MultiFunctionalDetector.hh"
#include "G4VPrimitiveScorer.hh"
ML2Run::ML2Run(const std::vector<G4String> mfdName) : G4Run()
{
G4SDManager* pSDman = G4SDManager::GetSDMpointer();
//=================================================
// Initalize RunMaps for accumulation.
// Get CollectionIDs for HitCollections.
//=================================================
G4int nMfd = mfdName.size();
for ( G4int idet = 0; idet < nMfd ; idet++){ // Loop for all MFD.
G4String detName = mfdName[idet];
//--- Seek and Obtain MFD objects from SDmanager.
G4MultiFunctionalDetector* mfd =
(G4MultiFunctionalDetector*)(pSDman->FindSensitiveDetector(detName));
//
if ( mfd ){
//--- Loop over the registered primitive scorers.
for (G4int icol = 0; icol < mfd->GetNumberOfPrimitives(); icol++){
// Get Primitive Scorer object.
G4VPrimitiveScorer* scorer=mfd->GetPrimitive(icol);
// collection name and collectionID for HitsCollection,
// where type of HitsCollection is G4THitsMap in case of primitive
// scorer.
// The collection name is given by <MFD name>/<Primitive Scorer name>.
G4String collectionName = scorer->GetName();
G4String fullCollectionName = detName+"/"+collectionName;
G4int collectionID = pSDman->GetCollectionID(fullCollectionName);
//
if ( collectionID >= 0 ){
G4cout << "++ "<<fullCollectionName<< " id " << collectionID
<< G4endl;
// Store obtained HitsCollection information into data members.
// And, creates new G4THitsMap for accumulating quantities during RUN.
fCollName.push_back(fullCollectionName);
fCollID.push_back(collectionID);
fRunMap.push_back(new G4THitsMap<G4double>(detName,collectionName));
}else{
G4cout << "** collection " << fullCollectionName << " not found. "
<< G4endl;
}
}
}
}
}
// clear all data members.
ML2Run::~ML2Run()
{
//--- Clear HitsMap for RUN
G4int nMap = fRunMap.size();
for ( G4int i = 0; i < nMap; i++){
if(fRunMap[i] ) fRunMap[i]->clear();
}
fCollName.clear();
fCollID.clear();
fRunMap.clear();
}
//
// RecordEvent is called at end of event.
// For scoring purpose, the resultant quantity in a event,
// is accumulated during a Run.
void ML2Run::RecordEvent(const G4Event* aEvent)
{
numberOfEvent++; // This is an original line.
//=============================
// HitsCollection of This Event
//============================
G4HCofThisEvent* pHCE = aEvent->GetHCofThisEvent();
if (!pHCE) return;
//=======================================================
// Sum up HitsMap of this Event into HitsMap of this RUN
//=======================================================
G4int nCol = fCollID.size();
for ( G4int i = 0; i < nCol ; i++ ){ // Loop over HitsCollection
G4THitsMap<G4double>* evtMap=0;
if ( fCollID[i] >= 0 ){ // Collection is attached to pHCE
evtMap = (G4THitsMap<G4double>*)(pHCE->GetHC(fCollID[i]));
}else{
G4cout <<" Error evtMap Not Found "<< i << G4endl;
}
if ( evtMap ) {
//=== Sum up HitsMap of this event to HitsMap of RUN.===
*fRunMap[i] += *evtMap;
//======================================================
}
}
}
void ML2Run::Merge(const G4Run * aRun)
{
const ML2Run * localRun = static_cast<const ML2Run *>(aRun);
//=======================================================
// Merge HitsMap of working threads
//=======================================================
G4int nCol = localRun->fCollID.size();
for ( G4int i = 0; i < nCol ; i++ ){ // Loop over HitsCollection
if ( localRun->fCollID[i] >= 0 ){
*fRunMap[i] += *localRun->fRunMap[i];
}
}
G4Run::Merge(aRun);
}
// Access method for HitsMap of the RUN
//
//-----
// Access HitsMap.
// By MultiFunctionalDetector name and Collection Name.
G4THitsMap<G4double>* ML2Run::GetHitsMap(const G4String& detName,
const G4String& colName){
G4String fullName = detName+"/"+colName;
return GetHitsMap(fullName);
}
// Access HitsMap.
// By full description of collection name, that is
// <MultiFunctional Detector Name>/<Primitive Scorer Name>
G4THitsMap<G4double>* ML2Run::GetHitsMap(const G4String& fullName){
G4int nCol = fCollName.size();
for ( G4int i = 0; i < nCol; i++){
if ( fCollName[i] == fullName ){
return fRunMap[i];
}
}
return NULL;
}
void ML2Run::DumpAllScorer(){
// - Number of HitsMap in this RUN.
G4int n = GetNumberOfHitsMap();
// - GetHitsMap and dump values.
for ( G4int i = 0; i < n ; i++ ){
G4THitsMap<G4double>* runMap =GetHitsMap(i);
if ( runMap ) {
G4cout << " PrimitiveScorer RUN "
<< runMap->GetSDname() <<","<< runMap->GetName() << G4endl;
G4cout << " Number of entries " << runMap->entries() << G4endl;
}
}
}
@@ -41,55 +41,114 @@
//*******************************************************//
#include "G4ios.hh"
#include "ML2RunAction.hh"
#include "ML2Run.hh"
#include "G4THitsMap.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"
CML2RunAction::CML2RunAction(CML2Convergence *conv, G4int nB, G4bool bOV)
CML2RunAction::CML2RunAction(CML2Convergence *conv, G4int nB, G4bool bOV, G4int voxelX, G4int voxelY, G4int voxelZ): fNx(voxelX), fNy(voxelY), fNz(voxelZ)
{
bRotationTranslationFilesNames=true;
convergence=conv;
nBeam=nB;
bOnlyVisio=bOV;
nLoop=0;
bRotationTranslationFileNames = true;
convergence = conv;
nBeam = nB;
bOnlyVisio = bOV;
nLoop = 0;
fSDName.push_back(G4String("PhantomSD"));
}
CML2RunAction::~CML2RunAction(void)
{
fSDName.clear();
}
void CML2RunAction::BeginOfRunAction(const G4Run *)
G4Run* CML2RunAction::GenerateRun()
{
// SUSANNA
// Generate new RUN object, which is specially
// dedicated for MultiFunctionalDetector scheme.
return new ML2Run(fSDName);
}
void CML2RunAction::BeginOfRunAction(const G4Run * aRun)
{
G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl;
G4String fullName;
if (bRotationTranslationFilesNames)
{fullName=CML2AcceleratorConstruction::GetInstance()->getCurrentRotationString()+
CML2PhantomConstruction::GetInstance()->getCurrentTranslationString();}
if (bRotationTranslationFileNames)
{
fullName = CML2AcceleratorConstruction::GetInstance()->getCurrentRotationString()+
CML2PhantomConstruction::GetInstance()->getCurrentTranslationString();
}
else
{fullName="";}
CML2PhantomConstruction::GetInstance()->setNewName(fullName);
{
fullName = "";
}
// CML2PhantomConstruction::GetInstance()->setNewName(fullName);
CML2AcceleratorConstruction::GetInstance()->writeInfo();
CML2PhantomConstruction::GetInstance()->writeInfo();
std::cout<<"*********************************************"<<'\n';
if (convergence->getNMaxLoops()<0 || bOnlyVisio)
G4cout << "*********************************************" << G4endl;
if (convergence -> getNMaxLoops() < 0 || bOnlyVisio)
{
std::cout << "loop n. "<<++nLoop <<'\n';
G4cout << "loop n. " << ++nLoop << G4endl;
G4cout << "Launched " << nBeam << " random primary particles" << G4endl;
}
else
{
std::cout << "loop n. "<<++nLoop<<"/" <<convergence->getNMaxLoops() <<'\n';
G4cout << "loop n. " << ++nLoop << "/" << convergence->getNMaxLoops() << G4endl;
G4cout << "Launched " << nBeam << " random primary particles" << G4endl;
}
if (!bOnlyVisio)
{std::cout << "Launched "<< nBeam <<" random primary particles" << '\n';}
std::cout<<"*********************************************"<<'\n';
{
G4cout <<"Launched " << nBeam << " random primary particles" << G4endl;
}
G4cout<<"*********************************************"<<'\n';
MyTime.Start();
}
void CML2RunAction::EndOfRunAction(const G4Run *)
void CML2RunAction::EndOfRunAction(const G4Run * aRun)
{
CML2WorldConstruction::GetInstance()->savePhantomData();
CML2WorldConstruction::GetInstance()->savePhaseSpaceData();
if(!IsMaster()) return;
ML2Run* ml2Run = (ML2Run*)aRun;
//--- Dump all socred quantities involved in RE02Run.
ml2Run->DumpAllScorer();
//---
//---------------------------------------------
// Dump accumulated quantities for this RUN.
// (Display only central region of x-y plane)
//---------------------------------------------
G4THitsMap<G4double>* totDose = ml2Run->GetHitsMap("PhantomSD/TotalDose");
G4int ix;
G4int iy;
G4int iz;
std::ofstream file("totDose.txt");
for ( iz = 0; iz < fNz; iz++){
for ( iy = 0; iy < fNy; iy++){
for (ix = 0; ix < fNx; ix++){
G4double* TotD = (*totDose)[CopyNo(ix,iy,iz)];
if ( !TotD ) TotD = new G4double(0.0);
if (TotD!=0) file << ix << " "<<iy<<" "<<iz<<" "<< *TotD/gray << G4endl;
}
}
}
file.close();
// CML2WorldConstruction::GetInstance()->savePhantomData();
// CML2WorldConstruction::GetInstance()->savePhaseSpaceData();
convergence->saveResults();
MyTime.Stop();
loopElapsedTime=MyTime.GetUserElapsed();
std::cout << "loop elapsed time [s] : "<< loopElapsedTime << '\n';
std::cout <<'\n';
loopElapsedTime = MyTime.GetUserElapsed();
G4cout << "loop elapsed time [s] : " << loopElapsedTime << '\n' << G4endl;
}
@@ -0,0 +1,68 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2RunAction.hh"
#include "ML2RunActionMessenger.hh"
#include "G4UIcmdWithAString.hh"
#include "G4SystemOfUnits.hh"
CML2RunActionMessenger::CML2RunActionMessenger(CML2RunAction *runAction) : fRunAction(runAction)
{
cmd = new G4UIcmdWithAString("/run/outputName", this);
cmd -> SetDefaultValue("totDose.txt");
cmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
}
CML2RunActionMessenger::~CML2RunActionMessenger()
{
delete cmd;
}
void CML2RunActionMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
// Change the material of the phantom
if( command == cmd )
{ fRunAction -> ChangeOutputFileName(newValue);}
}
@@ -1,194 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2SDWithParticle.hh"
#include "ML2ExpVoxels.hh"
#include "ML2AcceleratorConstruction.hh"
#include "G4SystemOfUnits.hh"
CML2SDWithParticle::CML2SDWithParticle()
: G4VSensitiveDetector("killer_plane"),particles(0)
{
idType=idSD_KillerPlane;
bStopAtPhaseSpace=true;
nTotalParticles=0;
bActive=true;
}
CML2SDWithParticle::CML2SDWithParticle(G4int id, G4int maxPartFile,
G4int seed, G4int nMaxPart, G4String name,
G4String PhaseSpaceOutFile, G4bool bSave, G4bool bStop,
SPrimaryParticle *pData, G4double ZPos)
: G4VSensitiveDetector(name),particles(0)
{
accTargetZPosition=ZPos;
max_N_particles_in_PhSp_File=maxPartFile;
nMaxParticlesInRamPhaseSpace = nMaxPart;
idType=id;
primaryParticleData=pData;
bActive=true;
nParticle=0;
nTotalParticles=0;
bSavePhaseSpace=bSave;
bStopAtPhaseSpace=bStop;
if (bSavePhaseSpace)
{particles=new Sparticle[nMaxPart];}
G4String seedName;
char a[10];
sprintf(a,"%d", seed);
seedName=(G4String)a;
fullOutFileData=PhaseSpaceOutFile+"_"+seedName+".txt";
fullOutFileData=PhaseSpaceOutFile+"_"+seedName+".txt";
}
CML2SDWithParticle::~CML2SDWithParticle()
{
if (particles!=0)
{
delete [] particles;
}
}
void CML2SDWithParticle::saveHeaderParticles()
{
std::ofstream out;
out.open(fullOutFileData, std::ios::out);
out << "Sensitive Detector-Particles"<<G4endl;
out << "n Total Events,\t x [mm],\t y [mm],\t z [mm],\t dirX,\t dirY,\t dirZ,\t KinEnergy [MeV],\t part Type,\t primary part type,\t nPrimaryPart" << G4endl;
out.close();
}
void CML2SDWithParticle::saveDataParticles(G4int nPart)
{
std::ofstream out;
out.open(fullOutFileData, std::ios::app);
static G4int nTotParticles=0;
for (int i=0; i< nPart; i++)
{
out << nTotParticles++ << '\t';
// out << particles[i].volumeName << '\t';
out << particles[i].pos.getX()/mm << '\t';
out << particles[i].pos.getY()/mm << '\t';
out << (accTargetZPosition + particles[i].pos.getZ())/mm << '\t'; // it translates the current z value in global coordinates to the accelerator local coordinates (only z)
out << particles[i].dir.getX() << '\t';
out << particles[i].dir.getY() << '\t';
out << particles[i].dir.getZ() << '\t';
out << particles[i].kinEnergy/MeV << '\t';
out << particles[i].partPDGE<< '\t';
out << particles[i].primaryParticlePDGE<< '\t';
out << particles[i].nPrimaryPart<< G4endl;
}
out.close();
}
G4bool CML2SDWithParticle::ProcessHits(G4Step *aStep, G4TouchableHistory *)
{
if (bActive && (CML2AcceleratorConstruction::GetInstance()->getPhysicalVolume()->GetRotation()->isIdentity()))
{
G4double energyKin= aStep->GetTrack()->GetKineticEnergy();
static bool bFirstTime=true;
if (idType==idSD_KillerPlane)
{
nTotalParticles++;
aStep->GetTrack()->SetTrackStatus(fStopAndKill);
}
else
{
if (energyKin>0.)
{
particles[nParticle].volumeName="";
particles[nParticle].pos=aStep->GetPreStepPoint()->GetPosition();
particles[nParticle].dir=aStep->GetPreStepPoint()->GetMomentumDirection();
particles[nParticle].kinEnergy=energyKin;
particles[nParticle].partPDGE=aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
particles[nParticle].primaryParticlePDGE=primaryParticleData->partPDGE;
particles[nParticle].nPrimaryPart=primaryParticleData->nPrimaryParticle;
nParticle++;
nTotalParticles++;
if (nTotalParticles==max_N_particles_in_PhSp_File)
{
if (bFirstTime)
{
bFirstTime=false;
saveHeaderParticles();
}
saveDataParticles(nParticle);
nParticle=0;
bActive =false;// to stop the phase space creation
}
if (nParticle==nMaxParticlesInRamPhaseSpace)
{
if (bFirstTime)
{
bFirstTime=false;
saveHeaderParticles();
}
saveDataParticles(nParticle);
nParticle=0;
}
Sparticle *particle=new Sparticle;
particle->dir=aStep->GetPreStepPoint()->GetMomentumDirection();
particle->pos=aStep->GetPreStepPoint()->GetPosition();
particle->kinEnergy=energyKin;
particle->nPrimaryPart=nTotalParticles; // to pass the id of this phase space particle
particle->partPDGE=aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
particle->primaryParticlePDGE=primaryParticleData->partPDGE;
particle->volumeId=-1;
particle->volumeName="-1";
}
if (bStopAtPhaseSpace)
{aStep->GetTrack()->SetTrackStatus(fStopAndKill);}
}
}
else
{
if (bStopAtPhaseSpace)
{aStep->GetTrack()->SetTrackStatus(fStopAndKill);}
}
return true;
}
void CML2SDWithParticle::save()
{
if ((bActive) && (nParticle>0) && (CML2AcceleratorConstruction::GetInstance()->getPhysicalVolume()->GetRotation()->isIdentity()))
{saveDataParticles(nParticle);nParticle=0;}
}
@@ -1,295 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// The code was written by :
// ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
// *Barbara Caccia barbara.caccia@iss.it
// with the support of Pablo Cirrone (LNS, INFN Catania Italy)
// with the contribute of Alessandro Occhigrossi*
//
// ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
// *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
// Viale Regina Elena 299, 00161 Roma (Italy)
// tel (39) 06 49902246
// fax (39) 06 49387075
//
// more information:
// http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
//
//*******************************************************//
#include "ML2SDWithVoxels.hh"
#include "ML2ExpVoxels.hh"
#include "G4SystemOfUnits.hh"
// *************************************************************************************
CML2SDWithVoxels::CML2SDWithVoxels(G4String name, G4int voxSave,
G4int seed, G4String ROGOutFile,
G4bool bROG, G4ThreeVector ctr, G4ThreeVector hSiz,
G4int NumVX, G4int NumVY, G4int NumVZ)
: G4VSensitiveDetector(name),voxelsSum(0), voxelsSingle(0)
{
saving_in_ROG_Voxels_every_events=voxSave;
bSaveROG=bROG;
bActive=true;
nParticle=0;
nParticleValatile=0;
nTotalEvents=0;
nSingleTotalEvents=0;
density=1.;
voxelVolume=0.;
voxelMass=0.;
nRecycling=1;
G4String seedName;
char a[10];
sprintf(a,"%d", seed);
seedName=(G4String)a;
fullOutFileData=ROGOutFile+"_"+seedName+".txt";
fullOutFileDataSingle="";
if(bSaveROG)
{
centre=ctr;
halfSize=hSiz;
NumberOfVoxelsAlongX=NumVX;
NumberOfVoxelsAlongY=NumVY;
NumberOfVoxelsAlongZ=NumVZ;
halfXVoxelDimensionX=halfSize.getX()/NumberOfVoxelsAlongX;
halfXVoxelDimensionY=halfSize.getY()/NumberOfVoxelsAlongY;
halfXVoxelDimensionZ=halfSize.getZ()/NumberOfVoxelsAlongZ;
voxelVolume=halfXVoxelDimensionX*halfXVoxelDimensionY*halfXVoxelDimensionZ*8.;
// voxels to store and save the sum of the geometry configurations
voxelsSum=new Svoxel**[NumberOfVoxelsAlongX];
for (int ix=0; ix< NumberOfVoxelsAlongX; ix++)
{
voxelsSum[ix]=new Svoxel*[NumberOfVoxelsAlongY];
for (int iy=0; iy< NumberOfVoxelsAlongY; iy++)
{
voxelsSum[ix][iy]=new Svoxel[NumberOfVoxelsAlongZ];
for (int iz=0; iz< NumberOfVoxelsAlongZ; iz++)
{
voxelsSum[ix][iy][iz].volumeId=-1;
voxelsSum[ix][iy][iz].depEnergy=0.;
voxelsSum[ix][iy][iz].depEnergy2=0.;
voxelsSum[ix][iy][iz].depEnergyNorm=0.;
voxelsSum[ix][iy][iz].depEnergyNormError=0.;
voxelsSum[ix][iy][iz].expDose=0.;
voxelsSum[ix][iy][iz].halfSize.set(halfXVoxelDimensionX, halfXVoxelDimensionY, halfXVoxelDimensionZ);
voxelsSum[ix][iy][iz].pos.set(2.*(ix)*halfXVoxelDimensionX -halfSize.getX()+halfXVoxelDimensionX + centre.getX(),
2.*(iy)*halfXVoxelDimensionY -halfSize.getY()+halfXVoxelDimensionY + centre.getY(),
2.*(iz)*halfXVoxelDimensionZ -halfSize.getZ()+halfXVoxelDimensionZ + centre.getZ());
voxelsSum[ix][iy][iz].nEvents=0;
}
}
}
// voxels to store and save the single geometry configuration
voxelsSingle=new Svoxel**[NumberOfVoxelsAlongX];
for (int ix=0; ix< NumberOfVoxelsAlongX; ix++)
{
voxelsSingle[ix]=new Svoxel*[NumberOfVoxelsAlongY];
for (int iy=0; iy< NumberOfVoxelsAlongY; iy++)
{
voxelsSingle[ix][iy]=new Svoxel[NumberOfVoxelsAlongZ];
for (int iz=0; iz< NumberOfVoxelsAlongZ; iz++)
{
voxelsSingle[ix][iy][iz].volumeId=-1;
voxelsSingle[ix][iy][iz].depEnergy=0.;
voxelsSingle[ix][iy][iz].depEnergy2=0.;
voxelsSingle[ix][iy][iz].depEnergyNorm=0.;
voxelsSingle[ix][iy][iz].depEnergyNormError=0.;
voxelsSingle[ix][iy][iz].expDose=0.;
voxelsSingle[ix][iy][iz].halfSize.set(halfXVoxelDimensionX, halfXVoxelDimensionY, halfXVoxelDimensionZ);
voxelsSingle[ix][iy][iz].pos.set(2.*(ix)*halfXVoxelDimensionX -halfSize.getX()+halfXVoxelDimensionX + centre.getX(),
2.*(iy)*halfXVoxelDimensionY -halfSize.getY()+halfXVoxelDimensionY + centre.getY(),
2.*(iz)*halfXVoxelDimensionZ -halfSize.getZ()+halfXVoxelDimensionZ + centre.getZ());
voxelsSingle[ix][iy][iz].nEvents=0;
}
}
}
}
}
CML2SDWithVoxels::~CML2SDWithVoxels()
{
if(bSaveROG)
{
delete [] voxelsSum;
delete [] voxelsSingle;
}
}
void CML2SDWithVoxels::resetVoxelsSingle()
{
for (int ix=0; ix< NumberOfVoxelsAlongX; ix++)
{
for (int iy=0; iy< NumberOfVoxelsAlongY; iy++)
{
for (int iz=0; iz< NumberOfVoxelsAlongZ; iz++)
{
voxelsSingle[ix][iy][iz].volumeId=-1;
voxelsSingle[ix][iy][iz].depEnergy=0.;
voxelsSingle[ix][iy][iz].depEnergy2=0.;
voxelsSingle[ix][iy][iz].depEnergyNorm=0.;
voxelsSingle[ix][iy][iz].depEnergyNormError=0.;
voxelsSingle[ix][iy][iz].expDose=0.;
voxelsSingle[ix][iy][iz].halfSize.set(halfXVoxelDimensionX, halfXVoxelDimensionY, halfXVoxelDimensionZ);
voxelsSingle[ix][iy][iz].pos.set(2.*(ix)*halfXVoxelDimensionX -halfSize.getX()+halfXVoxelDimensionX + centre.getX(),
2.*(iy)*halfXVoxelDimensionY -halfSize.getY()+halfXVoxelDimensionY + centre.getY(),
2.*(iz)*halfXVoxelDimensionZ -halfSize.getZ()+halfXVoxelDimensionZ + centre.getZ());
voxelsSingle[ix][iy][iz].nEvents=0;
}
}
}
nSingleTotalEvents=0;
}
G4bool CML2SDWithVoxels::ProcessHits(G4Step *aStep, G4TouchableHistory *ROHist)
{
if (bActive)
{
G4double energyDep = aStep->GetTotalEnergyDeposit();
if (bSaveROG && energyDep>0.)
{
G4int ix, iy, iz;
G4String volumeName;
ix=ROHist->GetReplicaNumber(2);
iy=ROHist->GetReplicaNumber(0);
iz=ROHist->GetReplicaNumber(1);
density=aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial()->GetDensity();
voxelMass=voxelVolume*density;
energyDep/=voxelMass*nRecycling;
voxelsSum[ix][iy][iz].volumeId=getIdFromVolumeName(aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial()->GetName());
voxelsSum[ix][iy][iz].depEnergy+=energyDep;
voxelsSum[ix][iy][iz].depEnergy2+=energyDep*energyDep;
voxelsSum[ix][iy][iz].nEvents++;
voxelsSingle[ix][iy][iz].volumeId=getIdFromVolumeName(aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial()->GetName());
voxelsSingle[ix][iy][iz].depEnergy+=energyDep;
voxelsSingle[ix][iy][iz].depEnergy2+=energyDep*energyDep;
voxelsSingle[ix][iy][iz].nEvents++;
nTotalEvents++;
nSingleTotalEvents++;
if (nTotalEvents%saving_in_ROG_Voxels_every_events==0 && nTotalEvents>0)
{
save();
}
}
}
return true;
}
G4int CML2SDWithVoxels::getIdFromVolumeName(G4String name)
{
for (int i=0; i<(int)volumeNameIdLink.size(); i++)
{
if (volumeNameIdLink[i].volumeName==name)
{
return volumeNameIdLink[i].volumeId;
break;
}
}
return -1;
}
void CML2SDWithVoxels::save()
{
std::cout<< "n. of events collected in the whole ROG phantom for all geometries: "<< nTotalEvents<< G4endl;
std::cout<< "n. of events collected in the whole ROG phantom for the current geometry: "<< nSingleTotalEvents<< G4endl;
if (nTotalEvents>0)
{saveData(fullOutFileData, voxelsSum);}
if (nSingleTotalEvents>0)
{saveData(fullOutFileDataSingle, voxelsSingle);}
}
void CML2SDWithVoxels::saveData(G4String Filename, Svoxel ***voxels)
{
std::ofstream out;
out.open(Filename, std::ios::out);
out << "Sensitive Detector-Voxels. Total number of events, [mm]->centreX centreY centreZ HalfSizeX HalfSizeY HalfSizeZ minX maxX, minY maxY, minZ maxZ, Dx, Dy, Dz, nX, nY, nZ: \n";
out <<nTotalEvents<<'\t';
out <<centre.getX()/mm << '\t' << centre.getY()/mm<< '\t'<< centre.getZ()/mm<<'\t';
out <<halfSize.getX()/mm << '\t' << halfSize.getY()/mm <<'\t'<< halfSize.getZ()/mm<<'\t';
out <<(centre.getX()-halfSize.getX())/mm<<'\t'<<(centre.getX()+halfSize.getX())/mm<<'\t';
out <<(centre.getY()-halfSize.getY())/mm<<'\t'<<(centre.getY()+halfSize.getY())/mm<<'\t';
out <<(centre.getZ()-halfSize.getZ())/mm<<'\t'<<(centre.getZ()+halfSize.getZ())/mm<<'\t';
out <<halfXVoxelDimensionX/mm<<'\t'<<halfXVoxelDimensionY/mm<<'\t'<<halfXVoxelDimensionZ/mm<<'\t';
out <<NumberOfVoxelsAlongX <<'\t'<<NumberOfVoxelsAlongY <<'\t'<<NumberOfVoxelsAlongZ <<'\n';
out << "Number of physical volumes: "<< volumeNameIdLink.size() << '\n';
for (int i=0; i<(int)volumeNameIdLink.size(); i++)
{
out << volumeNameIdLink[i].volumeName <<'\t'<< volumeNameIdLink[i].volumeId << G4endl;
}
out << "Phys Volume x [mm], y [mm], z [mm], ix, iy, iz, Dose [Gy], Dose2 [Gy^2], nEvents" << G4endl;
for (int ix=0; ix< NumberOfVoxelsAlongX; ix++)
{
for (int iy=0; iy< NumberOfVoxelsAlongY; iy++)
{
for (int iz=0; iz< NumberOfVoxelsAlongZ; iz++)
{
if (voxels[ix][iy][iz].nEvents>0)
{
out << voxels[ix][iy][iz].volumeId << '\t';
out << voxels[ix][iy][iz].pos.getX()/mm << '\t';
out << voxels[ix][iy][iz].pos.getY()/mm << '\t';
out << voxels[ix][iy][iz].pos.getZ()/mm << '\t';
out << ix << '\t';
out << iy << '\t';
out << iz << '\t';
out << voxels[ix][iy][iz].depEnergy/(joule/kg) << '\t';
out << voxels[ix][iy][iz].depEnergy2/((joule/kg)*(joule/kg)) << '\t';
out << voxels[ix][iy][iz].nEvents << G4endl;
}
}
}
}
out.close();
}
void CML2SDWithVoxels::setFullOutFileDataSingle(G4String val)
{
unsigned int ind = fullOutFileData.find(".txt");
G4String onlyName=fullOutFileData.substr( 0, ind);
if (val=="")
{
static unsigned int indGeom=0;
char cT[5];
sprintf(cT,"%d",indGeom);
fullOutFileDataSingle=onlyName+"Single_"+G4String(cT)+".txt";
indGeom++;
}
else
{
fullOutFileDataSingle=onlyName+val+".txt";
}
}
@@ -47,8 +47,6 @@
#include "G4VSensitiveDetector.hh"
#include "G4TouchableHistory.hh"
#include "G4VReadOutGeometry.hh"
CML2SteppingAction::CML2SteppingAction(CML2Convergence *conv)
{
convergence=conv;
@@ -40,21 +40,20 @@
//
//*******************************************************//
#include "ML2WorldConstruction.hh"
#include "G4SystemOfUnits.hh"
CML2WorldConstruction::CML2WorldConstruction():acceleratorEnv(0),phantomEnv(0),PVWorld(0),phaseSpace(0),backScatteredPlane(0)
{
phantomEnv=CML2PhantomConstruction::GetInstance();
acceleratorEnv=CML2AcceleratorConstruction::GetInstance();
bWorldCreated=false;
phantomEnv = CML2PhantomConstruction::GetInstance();
acceleratorEnv = CML2AcceleratorConstruction::GetInstance();
bWorldCreated = false;
bOnlyVisio = 0;
}
CML2WorldConstruction::~CML2WorldConstruction(void)
{
delete PVWorld;
delete phantomEnv;
delete acceleratorEnv;
delete phaseSpace;
delete backScatteredPlane;
}
@@ -78,51 +77,74 @@ G4VPhysicalVolume* CML2WorldConstruction::Construct()
bool CML2WorldConstruction::create(SInputData *inputData, bool bOV)
{
// create the world box
bOnlyVisio=bOV;
G4double halfSize=3000.*mm;
G4Material *Vacuum=G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
bOnlyVisio = bOV;
G4double halfSize = 3000.*mm;
G4Material *Vacuum = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4Box *worldB = new G4Box("worldG", halfSize, halfSize, halfSize);
G4LogicalVolume *worldLV = new G4LogicalVolume(worldB, Vacuum, "worldL", 0, 0, 0);
G4VisAttributes* simpleWorldVisAtt= new G4VisAttributes(G4Colour::Black());
simpleWorldVisAtt->SetVisibility(false);
// simpleWorldVisAtt->SetForceSolid(false);
worldLV->SetVisAttributes(simpleWorldVisAtt);
PVWorld= new G4PVPlacement(0, G4ThreeVector(0.,0.,0.), "worldPV", worldLV, 0, false, 0);
G4VisAttributes* simpleWorldVisAtt = new G4VisAttributes(G4Colour::Black());
simpleWorldVisAtt -> SetVisibility(true);
worldLV -> SetVisAttributes(simpleWorldVisAtt);
PVWorld = new G4PVPlacement(0, G4ThreeVector(0.,0.,0.), "worldPV", worldLV, 0, false, 0);
// create the accelerator-world box
if (!acceleratorEnv->Construct(PVWorld, bOV))
if (!acceleratorEnv -> Construct(PVWorld, bOV))
{
std::cout <<"\n\n The macro file '"<<inputData->generalData.StartFileInputData<<"' refers to a not defined accelerator.\n"<< acceleratorEnv->getAcceleratorName()<<"\n\nSTOP\n\n" << G4endl;
G4cout << "\n\n The macro file '" << inputData->generalData.StartFileInputData <<
"' refers to a not defined accelerator.\n" << acceleratorEnv->getAcceleratorName() <<
"\n\nSTOP\n\n" << G4endl;
return false;
}
// create the phantom-world box
if (!phantomEnv->Construct(PVWorld, inputData->generalData.saving_in_ROG_Voxels_every_events, inputData->generalData.seed, inputData->generalData.ROGOutFile, inputData->generalData.bSaveROG, bOV))
if ( !phantomEnv->Construct(PVWorld,
inputData->voxelSegmentation.nX,
inputData->voxelSegmentation.nY,
inputData->voxelSegmentation.nZ,
bOV) )
{
std::cout <<"\n\n The macro file '"<<inputData->generalData.StartFileInputData<<"' refers to a not defined phantom.\n"<< phantomEnv->getPhantomName()<<"\n\nSTOP\n\n" << G4endl;
G4cout << "\n\n The macro file '" << inputData->generalData.StartFileInputData <<
"' refers to a not defined phantom.\n" << phantomEnv->getPhantomName() <<
"\n\nSTOP\n\n" << G4endl;
return false;
}
// if the bSavePhaseSpace flag is true create a phase plane
if (inputData->generalData.bSavePhaseSpace)
/*
if (inputData -> generalData.bSavePhaseSpace)
{
phaseSpace=new CML2PhaseSpaces();
if (inputData->generalData.bForcePhaseSpaceBeforeJaws)
{inputData->generalData.centrePhaseSpace.setZ(acceleratorEnv->getZ_Value_PhaseSpaceBeforeJaws());}
phaseSpace->createPlane(idSD_PhaseSpace, inputData->generalData.max_N_particles_in_PhSp_File, inputData->generalData.seed, inputData->generalData.nMaxParticlesInRamPlanePhaseSpace, acceleratorEnv->getPhysicalVolume(), "PhSp", inputData->generalData.PhaseSpaceOutFile, inputData->generalData.bSavePhaseSpace, inputData->generalData.bStopAtPhaseSpace, inputData->generalData.centrePhaseSpace, inputData->generalData.halfSizePhaseSpace,&inputData->primaryParticleData, acceleratorEnv->getAcceleratorIsoCentre());
phaseSpace = new CML2PhaseSpaces();
if (inputData -> generalData.bForcePhaseSpaceBeforeJaws)
{
inputData -> generalData.centrePhaseSpace.setZ(acceleratorEnv->getZ_Value_PhaseSpaceBeforeJaws());
}
phaseSpace -> createPlane(idSD_PhaseSpace,
inputData->generalData.max_N_particles_in_PhSp_File,
inputData->generalData.seed,
inputData->generalData.nMaxParticlesInRamPlanePhaseSpace,
acceleratorEnv->getPhysicalVolume(), "PhSp",
inputData->generalData.PhaseSpaceOutFile,
inputData->generalData.bSavePhaseSpace,
inputData->generalData.bStopAtPhaseSpace,
inputData->generalData.centrePhaseSpace,
inputData->generalData.halfSizePhaseSpace,
&inputData->primaryParticleData,
acceleratorEnv->getAcceleratorIsoCentre()); // phase space plane, yellow
}
// create a killer plane to destroy the particles back scattered from the target
backScatteredPlane=new CML2PhaseSpaces();
backScatteredPlane->createPlane(acceleratorEnv->getPhysicalVolume(), "killerPlane", G4ThreeVector(0, 0, -50*mm), G4ThreeVector(200*mm, 200*mm, 1*mm));
bWorldCreated=true;
return true;
backScatteredPlane = new CML2PhaseSpaces();
backScatteredPlane -> createPlane(acceleratorEnv->getPhysicalVolume(),
"killerPlane", G4ThreeVector(0, 0, -50*mm), G4ThreeVector(200*mm, 200*mm, 1*mm)); // killer plane, cyan
*/
bWorldCreated = true;
return bWorldCreated;
}
void CML2WorldConstruction::checkVolumeOverlap()
{
// loop inside all the daughters volumes
std::cout<< G4endl;
G4cout<< G4endl;
// bool bCheckOverlap;
// bCheckOverlap=false;
@@ -141,21 +163,26 @@ void CML2WorldConstruction::checkVolumeOverlap()
}
}
}
std::cout<< G4endl;
G4cout<< G4endl;
}
bool CML2WorldConstruction::newGeometry()
{
G4bool bNewRotation=false;
G4bool bNewCentre=false;
G4bool bNewGeometry=false;
bNewCentre=phantomEnv->applyNewCentre();
G4RotationMatrix *rmInv=acceleratorEnv->rotateAccelerator();
G4bool bNewRotation = false;
G4bool bNewCentre = false;
G4bool bNewGeometry = false;
bNewCentre = phantomEnv -> applyNewCentre();
G4RotationMatrix *rmInv = acceleratorEnv -> rotateAccelerator();
if (rmInv!=0)
{
CML2PrimaryGenerationAction::GetInstance()->setRotation(rmInv);
bNewRotation=true;
bNewRotation = true;
}
if (bNewRotation || bNewCentre){bNewGeometry=true;}
if (bNewRotation || bNewCentre)
{
bNewGeometry = true;
}
return bNewGeometry;
}