Import Geant4 10.7.0 source tree

This commit is contained in:
Gabriele Cosmo
2020-12-04 12:30:43 +01:00
parent 67ba86d073
commit dab42d2018
3770 changed files with 226369 additions and 286486 deletions
@@ -0,0 +1,88 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 3.8...3.18 FATAL_ERROR)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
project(HGCal_testbeam)
#----------------------------------------------------------------------------
# Find Geant4 package, activating all available UI and Vis drivers by default
# You can set WITH_GEANT4_UIVIS to OFF via the command line or ccmake/cmake-gui
# to build a batch mode only executable
#
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
if(WITH_GEANT4_UIVIS)
find_package(Geant4 REQUIRED ui_all vis_all)
else()
find_package(Geant4 REQUIRED)
endif()
#----------------------------------------------------------------------------
# Find ROOT (required package only for reading input particles from file)
#
find_package(ROOT QUIET NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
if (ROOT_FOUND)
message(STATUS "Found ROOT: ${ROOT_DIR}. Particles read from file can be used as generator.")
add_definitions(-DWITHROOT)
include_directories(${ROOT_INCLUDE_DIRS})
endif()
#----------------------------------------------------------------------------
# Setup Geant4 include directories and compile definitions
#
include(${Geant4_USE_FILE})
#----------------------------------------------------------------------------
# Locate sources and headers for this project
#
include_directories(${PROJECT_SOURCE_DIR}/include
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(HGCal_testbeam hgcal_testbeam.cc ${sources} ${headers})
target_link_libraries(HGCal_testbeam ${Geant4_LIBRARIES})
if (ROOT_FOUND)
target_link_libraries(HGCal_testbeam ${ROOT_LIBRARIES})
set_target_properties(HGCal_testbeam PROPERTIES CXX_STANDARD 17)
endif()
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build HGCal)testbeam. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(HGCAL_SCRIPTS
init_vis.mac
run.mac
vis.mac
)
foreach(_script ${HGCAL_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
endforeach()
if (ROOT_FOUND)
configure_file(
${PROJECT_SOURCE_DIR}/readFromFile.mac
${PROJECT_BINARY_DIR}/readFromFile.mac
COPYONLY
)
endif()
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS HGCal_testbeam DESTINATION bin)
@@ -0,0 +1,16 @@
# --------------------------------
# GNUmakefile for examples module.
# --------------------------------
name := HGCal_testbeam
G4TARGET := $(name)
G4EXLIB := true
ifndef G4INSTALL
G4INSTALL = ../..
endif
.PHONY: all
all: lib bin
include $(G4INSTALL)/config/binmake.gmk
+18
View File
@@ -0,0 +1,18 @@
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
Example HGCal_testbeam History file
---------------------------
This file should be used by the G4 example coordinator to briefly
summarize all major modifications introduced in the code and keep
track of all tags.
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
02-Nov-20 A. Zaborowska (exhgcaltb-V10-06-00)
- Create HGCal_testbeam example based on Thorben Quast application
+227
View File
@@ -0,0 +1,227 @@
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
Example HGCal_testbeam
----------------------
This example is based on the Geant4 standalone application developed
by Thorben Quast for the CMS HGCal studies:
https://github.com/ThorbenQuast/HGCal_TB_Geant4.
The goal of this example is to demonstrate a test beam setup used
in HEP experiments, and as a base for the validation studies and
comparison with experiment data.
It presents a test beam setup used in the HGCal studies in October
2018. It can be easily extended to other configurations.
Details on the High Granularity Calorimeter (HGCal) can be found
i.a. in the Technical Design Report:
https://cds.cern.ch/record/2293646/files/CMS-TDR-019.pdf
1. Detector description
-----------------------
Detector construction in this example assumes that the setup is
constructed with different elements placed one behind another along
z axis (beam axis).
There are 3 configurations user can choose from, and could be set
with UI command:
/HGCalTestbeam/setup/configuration <ID>
where <ID> by default is equal to 0, which means the HGCal testbeam
setup used in October 2018.
<ID> 1 builds the same calorimeter setup, but places in front of it
several beamline elements.
<ID> 2 builds a very simplistic test configuration.
Whenever a silicon wafer or SiPM is placed in the detector, a sensitive
volume is attached to it, and will be used to collect signal.
Silicon wafer is divided into cells (pixels), and each individual pixel
can collect signal.
In order to change the maximum step size allowed in silicon pixels:
/HGCalTestbeam/setup/stepSilicon <STEP>
where <STEP> is value of the max step size in micrometres. By default
<STEP> is equal to 30 um.
2. Signal
---------
Energy deposited within silicon pixels and SiPMs is registered in the
sensitive detectors. Each deposit is added individually to the vector
of hits, in order to allow the digitisation.
Digitisation is performed at the end of the event. It accumulates the
energy deposits within pixels, taking into account the time cut on the
arrival of signal (global time of energy deposit). By default no time
cut is applied which means all the deposits are counted. It can be set
using UI command:
/HGCalTestbeam/hits/timeCut <TIME>
where <TIME> is the maximum global time of the energy deposit that
would be counted into the signal within the pixel.
Another hit parameter is TOA (time of arrival) which is calculated
as time of the energy deposit which added to the digitised pixel energy
exceeds the threshold. By default the threshold is equal to 0, which
means that any hit will exceed the value, so TOA of pixel equals to
the time of the first energy deposit. It can be set using UI command:
/HGCalTestbeam/hits/toaThreshold <ENERGY_THRESHOLD>
where <ENERGY_THRESHOLD> indicates the threshold the sum of energy
needs to exceed to be counted as time of arrival.
Additionally, for silicon pixels, time of the last energy deposit
(within the time window) is recorded.
3. Output
---------
Output with event signal is stored in ntuple and saved to a ROOT file.
Its name can be set with UI command:
/HGCalTestbeam/output/file <NAME>
Created TTree "hits" contains following branches:
+---------------------------------+-----------------+------+-------------------------------------------+
| Branch | Type | Unit | Description |
+---------------------------------+-----------------+------+-------------------------------------------+
| event | int | - | |
| pdgID | vector<int> | - | PDG code of primary particles |
| beamEnergy | vector<double> | GeV | initial energy of primaries |
| beamX_cm | vector<double> | cm | initial X position of primaries |
| beamY_cm | vector<double> | cm | initial Y position of primaries |
| beamZ_cm | vector<double> | cm | initial Z position of primaries |
| siliconHits_ID | vector<int> | - | ID of hits in Si (=1e3*waferID+cellID) |
| siliconHits_x_cm | vector<double> | cm | X position of Si pixel |
| siliconHits_y_cm | vector<double> | cm | Y position of Si pixel |
| siliconHits_z_cm | vector<double> | cm | Z position of Si pixel |
| siliconHits_Edep_keV | vector<double> | keV | energy deposited within Si pixel |
| siliconHits_EdepNonIonizing_keV | vector<double> | keV | non-ionizing energy deposit (Si) |
| siliconHits_TOA_ns | vector<double> | ns | time of arrival for Si pixel |
| siliconHits_TOA_last_ns | vector<double> | ns | time of last arrival for Si pixel |
| siliconHits_type | vector<int> | - | hit type for Si pixel (=0) |
| SiPMHits_ID | vector<int> | - | ID of hits in SiPM (=1e3*sensorID+cellID) |
| SiPMHits_x_cm | vector<double> | cm | X position of SiPM |
| SiPMHits_y_cm | vector<double> | cm | Y position of SiPM |
| SiPMHits_z_cm | vector<double> | cm | Z position of SiPM |
| SiPMHits_Edep_keV | vector<double> | keV | energy deposited within SiPM |
| SiPMHits_EdepNonIonizing_keV | vector<double> | keV | non-ionizing energy deposit (SiPM) |
| SiPMHits_TOA_ns | vector<double> | ns | time of arrival for SiPM |
| SiPMHits_type | vector<int> | - | hit type for SiPM (= 1) |
| signalSum_HGCAL_GeV | double | GeV | sum of energy deposited in Si pixels |
| COGZ_HGCAL_cm | double | cm | energy-weighted shower depth in z |
| NHits_HGCAL | int | - | number of Si pixel hits |
| signalSum_AHCAL_GeV | double | GeV | sum of energy deposited in SiPMs |
| COGZ_AHCAL_cm | double | cm | energy-weighted shower depth in z |
| NHits_AHCAL | int | - | number of SiPM hits |
+---------------------------------+-----------------+------+-------------------------------------------+
4. Primary particle generator
-----------------------------
Particle gun is used as a default primary particle generator.
It can be controlled with standard UI commands (/gun/) and with
additional ones introduced by the messenger:
/HGCalTestbeam/generator/momentumSpread <VALUE>
to change constant particle energy to Gaussian distribution with
sigma expressed in units of the initial energy (e.g. <VALUE>=0.05
means sigma of 0.05 * E). By default it equals to 0 and constant
energy value is used.
/HGCalTestbeam/generator/beamSpread <none/Gaussian/flat>
to define type of beam position spread. By default none is used.
/HGCalTestbeam/generator/beamSpreadX <SIZE>
to define size of beam spread along x axis. It is sigma of a
Gaussian distribution, or half-width of a flat distribution.
/HGCalTestbeam/generator/beamSpreadY <SIZE>
to define size of beam spread along y axis. It is sigma of a
Gaussian distribution, or half-width of a flat distribution.
/HGCalTestbeam/generator/fBeamZ0 <POSITION>
to define beam position along z axis. By default edge of the
world volume is used.
Additionally, if installation was done with ROOT package (CMake
was able to locate it), an option of input read from the ROOT file
is enabled. It can be activated with
/HGCalTestbeam/generator/fReadInputFile true
/HGCalTestbeam/generator/fPathInputFile <FILE>
sets the path to the input file.
/HGCalTestbeam/generator/startFromEvent <N>
allows to start simulation from Nth event.
Please note that in current implementation input from file needs to be
executed in a non-multithreaded mode (or with 1 thread).
Input file needs to have following structure:
- TDirectory "VirtualDetector"
- TNtuple "HGCAL" with branches:
+---------+-------+------+-------------------------------+
| Branch | Type | Unit | Description |
+---------+-------+------+-------------------------------+
| EventID | float | - | ID of event |
| PDGid | float | - | Particle type (PDG code) |
| x | float | mm | Initial X position |
| y | float | mm | Initial Y position |
| Px | float | MeV | Initial momentum along X axis |
| Py | float | MeV | Initial momentum along Y axis |
| Pz | float | MeV | Initial momentum along Z axis |
+---------+-------+------+-------------------------------+
Several particles may belong to the same event, in which case all
of them are read from the input file.
Z position is set to Z position of the entrance of the HGCal detector.
5. How to run the example
-------------------------
Example can be run in interactive mode, with visualisation:
./HGCal_testbeam
It will execute init_vis.mac and vis.mac.
To run in a batch mode, specify the path to the macro:
./HGCal_testbeam run.mac
which will run 10 single-electron events, with beam energy of 30 GeV.
The beam position is smeared with Gaussian with x/y sigma of 1.5 cm.
The momentum is smeared with Gaussian with sigma of 5% (2.5 GeV).
Z beam position is set to -1 m.
Maximum step size in Si pixel is 20 um.
The name of the created file is output_eM_smeared_30GeV_10events.root.
6. Additional settings
----------------------
6.1. Particle input from ROOT file
----------------------------------
If ROOT is found by CMake, it allows to use ROOT file as the input to
the primary generator. See more in the description of "4. Primary
particle generator".
./HGCal_testbeam readFromFile.mac
Macro readFromFile.mac can be used but name of the input file should
be specified (not provided with the example). This mode is meant to
be used in the validation with experimental data with geant-val.
@@ -0,0 +1,131 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction.hh"
#include "ActionInitialization.hh"
#include "G4RunManagerFactory.hh"
#include "G4UImanager.hh"
#include "FTFP_BERT.hh"
#include "FTFPCMS_BERT_EMM.hh"
#include "G4PhysListFactory.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
#include "Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main(int argc,char** argv)
{
// Detect interactive mode (if no arguments) and define UI session
//
G4UIExecutive* ui = 0;
if ( argc == 1 ) {
ui = new G4UIExecutive(argc, argv);
}
// Choose the Random engine
G4Random::setTheEngine(new CLHEP::RanecuEngine);
// Initialization of Run manager
auto* runManager =
G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default);
// Set mandatory initialization classes
//
// Detector construction
runManager->SetUserInitialization(new DetectorConstruction());
// Physics List name defined via environment variable
// or the default FTFP_BERT is used
G4VModularPhysicsList* physicsList = nullptr;
G4String physName = "";
char* PLenv = std::getenv("PHYSLIST");
if (PLenv)
physName = G4String(PLenv);
if ("FTFP_BERT_EMM" == physName || "FTFPCMS_BERT_EMM" == physName)
physicsList = new FTFPCMS_BERT_EMM;
else if ("" == physName)
{
physName = "FTFP_BERT";
physicsList = new FTFP_BERT;
}
if (!physicsList)
{
G4PhysListFactory factory;
physicsList = factory.GetReferencePhysList(physName);
}
if (!physicsList)
{
G4ExceptionDescription msg;
msg << "Unknown physics list defined in environment variable PHYSLIST: " << PLenv << "\n";
msg<< "Consider extension of main to take it into account.\n";
G4Exception("HGCal_testbeam::main()", "UnknownPhysicsList", FatalException, msg);
}
physicsList->SetVerboseLevel(1);
runManager->SetUserInitialization(physicsList);
// User action initialization
runManager->SetUserInitialization(new ActionInitialization());
// Get the pointer to the User Interface manager
G4UImanager* UImanager = G4UImanager::GetUIpointer();
// Process macro or start UI session
//
if ( ! ui ) {
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand(command+fileName);
}
else {
// Initialize visualization
G4VisManager *visManager = new G4VisExecutive;
// G4VisExecutive can take a verbosity argument - see /vis/verbose guidance.
// G4VisManager* visManager = new G4VisExecutive("Quiet");
visManager->Initialize();
// interactive mode
//UImanager->ApplyCommand("/control/execute init_vis.mac");
UImanager->ApplyCommand("/control/execute init_vis.mac");
ui->SessionStart();
delete ui;
delete visManager;
}
// Job termination
// Free the store: user actions, physics_list and detector_description are
// owned and deleted by the run manager, so they should not be deleted
// in the main() program !
delete runManager;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -0,0 +1,48 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef ACTIONINITIALIZATION_HH
#define ACTIONINITIALIZATION_HH
#include "G4VUserActionInitialization.hh"
/**
* @brief Initialization of user actions.
*
* Initialises the primary generator, and user actions (event, run) to store
* output.
*
*/
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization();
virtual ~ActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
};
#endif /* ACTIONINITIALIZATION_HH */
@@ -0,0 +1,51 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef CMSEMSTANDARDPHYSICSHCAL_HH
#define CMSEMSTANDARDPHYSICSHCAL_HH
#include "G4VPhysicsConstructor.hh"
/**
* @brief EM physics
*
* Used in FTFPCMS_BERT_EMM physics list. Copy from test46.
*
*/
class CMSEmStandardPhysicsHcal : public G4VPhysicsConstructor {
public:
explicit CMSEmStandardPhysicsHcal(G4int ver);
virtual ~CMSEmStandardPhysicsHcal();
virtual void ConstructParticle();
virtual void ConstructProcess();
private:
G4int fVerbose = 0;
};
#endif /* CMSEMSTANDARDPHYSICSHCAL_HH */
@@ -0,0 +1,88 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION_HH
#define DETECTORCONSTRUCTION_HH
#include "G4VUserDetectorConstruction.hh"
#include "G4Types.hh"
#include <utility>
#include <vector>
class G4VPhysicalVolume;
class G4LogicalVolume;
class G4GenericMessenger;
class HGCalTBMaterials;
/**
* @brief Detector construction.
*
* Creates a detector with a configuration set by UI commands. By default a test
* module is build (few elements including a silicon sensor).
* Sensitive detectors are attached to silicon sensors.
*
*/
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction();
virtual ~DetectorConstruction();
virtual G4VPhysicalVolume *Construct();
virtual void ConstructSDandField();
private:
/// Define UI commands: configuration of detector (geometry setup), and
/// maximal step size in silicon
void DefineCommands();
/// Set detector setup configuration based on ID
/// @param[in] aValue ID of detector configuration
void SelectConfiguration(G4int aValue);
/// Set maximal size of step within silicon sensor
/// Can be changed by the UI command /HGCalTestbeam/setup/stepSilicon
/// @param[in] aValue Max step size
void SetStepSizeSilicon(G4double aValue);
/// Helper method placing the logical volumes from map of elements
void ConstructHGCal();
/// Pointer to the logical volume of the world
G4LogicalVolume *fLogicWorld = nullptr;
/// Pointer to the messenger for UI commands
G4GenericMessenger *fMessenger = nullptr;
/// Pointer to the class that defines materials and logical volumes of all
/// possible elements, to be placed according to the configuration setup
HGCalTBMaterials *fMaterials = nullptr;
/// Map of elements to be placed along z axis: name and distance to the
/// previous element is specified
std::vector<std::pair<G4String, G4double>> fElementsMap;
/// Viewpoint for the visualisation
G4double fVisViewpoint = 0;
/// Configuration of the detector setup
/// Can be changed by the UI command /HGCalTestbeam/setup/configuration
G4int fConfiguration = 0;
};
#endif /* DETECTORCONSTRUCTION_HH */
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION0_HH
#define DETECTORCONSTRUCTION0_HH
#include "G4String.hh"
#include "G4Types.hh"
#include <vector>
#include <utility>
/// Add module of silicon sensor with absorbers, readout, and support, for the
/// electromagnetic calorimeter (EE).
/// @param[in] aEEid ID of module in the setup (not all modules are identical)
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[in] aAirBefore How much air should be added before the current module
/// (before the first iron)
/// @param[in] aAirMid How much air should be added in the middle (before the
/// first PCB)
void add_EE(G4int aEEid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid);
/// Add module of scintillator sensor with absorbers, readout, and support, for
/// the hadronic calorimeter (FH).
/// @param[in] aFHid ID of module in the setup (not all modules are identical)
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[in] aAirBefore How much air should be added before the current module
/// (before the first iron)
/// @param[in] aAirMid How much air should be added in the middle (before the
/// first PCB)
void add_FH(G4int aFHid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid);
/// Define detector setup for test beam run in October 2018
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[out] aViewpoint Targer point to be set in the visualisation
void DetectorConstruction0(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint);
#endif /* DETECTORCONSTRUCTION0_HH */
@@ -0,0 +1,45 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION1_HH
#define DETECTORCONSTRUCTION1_HH
#include "G4String.hh"
#include "G4Types.hh"
#include <vector>
#include <utility>
/// Define detector setup for test beam run in October 2018
/// Include the beamline elements in the simulation.
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[out] aViewpoint Targer point to be set in the visualisation
void DetectorConstruction1(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint);
#endif /* DETECTORCONSTRUCTION1_HH */
@@ -0,0 +1,42 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef DETECTORCONSTRUCTION2_HH
#define DETECTORCONSTRUCTION2_HH
#include "G4Types.hh"
#include "G4String.hh"
#include <utility>
#include <vector>
/// Define test setup
/// @param[out] aDzMap List of element names and air gap to be placed in front
/// of the element
/// @param[out] aViewpoint Targer point to be set in the visualisation
void DetectorConstruction2(std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint);
#endif /* DETECTORCONSTRUCTION2_HH */
@@ -0,0 +1,129 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef EVENTACTION_HH
#define EVENTACTION_HH
#include "G4UserEventAction.hh"
#include "G4Types.hh"
#include <vector>
class G4GenericMessenger;
/**
* @brief Event action class
*
* Fills ntuples with information about hits in sensitive detectors.
*
*/
class EventAction : public G4UserEventAction {
public:
EventAction();
virtual ~EventAction();
virtual void BeginOfEventAction(const G4Event *event);
virtual void EndOfEventAction(const G4Event *event);
/// Vector of primary particles in an event: PDG type
std::vector<G4int> fPrimariesPDG;
/// Vector of primary particles in an event: particle energy (in GeV)
std::vector<G4double> fPrimariesEnergy;
/// Vector of primary particles in an event: vertex position x (in cm)
std::vector<G4double> fPrimariesX;
/// Vector of primary particles in an event: vertex position y (in cm)
std::vector<G4double> fPrimariesY;
/// Vector of primary particles in an event: vertex position z (in cm)
std::vector<G4double> fPrimariesZ;
/// Vector of hits in silicon sensors: hit ID
std::vector<G4int> fSiHitsID;
/// Vector of hits in silicon sensors: hit position x (in cm)
std::vector<G4double> fSiHitsX;
/// Vector of hits in silicon sensors: hit position y (in cm)
std::vector<G4double> fSiHitsY;
/// Vector of hits in silicon sensors: hit position z (in cm)
std::vector<G4double> fSiHitsZ;
/// Vector of hits in silicon sensors: hit energy (in keV)
std::vector<G4double> fSiHitsEdep;
/// Vector of hits in silicon sensors: hit non-ionizing energy (in keV)
std::vector<G4double> fSiHitsEdepNonIonising;
/// Vector of hits in silicon sensors: hit time of arrival (in ns)
/// calculated as global time of energy deposit which added to hit energy
/// exceeds the toa threshold (by default threshold is 0, so it is the first
/// deposit)
std::vector<G4double> fSiHitsTOA;
/// Vector of hits in silicon sensors: hit time of last arrival (in ns)
/// calculated as global time of energy deposit which is the last deposit
/// that fits within the digitisation time window (by default window is
/// undefined, so it is the last deposit)
std::vector<G4double> fSiHitsTOAlast;
/// Vector of hits in silicon sensors: hit type
/// Simulation defines only hits of type 0 (hexagonal cells, no calibration or
/// edge cell is constructed)
std::vector<G4int> fSiHitsType;
/// Vector of hits in SiPM: hit ID
std::vector<G4int> fSiPMhitsID;
/// Vector of hits in SiPM: hit position x (in cm)
std::vector<G4double> fSiPMhitsX;
/// Vector of hits in SiPM: hit position y (in cm)
std::vector<G4double> fSiPMhitsY;
/// Vector of hits in SiPM: hit position z (in cm)
std::vector<G4double> fSiPMhitsZ;
/// Vector of hits in SiPM: hit energy (in keV)
std::vector<G4double> fSiPMhitsEdep;
/// Vector of hits in SiPM: hit non-ionizing energy (in keV)
std::vector<G4double> fSiPMhitsEdepNonIonising;
/// Vector of hits in SiPM: hit time of last arrival (in ns)
/// calculated as global time of energy deposit which is the last deposit
/// that fits within the digitisation time window (by default window is
/// undefined, so it is the last deposit)
std::vector<G4double> fSiPMhitsTOA;
/// Vector of hits in silicon sensors: hit type
/// Simulation defines only hits of type 1
std::vector<G4int> fSiPMhitsType;
private:
/// Define UI commands: digitisation of hits with the time cut on deposits
/// (time window), and the energy threshold for the first deposit counted as
/// the time of arrival
void DefineCommands();
/// Pointer to the messenger for UI commands
G4GenericMessenger *fMessenger = nullptr;
/// Time window for hit digitisation (in ns)
/// By default undefined window indicates the last created deposit will set up
/// the time
/// Can be changed by the UI command /HGCalTestbeam/hits/timeCut
G4double fHitTimeCut = -1;
/// Time of arrival threshold (in keV)
/// Default value of 0 indicates the first created deposit will set up the
/// time, independent on the amount of deposited energy
/// Can be changed by the UI command /HGCalTestbeam/hits/toaThreshold
G4double fToaThreshold = 0;
};
#endif /* EVENTACTION_HH */
@@ -0,0 +1,47 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef FTFPCMS_BERT_EMM_HH
#define FTFPCMS_BERT_EMM_HH
#include "G4VModularPhysicsList.hh"
/**
* @brief FTFPCMS_BERT_EMM physics list
*
* FTFPCMS_BERT_EMM physics list. Copy from test46.
*
*/
class FTFPCMS_BERT_EMM : public G4VModularPhysicsList {
public:
explicit FTFPCMS_BERT_EMM(G4int ver = 1);
virtual ~FTFPCMS_BERT_EMM();
virtual void SetCuts();
};
#endif /* FTFPCMS_BERT_EMM_HH */
@@ -0,0 +1,210 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef HGCALTBMATERIALS_HH
#define HGCALTBMATERIALS_HH
#include "G4Types.hh"
#include "G4String.hh"
#include "CLHEP/Units/SystemOfUnits.h"
#include <map>
class G4Box;
class G4LogicalVolume;
class G4Material;
class G4SubtractionSolid;
/// Construction of a hexagon solid
/// @param[in] name Name of the solid
/// @param[in] cellThickness Thickness of the hexagon
/// @param[in] cellSideLength Length of a side of the haxagon
/// @return Solid
G4SubtractionSolid *HexagonSolid(G4String name, G4double cellThickness,
G4double cellSideLength);
/// Construction of a logical volume
/// @param[in] name Name of the solid
/// @param[in] cellThickness Thickness of the hexagon
/// @param[in] cellSideLength Length of a side of the haxagon
/// @param[in] material Material
/// @return Logical volume
G4LogicalVolume *HexagonLogical(G4String name, G4double cellThickness,
G4double cellSideLength, G4Material *material);
/**
* @brief HGCal material and elements definitions
*
* Defines materials used for HGCal test-beam.
* Creates logical volumes for every element that may be constructed and placed
* in the test beam.
*
*/
class HGCalTBMaterials {
public:
/// Create HGCal materials
HGCalTBMaterials();
/// Set visualisation attributes
void SetEventDisplayColorScheme();
/// Get length of the beam line (world)
inline G4double GetBeamLineLength() const { return fBeamLineLength; }
/// Get transverse size of the beam line (world)
inline G4double GetBeamLineXY() const { return fBeamLineXY; }
/// Get pointer to the air material
G4Material *GetAir() { return fMatAIR; }
/// Place logical volume
/// @param[in] aName Name of the logical volume
/// @param[in,out] aZ0 Position in front of the logical volume, incremented by
/// half the thickness for placement, and by another half thickness to return
/// the position just behind the placed volume
/// @param[in] aLogicMother Pointer to mother volume for placement
void PlaceItemInLogicalVolume(std::string aName, G4double &aZ0,
G4LogicalVolume *aLogicMother);
/// Get logical volume of silicon pixel (cell)
G4LogicalVolume *GetSiPixelLogical() { return this->fSiPixelLogical; }
/// Get logical volume of SiPM
G4LogicalVolume *GetAHCALSiPMlogical() { return this->fAHCALSiPMlogical; }
/// Get any logical volume by name
inline const G4LogicalVolume *GetLogicalVolume(G4String aName) {
return fLogicalVolumeMap[aName];
};
/// Get thickness of logical volume by name
inline G4double GetThickness(std::string aName) {
return fThicknessMap[aName];
};
private:
/// Define materisals used in HGCal test-beam
void DefineMaterials();
/// Define silicon wafer logical volume from silicon cells/pixels
void DefineSiWaferAndCells();
/// Define logical volumes for HGCal baseplates (CuW, Cu, PCB, Kapton layers)
void DefineHGCalBaseplates();
/// Define logical volumes for HGCal cases (Al, Steel)
void DefineHGCalCases();
/// Define logical volumes for HGCal electromagnetic part absorbers (Pb, Cu,
/// W)
void DefineHGCalEEAbsorbers();
/// Define logical volumes for HGCal hadronic part absorbers (Cu, Fe)
void DefineHGCalFHAbsorbers();
/// Define logical volumes for AHCAL SiPM
void DefineAHCALSiPM();
/// Define logical volumes for AHCAL absorbers
void DefineAHCALAbsorbers();
/// Define logical volumes for beamline elements (MCP, scintillators, DWC)
void DefineBeamLineElements();
/// Length of the beam line
G4double fBeamLineLength = 90 * CLHEP::m;
/// Transverse dimension of the beam line
G4double fBeamLineXY = 4 * CLHEP::m;
/// Rotation angle of silicon hexagon
G4double fAlpha;
/// Side length of silicon cell hexagon
G4double fSiPixelSideLength;
/// Thickness of silicon wafer hexagon
G4double fSiWaferThickness;
/// Side length of silicon wafer haxagon
G4double fSiWaferSideLength;
/// Transverse size of AHCAL SiPM
G4double fAHCALSiPMxy;
/// Box representing AHCAL SiPM
G4Box *fAHCALSiPMsolid;
/// Map of volume name to its thickness
std::map<G4String, G4double> fThicknessMap;
/// Map of volume name to its logical volume
std::map<G4String, G4LogicalVolume *> fLogicalVolumeMap;
/// Map of volume name to counter of placed copies
std::map<G4String, int> fCopyCounterMap;
/// Materials
G4Material *fMatVacuum;
G4Material *fMatAIR;
G4Material *fMatAr;
G4Material *fMatAl;
G4Material *fMatFe;
G4Material *fMatGlass;
G4Material *fMatSteel;
G4Material *fMatPb;
G4Material *fMatCu;
G4Material *fMatW;
G4Material *fMatSi;
G4Material *fMatKAPTON;
G4Material *fMatAu;
G4Material *fMatPCB;
G4Material *fMatQuartz;
G4Material *fMatPolystyrene;
G4Material *fMatCuW;
G4Material *fMatC;
G4Material *fMatH;
G4Material *fMatO;
G4Material *fMatMn;
G4Material *fMatCr;
G4Material *fMatNi;
G4Material *fMatPolyethylene;
G4Material *fMatFreon;
G4Material *fMatScintillator;
G4Material *fMatArCO2;
G4Material *fMatCl;
G4Material *fMatF;
/// Logical volumes
G4LogicalVolume *fSiPixelLogical;
G4LogicalVolume *fSiWaferLogical;
G4LogicalVolume *fCuWbaseplateLogical;
G4LogicalVolume *fCuWbaseplate550umLogical;
G4LogicalVolume *fCuWbaseplate610umLogical;
G4LogicalVolume *fCuWbaseplate710umLogical;
G4LogicalVolume *fCuBaseplateLogical;
G4LogicalVolume *fCuBaseplate25umLogical;
G4LogicalVolume *fCuBaseplate175umLogical;
G4LogicalVolume *fPCBbaseplateLogical;
G4LogicalVolume *fPCBbaseplateThinLogical;
G4LogicalVolume *fKaptonLayerLogical;
G4LogicalVolume *fAlCaseLogical;
G4LogicalVolume *fAlCaseThickLogical;
G4LogicalVolume *fAlChipLogical;
G4LogicalVolume *fSteelCaseLogical;
G4LogicalVolume *fSteelCaseThickLogical;
G4LogicalVolume *fPbAbsorberEElogical;
G4LogicalVolume *fFeAbsorberEElogical;
G4LogicalVolume *fCuAbsorberEElogical;
G4LogicalVolume *fWabsorberEElogical;
G4LogicalVolume *fW2mmAbsorberEEDESY2018Logical;
G4LogicalVolume *fW4mmAbsorberEEDESY2018Logical;
G4LogicalVolume *fCuAbsorberFHlogical;
G4LogicalVolume *fFeAbsorberFHlogical;
G4LogicalVolume *fAHCALSiPMlogical;
G4LogicalVolume *fAHCALSiPM2x2HUBlogical;
G4LogicalVolume *fAlAbsorberAHCALlogical;
G4LogicalVolume *fPCBAHCALlogical;
G4LogicalVolume *fFeAbsorberAHCALlogical;
G4LogicalVolume *fScintillatorLogical;
G4LogicalVolume *fScintillatorThinLogical;
G4LogicalVolume *fMCPlogical;
G4LogicalVolume *fDWClogical;
G4LogicalVolume *fDWCgasLogical;
G4LogicalVolume *fCK3logical;
};
#endif /* HGCALTBMATERIALS_HH */
@@ -0,0 +1,224 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef PRIMARYGENERATORACTION_HH
#define PRIMARYGENERATORACTION_HH
#include "G4String.hh"
#include "G4VUserPrimaryGeneratorAction.hh"
#include "CLHEP/Units/SystemOfUnits.h"
class G4ParticleGun;
class G4Event;
class G4Box;
class PrimaryGeneratorMessenger;
#ifdef WITHROOT
#include <RtypesCore.h>
class TFile;
class TTreeReader;
template <typename T> class TTreeReaderValue;
#endif
/**
* @brief Primary generator
*
* Primary generator action.
*
* By default particle gun is used. It can be controlled with standard UI
* commands (/gun/) and with additional ones introduced by the messenger.
* "/HGCalTestbeam/generator/momentumSpread <VALUE>" to change constant
* particle energy to Gaussian distribution with sigma expressed in units of the
* initial energy (e.g. value 0.05 means sigma of 0.05 * E).
* By default it equals to 0 and constant energy value is used.
* "/HGCalTestbeam/generator/beamSpread <none/Gaussian/flat>" to define type of
* beam position spread. By default none is used.
* "/HGCalTestbeam/generator/beamSpreadX <SIZE>" to define size of beam spread
* along x axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/beamSpreadY <SIZE>" to define size of beam spread
* along y axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/fBeamZ0 <POSITION>" to define beam position along z
* axis. By default edge of the world volume is used.
*
* If installation was done with ROOT package (CMake was able to locate it),
* an additional option of input read from the ROOT file is enabled.
* It can be activated with "/HGCalTestbeam/generator/fReadInputFile true".
* "/HGCalTestbeam/generator/fPathInputFile <FILE>" sets the path to the input
* file.
* "/HGCalTestbeam/generator/startFromEvent <N>" allows to start simulation from
* Nth event.
* Please note that in current implementation input from file needs to be
* executed in a non-multithreaded mode (or with 1 thread).
*
*/
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
public:
PrimaryGeneratorAction();
virtual ~PrimaryGeneratorAction();
virtual void GeneratePrimaries(G4Event *);
const G4ParticleGun *GetParticleGun() const { return fParticleGun; }
#ifdef WITHROOT
/// Open input file with list of particles
void OpenInput();
/// Set flag indicating that particles should be read from file
inline void SetIfUseInputFiles(G4bool aUseInputFiles) {
fReadInputFile = aUseInputFiles;
};
/// Set the flag indicating that particles should be read from file
inline G4bool GetIfUseInputFiles() { return fReadInputFile; }
/// Set the path to the input file
inline void SetInputFiles(G4String aInputFiles) {
fPathInputFile = aInputFiles;
};
/// Get the path to the input file
inline G4String GetInputFiles() const { return fPathInputFile; }
/// Set ID of the first event to be read for the simulation
inline void SetStartFromEvent(G4int aStartFromEvent) {
fStartFromEvent = aStartFromEvent;
};
/// Get ID of the first event to be read for the simulation
inline G4int GetStartFromEvent() const { return fStartFromEvent; }
#endif
/// Set sigma of the Gaussian distribution for the momentum spread
/// @param[in] aMomentumSpread sigma of Gaussian distribution expressed in
/// units of initial energy (e.g. 0.05 means sigma = 0.05 * E)
inline void SetMomentumSpread(G4double aMomentumSpread) {
fMomentumGaussianSpread = aMomentumSpread;
};
/// Get sigma of the Gaussian distribution for the momentum spread
inline G4double GetMomentumSpread() const { return fMomentumGaussianSpread; }
/// Set type of beam position spread
/// @param[in] aType Type of beam position spread: "none", "Gaussian" or
/// "flat". By default "none" is used.
inline void SetBeamSpreadType(G4String aType) {
if (aType == "none")
fBeamType = eNone;
if (aType == "Gaussian")
fBeamType = eGaussian;
if (aType == "flat")
fBeamType = eFlat;
}
/// Get type of beam position spread
inline G4String GetBeamSpreadType() const {
switch (fBeamType) {
case eNone:
return "none";
break;
case eGaussian:
return "Gaussian";
break;
case eFlat:
return "flat";
break;
}
return "";
}
/// Set size of beam position spread along X axis
/// @param[in] aBeamSpreadX Size of beam position spread. Sigma for Gaussian
/// distribution or half-width of flat distribution.
inline void SetBeamSpreadX(G4double aBeamSpreadX) {
fSigmaBeamX = aBeamSpreadX;
}
/// Get size of beam position spread along X axis
inline G4double GetBeamSpreadX() const { return fSigmaBeamX; }
/// Set size of beam position spread along Y axis
/// @param[in] aBeamSpreadY Size of beam position spread. Sigma for Gaussian
/// distribution or half-width of flat distribution.
inline void SetBeamSpreadY(G4double aBeamSpreadY) {
fSigmaBeamY = aBeamSpreadY;
}
/// Get size of beam position spread along Y axis
inline G4double GetBeamSpreadY() const { return fSigmaBeamY; }
/// Set initial beam position along Z axis
/// By default edge of world volume is used
inline void SetBeamZ0(G4double aBeamZ0) { fBeamZ0 = aBeamZ0; }
/// Get initial beam position along Z axis
inline G4double GetBeamZ0() const { return fBeamZ0; }
private:
/// Pointer to the particle gun
G4ParticleGun *fParticleGun;
/// Pointer to the world volume for initial beam position
G4Box *fEnvelopeBox;
/// Pointer to the messenger with custom UI commands
PrimaryGeneratorMessenger *fMessenger;
/// enum describing the beam position spread in transverse plane
enum eBeamType { eNone, eGaussian, eFlat };
/// Type of beam position spread in transverse dimension
eBeamType fBeamType = eBeamType::eNone;
/// Size of beam position spread along X axis
/// Sigma for Gaussian, and half-width for flat distribution
G4double fSigmaBeamX = 0;
/// Size of beam position spread along Y axis
/// Sigma for Gaussian, and half-width for flat distribution
G4double fSigmaBeamY = 0;
/// Initial beam position along Z axis
G4double fBeamZ0 = -999 * CLHEP::m;
/// Sigma of Gaussian momentum spread
G4double fMomentumGaussianSpread = 0;
#ifdef WITHROOT
/// Flag indicating if primaries should be read from file instead of using
/// the particle gun
G4bool fReadInputFile = false;
/// Path to the input file
G4String fPathInputFile = "";
/// ID of the first event in the file to be used in this simulation
G4int fStartFromEvent = 0;
/// Counter of event
G4int fEventCounter = -1;
/// Pointer to the input file
TFile *fInputFile = nullptr;
/// Pointer to the tree containing particles
TTreeReader *fHgcalReader = nullptr;
/// Reader of event ID
TTreeReaderValue<Float_t> *fHgcalEventId;
/// Reader of particle PDG
TTreeReaderValue<Float_t> *fHgcalPdgId;
/// Reader of particle X position (in mm)
TTreeReaderValue<Float_t> *fHgcalPosX;
/// Reader of particle Y position (in mm)
TTreeReaderValue<Float_t> *fHgcalPosY;
/// Reader of particle Z position (in mm)
TTreeReaderValue<Float_t> *fHgcalPosZ;
/// Reader of particle X momentum (in MeV)
TTreeReaderValue<Float_t> *fHgcalMomX;
/// Reader of particle Y momentum (in MeV)
TTreeReaderValue<Float_t> *fHgcalMomY;
/// Reader of particle Z momentum (in MeV)
TTreeReaderValue<Float_t> *fHgcalMomZ;
#endif
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,110 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef PRIMARYGENERATORMMESSENGER_HH
#define PRIMARYGENERATORMMESSENGER_HH
#include "G4UImessenger.hh"
class G4UIdirectory;
class G4UIcmdWithABool;
class G4UIcmdWithAnInteger;
class G4UIcmdWithAString;
class G4UIcmdWithADouble;
class G4UIcmdWithADoubleAndUnit;
class PrimaryGeneratorAction;
/**
* @brief Primary generator messenger
*
* Defines UI commands to set up the primary generator.
*
* By default particle gun is used as the primary generator. It can be
* controlled with standard UI commands (/gun/).
*
* "/HGCalTestbeam/generator/momentumSpread <VALUE>" to change constant
* particle energy to Gaussian distribution with sigma expressed in units of the
* initial energy (e.g. value 0.05 means sigma of 0.05 * E).
* By default it equals to 0 and constant energy value is used.
* "/HGCalTestbeam/generator/beamSpread <none/Gaussian/flat>" to define type of
* beam position spread. By default none is used.
* "/HGCalTestbeam/generator/beamSpreadX <SIZE>" to define size of beam spread
* along x axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/beamSpreadY <SIZE>" to define size of beam spread
* along y axis. It is sigma of a Gaussian distribution, or half-width of a
* flat distribution.
* "/HGCalTestbeam/generator/beamZ0 <POSITION>" to define beam position along z
* axis. By default edge of the world volume is used.
*
* If installation was done with ROOT package (CMake was able to locate it),
* an additional option of input read from the ROOT file is enabled.
* It can be activated with "/HGCalTestbeam/generator/readInputFile true".
* "/HGCalTestbeam/generator/pathInputFile <FILE>" sets the path to the input
* file.
* "/HGCalTestbeam/generator/startFromEvent <N>" allows to start simulation from
* Nth event.
* Please note that in current implementation input from file needs to be
* executed in a non-multithreaded mode (or with 1 thread).
*
*/
class PrimaryGeneratorMessenger : public G4UImessenger {
public:
explicit PrimaryGeneratorMessenger(PrimaryGeneratorAction *aPrimaryGeneratorAction);
~PrimaryGeneratorMessenger();
public:
void SetNewValue(G4UIcommand *command, G4String newValues);
G4String GetCurrentValue(G4UIcommand *command);
private:
/// Pointer to the primmary generator
PrimaryGeneratorAction *fPrimaryGenerator;
private:
/// Directory for UI commands
G4UIdirectory *fDirectory;
#ifdef WITHROOT
/// Command specyfing if primary event should be read from file
G4UIcmdWithABool *fReadInputCmd;
/// Command to set the path to the input file
G4UIcmdWithAString *fPathInputCmd;
/// Command to set ID of the first event to be read from the file
G4UIcmdWithAnInteger *fStartFromEventCmd;
#endif
/// Command to set the sigma of the Gaussian momentum spread
G4UIcmdWithADouble *fMomentumSpreadCmd;
/// Command to set the type of transverse beam position spread
G4UIcmdWithAString *fBeamSpreadTypeCmd;
/// Command to set the size of beam position spread along X axis
G4UIcmdWithADoubleAndUnit *fBeamSpreadXCmd;
/// Command to set the size of beam position spread along Y axis
G4UIcmdWithADoubleAndUnit *fBeamSpreadYCmd;
/// Command to set the initial beam position size along Z axis
G4UIcmdWithADoubleAndUnit *fBeamZ0Cmd;
};
#endif /*PRIMARYGENERATORMMESSENGER_HH */
@@ -0,0 +1,62 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef RUNACTION_HH
#define RUNACTION_HH
#include "G4UserRunAction.hh"
#include "G4String.hh"
class G4Run;
class EventAction;
class G4GenericMessenger;
/**
* @brief Run action
*
* Creates the output file with ntuple.
* Output name can be changed with UI command "/HGCalTestbeam/output/file
* <NAME>"
*
*/
class RunAction : public G4UserRunAction {
public:
explicit RunAction(EventAction *);
virtual ~RunAction();
virtual void BeginOfRunAction(const G4Run *);
virtual void EndOfRunAction(const G4Run *);
private:
/// Pointer to the event action to retrieve vectors
EventAction *fEventAction;
/// Name of the output file
G4String fOutputFileDir;
/// Pointer to the command messenger
G4GenericMessenger *fMessenger;
};
#endif /* RUNACTION_HH */
@@ -0,0 +1,137 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef SIPMHIT_HHinline
#define SIPMHIT_HHinline
#include "G4THitsCollection.hh"
#include "G4VHit.hh"
#include "G4Types.hh"
#include "G4String.hh"
#include <vector>
/**
* @brief SiPM hit
*
* Stores information of energy deposited in the SiPM.
*
* Hits can be digitised, to take into account the time window for the deposits
* as well as to set the time information based on the energy threshold.
* By default no time window is used (all energy deposits are counted), as well
* as no energy threshold is used (time of the first energy deposit, however
* small, is counted as hit time).
*
*/
class SiPMHit : public G4VHit {
public:
/// Constructor
/// @param[in] aName Name of the pixel volume
/// @param[in] aCopyNoSensor ID of the sensor
/// @param[in] aCopyNoCell ID of the cell
SiPMHit(G4String aName, G4int aCopyNoSensor, G4int aCopyNoCell);
~SiPMHit(){};
/// Get hit ID calculated as 1000 * sensorID + cellID
G4int ID() { return 1000 * fCopyNumSensor + fCopyNumCell; }
/// Add non-zero energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdep(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdep.push_back(std::make_pair(aEnergy, aTime));
}
/// Add non-zero non-ionizing energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdepNonIonizing(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdepNonIonizing.push_back(std::make_pair(aEnergy, aTime));
}
/// Digitise hit
/// Calculate time of hit as global time of energy deposit which added
/// to hit energy exceeds the energy threshold. Take into account only
/// deposits with global time within the timeWindow.
/// @param[in] timeWindow Maximal global time for deposit, caounted from
/// the time of the first deposit
/// @param[in] toaThreshold Energy threshold, first deposit that adds to
/// the hit energy and exceeds the threshold is counted as time of
/// arrival.
void Digitise(const G4double timeWindow, const G4double toaThreshold);
/// Set hit position
/// @param[in] x X position
/// @param[in] y Y position
/// @param[in] z Z position
inline void SetPosition(G4double x, G4double y, G4double z) {
fPosX = x;
fPosY = y;
fPosZ = z;
}
/// Get hit X position
inline G4double GetX() const { return fPosX; }
/// Get hit Y position
inline G4double GetY() const { return fPosY; }
/// Get hit Z position
inline G4double GetZ() const { return fPosZ; }
/// Check if hit is valid
inline G4bool isValidHit() const { return fIsValidHit; }
/// Get hit energy
inline G4double GetEdep() const { return fEdepDigi; }
/// Get hit non-ionizing energy
inline G4double GetEdepNonIonizing() const { return fEdepNonIonizingDigi; }
/// Get time of arrival
inline G4double GetTOA() const { return fTimeOfArrival; }
private:
/// Name of the logical volume
G4String fVolumeName = "";
/// ID of the sensor
G4int fCopyNumCell = -1;
/// ID of the cell
G4int fCopyNumSensor = -1;
/// Position along x axis
G4double fPosX = -1;
/// Position along y axis
G4double fPosY = -1;
/// Position along z axis
G4double fPosZ = -1;
/// Vector of energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdep;
/// Vector of non-ionizing energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdepNonIonizing;
/// Flag indicating if hit is valid (digitised and with non-zero energy)
G4bool fIsValidHit = false;
/// Energy of the digitised hit
G4double fEdepDigi = -1;
/// Non-ionizing energy of the digitised hit
G4double fEdepNonIonizingDigi = -1;
/// Time of arrival of the digitised hit
G4double fTimeOfArrival = -1;
};
typedef G4THitsCollection<SiPMHit> SiPMHitCollection;
#endif /* SIPMHIT_HH */
@@ -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. *
// ********************************************************************
//
#ifndef SIPMSD_HH
#define SIPMSD_HH
#include "SiPMHit.hh"
#include "G4VSensitiveDetector.hh"
#include "G4Types.hh"
#include <map>
/**
* @brief Sensitive detector for SiPMs
*
* Processes step information and stores it in SiPM hits.
* Information is stored in units of:
* - keV for energy
* - cm for position
*
*/
class SiPMSD : public G4VSensitiveDetector {
public:
explicit SiPMSD(G4String name);
~SiPMSD();
/// Hits are processed and added to the temporary map of hit ID to hit
/// pointer. Energy is stored in units of keV, and position in cm.
G4bool ProcessHits(G4Step *step, G4TouchableHistory *ROhist);
void Initialize(G4HCofThisEvent *HCE);
/// Temporary map of hits is stored in hit collection, to be retrieved
/// for analysis by the event action
void EndOfEvent(G4HCofThisEvent *HCE);
private:
/// Hit collection stored in the event, filled in at the end of event based
/// on temporary hits
SiPMHitCollection *fHitCollection = nullptr;
/// ID of hit collection
G4int fHCID = -1;
/// Temporary map of hits (ID: hit) collected within one event
std::map<G4int, SiPMHit *> fTmpHits;
};
#endif /* SIPMSD_HH */
@@ -0,0 +1,142 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef SILICONPIXELHIT_HH
#define SILICONPIXELHIT_HH
#include "G4THitsCollection.hh"
#include "G4VHit.hh"
#include "G4Types.hh"
#include <vector>
/**
* @brief Silicon pixel hit
*
* Stores information of energy deposited in the silicon pixel.
*
* Hits can be digitised, to take into account the time window for the deposits
* as well as to set the time information based on the energy threshold.
* By default no time window is used (all energy deposits are counted), as well
* as no energy threshold is used (time of the first energy deposit, however
* small, is counted as hit time).
*
*/
class SiliconPixelHit : public G4VHit {
public:
/// Constructor
/// @param[in] aName Name of the pixel volume
/// @param[in] aCopyNumSensor ID of the sensor
/// @param[in] aCopyNumCell ID of the cell
SiliconPixelHit(G4String aName, G4int aCopyNumSensor, G4int aCopyNumCell);
~SiliconPixelHit(){};
/// Draw pixels
void Draw();
/// Get hit ID calculated as 1000 * sensorID + cellID
G4int ID() { return 1000 * fCopyNumSensor + fCopyNumCell; }
/// Add non-zero energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdep(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdep.push_back(std::make_pair(aEnergy, aTime));
}
/// Add non-zero non-ionizing energy deposit to vector of deposits
/// @param[in] aEnergy Deposited energy
/// @param[in] aTime Time of deposit
inline void AddEdepNonIonizing(const G4double aEnergy, const G4double aTime) {
if (aEnergy > 0)
fEdepNonIonizing.push_back(std::make_pair(aEnergy, aTime));
}
/// Digitise hit
/// Calculate time of hit as global time of energy deposit which added
/// to hit energy exceeds the energy threshold. Take into account only
/// deposits with global time within the time window.
/// @param[in] aTimeWindow Maximal global time for deposit, caounted from
/// the time of the first deposit
/// @param[in] aToaThreshold Energy threshold, first deposit that adds to
/// the hit energy and exceeds the threshold is counted as time of
/// arrival.
void Digitise(const G4double aTimeWindow, const G4double aToaThreshold);
/// Set hit position
/// @param[in] x X position
/// @param[in] y Y position
/// @param[in] z Z position
inline void SetPosition(G4double x, G4double y, G4double z) {
fPosX = x;
fPosY = y;
fPosZ = z;
}
/// Get hit X position
inline G4double GetX() const { return fPosX; }
/// Get hit Y position
inline G4double GetY() const { return fPosY; }
/// Get hit Z position
inline G4double GetZ() const { return fPosZ; }
/// Check if hit is valid
inline G4bool isValidHit() const { return fIsValidHit; }
/// Get hit energy
inline G4double GetEdep() const { return fEdepDigi; }
/// Get hit non-ionizing energy
inline G4double GetEdepNonIonizing() const { return fEdepNonIonizingDigi; }
/// Get time of arrival
inline G4double GetTOA() const { return fTimeOfArrival; }
/// Get time of arrival from the last energy deposit
inline G4double GetLastTOA() const { return fTimeOfArrivalLast; }
private:
/// Name of the logical volume
G4String fVolumeName = "";
/// ID of the sensor
G4int fCopyNumCell = -1;
/// ID of the cell
G4int fCopyNumSensor = -1;
/// Position along x axis
G4double fPosX = -1;
/// Position along y axis
G4double fPosY = -1;
/// Position along z axis
G4double fPosZ = -1;
/// Vector of energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdep;
/// Vector of non-ionizing energy deposits (and their global time)
std::vector<std::pair<G4double, G4double>> fEdepNonIonizing;
/// Flag indicating if hit is valid (digitised and with non-zero energy)
G4bool fIsValidHit = false;
/// Energy of the digitised hit
G4double fEdepDigi = -1;
/// Non-ionizing energy of the digitised hit
G4double fEdepNonIonizingDigi = -1;
/// Time of arrival of the digitised hit
G4double fTimeOfArrival = -1;
/// Last time of arrival of the digitised hit
G4double fTimeOfArrivalLast = -1;
};
typedef G4THitsCollection<SiliconPixelHit> SiliconPixelHitCollection;
#endif /* SILICONPIXELHIT_HH */
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#ifndef SILICONPIXELSD_HH
#define SILICONPIXELSD_HH
#include "G4VSensitiveDetector.hh"
#include "SiliconPixelHit.hh"
#include "G4Types.hh"
#include <map>
/**
* @brief Sensitive detector for silicon pixels
*
* Processes step information and stores it in silicon hits.
* Information is stored in units of:
* - keV for energy
* - cm for position
*
*/
class SiliconPixelSD : public G4VSensitiveDetector {
public:
explicit SiliconPixelSD(G4String name);
~SiliconPixelSD();
/// Hits are processed and added to the temporary map of hit ID to hit
/// pointer. Energy is stored in units of keV, and position in cm.
G4bool ProcessHits(G4Step *step, G4TouchableHistory *ROhist);
void Initialize(G4HCofThisEvent *HCE);
/// Temporary map of hits is stored in hit collection, to be retrieved
/// for analysis by the event action
void EndOfEvent(G4HCofThisEvent *HCE);
private:
/// Hit collection stored in the event, filled in at the end of event based
/// on temporary hits
SiliconPixelHitCollection *fHitCollection = nullptr;
/// ID of hit collection
G4int fHCID = -1;
/// Temporary map of hits (ID: hit) collected within one event
std::map<G4int, SiliconPixelHit *> fTmpHits;
};
#endif /* SILICONPIXELSD_HH */
@@ -0,0 +1,13 @@
# Macro file for the initialization of example HGCal_testbeam
# in interactive session
#
# Set some default verbose
/control/verbose 2
/control/saveHistory
/run/verbose 2
#
# Initialize kernel
/run/initialize
#
# Visualization setting
/control/execute vis.mac
@@ -0,0 +1,26 @@
# Macro file for sample run of the HGCal testbeam simulation
#
# Set verbosity levels
#/control/verbose 2
#/control/saveHistory
#/run/verbose 2
#/tracking/verbose 2
# Use only one thread
/run/numberOfThreads 1
# Initialize kernel
/run/initialize
# Choose geometry setup
/HGCalTestbeam/setup/configuration 0
# Read input particles from file
/HGCalTestbeam/generator/readInputFile true
# Substitute <INPUTFILE.root> with name of the file
/HGCalTestbeam/generator/pathInputFile INPUTFILE.root
/HGCalTestbeam/generator/startFromEvent 0
/HGCalTestbeam/output/file output_inputFromFile_10events.root
/run/beamOn 10
+32
View File
@@ -0,0 +1,32 @@
# Macro file for sample run of the HGCal testbeam simulation
#
# Set verbosity levels
#/control/verbose 2
#/control/saveHistory
#/run/verbose 2
#/tracking/verbose 2
# Initialize kernel
/run/initialize
# Choose geometry setup
/HGCalTestbeam/setup/configuration 0
# Electrons
/gun/energy 30 GeV
/gun/particle e-
# Smeared beam position and momentum
# 5% Gaussian spread of momentum
/HGCalTestbeam/generator/momentumSpread 0.05
# Gaussian spread of transverse beam position (sigma 1.5 cm)
/HGCalTestbeam/generator/beamSpread Gaussian # none flat
/HGCalTestbeam/generator/beamSpreadX 1.5 cm
/HGCalTestbeam/generator/beamSpreadY 1.5 cm
/HGCalTestbeam/generator/beamZ0 -1 m
# Choose max step in silicon pixel (in um)
/HGCalTestbeam/setup/stepSilicon 20
/HGCalTestbeam/output/file output_eM_smeared_30GeV_10events.root
/run/beamOn 10
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "ActionInitialization.hh"
#include "EventAction.hh"
#include "PrimaryGeneratorAction.hh"
#include "RunAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ActionInitialization::~ActionInitialization() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::BuildForMaster() const {
EventAction *eventAction = new EventAction();
SetUserAction(new RunAction(eventAction));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ActionInitialization::Build() const {
SetUserAction(new PrimaryGeneratorAction);
EventAction *eventAction = new EventAction();
SetUserAction(eventAction);
RunAction *runAction = new RunAction(eventAction);
SetUserAction(runAction);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,381 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "CMSEmStandardPhysicsHcal.hh"
#include "G4EmParameters.hh"
#include "G4LossTableManager.hh"
#include "G4ParticleDefinition.hh"
#include "G4UAtomicDeexcitation.hh"
#include "G4ComptonScattering.hh"
#include "G4GammaConversion.hh"
#include "G4PhotoElectricEffect.hh"
#include "G4CoulombScattering.hh"
#include "G4MuMultipleScattering.hh"
#include "G4UrbanMscModel.hh"
#include "G4WentzelVIModel.hh"
#include "G4eCoulombScatteringModel.hh"
#include "G4eMultipleScattering.hh"
#include "G4hMultipleScattering.hh"
#include "G4eBremsstrahlung.hh"
#include "G4eIonisation.hh"
#include "G4eplusAnnihilation.hh"
#include "G4MuBremsstrahlung.hh"
#include "G4MuIonisation.hh"
#include "G4MuPairProduction.hh"
#include "G4hBremsstrahlung.hh"
#include "G4hIonisation.hh"
#include "G4hPairProduction.hh"
#include "G4ionIonisation.hh"
#include "G4Alpha.hh"
#include "G4AntiLambdacPlus.hh"
#include "G4AntiOmegaMinus.hh"
#include "G4AntiProton.hh"
#include "G4AntiSigmaMinus.hh"
#include "G4AntiSigmaPlus.hh"
#include "G4AntiXiMinus.hh"
#include "G4AntiXicPlus.hh"
#include "G4BMesonMinus.hh"
#include "G4BMesonPlus.hh"
#include "G4DMesonMinus.hh"
#include "G4DMesonPlus.hh"
#include "G4Deuteron.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
#include "G4GenericIon.hh"
#include "G4He3.hh"
#include "G4KaonMinus.hh"
#include "G4KaonPlus.hh"
#include "G4LambdacPlus.hh"
#include "G4MuonMinus.hh"
#include "G4MuonPlus.hh"
#include "G4OmegaMinus.hh"
#include "G4PionMinus.hh"
#include "G4PionPlus.hh"
#include "G4Positron.hh"
#include "G4Proton.hh"
#include "G4SigmaMinus.hh"
#include "G4SigmaPlus.hh"
#include "G4TauMinus.hh"
#include "G4TauPlus.hh"
#include "G4Triton.hh"
#include "G4XiMinus.hh"
#include "G4XicPlus.hh"
#include "G4BuilderType.hh"
#include "G4PhysicsListHelper.hh"
#include "G4RegionStore.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
CMSEmStandardPhysicsHcal::CMSEmStandardPhysicsHcal(G4int ver)
: G4VPhysicsConstructor("CMSEmStandard_emm"), fVerbose(ver) {
G4EmParameters *param = G4EmParameters::Instance();
param->SetDefaults();
param->SetVerbose(fVerbose);
param->SetApplyCuts(true);
param->SetMscRangeFactor(0.2);
param->SetMscStepLimitType(fMinimal);
SetPhysicsType(bElectromagnetic);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
CMSEmStandardPhysicsHcal::~CMSEmStandardPhysicsHcal() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void CMSEmStandardPhysicsHcal::ConstructParticle() {
// gamma
G4Gamma::Gamma();
// leptons
G4Electron::Electron();
G4Positron::Positron();
G4MuonPlus::MuonPlus();
G4MuonMinus::MuonMinus();
G4TauMinus::TauMinusDefinition();
G4TauPlus::TauPlusDefinition();
// mesons
G4PionPlus::PionPlusDefinition();
G4PionMinus::PionMinusDefinition();
G4KaonPlus::KaonPlusDefinition();
G4KaonMinus::KaonMinusDefinition();
G4DMesonMinus::DMesonMinusDefinition();
G4DMesonPlus::DMesonPlusDefinition();
G4BMesonMinus::BMesonMinusDefinition();
G4BMesonPlus::BMesonPlusDefinition();
// barions
G4Proton::Proton();
G4AntiProton::AntiProton();
G4SigmaMinus::SigmaMinusDefinition();
G4AntiSigmaMinus::AntiSigmaMinusDefinition();
G4SigmaPlus::SigmaPlusDefinition();
G4AntiSigmaPlus::AntiSigmaPlusDefinition();
G4XiMinus::XiMinusDefinition();
G4AntiXiMinus::AntiXiMinusDefinition();
G4OmegaMinus::OmegaMinusDefinition();
G4AntiOmegaMinus::AntiOmegaMinusDefinition();
G4LambdacPlus::LambdacPlusDefinition();
G4AntiLambdacPlus::AntiLambdacPlusDefinition();
G4XicPlus::XicPlusDefinition();
G4AntiXicPlus::AntiXicPlusDefinition();
// ions
G4Deuteron::Deuteron();
G4Triton::Triton();
G4He3::He3();
G4Alpha::Alpha();
G4GenericIon::GenericIonDefinition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void CMSEmStandardPhysicsHcal::ConstructProcess() {
if (fVerbose > 0) {
G4cout << "### " << GetPhysicsName() << " Construct Processes " << G4endl;
}
// This EM builder takes default models of Geant4 10 EMV.
// Multiple scattering by Urban for all particles
// except e+e- below 100 MeV for which the Urban93 model is used
G4PhysicsListHelper *ph = G4PhysicsListHelper::GetPhysicsListHelper();
// muon & hadron bremsstrahlung and pair production
G4MuBremsstrahlung *mub = nullptr;
G4MuPairProduction *mup = nullptr;
G4hBremsstrahlung *pib = nullptr;
G4hPairProduction *pip = nullptr;
G4hBremsstrahlung *kb = nullptr;
G4hPairProduction *kp = nullptr;
G4hBremsstrahlung *pb = nullptr;
G4hPairProduction *pp = nullptr;
// muon & hadron multiple scattering
G4MuMultipleScattering *mumsc = nullptr;
G4MuMultipleScattering *pimsc = nullptr;
G4MuMultipleScattering *kmsc = nullptr;
G4MuMultipleScattering *pmsc = nullptr;
G4hMultipleScattering *hmsc = nullptr;
G4CoulombScattering *muss = nullptr;
G4CoulombScattering *piss = nullptr;
G4CoulombScattering *kss = nullptr;
G4CoulombScattering *pss = nullptr;
// high energy limit for e+- scattering models and bremsstrahlung
G4double highEnergyLimit = 100 * CLHEP::MeV;
G4Region *aRegion = G4RegionStore::GetInstance()->GetRegion("HcalRegion");
auto myParticleIterator = GetParticleIterator();
myParticleIterator->reset();
while ((*myParticleIterator)()) {
G4ParticleDefinition *particle = myParticleIterator->value();
G4String particleName = particle->GetParticleName();
if (particleName == "gamma") {
ph->RegisterProcess(new G4PhotoElectricEffect(), particle);
ph->RegisterProcess(new G4ComptonScattering(), particle);
ph->RegisterProcess(new G4GammaConversion(), particle);
} else if (particleName == "e-") {
G4eIonisation *eioni = new G4eIonisation();
eioni->SetStepFunction(0.8, 1.0 * CLHEP::mm);
G4eMultipleScattering *msc = new G4eMultipleScattering;
msc->SetStepLimitType(fMinimal);
G4UrbanMscModel *msc1 = new G4UrbanMscModel();
G4WentzelVIModel *msc2 = new G4WentzelVIModel();
G4UrbanMscModel *msc3 = new G4UrbanMscModel();
msc3->SetLocked(true);
msc1->SetHighEnergyLimit(highEnergyLimit);
msc2->SetLowEnergyLimit(highEnergyLimit);
msc3->SetHighEnergyLimit(highEnergyLimit);
msc->AddEmModel(0, msc1);
msc->AddEmModel(0, msc2);
msc->AddEmModel(-1, msc3, aRegion);
G4eCoulombScatteringModel *ssm = new G4eCoulombScatteringModel();
G4CoulombScattering *ss = new G4CoulombScattering();
ss->SetEmModel(ssm, 1);
ss->SetMinKinEnergy(highEnergyLimit);
ssm->SetLowEnergyLimit(highEnergyLimit);
ssm->SetActivationLowEnergyLimit(highEnergyLimit);
ph->RegisterProcess(msc, particle);
ph->RegisterProcess(eioni, particle);
ph->RegisterProcess(new G4eBremsstrahlung(), particle);
ph->RegisterProcess(ss, particle);
} else if (particleName == "e+") {
G4eIonisation *eioni = new G4eIonisation();
eioni->SetStepFunction(0.8, 1.0 * CLHEP::mm);
G4eMultipleScattering *msc = new G4eMultipleScattering;
msc->SetStepLimitType(fMinimal);
G4UrbanMscModel *msc1 = new G4UrbanMscModel();
G4WentzelVIModel *msc2 = new G4WentzelVIModel();
G4UrbanMscModel *msc3 = new G4UrbanMscModel();
msc1->SetHighEnergyLimit(highEnergyLimit);
msc2->SetLowEnergyLimit(highEnergyLimit);
msc3->SetHighEnergyLimit(highEnergyLimit);
msc3->SetLocked(true);
msc->AddEmModel(0, msc1);
msc->AddEmModel(0, msc2);
msc->AddEmModel(-1, msc3, aRegion);
G4eCoulombScatteringModel *ssm = new G4eCoulombScatteringModel();
G4CoulombScattering *ss = new G4CoulombScattering();
ss->SetEmModel(ssm, 1);
ss->SetMinKinEnergy(highEnergyLimit);
ssm->SetLowEnergyLimit(highEnergyLimit);
ssm->SetActivationLowEnergyLimit(highEnergyLimit);
ph->RegisterProcess(msc, particle);
ph->RegisterProcess(eioni, particle);
ph->RegisterProcess(new G4eBremsstrahlung(), particle);
ph->RegisterProcess(new G4eplusAnnihilation(), particle);
ph->RegisterProcess(ss, particle);
} else if (particleName == "mu+" || particleName == "mu-") {
if (nullptr == mub) {
mub = new G4MuBremsstrahlung();
mup = new G4MuPairProduction();
mumsc = new G4MuMultipleScattering();
mumsc->AddEmModel(0, new G4WentzelVIModel());
muss = new G4CoulombScattering();
}
ph->RegisterProcess(mumsc, particle);
ph->RegisterProcess(new G4MuIonisation(), particle);
ph->RegisterProcess(mub, particle);
ph->RegisterProcess(mup, particle);
ph->RegisterProcess(muss, particle);
} else if (particleName == "alpha" || particleName == "He3") {
ph->RegisterProcess(new G4hMultipleScattering(), particle);
ph->RegisterProcess(new G4ionIonisation(), particle);
} else if (particleName == "GenericIon") {
if (nullptr == hmsc) {
hmsc = new G4hMultipleScattering("ionmsc");
}
ph->RegisterProcess(hmsc, particle);
ph->RegisterProcess(new G4ionIonisation(), particle);
} else if (particleName == "pi+" || particleName == "pi-") {
if (nullptr == pib) {
pib = new G4hBremsstrahlung();
pip = new G4hPairProduction();
pimsc = new G4MuMultipleScattering();
pimsc->AddEmModel(0, new G4WentzelVIModel());
piss = new G4CoulombScattering();
}
ph->RegisterProcess(pimsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
ph->RegisterProcess(pib, particle);
ph->RegisterProcess(pip, particle);
ph->RegisterProcess(piss, particle);
} else if (particleName == "kaon+" || particleName == "kaon-") {
if (nullptr == kb) {
kb = new G4hBremsstrahlung();
kp = new G4hPairProduction();
kmsc = new G4MuMultipleScattering();
kmsc->AddEmModel(0, new G4WentzelVIModel());
kss = new G4CoulombScattering();
}
ph->RegisterProcess(kmsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
ph->RegisterProcess(kb, particle);
ph->RegisterProcess(kp, particle);
ph->RegisterProcess(kss, particle);
} else if (particleName == "proton" || particleName == "anti_proton") {
if (nullptr == pb) {
pb = new G4hBremsstrahlung();
pp = new G4hPairProduction();
pmsc = new G4MuMultipleScattering();
pmsc->AddEmModel(0, new G4WentzelVIModel());
pss = new G4CoulombScattering();
}
ph->RegisterProcess(pmsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
ph->RegisterProcess(pb, particle);
ph->RegisterProcess(pp, particle);
ph->RegisterProcess(pss, particle);
} else if (particleName == "B+" || particleName == "B-" ||
particleName == "D+" || particleName == "D-" ||
particleName == "Ds+" || particleName == "Ds-" ||
particleName == "anti_He3" || particleName == "anti_alpha" ||
particleName == "anti_deuteron" ||
particleName == "anti_lambda_c+" ||
particleName == "anti_omega-" ||
particleName == "anti_sigma_c+" ||
particleName == "anti_sigma_c++" ||
particleName == "anti_sigma+" || particleName == "anti_sigma-" ||
particleName == "anti_triton" || particleName == "anti_xi_c+" ||
particleName == "anti_xi-" || particleName == "deuteron" ||
particleName == "lambda_c+" || particleName == "omega-" ||
particleName == "sigma_c+" || particleName == "sigma_c++" ||
particleName == "sigma+" || particleName == "sigma-" ||
particleName == "tau+" || particleName == "tau-" ||
particleName == "triton" || particleName == "xi_c+" ||
particleName == "xi-") {
if (nullptr == hmsc) {
hmsc = new G4hMultipleScattering("ionmsc");
}
ph->RegisterProcess(hmsc, particle);
ph->RegisterProcess(new G4hIonisation(), particle);
}
}
// Deexcitation
//
G4VAtomDeexcitation *de = new G4UAtomicDeexcitation();
G4LossTableManager::Instance()->SetAtomDeexcitation(de);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,194 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction.hh"
#include "HGCalTBMaterials.hh"
#include "SiPMSD.hh"
#include "SiliconPixelSD.hh"
#include "DetectorConstruction0.hh"
#include "DetectorConstruction1.hh"
#include "DetectorConstruction2.hh"
#include "G4Box.hh"
#include "G4PVPlacement.hh"
#include "G4GenericMessenger.hh"
#include "G4LogicalVolume.hh"
#include "G4ProductionCuts.hh"
#include "G4RunManager.hh"
#include "G4SDManager.hh"
#include "G4UImanager.hh"
#include "G4UserLimits.hh"
#include "G4String.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
: G4VUserDetectorConstruction(), fConfiguration(-1) {
DefineCommands();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume *DetectorConstruction::Construct() {
// definition of the fMaterials
fMaterials = new HGCalTBMaterials();
fMaterials->SetEventDisplayColorScheme();
/***** Definition of the world = beam line *****/
// World = Beam line
G4Box *solidWorld = new G4Box("World", 0.5 * fMaterials->GetBeamLineXY(),
0.5 * fMaterials->GetBeamLineXY(),
0.5 * fMaterials->GetBeamLineLength());
G4Material *world_mat = fMaterials->GetAir();
fLogicWorld = new G4LogicalVolume(solidWorld, world_mat, "World");
G4VPhysicalVolume *physWorld = new G4PVPlacement(
0, G4ThreeVector(0., 0., 0.), fLogicWorld, "World", 0, false, 0, true);
return physWorld;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructHGCal() {
G4double z0 = -fMaterials->GetBeamLineLength() / 2.;
std::cout << "Constructing configuration " << fConfiguration << std::endl;
/***** START GENERIC PLACEMENT ALGORITHM FOR THE SETUP *****/
for (size_t item_index = 0; item_index < fElementsMap.size(); item_index++) {
std::string item_type = fElementsMap[item_index].first;
G4double dz = fElementsMap[item_index].second;
z0 += dz;
// places the item at inside the world at z0, z0 is incremented by the
// item's thickness
fMaterials->PlaceItemInLogicalVolume(item_type, z0, fLogicWorld);
}
G4RunManager::GetRunManager()->GeometryHasBeenModified();
G4UImanager *UImanager = G4UImanager::GetUIpointer();
UImanager->ApplyCommand("/vis/drawVolume");
UImanager->ApplyCommand("/vis/viewer/set/targetPoint 0 0 " +
std::to_string(fVisViewpoint / CLHEP::m) + " m");
UImanager->ApplyCommand("/vis/scene/add/trajectories smooth");
UImanager->ApplyCommand("/vis/scene/add/hits");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::ConstructSDandField() {
G4SDManager *sdman = G4SDManager::GetSDMpointer();
SiliconPixelSD *sensitiveSilicon = new SiliconPixelSD(
(fMaterials->GetSiPixelLogical()->GetName() + "_sensitive").c_str());
sdman->AddNewDetector(sensitiveSilicon);
fMaterials->GetSiPixelLogical()->SetSensitiveDetector(sensitiveSilicon);
SiPMSD *sensitiveSiPM = new SiPMSD(
(fMaterials->GetAHCALSiPMlogical()->GetName() + "_sensitive").c_str());
sdman->AddNewDetector(sensitiveSiPM);
fMaterials->GetAHCALSiPMlogical()->SetSensitiveDetector(sensitiveSiPM);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SelectConfiguration(G4int val) {
if (fConfiguration != -1) {
G4ExceptionDescription msg;
msg << "Configuration " << fConfiguration << " is already placed.\n"
<< "Configuration can be set only once. Please restart (and\n"
<< "edit your macro if necessary).\n";
G4Exception("DetectorConstruction::SelectConfiguration()", "MultipleConfig",
JustWarning, msg);
return;
}
fVisViewpoint = 0;
if (val == 0)
DetectorConstruction0(fElementsMap, fVisViewpoint);
else if (val == 1)
DetectorConstruction1(fElementsMap, fVisViewpoint);
else if (val == 2)
DetectorConstruction2(fElementsMap, fVisViewpoint);
else {
G4ExceptionDescription msg;
msg << "Configuration " << val << " is not implemented.\n"
<< "Choose between configuration 0, 1, and 2.\n";
G4Exception("DetectorConstruction::SelectConfiguration()", "WrongConfig",
JustWarning, msg);
return;
}
fConfiguration = val;
ConstructHGCal();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetStepSizeSilicon(G4double val) {
// setting the step size in silicon:
G4double maxTrackLength = val * 0.001 * CLHEP::mm;
fMaterials->GetSiPixelLogical()->SetUserLimits(
new G4UserLimits(0, maxTrackLength));
G4Region *reg = fMaterials->GetSiPixelLogical()->GetRegion();
G4ProductionCuts *cuts = new G4ProductionCuts;
cuts->SetProductionCut(maxTrackLength);
reg->SetProductionCuts(cuts);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::DefineCommands() {
// define command directory using generic messenger class
fMessenger = new G4GenericMessenger(this, "/HGCalTestbeam/setup/",
"Configuration specifications");
// configuration command
auto &configCmd = fMessenger->DeclareMethod(
"configuration", &DetectorConstruction::SelectConfiguration,
"Select the configuration (0 for HGCal test beam, 1 for same HGCal"
" with beamline (upstream material), or 2 for simple test setup)");
configCmd.SetParameterName("index", true);
configCmd.SetDefaultValue("0");
auto &SiStepSizeCmd = fMessenger->DeclareMethod(
"stepSilicon", &DetectorConstruction::SetStepSizeSilicon,
"Maximum step size in silicon pixels, unit: microns");
SiStepSizeCmd.SetParameterName("size", true);
SiStepSizeCmd.SetDefaultValue("30.");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,227 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction0.hh"
#include "CLHEP/Units/SystemOfUnits.h"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void add_EE(G4int aEEid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid) {
aDzMap.push_back(std::make_pair("Fe_absorber_EE",
aAirBefore)); // aAirBefore AIR + 0.3 mm Fe
aDzMap.push_back(std::make_pair("Pb_absorber_EE", 0)); // 0 + 4.9mm Pb
aDzMap.push_back(std::make_pair("Fe_absorber_EE", 0)); // 0 + 0.3 mm Fe
aDzMap.push_back(std::make_pair("PCB", aAirMid)); // aAirMid AIR +1.3mm
aDzMap.push_back(std::make_pair("Cu_baseplate_175um", 0.)); // 0 + 0.175mm Cu
aDzMap.push_back(std::make_pair("Si_wafer", 0.)); // 0.3 mm
aDzMap.push_back(std::make_pair("Cu_baseplate_25um", 0.)); // 0 + 0.025mm Cu
aDzMap.push_back(std::make_pair("Kapton_layer", 0.)); // 0.075 mm
if (aEEid == 11 || aEEid == 12)
aDzMap.push_back(std::make_pair("Cu_baseplate", 0.)); // 1.2 mm
aDzMap.push_back(std::make_pair("CuW_baseplate", 0.)); // 1.2 mm
if (aEEid == 13)
aDzMap.push_back(std::make_pair("CuW_baseplate_550um", 0.)); // 0.55 mm
if (aEEid == 14)
aDzMap.push_back(std::make_pair("CuW_baseplate_610um", 0.)); // 0.61 mm
aDzMap.push_back(std::make_pair("Cu_absorber_EE", 0.)); // 6 mm
if (aEEid == 13)
aDzMap.push_back(std::make_pair("CuW_baseplate_610um", 0.)); // 0.61 mm
if (aEEid == 14)
aDzMap.push_back(std::make_pair("CuW_baseplate_710um", 0.)); // 0.71 mm
aDzMap.push_back(std::make_pair("CuW_baseplate", 0.)); // 1.2 mm
if (aEEid == 11 || aEEid == 12)
aDzMap.push_back(std::make_pair("Cu_baseplate", 0.)); // 1.2 mm
aDzMap.push_back(std::make_pair("Kapton_layer", 0.)); // 0.075 mm
aDzMap.push_back(std::make_pair("Cu_baseplate_25um", 0.)); // 0 + 0.025mm Cu
aDzMap.push_back(std::make_pair("Si_wafer", 0.)); // 0.3 mm
aDzMap.push_back(std::make_pair("Cu_baseplate_175um", 0.)); // 0 + 0.175mm Cu
aDzMap.push_back(std::make_pair("PCB", 0)); // 1.3 mm
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void add_FH(G4int aFHid, std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double aAirBefore, G4double aAirMid) {
std::string layout = "";
if (aFHid < 10)
layout = "_DAISY";
if (!(aFHid == 1 || aFHid == 7))
aDzMap.push_back(std::make_pair("Fe_absorber_FH",
aAirBefore)); // aAirBefore AIR + 40 mm Fe
aDzMap.push_back(
std::make_pair("PCB" + layout, aAirMid)); // aAirMid AIR + 1.3 mm
aDzMap.push_back(
std::make_pair("Cu_baseplate_175um" + layout, 0.)); // 0.175mm Cu
aDzMap.push_back(std::make_pair("Si_wafer" + layout, 0.)); // 0.3 mm
if (aFHid == 5) {
aDzMap.push_back(std::make_pair("PCB_thin" + layout, 0)); // 1.2 mm
}
if (aFHid != 5) {
aDzMap.push_back(
std::make_pair("Cu_baseplate_25um" + layout, 0.)); // 0.025mm Cu
aDzMap.push_back(std::make_pair("Kapton_layer" + layout, 0.)); // 0.075 mm
}
if (aFHid == 6) {
aDzMap.push_back(
std::make_pair("Cu_baseplate_25um" + layout, 0.)); // 0.025mm Cu
aDzMap.push_back(std::make_pair("Kapton_layer" + layout, 0.)); // 0.075 mm
}
if (aFHid != 5 && aFHid < 9)
aDzMap.push_back(std::make_pair("Cu_baseplate" + layout, 0.)); // 1.2 mm
if (aFHid == 9 || aFHid == 10)
aDzMap.push_back(std::make_pair("CuW_baseplate" + layout, 0.)); // 1.2 mm
if (aFHid != 10)
aDzMap.push_back(std::make_pair("Cu_baseplate" + layout, 0.)); // 1.2 mm
aDzMap.push_back(std::make_pair("Cu_absorber_FH", 0.)); // 6 * mm
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction0(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint) {
aViewpoint = 0.75 * CLHEP::m;
// map means: position this material starting at z, where:
// z += <second>
// z = z0+ 0.5 * thickness[<first>]
// world (and beam) starts at -45 m
G4double firstOffset = 2.6 * CLHEP::cm;
// if no beamline is present - shift by beamline length 45.0015 m
if (aDzMap.size() == 0) {
firstOffset += 45.0015 * CLHEP::m;
}
aDzMap.push_back(std::make_pair("Al_case_thick", firstOffset)); // 5 mm Al
aDzMap.push_back(std::make_pair("Al_case", 0)); // 2.1 mm Al
// EE1
add_EE(1, aDzMap, 119.7 * CLHEP::mm, 4.7 * CLHEP::mm);
// EE2
add_EE(2, aDzMap, 7.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE3
add_EE(3, aDzMap, 7.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE4
add_EE(4, aDzMap, 8.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE5
add_EE(5, aDzMap, 8.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE6
add_EE(6, aDzMap, 8.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE7
add_EE(7, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE8
add_EE(8, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE9
add_EE(9, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE10
add_EE(10, aDzMap, 6.7 * CLHEP::mm, 3.7 * CLHEP::mm);
// EE11
add_EE(11, aDzMap, 6.7 * CLHEP::mm, 5.5 * CLHEP::mm);
// EE12
add_EE(12, aDzMap, 9.5 * CLHEP::mm, 5.5 * CLHEP::mm);
// EE13
add_EE(13, aDzMap, 9.5 * CLHEP::mm, 3.145 * CLHEP::mm);
// EE14
add_EE(14, aDzMap, 10.09 * CLHEP::mm, 3.095 * CLHEP::mm);
aDzMap.push_back(std::make_pair("Steel_case_thick", 0)); // 40 mm
aDzMap.push_back(std::make_pair("Al_case", 44 * CLHEP::mm)); // 2.1 mm
// beginning of FH
aDzMap.push_back(std::make_pair("Steel_case", 0)); // 9 mm
// FH1
add_FH(1, aDzMap, 0, 8.8 * CLHEP::mm);
// FH2
add_FH(2, aDzMap, 8 * CLHEP::mm, 8.8 * CLHEP::mm);
// FH3
add_FH(3, aDzMap, 3 * CLHEP::mm, 13.8 * CLHEP::mm);
// FH4
add_FH(4, aDzMap, 5 * CLHEP::mm, 12.8 * CLHEP::mm);
// FH5
add_FH(5, aDzMap, 7 * CLHEP::mm, 9.8 * CLHEP::mm);
// FH6
add_FH(6, aDzMap, 6 * CLHEP::mm, 10.7 * CLHEP::mm);
// cases
aDzMap.push_back(std::make_pair("Steel_case", 4 * CLHEP::mm)); // 9 mm
aDzMap.push_back(std::make_pair("Fe_absorber_FH", 36 * CLHEP::mm)); // 40 mm
aDzMap.push_back(std::make_pair("Steel_case", 52 * CLHEP::mm)); // 9 mm
// FH7
add_FH(7, aDzMap, 0, 8.8 * CLHEP::mm);
// FH8
add_FH(8, aDzMap, 7 * CLHEP::mm, 16.8 * CLHEP::mm);
// FH9
add_FH(9, aDzMap, 9 * CLHEP::mm, 14.8 * CLHEP::mm);
// FH10
add_FH(10, aDzMap, 10 * CLHEP::mm, 18 * CLHEP::mm);
// FH11
add_FH(11, aDzMap, 8 * CLHEP::mm, 17 * CLHEP::mm);
// FH12
add_FH(12, aDzMap, 7 * CLHEP::mm, 17 * CLHEP::mm);
aDzMap.push_back(std::make_pair("Steel_case", 29 * CLHEP::mm));
// AHCAL
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 50.0 * CLHEP::cm));
for (int l = 0; l < 39; l++) {
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.5 * CLHEP::cm));
aDzMap.push_back(std::make_pair("AHCAL_SiPM_2x2HUB", 0.));
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.));
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 0.5 * CLHEP::cm));
}
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 1.1 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 1.1 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.5 * CLHEP::cm));
aDzMap.push_back(std::make_pair("AHCAL_SiPM_2x2HUB", 0.));
aDzMap.push_back(std::make_pair("Al_absorber_AHCAL", 0.));
aDzMap.push_back(std::make_pair("Fe_absorber_AHCAL", 0.5 * CLHEP::cm));
}
@@ -0,0 +1,67 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction1.hh"
#include "DetectorConstruction0.hh"
#include "CLHEP/Units/SystemOfUnits.h"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction1(
std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint) {
// map means: position this material starting at z, where:
// z += <second>
// z = z0+ 0.5 * thickness[<first>]
// first define beamline elements
// WChambUpstream
// world (and beam) starts at -45 m
aDzMap.push_back(std::make_pair("DWC", 12.2825 * CLHEP::m)); // at -32.7175 m
aDzMap.push_back(std::make_pair("CK3", 0.0 * CLHEP::m)); // at -30.69 m
aDzMap.push_back(std::make_pair("DWC", 56.2 * CLHEP::cm)); // at -30.073 cm
aDzMap.push_back(std::make_pair("DWC", 101.5 * CLHEP::cm)); // at -2900.3 cm
aDzMap.push_back(std::make_pair("Scintillator_thin", 23.9 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Scintillator_thin", 13.9 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Scintillator_thin", 13.9 * CLHEP::cm));
aDzMap.push_back(std::make_pair("Scintillator_thin", 103.8 * CLHEP::cm));
aDzMap.push_back(std::make_pair("DWC", 34.8 * CLHEP::cm)); // at -2700.5 cm
// HaloCounters not implemented (as offset in X or Y)
// WChambDown
aDzMap.push_back(std::make_pair("DWC", 18.15 * CLHEP::m)); // at -880 cm
aDzMap.push_back(std::make_pair("DWC", 7.145 * CLHEP::m)); // at -160 cm
// S5
aDzMap.push_back(std::make_pair("Scintillator", 1.354 * CLHEP::m));
// S6
aDzMap.push_back(std::make_pair("Scintillator", 14 * CLHEP::cm));
// next use already defined HGCal configuration
DetectorConstruction0(aDzMap, aViewpoint);
}
@@ -0,0 +1,38 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "DetectorConstruction2.hh"
#include "CLHEP/Units/SystemOfUnits.h"
void DetectorConstruction2(std::vector<std::pair<G4String, G4double>> &aDzMap,
G4double &aViewpoint) {
aViewpoint = 0;
aDzMap.push_back(std::make_pair("PCB", 45 * CLHEP::m));
aDzMap.push_back(std::make_pair("Si_wafer", 0.));
aDzMap.push_back(std::make_pair("Kapton_layer", 0.3 * CLHEP::mm));
aDzMap.push_back(std::make_pair("CuW_baseplate", 0.));
aDzMap.push_back(std::make_pair("Cu_absorber_EE", 0.));
}
@@ -0,0 +1,196 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "EventAction.hh"
#include "SiPMHit.hh"
#include "SiliconPixelHit.hh"
#include "G4Event.hh"
#include "G4SDManager.hh"
#include "G4GenericMessenger.hh"
#include "g4root.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::EventAction() : G4UserEventAction() { DefineCommands(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventAction::~EventAction() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::BeginOfEventAction(const G4Event *) {
fPrimariesPDG.clear();
fPrimariesEnergy.clear();
fPrimariesX.clear();
fPrimariesY.clear();
fPrimariesZ.clear();
fSiHitsID.clear();
fSiHitsX.clear();
fSiHitsY.clear();
fSiHitsZ.clear();
fSiHitsEdep.clear();
fSiHitsEdepNonIonising.clear();
fSiHitsTOA.clear();
fSiHitsTOAlast.clear();
fSiHitsType.clear();
fSiPMhitsID.clear();
fSiPMhitsX.clear();
fSiPMhitsY.clear();
fSiPMhitsZ.clear();
fSiPMhitsEdep.clear();
fSiPMhitsEdepNonIonising.clear();
fSiPMhitsTOA.clear();
fSiPMhitsType.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event *event) {
// sanity check
if (event->GetNumberOfPrimaryVertex() == 0)
return;
auto analysisManager = G4AnalysisManager::Instance();
analysisManager->FillNtupleIColumn(0, event->GetEventID());
// fill for all primary input particles
for (G4int iVertex = 0; iVertex < event->GetNumberOfPrimaryVertex();
iVertex++) {
auto vertex = event->GetPrimaryVertex(iVertex);
fPrimariesX.push_back(vertex->GetX0() / CLHEP::cm);
fPrimariesY.push_back(vertex->GetY0() / CLHEP::cm);
fPrimariesZ.push_back(vertex->GetZ0() / CLHEP::cm);
for (G4int iParticle = 0; iParticle < vertex->GetNumberOfParticle();
iParticle++) {
auto particle = vertex->GetPrimary(iParticle);
fPrimariesPDG.push_back(particle->GetPDGcode());
fPrimariesEnergy.push_back(particle->GetTotalEnergy() / CLHEP::GeV);
}
}
auto hce = event->GetHCofThisEvent();
auto sdManager = G4SDManager::GetSDMpointer();
G4int collId;
// HGCAL EE + FH
collId = sdManager->GetCollectionID("SiliconPixelHitCollection");
auto hc = hce->GetHC(collId);
if (!hc)
return;
double esumHGCAL = 0;
double cogzHGCAL = 0;
int NhitsHGCAL = 0;
for (unsigned int i = 0; i < hc->GetSize(); ++i) {
auto hit = static_cast<SiliconPixelHit *>(hc->GetHit(i));
hit->Digitise(fHitTimeCut / CLHEP::ns, fToaThreshold / CLHEP::keV);
if (hit->isValidHit()) {
fSiHitsID.push_back(hit->ID());
fSiHitsX.push_back(hit->GetX());
fSiHitsY.push_back(hit->GetY());
fSiHitsZ.push_back(hit->GetZ());
fSiHitsEdep.push_back(hit->GetEdep());
fSiHitsEdepNonIonising.push_back(hit->GetEdepNonIonizing());
fSiHitsTOA.push_back(hit->GetTOA());
fSiHitsTOAlast.push_back(hit->GetLastTOA());
fSiHitsType.push_back(0);
NhitsHGCAL++;
esumHGCAL += hit->GetEdep() * CLHEP::keV / CLHEP::MeV;
cogzHGCAL += hit->GetZ() * hit->GetEdep();
}
}
if (esumHGCAL > 0)
cogzHGCAL /= esumHGCAL;
analysisManager->FillNtupleDColumn(23, esumHGCAL / CLHEP::GeV);
analysisManager->FillNtupleDColumn(24, cogzHGCAL);
analysisManager->FillNtupleIColumn(25, NhitsHGCAL);
// AHCAL
collId = sdManager->GetCollectionID("SiPMHitCollection");
hc = hce->GetHC(collId);
if (!hc)
return;
double esumAHCAL = 0;
double cogzAHCAL = 0;
int NhitsAHCAL = 0;
for (unsigned int i = 0; i < hc->GetSize(); ++i) {
auto hit = static_cast<SiPMHit *>(hc->GetHit(i));
hit->Digitise(-1, 0);
if (hit->isValidHit()) {
fSiPMhitsID.push_back(hit->ID());
fSiPMhitsX.push_back(hit->GetX());
fSiPMhitsY.push_back(hit->GetY());
fSiPMhitsZ.push_back(hit->GetZ());
fSiPMhitsEdep.push_back(hit->GetEdep());
fSiPMhitsEdepNonIonising.push_back(hit->GetEdepNonIonizing());
fSiPMhitsTOA.push_back(hit->GetTOA());
fSiPMhitsType.push_back(1);
NhitsAHCAL++;
esumAHCAL += hit->GetEdep() * CLHEP::keV / CLHEP::MeV;
cogzAHCAL += hit->GetZ() * hit->GetEdep();
}
}
if (esumAHCAL > 0)
cogzAHCAL /= esumAHCAL;
analysisManager->FillNtupleDColumn(26, esumAHCAL / CLHEP::GeV);
analysisManager->FillNtupleDColumn(27, cogzAHCAL);
analysisManager->FillNtupleIColumn(28, NhitsAHCAL);
analysisManager->AddNtupleRow();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::DefineCommands() {
fMessenger = new G4GenericMessenger(this, "/HGCalTestbeam/hits/",
"Primary generator control");
// time cut command
auto &timeCutCmd = fMessenger->DeclarePropertyWithUnit(
"timeCut", "ns", fHitTimeCut,
"Size of time window for hit digitalisation");
timeCutCmd.SetParameterName("timeCut", true);
timeCutCmd.SetRange("timeCut>=-1");
timeCutCmd.SetDefaultValue("-1");
// toa threshold command
auto &toaThresholdCmd = fMessenger->DeclarePropertyWithUnit(
"toaThreshold", "keV", fToaThreshold, "Threshold for TOA activation");
toaThresholdCmd.SetParameterName("toaThreshold", true);
toaThresholdCmd.SetRange("toaThreshold>=0");
toaThresholdCmd.SetDefaultValue("0");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,78 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "FTFPCMS_BERT_EMM.hh"
#include "CMSEmStandardPhysicsHcal.hh"
#include "G4DecayPhysics.hh"
#include "G4EmExtraPhysics.hh"
#include "G4HadronElasticPhysics.hh"
#include "G4IonPhysics.hh"
#include "G4NeutronTrackingCut.hh"
#include "G4StoppingPhysics.hh"
#include "G4HadronPhysicsFTFP_BERT.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
FTFPCMS_BERT_EMM::FTFPCMS_BERT_EMM(G4int ver) {
defaultCutValue = 0.7 * CLHEP::mm;
SetVerboseLevel(ver);
G4cout << "You are using "
<< "FTFP_BERT_EMM " << G4endl;
// EM Physics
RegisterPhysics(new CMSEmStandardPhysicsHcal(ver));
// Synchroton Radiation & GN Physics
RegisterPhysics(new G4EmExtraPhysics(ver));
// Decays
RegisterPhysics(new G4DecayPhysics(ver));
// Hadron Elastic scattering
RegisterPhysics(new G4HadronElasticPhysics(ver));
RegisterPhysics(new G4HadronPhysicsFTFP_BERT(ver));
// Stopping Physics
RegisterPhysics(new G4StoppingPhysics(ver));
// Ion Physics
RegisterPhysics(new G4IonPhysics(ver));
// Neutron tracking cut
RegisterPhysics(new G4NeutronTrackingCut(ver));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
FTFPCMS_BERT_EMM::~FTFPCMS_BERT_EMM() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void FTFPCMS_BERT_EMM::SetCuts() { SetCutsWithDefault(); }
@@ -0,0 +1,840 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "HGCalTBMaterials.hh"
#include "G4Box.hh"
#include "G4Colour.hh"
#include "G4Element.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4PVPlacement.hh"
#include "G4RotationMatrix.hh"
#include "G4SubtractionSolid.hh"
#include "G4ThreeVector.hh"
#include "G4Tubs.hh"
#include "G4VisAttributes.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4SubtractionSolid *HexagonSolid(G4String aName, G4double aCellThickness,
G4double aCellSideLength) {
G4double fullCcellX = (2.) * aCellSideLength;
G4double fullCellY = std::sqrt(3.) * aCellSideLength;
G4Box *solidFullcell = new G4Box(aName, // its aName
0.5 * fullCcellX, 0.5 * fullCellY,
0.5 * aCellThickness); // its size
G4double deltaXDash = aCellSideLength;
G4double deltaYDash = std::sqrt(3) / 4 * aCellSideLength;
G4Box *solidCutcell = new G4Box(aName, // its aName
0.5 * deltaXDash, 0.5 * (deltaYDash),
1. * aCellThickness); // its size
G4double deltaTheta[4] = {30. * CLHEP::deg, 150. * CLHEP::deg, 210. * CLHEP::deg, 330. * CLHEP::deg};
G4double deltaThetaRot[4] = {60. * CLHEP::deg, 120. * CLHEP::deg, 240 * CLHEP::deg, 300 * CLHEP::deg};
G4double delta = std::sqrt(3) / 2 * aCellSideLength + deltaYDash / 2;
G4RotationMatrix *rot = new G4RotationMatrix;
rot->rotateZ(deltaThetaRot[0]);
std::vector<G4SubtractionSolid *> subtracted;
subtracted.push_back(
new G4SubtractionSolid("cellSubtracted", solidFullcell, solidCutcell, rot,
G4ThreeVector(std::cos(deltaTheta[0]) * delta,
std::sin(deltaTheta[0]) * delta, 0.)));
for (int i = 1; i < 4; i++) {
rot->rotateZ(-deltaThetaRot[i - 1]);
rot->rotateZ(deltaThetaRot[i]);
subtracted.push_back(new G4SubtractionSolid(
"cellSubtracted", subtracted[i - 1], solidCutcell, rot,
G4ThreeVector(std::cos(deltaTheta[i]) * delta, std::sin(deltaTheta[i]) * delta,
0.)));
}
delete rot;
return subtracted[3];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4LogicalVolume *HexagonLogical(G4String aName, G4double aCellThickness,
G4double aCellSideLength,
G4Material *aMaterial) {
return new G4LogicalVolume(
HexagonSolid(aName, aCellThickness, aCellSideLength), // its solid
aMaterial, // its aMaterial
aName); // its aName
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineMaterials() {
/***** Definition of all available materials *****/
// Get nist aMaterial manager
G4NistManager *nist = G4NistManager::Instance();
fMatVacuum = nist->FindOrBuildMaterial("G4_Galactic");
fMatAIR = nist->FindOrBuildMaterial("G4_AIR");
fMatAr = nist->FindOrBuildMaterial("G4_Ar");
fMatAl = nist->FindOrBuildMaterial("G4_Al");
fMatFe = nist->FindOrBuildMaterial("G4_Fe");
fMatGlass = nist->FindOrBuildMaterial("G4_GLASS_PLATE");
fMatPb = nist->FindOrBuildMaterial("G4_Pb");
fMatCu = nist->FindOrBuildMaterial("G4_Cu");
fMatW = nist->FindOrBuildMaterial("G4_W");
fMatSi = nist->FindOrBuildMaterial("G4_Si");
fMatAu = nist->FindOrBuildMaterial("G4_Au");
fMatQuartz = nist->FindOrBuildMaterial("G4_SILICON_DIOXIDE");
fMatC = nist->FindOrBuildMaterial("G4_C");
fMatH = nist->FindOrBuildMaterial("G4_H");
fMatO = nist->FindOrBuildMaterial("G4_O");
fMatMn = nist->FindOrBuildMaterial("G4_Mn");
fMatCr = nist->FindOrBuildMaterial("G4_Cr");
fMatNi = nist->FindOrBuildMaterial("G4_Ni");
fMatPolyethylene = nist->FindOrBuildMaterial("G4_POLYETHYLENE");
fMatCl = nist->FindOrBuildMaterial("G4_Cl");
fMatF = nist->FindOrBuildMaterial("G4_F");
// AHCAL SiPMs
G4double a = 1.01 * CLHEP::g / CLHEP::mole;
G4Element *elH = new G4Element("Hydrogen", "H2", 1., a);
a = 12.01 * CLHEP::g / CLHEP::mole;
G4Element *elC = new G4Element("Carbon", "C", 6., a);
G4double density = 1.032 * CLHEP::g / CLHEP::cm3;
fMatPolystyrene = new G4Material("Polystyrene", density, 2);
fMatPolystyrene->AddElement(elC, 19);
fMatPolystyrene->AddElement(elH, 21);
// CuW alloy: 60% Cu, 40% W in mass
G4double CuFracInCuW = 0.75;
fMatCuW = new G4Material("CuW", 14.979 * CLHEP::g / CLHEP::cm3, 2);
fMatCuW->AddMaterial(fMatCu, CuFracInCuW);
fMatCuW->AddMaterial(fMatW, 1 - CuFracInCuW);
// PCB aMaterial
fMatPCB = new G4Material("PCB", 1.7 * CLHEP::g / CLHEP::cm3, 4);
fMatPCB->AddMaterial(fMatC, 0.13232243);
fMatPCB->AddMaterial(fMatH, 0.032572448);
fMatPCB->AddMaterial(fMatO, 0.48316123);
fMatPCB->AddMaterial(fMatSi, 0.35194389);
// Kapton aMaterial
fMatKAPTON = new G4Material("Kapton", 1.11 * CLHEP::g / CLHEP::cm3, 3);
fMatKAPTON->AddMaterial(fMatC, 0.59985105);
fMatKAPTON->AddMaterial(fMatH, 0.080541353);
fMatKAPTON->AddMaterial(fMatO, 0.31960759);
// steel
fMatSteel = new G4Material("StainlessSteel", 8.02 * CLHEP::g / CLHEP::cm3, 5);
fMatSteel->AddMaterial(fMatFe, 0.6996);
fMatSteel->AddMaterial(fMatC, 0.0004);
fMatSteel->AddMaterial(fMatMn, 0.01);
fMatSteel->AddMaterial(fMatCr, 0.19);
fMatSteel->AddMaterial(fMatNi, 0.1);
// Scintillator aMaterial
fMatScintillator = new G4Material("Scintillator", 1.032 * CLHEP::g / CLHEP::cm3, 2);
fMatScintillator->AddMaterial(fMatC, 0.91512109);
fMatScintillator->AddMaterial(fMatH, 0.084878906);
// DWC gas
fMatArCO2 = new G4Material("ArCO2", 1.729 * CLHEP::mg / CLHEP::cm3, 3);
fMatArCO2->AddMaterial(fMatAr, 0.475815);
fMatArCO2->AddMaterial(fMatC, 0.14306133);
fMatArCO2->AddMaterial(fMatO, 0.38112367);
fMatFreon = new G4Material("Freon-12", 4.93 * CLHEP::mg / CLHEP::cm3, 3);
fMatFreon->AddMaterial(fMatC, 0.099340816);
fMatFreon->AddMaterial(fMatCl, 0.58640112);
fMatFreon->AddMaterial(fMatF, 0.31425807);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::SetEventDisplayColorScheme() {
G4VisAttributes *visAttributes;
visAttributes = new G4VisAttributes(G4Colour(.0, 0.0, 0.0));
visAttributes->SetVisibility(false);
fSiWaferLogical->SetVisAttributes(visAttributes);
visAttributes = new G4VisAttributes(G4Colour(.3, 0.3, 0.3, 0.2));
visAttributes->SetVisibility(true);
fSiPixelLogical->SetVisAttributes(visAttributes);
visAttributes = new G4VisAttributes(G4Colour(0.4, 0.4, 0.4, 0.01));
visAttributes->SetVisibility(false);
fCuWbaseplateLogical->SetVisAttributes(visAttributes);
fCuWbaseplate550umLogical->SetVisAttributes(visAttributes);
fCuWbaseplate610umLogical->SetVisAttributes(visAttributes);
fCuWbaseplate710umLogical->SetVisAttributes(visAttributes);
fCuBaseplateLogical->SetVisAttributes(visAttributes);
fCuBaseplate25umLogical->SetVisAttributes(visAttributes);
fCuBaseplate175umLogical->SetVisAttributes(visAttributes);
fPCBbaseplateLogical->SetVisAttributes(visAttributes);
fPCBbaseplateThinLogical->SetVisAttributes(visAttributes);
fKaptonLayerLogical->SetVisAttributes(visAttributes);
fAlCaseLogical->SetVisAttributes(visAttributes);
fAlCaseThickLogical->SetVisAttributes(visAttributes);
fSteelCaseLogical->SetVisAttributes(visAttributes);
fSteelCaseThickLogical->SetVisAttributes(visAttributes);
fPbAbsorberEElogical->SetVisAttributes(visAttributes);
fFeAbsorberEElogical->SetVisAttributes(visAttributes);
fCuAbsorberEElogical->SetVisAttributes(visAttributes);
fWabsorberEElogical->SetVisAttributes(visAttributes);
fW2mmAbsorberEEDESY2018Logical->SetVisAttributes(visAttributes);
fW4mmAbsorberEEDESY2018Logical->SetVisAttributes(visAttributes);
fCuAbsorberFHlogical->SetVisAttributes(visAttributes);
fFeAbsorberFHlogical->SetVisAttributes(visAttributes);
fAHCALSiPMlogical->SetVisAttributes(visAttributes);
fAHCALSiPM2x2HUBlogical->SetVisAttributes(visAttributes);
fAlAbsorberAHCALlogical->SetVisAttributes(visAttributes);
fPCBAHCALlogical->SetVisAttributes(visAttributes);
fFeAbsorberAHCALlogical->SetVisAttributes(visAttributes);
fScintillatorLogical->SetVisAttributes(visAttributes);
fScintillatorThinLogical->SetVisAttributes(visAttributes);
fMCPlogical->SetVisAttributes(visAttributes);
fCK3logical->SetVisAttributes(visAttributes);
fDWClogical->SetVisAttributes(visAttributes);
fDWCgasLogical->SetVisAttributes(visAttributes);
fAlChipLogical->SetVisAttributes(visAttributes);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HGCalTBMaterials::HGCalTBMaterials() {
DefineMaterials();
DefineSiWaferAndCells();
DefineHGCalBaseplates();
DefineHGCalCases();
DefineHGCalEEAbsorbers();
DefineHGCalFHAbsorbers();
DefineAHCALSiPM();
DefineAHCALAbsorbers();
DefineBeamLineElements();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineSiWaferAndCells() {
/***** Definition of silicon (wafer) sensors *****/
// 300 microns thickness only
fSiPixelSideLength = 0.6496345 * CLHEP::cm;
fSiWaferThickness = 0.3 * CLHEP::mm;
fAlpha = 60. / 180. * CLHEP::pi;
fSiWaferSideLength = 11 * fSiPixelSideLength;
fSiWaferLogical = HexagonLogical("Si_wafer", fSiWaferThickness,
fSiWaferSideLength, fMatAIR);
// Silicon pixel setups
double dx = 2 * std::sin(fAlpha) * fSiPixelSideLength;
double dy = fSiPixelSideLength * (2. + 2 * std::cos(fAlpha));
fSiPixelLogical =
HexagonLogical("SiCell", fSiWaferThickness, fSiPixelSideLength, fMatSi);
int index = 1;
int nRows[11] = {7, 6, 7, 6, 5, 6, 5, 4, 5, 4, 3};
for (int nC = 0; nC < 11; nC++) {
for (int middle_index = 0; middle_index < nRows[nC]; middle_index++) {
new G4PVPlacement(
0,
G4ThreeVector(dy * (middle_index - nRows[nC] / 2. + 0.5), nC * dx / 2,
0.),
fSiPixelLogical, "SiCell", fSiWaferLogical, false, index++, true);
if (nC <= 0)
continue;
new G4PVPlacement(
0,
G4ThreeVector(dy * (middle_index - nRows[nC] / 2. + 0.5),
-nC * dx / 2, 0.),
fSiPixelLogical, "SiCell", fSiWaferLogical, false, index++, true);
}
}
fThicknessMap["Si_wafer"] = fSiWaferThickness;
fLogicalVolumeMap["Si_wafer"] = fSiWaferLogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalBaseplates() {
/***** Definition of all baseplates *****/
// CuW
G4double CuWbaseplateThickness = 1.2 * CLHEP::mm;
G4double CuWbaseplatesideLength = 11 * fSiPixelSideLength;
fCuWbaseplateLogical = HexagonLogical("CuW_baseplate", CuWbaseplateThickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate"] = CuWbaseplateThickness;
fLogicalVolumeMap["CuW_baseplate"] = fCuWbaseplateLogical;
G4double CuWbaseplate550umthickness = 0.55 * CLHEP::mm;
fCuWbaseplate550umLogical =
HexagonLogical("CuW_baseplate_550um", CuWbaseplate550umthickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate_550um"] = CuWbaseplate550umthickness;
fLogicalVolumeMap["CuW_baseplate_550um"] = fCuWbaseplate550umLogical;
G4double CuWbaseplate610umThickness = 0.61 * CLHEP::mm;
fCuWbaseplate610umLogical =
HexagonLogical("CuW_baseplate_610um", CuWbaseplate610umThickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate_610um"] = CuWbaseplate610umThickness;
fLogicalVolumeMap["CuW_baseplate_610um"] = fCuWbaseplate610umLogical;
G4double CuWbaseplate710umThickness = 0.71 * CLHEP::mm;
fCuWbaseplate710umLogical =
HexagonLogical("CuW_baseplate_710um", CuWbaseplate710umThickness,
CuWbaseplatesideLength, fMatCuW);
fThicknessMap["CuW_baseplate_710um"] = CuWbaseplate710umThickness;
fLogicalVolumeMap["CuW_baseplate_710um"] = fCuWbaseplate710umLogical;
// Cu
G4double CuBaseplateThickness = 1.2 * CLHEP::mm;
G4double CuBaseplatesideLength = 11 * fSiPixelSideLength;
fCuBaseplateLogical = HexagonLogical("Cu_baseplate", CuBaseplateThickness,
CuBaseplatesideLength, fMatCu);
fThicknessMap["Cu_baseplate"] = CuBaseplateThickness;
fLogicalVolumeMap["Cu_baseplate"] = fCuBaseplateLogical;
G4double CuBaseplate25umThickness = 0.025 * CLHEP::mm;
fCuBaseplate25umLogical =
HexagonLogical("Cu_baseplate_25um", CuBaseplate25umThickness,
CuBaseplatesideLength, fMatCu);
fThicknessMap["Cu_baseplate_25um"] = CuBaseplate25umThickness;
fLogicalVolumeMap["Cu_baseplate_25um"] = fCuBaseplate25umLogical;
G4double CuBaseplate175umThickness = 0.175 * CLHEP::mm;
fCuBaseplate175umLogical =
HexagonLogical("Cu_baseplate_175um", CuBaseplate175umThickness,
CuBaseplatesideLength, fMatCu);
fThicknessMap["Cu_baseplate_175um"] = CuBaseplate175umThickness;
fLogicalVolumeMap["Cu_baseplate_175um"] = fCuBaseplate175umLogical;
// PCB
G4double PCBbaseplateThickness = 1.3 * CLHEP::mm;
G4double PCBbaseplateSideLength = 11 * fSiPixelSideLength;
fPCBbaseplateLogical = HexagonLogical("PCB", PCBbaseplateThickness,
PCBbaseplateSideLength, fMatPCB);
fThicknessMap["PCB"] = PCBbaseplateThickness;
fLogicalVolumeMap["PCB"] = fPCBbaseplateLogical;
G4double PCBbaseplateThinThickness = 1.2 * CLHEP::mm;
fPCBbaseplateThinLogical = HexagonLogical(
"PCB_thin", PCBbaseplateThinThickness, PCBbaseplateSideLength, fMatPCB);
fThicknessMap["PCB_thin"] = PCBbaseplateThinThickness;
fLogicalVolumeMap["PCB_thin"] = fPCBbaseplateThinLogical;
// Kapton layer
G4double KaptonLayerThickness = 0.075 * CLHEP::mm;
G4double KaptonLayerSideLength = 11 * fSiPixelSideLength;
fKaptonLayerLogical = HexagonLogical("Kapton_layer", KaptonLayerThickness,
KaptonLayerSideLength, fMatKAPTON);
fThicknessMap["Kapton_layer"] = KaptonLayerThickness;
fLogicalVolumeMap["Kapton_layer"] = fKaptonLayerLogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalCases() {
G4double AlCaseThickness = 2.1 * CLHEP::mm;
G4double AlCaseXY = 40 * CLHEP::cm;
G4Box *AlCaseSolid = new G4Box("Al_case", 0.5 * AlCaseXY, 0.5 * AlCaseXY,
0.5 * AlCaseThickness);
fAlCaseLogical = new G4LogicalVolume(AlCaseSolid, fMatAl, "Al_case");
fThicknessMap["Al_case"] = AlCaseThickness;
fLogicalVolumeMap["Al_case"] = fAlCaseLogical;
G4double AlCaseThickThickness = 5 * CLHEP::mm;
G4Box *AlCaseThickSolid =
new G4Box("Al_case_thick", 0.5 * AlCaseXY, 0.5 * AlCaseXY,
0.5 * AlCaseThickThickness);
fAlCaseThickLogical =
new G4LogicalVolume(AlCaseThickSolid, fMatAl, "Al_case_thick");
fThicknessMap["Al_case_thick"] = AlCaseThickThickness;
fLogicalVolumeMap["Al_case_thick"] = fAlCaseThickLogical;
G4double SteelCaseThickness = 9 * CLHEP::mm;
G4double SteelCaseXY = 60 * CLHEP::cm;
G4Box *SteelCaseSolid =
new G4Box("Steel_case", 0.5 * SteelCaseXY, 0.5 * SteelCaseXY,
0.5 * SteelCaseThickness);
fSteelCaseLogical = new G4LogicalVolume(SteelCaseSolid, fMatFe, "Steel_case");
fThicknessMap["Steel_case"] = SteelCaseThickness;
fLogicalVolumeMap["Steel_case"] = fSteelCaseLogical;
G4double SteelCaseThickThickness = 40 * CLHEP::mm;
G4Box *SteelCaseThickSolid =
new G4Box("Steel_case_thick", 0.5 * SteelCaseXY, 0.5 * SteelCaseXY,
0.5 * SteelCaseThickThickness);
fSteelCaseThickLogical =
new G4LogicalVolume(SteelCaseThickSolid, fMatFe, "Steel_case_thick");
fThicknessMap["Steel_case_thick"] = SteelCaseThickThickness;
fLogicalVolumeMap["Steel_case_thick"] = fSteelCaseThickLogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalEEAbsorbers() {
// defintion of absorber plates in the EE part
G4double PbAbsorberEEthickness = 4.9 * CLHEP::mm;
G4double PbAbsorberEExy = 30 * CLHEP::cm;
G4Box *PbAbsorberEEsolid =
new G4Box("Pb_absorber_EE", 0.5 * PbAbsorberEExy, 0.5 * PbAbsorberEExy,
0.5 * PbAbsorberEEthickness);
fPbAbsorberEElogical =
new G4LogicalVolume(PbAbsorberEEsolid, fMatPb, "Pb_absorber_EE");
fThicknessMap["Pb_absorber_EE"] = PbAbsorberEEthickness;
fLogicalVolumeMap["Pb_absorber_EE"] = fPbAbsorberEElogical;
G4double FeAbsorberEEthickness = 0.3 * CLHEP::mm;
G4double FeAbsorberEExy = 30 * CLHEP::cm;
G4Box *FeAbsorberEEsolid =
new G4Box("Fe_absorber_EE", 0.5 * FeAbsorberEExy, 0.5 * FeAbsorberEExy,
0.5 * FeAbsorberEEthickness);
fFeAbsorberEElogical =
new G4LogicalVolume(FeAbsorberEEsolid, fMatFe, "Fe_absorber_EE");
fThicknessMap["Fe_absorber_EE"] = FeAbsorberEEthickness;
fLogicalVolumeMap["Fe_absorber_EE"] = fFeAbsorberEElogical;
G4double CuAbsorberEEthickness = 6 * CLHEP::mm;
G4double CuAbsorberEExy = 30 * CLHEP::cm;
G4Box *CuAbsorberEEsolid =
new G4Box("Cu_absorber_EE", 0.5 * CuAbsorberEExy, 0.5 * CuAbsorberEExy,
0.5 * CuAbsorberEEthickness);
fCuAbsorberEElogical =
new G4LogicalVolume(CuAbsorberEEsolid, fMatCu, "Cu_absorber_EE");
fThicknessMap["Cu_absorber_EE"] = CuAbsorberEEthickness;
fLogicalVolumeMap["Cu_absorber_EE"] = fCuAbsorberEElogical;
G4double WabsorberEEthickness = 2.8 * CLHEP::mm;
G4double WabsorberEExy = 30 * CLHEP::cm;
G4Box *WabsorberEEsolid =
new G4Box("W_absorber_EE", 0.5 * WabsorberEExy, 0.5 * WabsorberEExy,
0.5 * WabsorberEEthickness);
fWabsorberEElogical =
new G4LogicalVolume(WabsorberEEsolid, fMatW, "W_absorber_EE");
fThicknessMap["W_absorber_EE"] = WabsorberEEthickness;
fLogicalVolumeMap["W_absorber_EE"] = fWabsorberEElogical;
G4double W2mmAbsorberEEDESY2018thickness = 2. * CLHEP::mm;
G4double W2mmAbsorberEEDESY2018xy = 15 * CLHEP::cm;
G4Box *W2mmAbsorberEEDESY2018solid = new G4Box(
"W_2mm_absorber_EE_DESY2018", 0.5 * W2mmAbsorberEEDESY2018xy,
0.5 * W2mmAbsorberEEDESY2018xy, 0.5 * W2mmAbsorberEEDESY2018thickness);
fW2mmAbsorberEEDESY2018Logical = new G4LogicalVolume(
W2mmAbsorberEEDESY2018solid, fMatW, "W_2mm_absorber_EE_DESY2018");
fThicknessMap["W_2mm_absorber_EE_DESY2018"] = W2mmAbsorberEEDESY2018thickness;
fLogicalVolumeMap["W_2mm_absorber_EE_DESY2018"] =
fW2mmAbsorberEEDESY2018Logical;
G4double W4mmAbsorberEEDESY2018thickness = 4. * CLHEP::mm;
G4double W4mmAbsorberEEDESY2018xy = 15 * CLHEP::cm;
G4Box *W4mmAbsorberEEDESY2018solid = new G4Box(
"W_4mm_absorber_EE_DESY2018", 0.5 * W4mmAbsorberEEDESY2018xy,
0.5 * W4mmAbsorberEEDESY2018xy, 0.5 * W4mmAbsorberEEDESY2018thickness);
fW4mmAbsorberEEDESY2018Logical = new G4LogicalVolume(
W4mmAbsorberEEDESY2018solid, fMatW, "W_4mm_absorber_EE_DESY2018");
fThicknessMap["W_4mm_absorber_EE_DESY2018"] = W4mmAbsorberEEDESY2018thickness;
fLogicalVolumeMap["W_4mm_absorber_EE_DESY2018"] =
fW4mmAbsorberEEDESY2018Logical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineHGCalFHAbsorbers() {
// defintion of absorber plates in the FH part
G4double CuAbsorberFHthickness = 6 * CLHEP::mm;
G4double CuAbsorberFHxy = 50 * CLHEP::cm;
G4Box *CuAbsorberFHsolid =
new G4Box("Cu_absorber_FH", 0.5 * CuAbsorberFHxy, 0.5 * CuAbsorberFHxy,
0.5 * CuAbsorberFHthickness);
fCuAbsorberFHlogical =
new G4LogicalVolume(CuAbsorberFHsolid, fMatCu, "Cu_absorber_FH");
fThicknessMap["Cu_absorber_FH"] = CuAbsorberFHthickness;
fLogicalVolumeMap["Cu_absorber_FH"] = fCuAbsorberFHlogical;
G4double FeAbsorberFHthickness = 40 * CLHEP::mm;
G4double FeAbsorberFHxy = 50 * CLHEP::cm;
G4Box *FeAbsorberFHsolid =
new G4Box("Fe_absorber_FH", 0.5 * FeAbsorberFHxy, 0.5 * FeAbsorberFHxy,
0.5 * FeAbsorberFHthickness);
fFeAbsorberFHlogical =
new G4LogicalVolume(FeAbsorberFHsolid, fMatFe, "Fe_absorber_FH");
fThicknessMap["Fe_absorber_FH"] = FeAbsorberFHthickness;
fLogicalVolumeMap["Fe_absorber_FH"] = fFeAbsorberFHlogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineAHCALSiPM() {
G4double AHCALSiPMthickness = 5.4 * CLHEP::mm;
fAHCALSiPMxy = 3 * CLHEP::cm;
fAHCALSiPMsolid = new G4Box("AHCAL_SiPM", 0.5 * fAHCALSiPMxy,
0.5 * fAHCALSiPMxy, 0.5 * AHCALSiPMthickness);
fAHCALSiPMlogical =
new G4LogicalVolume(fAHCALSiPMsolid, fMatPolystyrene, "AHCAL_SiPM");
fThicknessMap["AHCAL_SiPM"] = AHCALSiPMthickness;
fLogicalVolumeMap["AHCAL_SiPM"] = fAHCALSiPMlogical;
G4double AHCALSiPM2x2HUBxy = 2 * 12 * fAHCALSiPMxy + 0.01 * CLHEP::mm;
G4double AHCALSiPM2x2HUBthickness = AHCALSiPMthickness + 0.01 * CLHEP::mm;
G4Box *AHCALSiPM2x2HUBsolid =
new G4Box("AHCAL_SiPM_2x2HUB", 0.5 * AHCALSiPM2x2HUBxy,
0.5 * AHCALSiPM2x2HUBxy, 0.5 * AHCALSiPM2x2HUBthickness);
fAHCALSiPM2x2HUBlogical =
new G4LogicalVolume(AHCALSiPM2x2HUBsolid, fMatAIR, "AHCAL_SiPM_2x2HUB");
fThicknessMap["AHCAL_SiPM_2x2HUB"] = AHCALSiPM2x2HUBthickness;
fLogicalVolumeMap["AHCAL_SiPM_2x2HUB"] = fAHCALSiPM2x2HUBlogical;
int copy_counter = 0;
for (float _dx = -11.5; _dx <= 11.5; _dx = _dx + 1.)
for (float _dy = -11.5; _dy <= 11.5; _dy = _dy + 1.)
new G4PVPlacement(
0, G4ThreeVector(_dx * fAHCALSiPMxy, _dy * fAHCALSiPMxy, 0),
fAHCALSiPMlogical, "AHCAL_SiPM", fAHCALSiPM2x2HUBlogical, false,
copy_counter++, true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineAHCALAbsorbers() {
G4double AlAbsorberAHCALthickness = 1 * CLHEP::mm;
G4double AlAbsorberAHCALxy = 2 * 12 * fAHCALSiPMxy;
G4Box *AlAbsorberAHCALsolid =
new G4Box("Al_absorber_AHCAL", 0.5 * AlAbsorberAHCALxy,
0.5 * AlAbsorberAHCALxy, 0.5 * AlAbsorberAHCALthickness);
fAlAbsorberAHCALlogical =
new G4LogicalVolume(AlAbsorberAHCALsolid, fMatAl, "Al_absorber_AHCAL");
fThicknessMap["Al_absorber_AHCAL"] = AlAbsorberAHCALthickness;
fLogicalVolumeMap["Al_absorber_AHCAL"] = fAlAbsorberAHCALlogical;
G4double PCBAHCALthickness = 1.2 * CLHEP::mm;
G4double PCBAHCALxy = 2 * 12 * fAHCALSiPMxy;
G4Box *PCBAHCALsolid = new G4Box("PCB_AHCAL", 0.5 * PCBAHCALxy,
0.5 * PCBAHCALxy, 0.5 * PCBAHCALthickness);
fPCBAHCALlogical = new G4LogicalVolume(PCBAHCALsolid, fMatPCB, "PCB_AHCAL");
fThicknessMap["PCB_AHCAL"] = PCBAHCALthickness;
fLogicalVolumeMap["PCB_AHCAL"] = fPCBAHCALlogical;
G4double FeAbsorberAHCALthickness = 17 * CLHEP::mm;
G4double FeAbsorberAHCALx = 80.8 * CLHEP::cm;
G4double FeAbsorberAHCALy = 65.7 * CLHEP::cm;
G4Box *FeAbsorberAHCALsolid =
new G4Box("Fe_absorber_AHCAL", 0.5 * FeAbsorberAHCALx,
0.5 * FeAbsorberAHCALy, 0.5 * FeAbsorberAHCALthickness);
fFeAbsorberAHCALlogical =
new G4LogicalVolume(FeAbsorberAHCALsolid, fMatFe, "Fe_absorber_AHCAL");
fThicknessMap["Fe_absorber_AHCAL"] = FeAbsorberAHCALthickness;
fLogicalVolumeMap["Fe_absorber_AHCAL"] = fFeAbsorberAHCALlogical;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::DefineBeamLineElements() {
/***** Definition of beam line elements *****/
// scintillators
G4double scintillatorThickness = 2 * 2 * CLHEP::cm;
G4double scintillatorXY = 2 * 9.5 * CLHEP::cm;
G4Box *scintillatorSolid =
new G4Box("Scintillator", 0.5 * scintillatorXY, 0.5 * scintillatorXY,
0.5 * scintillatorThickness);
fScintillatorLogical =
new G4LogicalVolume(scintillatorSolid, fMatScintillator, "Scintillator");
fThicknessMap["Scintillator"] = scintillatorThickness;
fLogicalVolumeMap["Scintillator"] = fScintillatorLogical;
G4double fScintillatorThinThickness = 1 * CLHEP::cm;
G4Box *fScintillatorThinSolid =
new G4Box("Scintillator_thin", 0.5 * scintillatorXY, 0.5 * scintillatorXY,
0.5 * fScintillatorThinThickness);
fScintillatorThinLogical = new G4LogicalVolume(
fScintillatorThinSolid, fMatScintillator, "Scintillator_thin");
fThicknessMap["Scintillator_thin"] = fScintillatorThinThickness;
fLogicalVolumeMap["Scintillator_thin"] = fScintillatorThinLogical;
// MCPs = quartz disks
G4double MCPthickness = 10 * CLHEP::mm;
G4double MCPradius = 2 * CLHEP::cm;
G4Tubs *MCPsolid =
new G4Tubs("MCP", 0., MCPradius, MCPthickness, 0, 360 * CLHEP::degree);
fMCPlogical = new G4LogicalVolume(MCPsolid, fMatQuartz, "MCP");
fThicknessMap["MCP"] = MCPthickness;
fLogicalVolumeMap["MCP"] = fMCPlogical;
// CK3
G4double CK3thickness = 2 * CLHEP::m;
G4double CK3radius = 8.35 * CLHEP::cm;
G4Tubs *CK3solid =
new G4Tubs("CK3", 0., CK3radius, 0.5 * CK3thickness, 0, 360 * CLHEP::degree);
fCK3logical = new G4LogicalVolume(CK3solid, fMatFreon, "CK3");
fThicknessMap["CK3"] = CK3thickness;
fLogicalVolumeMap["CK3"] = fCK3logical;
// Aluminium circle for testing of chip impact
G4double AlChipXY = 1 * CLHEP::cm;
G4double AlChipThickness = 0.89 * CLHEP::mm; // corresponds to 1% X0
G4Box *AlChipSolid = new G4Box("Al_chip", 0.5 * AlChipXY, 0.5 * AlChipXY,
0.5 * AlChipThickness);
fAlChipLogical = new G4LogicalVolume(AlChipSolid, fMatAl, "Al_chip");
fThicknessMap["Al_chip"] = AlChipThickness;
fLogicalVolumeMap["Al_chip"] = fAlChipLogical;
// DWC related aMaterial
G4double DWCthickness = 2 * 27.5 * CLHEP::mm;
G4double DWCxy = 2 * 11 * CLHEP::cm;
G4Box *DWCsolid =
new G4Box("DWC", 0.5 * DWCxy, 0.5 * DWCxy, 0.5 * DWCthickness);
fDWClogical = new G4LogicalVolume(DWCsolid, fMatAIR, "DWC");
fThicknessMap["DWC"] = DWCthickness;
fLogicalVolumeMap["DWC"] = fDWClogical;
// WChambGas
G4double DWCgasThickness = 2 * 22.5 * CLHEP::mm;
G4double DWCgasXY = 2 * 8.5 * CLHEP::cm;
G4Box *DWCgasSolid = new G4Box("DWC_gas", 0.5 * DWCgasXY, 0.5 * DWCgasXY,
0.5 * DWCgasThickness);
fDWCgasLogical = new G4LogicalVolume(DWCgasSolid, fMatArCO2, "DWC_gas");
new G4PVPlacement(0, G4ThreeVector(0, 0., 0.), fDWCgasLogical, "DWC_gas",
fDWClogical, false, 0, true);
G4VisAttributes *visAttributes = new G4VisAttributes(G4Colour(.0, 0.0, 0.0));
visAttributes->SetVisibility(false);
// WChambWindow
G4double DWCwindowThickness = 0.025 * CLHEP::mm;
G4double DWCwindowXY = 2 * 5.5 * CLHEP::cm;
G4Box *DWCwindowSolid =
new G4Box("DWC_window", 0.5 * DWCwindowXY, 0.5 * DWCwindowXY,
0.5 * DWCwindowThickness);
auto DWCwindowLogical =
new G4LogicalVolume(DWCwindowSolid, fMatKAPTON, "DWC_window");
DWCwindowLogical->SetVisAttributes(visAttributes);
new G4PVPlacement(
0, G4ThreeVector(0, 0., 27.5 * CLHEP::mm - DWCwindowThickness / 2.),
DWCwindowLogical, "DWC_window_0", fDWClogical, true, 0, true);
new G4PVPlacement(
0, G4ThreeVector(0, 0., -(27.5 * CLHEP::mm - DWCwindowThickness / 2.)),
DWCwindowLogical, "DWC_window_1", fDWClogical, true, 1, true);
G4RotationMatrix *rotation = new G4RotationMatrix();
rotation->rotateZ(90 * CLHEP::deg);
// WChambAl1
G4double DWCal1thickness = 2 * 2.5 * CLHEP::mm;
G4double DWCal1x = 2 * 8.25 * CLHEP::cm;
G4double DWCal1y = 2 * 2.75 * CLHEP::cm;
G4Box *DWCal1solid =
new G4Box("DWC_al1", 0.5 * DWCal1x, 0.5 * DWCal1y, 0.5 * DWCal1thickness);
auto DWCal1logical = new G4LogicalVolume(DWCal1solid, fMatAl, "DWC_al1");
DWCal1logical->SetVisAttributes(visAttributes);
new G4PVPlacement(0,
G4ThreeVector(0.5 * DWCal1y, 0.5 * DWCal1x,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_0", fDWClogical, true, 0, true);
new G4PVPlacement(rotation,
G4ThreeVector(-0.5 * DWCal1x, 0.5 * DWCal1y,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_1", fDWClogical, true, 1, true);
new G4PVPlacement(0,
G4ThreeVector(-0.5 * DWCal1y, -0.5 * DWCal1x,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_2", fDWClogical, true, 2, true);
new G4PVPlacement(rotation,
G4ThreeVector(0.5 * DWCal1x, -0.5 * DWCal1y,
(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_3", fDWClogical, true, 3, true);
new G4PVPlacement(
0,
G4ThreeVector(0.5 * DWCal1y, 0.5 * DWCal1x,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_4", fDWClogical, true, 4, true);
new G4PVPlacement(
rotation,
G4ThreeVector(-0.5 * DWCal1x, 0.5 * DWCal1y,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_5", fDWClogical, true, 5, true);
new G4PVPlacement(
0,
G4ThreeVector(-0.5 * DWCal1y, -0.5 * DWCal1x,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_6", fDWClogical, true, 6, true);
new G4PVPlacement(
rotation,
G4ThreeVector(0.5 * DWCal1x, -0.5 * DWCal1y,
-(0.5 * DWCthickness - 0.5 * DWCal1thickness)),
DWCal1logical, "DWC_al1_7", fDWClogical, true, 7, true);
// WChambAl2
G4double DWCal2thickness = 2 * 2.25 * CLHEP::cm;
G4double DWCal2x = 2 * 10.75 * CLHEP::cm;
G4double DWCal2y = 2 * 2.5 * CLHEP::mm;
G4Box *DWCal2solid =
new G4Box("DWC_al2", 0.5 * DWCal2x, 0.5 * DWCal2y, 0.5 * DWCal2thickness);
auto DWCal2logical = new G4LogicalVolume(DWCal2solid, fMatAl, "DWC_al2");
DWCal2logical->SetVisAttributes(visAttributes);
new G4PVPlacement(0, G4ThreeVector(0.5 * DWCal2y, 0.5 * DWCal2x, 0),
DWCal2logical, "DWC_al2_0", fDWClogical, true, 0, true);
new G4PVPlacement(rotation, G4ThreeVector(-0.5 * DWCal2x, 0.5 * DWCal2y, 0),
DWCal2logical, "DWC_al2_1", fDWClogical, true, 1, true);
new G4PVPlacement(0, G4ThreeVector(-0.5 * DWCal2y, -0.5 * DWCal2x, 0),
DWCal2logical, "DWC_al2_2", fDWClogical, true, 2, true);
new G4PVPlacement(rotation, G4ThreeVector(0.5 * DWCal2x, -0.5 * DWCal2y, 0),
DWCal2logical, "DWC_al2_3", fDWClogical, true, 3, true);
// WChambGasVet
G4double DWCgasVetThickness = 2 * 2.5 * CLHEP::mm;
G4double DWCgasVetX = 2 * 7.25 * CLHEP::cm;
G4double DWCgasVetY = 2 * 1.25 * CLHEP::cm;
G4Box *DWCgasVetSolid = new G4Box("DWC_gasVet", 0.5 * DWCgasVetX,
0.5 * DWCgasVetY, 0.5 * DWCgasVetThickness);
auto DWCgasVetLogical =
new G4LogicalVolume(DWCgasVetSolid, fMatPolyethylene, "DWC_gasVet");
DWCgasVetLogical->SetVisAttributes(visAttributes);
new G4PVPlacement(0,
G4ThreeVector(0.5 * DWCgasVetY, 0.5 * DWCgasVetX,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_0", fDWCgasLogical, true, 0,
true);
new G4PVPlacement(rotation,
G4ThreeVector(-0.5 * DWCgasVetX, 0.5 * DWCgasVetY,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_1", fDWCgasLogical, true, 1,
true);
new G4PVPlacement(0,
G4ThreeVector(-0.5 * DWCgasVetY, -0.5 * DWCgasVetX,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_2", fDWCgasLogical, true, 2,
true);
new G4PVPlacement(rotation,
G4ThreeVector(0.5 * DWCgasVetX, -0.5 * DWCgasVetY,
0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_3", fDWCgasLogical, true, 3,
true);
new G4PVPlacement(0, G4ThreeVector(0.5 * DWCgasVetY, 0.5 * DWCgasVetX, 0),
DWCgasVetLogical, "DWC_gasVet_4", fDWCgasLogical, true, 4,
true);
new G4PVPlacement(
rotation, G4ThreeVector(-0.5 * DWCgasVetX, 0.5 * DWCgasVetY, 0),
DWCgasVetLogical, "DWC_gasVet_5", fDWCgasLogical, true, 5, true);
new G4PVPlacement(0, G4ThreeVector(-0.5 * DWCgasVetY, -0.5 * DWCgasVetX, 0),
DWCgasVetLogical, "DWC_gasVet_6", fDWCgasLogical, true, 6,
true);
new G4PVPlacement(
rotation, G4ThreeVector(0.5 * DWCgasVetX, -0.5 * DWCgasVetY, 0),
DWCgasVetLogical, "DWC_gasVet_7", fDWCgasLogical, true, 7, true);
new G4PVPlacement(
0,
G4ThreeVector(0.5 * DWCgasVetY, 0.5 * DWCgasVetX,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_8", fDWCgasLogical, true, 8, true);
new G4PVPlacement(
rotation,
G4ThreeVector(-0.5 * DWCgasVetX, 0.5 * DWCgasVetY,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_9", fDWCgasLogical, true, 9, true);
new G4PVPlacement(
0,
G4ThreeVector(-0.5 * DWCgasVetY, -0.5 * DWCgasVetX,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_10", fDWCgasLogical, true, 10, true);
new G4PVPlacement(
rotation,
G4ThreeVector(0.5 * DWCgasVetX, -0.5 * DWCgasVetY,
-0.5 * (DWCgasThickness - DWCgasVetThickness)),
DWCgasVetLogical, "DWC_gasVet_11", fDWCgasLogical, true, 11, true);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void HGCalTBMaterials::PlaceItemInLogicalVolume(std::string aName,
G4double &aZ0,
G4LogicalVolume *aLogicMother) {
if (aName.find("_DAISY") != std::string::npos) {
aName.resize(aName.find("_DAISY"));
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
double dx_ = 2 * std::sin(fAlpha) * 11 * fSiPixelSideLength;
double dy_ = 11 * fSiPixelSideLength * (2. + 2 * std::cos(fAlpha));
int nRows_[3] = {1, 2, 1};
for (int nC = 0; nC < 3; nC++) {
for (int middle_index = 0; middle_index < nRows_[nC]; middle_index++) {
new G4PVPlacement(
0,
G4ThreeVector(dy_ * (middle_index - nRows_[nC] / 2. + 0.5),
-nC * dx_ / 2, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
if (nC <= 0)
continue;
new G4PVPlacement(
0,
G4ThreeVector(dy_ * (middle_index - nRows_[nC] / 2. + 0.5),
+nC * dx_ / 2, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
}
}
aZ0 += fThicknessMap[aName];
} else if (aName.find("_SUMMER2017TRIPLET") != std::string::npos) {
aName.resize(aName.find("_SUMMER2017TRIPLET"));
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
double dx_ = 2 * std::sin(fAlpha) * 11 * fSiPixelSideLength;
double dy_ = 11 * fSiPixelSideLength * (2. + 2 * std::cos(fAlpha));
int nRows_[2] = {1, 2};
for (int nC = 0; nC < 2; nC++) {
new G4PVPlacement(0,
G4ThreeVector(-dy_ * (0 - nRows_[nC] / 2. + 0.5),
-nC * dx_ / 2,
aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
if (nC <= 0)
continue;
new G4PVPlacement(0,
G4ThreeVector(-dy_ * (0 - nRows_[nC] / 2. + 0.5),
+nC * dx_ / 2,
aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
}
aZ0 += fThicknessMap[aName];
} else if (aName.find("_rot30") != std::string::npos) {
aName.resize(aName.find("_rot30"));
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
G4RotationMatrix *rot = new G4RotationMatrix;
rot->rotateZ(30 * CLHEP::deg);
new G4PVPlacement(rot,
G4ThreeVector(0, 0, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
aZ0 += fThicknessMap[aName];
} else {
if (fCopyCounterMap.find(aName) == fCopyCounterMap.end())
fCopyCounterMap[aName] = 0;
new G4PVPlacement(0, G4ThreeVector(0, 0, aZ0 + 0.5 * fThicknessMap[aName]),
fLogicalVolumeMap[aName], aName, aLogicMother, false,
fCopyCounterMap[aName]++, true);
aZ0 += fThicknessMap[aName];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,230 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "PrimaryGeneratorAction.hh"
#include "PrimaryGeneratorMessenger.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4RunManager.hh"
#include "Randomize.hh"
#ifdef WITHROOT
#include "G4MTRunManager.hh"
#include "G4Run.hh"
#include "TFile.h"
#include "TTreeReader.h"
#include "TTreeReaderValue.h"
#endif
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::PrimaryGeneratorAction()
: G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr),
fEnvelopeBox(nullptr) {
G4int n_particle = 1;
fParticleGun = new G4ParticleGun(n_particle);
// default particle kinematic
G4ParticleTable *particleTable = G4ParticleTable::GetParticleTable();
G4String particleName;
G4ParticleDefinition *particle =
particleTable->FindParticle(particleName = "e+");
fParticleGun->SetParticleDefinition(particle);
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
fParticleGun->SetParticleEnergy(30. * CLHEP::GeV);
fParticleGun->SetParticlePosition(G4ThreeVector(0., 0., 0.));
fMessenger = new PrimaryGeneratorMessenger(this);
#ifdef WITHROOT
if (fReadInputFile)
OpenInput();
#endif
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifdef WITHROOT
void PrimaryGeneratorAction::OpenInput() {
if (fInputFile != nullptr) {
delete fInputFile;
fInputFile = nullptr;
}
fInputFile = new TFile(fPathInputFile, "READ");
if (fInputFile == nullptr || fInputFile->IsZombie()) {
G4ExceptionDescription msg;
msg << "Input file '" << fPathInputFile << "' cannot be opened.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()", "WrongInputName",
FatalErrorInArgument, msg);
}
auto fileDirectory =
dynamic_cast<TDirectory *>(fInputFile->Get("VirtualDetector"));
if (fileDirectory == nullptr) {
G4ExceptionDescription msg;
msg << "Input file '" << fPathInputFile
<< "' does not contain 'VirtualDetector' directory.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"WrongInputDirectory", FatalErrorInArgument, msg);
}
fHgcalReader = new TTreeReader("HGCAL", fileDirectory);
fHgcalEventId = new TTreeReaderValue<Float_t>(*fHgcalReader, "EventID");
fHgcalPdgId = new TTreeReaderValue<Float_t>(*fHgcalReader, "PDGid");
fHgcalPosX = new TTreeReaderValue<Float_t>(*fHgcalReader, "x");
fHgcalPosY = new TTreeReaderValue<Float_t>(*fHgcalReader, "y");
fHgcalMomX = new TTreeReaderValue<Float_t>(*fHgcalReader, "Px");
fHgcalMomY = new TTreeReaderValue<Float_t>(*fHgcalReader, "Py");
fHgcalMomZ = new TTreeReaderValue<Float_t>(*fHgcalReader, "Pz");
return;
}
#endif
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorAction::~PrimaryGeneratorAction() {
delete fParticleGun;
#ifdef WITHROOT
delete fInputFile;
#endif
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent) {
#ifdef WITHROOT
if (fReadInputFile) {
// get primary particles from input file
if (fInputFile == nullptr) {
OpenInput();
}
Float_t currentEventId = -1;
while (fHgcalReader->Next()) {
// First particle - set event ID
if (currentEventId == -1) {
currentEventId = **fHgcalEventId;
fEventCounter++;
// check if event should be ignored (is before the start position)
if (fEventCounter < fStartFromEvent)
continue;
} else {
// check if event is to be skipped
if (fEventCounter < fStartFromEvent) {
if (currentEventId != **fHgcalEventId)
currentEventId = -1;
continue;
} else {
// check if current particle belongs to the next event
if (currentEventId != **fHgcalEventId)
break;
}
}
auto vertex = new G4PrimaryVertex(
G4ThreeVector(**fHgcalPosX, **fHgcalPosY, 32.5 * CLHEP::mm), 0 * CLHEP::s);
auto particleDefinition =
G4ParticleTable::GetParticleTable()->FindParticle(**fHgcalPdgId);
auto particle = new G4PrimaryParticle(particleDefinition);
G4ThreeVector momentum(**fHgcalMomX, **fHgcalMomY, **fHgcalMomZ);
particle->SetMomentumDirection(momentum.unit());
particle->SetKineticEnergy(momentum.mag());
vertex->SetPrimary(particle);
anEvent->AddPrimaryVertex(vertex);
}
// if no particles are left - terminate run
if (fEventCounter >= fStartFromEvent &&
anEvent->GetNumberOfPrimaryVertex() == 0) {
G4ExceptionDescription msg;
msg << "Input file does not contain any more events (current event ID = "
<< anEvent->GetEventID() << ").\n";
msg << "Run will be aborted with " << anEvent->GetEventID()
<< " events processed.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"EndOfInputFile", JustWarning, msg);
G4RunManager::GetRunManager()->AbortRun();
}
// warn if this is the last event and some events are left in the file
// unprocessed
if (G4RunManager::GetRunManager()
->GetCurrentRun()
->GetNumberOfEventToBeProcessed() == anEvent->GetEventID() + 1) {
G4ExceptionDescription msg;
msg << "Input file contains more events than requested in the run.\n";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"UnusedEventsInInputFile", JustWarning, msg);
}
} else
#endif
{
// Beam position: z
// Use value set by UI command, or set it to edge of the world volume
if (fBeamZ0 == -999 * CLHEP::m) {
G4double worldDZ = 0;
if (!fEnvelopeBox) {
G4LogicalVolume *envLV =
G4LogicalVolumeStore::GetInstance()->GetVolume("World");
if (envLV)
fEnvelopeBox = dynamic_cast<G4Box *>(envLV->GetSolid());
}
if (fEnvelopeBox) {
worldDZ = fEnvelopeBox->GetZHalfLength();
fBeamZ0 = -worldDZ;
} else {
G4ExceptionDescription msg;
msg << "World volume of box shape not found.\n";
msg << "Perhaps you have changed geometry.\n";
msg << "The gun will be place at the center.";
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
"WorldVolume", JustWarning, msg);
}
}
// Beam position: x,y
switch (fBeamType) {
case eNone:
default:
fParticleGun->SetParticlePosition(G4ThreeVector(0, 0, fBeamZ0));
break;
case eGaussian:
fParticleGun->SetParticlePosition(
G4ThreeVector(G4RandGauss::shoot(0., fSigmaBeamX),
G4RandGauss::shoot(0., fSigmaBeamY), fBeamZ0));
break;
case eFlat:
fParticleGun->SetParticlePosition(
G4ThreeVector(G4RandFlat::shoot(-fSigmaBeamX, fSigmaBeamX),
G4RandFlat::shoot(-fSigmaBeamY, fSigmaBeamY), fBeamZ0));
break;
}
// Particle momentum
if (fMomentumGaussianSpread > 0) {
double energy = fParticleGun->GetParticleEnergy();
energy += G4RandGauss::shoot(0., fMomentumGaussianSpread) * energy;
fParticleGun->SetParticleEnergy(energy);
}
fParticleGun->GeneratePrimaryVertex(anEvent);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,180 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "PrimaryGeneratorMessenger.hh"
#include "PrimaryGeneratorAction.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIdirectory.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorMessenger::PrimaryGeneratorMessenger(
PrimaryGeneratorAction *aPrimaryGeneratorAction)
: fPrimaryGenerator(aPrimaryGeneratorAction) {
fDirectory = new G4UIdirectory("/HGCalTestbeam/generator/");
fDirectory->SetGuidance("Primary generator control commands.");
#ifdef WITHROOT
fReadInputCmd =
new G4UIcmdWithABool("/HGCalTestbeam/generator/readInputFile", this);
fReadInputCmd->SetGuidance(
"If instead of particle gun, particle data should be read from file.");
fReadInputCmd->SetParameterName("ifInput", true);
fReadInputCmd->SetDefaultValue(false);
fPathInputCmd =
new G4UIcmdWithAString("/HGCalTestbeam/generator/pathInputFile", this);
fPathInputCmd->SetGuidance("Path to input file containing particle data.");
fPathInputCmd->SetParameterName("path", true);
fStartFromEventCmd =
new G4UIcmdWithAnInteger("/HGCalTestbeam/generator/startFromEvent", this);
fStartFromEventCmd->SetGuidance(
"From which event in the file HGCalTestbeam should be started.");
fStartFromEventCmd->SetParameterName("startFrom", true);
fStartFromEventCmd->SetDefaultValue(0);
#endif
fMomentumSpreadCmd =
new G4UIcmdWithADouble("/HGCalTestbeam/generator/momentumSpread", this);
fMomentumSpreadCmd->SetGuidance("For particle gun generator:");
fMomentumSpreadCmd->SetGuidance(
"Gaussian momentum spread relative to gun energy");
fMomentumSpreadCmd->SetGuidance("(e.g. 0.05 means 5% * gun energy))");
fMomentumSpreadCmd->SetParameterName("momentumSpread", true);
fMomentumSpreadCmd->SetRange("momentumSpread>=0");
fMomentumSpreadCmd->SetDefaultValue(0);
fBeamSpreadTypeCmd =
new G4UIcmdWithAString("/HGCalTestbeam/generator/beamSpread", this);
fBeamSpreadTypeCmd->SetGuidance("Type of beam profile spread.");
fBeamSpreadTypeCmd->SetParameterName("beamSpreadType", true);
fBeamSpreadTypeCmd->SetCandidates("none Gaussian flat");
fBeamSpreadTypeCmd->SetDefaultValue("none");
fBeamSpreadXCmd = new G4UIcmdWithADoubleAndUnit(
"/HGCalTestbeam/generator/beamSpreadX", this);
fBeamSpreadXCmd->SetGuidance("Defines sigma_X for Gaussian spread, or "
"half-side range for flat spread.");
fBeamSpreadXCmd->SetParameterName("sigmaBeamX", true, true);
fBeamSpreadXCmd->SetRange("sigmaBeamX>=0");
fBeamSpreadXCmd->SetDefaultUnit("cm");
fBeamSpreadXCmd->SetUnitCandidates("micron mm cm m km");
fBeamSpreadYCmd = new G4UIcmdWithADoubleAndUnit(
"/HGCalTestbeam/generator/beamSpreadY", this);
fBeamSpreadYCmd->SetGuidance("Defines sigma_Y for Gaussian spread, or "
"half-side range for flat spread.");
fBeamSpreadYCmd->SetParameterName("sigmaBeamY", true, true);
fBeamSpreadYCmd->SetRange("sigmaBeamY>=0");
fBeamSpreadYCmd->SetDefaultUnit("cm");
fBeamSpreadYCmd->SetUnitCandidates("micron mm cm m km");
fBeamZ0Cmd =
new G4UIcmdWithADoubleAndUnit("/HGCalTestbeam/generator/beamZ0", this);
fBeamZ0Cmd->SetGuidance(
"Beam position along the beam line (default: edge of the world volume).");
fBeamZ0Cmd->SetParameterName("z0", true, true);
fBeamZ0Cmd->SetDefaultUnit("cm");
fBeamZ0Cmd->SetUnitCandidates("micron mm cm m km");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
PrimaryGeneratorMessenger::~PrimaryGeneratorMessenger() {
delete fDirectory;
#ifdef WITHROOT
delete fReadInputCmd;
delete fPathInputCmd;
delete fStartFromEventCmd;
#endif
delete fMomentumSpreadCmd;
delete fBeamSpreadTypeCmd;
delete fBeamSpreadXCmd;
delete fBeamSpreadYCmd;
delete fBeamZ0Cmd;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void PrimaryGeneratorMessenger::SetNewValue(G4UIcommand *command,
G4String newValues) {
if (command == fMomentumSpreadCmd) {
fPrimaryGenerator->SetMomentumSpread(
fMomentumSpreadCmd->GetNewDoubleValue(newValues));
} else if (command == fBeamSpreadTypeCmd) {
fPrimaryGenerator->SetBeamSpreadType(newValues);
} else if (command == fBeamSpreadXCmd) {
fPrimaryGenerator->SetBeamSpreadX(
fBeamSpreadXCmd->GetNewDoubleValue(newValues));
} else if (command == fBeamSpreadYCmd) {
fPrimaryGenerator->SetBeamSpreadY(
fBeamSpreadYCmd->GetNewDoubleValue(newValues));
} else if (command == fBeamZ0Cmd) {
fPrimaryGenerator->SetBeamZ0(fBeamZ0Cmd->GetNewDoubleValue(newValues));
}
#ifdef WITHROOT
else if (command == fReadInputCmd) {
fPrimaryGenerator->SetIfUseInputFiles(
fReadInputCmd->GetNewBoolValue(newValues));
} else if (command == fPathInputCmd) {
fPrimaryGenerator->SetInputFiles(newValues);
} else if (command == fStartFromEventCmd) {
fPrimaryGenerator->SetStartFromEvent(
fStartFromEventCmd->GetNewIntValue(newValues));
}
#endif
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4String PrimaryGeneratorMessenger::GetCurrentValue(G4UIcommand *command) {
G4String cv;
if (command == fMomentumSpreadCmd) {
cv = fMomentumSpreadCmd->ConvertToString(
fPrimaryGenerator->GetMomentumSpread());
} else if (command == fBeamSpreadTypeCmd) {
cv = fPrimaryGenerator->GetBeamSpreadType();
} else if (command == fBeamSpreadXCmd) {
cv = fBeamSpreadXCmd->ConvertToString(fPrimaryGenerator->GetBeamSpreadX());
} else if (command == fBeamSpreadYCmd) {
cv = fBeamSpreadYCmd->ConvertToString(fPrimaryGenerator->GetBeamSpreadY());
} else if (command == fBeamZ0Cmd) {
cv = fBeamZ0Cmd->ConvertToString(fPrimaryGenerator->GetBeamZ0());
}
#ifdef WITHROOT
else if (command == fReadInputCmd) {
cv =
fReadInputCmd->ConvertToString(fPrimaryGenerator->GetIfUseInputFiles());
} else if (command == fPathInputCmd) {
cv = fPrimaryGenerator->GetInputFiles();
}
#endif
return cv;
}
@@ -0,0 +1,142 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "RunAction.hh"
#include "EventAction.hh"
#include "G4UserRunAction.hh"
#include "G4GenericMessenger.hh"
#include "G4String.hh"
#include "g4root.hh"
#include <iostream>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::RunAction(EventAction *eventAction)
: G4UserRunAction(), fEventAction(eventAction),
fOutputFileDir("sim_HGCalTB_G4Standalone") {
fMessenger =
new G4GenericMessenger(this, "/HGCalTestbeam/output/", "Output control");
// randomizePrimary command
auto &fileNameCommand = fMessenger->DeclareProperty("file", fOutputFileDir);
G4String guidance = "Define output file location.";
fileNameCommand.SetGuidance(guidance);
fileNameCommand.SetParameterName("filename", true);
fileNameCommand.SetDefaultValue("sim_HGCalTB_G4Standalone");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
RunAction::~RunAction() { delete G4AnalysisManager::Instance(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::BeginOfRunAction(const G4Run *) {
// Create analysis manager
// The choice of analysis technology is done via selection of a namespaces
auto analysisManager = G4AnalysisManager::Instance();
G4cout << "Using " << analysisManager->GetType() << G4endl;
// Default settings
analysisManager->SetNtupleMerging(true);
analysisManager->SetVerboseLevel(1);
std::cout << "Output file is: " << fOutputFileDir << std::endl;
analysisManager->SetFileName(fOutputFileDir);
if (fEventAction) {
analysisManager->CreateNtuple("hits", "hits");
analysisManager->CreateNtupleIColumn("event"); // column Id = 0
analysisManager->CreateNtupleIColumn(
"pdgID", fEventAction->fPrimariesPDG); // column Id = 1
analysisManager->CreateNtupleDColumn(
"beamEnergy", fEventAction->fPrimariesEnergy); // column Id = 2
analysisManager->CreateNtupleDColumn(
"beamX_cm", fEventAction->fPrimariesX); // column Id = 3
analysisManager->CreateNtupleDColumn(
"beamY_cm", fEventAction->fPrimariesY); // column Id = 4
analysisManager->CreateNtupleDColumn(
"beamZ_cm", fEventAction->fPrimariesZ); // column Id = 5
analysisManager->CreateNtupleIColumn("siliconHits_ID",
fEventAction->fSiHitsID);
analysisManager->CreateNtupleDColumn("siliconHits_x_cm",
fEventAction->fSiHitsX);
analysisManager->CreateNtupleDColumn("siliconHits_y_cm",
fEventAction->fSiHitsY);
analysisManager->CreateNtupleDColumn("siliconHits_z_cm",
fEventAction->fSiHitsZ);
analysisManager->CreateNtupleDColumn("siliconHits_Edep_keV",
fEventAction->fSiHitsEdep);
analysisManager->CreateNtupleDColumn("siliconHits_EdepNonIonizing_keV",
fEventAction->fSiHitsEdepNonIonising);
analysisManager->CreateNtupleDColumn("siliconHits_TOA_ns",
fEventAction->fSiHitsTOA);
analysisManager->CreateNtupleDColumn("siliconHits_TOA_last_ns",
fEventAction->fSiHitsTOA);
analysisManager->CreateNtupleIColumn("siliconHits_type",
fEventAction->fSiHitsType);
analysisManager->CreateNtupleIColumn("SiPMHits_ID",
fEventAction->fSiPMhitsID);
analysisManager->CreateNtupleDColumn("SiPMHits_x_cm",
fEventAction->fSiPMhitsX);
analysisManager->CreateNtupleDColumn("SiPMHits_y_cm",
fEventAction->fSiPMhitsY);
analysisManager->CreateNtupleDColumn("SiPMHits_z_cm",
fEventAction->fSiPMhitsZ);
analysisManager->CreateNtupleDColumn("SiPMHits_Edep_keV",
fEventAction->fSiPMhitsEdep);
analysisManager->CreateNtupleDColumn(
"SiPMHits_EdepNonIonizing_keV", fEventAction->fSiPMhitsEdepNonIonising);
analysisManager->CreateNtupleDColumn("SiPMHits_TOA_ns",
fEventAction->fSiPMhitsTOA);
analysisManager->CreateNtupleIColumn("SiPMHits_type",
fEventAction->fSiPMhitsType);
analysisManager->CreateNtupleDColumn(
"signalSum_HGCAL_GeV"); // column Id = 23
analysisManager->CreateNtupleDColumn("COGZ_HGCAL_cm"); // column Id = 24
analysisManager->CreateNtupleIColumn("NHits_HGCAL"); // column Id = 25
analysisManager->CreateNtupleDColumn(
"signalSum_AHCAL_GeV"); // column Id = 26
analysisManager->CreateNtupleDColumn("COGZ_AHCAL_cm"); // column Id = 27
analysisManager->CreateNtupleIColumn("NHits_AHCAL"); // column Id = 28
analysisManager->FinishNtuple();
}
analysisManager->OpenFile();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void RunAction::EndOfRunAction(const G4Run *) {
auto analysisManager = G4AnalysisManager::Instance();
analysisManager->Write();
analysisManager->CloseFile();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,86 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiPMHit.hh"
#include <cstdlib>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SiPMHit::SiPMHit(G4String aVolumeName, G4int aCopyNumSensor,
G4int aCopyNumCell)
: fVolumeName(aVolumeName), fCopyNumCell(aCopyNumCell),
fCopyNumSensor(aCopyNumSensor) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiPMHit::Digitise(const G4double aTimeWindow,
const G4double aToaThreshold) {
// process energy deposits
if (fEdep.size() == 0) {
fIsValidHit = false;
return;
}
std::sort(fEdep.begin(), fEdep.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
G4double firstHitTime = fEdep[0].second;
fEdepDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow < 0 || fEdep[i].second < firstHitTime + aTimeWindow)
fEdepDigi += fEdep[i].first;
#ifdef DEBUG
else
std::cout << "Rejecting hit (" << fEdep[i].first << " keV) at time "
<< fEdep[i].second << "(start: " << firstHitTime << ")"
<< std::endl;
#endif
if ((fTimeOfArrival == -1) && (fEdepDigi > aToaThreshold))
fTimeOfArrival = fEdep[i].second;
}
fIsValidHit = (fEdepDigi > 0);
// non ionizing part, does not contribute to TOAs
if (fEdepNonIonizing.size() == 0)
return;
std::sort(fEdepNonIonizing.begin(), fEdepNonIonizing.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
fEdepNonIonizingDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow == -1 ||
fEdepNonIonizing[i].second < firstHitTime + aTimeWindow)
fEdepNonIonizingDigi += fEdepNonIonizing[i].first;
}
}
@@ -0,0 +1,77 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiPMSD.hh"
SiPMSD::SiPMSD(G4String name) : G4VSensitiveDetector("SiPMHitCollection") {
G4cout << "creating a sensitive detector with name: " << name << G4endl;
collectionName.insert("SiPMHitCollection");
}
SiPMSD::~SiPMSD() {}
void SiPMSD::Initialize(G4HCofThisEvent *HCE) {
fHitCollection = new SiPMHitCollection(GetName(), collectionName[0]);
if (fHCID < 0)
fHCID = GetCollectionID(0);
HCE->AddHitsCollection(fHCID, fHitCollection);
fTmpHits.clear();
}
void SiPMSD::EndOfEvent(G4HCofThisEvent *) {
for (auto it = fTmpHits.begin(); it != fTmpHits.end(); ++it)
fHitCollection->insert(it->second);
}
G4bool SiPMSD::ProcessHits(G4Step *step, G4TouchableHistory *) {
G4TouchableHandle touchable = step->GetPreStepPoint()->GetTouchableHandle();
G4int copyNumCell = touchable->GetVolume(0)->GetCopyNo();
G4int copyNumSensor = touchable->GetVolume(1)->GetCopyNo();
int tmp_ID = 1000 * copyNumSensor + copyNumCell;
if (fTmpHits.find(tmp_ID) == fTmpHits.end()) { // make new hit
G4String vol_name = touchable->GetVolume(0)->GetName();
fTmpHits[tmp_ID] = new SiPMHit(vol_name, copyNumSensor, copyNumCell);
G4double hitX = (touchable->GetVolume(1)->GetTranslation().x() +
touchable->GetVolume(0)->GetTranslation().x()) /
CLHEP::cm;
G4double hitY = (touchable->GetVolume(1)->GetTranslation().x() +
touchable->GetVolume(0)->GetTranslation().y()) /
CLHEP::cm;
G4double hitZ = touchable->GetVolume(1)->GetTranslation().z() / CLHEP::cm;
fTmpHits[tmp_ID]->SetPosition(hitX, hitY, hitZ); // in cm
}
G4double edep = step->GetTotalEnergyDeposit() / CLHEP::keV; // in keV
G4double edepNonIonizing = step->GetNonIonizingEnergyDeposit() / CLHEP::keV;
G4double timedep = step->GetPostStepPoint()->GetGlobalTime() / CLHEP::ns;
fTmpHits[tmp_ID]->AddEdep(edep, timedep);
fTmpHits[tmp_ID]->AddEdepNonIonizing(edepNonIonizing, timedep);
return true;
}
@@ -0,0 +1,112 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiliconPixelHit.hh"
#include "G4RotationMatrix.hh"
#include "G4SubtractionSolid.hh"
#include "G4Transform3D.hh"
#include "G4VVisManager.hh"
#include "G4VisAttributes.hh"
#include "HGCalTBMaterials.hh"
#include <cstdlib>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SiliconPixelHit::SiliconPixelHit(G4String aVolumeName, G4int aCopyNumSensor,
G4int aCopyNumCell)
: fVolumeName(aVolumeName), fCopyNumCell(aCopyNumCell),
fCopyNumSensor(aCopyNumSensor) {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelHit::Digitise(const G4double aTimeWindow,
const G4double aToaThreshold) {
// process energy deposits
if (fEdep.size() == 0) {
fIsValidHit = false;
return;
}
std::sort(fEdep.begin(), fEdep.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
G4double firstHitTime = fEdep[0].second;
fEdepDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow < 0 || fEdep[i].second < firstHitTime + aTimeWindow)
fEdepDigi += fEdep[i].first;
if (fEdepDigi > aToaThreshold) {
if (fTimeOfArrival == -1)
fTimeOfArrival = fEdep[i].second;
fTimeOfArrivalLast = fEdep[i].second;
}
}
fIsValidHit = (fEdepDigi > 0);
// non ionizing part, does not contribute to TOAs
if (fEdepNonIonizing.size() == 0)
return;
std::sort(fEdepNonIonizing.begin(), fEdepNonIonizing.end(),
[](const std::pair<G4double, G4double> &left,
const std::pair<G4double, G4double> &right) {
return left.second < right.second; // second = time
});
fEdepNonIonizingDigi = 0;
for (size_t i = 0; i < fEdep.size(); i++) {
if (aTimeWindow == -1 ||
fEdepNonIonizing[i].second < firstHitTime + aTimeWindow)
fEdepNonIonizingDigi += fEdepNonIonizing[i].first;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelHit::Draw() {
G4VVisManager *pVVisManager = G4VVisManager::GetConcreteInstance();
if (!(fEdepDigi > 0))
return;
if (pVVisManager) {
if (!pVVisManager->FilterHit(*this))
return;
G4Transform3D trans(G4RotationMatrix(),
G4ThreeVector(fPosX * CLHEP::cm, fPosY * CLHEP::cm, fPosZ * CLHEP::cm));
G4VisAttributes attribs;
auto solid = HexagonSolid("dummy", 0.3 * CLHEP::mm, 0.6496345 * CLHEP::cm);
G4Colour colour(1, 0, 0);
attribs.SetColour(colour);
attribs.SetForceSolid(true);
pVVisManager->Draw(*solid, attribs, trans);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,92 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "SiliconPixelSD.hh"
#include "G4String.hh"
SiliconPixelSD::SiliconPixelSD(G4String name)
: G4VSensitiveDetector("SiliconPixelHitCollection") {
G4cout << "creating a sensitive detector with name: " << name << G4endl;
collectionName.insert("SiliconPixelHitCollection");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
SiliconPixelSD::~SiliconPixelSD() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelSD::Initialize(G4HCofThisEvent *HCE) {
fHitCollection = new SiliconPixelHitCollection(GetName(), collectionName[0]);
if (fHCID < 0)
fHCID = GetCollectionID(0);
HCE->AddHitsCollection(fHCID, fHitCollection);
fTmpHits.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void SiliconPixelSD::EndOfEvent(G4HCofThisEvent *) {
for (auto it = fTmpHits.begin(); it != fTmpHits.end(); ++it)
fHitCollection->insert(it->second);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool SiliconPixelSD::ProcessHits(G4Step *step, G4TouchableHistory *) {
G4TouchableHandle touchable = step->GetPreStepPoint()->GetTouchableHandle();
G4int copyNumCell = touchable->GetVolume(0)->GetCopyNo();
G4int copyNumSensor = touchable->GetVolume(1)->GetCopyNo();
int tmp_ID = 1000 * copyNumSensor + copyNumCell;
if (fTmpHits.find(tmp_ID) == fTmpHits.end()) { // make new hit
G4String vol_name = touchable->GetVolume(0)->GetName();
fTmpHits[tmp_ID] =
new SiliconPixelHit(vol_name, copyNumSensor, copyNumCell);
G4double hitX = (touchable->GetVolume(1)->GetTranslation().x() +
touchable->GetVolume(0)->GetTranslation().x()) /
CLHEP::cm;
G4double hitY = (touchable->GetVolume(1)->GetTranslation().y() +
touchable->GetVolume(0)->GetTranslation().y()) /
CLHEP::cm;
G4double hitZ = touchable->GetVolume(1)->GetTranslation().z() / CLHEP::cm;
fTmpHits[tmp_ID]->SetPosition(hitX, hitY, hitZ); // in cm
}
G4double edep = step->GetTotalEnergyDeposit() / CLHEP::keV; // in keV
G4double edepNonIonizing = step->GetNonIonizingEnergyDeposit() / CLHEP::keV;
G4double timedep = step->GetPostStepPoint()->GetGlobalTime() / CLHEP::ns;
fTmpHits[tmp_ID]->AddEdep(edep, timedep);
fTmpHits[tmp_ID]->AddEdepNonIonizing(edepNonIonizing, timedep);
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+94
View File
@@ -0,0 +1,94 @@
# Macro file for the visualization settings of the HGCal testbeam simulation
#
# Use these open statements to open selected visualization
#
# Use this open statement to create an OpenGL view:
/vis/open OGL 800x600-0+0
#
# Use this open statement to create an OpenInventor view:
#/vis/open OI
#
# Use this open statement to create a .prim file suitable for
# viewing in DAWN:
#/vis/open DAWNFILE
#
# Use this open statement to create a .heprep file suitable for
# viewing in HepRApp:
#/vis/open HepRepFile
#
# Use this open statement to create a .wrl file suitable for
# viewing in a VRML viewer:
#/vis/open VRML2FILE
#
# Disable auto refresh and quieten vis messages whilst scene and
# trajectories are established:
/vis/viewer/set/autoRefresh false
/vis/verbose errors
#
#
# Specify view angle:
/vis/viewer/set/hiddenMarker true
/vis/viewer/set/viewpointThetaPhi -45 30
/vis/viewer/zoom 2
#
# Specify style (surface, wireframe, auxiliary edges,...)
/vis/viewer/set/style surface
/vis/viewer/set/auxiliaryEdge true
/vis/viewer/set/lineSegmentsPerCircle 100
#
# Draw smooth trajectories at end of event, showing trajectory points
# as markers 2 pixels wide:
/vis/modeling/trajectories/create/drawByCharge
/vis/modeling/trajectories/drawByCharge-0/default/setDrawStepPts true
/vis/modeling/trajectories/drawByCharge-0/default/setStepPtsSize 2
# (if too many tracks cause core dump => /tracking/storeTrajectory 0)
#
#
# To draw only gammas:
/vis/filtering/trajectories/create/particleFilter particleFilter-0
/vis/filtering/trajectories/particleFilter-0/add gamma
#
# To invert the above, drawing all particles except gammas,
# keep the above two lines but also add:
/vis/filtering/trajectories/particleFilter-0/invert true
#
# Momentum selection for the drawing
/vis/filtering/trajectories/create/attributeFilter
/vis/filtering/trajectories/attributeFilter-0/setAttribute IMag
/vis/filtering/trajectories/attributeFilter-0/addInterval 10. MeV 1000 GeV
/vis/modeling/trajectories/create/drawByAttribute
/vis/modeling/trajectories/drawByAttribute-0/setAttribute IMag
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval1 1 MeV 10 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval2 10 MeV 100 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval3 100 MeV 200 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval4 200.0 MeV 500 MeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval5 500 MeV 0.9 GeV
/vis/modeling/trajectories/drawByAttribute-0/addInterval interval6 0.9 GeV 10000 GeV
/vis/modeling/trajectories/drawByAttribute-0/interval1/setLineColourRGBA 0.1 0.1 0.1 0.3
/vis/modeling/trajectories/drawByAttribute-0/interval2/setLineColourRGBA 1 0.3 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval3/setLineColourRGBA 1 1 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval4/setLineColourRGBA 0 1 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval5/setLineColourRGBA 1 0 0 1
/vis/modeling/trajectories/drawByAttribute-0/interval6/setLineColourRGBA 0 0 1 1
# Make the background white
/vis/viewer/set/background 1 1 1 1.0
# Make the "World" box invisible
/vis/geometry/set/visibility World 0 false
# Re-establish auto refreshing and verbosity:
/vis/viewer/set/autoRefresh true
/vis/verbose warnings
#
# For file-based drivers, use this to create an empty detector view:
#/vis/viewer/flush
# Change the display limits
/vis/ogl/set/displayListLimit 500000
# Choose geometry setup
/HGCalTestbeam/setup/configuration 0