11.2.2011 Kamil Sedlak
1) correction of GNUmakefile - by mistake a musrSimTest was set there instead of musrSim 2) replacing odet_timeE variable by odet_timeMean 3) replacing one obsolete method from stepping action (Geant 4.9.4 was complaining) by a proper method 4) update of the first part of the documentation 5) implementing a possibility to write out output Root data into a different directory 6) perhaps some other minor changes
This commit is contained in:
parent
a5e99ed164
commit
c2025fea97
@ -3,7 +3,7 @@
|
|||||||
# GNUmakefile for examples module. Gabriele Cosmo, 06/04/98.
|
# GNUmakefile for examples module. Gabriele Cosmo, 06/04/98.
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
name := musrSimTest
|
name := musrSim
|
||||||
G4TARGET := $(name)
|
G4TARGET := $(name)
|
||||||
G4EXLIB := true
|
G4EXLIB := true
|
||||||
##LDFLAGS := $(shell root-config --glibs)
|
##LDFLAGS := $(shell root-config --glibs)
|
||||||
|
BIN
doc/musrSim.pdf
BIN
doc/musrSim.pdf
Binary file not shown.
291
doc/musrSim.tex
291
doc/musrSim.tex
@ -47,40 +47,62 @@ Geant4}. The root output variables are also described.
|
|||||||
\section{Scope of the musrSim program}
|
\section{Scope of the musrSim program}
|
||||||
The program ``musrSim'' is a relatively general program that can be used to simulate
|
The program ``musrSim'' is a relatively general program that can be used to simulate
|
||||||
the response of a $\mu$SR~\cite{Blundel:1999} instruments (detectors) to muons and their decay particles
|
the response of a $\mu$SR~\cite{Blundel:1999} instruments (detectors) to muons and their decay particles
|
||||||
(electrons, positrons and gammas). Even though musrSim is tailored to the needs of
|
(electrons, positrons and gammas), optionaly including ``optical photons''.
|
||||||
the $\mu$SR technique~\cite{shirokaGeant}, it has been used also in the detector development
|
Even though musrSim is tailored to the needs of
|
||||||
|
the $\mu$SR technique~\cite{shirokaGeant}, it has been used also
|
||||||
|
in the studies of beam-line elements like spin rotators, as well as
|
||||||
|
in the detector development
|
||||||
studies without any muons involved, e.g.\ to test the response of an APD-based
|
studies without any muons involved, e.g.\ to test the response of an APD-based
|
||||||
scintillator counters to the irradiation of Sr radioactive source~\cite{AlexeyTestAPD}.
|
scintillator counters to the irradiation of Sr radioactive source~\cite{AlexeyTestAPD}.
|
||||||
|
It should be streitforward to apply musrSim also to the low energy particle-physics
|
||||||
|
experiments with muons.
|
||||||
|
|
||||||
The program is based on the Geant4~\cite{geant} and Root~\cite{root} libraries.
|
The program is based on the Geant4~\cite{geant} and Root~\cite{root} libraries.
|
||||||
Geant4 is Monte Carlo toolkit used (not only) in particle physics to simulate
|
Geant4 is Monte Carlo toolkit used (not only) in particle physics to simulate
|
||||||
the passage of particles through the detectors.
|
the passage of particles through detectors.
|
||||||
Root is an analysis tool that allows to manipulate and analyse the simulated data,
|
Root is an analysis tool that allows one to manipulate and analyse the simulated data,
|
||||||
namely to plot histograms and other graphical output.
|
namely to plot histograms and other graphical output.
|
||||||
|
|
||||||
|
The simulation of an instrument consists of two steps -- simulation of the instrument
|
||||||
|
response, which is done by ``musrSim'' program, and the subsequent analysis of the
|
||||||
|
simulated output by either ``musrSimAna'' program (in case of \musr instruments) or
|
||||||
|
by Root (if a special analysis is required, e.g.\ for non-\musr apparatus).
|
||||||
|
The reason for this spit is purely
|
||||||
|
practical -- while it takes a lot of computer time to simulate large statistics data
|
||||||
|
with musrSim, the subsequent analysis of the simulated data is relatively quick
|
||||||
|
and allows the user to optimise and test different options of the analysis
|
||||||
|
(e.g.\ different thresholds in positron counters, different logic in connecting
|
||||||
|
veto and coincidence detectors, different rate of incoming muons, ...).
|
||||||
|
The ``musrSimAna'' program is described in a separate manual.
|
||||||
|
|
||||||
The aim of the musrSim is to provide an easy-to-use simulation program, which does
|
The aim of the musrSim is to provide an easy-to-use simulation program, which does
|
||||||
not require a deep knowledge of Geant4 in order to simulate a ($\mu$SR) detector.
|
not require a deep knowledge of Geant4 in order to simulate a ($\mu$SR) detector.
|
||||||
In our view, the main advantages of musrSim are:
|
In our view, the main advantages of musrSim are:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Simple way how to define or modify the instrument geometry.
|
\item Simple way how to define or modify the instrument geometry, including
|
||||||
\item Limited (ideally no) need to modify and/or recompile the source code.
|
the sample environment, collimators and other parts.
|
||||||
|
\item Limited (ideally no) need to modify and/or recompile the source code,
|
||||||
|
because the parameters defining the instrument geometry, initial muon beam,
|
||||||
|
electromagnetic fields, and other parameters are defined in
|
||||||
|
a text file (the so called ``macro file'').
|
||||||
\item Implementation of the $\mu$SR-specific classes (muon spin rotation
|
\item Implementation of the $\mu$SR-specific classes (muon spin rotation
|
||||||
in magnetic fields, muonium formation and decay, ...).
|
in magnetic fields, muonium formation and decay, ...).
|
||||||
\item Possibility to read in the output files of the TURTLE~\cite{turtle}
|
\item Possibility to read in the output files of the TURTLE~\cite{turtle}
|
||||||
program for the beam-line simulation.
|
program for the beam-line simulation.
|
||||||
\item Simple way how to define (overlapping) electromagnetic fields.
|
\item Simple way how to define (overlapping) electromagnetic fields.
|
||||||
\item Output in the Root tree.
|
\item Output in the Root tree.
|
||||||
|
\item Possibility to analyse the output with a general ``musrSimAna'' program.
|
||||||
|
\item Possibility to use musrSim easily for calculating muon stopping profile
|
||||||
|
(also in e.g.\ sample cells) or in developments of detector components
|
||||||
|
(e.g.\ light propagation in the scintillator of a positron/muon counter
|
||||||
|
and the subsequent light collectin in a photomultiplier tube or APD).
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
%
|
%
|
||||||
On the other hand, there are also some drawbacks and limitations:
|
On the other hand, there are also some drawbacks and limitations:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item The user has to have an installation of Geant4 and Root before installing musrSim.
|
\item The user has to have an installation of Geant4 and Root before installing musrSim.
|
||||||
\item It is supposed the user will analyse the data with Root, therefore
|
\item It is supposed the user will analyse the data with Root, therefore
|
||||||
Root has to be installed and some knowledge of it is needed.
|
Root has to be installed.
|
||||||
Even though is relatively easy to simulate a $\mu$SR instrument,
|
|
||||||
and to create the output Root file without even knowing the c++
|
|
||||||
programming language, some c++ programming is needed to
|
|
||||||
analyse the simulation output and to plot graphs.
|
|
||||||
\item At present time the program does not simulate any muon-spin related
|
\item At present time the program does not simulate any muon-spin related
|
||||||
physics processes happening in the sample, except for the muon
|
physics processes happening in the sample, except for the muon
|
||||||
spin rotation.
|
spin rotation.
|
||||||
@ -95,17 +117,25 @@ On the other hand, there are also some drawbacks and limitations:
|
|||||||
%=============================================================================================
|
%=============================================================================================
|
||||||
\section{How to install and run musrSim}
|
\section{How to install and run musrSim}
|
||||||
To install and run musrSim, one has to install Geant4 and Root first.
|
To install and run musrSim, one has to install Geant4 and Root first.
|
||||||
The present version of musrSim has been tested with Geant version 4.9.1, patch no.~3
|
The present version of musrSim has been tested with Geant version 4.9.4,
|
||||||
and Root version 5.20.00.
|
and with Root version 5.24.00. While the version of Root should not be critical,
|
||||||
|
the users of musrSim are encouraged to always use the latest version of Geant4
|
||||||
|
due to continuous improvements of this package. A novice
|
||||||
|
user of Geant4 may consider reading 30 pages of chapter~2 of the
|
||||||
|
Geant4 User's Guide for Application Developers, called
|
||||||
|
``Getting Started with Geant4 - Running a Simple Example''.
|
||||||
|
|
||||||
Once Geant4 has been successfully installed and some of the default Geant4 exmples
|
Once Geant4 has been successfully installed and some of the default Geant4 examples
|
||||||
has been run, the musrSim installation package can be downloaded from the web page
|
has been run, the musrSim installation package can be downloaded from the web page
|
||||||
http://lmu.web.psi.ch/simulation/index.html.
|
http://lmu.web.psi.ch/simulation/index.html.
|
||||||
Usually the ``env.sh'' script has to be run to set-up the environment variables
|
Usually the ``env.sh'' script has to be run to set-up the environment variables
|
||||||
appropriatelly before the musrSim or any other Geant4 application can be compiled
|
appropriatelly before the musrSim (and/or any other Geant4 application) can be compiled
|
||||||
or run.
|
and run.
|
||||||
The simulation can be executed by \emph{``musrSim RUNNUMBER.mac''}, where RUNNUMBER.mac is a ``macro file''
|
The simulation is started by executing:
|
||||||
containing the information about the instrument setup. The string ``RUNNUMBER'' represents the integer run number.
|
|
||||||
|
{\bf $>$ musrSim \emph{RUNNUMBER}.mac} \\
|
||||||
|
where \emph{RUNNUMBER}.mac is a ``macro file'' containing the information about
|
||||||
|
the instrument setup. The string \emph{RUNNUMBER} is an integer representing the run number.
|
||||||
|
|
||||||
In order to simulate a new instrument, the user has to define the following blocks of information
|
In order to simulate a new instrument, the user has to define the following blocks of information
|
||||||
in the macro file:
|
in the macro file:
|
||||||
@ -113,10 +143,12 @@ in the macro file:
|
|||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Define the geometry (the so-called ``volumes'') of the new instrument.
|
\item Define the geometry (the so-called ``volumes'') of the new instrument.
|
||||||
Note that in Geant4 volumes can be included inside other volumes
|
Note that in Geant4 volumes can be included inside other volumes
|
||||||
(a ``daughter'' volume is positioned inside the ``mother'' volume),
|
(a ``daughter'' volume is positioned inside its ``mother'' volume),
|
||||||
and it is therefore necessary to distinguish between the global (world)
|
and it is therefore necessary to distinguish between the global (world)
|
||||||
coordinates and the coordinates of the daughter volumes (local coordinates).
|
coordinates and the coordinates of the daughter volumes (local coordinates).
|
||||||
It is not allowed to overlap any two different volumes partially.
|
It is not allowed to overlap the volumes (with the exception of the
|
||||||
|
daughter and mother volume, in which case the daughter volume has to be fully
|
||||||
|
contained within its mother volume).
|
||||||
\item Define the electric and magnetic fields.
|
\item Define the electric and magnetic fields.
|
||||||
\item Define physics processes relevant for your case.
|
\item Define physics processes relevant for your case.
|
||||||
\item Define the initial muon parameters (more generally -- initial particle parameters).
|
\item Define the initial muon parameters (more generally -- initial particle parameters).
|
||||||
@ -126,10 +158,28 @@ in the macro file:
|
|||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
By default, the output of the simulation is written out in the subdirectory ``data'' with
|
By default, the output of the simulation is written out in the subdirectory ``data'' with
|
||||||
the name ``musr\_RUNNUMBER.root''. The default ``data'' directory can be changed by the
|
the name ``musr\_RUNNUMBER.root''. The default ``data'' subdirectory can be changed
|
||||||
command ``/musr/command rootOutputDirectoryName \emph{dirName}''.
|
(see Chapter~\ref{sec:otherParameters}). The simulated data are storred in a Root tree,
|
||||||
(Note that the execution of the simulation can be terminated gently by creating a file ``RUNNUMBER.stop'' in the working directory.)
|
which is some kind of a table with many variables for every simulated event, inside
|
||||||
|
the musr\_RUNNUMBER.root file.
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\section{How to stop musrSim}
|
||||||
|
The execution of musrSim stops as soon as one of the following condition is fulfilled:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Number of simulated events reaches the number of required events defined by
|
||||||
|
command ``{\bf /run/beamOn \emph{nrOfEvents}}'' (see Chapter~\ref{sec:otherParameters}).
|
||||||
|
\item Time for which the simulation is running exceeds the maximum allowed time defined
|
||||||
|
by command ``{\bf /musr/command maximumRunTimeAllowed \emph{timeMax}}''
|
||||||
|
(see Chapter~\ref{sec:otherParameters}).
|
||||||
|
\item Within a few seconds after a file ``RUNNUMBER.stop'' is created in the
|
||||||
|
directory, in which the musrSim program was started. This allows the user
|
||||||
|
to stop the simulation gently at any time.
|
||||||
|
\end{itemize}
|
||||||
|
If the musrSim program is killed in any other way, the output Root file does not close properly, and
|
||||||
|
subsequently can not be analysed. The simulated data are lost.
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Conventions}
|
\section{Conventions}
|
||||||
The default units of the musrSim in both the macro file (RUNNUMBER.mac) and in the Root tree
|
The default units of the musrSim in both the macro file (RUNNUMBER.mac) and in the Root tree
|
||||||
are summarised in table~\ref{tab:units}.
|
are summarised in table~\ref{tab:units}.
|
||||||
@ -140,36 +190,61 @@ are summarised in table~\ref{tab:units}.
|
|||||||
\lower 1mm \hbox{\textbf{Quantity}} && \lower 1mm \hbox{\textbf{Default unit}} \\[5pt]
|
\lower 1mm \hbox{\textbf{Quantity}} && \lower 1mm \hbox{\textbf{Default unit}} \\[5pt]
|
||||||
\hline
|
\hline
|
||||||
Length && mm \\
|
Length && mm \\
|
||||||
Time && $\mu$s \\
|
Time && $\mu$s (sometimes ns) \\
|
||||||
Energy && MeV \\
|
Energy && MeV \\
|
||||||
Momentum && MeV/c\\
|
Momentum && MeV/c\\
|
||||||
Magnetic field && tesla \\
|
Magnetic field && tesla \\
|
||||||
Electric field && keV/mm \\
|
Electric field && keV/mm \\
|
||||||
|
Anlgel && degree \\
|
||||||
\hline
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\caption{The default units in musrSim.}
|
\caption{The default units of musrSim.}
|
||||||
\label{tab:units}
|
\label{tab:units}
|
||||||
\end{table}
|
\end{table}
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\section{Tips and tricks}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Visualise your instrument geometry during its construction.
|
||||||
|
\item Check the output file for error messages, especially for volume overlaps.
|
||||||
|
\item Note the the dimensions in volume definitions are often half-lenghts, not
|
||||||
|
the lenghts (e.g.\ half-lengths of the box edges).
|
||||||
|
\item The order of some commands in macro file matters -- e.g.\ one has to define
|
||||||
|
a mother volume before the daughter volume, etc.
|
||||||
|
\item Threre are some special volume names, namely \emph{World},
|
||||||
|
\emph{Target} (same as \emph{target}), \emph{M0}, \emph{M1}, \emph{M2} and
|
||||||
|
volumes starging with keywords \emph{Shield} (same as \emph{shield}), and
|
||||||
|
volumes containing string \emph{save}. All these volume influence the
|
||||||
|
behaviour of the simulation, so understand how they act (see different chapters
|
||||||
|
of this manual) before you use them.
|
||||||
|
\item When implementing a new magnetic or electric field always check that fields at
|
||||||
|
a few random space points correspond to the field you expect to observe
|
||||||
|
(use command /musr/command globalfield printFieldValueAtPoint~).
|
||||||
|
\end{itemize}
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Detector construction}
|
\section{Detector construction}
|
||||||
|
The user must first define the instrument geometry in the macro file. It should be realively
|
||||||
|
easy to understand how this is done from the example macro files distributed with musrSim
|
||||||
|
program.
|
||||||
|
|
||||||
|
An important parameter to note in the following description of ``/musr/command construct''
|
||||||
|
command is the \emph{idNumber} -- an integer number uniquely identifying every volume.
|
||||||
|
The ID volume numbers are later on used also in the musrSimAna program, when some identification
|
||||||
|
of a volume becomes necessary (i.e.\ volumes are described by \emph{idNumber} rather than
|
||||||
|
by their \emph{name} command later on).
|
||||||
|
|
||||||
|
Another crutial parameter in ``/musr/command construct'' command
|
||||||
|
is \emph{sensitiveClass}, which defines whether the volume
|
||||||
|
is sensitive (i.e.\ a signal can be detected in the volume) or not (i.e.\ the volume
|
||||||
|
is just a dead material influencing the penetrating particles but not detecting them).
|
||||||
|
|
||||||
|
|
||||||
\begin{description}
|
\begin{description}
|
||||||
|
|
||||||
\item{\bf /musr/command rotation \emph{matrixName} $\alpha$ $\beta$ $\gamma$} \\
|
|
||||||
{\bf /musr/command rotation \emph{matrixName} \emph{vx} \emph{vy} \emph{vz} \emph{angle}}\\
|
|
||||||
These commands define a rotation matrix of the name \emph{matrixName} that can be used later on
|
|
||||||
during the definition of the detector geometry (see command ``/musr/command construct'').
|
|
||||||
It can be defined either by the Euler angles (if there are three float parameters behind the
|
|
||||||
\emph{matrixName}) or by the vector \emph{(vx,vy,vz)} and an \emph{angle} of rotation around this
|
|
||||||
vector (if the fourth float parameter behind the \emph{matrixName} is non-zero).
|
|
||||||
All angles are specified in degrees.
|
|
||||||
|
|
||||||
\item{\bf /musr/command construct \emph{solid} \emph{name} \emph{dimensions} ... \emph{material}
|
\item{\bf /musr/command construct \emph{solid} \emph{name} \emph{dimensions} ... \emph{material}
|
||||||
\emph{x} \emph{y} \emph{z} \emph{motherVolume} \emph{matrixName}
|
\emph{x} \emph{y} \emph{z} \emph{motherVolume} \emph{matrixName}
|
||||||
\emph{sensitiveClass} \emph{idNumber} }\\
|
\emph{sensitiveClass} \emph{idNumber} }\\
|
||||||
This command defines a volume in {\sc Geant4} (It comprises three steps of {\sc Geant4}: defines a solid,
|
This command defines a volume in {\sc Geant4} (It comprises three steps of {\sc Geant4}: defines a solid,
|
||||||
logical volume and physical volume. Details can to be found in {\sc Geant4} manual). \\
|
logical volume and physical volume. Details can be found in {\sc Geant4} manual). \\
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \emph{solid} (string) can be one of the G4VSolid.cc particular types, presently ``tubs'', ``cons'',
|
\item \emph{solid} (string) can be one of the G4VSolid.cc particular types, presently ``tubs'', ``cons'',
|
||||||
``box'', ``trd'', ``sphere'', ``para'',
|
``box'', ``trd'', ``sphere'', ``para'',
|
||||||
@ -178,12 +253,15 @@ are summarised in table~\ref{tab:units}.
|
|||||||
(a tube with a rectangular hole along its axis), "tubsboxsegm"
|
(a tube with a rectangular hole along its axis), "tubsboxsegm"
|
||||||
(a volume that looks like an intersection of tube and box) and
|
(a volume that looks like an intersection of tube and box) and
|
||||||
``trd90y'' (a trd volume rotated by 90 degrees around $y$ axis in addition
|
``trd90y'' (a trd volume rotated by 90 degrees around $y$ axis in addition
|
||||||
to the rotation requested by \emph{matrixName}). Not all G4VSolids are
|
to the rotation requested by \emph{matrixName}),
|
||||||
|
``cylpart'' (cylinder from which a box has been subtracted)
|
||||||
|
``GPDcollimator'' (collimator used at GPD instrument). Not all G4VSolids defined
|
||||||
|
in Geant4 are
|
||||||
presently supported, but it is relatively easy to implement a new kind of solids
|
presently supported, but it is relatively easy to implement a new kind of solids
|
||||||
in the musrDetectorConstruction.cc class.
|
in the musrDetectorConstruction.cc class.
|
||||||
\item \emph{name} (string) stands for the name of the volume. As the command
|
\item \emph{name} (string) stands for the name of the volume. As the command
|
||||||
``/musr/command construct'' constructs
|
``/musr/command construct'' constructs
|
||||||
three kinds of classes/volumes (the solid, logical volume and physical
|
three kinds of Geant4 classes/volumes (the solid, logical volume and physical
|
||||||
volume), there are three names of the concrete volume used internally inside
|
volume), there are three names of the concrete volume used internally inside
|
||||||
musrSim: sol\_\emph{name}, log\_\emph{name} and phys\_\emph{name}.
|
musrSim: sol\_\emph{name}, log\_\emph{name} and phys\_\emph{name}.
|
||||||
The main volume, inside which all other volumes are positioned, has to be called ``World''.
|
The main volume, inside which all other volumes are positioned, has to be called ``World''.
|
||||||
@ -198,17 +276,17 @@ are summarised in table~\ref{tab:units}.
|
|||||||
``G4\_PLASTIC\_SC\_VINYLTOLUENE'' for a scintillator, ...).
|
``G4\_PLASTIC\_SC\_VINYLTOLUENE'' for a scintillator, ...).
|
||||||
One can also define a new material inside the function
|
One can also define a new material inside the function
|
||||||
musrDetectorConstruction::DefineMaterials(). Presently ``Mylar'', ``Brass''
|
musrDetectorConstruction::DefineMaterials(). Presently ``Mylar'', ``Brass''
|
||||||
``Steel'', ``Macor'', ``MCPglass'', ``MgO'', ``SiO2'', ``K2O'' and ``B2O3'' are defined there.
|
``Steel'', ``Macor'', ``MCPglass'', ``MgO'', ``SiO2'', ``Al2O3'', ``K2O'' and ``B2O3'' are defined there.
|
||||||
\item \emph{x, y, z} (floats) -- coordinates of the volume, used to position the volume within
|
\item \emph{x, y, z} (floats) -- coordinates of the volume, used to position the volume within
|
||||||
its mother volume (as used by the G4PVPlacement).
|
its mother volume (as used by the G4PVPlacement).
|
||||||
Thus these coordinates are interpreted in the local coordinate system of the \emph{motherVolume}.
|
Thus these coordinates are interpreted in the local coordinate system of the \emph{motherVolume}.
|
||||||
\item \emph{motherVolume} (string) -- name of the mother volume, in which the given volume should be
|
\item \emph{motherVolume} (string) -- name of the mother volume, in which the given volume should be
|
||||||
positioned. Note that the mother volume has to be defined first (before its
|
positioned. Note that the mother volume has to be defined first (before its
|
||||||
daughter), and that the name of mother starts with a string {\bf log\_}\emph{name},
|
daughter), and that the name of mother starts with a string {\bf log\_}\emph{mothername},
|
||||||
following the naming convention defined above.
|
following the naming convention defined above.
|
||||||
When the ``World'' volume is defined, its \emph{motherVolume} should be set to ``no\_logical\_volume''.
|
When the ``World'' volume is defined, its \emph{motherVolume} should be set to ``no\_logical\_volume''.
|
||||||
\item \emph{matrixName} (string) -- name of the rotation matrix that will be used to position
|
\item \emph{matrixName} (string) -- name of the rotation matrix that will be used to position
|
||||||
the volume inside its mother volume (as used in member function G4PVPlacement).
|
the volume inside its mother volume (as used by the G4PVPlacement).
|
||||||
Use string ``norot'' if no rotation is required for the given volume.
|
Use string ``norot'' if no rotation is required for the given volume.
|
||||||
Otherwise the rotation matrix has to be defined by the command line
|
Otherwise the rotation matrix has to be defined by the command line
|
||||||
``/musr/command rotation'' {\bf before} the given volume is defined.
|
``/musr/command rotation'' {\bf before} the given volume is defined.
|
||||||
@ -227,6 +305,15 @@ are summarised in table~\ref{tab:units}.
|
|||||||
(the variable ``det\_ID[det\_n]'').
|
(the variable ``det\_ID[det\_n]'').
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
\item{\bf /musr/command rotation \emph{matrixName} $\alpha$ $\beta$ $\gamma$} \\
|
||||||
|
{\bf /musr/command rotation \emph{matrixName} \emph{vx} \emph{vy} \emph{vz} \emph{angle}}\\
|
||||||
|
These commands define a rotation matrix of the name \emph{matrixName} that can be used
|
||||||
|
during the definition of the detector geometry (see the command ``/musr/command construct'').
|
||||||
|
It can be defined either by the Euler angles (if there are three float parameters behind the
|
||||||
|
\emph{matrixName}) or by the vector \emph{(vx,vy,vz)} and an \emph{angle} of rotation around this
|
||||||
|
vector (if the fourth float parameter behind the \emph{matrixName} is non-zero).
|
||||||
|
All angles are specified in degrees.
|
||||||
|
|
||||||
\item{\bf /musr/command region define \emph{regionName} \emph{logicalVolume}}\\
|
\item{\bf /musr/command region define \emph{regionName} \emph{logicalVolume}}\\
|
||||||
The ``G4Region'' can be created using this command, and a logical volume of the
|
The ``G4Region'' can be created using this command, and a logical volume of the
|
||||||
name \emph{logicalVolume} will be assigned to it. If the G4Region of the name
|
name \emph{logicalVolume} will be assigned to it. If the G4Region of the name
|
||||||
@ -242,7 +329,8 @@ are summarised in table~\ref{tab:units}.
|
|||||||
Set the so-called ``production cuts'' in the G4Region called \emph{regionName}.
|
Set the so-called ``production cuts'' in the G4Region called \emph{regionName}.
|
||||||
The variables \emph{gammaCut, electronCut} and \emph{positronCut} are given in mm.
|
The variables \emph{gammaCut, electronCut} and \emph{positronCut} are given in mm.
|
||||||
\end{description}
|
\end{description}
|
||||||
Three special volumes ``Target, M0, M1 and M2''.
|
|
||||||
|
{\huge !!! EDIT: !!! Three special volumes ``Target, M0, M1 and M2''.}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Electric and magnetic fields}
|
\section{Electric and magnetic fields}
|
||||||
@ -255,7 +343,7 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
\emph{[fieldValueFinal]} \emph{[fieldNrOfSteps]}} \\
|
\emph{[fieldValueFinal]} \emph{[fieldNrOfSteps]}} \\
|
||||||
This command specifies the electric and/or magnetic fields, which are (in some sense)
|
This command specifies the electric and/or magnetic fields, which are (in some sense)
|
||||||
independent of any logical volume and can overlap with each other.
|
independent of any logical volume and can overlap with each other.
|
||||||
In the case of tabulated field read in from and external field map file the
|
In the case of tabulated field read in from an external field map file, the
|
||||||
field values used internally by the Geant4 are linearly interpolated using
|
field values used internally by the Geant4 are linearly interpolated using
|
||||||
eight (3D) or four (2D) grid points surrounding the point of interest.
|
eight (3D) or four (2D) grid points surrounding the point of interest.
|
||||||
%
|
%
|
||||||
@ -263,15 +351,15 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
\item \emph{fieldName} (string) -- name of the field (important mainly for the user and
|
\item \emph{fieldName} (string) -- name of the field (important mainly for the user and
|
||||||
print-out messages of the musrSim.
|
print-out messages of the musrSim.
|
||||||
\item \emph{half\_x}, \emph{half\_y}, \emph{half\_z} (floats) -- the (half) dimensions
|
\item \emph{half\_x}, \emph{half\_y}, \emph{half\_z} (floats) -- the (half) dimensions
|
||||||
of the box, within which the uniform field is defined.
|
of the box, within which the uniform field is defined. Used only for the uniform fields.
|
||||||
\item {\bf uniform / fromfile} -- specifies whether the field is uniform within
|
\item {\bf uniform / fromfile} -- specifies whether the field is uniform within
|
||||||
some volume or whether it is read in from an external file as a field-map.
|
some volume or whether it is read in from an external file as a field-map.
|
||||||
\item \emph{X}, \emph{Y}, \emph{Z} (floats) -- position of the centre of the field
|
\item \emph{X}, \emph{Y}, \emph{Z} (floats) -- position of the centre of the field
|
||||||
in the {\bf global} coordinate system. IMPORTANT: For some technical internal
|
in the {\bf global} coordinate system. IMPORTANT: For some technical internal
|
||||||
Geant4 reasons, this POSITION HAS TO LAY WITHIN THE \emph{logicalVolume}!
|
Geant4 reasons, this \bf{POSITION HAS TO LAY WITHIN THE \emph{logicalVolume}!}
|
||||||
(Note that the logical volume may be positioned somewhere deep in a volume
|
Note that the logical volume may be positioned somewhere deep in a volume
|
||||||
structure, not directly within the ``World'' volume, and
|
structure, not directly within the ``World'' volume, and
|
||||||
therefore the (local) coordinates in the definition of the the logical volume
|
therefore the (local) coordinates in the definition of the logical volume
|
||||||
do not have to match the (global) coordinates \emph{X}, \emph{Y} and \emph{Z}.
|
do not have to match the (global) coordinates \emph{X}, \emph{Y} and \emph{Z}.
|
||||||
\item \emph{logicalVolume} (string) -- specifies the logical volume, to which
|
\item \emph{logicalVolume} (string) -- specifies the logical volume, to which
|
||||||
the field is ``assigned''. One may ask, why a logical volume is needed for a field
|
the field is ``assigned''. One may ask, why a logical volume is needed for a field
|
||||||
@ -289,15 +377,17 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
larger volume. The volume can also be made of vacuum (i.e.\ G4\_Galactic).
|
larger volume. The volume can also be made of vacuum (i.e.\ G4\_Galactic).
|
||||||
\item \emph{Bx}, \emph{By}, \emph{Bz}, \emph{Ex}, \emph{Ey}, \emph{Ez} (float) -- the vector
|
\item \emph{Bx}, \emph{By}, \emph{Bz}, \emph{Ex}, \emph{Ey}, \emph{Ez} (float) -- the vector
|
||||||
of the uniform electromagnetic field. The units are tesla, for the first three
|
of the uniform electromagnetic field. The units are tesla, for the first three
|
||||||
components, and kilovolt/mm for the last three components.
|
components, and kilovolt/mm for the last three components.
|
||||||
|
Used only for the uniform fields.
|
||||||
\item \emph{fieldTableType} (string) -- specifies the format in which the field map is
|
\item \emph{fieldTableType} (string) -- specifies the format in which the field map is
|
||||||
written in the file. In general, the field is specified in a grid of
|
written in the file. In general, the field is specified in a grid of
|
||||||
three space coordinates $x$, $y$ and $z$ (3D).
|
three space coordinates $x$, $y$ and $z$ (3D).
|
||||||
Sometimes it is convenient to use the symmetry of the field
|
Sometimes it is convenient to use the symmetry of the field
|
||||||
and to reduce the field description to $R$ and $z$ (2D) only.
|
and to reduce the field description to $R$ and $z$ (2D) only.
|
||||||
In the following, we use this terms: \\
|
In the following, we use the following terms: \\
|
||||||
\emph{nx, ny, nz} or \emph{nR, nz} -- the number of divisions of the grid in
|
\emph{nx, ny, nz} -- the number of divisions of the grid in
|
||||||
\emph{x, y, z} or \emph{R, z}.
|
\emph{x, y, z}.\\
|
||||||
|
\emph{nR, nz} -- the number of divisions of the grid in \emph{R, z}.\\
|
||||||
\emph{length unit} -- the unit in which the grid coordinates are specified, usually
|
\emph{length unit} -- the unit in which the grid coordinates are specified, usually
|
||||||
cm or m.\\
|
cm or m.\\
|
||||||
\emph{field normalisation factor} -- a multiplicative factor applied to the values
|
\emph{field normalisation factor} -- a multiplicative factor applied to the values
|
||||||
@ -329,9 +419,9 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
However, a different \emph{field normalisation factor} can be specified
|
However, a different \emph{field normalisation factor} can be specified
|
||||||
in the field map file using the keyword ``fieldNormalisation \emph{number}''
|
in the field map file using the keyword ``fieldNormalisation \emph{number}''
|
||||||
before the line started with 0.\\
|
before the line started with 0.\\
|
||||||
It is expected that the we first loop over the $z$ coordinate of the field map,
|
It is expected that the first loop goes over the $z$ coordinate of the field map,
|
||||||
then (when $z$ changed from minimum to maximum) it is looped over $y$ coordinate,
|
then (after $z$ changed from minimum to maximum) it is looped over the $y$ coordinate,
|
||||||
and the highest-lever loop goes over $x$ coordinate. Hoever, if the order
|
and the highest-level loop goes over $x$ coordinate. However, if the order
|
||||||
of looping is reversed in the field map, it can be specified using the
|
of looping is reversed in the field map, it can be specified using the
|
||||||
keyword ``variableIncreasingOrder xyz'' placed in the field map before
|
keyword ``variableIncreasingOrder xyz'' placed in the field map before
|
||||||
the line started with 0.\\
|
the line started with 0.\\
|
||||||
@ -356,7 +446,7 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
Similar case is the ``symmetryType 2'', where the planes of symmetry are
|
Similar case is the ``symmetryType 2'', where the planes of symmetry are
|
||||||
(x,y) and (y,z).
|
(x,y) and (y,z).
|
||||||
These two symmetry types are realised in a the spin rotator oriented along the z axis.\\
|
These two symmetry types are realised in a the spin rotator oriented along the z axis.\\
|
||||||
Example of the beginning of the field map file:\\
|
Example of the beginning of the 3DBOpera-type field map file:\\
|
||||||
2 2 55\\
|
2 2 55\\
|
||||||
1 X\\
|
1 X\\
|
||||||
2 Y\\
|
2 Y\\
|
||||||
@ -396,7 +486,7 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
\emph{R, z, dummy, Field\_R, Field\_z, dummy}\\
|
\emph{R, z, dummy, Field\_R, Field\_z, dummy}\\
|
||||||
\item \emph{fieldInputFileName} (string) -- Name of the field map file.
|
\item \emph{fieldInputFileName} (string) -- Name of the field map file.
|
||||||
\item \emph{fieldValue} (float) -- the value of the field at some reference point
|
\item \emph{fieldValue} (float) -- the value of the field at some reference point
|
||||||
(usually in the centre of the field). It serves as some multiplicative
|
(usually in the centre of the field). It acts as an multiplicative
|
||||||
factor. The units are tesla for the magnetic field and kV/mm
|
factor. The units are tesla for the magnetic field and kV/mm
|
||||||
for the electric field.
|
for the electric field.
|
||||||
\item \emph{[fieldValueFinal]} and \emph{[fieldNrOfSteps]} (floats)
|
\item \emph{[fieldValueFinal]} and \emph{[fieldNrOfSteps]} (floats)
|
||||||
@ -415,7 +505,7 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
See ``musrDetectorConstruction.cc'' and ``BLEngeFunction.hh'' for the details.
|
See ``musrDetectorConstruction.cc'' and ``BLEngeFunction.hh'' for the details.
|
||||||
|
|
||||||
\item{\bf /musr/command globalfield setparameter \emph{parameterName} \emph{parameterValue} }\\
|
\item{\bf /musr/command globalfield setparameter \emph{parameterName} \emph{parameterValue} }\\
|
||||||
Set up some parameters used internally by Geant4 when calculating the motion
|
Set up some accuracy parameters used internally by Geant4 when calculating the motion
|
||||||
of charged particles in the magnetic field.\\
|
of charged particles in the magnetic field.\\
|
||||||
\emph{parameterName} (string) -- one of the following parameters: ``SetDeltaIntersection''
|
\emph{parameterName} (string) -- one of the following parameters: ``SetDeltaIntersection''
|
||||||
``SetDeltaOneStep'', ``SetMinimumEpsilonStep'', ``SetMaximumEpsilonStep'',
|
``SetDeltaOneStep'', ``SetMinimumEpsilonStep'', ``SetMaximumEpsilonStep'',
|
||||||
@ -444,24 +534,34 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
\emph{particle} (string) -- name of the particle to which a process is applied.\\
|
\emph{particle} (string) -- name of the particle to which a process is applied.\\
|
||||||
\emph{process} (string) -- name of the process to be assigned.\\
|
\emph{process} (string) -- name of the process to be assigned.\\
|
||||||
\emph{ordAtRestDoIt, ordAlongSteptDoIt, ordPostStepDoIt} (int) -- priority switches.\\
|
\emph{ordAtRestDoIt, ordAlongSteptDoIt, ordPostStepDoIt} (int) -- priority switches.\\
|
||||||
See the file musrPhysicsList.cc for the list of defined processes (e.g. G4MultipleScattering,
|
See the file musrPhysicsList.cc for the list of defined processes (e.g. G4eMultipleScattering,
|
||||||
G4eIonisation, ...) and Geant4 manual for the detail description of the processes.
|
G4eIonisation, ...) and Geant4 manual for the detail description of the processes.
|
||||||
|
|
||||||
There is one special process, combined from G4MultipleScattering and G4CoulombScattering,
|
% There is one special process, combined from G4MultipleScattering and G4CoulombScattering,
|
||||||
defined by the following command:\\
|
% defined by the following command:\\
|
||||||
{\bf /musr/command process addProcess \emph{particle} MultipleAndCoulombScattering \emph{ordAtRestDoIt} \emph{ordAlongSteptDoIt} \emph{ordPostStepDoIt} \emph{G4Region1} [\emph{G4Region2}] [\emph{G4Region3}]}\\
|
%{\bf /musr/command process addProcess \emph{particle} MultipleAndCoulombScattering \emph{ordAtRestDoIt} \emph{ordAlongSteptDoIt} \emph{ordPostStepDoIt} \emph{G4Region1} [\emph{G4Region2}] [\emph{G4Region3}]}\\
|
||||||
The G4MultipleScattering (rough but very fast approximation of scattering) will be applied
|
% The G4MultipleScattering (rough but very fast approximation of scattering) will be applied
|
||||||
elsewhere in the detector, except for the \emph{G4Region1} (and eventually \emph{G4Region2}
|
% elsewhere in the detector, except for the \emph{G4Region1} (and eventually \emph{G4Region2}
|
||||||
and \emph{G4Region3}), where more precise but very slow process G4CoulombScattering
|
% and \emph{G4Region3}), where more precise but very slow process G4CoulombScattering
|
||||||
will be applied instead of G4MultipleScattering. Note that up to three
|
% will be applied instead of G4MultipleScattering. Note that up to three
|
||||||
G4Regions are supported at the moment, but this limitation is not intrinsic to {\sc Geant4}
|
% G4Regions are supported at the moment, but this limitation is not intrinsic to {\sc Geant4}
|
||||||
and it can be therefore changed in musrPhysicsList.cc, if needed. The G4Regions have to
|
% and it can be therefore changed in musrPhysicsList.cc, if needed. The G4Regions have to
|
||||||
be defined in the detector construction phase by the command ``/musr/command region define ...''.
|
% be defined in the detector construction phase by the command ``/musr/command region define ...''.
|
||||||
|
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
%=============================================================================================
|
%=============================================================================================
|
||||||
\section{Initial (muon) beam parameters}
|
\section{Initial (muon) beam parameters}
|
||||||
|
%
|
||||||
|
In historical versions of musrSim
|
||||||
|
it had been implicitly assumed that the (muon) beam was oriented along the $z$-axis. Many
|
||||||
|
variables defined below are therefore related to this $z$-axis (e.g.\ beam tilt, vertex sigma, ...).
|
||||||
|
However, later on we implemented a possibility to change the direction of the initial beam
|
||||||
|
to a random vector by the command ``/gun/direction''. It now works like this:
|
||||||
|
the primary particles are first generated using all parameters of /gun/* commands
|
||||||
|
as if the beam went along the $z$-axis, and just in the last moment before Geant4 starts
|
||||||
|
to track them, they are (optionaly) rotated to the direction defined by the /gun/direction command.
|
||||||
|
This way the smearing of the vertex as well as beam tilt/pitch are propagated through the rotation.
|
||||||
|
|
||||||
\begin{description}
|
\begin{description}
|
||||||
\item{\bf /gun/primaryparticle \emph{primaryParticleName}}\\
|
\item{\bf /gun/primaryparticle \emph{primaryParticleName}}\\
|
||||||
@ -472,20 +572,33 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
\item{\bf /gun/meanarrivaltime \emph{meanArrivalTime}}\\
|
\item{\bf /gun/meanarrivaltime \emph{meanArrivalTime}}\\
|
||||||
(default: /gun/meanarrivaltime 33.33333 microsecond)\\
|
(default: /gun/meanarrivaltime 33.33333 microsecond)\\
|
||||||
Set mean arrival time difference between two subsequent muons (at continuos beam).
|
Set mean arrival time difference between two subsequent muons (at continuos beam).
|
||||||
The output variable ``timeToNextEvent'' is subsequently generated using
|
The output variable ``timeToNextEvent'' is subsequently randomly generated using
|
||||||
the value of \emph{meanArrivalTime} and filled into the Root tree.
|
the value of \emph{meanArrivalTime} and filled into the Root tree.
|
||||||
|
|
||||||
|
\item{\bf /gun/starttime \emph{t0} \emph{unit}}\\
|
||||||
|
By default, muons are generated at time = 0. The time of generation of muons can be
|
||||||
|
set randomly according to the Gaussian or uniform distribution using variables
|
||||||
|
``/gun/starttime'' and ``/gun/starttimesigma''. See the description of the
|
||||||
|
``/gun/vertexsigma'' to understand how the choice is done. This command appears
|
||||||
|
useful for the simulation of the laser-induced muon beam at ISIS,
|
||||||
|
however it might be confusing or misleading when used together with
|
||||||
|
the /gun/meanarrivaltime command. It is therefore recommended not to use it
|
||||||
|
unless necessary.
|
||||||
|
|
||||||
|
\item{\bf /gun/starttimesigma \emph{t0} \emph{unit}}\\
|
||||||
|
See the description of ``/gun/starttime'' command.
|
||||||
|
|
||||||
\item{\bf /gun/vertex \emph{x0} \emph{y0} \emph{z0} \emph{unit}}\\
|
\item{\bf /gun/vertex \emph{x0} \emph{y0} \emph{z0} \emph{unit}}\\
|
||||||
(default: /gun/vertex 0 0 -100 mm) \\
|
(default: /gun/vertex 0 0 -100 mm) \\
|
||||||
Set mean values of the $x$, $y$ and $z$ coordinates of the generated particles (muons).
|
Set mean values of the $x$, $y$ and $z$ coordinates of the generated particles (muons).
|
||||||
The smearing around these mean values instead is set by /gun/vertexsigma and
|
The smearing around these mean values can be set by /gun/vertexsigma and
|
||||||
restricted by /gun/vertexboundary (see below).\\
|
restricted by /gun/vertexboundary and/or /gun/boxboundary (see below).\\
|
||||||
(Applicable also to TURTLE input).
|
(Applicable also to TURTLE input).
|
||||||
|
|
||||||
\item{\bf /gun/vertexsigma \emph{xSigma} \emph{ySigma} \emph{zSigma} \emph{unit}}\\
|
\item{\bf /gun/vertexsigma \emph{xSigma} \emph{ySigma} \emph{zSigma} \emph{unit}}\\
|
||||||
(default: /gun/vertexsigma 0 0 0 mm) \\
|
(default: /gun/vertexsigma 0 0 0 mm) \\
|
||||||
If {\it xSigma} $>0$ ... set $\sigma$, i.e. the standard deviation (RMS), of the $x$ coordinate
|
If {\it xSigma} $>0$ ... set $\sigma_x$, i.e. the standard deviation (RMS), of the $x$ coordinate
|
||||||
of the generated particles (muons) to $\sigma=xSigma$. The $x$ coordinate of the initial
|
of the generated particles (muons) to $\sigma_x=xSigma$. The $x$ coordinate of the initial
|
||||||
muon is then generated according to the Gaussian distribution with the mean value of $x0$
|
muon is then generated according to the Gaussian distribution with the mean value of $x0$
|
||||||
and the standard deviation of {\it xSigma}. \\
|
and the standard deviation of {\it xSigma}. \\
|
||||||
If {\it xSigma} $<0$ ... the $x$ coordinate of the initial
|
If {\it xSigma} $<0$ ... the $x$ coordinate of the initial
|
||||||
@ -494,15 +607,6 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
Similar is true for {\it ySigma} and {\it zSigma}. \\
|
Similar is true for {\it ySigma} and {\it zSigma}. \\
|
||||||
(Ignored by the TURTLE input).
|
(Ignored by the TURTLE input).
|
||||||
|
|
||||||
\item{\bf /gun/starttime \emph{t0} \emph{unit}}\\
|
|
||||||
By default, muons are generated at time = 0. The time of generation of muons can be
|
|
||||||
set randomly according to the Gaussian or uniform distribution using variables
|
|
||||||
``/gun/starttime'' and ``/gun/starttimesigma''. See the description of the
|
|
||||||
``/gun/vertexsigma'' to understand how the choice is done.
|
|
||||||
|
|
||||||
\item{\bf /gun/starttimesigma \emph{t0} \emph{unit}}\\
|
|
||||||
See the description of ``/gun/starttime'' command.
|
|
||||||
|
|
||||||
\item{\bf /gun/vertexboundary \emph{R\_max} \emph{z\_min} \emph{z\_max} \emph{unit}}\\
|
\item{\bf /gun/vertexboundary \emph{R\_max} \emph{z\_min} \emph{z\_max} \emph{unit}}\\
|
||||||
Set maximum allowed radius, and minimum and maximum z coordinate of the generated particles (muons).
|
Set maximum allowed radius, and minimum and maximum z coordinate of the generated particles (muons).
|
||||||
This command might be useful especially if the user wants to restrict the
|
This command might be useful especially if the user wants to restrict the
|
||||||
@ -528,7 +632,7 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
The variables \emph{xMaxSource0}, \emph{yMaxSource0} and \emph{xMaxSource0} define the
|
The variables \emph{xMaxSource0}, \emph{yMaxSource0} and \emph{xMaxSource0} define the
|
||||||
centre of the box, the variables \emph{xMaxSource}, \emph{yMaxSource} and \emph{xMaxSource} define the
|
centre of the box, the variables \emph{xMaxSource}, \emph{yMaxSource} and \emph{xMaxSource} define the
|
||||||
halfwidth, halfheight and halflength of the box. \\
|
halfwidth, halfheight and halflength of the box. \\
|
||||||
This command can be useful for muonium excitations by laser (low energy muon beam induced by laser).\\
|
This command can be useful for the laser-induced muon beam at ISIS.\\
|
||||||
(Ignored by the TURTLE input).
|
(Ignored by the TURTLE input).
|
||||||
|
|
||||||
\item{\bf /gun/kenergy \emph{kineticEnergy} \emph{unit}}\\
|
\item{\bf /gun/kenergy \emph{kineticEnergy} \emph{unit}}\\
|
||||||
@ -599,6 +703,13 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
``/gun/muonPolarizVector'' is smaller than 1e-8!} \\
|
``/gun/muonPolarizVector'' is smaller than 1e-8!} \\
|
||||||
(Applicable also to TURTLE input).
|
(Applicable also to TURTLE input).
|
||||||
|
|
||||||
|
\item{\bf /gun/direction \emph{xDirection} \emph{yDirection} \emph{zDirection}}\\
|
||||||
|
Set initial beam direction as a vector (without units).
|
||||||
|
The vector does not have to be normalised to 1. Both beam direction
|
||||||
|
and beam spot are rotated.
|
||||||
|
See comments at the beginning of this chapter.\\
|
||||||
|
(Applicable also to TURTLE input).
|
||||||
|
|
||||||
\item{\bf /gun/decaytimelimits \emph{muDecayTimeMin} \emph{muDecayTimeMax} \emph{muMeanLife} \emph{unit}}\\
|
\item{\bf /gun/decaytimelimits \emph{muDecayTimeMin} \emph{muDecayTimeMax} \emph{muMeanLife} \emph{unit}}\\
|
||||||
(default: /gun/decaytimelimits $-1$ $-1$ 2197.03\,ns ) \\
|
(default: /gun/decaytimelimits $-1$ $-1$ 2197.03\,ns ) \\
|
||||||
If {\it muDecayTimeMax} is less or equal to zero, this command is ignored,
|
If {\it muDecayTimeMax} is less or equal to zero, this command is ignored,
|
||||||
@ -617,16 +728,16 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
more events than saved in the TURTLE file), the TURTLE file be be rewind to its
|
more events than saved in the TURTLE file), the TURTLE file be be rewind to its
|
||||||
beginning. Note that this does not mean that the same events will be simulated
|
beginning. Note that this does not mean that the same events will be simulated
|
||||||
after the rewind, because the random seed will be set differently than at the
|
after the rewind, because the random seed will be set differently than at the
|
||||||
beginning of the simulation. Note that the muons initialised
|
beginning of the simulation. The muons initialised
|
||||||
at the same position and with the same momentum will have completely different
|
at the same position and with the same momentum will have completely different
|
||||||
(random) multiple scattering, penetration depths, decay times,
|
(random) multiple scattering, penetration depths, decay times,
|
||||||
decay positron energies and angles, ..., and therefore will be (almost completely)
|
decay positron energies and angles, ..., and therefore will be (almost completely)
|
||||||
different events not affecting the statistical quality of the sample.
|
different events not affecting the statistical quality of the simulation.
|
||||||
|
|
||||||
\item{\bf /gun/turtleZ0position \emph{z0\_InitialTurtle} \emph{unit}}\\
|
\item{\bf /gun/turtleZ0position \emph{z0\_InitialTurtle} \emph{unit}}\\
|
||||||
Set the z-position which has been used to generate the TURTLE file.\\
|
Set the z-position which has been used to generate the TURTLE file.\\
|
||||||
If this value differs from the $z0$ value of the ``/gun/vertex'' command,
|
If this value differs from the $z0$ value of the ``/gun/vertex'' command,
|
||||||
than the particle initial position is extrapolated from $z0\_InitialTurtle$
|
than the particle initial position is linearly extrapolated from $z0\_InitialTurtle$
|
||||||
to the point corresponding to $z0$, using the direction of its momenta.\\
|
to the point corresponding to $z0$, using the direction of its momenta.\\
|
||||||
MORE DETAILS:\\
|
MORE DETAILS:\\
|
||||||
When running TURTLE (e.g. when generating the TURTLE file using the TURTLE program),
|
When running TURTLE (e.g. when generating the TURTLE file using the TURTLE program),
|
||||||
@ -674,7 +785,8 @@ Three special volumes ``Target, M0, M1 and M2''.
|
|||||||
the decays of radioactive atoms and for other purposes.
|
the decays of radioactive atoms and for other purposes.
|
||||||
Whenever the /gps/ keyword is used, the ``G4ParticleGun'' is not initiated
|
Whenever the /gps/ keyword is used, the ``G4ParticleGun'' is not initiated
|
||||||
(and all /gun/* commands are ignored).
|
(and all /gun/* commands are ignored).
|
||||||
The description of GPS can be found on the web, some of the useful commands are:\\
|
The description of GPS can be found at http://reat.space.qinetiq.com/gps/~,
|
||||||
|
some of the useful commands are:\\
|
||||||
/gps/particle ion\\
|
/gps/particle ion\\
|
||||||
/gps/ion 38 90 0 0\\
|
/gps/ion 38 90 0 0\\
|
||||||
/gps/position 0 0 0\\
|
/gps/position 0 0 0\\
|
||||||
@ -804,7 +916,7 @@ in order to simulate optical photons:
|
|||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
\subsection*{Tips and tricks}
|
\subsection*{Tips and tricks for optical photons}
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item One has to assign a non-zero EFFICIENCY and a REFLECTIVITY smaller than 1 to a boundary surface
|
\item One has to assign a non-zero EFFICIENCY and a REFLECTIVITY smaller than 1 to a boundary surface
|
||||||
between the scintillator and sensitive device (e.g.\ an APD).
|
between the scintillator and sensitive device (e.g.\ an APD).
|
||||||
@ -816,6 +928,7 @@ in order to simulate optical photons:
|
|||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Some other parameters}
|
\section{Some other parameters}
|
||||||
|
\label{sec:otherParameters}
|
||||||
%
|
%
|
||||||
\begin{description}
|
\begin{description}
|
||||||
\item{\bf /run/beamOn \emph{nrOfEvents}}\\
|
\item{\bf /run/beamOn \emph{nrOfEvents}}\\
|
||||||
|
@ -80,7 +80,7 @@ class musrRootOutput {
|
|||||||
G4int idVolVertex, G4int idProcVertex, G4int idTrackVertex, G4int particleID) ;
|
G4int idVolVertex, G4int idProcVertex, G4int idTrackVertex, G4int particleID) ;
|
||||||
|
|
||||||
void SetOPSAinfo (G4int nDetectors, G4int ID, G4int nPhot, G4double timeFirst, G4double timeA,
|
void SetOPSAinfo (G4int nDetectors, G4int ID, G4int nPhot, G4double timeFirst, G4double timeA,
|
||||||
G4double timeB, G4double timeC, G4double timeD, G4double timeE, G4double timeLast,
|
G4double timeB, G4double timeC, G4double timeD, G4double timeMean, G4double timeLast,
|
||||||
G4double timeCFD, G4double amplCFD);
|
G4double timeCFD, G4double amplCFD);
|
||||||
|
|
||||||
void SetSaveDetectorInfo (G4int ID, G4int particleID, G4double ke, G4double x, G4double y, G4double z, G4double time,
|
void SetSaveDetectorInfo (G4int ID, G4int particleID, G4double ke, G4double x, G4double y, G4double z, G4double time,
|
||||||
@ -221,7 +221,7 @@ class musrRootOutput {
|
|||||||
static G4bool store_odet_timeB;
|
static G4bool store_odet_timeB;
|
||||||
static G4bool store_odet_timeC;
|
static G4bool store_odet_timeC;
|
||||||
static G4bool store_odet_timeD;
|
static G4bool store_odet_timeD;
|
||||||
static G4bool store_odet_timeE;
|
static G4bool store_odet_timeMean;
|
||||||
static G4bool store_odet_timeLast;
|
static G4bool store_odet_timeLast;
|
||||||
static G4bool store_odet_timeCFD;
|
static G4bool store_odet_timeCFD;
|
||||||
static G4bool store_odet_amplCFD;
|
static G4bool store_odet_amplCFD;
|
||||||
@ -329,7 +329,7 @@ class musrRootOutput {
|
|||||||
G4double odet_timeB[odet_nMax];
|
G4double odet_timeB[odet_nMax];
|
||||||
G4double odet_timeC[odet_nMax];
|
G4double odet_timeC[odet_nMax];
|
||||||
G4double odet_timeD[odet_nMax];
|
G4double odet_timeD[odet_nMax];
|
||||||
G4double odet_timeE[odet_nMax];
|
G4double odet_timeMean[odet_nMax];
|
||||||
G4double odet_timeLast[odet_nMax];
|
G4double odet_timeLast[odet_nMax];
|
||||||
G4double odet_timeCFD[odet_nMax];
|
G4double odet_timeCFD[odet_nMax];
|
||||||
G4double odet_amplCFD[odet_nMax];
|
G4double odet_amplCFD[odet_nMax];
|
||||||
|
@ -78,12 +78,14 @@ class musrScintSD : public G4VSensitiveDetector
|
|||||||
// Optical Photon Signal Analysis (OPSA)
|
// Optical Photon Signal Analysis (OPSA)
|
||||||
void Set_OPSA_minNrOfDetectedPhotons(G4int val) {OPSA_minNrOfDetectedPhotons=val;}
|
void Set_OPSA_minNrOfDetectedPhotons(G4int val) {OPSA_minNrOfDetectedPhotons=val;}
|
||||||
void Set_OPSA_SignalSeparationTime(G4double val) {OPSA_signalSeparationTime=val;}
|
void Set_OPSA_SignalSeparationTime(G4double val) {OPSA_signalSeparationTime=val;}
|
||||||
void Set_OPSA_frac(G4double a, G4double b, G4double c, G4double d, G4double e)
|
void Set_OPSA_frac(G4double a, G4double b, G4double c, G4double d)
|
||||||
{OPSA_fracA=a; OPSA_fracB=b; OPSA_fracC=c; OPSA_fracD=d; OPSA_fracE=e;}
|
{OPSA_fracA=a; OPSA_fracB=b; OPSA_fracC=c; OPSA_fracD=d;}
|
||||||
void Set_OPSA_CFD(G4double a1, G4double delay, G4double timeShiftOffset)
|
void Set_OPSA_CFD(G4double a1, G4double delay, G4double timeShiftOffset)
|
||||||
{OPSA_CFD_a1=a1; OPSA_CFD_delay=delay; OPSA_CFD_timeShiftOffset = timeShiftOffset;}
|
{OPSA_CFD_a1=a1; OPSA_CFD_delay=delay; OPSA_CFD_timeShiftOffset = timeShiftOffset;}
|
||||||
void AddEventIDToMultimapOfEventIDsForOPSAhistos (G4int ev_ID, G4int detector_ID) {
|
void AddEventIDToMultimapOfEventIDsForOPSAhistos (G4int ev_ID, G4int detector_ID) {
|
||||||
bool_multimapOfEventIDsForOPSAhistosEXISTS=true;
|
bool_multimapOfEventIDsForOPSAhistosEXISTS=true;
|
||||||
|
if (ev_ID==-1) bool_StoreThisOPSAhistSUMMED = true;
|
||||||
|
if (ev_ID==-2) bool_StoreThisOPSAhistALL = true;
|
||||||
multimapOfEventIDsForOPSAhistos.insert(std::pair<G4int,G4int>(ev_ID,detector_ID));
|
multimapOfEventIDsForOPSAhistos.insert(std::pair<G4int,G4int>(ev_ID,detector_ID));
|
||||||
}
|
}
|
||||||
void SetOPSAhistoBinning(Int_t nBins, Double_t min, Double_t max) {
|
void SetOPSAhistoBinning(Int_t nBins, Double_t min, Double_t max) {
|
||||||
@ -115,11 +117,12 @@ class musrScintSD : public G4VSensitiveDetector
|
|||||||
G4double OPSA_fracB;
|
G4double OPSA_fracB;
|
||||||
G4double OPSA_fracC;
|
G4double OPSA_fracC;
|
||||||
G4double OPSA_fracD;
|
G4double OPSA_fracD;
|
||||||
G4double OPSA_fracE;
|
|
||||||
typedef std::multimap<G4int,signalInfo*> OPSA_signal_MapType;
|
typedef std::multimap<G4int,signalInfo*> OPSA_signal_MapType;
|
||||||
OPSA_signal_MapType OPSA_signal_Map;
|
OPSA_signal_MapType OPSA_signal_Map;
|
||||||
|
|
||||||
G4bool bool_multimapOfEventIDsForOPSAhistosEXISTS;
|
G4bool bool_multimapOfEventIDsForOPSAhistosEXISTS;
|
||||||
|
G4bool bool_StoreThisOPSAhistSUMMED;
|
||||||
|
G4bool bool_StoreThisOPSAhistALL;
|
||||||
typedef std::multimap<G4int,G4int> multimapOfEventIDsForOPSAhistos_Type;
|
typedef std::multimap<G4int,G4int> multimapOfEventIDsForOPSAhistos_Type;
|
||||||
multimapOfEventIDsForOPSAhistos_Type multimapOfEventIDsForOPSAhistos;
|
multimapOfEventIDsForOPSAhistos_Type multimapOfEventIDsForOPSAhistos;
|
||||||
TH1D* OPSAhisto;
|
TH1D* OPSAhisto;
|
||||||
|
@ -711,9 +711,9 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
|||||||
myMusrScintSD -> Set_OPSA_SignalSeparationTime(fVarValue*nanosecond);
|
myMusrScintSD -> Set_OPSA_SignalSeparationTime(fVarValue*nanosecond);
|
||||||
}
|
}
|
||||||
else if (strcmp(varName,"photonFractions")==0) {
|
else if (strcmp(varName,"photonFractions")==0) {
|
||||||
double a, b, c, d, e;
|
double a, b, c, d;
|
||||||
sscanf(&line[0],"%*s %*s %*s %lf %lf %lf %lf %lf",&a, &b, &c, &d, &e);
|
sscanf(&line[0],"%*s %*s %*s %lf %lf %lf %lf",&a, &b, &c, &d);
|
||||||
myMusrScintSD -> Set_OPSA_frac(a,b,c,d,e);
|
myMusrScintSD -> Set_OPSA_frac(a,b,c,d);
|
||||||
}
|
}
|
||||||
else if (strcmp(varName,"eventsForOPSAhistos")==0) {
|
else if (strcmp(varName,"eventsForOPSAhistos")==0) {
|
||||||
int i_eventID, i_detectorID;
|
int i_eventID, i_detectorID;
|
||||||
@ -1169,7 +1169,7 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
|||||||
if (strcmp(tmpString2,"odet_timeB")==0) {musrRootOutput::store_odet_timeB = false;}
|
if (strcmp(tmpString2,"odet_timeB")==0) {musrRootOutput::store_odet_timeB = false;}
|
||||||
if (strcmp(tmpString2,"odet_timeC")==0) {musrRootOutput::store_odet_timeC = false;}
|
if (strcmp(tmpString2,"odet_timeC")==0) {musrRootOutput::store_odet_timeC = false;}
|
||||||
if (strcmp(tmpString2,"odet_timeD")==0) {musrRootOutput::store_odet_timeD = false;}
|
if (strcmp(tmpString2,"odet_timeD")==0) {musrRootOutput::store_odet_timeD = false;}
|
||||||
if (strcmp(tmpString2,"odet_timeE")==0) {musrRootOutput::store_odet_timeE = false;}
|
if (strcmp(tmpString2,"odet_timeMean")==0) {musrRootOutput::store_odet_timeMean = false;}
|
||||||
if (strcmp(tmpString2,"odet_timeLast")==0) {musrRootOutput::store_odet_timeLast = false;}
|
if (strcmp(tmpString2,"odet_timeLast")==0) {musrRootOutput::store_odet_timeLast = false;}
|
||||||
}
|
}
|
||||||
else if(strcmp(storeIt,"on")==0) {
|
else if(strcmp(storeIt,"on")==0) {
|
||||||
|
@ -156,7 +156,7 @@ G4bool musrRootOutput::store_odet_timeA = true;
|
|||||||
G4bool musrRootOutput::store_odet_timeB = true;
|
G4bool musrRootOutput::store_odet_timeB = true;
|
||||||
G4bool musrRootOutput::store_odet_timeC = true;
|
G4bool musrRootOutput::store_odet_timeC = true;
|
||||||
G4bool musrRootOutput::store_odet_timeD = true;
|
G4bool musrRootOutput::store_odet_timeD = true;
|
||||||
G4bool musrRootOutput::store_odet_timeE = true;
|
G4bool musrRootOutput::store_odet_timeMean = true;
|
||||||
G4bool musrRootOutput::store_odet_timeLast = true;
|
G4bool musrRootOutput::store_odet_timeLast = true;
|
||||||
G4bool musrRootOutput::store_odet_timeCFD = true;
|
G4bool musrRootOutput::store_odet_timeCFD = true;
|
||||||
G4bool musrRootOutput::store_odet_amplCFD = true;
|
G4bool musrRootOutput::store_odet_amplCFD = true;
|
||||||
@ -173,6 +173,11 @@ void musrRootOutput::BeginOfRunAction() {
|
|||||||
// sprintf(RootOutputFileName, "data/musr_%i.root", tmpRunNr);
|
// sprintf(RootOutputFileName, "data/musr_%i.root", tmpRunNr);
|
||||||
sprintf(RootOutputFileName, "%s/musr_%i.root",rootOutputDirectoryName,tmpRunNr);
|
sprintf(RootOutputFileName, "%s/musr_%i.root",rootOutputDirectoryName,tmpRunNr);
|
||||||
rootFile=new TFile(RootOutputFileName,"recreate");
|
rootFile=new TFile(RootOutputFileName,"recreate");
|
||||||
|
if (rootFile->IsZombie()) {
|
||||||
|
char message[200];
|
||||||
|
sprintf(message,"musrRootOutput::BeginOfRunAction() Root output file %s can not be created",RootOutputFileName);
|
||||||
|
musrErrorMessage::GetInstance()->musrError(FATAL,message,false);
|
||||||
|
}
|
||||||
rootTree=new TTree("t1","a simple Tree with simple variables");
|
rootTree=new TTree("t1","a simple Tree with simple variables");
|
||||||
if (store_runID) {rootTree->Branch("runID",&runID,"runID/I");}
|
if (store_runID) {rootTree->Branch("runID",&runID,"runID/I");}
|
||||||
if (store_eventID) {rootTree->Branch("eventID",&eventID,"eventID/I");}
|
if (store_eventID) {rootTree->Branch("eventID",&eventID,"eventID/I");}
|
||||||
@ -283,7 +288,7 @@ void musrRootOutput::BeginOfRunAction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (store_odet_ID || store_odet_nPhot || store_odet_timeFirst || store_odet_timeA || store_odet_timeB ||
|
if (store_odet_ID || store_odet_nPhot || store_odet_timeFirst || store_odet_timeA || store_odet_timeB ||
|
||||||
store_odet_timeC || store_odet_timeD || store_odet_timeE || store_odet_timeLast || store_odet_timeCFD || store_odet_amplCFD)
|
store_odet_timeC || store_odet_timeD || store_odet_timeMean || store_odet_timeLast || store_odet_timeCFD || store_odet_amplCFD)
|
||||||
{rootTree->Branch("odet_n",&odet_n,"odet_n/I");}
|
{rootTree->Branch("odet_n",&odet_n,"odet_n/I");}
|
||||||
if (store_odet_ID) {rootTree->Branch("odet_ID",&odet_ID,"odet_ID[odet_n]/I");}
|
if (store_odet_ID) {rootTree->Branch("odet_ID",&odet_ID,"odet_ID[odet_n]/I");}
|
||||||
if (store_odet_nPhot) {rootTree->Branch("odet_nPhot",&odet_nPhot,"odet_nPhot[odet_n]/I");}
|
if (store_odet_nPhot) {rootTree->Branch("odet_nPhot",&odet_nPhot,"odet_nPhot[odet_n]/I");}
|
||||||
@ -292,7 +297,7 @@ void musrRootOutput::BeginOfRunAction() {
|
|||||||
if (store_odet_timeB) {rootTree->Branch("odet_timeB",&odet_timeB,"odet_timeB[odet_n]/D");}
|
if (store_odet_timeB) {rootTree->Branch("odet_timeB",&odet_timeB,"odet_timeB[odet_n]/D");}
|
||||||
if (store_odet_timeC) {rootTree->Branch("odet_timeC",&odet_timeC,"odet_timeC[odet_n]/D");}
|
if (store_odet_timeC) {rootTree->Branch("odet_timeC",&odet_timeC,"odet_timeC[odet_n]/D");}
|
||||||
if (store_odet_timeD) {rootTree->Branch("odet_timeD",&odet_timeD,"odet_timeD[odet_n]/D");}
|
if (store_odet_timeD) {rootTree->Branch("odet_timeD",&odet_timeD,"odet_timeD[odet_n]/D");}
|
||||||
if (store_odet_timeE) {rootTree->Branch("odet_timeE",&odet_timeE,"odet_timeE[odet_n]/D");}
|
if (store_odet_timeMean) {rootTree->Branch("odet_timeMean",&odet_timeMean,"odet_timeMean[odet_n]/D");}
|
||||||
if (store_odet_timeLast) {rootTree->Branch("odet_timeLast",&odet_timeLast,"odet_timeLast[odet_n]/D");}
|
if (store_odet_timeLast) {rootTree->Branch("odet_timeLast",&odet_timeLast,"odet_timeLast[odet_n]/D");}
|
||||||
if (store_odet_timeCFD) {rootTree->Branch("odet_timeCFD",&odet_timeCFD,"odet_timeCFD[odet_n]/D");}
|
if (store_odet_timeCFD) {rootTree->Branch("odet_timeCFD",&odet_timeCFD,"odet_timeCFD[odet_n]/D");}
|
||||||
if (store_odet_amplCFD) {rootTree->Branch("odet_amplCFD",&odet_amplCFD,"odet_amplCFD[odet_n]/D");}
|
if (store_odet_amplCFD) {rootTree->Branch("odet_amplCFD",&odet_amplCFD,"odet_amplCFD[odet_n]/D");}
|
||||||
@ -534,7 +539,7 @@ void musrRootOutput::SetDetectorInfoVvv (G4int nDetectors,
|
|||||||
|
|
||||||
|
|
||||||
void musrRootOutput::SetOPSAinfo (G4int nDetectors, G4int ID, G4int nPhot, G4double timeFirst, G4double timeA,
|
void musrRootOutput::SetOPSAinfo (G4int nDetectors, G4int ID, G4int nPhot, G4double timeFirst, G4double timeA,
|
||||||
G4double timeB, G4double timeC, G4double timeD, G4double timeE, G4double timeLast, G4double timeCFD, G4double amplCFD)
|
G4double timeB, G4double timeC, G4double timeD, G4double timeMean, G4double timeLast, G4double timeCFD, G4double amplCFD)
|
||||||
{
|
{
|
||||||
if ((nDetectors<0)||(nDetectors>=(odet_nMax-1))) {
|
if ((nDetectors<0)||(nDetectors>=(odet_nMax-1))) {
|
||||||
char message[200];
|
char message[200];
|
||||||
@ -551,7 +556,7 @@ void musrRootOutput::SetOPSAinfo (G4int nDetectors, G4int ID, G4int nPhot, G4
|
|||||||
odet_timeB[nDetectors]=timeB/microsecond;
|
odet_timeB[nDetectors]=timeB/microsecond;
|
||||||
odet_timeC[nDetectors]=timeC/microsecond;
|
odet_timeC[nDetectors]=timeC/microsecond;
|
||||||
odet_timeD[nDetectors]=timeD/microsecond;
|
odet_timeD[nDetectors]=timeD/microsecond;
|
||||||
odet_timeE[nDetectors]=timeE/microsecond;
|
odet_timeMean[nDetectors]=timeMean/microsecond;
|
||||||
odet_timeLast[nDetectors]=timeLast/microsecond;
|
odet_timeLast[nDetectors]=timeLast/microsecond;
|
||||||
odet_timeCFD[nDetectors]=timeCFD/microsecond;
|
odet_timeCFD[nDetectors]=timeCFD/microsecond;
|
||||||
odet_amplCFD[nDetectors]=amplCFD;
|
odet_amplCFD[nDetectors]=amplCFD;
|
||||||
|
@ -72,8 +72,9 @@ musrScintSD::musrScintSD(G4String name)
|
|||||||
OPSA_fracB = 0.05;
|
OPSA_fracB = 0.05;
|
||||||
OPSA_fracC = 0.10;
|
OPSA_fracC = 0.10;
|
||||||
OPSA_fracD = 0.20;
|
OPSA_fracD = 0.20;
|
||||||
OPSA_fracE = 0.5;
|
|
||||||
bool_multimapOfEventIDsForOPSAhistosEXISTS = false;
|
bool_multimapOfEventIDsForOPSAhistosEXISTS = false;
|
||||||
|
bool_StoreThisOPSAhistSUMMED = false;
|
||||||
|
bool_StoreThisOPSAhistALL = false;
|
||||||
OPSAhistoNbin = 100;
|
OPSAhistoNbin = 100;
|
||||||
OPSAhistoMin =0;
|
OPSAhistoMin =0;
|
||||||
OPSAhistoMax = 10.;
|
OPSAhistoMax = 10.;
|
||||||
@ -530,13 +531,14 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
|
|
||||||
for (optHitMapType::const_iterator it=optHitMap.begin() ; it != optHitMap.end(); it++ ) {
|
for (optHitMapType::const_iterator it=optHitMap.begin() ; it != optHitMap.end(); it++ ) {
|
||||||
G4bool boolStoreThisOPSAhist = false;
|
G4bool boolStoreThisOPSAhist = false;
|
||||||
G4bool boolStoreThisOPSAhistSUMMED = false;
|
// G4bool boolStoreThisOPSAhistSUMMED = false;
|
||||||
G4int OPSA_detID= it->first;
|
G4int OPSA_detID= it->first;
|
||||||
optHitDetectorMapType* optHitDetectorMap = it->second;
|
optHitDetectorMapType* optHitDetectorMap = it->second;
|
||||||
|
|
||||||
// Check whether OPSA histograming of times of optical photon detection is required for this eventID.
|
// Check whether OPSA histograming of times of optical photon detection is required for this eventID.
|
||||||
if (bool_multimapOfEventIDsForOPSAhistosEXISTS) {
|
if (bool_multimapOfEventIDsForOPSAhistosEXISTS) {
|
||||||
if (multimapOfEventIDsForOPSAhistos.find(eeeventID)!=multimapOfEventIDsForOPSAhistos.end()) {
|
if (bool_StoreThisOPSAhistALL) boolStoreThisOPSAhist = true;
|
||||||
|
else if (multimapOfEventIDsForOPSAhistos.find(eeeventID)!=multimapOfEventIDsForOPSAhistos.end()) {
|
||||||
// Now check whether the histogramming is required for the currently analysed detector.
|
// Now check whether the histogramming is required for the currently analysed detector.
|
||||||
std::pair<multimapOfEventIDsForOPSAhistos_Type::iterator,multimapOfEventIDsForOPSAhistos_Type::iterator> retOPSAhist;
|
std::pair<multimapOfEventIDsForOPSAhistos_Type::iterator,multimapOfEventIDsForOPSAhistos_Type::iterator> retOPSAhist;
|
||||||
multimapOfEventIDsForOPSAhistos_Type::iterator itOPSAhist;
|
multimapOfEventIDsForOPSAhistos_Type::iterator itOPSAhist;
|
||||||
@ -547,10 +549,10 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
if ( (itOPSAhist->second == 0) || (itOPSAhist->second == OPSA_detID) ) boolStoreThisOPSAhist = true;
|
if ( (itOPSAhist->second == 0) || (itOPSAhist->second == OPSA_detID) ) boolStoreThisOPSAhist = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (multimapOfEventIDsForOPSAhistos.find(-1)!=multimapOfEventIDsForOPSAhistos.end()) {
|
// if (multimapOfEventIDsForOPSAhistos.find(-1)!=multimapOfEventIDsForOPSAhistos.end()) {
|
||||||
// The user requires to store OPSA timing histograms summed up for all events together
|
// // The user requires to store OPSA timing histograms summed up for all events together
|
||||||
boolStoreThisOPSAhistSUMMED = true;
|
// boolStoreThisOPSAhistSUMMED = true;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optHitDetectorMap->empty()) continue;
|
if (optHitDetectorMap->empty()) continue;
|
||||||
@ -564,7 +566,7 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
G4double OPSA_timeB = -1000000;
|
G4double OPSA_timeB = -1000000;
|
||||||
G4double OPSA_timeC = -1000000;
|
G4double OPSA_timeC = -1000000;
|
||||||
G4double OPSA_timeD = -1000000;
|
G4double OPSA_timeD = -1000000;
|
||||||
G4double OPSA_timeE = -1000000;
|
G4double OPSA_timeMean = -1000000;
|
||||||
G4double OPSA_timeLast = -1000000;
|
G4double OPSA_timeLast = -1000000;
|
||||||
G4double OPSA_CFD_time = -1000000;
|
G4double OPSA_CFD_time = -1000000;
|
||||||
G4double OPSA_CFD_ampl = -1000;
|
G4double OPSA_CFD_ampl = -1000;
|
||||||
@ -593,7 +595,6 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
G4int NB = int (OPSA_fracB * OPSA_f_nPhot + 0.5); if (NB<=0) NB=1;
|
G4int NB = int (OPSA_fracB * OPSA_f_nPhot + 0.5); if (NB<=0) NB=1;
|
||||||
G4int NC = int (OPSA_fracC * OPSA_f_nPhot + 0.5); if (NC<=0) NC=1;
|
G4int NC = int (OPSA_fracC * OPSA_f_nPhot + 0.5); if (NC<=0) NC=1;
|
||||||
G4int ND = int (OPSA_fracD * OPSA_f_nPhot + 0.5); if (ND<=0) ND=1;
|
G4int ND = int (OPSA_fracD * OPSA_f_nPhot + 0.5); if (ND<=0) ND=1;
|
||||||
G4int NE = int (OPSA_fracE * OPSA_f_nPhot + 0.5); if (NE<=0) NE=1;
|
|
||||||
|
|
||||||
Int_t nP=0;
|
Int_t nP=0;
|
||||||
// Define OPSA histograms if required for this event
|
// Define OPSA histograms if required for this event
|
||||||
@ -614,7 +615,7 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
OPSA_CFD = new TH1D(nameHist, nameHistTitle, OPSAhistoNbin, OPSAhistoMin, OPSAhistoMax);
|
OPSA_CFD = new TH1D(nameHist, nameHistTitle, OPSAhistoNbin, OPSAhistoMin, OPSAhistoMax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (boolStoreThisOPSAhistSUMMED) {
|
if (bool_StoreThisOPSAhistSUMMED) {
|
||||||
iHistNrSUM++;
|
iHistNrSUM++;
|
||||||
char nameHist[200]; sprintf(nameHist,"OPSAhistSUM_%d_%d",OPSA_detID,iHistNrSUM);
|
char nameHist[200]; sprintf(nameHist,"OPSAhistSUM_%d_%d",OPSA_detID,iHistNrSUM);
|
||||||
char nameHist0[200]; sprintf(nameHist0,"OPSAhistSUM0_%d_%d",OPSA_detID,iHistNrSUM);
|
char nameHist0[200]; sprintf(nameHist0,"OPSAhistSUM0_%d_%d",OPSA_detID,iHistNrSUM);
|
||||||
@ -642,10 +643,9 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
if (nP==NB) OPSA_timeB = timePhot;
|
if (nP==NB) OPSA_timeB = timePhot;
|
||||||
if (nP==NC) OPSA_timeC = timePhot;
|
if (nP==NC) OPSA_timeC = timePhot;
|
||||||
if (nP==ND) OPSA_timeD = timePhot;
|
if (nP==ND) OPSA_timeD = timePhot;
|
||||||
if (nP==NE) OPSA_timeE = timePhot;
|
|
||||||
if (nP==OPSA_nPhot) OPSA_timeLast = timePhot;
|
if (nP==OPSA_nPhot) OPSA_timeLast = timePhot;
|
||||||
if ((boolStoreThisOPSAhist)||(bool_pulseShapeExists)) OPSAhisto->Fill(timePhot-OPSA_timeFirst+0.00000000001);
|
if ((boolStoreThisOPSAhist)||(bool_pulseShapeExists)) OPSAhisto->Fill(timePhot-OPSA_timeFirst+0.00000000001);
|
||||||
if (boolStoreThisOPSAhistSUMMED) {
|
if (bool_StoreThisOPSAhistSUMMED) {
|
||||||
OPSAhistoSUM ->Fill(timePhot-OPSA_timeFirst+0.00000000001);
|
OPSAhistoSUM ->Fill(timePhot-OPSA_timeFirst+0.00000000001);
|
||||||
OPSAhistoSUM0->Fill(timePhot+0.00000000001);
|
OPSAhistoSUM0->Fill(timePhot+0.00000000001);
|
||||||
}
|
}
|
||||||
@ -653,6 +653,7 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
|
|
||||||
// OPSAhisto->Fit(poiss,"Q");
|
// OPSAhisto->Fit(poiss,"Q");
|
||||||
if (boolStoreThisOPSAhist) OPSAhisto->Write();
|
if (boolStoreThisOPSAhist) OPSAhisto->Write();
|
||||||
|
OPSA_timeMean = OPSAhisto->GetMean();
|
||||||
|
|
||||||
// if required, convert the histogram with photon times to histogram of electronic pulse shape
|
// if required, convert the histogram with photon times to histogram of electronic pulse shape
|
||||||
if (bool_pulseShapeExists) {
|
if (bool_pulseShapeExists) {
|
||||||
@ -674,7 +675,7 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
Double_t xValue = (iBin-0.5)*OPSAhistoBinWidth;
|
Double_t xValue = (iBin-0.5)*OPSAhistoBinWidth;
|
||||||
OPSA_CFD->Fill(xValue,signalValue*OPSA_CFD_a1);
|
OPSA_CFD->Fill(xValue,signalValue*OPSA_CFD_a1);
|
||||||
Double_t xValueShifted = xValue + OPSA_CFD_delay;
|
Double_t xValueShifted = xValue + OPSA_CFD_delay;
|
||||||
if (xValueShifted>OPSAhistoMax) break; //return if out of range;
|
if (xValueShifted>OPSAhistoMax) continue; //return if out of range;
|
||||||
OPSA_CFD->Fill(xValueShifted,signalValue);
|
OPSA_CFD->Fill(xValueShifted,signalValue);
|
||||||
}
|
}
|
||||||
if (boolStoreThisOPSAhist) OPSA_CFD -> Write();
|
if (boolStoreThisOPSAhist) OPSA_CFD -> Write();
|
||||||
@ -708,7 +709,7 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
signalInfo* mySignalInfo = new signalInfo(OPSA_detID,OPSA_nPhot,OPSA_timeFirst,OPSA_timeA,OPSA_timeB,OPSA_timeC,
|
signalInfo* mySignalInfo = new signalInfo(OPSA_detID,OPSA_nPhot,OPSA_timeFirst,OPSA_timeA,OPSA_timeB,OPSA_timeC,
|
||||||
OPSA_timeD,OPSA_timeE,OPSA_timeLast,OPSA_CFD_time,OPSA_CFD_ampl);
|
OPSA_timeD,OPSA_timeMean,OPSA_timeLast,OPSA_CFD_time,OPSA_CFD_ampl);
|
||||||
OPSA_signal_Map.insert(std::pair<G4int,signalInfo*>(OPSA_nPhot,mySignalInfo) );
|
OPSA_signal_Map.insert(std::pair<G4int,signalInfo*>(OPSA_nPhot,mySignalInfo) );
|
||||||
}
|
}
|
||||||
OPSA_nPhot = 0;
|
OPSA_nPhot = 0;
|
||||||
@ -717,7 +718,7 @@ void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
|||||||
OPSA_timeB = -1000000;
|
OPSA_timeB = -1000000;
|
||||||
OPSA_timeC = -1000000;
|
OPSA_timeC = -1000000;
|
||||||
OPSA_timeD = -1000000;
|
OPSA_timeD = -1000000;
|
||||||
OPSA_timeE = -1000000;
|
OPSA_timeMean = -1000000;
|
||||||
OPSA_timeLast = -1000000;
|
OPSA_timeLast = -1000000;
|
||||||
OPSA_CFD_time = -1000000;
|
OPSA_CFD_time = -1000000;
|
||||||
OPSA_CFD_ampl = -1000;
|
OPSA_CFD_ampl = -1000;
|
||||||
|
@ -89,14 +89,21 @@ void musrSteppingAction::DoAtTheBeginningOfEvent() {
|
|||||||
void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
||||||
|
|
||||||
G4Track* aTrack = aStep->GetTrack();
|
G4Track* aTrack = aStep->GetTrack();
|
||||||
|
G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
|
||||||
|
G4StepPoint* postStepPoint = aStep->GetPostStepPoint();
|
||||||
|
G4ThreeVector preStepPosition = preStepPoint->GetPosition();
|
||||||
|
G4ThreeVector postStepPosition = postStepPoint->GetPosition();
|
||||||
|
|
||||||
// suspend the track if too many steps has already happened (relevant at high field)
|
// suspend the track if too many steps has already happened (relevant at high field)
|
||||||
if (aTrack->GetCurrentStepNumber()>100000) {
|
if (aTrack->GetCurrentStepNumber()>100000) {
|
||||||
musrErrorMessage::GetInstance()->musrError(WARNING,
|
musrErrorMessage::GetInstance()->musrError(WARNING,
|
||||||
"musrSteppingAction: Current number of steps for the track > 100000 ==> TRACK KILLED",true);
|
"musrSteppingAction: Current number of steps for the track > 100000 ==> TRACK KILLED",true);
|
||||||
G4double x=aStep->GetPostStepPoint()->GetPosition().x()/mm;
|
// G4double x=aStep->GetPostStepPoint()->GetPosition().x()/mm;
|
||||||
G4double y=aStep->GetPostStepPoint()->GetPosition().y()/mm;
|
// G4double y=aStep->GetPostStepPoint()->GetPosition().y()/mm;
|
||||||
G4double z=aStep->GetPostStepPoint()->GetPosition().z()/mm;
|
// G4double z=aStep->GetPostStepPoint()->GetPosition().z()/mm;
|
||||||
|
G4double x = postStepPosition.x()/mm;
|
||||||
|
G4double y = postStepPosition.y()/mm;
|
||||||
|
G4double z = postStepPosition.z()/mm;
|
||||||
G4double E=aTrack->GetVertexKineticEnergy()/MeV;
|
G4double E=aTrack->GetVertexKineticEnergy()/MeV;
|
||||||
myRootOutput->htest1->Fill(x,y);
|
myRootOutput->htest1->Fill(x,y);
|
||||||
myRootOutput->htest2->Fill(sqrt(x*x+y*y),z);
|
myRootOutput->htest2->Fill(sqrt(x*x+y*y),z);
|
||||||
@ -118,13 +125,14 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
|
|
||||||
// Temporary fix to avoid crashes caused by particles with unphysically high energies
|
// Temporary fix to avoid crashes caused by particles with unphysically high energies
|
||||||
// (probably corrupted event?)
|
// (probably corrupted event?)
|
||||||
if ((aStep->GetPreStepPoint()->GetKineticEnergy()) > (1*GeV)) {
|
// if ((aStep->GetPreStepPoint()->GetKineticEnergy()) > (1*GeV)) {
|
||||||
|
if ((preStepPoint->GetKineticEnergy()) > (1*GeV)) {
|
||||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,
|
musrErrorMessage::GetInstance()->musrError(SERIOUS,
|
||||||
"musrSteppingAction: kinetic energy of a particle larger than 1GeV! STRANGE FOR muSR!",false);
|
"musrSteppingAction: kinetic energy of a particle larger than 1GeV! STRANGE FOR muSR!",false);
|
||||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||||
G4cout<<" Event nr.:"<<fRunManager->GetCurrentEvent()->GetEventID()
|
G4cout<<" Event nr.:"<<fRunManager->GetCurrentEvent()->GetEventID()
|
||||||
<<", the particle \""<< aTrack->GetDynamicParticle()->GetDefinition()->GetParticleName()
|
<<", the particle \""<< aTrack->GetDynamicParticle()->GetDefinition()->GetParticleName()
|
||||||
<<"\" has energy of "<<(aStep->GetPreStepPoint()->GetKineticEnergy())/GeV<<" GeV."<<G4endl;
|
<<"\" has energy of "<<(preStepPoint->GetKineticEnergy())/GeV<<" GeV."<<G4endl;
|
||||||
G4cout<<" Deleting the event!"<<G4endl;
|
G4cout<<" Deleting the event!"<<G4endl;
|
||||||
G4cout.flush();
|
G4cout.flush();
|
||||||
myRootOutput->SetEventWeight(0);
|
myRootOutput->SetEventWeight(0);
|
||||||
@ -188,7 +196,7 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
if (aTrack->GetCreatorProcess()->GetProcessName() == "RadioactiveDecay") {
|
if (aTrack->GetCreatorProcess()->GetProcessName() == "RadioactiveDecay") {
|
||||||
if (aTrack->GetDefinition()->GetParticleName()=="e-") {
|
if (aTrack->GetDefinition()->GetParticleName()=="e-") {
|
||||||
if (aTrack->GetCurrentStepNumber()==1) {
|
if (aTrack->GetCurrentStepNumber()==1) {
|
||||||
G4double electron_kinetic_energy=aStep->GetPreStepPoint()->GetKineticEnergy();
|
G4double electron_kinetic_energy=preStepPoint->GetKineticEnergy();
|
||||||
myRootOutput->htest4->Fill(electron_kinetic_energy);
|
myRootOutput->htest4->Fill(electron_kinetic_energy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,17 +219,17 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
G4int tmpVolumeID=saveVolumeMapping[actualVolume];
|
G4int tmpVolumeID=saveVolumeMapping[actualVolume];
|
||||||
if (tmpVolumeID!=0) {
|
if (tmpVolumeID!=0) {
|
||||||
G4int particle_id_save=p_definition->GetPDGEncoding();
|
G4int particle_id_save=p_definition->GetPDGEncoding();
|
||||||
G4double ke_save=aStep->GetPreStepPoint()->GetKineticEnergy();
|
G4double ke_save=preStepPoint->GetKineticEnergy();
|
||||||
G4double x_save=aStep->GetPreStepPoint()->GetPosition().x();
|
G4double x_save=preStepPosition.x();
|
||||||
G4double y_save=aStep->GetPreStepPoint()->GetPosition().y();
|
G4double y_save=preStepPosition.y();
|
||||||
G4double z_save=aStep->GetPreStepPoint()->GetPosition().z();
|
G4double z_save=preStepPosition.z();
|
||||||
G4double time_save=aStep->GetPreStepPoint()->GetGlobalTime();
|
G4double time_save=preStepPoint->GetGlobalTime();
|
||||||
G4double px_save=aStep->GetPreStepPoint()->GetMomentum().x();
|
G4double px_save=preStepPoint->GetMomentum().x();
|
||||||
G4double py_save=aStep->GetPreStepPoint()->GetMomentum().y();
|
G4double py_save=preStepPoint->GetMomentum().y();
|
||||||
G4double pz_save=aStep->GetPreStepPoint()->GetMomentum().z();
|
G4double pz_save=preStepPoint->GetMomentum().z();
|
||||||
G4double polx_save=aStep->GetPreStepPoint()->GetPolarization().x();
|
G4double polx_save=preStepPoint->GetPolarization().x();
|
||||||
G4double poly_save=aStep->GetPreStepPoint()->GetPolarization().y();
|
G4double poly_save=preStepPoint->GetPolarization().y();
|
||||||
G4double polz_save=aStep->GetPreStepPoint()->GetPolarization().z();
|
G4double polz_save=preStepPoint->GetPolarization().z();
|
||||||
myRootOutput->SetSaveDetectorInfo(tmpVolumeID,particle_id_save,ke_save,x_save,y_save,z_save,time_save,px_save,py_save,pz_save,polx_save,poly_save,polz_save);
|
myRootOutput->SetSaveDetectorInfo(tmpVolumeID,particle_id_save,ke_save,x_save,y_save,z_save,time_save,px_save,py_save,pz_save,polx_save,poly_save,polz_save);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,10 +244,7 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
muAlreadyWasInTargetInThisEvent=true;
|
muAlreadyWasInTargetInThisEvent=true;
|
||||||
myRootOutput->SetPolInTarget(aTrack->GetPolarization());
|
myRootOutput->SetPolInTarget(aTrack->GetPolarization());
|
||||||
myRootOutput->SetTimeInTarget(aTrack->GetGlobalTime());
|
myRootOutput->SetTimeInTarget(aTrack->GetGlobalTime());
|
||||||
G4ThreeVector p_beforeEnteringTarget = aTrack->GetMomentum() - aStep->GetDeltaMomentum(); // must be - sign because DeltaMomentum is negative
|
myRootOutput->SetMomentumInTarget(preStepPoint->GetMomentum());
|
||||||
// std::cout<<"(aStep->GetDeltaMomentum()).z() = "<<(aStep->GetDeltaMomentum()).z()<<std::endl;
|
|
||||||
myRootOutput->SetMomentumInTarget(p_beforeEnteringTarget);
|
|
||||||
// myRootOutput->SetMomentumInTarget(aTrack->GetMomentum());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((actualVolume=="log_M0")||(actualVolume=="log_m0")) {
|
else if ((actualVolume=="log_M0")||(actualVolume=="log_m0")) {
|
||||||
@ -271,10 +276,9 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
// force Geant to use very small step size.
|
// force Geant to use very small step size.
|
||||||
if (boolCalculateFieldIntegral) {
|
if (boolCalculateFieldIntegral) {
|
||||||
if (F04GlobalField::Exists()) {
|
if (F04GlobalField::Exists()) {
|
||||||
G4ThreeVector position_tmp = aStep->GetPostStepPoint()->GetPosition();
|
CoordinateForFieldIntegral[0] = postStepPosition.x();
|
||||||
CoordinateForFieldIntegral[0] = position_tmp.x();
|
CoordinateForFieldIntegral[1] = postStepPosition.y();
|
||||||
CoordinateForFieldIntegral[1] = position_tmp.y();
|
CoordinateForFieldIntegral[2] = postStepPosition.z();
|
||||||
CoordinateForFieldIntegral[2] = position_tmp.z();
|
|
||||||
CoordinateForFieldIntegral[3] = aTrack->GetGlobalTime();
|
CoordinateForFieldIntegral[3] = aTrack->GetGlobalTime();
|
||||||
F04GlobalField::getObject() -> GetFieldValue(CoordinateForFieldIntegral,FieldForFieldIntegral);
|
F04GlobalField::getObject() -> GetFieldValue(CoordinateForFieldIntegral,FieldForFieldIntegral);
|
||||||
// G4cout<<"B=("<<FieldForFieldIntegral[0]/tesla<<","<<FieldForFieldIntegral[1]/tesla<<","<<FieldForFieldIntegral[2]/tesla<<")"<<G4endl;
|
// G4cout<<"B=("<<FieldForFieldIntegral[0]/tesla<<","<<FieldForFieldIntegral[1]/tesla<<","<<FieldForFieldIntegral[2]/tesla<<")"<<G4endl;
|
||||||
@ -285,15 +289,15 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
BxIntegral += stepLength * FieldForFieldIntegral[0];
|
BxIntegral += stepLength * FieldForFieldIntegral[0];
|
||||||
ByIntegral += stepLength * FieldForFieldIntegral[1];
|
ByIntegral += stepLength * FieldForFieldIntegral[1];
|
||||||
BzIntegral += stepLength * FieldForFieldIntegral[2];
|
BzIntegral += stepLength * FieldForFieldIntegral[2];
|
||||||
BzIntegral1 += ( position_tmp.z() - aStep->GetPreStepPoint()->GetPosition().z() ) * FieldForFieldIntegral[2];
|
BzIntegral1 += ( postStepPosition.z() - preStepPoint->GetPosition().z() ) * FieldForFieldIntegral[2];
|
||||||
BzIntegral2 += stepLength;
|
BzIntegral2 += stepLength;
|
||||||
BzIntegral3 += ( position_tmp.z() - aStep->GetPreStepPoint()->GetPosition().z() );
|
BzIntegral3 += ( postStepPosition.z() - preStepPoint->GetPosition().z() );
|
||||||
// G4cout<<"BzIntegral="<<BzIntegral<<" stepLength="<<stepLength<<"FieldForFieldIntegral[2]="<<FieldForFieldIntegral[2]<<G4endl;
|
// G4cout<<"BzIntegral="<<BzIntegral<<" stepLength="<<stepLength<<"FieldForFieldIntegral[2]="<<FieldForFieldIntegral[2]<<G4endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick up process "DecayWithSpin":
|
// Pick up process "DecayWithSpin":
|
||||||
const G4VProcess* process = aStep->GetPostStepPoint()->GetProcessDefinedStep();
|
const G4VProcess* process = postStepPoint->GetProcessDefinedStep();
|
||||||
if (process!=NULL) {
|
if (process!=NULL) {
|
||||||
G4String processName = process->GetProcessName();
|
G4String processName = process->GetProcessName();
|
||||||
if (processName=="DecayWithSpin") {
|
if (processName=="DecayWithSpin") {
|
||||||
@ -324,9 +328,8 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
|
|
||||||
// Store the information about the decaying muon and store it in the Root tree
|
// Store the information about the decaying muon and store it in the Root tree
|
||||||
G4double timeOfDecay_tmp=aTrack->GetGlobalTime();
|
G4double timeOfDecay_tmp=aTrack->GetGlobalTime();
|
||||||
G4ThreeVector positionOfDecay_tmp = aStep->GetPostStepPoint()->GetPosition();
|
|
||||||
G4double BFieldAtOrigin[6] = {0.,0.,0.,0.,0.,0.};
|
G4double BFieldAtOrigin[6] = {0.,0.,0.,0.,0.,0.};
|
||||||
G4double PointOfDecay[4] ={positionOfDecay_tmp.x(),positionOfDecay_tmp.y(),positionOfDecay_tmp.z(),timeOfDecay_tmp};
|
G4double PointOfDecay[4] ={postStepPosition.x(),postStepPosition.y(),postStepPosition.z(),timeOfDecay_tmp};
|
||||||
if (F04GlobalField::Exists()) {
|
if (F04GlobalField::Exists()) {
|
||||||
F04GlobalField* myGlobalField = F04GlobalField::getObject();
|
F04GlobalField* myGlobalField = F04GlobalField::getObject();
|
||||||
myGlobalField->GetFieldValue(PointOfDecay,BFieldAtOrigin);
|
myGlobalField->GetFieldValue(PointOfDecay,BFieldAtOrigin);
|
||||||
@ -344,7 +347,7 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
}
|
}
|
||||||
myRootOutput->SetDecayTime(timeOfDecay_tmp);
|
myRootOutput->SetDecayTime(timeOfDecay_tmp);
|
||||||
myRootOutput->SetDecayPolarisation(aTrack->GetPolarization());
|
myRootOutput->SetDecayPolarisation(aTrack->GetPolarization());
|
||||||
myRootOutput->SetDecayPosition(positionOfDecay_tmp);
|
myRootOutput->SetDecayPosition(postStepPosition);
|
||||||
myRootOutput->SetDecayDetectorID(actualVolume);
|
myRootOutput->SetDecayDetectorID(actualVolume);
|
||||||
myRootOutput->SetBField(BFieldAtOrigin);
|
myRootOutput->SetBField(BFieldAtOrigin);
|
||||||
if (boolCalculateFieldIntegral) {
|
if (boolCalculateFieldIntegral) {
|
||||||
@ -362,10 +365,6 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// G4ThreeVector position = aStep->GetPostStepPoint()->GetPosition();
|
|
||||||
// G4ThreeVector polarization=aTrack->GetDynamicParticle()->GetPolarization();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // particle is not muon
|
else { // particle is not muon
|
||||||
|
Loading…
x
Reference in New Issue
Block a user