Import Geant4 11.3.0.beta source tree
This commit is contained in:
@@ -24,14 +24,13 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03ActionInitialisation.hh"
|
||||
#include "Par03PrimaryGeneratorAction.hh"
|
||||
|
||||
#include "Par03EventAction.hh"
|
||||
#include "Par03PrimaryGeneratorAction.hh"
|
||||
#include "Par03RunAction.hh"
|
||||
|
||||
Par03ActionInitialisation::Par03ActionInitialisation(
|
||||
Par03DetectorConstruction* aDetector)
|
||||
: G4VUserActionInitialization()
|
||||
, fDetector(aDetector)
|
||||
Par03ActionInitialisation::Par03ActionInitialisation(Par03DetectorConstruction* aDetector)
|
||||
: G4VUserActionInitialization(), fDetector(aDetector)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -24,36 +24,33 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03DetectorConstruction.hh"
|
||||
#include "Par03DetectorMessenger.hh"
|
||||
#include "Par03SensitiveDetector.hh"
|
||||
#include "Par03EMShowerModel.hh"
|
||||
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "Par03DetectorMessenger.hh"
|
||||
#include "Par03EMShowerModel.hh"
|
||||
#include "Par03SensitiveDetector.hh"
|
||||
|
||||
#include "G4Box.hh"
|
||||
#include "G4Tubs.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4PVPlacement.hh"
|
||||
#include "G4PVReplica.hh"
|
||||
#include "G4VisAttributes.hh"
|
||||
#include "G4RunManager.hh"
|
||||
|
||||
#include "G4SDManager.hh"
|
||||
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
#include "G4Region.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4Tubs.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4VisAttributes.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Par03DetectorConstruction::Par03DetectorConstruction()
|
||||
: G4VUserDetectorConstruction()
|
||||
Par03DetectorConstruction::Par03DetectorConstruction() : G4VUserDetectorConstruction()
|
||||
{
|
||||
fDetectorMessenger = new Par03DetectorMessenger(this);
|
||||
|
||||
G4NistManager* nistManager = G4NistManager::Instance();
|
||||
fDetectorMaterial = nistManager->FindOrBuildMaterial("G4_Fe");
|
||||
fDetectorMaterial = nistManager->FindOrBuildMaterial("G4_Fe");
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -66,51 +63,50 @@ G4VPhysicalVolume* Par03DetectorConstruction::Construct()
|
||||
{
|
||||
//--------- Material definition ---------
|
||||
G4NistManager* nistManager = G4NistManager::Instance();
|
||||
G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR");
|
||||
G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR");
|
||||
|
||||
//--------- Derived dimensions ---------
|
||||
G4double full2Pi = 2. * CLHEP::pi * rad;
|
||||
G4double full2Pi = 2. * CLHEP::pi * rad;
|
||||
G4double layerThickness = fDetectorLength / fNbOfLayers;
|
||||
G4double cellPhi = full2Pi / fNbOfPhiCells;
|
||||
G4double cellDR = fDetectorRadius / fNbOfRhoCells;
|
||||
G4double cellPhi = full2Pi / fNbOfPhiCells;
|
||||
G4double cellDR = fDetectorRadius / fNbOfRhoCells;
|
||||
|
||||
//--------- World ---------
|
||||
auto fSolidWorld = new G4Box("World", // name
|
||||
fWorldSize / 2., // half-width in X
|
||||
fWorldSize / 2., // half-width in Y
|
||||
fWorldSize / 2.); // half-width in Z
|
||||
auto fLogicWorld = new G4LogicalVolume(fSolidWorld, // solid
|
||||
air, // material
|
||||
"World"); // name
|
||||
auto fPhysicWorld = new G4PVPlacement(0, // no rotation
|
||||
auto fSolidWorld = new G4Box("World", // name
|
||||
fWorldSize / 2., // half-width in X
|
||||
fWorldSize / 2., // half-width in Y
|
||||
fWorldSize / 2.); // half-width in Z
|
||||
auto fLogicWorld = new G4LogicalVolume(fSolidWorld, // solid
|
||||
air, // material
|
||||
"World"); // name
|
||||
auto fPhysicWorld = new G4PVPlacement(0, // no rotation
|
||||
G4ThreeVector(), // at (0,0,0)
|
||||
fLogicWorld, // logical volume
|
||||
"World", // name
|
||||
0, // mother volume
|
||||
false, // not used
|
||||
999, // copy number
|
||||
true); // copy number
|
||||
fLogicWorld, // logical volume
|
||||
"World", // name
|
||||
0, // mother volume
|
||||
false, // not used
|
||||
999, // copy number
|
||||
true); // copy number
|
||||
|
||||
//--------- Detector envelope ---------
|
||||
auto fSolidDetector = new G4Tubs("Detector", // name
|
||||
0, // inner radius
|
||||
fDetectorRadius, // outer radius
|
||||
fDetectorLength / 2., // half-width in Z
|
||||
0, // start angle
|
||||
full2Pi); // delta angle
|
||||
auto fSolidDetector = new G4Tubs("Detector", // name
|
||||
0, // inner radius
|
||||
fDetectorRadius, // outer radius
|
||||
fDetectorLength / 2., // half-width in Z
|
||||
0, // start angle
|
||||
full2Pi); // delta angle
|
||||
auto fLogicDetector = new G4LogicalVolume(fSolidDetector, // solid
|
||||
fDetectorMaterial, // material
|
||||
"Detector"); // name
|
||||
new G4PVPlacement(
|
||||
0, // no rotation
|
||||
G4ThreeVector(0, 0,
|
||||
fDetectorLength / 2), // detector face starts at (0,0,0)
|
||||
fLogicDetector, // logical volume
|
||||
"Detector", // name
|
||||
fLogicWorld, // mother volume
|
||||
false, // not used
|
||||
99, // copy number
|
||||
true); // check overlaps
|
||||
"Detector"); // name
|
||||
new G4PVPlacement(0, // no rotation
|
||||
G4ThreeVector(0, 0,
|
||||
fDetectorLength / 2), // detector face starts at (0,0,0)
|
||||
fLogicDetector, // logical volume
|
||||
"Detector", // name
|
||||
fLogicWorld, // mother volume
|
||||
false, // not used
|
||||
99, // copy number
|
||||
true); // check overlaps
|
||||
|
||||
// Region for fast simulation
|
||||
auto detectorRegion = new G4Region("DetectorRegion");
|
||||
@@ -118,88 +114,88 @@ G4VPhysicalVolume* Par03DetectorConstruction::Construct()
|
||||
|
||||
//--------- Readout geometry ---------
|
||||
// Layers (along z)
|
||||
auto fSolidLayer = new G4Tubs("Layer", // name
|
||||
0, // inner radius
|
||||
fDetectorRadius, // outer radius
|
||||
layerThickness / 2., // half-width in Z
|
||||
0, // start angle
|
||||
full2Pi); // delta angle
|
||||
auto fSolidLayer = new G4Tubs("Layer", // name
|
||||
0, // inner radius
|
||||
fDetectorRadius, // outer radius
|
||||
layerThickness / 2., // half-width in Z
|
||||
0, // start angle
|
||||
full2Pi); // delta angle
|
||||
auto fLogicLayer = new G4LogicalVolume(fSolidLayer, // solid
|
||||
air, // material
|
||||
"Layer"); // name
|
||||
if(fNbOfLayers > 1)
|
||||
new G4PVReplica("Layer", // name
|
||||
fLogicLayer, // logical volume
|
||||
fLogicDetector, // mother volume
|
||||
kZAxis, // axis of replication
|
||||
fNbOfLayers, // number of replicas
|
||||
air, // material
|
||||
"Layer"); // name
|
||||
if (fNbOfLayers > 1)
|
||||
new G4PVReplica("Layer", // name
|
||||
fLogicLayer, // logical volume
|
||||
fLogicDetector, // mother volume
|
||||
kZAxis, // axis of replication
|
||||
fNbOfLayers, // number of replicas
|
||||
layerThickness); // width of single replica
|
||||
else
|
||||
new G4PVPlacement(0, // no rotation
|
||||
new G4PVPlacement(0, // no rotation
|
||||
G4ThreeVector(), // place at centre of mother volume
|
||||
fLogicLayer, // logical volume
|
||||
"Layer", // name
|
||||
fLogicDetector, // mother volume
|
||||
false, // not used
|
||||
0, // copy number
|
||||
true); // check overlaps
|
||||
fLogicLayer, // logical volume
|
||||
"Layer", // name
|
||||
fLogicDetector, // mother volume
|
||||
false, // not used
|
||||
0, // copy number
|
||||
true); // check overlaps
|
||||
|
||||
// Layer segment (division in phi)
|
||||
auto fSolidRow = new G4Tubs("Row", // name
|
||||
0, // inner radius
|
||||
fDetectorRadius, // outer radius
|
||||
auto fSolidRow = new G4Tubs("Row", // name
|
||||
0, // inner radius
|
||||
fDetectorRadius, // outer radius
|
||||
layerThickness / 2., // half-width in Z
|
||||
0, // start angle
|
||||
cellPhi); // delta angle
|
||||
0, // start angle
|
||||
cellPhi); // delta angle
|
||||
|
||||
auto fLogicRow = new G4LogicalVolume(fSolidRow, // solid
|
||||
air, // material
|
||||
auto fLogicRow = new G4LogicalVolume(fSolidRow, // solid
|
||||
air, // material
|
||||
"Segment"); // name
|
||||
if(fNbOfPhiCells > 1)
|
||||
new G4PVReplica("Segment", // name
|
||||
fLogicRow, // logical volume
|
||||
fLogicLayer, // mother volume
|
||||
kPhi, // axis of replication
|
||||
if (fNbOfPhiCells > 1)
|
||||
new G4PVReplica("Segment", // name
|
||||
fLogicRow, // logical volume
|
||||
fLogicLayer, // mother volume
|
||||
kPhi, // axis of replication
|
||||
fNbOfPhiCells, // number of replicas
|
||||
cellPhi); // width of single replica
|
||||
cellPhi); // width of single replica
|
||||
else
|
||||
new G4PVPlacement(0, // no rotation
|
||||
new G4PVPlacement(0, // no rotation
|
||||
G4ThreeVector(), // place at centre of mother volume
|
||||
fLogicRow, // logical volume
|
||||
"Row", // name
|
||||
fLogicLayer, // mother volume
|
||||
false, // not used
|
||||
0, // copy number
|
||||
true); // check overlaps
|
||||
fLogicRow, // logical volume
|
||||
"Row", // name
|
||||
fLogicLayer, // mother volume
|
||||
false, // not used
|
||||
0, // copy number
|
||||
true); // check overlaps
|
||||
|
||||
// Final cells (segment slices in radius)
|
||||
// No volume can be placed inside a radial replication
|
||||
auto fSolidCell = new G4Tubs("Cell", // name
|
||||
0, // inner radius
|
||||
cellDR, // outer radius
|
||||
auto fSolidCell = new G4Tubs("Cell", // name
|
||||
0, // inner radius
|
||||
cellDR, // outer radius
|
||||
layerThickness / 2., // half-width in Z
|
||||
0, // start angle
|
||||
cellPhi); // delta angle
|
||||
0, // start angle
|
||||
cellPhi); // delta angle
|
||||
|
||||
fLogicCell = new G4LogicalVolume(fSolidCell, // solid
|
||||
fLogicCell = new G4LogicalVolume(fSolidCell, // solid
|
||||
fDetectorMaterial, // material
|
||||
"Cell"); // name
|
||||
if(fNbOfRhoCells > 1)
|
||||
new G4PVReplica("Cell", // name
|
||||
fLogicCell, // logical volume
|
||||
fLogicRow, // mother volume
|
||||
kRho, // axis of replication
|
||||
"Cell"); // name
|
||||
if (fNbOfRhoCells > 1)
|
||||
new G4PVReplica("Cell", // name
|
||||
fLogicCell, // logical volume
|
||||
fLogicRow, // mother volume
|
||||
kRho, // axis of replication
|
||||
fNbOfRhoCells, // number of replicas
|
||||
cellDR); // width of single replica
|
||||
cellDR); // width of single replica
|
||||
else
|
||||
new G4PVPlacement(0, // no rotation
|
||||
new G4PVPlacement(0, // no rotation
|
||||
G4ThreeVector(), // place at centre of mother volume
|
||||
fLogicCell, // logical volume
|
||||
"Cell", // name
|
||||
fLogicRow, // mother volume
|
||||
false, // not used
|
||||
0, // copy number
|
||||
true); // check overlaps
|
||||
fLogicCell, // logical volume
|
||||
"Cell", // name
|
||||
fLogicRow, // mother volume
|
||||
false, // not used
|
||||
0, // copy number
|
||||
true); // check overlaps
|
||||
|
||||
//--------- Visualisation settings ---------
|
||||
fLogicWorld->SetVisAttributes(G4VisAttributes::GetInvisible());
|
||||
@@ -218,13 +214,12 @@ G4VPhysicalVolume* Par03DetectorConstruction::Construct()
|
||||
|
||||
void Par03DetectorConstruction::ConstructSDandField()
|
||||
{
|
||||
Par03SensitiveDetector* caloSD = new Par03SensitiveDetector(
|
||||
"sensitiveDetector", fNbOfLayers, fNbOfPhiCells, fNbOfRhoCells);
|
||||
Par03SensitiveDetector* caloSD =
|
||||
new Par03SensitiveDetector("sensitiveDetector", fNbOfLayers, fNbOfPhiCells, fNbOfRhoCells);
|
||||
G4SDManager::GetSDMpointer()->AddNewDetector(caloSD);
|
||||
SetSensitiveDetector(fLogicCell, caloSD);
|
||||
|
||||
auto detectorRegion =
|
||||
G4RegionStore::GetInstance()->GetRegion("DetectorRegion");
|
||||
auto detectorRegion = G4RegionStore::GetInstance()->GetRegion("DetectorRegion");
|
||||
new Par03EMShowerModel("model", detectorRegion);
|
||||
}
|
||||
|
||||
@@ -236,9 +231,8 @@ void Par03DetectorConstruction::Print() const
|
||||
<< "\n--- Detector material:\t" << fDetectorMaterial->GetName()
|
||||
<< "\n--- Detector length:\t" << G4BestUnit(fDetectorLength, "Length")
|
||||
<< "\n--- Detector radius:\t" << G4BestUnit(fDetectorRadius, "Length")
|
||||
<< "\n--- Number of layers:\t" << fNbOfLayers
|
||||
<< "\n--- Number of R-cells:\t" << fNbOfRhoCells
|
||||
<< "\n--- Number of phi-cells:\t" << fNbOfPhiCells << G4endl;
|
||||
<< "\n--- Number of layers:\t" << fNbOfLayers << "\n--- Number of R-cells:\t"
|
||||
<< fNbOfRhoCells << "\n--- Number of phi-cells:\t" << fNbOfPhiCells << G4endl;
|
||||
G4cout << "-----------------------------------------------------" << G4endl;
|
||||
}
|
||||
|
||||
@@ -248,11 +242,11 @@ void Par03DetectorConstruction::SetMaterial(const G4String& aName)
|
||||
{
|
||||
// search material by its name
|
||||
G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial(aName);
|
||||
if(material)
|
||||
if (material)
|
||||
fDetectorMaterial = material;
|
||||
else
|
||||
G4Exception("Par03DetectorConstruction::SetMaterial()", "InvalidSetup",
|
||||
FatalException, ("Unknown material name: " + aName).c_str());
|
||||
G4Exception("Par03DetectorConstruction::SetMaterial()", "InvalidSetup", FatalException,
|
||||
("Unknown material name: " + aName).c_str());
|
||||
G4RunManager::GetRunManager()->PhysicsHasBeenModified();
|
||||
}
|
||||
|
||||
@@ -261,11 +255,10 @@ void Par03DetectorConstruction::SetMaterial(const G4String& aName)
|
||||
void Par03DetectorConstruction::SetRadius(G4double aRadius)
|
||||
{
|
||||
// check if fits within world volume
|
||||
if(aRadius >= fWorldSize / 2.)
|
||||
G4Exception("Par03DetectorConstruction::SetRadius()", "InvalidSetup",
|
||||
FatalException,
|
||||
("Detector radius cannot be larger than the world size (" +
|
||||
G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
|
||||
if (aRadius >= fWorldSize / 2.)
|
||||
G4Exception("Par03DetectorConstruction::SetRadius()", "InvalidSetup", FatalException,
|
||||
("Detector radius cannot be larger than the world size ("
|
||||
+ G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
|
||||
.c_str());
|
||||
fDetectorRadius = aRadius;
|
||||
}
|
||||
@@ -274,11 +267,10 @@ void Par03DetectorConstruction::SetRadius(G4double aRadius)
|
||||
void Par03DetectorConstruction::SetLength(G4double aLength)
|
||||
{
|
||||
// check if fits within world volume
|
||||
if(aLength >= fWorldSize / 2.)
|
||||
G4Exception("Par03DetectorConstruction::SetLength()", "InvalidSetup",
|
||||
FatalException,
|
||||
("Detector length cannot be larger than the world size (" +
|
||||
G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
|
||||
if (aLength >= fWorldSize / 2.)
|
||||
G4Exception("Par03DetectorConstruction::SetLength()", "InvalidSetup", FatalException,
|
||||
("Detector length cannot be larger than the world size ("
|
||||
+ G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
|
||||
.c_str());
|
||||
fDetectorLength = aLength;
|
||||
}
|
||||
@@ -24,20 +24,19 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03DetectorMessenger.hh"
|
||||
|
||||
#include "Par03DetectorConstruction.hh"
|
||||
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Par03DetectorMessenger::Par03DetectorMessenger(
|
||||
Par03DetectorConstruction* aDetector)
|
||||
: G4UImessenger()
|
||||
, fDetector(aDetector)
|
||||
Par03DetectorMessenger::Par03DetectorMessenger(Par03DetectorConstruction* aDetector)
|
||||
: G4UImessenger(), fDetector(aDetector)
|
||||
{
|
||||
fExampleDir = new G4UIdirectory("/Par03/");
|
||||
fExampleDir->SetGuidance("UI commands specific to this example");
|
||||
@@ -48,51 +47,43 @@ Par03DetectorMessenger::Par03DetectorMessenger(
|
||||
fPrintCmd = new G4UIcmdWithoutParameter("/Par03/detector/print", this);
|
||||
fPrintCmd->SetGuidance("Print current settings.");
|
||||
|
||||
fDetectorRadiusCmd =
|
||||
new G4UIcmdWithADoubleAndUnit("/Par03/detector/setDetectorRadius", this);
|
||||
fDetectorRadiusCmd->SetGuidance(
|
||||
"Set tranverse size of the detector (cylinder radius)");
|
||||
fDetectorRadiusCmd = new G4UIcmdWithADoubleAndUnit("/Par03/detector/setDetectorRadius", this);
|
||||
fDetectorRadiusCmd->SetGuidance("Set tranverse size of the detector (cylinder radius)");
|
||||
fDetectorRadiusCmd->SetParameterName("Size", false);
|
||||
fDetectorRadiusCmd->SetRange("Size>0.");
|
||||
fDetectorRadiusCmd->SetUnitCategory("Length");
|
||||
fDetectorRadiusCmd->AvailableForStates(G4State_PreInit);
|
||||
fDetectorRadiusCmd->SetToBeBroadcasted(false);
|
||||
|
||||
fDetectorLengthCmd =
|
||||
new G4UIcmdWithADoubleAndUnit("/Par03/detector/setDetectorLength", this);
|
||||
fDetectorLengthCmd->SetGuidance(
|
||||
"Set length of the detector (cylinder length)");
|
||||
fDetectorLengthCmd = new G4UIcmdWithADoubleAndUnit("/Par03/detector/setDetectorLength", this);
|
||||
fDetectorLengthCmd->SetGuidance("Set length of the detector (cylinder length)");
|
||||
fDetectorLengthCmd->SetParameterName("Size", false);
|
||||
fDetectorLengthCmd->SetRange("Size>0.");
|
||||
fDetectorLengthCmd->SetUnitCategory("Length");
|
||||
fDetectorLengthCmd->AvailableForStates(G4State_PreInit);
|
||||
fDetectorLengthCmd->SetToBeBroadcasted(false);
|
||||
|
||||
fDetectorMaterialCmd =
|
||||
new G4UIcmdWithAString("/Par03/detector/setDetectorMaterial", this);
|
||||
fDetectorMaterialCmd = new G4UIcmdWithAString("/Par03/detector/setDetectorMaterial", this);
|
||||
fDetectorMaterialCmd->SetGuidance("Material of the detector.");
|
||||
fDetectorMaterialCmd->SetParameterName("Name", false);
|
||||
fDetectorMaterialCmd->AvailableForStates(G4State_PreInit);
|
||||
fDetectorMaterialCmd->SetToBeBroadcasted(false);
|
||||
|
||||
fNbLayersCmd =
|
||||
new G4UIcmdWithAnInteger("/Par03/detector/setNbOfLayers", this);
|
||||
fNbLayersCmd = new G4UIcmdWithAnInteger("/Par03/detector/setNbOfLayers", this);
|
||||
fNbLayersCmd->SetGuidance("Set number of layers.");
|
||||
fNbLayersCmd->SetParameterName("NbLayers", false);
|
||||
fNbLayersCmd->SetRange("NbLayers>0");
|
||||
fNbLayersCmd->AvailableForStates(G4State_PreInit);
|
||||
fNbLayersCmd->SetToBeBroadcasted(false);
|
||||
|
||||
fNbRhoCellsCmd =
|
||||
new G4UIcmdWithAnInteger("/Par03/detector/setNbOfRhoCells", this);
|
||||
fNbRhoCellsCmd = new G4UIcmdWithAnInteger("/Par03/detector/setNbOfRhoCells", this);
|
||||
fNbRhoCellsCmd->SetGuidance("Set number of cells along radius.");
|
||||
fNbRhoCellsCmd->SetParameterName("NbRhoCells", false);
|
||||
fNbRhoCellsCmd->SetRange("NbRhoCells>0");
|
||||
fNbRhoCellsCmd->AvailableForStates(G4State_PreInit);
|
||||
fNbRhoCellsCmd->SetToBeBroadcasted(false);
|
||||
|
||||
fNbPhiCellsCmd =
|
||||
new G4UIcmdWithAnInteger("/Par03/detector/setNbOfPhiCells", this);
|
||||
fNbPhiCellsCmd = new G4UIcmdWithAnInteger("/Par03/detector/setNbOfPhiCells", this);
|
||||
fNbPhiCellsCmd->SetGuidance("Set number of cells in azimuthal angle.");
|
||||
fNbPhiCellsCmd->SetParameterName("NbPhiCells", false);
|
||||
fNbPhiCellsCmd->SetRange("NbPhiCells>0");
|
||||
@@ -117,35 +108,27 @@ Par03DetectorMessenger::~Par03DetectorMessenger()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void Par03DetectorMessenger::SetNewValue(G4UIcommand* aCommand,
|
||||
G4String aNewValue)
|
||||
void Par03DetectorMessenger::SetNewValue(G4UIcommand* aCommand, G4String aNewValue)
|
||||
{
|
||||
if(aCommand == fPrintCmd)
|
||||
{
|
||||
if (aCommand == fPrintCmd) {
|
||||
fDetector->Print();
|
||||
}
|
||||
else if(aCommand == fDetectorRadiusCmd)
|
||||
{
|
||||
else if (aCommand == fDetectorRadiusCmd) {
|
||||
fDetector->SetRadius(fDetectorRadiusCmd->GetNewDoubleValue(aNewValue));
|
||||
}
|
||||
else if(aCommand == fDetectorLengthCmd)
|
||||
{
|
||||
else if (aCommand == fDetectorLengthCmd) {
|
||||
fDetector->SetLength(fDetectorRadiusCmd->GetNewDoubleValue(aNewValue));
|
||||
}
|
||||
else if(aCommand == fDetectorMaterialCmd)
|
||||
{
|
||||
else if (aCommand == fDetectorMaterialCmd) {
|
||||
fDetector->SetMaterial(aNewValue);
|
||||
}
|
||||
else if(aCommand == fNbLayersCmd)
|
||||
{
|
||||
else if (aCommand == fNbLayersCmd) {
|
||||
fDetector->SetNbOfLayers(fNbLayersCmd->GetNewIntValue(aNewValue));
|
||||
}
|
||||
else if(aCommand == fNbRhoCellsCmd)
|
||||
{
|
||||
else if (aCommand == fNbRhoCellsCmd) {
|
||||
fDetector->SetNbOfRhoCells(fNbRhoCellsCmd->GetNewIntValue(aNewValue));
|
||||
}
|
||||
else if(aCommand == fNbPhiCellsCmd)
|
||||
{
|
||||
else if (aCommand == fNbPhiCellsCmd) {
|
||||
fDetector->SetNbOfPhiCells(fNbPhiCellsCmd->GetNewIntValue(aNewValue));
|
||||
}
|
||||
}
|
||||
@@ -156,28 +139,22 @@ G4String Par03DetectorMessenger::GetCurrentValue(G4UIcommand* aCommand)
|
||||
{
|
||||
G4String cv;
|
||||
|
||||
if(aCommand == fDetectorRadiusCmd)
|
||||
{
|
||||
if (aCommand == fDetectorRadiusCmd) {
|
||||
cv = fDetectorRadiusCmd->ConvertToString(fDetector->GetRadius(), "mm");
|
||||
}
|
||||
else if(aCommand == fDetectorLengthCmd)
|
||||
{
|
||||
else if (aCommand == fDetectorLengthCmd) {
|
||||
cv = fDetectorLengthCmd->ConvertToString(fDetector->GetLength(), "mm");
|
||||
}
|
||||
else if(aCommand == fDetectorMaterialCmd)
|
||||
{
|
||||
else if (aCommand == fDetectorMaterialCmd) {
|
||||
cv = fDetector->GetMaterial();
|
||||
}
|
||||
else if(aCommand == fNbLayersCmd)
|
||||
{
|
||||
else if (aCommand == fNbLayersCmd) {
|
||||
cv = fNbLayersCmd->ConvertToString(fDetector->GetNbOfLayers());
|
||||
}
|
||||
else if(aCommand == fNbPhiCellsCmd)
|
||||
{
|
||||
else if (aCommand == fNbPhiCellsCmd) {
|
||||
cv = fNbPhiCellsCmd->ConvertToString(fDetector->GetNbOfPhiCells());
|
||||
}
|
||||
else if(aCommand == fNbRhoCellsCmd)
|
||||
{
|
||||
else if (aCommand == fNbRhoCellsCmd) {
|
||||
cv = fNbRhoCellsCmd->ConvertToString(fDetector->GetNbOfRhoCells());
|
||||
}
|
||||
return cv;
|
||||
|
||||
@@ -23,38 +23,34 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03EMShowerModel.hh"
|
||||
#include "Par03EMShowerMessenger.hh"
|
||||
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithADouble.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "Par03EMShowerModel.hh"
|
||||
|
||||
Par03EMShowerMessenger::Par03EMShowerMessenger(Par03EMShowerModel* aModel)
|
||||
: fModel(aModel)
|
||||
#include "G4UIcmdWithADouble.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
|
||||
Par03EMShowerMessenger::Par03EMShowerMessenger(Par03EMShowerModel* aModel) : fModel(aModel)
|
||||
{
|
||||
fDirectory = new G4UIdirectory("/Par03/fastSim/");
|
||||
fDirectory->SetGuidance(
|
||||
"Set mesh parameters for the example fast sim model.");
|
||||
fDirectory->SetGuidance("Set mesh parameters for the example fast sim model.");
|
||||
|
||||
fPrintCmd = new G4UIcmdWithoutParameter("/Par03/fastSim/print", this);
|
||||
fPrintCmd->SetGuidance("Print current settings.");
|
||||
|
||||
fSigmaCmd = new G4UIcmdWithADoubleAndUnit(
|
||||
"/Par03/fastSim/transverseProfile/sigma", this);
|
||||
fSigmaCmd = new G4UIcmdWithADoubleAndUnit("/Par03/fastSim/transverseProfile/sigma", this);
|
||||
fSigmaCmd->SetGuidance("Set sigma parameter of 2D Gaussian distribution.");
|
||||
fSigmaCmd->SetParameterName("Sigma", false);
|
||||
fSigmaCmd->SetUnitCategory("Length");
|
||||
|
||||
fAlphaCmd =
|
||||
new G4UIcmdWithADouble("/Par03/fastSim/longitudinalProfile/alpha", this);
|
||||
fAlphaCmd = new G4UIcmdWithADouble("/Par03/fastSim/longitudinalProfile/alpha", this);
|
||||
fAlphaCmd->SetGuidance("Set alpha parameter of Gamma distribution.");
|
||||
fAlphaCmd->SetParameterName("Alpha", false);
|
||||
|
||||
fBetaCmd =
|
||||
new G4UIcmdWithADouble("/Par03/fastSim/longitudinalProfile/beta", this);
|
||||
fBetaCmd = new G4UIcmdWithADouble("/Par03/fastSim/longitudinalProfile/beta", this);
|
||||
fBetaCmd->SetGuidance("Set beta parameter of Gamma distribution.");
|
||||
fBetaCmd->SetParameterName("Beta", false);
|
||||
|
||||
@@ -65,10 +61,8 @@ Par03EMShowerMessenger::Par03EMShowerMessenger(Par03EMShowerModel* aModel)
|
||||
"the sensitive detector.");
|
||||
fNbOfHitsCmd->SetParameterName("Number", false);
|
||||
|
||||
fLongMaxDepthCmd =
|
||||
new G4UIcmdWithADouble("/Par03/fastSim/longitudinalProfile/maxDepth", this);
|
||||
fLongMaxDepthCmd->SetGuidance(
|
||||
"Set maximum shower depth used in parametrisation.");
|
||||
fLongMaxDepthCmd = new G4UIcmdWithADouble("/Par03/fastSim/longitudinalProfile/maxDepth", this);
|
||||
fLongMaxDepthCmd->SetGuidance("Set maximum shower depth used in parametrisation.");
|
||||
fLongMaxDepthCmd->SetGuidance("Expressed in units of radiation length.");
|
||||
fLongMaxDepthCmd->SetParameterName("Depth", false);
|
||||
}
|
||||
@@ -88,31 +82,24 @@ Par03EMShowerMessenger::~Par03EMShowerMessenger()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void Par03EMShowerMessenger::SetNewValue(G4UIcommand* aCommand,
|
||||
G4String aNewValues)
|
||||
void Par03EMShowerMessenger::SetNewValue(G4UIcommand* aCommand, G4String aNewValues)
|
||||
{
|
||||
if(aCommand == fPrintCmd)
|
||||
{
|
||||
if (aCommand == fPrintCmd) {
|
||||
fModel->Print();
|
||||
}
|
||||
else if(aCommand == fSigmaCmd)
|
||||
{
|
||||
else if (aCommand == fSigmaCmd) {
|
||||
fModel->SetSigma(fSigmaCmd->GetNewDoubleValue(aNewValues));
|
||||
}
|
||||
else if(aCommand == fAlphaCmd)
|
||||
{
|
||||
else if (aCommand == fAlphaCmd) {
|
||||
fModel->SetAlpha(fAlphaCmd->GetNewDoubleValue(aNewValues));
|
||||
}
|
||||
else if(aCommand == fBetaCmd)
|
||||
{
|
||||
else if (aCommand == fBetaCmd) {
|
||||
fModel->SetBeta(fBetaCmd->GetNewDoubleValue(aNewValues));
|
||||
}
|
||||
else if(aCommand == fNbOfHitsCmd)
|
||||
{
|
||||
else if (aCommand == fNbOfHitsCmd) {
|
||||
fModel->SetNbOfHits(fNbOfHitsCmd->GetNewIntValue(aNewValues));
|
||||
}
|
||||
else if(aCommand == fLongMaxDepthCmd)
|
||||
{
|
||||
else if (aCommand == fLongMaxDepthCmd) {
|
||||
fModel->SetLongMaxDepth(fLongMaxDepthCmd->GetNewDoubleValue(aNewValues));
|
||||
}
|
||||
}
|
||||
@@ -123,24 +110,19 @@ G4String Par03EMShowerMessenger::GetCurrentValue(G4UIcommand* aCommand)
|
||||
{
|
||||
G4String cv;
|
||||
|
||||
if(aCommand == fSigmaCmd)
|
||||
{
|
||||
if (aCommand == fSigmaCmd) {
|
||||
cv = fSigmaCmd->ConvertToString(fModel->GetSigma());
|
||||
}
|
||||
else if(aCommand == fAlphaCmd)
|
||||
{
|
||||
else if (aCommand == fAlphaCmd) {
|
||||
cv = fAlphaCmd->ConvertToString(fModel->GetAlpha());
|
||||
}
|
||||
else if(aCommand == fBetaCmd)
|
||||
{
|
||||
else if (aCommand == fBetaCmd) {
|
||||
cv = fBetaCmd->ConvertToString(fModel->GetBeta());
|
||||
}
|
||||
else if(aCommand == fNbOfHitsCmd)
|
||||
{
|
||||
else if (aCommand == fNbOfHitsCmd) {
|
||||
cv = fNbOfHitsCmd->ConvertToString(fModel->GetNbOfHits());
|
||||
}
|
||||
else if(aCommand == fLongMaxDepthCmd)
|
||||
{
|
||||
else if (aCommand == fLongMaxDepthCmd) {
|
||||
cv = fLongMaxDepthCmd->ConvertToString(fModel->GetLongMaxDepth());
|
||||
}
|
||||
return cv;
|
||||
|
||||
@@ -24,29 +24,30 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03EMShowerModel.hh"
|
||||
|
||||
#include "Par03EMShowerMessenger.hh"
|
||||
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4FastHit.hh"
|
||||
#include "G4FastSimHitMaker.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4FastHit.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4FastSimHitMaker.hh"
|
||||
|
||||
Par03EMShowerModel::Par03EMShowerModel(G4String aModelName, G4Region* aEnvelope)
|
||||
: G4VFastSimulationModel(aModelName, aEnvelope)
|
||||
, fMessenger(new Par03EMShowerMessenger(this))
|
||||
, fHitMaker(new G4FastSimHitMaker)
|
||||
: G4VFastSimulationModel(aModelName, aEnvelope),
|
||||
fMessenger(new Par03EMShowerMessenger(this)),
|
||||
fHitMaker(new G4FastSimHitMaker)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Par03EMShowerModel::Par03EMShowerModel(G4String aModelName)
|
||||
: G4VFastSimulationModel(aModelName)
|
||||
, fMessenger(new Par03EMShowerMessenger(this))
|
||||
, fHitMaker(new G4FastSimHitMaker)
|
||||
: G4VFastSimulationModel(aModelName),
|
||||
fMessenger(new Par03EMShowerMessenger(this)),
|
||||
fHitMaker(new G4FastSimHitMaker)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -55,12 +56,11 @@ Par03EMShowerModel::~Par03EMShowerModel() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool Par03EMShowerModel::IsApplicable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
G4bool Par03EMShowerModel::IsApplicable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
return &aParticleType == G4Electron::ElectronDefinition() ||
|
||||
&aParticleType == G4Positron::PositronDefinition() ||
|
||||
&aParticleType == G4Gamma::GammaDefinition();
|
||||
return &aParticleType == G4Electron::ElectronDefinition()
|
||||
|| &aParticleType == G4Positron::PositronDefinition()
|
||||
|| &aParticleType == G4Gamma::GammaDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -68,8 +68,7 @@ G4bool Par03EMShowerModel::IsApplicable(
|
||||
G4bool Par03EMShowerModel::ModelTrigger(const G4FastTrack& aFastTrack)
|
||||
{
|
||||
// Check energy
|
||||
if(aFastTrack.GetPrimaryTrack()->GetKineticEnergy() < 1 * GeV)
|
||||
{
|
||||
if (aFastTrack.GetPrimaryTrack()->GetKineticEnergy() < 1 * GeV) {
|
||||
return false;
|
||||
}
|
||||
// Check length of detector
|
||||
@@ -77,14 +76,13 @@ G4bool Par03EMShowerModel::ModelTrigger(const G4FastTrack& aFastTrack)
|
||||
// will fit inside. Required max shower depth is defined by fLongMaxDepth, and
|
||||
// can be changed with UI command `/Par03/fastSim/longitudinalProfile/maxDepth
|
||||
G4double X0 = aFastTrack.GetPrimaryTrack()->GetMaterial()->GetRadlen();
|
||||
auto particleDirection = aFastTrack.GetPrimaryTrackLocalDirection();
|
||||
auto particlePosition = aFastTrack.GetPrimaryTrackLocalPosition();
|
||||
G4double detectorDepthInMM = aFastTrack.GetEnvelopeSolid()->DistanceToOut(
|
||||
particlePosition, particleDirection);
|
||||
auto particleDirection = aFastTrack.GetPrimaryTrackLocalDirection();
|
||||
auto particlePosition = aFastTrack.GetPrimaryTrackLocalPosition();
|
||||
G4double detectorDepthInMM =
|
||||
aFastTrack.GetEnvelopeSolid()->DistanceToOut(particlePosition, particleDirection);
|
||||
G4double detectorDepthInX0 = detectorDepthInMM / X0;
|
||||
// check if detector depth is sufficient to create showers
|
||||
if(detectorDepthInX0 < fLongMaxDepth)
|
||||
{
|
||||
if (detectorDepthInX0 < fLongMaxDepth) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -92,8 +90,7 @@ G4bool Par03EMShowerModel::ModelTrigger(const G4FastTrack& aFastTrack)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void Par03EMShowerModel::DoIt(const G4FastTrack& aFastTrack,
|
||||
G4FastStep& aFastStep)
|
||||
void Par03EMShowerModel::DoIt(const G4FastTrack& aFastTrack, G4FastStep& aFastStep)
|
||||
{
|
||||
// Remove particle from further processing by G4
|
||||
aFastStep.KillPrimaryTrack();
|
||||
@@ -102,42 +99,37 @@ void Par03EMShowerModel::DoIt(const G4FastTrack& aFastTrack,
|
||||
// No need to create any deposit, it will be handled by this model (and
|
||||
// G4FastSimHitMaker that will call the sensitive detector)
|
||||
aFastStep.ProposeTotalEnergyDeposited(0);
|
||||
auto particlePosition = aFastTrack.GetPrimaryTrackLocalPosition();
|
||||
auto particlePosition = aFastTrack.GetPrimaryTrackLocalPosition();
|
||||
auto particleDirection = aFastTrack.GetPrimaryTrackLocalDirection();
|
||||
|
||||
// Calculate how to create energy deposits
|
||||
// Following PDG 33.5 chapter
|
||||
// material calculation assumes homogeneous detector (true for Par03 example)
|
||||
auto material = aFastTrack.GetPrimaryTrack()->GetMaterial();
|
||||
auto material = aFastTrack.GetPrimaryTrack()->GetMaterial();
|
||||
G4double materialX0 = material->GetRadlen();
|
||||
G4double materialZ = material->GetZ();
|
||||
G4double materialZ = material->GetZ();
|
||||
// EC estimation follows PDG fit to solids in Fig. 33.14 (rms 2.2%)
|
||||
G4double materialEc = 610 * MeV / (materialZ + 1.24);
|
||||
// RM estimation follows PDG Eq. (33.37) (rms 2.2%)
|
||||
G4double materialRM = 21.2052 * MeV * materialX0 / materialEc;
|
||||
G4double particleY = energy / materialEc;
|
||||
G4double particleY = energy / materialEc;
|
||||
// Estimate shower maximum and alpha parameter of Gamma distribution
|
||||
// that describes the longitudinal profile (PDG Eq. (33.35))
|
||||
// unless alpha is specified by UI command
|
||||
if(fAlpha < 0)
|
||||
{
|
||||
if (fAlpha < 0) {
|
||||
// from PDG Eq. (33.36)
|
||||
G4double particleTmax = std::log(particleY);
|
||||
if(aFastTrack.GetPrimaryTrack()->GetParticleDefinition() ==
|
||||
G4Gamma::GammaDefinition())
|
||||
{
|
||||
if (aFastTrack.GetPrimaryTrack()->GetParticleDefinition() == G4Gamma::GammaDefinition()) {
|
||||
particleTmax += 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
particleTmax -= 0.5;
|
||||
}
|
||||
fAlpha = particleTmax * fBeta + 1;
|
||||
}
|
||||
// Unless sigma of Gaussian distribution describing the transverse profile
|
||||
// is specified by UI command, use value calculated from Moliere Radius
|
||||
if(fSigma < 0)
|
||||
{
|
||||
if (fSigma < 0) {
|
||||
// 90% of shower is contained within 1 * R_M
|
||||
// 1.645 * std dev of Gaussian contains 90%
|
||||
fSigma = materialRM / 1.645;
|
||||
@@ -146,13 +138,12 @@ void Par03EMShowerModel::DoIt(const G4FastTrack& aFastTrack,
|
||||
// Calculate rotation matrix along the particle momentum direction
|
||||
// It will rotate the shower axes to match the incoming particle direction
|
||||
G4RotationMatrix rotMatrix = G4RotationMatrix();
|
||||
double particleTheta = particleDirection.theta();
|
||||
double particlePhi = particleDirection.phi();
|
||||
double epsilon = 1e-3;
|
||||
double particleTheta = particleDirection.theta();
|
||||
double particlePhi = particleDirection.phi();
|
||||
double epsilon = 1e-3;
|
||||
rotMatrix.rotateY(particleTheta);
|
||||
// do not use (random) phi if x==y==0
|
||||
if(!(std::fabs(particleDirection.x()) < epsilon &&
|
||||
std::fabs(particleDirection.y()) < epsilon))
|
||||
if (!(std::fabs(particleDirection.x()) < epsilon && std::fabs(particleDirection.y()) < epsilon))
|
||||
rotMatrix.rotateZ(particlePhi);
|
||||
|
||||
// Create hits
|
||||
@@ -160,21 +151,19 @@ void Par03EMShowerModel::DoIt(const G4FastTrack& aFastTrack,
|
||||
// then get random numbers from uniform distribution for azimuthal angle, and
|
||||
// from Gaussian for radius
|
||||
G4ThreeVector position;
|
||||
G4double gammaMax = Gamma((fAlpha - 1) / fBeta, fAlpha, fBeta);
|
||||
G4double gammaMax = Gamma((fAlpha - 1) / fBeta, fAlpha, fBeta);
|
||||
G4int generatedHits = 0;
|
||||
while(generatedHits < fNbOfHits)
|
||||
{
|
||||
while (generatedHits < fNbOfHits) {
|
||||
G4double random1 = G4UniformRand() * fLongMaxDepth;
|
||||
G4double random2 = G4UniformRand() * gammaMax;
|
||||
if(Gamma(random1, fAlpha, fBeta) >= random2)
|
||||
{
|
||||
if (Gamma(random1, fAlpha, fBeta) >= random2) {
|
||||
// Generate corresponding rho (phi) from Gaussian (flat) distribution
|
||||
G4double phiPosition = G4UniformRand() * 2 * CLHEP::pi;
|
||||
G4double rhoPosition = G4RandGauss::shoot(0, fSigma);
|
||||
position = particlePosition +
|
||||
rotMatrix * G4ThreeVector(rhoPosition * std::sin(phiPosition),
|
||||
rhoPosition * std::cos(phiPosition),
|
||||
random1 * materialX0);
|
||||
position = particlePosition
|
||||
+ rotMatrix
|
||||
* G4ThreeVector(rhoPosition * std::sin(phiPosition),
|
||||
rhoPosition * std::cos(phiPosition), random1 * materialX0);
|
||||
// Create energy deposit in the detector
|
||||
// This will call appropriate sensitive detector class
|
||||
fHitMaker->make(G4FastHit(position, energy / fNbOfHits), aFastTrack);
|
||||
@@ -190,17 +179,16 @@ void Par03EMShowerModel::Print() const
|
||||
G4cout << "Par03EMShowerModel: " << G4endl;
|
||||
G4cout << "Gaussian distribution (transverse plane): \tmu = 0, sigma = "
|
||||
<< G4BestUnit(fSigma, "Length") << G4endl;
|
||||
if(fSigma < 0)
|
||||
if (fSigma < 0)
|
||||
G4cout << "Negative sigma value means that it will be recalculated "
|
||||
"from the value of the Moliere radius of the detector material, "
|
||||
"taking into account that 90% of the area below the Gaussian "
|
||||
"distribution (from mu - 1.645 sigma to mu + 1.645 sigma) "
|
||||
"corresponds to area within 1 Moliere radius."
|
||||
<< G4endl;
|
||||
G4cout << "Gamma distribution (along shower axis): \talpha = " << fAlpha
|
||||
<< ", beta = " << fBeta << ", max depth = " << fLongMaxDepth << " X0"
|
||||
<< G4endl;
|
||||
if(fAlpha < 0)
|
||||
G4cout << "Gamma distribution (along shower axis): \talpha = " << fAlpha << ", beta = " << fBeta
|
||||
<< ", max depth = " << fLongMaxDepth << " X0" << G4endl;
|
||||
if (fAlpha < 0)
|
||||
G4cout << "Negative alpha value means that it will be recalculated "
|
||||
"from the critical energy of the detector material, particle "
|
||||
"type, and beta parameter.\n alpha = beta * T_max, where T_max = "
|
||||
|
||||
@@ -24,20 +24,18 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03EventAction.hh"
|
||||
#include "Par03Hit.hh"
|
||||
|
||||
#include "Par03DetectorConstruction.hh"
|
||||
#include "Par03Hit.hh"
|
||||
|
||||
#include "G4AnalysisManager.hh"
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4HCofThisEvent.hh"
|
||||
#include "G4Event.hh"
|
||||
#include "G4EventManager.hh"
|
||||
#include "G4HCofThisEvent.hh"
|
||||
#include "G4SDManager.hh"
|
||||
|
||||
Par03EventAction::Par03EventAction(Par03DetectorConstruction* aDetector)
|
||||
: G4UserEventAction()
|
||||
, fHitCollectionID(-1)
|
||||
, fTimer()
|
||||
, fDetector(aDetector)
|
||||
: G4UserEventAction(), fHitCollectionID(-1), fTimer(), fDetector(aDetector)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -46,7 +44,10 @@ Par03EventAction::~Par03EventAction() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void Par03EventAction::BeginOfEventAction(const G4Event*) { fTimer.Start(); }
|
||||
void Par03EventAction::BeginOfEventAction(const G4Event*)
|
||||
{
|
||||
fTimer.Start();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -54,71 +55,62 @@ void Par03EventAction::EndOfEventAction(const G4Event* aEvent)
|
||||
{
|
||||
fTimer.Stop();
|
||||
// Get hits collection ID (only once)
|
||||
if(fHitCollectionID == -1)
|
||||
{
|
||||
if (fHitCollectionID == -1) {
|
||||
fHitCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("hits");
|
||||
}
|
||||
// Get hits collection
|
||||
auto hitsCollection = static_cast<Par03HitsCollection*>(
|
||||
aEvent->GetHCofThisEvent()->GetHC(fHitCollectionID));
|
||||
auto hitsCollection =
|
||||
static_cast<Par03HitsCollection*>(aEvent->GetHCofThisEvent()->GetHC(fHitCollectionID));
|
||||
|
||||
if(hitsCollection == nullptr)
|
||||
{
|
||||
if (hitsCollection == nullptr) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Cannot access hitsCollection ID " << fHitCollectionID;
|
||||
G4Exception("Par03EventAction::GetHitsCollection()", "MyCode0001",
|
||||
FatalException, msg);
|
||||
G4Exception("Par03EventAction::GetHitsCollection()", "MyCode0001", FatalException, msg);
|
||||
}
|
||||
// Get analysis manager
|
||||
auto analysisManager = G4AnalysisManager::Instance();
|
||||
// Retrieve only once detector dimensions
|
||||
if(fCellSizeZ == 0)
|
||||
{
|
||||
fCellSizeZ = fDetector->GetLength() / fDetector->GetNbOfLayers();
|
||||
if (fCellSizeZ == 0) {
|
||||
fCellSizeZ = fDetector->GetLength() / fDetector->GetNbOfLayers();
|
||||
fCellSizeRho = fDetector->GetRadius() / fDetector->GetNbOfRhoCells();
|
||||
}
|
||||
|
||||
// Retrieve information from primary vertex and primary particle
|
||||
// To calculate shower axis and entry point to the detector
|
||||
auto primaryVertex = G4EventManager::GetEventManager()
|
||||
->GetConstCurrentEvent()
|
||||
->GetPrimaryVertex();
|
||||
auto primaryParticle = primaryVertex->GetPrimary(0);
|
||||
auto primaryVertex =
|
||||
G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetPrimaryVertex();
|
||||
auto primaryParticle = primaryVertex->GetPrimary(0);
|
||||
G4double primaryEnergy = primaryParticle->GetTotalEnergy();
|
||||
// Estimate from vertex and particle direction the entry point to the detector
|
||||
// Calculate entrance point to the detector located at z = 0
|
||||
auto primaryDirection = primaryParticle->GetMomentumDirection();
|
||||
auto primaryEntrance = primaryVertex->GetPosition() -
|
||||
primaryVertex->GetPosition().z() * primaryDirection;
|
||||
auto primaryEntrance =
|
||||
primaryVertex->GetPosition() - primaryVertex->GetPosition().z() * primaryDirection;
|
||||
G4double cosDirection = std::cos(primaryDirection.theta());
|
||||
G4double sinDirection = std::sin(primaryDirection.theta());
|
||||
|
||||
// Fill histograms
|
||||
Par03Hit* hit = nullptr;
|
||||
G4double hitEn = 0;
|
||||
Par03Hit* hit = nullptr;
|
||||
G4double hitEn = 0;
|
||||
G4double totalEnergy = 0;
|
||||
G4int hitZ = -1;
|
||||
G4int hitRho = -1;
|
||||
G4int hitType = -1;
|
||||
G4int hitZ = -1;
|
||||
G4int hitRho = -1;
|
||||
G4int hitType = -1;
|
||||
G4double tDistance = 0., rDistance = 0.;
|
||||
G4double tFirstMoment = 0., tSecondMoment = 0.;
|
||||
G4double rFirstMoment = 0., rSecondMoment = 0.;
|
||||
for(size_t iHit = 0; iHit < hitsCollection->entries(); iHit++)
|
||||
{
|
||||
hit = static_cast<Par03Hit*>(hitsCollection->GetHit(iHit));
|
||||
hitZ = hit->GetZid();
|
||||
hitRho = hit->GetRhoId();
|
||||
hitEn = hit->GetEdep();
|
||||
for (size_t iHit = 0; iHit < hitsCollection->entries(); iHit++) {
|
||||
hit = static_cast<Par03Hit*>(hitsCollection->GetHit(iHit));
|
||||
hitZ = hit->GetZid();
|
||||
hitRho = hit->GetRhoId();
|
||||
hitEn = hit->GetEdep();
|
||||
hitType = hit->GetType();
|
||||
if(hitEn > 0)
|
||||
{
|
||||
if (hitEn > 0) {
|
||||
totalEnergy += hitEn;
|
||||
tDistance =
|
||||
hitZ * fCellSizeZ * cosDirection +
|
||||
(hitRho * fCellSizeRho - primaryEntrance.perp()) * sinDirection;
|
||||
rDistance =
|
||||
hitZ * fCellSizeZ * (-sinDirection) +
|
||||
(hitRho * fCellSizeRho - primaryEntrance.perp()) * cosDirection;
|
||||
tDistance = hitZ * fCellSizeZ * cosDirection
|
||||
+ (hitRho * fCellSizeRho - primaryEntrance.perp()) * sinDirection;
|
||||
rDistance = hitZ * fCellSizeZ * (-sinDirection)
|
||||
+ (hitRho * fCellSizeRho - primaryEntrance.perp()) * cosDirection;
|
||||
tFirstMoment += hitEn * tDistance;
|
||||
rFirstMoment += hitEn * rDistance;
|
||||
analysisManager->FillH1(4, tDistance, hitEn);
|
||||
@@ -136,18 +128,16 @@ void Par03EventAction::EndOfEventAction(const G4Event* aEvent)
|
||||
analysisManager->FillH1(7, rFirstMoment);
|
||||
|
||||
// Second loop over hits to calculate second moments
|
||||
for(size_t iHit = 0; iHit < hitsCollection->entries(); iHit++)
|
||||
{
|
||||
hit = static_cast<Par03Hit*>(hitsCollection->GetHit(iHit));
|
||||
hitEn = hit->GetEdep();
|
||||
hitZ = hit->GetZid();
|
||||
for (size_t iHit = 0; iHit < hitsCollection->entries(); iHit++) {
|
||||
hit = static_cast<Par03Hit*>(hitsCollection->GetHit(iHit));
|
||||
hitEn = hit->GetEdep();
|
||||
hitZ = hit->GetZid();
|
||||
hitRho = hit->GetRhoId();
|
||||
if(hitEn > 0)
|
||||
{
|
||||
tDistance = hitZ * fCellSizeZ * cosDirection +
|
||||
(hitRho * fCellSizeRho - primaryEntrance.r()) * sinDirection;
|
||||
rDistance = hitZ * fCellSizeZ * (-sinDirection) +
|
||||
(hitRho * fCellSizeRho - primaryEntrance.r()) * cosDirection;
|
||||
if (hitEn > 0) {
|
||||
tDistance = hitZ * fCellSizeZ * cosDirection
|
||||
+ (hitRho * fCellSizeRho - primaryEntrance.r()) * sinDirection;
|
||||
rDistance = hitZ * fCellSizeZ * (-sinDirection)
|
||||
+ (hitRho * fCellSizeRho - primaryEntrance.r()) * cosDirection;
|
||||
tSecondMoment += hitEn * std::pow(tDistance - tFirstMoment, 2);
|
||||
rSecondMoment += hitEn * std::pow(rDistance - rFirstMoment, 2);
|
||||
}
|
||||
|
||||
@@ -25,22 +25,20 @@
|
||||
//
|
||||
#include "Par03Hit.hh"
|
||||
|
||||
#include "G4VisAttributes.hh"
|
||||
#include "G4Tubs.hh"
|
||||
#include "G4Colour.hh"
|
||||
#include "G4AttDefStore.hh"
|
||||
#include "G4AttDef.hh"
|
||||
#include "G4AttDefStore.hh"
|
||||
#include "G4AttValue.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4VVisManager.hh"
|
||||
#include "G4Colour.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Tubs.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4VVisManager.hh"
|
||||
#include "G4VisAttributes.hh"
|
||||
|
||||
G4ThreadLocal G4Allocator<Par03Hit>* Par03HitAllocator;
|
||||
|
||||
Par03Hit::Par03Hit()
|
||||
: G4VHit()
|
||||
{}
|
||||
Par03Hit::Par03Hit() : G4VHit() {}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -48,17 +46,16 @@ Par03Hit::~Par03Hit() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Par03Hit::Par03Hit(const Par03Hit& aRight)
|
||||
: G4VHit()
|
||||
Par03Hit::Par03Hit(const Par03Hit& aRight) : G4VHit()
|
||||
{
|
||||
fEdep = aRight.fEdep;
|
||||
fZId = aRight.fZId;
|
||||
fRhoId = aRight.fRhoId;
|
||||
fPhiId = aRight.fPhiId;
|
||||
fTime = aRight.fTime;
|
||||
fPos = aRight.fPos;
|
||||
fRot = aRight.fRot;
|
||||
fType = aRight.fType;
|
||||
fEdep = aRight.fEdep;
|
||||
fZId = aRight.fZId;
|
||||
fRhoId = aRight.fRhoId;
|
||||
fPhiId = aRight.fPhiId;
|
||||
fTime = aRight.fTime;
|
||||
fPos = aRight.fPos;
|
||||
fRot = aRight.fRot;
|
||||
fType = aRight.fType;
|
||||
fLogVol = aRight.fLogVol;
|
||||
}
|
||||
|
||||
@@ -66,14 +63,14 @@ Par03Hit::Par03Hit(const Par03Hit& aRight)
|
||||
|
||||
const Par03Hit& Par03Hit::operator=(const Par03Hit& aRight)
|
||||
{
|
||||
fEdep = aRight.fEdep;
|
||||
fZId = aRight.fZId;
|
||||
fRhoId = aRight.fRhoId;
|
||||
fPhiId = aRight.fPhiId;
|
||||
fTime = aRight.fTime;
|
||||
fPos = aRight.fPos;
|
||||
fRot = aRight.fRot;
|
||||
fType = aRight.fType;
|
||||
fEdep = aRight.fEdep;
|
||||
fZId = aRight.fZId;
|
||||
fRhoId = aRight.fRhoId;
|
||||
fPhiId = aRight.fPhiId;
|
||||
fTime = aRight.fTime;
|
||||
fPos = aRight.fPos;
|
||||
fRot = aRight.fRot;
|
||||
fType = aRight.fType;
|
||||
fLogVol = aRight.fLogVol;
|
||||
return *this;
|
||||
}
|
||||
@@ -82,8 +79,7 @@ const Par03Hit& Par03Hit::operator=(const Par03Hit& aRight)
|
||||
|
||||
int Par03Hit::operator==(const Par03Hit& aRight) const
|
||||
{
|
||||
return (fRhoId == aRight.fRhoId && fPhiId == aRight.fPhiId &&
|
||||
fZId == aRight.fZId);
|
||||
return (fRhoId == aRight.fRhoId && fPhiId == aRight.fPhiId && fZId == aRight.fZId);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -92,25 +88,20 @@ void Par03Hit::Draw()
|
||||
{
|
||||
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
|
||||
// Hits can be filtered out in visualisation
|
||||
if(!pVVisManager->FilterHit(*this))
|
||||
return;
|
||||
if (!pVVisManager->FilterHit(*this)) return;
|
||||
// Do not draw empty hits
|
||||
if(fEdep < 0)
|
||||
return;
|
||||
if(pVVisManager)
|
||||
{
|
||||
if (fEdep < 0) return;
|
||||
if (pVVisManager) {
|
||||
G4Transform3D trans(fRot, fPos);
|
||||
G4VisAttributes attribs;
|
||||
// Create default dimensions
|
||||
G4Tubs solid("draw", 0, 1 * cm, 1 * cm, 0, 0.05 * CLHEP::pi);
|
||||
if(fLogVol)
|
||||
{
|
||||
if (fLogVol) {
|
||||
const G4VisAttributes* pVA = fLogVol->GetVisAttributes();
|
||||
if(pVA)
|
||||
attribs = *pVA;
|
||||
if (pVA) attribs = *pVA;
|
||||
// Cannot use directly fLogVol due to rho parametrisation (change of
|
||||
// solid!) Recalculation of radius is needed
|
||||
solid = *dynamic_cast<G4Tubs*>(fLogVol->GetSolid());
|
||||
solid = *dynamic_cast<G4Tubs*>(fLogVol->GetSolid());
|
||||
double dR = solid.GetOuterRadius() - solid.GetInnerRadius();
|
||||
solid.SetInnerRadius(solid.GetInnerRadius() + fRhoId * dR);
|
||||
solid.SetOuterRadius(solid.GetOuterRadius() + fRhoId * dR);
|
||||
@@ -131,18 +122,13 @@ void Par03Hit::Draw()
|
||||
const std::map<G4String, G4AttDef>* Par03Hit::GetAttDefs() const
|
||||
{
|
||||
G4bool isNew;
|
||||
std::map<G4String, G4AttDef>* store =
|
||||
G4AttDefStore::GetInstance("Par03Hit", isNew);
|
||||
if(isNew)
|
||||
{
|
||||
(*store)["HitType"] =
|
||||
G4AttDef("HitType", "Hit Type", "Physics", "", "G4String");
|
||||
(*store)["Energy"] = G4AttDef("Energy", "Energy Deposited", "Physics",
|
||||
"G4BestUnit", "G4double");
|
||||
(*store)["Time"] =
|
||||
G4AttDef("Time", "Time", "Physics", "G4BestUnit", "G4double");
|
||||
(*store)["Pos"] =
|
||||
G4AttDef("Pos", "Position", "Physics", "G4BestUnit", "G4ThreeVector");
|
||||
std::map<G4String, G4AttDef>* store = G4AttDefStore::GetInstance("Par03Hit", isNew);
|
||||
if (isNew) {
|
||||
(*store)["HitType"] = G4AttDef("HitType", "Hit Type", "Physics", "", "G4String");
|
||||
(*store)["Energy"] =
|
||||
G4AttDef("Energy", "Energy Deposited", "Physics", "G4BestUnit", "G4double");
|
||||
(*store)["Time"] = G4AttDef("Time", "Time", "Physics", "G4BestUnit", "G4double");
|
||||
(*store)["Pos"] = G4AttDef("Pos", "Position", "Physics", "G4BestUnit", "G4ThreeVector");
|
||||
}
|
||||
return store;
|
||||
}
|
||||
@@ -163,7 +149,6 @@ std::vector<G4AttValue>* Par03Hit::CreateAttValues() const
|
||||
|
||||
void Par03Hit::Print()
|
||||
{
|
||||
std::cout << "\tHit " << fEdep / MeV << " MeV at " << fPos / cm
|
||||
<< " cm (R,phi,z)= (" << fRhoId << ", " << fPhiId << ", " << fZId
|
||||
<< "), " << fTime << " ns" << std::endl;
|
||||
std::cout << "\tHit " << fEdep / MeV << " MeV at " << fPos / cm << " cm (R,phi,z)= (" << fRhoId
|
||||
<< ", " << fPhiId << ", " << fZId << "), " << fTime << " ns" << std::endl;
|
||||
}
|
||||
|
||||
@@ -30,16 +30,14 @@
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
Par03PrimaryGeneratorAction::Par03PrimaryGeneratorAction()
|
||||
: G4VUserPrimaryGeneratorAction()
|
||||
, fParticleGun(nullptr)
|
||||
: G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr)
|
||||
{
|
||||
G4int n_particle = 1;
|
||||
fParticleGun = new G4ParticleGun(n_particle);
|
||||
fParticleGun = new G4ParticleGun(n_particle);
|
||||
// Default particle properties
|
||||
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
|
||||
G4String particleName;
|
||||
G4ParticleDefinition* particle =
|
||||
particleTable->FindParticle(particleName = "e-");
|
||||
G4ParticleDefinition* particle = particleTable->FindParticle(particleName = "e-");
|
||||
fParticleGun->SetParticleDefinition(particle);
|
||||
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
|
||||
fParticleGun->SetParticleEnergy(10. * GeV);
|
||||
@@ -48,7 +46,10 @@ Par03PrimaryGeneratorAction::Par03PrimaryGeneratorAction()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Par03PrimaryGeneratorAction::~Par03PrimaryGeneratorAction() { delete fParticleGun; }
|
||||
Par03PrimaryGeneratorAction::~Par03PrimaryGeneratorAction()
|
||||
{
|
||||
delete fParticleGun;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03RunAction.hh"
|
||||
|
||||
#include "Par03DetectorConstruction.hh"
|
||||
|
||||
#include "G4AnalysisManager.hh"
|
||||
|
||||
Par03RunAction::Par03RunAction(Par03DetectorConstruction* aDetector)
|
||||
: G4UserRunAction()
|
||||
, fDetector(aDetector)
|
||||
: G4UserRunAction(), fDetector(aDetector)
|
||||
{
|
||||
// Create analysis manager
|
||||
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
|
||||
@@ -49,9 +49,9 @@ Par03RunAction::~Par03RunAction() = default;
|
||||
void Par03RunAction::BeginOfRunAction(const G4Run*)
|
||||
{
|
||||
// Get detector dimensions
|
||||
G4int cellNumZ = fDetector->GetNbOfLayers();
|
||||
G4int cellNumRho = fDetector->GetNbOfRhoCells();
|
||||
G4double cellSizeZ = fDetector->GetLength() / cellNumZ;
|
||||
G4int cellNumZ = fDetector->GetNbOfLayers();
|
||||
G4int cellNumRho = fDetector->GetNbOfRhoCells();
|
||||
G4double cellSizeZ = fDetector->GetLength() / cellNumZ;
|
||||
G4double cellSizeRho = fDetector->GetRadius() / cellNumRho;
|
||||
// Default max value of energy stored in histogram (in GeV)
|
||||
G4double maxEnergy = 100;
|
||||
@@ -60,50 +60,36 @@ void Par03RunAction::BeginOfRunAction(const G4Run*)
|
||||
auto analysisManager = G4AnalysisManager::Instance();
|
||||
|
||||
// Creating control histograms
|
||||
analysisManager->CreateH1("energyParticle",
|
||||
"Primary energy;E_{MC} (GeV);Entries", 256, 0,
|
||||
analysisManager->CreateH1("energyParticle", "Primary energy;E_{MC} (GeV);Entries", 256, 0,
|
||||
1.1 * maxEnergy);
|
||||
analysisManager->CreateH1("energyDeposited",
|
||||
"Deposited energy;E_{MC} (GeV);Entries", 256, 0,
|
||||
analysisManager->CreateH1("energyDeposited", "Deposited energy;E_{MC} (GeV);Entries", 256, 0,
|
||||
1.1 * maxEnergy);
|
||||
analysisManager->CreateH1(
|
||||
"energyRatio",
|
||||
"Ratio of energy deposited to primary;E_{dep} / E_{MC};Entries", 1024, 0,
|
||||
1);
|
||||
analysisManager->CreateH1("time", "Simulation time; time (s);Entries", 2048,
|
||||
0, 30);
|
||||
analysisManager->CreateH1(
|
||||
"longProfile", "Longitudinal profile;t (mm);#LTE#GT (MeV)", cellNumZ,
|
||||
-0.5 * cellSizeZ, (cellNumZ - 0.5) * cellSizeZ);
|
||||
analysisManager->CreateH1(
|
||||
"transProfile", "Transverse profile;r (mm);#LTE#GT (MeV)", cellNumRho,
|
||||
-0.5 * cellSizeRho, (cellNumRho - 0.5) * cellSizeRho);
|
||||
analysisManager->CreateH1(
|
||||
"longFirstMoment",
|
||||
"First moment of longitudinal distribution;#LT#lambda#GT (mm);Entries",
|
||||
1024, -0.5 * cellSizeZ,
|
||||
cellNumZ * cellSizeZ / 2); // arbitrary scaling of max value on axis
|
||||
"energyRatio", "Ratio of energy deposited to primary;E_{dep} / E_{MC};Entries", 1024, 0, 1);
|
||||
analysisManager->CreateH1("time", "Simulation time; time (s);Entries", 2048, 0, 30);
|
||||
analysisManager->CreateH1("longProfile", "Longitudinal profile;t (mm);#LTE#GT (MeV)", cellNumZ,
|
||||
-0.5 * cellSizeZ, (cellNumZ - 0.5) * cellSizeZ);
|
||||
analysisManager->CreateH1("transProfile", "Transverse profile;r (mm);#LTE#GT (MeV)", cellNumRho,
|
||||
-0.5 * cellSizeRho, (cellNumRho - 0.5) * cellSizeRho);
|
||||
analysisManager->CreateH1("longFirstMoment",
|
||||
"First moment of longitudinal distribution;#LT#lambda#GT (mm);Entries",
|
||||
1024, -0.5 * cellSizeZ,
|
||||
cellNumZ * cellSizeZ / 2); // arbitrary scaling of max value on axis
|
||||
analysisManager->CreateH1("transFirstMoment",
|
||||
"First moment of transverse distribution;#LTr#GT "
|
||||
"(mm);Entries",
|
||||
1024, -0.5 * cellSizeRho,
|
||||
cellNumRho * cellSizeRho /
|
||||
10); // arbitrary scaling of max value on axis
|
||||
cellNumRho * cellSizeRho
|
||||
/ 10); // arbitrary scaling of max value on axis
|
||||
analysisManager->CreateH1(
|
||||
"longSecondMoment",
|
||||
"Second moment of longitudinal distribution;#LT#lambda^{2}#GT "
|
||||
"(mm^{2});Entries",
|
||||
1024, 0,
|
||||
std::pow(cellNumZ * cellSizeZ, 2) /
|
||||
25); // arbitrary scaling of max value on axis
|
||||
1024, 0, std::pow(cellNumZ * cellSizeZ, 2) / 25); // arbitrary scaling of max value on axis
|
||||
analysisManager->CreateH1(
|
||||
"transSecondMoment",
|
||||
"Second moment of transverse distribution;#LTr^{2}#GT (mm^{2});Entries",
|
||||
1024, 0,
|
||||
std::pow(cellNumRho * cellSizeRho, 2) /
|
||||
25); // arbitrary scaling of max value on axis
|
||||
analysisManager->CreateH1(
|
||||
"hitType", "hit type;type (0=full, 1= fast);Entries", 2, -0.5, 1.5);
|
||||
"transSecondMoment", "Second moment of transverse distribution;#LTr^{2}#GT (mm^{2});Entries",
|
||||
1024, 0, std::pow(cellNumRho * cellSizeRho, 2) / 25); // arbitrary scaling of max value on axis
|
||||
analysisManager->CreateH1("hitType", "hit type;type (0=full, 1= fast);Entries", 2, -0.5, 1.5);
|
||||
|
||||
// Open an output file
|
||||
analysisManager->OpenFile();
|
||||
|
||||
@@ -24,27 +24,24 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "Par03SensitiveDetector.hh"
|
||||
|
||||
#include "Par03Hit.hh"
|
||||
|
||||
#include "G4HCofThisEvent.hh"
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4TouchableHistory.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4SDManager.hh"
|
||||
|
||||
Par03SensitiveDetector::Par03SensitiveDetector(G4String aName)
|
||||
: G4VSensitiveDetector(aName)
|
||||
Par03SensitiveDetector::Par03SensitiveDetector(G4String aName) : G4VSensitiveDetector(aName)
|
||||
{
|
||||
collectionName.insert("hits");
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Par03SensitiveDetector::Par03SensitiveDetector(G4String aName, G4int aNumLayers,
|
||||
G4int aNumRho, G4int aNumPhi)
|
||||
: G4VSensitiveDetector(aName)
|
||||
, fCellNoZ(aNumLayers)
|
||||
, fCellNoRho(aNumRho)
|
||||
, fCellNoPhi(aNumPhi)
|
||||
Par03SensitiveDetector::Par03SensitiveDetector(G4String aName, G4int aNumLayers, G4int aNumRho,
|
||||
G4int aNumPhi)
|
||||
: G4VSensitiveDetector(aName), fCellNoZ(aNumLayers), fCellNoRho(aNumRho), fCellNoPhi(aNumPhi)
|
||||
{
|
||||
collectionName.insert("hits");
|
||||
}
|
||||
@@ -57,21 +54,17 @@ Par03SensitiveDetector::~Par03SensitiveDetector() = default;
|
||||
|
||||
void Par03SensitiveDetector::Initialize(G4HCofThisEvent* aHCE)
|
||||
{
|
||||
fHitsCollection =
|
||||
new Par03HitsCollection(SensitiveDetectorName, collectionName[0]);
|
||||
if(fHitCollectionID < 0)
|
||||
{
|
||||
fHitCollectionID =
|
||||
G4SDManager::GetSDMpointer()->GetCollectionID(fHitsCollection);
|
||||
fHitsCollection = new Par03HitsCollection(SensitiveDetectorName, collectionName[0]);
|
||||
if (fHitCollectionID < 0) {
|
||||
fHitCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID(fHitsCollection);
|
||||
}
|
||||
aHCE->AddHitsCollection(fHitCollectionID, fHitsCollection);
|
||||
|
||||
// fill calorimeter hits with zero energy deposition
|
||||
for(G4int iphi = 0; iphi < fCellNoPhi; iphi++)
|
||||
for(G4int irho = 0; irho < fCellNoRho; irho++)
|
||||
for(G4int iz = 0; iz < fCellNoZ; iz++)
|
||||
{
|
||||
auto hit = new Par03Hit();
|
||||
for (G4int iphi = 0; iphi < fCellNoPhi; iphi++)
|
||||
for (G4int irho = 0; irho < fCellNoRho; irho++)
|
||||
for (G4int iz = 0; iz < fCellNoZ; iz++) {
|
||||
auto hit = new Par03Hit();
|
||||
fHitsCollection->insert(hit);
|
||||
}
|
||||
}
|
||||
@@ -81,11 +74,9 @@ void Par03SensitiveDetector::Initialize(G4HCofThisEvent* aHCE)
|
||||
G4bool Par03SensitiveDetector::ProcessHits(G4Step* aStep, G4TouchableHistory*)
|
||||
{
|
||||
G4double edep = aStep->GetTotalEnergyDeposit();
|
||||
if(edep == 0.)
|
||||
return true;
|
||||
if (edep == 0.) return true;
|
||||
|
||||
auto aTouchable =
|
||||
(G4TouchableHistory*) (aStep->GetPreStepPoint()->GetTouchable());
|
||||
auto aTouchable = (G4TouchableHistory*)(aStep->GetPreStepPoint()->GetTouchable());
|
||||
|
||||
auto hit = RetrieveAndSetupHit(aTouchable);
|
||||
|
||||
@@ -94,27 +85,23 @@ G4bool Par03SensitiveDetector::ProcessHits(G4Step* aStep, G4TouchableHistory*)
|
||||
|
||||
// Fill time information from G4Step
|
||||
// If it's already filled, choose hit with earliest global time
|
||||
if(hit->GetTime() == -1 ||
|
||||
hit->GetTime() > aStep->GetTrack()->GetGlobalTime())
|
||||
if (hit->GetTime() == -1 || hit->GetTime() > aStep->GetTrack()->GetGlobalTime())
|
||||
hit->SetTime(aStep->GetTrack()->GetGlobalTime());
|
||||
|
||||
// Set hit type to full simulation (only if hit is not already marked as fast
|
||||
// sim)
|
||||
if(hit->GetType() != 1)
|
||||
hit->SetType(0);
|
||||
if (hit->GetType() != 1) hit->SetType(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool Par03SensitiveDetector::ProcessHits(const G4FastHit* aHit,
|
||||
const G4FastTrack* aTrack,
|
||||
G4bool Par03SensitiveDetector::ProcessHits(const G4FastHit* aHit, const G4FastTrack* aTrack,
|
||||
G4TouchableHistory* aTouchable)
|
||||
{
|
||||
G4double edep = aHit->GetEnergy();
|
||||
if(edep == 0.)
|
||||
return true;
|
||||
if (edep == 0.) return true;
|
||||
|
||||
auto hit = RetrieveAndSetupHit(aTouchable);
|
||||
|
||||
@@ -123,9 +110,7 @@ G4bool Par03SensitiveDetector::ProcessHits(const G4FastHit* aHit,
|
||||
|
||||
// Fill time information from G4FastTrack
|
||||
// If it's already filled, choose hit with earliest global time
|
||||
if(hit->GetTime() == -1 ||
|
||||
hit->GetTime() > aTrack->GetPrimaryTrack()->GetGlobalTime())
|
||||
{
|
||||
if (hit->GetTime() == -1 || hit->GetTime() > aTrack->GetPrimaryTrack()->GetGlobalTime()) {
|
||||
hit->SetTime(aTrack->GetPrimaryTrack()->GetGlobalTime());
|
||||
}
|
||||
|
||||
@@ -138,27 +123,22 @@ G4bool Par03SensitiveDetector::ProcessHits(const G4FastHit* aHit,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Par03Hit* Par03SensitiveDetector::RetrieveAndSetupHit(
|
||||
G4TouchableHistory* aTouchable)
|
||||
Par03Hit* Par03SensitiveDetector::RetrieveAndSetupHit(G4TouchableHistory* aTouchable)
|
||||
{
|
||||
G4int rhoNo = aTouchable->GetCopyNumber(0); // cell
|
||||
G4int phiNo = aTouchable->GetCopyNumber(1); // segment
|
||||
G4int zNo = aTouchable->GetCopyNumber(2); // layer
|
||||
G4int zNo = aTouchable->GetCopyNumber(2); // layer
|
||||
|
||||
std::size_t hitID = fCellNoRho * fCellNoZ * phiNo + fCellNoZ * rhoNo + zNo;
|
||||
|
||||
if(hitID >= fHitsCollection->entries())
|
||||
{
|
||||
G4Exception(
|
||||
"Par03SensitiveDetector::RetrieveAndSetupHit()", "InvalidSetup",
|
||||
FatalException,
|
||||
"Size of hit collection in Par03SensitiveDetector is smaller than the "
|
||||
"number of cells created in Par03DetectorConstruction!");
|
||||
if (hitID >= fHitsCollection->entries()) {
|
||||
G4Exception("Par03SensitiveDetector::RetrieveAndSetupHit()", "InvalidSetup", FatalException,
|
||||
"Size of hit collection in Par03SensitiveDetector is smaller than the "
|
||||
"number of cells created in Par03DetectorConstruction!");
|
||||
}
|
||||
Par03Hit* hit = (*fHitsCollection)[hitID];
|
||||
|
||||
if(hit->GetRhoId() < 0)
|
||||
{
|
||||
if (hit->GetRhoId() < 0) {
|
||||
hit->SetRhoId(rhoNo);
|
||||
hit->SetPhiId(phiNo);
|
||||
hit->SetZid(zNo);
|
||||
|
||||
Reference in New Issue
Block a user