Kamil Sedlak 2009-05-18
This is the first version of the muSR simulation code (musrSim) based on the merged codes of Kamil Sedlak and Toni Shiroka. It should be a running version of the simulation code, however it has not been very well tested, therefore it will probably need some further development.
This commit is contained in:
commit
fcd5eea567
36
GNUmakefile
Normal file
36
GNUmakefile
Normal file
@ -0,0 +1,36 @@
|
||||
# $Id: GNUmakefile,v 1.2 2008/10/21 14:34:02 sedlak Exp $
|
||||
# --------------------------------------------------------------
|
||||
# GNUmakefile for examples module. Gabriele Cosmo, 06/04/98.
|
||||
# --------------------------------------------------------------
|
||||
|
||||
name := musrSim
|
||||
G4TARGET := $(name)
|
||||
G4EXLIB := true
|
||||
##LDFLAGS := $(shell root-config --glibs)
|
||||
#ROOTLIBS := ${shell root-config --glibs}
|
||||
#LDFLAGS := -L./ ${ROOTLIBS}
|
||||
|
||||
# Root (exlude libNew and libpthread from library list)
|
||||
#ROOTINC = -I$(ROOTSYS)/include
|
||||
|
||||
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) -lMinuit -lHtml
|
||||
ROOTLIBS := $(filter-out -lNew,$(ROOTLIBS))
|
||||
#ROOTLIBS := $(filter-out -lpthread,$(ROOTLIBS))
|
||||
#
|
||||
#ROOTLIBS := $(filter-out -lThread,$(ROOTLIBS))
|
||||
## ROOTLIBS := $(filter-out -lpthread,$(ROOTLIBS))
|
||||
#ROOTLIBS := $(filter-out -pthread,$(ROOTLIBS))
|
||||
|
||||
# Extra flags for G4
|
||||
#CPPFLAGS += $(ROOTINC)
|
||||
#LDLIBS += $(ROOTLIBS)
|
||||
EXTRALIBS += $(ROOTLIBS)
|
||||
CPPFLAGS += -g
|
||||
ifndef G4INSTALL
|
||||
G4INSTALL = ../../..
|
||||
endif
|
||||
|
||||
.PHONY: all
|
||||
all: lib bin
|
||||
|
||||
include $(G4INSTALL)/config/binmake.gmk
|
45
doc/README_notes.txt
Normal file
45
doc/README_notes.txt
Normal file
@ -0,0 +1,45 @@
|
||||
SPECIAL SETTING SPECIFIED IN SOME FILES:
|
||||
|
||||
===========================================================================
|
||||
1) ~/.bashrc file:
|
||||
|
||||
The following lines were added to the ~/.bashrc file:
|
||||
|
||||
export ROOTSYS="/usr/local/root/5.20.00"
|
||||
export PATH=$ROOTSYS/bin:$PATH
|
||||
if [ $LD_LIBRARY_PATH ] ; then
|
||||
export LD_LIBRARY_PATH=$ROOTSYS/lib:$LD_LIBRARY_PATH
|
||||
else
|
||||
export LD_LIBRARY_PATH=$ROOTSYS/lib
|
||||
fi
|
||||
if [ $CPPFLAGS ] ; then
|
||||
export CPPLFLAGS=-I$ROOTSYS/include:$CPPFLAGS
|
||||
else
|
||||
export CPPFLAGS=-I$ROOTSYS/include
|
||||
fi
|
||||
source /afs/psi.ch/user/s/sedlak/.alias
|
||||
|
||||
===========================================================================
|
||||
2) /home/geant4/4.9.1.p03/env.sh file:
|
||||
|
||||
Inside the "/home/geant4/4.9.1.p03/env.sh", the following lines were inserted
|
||||
just before the last two lines " PATH=${PATH}:${G4WORKDIR}/bin/${G4SYSTEM} " and
|
||||
" export PATH " :
|
||||
|
||||
if [ $LD_LIBRARY_PATH ] ; then
|
||||
LD_LIBRARY_PATH=${G4LIB}/${G4SYSTEM}:${CLHEP_BASE_DIR}/lib:${LD_LIBRARY_PATH}
|
||||
export LD_LIBRARY_PATH
|
||||
else
|
||||
LD_LIBRARY_PATH=${G4LIB}/${G4SYSTEM}:${CLHEP_BASE_DIR}/lib
|
||||
export LD_LIBRARY_PATH
|
||||
fi
|
||||
echo "On this machine the LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
|
||||
|
||||
===========================================================================
|
||||
3) ~/.alias file
|
||||
|
||||
The following alias can be used to set-up the environment variables for Geant4:
|
||||
|
||||
alias g4='export G4WORKDIR="/home/sedlak/bin_4.9.1.p03"; source /home/geant4/4.9.1.p03/env.sh; export G4VRMLFILE_VIEWER="vrmlview"; echo "On this machine the G4VRMLFILE_VIEWER=$G4VRMLFILE_VIEWER"'
|
||||
|
||||
===========================================================================
|
210
doc/README_what_needs_to_be_changed_in_mac_file.txt
Normal file
210
doc/README_what_needs_to_be_changed_in_mac_file.txt
Normal file
@ -0,0 +1,210 @@
|
||||
To migrate the steering (*.mac) file of Toni Shiroka to a stearing file that
|
||||
runs with the new migrated version of "musrSim", do the following changes:
|
||||
|
||||
1) replace all "lem4" by "musr", namely:
|
||||
/lem4/command --> /musr/command
|
||||
lem4/ScintSD --> musr/ScintSD
|
||||
but do not change "lem4" in the name of the field map file, if such file exists (?)
|
||||
|
||||
2) replace all "cones" by "cons" (This respects the naming convention of Geant4 solids "G4cons"):
|
||||
/musr/command construct cones ---> /musr/command construct cons
|
||||
|
||||
3) modify the lines where uniform magnetic field is defined:
|
||||
old: /musr/command globalfield Trigg0_field 0. 0. -1149.15 uniform log_TriggE0 0 0 0 0 0 0.373
|
||||
new: /musr/command globalfield Trigg0_field 45 45 5 uniform 0. 0. -1149.15 log_TriggE0 0 0 0 0 0 0.373
|
||||
(the three coordinates which define the position of the centre of the field are shifted after the
|
||||
keyword "uniform", and the three half-dimensions of the box, in which the field is being defined, are
|
||||
specified before the keyword "uniform". These three coorinates (e.g. 45 45 5) are taken from the
|
||||
definition of the logical volume (e.g. in our example from
|
||||
/musr/command construct box TriggE0 45 45 5 G4_Galactic 0 0 -57.15 log_TriggerV norot dead 630 nofield )
|
||||
|
||||
4) Replace the way how physics processes are defined, i.e.:
|
||||
Add:
|
||||
|
||||
###################################################################################
|
||||
######################### P H Y S I C S P R O C E S S E S ##################
|
||||
###################################################################################
|
||||
# --- Low Energy (default) ---
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyPhotoElectric
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyCompton
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyGammaConversion
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyRayleigh
|
||||
/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
/musr/command process addProcess e- G4LowEnergyIonisation -1 2 2
|
||||
/musr/command process addProcess e- G4LowEnergyBremsstrahlung -1 -1 3
|
||||
/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
/musr/command process addProcess e+ G4eIonisation -1 2 2
|
||||
/musr/command process addProcess e+ G4eBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess e+ G4eplusAnnihilation 0 -1 4
|
||||
#
|
||||
# --- High Energy ---
|
||||
#/musr/command process addDiscreteProcess gamma G4PhotoElectricEffect
|
||||
#/musr/command process addDiscreteProcess gamma G4ComptonScattering
|
||||
#/musr/command process addDiscreteProcess gamma G4GammaConversion
|
||||
#/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
#/musr/command process addProcess e- G4eIonisation -1 2 2
|
||||
#/musr/command process addProcess e- G4eBremsstrahlung -1 3 3
|
||||
#/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
#/musr/command process addProcess e+ G4eIonisation -1 2 2
|
||||
#/musr/command process addProcess e+ G4eBremsstrahlung -1 3 3
|
||||
#/musr/command process addProcess e+ G4eplusAnnihilation 0 -1 4
|
||||
#
|
||||
# --- Penelope ---
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopePhotoElectric
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeCompton
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeGammaConversion
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeRayleigh
|
||||
#/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
#/musr/command process addProcess e- G4PenelopeIonisation -1 2 2
|
||||
#/musr/command process addProcess e- G4PenelopeBremsstrahlung -1 -1 3
|
||||
#/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
#/musr/command process addProcess e+ G4PenelopeIonisation, -1 2 2
|
||||
#/musr/command process addProcess e+ G4PenelopeBremsstrahlung, -1 -1 3
|
||||
#/musr/command process addProcess e+ G4PenelopeAnnihilation, 0 -1 4
|
||||
#
|
||||
# --- Muons ---
|
||||
/musr/command process addProcess mu+ G4MultipleScattering -1 1 1
|
||||
#/musr/command process addProcess mu+ MultipleAndCoulombScattering -1 1 1 goulombRegion
|
||||
#/musr/command process addDiscreteProcess mu+ G4CoulombScattering
|
||||
/musr/command process addProcess mu+ G4MuIonisation -1 2 2
|
||||
/musr/command process addProcess mu+ G4MuBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess mu+ G4MuPairProduction -1 4 4
|
||||
/musr/command process addProcess mu- G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess mu- G4CoulombScattering
|
||||
/musr/command process addProcess mu- G4MuIonisation -1 2 2
|
||||
/musr/command process addProcess mu- G4MuBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess mu- G4MuPairProduction -1 4 4
|
||||
# --- Muonium ---
|
||||
/musr/command process addProcess mu+ musrMuFormation -1 -1 2
|
||||
#cks - the following line not supported yet, has to be tested (at the moment, musrMuScatter is hard wired in the musrPhysicsList.cc):
|
||||
#/musr/command process addProcess Mu musrMuScatter -1 -1 1
|
||||
|
||||
|
||||
|
||||
And remove the obsolete "/musr/command typeofprocesses" :
|
||||
|
||||
# Set processes from: lowenergy, penelope, coulombAndMultiple (default, Coul. only for CFoil), coulomb (for all, very slow).
|
||||
/musr/command typeofprocesses coulombAndMultiple
|
||||
#*/musr/command typeofprocesses penelope
|
||||
#*/musr/command includeMuoniumProcesses false
|
||||
|
||||
|
||||
|
||||
5) Replace "SetUserMinEkine":
|
||||
|
||||
Old:
|
||||
/musr/command SetUserMinEkine log_World 0.1
|
||||
|
||||
New (and more general):
|
||||
#/musr/command SetUserLimits log_World ustepMax(mm) utrakMax(mm) utimeMax(ns) uekinMin(MeV) urangMin(mm)
|
||||
/musr/command SetUserLimits log_World -1 -1 -1 1e-7 -1
|
||||
|
||||
|
||||
|
||||
Note: The old command
|
||||
/musr/command SetUserLimits log_CFoil 1e-8
|
||||
should still be OK, but for safety reasons it might be better to replace it by
|
||||
/musr/command SetUserLimits log_CFoil 1e-8 -1 -1 -1 -1
|
||||
|
||||
However!!! - this line was ignored in the old code (as one can see in the text output
|
||||
of the simulation, so perhaps it should be commented out - such a small
|
||||
step is probably danger to use!
|
||||
|
||||
|
||||
6) Add the following lines to anable/disable the Root output variables:
|
||||
###################################################################################
|
||||
######################### R O O T O U T P U T ##############################
|
||||
###################################################################################
|
||||
#/musr/command rootOutput runID off
|
||||
#/musr/command rootOutput eventID off
|
||||
#/musr/command rootOutput weight off
|
||||
#/musr/command rootOutput BFieldAtDecay off
|
||||
#/musr/command rootOutput muIniPosX off
|
||||
#/musr/command rootOutput muIniPosY off
|
||||
#/musr/command rootOutput muIniPosZ off
|
||||
#/musr/command rootOutput muIniMomX off
|
||||
#/musr/command rootOutput muIniMomY off
|
||||
#/musr/command rootOutput muIniMomZ off
|
||||
#/musr/command rootOutput muIniPolX off
|
||||
#/musr/command rootOutput muIniPolY off
|
||||
#/musr/command rootOutput muIniPolZ off
|
||||
#/musr/command rootOutput muDecayDetID off
|
||||
#/musr/command rootOutput muDecayPosX off
|
||||
#/musr/command rootOutput muDecayPosY off
|
||||
#/musr/command rootOutput muDecayPosZ off
|
||||
#/musr/command rootOutput muDecayTime off
|
||||
#/musr/command rootOutput muDecayPolX off
|
||||
#/musr/command rootOutput muDecayPolY off
|
||||
#/musr/command rootOutput muDecayPolZ off
|
||||
#/musr/command rootOutput muTargetTime off
|
||||
#/musr/command rootOutput muTargetPolX off
|
||||
#/musr/command rootOutput muTargetPolY off
|
||||
#/musr/command rootOutput muTargetPolZ off
|
||||
#/musr/command rootOutput muM0Time off
|
||||
#/musr/command rootOutput muM0PolX off
|
||||
#/musr/command rootOutput muM0PolY off
|
||||
#/musr/command rootOutput muM0PolZ off
|
||||
/musr/command rootOutput muM1Time off
|
||||
/musr/command rootOutput muM1PolX off
|
||||
/musr/command rootOutput muM1PolY off
|
||||
/musr/command rootOutput muM1PolZ off
|
||||
/musr/command rootOutput muM2Time off
|
||||
/musr/command rootOutput muM2PolX off
|
||||
/musr/command rootOutput muM2PolY off
|
||||
/musr/command rootOutput muM2PolZ off
|
||||
#/musr/command rootOutput posIniMomX off
|
||||
#/musr/command rootOutput posIniMomY off
|
||||
#/musr/command rootOutput posIniMomZ off
|
||||
#/musr/command rootOutput fieldNomVal off
|
||||
#/musr/command rootOutput det_ID off
|
||||
#/musr/command rootOutput det_edep off
|
||||
#/musr/command rootOutput det_edep_el off
|
||||
#/musr/command rootOutput det_edep_pos off
|
||||
#/musr/command rootOutput det_edep_gam off
|
||||
#/musr/command rootOutput det_edep_mup off
|
||||
#/musr/command rootOutput det_nsteps off
|
||||
#/musr/command rootOutput det_length off
|
||||
#/musr/command rootOutput det_start off
|
||||
#/musr/command rootOutput det_end off
|
||||
#/musr/command rootOutput det_x off
|
||||
#/musr/command rootOutput det_y off
|
||||
#/musr/command rootOutput det_z off
|
||||
#/musr/command rootOutput det_kine off
|
||||
/musr/command rootOutput det_VrtxKine off
|
||||
/musr/command rootOutput det_VrtxX off
|
||||
/musr/command rootOutput det_VrtxY off
|
||||
/musr/command rootOutput det_VrtxZ off
|
||||
/musr/command rootOutput det_VrtxVolID off
|
||||
/musr/command rootOutput det_VrtxProcID off
|
||||
/musr/command rootOutput det_VrtxTrackID off
|
||||
/musr/command rootOutput det_VrtxParticleID off
|
||||
/musr/command rootOutput det_VvvKine off
|
||||
/musr/command rootOutput det_VvvX off
|
||||
/musr/command rootOutput det_VvvY off
|
||||
/musr/command rootOutput det_VvvZ off
|
||||
/musr/command rootOutput det_VvvVolID off
|
||||
/musr/command rootOutput det_VvvProcID off
|
||||
/musr/command rootOutput det_VvvTrackID off
|
||||
/musr/command rootOutput det_VvvParticleID off
|
||||
### Root variables that are not written out by default, but can be switched on:
|
||||
#/musr/command rootOutput fieldIntegralBx on
|
||||
#/musr/command rootOutput fieldIntegralBy on
|
||||
#/musr/command rootOutput fieldIntegralBz on
|
||||
#/musr/command rootOutput fieldIntegralBz1 on
|
||||
#/musr/command rootOutput fieldIntegralBz2 on
|
||||
#/musr/command rootOutput fieldIntegralBz3 on
|
||||
|
||||
|
||||
|
||||
7) Replace the (solid-name) keyword "trd" by "trd90y".
|
||||
|
||||
8) Remove all keywords "nofield" at the end of the commands
|
||||
" /musr/command construct ... " , since this does not have any meaning
|
||||
any more (it had been used before we switched to "GlobalField").
|
||||
|
518
doc/dis04.cls
Normal file
518
doc/dis04.cls
Normal file
@ -0,0 +1,518 @@
|
||||
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
||||
\ProvidesPackage{dis04}[2004/01/07 DIS'04 document class]
|
||||
\newif\if@restonecol
|
||||
\newif\if@titlepage
|
||||
%
|
||||
\DeclareOption{draft}{\setlength\overfullrule{5pt}}
|
||||
\DeclareOption{final}{\setlength\overfullrule{0pt}}
|
||||
\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue}
|
||||
%
|
||||
\ExecuteOptions{a4paper,10pt,twoside,final}
|
||||
\ProcessOptions
|
||||
%
|
||||
%\def\publ{\hss \copyright ~Institute of Experimental Physics SAS, Ko\v sice, Slovakia\hss}
|
||||
\def\publ{\hspace{10cm} }
|
||||
%
|
||||
\renewcommand\normalsize{%
|
||||
\@setfontsize\normalsize\@xpt\@xiipt
|
||||
\abovedisplayskip6\p@\@plus4\p@\@minus2\p@
|
||||
\abovedisplayshortskip\abovedisplayskip
|
||||
\belowdisplayshortskip\abovedisplayshortskip
|
||||
\belowdisplayskip\abovedisplayskip
|
||||
\let\@listi\@listI}
|
||||
\normalsize
|
||||
\newcommand\small{%
|
||||
\@setfontsize\small\@ixpt{11}%
|
||||
\abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@
|
||||
\abovedisplayshortskip \z@ \@plus2\p@
|
||||
\belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
|
||||
\def\@listi{\leftmargin\leftmargini
|
||||
\topsep 4\p@ \@plus2\p@ \@minus2\p@
|
||||
\parsep 2\p@ \@plus\p@ \@minus\p@
|
||||
\itemsep \parsep}%
|
||||
\belowdisplayskip \abovedisplayskip
|
||||
}
|
||||
\newcommand\footnotesize{%
|
||||
\@setfontsize\footnotesize\@viiipt{9.5}%
|
||||
\abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@
|
||||
\abovedisplayshortskip \z@ \@plus\p@
|
||||
\belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@
|
||||
\def\@listi{\leftmargin\leftmargini
|
||||
\topsep 3\p@ \@plus\p@ \@minus\p@
|
||||
\parsep 2\p@ \@plus\p@ \@minus\p@
|
||||
\itemsep \parsep}%
|
||||
\belowdisplayskip \abovedisplayskip
|
||||
}
|
||||
\newcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt}
|
||||
\newcommand\tiny{\@setfontsize\tiny\@vpt\@vipt}
|
||||
\newcommand\large{\@setfontsize\large\@xiipt{14}}
|
||||
\newcommand\Large{\@setfontsize\Large\@xivpt{18}}
|
||||
\newcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}}
|
||||
\newcommand\huge{\@setfontsize\huge\@xxpt{25}}
|
||||
\newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}}
|
||||
\setlength\parindent{0.25in}
|
||||
\setlength\smallskipamount{3\p@ \@plus 1\p@ \@minus 1\p@}
|
||||
\setlength\medskipamount{6\p@ \@plus 2\p@ \@minus 2\p@}
|
||||
\setlength\bigskipamount{12\p@ \@plus 4\p@ \@minus 4\p@}
|
||||
%%%%%%
|
||||
%
|
||||
\newdimen\trimheight
|
||||
\newdimen\trimwidth
|
||||
\newdimen\typeheight
|
||||
\newdimen\typewidth
|
||||
\newdimen\tempdimen
|
||||
\newdimen\normaltextheight
|
||||
%
|
||||
|
||||
\trimheight9.75in
|
||||
\addtolength\trimheight{.047in}
|
||||
\trimwidth6.50in
|
||||
%cks \typeheight48.10pc
|
||||
\typeheight60.pc
|
||||
%
|
||||
\setlength\parindent{1.5em}%10\p@
|
||||
\setlength\headheight{6\p@}
|
||||
\setlength\headsep {15pt}%11
|
||||
\setlength\topskip {7\p@}%{10\p@}
|
||||
\setlength\footskip{18pt}
|
||||
\setlength\maxdepth{4\p@}
|
||||
\setlength\@maxdepth\maxdepth
|
||||
%cks \setlength\textwidth{30pc}
|
||||
\setlength\textwidth{38pc}
|
||||
\setlength\textheight\typeheight
|
||||
\advance\textheight-\headheight
|
||||
\advance\textheight-\headsep
|
||||
%\advance\textheight\topskip%Comment
|
||||
\advance\textheight-3pt %comment
|
||||
\setlength\normaltextheight{\textheight}
|
||||
%cks \setlength\oddsidemargin{60pt}%.625in%
|
||||
%cks \setlength\evensidemargin{\trimwidth}
|
||||
\setlength\oddsidemargin{0pt}
|
||||
\setlength\evensidemargin{455pt}
|
||||
\addtolength\evensidemargin{-\textwidth}
|
||||
\addtolength\evensidemargin{-\oddsidemargin}
|
||||
\setlength\marginparwidth{.75in}
|
||||
\setlength\marginparsep{7\p@}
|
||||
\setlength\marginparpush{5\p@}
|
||||
%cks \setlength\topmargin{.65926in}%
|
||||
\setlength\topmargin{0.in}%
|
||||
\setlength\footnotesep{6\p@}%6pt
|
||||
\setlength{\skip\footins}{11\p@ \@plus 5\p@ \@minus 2\p@}
|
||||
\setlength\floatsep {18\p@ \@plus 2\p@ \@minus 2\p@}
|
||||
\setlength\textfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
|
||||
\setlength\intextsep {18\p@ \@plus 2\p@ \@minus 2\p@}
|
||||
\setlength\dblfloatsep {18\p@ \@plus 2\p@ \@minus 2\p@}
|
||||
\setlength\dbltextfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
|
||||
\setlength\@fptop{0\p@}
|
||||
\setlength\@fpsep{8\p@ \@plus 2fil}
|
||||
\setlength\@fpbot{0\p@ \@plus 1fil}
|
||||
\setlength\@dblfptop{0\p@ \@plus 1fil}
|
||||
\setlength\@dblfpsep{8\p@ \@plus 2fil}
|
||||
\setlength\@dblfpbot{0\p@ \@plus 1fil}
|
||||
\setlength\partopsep{0\p@}
|
||||
%
|
||||
\setlength\lineskip{1\p@}
|
||||
\setlength\normallineskip{1\p@}%
|
||||
\renewcommand\baselinestretch{}%{}
|
||||
\setlength\parskip{0\p@}
|
||||
\@lowpenalty 51
|
||||
\@medpenalty 151
|
||||
\@highpenalty 301
|
||||
\@beginparpenalty -\@lowpenalty
|
||||
\@endparpenalty -\@lowpenalty
|
||||
\@itempenalty -\@lowpenalty
|
||||
%
|
||||
\def\@listi{\leftmargin\leftmargini
|
||||
\parsep 4\p@ \@plus2\p@ \@minus\p@
|
||||
\topsep 8\p@ \@plus2\p@ \@minus4\p@
|
||||
\itemsep4\p@ \@plus2\p@ \@minus\p@}
|
||||
\let\@listI\@listi
|
||||
\@listi
|
||||
\def\@listii {\leftmargin\leftmarginii
|
||||
\labelwidth\leftmarginii
|
||||
\advance\labelwidth-\labelsep
|
||||
\topsep 4\p@ \@plus2\p@ \@minus\p@
|
||||
\parsep 2\p@ \@plus\p@ \@minus\p@
|
||||
\itemsep \parsep}
|
||||
\def\@listiii{\leftmargin\leftmarginiii
|
||||
\labelwidth\leftmarginiii
|
||||
\advance\labelwidth-\labelsep
|
||||
\topsep 2\p@ \@plus\p@\@minus\p@
|
||||
\parsep \z@
|
||||
\partopsep \p@ \@plus\z@ \@minus\p@
|
||||
\itemsep \topsep}
|
||||
\def\@listiv {\leftmargin\leftmarginiv
|
||||
\labelwidth\leftmarginiv
|
||||
\advance\labelwidth-\labelsep}
|
||||
\def\@listv {\leftmargin\leftmarginv
|
||||
\labelwidth\leftmarginv
|
||||
\advance\labelwidth-\labelsep}
|
||||
\def\@listvi {\leftmargin\leftmarginvi
|
||||
\labelwidth\leftmarginvi
|
||||
\advance\labelwidth-\labelsep}
|
||||
%
|
||||
\setcounter{topnumber}{3}
|
||||
\def\topfraction{.98}
|
||||
\setcounter{bottomnumber}{3}
|
||||
\def\bottomfraction{.98}
|
||||
\setcounter{totalnumber}{6}%4
|
||||
\def\textfraction{.01}
|
||||
\def\floatpagefraction{.98100}
|
||||
\setcounter{dbltopnumber}{2}
|
||||
\def\dbltopfraction{.981}
|
||||
\def\dblfloatpagefraction{.99}
|
||||
%
|
||||
\newcounter {prvastrana}
|
||||
%
|
||||
\def\ps@myheadings{%
|
||||
\def\@oddfoot{\ifnum\c@page=\c@prvastrana{
|
||||
\noindent{\small \publ}\rm\thepage}
|
||||
\else{}\fi}
|
||||
|
||||
\def\@evenfoot{\ifnum\c@page=\c@prvastrana{
|
||||
\noindent\rm\thepage{\small \publ}}
|
||||
\else{}\fi}
|
||||
|
||||
\def\@evenhead{%
|
||||
\ifnum\c@page=\c@prvastrana{%
|
||||
%Proceedings of the DIS'2004,~\v Strbsk\'e Pleso,~Slovakia~p.~\number\c@prvastrana -- \hfill
|
||||
%Proceedings of the DIS'2004,~\v Strbsk\'e Pleso,~Slovakia\hfill
|
||||
Internal PSI draft\hfill
|
||||
}
|
||||
\else{\thepage\hfill{\sl\runauthor}\qquad}\fi}
|
||||
|
||||
\def\@oddhead{%
|
||||
\ifnum\c@page=\c@prvastrana{%
|
||||
%Proceedings of the DIS'2004,~\v Strbsk\'e Pleso,~Slovakia~p.~\number\c@prvastrana -- \hfill
|
||||
%Proceedings of the DIS'2004,~\v Strbsk\'e Pleso,~Slovakia\hfill
|
||||
Internal PSI draft\hfill
|
||||
}
|
||||
\else \qquad{\sl\shorttitle}\hfill\thepage\fi}
|
||||
}
|
||||
%
|
||||
\newcommand\maketitle{\par
|
||||
\begingroup
|
||||
\renewcommand\thefootnote{\@fnsymbol\c@footnote}%
|
||||
\def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
|
||||
\long\def\@makefntext##1{\parindent 1em\noindent
|
||||
\hb@xt@1.8em{%
|
||||
\hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
|
||||
\if@twocolumn
|
||||
\ifnum \col@number=\@ne
|
||||
\@maketitle
|
||||
\else
|
||||
\twocolumn[\@maketitle]%
|
||||
\fi
|
||||
\else
|
||||
\newpage
|
||||
\global\@topnum\z@ % Prevents figures from going at top of page.
|
||||
\@maketitle
|
||||
\fi
|
||||
% \thispagestyle{plain}
|
||||
\@thanks
|
||||
\endgroup
|
||||
\setcounter{footnote}{0}%
|
||||
\setcounter{prvastrana}{\thepage}
|
||||
\global\let\thanks\relax
|
||||
\global\let\maketitle\relax
|
||||
\global\let\@maketitle\relax
|
||||
\global\let\@thanks\@empty
|
||||
\global\let\@author\@empty
|
||||
\global\let\@date\@empty
|
||||
\global\let\@title\@empty
|
||||
\global\let\title\relax
|
||||
\global\let\author\relax
|
||||
\global\let\date\relax
|
||||
\global\let\and\relax
|
||||
}
|
||||
%
|
||||
\def\title#1{\gdef\@title{\uppercase{#1}}}
|
||||
\def\@title{\@latex@error{No \expand\title given}\@ehc}
|
||||
%%
|
||||
\def\@maketitle{%
|
||||
\newpage
|
||||
\null
|
||||
\vskip 2em%
|
||||
%\vspace*{-14pt}
|
||||
\begin{center}%
|
||||
\let \footnote \thanks
|
||||
{\bf \@title \par}%
|
||||
\vskip 2em%
|
||||
\@aabuffer
|
||||
\end{center}%
|
||||
\par}
|
||||
% \vskip 1.5em}
|
||||
%
|
||||
\def\@aabuffer{}
|
||||
\def\author #1{\expandafter\def\expandafter\@aabuffer\expandafter
|
||||
{\@aabuffer\small\rm\uppercase{#1}\relax\par
|
||||
\vspace*{2pt}}}%\vspace{0.75em}
|
||||
\def\address#1{\expandafter\def\expandafter\@aabuffer\expandafter
|
||||
{\@aabuffer\small\it #1\relax\par
|
||||
\vspace*{10pt}}}
|
||||
%
|
||||
\setcounter{secnumdepth}{2}
|
||||
\newcounter {section}
|
||||
\newcounter {subsection}[section]
|
||||
\renewcommand\thesection {\@arabic\c@section}
|
||||
\renewcommand\thesubsection {\thesection.\@arabic\c@subsection}
|
||||
%
|
||||
\newcommand\section{\@startsection {section}{1}{\z@}%
|
||||
{-3.50ex \@plus -1ex \@minus -.2ex}%
|
||||
{2.3ex \@plus.2ex}%
|
||||
{\rightskip1pc plus1fil\normalfont\normalsize\bfseries}}
|
||||
\newcommand\subsection{\@startsection{subsection}{2}{\z@}%
|
||||
{-3.25ex\@plus -1ex \@minus -.2ex}%
|
||||
{1.5ex \@plus .2ex}%
|
||||
{\rightskip1pc plus1fil\normalfont\normalsize\it }}
|
||||
%
|
||||
\setlength\leftmargini {2em}
|
||||
\leftmargin \leftmargini
|
||||
\setlength\leftmarginii {2.2em}
|
||||
\setlength\leftmarginiii {1.87em}
|
||||
\setlength\leftmarginiv {1.7em}
|
||||
\setlength\leftmarginv {.5em}
|
||||
\setlength\leftmarginvi {.5em}
|
||||
\setlength \labelsep {.5em}
|
||||
\setlength \labelwidth{\leftmargini}
|
||||
\addtolength\labelwidth{-\labelsep}
|
||||
\@beginparpenalty -\@lowpenalty
|
||||
\@endparpenalty -\@lowpenalty
|
||||
\@itempenalty -\@lowpenalty
|
||||
\renewcommand\theenumi{\@arabic\c@enumi}
|
||||
\renewcommand\theenumii{\@alph\c@enumii}
|
||||
\renewcommand\theenumiii{\@roman\c@enumiii}
|
||||
\renewcommand\theenumiv{\@Alph\c@enumiv}
|
||||
\newcommand\labelenumi{\theenumi.}
|
||||
\newcommand\labelenumii{(\theenumii)}
|
||||
\newcommand\labelenumiii{\theenumiii.}
|
||||
\newcommand\labelenumiv{\theenumiv.}
|
||||
\renewcommand\p@enumii{\theenumi}
|
||||
\renewcommand\p@enumiii{\theenumi(\theenumii)}
|
||||
\renewcommand\p@enumiv{\p@enumiii\theenumiii}
|
||||
\newcommand\labelitemi{$\m@th\bullet$}
|
||||
\newcommand\labelitemii{\normalfont\bfseries --}
|
||||
\newcommand\labelitemiii{$\m@th\ast$}
|
||||
\newcommand\labelitemiv{$\m@th\cdot$}
|
||||
\newenvironment{description}
|
||||
{\list{}{\labelwidth\z@ \itemindent-\leftmargin
|
||||
\let\makelabel\descriptionlabel}}
|
||||
{\endlist}
|
||||
\newcommand*\descriptionlabel[1]{\hspace\labelsep
|
||||
\normalfont\bfseries #1}
|
||||
%
|
||||
|
||||
\def\abstracts#1{
|
||||
\begin{center}
|
||||
{\begin{minipage}{4.2truein}
|
||||
\footnotesize
|
||||
\parindent=0pt #1\par
|
||||
\end{minipage}}\end{center}
|
||||
\vskip 2em \par}
|
||||
|
||||
\newenvironment{quotation}
|
||||
{\list{}{\listparindent 1.5em%
|
||||
\itemindent \listparindent
|
||||
\rightmargin \leftmargin
|
||||
\parsep \z@ \@plus\p@}%
|
||||
\item\relax}
|
||||
{\endlist}
|
||||
%
|
||||
\newenvironment{quote}
|
||||
{\list{}{\rightmargin\leftmargin}%
|
||||
\item\relax}
|
||||
{\endlist}
|
||||
%
|
||||
%FOLLOWING THREE COMMANDS ARE FOR `LIST' COMMAND.
|
||||
\topsep=0in
|
||||
\parsep=0in
|
||||
\itemsep=0in
|
||||
%
|
||||
\newcounter{arabiclistc}
|
||||
\newenvironment{arabiclist}
|
||||
{\setcounter{arabiclistc}{0}
|
||||
\begin{list}{\arabic{arabiclistc}}
|
||||
{\usecounter{arabiclistc}
|
||||
\setlength{\parsep}{0pt}
|
||||
\setlength{\itemsep}{0pt}}}{\end{list}}
|
||||
%
|
||||
%ACKNOWLEDGEMENT: this portion is from John Hershberger
|
||||
%
|
||||
\def\@citex[#1]#2{\if@filesw\immediate\write\@auxout
|
||||
{\string\citation{#2}}\fi
|
||||
\def\@citea{}\@cite{\@for\@citeb:=#2\do
|
||||
{\@citea\def\@citea{,}\@ifundefined
|
||||
{b@\@citeb}{{\bf ?}\@warning
|
||||
{Citation `\@citeb' on page \thepage \space undefined}}
|
||||
{\csname b@\@citeb\endcsname}}}{#1}}
|
||||
%
|
||||
\newif\if@cghi
|
||||
\def\cite{\@cghitrue\@ifnextchar [{\@tempswatrue
|
||||
\@citex}{\@tempswafalse\@citex[]}}
|
||||
\def\citelow{\@cghifalse\@ifnextchar [{\@tempswatrue
|
||||
\@citex}{\@tempswafalse\@citex[]}}
|
||||
%\def\@cite#1#2{{$^{#1}$\if@tempswa\typeout
|
||||
\def\@cite#1#2{{[#1]\if@tempswa\typeout
|
||||
{Warning: optional citation argument ignored: `#2'} \fi}}
|
||||
\newcommand{\citeup}{\cite}
|
||||
%
|
||||
\newcommand\appendix{\par
|
||||
\setcounter{section}{0}%
|
||||
\setcounter{subsection}{0}%
|
||||
\renewcommand\thesection{\@Alph\c@section}
|
||||
\section*{\appendixname}}
|
||||
%
|
||||
\setlength\arraycolsep{1.5\p@}%5pt
|
||||
\setlength\tabcolsep{6\p@}
|
||||
\setlength\arrayrulewidth{.4\p@}
|
||||
\setlength\doublerulesep{2\p@}
|
||||
\setlength\tabbingsep{\labelsep}
|
||||
\skip\@mpfootins = \skip\footins
|
||||
\setlength\fboxsep{3\p@}
|
||||
\setlength\fboxrule{.4\p@}
|
||||
\renewcommand\theequation{\@arabic\c@equation}
|
||||
%%
|
||||
\InputIfFileExists{psfig.sty}{}{}
|
||||
\InputIfFileExists{epsf.sty}{}{}
|
||||
\InputIfFileExists{epsfsafe.tex}{}{}
|
||||
\InputIfFileExists{epsfig.sty}{}{}
|
||||
%
|
||||
\newcounter{figure}
|
||||
\renewcommand\thefigure{\@arabic\c@figure}
|
||||
\def\fps@figure{tbp}
|
||||
\def\ftype@figure{1}
|
||||
\def\ext@figure{lof}
|
||||
\def\fnum@figure{\figurename~\thefigure}
|
||||
\newenvironment{figure}
|
||||
{\@float{figure}}
|
||||
{\end@float}
|
||||
\newenvironment{figure*}
|
||||
{\@dblfloat{figure}}
|
||||
{\end@dblfloat}
|
||||
%
|
||||
\newcounter{table}
|
||||
\renewcommand\thetable{\@arabic\c@table}
|
||||
\def\fps@table{tbp}
|
||||
\def\ftype@table{2}
|
||||
\def\ext@table{lot}
|
||||
\def\fnum@table{\tablename~\thetable}
|
||||
\newenvironment{table}
|
||||
{\@float{table}}
|
||||
{\end@float}
|
||||
\newenvironment{table*}
|
||||
{\@dblfloat{table}}
|
||||
{\end@dblfloat}
|
||||
%
|
||||
\newlength\abovecaptionskip
|
||||
\newlength\belowcaptionskip
|
||||
\setlength\abovecaptionskip{10\p@}
|
||||
\setlength\belowcaptionskip{6\p@}
|
||||
\def\captionfont{\normalfont\footnotesize{}}
|
||||
\long\def\@makecaption#1#2{%
|
||||
\captionfont
|
||||
\vskip\abovecaptionskip
|
||||
\sbox\@tempboxa{#1.\hskip.5em#2}%
|
||||
\ifdim \wd\@tempboxa >\hsize
|
||||
\noindent #1.\hskip.5em#2\par
|
||||
\else
|
||||
\global \@minipagefalse
|
||||
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
|
||||
\fi
|
||||
\vskip\belowcaptionskip}
|
||||
%
|
||||
\def\figurebox#1#2#3{%
|
||||
\def\arg{#3}%
|
||||
\ifx\arg\empty
|
||||
{\hfill\vbox{\hsize#2\hrule\hbox to #2{\vrule\hfill\vbox to #1{\hsize#2\vfill}\vrule}\hrule}\hfill}%
|
||||
\else
|
||||
{\hfill\epsfbox{#3}\hfill}%
|
||||
\fi}
|
||||
%
|
||||
\def\@figurecaption#1#2{\unskip\vskip10pt{#1.\hskip.5em#2\par}}
|
||||
%
|
||||
\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
|
||||
\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
|
||||
\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
|
||||
\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
|
||||
\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
|
||||
\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}
|
||||
\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}
|
||||
\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal}
|
||||
\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal}
|
||||
\newcommand\@pnumwidth{1.55em}
|
||||
\newcommand\@tocrmarg{2.55em}
|
||||
\newcommand\@dotsep{4.5}
|
||||
%
|
||||
\newenvironment{thebibliography}[1]
|
||||
{\section*{\refname}
|
||||
\begin{list}{\arabic{enumi}.}
|
||||
{\usecounter{enumi}\setlength{\parsep}{0pt}
|
||||
\setlength{\itemsep}{0pt} \settowidth
|
||||
{\labelwidth}{#1.}\sloppy}}{\end{list}}
|
||||
%%
|
||||
\newenvironment{theindex}
|
||||
{\if@twocolumn
|
||||
\@restonecolfalse
|
||||
\else
|
||||
\@restonecoltrue
|
||||
\fi
|
||||
\columnseprule \z@
|
||||
\columnsep 35\p@
|
||||
\twocolumn[\section*{\indexname}]%
|
||||
\@mkboth{\MakeUppercase\indexname}%
|
||||
{\MakeUppercase\indexname}%
|
||||
\thispagestyle{plain}\parindent\z@
|
||||
\parskip\z@ \@plus .3\p@\relax
|
||||
\let\item\@idxitem}
|
||||
{\if@restonecol\onecolumn\else\clearpage\fi}
|
||||
\newcommand\@idxitem{\par\hangindent 40\p@}
|
||||
\newcommand\subitem{\@idxitem \hspace*{20\p@}}
|
||||
\newcommand\subsubitem{\@idxitem \hspace*{30\p@}}
|
||||
\newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax}
|
||||
%
|
||||
\renewcommand\footnoterule{%
|
||||
\kern-3\p@
|
||||
\hrule\@width.4\columnwidth
|
||||
\kern2.6\p@}
|
||||
\newcommand\@makefntext[1]{%
|
||||
\parindent 1em%
|
||||
\noindent
|
||||
\@makefnmark#1}
|
||||
%
|
||||
\def\thefootnote{\alph{footnote}}
|
||||
\def\@makefnmark{{$^{\@thefnmark}$}}
|
||||
%
|
||||
\newcommand\contentsname{Contents}
|
||||
\newcommand\listfigurename{List of Figures}
|
||||
\newcommand\listtablename{List of Tables}
|
||||
\newcommand\refname{References}
|
||||
\newcommand\indexname{Index}
|
||||
\newcommand\figurename{Figure}
|
||||
\newcommand\tablename{Table}
|
||||
\newcommand\partname{Part}
|
||||
\newcommand\appendixname{Appendix}
|
||||
\newcommand\abstractname{Abstract}
|
||||
%
|
||||
%
|
||||
\bibliographystyle{unsrt}
|
||||
\arraycolsep1.5pt
|
||||
%
|
||||
%%%%%%%%%%%%%%%%
|
||||
%
|
||||
\setlength\columnsep{0.25in}
|
||||
\setlength\columnseprule{0\p@}
|
||||
|
||||
\pagestyle{myheadings}
|
||||
\pagenumbering{arabic}
|
||||
\flushbottom
|
||||
\def\sloppy{\tolerance=100000\hfuzz=\maxdimen\vfuzz=\maxdimen}
|
||||
\vbadness=12000
|
||||
\hbadness=12000
|
||||
\sloppy
|
||||
\onecolumn
|
||||
\endinput
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
|
BIN
doc/musrSim.pdf
Normal file
BIN
doc/musrSim.pdf
Normal file
Binary file not shown.
469
doc/musrSim.tex
Normal file
469
doc/musrSim.tex
Normal file
@ -0,0 +1,469 @@
|
||||
\documentclass[twoside]{dis04}
|
||||
%\def\runauthor{Kamil Sedl\'{a}k}
|
||||
\def\runauthor{PSI}
|
||||
% for the H1 collaboration}
|
||||
\def\shorttitle{musrSim}
|
||||
\begin{document}
|
||||
|
||||
%\newcommand{\xgmy}{\ensuremath{x^{\mathrm{jets}}_\gamma} }
|
||||
%\newcommand{\GeV}{\ensuremath{\mathrm{GeV}} }
|
||||
%\newcommand{\pb}{\ensuremath{\mathrm{pb}} }
|
||||
%\newcommand{\gevsq}{\ensuremath{\mathrm{GeV}^2} }
|
||||
%\newcommand{\Etone}{\ensuremath{E^*_{T\, 1}} }
|
||||
%\newcommand{\Ettwo}{\ensuremath{E^*_{T\, 2}} }
|
||||
%\newcommand{\Etmy}{\ensuremath{E^*_T} }
|
||||
%\newcommand{\etaone}{\ensuremath{\eta^*_{1}} }
|
||||
%\newcommand{\etatwo}{\ensuremath{\eta^*_{2}} }
|
||||
%\newcommand{\etamy}{\ensuremath{\eta^*} }
|
||||
%\newcommand{\ycut}{\ensuremath{y_c} }
|
||||
\newcommand{\musr}{\ensuremath{\mu}SR}
|
||||
|
||||
\title{Manual of musrSim}
|
||||
%\title{GEANT Simulation Program for the
|
||||
%$\mathbf{\mu}$SR Instruments}
|
||||
|
||||
\author{Kamil Sedl\'ak and Toni Shiroka PSI}
|
||||
|
||||
%\address{{\rm (on behalf of the H1 collaboration)}\\
|
||||
%Institute of Physics AS\,CR\\
|
||||
%%Academy of Sciences of the Czech Republic
|
||||
%Na Slovance 2, 182 21 Praha 8, Czech Republic\\
|
||||
%E-mail: ksedlak@fzu.cz}
|
||||
|
||||
\maketitle
|
||||
|
||||
\abstracts{
|
||||
The program ``musrSim'' is a simulation program based on Geant4
|
||||
optimised for the $\mu$SR instruments.
|
||||
This document describes some of the commands used in the user macros
|
||||
of the simulation program for the $\mu$SR instruments based on the {\sc
|
||||
Geant4}. The root output variables are also described.
|
||||
}
|
||||
|
||||
|
||||
\section{Initial muon parameters}
|
||||
|
||||
\begin{description}
|
||||
\item{\bf /gun/vertex \emph{x0} \emph{y0} \emph{z0} \emph{unit}}\\
|
||||
(default: /gun/vertex 0 0 -100 mm) \\
|
||||
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
|
||||
restricted by /gun/vertexboundary (see below).\\
|
||||
(Applicable also to TURTLE input).
|
||||
|
||||
\item{\bf /gun/vertexsigma \emph{xSigma} \emph{ySigma} \emph{zSigma} \emph{unit}}\\
|
||||
(default: /gun/vertexsigma 0 0 0 mm) \\
|
||||
If {\it xSigma} $>0$ ... set $\sigma$, i.e. the standard deviation (RMS), of the $x$ coordinate
|
||||
of the generated particles (muons) to $\sigma=xSigma$. The $x$ coordinate of the initial
|
||||
muon is then generated according to the Gaussian distribution with the mean value of $x0$
|
||||
and the standard deviation of {\it xSigma}. \\
|
||||
If {\it xSigma} $<0$ ... the $x$ coordinate of the initial
|
||||
muon is generated {\bf uniformly} in the interval of ($x0-$ {\it xSigma}, $x0+$ {\it xSigma}).\\
|
||||
If {\it xSigma} $= 0$ ... no smearing on the $x$ coordinate is applied.\\
|
||||
Similar is true for {\it ySigma} and {\it zSigma}. \\
|
||||
This variables are ignored when TURTLE input is requested.
|
||||
|
||||
\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).
|
||||
This command might be useful especially if the user wants to restrict the
|
||||
area, in which initial particles are created, e.g.\ to force the initial muons
|
||||
to be created inside the beam pipe.
|
||||
|
||||
If the particles (muons) are read in from an external TURTLE file,
|
||||
only the restriction on the maximum radius \emph{R\_max}
|
||||
is applied on the initial particles, while \emph{z\_min} and \emph{z\_max} are ignored.
|
||||
|
||||
\item{\bf /gun/kenergy \emph{kineticEnergy} \emph{unit}}\\
|
||||
Set the mean kinetic energy of the initial particles (muons).
|
||||
|
||||
\item{\bf /gun/momentum \emph{momentum} \emph{unit}}\\
|
||||
Set the mean momentum of the initial particles (muons).
|
||||
|
||||
\item{\bf /gun/momentumsmearing \emph{momentumSigma} \emph{unit}}\\
|
||||
Set $\sigma$, i.e. the standard deviation (RMS), of the momentum spread, which
|
||||
is aplied randomly to each generated initial particle (muon). It is the magnitude
|
||||
of the momentum, which is smeared. \\
|
||||
(Ignored by the TURTLE input. However,
|
||||
a similar command ``/gun/turtleMomentumBite'' can be used for the TURTLE input file.)
|
||||
|
||||
\item{\bf /gun/momentumboundary \emph{p\_min} \emph{p\_max} \emph{dummy} \emph{unit}}\\
|
||||
Set a boundary for the minimum and maximum momentum of the initial particles (muons).
|
||||
The third argument \emph{dummy} is ignored.\\
|
||||
(Presently ignored by the TURTLE input).
|
||||
|
||||
\item{\bf /gun/tilt \emph{xangle0} \emph{yangle0} \emph{dummy} \emph{unit}}\\
|
||||
The ``beam tilt'' is understood as a constant angle tilt that is applied to
|
||||
all initial particles (muons) regardless on their distance from the centre of the beam.\\
|
||||
(Applicable also to TURTLE input).
|
||||
|
||||
\item{\bf /gun/tiltsigma \emph{xangleSigma} \emph{yangleSigma} \emph{dummy} \emph{unit}}\\
|
||||
Gaussian smearing of the tilt angle.\\
|
||||
(Presently ignored by the TURTLE input).
|
||||
|
||||
\item{\bf /gun/pitch \emph{pitch} \emph{unit}}\\
|
||||
The ``beam pitch'' is understood as a variable angle applied to the initial particles
|
||||
(muons), which is directly proportional to the distance from the beam axis.
|
||||
The particles closer to the beam axis become smaller pitch than particles further away
|
||||
from the beam axis.
|
||||
The angle given as \emph{pitch} will be applied to a particle generated 1\,mm away from the
|
||||
beam centre, i.e. the particle generated 7\,mm away from the beam axis will be assigned
|
||||
the angle of $7\cdot pitch$.
|
||||
The pitch allows the user to focus or defocuse the initial particle
|
||||
beam. Particles will be focused for positive pitch and defocused for the negative pitch.\\
|
||||
(Applicable also to TURTLE input).
|
||||
|
||||
\item{\bf /gun/muonPolarizVector \emph{xpolaris} \emph{ypolaris} \emph{zpolaris}}\\
|
||||
Set polarisation of the initial particle (muon) in a form of a vector
|
||||
$P=(xpolaris,ypolaris,zpolaris)$. The polarisation vector does not have to be normalised,
|
||||
the normalisation will be done internally by the program.
|
||||
However note that if the magnitude of P is set to less than 1e-8, the user can
|
||||
achieve an unpolarised muon beam. See the source code of musrPrimaryGeneratorAction.cc
|
||||
if you need to use unpolarised beam by this parameter, because there is some trick
|
||||
based on the magnitude of P.\\
|
||||
(Applicable also to TURTLE input).
|
||||
|
||||
\item{\bf /gun/muonPolarizFraction \emph{polarisFraction}}\\
|
||||
Set the fraction of the muon polarisation. The variable \emph{polarisFraction}
|
||||
has to be set in the range of -1 to 1. \\
|
||||
If \emph{polarisFraction} is set to 1, all muons are polarised in the direction
|
||||
of polarisation vector defined by ``/gun/muonPolarizVector''.\\
|
||||
If \emph{polarisFraction} is set to 0, half of the muons are polarised in the direction
|
||||
of polarisation vector, the second half is polarised in the oposite dirrection, so
|
||||
in the end the muon beam should act as unpolarised.\\
|
||||
If \emph{polarisFraction} is set to -1, all muons are polarised in the direction
|
||||
oposite to the polarisation vector.\\
|
||||
{\bf If \emph{polarisFraction} is set to 0.9, then 95\% of the muons is polarised
|
||||
in in the direction of polarisation vector, and 5\% of them is polarised in the
|
||||
oposite dirrection!}.\\
|
||||
{\bf This command is ignored if magnitude of polarisation vector defined by
|
||||
``/gun/muonPolarizVector'' is smaller than 1e-8!} \\
|
||||
(Applicable also to TURTLE input).
|
||||
|
||||
\item{\bf /gun/decaytimelimits \emph{muDecayTimeMin} \emph{muDecayTimeMax} \emph{muMeanLife} \emph{unit}}\\
|
||||
(default: /gun/decaytimelimits $-1$ $-1$ 2197.03\,ns ) \\
|
||||
If {\it muDecayTimeMax} is less or equal to zero, this command is ignored,
|
||||
and the muon decay time is set internally by {\sc Geant4}.
|
||||
Otherwise the muon will be forced to decay within a time interval given by
|
||||
{\it muDecayTimeMin} and {\it muDecayTimeMax}, and the mean muon lifetime will
|
||||
be set to {\it muMeanLife}. In such case {\it muDecayTimeMin}
|
||||
has to be equal or larger than 0 and {\it muDecayTimeMax} has to be
|
||||
larger {\bf or equal} to {\it muDecayTimeMin}.\\
|
||||
(Applicable also to TURTLE input).
|
||||
|
||||
\item{\bf /gun/turtlefilename \emph{turtleFileName}}\\
|
||||
Set the filename of the TURTLE input file. If this varialble is set, TURTLE file
|
||||
will be used to initiate muons. Otherwise the mouns would be generated randomly.
|
||||
|
||||
\item{\bf /gun/turtleZ0position \emph{z0\_InitialTurtle} \emph{unit}}\\
|
||||
Set the z-position which has been used to generate the TURTLE file.\\
|
||||
If this value differes from the $z0$ value of the ``/gun/vertex'' command,
|
||||
than the particle initial position is extrapolated from $z0\_InitialTurtle$
|
||||
to the point corresponding to $z0$, using the direction of its momenta.\\
|
||||
MORE DETAILS:\\
|
||||
When running TURTLE (e.g. when generating the TURTLE file using the TURTLE program),
|
||||
the user has to specify the $z$ position, at which the TURTLE particles (muons) would be exported.
|
||||
Sometimes this $z$ position does not correspond to the point of origin of the musrSim
|
||||
geometry. In such case, the variable \emph{z0\_InitialTurtle} should be set to the
|
||||
value, that in musrSim coordinate system corresponds to the point, at which the TURTLE
|
||||
file was exported. For example -- if the TURTLE file was exported just after the last
|
||||
quadrupole of a beam-pipe, and in the simulation the edge of the last quadrupole corresponds
|
||||
to 100\,cm, than the \emph{z0\_InitialTurtle} should be also set to 100\,cm.\\
|
||||
|
||||
\item{\bf /gun/turtleMomentumBite \emph{turtleMomentumP0} \emph{turtleSmearingFactor} \emph{dummy} }\\
|
||||
Modify the smearing of the momentum bite specified in the TURTLE input file.
|
||||
Normally the muon momentum is defined already in the turtle input file. This command allows the user
|
||||
to modify the momentum smearing (momentum bite) of the muon beam.
|
||||
The variable \emph{turtleMomentumP0} will be taken as the mean momentum (in MeV/c), around which
|
||||
the momentum will be increased/decreased. It does not have to be the real mean value of the initial muon momentum distribution.
|
||||
The variable \emph{turtleSmearingFactor} is the smearing factor in per cent, by which the momentum bite
|
||||
will be increased/decreased around the \emph{turtleMomentumP0}. The following equation is used to change the
|
||||
muon momentum: $p^{new}$ = {\it turtleMomentumP0} - ({\it turtleMomentumP0}-$p^{TURTLE}$)$\cdot$0.01$\cdot${\it turtleSmearingFactor}.\\
|
||||
This means that:\\
|
||||
{\it turtleSmearingFactor} = 100 ... the muon beam momentum will not be modified.\\
|
||||
{\it turtleSmearingFactor} = 0 ~~... the muon beam momentum will be set to the constant value of {\it turtleMomentumP0}.\\
|
||||
{\it turtleSmearingFactor} = 200 ... the muon beam will have two times broader distribution compared to the original TURTLE file.
|
||||
|
||||
\item{\bf /gun/turtleFirstEventNr \emph{lineNumberOfTurtleFile} }\\
|
||||
|
||||
\end{description}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Detector construction}
|
||||
|
||||
\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 ``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}=string \emph{name}=string \emph{dimensions}=float ... \emph{material}=string
|
||||
\emph{x}=float \emph{y}=float \emph{z}=float \emph{motherVolume}=string \emph{rotationMatrix}=string
|
||||
\emph{sensitiveClass}=string \emph{idNumber}=int }\\
|
||||
This command defines a volume in {\sc Geant4} (It comprises three steps of {\sc Geant4}: defines a solid,
|
||||
logical volume and physical volume. More details have to be found in {\sc Geant4} manual). \\
|
||||
\begin{itemize}
|
||||
\item \emph{solid} can be one of the G4VSolid.cc particular types, presently ``tubs'', ``box'', ``sphere'',
|
||||
or it can be one of the specifically implemented solids by our program as ``uprofile''
|
||||
(an U-profiled bar), ``alcSupportPlate'' (shape specific to ALC support plate), ``tubsbox''
|
||||
(a tube with a rectangular hole along its axis) and "tubsboxsegm"
|
||||
(a volume that looks like an intersection of tube and box). Not all G4VSolids are
|
||||
presently supported, but it is relatively easy to implement a new kind of solids
|
||||
in the musrDetectorConstruction.cc class.
|
||||
\item \emph{name} stands for the name of the volume. As the ``/musr/command construct'' construct
|
||||
three kinds of classes (volumes) -- the solid, logical volume and physical
|
||||
volume -- there are three names of the concrete volume used internally inside
|
||||
the program: 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''.
|
||||
\item \emph{dimensions} define the size of the required solid. They are kept equivalent to the
|
||||
dimensions of solids as used in {\sc Geant4}. For example the ``box'' is defined
|
||||
by its halfwidths along $x$, $y$ and $z$ coordinates. Note that the number of
|
||||
\emph{dimensions} varies for each type of solid.
|
||||
\item \emph{material} one of the materials defined in {\sc Geant4}, namely in the file
|
||||
\$G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc (e.g. ``G4\_Galactic'' for
|
||||
vacuum, ``G4\_Cu'' for copper, ``G4\_AIR'' for air and
|
||||
``G4\_PLASTIC\_SC\_VINYLTOLUENE'' for a scintillator).
|
||||
One can also define a new material inside the function
|
||||
musrDetectorConstruction::DefineMaterials(). Presently ``Mylar'', ``Brass''
|
||||
and ``Steel'' are defined there.
|
||||
\item \emph{x, y, z} -- coordinates of the volume, used to position the volume within
|
||||
its mother volume (as used by the G4PVPlacement).
|
||||
\item \emph{motherVolume} -- 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
|
||||
daughter), and that the name of mother starts with a string {\bf log\_}\emph{name},
|
||||
following the naming convention defined above.
|
||||
When the ``World'' volume is defined, its \emph{motherVolume} should be set to ``no\_logical\_volume''.
|
||||
\item \emph{rotationMatrix} -- name of the rotation matrix that will be used to position
|
||||
the volume inside its mother volume (as used in member function G4PVPlacement()).
|
||||
Use string ``norot'' if no rotation is required for the given volume.
|
||||
Otherwise the rotation matrix has to be defined by the command line
|
||||
``/musr/command rotation'' {\bf before} the given is defined.
|
||||
\item \emph{sensitiveClass} -- specifies whether the volume is sensitive or not.
|
||||
Use the string ``dead'' for the non-senstive volume (i.e.\ for the dead material),
|
||||
and the string ``musr/ScintSD'' for a scintillator (a sensitive volume, i.e.\
|
||||
a volume where hits are observed). No other detector type
|
||||
(other than ``dead'' and ``musr/ScintSD'') is supported at the moment, but
|
||||
the program might be extended in the future (e.g. to properly include also the
|
||||
semiconductor tracking detectors, etc.).
|
||||
\item \emph{idNumber} -- idNumber serves as a unique identifier of the volume. It is primarily
|
||||
used in the output Root tree to identify the volume: 1) in which muons stop
|
||||
(tree variable ``muDecayDetID''),
|
||||
2) in which hits were deposited in case of sensitive volume
|
||||
(the variable ``det\_ID[det\_n]'').
|
||||
\end{itemize}
|
||||
%tubs beampipeA 0 128 500 0 360 G4_Galactic 0 0 -800 log_World norot dead 232
|
||||
|
||||
\item{\bf /musr/command logicalVolumeToBeReweighted mu \emph{logicalVolume}=string \emph{weight}=int }\\
|
||||
(default: not defined; no reweighting is done unless explicitly requested by this command.) \\
|
||||
Events can be reweighted by this command. If muon {\bf stops and decays} in the
|
||||
volume \emph{logicalVolume}, the event will be reweighted using the requested \emph{weight}.
|
||||
Namely, only each $n^{th}$ event will be stored ($n=$\emph{weight}) with the parameter
|
||||
``weight'' in the Root output tree set to \emph{weight}, while other (non-$n^{th}$) events
|
||||
will be aborted. (The decision which event is to be stored and which to be aborted is
|
||||
done at random). This reweighting might be usefull in the cases when the user wants to speed-up the
|
||||
simulation (respectively to reduce the number of fully simulated events), while keeping
|
||||
the high number of events interesting for the analysis. For example, one can set
|
||||
the reweighting of events in which muons stop in the collimator. One should then
|
||||
use the \emph{weight} stored in the Root tree when filling histograms.
|
||||
Compared to the simulation with no weighting applied, the histograms with weighted events
|
||||
will have larger errors, but the distribution should not differ more then within the
|
||||
statistical errors.\\
|
||||
Note that the \emph{weight} parameter is integer, and ``mu'' stands for ``muons''
|
||||
(at the moment reweighting based on electrons or positrons is not supported).
|
||||
|
||||
|
||||
\end{description}
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Visualisation}
|
||||
|
||||
\begin{description}
|
||||
\item{\bf /musr/command visattributes \emph{volumeName} \emph{color}}\\
|
||||
{\bf /musr/command visattributes \emph{materialName} \emph{color}}\\
|
||||
In case of visualisation,
|
||||
one can set the color of a logical volume \emph{volumeName} or of all volumes made
|
||||
of the material with the name \emph{materialName}. The distinction between the
|
||||
two options is by the first four letters of the \emph{volumeName} -- if it contains
|
||||
the string ``log\_'', it is considered as \emph{volumeName}, otherwise it is
|
||||
considered to be a material with \emph{materialName}.
|
||||
|
||||
Presently the following colors are predefined: ``invisible'', ``white'', ``black'',
|
||||
``red'', ``green'', ``blue'', ``lightblue'', ``yellow'', ``gray'', ``cyan'' and ``magenta''.
|
||||
New colours can be easily added, if needed, in the member function
|
||||
``musrDetectorConstruction::SetColourOfLogicalVolume''.
|
||||
|
||||
\end{description}
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Physics processes}
|
||||
|
||||
\begin{description}
|
||||
\item{\bf /musr/command process addDiscreteProcess \emph{particle}=string \emph{process}=string }\\
|
||||
{\bf /musr/command process addProcess \emph{particle}=string \emph{process}=string \emph{ordAtRestDoIt}=int \emph{ordAlongSteptDoIt}=int \emph{ordPostStepDoIt}=int }\\
|
||||
Adds processes for particles. See {\sc Geant4} manual for more details. Look in the
|
||||
file musrPhysicsList.cc for the list of defined processes (e.g. G4MultipleScattering,
|
||||
G4eIonisation, ...)
|
||||
|
||||
There is one special process, combined from G4MultipleScattering and G4CoulombScattering,
|
||||
defined by the following command:\\
|
||||
{\bf /musr/command process addProcess \emph{particle}=string MultipleAndCoulombScattering \emph{ordAtRestDoIt}=int \emph{ordAlongSteptDoIt}=int \emph{ordPostStepDoIt}=int \emph{G4Region1}=string [\emph{G4Region2}=string] [\emph{G4Region3}=string] }\\
|
||||
The G4MultipleScattering (rough but very fast approximation of scattering) will be applied
|
||||
elswhere in the detector, except for the \emph{G4Region1} (and eventually \emph{G4Region2}
|
||||
and \emph{G4Region3}), where more precise but very slow process G4CoulombScattering
|
||||
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}
|
||||
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 ...''.
|
||||
|
||||
\end{description}
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\clearpage
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Output root tree variables}
|
||||
The value of -999 or -1000 indicates that the given variable could not be filled
|
||||
(was undefined in a given event).
|
||||
For example if the variable ``muTargetTime'' is set to -1000 it means that the initial muon missed the sample,
|
||||
and therefore no time can be assigned to the sample hit.
|
||||
|
||||
\begin{description}
|
||||
\item{\bf runID} (Int\_t) -- run ID number.
|
||||
\item{\bf eventID} (Int\_t) -- event ID number.
|
||||
\item{\bf weight} (Double\_t) -- event weight.
|
||||
\item{\bf BFieldAtDecay\_Bx, BFieldAtDecay\_By, BFieldAtDecay\_Bz, BFieldAtDecay\_B3, BFieldAtDecay\_B4, BFieldAtDecay\_B5} (Double\_t) --
|
||||
value of the 6 coordinates of the electromagnetic field at the position and time where and when the muon decayed.
|
||||
The first three coordinates correspond to the magnetic field, the last three to the electric field.
|
||||
\item{\bf muIniPosX, muIniPosY, muIniPosZ} (Double\_t) -- initial position where muon was generated (in mm).
|
||||
\item{\bf muIniMomX, muIniMomY, muIniMomZ} (Double\_t) -- initial momentum of the muon when it was generated (in MeV/c).
|
||||
\item{\bf muIniPolX, muIniPolY, muIniPolZ} (Double\_t) -- initial polarisation of the muon when it was generated.
|
||||
\item{\bf muDecayDetID} (Int\_t) -- ID number of the detector in which the muon stopped and decayed.
|
||||
\item{\bf muDecayPosX, muDecayPosY, muDecayPosZ} (Double\_t) -- the position where the muon stopped and decayed (in mm).
|
||||
\item{\bf muDecayTime} (Double\_t) -- the time at which the muon stopped and decayed (in $\mu$s).
|
||||
\item{\bf muDecayPolX, muDecayPolY, muDecayPolZ} (Double\_t) -- polarisation of the muon when it stopped and decayed.
|
||||
\item{\bf muTargetTime} (Double\_t) -- time at which the muon entered the volume whose name starts by ``target'' -- usually the sample (in $\mu$s).
|
||||
\item{\bf muTargetPolX, muTargetPolY, muTargetPolZ} (Double\_t) -- polarisation of the muon when it entered the volume whose name starts with ``target'' -- usually the sample.
|
||||
\item{\bf muM0Time} (Double\_t) -- time at which the muon entered the detector called ``M0'' or ``m0'' (in $\mu$s).
|
||||
\item{\bf muM0PolX, muM0PolY, muM0PolZ} (Double\_t) -- polarisation of the muon when it entered the detector called ``M0'' or ``m0''.
|
||||
\item{\bf muM1Time} (Double\_t) -- time at which the muon entered the detector called ``M1'' or ``m1'' (in $\mu$s).
|
||||
\item{\bf muM1PolX, muM1PolY, muM1PolZ} (Double\_t) -- polarisation of the muon when it entered the detector called ``M1'' or ``m1''.
|
||||
\item{\bf muM2Time} (Double\_t) -- time at which the muon entered the detector called ``M2'' or ``m2'' (in $\mu$s).
|
||||
\item{\bf muM2PolX, muM2PolY, muM2PolZ} (Double\_t) -- polarisation of the muon when it entered the detector called ``M2'' or ``m2''.
|
||||
\item{\bf posIniMomX, posIniMomY, posIniMomY} (Double\_t) -- Initial momentum of the decay positron (in MeV/c).
|
||||
\item{\bf nFieldNomVal} (Int\_t) -- number of the elementary fields that make together the global field.
|
||||
\item{\bf fieldNomVal[nFieldNomVal]} (array of Double\_t) -- nominal values of all elementary fields.
|
||||
(They are usually constant, but sometimes they may vary from event to event).
|
||||
\item{\bf BxIntegral, ByIntegral, BzIntegral, BzIntegral1, BzIntegral2, BzIntegral3} (Double\_t) --
|
||||
calculates the field integrals along the muon path and path lengths defined as
|
||||
\begin{eqnarray}
|
||||
\mathrm{BxIntegral} & = & \int_{\mu\ \mathrm{path}} B_x(s)\, ds \\
|
||||
\mathrm{ByIntegral} & = & \int_{\mu\ \mathrm{path}} B_y(s)\, ds \\
|
||||
\mathrm{BzIntegral} & = & \int_{\mu\ \mathrm{path}} B_z(s)\, ds \\
|
||||
\mathrm{BzIntegral1} & = & \int_{Z_0}^{Z_{decay}} B_z(z)\, dz \\
|
||||
\mathrm{BzIntegral2} & = & \int_{\mu\ \mathrm{path}} ds \\
|
||||
\mathrm{BzIntegral3} & = & \int_{Z_0}^{Z_{decay}} dz
|
||||
\end{eqnarray}
|
||||
The units are tesla$\cdot$m (for the first four variables) and mm (for the last two variables).
|
||||
To calculate the integrals properly, the user must force Geant to use very small step size
|
||||
(e.g.\ by using something like ``/musr/command globalfield setparameter SetLargestAcceptableStep 2''),
|
||||
and probably also to generate the muons well outside the magnetic field and put target such
|
||||
that muons stop at $z=0$.
|
||||
|
||||
Note that these variables are by default not calculated (and not stored) and therefore the user has
|
||||
to switch the calculation on by ``/musr/command rootOutput fieldIntegralBx on'' in the macro file.
|
||||
|
||||
\item{\bf det\_n} (Int\_t) -- number of ``detector hits'' in this event. Note that more then 1 detector
|
||||
might be hit, and even the same detector might be hit more than once. The hit might be induced by just one
|
||||
particle, by more then one particle originating from the same particle initially hitting the detector,
|
||||
or from more ``independent'' particles.
|
||||
For example, the decay positron can emit an Bremsstrahlung photon in the sample and then both the Bremsstrahlung
|
||||
photon and positron hit the same positron counter at approximately the same time.
|
||||
\item{\bf det\_ID[det\_n]} (array of Int\_t) -- ID number of the detector where the given hit occurred.
|
||||
\item{\bf det\_edep[det\_n]} (array of Double\_t) -- energy deposited in the given hit (in MeV).
|
||||
\item{\bf det\_edep\_el[det\_n]} (array of Double\_t) -- energy deposited in the given hit due to electron-based interactions (in MeV).
|
||||
\item{\bf det\_edep\_pos[det\_n]} (array of Double\_t) -- energy deposited in the given hit due to positron-based interactions (in MeV).
|
||||
\item{\bf det\_edep\_gam[det\_n]} (array of Double\_t) -- energy deposited in the given hit due to photon-based interactions (in MeV).
|
||||
\item{\bf det\_edep\_mup[det\_n]} (array of Double\_t) -- energy deposited in the given hit due to muon-based interactions (in MeV).
|
||||
\item{\bf det\_nsteps[det\_n]} (array of Int\_t) -- number of ``steps'' (in {\sc Geant4} terminology) that were
|
||||
integrated together in the given hit. (The det\_edep[] energy is the sum of the energy deposits during all these steps).
|
||||
\item{\bf det\_length[det\_n]} (array of Double\_t) -- the length of the trajectory of the particle (particles) that contributed to
|
||||
the given hit (in mm).
|
||||
\item{\bf det\_time\_start[det\_n], det\_time\_end[det\_n]} (array of Double\_t) -- the initial and final time belonging of the hit.
|
||||
It should be the ``global time'' of the track when the first and last hit occurred (in $\mu$s).
|
||||
\item{\bf det\_x[det\_n], det\_y[det\_n], det\_z[det\_n]} (array of Double\_t) -- the coordinates of the first step of the given hit.
|
||||
%\item{\bf det\_kine[det\_n]} (array of Double\_t) -- should be kinetic energy, but not sure whether it is filled correctly (in MeV).
|
||||
\item{\bf det\_Vrtx*****[det\_n]} -- All the variables starting with ``det\_Vrtx'' refer to the particle with the first (in time) energy deposit
|
||||
belonging to the given hit. (Note that the hit might be induceed by more than one particle.) The vertex, at which
|
||||
the particle was created, may or may not be positioned within the sensitive volume, in which the hit is observed.
|
||||
\item{\bf det\_VrtxKine[det\_n]} (array of Double\_t) -- the kinetic energy of the first (in time) particle belonging to the hit.
|
||||
\item{\bf det\_VrtxX[det\_n], det\_VrtxY[det\_n], det\_VrtxZ[det\_n]} (array of Double\_t) -- the position of the vertex of
|
||||
the first particle that belongs to the given hit (in mm).
|
||||
\item{\bf det\_VrtxVolID[det\_n]} (array of Int\_t) -- ID of the detector in which the vertex (see above) was created.
|
||||
\item{\bf det\_VrtxProcID[det\_n]} (array of Int\_t) -- ID of the physics process in which the vertex (see above) was created.
|
||||
\item{\bf det\_VrtxTrackID[det\_n]} (array of Int\_t) -- track ID of the first particle that belongs to the given hit.
|
||||
If the track ID is negative, there were more than just one track contributing to this hit. The absolute value
|
||||
of det\_VrtxTrackID[det\_n] corresponds to the first (in time) track.
|
||||
\item{\bf det\_VrtxParticleID[det\_n]} (array of Int\_t) -- particle ID of the first particle that belongs to the given hit.
|
||||
\item{\bf det\_Vvv*****[det\_n]} -- similar to the variables det\_Vrtx*****[det\_n] above, but if the first particle
|
||||
belonging to the hit was created inside of the logical volume where the hit occurs, then it's track is followed
|
||||
to its mother track (even several times) until the track (particle) is found that has been created outside the
|
||||
given volume. This way one can better investigate which (hopefully) single particle coused the hit. Even though
|
||||
even in this case it is not guarranteed that only a single particle gave origin to the hit, it is quite likely, though,
|
||||
that it was in fact just a single particle. If the
|
||||
\item{\bf save\_n} (Int\_t) -- number of special kind of ``save'' volume that were hit in this event. The ``save volume'' is
|
||||
any volume whose name starts with letters ``save''. Their purpose in the simulation is usually to check positions
|
||||
and momenta of particles at some position of the detector, even if the particle does not deposit any energy in
|
||||
the given ``save'' volume. Save volumes can therefore be made of vacuum.
|
||||
\item{\bf save\_detID[save\_n]} (array of Int\_t) -- ID number of the save volume.
|
||||
\item{\bf save\_particleID[save\_n]} (array of Int\_t) -- particle ID of the particle that entered the save volume.
|
||||
\item{\bf save\_x[save\_n], save\_y[save\_n], save\_z[save\_n]} (array of Double\_t) -- position of the particle where it
|
||||
entered the save volume (``GetPreStepPoint()'') (in mm).
|
||||
\item{\bf save\_px[save\_n], save\_py[save\_n], save\_pz[save\_n]} (array of Double\_t) -- momentum of the particle when it
|
||||
entered the save volume (in GeV).
|
||||
|
||||
\end{description}
|
||||
\clearpage
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
|
||||
%
|
||||
%\begin{figure}\centering
|
||||
%\epsfig{file=pict/HiFi_01.eps,width=\linewidth,%
|
||||
%bbllx=56pt,bblly=288pt,bburx=505pt,bbury=555pt,clip=}
|
||||
%\caption{The cross-section of the first version of the High Field \musr\ apparatus including
|
||||
%an example interaction. Only the inner part of the apparatus is shown. The picture was generated
|
||||
%using GEANT package.}
|
||||
%\label{HiFi_01}
|
||||
%\end{figure}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Conclusions}
|
||||
The ...
|
||||
in~\cite{Aktas:2004px}.
|
||||
|
||||
\section{Appendix A: Steering file for the simulation}
|
||||
\begin{verbatim}
|
||||
# Macro file for seg06.cc
|
||||
# set detector parameters
|
||||
# This line fills some space
|
||||
# This line fills some space
|
||||
/run/beamOn 2
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\begin{thebibliography}{0}
|
||||
|
||||
%\cite{Aktas:2004px}
|
||||
\bibitem{Aktas:2004px}
|
||||
A.~Aktas {\it et al.} [H1 Collaboration],
|
||||
%``Measurement of dijet production at low Q**2 at HERA,''
|
||||
Submitted to Eur.\,Phys.\,J.\,{\bf C}, [hep-ex/0401010].
|
||||
%%CITATION = HEP-EX 0401010;%%
|
||||
|
||||
|
||||
|
||||
|
||||
\end{thebibliography}
|
||||
|
||||
\end{document}
|
160
include/BLEngeFunction.hh
Normal file
160
include/BLEngeFunction.hh
Normal file
@ -0,0 +1,160 @@
|
||||
// BLEngeFunction.hh
|
||||
/*
|
||||
This source file is part of G4beamline, http://g4beamline.muonsinc.com
|
||||
Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#ifndef BLENGEFUNCTION_HH
|
||||
#define BLENGEFUNCTION_HH
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/** enum BLEngeType specifies the default parameters of BLEngeFunction.
|
||||
**/
|
||||
enum BLEngeType { ENGE_BLOCK, ENGE_BEND, ENGE_QUAD, ENGE_OTHER };
|
||||
|
||||
/** class EngeFunction implements the Enge function for fringe fields.
|
||||
*
|
||||
* z is the distance from the nominal edge, with z=0 being the edge.
|
||||
* it should be divided by the aperture diameter or full width/height.
|
||||
* z<0 is inside, z>0 is outside.
|
||||
*
|
||||
* See the COSY reference manual (pp 32-35) for suggested values of
|
||||
* a1-a6, or use the ENGE_BEND or ENGE_QUAD types (which come from there).
|
||||
* http://cosy.pa.msu.edu/cosymanu/index.html
|
||||
*
|
||||
* Mathematica was used to compute the derivatives.
|
||||
**/
|
||||
class BLEngeFunction {
|
||||
BLEngeType type;
|
||||
double a1,a2,a3,a4,a5,a6;
|
||||
public:
|
||||
/// default constructor.
|
||||
BLEngeFunction() { type=ENGE_BLOCK; set(0,0,0,0,0,0); }
|
||||
/// constructor for common magnet types.
|
||||
BLEngeFunction(BLEngeType t) {
|
||||
switch(t) {
|
||||
case ENGE_BLOCK:
|
||||
case ENGE_OTHER:
|
||||
set(0,0,0,0,0,0);
|
||||
break;
|
||||
case ENGE_BEND:
|
||||
set(0.478959,1.911289,-1.185953,1.630554,-1.082657,0.318111);
|
||||
break;
|
||||
case ENGE_QUAD:
|
||||
set(0.296471,4.533219,-2.270982,1.068627,-0.036391,0.022261);
|
||||
break;
|
||||
}
|
||||
type = t;
|
||||
}
|
||||
/// general constructor.
|
||||
BLEngeFunction(double _a1, double _a2, double _a3, double _a4,
|
||||
double _a5, double _a6) {
|
||||
set(_a1,_a2,_a3,_a4,_a5,_a6);
|
||||
}
|
||||
/// set the parameters.
|
||||
void set(double _a1, double _a2, double _a3, double _a4,
|
||||
double _a5, double _a6) {
|
||||
a1=_a1; a2=_a2; a3=_a3; a4=_a4; a5=_a5; a6=_a6;
|
||||
if(a1==0.0 && a2==0.0 && a3==0.0 && a4==0.0 && a5==0.0 &&
|
||||
a6==0.0)
|
||||
type = ENGE_BLOCK;
|
||||
else
|
||||
type = ENGE_OTHER;
|
||||
}
|
||||
/// evaluate the Enge function at z.
|
||||
double operator()(double z) const {
|
||||
if(type == ENGE_BLOCK) return (z<=0.0 ? 1.0 : 0.0);
|
||||
if(z < -4.0) return 1.0;
|
||||
if(z > 4.0) return 0.0;
|
||||
return 1.0/(1.0+exp(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*a6))))));
|
||||
}
|
||||
/// evaluate the derivative of the Enge function at z.
|
||||
double prime(double z) const {
|
||||
if(type == ENGE_BLOCK) return 0.0;
|
||||
if(fabs(z) > 4.0) return 0.0;
|
||||
double exp1 = exp(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*a6)))));
|
||||
return -exp1/(1.0+exp1)/(1.0+exp1)*
|
||||
(a2+z*(2.0*a3+z*(3.0*a4+z*(4.0*a5+z*5.0*a6))));
|
||||
}
|
||||
double first(double z) { return prime(z); }
|
||||
/// evaluate the second derivative of the Enge function at z.
|
||||
double second(double z) const {
|
||||
if(type == ENGE_BLOCK) return 0.0;
|
||||
if(fabs(z) > 4.0) return 0.0;
|
||||
double f1 = a1+z*(a2+z*(a3+z*(a4+z*(a5+z*a6))));
|
||||
double f2 = (a2+2*a3*z+3*a4*z*z+4*a5*z*z*z+5*a6*z*z*z*z);
|
||||
double f3 = (2*a3+6*a4*z+12*a5*z*z+20*a6*z*z*z);
|
||||
double exp1 = exp(f1);
|
||||
return exp1*((exp1-1.0)*f2*f2-(1.0+exp1)*f3)/
|
||||
(1.0+exp1)/(1.0+exp1)/(1.0+exp1);
|
||||
}
|
||||
/// evaluate the third derivative of the Enge function at z.
|
||||
double third(double z) const {
|
||||
if(type == ENGE_BLOCK) return 0.0;
|
||||
if(fabs(z) > 4.0) return 0.0;
|
||||
double f1 = a1+z*(a2+z*(a3+z*(a4+z*(a5+z*a6))));
|
||||
double f2 = a2+z*(2*a3+z*(3*a4+4*a5*z+5*a6*z*z));
|
||||
double f3 = 2*(a3+z*(3*a4+2*z*(3*a5+5*a6*z)));
|
||||
double f4 = a4+2.0*z*(2.0*a5+5.0*a6*z);
|
||||
double exp1 = exp(f1);
|
||||
double onepexp1 = 1.0 + exp1;
|
||||
return -exp1*(6*exp1*exp1*f2*f2*f2-6*exp1*f2*(f2*f2+f3)*onepexp1
|
||||
+(f2*f2*f2+3*f2*f3+6*f4)*onepexp1*onepexp1)
|
||||
/(onepexp1*onepexp1*onepexp1*onepexp1);
|
||||
}
|
||||
/// evaluate the fourth derivative of the Enge function at z.
|
||||
double fourth(double z) const {
|
||||
if(type == ENGE_BLOCK) return 0.0;
|
||||
if(fabs(z) > 4.0) return 0.0;
|
||||
double f1 = a1+z*(a2+z*(a3+z*(a4+z*(a5+z*a6))));
|
||||
double f2 = a2+z*(2*a3+z*(3*a4+4*a5*z+5*a6*z*z));
|
||||
double f3 = 2*(a3+z*(3*a4+2*z*(3*a5+5*a6*z)));
|
||||
double f4 = a4+2.0*z*(2.0*a5+5.0*a6*z);
|
||||
double f5 = a5 + 5*a6*z;
|
||||
double exp1 = exp(f1);
|
||||
double onepexp1 = 1.0 + exp1;
|
||||
return -exp1*(-24*exp1*exp1*exp1*f2*f2*f2*f2+onepexp1*
|
||||
(36*exp1*exp1*f2*f2*(f2*f2+f3)-2*exp1*(7*f2*f2*f2*f2
|
||||
+18*f2*f2*f3+3*f3*f3+24*f2*f4)*onepexp1
|
||||
+(f2*f2*f2*f2+6*f2*f2*f3+3*f3*f3+24*f2*f4+24*f5)
|
||||
*onepexp1*onepexp1))
|
||||
/(onepexp1*onepexp1*onepexp1*onepexp1*onepexp1);
|
||||
}
|
||||
/// evaluate the fifth derivative of the Enge function at z.
|
||||
double fifth(double z) const {
|
||||
if(type == ENGE_BLOCK) return 0.0;
|
||||
if(fabs(z) > 4.0) return 0.0;
|
||||
double f1 = a1+z*(a2+z*(a3+z*(a4+z*(a5+z*a6))));
|
||||
double f2 = a2+z*(2*a3+z*(3*a4+4*a5*z+5*a6*z*z));
|
||||
double f3 = 2*(a3+z*(3*a4+2*z*(3*a5+5*a6*z)));
|
||||
double f4 = a4+2.0*z*(2.0*a5+5.0*a6*z);
|
||||
double f5 = a5 + 5*a6*z;
|
||||
double exp1 = exp(f1);
|
||||
double onepexp1 = 1.0 + exp1;
|
||||
return -exp1/(onepexp1*onepexp1*onepexp1*onepexp1*onepexp1*onepexp1)
|
||||
*(120*exp1*exp1*exp1*exp1*f2*f2*f2*f2*f2
|
||||
-240*exp1*exp1*exp1*f2*f2*f2*(f2*f2+f3)*onepexp1
|
||||
+onepexp1*onepexp1*(30*exp1*exp1*f2*(5*f2*f2*f2*f2
|
||||
+12*f2*f2*f3+3*f3*f3+12*f2*f4)-10*exp1*(3*f2*f2*f2*f2*f2
|
||||
+14*f2*f2*f2*f3+9*f2*f3*f3+36*f2*f2*f4+12*f3*f4+24*f2*f5)
|
||||
*onepexp1+(120*a6+f2*f2*f2*f2*f2+10*f2*f2*f2*f3+60*f2*f2*f4
|
||||
+60*f3*f4+15*f2*(f3*f3+8*f5))*onepexp1*onepexp1));
|
||||
}
|
||||
/// return the type of Enge function
|
||||
BLEngeType getType() const { return type; }
|
||||
};
|
||||
|
||||
#endif // BLENGEFUNCTION_HH
|
171
include/F04ElementField.hh
Normal file
171
include/F04ElementField.hh
Normal file
@ -0,0 +1,171 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#ifndef F04ElementField_h
|
||||
#define F04ElementField_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
#include "G4UserLimits.hh"
|
||||
#include "G4VisAttributes.hh"
|
||||
|
||||
// class F04ElementField - interface for the EM field of one element
|
||||
|
||||
// This is the interface class used by GlobalField to compute the field
|
||||
// value at a given point[].
|
||||
|
||||
// An element that represents an element with an EM field will
|
||||
// derive a class from this one and implement the computation for the
|
||||
// element. The construct() function will add the derived object into
|
||||
// GlobalField.
|
||||
|
||||
class F04ElementField
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
F04ElementField& operator=(const F04ElementField&);
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
F04ElementField(const G4ThreeVector, G4LogicalVolume*);
|
||||
|
||||
/// the actual implementation constructs the F04ElementField
|
||||
void construct();
|
||||
|
||||
/// Destructor.
|
||||
virtual ~F04ElementField() { if (aNavigator) delete aNavigator; }
|
||||
|
||||
/// setMaxStep(G4double) sets the max. step size
|
||||
void setMaxStep(G4double s)
|
||||
{
|
||||
maxStep = s;
|
||||
userLimits->SetMaxAllowedStep(maxStep);
|
||||
lvolume->SetUserLimits(userLimits);
|
||||
}
|
||||
|
||||
/// getMaxStep() returns the max. step size
|
||||
G4double getMaxStep() { return maxStep; }
|
||||
|
||||
/// setColor(G4String) sets the color
|
||||
void setColor(G4String c)
|
||||
{
|
||||
color = c;
|
||||
lvolume->SetVisAttributes(getVisAttribute(color));
|
||||
}
|
||||
|
||||
/// getColor() returns the color
|
||||
G4String getColor() { return color; }
|
||||
|
||||
/// getVisAttribute() returns the appropriate G4VisAttributes.
|
||||
static G4VisAttributes* getVisAttribute(G4String color);
|
||||
|
||||
/// setGlobalPoint() ensures that the point is within the global
|
||||
/// bounding box of this ElementField's global coordinates.
|
||||
/// Normally called 8 times for the corners of the local bounding
|
||||
/// box, after a local->global coordinate transform.
|
||||
/// If never called, the global bounding box is infinite.
|
||||
/// BEWARE: if called only once, the bounding box is just a point.
|
||||
void setGlobalPoint(const G4double point[4])
|
||||
{
|
||||
if(minX == -DBL_MAX || minX > point[0]) minX = point[0];
|
||||
if(minY == -DBL_MAX || minY > point[1]) minY = point[1];
|
||||
if(minZ == -DBL_MAX || minZ > point[2]) minZ = point[2];
|
||||
if(maxX == DBL_MAX || maxX < point[0]) maxX = point[0];
|
||||
if(maxY == DBL_MAX || maxY < point[1]) maxY = point[1];
|
||||
if(maxZ == DBL_MAX || maxZ < point[2]) maxZ = point[2];
|
||||
}
|
||||
|
||||
/// isInBoundingBox() returns true if the point is within the
|
||||
/// global bounding box - global coordinates.
|
||||
bool isInBoundingBox(const G4double point[4]) const
|
||||
{
|
||||
if(point[2] < minZ || point[2] > maxZ) return false;
|
||||
if(point[0] < minX || point[0] > maxX) return false;
|
||||
if(point[1] < minY || point[1] > maxY) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// addFieldValue() will add the field value for this element to field[].
|
||||
/// Implementations must be sure to verify that point[] is within
|
||||
/// the field region, and do nothing if not.
|
||||
/// point[] is in global coordinates and geant4 units; x,y,z,t.
|
||||
/// field[] is in geant4 units; Bx,By,Bz,Ex,Ey,Ez.
|
||||
/// For efficiency, the caller may (but need not) call
|
||||
/// isInBoundingBox(point), and only call this function if that
|
||||
/// returns true.
|
||||
virtual void
|
||||
addFieldValue(const G4double point[4], G4double field[6]) const = 0;
|
||||
|
||||
virtual G4double getLength() = 0;
|
||||
virtual G4double getWidth() = 0;
|
||||
virtual G4double getHeight() = 0;
|
||||
|
||||
void SetElementFieldName(G4String name) {elementFieldName=name;}
|
||||
G4String GetElementFieldName() {return elementFieldName;}
|
||||
void SetEventNrDependentField(G4double initialField, G4double finalField, G4int nrOfSteps);
|
||||
std::map<G4int,G4double> GetEventNrDependentField() const {return changeFieldInStepsMap;}
|
||||
void SetElementFieldValueIfNeeded(G4int eventNr);
|
||||
|
||||
virtual G4double GetNominalFieldValue() = 0;
|
||||
virtual void SetNominalFieldValue(G4double newFieldValue) =0;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
G4LogicalVolume* lvolume;
|
||||
|
||||
G4AffineTransform global2local;
|
||||
|
||||
// F04ElementField(const F04ElementField&);
|
||||
|
||||
private:
|
||||
|
||||
static G4Navigator* aNavigator;
|
||||
|
||||
G4String color;
|
||||
|
||||
G4ThreeVector center;
|
||||
G4double minX, minY, minZ, maxX, maxY,maxZ;
|
||||
|
||||
G4double maxStep;
|
||||
G4UserLimits* userLimits;
|
||||
|
||||
G4String elementFieldName;
|
||||
std::map<G4int,G4double> changeFieldInStepsMap;
|
||||
};
|
||||
|
||||
#endif
|
73
include/F04FieldMessenger.hh
Normal file
73
include/F04FieldMessenger.hh
Normal file
@ -0,0 +1,73 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#ifndef F04FieldMessenger_h
|
||||
#define F04FieldMessenger_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4UImessenger.hh"
|
||||
|
||||
class F04GlobalField;
|
||||
class G4UIdirectory;
|
||||
class G4UIcmdWithAString;
|
||||
class G4UIcmdWithAnInteger;
|
||||
class G4UIcmdWithADoubleAndUnit;
|
||||
class G4UIcmdWithoutParameter;
|
||||
|
||||
class F04FieldMessenger: public G4UImessenger
|
||||
{
|
||||
public:
|
||||
F04FieldMessenger(F04GlobalField* );
|
||||
~F04FieldMessenger();
|
||||
|
||||
void SetNewValue(G4UIcommand*, G4String);
|
||||
void SetNewValue(G4UIcommand*, G4int);
|
||||
|
||||
private:
|
||||
|
||||
F04GlobalField* fGlobalField;
|
||||
|
||||
G4UIdirectory* detDir;
|
||||
|
||||
G4UIcmdWithAnInteger* fStepperCMD;
|
||||
G4UIcmdWithADoubleAndUnit* fMinStepCMD;
|
||||
G4UIcmdWithADoubleAndUnit* fDeltaChordCMD;
|
||||
G4UIcmdWithADoubleAndUnit* fDeltaOneStepCMD;
|
||||
G4UIcmdWithADoubleAndUnit* fDeltaIntersectionCMD;
|
||||
G4UIcmdWithADoubleAndUnit* fEpsMinCMD;
|
||||
G4UIcmdWithADoubleAndUnit* fEpsMaxCMD;
|
||||
G4UIcmdWithoutParameter* fUpdateCMD;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
195
include/F04GlobalField.hh
Normal file
195
include/F04GlobalField.hh
Normal file
@ -0,0 +1,195 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#ifndef F04GlobalField_h
|
||||
#define F04GlobalField_h 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "G4FieldManager.hh"
|
||||
#include "G4PropagatorInField.hh"
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4ChordFinder.hh"
|
||||
|
||||
//#include "G4MagneticField.hh"
|
||||
#include "G4ElectroMagneticField.hh"
|
||||
|
||||
#include "G4Mag_EqRhs.hh"
|
||||
#include "G4Mag_SpinEqRhs.hh"
|
||||
|
||||
#include "G4EqMagElectricField.hh"
|
||||
#include "G4EqEMFieldWithSpin.hh"
|
||||
|
||||
#include "F04FieldMessenger.hh"
|
||||
#include "F04ElementField.hh"
|
||||
|
||||
// F04GlobalField - handles the global ElectroMagnetic field
|
||||
//
|
||||
// There is a single G04GlobalField object.
|
||||
//
|
||||
// The field from each individual beamline element is given by a
|
||||
// ElementField object. Any number of overlapping ElementField
|
||||
// objects can be added to the global field. Any element that
|
||||
// represents an element with an EM field must add the appropriate
|
||||
// ElementField to the global GlobalField object.
|
||||
|
||||
typedef std::vector<F04ElementField*> FieldList;
|
||||
|
||||
class F04GlobalField : public G4ElectroMagneticField {
|
||||
//class F04GlobalField : public G4MagneticField {
|
||||
|
||||
private:
|
||||
|
||||
F04GlobalField();
|
||||
F04GlobalField(const F04GlobalField&);
|
||||
|
||||
public:
|
||||
~F04GlobalField();
|
||||
|
||||
private:
|
||||
F04GlobalField& operator=(const F04GlobalField&);
|
||||
|
||||
void setupArray();
|
||||
|
||||
public:
|
||||
|
||||
/// getObject() returns the single F04GlobalField object.
|
||||
/// It is constructed, if necessary.
|
||||
static F04GlobalField* getObject();
|
||||
|
||||
//
|
||||
static G4bool Exists() {if (object==NULL) {return false;} else {return true;}; }
|
||||
|
||||
/// GetFieldValue() returns the field value at a given point[].
|
||||
/// field is really field[6]: Bx,By,Bz,Ex,Ey,Ez.
|
||||
/// point[] is in global coordinates: x,y,z,t.
|
||||
void GetFieldValue(const G4double* point, G4double* field) const;
|
||||
|
||||
/// DoesFieldChangeEnergy() returns true.
|
||||
// cks - for testing just on magnetic field use DoesFieldChangeEnergy()=false;
|
||||
G4bool DoesFieldChangeEnergy() const { return true; }
|
||||
// G4bool DoesFieldChangeEnergy() const { return false; }
|
||||
|
||||
/// addElementField() adds the ElementField object for a single
|
||||
/// element to the global field.
|
||||
void addElementField(F04ElementField* f) { if (fields) fields->push_back(f); }
|
||||
|
||||
/// clear() removes all ElementField-s from the global object,
|
||||
/// and destroys them. Used before the geometry is completely
|
||||
/// re-created.
|
||||
void clear();
|
||||
|
||||
/// updates all field tracking objects and clear()
|
||||
void updateField();
|
||||
|
||||
/// Set the Stepper types
|
||||
void SetStepperType( G4int i ) { fStepperType = i; }
|
||||
|
||||
/// Set the Stepper
|
||||
void SetStepper();
|
||||
|
||||
/// Set the minimum step length
|
||||
void SetMinStep(G4double s) { minStep = s; G4cout<<"F04GlobalField::SetMinStep: minStep set to "<<minStep/mm<<" mm."<<G4endl; }
|
||||
|
||||
/// Set the delta chord length
|
||||
void SetDeltaChord(G4double s) { deltaChord = s; }
|
||||
|
||||
/// Set the delta one step length
|
||||
void SetDeltaOneStep(G4double s) { deltaOneStep = s; }
|
||||
|
||||
/// Set the delta intersection length
|
||||
void SetDeltaIntersection(G4double s) { deltaIntersection = s; }
|
||||
|
||||
/// Set the minimum eps length
|
||||
void SetEpsMin(G4double s) { epsMin = s; }
|
||||
|
||||
/// Set the maximum eps length
|
||||
void SetEpsMax(G4double s) { epsMax = s; }
|
||||
|
||||
/// Return the list of Element Fields
|
||||
FieldList* getFields() { return fields; }
|
||||
|
||||
// G4bool DoesAnyFieldValueNeedsToBeChanged(G4int eventNumber) {return globalChangeFieldInStepsMap[eventNumber];}
|
||||
void CheckWhetherAnyNominalFieldValueNeedsToBeChanged(G4int eventNumber);
|
||||
|
||||
// Add point, at which user wishes to print out the field value
|
||||
void AddPointForFieldTesting(G4ThreeVector point) {pointsAtWhichUserWantsToPrintFieldValue.push_back(point);}
|
||||
|
||||
// Print field value at all points user wished to be print out:
|
||||
void PrintFieldAtRequestedPoints() const;
|
||||
|
||||
protected:
|
||||
|
||||
/// Get the global field manager
|
||||
G4FieldManager* GetGlobalFieldManager();
|
||||
|
||||
private:
|
||||
|
||||
static F04GlobalField* object;
|
||||
|
||||
G4int nfp;
|
||||
G4bool first;
|
||||
|
||||
FieldList* fields;
|
||||
|
||||
const F04ElementField **fp;
|
||||
|
||||
std::vector<G4ThreeVector> pointsAtWhichUserWantsToPrintFieldValue;
|
||||
|
||||
private:
|
||||
|
||||
G4int fStepperType;
|
||||
|
||||
G4double minStep;
|
||||
G4double deltaChord;
|
||||
G4double deltaOneStep;
|
||||
G4double deltaIntersection;
|
||||
G4double epsMin;
|
||||
G4double epsMax;
|
||||
|
||||
// G4Mag_EqRhs* fEquation;
|
||||
// G4Mag_SpinEqRhs* fEquation;
|
||||
// G4EqMagElectricField* fEquation;
|
||||
G4EqEMFieldWithSpin* fEquation;
|
||||
|
||||
G4FieldManager* fFieldManager;
|
||||
G4PropagatorInField* fFieldPropagator;
|
||||
G4MagIntegratorStepper* fStepper;
|
||||
G4ChordFinder* fChordFinder;
|
||||
|
||||
F04FieldMessenger* fFieldMessenger;
|
||||
|
||||
std::map<G4int,G4bool> globalChangeFieldInStepsMap;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
71
include/MuDecayChannel.hh
Normal file
71
include/MuDecayChannel.hh
Normal file
@ -0,0 +1,71 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4MuonDecayChannel.hh,v 1.6 2006/06/29 19:23:35 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-00 $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
// History: first implementation, based on object model of
|
||||
// 30 May 1997 H.Kurashige
|
||||
// ------------------------------------------------------------
|
||||
#ifndef MuDecayChannel_h
|
||||
#define MuDecayChannel_h 1
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4VDecayChannel.hh"
|
||||
|
||||
class MuDecayChannel :public G4VDecayChannel
|
||||
{
|
||||
// Class Decription
|
||||
// This class describes muon decay kinemtics.
|
||||
// This version neglects muon polarization
|
||||
// assumes the pure V-A coupling
|
||||
// gives incorrect energy spectrum for neutrinos
|
||||
//
|
||||
|
||||
public: // With Description
|
||||
//Constructors
|
||||
MuDecayChannel(const G4String& theParentName,
|
||||
G4double theBR);
|
||||
// Destructor
|
||||
virtual ~MuDecayChannel();
|
||||
|
||||
public: // With Description
|
||||
virtual G4DecayProducts *DecayIt(G4double);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
130
include/MuDecayChannelWithSpin.hh
Normal file
130
include/MuDecayChannelWithSpin.hh
Normal file
@ -0,0 +1,130 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
// History:
|
||||
// 17 August 2004 P.Gumplinger and T.MacPhail
|
||||
// samples Michel spectrum including 1st order
|
||||
// radiative corrections
|
||||
// Reference: Florian Scheck "Muon Physics", in Physics Reports
|
||||
// (Review Section of Physics Letters) 44, No. 4 (1978)
|
||||
// 187-248. North-Holland Publishing Company, Amsterdam
|
||||
// at page 210 cc.
|
||||
//
|
||||
// W.E. Fisher and F. Scheck, Nucl. Phys. B83 (1974) 25.
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
#ifndef MuDecayChannelWithSpin_hh
|
||||
#define MuDecayChannelWithSpin_hh 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "MuDecayChannel.hh"
|
||||
|
||||
class MuDecayChannelWithSpin : public MuDecayChannel
|
||||
{
|
||||
// Class Decription
|
||||
// This class describes muon decay kinemtics.
|
||||
// This version assumes V-A coupling with 1st order radiative correctons,
|
||||
// the standard model Michel parameter values, but
|
||||
// gives incorrect energy spectrum for neutrinos
|
||||
|
||||
public: // With Description
|
||||
|
||||
//Constructors
|
||||
MuDecayChannelWithSpin(const G4String& theParentName,
|
||||
G4double theBR);
|
||||
// Destructor
|
||||
virtual ~MuDecayChannelWithSpin();
|
||||
|
||||
public: // With Description
|
||||
|
||||
virtual G4DecayProducts *DecayIt(G4double);
|
||||
|
||||
void SetPolarization(G4ThreeVector);
|
||||
const G4ThreeVector& GetPolarization() const;
|
||||
|
||||
private:
|
||||
|
||||
G4ThreeVector parent_polarization;
|
||||
|
||||
// Radiative Correction Factors
|
||||
|
||||
G4double F_c(G4double x, G4double x0);
|
||||
G4double F_theta(G4double x, G4double x0);
|
||||
G4double R_c(G4double x);
|
||||
|
||||
G4double EMMU;
|
||||
G4double EMASS;
|
||||
|
||||
};
|
||||
|
||||
inline void MuDecayChannelWithSpin::SetPolarization(G4ThreeVector polar)
|
||||
{
|
||||
parent_polarization = polar;
|
||||
}
|
||||
|
||||
inline const G4ThreeVector& MuDecayChannelWithSpin::GetPolarization() const
|
||||
{
|
||||
return parent_polarization;
|
||||
}
|
||||
|
||||
inline G4double MuDecayChannelWithSpin::F_c(G4double x, G4double x0)
|
||||
{
|
||||
G4double omega = std::log(EMMU/EMASS);
|
||||
|
||||
G4double f_c;
|
||||
|
||||
f_c = (5.+17.*x-34.*x*x)*(omega+std::log(x))-22.*x+34.*x*x;
|
||||
f_c = (1.-x)/(3.*x*x)*f_c;
|
||||
f_c = (6.-4.*x)*R_c(x)+(6.-6.*x)*std::log(x) + f_c;
|
||||
f_c = (fine_structure_const/twopi) * (x*x-x0*x0) * f_c;
|
||||
|
||||
return f_c;
|
||||
}
|
||||
|
||||
inline G4double MuDecayChannelWithSpin::F_theta(G4double x, G4double x0)
|
||||
{
|
||||
G4double omega = std::log(EMMU/EMASS);
|
||||
|
||||
G4double f_theta;
|
||||
|
||||
f_theta = (1.+x+34*x*x)*(omega+std::log(x))+3.-7.*x-32.*x*x;
|
||||
f_theta = f_theta + ((4.*(1.-x)*(1.-x))/x)*std::log(1.-x);
|
||||
f_theta = (1.-x)/(3.*x*x) * f_theta;
|
||||
f_theta = (2.-4.*x)*R_c(x)+(2.-6.*x)*std::log(x)-f_theta;
|
||||
f_theta = (fine_structure_const/twopi) * (x*x-x0*x0) * f_theta;
|
||||
|
||||
return f_theta;
|
||||
}
|
||||
|
||||
#endif
|
70
include/meyer.hh
Normal file
70
include/meyer.hh
Normal file
@ -0,0 +1,70 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//*
|
||||
// LOW ENERGY MUON SPIN RELAXATION, ROTATION, RADIATION Geant4 SIMULATION
|
||||
// ID : MEYER.hh , v 1.0
|
||||
// AUTHOR: Taofiq PARAISO
|
||||
// DATE : 2005-04
|
||||
//
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
|
||||
//
|
||||
// & &&&&&&&&&& &&&&&&& &&&&&&&&
|
||||
// & & && && & &&
|
||||
// & & & & & & &&
|
||||
// & &&&&&&& & & &&&&&& &&&&&&&&
|
||||
// & & & && & & &&
|
||||
// & & && & & && && & &
|
||||
// &&&&&&&&&& &&&&&&&&&& & &&&&& && &&&&&&& & &&
|
||||
// &
|
||||
// &
|
||||
// &
|
||||
// &
|
||||
// MEYER
|
||||
/*
|
||||
fIRST IMPLEMENTATION BY ANLSEM,H. IN FORTRAN
|
||||
C++ CONVERSION T.K.PARAISO 04-2005
|
||||
|
||||
!!! IMPORTANT !!!
|
||||
|
||||
Notice:
|
||||
Tables definition changes between FORTRAN and C++:
|
||||
1/ Fortran indices start at 1 and C++ indices start at 0
|
||||
2/ Tables are defined as table[column][row] in Fortran
|
||||
table[row][column] in c++
|
||||
|
||||
usefull reference
|
||||
http://gershwin.ens.fr/vdaniel/Doc-Locale/Langages-Program-Scientific/Fortran/Tutorial/arrays.htm
|
||||
|
||||
*/
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
|
||||
|
||||
|
||||
#ifndef meyer_h
|
||||
#define meyer_h 1
|
||||
|
||||
#include <iomanip>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include "globals.hh"
|
||||
|
||||
class meyer
|
||||
{
|
||||
public:
|
||||
meyer();
|
||||
~meyer();
|
||||
|
||||
void GFunctions(double*, double*, double);
|
||||
void Get_F_Function_Meyer(double tau, double Ekin, double Z1, double Z2, double m1, double m2);
|
||||
void F_Functions_Meyer( double tau,double thetaSchlange,double *f1,double *f2);
|
||||
void Get_F_Function(double tau,double theta, double Ekin, double Z1, double Z2, double m1, double m2, double* F);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
60
include/musrDetectorConstruction.hh
Normal file
60
include/musrDetectorConstruction.hh
Normal file
@ -0,0 +1,60 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrDetectorConstruction_h
|
||||
#define musrDetectorConstruction_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4VUserDetectorConstruction.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4RotationMatrix.hh"
|
||||
#include "G4FieldManager.hh"
|
||||
#include <map>
|
||||
|
||||
class G4Tubs;
|
||||
class G4Box;
|
||||
class G4Cons;
|
||||
class G4Trd;
|
||||
class G4LogicalVolume;
|
||||
class G4VPhysicalVolume;
|
||||
class G4Material;
|
||||
class musrDetectorMessenger;
|
||||
class musrScintSD;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrDetectorConstruction : public G4VUserDetectorConstruction
|
||||
{
|
||||
public:
|
||||
|
||||
musrDetectorConstruction();
|
||||
~musrDetectorConstruction();
|
||||
|
||||
public:
|
||||
|
||||
G4VPhysicalVolume* Construct();
|
||||
|
||||
|
||||
void UpdateGeometry();
|
||||
void SetInputParameterFileName(G4String fileName) {parameterFileName=fileName;};
|
||||
void ReportGeometryProblem(char myString[501]);
|
||||
void ReportProblemInStearingFile(char* myString);
|
||||
G4Material* CharToMaterial(char myString[100]);
|
||||
G4LogicalVolume* FindLogicalVolume(G4String LogicalVolumeName);
|
||||
void SetColourOfLogicalVolume(G4LogicalVolume* pLogVol,char* colour);
|
||||
|
||||
private:
|
||||
G4String parameterFileName; // name of the file with the geometry parameters
|
||||
G4bool checkOverlap; // parameter to check ovelaping volumes
|
||||
G4double largestAcceptableStep; // parameter defining largest step in the magnetic field
|
||||
|
||||
musrScintSD* aScintSD;
|
||||
musrDetectorMessenger* detectorMessenger; // pointer to the Messenger
|
||||
|
||||
std::map<std::string,G4RotationMatrix*> pointerToRotationMatrix;
|
||||
std::map<std::string,G4FieldManager*> pointerToField;
|
||||
|
||||
private:
|
||||
void DefineMaterials();
|
||||
};
|
||||
|
||||
#endif
|
49
include/musrDetectorMessenger.hh
Normal file
49
include/musrDetectorMessenger.hh
Normal file
@ -0,0 +1,49 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrDetectorMessenger_h
|
||||
#define musrDetectorMessenger_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4UImessenger.hh"
|
||||
|
||||
class musrDetectorConstruction;
|
||||
class G4UIdirectory;
|
||||
class G4UIcmdWithAString;
|
||||
class G4UIcmdWithADoubleAndUnit;
|
||||
class G4UIcmdWithAnInteger;
|
||||
class G4UIcmdWithoutParameter;
|
||||
class G4UIcmdWith3Vector;
|
||||
class G4UIcmdWith3VectorAndUnit;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrDetectorMessenger: public G4UImessenger
|
||||
{
|
||||
public:
|
||||
musrDetectorMessenger(musrDetectorConstruction*);
|
||||
~musrDetectorMessenger();
|
||||
|
||||
void SetNewValue(G4UIcommand*, G4String);
|
||||
|
||||
private:
|
||||
musrDetectorConstruction* myDetector;
|
||||
|
||||
G4UIdirectory* musrDir;
|
||||
G4UIdirectory* detDir;
|
||||
G4UIdirectory* runDir;
|
||||
G4UIcmdWithAString* Ignore1Cmd;
|
||||
G4UIcmdWithAString* Ignore2Cmd;
|
||||
G4UIcmdWithAnInteger* RunIDSetCmd;
|
||||
G4UIcmdWithAnInteger* RandomOptionCmd;
|
||||
G4UIcmdWithAnInteger* HowOftenToPrintEventCmd;
|
||||
G4UIcmdWithAnInteger* RndmEventToSaveSeedsCmd;
|
||||
G4UIcmdWithoutParameter* UpdateCmd;
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
||||
|
29
include/musrErrorMessage.hh
Normal file
29
include/musrErrorMessage.hh
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef musrErrorMessage_h
|
||||
#define musrErrorMessage_h 1
|
||||
|
||||
#include <map>
|
||||
#include "globals.hh"
|
||||
enum SEVERITY {INFO, WARNING, SERIOUS, FATAL};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SEVERITY mesSeverity;
|
||||
int nTimes;
|
||||
} ErrorStruct;
|
||||
|
||||
class musrErrorMessage {
|
||||
public:
|
||||
musrErrorMessage();
|
||||
~musrErrorMessage();
|
||||
static musrErrorMessage* GetInstance();
|
||||
void musrError(SEVERITY severity, G4String message, G4bool silent);
|
||||
void PrintErrorSummary();
|
||||
|
||||
private:
|
||||
static musrErrorMessage* pointerToErrors;
|
||||
G4int nErrors;
|
||||
// std::map<G4String,int> ErrorMapping;
|
||||
std::map<G4String,ErrorStruct> ErrorMapping;
|
||||
std::map<SEVERITY,G4String> severityWord;
|
||||
};
|
||||
#endif
|
43
include/musrEventAction.hh
Normal file
43
include/musrEventAction.hh
Normal file
@ -0,0 +1,43 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrEventAction_h
|
||||
#define musrEventAction_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4UserEventAction.hh"
|
||||
class G4Timer;
|
||||
class G4Event;
|
||||
class musrMagneticField;
|
||||
class musrTabulatedField3D;
|
||||
class musrTabulatedField2D;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrEventAction : public G4UserEventAction
|
||||
{
|
||||
public:
|
||||
musrEventAction();
|
||||
~musrEventAction();
|
||||
|
||||
public:
|
||||
void BeginOfEventAction(const G4Event*);
|
||||
void EndOfEventAction(const G4Event*);
|
||||
static musrEventAction* GetInstance();
|
||||
|
||||
private:
|
||||
// pointer to this class
|
||||
static musrEventAction* pointer;
|
||||
//
|
||||
G4Timer* timer;
|
||||
// Variables for the time-dependent magnetic field
|
||||
G4bool timeDependentField;
|
||||
time_t timeOfRunStart;
|
||||
|
||||
public:
|
||||
static G4int nHowOftenToPrintEvent;
|
||||
static G4double maximumRunTimeAllowed;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
80
include/musrMuFormation.hh
Normal file
80
include/musrMuFormation.hh
Normal file
@ -0,0 +1,80 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
// Muonium Formation according to yield.cc function (through GetYields method).
|
||||
// Id : musrMuFormation.hh, v 1.4
|
||||
// Author: Taofiq PARAISO, T. Shiroka
|
||||
// Date : 2007-12
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
|
||||
#ifndef musrMuFormation_h
|
||||
#define musrMuFormation_h 1
|
||||
|
||||
#include "G4VDiscreteProcess.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
|
||||
#include "yields.hh"
|
||||
|
||||
/*! musrMuFormation class defines the muonium formation process in the Carbon foil
|
||||
* according to yields from Gonin's paper Sci. Rev. Instrum. 65(3), 648-652 (1994).
|
||||
* \image html yields3.gif The muonium formation yields.
|
||||
* The main parameters are the foil thickness and muon energy. For a given energy,
|
||||
* a corresponding proportion of the muons will be converted into Muonium.
|
||||
* Concretely, the muon is eliminated and replaced by a Muonium with identical
|
||||
* properties, including time, energy, momentum, position etc.
|
||||
*
|
||||
* The process is executed at the END of a step, i.e. the muon is converted into
|
||||
* Muonium AFTER flying through the Carbon foil (see also yields.hh). */
|
||||
|
||||
class musrMuFormation : public G4VDiscreteProcess
|
||||
{
|
||||
public:
|
||||
|
||||
musrMuFormation(const G4String& name = "MuFormation", // process description
|
||||
G4ProcessType aType = fElectromagnetic);
|
||||
|
||||
~musrMuFormation();
|
||||
|
||||
//! - Main method. Muonium formation process is executed at the END of a step. */
|
||||
G4VParticleChange* PostStepDoIt(
|
||||
const G4Track&,
|
||||
const G4Step&);
|
||||
|
||||
G4double GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition);
|
||||
|
||||
|
||||
//! Condition for process application (step Object).
|
||||
G4bool CheckCondition(const G4Step& aStep);
|
||||
|
||||
//! Condition for process application (step Pointer).
|
||||
G4bool CheckCondition(const G4Step* aStep);
|
||||
|
||||
|
||||
G4String p_name;
|
||||
G4bool condition;
|
||||
|
||||
|
||||
void GetDatas( const G4Step* aStep);
|
||||
// model parameters
|
||||
G4ParticleTable* particleTable;
|
||||
G4ParticleDefinition* particle;
|
||||
Yields Gonin;
|
||||
G4double yvector[3];
|
||||
G4double rnd;
|
||||
G4DynamicParticle *DP;
|
||||
|
||||
//! The particle change object.
|
||||
G4VParticleChange fParticleChange;
|
||||
|
||||
void PrepareSecondary(const G4Track&);
|
||||
G4Track* aSecondary;
|
||||
|
||||
void InitializeSecondaries(const G4Track&);
|
||||
};
|
||||
|
||||
#endif
|
57
include/musrMuScatter.hh
Normal file
57
include/musrMuScatter.hh
Normal file
@ -0,0 +1,57 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
// Muonium "Scattering"
|
||||
// Id : musrMuScatter.hh, v 1.4
|
||||
// Author: Taofiq PARAISO, T. Shiroka
|
||||
// Date : 2007-12
|
||||
// Notes : Simplified model for Mu scattering. Spin effects have been excluded.
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
|
||||
/*!
|
||||
* musrMuScatter class defines the Muonium scattering process. It implements a very
|
||||
* basic model which assumes Muonium looses its electron as soon as it enters any
|
||||
* material (except for vacuum and CFoil). The class has only a PostStepDoIt method.
|
||||
* The in-flight Muonium spin precession has been supressed. */
|
||||
|
||||
#ifndef musrMuScatter_h
|
||||
#define musrMuScatter_h 1
|
||||
|
||||
#include "G4VDiscreteProcess.hh"
|
||||
|
||||
class musrMuScatter : public G4VDiscreteProcess
|
||||
{
|
||||
public:
|
||||
musrMuScatter(const G4String& name="MuScatt", // process description
|
||||
G4ProcessType aType = fGeneral);
|
||||
|
||||
~musrMuScatter();
|
||||
|
||||
//! \mm The actions are taken at the end of the step.
|
||||
G4VParticleChange* PostStepDoIt(const G4Track&,
|
||||
const G4Step&);
|
||||
|
||||
G4double GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition);
|
||||
|
||||
//! The condition for applying the process.
|
||||
G4bool CheckCondition(const G4Step& aStep);
|
||||
|
||||
|
||||
G4bool condition;
|
||||
G4double itime, gtime, ftime,deltatime;
|
||||
G4String p_name;
|
||||
G4DynamicParticle *DP;
|
||||
G4ParticleChange fParticleChange;
|
||||
|
||||
void PrepareSecondary(const G4Track&);
|
||||
G4Track* aSecondary;
|
||||
|
||||
void InitializeSecondaries(const G4Track&);
|
||||
};
|
||||
|
||||
#endif
|
77
include/musrMuonium.hh
Normal file
77
include/musrMuonium.hh
Normal file
@ -0,0 +1,77 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: musrMuonium.hh,v 1.10 2006/06/29 19:20:21 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-00 $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
// History: first implementation, based on object model of
|
||||
// 4-th April 1996, G.Cosmo
|
||||
// ****************************************************************
|
||||
// New implementation as a utility class M.Asai, 26 July 2004
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
#ifndef musrMuonium_h
|
||||
#define musrMuonium_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
// ######################################################################
|
||||
// ### MUONIUM ###
|
||||
// ######################################################################
|
||||
|
||||
class musrMuonium : public G4ParticleDefinition
|
||||
{
|
||||
private:
|
||||
static musrMuonium* theInstance;
|
||||
musrMuonium(){}
|
||||
~musrMuonium(){}
|
||||
|
||||
public:
|
||||
static musrMuonium* Definition();
|
||||
static musrMuonium* MuoniumDefinition();
|
||||
static musrMuonium* Muonium();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
44
include/musrParameters.hh
Normal file
44
include/musrParameters.hh
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef musrParameters_h
|
||||
#define musrParameters_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
class musrParameters {
|
||||
public:
|
||||
musrParameters(G4String steeringFileName);
|
||||
~musrParameters();
|
||||
|
||||
static musrParameters* GetInstance();
|
||||
|
||||
static G4String mySteeringFileName; // name of the steering file (e.g. the *.mac file)
|
||||
static G4bool storeOnlyEventsWithHits; // variable specifying whether to store interesting
|
||||
// or all events into the ROOT tree. (default = true)
|
||||
static G4int storeOnlyEventsWithHitInDetID; // simillar to "storeOnlyEventsWithHits". The event is stored
|
||||
// only and only if there was a hit in the detector with the ID
|
||||
// equal to storeOnlyEventsWithHitInDetID.
|
||||
// The storeOnlyEventsWithHitInDetID has to be non zero.
|
||||
static G4double signalSeparationTime; // minimim time separation between two subsequent signal
|
||||
static G4bool storeOnlyTheFirstTimeHit; // if true, only the hit that happened first will be
|
||||
// stored, anything else will be ignored
|
||||
// (usefull for some special studies, not for a serious simulation)
|
||||
static G4bool killAllPositrons; // if true, all positron tracks will be deleted (usefull for the studies of the muon beam)
|
||||
static G4bool killAllGammas; //
|
||||
static G4bool killAllNeutrinos; //
|
||||
//cks static G4bool includeMuoniumProcesses; // If true, includes Muonium formation and all
|
||||
//cks // other Mu-related processes in the simulation
|
||||
static G4bool boolG4GeneralParticleSource; // if true, G4GeneralParticleSource will be initialised instead of G4ParticleGun
|
||||
// - needed for the radioactive source
|
||||
static G4bool boolG4OpticalPhotons; // if true, optical photons will be used (in the sensitive scintillators)
|
||||
static G4bool field_DecayWithSpin; // if true, then the routins for calculating the magnetic field will
|
||||
// use more precise argument. This variable is set to "true" by
|
||||
// the SteppinAction and reset to "false" in the GetFieldValue.
|
||||
// It is being changed on step by step basis.
|
||||
static G4int nrOfEventsToBeGenerated; // Nr of events to be simulated in this run (set by /run/beamOn command)
|
||||
private:
|
||||
static musrParameters* pointerToParameters;
|
||||
G4bool boolG4RegionRequested; // variable used internally just to check that no new volume is defined after
|
||||
// a G4Region has been requested - perhaps unnecessary check, but just to be on the safe side
|
||||
|
||||
};
|
||||
|
||||
#endif
|
52
include/musrPhysicsList.hh
Normal file
52
include/musrPhysicsList.hh
Normal file
@ -0,0 +1,52 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrPhysicsList_h
|
||||
#define musrPhysicsList_h 1
|
||||
|
||||
#include "G4VUserPhysicsList.hh"
|
||||
#include "globals.hh"
|
||||
//cks Added to have Geant default muon decay with spin
|
||||
#include "G4DecayWithSpin.hh"
|
||||
//#include "musrDecayWithSpin.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrPhysicsList: public G4VUserPhysicsList
|
||||
{
|
||||
public:
|
||||
musrPhysicsList();
|
||||
~musrPhysicsList();
|
||||
|
||||
protected:
|
||||
// Construct particle and physics
|
||||
void ConstructParticle();
|
||||
void ConstructProcess();
|
||||
|
||||
void SetCuts();
|
||||
|
||||
|
||||
protected:
|
||||
// these methods Construct particles
|
||||
void ConstructBosons();
|
||||
void ConstructLeptons();
|
||||
void ConstructMesons();
|
||||
void ConstructBaryons();
|
||||
|
||||
protected:
|
||||
// these methods Construct physics processes and register them
|
||||
void ConstructGeneral();
|
||||
void ConstructEM();
|
||||
|
||||
private:
|
||||
// char myProcesses[100];
|
||||
// G4String parameterFileName; // name of the file with the physics list defined
|
||||
void ReportProblemWithProcessDefinition(char myString[501]);
|
||||
G4Region* FindG4Region(G4String regionName, char* lineOfSteeringFile);
|
||||
char eMessage[200];
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
||||
|
||||
|
108
include/musrPrimaryGeneratorAction.hh
Normal file
108
include/musrPrimaryGeneratorAction.hh
Normal file
@ -0,0 +1,108 @@
|
||||
|
||||
#ifndef musrPrimaryGeneratorAction_h
|
||||
#define musrPrimaryGeneratorAction_h 1
|
||||
|
||||
#include "G4VUserPrimaryGeneratorAction.hh"
|
||||
#include "globals.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
class G4GeneralParticleSource;
|
||||
class G4ParticleGun;
|
||||
class G4Event;
|
||||
class musrDetectorConstruction;
|
||||
class musrPrimaryGeneratorMessenger;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
class musrPrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
|
||||
{
|
||||
public:
|
||||
musrPrimaryGeneratorAction(musrDetectorConstruction*);
|
||||
~musrPrimaryGeneratorAction();
|
||||
|
||||
public:
|
||||
void GeneratePrimaries(G4Event*);
|
||||
void SetRndmFlag(G4String val) { rndmFlag = val;}
|
||||
void Setvertex(G4ThreeVector v) {x0=v[0]; y0=v[1]; z0=v[2];}
|
||||
void SetvertexSigma(G4ThreeVector v) {xSigma=v[0]; ySigma=v[1]; zSigma=v[2];}
|
||||
void SetvertexBoundary(G4ThreeVector v) {rMaxAllowed=v[0]; zMinAllowed=v[1]; zMaxAllowed=v[2];}
|
||||
void SetKEnergy(G4double val);
|
||||
void SetMomentum(G4double val) {p0=val;}
|
||||
void SetMomentumSmearing(G4double val) {pSigma=val;}
|
||||
void SetMomentumBoundary(G4ThreeVector v){pMinAllowed=v[0]; pMaxAllowed=v[1];}
|
||||
void SetTilt(G4ThreeVector v) {xangle0=v[0]; yangle0=v[1];}
|
||||
void SetSigmaTilt(G4ThreeVector v) {xangleSigma=v[0]; yangleSigma=v[1];}
|
||||
void SetPitch(G4double val) {pitch=val;}
|
||||
void SetInitialMuonPolariz(G4ThreeVector vIniPol);
|
||||
void SetInitialPolarizFraction(G4double val) {
|
||||
if ((val>1.)||(val<-1.)) {
|
||||
G4cout<<"musrPrimaryGeneratorAction.hh: SetInitialPolarizFraction(): polarisation fraction out of range ("<<val<<")"<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
polarisFraction=val;
|
||||
}
|
||||
void SetMuonDecayTimeLimits(G4ThreeVector decayTimeLimits);
|
||||
void SetTurtleInput(G4String turtleFileName);
|
||||
void SetTurtleInputFileToEventNo(G4int lineNumberOfTurtleFile);
|
||||
void SetTurtleZ0(G4double val) {z0_InitialTurtle=val;}
|
||||
void SetOrReadTheRandomNumberSeeds(G4int eventID);
|
||||
void SetTurtleMomentumBite (G4ThreeVector smearingParam)
|
||||
{turtleMomentumBite=true; turtleMomentumP0=smearingParam[0]*MeV; turtleSmearingFactor=smearingParam[1]*0.01;}
|
||||
|
||||
static G4String GetPrimaryName();
|
||||
|
||||
private:
|
||||
G4ParticleGun* particleGun; // pointer a to G4 service class
|
||||
G4GeneralParticleSource* particleSource; // pointer to the G4GeneralParticleSource, needed for radioactive samples
|
||||
musrDetectorConstruction* musrDetector; // pointer to the geometry
|
||||
|
||||
musrPrimaryGeneratorMessenger* gunMessenger; // messenger of this class
|
||||
G4String rndmFlag; // flag for a random impact point
|
||||
|
||||
// cks Implement also alpha and proton particles for the simulation of Juan Pablo Urrego
|
||||
G4ParticleDefinition* alphaParticle;
|
||||
G4ParticleDefinition* protonParticle;
|
||||
// csk
|
||||
|
||||
static G4String thePrimaryParticleName ;
|
||||
|
||||
G4double x0, y0, z0, xSigma, ySigma, zSigma, rMaxAllowed, zMinAllowed, zMaxAllowed;
|
||||
G4double p0, pSigma, pMinAllowed, pMaxAllowed;
|
||||
G4double xangle0, yangle0, xangleSigma, yangleSigma, pitch;
|
||||
G4bool UnpolarisedMuonBeam, TransversalyUnpolarisedMuonBeam;
|
||||
G4double xPolarisIni, yPolarisIni, zPolarisIni;
|
||||
G4double polarisFraction;
|
||||
G4double muonDecayTimeMin;
|
||||
G4double muonDecayTimeMax;
|
||||
G4double muonMeanLife;
|
||||
// For the Turtle input:
|
||||
FILE* fTurtleFile;
|
||||
G4bool takeMuonsFromTurtleFile;
|
||||
G4double z0_InitialTurtle; // z0 at whith the turtle file was generated.
|
||||
G4int numberOfGeneratedEvents; // number of generated events at the input (e.g. including Turtle events out of the beampipe)
|
||||
G4bool boolPrintInfoAboutGeneratedParticles;
|
||||
G4bool turtleMomentumBite;
|
||||
G4double turtleMomentumP0;
|
||||
G4double turtleSmearingFactor;
|
||||
|
||||
public:
|
||||
static G4bool setRandomNrSeedAccordingEventNr;
|
||||
static G4bool setRandomNrSeedFromFile;
|
||||
static G4bool setRandomNrSeedFromFile_RNDM;
|
||||
static G4int nRndmEventToSaveSeeds;
|
||||
static std::vector<int> * GetPointerToSeedVector();
|
||||
|
||||
G4double decaytime;
|
||||
|
||||
private:
|
||||
static std::vector<int> * pointerToSeedVector;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
46
include/musrPrimaryGeneratorMessenger.hh
Normal file
46
include/musrPrimaryGeneratorMessenger.hh
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef musrPrimaryGeneratorMessenger_h
|
||||
#define musrPrimaryGeneratorMessenger_h 1
|
||||
|
||||
#include "G4UImessenger.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
class musrPrimaryGeneratorAction;
|
||||
class G4UIcmdWithAString;
|
||||
class G4UIcmdWithADoubleAndUnit;
|
||||
class G4UIcmdWithADouble;
|
||||
class G4UIcmdWithAnInteger;
|
||||
class G4UIcmdWith3VectorAndUnit;
|
||||
class G4UIcmdWith3Vector;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
class musrPrimaryGeneratorMessenger: public G4UImessenger
|
||||
{
|
||||
public:
|
||||
musrPrimaryGeneratorMessenger(musrPrimaryGeneratorAction*);
|
||||
~musrPrimaryGeneratorMessenger();
|
||||
|
||||
void SetNewValue(G4UIcommand*, G4String);
|
||||
|
||||
private:
|
||||
musrPrimaryGeneratorAction* musrAction;
|
||||
G4UIcmdWith3VectorAndUnit* setvertexCmd;
|
||||
G4UIcmdWith3VectorAndUnit* setvertexSigmaCmd;
|
||||
G4UIcmdWith3VectorAndUnit* setvertexBoundaryCmd;
|
||||
G4UIcmdWithADoubleAndUnit* setKEnergyCmd;
|
||||
G4UIcmdWithADoubleAndUnit* setMomentumCmd;
|
||||
G4UIcmdWithADoubleAndUnit* setMomentumSmearingCmd;
|
||||
G4UIcmdWith3VectorAndUnit* setMomentumBoundaryCmd;
|
||||
G4UIcmdWith3VectorAndUnit* setTiltAngleCmd;
|
||||
G4UIcmdWith3VectorAndUnit* setSigmaTiltAngleCmd;
|
||||
G4UIcmdWithADoubleAndUnit* setPitchCmd;
|
||||
G4UIcmdWith3Vector* setMuonPolarizCmd;
|
||||
G4UIcmdWithADouble* setMuonPolarizFractionCmd;
|
||||
G4UIcmdWith3VectorAndUnit* setMuonDecayTimeCmd;
|
||||
G4UIcmdWithAString* setTurtleCmd;
|
||||
G4UIcmdWithADoubleAndUnit* setTurtleZ0Cmd;
|
||||
G4UIcmdWith3Vector* setTurtleMomentumBite;
|
||||
G4UIcmdWithAnInteger* setTurtleEventNrCmd;
|
||||
};
|
||||
#endif
|
||||
|
49
include/musrQuadrupole.hh
Normal file
49
include/musrQuadrupole.hh
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef musrQuadrupole_h
|
||||
#define musrQuadrupole_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "F04ElementField.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
//#include "G4ios.hh"
|
||||
#include "BLEngeFunction.hh"
|
||||
//#include <fstream>
|
||||
//#include <vector>
|
||||
//#include <cmath>
|
||||
const G4double FRINGE_ACCURACY=1.0e-4;
|
||||
|
||||
class musrQuadrupole : public F04ElementField
|
||||
{
|
||||
public:
|
||||
musrQuadrupole(G4double halflengthVal, G4double fieldRadiusVal, G4double gradientVal, G4double fringeFactorVal, G4LogicalVolume* logVolume, G4ThreeVector positionOfTheCenter);
|
||||
// musrQuadrupole is based on "BLCMDgenericquad" class of the G4beamline package.
|
||||
//
|
||||
|
||||
/// Destructor.
|
||||
virtual ~musrQuadrupole() {}
|
||||
|
||||
/// addFieldValue() adds the field for this solenoid into field[].
|
||||
/// point[] is in global coordinates.
|
||||
void addFieldValue( const G4double Point[4], G4double* field) const;
|
||||
|
||||
G4double GetNominalFieldValue();
|
||||
void SetNominalFieldValue(G4double newFieldValue);
|
||||
|
||||
// getWidth(), getHeight(), getLength(), return the dimensions of the field
|
||||
// (used to define the boundary of the field)
|
||||
virtual G4double getWidth() { return 2*fieldRadius; } // x coordinate
|
||||
virtual G4double getHeight() { return 2*fieldRadius; } // y coordinate
|
||||
virtual G4double getLength() { return 2*fringeMaxZ; } //{ return 2*halflength; } // z coordinate
|
||||
|
||||
|
||||
private:
|
||||
G4double gradient;
|
||||
G4double fieldRadius;
|
||||
G4double halflength;
|
||||
|
||||
G4double fringeMaxZ;
|
||||
G4double fringeDepth;
|
||||
|
||||
BLEngeFunction enge;
|
||||
};
|
||||
|
||||
#endif
|
291
include/musrRootOutput.hh
Normal file
291
include/musrRootOutput.hh
Normal file
@ -0,0 +1,291 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrRootOutput_h
|
||||
#define musrRootOutput_h 1
|
||||
|
||||
//#include "G4UserRunAction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
// ROOT
|
||||
#include "TFile.h"
|
||||
#include "TTree.h"
|
||||
#include "TH1.h"
|
||||
#include "TH2.h"
|
||||
#include "TVectorD.h"
|
||||
//
|
||||
#include <map>
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrRootOutput {
|
||||
public:
|
||||
musrRootOutput();
|
||||
~musrRootOutput();
|
||||
static musrRootOutput* GetRootInstance();
|
||||
|
||||
public:
|
||||
void BeginOfRunAction();
|
||||
void EndOfRunAction();
|
||||
void FillEvent();
|
||||
void ClearAllRootVariables();
|
||||
void SetVolumeIDMapping(std::string logivol, int volumeID);
|
||||
G4int ConvertVolumeToID(std::string logivol);
|
||||
G4int ConvertProcessToID(std::string processName);
|
||||
void SetSpecialSaveVolumeDefined() {boolIsAnySpecialSaveVolumeDefined=true;};
|
||||
|
||||
// Getting variables (just for debugging)
|
||||
G4double GetDecayPositionZ() {return muDecayPosZ_t;};
|
||||
G4double GetDecayTime() {return muDecayTime_t*microsecond;};
|
||||
G4double GetTimeInTarget() {return muTargetTime_t*microsecond;};
|
||||
|
||||
// Setting variables common to the whole event:
|
||||
void SetRunID (G4int id) {runID_t = id;};
|
||||
void SetEventID (G4int id) {eventID_t = id;};
|
||||
void SetDecayDetectorID (std::string detectorName) {muDecayDetID_t = SensDetectorMapping[detectorName];};
|
||||
void SetBField (G4double F[6]) {B_t[0]=F[0]/tesla; B_t[1]=F[1]/tesla; B_t[2]=F[2]/tesla;
|
||||
B_t[3]=F[3]/tesla; B_t[4]=F[4]/tesla; B_t[5]=F[5]/tesla;};
|
||||
void SetDecayPolarisation (G4ThreeVector pol) {muDecayPolX_t=pol.x(); muDecayPolY_t=pol.y(); muDecayPolZ_t=pol.z();};
|
||||
void SetDecayPosition (G4ThreeVector pos) {muDecayPosX_t=pos.x()/mm; muDecayPosY_t=pos.y()/mm;
|
||||
muDecayPosZ_t=pos.z()/mm;};
|
||||
void SetEventWeight (G4double w) {weight_t *= w;}
|
||||
void SetDetectorInfo (G4int nDetectors, G4int ID, G4int particleID, G4double edep,
|
||||
G4double edep_el, G4double edep_pos,
|
||||
G4double edep_gam, G4double edep_mup,G4int nsteps, G4double length, G4double t1,
|
||||
G4double t2, G4double x, G4double y, G4double z,
|
||||
G4double ek, G4double ekVertex, G4double xVertex, G4double yVertex, G4double zVertex,
|
||||
G4int idVolVertex, G4int idProcVertex, G4int idTrackVertex) ;
|
||||
|
||||
void SetDetectorInfoVvv (G4int nDetectors,
|
||||
G4double ekVertex, G4double xVertex, G4double yVertex, G4double zVertex,
|
||||
G4int idVolVertex, G4int idProcVertex, G4int idTrackVertex, G4int particleID) ;
|
||||
|
||||
void SetSaveDetectorInfo (G4int ID, G4int particleID, G4double ke, G4double x, G4double y, G4double z,
|
||||
G4double px, G4double py, G4double pz) ;
|
||||
|
||||
void SetInitialMuonParameters(G4double x, G4double y, G4double z, G4double px, G4double py, G4double pz,
|
||||
G4double xpolaris, G4double ypolaris, G4double zpolaris) {
|
||||
muIniPosX_t=x; muIniPosY_t=y; muIniPosZ_t=z;
|
||||
muIniMomX_t=px; muIniMomY_t=py; muIniMomZ_t=pz;
|
||||
muIniPolX_t=xpolaris; muIniPolY_t=ypolaris; muIniPolZ_t=zpolaris;
|
||||
}
|
||||
void PrintInitialMuonParameters() {
|
||||
G4cout<<"musrRootOutput.hh: Initial muon parameters: x="<<muIniPosX_t<<", y="<<muIniPosY_t<<", z="<<muIniPosZ_t
|
||||
<<", px="<<muIniMomX_t << ", py="<<muIniMomY_t<<", pz="<<muIniMomZ_t<<G4endl;
|
||||
G4cout<<" polx="<<muIniPolX_t<<", poly="<<muIniPolY_t<<", polz="<<muIniPolZ_t<<G4endl;
|
||||
G4cout<<" numberOfGeneratedEvents = "<<GeantParametersD[7]<<G4endl;
|
||||
}
|
||||
|
||||
void SetPolInTarget(G4ThreeVector pol) {muTargetPolX_t=pol.x(); muTargetPolY_t=pol.y(); muTargetPolZ_t=pol.z();};
|
||||
void SetTimeInTarget(G4double time) {muTargetTime_t = time/microsecond;};
|
||||
void SetPolInM0(G4ThreeVector pol) {muM0PolX_t=pol.x(); muM0PolY_t=pol.y(); muM0PolZ_t=pol.z();};
|
||||
void SetTimeInM0(G4double time) {muM0Time_t = time/microsecond;};
|
||||
void SetPolInM1(G4ThreeVector pol) {muM1PolX_t=pol.x(); muM1PolY_t=pol.y(); muM1PolZ_t=pol.z();};
|
||||
void SetTimeInM1(G4double time) {muM1Time_t = time/microsecond;};
|
||||
void SetPolInM2(G4ThreeVector pol) {muM2PolX_t=pol.x(); muM2PolY_t=pol.y(); muM2PolZ_t=pol.z();};
|
||||
void SetTimeInM2(G4double time) {muM2Time_t = time/microsecond;};
|
||||
void SetInitialPositronMomentum(G4ThreeVector mom) {posIniMomx_t=mom.x(); posIniMomy_t=mom.y(); posIniMomz_t=mom.z();};
|
||||
void SetDecayTime(G4double time) {muDecayTime_t=time/microsecond;};
|
||||
void SetNrFieldNomVal(G4int n) {nFieldNomVal = n;}
|
||||
void SetFieldNomVal(G4int i, G4double value);
|
||||
G4int GetNrOfVolumes() {return det_nMax;}
|
||||
void SetBFieldIntegral(G4double BxInt,G4double ByInt,G4double BzInt,G4double BzInt1,G4double BzInt2,G4double BzInt3) {
|
||||
BxIntegral_t=BxInt/m/tesla; ByIntegral_t=ByInt/m/tesla; BzIntegral_t=BzInt/m/tesla;
|
||||
BzIntegral1_t=BzInt1/m/tesla;BzIntegral2_t=BzInt2/mm;BzIntegral3_t=BzInt3/mm;
|
||||
}
|
||||
void StoreGeantParameter(Int_t i, Double_t value) {
|
||||
if (i<maxNGeantParameters) { GeantParametersD[i]=value; }
|
||||
else {G4cout<<"musrRootOutput.hh::StoreGeantParameter: index="<<i<<" out of range"
|
||||
<<" (maxNGeantParameters=" <<maxNGeantParameters<<")"<<G4endl;}
|
||||
};
|
||||
|
||||
|
||||
TH2F *htest1, *htest2;
|
||||
TH1F *htest3, *htest4, *htest5, *htest6, *htest7, *htest8;
|
||||
|
||||
public:
|
||||
static G4bool store_runID;
|
||||
static G4bool store_eventID;
|
||||
static G4bool store_weight;
|
||||
static G4bool store_BFieldAtDecay;
|
||||
static G4bool store_muIniPosX;
|
||||
static G4bool store_muIniPosY;
|
||||
static G4bool store_muIniPosZ;
|
||||
static G4bool store_muIniMomX;
|
||||
static G4bool store_muIniMomY;
|
||||
static G4bool store_muIniMomZ;
|
||||
static G4bool store_muIniPolX;
|
||||
static G4bool store_muIniPolY;
|
||||
static G4bool store_muIniPolZ;
|
||||
static G4bool store_muDecayDetID;
|
||||
static G4bool store_muDecayPosX;
|
||||
static G4bool store_muDecayPosY;
|
||||
static G4bool store_muDecayPosZ;
|
||||
static G4bool store_muDecayTime;
|
||||
static G4bool store_muDecayPolX;
|
||||
static G4bool store_muDecayPolY;
|
||||
static G4bool store_muDecayPolZ;
|
||||
static G4bool store_muTargetTime;
|
||||
static G4bool store_muTargetPolX;
|
||||
static G4bool store_muTargetPolY;
|
||||
static G4bool store_muTargetPolZ;
|
||||
static G4bool store_muM0Time;
|
||||
static G4bool store_muM0PolX;
|
||||
static G4bool store_muM0PolY;
|
||||
static G4bool store_muM0PolZ;
|
||||
static G4bool store_muM1Time;
|
||||
static G4bool store_muM1PolX;
|
||||
static G4bool store_muM1PolY;
|
||||
static G4bool store_muM1PolZ;
|
||||
static G4bool store_muM2Time;
|
||||
static G4bool store_muM2PolX;
|
||||
static G4bool store_muM2PolY;
|
||||
static G4bool store_muM2PolZ;
|
||||
static G4bool store_posIniMomX;
|
||||
static G4bool store_posIniMomY;
|
||||
static G4bool store_posIniMomZ;
|
||||
static G4bool store_det_ID;
|
||||
static G4bool store_det_edep;
|
||||
static G4bool store_det_edep_el;
|
||||
static G4bool store_det_edep_pos;
|
||||
static G4bool store_det_edep_gam;
|
||||
static G4bool store_det_edep_mup;
|
||||
static G4bool store_det_nsteps;
|
||||
static G4bool store_det_length;
|
||||
static G4bool store_det_start;
|
||||
static G4bool store_det_end;
|
||||
static G4bool store_det_x;
|
||||
static G4bool store_det_y;
|
||||
static G4bool store_det_z;
|
||||
static G4bool store_det_kine;
|
||||
static G4bool store_det_VrtxKine;
|
||||
static G4bool store_det_VrtxX;
|
||||
static G4bool store_det_VrtxY;
|
||||
static G4bool store_det_VrtxZ;
|
||||
static G4bool store_det_VrtxVolID;
|
||||
static G4bool store_det_VrtxProcID;
|
||||
static G4bool store_det_VrtxTrackID;
|
||||
static G4bool store_det_VrtxParticleID;
|
||||
static G4bool store_det_VvvKine;
|
||||
static G4bool store_det_VvvX;
|
||||
static G4bool store_det_VvvY;
|
||||
static G4bool store_det_VvvZ;
|
||||
static G4bool store_det_VvvVolID;
|
||||
static G4bool store_det_VvvProcID;
|
||||
static G4bool store_det_VvvTrackID;
|
||||
static G4bool store_det_VvvParticleID;
|
||||
static G4bool store_fieldNomVal;
|
||||
static G4bool store_fieldIntegralBx;
|
||||
static G4bool store_fieldIntegralBy;
|
||||
static G4bool store_fieldIntegralBz;
|
||||
static G4bool store_fieldIntegralBz1;
|
||||
static G4bool store_fieldIntegralBz2;
|
||||
static G4bool store_fieldIntegralBz3;
|
||||
|
||||
|
||||
static G4int oldEventNumberInG4EqEMFieldWithSpinFunction;
|
||||
|
||||
private:
|
||||
TFile* rootFile;
|
||||
TTree* rootTree;
|
||||
static musrRootOutput* pointerToRoot;
|
||||
static const Int_t maxNGeantParameters=30;
|
||||
Double_t GeantParametersD[maxNGeantParameters]; // parameters transfered from GEANT to Root
|
||||
// 0 ... fieldOption: 0 ... no field, 1 ... uniform, 2 ... gaussian, 3 ... from table
|
||||
// 1 ... fieldValue: intensity of the magnetic field
|
||||
// 2 ... minimum of the generated decay time of the muon (in microsecond)
|
||||
// 3 ... maximum of the generated decay time of the muon (in microsecond)
|
||||
// 4 ... muon mean life time (in microsecond)
|
||||
// 5 ... nr. of the last generated event
|
||||
// 6 ... run number
|
||||
// 7 ... numberOfGeneratedEvents (i.e. number of the generated events;
|
||||
// in case of Turtle nr. of events tried);
|
||||
|
||||
// Variables common to the whole event:
|
||||
Int_t runID_t;
|
||||
Int_t eventID_t;
|
||||
Double_t weight_t;
|
||||
Double_t B_t[6];
|
||||
Double_t muIniPosX_t, muIniPosY_t, muIniPosZ_t;
|
||||
Double_t muIniMomX_t, muIniMomY_t, muIniMomZ_t;
|
||||
Double_t muIniPolX_t, muIniPolY_t, muIniPolZ_t;
|
||||
Int_t muDecayDetID_t;
|
||||
Double_t muDecayPolX_t, muDecayPolY_t, muDecayPolZ_t;
|
||||
Double_t muTargetTime_t, muTargetPolX_t, muTargetPolY_t, muTargetPolZ_t;
|
||||
Double_t muM0Time_t, muM0PolX_t, muM0PolY_t, muM0PolZ_t;
|
||||
Double_t muM1Time_t, muM1PolX_t, muM1PolY_t, muM1PolZ_t;
|
||||
Double_t muM2Time_t, muM2PolX_t, muM2PolY_t, muM2PolZ_t;
|
||||
Double_t muDecayPosX_t, muDecayPosY_t, muDecayPosZ_t;
|
||||
Double_t muDecayTime_t;
|
||||
Double_t posIniMomx_t, posIniMomy_t, posIniMomz_t;
|
||||
|
||||
public:
|
||||
static const Int_t maxNFieldnNominalValues=30;
|
||||
private:
|
||||
Int_t nFieldNomVal;
|
||||
Double_t fieldNomVal[maxNFieldnNominalValues];
|
||||
Double_t BxIntegral_t, ByIntegral_t, BzIntegral_t;
|
||||
Double_t BzIntegral1_t, BzIntegral2_t, BzIntegral3_t;
|
||||
|
||||
// Variables for a particle in a given detector within the event
|
||||
public:
|
||||
static const Int_t maxNSubTracks=30;
|
||||
private:
|
||||
// Variables for the activity inside a given detector
|
||||
public:
|
||||
static const Int_t det_nMax=100; // must be by 1 higher than the real number of detector "hits", because
|
||||
// else the detector nr. 0 is counted (0 is used if no
|
||||
// SensDetectorMapping correspond to a given logical volume).
|
||||
private:
|
||||
G4int det_n;
|
||||
G4int det_ID[det_nMax];
|
||||
G4double det_edep[det_nMax];
|
||||
G4int det_nsteps[det_nMax];
|
||||
G4double det_length[det_nMax];
|
||||
G4double det_edep_el[det_nMax];
|
||||
G4double det_edep_pos[det_nMax];
|
||||
G4double det_edep_gam[det_nMax];
|
||||
G4double det_edep_mup[det_nMax];
|
||||
G4double det_time_start[det_nMax];
|
||||
G4double det_time_end[det_nMax];
|
||||
G4double det_x[det_nMax];
|
||||
G4double det_y[det_nMax];
|
||||
G4double det_z[det_nMax];
|
||||
G4double det_kine[det_nMax];
|
||||
G4double det_VrtxKine[det_nMax];
|
||||
G4double det_VrtxX[det_nMax];
|
||||
G4double det_VrtxY[det_nMax];
|
||||
G4double det_VrtxZ[det_nMax];
|
||||
G4int det_VrtxVolID[det_nMax];
|
||||
G4int det_VrtxProcID[det_nMax];
|
||||
G4int det_VrtxTrackID[det_nMax];
|
||||
G4int det_VrtxParticleID[det_nMax];
|
||||
G4double det_VvvKine[det_nMax];
|
||||
G4double det_VvvX[det_nMax];
|
||||
G4double det_VvvY[det_nMax];
|
||||
G4double det_VvvZ[det_nMax];
|
||||
G4int det_VvvVolID[det_nMax];
|
||||
G4int det_VvvProcID[det_nMax];
|
||||
G4int det_VvvTrackID[det_nMax];
|
||||
G4int det_VvvParticleID[det_nMax];
|
||||
|
||||
public:
|
||||
static const Int_t save_nMax=2000;
|
||||
|
||||
private:
|
||||
G4int save_n;
|
||||
G4int save_detID[save_nMax];
|
||||
G4int save_particleID[save_nMax];
|
||||
G4double save_ke[save_nMax];
|
||||
G4double save_x[save_nMax];
|
||||
G4double save_y[save_nMax];
|
||||
G4double save_z[save_nMax];
|
||||
G4double save_px[save_nMax];
|
||||
G4double save_py[save_nMax];
|
||||
G4double save_pz[save_nMax];
|
||||
|
||||
G4bool boolIsAnySpecialSaveVolumeDefined;
|
||||
|
||||
std::map<std::string,int> SensDetectorMapping;
|
||||
std::map<std::string,int> ProcessIDMapping;
|
||||
};
|
||||
|
||||
#endif
|
36
include/musrRunAction.hh
Normal file
36
include/musrRunAction.hh
Normal file
@ -0,0 +1,36 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrRunAction_h
|
||||
#define musrRunAction_h 1
|
||||
|
||||
#include "G4UserRunAction.hh"
|
||||
#include "globals.hh"
|
||||
#include "musrRootOutput.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class G4Timer;
|
||||
class G4Run;
|
||||
|
||||
class musrRunAction : public G4UserRunAction
|
||||
{
|
||||
public:
|
||||
musrRunAction();
|
||||
~musrRunAction();
|
||||
|
||||
public:
|
||||
void BeginOfRunAction(const G4Run*);
|
||||
void EndOfRunAction(const G4Run*);
|
||||
|
||||
private:
|
||||
G4Timer* timer;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
139
include/musrScintHit.hh
Normal file
139
include/musrScintHit.hh
Normal file
@ -0,0 +1,139 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrScintHit_h
|
||||
#define musrScintHit_h 1
|
||||
|
||||
#include "G4VHit.hh"
|
||||
#include "G4THitsCollection.hh"
|
||||
#include "G4Allocator.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4MagneticField.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
// ROOT
|
||||
#include "TFile.h"
|
||||
#include "TTree.h"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrScintHit : public G4VHit
|
||||
{
|
||||
public:
|
||||
|
||||
musrScintHit();
|
||||
~musrScintHit();
|
||||
musrScintHit(const musrScintHit&);
|
||||
const musrScintHit& operator=(const musrScintHit&);
|
||||
G4int operator==(const musrScintHit&) const;
|
||||
// bool operator() (musrScintHit hit1, musrScintHit hit2) { return (hit1.globalTime<hit2.globalTime);}
|
||||
|
||||
inline void* operator new(size_t);
|
||||
inline void operator delete(void*);
|
||||
|
||||
void Draw();
|
||||
void Print();
|
||||
|
||||
public:
|
||||
|
||||
void SetParticleName (G4String name) {particleName = name; }
|
||||
void SetParticleID (G4int id) {particleID = id; }
|
||||
void SetTrackID (G4int track) { trackID = track; }
|
||||
void SetEdep (G4double de) { edep = de; }
|
||||
void SetPrePos (G4ThreeVector xyz){ pre_pos = xyz; }
|
||||
void SetPostPos (G4ThreeVector xyz){ post_pos = xyz; }
|
||||
void SetPol (G4ThreeVector ijk){pol = ijk;}
|
||||
void SetLogVolName (G4String logivol) {logicalVolume = logivol;}
|
||||
void SetGlobTime (G4double gt) { globalTime = gt;}
|
||||
void SetFirstStepInVolumeFlag (G4bool flag) { firstStepInVolume=flag;}
|
||||
void SetLastStepInVolumeFlag (G4bool flag) { lastStepInVolume=flag;}
|
||||
void SetKineticEnergy (G4double en) { kineticEnergy = en;}
|
||||
void SetStepLength (G4double length) { stepLength = length;}
|
||||
void SetRunID(G4int i) {runID=i;}
|
||||
void SetEventID(G4int i) {eventID=i;}
|
||||
void SetVertexPosition(G4ThreeVector xyz) {vertexPosition = xyz; }
|
||||
void SetVertexKineticEnergy(G4double Ek) {vertexKineticEnergy = Ek; }
|
||||
void SetLogicalVolumeAtVertex(G4String logivol) {logicalVolumeAtVertex = logivol; }
|
||||
void SetCreatorProcessName(G4String name) {creatorProcess = name; }
|
||||
// void SetVerboseLevel (G4int n) { G4int musrScintHit::verboseLevel=n;};
|
||||
|
||||
G4String GetParticleName() {return particleName; }
|
||||
G4int GetParticleID() {return particleID; }
|
||||
G4int GetTrackID() { return trackID; }
|
||||
G4double GetEdep() { return edep; }
|
||||
G4ThreeVector GetPrePos(){ return pre_pos; }
|
||||
G4ThreeVector GetPostPos(){ return post_pos; }
|
||||
G4ThreeVector GetPol(){ return pol; }
|
||||
G4String GetLogVolName() { return logicalVolume; }
|
||||
G4double GetGlobalTime() { return globalTime; }
|
||||
G4bool GetFirstStepInVolumeFlag() {return firstStepInVolume;}
|
||||
G4bool GetLastStepInVolumeFlag() {return lastStepInVolume;}
|
||||
G4double GetKineticEnergy() { return kineticEnergy; }
|
||||
G4double GetStepLength() {return stepLength; }
|
||||
G4double* GetBField () {return BF;}
|
||||
G4int GetRunID() {return runID;}
|
||||
G4int GetEventID() {return eventID;}
|
||||
G4ThreeVector GetVertexPosition() { return vertexPosition; }
|
||||
G4double GetVertexKineticEnergy() { return vertexKineticEnergy; }
|
||||
G4String GetLogicalVolumeAtVertex() { return logicalVolumeAtVertex; }
|
||||
G4String GetCreatorProcessName() { return creatorProcess; }
|
||||
G4double point[4];
|
||||
G4double B[6];
|
||||
const G4Field *mfield;
|
||||
|
||||
private:
|
||||
|
||||
G4String particleName;
|
||||
G4int particleID;
|
||||
G4int trackID;
|
||||
G4double edep;
|
||||
G4ThreeVector pre_pos;
|
||||
G4ThreeVector post_pos;
|
||||
G4ThreeVector pol;
|
||||
G4String logicalVolume;
|
||||
G4double globalTime;
|
||||
G4bool firstStepInVolume;
|
||||
G4bool lastStepInVolume;
|
||||
G4double kineticEnergy;
|
||||
G4double stepLength;
|
||||
G4int eventID;
|
||||
G4int runID;
|
||||
G4double BF[6];
|
||||
G4ThreeVector vertexPosition; // Position of the vertex at which the actual track was created
|
||||
G4double vertexKineticEnergy; // Kinetic energy of the track when it was created
|
||||
G4String logicalVolumeAtVertex;
|
||||
G4String creatorProcess;
|
||||
|
||||
static G4int ScintMultihit;
|
||||
static G4int runIDoldScint;
|
||||
static G4int eventIDoldScint;
|
||||
static G4int NIS;
|
||||
static G4int ScintChamberNbold;
|
||||
|
||||
static G4int verboseLevel;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
typedef G4THitsCollection<musrScintHit> musrScintHitsCollection;
|
||||
|
||||
extern G4Allocator<musrScintHit> musrScintHitAllocator;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline void* musrScintHit::operator new(size_t)
|
||||
{
|
||||
void *aHit;
|
||||
aHit = (void *) musrScintHitAllocator.MallocSingle();
|
||||
return aHit;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline void musrScintHit::operator delete(void *aHit)
|
||||
{
|
||||
musrScintHitAllocator.FreeSingle((musrScintHit*) aHit);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
38
include/musrScintSD.hh
Normal file
38
include/musrScintSD.hh
Normal file
@ -0,0 +1,38 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrScintSD_h
|
||||
#define musrScintSD_h 1
|
||||
|
||||
#include "G4VSensitiveDetector.hh"
|
||||
#include "musrScintHit.hh"
|
||||
#include "musrRootOutput.hh"
|
||||
|
||||
class G4Step;
|
||||
class G4HCofThisEvent;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrScintSD : public G4VSensitiveDetector
|
||||
{
|
||||
public:
|
||||
musrScintSD(G4String);
|
||||
~musrScintSD();
|
||||
|
||||
void Initialize(G4HCofThisEvent*);
|
||||
G4bool ProcessHits(G4Step*, G4TouchableHistory*);
|
||||
void EndOfEvent(G4HCofThisEvent*);
|
||||
|
||||
private:
|
||||
musrScintHitsCollection* scintCollection;
|
||||
G4bool myStoreOnlyEventsWithHits;
|
||||
G4int myStoreOnlyEventsWithHitInDetID;
|
||||
G4double mySignalSeparationTime;
|
||||
G4bool myStoreOnlyTheFirstTimeHit;
|
||||
G4bool boolIsVvvInfoRequested;
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
||||
|
73
include/musrSteppingAction.hh
Normal file
73
include/musrSteppingAction.hh
Normal file
@ -0,0 +1,73 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef musrSteppingAction_h
|
||||
#define musrSteppingAction_h 1
|
||||
|
||||
#include "G4UserSteppingAction.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "globals.hh"
|
||||
#include "musrRootOutput.hh"
|
||||
#include <fstream>
|
||||
|
||||
class G4Timer;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrSteppingAction : public G4UserSteppingAction
|
||||
{
|
||||
public:
|
||||
|
||||
static musrSteppingAction* GetInstance();
|
||||
musrSteppingAction();
|
||||
~musrSteppingAction();
|
||||
|
||||
void UserSteppingAction(const G4Step *theStep);
|
||||
void DoAtTheBeginningOfEvent();
|
||||
void SetLogicalVolumeAsSpecialSaveVolume(G4String logicName, G4int volumeID);
|
||||
void SetVolumeForMuonEventReweighting(G4String logicName, G4int weight);
|
||||
G4bool GetInfoAboutOldTrack(G4int trackID, G4int& parentTrackID, G4int& particleID, G4double& vertexKine,
|
||||
G4ThreeVector& vertexPosition, G4String& vertexLogVol, G4String& vertexProcess);
|
||||
G4bool AreTracksCommingFromSameParent(G4int trackID1, G4int trackID2, G4String volumeName);
|
||||
static const G4int maxNumberOfOldTracks=200;
|
||||
G4bool IsVvvInfoRequested() {return boolIsVvvInfoRequested;}
|
||||
void SetVvvInfoRequested(G4bool boolvar) {boolIsVvvInfoRequested = boolvar;}
|
||||
void SetCalculationOfFieldIntegralRequested(G4bool decision) {boolCalculateFieldIntegral = decision;}
|
||||
|
||||
private:
|
||||
musrRootOutput* myRootOutput;
|
||||
G4Timer* timer;
|
||||
time_t realTimeWhenThisEventStarted;
|
||||
static musrSteppingAction* pointer;
|
||||
|
||||
G4bool muAlreadyWasInTargetInThisEvent;
|
||||
G4bool muAlreadyWasInM0InThisEvent;
|
||||
G4bool muAlreadyWasInM1InThisEvent;
|
||||
G4bool muAlreadyWasInM2InThisEvent;
|
||||
G4bool radioactiveElectronAlreadySavedInThisEvent;
|
||||
G4bool boolIsAnySpecialSaveVolumeDefined;
|
||||
G4bool boolIsVvvInfoRequested;
|
||||
std::map<G4String,G4int> saveVolumeMapping;
|
||||
G4String lastActualVolume;
|
||||
G4bool boolMuonEventReweighting;
|
||||
G4bool boolCalculateFieldIntegral;
|
||||
std::map<G4String,G4int> volumeMuonWeightMapping;
|
||||
|
||||
G4int indexOfOldTrack;
|
||||
std::map<G4int,G4int> myOldTracksMap;
|
||||
G4int particleID_oldTrack[maxNumberOfOldTracks];
|
||||
G4int parentTrackID_oldTrack[maxNumberOfOldTracks];
|
||||
G4double vertexKine_oldTrack[maxNumberOfOldTracks];
|
||||
G4ThreeVector vertexPosition_oldTrack[maxNumberOfOldTracks];
|
||||
G4String vertexLogVol_oldTrack[maxNumberOfOldTracks];
|
||||
G4String vertexProcess_oldTrack[maxNumberOfOldTracks];
|
||||
|
||||
// for field integral along the muon path (if its calculation is requested by the user)
|
||||
G4double BxIntegral, ByIntegral, BzIntegral;
|
||||
G4double BzIntegral1, BzIntegral2, BzIntegral3;
|
||||
G4double CoordinateForFieldIntegral[4];
|
||||
G4double FieldForFieldIntegral[6];
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
26
include/musrSteppingVerbose.hh
Normal file
26
include/musrSteppingVerbose.hh
Normal file
@ -0,0 +1,26 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrSteppingVerbose;
|
||||
|
||||
#ifndef musrSteppingVerbose_h
|
||||
#define musrSteppingVerbose_h 1
|
||||
|
||||
#include "G4SteppingVerbose.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class musrSteppingVerbose : public G4SteppingVerbose
|
||||
{
|
||||
public:
|
||||
|
||||
musrSteppingVerbose();
|
||||
~musrSteppingVerbose();
|
||||
|
||||
void StepInfo();
|
||||
void TrackingStarted();
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
68
include/musrTabulatedElementField.hh
Normal file
68
include/musrTabulatedElementField.hh
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef musrTabulatedElementField_h
|
||||
#define musrTabulatedElementField_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "F04ElementField.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
#include "G4ios.hh"
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
class musrTabulatedElementField : public F04ElementField
|
||||
{
|
||||
public:
|
||||
musrTabulatedElementField(const char* filename, const char* fldTableType, G4double fieldValue, G4LogicalVolume* logVolume, G4ThreeVector positionOfTheCenter);
|
||||
// "lenUnit" is the unit in which the grid coordinates are specified in the table
|
||||
// "fieldNormalisation" is the normalisation that has to be applied on the field values in the table
|
||||
// such that the values correspond do 1T nominal value
|
||||
// "fieldValue" is the field value (in T) that is required (i.e. values normalised to 1T will be
|
||||
// multiplied by this value).
|
||||
|
||||
/// Destructor.
|
||||
virtual ~musrTabulatedElementField() {}
|
||||
|
||||
/// addFieldValue() adds the field for this solenoid into field[].
|
||||
/// point[] is in global coordinates.
|
||||
void addFieldValue( const G4double Point[4], G4double* field) const;
|
||||
void addFieldValue2D( const G4double Point[4], G4double* field) const;
|
||||
void addFieldValue3D( const G4double Point[4], G4double* field) const;
|
||||
|
||||
G4double GetNominalFieldValue();
|
||||
void SetNominalFieldValue(G4double newFieldValue);
|
||||
|
||||
// getWidth(), getHeight(), getLength(), return the dimensions of the field
|
||||
// (used to define the boundary of the field)
|
||||
virtual G4double getWidth() {return maximumWidth;} // x coordinate
|
||||
virtual G4double getHeight() {return maximumHeight;} // y coordinate
|
||||
virtual G4double getLength() {return maximumLength;} // z coordinate
|
||||
|
||||
|
||||
private:
|
||||
// Storage space for the table
|
||||
std::vector< std::vector< std::vector< double > > > xField;
|
||||
std::vector< std::vector< std::vector< double > > > yField;
|
||||
std::vector< std::vector< std::vector< double > > > zField;
|
||||
std::vector< std::vector< double > > xField2D;
|
||||
std::vector< std::vector< double > > zField2D;
|
||||
// The dimensions of the table
|
||||
int nx,ny,nz;
|
||||
// The units of the field
|
||||
char fieldTableType[100];
|
||||
G4String fUnit;
|
||||
double fieUnit;
|
||||
char fldType;
|
||||
int fldDim;
|
||||
// The physical limits of the defined region
|
||||
double minimumx, maximumx, minimumy, maximumy, minimumz, maximumz;
|
||||
// The physical extent of the defined region
|
||||
double dx, dy, dz;
|
||||
double ffieldValue;
|
||||
double maximumWidth, maximumHeight, maximumLength;
|
||||
|
||||
void Invert(const char* indexToInvert);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
45
include/musrUniformField.hh
Normal file
45
include/musrUniformField.hh
Normal file
@ -0,0 +1,45 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
#ifndef UNIFORM_BFIELD_HH
|
||||
#define UNIFORM_BFIELD_HH
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4Box.hh"
|
||||
#include "F04ElementField.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
|
||||
// UniformField implements a constant electromagnetic field in any direction. TS
|
||||
|
||||
class musrUniformField : public F04ElementField
|
||||
{
|
||||
public:
|
||||
|
||||
musrUniformField(G4double EMF[6], G4double half_X, G4double half_Y, G4double half_Z, G4LogicalVolume*, G4ThreeVector);
|
||||
|
||||
virtual ~musrUniformField() {}
|
||||
|
||||
// TS: Define the two newly added VIRTUAL functions of F04ElementField
|
||||
G4double GetNominalFieldValue();
|
||||
void SetNominalFieldValue(G4double newFieldValue);
|
||||
|
||||
virtual G4double getLength() { return fieldLength; }
|
||||
virtual G4double getWidth() { return fieldWidth; }
|
||||
virtual G4double getHeight() { return fieldHeight; }
|
||||
|
||||
G4bool isOutside(G4ThreeVector& local) const;
|
||||
G4bool isWithin (G4ThreeVector& local) const;
|
||||
|
||||
void addFieldValue(const G4double point[4], G4double field[6]) const;
|
||||
|
||||
private:
|
||||
|
||||
G4double EMfield[6];
|
||||
|
||||
G4double fieldLength;
|
||||
G4double fieldWidth;
|
||||
G4double fieldHeight;
|
||||
};
|
||||
|
||||
#endif
|
44
include/yields.hh
Normal file
44
include/yields.hh
Normal file
@ -0,0 +1,44 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
// Muonium yields as a function of initial mu+ energies.
|
||||
// The method GetYields is used by MuFormation.
|
||||
// Id : yields.cc, v 1.1
|
||||
// Author: Taofiq PARAISO, T. Shiroka
|
||||
// Date : 2007-12
|
||||
// Notes : First implemented in Fortran by A. Hofer
|
||||
// C++ conversion by T.K. Paraiso 04-2005
|
||||
// Slight modifications by T. Shiroka
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
|
||||
#ifndef Yields_h
|
||||
#define Yield_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
The Muonium Yield function as well as the parameters are taken from:
|
||||
M. Gonin, R. Kallenbach, P. Bochsler: "Charge exchange of hydrogen atoms
|
||||
in carbon foils at 0.4 - 120 keV", Rev.Sci.Instrum. 65 (3), March 1994
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class Yields
|
||||
{
|
||||
|
||||
public:
|
||||
Yields(); // Class constructor
|
||||
~Yields(); // Class destructor
|
||||
|
||||
void GetYields(double E, double mass, double yvector[]);
|
||||
|
||||
private: // Some internal variables
|
||||
double Q_zero, Q_minus, D;
|
||||
double Yield_minus, Yield_zero, Yield_plus;
|
||||
|
||||
double aux1, aux2, aux3; // Auxiliary variables
|
||||
};
|
||||
|
||||
#endif
|
151
musrSim.cc
Normal file
151
musrSim.cc
Normal file
@ -0,0 +1,151 @@
|
||||
#include "musrDetectorConstruction.hh"
|
||||
#include "musrPhysicsList.hh"
|
||||
#include "musrPrimaryGeneratorAction.hh"
|
||||
#include "musrRunAction.hh"
|
||||
#include "musrEventAction.hh"
|
||||
#include "musrSteppingAction.hh"
|
||||
#include "musrSteppingVerbose.hh"
|
||||
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIterminal.hh"
|
||||
#include "G4UItcsh.hh"
|
||||
|
||||
// The following two lines are needed to cope with the problem of
|
||||
// "Error in <TPluginManager::FindHandler>: Cannot find plugin handler for TVirtualStreamerInfo!
|
||||
// Does $ROOTSYS/etc/plugins/TVirtualStreamerInfo exist?"
|
||||
#include "TROOT.h"
|
||||
#include "TPluginManager.h"
|
||||
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#ifdef G4VIS_USE
|
||||
// #include "musrVisManager.hh"
|
||||
#include "G4VisExecutive.hh"
|
||||
#include "G4TrajectoryDrawByCharge.hh" // TS Trajectory drawing by ID or charge
|
||||
#endif
|
||||
|
||||
#include "musrRootOutput.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
//#include "F04GlobalField.hh"
|
||||
|
||||
int main(int argc,char** argv) {
|
||||
|
||||
XInitThreads();
|
||||
|
||||
// choose the Random engine
|
||||
// CLHEP::HepRandom::setTheEngine(new CLHEP::RanecuEngine); // the /musr/run/randomOption 2 does not work with RanecuEngine
|
||||
CLHEP::HepRandom::setTheEngine(new CLHEP::HepJamesRandom);
|
||||
|
||||
//my Verbose output class
|
||||
G4VSteppingVerbose::SetInstance(new musrSteppingVerbose);
|
||||
|
||||
// Run manager
|
||||
G4RunManager * runManager = new G4RunManager;
|
||||
|
||||
// Create class "myParameters", which is a collection of many different parameters
|
||||
G4String steeringFileName=argv[1];
|
||||
musrParameters* myParameters = new musrParameters(steeringFileName);
|
||||
|
||||
// Create class "musrErrorMessage"
|
||||
musrErrorMessage* myErrorMessage = new musrErrorMessage();
|
||||
|
||||
// Create Root class for storing the output of the Geant simulation
|
||||
musrRootOutput* myRootOutput = new musrRootOutput();
|
||||
|
||||
// The following command is needed to cope with the problem of
|
||||
// "Error in <TPluginManager::FindHandler>: Cannot find plugin handler for TVirtualStreamerInfo!
|
||||
// Does $ROOTSYS/etc/plugins/TVirtualStreamerInfo exist?"
|
||||
// /* magic line from Rene - for future reference! */
|
||||
gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
|
||||
"*",
|
||||
"TStreamerInfo",
|
||||
"RIO",
|
||||
"TStreamerInfo()");
|
||||
|
||||
|
||||
// UserInitialization classes (mandatory)
|
||||
musrDetectorConstruction* musrdetector = new musrDetectorConstruction;
|
||||
if (argc>1) {
|
||||
G4int myRunNr=atoi(argv[1]); // Get the run number from the name of the
|
||||
// parameter file, if it starts with a number.
|
||||
if (myRunNr>0) {runManager->SetRunIDCounter(myRunNr);}
|
||||
musrdetector->SetInputParameterFileName(argv[1]);
|
||||
}
|
||||
runManager->SetUserInitialization(musrdetector);
|
||||
runManager->SetUserInitialization(new musrPhysicsList);
|
||||
|
||||
#ifdef G4VIS_USE
|
||||
// Visualization, if you choose to have it!
|
||||
// G4VisManager* visManager = new musrVisManager;
|
||||
G4VisManager* visManager = new G4VisExecutive; // TS Trajectory drawing by ID or charge
|
||||
visManager->Initialize();
|
||||
#endif
|
||||
|
||||
// UserAction classes
|
||||
runManager->SetUserAction(new musrPrimaryGeneratorAction(musrdetector));
|
||||
runManager->SetUserAction(new musrRunAction);
|
||||
runManager->SetUserAction(new musrEventAction);
|
||||
runManager->SetUserAction(new musrSteppingAction);
|
||||
|
||||
//Initialize G4 kernel
|
||||
runManager->Initialize();
|
||||
|
||||
//get the pointer to the User Interface manager
|
||||
G4UImanager * UI = G4UImanager::GetUIpointer();
|
||||
|
||||
if(argc==1)
|
||||
// Define (G)UI terminal for interactive mode
|
||||
{
|
||||
// G4UIterminal is a (dumb) terminal.
|
||||
G4UIsession * session = 0;
|
||||
#ifdef G4UI_USE_TCSH
|
||||
session = new G4UIterminal(new G4UItcsh);
|
||||
#else
|
||||
session = new G4UIterminal();
|
||||
#endif
|
||||
|
||||
UI->ApplyCommand("/control/execute vis.mac");
|
||||
session->SessionStart();
|
||||
delete session;
|
||||
}
|
||||
else
|
||||
// Batch mode
|
||||
{
|
||||
G4String command = "/control/execute ";
|
||||
G4String fileName = argv[1];
|
||||
UI->ApplyCommand(command+fileName);
|
||||
if (argc>2) {
|
||||
G4String SecondArgument = argv[2];
|
||||
if (SecondArgument=="idle") {
|
||||
G4UIsession * session = 0;
|
||||
#ifdef G4UI_USE_TCSH
|
||||
session = new G4UIterminal(new G4UItcsh);
|
||||
#else
|
||||
session = new G4UIterminal();
|
||||
#endif
|
||||
session->SessionStart();
|
||||
delete session;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G4VIS_USE
|
||||
delete visManager;
|
||||
#endif
|
||||
delete myRootOutput;
|
||||
delete myErrorMessage;
|
||||
delete myParameters;
|
||||
delete runManager;
|
||||
|
||||
// F04GlobalField* myGlobalField = F04GlobalField::getObject();
|
||||
// if (myGlobalField!=NULL) {delete myGlobalField;}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
812
run/1050.mac
Normal file
812
run/1050.mac
Normal file
@ -0,0 +1,812 @@
|
||||
# Macro file for musr.cc - Construct detector, set fields and other parameters.
|
||||
# Last modified by T. Shiroka: 17.03.2008
|
||||
#
|
||||
# Corrected TD and MCP2 distances by T. Prokscha, 07.11.2008.
|
||||
#
|
||||
|
||||
# How to run: musr 10xx.mac (append "idle" for prompt after running)
|
||||
# musr 10xx.mac > fname.txt (stores output on a txt file)
|
||||
#
|
||||
# Specify the geometry parameters in this file (all dimensions in mm)
|
||||
# a. Lines starting with hash marks "#" are comments
|
||||
# b Lines starting with #* are temporary comments. Remove/modify to change the configuration
|
||||
# c. Lines starting with /musr/command are commands for the executable program
|
||||
# d. Lines starting with /vis, /gun, etc. are common macro commands
|
||||
# e. Beam-line components are ordered from exp. area (MCP2) to trigger detector (TD)
|
||||
#
|
||||
# Syntax example (following /musr/command):
|
||||
# construct solid_type volume_name parameters_defining_solid material position mothers_name
|
||||
# (mothers_name starts with log_)
|
||||
# Examples
|
||||
#
|
||||
# Generate rotation matrix about n=(x,y,z) by th degrees
|
||||
# /musr/command rotation MName x y z th
|
||||
#
|
||||
# Construct a volume
|
||||
# /musr/command construct Type Name <volume parameters> Material X Y Z MotherVolume RotationMatrix Sensitivity RootID [nofield]
|
||||
# Type - can be tubs (cylindrical), box, sphere etc.
|
||||
# Name - Just the name of the volume
|
||||
# <volume parameters> - Depend on the Type you are creating
|
||||
# Material - Is the material in the volume, it can be G4_Galactic (vacuum), G4_PLASTIC_SC_VINYLTOLUENE (scintillator) etc.
|
||||
# X Y Z - The position vector relative to the MotherVolume
|
||||
# RotationMatrix - The rotation to be applied on the volume, it can be norot (no rotation) or other MName
|
||||
# Sensitivity - If the volume has a respones, it can be musr/ScintSD (detector), dead (no response)
|
||||
# RootID - An ID that will be saved in the root file for analysis
|
||||
# nofield - Obsolete, should be removed.
|
||||
#
|
||||
# Uniform field in volume
|
||||
# /musr/command globalfield FieldName half_x half_y half_z uniform X Y Z MotherVolume Bx By Bz Ex Ey Ez
|
||||
# FieldName - A simple name for the field
|
||||
# half_x half_y half_z - half lenghts of the box, within which the field is defined
|
||||
# X Y Z - Position vector relative to MotherVolume
|
||||
# MotherVolume - The volume containing the field
|
||||
# Bx By Bz - Magnetic field vector
|
||||
# Ex Ey Ez - Electric field vector
|
||||
#
|
||||
# Non-Uniform field according to a field map
|
||||
# /musr/command globalfield FieldName X Y Z fromfile MapDim MapFileName.map MotherVolume ModBE
|
||||
# FieldName - A simple name for the field
|
||||
# X Y Z - Position vector relative to MotherVolume
|
||||
# MotherVolume - The volume containing the field
|
||||
# MapDim - Dimension and type of field, it can be 2DE (2D Electric), 2DB (2D Magnetic), 3DE (3D Electric) and 3DB (3D Magnetic)
|
||||
# The 2D maps are propagated along the z axis to form the 3D map (to reduce the size of the map file)
|
||||
# MapFileName.map - The field where the field map is stored
|
||||
# ModBE - The size of the field (to scale the field map).
|
||||
###############################################################################################
|
||||
|
||||
# For the meaning of the acronyms see also the original G3 file ugeom.F at:
|
||||
# http://savannah.psi.ch/viewcvs/trunk/simulation/geant3/src/lemsr/ugeom.F?root=nemu%2Flem&rev=2964&view=markup
|
||||
|
||||
################################################################################################################
|
||||
# -- ROTATION MATRICES --
|
||||
################################################################################################################
|
||||
|
||||
# 3 parameters -> Define Euler angles (the 4th par. is set to zero).
|
||||
# 4 parameters -> Define axis + rotation.
|
||||
# HEP computations ordinarily use the active rotation viewpoint (object is rotated NOT axes).
|
||||
# Therefore, rotations about an axis imply ACTIVE COUNTER-CLOCKWISE rotation in this package.
|
||||
# Rotation around a specified axis means counter-clockwise rot. around the positive direction of the axis.
|
||||
|
||||
# Define rotations for the field maps of Trigger and Ring Anode:
|
||||
/musr/command rotation rotTrig 0 1 0 -45
|
||||
/musr/command rotation rotRAnR 0 0 1 -90
|
||||
/musr/command rotation rotRAnL 0 0 1 90
|
||||
/musr/command rotation rotRAnD 0 0 1 180
|
||||
|
||||
################################################################################################################
|
||||
# -- LEM GEOMETRY --
|
||||
################################################################################################################
|
||||
|
||||
# WORLD = Laboratory reference frame, the origin is in the centre of the LEM sample tube
|
||||
/musr/command construct box World 250 250 2250 G4_Galactic 0 0 0 no_logical_volume norot dead -1
|
||||
# MINIMUM WORD HALF LENGTH 1250 mm!
|
||||
#/musr/command construct box World 2000 2000 4000 G4_Galactic 0 0 0 no_logical_volume norot dead -1
|
||||
|
||||
# World visual attributes (optional)
|
||||
/musr/command visattributes log_World invisible
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Sc - Scintillators: U - up, D - down, L - left, R - right (with respect to muon's view - momentum direction)
|
||||
# 8 Scintillators in two concentric rings - Inner and Outer (see also the convention for the Ring Anode)
|
||||
#===============================================================================================================
|
||||
|
||||
## Inner Scintillators - I
|
||||
/musr/command construct tubs ScIU 90 95 130 45 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 011 nofield
|
||||
/musr/command construct tubs ScIR 90 95 130 135 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 012 nofield
|
||||
/musr/command construct tubs ScID 90 95 130 225 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 013 nofield
|
||||
/musr/command construct tubs ScIL 90 95 130 315 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 014 nofield
|
||||
|
||||
## Outer Scintillators - O
|
||||
/musr/command construct tubs ScOU 96 101 130 45 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 021 nofield
|
||||
/musr/command construct tubs ScOR 96 101 130 135 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 022 nofield
|
||||
/musr/command construct tubs ScOD 96 101 130 225 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 023 nofield
|
||||
/musr/command construct tubs ScOL 96 101 130 315 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 024 nofield
|
||||
|
||||
# Visual attributes (optional)
|
||||
#*/musr/command visattributes log_ScOU SCINT_style
|
||||
#*/musr/command visattributes log_ScOD dSCINT_style
|
||||
/musr/command visattributes log_ScOL darkred
|
||||
/musr/command visattributes log_ScIL darkred
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Experimental Area - Can host EITHER the Cryostat OR the MCP2 (For the tests we usually use the MCP)
|
||||
# Delimited by the F160 and F100 (blank end) flanges
|
||||
#
|
||||
# 07/Nov/2008: correct sample tube dimensions: the new tubes have 75 mm / 78 mm inner/outer radius
|
||||
#
|
||||
#===============================================================================================================
|
||||
|
||||
# MCP - Multi-Channel Plate 2 Chamber; V - Vacuum, S - Solid # Note: VERY IMPORTANT: mcpv_z = -92.5 mm!
|
||||
# OLD way of assigning a field
|
||||
#/musr/command construct tubs MCPV 0 76.5 254.5 0 360 G4_Galactic 0 0 -92.5 log_World norot dead 100 MCPSfield
|
||||
/musr/command construct tubs MCPV 0 75.0 254.5 0 360 G4_Galactic 0 0 -92.5 log_World norot dead 100 nofield
|
||||
/musr/command construct tubs MCPS 75.0 78.0 162.0 0 360 Steel 0 0 0 log_World norot dead 101 nofield
|
||||
|
||||
# F - Flanges: F160, F100, F200 (used only when the Asymmetry check is OFF)
|
||||
# F160 - 160 CF flange upstream of MCP2 tube
|
||||
# F100 (Blank end flange) # OLD Value was 162.0
|
||||
/musr/command construct tubs F160 78.0 101.25 11 0 360 Steel 0 0 -151.0 log_World norot dead 901 nofield
|
||||
/musr/command construct tubs F100 0 75.0 10 0 360 Steel 0 0 172.0 log_World norot dead 902 nofield
|
||||
|
||||
# NOTE: Original F100 referred to MCPV (as shown below) was moved to World.
|
||||
#/musr/command construct tubs F100 0 76.5 10 0 360 Steel 0 0 264.5 log_MCPV norot dead 902 nofield
|
||||
|
||||
|
||||
# Experimental Area visual attributes (optional)
|
||||
/musr/command visattributes log_MCPV invisible
|
||||
/musr/command visattributes log_MCPS invisible
|
||||
/musr/command visattributes log_F160 blue_style
|
||||
/musr/command visattributes log_F100 blue_style
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# MCP - Micro Channel Plate Detector MCP2 (Used as an alternative to cryostat) # mcpv_z = -92.5 mm!
|
||||
#
|
||||
# We have a 324 mm long sample tube;
|
||||
# the MCP2 front side is at 142 mm from the end of the sample tube.
|
||||
# the front face of the sample plate of the cryostat is 145 mm from the end of the sample tube.
|
||||
#
|
||||
#===============================================================================================================
|
||||
|
||||
# MCPM1 - MCP Macor ring 1
|
||||
# MCPD - electron multiplying glass disk (also known as target)
|
||||
# Sensitive surface at z = 20 mm wrt. World
|
||||
# MCPM2 - MCP Macor ring 2
|
||||
/musr/command construct tubs MCPM1 24 32.5 0.75 0 360 Macor 0 0 111.75 log_MCPV norot dead 201 nofield
|
||||
# Use it either as (DMCP-musr/ScintSD) - no info on mu+ polariz., or as (target-dead) with info on mu+ polariz.
|
||||
#*/musr/command construct tubs target 0 25.0 1.50 0 360 MCPglass 0 0 108.0 log_MCPV norot dead 032 nofield
|
||||
/musr/command construct tubs MCPM2 24 32.5 0.75 0 360 Macor 0 0 116.25 log_MCPV norot dead 203 nofield
|
||||
# NOTE: To intercept ALL the incoming muons, comment the DMCP and MCPM1 lines above and uncomment this one:
|
||||
#*aa/musr/command construct tubs DMCP 0 76.5 1.5 0 360 MCPglass 0 0 108 log_MCPV norot musr/ScintSD 202 nofield
|
||||
/musr/command construct tubs target 0 21.0 1.5 0 360 MCPglass 0 0 114 log_MCPV norot musr/ScintSD 202 nofield
|
||||
/musr/command construct tubs saveTarget 0 75.0 0.2 0 360 G4_Galactic 0 0 110.79 log_MCPV norot dead 222 nofield
|
||||
|
||||
# MCSR - Stainless Steel Ring for MCP2 mounting (modelled as a box with a circular hole)
|
||||
# MCVR - "Vacuum Ring" (circular hole)
|
||||
/musr/command construct box MCSR 36.5 36.5 1 Steel 0 0 118.5 log_MCPV norot dead 204 nofield
|
||||
/musr/command construct tubs MCVR 0 27.5 1 0 360 G4_Galactic 0 0 0 log_MCSR norot dead 205 nofield
|
||||
|
||||
# MCPA = MCP Anode (modelled as a box with two symmetrically subtracted "vacuum" disks)
|
||||
# ANVA1 - Anode "Vacuum" 1 - Part of MCP Anode
|
||||
# ANVA2 - Anode "Vacuum" 2 - Part of MCP Anode
|
||||
/musr/command construct box MCPA 36.5 36.5 4 Steel 0 0 129.5 log_MCPV norot dead 206 nofield
|
||||
/musr/command construct tubs ANVA1 0 27.5 1.5 0 360 G4_Galactic 0 0 -2.5 log_MCPA norot dead 207 nofield
|
||||
/musr/command construct tubs ANVA2 0 27.5 1.5 0 360 G4_Galactic 0 0 2.5 log_MCPA norot dead 208 nofield
|
||||
|
||||
# MCSS - MCP Stainless Steel Support Ring
|
||||
/musr/command construct tubs MCSS 40 48 2.5 0 360 Steel 0 0 162.3 log_MCPV norot dead 209 nofield
|
||||
|
||||
|
||||
# MCP2 visual attributes (optional)
|
||||
#/musr/command visattributes log_DMCP MCP_style
|
||||
#*/musr/command visattributes log_target MCP_style
|
||||
#*/musr/command visattributes log_MCPM1 MACOR_style
|
||||
#*------ /musr/command visattributes log_MCPM2 MACOR_style
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# CRY - Cryostat - Used as an ALTERNATIVE to MCP2 - Uncomment lines with #*. (Offset = 0.0 cm)
|
||||
#
|
||||
# at the moment, sample plate front face is still at z = 14.0mm --> should be changed to 17mm.
|
||||
#===============================================================================================================
|
||||
|
||||
# SAH - SAmple Holder components (Cu plate) Cu or Al plates 1. Cu plate (sample holder) on Cold finger, 0.5cm
|
||||
# SAPH - SAPpHire plate mounted between 1st and 2nd Cu plates, 6 mm thick, 60 mm diameter.
|
||||
# SAH3 is ignored because currently NOT use.
|
||||
#*/musr/command construct tubs SAH1 0 35 2.5 0 360 G4_Cu 0 0 119.0 log_MCPV norot dead 251 nofield
|
||||
#*/musr/command construct tubs SAH2 0 35 2 0 360 G4_Cu 0 0 108.5 log_MCPV norot dead 252 nofield
|
||||
#/musr/command construct tubs target 0 35 2 0 360 G4_Al 0 0 108.5 log_MCPV norot musr/ScintSD 252 nofield
|
||||
#*/musr/command construct tubs saveTarget 0 44 0.2 0 360 G4_Galactic 0 0 106.29 log_MCPV norot dead 253 nofield
|
||||
#/musr/command construct tubs SAH3 20 35 0.5 0 360 G4_Cu 0 0 106.0 log_MCPV norot dead 253 nofield
|
||||
#*/musr/command construct tubs SAPH 0 30 3 0 360 G4_ALUMINUM_OXIDE 0 0 113.5 log_MCPV norot dead 254 nofield
|
||||
|
||||
# Other components of the CRYostat (dimensions and position of CRY4 are only approx. because unknown)
|
||||
# COFI - COld FInger
|
||||
# CRY1 - End plate of cryostat (7 mm thick, 30 mm diameter)
|
||||
# CRY2 - Heat exchanger (assuming a 10 mm opening - Original dimensions not known.) # OLD pos. 160.0
|
||||
# CRY3 - Mounting ring for He-shield
|
||||
# CRY4 - 2 mm thick plate for mounting ring. This is just to close the downstream side.
|
||||
# CRSH - Lateral He-shield
|
||||
# CRSH2- Frontal He-shield Ring
|
||||
#*/musr/command construct tubs COFI 0 27.5 5 0 360 G4_Cu 0 0 126.5 log_MCPV norot dead 261 nofield
|
||||
#*/musr/command construct tubs CRY1 0 15 3.5 0 360 G4_Cu 0 0 135.0 log_MCPV norot dead 262 nofield
|
||||
#*/musr/command construct tubs CRY2 5 15 25 0 360 G4_Cu 0 0 163.5 log_MCPV norot dead 263 nofield
|
||||
#*/musr/command construct tubs CRY3 38 47 5.5 0 360 G4_Cu 0 0 143.5 log_MCPV norot dead 264 nofield
|
||||
#*/musr/command construct tubs CRY4 15 38 1 0 360 G4_Cu 0 0 143.5 log_MCPV norot dead 265 nofield
|
||||
#*/musr/command construct tubs CRSH 47 48 45 0 360 G4_Cu 0 0 108.5 log_MCPV norot dead 266 nofield
|
||||
#*/musr/command construct tubs CRSH2 30 48 0.5 0 360 G4_Cu 0 0 63.0 log_MCPV norot dead 267 nofield
|
||||
|
||||
# Electrical Field Guard Rings (distance between the guard rings: 16 mm)
|
||||
#*/musr/command construct tubs Guard1 29 38 1.5 0 360 G4_Cu 0 0 76.0 log_MCPV norot dead 271 nofield
|
||||
#*/musr/command construct tubs Guard2 29 38 1.5 0 360 G4_Cu 0 0 92.0 log_MCPV norot dead 272 nofield
|
||||
|
||||
|
||||
# Cryostat visual attributes (optional)
|
||||
#*/musr/command visattributes log_SAH1 oxsteel
|
||||
#*/musr/command visattributes log_SAH2 oxsteel
|
||||
#*/musr/command visattributes log_target oxsteel
|
||||
#*/musr/command visattributes log_SAPH MACOR_style
|
||||
#*/musr/command visattributes log_SAH3 oxsteel
|
||||
#*/musr/command visattributes log_CRSH invisible
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# RA - Ring Anode, M - middle part (closer to Ground Anode), E - end part (farther from the Ground Anode)
|
||||
# U - up, D - down, L - left, R - right (with respect to muon's view - momentum direction)
|
||||
# Note: 3.0 mm HALF gap at 45.1469 mm half radius => delta_ang = asin(3.0/45.1469)*180/pi = 3.81 deg.
|
||||
# Note: delta_ang = 3.1744 deg. for 2.5 mm HG. The angular extension goes e.g. from (45 + da) to (90 - 2*da).
|
||||
# Note: Ring Anode - Ground Anode distance was 15 mm => CHANGED to 12 mm! (Positions: 11.5 -> 8.5, -33.5 -> -36.5)
|
||||
#===============================================================================================================
|
||||
|
||||
# RA_Ez = -10.35+2.25 = -8.1 cm; RA_Mz= -10.35 - 2.25 = -12.6 cm; RA_Gz= -25.45+3.75 = -21.7 cm; mcpv_z = -9.25 cm
|
||||
/musr/command construct cons RA_EU 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV norot dead 301 nofield
|
||||
/musr/command construct cons RA_MU 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV norot dead 302 nofield
|
||||
/musr/command construct cons RA_ER 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV rotRAnR dead 303 nofield
|
||||
/musr/command construct cons RA_MR 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV rotRAnR dead 304 nofield
|
||||
/musr/command construct cons RA_ED 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV rotRAnD dead 305 nofield
|
||||
/musr/command construct cons RA_MD 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV rotRAnD dead 306 nofield
|
||||
/musr/command construct cons RA_EL 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV rotRAnL dead 307 nofield
|
||||
/musr/command construct cons RA_ML 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV rotRAnL dead 308 nofield
|
||||
|
||||
|
||||
# Dummy, thin cylindres used for applying the SAME RA field-map (ROTATED by 90 deg.) to different anodes.
|
||||
# NOTE: EM field cannot be applied to non simply connected bodies, as e.g. rings, cones, tori, etc.!
|
||||
/musr/command construct tubs RA_U 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.50 log_MCPV norot dead 322 nofield
|
||||
/musr/command construct tubs RA_R 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.52 log_MCPV rotRAnR dead 324 nofield
|
||||
/musr/command construct tubs RA_D 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.54 log_MCPV rotRAnD dead 326 nofield
|
||||
/musr/command construct tubs RA_L 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.56 log_MCPV rotRAnL dead 328 nofield
|
||||
|
||||
|
||||
# RA_G - Ring Anode Ground Cylinder
|
||||
/musr/command construct tubs RA_G 58 62.5 58.0 0 360 G4_Cu 0 0 -129.0 log_MCPV norot dead 351 nofield
|
||||
|
||||
|
||||
# Ring Anodes visual attributes (optional)
|
||||
/musr/command visattributes log_RA_EU oxsteel
|
||||
/musr/command visattributes log_RA_MR oxsteel
|
||||
/musr/command visattributes log_RA_G Grid_style
|
||||
|
||||
|
||||
# Alternative placement using World as a mother volume (mcpv_z = -92.5 mm). Check latter. These values refer to a 5 mm GAP!
|
||||
#/musr/command construct cons RA_EU 45.1469 62.5 33.5 39.0 22.5 48.1711 83.6578 Steel 0 0 -81 log_World norot dead 301 nofield
|
||||
#/musr/command construct cons RA_MU 56.7937 62.5 45.147 62.5 22.5 48.1711 83.6578 Steel 0 0 -126 log_World norot dead 302 nofield
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Gate Valve Area - Hosts the Ground Anode (upstream part of the Ring Anode) - Delimited by L3F1 and F200 flanges
|
||||
#===============================================================================================================
|
||||
|
||||
# GATS - 200 CF flange upstream of MCP2 tube covering the whole length of the gate valve chamber. For simplicity, we
|
||||
# choose the INNER diameter of the GATe valve Steel tube the same as the OUTER diameter of F200 (200 CF flange)
|
||||
/musr/command construct tubs GATS 103.25 126.5 92.5 0 360 Steel 0 0 -254.5 log_World norot dead 371 nofield
|
||||
|
||||
# Vacuum "Ring" (to avoid intersections with MCPV) - Not needed if world is already filled with vacuum.
|
||||
#*/musr/command construct tubs GATV 76.5 103.25 92.5 0 360 G4_Galactic 0 0 -254.5 log_World norot dead 370 nofield
|
||||
|
||||
# F200 - 200 CF flange upstream of MCP2 tube to connect to gate valve chamber
|
||||
/musr/command construct tubs F200 76.5 103.25 12 0 360 Steel 0 0 -174.0 log_World norot dead 372 nofield
|
||||
|
||||
# NOTE: When using GATV comment the F200 above and uncomment the following (change mother to log_GATV).
|
||||
#*/musr/command construct tubs F200 76.5 103.25 12 0 360 Steel 0 0 80.5 log_GATV norot dead 372 nofield
|
||||
|
||||
|
||||
# Gate Valve Area visual attributes (optional)
|
||||
/musr/command visattributes log_GATS SCINT_style
|
||||
/musr/command visattributes log_F200 blue_style
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# L3 - 3rd Einzel Lens # L3z = -56.7 cm. ATT: DUMMY FIELD change to electric L3Efield!
|
||||
#===============================================================================================================
|
||||
# Lens Gap = 12.0 mm => G/D = 12/130 ~ 0.1 (Lens Gap = gap between Ground and Anode, D - Diameter)
|
||||
|
||||
# L3 envelope (Tube + Flanges)
|
||||
# L3VA - Lens 3 Vacuum
|
||||
# L3ST - Lens 3 Steel tube (inner dia: 200 mm, outer dia: 206 mm, length: 720 mm)
|
||||
# L3F1 - Lens 3 Flange 1, z = L3z + 208 mm
|
||||
# L3F2 - Lens 3 Flange 2, z = L3z - 208 mm
|
||||
|
||||
/musr/command construct tubs L3VA 0 100 220 0 360 G4_Galactic 0 0 -567 log_World norot dead 400 nofield
|
||||
/musr/command construct tubs L3ST 100 103 220 0 360 Steel 0 0 -567 log_World norot dead 401 nofield
|
||||
/musr/command construct tubs L3F1 103 126.5 12 0 360 Steel 0 0 -359 log_World norot dead 402 nofield
|
||||
/musr/command construct tubs L3F2 103 126.5 12 0 360 Steel 0 0 -775 log_World norot dead 403 nofield
|
||||
|
||||
# GPn - Ground Potential Electrodes
|
||||
# n = 1-4 and 5-8 - components of the Ground Electrodes
|
||||
# GP1 - Ground Electrode (inner dia: 130 mm, outer dia: 134 mm, length: 133 mm)
|
||||
# GP2 - outer electrode surface (LN2 cooling vessel)
|
||||
# GP3 - first ring cap
|
||||
# GP4 - second ring cap
|
||||
|
||||
# n = 1-4 - Ground Electrode 1 (further from TD). See above for the meaning of acronyms.
|
||||
/musr/command construct tubs L3GP1 65 67 66.5 0 360 Steel 0 0 133.5 log_L3VA norot dead 421 nofield
|
||||
/musr/command construct tubs L3GP2 81 83 66.5 0 360 Steel 0 0 133.5 log_L3VA norot dead 422 nofield
|
||||
/musr/command construct tubs L3GP3 67 81 4 0 360 Steel 0 0 196.0 log_L3VA norot dead 423 nofield
|
||||
/musr/command construct tubs L3GP4 67 81 4 0 360 Steel 0 0 71.0 log_L3VA norot dead 424 nofield
|
||||
|
||||
# n = 5-8 - Ground Electrode 2 (closer to TD). See above for the meaning of acronyms.
|
||||
/musr/command construct tubs L3GP5 65 67 66.5 0 360 Steel 0 0 -133.5 log_L3VA norot dead 431 nofield
|
||||
/musr/command construct tubs L3GP6 81 83 66.5 0 360 Steel 0 0 -133.5 log_L3VA norot dead 432 nofield
|
||||
/musr/command construct tubs L3GP7 67 81 4 0 360 Steel 0 0 -196.0 log_L3VA norot dead 433 nofield
|
||||
/musr/command construct tubs L3GP8 67 81 4 0 360 Steel 0 0 -71.0 log_L3VA norot dead 434 nofield
|
||||
|
||||
# HP - High Potential Electrode (Central Anode - usually at +8.7 kV, for a 15 keV muon beam)
|
||||
/musr/command construct tubs L3HP 65 83 55 0 360 Steel 0 0 0 log_L3VA norot dead 451 nofield
|
||||
|
||||
|
||||
# Lens 3 visual attributes (optional)
|
||||
/musr/command visattributes log_L3VA invisible
|
||||
/musr/command visattributes log_L3ST invisible
|
||||
/musr/command visattributes log_L3HP darkred
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# IP - Intermediate Piece (between Trigger Detector and Einzel Lens 3)
|
||||
# Original name was CGate - B-field Coil Compensation Gate?! # CompGatez = -86.55 cm; // L3z - 22 - 7.85 cm
|
||||
#===============================================================================================================
|
||||
# IPV (but also others) are just empty volumes "filled" with vacuum. Sometimes used to apply EM fields to restricted areas.
|
||||
/musr/command construct tubs IPV 0 100 78.5 0 360 G4_Galactic 0 0 -865.5 log_World norot dead 500 nofield
|
||||
# IPCF - Intermediate Piece Central Flange (same as L3 Flanges)
|
||||
# IPST - Intermediate Piece Steel Tube (same diameter as L3 Steel Tube)
|
||||
/musr/command construct tubs IPCF 103 126.5 12.0 0 360 Steel 0 0 -865.5 log_World norot dead 501 nofield
|
||||
/musr/command construct tubs IPST 100 103 78.5 0 360 Steel 0 0 -865.5 log_World norot dead 502 nofield
|
||||
|
||||
|
||||
# IP visual attributes (optional)
|
||||
/musr/command visattributes log_IPV invisible
|
||||
/musr/command visattributes log_IPCF blue_style
|
||||
/musr/command visattributes log_IPST gray
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Trigger - Trigger Detector # Triggerz = -1092 mm; total length of TD is 110 mm; carbon foil at -1144 mm.
|
||||
#===============================================================================================================
|
||||
|
||||
# Trigger tube and relative vacuum
|
||||
/musr/command construct tubs TriggerV 0 100 148 0 360 G4_Galactic 0 0 -1092 log_World norot dead 600 nofield
|
||||
/musr/command construct tubs Trigger 100 103 148 0 360 Steel 0 0 -1092 log_World norot dead 601 nofield
|
||||
|
||||
# TF - Trigger tube flanges
|
||||
/musr/command construct tubs TF1 103 126.5 12 0 360 Steel 0 0 -956 log_World norot dead 611 nofield
|
||||
/musr/command construct tubs TF2 103 126.5 12 0 360 Steel 0 0 -1228 log_World norot dead 612 nofield
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# trigger foil is 52mm upstream of Triggerz, i.e. at -1144 mm
|
||||
#-------------------------------------------------------------
|
||||
# Carbon Foil (default HALF-thickness 0.000005147 mm, see below => CFoil thick = 10.3 nm).
|
||||
# USE THE NAME CFoil or coulombCFoil, otherwise musrMuFormation won't work!
|
||||
####/musr/command construct box CFoil 60 60 0.000005147 G4_GRAPHITE 0 0 -45 log_TriggerV norot dead 621 nofield
|
||||
/musr/command construct box CFoil 60 60 0.0000044 G4_GRAPHITE 0 0 -52.1 log_TriggerV norot dead 621 nofield
|
||||
####/musr/command construct box coulombCFoil 60 60 0.000005147 G4_GRAPHITE 0 0 -45 log_TriggerV norot dead 621 nofield
|
||||
|
||||
# Notes: NIST tables use G4_GRAPHITE with 1.7 g/cm3 and 78 eV ioniz. energy.
|
||||
# An area density of 2.20 ug/cm2 implies a CF thickn. = (2.20*1.e-6/1.70)*cm = 1.294e-5 mm - Total thickness
|
||||
# An area density of 1.75 ug/cm2 implies a CF thickn. = (1.75*1.e-6/1.70)*cm = 1.029e-5 mm - Total thickness
|
||||
# If necessary, use Graphite as defined in musrDetectorConstruction.cc and set any density.
|
||||
|
||||
# Dummy plane to intercept outgoing muons from the Carbon foil.
|
||||
#*/musr/command construct box saveCFoil 60 60 5e-4 G4_Galactic 0 0 -52.0005 log_TriggerV norot dead 623 nofield
|
||||
#*/musr/command construct box saveBeforeCFoil 60 60 5e-4 G4_Galactic 0 0 -52.105 log_TriggerV norot dead 623 nofield
|
||||
#*/musr/command construct box saveAfterTD 60 60 5e-4 G4_Galactic 0 0 58.0006 log_TriggerV norot dead 623 nofield
|
||||
|
||||
|
||||
# Electrical Field areas in the Trigger Detector
|
||||
# En = Electrical Field n: TnFieldMgr (n = 1-3)
|
||||
# Original TriggE2: [4.*sqrt(2), 4.5, 0.7/sqrt(2)] cm -> changed due to overlaps with E1 and E3
|
||||
/musr/command construct box TriggE0 45 45 5 G4_Galactic 0 0 -57.15 log_TriggerV norot dead 630 nofield
|
||||
/musr/command construct box TriggE1 45 45 4 G4_Galactic 0 0 -48.0 log_TriggerV norot dead 631 nofield
|
||||
/musr/command construct box TriggE2 45 45 4.9497 G4_Galactic 0 0 2.25 log_TriggerV rotTrig dead 632 nofield
|
||||
/musr/command construct box TriggE3 45 45 4 G4_Galactic 0 0 54.0 log_TriggerV norot dead 633
|
||||
|
||||
# Beam spot (just for having a visual idea!)
|
||||
/musr/command construct tubs BSpot 0 20 1 0 360 G4_Galactic 0 0 -63.15 log_TriggerV norot dead 650 nofield
|
||||
|
||||
|
||||
# Trigger visual attributes (optional)
|
||||
/musr/command visattributes log_TriggerV invisible
|
||||
/musr/command visattributes log_Trigger invisible
|
||||
/musr/command visattributes saveCFoil invisible
|
||||
# Bug: It seems that if you set this to invisible the program stops. I see no reason for that!
|
||||
#/musr/command visattributes log_saveAfterTD invisible
|
||||
/musr/command visattributes log_BSpot invisible
|
||||
#*/musr/command visattributes saveCFoil MACOR_style
|
||||
#*/musr/command visattributes log_saveAfterTD darkred
|
||||
/musr/command visattributes log_BSpot darkred
|
||||
|
||||
# One can set visible attrib. also on a MATERIAL basis, rather than on log_VOL.
|
||||
# E.g. /musr/command visattributes Steel red
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- Setting the ELECTRIC and MAGNETIC fields --
|
||||
################################################################################################################
|
||||
|
||||
# Use ABSOLUTE coordinates to specify the field position (i.e. with respect to GLOBAL WORLD)!
|
||||
# Default field units: Magnetic - T, Electric - kV/mm (or kV for E-field maps).
|
||||
# NOTE: Applying a field to an invisible log_vol makes is visible!
|
||||
|
||||
### Electric field at TRIGGER Detector TD: Three different uniform fields
|
||||
/musr/command globalfield Trigg0_field 45 45 5 uniform 0. 0. -1149.15 log_TriggE0 0 0 0 0 0 0.373
|
||||
/musr/command globalfield Trigg1_field 45 45 4 uniform 0. 0. -1140. log_TriggE1 0 0 0 0 0 -0.02375
|
||||
/musr/command globalfield Trigg2_field 45 45 4.9497 uniform 0. 0. -1089.75 log_TriggE2 0 0 0 0 0 0.041416
|
||||
/musr/command globalfield Trigg3_field 45 45 4 uniform 0. 0. -1038.0 log_TriggE3 0 0 0 0 0 -0.49375
|
||||
|
||||
|
||||
### Electric field at Einzel LENS 3 - from folded 2D axial field map (f - folded, i.e. symmetric)
|
||||
# Typically V = +8.7 kV for a muon beam at 15 keV. Use either 2DE L3_Erz.map or
|
||||
#
|
||||
# ATTENTION: The electric field is ANTI-symmetric: DO NOT use folded field map L3_Erz4.map!!
|
||||
#
|
||||
/musr/command globalfield Lens3_field 0. 0. -567. fromfile 2DE L3_Erz.map log_L3VA 8.352
|
||||
# To change the field in regular steps (e.g. for testing) use (f_min f_max step_no), e.g.:
|
||||
#*/musr/command globalfield Lens3_field 0. 0. -567. fromfile 2DE L3_Erz.map log_L3VA 7 11 5
|
||||
|
||||
|
||||
### Electric field at RING ANODE - from 3DE field map
|
||||
# Typically set at +11.0 kV for a muon beam at 15 keV
|
||||
# To create an arbitrary configuration, switch on all fields and set different potentials.
|
||||
#######/musr/command globalfield RngAnU_field 0. 0. -167.00 fromfile 3DE EM_3D_extc.map log_RA_U 11.0
|
||||
/musr/command globalfield RngAnL_field 0. 0. -143.06 fromfile 3DE EM_3D_ext_gridf.map log_RA_L 10.145
|
||||
/musr/command globalfield RngAnR_field 0. 0. -143.02 fromfile 3DE EM_3D_ext_gridf.map log_RA_R 10.955
|
||||
/musr/command globalfield RngAnU_field 0. 0. -143.00 fromfile 3DE EM_3D_ext_gridf.map log_RA_U 10.560
|
||||
/musr/command globalfield RngAnD_field 0. 0. -143.04 fromfile 3DE EM_3D_ext_gridf.map log_RA_D 10.569
|
||||
|
||||
### LAST FIELD OK: EM_3D_ext2f.map
|
||||
# EXTENDED MAPS (from -28 to +20 mm) EM_3D_extc.map or EM_3D_extf.map (coord + field or field only)
|
||||
# "Best" results with EM_RA_3D.map, even though this is not a precise map (poor meshing).
|
||||
#RA_1kV_upf_raw.map
|
||||
#RA_1kV_upf.map # EM_extendf2.map give rise to "strange spots" -> lem4_1047_RA13.eps
|
||||
|
||||
### Electric field at SAMPLE space. Three possible field maps: Sample, G1 and G2 (closest to sample)
|
||||
# To create an arbitrary configuration, switch on all fields and set different potentials.
|
||||
# Field extension along z: 50 mm. Center of MCPV at z = -92.5 mm. Sample face at: z = 108.5 (4 mm thick - SAH2).
|
||||
# Position of the field: (-92.5 - 50/2) + (108.5 - 4/2) = -11 mm wrt. WORLD! =>
|
||||
#*/musr/command globalfield Sample_field 0. 0. -11.0 fromfile 2DE sample_Erz.map log_MCPV 9.0
|
||||
#*/musr/command globalfield Guard2_field 0. 0. -11.0 fromfile 2DE guard2_Erz.map log_MCPV 6.0
|
||||
#*/musr/command globalfield Guard1_field 0. 0. -11.0 fromfile 2DE guard1_Erz.map log_MCPV 3.0
|
||||
|
||||
|
||||
### Magnetic field at SAMPLE space (use either a uniform field or a field map).
|
||||
# Use either DMCP or MCPV to apply a CONSTANT field strictly to the sample or also to the surroundings, resp.!
|
||||
#*/musr/command globalfield Magnet_field ? ? ? uniform 0. 0. 14.5 log_DMCP 0 0.005 0 0 0 0
|
||||
# Use field map to set field to 20 G TF
|
||||
# Extended map has -100/100 cm z extension, field center at +70, original -85/85, center at +85
|
||||
#######/musr/command globalfield Magnet_field 0. 0. -836.0 fromfile 2DB sample_Brz.map log_IPV 0.002
|
||||
#*/musr/command globalfield Magnet_field 0. 0. -686.0 fromfile 2DB sample_Brz_ext.map log_L3VA 0.002
|
||||
|
||||
|
||||
# Set parameters for particle tracking in an EM field
|
||||
/musr/command globalfield setparameter SetLargestAcceptableStep 5
|
||||
/musr/command globalfield setparameter SetMinimumEpsilonStep 5e-5
|
||||
/musr/command globalfield setparameter SetMaximumEpsilonStep 0.001
|
||||
/musr/command globalfield setparameter SetDeltaOneStep 0.1
|
||||
/musr/command globalfield setparameter SetDeltaIntersection 0.01
|
||||
/musr/command globalfield printparameters
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- Testing the ELECTRIC and MAGNETIC fields (OPTIONAL) --
|
||||
################################################################################################################
|
||||
|
||||
# FIELD CHECKS at different beam transport components (from trigg. to sample)
|
||||
# All distances in mm and in GLOBAL coordinates (preferably at field center)
|
||||
# The test points below are just some examples. Any point can be checked.
|
||||
|
||||
# Trigger 0
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1149.15
|
||||
|
||||
# Trigger 1
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1140.
|
||||
# Trigger 2
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1089.75
|
||||
# Trigger 3
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1038.0
|
||||
|
||||
# Einzel Lens 3 - L3 (center at -567.0, but max field at rel. +/-62 mm)
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -507.0
|
||||
|
||||
# Ring Anode - RA (center at -167.0, but max field at rel. -16/+132 mm)
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -35.0
|
||||
|
||||
# Sample space (center at -11.0, but max field at rel. +24 mm)
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. 13.0
|
||||
|
||||
# Check magnetic field at sample space
|
||||
#*/musr/command globalfield printFieldValueAtPoint 10. 0. 13.0
|
||||
# Check magnetic field at the lower field end limit
|
||||
#*/musr/command globalfield printFieldValueAtPoint 0. 20. -1680.
|
||||
|
||||
|
||||
|
||||
###################################################################################
|
||||
######################### P H Y S I C S P R O C E S S E S ##################
|
||||
###################################################################################
|
||||
# --- Low Energy (default) ---
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyPhotoElectric
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyCompton
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyGammaConversion
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyRayleigh
|
||||
/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
/musr/command process addProcess e- G4LowEnergyIonisation -1 2 2
|
||||
/musr/command process addProcess e- G4LowEnergyBremsstrahlung -1 -1 3
|
||||
/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
/musr/command process addProcess e+ G4eIonisation -1 2 2
|
||||
/musr/command process addProcess e+ G4eBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess e+ G4eplusAnnihilation 0 -1 4
|
||||
#
|
||||
# --- High Energy ---
|
||||
#/musr/command process addDiscreteProcess gamma G4PhotoElectricEffect
|
||||
#/musr/command process addDiscreteProcess gamma G4ComptonScattering
|
||||
#/musr/command process addDiscreteProcess gamma G4GammaConversion
|
||||
#/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
#/musr/command process addProcess e- G4eIonisation -1 2 2
|
||||
#/musr/command process addProcess e- G4eBremsstrahlung -1 3 3
|
||||
#/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
#/musr/command process addProcess e+ G4eIonisation -1 2 2
|
||||
#/musr/command process addProcess e+ G4eBremsstrahlung -1 3 3
|
||||
#/musr/command process addProcess e+ G4eplusAnnihilation 0 -1 4
|
||||
#
|
||||
# --- Penelope ---
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopePhotoElectric
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeCompton
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeGammaConversion
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeRayleigh
|
||||
#/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
#/musr/command process addProcess e- G4PenelopeIonisation -1 2 2
|
||||
#/musr/command process addProcess e- G4PenelopeBremsstrahlung -1 -1 3
|
||||
#/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
#/musr/command process addProcess e+ G4PenelopeIonisation, -1 2 2
|
||||
#/musr/command process addProcess e+ G4PenelopeBremsstrahlung, -1 -1 3
|
||||
#/musr/command process addProcess e+ G4PenelopeAnnihilation, 0 -1 4
|
||||
#
|
||||
# --- Muons ---
|
||||
/musr/command process addProcess mu+ G4MultipleScattering -1 1 1
|
||||
#/musr/command process addProcess mu+ MultipleAndCoulombScattering -1 1 1 goulombRegion
|
||||
#/musr/command process addDiscreteProcess mu+ G4CoulombScattering
|
||||
/musr/command process addProcess mu+ G4MuIonisation -1 2 2
|
||||
/musr/command process addProcess mu+ G4MuBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess mu+ G4MuPairProduction -1 4 4
|
||||
/musr/command process addProcess mu- G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess mu- G4CoulombScattering
|
||||
/musr/command process addProcess mu- G4MuIonisation -1 2 2
|
||||
/musr/command process addProcess mu- G4MuBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess mu- G4MuPairProduction -1 4 4
|
||||
# --- Muonium ---
|
||||
/musr/command process addProcess mu+ musrMuFormation -1 -1 2
|
||||
#cks - the following line not supported yet, has to be tested (at the moment, musrMuScatter is hard wired in the musrPhysicsList.cc):
|
||||
#/musr/command process addProcess Mu musrMuScatter -1 -1 1
|
||||
###################################################################################
|
||||
######################### R O O T O U T P U T ##############################
|
||||
###################################################################################
|
||||
#/musr/command rootOutput runID off
|
||||
#/musr/command rootOutput eventID off
|
||||
#/musr/command rootOutput weight off
|
||||
#/musr/command rootOutput BFieldAtDecay off
|
||||
#/musr/command rootOutput muIniPosX off
|
||||
#/musr/command rootOutput muIniPosY off
|
||||
#/musr/command rootOutput muIniPosZ off
|
||||
#/musr/command rootOutput muIniMomX off
|
||||
#/musr/command rootOutput muIniMomY off
|
||||
#/musr/command rootOutput muIniMomZ off
|
||||
#/musr/command rootOutput muIniPolX off
|
||||
#/musr/command rootOutput muIniPolY off
|
||||
#/musr/command rootOutput muIniPolZ off
|
||||
#/musr/command rootOutput muDecayDetID off
|
||||
#/musr/command rootOutput muDecayPosX off
|
||||
#/musr/command rootOutput muDecayPosY off
|
||||
#/musr/command rootOutput muDecayPosZ off
|
||||
#/musr/command rootOutput muDecayTime off
|
||||
#/musr/command rootOutput muDecayPolX off
|
||||
#/musr/command rootOutput muDecayPolY off
|
||||
#/musr/command rootOutput muDecayPolZ off
|
||||
#/musr/command rootOutput muTargetTime off
|
||||
#/musr/command rootOutput muTargetPolX off
|
||||
#/musr/command rootOutput muTargetPolY off
|
||||
#/musr/command rootOutput muTargetPolZ off
|
||||
#/musr/command rootOutput muM0Time off
|
||||
#/musr/command rootOutput muM0PolX off
|
||||
#/musr/command rootOutput muM0PolY off
|
||||
#/musr/command rootOutput muM0PolZ off
|
||||
/musr/command rootOutput muM1Time off
|
||||
/musr/command rootOutput muM1PolX off
|
||||
/musr/command rootOutput muM1PolY off
|
||||
/musr/command rootOutput muM1PolZ off
|
||||
/musr/command rootOutput muM2Time off
|
||||
/musr/command rootOutput muM2PolX off
|
||||
/musr/command rootOutput muM2PolY off
|
||||
/musr/command rootOutput muM2PolZ off
|
||||
#/musr/command rootOutput posIniMomX off
|
||||
#/musr/command rootOutput posIniMomY off
|
||||
#/musr/command rootOutput posIniMomZ off
|
||||
#/musr/command rootOutput fieldNomVal off
|
||||
#/musr/command rootOutput det_ID off
|
||||
#/musr/command rootOutput det_edep off
|
||||
#/musr/command rootOutput det_edep_el off
|
||||
#/musr/command rootOutput det_edep_pos off
|
||||
#/musr/command rootOutput det_edep_gam off
|
||||
#/musr/command rootOutput det_edep_mup off
|
||||
#/musr/command rootOutput det_nsteps off
|
||||
#/musr/command rootOutput det_length off
|
||||
#/musr/command rootOutput det_start off
|
||||
#/musr/command rootOutput det_end off
|
||||
#/musr/command rootOutput det_x off
|
||||
#/musr/command rootOutput det_y off
|
||||
#/musr/command rootOutput det_z off
|
||||
#/musr/command rootOutput det_kine off
|
||||
/musr/command rootOutput det_VrtxKine off
|
||||
/musr/command rootOutput det_VrtxX off
|
||||
/musr/command rootOutput det_VrtxY off
|
||||
/musr/command rootOutput det_VrtxZ off
|
||||
/musr/command rootOutput det_VrtxVolID off
|
||||
/musr/command rootOutput det_VrtxProcID off
|
||||
/musr/command rootOutput det_VrtxTrackID off
|
||||
/musr/command rootOutput det_VrtxParticleID off
|
||||
/musr/command rootOutput det_VvvKine off
|
||||
/musr/command rootOutput det_VvvX off
|
||||
/musr/command rootOutput det_VvvY off
|
||||
/musr/command rootOutput det_VvvZ off
|
||||
/musr/command rootOutput det_VvvVolID off
|
||||
/musr/command rootOutput det_VvvProcID off
|
||||
/musr/command rootOutput det_VvvTrackID off
|
||||
/musr/command rootOutput det_VvvParticleID off
|
||||
### Root variables that are not written out by default, but can be switched on:
|
||||
#/musr/command rootOutput fieldIntegralBx on
|
||||
#/musr/command rootOutput fieldIntegralBy on
|
||||
#/musr/command rootOutput fieldIntegralBz on
|
||||
#/musr/command rootOutput fieldIntegralBz1 on
|
||||
#/musr/command rootOutput fieldIntegralBz2 on
|
||||
#/musr/command rootOutput fieldIntegralBz3 on
|
||||
#
|
||||
################################################################################################################
|
||||
# -- Setting simulation PARAMETERS --
|
||||
################################################################################################################
|
||||
|
||||
# Set the overall range cut (default 0.1 mm)
|
||||
#*/run/setCut 1 mm
|
||||
|
||||
# Set the range cut on particular volumes (in mm)
|
||||
#/musr/command SetUserLimits log_CFoil 1e-8 -1 -1 -1 -1
|
||||
#*/musr/command SetUserLimits log_target 0.01 -1 -1 -1 -1
|
||||
#*/musr/command SetUserLimits log_targetscint 0.01 -1 -1 -1 -1
|
||||
#*/musr/command SetUserLimits log_cryostatscint 0.01 -1 -1 -1 -1
|
||||
|
||||
# Set particle energy cuts on particular volumes (in MeV)
|
||||
#/musr/command SetUserLimits log_World ustepMax(mm) utrakMax(mm) utimeMax(ns) uekinMin(MeV) urangMin(mm)
|
||||
/musr/command SetUserLimits log_World -1 -1 -1 1e-7 -1
|
||||
|
||||
# Store ALL the events in a ROOT tree or just the interesting ones? (default is true)
|
||||
#*/musr/command storeOnlyEventsWithHits false
|
||||
|
||||
# Set the minimum time separation between two subsequent signals in the same detector (in ns)
|
||||
/musr/command signalSeparationTime 0.1
|
||||
|
||||
# Override runID number
|
||||
#*/musr/run/runID 21
|
||||
|
||||
# Set the frequency of event printing
|
||||
/musr/run/howOftenToPrintEvent 1000
|
||||
|
||||
# RANDOM option choices: (specify the random number generator initialisation)
|
||||
# 0 ... no initialisation (default)
|
||||
# 1 ... use actual computer time to initialise now
|
||||
# 2 ... use event number to initialise at the beginning of each event
|
||||
# 3 ... read in the random no. initial values for each event from a file
|
||||
/musr/run/randomOption 2
|
||||
|
||||
# VISUALIZATION options
|
||||
# To enable or disable visualization uncomment one of these lines
|
||||
# To modify visualization options edit the file vis.mac
|
||||
/vis/disable
|
||||
#*/control/execute vis.mac
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- Setting PARTICLE GUN parameters --
|
||||
################################################################################################################
|
||||
|
||||
# Default momentum direction: 001, i.e. 0z.
|
||||
# Default muon spin direction: 100, i.e. 0x.
|
||||
# Default particle type: mu+ (can be changed to Mu)
|
||||
|
||||
# Set particle type
|
||||
#*/gun/particle Mu
|
||||
/gun/particle mu+
|
||||
|
||||
# Set beam vertex
|
||||
# CFoil at -1144 mm, acceleration starts at -1154.15 mm
|
||||
/gun/vertex 0. 0. -1155. mm
|
||||
|
||||
# A point-like uniform beam
|
||||
#/gun/vertexsigma -0.1 -0.1 0 mm
|
||||
|
||||
# Set beam transverse spread (default GAUSSIAN spread)
|
||||
# If FWHM = 10 mm ==> sigma = 10/2.354 = 4.2481 mm (last 0 is a dummy value)
|
||||
# Negative sigma values => random FLAT RECTANGULAR distribution (area 2x.2y)
|
||||
# Use vertexboundary with (vb < sigma_xy) to obtain a CIRCULAR beam spot
|
||||
# /gun/vertexsigma 0 0 0 mm ==> Very SLOW with mag. field ON and centered beam
|
||||
#*/gun/vertexsigma 42.5 42.5 0 mm
|
||||
/gun/vertexsigma -20 -20 0 mm
|
||||
/gun/vertexboundary 20 -1e6 1e6 mm
|
||||
|
||||
# /gun/vertexboundary: rMaxAllowed, zMinAllowed, zMaxAllowed # Beam AND gating
|
||||
#*/gun/vertexboundary 7 -1314.4 -1305 mm
|
||||
# Without restrictions in z, but only on r:
|
||||
#*/gun/vertexboundary 3 -1e6 1e6 mm
|
||||
|
||||
# Set beam momentum (USE only as an ALTERNATIVE to setting energy!)
|
||||
# /gun/momentum 0 0 29.79 MeV
|
||||
#*/gun/momentum 0 0 1.8 MeV
|
||||
# Energy loss at p = 1.2 MeV/c (E = 6.8 keV) => 1.23 +/- 0.2 keV
|
||||
# Energy loss at p = 1.8 MeV/c (E = 15.3 keV) => 1.25 +/- 0.3 keV
|
||||
# 1.2 MeV/c -> 6.8 keV, 1.8 MeV/c -> 15.3 keV
|
||||
# muon rest mass = 105.658 MeV/c2
|
||||
|
||||
# Set muon energy before hitting TD; a constant field in front of the C-foil accelerates the muons
|
||||
# to add 3.73 keV
|
||||
/gun/kenergy 15.0 keV
|
||||
|
||||
# Set beam momentum direction
|
||||
/gun/direction 0.0 0.0 1.0
|
||||
|
||||
# Set muon spin direction
|
||||
/gun/muonPolarizVector 1 0 0
|
||||
|
||||
|
||||
# Other useful test parameters:
|
||||
#
|
||||
# FWHM = 3% ==> sigma = 29.79*0.03/2.354 = 0.37965 MeV/c
|
||||
#*/gun/momentumsmearing 0.37965 MeV
|
||||
#---/gun/momentumboundary: pMinAllowed, pMaxAllowed, dummy
|
||||
#*/gun/momentumboundary 20 40 0 MeV
|
||||
#---/gun/tilt: xangle, yangle, dummy
|
||||
#*/gun/tilt 0 0.5 0 deg
|
||||
#---/gun/tiltsigma: xangleSigma, yangleSigma, dummy (1 degree at 1 m => 17 mm)
|
||||
#*/gun/tiltsigma 0.2 0.2 0 deg
|
||||
#*/gun/pitch 0.5 deg
|
||||
#---/gun/decaytimelimits: decayMin, decayMax, decayTime
|
||||
#*/gun/decaytimelimits 10400 10420 2197.03 ns
|
||||
|
||||
# Selectively inactivate or activate sensitive detectors
|
||||
#*/hits/inactivate /musr/ScintSD
|
||||
|
||||
# Only for code debugging!
|
||||
#/tracking/verbose 1
|
||||
|
||||
# BEAM ON
|
||||
#*/run/beamOn 1000000
|
||||
#*/run/beamOn 2
|
||||
/run/beamOn 1000
|
||||
|
697
run/1050_old_version_WILL_NOT_RUN_WITH_musrSim.mac
Normal file
697
run/1050_old_version_WILL_NOT_RUN_WITH_musrSim.mac
Normal file
@ -0,0 +1,697 @@
|
||||
# Macro file for musr.cc - Construct detector, set fields and other parameters.
|
||||
# Last modified by T. Shiroka: 17.03.2008
|
||||
#
|
||||
# Corrected TD and MCP2 distances by T. Prokscha, 07.11.2008.
|
||||
#
|
||||
|
||||
# How to run: musr 10xx.mac (append "idle" for prompt after running)
|
||||
# musr 10xx.mac > fname.txt (stores output on a txt file)
|
||||
|
||||
###############################################################################################
|
||||
# #
|
||||
# Specify the geometry parameters in this file (all dimensions in mm) #
|
||||
# a. Lines starting with hash marks "#" are comments #
|
||||
# b Lines starting with #* are temporary comments. Remove/modify to change the configuration #
|
||||
# c. Lines starting with /musr/command are commands for the executable program #
|
||||
# d. Lines starting with /vis, /gun, etc. are common macro commands #
|
||||
# e. Beam-line components are ordered from exp. area (MCP2) to trigger detector (TD) #
|
||||
#---------------------------------------------------------------------------------------------#
|
||||
# Syntax example (following /musr/command): #
|
||||
# construct solid_type volume_name parameters_defining_solid material position mothers_name #
|
||||
# (mothers_name starts with log_) #
|
||||
###############################################################################################
|
||||
|
||||
# For the meaning of the acronyms see also the original G3 file ugeom.F at:
|
||||
# http://savannah.psi.ch/viewcvs/trunk/simulation/geant3/src/lemsr/ugeom.F?root=nemu%2Flem&rev=2964&view=markup
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- ROTATION MATRICES --
|
||||
################################################################################################################
|
||||
|
||||
# 3 parameters -> Define Euler angles (the 4th par. is set to zero).
|
||||
# 4 parameters -> Define axis + rotation.
|
||||
# HEP computations ordinarily use the active rotation viewpoint (object is rotated NOT axes).
|
||||
# Therefore, rotations about an axis imply ACTIVE COUNTER-CLOCKWISE rotation in this package.
|
||||
# Rotation around a specified axis means counter-clockwise rot. around the positive direction of the axis.
|
||||
|
||||
# Define rotations for the field maps of Trigger and Ring Anode:
|
||||
/musr/command rotation rotTrig 0 1 0 -45
|
||||
/musr/command rotation rotRAnR 0 0 1 -90
|
||||
/musr/command rotation rotRAnL 0 0 1 90
|
||||
/musr/command rotation rotRAnD 0 0 1 180
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- LEM GEOMETRY --
|
||||
################################################################################################################
|
||||
|
||||
# WORLD = Laboratory reference frame, the origin is in the centre of the LEM sample tube
|
||||
/musr/command construct box World 250 250 2250 G4_Galactic 0 0 0 no_logical_volume norot dead -1
|
||||
# MINIMUM WORD HALF LENGTH 1250 mm!
|
||||
#/musr/command construct box World 2000 2000 4000 G4_Galactic 0 0 0 no_logical_volume norot dead -1
|
||||
|
||||
# World visual attributes (optional)
|
||||
/musr/command visattributes log_World invisible
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Sc - Scintillators: U - up, D - down, L - left, R - right (with respect to muon's view - momentum direction)
|
||||
# 8 Scintillators in two concentric rings - Inner and Outer (see also the convention for the Ring Anode)
|
||||
#===============================================================================================================
|
||||
|
||||
## Inner Scintillators - I
|
||||
/musr/command construct tubs ScIU 90 95 130 45 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 011 nofield
|
||||
/musr/command construct tubs ScIR 90 95 130 135 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 012 nofield
|
||||
/musr/command construct tubs ScID 90 95 130 225 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 013 nofield
|
||||
/musr/command construct tubs ScIL 90 95 130 315 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 014 nofield
|
||||
|
||||
## Outer Scintillators - O
|
||||
/musr/command construct tubs ScOU 96 101 130 45 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 021 nofield
|
||||
/musr/command construct tubs ScOR 96 101 130 135 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 022 nofield
|
||||
/musr/command construct tubs ScOD 96 101 130 225 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 023 nofield
|
||||
/musr/command construct tubs ScOL 96 101 130 315 90 G4_PLASTIC_SC_VINYLTOLUENE 0 0 0 log_World norot musr/ScintSD 024 nofield
|
||||
|
||||
# Visual attributes (optional)
|
||||
#*/musr/command visattributes log_ScOU SCINT_style
|
||||
#*/musr/command visattributes log_ScOD dSCINT_style
|
||||
/musr/command visattributes log_ScOL darkred
|
||||
/musr/command visattributes log_ScIL darkred
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Experimental Area - Can host EITHER the Cryostat OR the MCP2 (For the tests we usually use the MCP)
|
||||
# Delimited by the F160 and F100 (blank end) flanges
|
||||
#
|
||||
# 07/Nov/2008: correct sample tube dimensions: the new tubes have 75 mm / 78 mm inner/outer radius
|
||||
#
|
||||
#===============================================================================================================
|
||||
|
||||
# MCP - Multi-Channel Plate 2 Chamber; V - Vacuum, S - Solid # Note: VERY IMPORTANT: mcpv_z = -92.5 mm!
|
||||
# OLD way of assigning a field
|
||||
#/musr/command construct tubs MCPV 0 76.5 254.5 0 360 G4_Galactic 0 0 -92.5 log_World norot dead 100 MCPSfield
|
||||
/musr/command construct tubs MCPV 0 75.0 254.5 0 360 G4_Galactic 0 0 -92.5 log_World norot dead 100 nofield
|
||||
/musr/command construct tubs MCPS 75.0 78.0 162.0 0 360 Steel 0 0 0 log_World norot dead 101 nofield
|
||||
|
||||
# F - Flanges: F160, F100, F200 (used only when the Asymmetry check is OFF)
|
||||
# F160 - 160 CF flange upstream of MCP2 tube
|
||||
# F100 (Blank end flange) # OLD Value was 162.0
|
||||
/musr/command construct tubs F160 78.0 101.25 11 0 360 Steel 0 0 -151.0 log_World norot dead 901 nofield
|
||||
/musr/command construct tubs F100 0 75.0 10 0 360 Steel 0 0 172.0 log_World norot dead 902 nofield
|
||||
|
||||
# NOTE: Original F100 referred to MCPV (as shown below) was moved to World.
|
||||
#/musr/command construct tubs F100 0 76.5 10 0 360 Steel 0 0 264.5 log_MCPV norot dead 902 nofield
|
||||
|
||||
|
||||
# Experimental Area visual attributes (optional)
|
||||
/musr/command visattributes log_MCPV invisible
|
||||
/musr/command visattributes log_MCPS invisible
|
||||
/musr/command visattributes log_F160 blue_style
|
||||
/musr/command visattributes log_F100 blue_style
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# MCP - Micro Channel Plate Detector MCP2 (Used as an alternative to cryostat) # mcpv_z = -92.5 mm!
|
||||
#
|
||||
# We have a 324 mm long sample tube;
|
||||
# the MCP2 front side is at 142 mm from the end of the sample tube.
|
||||
# the front face of the sample plate of the cryostat is 145 mm from the end of the sample tube.
|
||||
#
|
||||
#===============================================================================================================
|
||||
|
||||
# MCPM1 - MCP Macor ring 1
|
||||
# MCPD - electron multiplying glass disk (also known as target)
|
||||
# Sensitive surface at z = 20 mm wrt. World
|
||||
# MCPM2 - MCP Macor ring 2
|
||||
#*/musr/command construct tubs MCPM1 24 32.5 0.75 0 360 Macor 0 0 105.75 log_MCPV norot dead 201 nofield
|
||||
# Use it either as (DMCP-musr/ScintSD) - no info on mu+ polariz., or as (target-dead) with info on mu+ polariz.
|
||||
#*/musr/command construct tubs target 0 25.0 1.50 0 360 MCPglass 0 0 108.0 log_MCPV norot dead 032 nofield
|
||||
/musr/command construct tubs MCPM2 24 32.5 0.75 0 360 Macor 0 0 116.25 log_MCPV norot dead 203 nofield
|
||||
# NOTE: To intercept ALL the incoming muons, comment the DMCP and MCPM1 lines above and uncomment this one:
|
||||
#*/musr/command construct tubs DMCP 0 76.5 1.5 0 360 MCPglass 0 0 108 log_MCPV norot musr/ScintSD 202 nofield
|
||||
/musr/command construct tubs target 0 75.0 1.5 0 360 MCPglass 0 0 114 log_MCPV norot musr/ScintSD 202 nofield
|
||||
|
||||
# MCSR - Stainless Steel Ring for MCP2 mounting (modelled as a box with a circular hole)
|
||||
# MCVR - "Vacuum Ring" (circular hole)
|
||||
/musr/command construct box MCSR 36.5 36.5 1 Steel 0 0 118.5 log_MCPV norot dead 204 nofield
|
||||
/musr/command construct tubs MCVR 0 27.5 1 0 360 G4_Galactic 0 0 0 log_MCSR norot dead 205 nofield
|
||||
|
||||
# MCPA = MCP Anode (modelled as a box with two symmetrically subtracted "vacuum" disks)
|
||||
# ANVA1 - Anode "Vacuum" 1 - Part of MCP Anode
|
||||
# ANVA2 - Anode "Vacuum" 2 - Part of MCP Anode
|
||||
/musr/command construct box MCPA 36.5 36.5 4 Steel 0 0 129.5 log_MCPV norot dead 206 nofield
|
||||
/musr/command construct tubs ANVA1 0 27.5 1.5 0 360 G4_Galactic 0 0 -2.5 log_MCPA norot dead 207 nofield
|
||||
/musr/command construct tubs ANVA2 0 27.5 1.5 0 360 G4_Galactic 0 0 2.5 log_MCPA norot dead 208 nofield
|
||||
|
||||
# MCSS - MCP Stainless Steel Support Ring
|
||||
/musr/command construct tubs MCSS 40 48 2.5 0 360 Steel 0 0 162.3 log_MCPV norot dead 209 nofield
|
||||
|
||||
|
||||
# MCP2 visual attributes (optional)
|
||||
#/musr/command visattributes log_DMCP MCP_style
|
||||
#*/musr/command visattributes log_target MCP_style
|
||||
#*/musr/command visattributes log_MCPM1 MACOR_style
|
||||
/musr/command visattributes log_MCPM2 MACOR_style
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# CRY - Cryostat - Used as an ALTERNATIVE to MCP2 - Uncomment lines with #*. (Offset = 0.0 cm)
|
||||
#
|
||||
# at the moment, sample plate front face is still at z = 14.0mm --> should be changed to 17mm.
|
||||
#===============================================================================================================
|
||||
|
||||
# SAH - SAmple Holder components (Cu plate) Cu or Al plates 1. Cu plate (sample holder) on Cold finger, 0.5cm
|
||||
# SAPH - SAPpHire plate mounted between 1st and 2nd Cu plates, 6 mm thick, 60 mm diameter.
|
||||
# SAH3 is ignored because currently NOT use.
|
||||
#*/musr/command construct tubs SAH1 0 35 2.5 0 360 G4_Cu 0 0 119.0 log_MCPV norot dead 251 nofield
|
||||
#*/musr/command construct tubs SAH2 0 35 2 0 360 G4_Cu 0 0 108.5 log_MCPV norot dead 252 nofield
|
||||
#/musr/command construct tubs SAH3 20 35 0.5 0 360 G4_Cu 0 0 106.0 log_MCPV norot dead 253 nofield
|
||||
#*/musr/command construct tubs SAPH 0 30 3 0 360 G4_ALUMINUM_OXIDE 0 0 113.5 log_MCPV norot dead 254 nofield
|
||||
|
||||
# Other components of the CRYostat (dimensions and position of CRY4 are only approx. because unknown)
|
||||
# COFI - COld FInger
|
||||
# CRY1 - End plate of cryostat (7 mm thick, 30 mm diameter)
|
||||
# CRY2 - Heat exchanger (assuming a 10 mm opening - Original dimensions not known.) # OLD pos. 160.0
|
||||
# CRY3 - Mounting ring for He-shield
|
||||
# CRY4 - 2 mm thick plate for mounting ring. This is just to close the downstream side.
|
||||
# CRSH - Lateral He-shield
|
||||
# CRSH2- Frontal He-shield Ring
|
||||
#*/musr/command construct tubs COFI 0 27.5 5 0 360 G4_Cu 0 0 126.5 log_MCPV norot dead 261 nofield
|
||||
#*/musr/command construct tubs CRY1 0 15 3.5 0 360 G4_Cu 0 0 135.0 log_MCPV norot dead 262 nofield
|
||||
#*/musr/command construct tubs CRY2 5 15 25 0 360 G4_Cu 0 0 163.5 log_MCPV norot dead 263 nofield
|
||||
#*/musr/command construct tubs CRY3 38 47 5.5 0 360 G4_Cu 0 0 143.5 log_MCPV norot dead 264 nofield
|
||||
#*/musr/command construct tubs CRY4 15 38 1 0 360 G4_Cu 0 0 143.5 log_MCPV norot dead 265 nofield
|
||||
#*/musr/command construct tubs CRSH 47 48 45 0 360 G4_Cu 0 0 108.5 log_MCPV norot dead 266 nofield
|
||||
#*/musr/command construct tubs CRSH2 30 48 0.5 0 360 G4_Cu 0 0 63.0 log_MCPV norot dead 267 nofield
|
||||
|
||||
# Electrical Field Guard Rings (distance between the guard rings: 16 mm)
|
||||
#*/musr/command construct tubs Guard1 29 38 1.5 0 360 G4_Cu 0 0 76.0 log_MCPV norot dead 271 nofield
|
||||
#*/musr/command construct tubs Guard2 29 38 1.5 0 360 G4_Cu 0 0 92.0 log_MCPV norot dead 272 nofield
|
||||
|
||||
|
||||
# Cryostat visual attributes (optional)
|
||||
#*/musr/command visattributes log_SAH1 oxsteel
|
||||
#*/musr/command visattributes log_SAH2 oxsteel
|
||||
#*/musr/command visattributes log_SAPH MACOR_style
|
||||
#/musr/command visattributes log_SAH3 oxsteel
|
||||
#/musr/command visattributes log_CRSH invisible
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# RA - Ring Anode, M - middle part (closer to Ground Anode), E - end part (farther from the Ground Anode)
|
||||
# U - up, D - down, L - left, R - right (with respect to muon's view - momentum direction)
|
||||
# Note: 3.0 mm HALF gap at 45.1469 mm half radius => delta_ang = asin(3.0/45.1469)*180/pi = 3.81 deg.
|
||||
# Note: delta_ang = 3.1744 deg. for 2.5 mm HG. The angular extension goes e.g. from (45 + da) to (90 - 2*da).
|
||||
# Note: Ring Anode - Ground Anode distance was 15 mm => CHANGED to 12 mm! (Positions: 11.5 -> 8.5, -33.5 -> -36.5)
|
||||
#===============================================================================================================
|
||||
|
||||
# RA_Ez = -10.35+2.25 = -8.1 cm; RA_Mz= -10.35 - 2.25 = -12.6 cm; RA_Gz= -25.45+3.75 = -21.7 cm; mcpv_z = -9.25 cm
|
||||
/musr/command construct cons RA_EU 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV norot dead 301 nofield
|
||||
/musr/command construct cons RA_MU 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV norot dead 302 nofield
|
||||
/musr/command construct cons RA_ER 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV rotRAnR dead 303 nofield
|
||||
/musr/command construct cons RA_MR 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV rotRAnR dead 304 nofield
|
||||
/musr/command construct cons RA_ED 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV rotRAnD dead 305 nofield
|
||||
/musr/command construct cons RA_MD 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV rotRAnD dead 306 nofield
|
||||
/musr/command construct cons RA_EL 45.1469 62.5 33.5 39.0 22.5 48.81 82.38 Steel 0 0 8.5 log_MCPV rotRAnL dead 307 nofield
|
||||
/musr/command construct cons RA_ML 56.7937 62.5 45.147 62.5 22.5 48.81 82.38 Steel 0 0 -36.5 log_MCPV rotRAnL dead 308 nofield
|
||||
|
||||
|
||||
# Dummy, thin cylindres used for applying the SAME RA field-map (ROTATED by 90 deg.) to different anodes.
|
||||
# NOTE: EM field cannot be applied to non simply connected bodies, as e.g. rings, cones, tori, etc.!
|
||||
/musr/command construct tubs RA_U 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.50 log_MCPV norot dead 322 nofield
|
||||
/musr/command construct tubs RA_R 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.52 log_MCPV rotRAnR dead 324 nofield
|
||||
/musr/command construct tubs RA_D 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.54 log_MCPV rotRAnD dead 326 nofield
|
||||
/musr/command construct tubs RA_L 0 0.01 0.005 0 360 G4_Galactic 0 0 -50.56 log_MCPV rotRAnL dead 328 nofield
|
||||
|
||||
|
||||
# RA_G - Ring Anode Ground Cylinder
|
||||
/musr/command construct tubs RA_G 58 62.5 58.0 0 360 G4_Cu 0 0 -129.0 log_MCPV norot dead 351 nofield
|
||||
|
||||
|
||||
# Ring Anodes visual attributes (optional)
|
||||
/musr/command visattributes log_RA_EU oxsteel
|
||||
/musr/command visattributes log_RA_MR oxsteel
|
||||
/musr/command visattributes log_RA_G Grid_style
|
||||
|
||||
|
||||
# Alternative placement using World as a mother volume (mcpv_z = -92.5 mm). Check latter. These values refer to a 5 mm GAP!
|
||||
#/musr/command construct cons RA_EU 45.1469 62.5 33.5 39.0 22.5 48.1711 83.6578 Steel 0 0 -81 log_World norot dead 301 nofield
|
||||
#/musr/command construct cons RA_MU 56.7937 62.5 45.147 62.5 22.5 48.1711 83.6578 Steel 0 0 -126 log_World norot dead 302 nofield
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Gate Valve Area - Hosts the Ground Anode (upstream part of the Ring Anode) - Delimited by L3F1 and F200 flanges
|
||||
#===============================================================================================================
|
||||
|
||||
# GATS - 200 CF flange upstream of MCP2 tube covering the whole length of the gate valve chamber. For simplicity, we
|
||||
# choose the INNER diameter of the GATe valve Steel tube the same as the OUTER diameter of F200 (200 CF flange)
|
||||
/musr/command construct tubs GATS 103.25 126.5 92.5 0 360 Steel 0 0 -254.5 log_World norot dead 371 nofield
|
||||
|
||||
# Vacuum "Ring" (to avoid intersections with MCPV) - Not needed if world is already filled with vacuum.
|
||||
#*/musr/command construct tubs GATV 76.5 103.25 92.5 0 360 G4_Galactic 0 0 -254.5 log_World norot dead 370 nofield
|
||||
|
||||
# F200 - 200 CF flange upstream of MCP2 tube to connect to gate valve chamber
|
||||
/musr/command construct tubs F200 76.5 103.25 12 0 360 Steel 0 0 -174.0 log_World norot dead 372 nofield
|
||||
|
||||
# NOTE: When using GATV comment the F200 above and uncomment the following (change mother to log_GATV).
|
||||
#*/musr/command construct tubs F200 76.5 103.25 12 0 360 Steel 0 0 80.5 log_GATV norot dead 372 nofield
|
||||
|
||||
|
||||
# Gate Valve Area visual attributes (optional)
|
||||
/musr/command visattributes log_GATS SCINT_style
|
||||
/musr/command visattributes log_F200 blue_style
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# L3 - 3rd Einzel Lens # L3z = -56.7 cm. ATT: DUMMY FIELD change to electric L3Efield!
|
||||
#===============================================================================================================
|
||||
# Lens Gap = 12.0 mm => G/D = 12/130 ~ 0.1 (Lens Gap = gap between Ground and Anode, D - Diameter)
|
||||
|
||||
# L3 envelope (Tube + Flanges)
|
||||
# L3VA - Lens 3 Vacuum
|
||||
# L3ST - Lens 3 Steel tube (inner dia: 200 mm, outer dia: 206 mm, length: 720 mm)
|
||||
# L3F1 - Lens 3 Flange 1, z = L3z + 208 mm
|
||||
# L3F2 - Lens 3 Flange 2, z = L3z - 208 mm
|
||||
|
||||
/musr/command construct tubs L3VA 0 100 220 0 360 G4_Galactic 0 0 -567 log_World norot dead 400 nofield
|
||||
/musr/command construct tubs L3ST 100 103 220 0 360 Steel 0 0 -567 log_World norot dead 401 nofield
|
||||
/musr/command construct tubs L3F1 103 126.5 12 0 360 Steel 0 0 -359 log_World norot dead 402 nofield
|
||||
/musr/command construct tubs L3F2 103 126.5 12 0 360 Steel 0 0 -775 log_World norot dead 403 nofield
|
||||
|
||||
# GPn - Ground Potential Electrodes
|
||||
# n = 1-4 and 5-8 - components of the Ground Electrodes
|
||||
# GP1 - Ground Electrode (inner dia: 130 mm, outer dia: 134 mm, length: 133 mm)
|
||||
# GP2 - outer electrode surface (LN2 cooling vessel)
|
||||
# GP3 - first ring cap
|
||||
# GP4 - second ring cap
|
||||
|
||||
# n = 1-4 - Ground Electrode 1 (further from TD). See above for the meaning of acronyms.
|
||||
/musr/command construct tubs L3GP1 65 67 66.5 0 360 Steel 0 0 133.5 log_L3VA norot dead 421 nofield
|
||||
/musr/command construct tubs L3GP2 81 83 66.5 0 360 Steel 0 0 133.5 log_L3VA norot dead 422 nofield
|
||||
/musr/command construct tubs L3GP3 67 81 4 0 360 Steel 0 0 196.0 log_L3VA norot dead 423 nofield
|
||||
/musr/command construct tubs L3GP4 67 81 4 0 360 Steel 0 0 71.0 log_L3VA norot dead 424 nofield
|
||||
|
||||
# n = 5-8 - Ground Electrode 2 (closer to TD). See above for the meaning of acronyms.
|
||||
/musr/command construct tubs L3GP5 65 67 66.5 0 360 Steel 0 0 -133.5 log_L3VA norot dead 431 nofield
|
||||
/musr/command construct tubs L3GP6 81 83 66.5 0 360 Steel 0 0 -133.5 log_L3VA norot dead 432 nofield
|
||||
/musr/command construct tubs L3GP7 67 81 4 0 360 Steel 0 0 -196.0 log_L3VA norot dead 433 nofield
|
||||
/musr/command construct tubs L3GP8 67 81 4 0 360 Steel 0 0 -71.0 log_L3VA norot dead 434 nofield
|
||||
|
||||
# HP - High Potential Electrode (Central Anode - usually at +8.7 kV, for a 15 keV muon beam)
|
||||
/musr/command construct tubs L3HP 65 83 55 0 360 Steel 0 0 0 log_L3VA norot dead 451 nofield
|
||||
|
||||
|
||||
# Lens 3 visual attributes (optional)
|
||||
/musr/command visattributes log_L3VA invisible
|
||||
/musr/command visattributes log_L3ST invisible
|
||||
/musr/command visattributes log_L3HP darkred
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# IP - Intermediate Piece (between Trigger Detector and Einzel Lens 3)
|
||||
# Original name was CGate - B-field Coil Compensation Gate?! # CompGatez = -86.55 cm; // L3z - 22 - 7.85 cm
|
||||
#===============================================================================================================
|
||||
# IPV (but also others) are just empty volumes "filled" with vacuum. Sometimes used to apply EM fields to restricted areas.
|
||||
/musr/command construct tubs IPV 0 100 78.5 0 360 G4_Galactic 0 0 -865.5 log_World norot dead 500 nofield
|
||||
# IPCF - Intermediate Piece Central Flange (same as L3 Flanges)
|
||||
# IPST - Intermediate Piece Steel Tube (same diameter as L3 Steel Tube)
|
||||
/musr/command construct tubs IPCF 103 126.5 12.0 0 360 Steel 0 0 -865.5 log_World norot dead 501 nofield
|
||||
/musr/command construct tubs IPST 100 103 78.5 0 360 Steel 0 0 -865.5 log_World norot dead 502 nofield
|
||||
|
||||
|
||||
# IP visual attributes (optional)
|
||||
/musr/command visattributes log_IPV invisible
|
||||
/musr/command visattributes log_IPCF blue_style
|
||||
/musr/command visattributes log_IPST gray
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================================================
|
||||
# Trigger - Trigger Detector # Triggerz = -1092 mm; total length of TD is 110 mm; carbon foil at -1144 mm.
|
||||
#===============================================================================================================
|
||||
|
||||
# Trigger tube and relative vacuum
|
||||
/musr/command construct tubs TriggerV 0 100 148 0 360 G4_Galactic 0 0 -1092 log_World norot dead 600 nofield
|
||||
/musr/command construct tubs Trigger 100 103 148 0 360 Steel 0 0 -1092 log_World norot dead 601 nofield
|
||||
|
||||
# TF - Trigger tube flanges
|
||||
/musr/command construct tubs TF1 103 126.5 12 0 360 Steel 0 0 -956 log_World norot dead 611 nofield
|
||||
/musr/command construct tubs TF2 103 126.5 12 0 360 Steel 0 0 -1228 log_World norot dead 612 nofield
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# trigger foil is 52mm upstream of Triggerz, i.e. at -1144 mm
|
||||
#-------------------------------------------------------------
|
||||
# Carbon Foil (default HALF-thickness 0.000005147 mm, see below => CFoil thick = 10.3 nm).
|
||||
# USE THE NAME CFoil or coulombCFoil, otherwise musrMuFormation won't work!
|
||||
####/musr/command construct box CFoil 60 60 0.000005147 G4_GRAPHITE 0 0 -45 log_TriggerV norot dead 621 nofield
|
||||
/musr/command construct box CFoil 60 60 0.0000049 G4_GRAPHITE 0 0 -52.1 log_TriggerV norot dead 621 nofield
|
||||
####/musr/command construct box coulombCFoil 60 60 0.000005147 G4_GRAPHITE 0 0 -45 log_TriggerV norot dead 621 nofield
|
||||
|
||||
# Notes: NIST tables use G4_GRAPHITE with 1.7 g/cm3 and 78 eV ioniz. energy.
|
||||
# An area density of 2.20 ug/cm2 implies a CF thickn. = (2.20*1.e-6/1.70)*cm = 1.294e-5 mm - Total thickness
|
||||
# An area density of 1.75 ug/cm2 implies a CF thickn. = (1.75*1.e-6/1.70)*cm = 1.029e-5 mm - Total thickness
|
||||
# If necessary, use Graphite as defined in musrDetectorConstruction.cc and set any density.
|
||||
|
||||
# Dummy plane to intercept outgoing muons from the Carbon foil.
|
||||
#*/musr/command construct box saveCFoil 60 60 5e-4 G4_Galactic 0 0 -52.0005 log_TriggerV norot dead 623 nofield
|
||||
/musr/command construct box saveAfterTD 60 60 5e-4 G4_Galactic 0 0 58.0006 log_TriggerV norot dead 623 nofield
|
||||
|
||||
|
||||
# Electrical Field areas in the Trigger Detector
|
||||
# En = Electrical Field n: TnFieldMgr (n = 1-3)
|
||||
# Original TriggE2: [4.*sqrt(2), 4.5, 0.7/sqrt(2)] cm -> changed due to overlaps with E1 and E3
|
||||
/musr/command construct box TriggE0 45 45 5 G4_Galactic 0 0 -57.15 log_TriggerV norot dead 630 nofield
|
||||
/musr/command construct box TriggE1 45 45 4 G4_Galactic 0 0 -48.0 log_TriggerV norot dead 631 nofield
|
||||
/musr/command construct box TriggE2 45 45 4.9497 G4_Galactic 0 0 2.25 log_TriggerV rotTrig dead 632 nofield
|
||||
/musr/command construct box TriggE3 45 45 4 G4_Galactic 0 0 54.0 log_TriggerV norot dead 633
|
||||
|
||||
# Beam spot (just for having a visual idea!)
|
||||
/musr/command construct tubs BSpot 0 20 1 0 360 G4_Galactic 0 0 -63.15 log_TriggerV norot dead 650 nofield
|
||||
|
||||
|
||||
# Trigger visual attributes (optional)
|
||||
/musr/command visattributes log_TriggerV invisible
|
||||
/musr/command visattributes log_Trigger invisible
|
||||
#*/musr/command visattributes saveCFoil MACOR_style
|
||||
/musr/command visattributes log_saveAfterTD darkred
|
||||
/musr/command visattributes log_BSpot darkred
|
||||
|
||||
# One can set visible attrib. also on a MATERIAL basis, rather than on log_VOL.
|
||||
# E.g. /musr/command visattributes Steel red
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- Setting the ELECTRIC and MAGNETIC fields --
|
||||
################################################################################################################
|
||||
|
||||
# Use ABSOLUTE coordinates to specify the field position (i.e. with respect to GLOBAL WORLD)!
|
||||
# Default field units: Magnetic - T, Electric - kV/mm (or kV for E-field maps).
|
||||
# NOTE: Applying a field to an invisible log_vol makes is visible!
|
||||
|
||||
### Electric field at TRIGGER Detector TD: Three different uniform fields
|
||||
/musr/command globalfield Trigg0_field 45 45 5 uniform 0. 0. -1149.15 log_TriggE0 0 0 0 0 0 0.373
|
||||
/musr/command globalfield Trigg1_field 45 45 4 uniform 0. 0. -1140. log_TriggE1 0 0 0 0 0 -0.02375
|
||||
/musr/command globalfield Trigg2_field 45 45 4.9497 uniform 0. 0. -1089.75 log_TriggE2 0 0 0 0 0 0.041416
|
||||
/musr/command globalfield Trigg3_field 45 45 4 uniform 0. 0. -1038.0 log_TriggE3 0 0 0 0 0 -0.49375
|
||||
|
||||
|
||||
### Electric field at Einzel LENS 3 - from folded 2D axial field map (f - folded, i.e. symmetric)
|
||||
# Typically V = +8.7 kV for a muon beam at 15 keV. Use either 2DE L3_Erz.map or
|
||||
#
|
||||
# ATTENTION: The electric field is ANTI-symmetric: DO NOT use folded field map L3_Erz4.map!!
|
||||
#
|
||||
/musr/command globalfield Lens3_field 0. 0. -567. fromfile 2DE L3_Erz.map log_L3VA 6.51
|
||||
# To change the field in regular steps (e.g. for testing) use (f_min f_max step_no), e.g.:
|
||||
#*/musr/command globalfield Lens3_field 0. 0. -567. fromfile 2DE L3_Erz.map log_L3VA 7 11 5
|
||||
|
||||
|
||||
### Electric field at RING ANODE - from 3DE field map
|
||||
# Typically set at +11.0 kV for a muon beam at 15 keV
|
||||
# To create an arbitrary configuration, switch on all fields and set different potentials.
|
||||
#######/musr/command globalfield RngAnU_field 0. 0. -167.00 fromfile 3DE EM_3D_extc.map log_RA_U 11.0
|
||||
/musr/command globalfield RngAnU_field 0. 0. -143.00 fromfile 3DE EM_3D_ext_gridf.map log_RA_U 8.26
|
||||
/musr/command globalfield RngAnR_field 0. 0. -143.02 fromfile 3DE EM_3D_ext_gridf.map log_RA_R 8.26
|
||||
/musr/command globalfield RngAnD_field 0. 0. -143.04 fromfile 3DE EM_3D_ext_gridf.map log_RA_D 8.26
|
||||
/musr/command globalfield RngAnL_field 0. 0. -143.06 fromfile 3DE EM_3D_ext_gridf.map log_RA_L 8.26
|
||||
|
||||
### LAST FIELD OK: EM_3D_ext2f.map
|
||||
# EXTENDED MAPS (from -28 to +20 mm) EM_3D_extc.map or EM_3D_extf.map (coord + field or field only)
|
||||
# "Best" results with EM_RA_3D.map, even though this is not a precise map (poor meshing).
|
||||
#RA_1kV_upf_raw.map
|
||||
#RA_1kV_upf.map # EM_extendf2.map give rise to "strange spots" -> lem4_1047_RA13.eps
|
||||
|
||||
### Electric field at SAMPLE space. Three possible field maps: Sample, G1 and G2 (closest to sample)
|
||||
# To create an arbitrary configuration, switch on all fields and set different potentials.
|
||||
# Field extension along z: 50 mm. Center of MCPV at z = -92.5 mm. Sample face at: z = 108.5 (4 mm thick - SAH2).
|
||||
# Position of the field: (-92.5 - 50/2) + (108.5 - 4/2) = -11 mm wrt. WORLD! =>
|
||||
#*/musr/command globalfield Sample_field 0. 0. -11.0 fromfile 2DE sample_Erz.map log_MCPV 9.0
|
||||
#*/musr/command globalfield Guard2_field 0. 0. -11.0 fromfile 2DE guard2_Erz.map log_MCPV 6.0
|
||||
#*/musr/command globalfield Guard1_field 0. 0. -11.0 fromfile 2DE guard1_Erz.map log_MCPV 3.0
|
||||
|
||||
|
||||
### Magnetic field at SAMPLE space (use either a uniform field or a field map).
|
||||
# Use either DMCP or MCPV to apply a CONSTANT field strictly to the sample or also to the surroundings, resp.!
|
||||
#*/musr/command globalfield Magnet_field ? ? ? uniform 0. 0. 14.5 log_DMCP 0 0.005 0 0 0 0
|
||||
# Use field map to set field to 20 G TF
|
||||
# Extended map has -100/100 cm z extension, field center at +70, original -85/85, center at +85
|
||||
#######/musr/command globalfield Magnet_field 0. 0. -836.0 fromfile 2DB sample_Brz.map log_IPV 0.002
|
||||
#*/musr/command globalfield Magnet_field 0. 0. -686.0 fromfile 2DB sample_Brz_ext.map log_L3VA 0.002
|
||||
|
||||
|
||||
# Set parameters for particle tracking in an EM field
|
||||
/musr/command globalfield setparameter SetLargestAcceptableStep 5
|
||||
/musr/command globalfield setparameter SetMinimumEpsilonStep 5e-5
|
||||
/musr/command globalfield setparameter SetMaximumEpsilonStep 0.001
|
||||
/musr/command globalfield setparameter SetDeltaOneStep 0.1
|
||||
/musr/command globalfield setparameter SetDeltaIntersection 0.01
|
||||
/musr/command globalfield printparameters
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- Testing the ELECTRIC and MAGNETIC fields (OPTIONAL) --
|
||||
################################################################################################################
|
||||
|
||||
# FIELD CHECKS at different beam transport components (from trigg. to sample)
|
||||
# All distances in mm and in GLOBAL coordinates (preferably at field center)
|
||||
# The test points below are just some examples. Any point can be checked.
|
||||
|
||||
# Trigger 0
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1149.15
|
||||
|
||||
# Trigger 1
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1140.
|
||||
# Trigger 2
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1089.75
|
||||
# Trigger 3
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -1038.0
|
||||
|
||||
# Einzel Lens 3 - L3 (center at -567.0, but max field at rel. +/-62 mm)
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -507.0
|
||||
|
||||
# Ring Anode - RA (center at -167.0, but max field at rel. -16/+132 mm)
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. -35.0
|
||||
|
||||
# Sample space (center at -11.0, but max field at rel. +24 mm)
|
||||
/musr/command globalfield printFieldValueAtPoint 0. 0. 13.0
|
||||
|
||||
# Check magnetic field at sample space
|
||||
#*/musr/command globalfield printFieldValueAtPoint 10. 0. 13.0
|
||||
# Check magnetic field at the lower field end limit
|
||||
#*/musr/command globalfield printFieldValueAtPoint 0. 20. -1680.
|
||||
|
||||
|
||||
|
||||
###################################################################################
|
||||
######################### P H Y S I C S P R O C E S S E S ##################
|
||||
###################################################################################
|
||||
# --- Low Energy (default) ---
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyPhotoElectric
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyCompton
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyGammaConversion
|
||||
/musr/command process addDiscreteProcess gamma G4LowEnergyRayleigh
|
||||
/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
/musr/command process addProcess e- G4LowEnergyIonisation -1 2 2
|
||||
/musr/command process addProcess e- G4LowEnergyBremsstrahlung -1 -1 3
|
||||
/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
/musr/command process addProcess e+ G4eIonisation -1 2 2
|
||||
/musr/command process addProcess e+ G4eBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess e+ G4eplusAnnihilation 0 -1 4
|
||||
#
|
||||
# --- High Energy ---
|
||||
#/musr/command process addDiscreteProcess gamma G4PhotoElectricEffect
|
||||
#/musr/command process addDiscreteProcess gamma G4ComptonScattering
|
||||
#/musr/command process addDiscreteProcess gamma G4GammaConversion
|
||||
#/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
#/musr/command process addProcess e- G4eIonisation -1 2 2
|
||||
#/musr/command process addProcess e- G4eBremsstrahlung -1 3 3
|
||||
#/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
#/musr/command process addProcess e+ G4eIonisation -1 2 2
|
||||
#/musr/command process addProcess e+ G4eBremsstrahlung -1 3 3
|
||||
#/musr/command process addProcess e+ G4eplusAnnihilation 0 -1 4
|
||||
#
|
||||
# --- Penelope ---
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopePhotoElectric
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeCompton
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeGammaConversion
|
||||
#/musr/command process addDiscreteProcess gamma G4PenelopeRayleigh
|
||||
#/musr/command process addProcess e- G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e- G4CoulombScattering
|
||||
#/musr/command process addProcess e- G4PenelopeIonisation -1 2 2
|
||||
#/musr/command process addProcess e- G4PenelopeBremsstrahlung -1 -1 3
|
||||
#/musr/command process addProcess e+ G4MultipleScattering -1 1 1
|
||||
##/musr/command process addDiscreteProcess e+ G4CoulombScattering
|
||||
#/musr/command process addProcess e+ G4PenelopeIonisation, -1 2 2
|
||||
#/musr/command process addProcess e+ G4PenelopeBremsstrahlung, -1 -1 3
|
||||
#/musr/command process addProcess e+ G4PenelopeAnnihilation, 0 -1 4
|
||||
#
|
||||
# --- Muons ---
|
||||
/musr/command process addProcess mu+ G4MultipleScattering -1 1 1
|
||||
#/musr/command process addProcess mu+ MultipleAndCoulombScattering -1 1 1 goulombRegion
|
||||
#/musr/command process addDiscreteProcess mu+ G4CoulombScattering
|
||||
/musr/command process addProcess mu+ G4MuIonisation -1 2 2
|
||||
/musr/command process addProcess mu+ G4MuBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess mu+ G4MuPairProduction -1 4 4
|
||||
/musr/command process addProcess mu- G4MultipleScattering -1 1 1
|
||||
#/musr/command process addDiscreteProcess mu- G4CoulombScattering
|
||||
/musr/command process addProcess mu- G4MuIonisation -1 2 2
|
||||
/musr/command process addProcess mu- G4MuBremsstrahlung -1 3 3
|
||||
/musr/command process addProcess mu- G4MuPairProduction -1 4 4
|
||||
# --- Muonium ---
|
||||
/musr/command process addProcess mu+ musrMuFormation -1 -1 2
|
||||
#cks - the following line not supported yet, has to be tested (at the moment, musrMuScatter is hard wired in the musrPhysicsList.cc):
|
||||
#/musr/command process addProcess Mu musrMuScatter -1 -1 1
|
||||
################################################################################################################
|
||||
# -- Setting simulation PARAMETERS --
|
||||
################################################################################################################
|
||||
|
||||
# Set the overall range cut (default 0.1 mm)
|
||||
#*/run/setCut 1 mm
|
||||
|
||||
# Set the range cut on particular volumes (in mm)
|
||||
/musr/command SetUserLimits log_CFoil 1e-8
|
||||
#*/musr/command SetUserLimits log_target 0.01
|
||||
#*/musr/command SetUserLimits log_targetscint 0.01
|
||||
#*/musr/command SetUserLimits log_cryostatscint 0.01
|
||||
|
||||
# Set particle energy cuts on particular volumes (in MeV)
|
||||
#/musr/command SetUserMinEkine log_World 0.1
|
||||
#/musr/command SetUserLimits log_World ustepMax(mm) utrakMax(mm) utimeMax(ns) uekinMin(MeV) urangMin(mm)
|
||||
/musr/command SetUserLimits log_World -1 -1 -1 1e-7 -1
|
||||
|
||||
# Store ALL the events in a ROOT tree or just the interesting ones? (default is true)
|
||||
#*/musr/command storeOnlyEventsWithHits false
|
||||
|
||||
# Set the minimum time separation between two subsequent signals in the same detector (in ns)
|
||||
/musr/command signalSeparationTime 0.1
|
||||
|
||||
# Override runID number
|
||||
#*/musr/run/runID 21
|
||||
|
||||
# Set the frequency of event printing
|
||||
/musr/run/howOftenToPrintEvent 1000
|
||||
|
||||
# RANDOM option choices: (specify the random number generator initialisation)
|
||||
# 0 ... no initialisation (default)
|
||||
# 1 ... use actual computer time to initialise now # Pseudo-random numbers
|
||||
# 2 ... use event number to initialise at the beginning of each event # Reproducible numbers
|
||||
# 3 ... read in the random no. initial values for each event from a file
|
||||
/musr/run/randomOption 2
|
||||
|
||||
# VISUALIZATION options
|
||||
# To enable or disable visualization uncomment one of these lines
|
||||
# To modify visualization options edit the file vis.mac
|
||||
/vis/disable
|
||||
#*/control/execute vis.mac
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# -- Setting PARTICLE GUN parameters --
|
||||
################################################################################################################
|
||||
|
||||
# Default momentum direction: 001, i.e. 0z.
|
||||
# Default muon spin direction: 100, i.e. 0x.
|
||||
# Default particle type: mu+ (can be changed to Mu)
|
||||
|
||||
# Set particle type
|
||||
#*/gun/particle Mu
|
||||
/gun/particle mu+
|
||||
|
||||
# Set beam vertex
|
||||
# CFoil at -1144 mm, acceleration starts at -1154.15 mm
|
||||
/gun/vertex 0. 0. -1155. mm
|
||||
|
||||
# A point-like uniform beam
|
||||
/gun/vertexsigma -0.1 -0.1 0 mm
|
||||
|
||||
# Set beam transverse spread (default GAUSSIAN spread)
|
||||
# If FWHM = 10 mm ==> sigma = 10/2.354 = 4.2481 mm (last 0 is a dummy value)
|
||||
# Negative sigma values => random FLAT RECTANGULAR distribution (area 2x.2y)
|
||||
# Use vertexboundary with (vb < sigma_xy) to obtain a CIRCULAR beam spot
|
||||
# /gun/vertexsigma 0 0 0 mm ==> Very SLOW with mag. field ON and centered beam
|
||||
#*/gun/vertexsigma 42.5 42.5 0 mm
|
||||
/gun/vertexsigma -20 -20 0 mm
|
||||
/gun/vertexboundary 20 -1e6 1e6 mm
|
||||
|
||||
# /gun/vertexboundary: rMaxAllowed, zMinAllowed, zMaxAllowed # Beam AND gating
|
||||
#*/gun/vertexboundary 7 -1314.4 -1305 mm
|
||||
# Without restrictions in z, but only on r:
|
||||
#*/gun/vertexboundary 3 -1e6 1e6 mm
|
||||
|
||||
# Set beam momentum (USE only as an ALTERNATIVE to setting energy!)
|
||||
# /gun/momentum 0 0 29.79 MeV
|
||||
#*/gun/momentum 0 0 1.8 MeV
|
||||
# Energy loss at p = 1.2 MeV/c (E = 6.8 keV) => 1.23 +/- 0.2 keV
|
||||
# Energy loss at p = 1.8 MeV/c (E = 15.3 keV) => 1.25 +/- 0.3 keV
|
||||
# 1.2 MeV/c -> 6.8 keV, 1.8 MeV/c -> 15.3 keV
|
||||
# muon rest mass = 105.658 MeV/c2
|
||||
|
||||
# Set muon energy before hitting TD; a constant field in front of the C-foil accelerates the muons
|
||||
# to add 3.73 keV
|
||||
/gun/kenergy 12.0 keV
|
||||
|
||||
# Set beam momentum direction
|
||||
/gun/direction 0.0 0.0 1.0
|
||||
|
||||
# Set muon spin direction
|
||||
/gun/muonPolarizVector 1 0 0
|
||||
|
||||
|
||||
# Other useful test parameters:
|
||||
#
|
||||
# FWHM = 3% ==> sigma = 29.79*0.03/2.354 = 0.37965 MeV/c
|
||||
#*/gun/momentumsmearing 0.37965 MeV
|
||||
#---/gun/momentumboundary: pMinAllowed, pMaxAllowed, dummy
|
||||
#*/gun/momentumboundary 20 40 0 MeV
|
||||
#---/gun/tilt: xangle, yangle, dummy
|
||||
#*/gun/tilt 0 0.5 0 deg
|
||||
#---/gun/tiltsigma: xangleSigma, yangleSigma, dummy (1 degree at 1 m => 17 mm)
|
||||
#*/gun/tiltsigma 0.2 0.2 0 deg
|
||||
#*/gun/pitch 0.5 deg
|
||||
#---/gun/decaytimelimits: decayMin, decayMax, decayTime
|
||||
#*/gun/decaytimelimits 10400 10420 2197.03 ns
|
||||
|
||||
# Selectively inactivate or activate sensitive detectors
|
||||
#*/hits/inactivate /musr/ScintSD
|
||||
|
||||
# Only for code debugging!
|
||||
#/tracking/verbose 1
|
||||
|
||||
# BEAM ON
|
||||
#*/run/beamOn 1000000
|
||||
#*/run/beamOn 2
|
||||
/run/beamOn 1000
|
||||
|
200
src/F04ElementField.cc
Normal file
200
src/F04ElementField.cc
Normal file
@ -0,0 +1,200 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 "G4GeometryManager.hh"
|
||||
#include "F04ElementField.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
|
||||
G4Navigator* F04ElementField::aNavigator;
|
||||
|
||||
F04ElementField::F04ElementField(G4ThreeVector c, G4LogicalVolume* lv)
|
||||
{
|
||||
elementFieldName="NAME_NOT_DEFINED";
|
||||
center = c;
|
||||
|
||||
minX = minY = minZ = -DBL_MAX;
|
||||
maxX = maxY = maxZ = DBL_MAX;
|
||||
|
||||
// G4cout<<"Kamil: F04GlobalField: addElementField() will be called: "<<G4endl;
|
||||
F04GlobalField::getObject()->addElementField(this);
|
||||
|
||||
color = "1,1,1";
|
||||
|
||||
userLimits = new G4UserLimits();
|
||||
|
||||
lvolume = lv;
|
||||
lvolume->SetVisAttributes(getVisAttribute(color));
|
||||
|
||||
maxStep = 1*mm;
|
||||
|
||||
userLimits->SetMaxAllowedStep(maxStep);
|
||||
|
||||
userLimits->SetUserMaxTrackLength(500.*m);
|
||||
userLimits->SetUserMaxTime(10*ms);
|
||||
// userLimits->SetUserMinEkine(0.1*MeV);
|
||||
// userLimits->SetUserMinRange(1*mm);
|
||||
|
||||
lvolume->SetUserLimits(userLimits);
|
||||
}
|
||||
|
||||
void F04ElementField::construct()
|
||||
{
|
||||
G4Navigator* theNavigator =
|
||||
G4TransportationManager::GetTransportationManager()->
|
||||
GetNavigatorForTracking();
|
||||
|
||||
if (!aNavigator) {
|
||||
aNavigator = new G4Navigator();
|
||||
if ( theNavigator->GetWorldVolume() )
|
||||
aNavigator->SetWorldVolume(theNavigator->GetWorldVolume());
|
||||
}
|
||||
|
||||
G4GeometryManager* geomManager = G4GeometryManager::GetInstance();
|
||||
|
||||
if (!geomManager->IsGeometryClosed()) {
|
||||
geomManager->OpenGeometry();
|
||||
geomManager->CloseGeometry(true);
|
||||
}
|
||||
|
||||
G4cout<<"F04ElementField: center="<<center.x()/mm<<", "<<center.y()/mm<<", "<<center.z()/mm<<" mm"<<G4endl;
|
||||
aNavigator->LocateGlobalPointAndSetup(center,0,false);
|
||||
|
||||
G4TouchableHistoryHandle fTouchable = aNavigator->
|
||||
CreateTouchableHistoryHandle();
|
||||
|
||||
G4int depth = fTouchable->GetHistoryDepth();
|
||||
for (G4int i = 0; i<depth; ++i) {
|
||||
if(fTouchable->GetVolume()->GetLogicalVolume() == lvolume)break;
|
||||
fTouchable->MoveUpHistory();
|
||||
}
|
||||
// Check that the point of origin of the field matches with the logical volume, to which it is assigned:
|
||||
G4String volumeName=lvolume->GetName();
|
||||
if (fTouchable->GetVolume()->GetLogicalVolume() != lvolume) {
|
||||
char eMessage[200];
|
||||
sprintf(eMessage,"F04ElementField.cc::construct(): Centre (point of origin) of the field outside the assigned logical volume \"%s\".",
|
||||
volumeName.c_str());
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
|
||||
}
|
||||
|
||||
// G4cout<<"+!+!+! global2local VOLUME NAME: "<<fTouchable->GetVolume()->GetName()<<G4endl;
|
||||
// Set global2local transform. The centre of the transformation is set to the centre of the volume, not
|
||||
// to the point "center", as one could naively expect. This is corrected a few lines later.
|
||||
global2local = fTouchable->GetHistory()->GetTopTransform();
|
||||
|
||||
// Print out the point of the origin of the field in the local coordinate system of the logical volume:
|
||||
G4ThreeVector local_center = global2local.TransformPoint(center);
|
||||
G4cout<<"\t==> "<<elementFieldName<<" in vol.=\""<<volumeName<<"\", center(local coord. system): "
|
||||
<<local_center.x()/mm<<", "<<local_center.y()/mm<<", "<<local_center.z()/mm<<" mm."<<G4endl;
|
||||
|
||||
// Now move the centre of the transformation such that it coincides with the point "center":
|
||||
global2local*=G4AffineTransform(-local_center);
|
||||
|
||||
// After moving the centre of the transformation, the point "local_center" should be set to 0., 0., 0. in
|
||||
// the following print-out message:
|
||||
// local_center = global2local.TransformPoint(center);
|
||||
// G4cout<<"\t==> "<<elementFieldName<<" (volume=\""<<volumeName<<"\", center of the field in local coordinate syst 2: "
|
||||
// <<local_center.x()/mm<<", "<<local_center.y()/mm<<", "<<local_center.z()/mm<<" mm.)"<<G4endl;
|
||||
|
||||
// set global bounding box
|
||||
G4double local[4], global[4];
|
||||
|
||||
G4ThreeVector globalPosition;
|
||||
local[3] = 0.0;
|
||||
for (int i=0; i<2; ++i) {
|
||||
local[0] = (i==0 ? -1.0 : 1.0) * getWidth()/2.;
|
||||
for (int j=0; j<2; ++j) {
|
||||
local[1] = (j==0 ? -1.0 : 1.0) * getHeight()/2.;
|
||||
for (int k=0; k<2; ++k) {
|
||||
local[2] = (k==0 ? -1.0 : 1.0) * getLength()/2.;
|
||||
G4ThreeVector localPosition(local[0],local[1],local[2]);
|
||||
globalPosition =
|
||||
global2local.Inverse().TransformPoint(localPosition);
|
||||
global[0] = globalPosition.x();
|
||||
global[1] = globalPosition.y();
|
||||
global[2] = globalPosition.z();
|
||||
setGlobalPoint(global);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4VisAttributes* F04ElementField::getVisAttribute(G4String color)
|
||||
{
|
||||
G4VisAttributes* p = NULL;
|
||||
if(color.size() > 0 &&
|
||||
(isdigit(color.c_str()[0]) || color.c_str()[0] == '.')) {
|
||||
G4double red=0.0, green=0.0, blue=0.0;
|
||||
if (sscanf(color.c_str(),"%lf,%lf,%lf",&red,&green,&blue) == 3) {
|
||||
p = new G4VisAttributes(true,G4Color(red,green,blue));
|
||||
} else {
|
||||
G4cout << " Invalid color " << color << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p) p = new G4VisAttributes(G4VisAttributes::Invisible);
|
||||
p->SetDaughtersInvisible(false);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void F04ElementField::SetEventNrDependentField(G4double initialField, G4double finalField, G4int nrOfSteps) {
|
||||
G4double eventNrStep = float(musrParameters::nrOfEventsToBeGenerated)/(nrOfSteps);
|
||||
G4double fieldStep = (finalField-initialField)/(nrOfSteps-1);
|
||||
// G4cout<<"musrParameters::nrOfEventsToBeGenerated="<<musrParameters::nrOfEventsToBeGenerated<<G4endl;
|
||||
// G4cout<<"fieldStep="<<fieldStep<<" eventNrStep="<<eventNrStep<<G4endl;
|
||||
for (G4int i=1; i<=nrOfSteps; i++) {
|
||||
G4int eventNumber = int(i*eventNrStep);
|
||||
G4double field = initialField + i*fieldStep;
|
||||
changeFieldInStepsMap[eventNumber]=field;
|
||||
}
|
||||
|
||||
G4cout << "Setting field in steps for field "<<elementFieldName<<G4endl;
|
||||
std::map<G4int,G4double>::iterator it;
|
||||
for ( it=changeFieldInStepsMap.begin() ; it != changeFieldInStepsMap.end(); it++ ) {
|
||||
G4cout << "Field will be changed at event "<< (*it).first << " to the value of " << (*it).second/tesla<<" T" << G4endl;
|
||||
// G4double nominalFieldValue=it->second;
|
||||
// it->SetNominalFieldValue(nominalFieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void F04ElementField::SetElementFieldValueIfNeeded(G4int eventNr) {
|
||||
std::map<G4int,G4double>::iterator itr;
|
||||
itr = changeFieldInStepsMap.find(eventNr);
|
||||
if (itr==F04ElementField::changeFieldInStepsMap.end()) {
|
||||
// eventNr was not found in the map ==> field is not going to change at this eventNr
|
||||
}
|
||||
else {
|
||||
G4double newFieldValue = itr->second;
|
||||
SetNominalFieldValue(newFieldValue);
|
||||
// G4cout<<"Nominal Field changed for "<<G4endl;
|
||||
}
|
||||
}
|
147
src/F04FieldMessenger.cc
Normal file
147
src/F04FieldMessenger.cc
Normal file
@ -0,0 +1,147 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 "F04FieldMessenger.hh"
|
||||
|
||||
#include "F04GlobalField.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
F04FieldMessenger::F04FieldMessenger(F04GlobalField* pEMfield)
|
||||
: fGlobalField(pEMfield)
|
||||
{
|
||||
detDir = new G4UIdirectory("/field/");
|
||||
detDir->SetGuidance(" Field tracking control ");
|
||||
|
||||
fStepperCMD = new G4UIcmdWithAnInteger("/field/setStepperType",this);
|
||||
fStepperCMD->SetGuidance("Select stepper type for field");
|
||||
fStepperCMD->SetParameterName("choice",true);
|
||||
fStepperCMD->SetDefaultValue(4);
|
||||
fStepperCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fUpdateCMD = new G4UIcmdWithoutParameter("/field/update",this);
|
||||
fUpdateCMD->SetGuidance("Update Field");
|
||||
fUpdateCMD->SetGuidance("This command MUST be applied before \"beamOn\" ");
|
||||
fUpdateCMD->SetGuidance("if you changed field settings.");
|
||||
fUpdateCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fMinStepCMD = new G4UIcmdWithADoubleAndUnit("/field/setMinStep",this);
|
||||
fMinStepCMD->SetGuidance("Define minimal step");
|
||||
fMinStepCMD->SetParameterName("min step",false,false);
|
||||
fMinStepCMD->SetDefaultUnit("mm");
|
||||
fMinStepCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fDeltaChordCMD = new G4UIcmdWithADoubleAndUnit("/field/setDeltaChord",this);
|
||||
fDeltaChordCMD->SetGuidance("Define delta chord");
|
||||
fDeltaChordCMD->SetParameterName("delta chord",false,false);
|
||||
fDeltaChordCMD->SetDefaultUnit("mm");
|
||||
fDeltaChordCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fDeltaOneStepCMD =
|
||||
new G4UIcmdWithADoubleAndUnit("/field/setDeltaOneStep",this);
|
||||
fDeltaOneStepCMD->SetGuidance("Define delta one step");
|
||||
fDeltaOneStepCMD->SetParameterName("delta one step",false,false);
|
||||
fDeltaOneStepCMD->SetDefaultUnit("mm");
|
||||
fDeltaOneStepCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fDeltaIntersectionCMD =
|
||||
new G4UIcmdWithADoubleAndUnit("/field/setDeltaIntersection",this);
|
||||
fDeltaIntersectionCMD->SetGuidance("Define delta intersection");
|
||||
fDeltaIntersectionCMD->SetParameterName("delta intersection",false,false);
|
||||
fDeltaIntersectionCMD->SetDefaultUnit("mm");
|
||||
fDeltaIntersectionCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fEpsMinCMD = new G4UIcmdWithADoubleAndUnit("/field/setEpsMin",this);
|
||||
fEpsMinCMD->SetGuidance("Define eps min");
|
||||
fEpsMinCMD->SetParameterName("eps min",false,false);
|
||||
fEpsMinCMD->SetDefaultUnit("mm");
|
||||
fEpsMinCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fEpsMaxCMD = new G4UIcmdWithADoubleAndUnit("/field/setEpsMax",this);
|
||||
fEpsMaxCMD->SetGuidance("Define eps max");
|
||||
fEpsMaxCMD->SetParameterName("eps max",false,false);
|
||||
fEpsMaxCMD->SetDefaultUnit("mm");
|
||||
fEpsMaxCMD->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
}
|
||||
|
||||
F04FieldMessenger::~F04FieldMessenger()
|
||||
{
|
||||
delete detDir;
|
||||
|
||||
delete fStepperCMD;
|
||||
delete fMinStepCMD;
|
||||
delete fDeltaChordCMD;
|
||||
delete fDeltaOneStepCMD;
|
||||
delete fDeltaIntersectionCMD;
|
||||
delete fEpsMinCMD;
|
||||
delete fEpsMaxCMD;
|
||||
delete fUpdateCMD;
|
||||
}
|
||||
|
||||
void F04FieldMessenger::SetNewValue( G4UIcommand* command, G4String newValue)
|
||||
{
|
||||
if( command == fStepperCMD )
|
||||
{
|
||||
fGlobalField->SetStepperType(fStepperCMD->GetNewIntValue(newValue));
|
||||
}
|
||||
if( command == fUpdateCMD )
|
||||
{
|
||||
fGlobalField->updateField();
|
||||
}
|
||||
if( command == fMinStepCMD )
|
||||
{
|
||||
fGlobalField->SetMinStep(fMinStepCMD->GetNewDoubleValue(newValue));
|
||||
}
|
||||
if( command == fDeltaChordCMD )
|
||||
{
|
||||
fGlobalField->SetDeltaChord(fDeltaChordCMD->GetNewDoubleValue(newValue));
|
||||
}
|
||||
if( command == fDeltaOneStepCMD )
|
||||
{
|
||||
fGlobalField->
|
||||
SetDeltaOneStep(fDeltaOneStepCMD->GetNewDoubleValue(newValue));
|
||||
}
|
||||
if( command == fDeltaIntersectionCMD )
|
||||
{
|
||||
fGlobalField->
|
||||
SetDeltaIntersection(fDeltaIntersectionCMD->GetNewDoubleValue(newValue));
|
||||
}
|
||||
if( command == fEpsMinCMD )
|
||||
{
|
||||
fGlobalField->SetEpsMin(fEpsMinCMD->GetNewDoubleValue(newValue));
|
||||
}
|
||||
if( command == fEpsMaxCMD )
|
||||
{
|
||||
fGlobalField->SetEpsMax(fEpsMaxCMD->GetNewDoubleValue(newValue));
|
||||
}
|
||||
}
|
330
src/F04GlobalField.cc
Normal file
330
src/F04GlobalField.cc
Normal file
@ -0,0 +1,330 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 <time.h>
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
#include "G4ExplicitEuler.hh"
|
||||
#include "G4ImplicitEuler.hh"
|
||||
#include "G4SimpleRunge.hh"
|
||||
#include "G4SimpleHeum.hh"
|
||||
#include "G4ClassicalRK4.hh"
|
||||
#include "G4CashKarpRKF45.hh"
|
||||
|
||||
#include "F04GlobalField.hh"
|
||||
// #include "F04GlobalFieldOldPoints.hh" //cks F04GlobalFieldOldPoints were introduced in order to keep the last few
|
||||
// values of the field, so that they do not have to be recalculated, if the
|
||||
// field at recent point is requested. It turned out not to be useful
|
||||
// (i.e. it did not speed-up the simulation)
|
||||
#include "musrRootOutput.hh"
|
||||
|
||||
F04GlobalField* F04GlobalField::object = 0;
|
||||
|
||||
F04GlobalField::F04GlobalField() : G4ElectroMagneticField(),
|
||||
minStep(0.01*mm), deltaChord(3.0*mm),
|
||||
deltaOneStep(0.01*mm), deltaIntersection(0.1*mm),
|
||||
epsMin(2.5e-7*mm), epsMax(0.05*mm),
|
||||
fEquation(0), fFieldManager(0),
|
||||
fFieldPropagator(0), fStepper(0), fChordFinder(0)
|
||||
// F04GlobalField::F04GlobalField() : G4MagneticField(),
|
||||
// minStep(0.01*mm), deltaChord(3.0*mm),
|
||||
// deltaOneStep(0.01*mm), deltaIntersection(0.1*mm),
|
||||
// epsMin(2.5e-7*mm), epsMax(0.05*mm),
|
||||
// fEquation(0), fFieldManager(0),
|
||||
// fFieldPropagator(0), fStepper(0), fChordFinder(0)
|
||||
{
|
||||
|
||||
fFieldMessenger = new F04FieldMessenger(this);
|
||||
|
||||
fields = new FieldList();
|
||||
|
||||
fStepperType = 4 ; // ClassicalRK4 is default stepper
|
||||
|
||||
// set object
|
||||
|
||||
object = this;
|
||||
|
||||
updateField();
|
||||
|
||||
//cks myOldFieldPoints = F04GlobalFieldOldPoints();
|
||||
|
||||
}
|
||||
|
||||
F04GlobalField::~F04GlobalField()
|
||||
{
|
||||
// cks 2009_05_14
|
||||
// For some reason, the "clear()" on the next line was causing the crash in some cases
|
||||
// (probably when more "Elementary fields" were created). The problem appeared
|
||||
// when running the 1050.mac file for the lem4. Fixed by commenting out the clear():
|
||||
// clear();
|
||||
delete fFieldMessenger;
|
||||
if (fEquation) delete fEquation;
|
||||
// if (fFieldManager) delete fFieldManager;
|
||||
// if (fFieldPropagator) delete fFieldPropagator;
|
||||
if (fStepper) delete fStepper;
|
||||
if (fChordFinder) delete fChordFinder;
|
||||
}
|
||||
|
||||
void F04GlobalField::updateField()
|
||||
{
|
||||
first = true;
|
||||
|
||||
nfp = 0;
|
||||
fp = 0;
|
||||
|
||||
clear();
|
||||
|
||||
// Construct equ. of motion of particles through B fields
|
||||
// fEquation = new G4Mag_EqRhs(this);
|
||||
// Construct equ. of motion of particles through e.m. fields
|
||||
// fEquation = new G4EqMagElectricField(this);
|
||||
// Construct equ. of motion of particles including spin through B fields
|
||||
// fEquation = new G4Mag_SpinEqRhs(this);
|
||||
// Construct equ. of motion of particles including spin through e.m. fields
|
||||
fEquation = new G4EqEMFieldWithSpin(this);
|
||||
|
||||
// Get transportation, field, and propagator managers
|
||||
G4TransportationManager* fTransportManager =
|
||||
G4TransportationManager::GetTransportationManager();
|
||||
|
||||
fFieldManager = GetGlobalFieldManager();
|
||||
|
||||
fFieldPropagator = fTransportManager->GetPropagatorInField();
|
||||
|
||||
// Need to SetFieldChangesEnergy to account for a time varying electric
|
||||
// field (r.f. fields)
|
||||
fFieldManager->SetFieldChangesEnergy(true);
|
||||
|
||||
// Set the field
|
||||
fFieldManager->SetDetectorField(this);
|
||||
|
||||
// Choose a stepper for integration of the equation of motion
|
||||
SetStepper();
|
||||
|
||||
// Create a cord finder providing the (global field, min step length,
|
||||
// a pointer to the stepper)
|
||||
fChordFinder = new G4ChordFinder((G4MagneticField*)this,minStep,fStepper);
|
||||
|
||||
// Set accuracy parameters
|
||||
fChordFinder->SetDeltaChord( deltaChord );
|
||||
|
||||
fFieldManager->SetAccuraciesWithDeltaOneStep(deltaOneStep);
|
||||
|
||||
fFieldManager->SetDeltaIntersection(deltaIntersection);
|
||||
|
||||
fFieldPropagator->SetMinimumEpsilonStep(epsMin);
|
||||
fFieldPropagator->SetMaximumEpsilonStep(epsMax);
|
||||
|
||||
// G4cout << "Accuracy Parameters:" <<
|
||||
// " MinStep=" << minStep <<
|
||||
// " DeltaChord=" << deltaChord <<
|
||||
// " DeltaOneStep=" << deltaOneStep << G4endl;
|
||||
// G4cout << " " <<
|
||||
// " DeltaIntersection=" << deltaIntersection <<
|
||||
// " EpsMin=" << epsMin <<
|
||||
// " EpsMax=" << epsMax << G4endl;
|
||||
|
||||
fFieldManager->SetChordFinder(fChordFinder);
|
||||
|
||||
}
|
||||
|
||||
F04GlobalField* F04GlobalField::getObject()
|
||||
{
|
||||
if (!object) new F04GlobalField();
|
||||
return object;
|
||||
}
|
||||
|
||||
void F04GlobalField::SetStepper()
|
||||
{
|
||||
if(fStepper) delete fStepper;
|
||||
|
||||
switch ( fStepperType )
|
||||
{
|
||||
case 0:
|
||||
// fStepper = new G4ExplicitEuler( fEquation, 8 ); // no spin tracking
|
||||
fStepper = new G4ExplicitEuler( fEquation, 12 ); // with spin tracking
|
||||
G4cout << "G4ExplicitEuler is called" << G4endl;
|
||||
break;
|
||||
case 1:
|
||||
// fStepper = new G4ImplicitEuler( fEquation, 8 ); // no spin tracking
|
||||
fStepper = new G4ImplicitEuler( fEquation, 12 ); // with spin tracking
|
||||
G4cout << "G4ImplicitEuler is called" << G4endl;
|
||||
break;
|
||||
case 2:
|
||||
// fStepper = new G4SimpleRunge( fEquation, 8 ); // no spin tracking
|
||||
fStepper = new G4SimpleRunge( fEquation, 12 ); // with spin tracking
|
||||
G4cout << "G4SimpleRunge is called" << G4endl;
|
||||
break;
|
||||
case 3:
|
||||
// fStepper = new G4SimpleHeum( fEquation, 8 ); // no spin tracking
|
||||
fStepper = new G4SimpleHeum( fEquation, 12 ); // with spin tracking
|
||||
G4cout << "G4SimpleHeum is called" << G4endl;
|
||||
break;
|
||||
case 4:
|
||||
// fStepper = new G4ClassicalRK4( fEquation, 8 ); // no spin tracking
|
||||
fStepper = new G4ClassicalRK4( fEquation, 12 ); // with spin tracking
|
||||
G4cout << "G4ClassicalRK4 (default) is called" << G4endl;
|
||||
break;
|
||||
case 5:
|
||||
// fStepper = new G4CashKarpRKF45( fEquation, 8 ); // no spin tracking
|
||||
fStepper = new G4CashKarpRKF45( fEquation, 12 ); // with spin tracking
|
||||
G4cout << "G4CashKarpRKF45 is called" << G4endl;
|
||||
break;
|
||||
default: fStepper = 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4FieldManager* F04GlobalField::GetGlobalFieldManager()
|
||||
{
|
||||
return G4TransportationManager::GetTransportationManager()
|
||||
->GetFieldManager();
|
||||
}
|
||||
|
||||
void F04GlobalField::GetFieldValue(const G4double* point, G4double* field) const
|
||||
{
|
||||
// NOTE: this routine dominates the CPU time for tracking.
|
||||
// Using the simple array fp[] instead of fields[]
|
||||
// directly sped it up
|
||||
|
||||
// G4cout<<"GlobalField: Field requested at point ("<<point[0]<<","<<point[1]<<","<<point[2]<<")"<<G4endl;
|
||||
//cks Check whether the requested point is the same as in the previous call
|
||||
// if (myOldFieldPoints.ThisPointWasCalculatedRecently(point,field)) {return;}
|
||||
|
||||
|
||||
field[0] = field[1] = field[2] = field[3] = field[4] = field[5] = 0.0;
|
||||
|
||||
// protect against Geant4 bug that calls us with point[] NaN.
|
||||
if(point[0] != point[0]) return;
|
||||
|
||||
// (can't use nfp or fp, as they may change)
|
||||
if (first) ((F04GlobalField*)this)->setupArray(); // (cast away const)
|
||||
|
||||
for (int i=0; i<nfp; ++i) {
|
||||
const F04ElementField* p = fp[i];
|
||||
if (p->isInBoundingBox(point)) {
|
||||
p->addFieldValue(point,field);
|
||||
}
|
||||
}
|
||||
|
||||
// cks NOT SURE WHETHER THE FOLLOWING WAS STILL NEEDED, HOWEVER REMOVED NOT
|
||||
// TO DISTURB THE LOW ENERGY MUONS.
|
||||
// Set some small field if field is almost zero (to avoid internal problems
|
||||
// of Geant at almost zero magnetic fields).
|
||||
// if (sqrt(field[0]*field[0]+field[1]*field[1]+field[2]*field[2])<0.00001*tesla) {
|
||||
// field[2] = 0.00001*tesla;
|
||||
// }
|
||||
|
||||
// cks myOldFieldPoints.StoreTheFieldPointForFutureReuse(point,field);
|
||||
}
|
||||
|
||||
void F04GlobalField::clear()
|
||||
{
|
||||
if (fields) {
|
||||
if (fields->size()>0) {
|
||||
FieldList::iterator i;
|
||||
//cks 2009_05_14 : The following line seems to cause problems (sometimes)
|
||||
// See the comment in F04GlobalField::~F04GlobalField() for more details.
|
||||
for (i=fields->begin(); i!=fields->end(); ++i) delete *i;
|
||||
fields->clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (fp) delete[] fp;
|
||||
first = true;
|
||||
|
||||
nfp = 0;
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
void F04GlobalField::setupArray()
|
||||
{
|
||||
first = false;
|
||||
nfp = fields->size();
|
||||
fp = new const F04ElementField* [nfp+1]; // add 1 so it's never 0
|
||||
for (int i=0; i<nfp; ++i) {
|
||||
fp[i] = (*fields)[i];
|
||||
//
|
||||
// Find the event numbers, for which the field changes, for each Element Field.
|
||||
// Then mark these event numbers in the Global Field, such that it can be efficiently
|
||||
// find out during the run-time, at which event number the field may change.
|
||||
std::map<G4int,G4double> localChangeFieldInStepsMap = fp[i] ->GetEventNrDependentField();
|
||||
std::map<G4int,G4double>::iterator it;
|
||||
for ( it=localChangeFieldInStepsMap.begin() ; it != localChangeFieldInStepsMap.end(); it++ ) {
|
||||
G4int eventNr = it->first;
|
||||
G4cout<<"globalChangeFieldInStepsMap set for event number "<<eventNr<<G4endl;
|
||||
globalChangeFieldInStepsMap[eventNr]=true;
|
||||
}
|
||||
}
|
||||
musrRootOutput::GetRootInstance()->SetNrFieldNomVal(nfp);
|
||||
}
|
||||
|
||||
|
||||
void F04GlobalField::CheckWhetherAnyNominalFieldValueNeedsToBeChanged(G4int eventNumber) {
|
||||
if (globalChangeFieldInStepsMap[eventNumber]) {
|
||||
// G4cout<<"We should check each Element Field Object whether its field needs to be changed:"<<G4endl;
|
||||
G4int jjj=0;
|
||||
FieldList::iterator i;
|
||||
for (i=fields->begin(); i!=fields->end(); ++i) {
|
||||
|
||||
// Set the nominal field value for the given field, if that has been requested for the given field
|
||||
(*i)->SetElementFieldValueIfNeeded(eventNumber);
|
||||
|
||||
// Get the nominal field value for the given field and store it in the Root output
|
||||
G4double nomFieldValue = (*i)->GetNominalFieldValue();
|
||||
musrRootOutput::GetRootInstance()->SetFieldNomVal(jjj,nomFieldValue);
|
||||
jjj++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Print field value at all points requested by the user:
|
||||
void F04GlobalField::PrintFieldAtRequestedPoints() const {
|
||||
G4ThreeVector p;
|
||||
G4double point[4];
|
||||
G4double Bfi[6]={0,0,0,0,0,0};
|
||||
for (unsigned int i=0; i < pointsAtWhichUserWantsToPrintFieldValue.size(); i++) {
|
||||
p = pointsAtWhichUserWantsToPrintFieldValue[i];
|
||||
point[0] = p.x();
|
||||
point[1] = p.y();
|
||||
point[2] = p.z();
|
||||
point[3] = 0.;
|
||||
object->GetFieldValue(point,Bfi);
|
||||
// printf (" Magnetic Field at %f, %f, %f mm is B= %10.10f, %10.10f, %10.10f tesla.\n",
|
||||
// point[0]/mm,point[1]/mm,point[2]/mm,Bfi[0]/tesla,Bfi[1]/tesla,Bfi[2]/tesla);
|
||||
printf (" EM field value at (%.f, %.f, %.f) mm is: B = (%0.10g, %0.10g, %0.10g) T, E = (%0.10g, %0.10g, %0.10g) kV/mm\n",
|
||||
point[0]/mm, point[1]/mm, point[2]/mm,
|
||||
Bfi[0]/tesla, Bfi[1]/tesla, Bfi[2]/tesla,
|
||||
Bfi[3]/(kilovolt/mm), Bfi[4]/(kilovolt/mm), Bfi[5]/(kilovolt/mm));
|
||||
}
|
||||
}
|
||||
|
||||
|
220
src/G4DecayWithSpin.cc
Normal file
220
src/G4DecayWithSpin.cc
Normal file
@ -0,0 +1,220 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
// History:
|
||||
// 17 August 2004 P. Gumplinger, T. MacPhail
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
#include "G4DecayWithSpin.hh"
|
||||
|
||||
#include "G4Step.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4DecayTable.hh"
|
||||
#include "G4MuonDecayChannelWithSpin.hh"
|
||||
|
||||
#include "G4Vector3D.hh"
|
||||
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4PropagatorInField.hh"
|
||||
#include "G4FieldManager.hh"
|
||||
#include "G4Field.hh"
|
||||
|
||||
#include "G4Transform3D.hh"
|
||||
|
||||
//cks
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "G4RunManager.hh"
|
||||
//#include "musrRootOutput.hh"
|
||||
//csk
|
||||
|
||||
G4DecayWithSpin::G4DecayWithSpin(const G4String& processName):G4Decay(processName){}
|
||||
//cks G4DecayWithSpin::G4DecayWithSpin(const G4String& processName):G4Decay(processName){SetVerboseLevel(3);}
|
||||
|
||||
G4DecayWithSpin::~G4DecayWithSpin(){}
|
||||
|
||||
G4VParticleChange* G4DecayWithSpin::DecayIt(const G4Track& aTrack, const G4Step& aStep)
|
||||
{
|
||||
// debugging: G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
// debugging: G4int eventNr=fRunManager->GetCurrentEvent()->GetEventID();
|
||||
// debugging: if ((eventNr>447715)&&(eventNr<45005)) SetVerboseLevel(3);
|
||||
// debugging: if (eventNr>=45005) SetVerboseLevel(0);
|
||||
|
||||
// get particle
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
|
||||
|
||||
// get parent_polarization
|
||||
G4ThreeVector parent_polarization = aParticle->GetPolarization();
|
||||
|
||||
if(parent_polarization == G4ThreeVector(0,0,0))
|
||||
{
|
||||
// Generate random polarization direction
|
||||
|
||||
G4double cost = 1. - 2.*G4UniformRand();
|
||||
G4double sint = std::sqrt((1.-cost)*(1.+cost));
|
||||
|
||||
G4double phi = twopi*G4UniformRand();
|
||||
G4double sinp = std::sin(phi);
|
||||
G4double cosp = std::cos(phi);
|
||||
|
||||
G4double px = sint*cosp;
|
||||
G4double py = sint*sinp;
|
||||
G4double pz = cost;
|
||||
|
||||
parent_polarization.setX(px);
|
||||
parent_polarization.setY(py);
|
||||
parent_polarization.setZ(pz);
|
||||
|
||||
}else{
|
||||
|
||||
G4FieldManager* fieldMgr = aStep.GetTrack()->GetVolume()->
|
||||
GetLogicalVolume()->GetFieldManager();
|
||||
|
||||
if (!fieldMgr) {
|
||||
G4TransportationManager *transportMgr =
|
||||
G4TransportationManager::GetTransportationManager();
|
||||
G4PropagatorInField* fFieldPropagator =
|
||||
transportMgr->GetPropagatorInField();
|
||||
if (fFieldPropagator) fieldMgr =
|
||||
fFieldPropagator->GetCurrentFieldManager();
|
||||
}
|
||||
|
||||
const G4Field* field = NULL;
|
||||
if(fieldMgr)field = fieldMgr->GetDetectorField();
|
||||
|
||||
// if (field && !(fieldMgr->DoesFieldChangeEnergy())) {
|
||||
if (field) {
|
||||
G4double point[4];
|
||||
point[0] = (aStep.GetPostStepPoint()->GetPosition())[0];
|
||||
point[1] = (aStep.GetPostStepPoint()->GetPosition())[1];
|
||||
point[2] = (aStep.GetPostStepPoint()->GetPosition())[2];
|
||||
point[3] = aTrack.GetGlobalTime();
|
||||
|
||||
G4double fieldValue[6];
|
||||
field -> GetFieldValue(point,fieldValue);
|
||||
|
||||
G4ThreeVector B(fieldValue[0],fieldValue[1],fieldValue[2]);
|
||||
|
||||
if ((B.mag2())>0) { // Call the spin precession only for non-zero mag. field
|
||||
parent_polarization = Spin_Precession(aStep,B,fRemainderLifeTime);
|
||||
// G4cout<<"G4DecayWithSpin: parent_polarization="<<parent_polarization<<", B="<<B[0]/tesla<<","<<B[1]/tesla<<","<<B[2]/tesla
|
||||
// <<", fRemainderLifeTime="<<fRemainderLifeTime<<G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// decay table
|
||||
G4DecayTable *decaytable = aParticleDef->GetDecayTable();
|
||||
|
||||
if (decaytable) {
|
||||
G4MuonDecayChannelWithSpin *decaychannel;
|
||||
decaychannel = (G4MuonDecayChannelWithSpin*)decaytable->SelectADecayChannel();
|
||||
if (decaychannel) decaychannel->SetPolarization(parent_polarization);
|
||||
}
|
||||
|
||||
G4ParticleChangeForDecay* pParticleChangeForDecay;
|
||||
|
||||
pParticleChangeForDecay = (G4ParticleChangeForDecay*)G4Decay::DecayIt(aTrack,aStep);
|
||||
|
||||
pParticleChangeForDecay->ProposePolarization(parent_polarization);
|
||||
|
||||
// pParticleChangeForDecay->DumpInfo();
|
||||
|
||||
return pParticleChangeForDecay;
|
||||
|
||||
}
|
||||
|
||||
G4ThreeVector G4DecayWithSpin::Spin_Precession( const G4Step& aStep,
|
||||
G4ThreeVector B, G4double deltatime )
|
||||
{
|
||||
G4double Bnorm = std::sqrt(sqr(B[0]) + sqr(B[1]) +sqr(B[2]) );
|
||||
|
||||
G4double q = aStep.GetTrack()->GetDefinition()->GetPDGCharge();
|
||||
G4double a = 1.165922e-3;
|
||||
G4double s_omega = 8.5062e+7*rad/(s*kilogauss);
|
||||
|
||||
G4double omega = -(q*s_omega)*(1.+a) * Bnorm;
|
||||
|
||||
G4double rotationangle = deltatime * omega;
|
||||
|
||||
G4Transform3D SpinRotation = G4Rotate3D(rotationangle,B.unit());
|
||||
|
||||
G4Vector3D Spin = aStep.GetTrack() -> GetPolarization();
|
||||
//cks 2008.10.09. Check that the polarisatin is normalised do 1
|
||||
G4double spinMagnitude = Spin.mag();
|
||||
if ((spinMagnitude>1.1)||(spinMagnitude<0.9)) {
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
G4int eventNr=fRunManager->GetCurrentEvent()->GetEventID();
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,
|
||||
"G4DecayWithSpin.cc::Spin_Precession: spin magnitude is large than 1.1 or smaller than 0.9! Strange!!!",true);
|
||||
G4cout<<"G4DecayWithSpin.cc::Spin_Precession: "
|
||||
<<"Event nr.:"<<eventNr
|
||||
<<", spin = ("<<Spin.x()<<","<<Spin.y()<<","<<Spin.z()<<")."<<G4endl;
|
||||
G4cout.flush();
|
||||
}
|
||||
Spin = Spin.unit();
|
||||
//csk
|
||||
|
||||
G4Vector3D newSpin = SpinRotation * Spin;
|
||||
|
||||
//cks 2008.10.09. Check that the polarisatin is normalised do 1
|
||||
G4double newSpinMagnitude = newSpin.mag();
|
||||
if ((newSpinMagnitude>1.1)||(newSpinMagnitude<0.9)) {
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
G4int eventNr=fRunManager->GetCurrentEvent()->GetEventID();
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,
|
||||
"G4DecayWithSpin.cc::Spin_Precession: NEW spin magnitude is large than 1.1 or smaller than 0.9! Strange!!!",true);
|
||||
G4cout<<"G4DecayWithSpin.cc::Spin_Precession: "
|
||||
<<"Event nr.:"<<eventNr
|
||||
<<", NEW spin = ("<<newSpin.x()<<","<<newSpin.y()<<","<<newSpin.z()<<")."<<G4endl;
|
||||
G4cout.flush();
|
||||
}
|
||||
newSpin = newSpin.unit();
|
||||
//csk
|
||||
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>2) {
|
||||
G4double normspin = std::sqrt(Spin*Spin);
|
||||
G4double normnewspin = std::sqrt(newSpin*newSpin);
|
||||
//G4double cosalpha = Spin*newSpin/normspin/normnewspin;
|
||||
//G4double alpha = std::acos(cosalpha);
|
||||
|
||||
G4cout << "AT REST::: PARAMETERS " << G4endl;
|
||||
G4cout << "Initial spin : " << Spin << G4endl;
|
||||
G4cout << "Delta time : " << deltatime << G4endl;
|
||||
G4cout << "Rotation angle: " << rotationangle/rad << G4endl;
|
||||
G4cout << "New spin : " << newSpin << G4endl;
|
||||
G4cout << "Checked norms : " << normspin <<" " << normnewspin << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
return newSpin;
|
||||
|
||||
}
|
177
src/G4EqEMFieldWithSpin.cc
Normal file
177
src/G4EqEMFieldWithSpin.cc
Normal file
@ -0,0 +1,177 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EqEMFieldWithSpin.cc,v 1.1 2008/10/21 14:50:32 sedlak Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
//
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
//
|
||||
// The only case another is required is when using a moving reference
|
||||
// frame ... or extending the class to include additional Forces,
|
||||
// eg an electric field
|
||||
//
|
||||
// 30.08.2007 Chris Gong, Peter Gumplinger
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EqEMFieldWithSpin.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "globals.hh"
|
||||
//cks
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "musrRootOutput.hh"
|
||||
//csk
|
||||
|
||||
G4EqEMFieldWithSpin::G4EqEMFieldWithSpin(G4ElectroMagneticField *emField )
|
||||
: G4EquationOfMotion( emField ) { anomaly = 1.165923e-3; }
|
||||
|
||||
void
|
||||
G4EqEMFieldWithSpin::SetChargeMomentumMass(G4double particleCharge, // e+ units
|
||||
G4double MomentumXc,
|
||||
G4double particleMass)
|
||||
{
|
||||
fElectroMagCof = eplus*particleCharge*c_light ;
|
||||
fMassCof = particleMass*particleMass ;
|
||||
|
||||
omegac = 0.105658387*GeV/particleMass * 2.837374841e-3*(rad/cm/kilogauss);
|
||||
|
||||
ParticleCharge = particleCharge;
|
||||
|
||||
E = std::sqrt(sqr(MomentumXc)+sqr(particleMass));
|
||||
beta = MomentumXc/E;
|
||||
gamma = E/particleMass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
G4EqEMFieldWithSpin::EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
|
||||
// Components of y:
|
||||
// 0-2 dr/ds,
|
||||
// 3-5 dp/ds - momentum derivatives
|
||||
|
||||
G4double pSquared = y[3]*y[3] + y[4]*y[4] + y[5]*y[5] ;
|
||||
|
||||
G4double Energy = std::sqrt( pSquared + fMassCof );
|
||||
G4double cof2 = Energy/c_light ;
|
||||
|
||||
G4double pModuleInverse = 1.0/std::sqrt(pSquared) ;
|
||||
|
||||
// G4double inverse_velocity = Energy * c_light * pModuleInverse;
|
||||
G4double inverse_velocity = Energy * pModuleInverse / c_light;
|
||||
|
||||
G4double cof1 = fElectroMagCof*pModuleInverse ;
|
||||
|
||||
// G4double vDotE = y[3]*Field[3] + y[4]*Field[4] + y[5]*Field[5] ;
|
||||
|
||||
|
||||
dydx[0] = y[3]*pModuleInverse ;
|
||||
dydx[1] = y[4]*pModuleInverse ;
|
||||
dydx[2] = y[5]*pModuleInverse ;
|
||||
|
||||
dydx[3] = cof1*(cof2*Field[3] + (y[4]*Field[2] - y[5]*Field[1])) ;
|
||||
|
||||
dydx[4] = cof1*(cof2*Field[4] + (y[5]*Field[0] - y[3]*Field[2])) ;
|
||||
|
||||
dydx[5] = cof1*(cof2*Field[5] + (y[3]*Field[1] - y[4]*Field[0])) ;
|
||||
|
||||
dydx[6] = dydx[8] = 0.;//not used
|
||||
|
||||
// Lab Time of flight
|
||||
dydx[7] = inverse_velocity;
|
||||
|
||||
G4ThreeVector BField(Field[0],Field[1],Field[2]);
|
||||
|
||||
G4ThreeVector u(y[3], y[4], y[5]);
|
||||
u *= pModuleInverse;
|
||||
|
||||
G4double udb = anomaly*beta*gamma/(1.+gamma) * (BField * u);
|
||||
G4double ucb = (anomaly+1./gamma)/beta;
|
||||
|
||||
G4ThreeVector Spin(y[9],y[10],y[11]);
|
||||
G4ThreeVector dSpin;
|
||||
|
||||
dSpin = ParticleCharge*omegac*(ucb*(Spin.cross(BField))-udb*(Spin.cross(u)));
|
||||
|
||||
// cks 2008.10.08
|
||||
// Check that Spin is not extremely high. The problem is, that in some events
|
||||
// (for extremely low moementum muons?) the MomentumXc is of the order of 1.e-07,
|
||||
// the ucb is extremely high (e.g. ucb = 690618107.) and then dSpin becomes
|
||||
// also extremely high. This problem cummulates and results in an unreasonably
|
||||
// high spin. For some reason Geant then ends up in an infinite loop.
|
||||
//
|
||||
// G4double spinMagnitude = Spin.mag();
|
||||
// if (spinMagnitude>1.01) dSpin /= spinMagnitude;
|
||||
// if (spinMagnitude>10.) {
|
||||
// dSpin=G4ThreeVector(0.,0.,0.);
|
||||
// G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
// G4int eventNr=fRunManager->GetCurrentEvent()->GetEventID();
|
||||
// if (eventNr!=musrRootOutput::oldEventNumberInG4EqEMFieldWithSpinFunction) {
|
||||
// musrRootOutput::oldEventNumberInG4EqEMFieldWithSpinFunction = eventNr;
|
||||
// musrErrorMessage::GetInstance()->musrError(SERIOUS,
|
||||
// "G4EqEMFieldWithSpin.cc:EvaluateRhsGivenB: spin is large than 10.! Strange!!! -> Deleting this event",true);
|
||||
// G4cout<<" + G4EqEMFieldWithSpin.cc:EvaluateRhsGivenB: "
|
||||
// <<"Event nr.:"<<eventNr<<", particle mass = "<<sqrt(fMassCof)/MeV<<" MeV"
|
||||
// <<", spin = ("<<Spin.x()<<","<<Spin.y()<<","<<Spin.z()<<")."<<G4endl;
|
||||
// G4cout.flush();
|
||||
// musrRootOutput::GetRootInstance()->SetEventWeight(0);
|
||||
// fRunManager->AbortEvent();
|
||||
// }
|
||||
// }
|
||||
|
||||
// if ((spinMagnitude<0.99)&&(spinMagnitude>0.1)&&( fabs(sqrt(fMassCof)/MeV-105.6584)<1) ) dSpin /= spinMagnitude;
|
||||
// if ((spinMagnitude<0.2)&&( fabs(sqrt(fMassCof)/MeV-105.6584)<1) ) {
|
||||
// dSpin=G4ThreeVector(0.,0.,0.);
|
||||
// G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
// G4int eventNr=fRunManager->GetCurrentEvent()->GetEventID();
|
||||
// if (eventNr!=musrRootOutput::oldEventNumberInG4EqEMFieldWithSpinFunction) {
|
||||
// musrRootOutput::oldEventNumberInG4EqEMFieldWithSpinFunction = eventNr;
|
||||
// musrErrorMessage::GetInstance()->musrError(SERIOUS,
|
||||
// "G4EqEMFieldWithSpin.cc:EvaluateRhsGivenB: spin for muon is smaller than 0.2! Strange!!! -> Deleting this event",true);
|
||||
// G4cout<<" - G4EqEMFieldWithSpin.cc:EvaluateRhsGivenB: "
|
||||
// <<"Event nr.:"<<eventNr<<", particle mass = "<<sqrt(fMassCof)/MeV<<" MeV"
|
||||
// <<", spin = ("<<Spin.x()<<","<<Spin.y()<<","<<Spin.z()<<")."<<G4endl;
|
||||
// G4cout.flush();
|
||||
// musrRootOutput::GetRootInstance()->SetEventWeight(0);
|
||||
// fRunManager->AbortEvent();
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
// csk
|
||||
|
||||
dydx[ 9] = dSpin.x();
|
||||
dydx[10] = dSpin.y();
|
||||
dydx[11] = dSpin.z();
|
||||
|
||||
return ;
|
||||
}
|
202
src/MuDecayChannel.cc
Normal file
202
src/MuDecayChannel.cc
Normal file
@ -0,0 +1,202 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: MuDecayChannel.cc,v 1.17 2006/06/29 19:25:34 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-00 $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
// History: first implementation, based on object model of
|
||||
// 30 May 1997 H.Kurashige
|
||||
//
|
||||
// Fix bug in calcuration of electron energy in DecayIt 28 Feb. 01 H.Kurashige
|
||||
//2005
|
||||
// M. Melissas ( melissas AT cppm.in2p3.fr)
|
||||
// J. Brunner ( brunner AT cppm.in2p3.fr)
|
||||
// Adding V-A fluxes for neutrinos using a new algortithm :
|
||||
// ------------------------------------------------------------
|
||||
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4DecayProducts.hh"
|
||||
#include "G4VDecayChannel.hh"
|
||||
#include "MuDecayChannel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4LorentzVector.hh"
|
||||
#include "G4LorentzRotation.hh"
|
||||
#include "G4RotationMatrix.hh"
|
||||
|
||||
MuDecayChannel::MuDecayChannel(const G4String& theParentName,
|
||||
G4double theBR)
|
||||
:G4VDecayChannel("Muonium Decay",1)
|
||||
{
|
||||
// set names for daughter particles
|
||||
if (theParentName == "Mu") {
|
||||
SetBR(theBR);
|
||||
SetParent("Mu");
|
||||
SetNumberOfDaughters(3);
|
||||
SetDaughter(0, "e+");
|
||||
SetDaughter(1, "nu_e");
|
||||
SetDaughter(2, "anti_nu_mu");
|
||||
} else {
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cout << "MuDecayChannel:: constructor :";
|
||||
G4cout << " parent particle is not muon but ";
|
||||
G4cout << theParentName << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
MuDecayChannel::~MuDecayChannel()
|
||||
{
|
||||
}
|
||||
|
||||
G4DecayProducts *MuDecayChannel::DecayIt(G4double)
|
||||
{
|
||||
// this version neglects muon polarization,and electron mass
|
||||
// assumes the pure V-A coupling
|
||||
// the Neutrinos are correctly V-A.
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) G4cout << "MuDecayChannel::DecayIt ";
|
||||
#endif
|
||||
|
||||
if (parent == 0) FillParent();
|
||||
if (daughters == 0) FillDaughters();
|
||||
|
||||
// parent mass
|
||||
G4double parentmass = parent->GetPDGMass();
|
||||
|
||||
//daughters'mass
|
||||
G4double daughtermass[3];
|
||||
G4double sumofdaughtermass = 0.0;
|
||||
for (G4int index=0; index<3; index++){
|
||||
daughtermass[index] = daughters[index]->GetPDGMass();
|
||||
sumofdaughtermass += daughtermass[index];
|
||||
}
|
||||
|
||||
//create parent G4DynamicParticle at rest
|
||||
G4ThreeVector dummy;
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
|
||||
//create G4Decayproducts
|
||||
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
|
||||
delete parentparticle;
|
||||
|
||||
// calculate daughter momentum
|
||||
G4double daughtermomentum[3];
|
||||
// calcurate electron energy
|
||||
G4double xmax = (1.0+daughtermass[0]*daughtermass[0]/parentmass/parentmass);
|
||||
G4double x;
|
||||
|
||||
G4double Ee,Ene;
|
||||
|
||||
G4double gam;
|
||||
G4double EMax=parentmass/2-daughtermass[0];
|
||||
|
||||
|
||||
//Generating Random Energy
|
||||
do {
|
||||
Ee=G4UniformRand();
|
||||
do{
|
||||
x=xmax*G4UniformRand();
|
||||
gam=G4UniformRand();
|
||||
}while (gam >x*(1.-x));
|
||||
Ene=x;
|
||||
} while ( Ene < (1.-Ee));
|
||||
G4double Enm=(2.-Ee-Ene);
|
||||
|
||||
|
||||
//initialisation of rotation parameters
|
||||
|
||||
G4double costheta,sintheta,rphi,rtheta,rpsi;
|
||||
costheta= 1.-2./Ee-2./Ene+2./Ene/Ee;
|
||||
sintheta=std::sqrt(1.-costheta*costheta);
|
||||
|
||||
|
||||
rphi=twopi*G4UniformRand()*rad;
|
||||
rtheta=(std::acos(2.*G4UniformRand()-1.));
|
||||
rpsi=twopi*G4UniformRand()*rad;
|
||||
|
||||
G4RotationMatrix rot;
|
||||
rot.set(rphi,rtheta,rpsi);
|
||||
|
||||
//electron 0
|
||||
daughtermomentum[0]=std::sqrt(Ee*Ee*EMax*EMax+2.0*Ee*EMax * daughtermass[0]);
|
||||
G4ThreeVector direction0(0.0,0.0,1.0);
|
||||
|
||||
direction0 *= rot;
|
||||
|
||||
G4DynamicParticle * daughterparticle = new G4DynamicParticle ( daughters[0], direction0 * daughtermomentum[0]);
|
||||
|
||||
products->PushProducts(daughterparticle);
|
||||
|
||||
//electronic neutrino 1
|
||||
|
||||
daughtermomentum[1]=std::sqrt(Ene*Ene*EMax*EMax+2.0*Ene*EMax * daughtermass[1]);
|
||||
G4ThreeVector direction1(sintheta,0.0,costheta);
|
||||
|
||||
direction1 *= rot;
|
||||
|
||||
G4DynamicParticle * daughterparticle1 = new G4DynamicParticle ( daughters[1], direction1 * daughtermomentum[1]);
|
||||
products->PushProducts(daughterparticle1);
|
||||
|
||||
//muonic neutrino 2
|
||||
|
||||
daughtermomentum[2]=std::sqrt(Enm*Enm*EMax*EMax +2.0*Enm*EMax*daughtermass[2]);
|
||||
G4ThreeVector direction2(-Ene/Enm*sintheta,0,-Ee/Enm-Ene/Enm*costheta);
|
||||
|
||||
direction2 *= rot;
|
||||
|
||||
G4DynamicParticle * daughterparticle2 = new G4DynamicParticle ( daughters[2],
|
||||
direction2 * daughtermomentum[2]);
|
||||
products->PushProducts(daughterparticle2);
|
||||
|
||||
|
||||
|
||||
|
||||
// output message
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cout << "MuDecayChannel::DecayIt ";
|
||||
G4cout << " create decay products in rest frame " <<G4endl;
|
||||
products->DumpInfo();
|
||||
}
|
||||
#endif
|
||||
return products;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
271
src/MuDecayChannelWithSpin.cc
Normal file
271
src/MuDecayChannelWithSpin.cc
Normal file
@ -0,0 +1,271 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
// History:
|
||||
// 17 August 2004 P.Gumplinger and T.MacPhail
|
||||
// samples Michel spectrum including 1st order
|
||||
// radiative corrections
|
||||
// Reference: Florian Scheck "Muon Physics", in Physics Reports
|
||||
// (Review Section of Physics Letters) 44, No. 4 (1978)
|
||||
// 187-248. North-Holland Publishing Company, Amsterdam
|
||||
// at page 210 cc.
|
||||
//
|
||||
// W.E. Fisher and F. Scheck, Nucl. Phys. B83 (1974) 25.
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
//
|
||||
#include "MuDecayChannelWithSpin.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4DecayProducts.hh"
|
||||
#include "G4LorentzVector.hh"
|
||||
|
||||
MuDecayChannelWithSpin::MuDecayChannelWithSpin(const G4String& theParentName,
|
||||
G4double theBR)
|
||||
: MuDecayChannel(theParentName,theBR)
|
||||
{
|
||||
}
|
||||
|
||||
MuDecayChannelWithSpin::~MuDecayChannelWithSpin()
|
||||
{
|
||||
}
|
||||
|
||||
G4DecayProducts *MuDecayChannelWithSpin::DecayIt(G4double)
|
||||
{
|
||||
// This version assumes V-A coupling with 1st order radiative correctons,
|
||||
// the standard model Michel parameter values, but
|
||||
// gives incorrect energy spectrum for neutrinos
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) G4cout << "MuDecayChannelWithSpin::DecayIt ";
|
||||
#endif
|
||||
|
||||
if (parent == 0) FillParent();
|
||||
if (daughters == 0) FillDaughters();
|
||||
|
||||
// parent mass
|
||||
G4double parentmass = parent->GetPDGMass();
|
||||
|
||||
EMMU = parentmass;
|
||||
|
||||
//daughters'mass
|
||||
G4double daughtermass[3];
|
||||
G4double sumofdaughtermass = 0.0;
|
||||
for (G4int index=0; index<3; index++){
|
||||
daughtermass[index] = daughters[index]->GetPDGMass();
|
||||
sumofdaughtermass += daughtermass[index];
|
||||
}
|
||||
|
||||
EMASS = daughtermass[0];
|
||||
|
||||
//create parent G4DynamicParticle at rest
|
||||
G4ThreeVector dummy;
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
|
||||
//create G4Decayproducts
|
||||
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
|
||||
delete parentparticle;
|
||||
|
||||
// calcurate electron energy
|
||||
|
||||
G4double michel_rho = 0.75; //Standard Model Michel rho
|
||||
G4double michel_delta = 0.75; //Standard Model Michel delta
|
||||
G4double michel_xsi = 1.00; //Standard Model Michel xsi
|
||||
G4double michel_eta = 0.00; //Standard Model eta
|
||||
|
||||
G4double rndm, x, ctheta;
|
||||
|
||||
G4double FG;
|
||||
G4double FG_max = 2.00;
|
||||
|
||||
G4double W_mue = (EMMU*EMMU+EMASS*EMASS)/(2.*EMMU);
|
||||
G4double x0 = EMASS/W_mue;
|
||||
|
||||
G4double x0_squared = x0*x0;
|
||||
|
||||
// ***************************************************
|
||||
// x0 <= x <= 1. and -1 <= y <= 1
|
||||
//
|
||||
// F(x,y) = f(x)*g(x,y); g(x,y) = 1.+g(x)*y
|
||||
// ***************************************************
|
||||
|
||||
// ***** sampling F(x,y) directly (brute force) *****
|
||||
|
||||
do{
|
||||
|
||||
// Sample the positron energy by sampling from F
|
||||
|
||||
rndm = G4UniformRand();
|
||||
|
||||
x = x0 + rndm*(1.-x0);
|
||||
|
||||
G4double x_squared = x*x;
|
||||
|
||||
G4double F_IS, F_AS, G_IS, G_AS;
|
||||
|
||||
F_IS = 1./6.*(-2.*x_squared+3.*x-x0_squared);
|
||||
F_AS = 1./6.*std::sqrt(x_squared-x0_squared)*(2.*x-2.+std::sqrt(1.-x0_squared));
|
||||
|
||||
G_IS = 2./9.*(michel_rho-0.75)*(4.*x_squared-3.*x-x0_squared);
|
||||
G_IS = G_IS + michel_eta*(1.-x)*x0;
|
||||
|
||||
G_AS = 3.*(michel_xsi-1.)*(1.-x);
|
||||
G_AS = G_AS+2.*(michel_xsi*michel_delta-0.75)*(4.*x-4.+std::sqrt(1.-x0_squared));
|
||||
G_AS = 1./9.*std::sqrt(x_squared-x0_squared)*G_AS;
|
||||
|
||||
F_IS = F_IS + G_IS;
|
||||
F_AS = F_AS + G_AS;
|
||||
|
||||
// *** Radiative Corrections ***
|
||||
|
||||
G4double R_IS = F_c(x,x0);
|
||||
|
||||
G4double F = 6.*F_IS + R_IS/std::sqrt(x_squared-x0_squared);
|
||||
|
||||
// *** Radiative Corrections ***
|
||||
|
||||
G4double R_AS = F_theta(x,x0);
|
||||
|
||||
rndm = G4UniformRand();
|
||||
|
||||
ctheta = 2.*rndm-1.;
|
||||
|
||||
G4double G = 6.*F_AS - R_AS/std::sqrt(x_squared-x0_squared);
|
||||
|
||||
FG = std::sqrt(x_squared-x0_squared)*F*(1.+(G/F)*ctheta);
|
||||
|
||||
if(FG>FG_max){
|
||||
G4cout<<"***Problem in Muon Decay *** : FG > FG_max"<<G4endl;
|
||||
FG_max = FG;
|
||||
}
|
||||
|
||||
rndm = G4UniformRand();
|
||||
|
||||
}while(FG<rndm*FG_max);
|
||||
|
||||
G4double energy = x * W_mue;
|
||||
|
||||
rndm = G4UniformRand();
|
||||
|
||||
G4double phi = twopi * rndm;
|
||||
|
||||
if(energy < EMASS) energy = EMASS;
|
||||
|
||||
// calculate daughter momentum
|
||||
G4double daughtermomentum[3];
|
||||
|
||||
daughtermomentum[0] = std::sqrt(energy*energy - EMASS*EMASS);
|
||||
|
||||
G4double stheta = std::sqrt(1.-ctheta*ctheta);
|
||||
G4double cphi = std::cos(phi);
|
||||
G4double sphi = std::sin(phi);
|
||||
|
||||
//Coordinates of the decay positron with respect to the muon spin
|
||||
|
||||
G4double px = stheta*cphi;
|
||||
G4double py = stheta*sphi;
|
||||
G4double pz = ctheta;
|
||||
|
||||
G4ThreeVector direction0(px,py,pz);
|
||||
|
||||
direction0.rotateUz(parent_polarization);
|
||||
|
||||
G4DynamicParticle * daughterparticle0
|
||||
= new G4DynamicParticle( daughters[0], daughtermomentum[0]*direction0);
|
||||
|
||||
products->PushProducts(daughterparticle0);
|
||||
|
||||
|
||||
// daughter 1 ,2 (neutrinos)
|
||||
// create neutrinos in the C.M frame of two neutrinos
|
||||
G4double energy2 = parentmass*(1.0 - x/2.0);
|
||||
G4double vmass = std::sqrt((energy2-daughtermomentum[0])*(energy2+daughtermomentum[0]));
|
||||
G4double beta = -1.0*daughtermomentum[0]/energy2;
|
||||
G4double costhetan = 2.*G4UniformRand()-1.0;
|
||||
G4double sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
|
||||
G4double phin = twopi*G4UniformRand()*rad;
|
||||
G4double sinphin = std::sin(phin);
|
||||
G4double cosphin = std::cos(phin);
|
||||
|
||||
G4ThreeVector direction1(sinthetan*cosphin,sinthetan*sinphin,costhetan);
|
||||
G4DynamicParticle * daughterparticle1
|
||||
= new G4DynamicParticle( daughters[1], direction1*(vmass/2.));
|
||||
G4DynamicParticle * daughterparticle2
|
||||
= new G4DynamicParticle( daughters[2], direction1*(-1.0*vmass/2.));
|
||||
|
||||
// boost to the muon rest frame
|
||||
G4LorentzVector p4;
|
||||
p4 = daughterparticle1->Get4Momentum();
|
||||
p4.boost( direction0.x()*beta, direction0.y()*beta, direction0.z()*beta);
|
||||
daughterparticle1->Set4Momentum(p4);
|
||||
p4 = daughterparticle2->Get4Momentum();
|
||||
p4.boost( direction0.x()*beta, direction0.y()*beta, direction0.z()*beta);
|
||||
daughterparticle2->Set4Momentum(p4);
|
||||
products->PushProducts(daughterparticle1);
|
||||
products->PushProducts(daughterparticle2);
|
||||
daughtermomentum[1] = daughterparticle1->GetTotalMomentum();
|
||||
daughtermomentum[2] = daughterparticle2->GetTotalMomentum();
|
||||
|
||||
// output message
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cout << "MuDecayChannelWithSpin::DecayIt ";
|
||||
G4cout << " create decay products in rest frame " <<G4endl;
|
||||
products->DumpInfo();
|
||||
}
|
||||
#endif
|
||||
return products;
|
||||
}
|
||||
|
||||
G4double MuDecayChannelWithSpin::R_c(G4double x){
|
||||
|
||||
G4int n_max = (int)(100.*x);
|
||||
|
||||
if(n_max<10)n_max=10;
|
||||
|
||||
G4double L2 = 0.0;
|
||||
|
||||
for(G4int n=1; n<=n_max; n++){
|
||||
L2 += std::pow(x,n)/(n*n);
|
||||
}
|
||||
|
||||
G4double omega = std::log(EMMU/EMASS);
|
||||
|
||||
G4double r_c;
|
||||
|
||||
r_c = 2.*L2-(pi*pi/3.)-2.;
|
||||
r_c = r_c + omega * (1.5+2.*std::log((1.-x)/x));
|
||||
r_c = r_c - std::log(x)*(2.*std::log(x)-1.);
|
||||
r_c = r_c + (3.*std::log(x)-1.-1./x)*std::log(1.-x);
|
||||
|
||||
return r_c;
|
||||
}
|
1032
src/meyer.cc
Normal file
1032
src/meyer.cc
Normal file
File diff suppressed because it is too large
Load Diff
1173
src/musrDetectorConstruction.cc
Normal file
1173
src/musrDetectorConstruction.cc
Normal file
File diff suppressed because it is too large
Load Diff
168
src/musrDetectorMessenger.cc
Normal file
168
src/musrDetectorMessenger.cc
Normal file
@ -0,0 +1,168 @@
|
||||
#include "musrDetectorMessenger.hh"
|
||||
#include "musrDetectorConstruction.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIcmdWith3Vector.hh"
|
||||
#include "G4UIcmdWith3VectorAndUnit.hh"
|
||||
|
||||
#include "G4RunManager.hh" //cks included in order to be able to change run ID
|
||||
#include "Randomize.hh" //cks included in order to initialise the random nr. generator by time
|
||||
#include <time.h> //cks -----------------------------||-------------------------------
|
||||
#include "musrEventAction.hh" // cks needed for setting the variable "nHowOftenToPrintEvent"
|
||||
#include "musrPrimaryGeneratorAction.hh" // cks needed for the initialisation of the random nr. generator by event nr.
|
||||
#include <vector>
|
||||
#include "globals.hh"
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
musrDetectorMessenger::musrDetectorMessenger(musrDetectorConstruction* myDet)
|
||||
:myDetector(myDet)
|
||||
{
|
||||
musrDir = new G4UIdirectory("/musr/");
|
||||
musrDir->SetGuidance("UI commands specific to this example.");
|
||||
|
||||
Ignore1Cmd = new G4UIcmdWithAString("/musr/ignore",this);
|
||||
Ignore1Cmd->SetGuidance("This command is ignored by the messenger, but used for the detector construction.");
|
||||
Ignore1Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
Ignore2Cmd = new G4UIcmdWithAString("/musr/command",this);
|
||||
Ignore2Cmd->SetGuidance("This command is ignored by the messenger, but used for the detector construction.");
|
||||
Ignore2Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
runDir = new G4UIdirectory("/musr/run/");
|
||||
runDir->SetGuidance("musr run control");
|
||||
|
||||
RunIDSetCmd = new G4UIcmdWithAnInteger("/musr/run/runID",this);
|
||||
RunIDSetCmd->SetGuidance("Set the run number");
|
||||
RunIDSetCmd->SetParameterName("something",false);
|
||||
RunIDSetCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
RandomOptionCmd = new G4UIcmdWithAnInteger("/musr/run/randomOption",this);
|
||||
RandomOptionCmd->SetGuidance("Specify the random number generator initialisation");
|
||||
RandomOptionCmd->SetGuidance(" 0 ... no initialisation (default)");
|
||||
RandomOptionCmd->SetGuidance(" 1 ... use actual computer time to initialise now");
|
||||
RandomOptionCmd->SetGuidance(" 2 ... use event number to initialise at the beginning of each event");
|
||||
RandomOptionCmd->SetGuidance(" 3 ... read in the random no. initial values for each event from a file");
|
||||
RandomOptionCmd->SetGuidance(" 4 ... read in the random no. initial values for each event from the file kamil.rndm");
|
||||
RandomOptionCmd->SetParameterName("randomOpt",false);
|
||||
RandomOptionCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
HowOftenToPrintEventCmd = new G4UIcmdWithAnInteger("/musr/run/howOftenToPrintEvent",this);
|
||||
HowOftenToPrintEventCmd->SetGuidance("Each n-th event will be notified. Set _n_ by this command.");
|
||||
HowOftenToPrintEventCmd->SetParameterName("howOftenToPrintEv",false);
|
||||
HowOftenToPrintEventCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
RndmEventToSaveSeedsCmd = new G4UIcmdWithAnInteger("/musr/run/rndmEventToSaveSeeds",this);
|
||||
RndmEventToSaveSeedsCmd -> SetGuidance("Save seeds of the random number generators of the given event number.");
|
||||
RndmEventToSaveSeedsCmd -> SetParameterName("rndmEventToSaveSe",false);
|
||||
RndmEventToSaveSeedsCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
detDir = new G4UIdirectory("/musr/det/");
|
||||
detDir->SetGuidance("detector control.");
|
||||
|
||||
UpdateCmd = new G4UIcmdWithoutParameter("/musr/det/update",this);
|
||||
UpdateCmd->SetGuidance("Update calorimeter geometry.");
|
||||
UpdateCmd->SetGuidance("This command MUST be applied before \"beamOn\" ");
|
||||
UpdateCmd->SetGuidance("if you changed geometrical value(s).");
|
||||
UpdateCmd->AvailableForStates(G4State_Idle);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrDetectorMessenger::~musrDetectorMessenger()
|
||||
{
|
||||
delete UpdateCmd;
|
||||
delete detDir;
|
||||
delete musrDir;
|
||||
delete Ignore1Cmd;
|
||||
delete Ignore2Cmd;
|
||||
delete RunIDSetCmd;
|
||||
delete RandomOptionCmd;
|
||||
delete HowOftenToPrintEventCmd;
|
||||
delete RndmEventToSaveSeedsCmd;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrDetectorMessenger::SetNewValue(G4UIcommand* command,G4String newValue) {
|
||||
|
||||
if( command == UpdateCmd )
|
||||
{ myDetector->UpdateGeometry(); }
|
||||
|
||||
if( command == RunIDSetCmd )
|
||||
{ (G4RunManager::GetRunManager())->SetRunIDCounter(RunIDSetCmd->GetNewIntValue(newValue));}
|
||||
|
||||
if( command == RandomOptionCmd )
|
||||
{
|
||||
G4int RandomOption=RandomOptionCmd->GetNewIntValue(newValue);
|
||||
if (RandomOption == 1) {
|
||||
// G4long seed=time(0); //returns time in seconds as an integer
|
||||
// HepRandom::setTheSeed(seed);//changes the seed of the random engine
|
||||
G4cout << "******************************************" << G4endl;
|
||||
G4cout << "*** Random Seed set by the system time ***" << G4endl;
|
||||
G4cout << "******************************************" << G4endl;
|
||||
long seeds[2];
|
||||
time_t systime = time(NULL);
|
||||
seeds[0] = (long) systime;
|
||||
seeds[1] = (long) (systime*G4UniformRand());
|
||||
G4cout << "seed1: " << seeds[0] << "; seed2: " << seeds[1] << G4endl;
|
||||
CLHEP::HepRandom::setTheSeeds(seeds);
|
||||
CLHEP::HepRandom::showEngineStatus();
|
||||
}
|
||||
else if (RandomOption == 2) {
|
||||
G4cout << "*******************************************" << G4endl;
|
||||
G4cout << "*** Random Seed set by the event number ***" << G4endl;
|
||||
G4cout << "*******************************************" << G4endl;
|
||||
// musrEventAction::setRandomNrSeedAccordingEventNr=1;
|
||||
musrPrimaryGeneratorAction::setRandomNrSeedAccordingEventNr=1;
|
||||
// musrEventAction::setMyEventNr(70);
|
||||
}
|
||||
else if (RandomOption == 3) {
|
||||
G4cout << "*******************************************" << G4endl;
|
||||
G4cout << "*** Random Seed set from external file ***" << G4endl;
|
||||
G4cout << "*******************************************" << G4endl;
|
||||
// musrEventAction::setRandomNrSeedFromFile=1;
|
||||
musrPrimaryGeneratorAction::setRandomNrSeedFromFile=1;
|
||||
std::ifstream indata;
|
||||
int num;
|
||||
|
||||
indata.open("randomNum.dat"); // opens the file
|
||||
if(!indata) { // file couldn't be opened
|
||||
G4cout << "Error: file could not be opened" << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
std::vector<int> * seedVector = musrPrimaryGeneratorAction::GetPointerToSeedVector();
|
||||
indata >> num;
|
||||
while ( !indata.eof() ) { // keep reading until end-of-file
|
||||
G4cout << "The next number is " << num << G4endl;
|
||||
seedVector->push_back(num);
|
||||
indata >> num; // sets EOF flag if no value found
|
||||
}
|
||||
indata.close();
|
||||
G4cout << "End-of-file reached.." << seedVector->size()<<G4endl;
|
||||
}
|
||||
else if (RandomOption == 4) {
|
||||
G4cout << "*********************************************" << G4endl;
|
||||
G4cout << "*** Random Seed set from kamil.rndm file ***" << G4endl;
|
||||
G4cout << "*********************************************" << G4endl;
|
||||
musrPrimaryGeneratorAction::setRandomNrSeedFromFile_RNDM=1;
|
||||
}
|
||||
}
|
||||
if ( command == HowOftenToPrintEventCmd )
|
||||
{
|
||||
G4int n = HowOftenToPrintEventCmd->GetNewIntValue(newValue);
|
||||
musrEventAction::nHowOftenToPrintEvent=n;
|
||||
}
|
||||
if ( command == RndmEventToSaveSeedsCmd )
|
||||
{
|
||||
G4int n = RndmEventToSaveSeedsCmd->GetNewIntValue(newValue);
|
||||
musrPrimaryGeneratorAction::nRndmEventToSaveSeeds=n;
|
||||
}
|
||||
|
||||
}
|
62
src/musrErrorMessage.cc
Normal file
62
src/musrErrorMessage.cc
Normal file
@ -0,0 +1,62 @@
|
||||
#include "musrErrorMessage.hh"
|
||||
|
||||
musrErrorMessage::musrErrorMessage():nErrors(1)
|
||||
{
|
||||
pointerToErrors=this;
|
||||
severityWord[INFO]="INFO";
|
||||
severityWord[WARNING]="WARNING";
|
||||
severityWord[SERIOUS]="SERIOUS";
|
||||
severityWord[FATAL]="FATAL";
|
||||
}
|
||||
|
||||
musrErrorMessage::~musrErrorMessage() {}
|
||||
|
||||
musrErrorMessage* musrErrorMessage::pointerToErrors=NULL;
|
||||
musrErrorMessage* musrErrorMessage::GetInstance() {
|
||||
return pointerToErrors;
|
||||
}
|
||||
|
||||
void musrErrorMessage::musrError(SEVERITY severity, G4String message, G4bool silent) {
|
||||
std::map<G4String,ErrorStruct>::iterator it;
|
||||
it = ErrorMapping.find(message);
|
||||
if (it == ErrorMapping.end()) { // The error message is called for the first time
|
||||
ErrorStruct actualErrorMessage;
|
||||
actualErrorMessage.mesSeverity = severity;
|
||||
actualErrorMessage.nTimes = 1;
|
||||
ErrorMapping[message]=actualErrorMessage;
|
||||
G4cout<<"!!!"<<severityWord[severity]<<"!!! "<<message<<" (First time occurrence)"<<G4endl;
|
||||
nErrors++;
|
||||
}
|
||||
else { // The error message is called for more than the first time
|
||||
(*it).second.nTimes++;
|
||||
}
|
||||
|
||||
// Print out the error message if required
|
||||
if ((!silent)||(severity==FATAL)) {
|
||||
if ((*it).second.nTimes>1) {
|
||||
G4cout<<"!!!"<<severityWord[severity]<<"!!! "<<message
|
||||
<<" ("<<(*it).second.nTimes<<" occurences)"<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (severity==FATAL) {
|
||||
G4cout<<"S T O P F O R C E D!"<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void musrErrorMessage::PrintErrorSummary() {
|
||||
std::map<G4String,ErrorStruct>::iterator it;
|
||||
G4cout<<"------ ERROR SUMMARY: ----------------------------------------------------------------"<<G4endl;
|
||||
for (G4int i=0; i<4; i++) {
|
||||
for ( it=ErrorMapping.begin() ; it != ErrorMapping.end(); it++ ) {
|
||||
if ((*it).second.mesSeverity==i) {
|
||||
G4cout<<severityWord[(*it).second.mesSeverity]<<" ("<<(*it).second.nTimes<<" times):"
|
||||
<< (*it).first <<G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
G4cout<<"-----------------------------------------------------------------------------------------"<<G4endl;
|
||||
}
|
92
src/musrEventAction.cc
Normal file
92
src/musrEventAction.cc
Normal file
@ -0,0 +1,92 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "musrEventAction.hh"
|
||||
#include "G4Event.hh"
|
||||
#include "G4EventManager.hh"
|
||||
#include "G4TrajectoryContainer.hh"
|
||||
#include "G4Trajectory.hh"
|
||||
#include "G4VVisManager.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4FieldManager.hh"
|
||||
#include "musrRootOutput.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "musrSteppingAction.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
#include "G4RunManager.hh" // needed just in order to save random number generator seed
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int musrEventAction::nHowOftenToPrintEvent=10000;
|
||||
G4double musrEventAction::maximumRunTimeAllowed=85000;
|
||||
|
||||
musrEventAction::musrEventAction() {
|
||||
pointer=this;
|
||||
}
|
||||
musrEventAction* musrEventAction::pointer=0;
|
||||
musrEventAction* musrEventAction::GetInstance() {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrEventAction::~musrEventAction()
|
||||
{
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrEventAction::BeginOfEventAction(const G4Event* evt) {
|
||||
// G4cout<<"musrEventAction::BeginOfEventAction:"<<G4endl;
|
||||
long thisEventNr = (long) (evt->GetEventID());
|
||||
|
||||
// if (thisEventNr == 44654) {trackingManager->SetVerboseLevel(2);}
|
||||
musrSteppingAction::GetInstance()->DoAtTheBeginningOfEvent();
|
||||
|
||||
if (F04GlobalField::Exists()) {
|
||||
F04GlobalField::getObject() -> CheckWhetherAnyNominalFieldValueNeedsToBeChanged(thisEventNr);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrEventAction::EndOfEventAction(const G4Event* evt) {
|
||||
// cout << ":." << flush;
|
||||
long thisEventNr = (long) evt->GetEventID();
|
||||
|
||||
// get number of stored trajectories
|
||||
G4TrajectoryContainer* trajectoryContainer = evt->GetTrajectoryContainer();
|
||||
G4int n_trajectories = 0;
|
||||
if (trajectoryContainer) n_trajectories = trajectoryContainer->entries();
|
||||
|
||||
// G4cout << ">>> Event " << evt->GetEventID() << G4endl;
|
||||
|
||||
// periodic printing
|
||||
//
|
||||
// if (thisEventNr != 0 and thisEventNr%10000 == 0) {
|
||||
if (thisEventNr == 0) timeOfRunStart=time(0);
|
||||
if ((time(0)-timeOfRunStart)>maximumRunTimeAllowed) {
|
||||
// Stop the execution of the run - the run took already too long time
|
||||
char eMessage[200];
|
||||
sprintf(eMessage,"musrEventAction::EndOfEventAction(): Run execution exceeded the allowed maximum time (maximum = %f sec) ==> RUN STOPPED",maximumRunTimeAllowed);
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,eMessage,false);
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
fRunManager->AbortRun(true);
|
||||
}
|
||||
if (thisEventNr != 0 and thisEventNr%nHowOftenToPrintEvent == 0) {
|
||||
time_t curr=time(0);
|
||||
//char * ctime(const time_t * tp);
|
||||
G4cout << ">>> Event " << evt->GetEventID() <<". Running already for "<<curr-timeOfRunStart<<" seconds. Present time: "<< ctime(&curr);
|
||||
G4cout.flush();
|
||||
// G4cout << " seed set to "<< CLHEP::HepRandom::getTheSeed();//<< G4endl;
|
||||
}
|
||||
|
||||
// extract the trajectories and draw them
|
||||
if (G4VVisManager::GetConcreteInstance()) {
|
||||
for (G4int i=0; i<n_trajectories; i++)
|
||||
{ G4Trajectory* trj = (G4Trajectory*)
|
||||
((*(evt->GetTrajectoryContainer()))[i]);
|
||||
trj->DrawTrajectory(1000);
|
||||
}
|
||||
}
|
||||
}
|
111
src/musrMuFormation.cc
Normal file
111
src/musrMuFormation.cc
Normal file
@ -0,0 +1,111 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
// Muonium Formation according to yield.cc function (through GetYields method).
|
||||
// Id : musrMuFormation.cc, v 1.4
|
||||
// Author: Taofiq PARAISO, T. Shiroka
|
||||
// Date : 2007-12
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
|
||||
#include "musrMuFormation.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
musrMuFormation::musrMuFormation(const G4String& name, G4ProcessType aType)
|
||||
: G4VDiscreteProcess(name, aType){}
|
||||
|
||||
musrMuFormation::~musrMuFormation(){}
|
||||
|
||||
G4VParticleChange* musrMuFormation::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& aStep)
|
||||
{ // Initialize ParticleChange (by setting all its members equal to
|
||||
// the corresponding members in G4Track)
|
||||
fParticleChange.Initialize(trackData);
|
||||
|
||||
G4Track theNewTrack;
|
||||
if(CheckCondition(aStep))
|
||||
{
|
||||
GetDatas(&aStep);
|
||||
G4Step theStep;
|
||||
PrepareSecondary( trackData);
|
||||
|
||||
fParticleChange.AddSecondary(aSecondary);
|
||||
fParticleChange.ProposeTrackStatus(fStopAndKill) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange.ProposeTrackStatus(trackData.GetTrackStatus()) ;
|
||||
}
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
|
||||
G4bool musrMuFormation::CheckCondition(const G4Step& aStep)
|
||||
{ // Decide when to call the MuFormation process - i.e. for muons going through the C foil.
|
||||
G4bool condition=false;
|
||||
p_name = aStep.GetTrack()->GetDefinition()->GetParticleName(); // particle name
|
||||
//if(p_name == "mu+"&&aStep.GetTrack()->GetVolume()->GetLogicalVolume()->GetName()=="log_CFoil")
|
||||
std::string logVolName = aStep.GetTrack()->GetVolume()->GetLogicalVolume()->GetName();
|
||||
if(p_name == "mu+" && ((logVolName=="log_coulombCFoil")||(logVolName=="log_CFoil")))
|
||||
{
|
||||
condition=true;
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
|
||||
G4double musrMuFormation::GetMeanFreePath(const G4Track&,
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
*condition = Forced;
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
|
||||
void musrMuFormation::GetDatas(const G4Step* aStep)
|
||||
{ // Particle generation according to yield table
|
||||
particleTable=G4ParticleTable::GetParticleTable();
|
||||
rnd=G4UniformRand();
|
||||
G4double E = aStep->GetTrack()->GetDynamicParticle()->GetKineticEnergy()/keV;
|
||||
Gonin.GetYields(E,105.658369*1000,yvector); // Energy [keV], muon mass [keV/c2], yield table
|
||||
G4String p_new = "Mu";
|
||||
|
||||
// Positive muon
|
||||
if(p_name=="mu+")
|
||||
{
|
||||
if(rnd<yvector[0])
|
||||
{
|
||||
particle = particleTable->FindParticle(p_name) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
particle = particleTable->FindParticle(p_new);
|
||||
}
|
||||
|
||||
// Set the new dynamic particle DP
|
||||
DP = new G4DynamicParticle(particle,
|
||||
aStep->GetTrack()->GetDynamicParticle()->GetMomentumDirection(),
|
||||
aStep->GetTrack()->GetDynamicParticle()->GetKineticEnergy());
|
||||
|
||||
// IMPORTANT : COPY THOSE DATA TO GET THE SAME PARTICLE PROPERTIES!!!
|
||||
// SHOULD BE KEPT WHEN BUILDING A PARTICLE CHANGE
|
||||
DP->SetProperTime( aStep->GetTrack()->GetDynamicParticle()->GetProperTime());
|
||||
DP->SetPolarization(aStep->GetTrack()->GetDynamicParticle()->GetPolarization().x(),
|
||||
aStep->GetTrack()->GetDynamicParticle()->GetPolarization().y(),
|
||||
aStep->GetTrack()->GetDynamicParticle()->GetPolarization().z());
|
||||
DP->SetPreAssignedDecayProperTime(aStep->GetTrack()->GetDynamicParticle()->GetPreAssignedDecayProperTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void musrMuFormation::PrepareSecondary(const G4Track& track)
|
||||
{
|
||||
if(p_name=="mu+")
|
||||
{
|
||||
aSecondary = new G4Track(DP,track.GetGlobalTime(),track.GetPosition());
|
||||
}
|
||||
}
|
86
src/musrMuScatter.cc
Normal file
86
src/musrMuScatter.cc
Normal file
@ -0,0 +1,86 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
// Muonium "Scattering"
|
||||
// Id : musrMuScatter.cc, v 1.4
|
||||
// Author: Taofiq PARAISO, T. Shiroka
|
||||
// Date : 2007-12
|
||||
// Notes : Simplified model for Mu scattering. Spin effects have been excluded.
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
|
||||
#include "musrMuScatter.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
musrMuScatter::musrMuScatter(const G4String& name,
|
||||
G4ProcessType aType)
|
||||
: G4VDiscreteProcess(name, aType){}
|
||||
|
||||
musrMuScatter:: ~musrMuScatter(){}
|
||||
|
||||
/*! - At the end of the step, the current volume is checked and if Muonium is in a solid
|
||||
material (except for the carbon foil where it is generated), it is stopped immediately. */
|
||||
G4VParticleChange* musrMuScatter::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
fParticleChange.Initialize(trackData);
|
||||
|
||||
//! Tao - Get time information */
|
||||
itime = trackData.GetProperTime();
|
||||
gtime = trackData.GetGlobalTime();
|
||||
ftime = trackData.GetDynamicParticle()->GetPreAssignedDecayProperTime();
|
||||
|
||||
deltatime = ftime - itime;
|
||||
fParticleChange.ProposeGlobalTime(deltatime + itime -gtime);
|
||||
|
||||
/*! - Set position, momentum, energy and time of the particle change. */
|
||||
fParticleChange.ProposePosition(trackData.GetPosition());
|
||||
fParticleChange.ProposeMomentumDirection(trackData.GetMomentumDirection());
|
||||
fParticleChange.ProposeEnergy(trackData.GetKineticEnergy());
|
||||
fParticleChange.ProposeGlobalTime(gtime);
|
||||
fParticleChange.ProposeProperTime(itime);
|
||||
fParticleChange.ProposeTrackStatus(trackData.GetTrackStatus()) ;
|
||||
|
||||
/*! - Verify the condition of applying the process: if Mu is in a material
|
||||
different than vacuum and carbon foil, then stop it directly. */
|
||||
if( CheckCondition(aStep))
|
||||
{
|
||||
fParticleChange.ProposePosition(trackData.GetStep()->GetPreStepPoint()->GetPosition());
|
||||
fParticleChange.ProposeTrackStatus(fStopButAlive) ;
|
||||
}
|
||||
|
||||
/*! - Return the changed particle object. */
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
|
||||
/*! - Muonium will be stopped as soon as it enters a material different than vacuum or C foil. */
|
||||
G4bool musrMuScatter::CheckCondition(const G4Step& aStep)
|
||||
{
|
||||
G4bool condition = false;
|
||||
p_name = aStep.GetTrack()->GetDefinition()->GetParticleName(); // particle name
|
||||
if(p_name == "Mu" && aStep.GetTrack()->GetVolume()->GetLogicalVolume()->GetName()!="log_CFoil" &&
|
||||
aStep.GetTrack()->GetVolume()->GetLogicalVolume()->GetMaterial()->GetName()!="G4_Galactic")
|
||||
{
|
||||
condition=true;
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
|
||||
G4double musrMuScatter::GetMeanFreePath(const G4Track&,
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
*condition = Forced;
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
|
||||
void musrMuScatter::PrepareSecondary(const G4Track& track)
|
||||
{
|
||||
aSecondary = new G4Track(DP,track.GetDynamicParticle()->GetPreAssignedDecayProperTime(),track.GetPosition());
|
||||
}
|
112
src/musrMuonium.cc
Normal file
112
src/musrMuonium.cc
Normal file
@ -0,0 +1,112 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: musrMuonium.cc,v 1.13 2007/03/15 06:53:58 kurasige Exp $
|
||||
// GEANT4 tag $Name: geant4-09-00 $
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// History: first implementation, based on object model of
|
||||
// 4th April 1996, G. Cosmo
|
||||
// **********************************************************************
|
||||
// New implementation as an utility class M. Asai, 26 July 2004
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#include "musrMuonium.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
|
||||
#include "MuDecayChannel.hh"
|
||||
#include "G4DecayTable.hh"
|
||||
|
||||
// ######################################################################
|
||||
// ### MUONIUM ###
|
||||
// ######################################################################
|
||||
musrMuonium* musrMuonium::theInstance = 0;
|
||||
|
||||
musrMuonium* musrMuonium::Definition()
|
||||
{
|
||||
if (theInstance !=0) return theInstance;
|
||||
const G4String name = "Mu";
|
||||
// search in particle table]
|
||||
G4ParticleTable* pTable = G4ParticleTable::GetParticleTable();
|
||||
G4ParticleDefinition* anInstance = pTable->FindParticle(name);
|
||||
if (anInstance ==0)
|
||||
{
|
||||
// create particle
|
||||
//
|
||||
// Arguments for constructor are as follows
|
||||
// name mass width charge
|
||||
// 2*spin parity C-conjugation
|
||||
// 2*Isospin 2*Isospin3 G-parity
|
||||
// type lepton number baryon number PDG encoding
|
||||
// stable lifetime decay table
|
||||
// shortlived subType anti_encoding
|
||||
anInstance = new G4ParticleDefinition(
|
||||
name, 0.1056584*GeV, 2.99591e-16*MeV, 0.*eplus,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
"lepton", -1, 0, -1313,
|
||||
false, 2197.03*ns, NULL,
|
||||
false, "mu"
|
||||
);
|
||||
// Bohr magnetron of Muonium - T. Shiroka
|
||||
// The magnetic moment of Mu is the sum of those of mu+ and e- with
|
||||
// the respective gyromagnetic ratio anomalies as coefficients
|
||||
|
||||
G4double muBmu = 0.5*eplus*hbar_Planck/(0.10565840*GeV/c_squared);
|
||||
G4double muBel = -0.5*eplus*hbar_Planck/(0.51099906*MeV/c_squared);
|
||||
G4double muB = 1.0011659208*muBmu + 1.0011596521859*muBel;
|
||||
|
||||
anInstance->SetPDGMagneticMoment( muB );
|
||||
|
||||
//create Decay Table
|
||||
G4DecayTable* table = new G4DecayTable();
|
||||
// create a decay channel
|
||||
G4VDecayChannel* mode = new MuDecayChannel("Mu",1.00);
|
||||
table->Insert(mode);
|
||||
anInstance->SetDecayTable(table);
|
||||
}
|
||||
theInstance = reinterpret_cast<musrMuonium*>(anInstance);
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
musrMuonium* musrMuonium::MuoniumDefinition()
|
||||
{
|
||||
return Definition();
|
||||
}
|
||||
|
||||
musrMuonium* musrMuonium::Muonium()
|
||||
{
|
||||
return Definition();
|
||||
}
|
||||
|
91
src/musrParameters.cc
Normal file
91
src/musrParameters.cc
Normal file
@ -0,0 +1,91 @@
|
||||
#include "musrParameters.hh"
|
||||
// #include "musrErrorMessage.hh" - musrErrorMessage class can not be used inside "musrParameters" constructor, because
|
||||
// musrErrorMessage is crated later!
|
||||
|
||||
musrParameters::musrParameters(G4String steeringFileName)
|
||||
{
|
||||
pointerToParameters = this;
|
||||
boolG4RegionRequested = false;
|
||||
mySteeringFileName = steeringFileName;
|
||||
|
||||
// Read in the parameters, which have to be known before the detector construction is run
|
||||
// (and therefore the parameters can not be read in in the musrDetectorConstruction.cc class).
|
||||
|
||||
FILE *fSteeringFile=fopen(steeringFileName.c_str(),"r");
|
||||
if (fSteeringFile==NULL) {
|
||||
G4cout<<"musrParameters::musrParameters: steeringFileName=\""<<steeringFileName
|
||||
<<"\" not opened for some reason."<<G4endl;
|
||||
G4cout << "S T O P F O R C E D" << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
G4cout<<"musrParameters::musrParameters: steeringFileName=\""<<steeringFileName<<"\" opened."<<G4endl;
|
||||
char line[501];
|
||||
|
||||
while (!feof(fSteeringFile)) {
|
||||
fgets(line,500,fSteeringFile);
|
||||
if ((line[0]!='#')&&(line[0]!='\n')&&(line[0]!='\r')) {
|
||||
char tmpString0[100]="Unset";
|
||||
sscanf(&line[0],"%s",tmpString0);
|
||||
// First find out how many events will be generated (needs to be known at an early stage, if the
|
||||
// field is to be set in steps):
|
||||
if (strcmp(tmpString0,"/run/beamOn")==0) {
|
||||
int nev;
|
||||
sscanf(&line[0],"%*s %d", &nev);
|
||||
musrParameters::nrOfEventsToBeGenerated = nev;
|
||||
}
|
||||
if (strncmp(tmpString0,"/gps/",5)==0) {
|
||||
musrParameters::boolG4GeneralParticleSource = true;
|
||||
G4cout<<"\n========================================================================"<<G4endl;
|
||||
G4cout<<"musrParameters.cc: GPS (General Particle Source) requested in the macro."<<G4endl;
|
||||
G4cout<<" GPS will be used instead of the primary generator action."<<G4endl;
|
||||
}
|
||||
|
||||
// Now find some private parameters that need to be initialised at early stage
|
||||
if ( (strcmp(tmpString0,"/musr/ignore")!=0)&&(strcmp(tmpString0,"/musr/command")!=0) ) continue;
|
||||
|
||||
char tmpString1[100]="Unset", tmpString2[100]="Unset", tmpString3[100]="Unset";
|
||||
sscanf(&line[0],"%*s %s %s %s",tmpString1,tmpString2,tmpString3);
|
||||
// if (strcmp(tmpString1,"G4GeneralParticleSource")==0){
|
||||
// if (strcmp(tmpString2,"true")==0){ musrParameters::boolG4GeneralParticleSource = true; }
|
||||
// }
|
||||
if (strcmp(tmpString1,"G4OpticalPhotons")==0){
|
||||
if (strcmp(tmpString2,"true")==0){ musrParameters::boolG4OpticalPhotons = true; }
|
||||
}
|
||||
if (strcmp(tmpString1,"region")==0) {
|
||||
boolG4RegionRequested = true;
|
||||
}
|
||||
if ( (strcmp(tmpString1,"construct")==0) && boolG4RegionRequested) {
|
||||
G4cout<<"musrParameters.cc: User requests to construct a detector volume "<<tmpString3<<G4endl;
|
||||
G4cout<<" after a previous G4Region definition."<<G4endl;
|
||||
G4cout<<" Perhaps not a crutial problem, but the execution will be stopped"<<G4endl;
|
||||
G4cout<<" anyway just to be on the safe side. Please correct "<<steeringFileName<<" file"<<G4endl;
|
||||
G4cout<<" such that G4Region is called only after all detector volumes have been created."<<G4endl;
|
||||
G4cout<<" S T O P F O R C E D!"<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fSteeringFile);
|
||||
}
|
||||
|
||||
musrParameters::~musrParameters() {}
|
||||
|
||||
musrParameters* musrParameters::pointerToParameters=NULL;
|
||||
musrParameters* musrParameters::GetInstance() {
|
||||
return pointerToParameters;
|
||||
}
|
||||
|
||||
G4String musrParameters::mySteeringFileName="Unset";
|
||||
G4bool musrParameters::storeOnlyEventsWithHits=true;
|
||||
G4int musrParameters::storeOnlyEventsWithHitInDetID=0;
|
||||
G4double musrParameters::signalSeparationTime=100*nanosecond;
|
||||
G4bool musrParameters::storeOnlyTheFirstTimeHit=false;
|
||||
G4bool musrParameters::field_DecayWithSpin=false;
|
||||
G4bool musrParameters::killAllPositrons=false;
|
||||
G4bool musrParameters::killAllGammas=false;
|
||||
G4bool musrParameters::killAllNeutrinos=true;
|
||||
G4bool musrParameters::boolG4GeneralParticleSource=false;
|
||||
G4bool musrParameters::boolG4OpticalPhotons=false;
|
||||
//cks G4bool musrParameters::includeMuoniumProcesses =true; // TS
|
||||
//G4bool musrParameters::boolG4GeneralParticleSource=true;
|
||||
G4int musrParameters::nrOfEventsToBeGenerated=0;
|
444
src/musrPhysicsList.cc
Normal file
444
src/musrPhysicsList.cc
Normal file
@ -0,0 +1,444 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "musrPhysicsList.hh"
|
||||
#include "G4VPhysicsConstructor.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4ParticleTypes.hh"
|
||||
|
||||
#include "G4MuonDecayChannel.hh"
|
||||
#include "G4DecayTable.hh"
|
||||
//cks Added to have Geant default muon decay with spin
|
||||
#include "G4MuonDecayChannelWithSpin.hh"
|
||||
#include "G4MuonRadiativeDecayChannelWithSpin.hh"
|
||||
#include "G4RadioactiveDecay.hh"
|
||||
#include "G4IonConstructor.hh"
|
||||
//TS Classes which account for Muonium as "particle" and its spin
|
||||
#include "musrMuonium.hh"
|
||||
#include "MuDecayChannel.hh"
|
||||
#include "MuDecayChannelWithSpin.hh"
|
||||
//
|
||||
#include "musrParameters.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrPhysicsList::musrPhysicsList(): G4VUserPhysicsList()
|
||||
{
|
||||
defaultCutValue = 0.1*mm;
|
||||
SetVerboseLevel(0);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrPhysicsList::~musrPhysicsList()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ConstructParticle()
|
||||
{
|
||||
|
||||
ConstructBosons();
|
||||
ConstructLeptons();
|
||||
ConstructMesons();
|
||||
ConstructBaryons();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ConstructBosons()
|
||||
{
|
||||
// pseudo-particles
|
||||
G4Geantino::GeantinoDefinition();
|
||||
G4ChargedGeantino::ChargedGeantinoDefinition();
|
||||
|
||||
// gamma
|
||||
G4Gamma::GammaDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ConstructLeptons()
|
||||
{
|
||||
// leptons
|
||||
// e+/-
|
||||
G4Electron::ElectronDefinition();
|
||||
G4Positron::PositronDefinition();
|
||||
// mu+/-
|
||||
G4MuonPlus::MuonPlusDefinition();
|
||||
G4MuonMinus::MuonMinusDefinition();
|
||||
//cks
|
||||
// G4DecayTable* MuonPlusDecayTable = new G4DecayTable();
|
||||
// MuonPlusDecayTable -> Insert(new musrMuonDecayChannel("mu+",1.00));
|
||||
// G4MuonPlus::MuonPlusDefinition() -> SetDecayTable(MuonPlusDecayTable);
|
||||
//csk
|
||||
//
|
||||
// Muonium - TS
|
||||
musrMuonium::MuoniumDefinition();
|
||||
//
|
||||
// nu_e
|
||||
G4NeutrinoE::NeutrinoEDefinition();
|
||||
G4AntiNeutrinoE::AntiNeutrinoEDefinition();
|
||||
// nu_mu
|
||||
G4NeutrinoMu::NeutrinoMuDefinition();
|
||||
G4AntiNeutrinoMu::AntiNeutrinoMuDefinition();
|
||||
|
||||
//cks: Trial to use Geant4 muon decay with spin
|
||||
G4DecayTable* MuonPlusDecayTable = new G4DecayTable();
|
||||
MuonPlusDecayTable -> Insert(new G4MuonDecayChannelWithSpin("mu+",1.00));
|
||||
// MuonPlusDecayTable -> Insert(new G4MuonDecayChannelWithSpin("mu+",0.986));
|
||||
// MuonPlusDecayTable -> Insert(new G4MuonRadiativeDecayChannelWithSpin("mu+",0.014));
|
||||
G4MuonPlus::MuonPlusDefinition() -> SetDecayTable(MuonPlusDecayTable);
|
||||
//
|
||||
// G4DecayTable* MuonMinusDecayTable = new G4DecayTable();
|
||||
// MuonMinusDecayTable -> Insert(new G4MuonDecayChannelWithSpin("mu-",1.00));
|
||||
// G4MuonMinus::MuonMinusDefinition() -> SetDecayTable(MuonMinusDecayTable);
|
||||
//csk
|
||||
//
|
||||
//TS: Using the muonium decay with and without spin
|
||||
G4DecayTable* MuoniumDecayTable = new G4DecayTable();
|
||||
MuoniumDecayTable -> Insert(new MuDecayChannel("Mu",0.50));
|
||||
MuoniumDecayTable -> Insert(new MuDecayChannelWithSpin("Mu",0.5));
|
||||
musrMuonium::MuoniumDefinition() -> SetDecayTable(MuoniumDecayTable);
|
||||
//MuoniumDecayTable ->DumpInfo(); // Info on muonium decay channels
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ConstructMesons()
|
||||
{
|
||||
// mesons
|
||||
// light mesons
|
||||
G4PionPlus::PionPlusDefinition();
|
||||
G4PionMinus::PionMinusDefinition();
|
||||
G4PionZero::PionZeroDefinition();
|
||||
G4Eta::EtaDefinition();
|
||||
G4EtaPrime::EtaPrimeDefinition();
|
||||
G4KaonPlus::KaonPlusDefinition();
|
||||
G4KaonMinus::KaonMinusDefinition();
|
||||
G4KaonZero::KaonZeroDefinition();
|
||||
G4AntiKaonZero::AntiKaonZeroDefinition();
|
||||
G4KaonZeroLong::KaonZeroLongDefinition();
|
||||
G4KaonZeroShort::KaonZeroShortDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ConstructBaryons()
|
||||
{
|
||||
// baryons
|
||||
G4Proton::ProtonDefinition();
|
||||
G4AntiProton::AntiProtonDefinition();
|
||||
|
||||
G4Neutron::NeutronDefinition();
|
||||
G4AntiNeutron::AntiNeutronDefinition();
|
||||
|
||||
// ions
|
||||
G4IonConstructor iConstructor;
|
||||
iConstructor.ConstructParticle();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ConstructProcess()
|
||||
{
|
||||
AddTransportation();
|
||||
ConstructEM();
|
||||
ConstructGeneral();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4ComptonScattering.hh"
|
||||
#include "G4GammaConversion.hh"
|
||||
#include "G4PhotoElectricEffect.hh"
|
||||
|
||||
#include "G4MultipleScattering.hh"
|
||||
|
||||
#include "G4eIonisation.hh"
|
||||
#include "G4eBremsstrahlung.hh"
|
||||
#include "G4eplusAnnihilation.hh"
|
||||
|
||||
#include "G4MuIonisation.hh"
|
||||
#include "G4MuBremsstrahlung.hh"
|
||||
#include "G4MuPairProduction.hh"
|
||||
|
||||
#include "G4hIonisation.hh"
|
||||
|
||||
#include "G4UserSpecialCuts.hh"
|
||||
|
||||
//#include "musrAtRestSpinRotation.hh"
|
||||
|
||||
// For low energy physics processes:
|
||||
#include "G4LowEnergyCompton.hh"
|
||||
//#include "G4LowEnergyPolarizedCompton.hh"
|
||||
#include "G4LowEnergyGammaConversion.hh"
|
||||
#include "G4LowEnergyPhotoElectric.hh"
|
||||
#include "G4LowEnergyRayleigh.hh"
|
||||
#include "G4LowEnergyBremsstrahlung.hh"
|
||||
#include "G4LowEnergyIonisation.hh"
|
||||
#include "G4hLowEnergyIonisation.hh"
|
||||
|
||||
|
||||
// For Penelope processes:
|
||||
#include "G4PenelopeCompton.hh"
|
||||
#include "G4PenelopeGammaConversion.hh"
|
||||
#include "G4PenelopePhotoElectric.hh"
|
||||
#include "G4PenelopeRayleigh.hh"
|
||||
#include "G4PenelopeIonisation.hh"
|
||||
#include "G4PenelopeBremsstrahlung.hh"
|
||||
#include "G4PenelopeAnnihilation.hh"
|
||||
|
||||
// For Coulomb scattering instead of multiple scattering
|
||||
#include "G4CoulombScattering.hh"
|
||||
#include "G4CoulombScatteringModel.hh"
|
||||
|
||||
// For Muonium formation in the Carbon foil
|
||||
#include "musrMuFormation.hh" // includes the yield function Y = Y(E).
|
||||
|
||||
// For a simple Muonium "scattering" when Mu hits solid materials
|
||||
#include "musrMuScatter.hh"
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ConstructEM()
|
||||
{
|
||||
// cks 2008.08.22. - Adding the possibility to define the processes from the steering file:
|
||||
char charSteeringFileName[1000]; strcpy(charSteeringFileName,(musrParameters::mySteeringFileName).c_str());
|
||||
FILE *fSteeringFile=fopen(charSteeringFileName,"r");
|
||||
if (fSteeringFile==NULL) {
|
||||
sprintf(eMessage,"musrPhysicsList::ConstructEM(): Failed to open macro file \"%s\" .",charSteeringFileName);
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
|
||||
}
|
||||
else {G4cout<<"musrPhysicsList: The Physics processes are being defined:"<<G4endl;}
|
||||
|
||||
char line[501];
|
||||
while (!feof(fSteeringFile)) {
|
||||
fgets(line,500,fSteeringFile);
|
||||
if ((line[0]!='#')&&(line[0]!='\n')&&(line[0]!='\r')) {
|
||||
char tmpString0[100]="Unset", tmpString1[100]="Unset",tmpString2[100]="Unset";
|
||||
sscanf(&line[0],"%s %s %s",tmpString0,tmpString1,tmpString2);
|
||||
if ( (strcmp(tmpString0,"/musr/ignore")!=0)&&(strcmp(tmpString0,"/musr/command")!=0) ) continue;
|
||||
if (strcmp(tmpString1,"process")!=0) continue;
|
||||
|
||||
if ((strcmp(tmpString2,"addProcess")==0)||(strcmp(tmpString2,"addDiscreteProcess")==0)) {
|
||||
char charParticleName[100], charProcessName[100];
|
||||
sscanf(&line[0],"%*s %*s %s %s %s",tmpString2,charParticleName,charProcessName);
|
||||
G4cout<<"musrPhysicsList: Defining process "<<charProcessName<<" for "<<charParticleName<<G4endl;
|
||||
G4String stringProcessName = charProcessName;
|
||||
G4String stringParticleName = charParticleName;
|
||||
G4ParticleDefinition* particleDefinition = G4ParticleTable::GetParticleTable() -> FindParticle(stringParticleName);
|
||||
// G4cout<<"particleDefinition of "<<stringParticleName<<" = "<<particleDefinition<<G4endl;
|
||||
if (particleDefinition==NULL) {
|
||||
sprintf(eMessage,"musrPhysicsList: Partile \"%s\" not found in G4ParticleTable when trying to assign process \"%s\".",
|
||||
charParticleName,charProcessName);
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
|
||||
}
|
||||
G4ProcessManager* pManager = particleDefinition->GetProcessManager();
|
||||
|
||||
if (strcmp(tmpString2,"addDiscreteProcess")==0) {
|
||||
if (stringProcessName=="G4PhotoElectricEffect") pManager->AddDiscreteProcess(new G4PhotoElectricEffect);
|
||||
else if (stringProcessName=="G4ComptonScattering") pManager->AddDiscreteProcess(new G4ComptonScattering);
|
||||
else if (stringProcessName=="G4GammaConversion") pManager->AddDiscreteProcess(new G4GammaConversion);
|
||||
else if (stringProcessName=="G4PenelopePhotoElectric") pManager->AddDiscreteProcess(new G4PenelopePhotoElectric);
|
||||
else if (stringProcessName=="G4PenelopeCompton") pManager->AddDiscreteProcess(new G4PenelopeCompton);
|
||||
else if (stringProcessName=="G4PenelopeGammaConversion") pManager->AddDiscreteProcess(new G4PenelopeGammaConversion);
|
||||
else if (stringProcessName=="G4PenelopeRayleigh") pManager->AddDiscreteProcess(new G4PenelopeRayleigh);
|
||||
else if (stringProcessName=="G4LowEnergyPhotoElectric") pManager->AddDiscreteProcess(new G4LowEnergyPhotoElectric);
|
||||
else if (stringProcessName=="G4LowEnergyCompton") pManager->AddDiscreteProcess(new G4LowEnergyCompton);
|
||||
else if (stringProcessName=="G4LowEnergyGammaConversion") pManager->AddDiscreteProcess(new G4LowEnergyGammaConversion);
|
||||
else if (stringProcessName=="G4LowEnergyRayleigh") pManager->AddDiscreteProcess(new G4LowEnergyRayleigh);
|
||||
|
||||
else if (stringProcessName=="G4CoulombScattering") pManager->AddDiscreteProcess(new G4CoulombScattering);
|
||||
else {
|
||||
sprintf(eMessage,"musrPhysicsList: Process \"%s\" is not implemented in musrPhysicsList.cc for addDiscreteProcess. It can be easily added.",
|
||||
charProcessName);
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
|
||||
}
|
||||
}
|
||||
else if (strcmp(tmpString2,"addProcess")==0) {
|
||||
G4int nr1, nr2, nr3;
|
||||
char charRegion1[100]="", charRegion2[100]="", charRegion3[100]="", charControlString[10]="";
|
||||
sscanf(&line[0],"%*s %*s %*s %*s %*s %d %d %d %s %s %s %s",&nr1,&nr2,&nr3,charRegion1,charRegion2,charRegion3,charControlString);
|
||||
if (stringProcessName=="G4MultipleScattering") pManager->AddProcess(new G4MultipleScattering,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4eIonisation") pManager->AddProcess(new G4eIonisation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4eBremsstrahlung") pManager->AddProcess(new G4eBremsstrahlung,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4eplusAnnihilation") pManager->AddProcess(new G4eplusAnnihilation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4PenelopeIonisation") pManager->AddProcess(new G4PenelopeIonisation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4PenelopeBremsstrahlung") pManager->AddProcess(new G4PenelopeBremsstrahlung,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4PenelopeAnnihilation") pManager->AddProcess(new G4PenelopeAnnihilation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4LowEnergyIonisation") pManager->AddProcess(new G4LowEnergyIonisation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4LowEnergyBremsstrahlung") pManager->AddProcess(new G4LowEnergyBremsstrahlung,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4MuIonisation") pManager->AddProcess(new G4MuIonisation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4MuBremsstrahlung") pManager->AddProcess(new G4MuBremsstrahlung,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4MuPairProduction") pManager->AddProcess(new G4MuPairProduction,nr1,nr2,nr3);
|
||||
// else if (stringProcessName=="G4DecayWithSpin") pManager->AddProcess(new G4DecayWithSpin,nr1,nr2,nr3);
|
||||
// else if (stringProcessName=="G4hIonisation") pManager->AddProcess(new G4hIonisation,nr1,nr2,nr3);
|
||||
// else if (stringProcessName=="G4hLowEnergyIonisation") pManager->AddProcess(new G4hLowEnergyIonisation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="musrMuFormation") pManager->AddProcess(new musrMuFormation,nr1,nr2,nr3);
|
||||
// cks: musrMuScatter could be uncommented here, but testing is needed, because Toni has some strange comments
|
||||
// in his original "musrPhysicsList.cc about implementing musrMuScatter.
|
||||
// else if (stringProcessName=="musrMuScatter") pManager->AddProcess(new musrMuScatter,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="MultipleAndCoulombScattering") {
|
||||
G4MultipleScattering* multScat = new G4MultipleScattering();
|
||||
// G4CoulombScattering* coulScat = new G4CoulombScattering();
|
||||
G4CoulombScatteringModel* coulScatModel = new G4CoulombScatteringModel();
|
||||
if (strcmp(charRegion1,"")!=0) {
|
||||
G4Region* regionForCoulomb = FindG4Region(charRegion1,line);
|
||||
G4cout<<" Adding Coulomb scattering model to multiple scattering model for region "<<charRegion1<<G4endl;
|
||||
multScat->AddEmModel(0,coulScatModel,regionForCoulomb);
|
||||
// multScat->AddEmModel(0,multScat,regionForCoulomb);
|
||||
}
|
||||
if (strcmp(charRegion2,"")!=0) {
|
||||
G4Region* regionForCoulomb = FindG4Region(charRegion2,line);
|
||||
G4cout<<" Adding Coulomb scattering model to multiple scattering model for region "<<charRegion2<<G4endl;
|
||||
multScat->AddEmModel(0,coulScatModel,regionForCoulomb);
|
||||
}
|
||||
if (strcmp(charRegion3,"")!=0) {
|
||||
G4Region* regionForCoulomb = FindG4Region(charRegion3,line);
|
||||
G4cout<<" Adding Coulomb scattering model to multiple scattering model for region "<<charRegion3<<G4endl;
|
||||
multScat->AddEmModel(0,coulScatModel,regionForCoulomb);
|
||||
}
|
||||
if (strcmp(charControlString,"")!=0) {
|
||||
G4cout<<"More than 3 regions requested for Coulomb Scattering, but presently only up to 3 such regions are supported."<<G4endl;
|
||||
G4cout<<"Please extend the number of supported regions in musrPhysicsList.cc to higher number."<<G4endl;
|
||||
G4cout<<"The extention of the code to larger number of regions is not very difficult."<<G4endl;
|
||||
G4cout<<" S T O P F O R C E D"<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
pManager->AddProcess(multScat,nr1,nr2,nr3);
|
||||
}
|
||||
else {
|
||||
sprintf(eMessage,"musrPhysicsList: Process \"%s\" is not implemented in musrPhysicsList.cc for addProcess. It can be easily added.",
|
||||
charProcessName);
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else ReportProblemWithProcessDefinition(line);
|
||||
}
|
||||
}
|
||||
fclose(fSteeringFile);
|
||||
|
||||
G4cout<<"\n\n\n\n"<<G4endl;
|
||||
// csk 2008.08.22.
|
||||
|
||||
//del G4String myTypeOfProcesses = musrParameters::GetInstance()->GetMyTypeOfProcesses();
|
||||
//del G4cout<<"musrPhysicsList::ConstructEM(): myTypeOfProcesses="<<myTypeOfProcesses<<G4endl;
|
||||
|
||||
theParticleIterator->reset();
|
||||
while( (*theParticleIterator)() ){
|
||||
G4ParticleDefinition* particle = theParticleIterator->value();
|
||||
G4ProcessManager* pmanager = particle->GetProcessManager();
|
||||
G4String particleName = particle->GetParticleName();
|
||||
|
||||
if ((particleName == "gamma")||(particleName == "e-")||(particleName == "e+")) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
else if ((particleName=="mu+")||(particleName=="mu-")) { //muon
|
||||
G4DecayWithSpin* theDecayProcess = new G4DecayWithSpin();
|
||||
// theDecayProcess->SetVerboseLevel(2);
|
||||
pmanager->AddProcess(theDecayProcess);
|
||||
pmanager ->SetProcessOrderingToLast(theDecayProcess, idxAtRest);
|
||||
pmanager ->SetProcessOrdering(theDecayProcess, idxPostStep);
|
||||
}
|
||||
|
||||
else if (particleName=="Mu") {
|
||||
// TS:
|
||||
// Muonium "scattering" Kamil: the following 3 lines could be replaced by reading the musrMuScatter
|
||||
// process through the steering file
|
||||
G4VProcess* aMuScatt = new musrMuScatter();
|
||||
pmanager->AddProcess(aMuScatt);
|
||||
pmanager->SetProcessOrdering(aMuScatt, idxPostStep, 1);
|
||||
//
|
||||
G4Decay* theDecayProcess = new G4Decay();
|
||||
//musrDecayWithSpin* theDecayProcess = new musrDecayWithSpin();
|
||||
pmanager->AddProcess(theDecayProcess);
|
||||
pmanager->SetProcessOrderingToLast(theDecayProcess, idxAtRest);
|
||||
pmanager->SetProcessOrdering(theDecayProcess, idxPostStep);
|
||||
}
|
||||
|
||||
|
||||
else if ((!particle->IsShortLived()) &&
|
||||
(particle->GetPDGCharge() != 0.0) &&
|
||||
(particle->GetParticleName() != "chargedgeantino")) {
|
||||
//all others charged particles except geantino
|
||||
pmanager->AddProcess(new G4MultipleScattering,-1, 1,1);
|
||||
// if (myTypeOfProcesses=="highenergy") {
|
||||
// pmanager->AddProcess(new G4hIonisation, -1, 2,2);
|
||||
// }
|
||||
// else {
|
||||
pmanager->AddProcess(new G4hLowEnergyIonisation, -1, 2,2);
|
||||
// }
|
||||
///pmanager->AddProcess(new G4UserSpecialCuts, -1,-1,3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
|
||||
#include "G4Decay.hh"
|
||||
void musrPhysicsList::ConstructGeneral() {
|
||||
if (musrParameters::boolG4GeneralParticleSource) {
|
||||
G4RadioactiveDecay* theRadioactiveDecay = new G4RadioactiveDecay();
|
||||
G4GenericIon* ion = G4GenericIon::GenericIon();
|
||||
|
||||
theParticleIterator->reset();
|
||||
while( (*theParticleIterator)() ){
|
||||
G4ParticleDefinition* particle = theParticleIterator->value();
|
||||
G4ProcessManager* pmanager = particle->GetProcessManager();
|
||||
|
||||
if (particle == ion) {
|
||||
pmanager->AddProcess(theRadioactiveDecay, 0, -1, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
#include "G4Region.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4ProductionCuts.hh"
|
||||
|
||||
void musrPhysicsList::SetCuts()
|
||||
{
|
||||
//G4VUserPhysicsList::SetCutsWithDefault method sets
|
||||
//the default cut value for all particle types
|
||||
//
|
||||
SetCutsWithDefault();
|
||||
|
||||
if (verboseLevel>0) DumpCutValuesTable();
|
||||
DumpCutValuesTable();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrPhysicsList::ReportProblemWithProcessDefinition(char myString[501]) {
|
||||
G4cout<<"\nE R R O R in musrPhysicsList.cc: "
|
||||
<<"Unknown keyword requested in the steering (*.mac) file :"<<G4endl;
|
||||
G4cout<<" "<<myString<<G4endl;
|
||||
G4cout<<"S T O P F O R C E D!"<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
G4Region* musrPhysicsList::FindG4Region(G4String regionName, char* lineOfSteeringFile) {
|
||||
G4Region* myRegion = G4RegionStore::GetInstance()->GetRegion(regionName,false);
|
||||
if( myRegion != NULL ) { // G4Region found
|
||||
return myRegion;
|
||||
}
|
||||
else { // G4Region not found
|
||||
G4cout<<"musrPhysicsList: G4Region "<<regionName<<" not found."<<G4endl;
|
||||
G4cout<<" The critical command line of the steering file is:"<<G4endl;
|
||||
G4cout<<" "<<lineOfSteeringFile<<G4endl;
|
||||
G4cout<<" S T O P F O R C E D"<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
427
src/musrPrimaryGeneratorAction.cc
Normal file
427
src/musrPrimaryGeneratorAction.cc
Normal file
@ -0,0 +1,427 @@
|
||||
#include "musrPrimaryGeneratorAction.hh"
|
||||
#include "musrDetectorConstruction.hh"
|
||||
#include "musrPrimaryGeneratorMessenger.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "G4Event.hh"
|
||||
#include "G4GeneralParticleSource.hh"
|
||||
#include "G4ParticleGun.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "time.h"
|
||||
#include <iomanip>
|
||||
#include "musrRootOutput.hh" //cks for storing some info in the Root output file
|
||||
#include "musrErrorMessage.hh"
|
||||
|
||||
|
||||
G4bool musrPrimaryGeneratorAction::setRandomNrSeedAccordingEventNr=0;
|
||||
G4bool musrPrimaryGeneratorAction::setRandomNrSeedFromFile=0;
|
||||
G4bool musrPrimaryGeneratorAction::setRandomNrSeedFromFile_RNDM=0;
|
||||
G4int musrPrimaryGeneratorAction::nRndmEventToSaveSeeds=-2;
|
||||
|
||||
std::vector<int> * musrPrimaryGeneratorAction::pointerToSeedVector=NULL;
|
||||
std::vector<int> * musrPrimaryGeneratorAction::GetPointerToSeedVector() {
|
||||
return pointerToSeedVector;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
musrPrimaryGeneratorAction::musrPrimaryGeneratorAction(
|
||||
musrDetectorConstruction* musrDC)
|
||||
:musrDetector(musrDC), x0(0), y0(0), z0(-10*cm), xSigma(0), ySigma(0), zSigma(0),
|
||||
rMaxAllowed(1e10*mm), zMinAllowed(-1e10*mm), zMaxAllowed(1e10*mm),
|
||||
p0(0), pSigma(0), pMinAllowed(0), pMaxAllowed(1e10*mm),
|
||||
xangle0(0), yangle0(0), xangleSigma(0), yangleSigma(0), pitch(0),
|
||||
UnpolarisedMuonBeam(false), TransversalyUnpolarisedMuonBeam(false), xPolarisIni(1.), yPolarisIni(0.), zPolarisIni(0.),
|
||||
polarisFraction(1.),
|
||||
muonDecayTimeMin(-1), muonDecayTimeMax(-1), muonMeanLife(2197.03*ns),
|
||||
takeMuonsFromTurtleFile(false), z0_InitialTurtle(0),
|
||||
numberOfGeneratedEvents(0),
|
||||
turtleMomentumBite(false), turtleMomentumP0(0.), turtleSmearingFactor(0.)
|
||||
//, firstCall(true)
|
||||
{
|
||||
//create a messenger for this class
|
||||
gunMessenger = new musrPrimaryGeneratorMessenger(this);
|
||||
|
||||
// create a vector for storing the event numbers as seeds for the random number generator
|
||||
pointerToSeedVector = new std::vector<int>;
|
||||
|
||||
// default particle kinematic
|
||||
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
|
||||
G4ParticleDefinition* muonParticle= particleTable->FindParticle("mu+");
|
||||
// cks Implement also alpha and proton particles for the simulation of Juan Pablo Urrego
|
||||
alphaParticle= particleTable->FindParticle("alpha");
|
||||
protonParticle= particleTable->FindParticle("proton");
|
||||
// csk
|
||||
|
||||
G4int n_particle = 1;
|
||||
if (musrParameters::boolG4GeneralParticleSource) {
|
||||
G4cout<<"musrPrimaryGeneratorAction: G4GeneralParticleSource is going to be initialised"<<G4endl;
|
||||
particleSource = new G4GeneralParticleSource ();
|
||||
}
|
||||
else {
|
||||
G4cout<<"musrPrimaryGeneratorAction: G4ParticleGun is going to be initialised"<<G4endl;
|
||||
particleGun = new G4ParticleGun(n_particle);
|
||||
particleGun->SetParticleDefinition(muonParticle);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
musrPrimaryGeneratorAction::~musrPrimaryGeneratorAction()
|
||||
{
|
||||
if (musrParameters::boolG4GeneralParticleSource) {delete particleSource;}
|
||||
else {delete particleGun;}
|
||||
delete gunMessenger;
|
||||
if (takeMuonsFromTurtleFile) {fclose(fTurtleFile);}
|
||||
G4cout<<"musrPrimaryGeneratorAction: Number of Generated Events = "<<numberOfGeneratedEvents<<G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void musrPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
|
||||
{
|
||||
// This function is called at the begining of event.
|
||||
|
||||
// Clear Root variables
|
||||
musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
myRootOutput->ClearAllRootVariables(); // Note that musrPrimaryGeneratorAction::GeneratePrimaries
|
||||
// is called before the musrEventAction::BeginOfEventAction.
|
||||
// Therefore "ClearAllRootVariables" is called already here
|
||||
// (before the "SetInitialMuonParameters".
|
||||
|
||||
// Set or read the seeds of random number generator
|
||||
boolPrintInfoAboutGeneratedParticles=false;
|
||||
SetOrReadTheRandomNumberSeeds(anEvent->GetEventID());
|
||||
|
||||
// If radioactive source is used, use G4GeneralParticleSource :
|
||||
if (musrParameters::boolG4GeneralParticleSource) {
|
||||
particleSource->GeneratePrimaryVertex(anEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
G4double x, y, z;
|
||||
G4double p;
|
||||
G4double xangle, yangle;
|
||||
|
||||
if (takeMuonsFromTurtleFile) {
|
||||
char line[501];
|
||||
G4int checkNrOfCounts=0;
|
||||
do {
|
||||
float xTmp, yTmp, xAngleTmp, yAngleTmp, pTmp;
|
||||
float dummy1, dummy2;
|
||||
int Ztmp=-1, Atmp=-1;
|
||||
fgets(line,500,fTurtleFile);
|
||||
if (feof(fTurtleFile)) {
|
||||
rewind(fTurtleFile);
|
||||
G4cout<<"End of TurtleFile, lets start from the beginning (numberOfGeneratedEvents = "<<numberOfGeneratedEvents<<")"<<G4endl;
|
||||
fgets(line,500,fTurtleFile);
|
||||
}
|
||||
numberOfGeneratedEvents++;
|
||||
sscanf(&line[0],"%g %g %g %g %g %g %g %d %d",&xTmp,&xAngleTmp,&yTmp,&yAngleTmp,&pTmp,&dummy1,&dummy2,&Ztmp,&Atmp);
|
||||
if (boolPrintInfoAboutGeneratedParticles) {
|
||||
G4cout<<"musrPrimaryGeneratorAction::GeneratePrimaries: Turtle input for this event: "
|
||||
<<xTmp<<", "<<xAngleTmp<<" "<<yTmp<<" "<<yAngleTmp<<" "<< pTmp<<G4endl;
|
||||
}
|
||||
//cks Implement also alpha and proton particles for the simulation of Juan Pablo Urrego
|
||||
if ((Ztmp==1)&&(Atmp==1)) {particleGun->SetParticleDefinition(protonParticle);}// G4cout<<"proton"<<G4endl;}
|
||||
else if ((Ztmp==2)&&(Atmp==4)) {particleGun->SetParticleDefinition(alphaParticle);}// G4cout<<"alpha particle"<<G4endl;}
|
||||
else if ((Ztmp==-1)&&(Atmp==-1)) {;}
|
||||
else {
|
||||
G4cout<<"musrPrimaryGeneratorAction: Unknown particle requested in the TURTLE input file: Z="
|
||||
<<Ztmp<<", A="<<Atmp<<G4endl<<"S T O P F O R C E D" << G4endl;
|
||||
G4cout<<xTmp<<", "<<xAngleTmp<<", "<<yTmp<<", "<<yAngleTmp<<", "<<pTmp<<", "<<dummy1<<", "<<dummy2<<", "<<Ztmp<<", "<<Atmp<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
//csk
|
||||
xangle = xAngleTmp*mrad;
|
||||
yangle = yAngleTmp*mrad;
|
||||
x = xTmp*cm + (z0-z0_InitialTurtle)*tan(xangle) ; // usually z0 is negative
|
||||
y = yTmp*cm + (z0-z0_InitialTurtle)*tan(yangle) ; // z0_InitialTurtle is the z0 at whith the turtle file was generated.
|
||||
p = pTmp*GeV;
|
||||
// add some offset, if requested:
|
||||
x = x + x0;
|
||||
y = y + y0;
|
||||
// add some beam tilt, if requested:
|
||||
xangle = xangle + xangle0;
|
||||
yangle = yangle + yangle0;
|
||||
// add some beam pitch, if requested:
|
||||
if (pitch!=0) {
|
||||
xangle += - pitch * (x-x0);
|
||||
yangle += - pitch * (y-y0);
|
||||
}
|
||||
// add/remove some momentum smearing, if requested
|
||||
if (turtleMomentumBite) {
|
||||
p = turtleMomentumP0 - (turtleMomentumP0-p)*turtleSmearingFactor;
|
||||
}
|
||||
checkNrOfCounts++;
|
||||
if (checkNrOfCounts>1000) {
|
||||
G4cout<<"musrPrimaryGeneratorAction::GeneratePrimaries: Too strict requirements on the r position!"<<G4endl;
|
||||
}
|
||||
} while( (x*x+y*y)>(rMaxAllowed*rMaxAllowed) );
|
||||
z=z0;
|
||||
// G4cout<<"x,y,z=("<<x/mm<<","<<y/mm<<","<<z/mm<<"), angles="<<xangle/mrad<<","<<yangle/mrad<<" p="<<p/MeV<<G4endl;
|
||||
}
|
||||
|
||||
else { // Generate the starting position of the muon by random
|
||||
// rMaxAllowed ... maximal radius, within which the muon can be generated
|
||||
// x0, y0, z0 ... central point around which the muons are generated
|
||||
// xSigma, ySigma, zSigma ... sigma of the (gaussian) distributions of the beam
|
||||
// x, y, z ... actual initial position of the generated muon
|
||||
|
||||
G4int checkNrOfCounts=0;
|
||||
numberOfGeneratedEvents++;
|
||||
do {
|
||||
if (xSigma>0) {x = G4RandGauss::shoot(x0,xSigma);} // Gaussian distribution
|
||||
else if (xSigma<0) {x = x0 + xSigma*(G4UniformRand()*2.-1.);} // Uniform step distribution
|
||||
else { x = x0;} // Point-like
|
||||
|
||||
if (ySigma>0) {y = G4RandGauss::shoot(y0,ySigma);}
|
||||
else if (ySigma<0) {y = y0 + ySigma*(G4UniformRand()*2.-1.);}
|
||||
else {y = y0;}
|
||||
|
||||
if (zSigma>0) {z = G4RandGauss::shoot(z0,zSigma);}
|
||||
else if (zSigma<0) {z = z0 + zSigma*(G4UniformRand()*2.-1.);}
|
||||
else {z = z0;}
|
||||
|
||||
checkNrOfCounts++;
|
||||
if (checkNrOfCounts>1000) {
|
||||
G4cout<<"musrPrimaryGeneratorAction::GeneratePrimaries: Too strict requirements on the r or z position!"<<G4endl;
|
||||
}
|
||||
} while( ((x*x+y*y)>(rMaxAllowed*rMaxAllowed))||(z>zMaxAllowed)||(z<zMinAllowed) );
|
||||
// The generated muon has to stay
|
||||
// within some well defined region,
|
||||
// e.g. within the beampipe
|
||||
|
||||
// Now generate the momentum
|
||||
checkNrOfCounts=0;
|
||||
do {
|
||||
if (pSigma>0) {p = G4RandGauss::shoot(p0,pSigma);}
|
||||
else {p=p0;}
|
||||
checkNrOfCounts++;
|
||||
if (checkNrOfCounts>1000) {
|
||||
G4cout<<"musrPrimaryGeneratorAction::GeneratePrimaries: Too strict requirements on the momentum!"<<G4endl;
|
||||
}
|
||||
} while ( (p>pMaxAllowed)||(p<pMinAllowed) );
|
||||
|
||||
|
||||
// Add some initial angle (px and py component of the momentum)
|
||||
if (xangleSigma>0) { xangle = G4RandGauss::shoot(xangle0,xangleSigma); }
|
||||
else { xangle = xangle0; }
|
||||
// Add the beam tilt, which depends on the distance from the beam centre.
|
||||
// if (xSigma>0) {xangle += - pitch * (x-x0)/xSigma; }
|
||||
if (pitch!=0) {xangle += - pitch * (x-x0); }
|
||||
|
||||
if (yangleSigma>0) { yangle = G4RandGauss::shoot(yangle0,yangleSigma); }
|
||||
else { yangle = yangle0; }
|
||||
// Add the beam tilt, which depends on the distance from the beam centre.
|
||||
// if (ySigma>0) {yangle += - pitch * (y-y0)/ySigma; }
|
||||
if (pitch!=0) {yangle += - pitch * (y-y0); }
|
||||
|
||||
} // end of the part specific for the muons generated by random rather then from TURTLE
|
||||
|
||||
|
||||
// Calculate the final momentum
|
||||
G4double px, py, pz;
|
||||
px = p*sin(xangle);
|
||||
py = p*sin(yangle);
|
||||
pz = std::sqrt(p*p - px*px - py*py);
|
||||
|
||||
|
||||
// Assign spin
|
||||
G4double xpolaris=0, ypolaris=0, zpolaris=0;
|
||||
if (UnpolarisedMuonBeam) {
|
||||
// for genarating random numbers on the sphere see http://mathworld.wolfram.com/SpherePointPicking.html
|
||||
G4double thetaTMP=pi/2;
|
||||
if(!TransversalyUnpolarisedMuonBeam) thetaTMP = acos(2. * G4UniformRand()-1);
|
||||
G4double phiTMP = 2. * pi * G4UniformRand();
|
||||
|
||||
xpolaris = std::sin(thetaTMP) * std::cos(phiTMP);;
|
||||
ypolaris = std::sin(thetaTMP) * std::sin(phiTMP);
|
||||
zpolaris = std::cos(thetaTMP);
|
||||
}
|
||||
else {
|
||||
if (G4UniformRand()>((1.-polarisFraction)/2.)) {
|
||||
xpolaris = xPolarisIni; ypolaris = yPolarisIni; zpolaris = zPolarisIni;
|
||||
// G4cout<<"spin up"<<G4endl;
|
||||
}
|
||||
else {
|
||||
xpolaris = -xPolarisIni; ypolaris = -yPolarisIni; zpolaris = -zPolarisIni;
|
||||
// G4cout<<"spin down"<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
particleGun->SetParticlePosition(G4ThreeVector(x,y,z));
|
||||
G4double particle_mass = particleGun->GetParticleDefinition()->GetPDGMass();
|
||||
G4double particleEnergy = std::sqrt(p*p+particle_mass*particle_mass)-particle_mass;
|
||||
particleGun->SetParticleEnergy(particleEnergy);
|
||||
particleGun->SetParticleMomentumDirection(G4ThreeVector(px,py,pz));
|
||||
particleGun->SetParticlePolarization(G4ThreeVector(xpolaris,ypolaris,zpolaris));
|
||||
particleGun->GeneratePrimaryVertex(anEvent);
|
||||
|
||||
// G4cout<<"musrPrimaryGeneratorAction: Parameters:"<<G4endl;
|
||||
// G4cout<<" x0,y0,z0="<<x0/mm<<","<<y0/mm<<","<<z0/mm<<" Sigma="<<xSigma/mm<<","<<ySigma/mm<<","<<zSigma/mm<<G4endl;
|
||||
// G4cout<<" rMaxAllowed="<<rMaxAllowed/mm<<" zMaxAllowed="<<zMaxAllowed/mm<<" zMinAllowed="<<zMinAllowed/mm<<G4endl;
|
||||
// G4cout<<" p0="<<p0/MeV<<" pSigma="<<pSigma/MeV
|
||||
// <<" pMinAllowed="<<pMinAllowed/MeV<<" pMaxAllowed=<<"<<pMaxAllowed/MeV<<G4endl;
|
||||
// G4cout<<" angle0="<<xangle0/deg<<","<<yangle0/deg<<",nic"
|
||||
// <<" Sigma="<<xangleSigma/deg<<","<<yangleSigma/deg<<",nic"<<G4endl;
|
||||
// G4cout<<" pitch="<<pitch/deg<<G4endl;
|
||||
//
|
||||
// G4cout<<"musrPrimaryGeneratorAction: Generated muon:"<<G4endl;
|
||||
// G4cout<<" x,y,z="<<x/mm<<","<<y/mm<<","<<z/mm<<" angle="<<xangle/deg<<","<< yangle/deg<<",nic"<<G4endl;
|
||||
// G4cout<<" p="<<px/MeV<<","<<py/MeV<<","<<pz/MeV<<" E="<< (particleGun->GetParticleEnergy())/MeV<<G4endl;
|
||||
// G4cout<<" polarisation="<<xpolaris<<","<<ypolaris<<","<<zpolaris<<G4endl;
|
||||
|
||||
|
||||
|
||||
|
||||
// if requested by "/gun/decaytimelimits", set the decay time of the muon such that it is within
|
||||
// the required time window. Otherwise the decay time is set internally by Geant.
|
||||
if (muonDecayTimeMax>0.) {
|
||||
// G4cout<<"muonDecayTimeMin="<<muonDecayTimeMin/ns<<" ns , muonDecayTimeMax="<<muonDecayTimeMax/ns
|
||||
// <<" ns , muonMeanLife="<<muonMeanLife/ns<<" ns."<<G4endl;
|
||||
// find the primary muon
|
||||
G4PrimaryParticle* generatedMuon = anEvent->GetPrimaryVertex(0)->GetPrimary(0);
|
||||
// G4double decayLowerLimit = 1-exp(-muonDecayTimeMin/muonMeanLife);
|
||||
// G4double decayUpperLimit = 1-exp(-muonDecayTimeMax/muonMeanLife);
|
||||
// G4double randomVal = G4UniformRand()*(decayUpperLimit-decayLowerLimit) + decayLowerLimit;
|
||||
// G4double decaytime = -muonMeanLife*log(1-randomVal);
|
||||
//
|
||||
// The following code is numerically more stable compared to the commented lines above:
|
||||
G4double expMin = exp(-muonDecayTimeMin/muonMeanLife);
|
||||
G4double expMax = exp(-muonDecayTimeMax/muonMeanLife);
|
||||
G4double decaytime = -muonMeanLife * log(G4UniformRand()*(expMax-expMin)+expMin);
|
||||
// G4cout<<"decaytime="<<decaytime/ns<<"ns."<< G4endl;
|
||||
generatedMuon->SetProperTime(decaytime);
|
||||
}
|
||||
|
||||
// Save variables into ROOT output file:
|
||||
myRootOutput->SetInitialMuonParameters(x,y,z,px,py,pz,xpolaris,ypolaris,zpolaris);
|
||||
myRootOutput->StoreGeantParameter(7,float(numberOfGeneratedEvents));
|
||||
if (boolPrintInfoAboutGeneratedParticles) {
|
||||
G4cout<<"musrPrimaryGeneratorAction::GeneratePrimaries: x="<<x<<", y="<<y<<", z="<<z<<G4endl;
|
||||
G4cout<<" px="<<px<<", py="<<py<<", pz="<<pz<<", xpolaris="<<xpolaris<<", ypolaris="<<ypolaris<<", zpolaris="<<zpolaris<<G4endl;
|
||||
G4cout<<" numberOfGeneratedEvents="<<numberOfGeneratedEvents<<G4endl;
|
||||
G4cout<<" ------------------------------------"<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============================================================================
|
||||
void musrPrimaryGeneratorAction::SetInitialMuonPolariz(G4ThreeVector vIniPol)
|
||||
{
|
||||
G4double magnitude=vIniPol.mag();
|
||||
if(magnitude<0.00000001) {
|
||||
G4cout<< "Unpolarised initial muons"<<G4endl;
|
||||
UnpolarisedMuonBeam=true;
|
||||
if ((magnitude<0.0000000085)&&(magnitude>0.0000000075)) {
|
||||
G4cout<< "Transversaly unpolarised initial muons"<<G4endl;
|
||||
TransversalyUnpolarisedMuonBeam=true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
xPolarisIni=vIniPol(0)/magnitude;
|
||||
yPolarisIni=vIniPol(1)/magnitude;
|
||||
zPolarisIni=vIniPol(2)/magnitude;
|
||||
G4cout<< "Initial Muon Polarisation set to ("<<xPolarisIni<<","<<yPolarisIni<<","<<zPolarisIni<<")"<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
void musrPrimaryGeneratorAction::SetMuonDecayTimeLimits(G4ThreeVector decayTimeLimits) {
|
||||
muonDecayTimeMin = decayTimeLimits[0];
|
||||
muonDecayTimeMax = decayTimeLimits[1];
|
||||
muonMeanLife = decayTimeLimits[2];
|
||||
// store the muon decay time parameters to the Root output
|
||||
musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
myRootOutput->StoreGeantParameter(2,muonDecayTimeMin/microsecond);
|
||||
myRootOutput->StoreGeantParameter(3,muonDecayTimeMax/microsecond);
|
||||
myRootOutput->StoreGeantParameter(4,muonMeanLife/microsecond);
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
void musrPrimaryGeneratorAction::SetTurtleInput(G4String turtleFileName) {
|
||||
takeMuonsFromTurtleFile = true;
|
||||
fTurtleFile = fopen(turtleFileName.c_str(),"r");
|
||||
if (fTurtleFile==NULL) {
|
||||
G4cout << "E R R O R : Failed to open TURTLE input file \"" << turtleFileName
|
||||
<<"\"."<< G4endl;
|
||||
G4cout << "S T O P F O R C E D" << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
else {G4cout << "Turtle input file \"" << turtleFileName <<"\" opened."<< G4endl;}
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
void musrPrimaryGeneratorAction::SetTurtleInputFileToEventNo(G4int lineNumberOfTurtleFile) {
|
||||
if (fTurtleFile==NULL) {
|
||||
G4cout << "musrPrimaryGeneratorAction::SetTurtleInputFileToEventNo:"
|
||||
<<" TURTLE input file not found - line number can not be set."<<G4endl;
|
||||
}
|
||||
else {
|
||||
char line[501];
|
||||
for (Int_t i=0; i<lineNumberOfTurtleFile; i++) {
|
||||
if (feof(fTurtleFile)) rewind(fTurtleFile);
|
||||
fgets(line,500,fTurtleFile);
|
||||
}
|
||||
G4cout << "musrPrimaryGeneratorAction::SetTurtleInputFileToEventNo: Turtle input file will start at line no.:"
|
||||
<< lineNumberOfTurtleFile <<G4endl;
|
||||
}
|
||||
}
|
||||
//===============================================================================
|
||||
void musrPrimaryGeneratorAction::SetOrReadTheRandomNumberSeeds(G4int eventID) {
|
||||
if (eventID == nRndmEventToSaveSeeds) {
|
||||
G4cout<<"musrPrimaryGeneratorAction::SetOrReadTheRandomNumberSeeds: S A V I N G R A N D O M N O. S E E D S"<<G4endl;
|
||||
G4cout<<" (for even nr. "<<eventID<<")"<<G4endl;
|
||||
G4RunManager::GetRunManager()->rndmSaveThisEvent();
|
||||
boolPrintInfoAboutGeneratedParticles = true;
|
||||
}
|
||||
if (eventID == 0) {
|
||||
if (setRandomNrSeedFromFile_RNDM) {
|
||||
G4cout<<"musrPrimaryGeneratorAction::SetOrReadTheRandomNumberSeeds: Restoring random number seeds from file kamil.rndm"<<G4endl;
|
||||
G4RunManager::GetRunManager()->RestoreRandomNumberStatus("kamil.rndm");
|
||||
boolPrintInfoAboutGeneratedParticles = true;
|
||||
}
|
||||
}
|
||||
if (setRandomNrSeedFromFile) {
|
||||
// G4cout<<"RandomNrInitialisers.size()="<<RandomNrInitialisers->size()<<G4endl;
|
||||
if (eventID < int(pointerToSeedVector->size())) {
|
||||
G4cout <<"musrEventAction.cc: seed will be set to="<< pointerToSeedVector->at(eventID)<<G4endl;
|
||||
CLHEP::HepRandom::setTheSeed(pointerToSeedVector->at(eventID));
|
||||
CLHEP::RandGauss::setFlag(false);
|
||||
boolPrintInfoAboutGeneratedParticles = true;
|
||||
}
|
||||
}
|
||||
else if (setRandomNrSeedAccordingEventNr) {
|
||||
// long seeds[2];
|
||||
// seeds[0] = (long) 234567890+thisEventNr*117;
|
||||
// seeds[1] = (long) 333222111+thisEventNr*173;
|
||||
//
|
||||
// // seeds[1] = (long) (evt->GetEventID());
|
||||
// // seeds[0] = (long) 123456789; // This leads to a gap in the decay time histogram fro N=100000 events
|
||||
// // seeds[1] = (long) 333222111+thisEventNr; // ----------------------------||------------------------------------
|
||||
// thisEventNr++;
|
||||
// CLHEP::HepRandom::setTheSeeds(seeds);
|
||||
// // G4cout << "seed1: " << seeds[0] << "; seed2: " << seeds[1] << G4endl;
|
||||
//
|
||||
// G4cout <<" thisEventNr="<<thisEventNr;
|
||||
CLHEP::HepRandom::setTheSeed(eventID);
|
||||
// G4cout <<" getTheSeed="<<CLHEP::HepRandom::getTheSeed()<< G4endl;
|
||||
CLHEP::RandGauss::setFlag(false);
|
||||
}
|
||||
}
|
||||
|
||||
void musrPrimaryGeneratorAction::SetKEnergy(G4double val) {
|
||||
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
|
||||
G4double mu_mass = particleTable->FindParticle("mu+")->GetPDGMass();
|
||||
p0=std::sqrt(val*val + 2*mu_mass*val);
|
||||
// G4cout<<"musrPrimaryGeneratorAction::SetKEnergy: Muon kinetic energy of "
|
||||
// <<val<<" MeV requested ==> initial muon momentum set to "<<p0<<" MeV/c"<<G4endl;
|
||||
}
|
177
src/musrPrimaryGeneratorMessenger.cc
Normal file
177
src/musrPrimaryGeneratorMessenger.cc
Normal file
@ -0,0 +1,177 @@
|
||||
#include "musrPrimaryGeneratorMessenger.hh"
|
||||
#include "musrPrimaryGeneratorAction.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithADouble.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcmdWith3Vector.hh"
|
||||
#include "G4UIcmdWith3VectorAndUnit.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
musrPrimaryGeneratorMessenger::musrPrimaryGeneratorMessenger(musrPrimaryGeneratorAction* musrGun)
|
||||
:musrAction(musrGun)
|
||||
{
|
||||
|
||||
setvertexCmd = new G4UIcmdWith3VectorAndUnit("/gun/vertex",this);
|
||||
setvertexCmd->SetGuidance(" Set x0, y0, z0 of the generated muons (with unit)");
|
||||
setvertexCmd->SetParameterName("mes_x0","mes_y0","mes_z0",true,true);
|
||||
setvertexCmd->SetDefaultUnit("mm");
|
||||
|
||||
setvertexSigmaCmd = new G4UIcmdWith3VectorAndUnit("/gun/vertexsigma",this);
|
||||
setvertexSigmaCmd->SetGuidance(" Set xSigma, ySigma, ySigma of the generated muons (with unit)");
|
||||
setvertexSigmaCmd->SetParameterName("mes_xSigma","mes_ySigma","mes_zSigma",true,true);
|
||||
setvertexSigmaCmd->SetDefaultUnit("mm");
|
||||
|
||||
setvertexBoundaryCmd = new G4UIcmdWith3VectorAndUnit("/gun/vertexboundary",this);
|
||||
setvertexBoundaryCmd->SetGuidance(" Set maximum allowed radius, zmin, zmax of the generated vertex (with unit)");
|
||||
setvertexBoundaryCmd->SetParameterName("mes_rMaxAllowed","mes_zMinAllowed","mes_zMaxAllowed",true,true);
|
||||
setvertexBoundaryCmd->SetDefaultUnit("mm");
|
||||
|
||||
setKEnergyCmd = new G4UIcmdWithADoubleAndUnit("/gun/kenergy",this);
|
||||
setKEnergyCmd->SetGuidance(" Set kinetic energy of the generated muons (with unit)");
|
||||
setKEnergyCmd->SetParameterName("mes_E0",true);
|
||||
setKEnergyCmd->SetDefaultUnit("MeV");
|
||||
|
||||
setMomentumCmd = new G4UIcmdWithADoubleAndUnit("/gun/momentum",this);
|
||||
setMomentumCmd->SetGuidance(" Set mean momentum of the generated muons (with unit)");
|
||||
setMomentumCmd->SetParameterName("mes_p0",true);
|
||||
setMomentumCmd->SetDefaultUnit("MeV");
|
||||
|
||||
setMomentumSmearingCmd = new G4UIcmdWithADoubleAndUnit("/gun/momentumsmearing",this);
|
||||
setMomentumSmearingCmd->SetGuidance(" Set sigma of the momentum of the generated muons (with unit)");
|
||||
setMomentumSmearingCmd->SetParameterName("mes_pSigma",true);
|
||||
setMomentumSmearingCmd->SetDefaultUnit("MeV");
|
||||
|
||||
setMomentumBoundaryCmd = new G4UIcmdWith3VectorAndUnit("/gun/momentumboundary",this);
|
||||
setMomentumBoundaryCmd->SetGuidance(" Set minimum and maximum momentum allowed (with unit, z component ignored)");
|
||||
setMomentumBoundaryCmd->SetParameterName("mes_pMinAllowed","mes_pMaxAllowed","mes_dummy",true,true);
|
||||
setMomentumBoundaryCmd->SetDefaultUnit("MeV");
|
||||
|
||||
setTiltAngleCmd = new G4UIcmdWith3VectorAndUnit("/gun/tilt",this);
|
||||
setTiltAngleCmd->SetGuidance(" Set tilt angle of the generated muons (with unit, z component ignored)");
|
||||
setTiltAngleCmd->SetParameterName("mes_xangle","mes_yangle","dummy",true,true);
|
||||
setTiltAngleCmd->SetDefaultUnit("deg");
|
||||
|
||||
setSigmaTiltAngleCmd = new G4UIcmdWith3VectorAndUnit("/gun/tiltsigma",this);
|
||||
setSigmaTiltAngleCmd->SetGuidance(" Set sigma of the tilt angle (with unit, z component ignored)");
|
||||
setSigmaTiltAngleCmd->SetParameterName("mes_xangleSigma","mes_yangleSigma","dummy",true,true);
|
||||
setSigmaTiltAngleCmd->SetDefaultUnit("deg");
|
||||
|
||||
setPitchCmd = new G4UIcmdWithADoubleAndUnit("/gun/pitch",this);
|
||||
setPitchCmd->SetGuidance(" Set pitch angle of the generated muons (with unit)");
|
||||
setPitchCmd->SetParameterName("mes_pitch",true);
|
||||
setPitchCmd->SetDefaultUnit("deg");
|
||||
|
||||
// setMuonPolarizCmd = new G4UIcmdWithAnInteger("/gun/muonpolarization",this);
|
||||
// setMuonPolarizCmd->SetGuidance(" Set initial mu polariz: 0=transverse, 1=longitudinal ");
|
||||
// setMuonPolarizCmd->SetParameterName("IniPol",true);
|
||||
// setMuonPolarizCmd->SetDefaultValue(0) ;
|
||||
|
||||
setMuonPolarizCmd = new G4UIcmdWith3Vector("/gun/muonPolarizVector",this);
|
||||
setMuonPolarizCmd->SetGuidance("Set initial mu polarisation as a vector (without unit)");
|
||||
setMuonPolarizCmd->SetGuidance(" The vector does not have to be normalised to 1");
|
||||
setMuonPolarizCmd->SetParameterName("mes_polarisX","mes_polarisY","mes_polarisZ",true,true);
|
||||
|
||||
setMuonPolarizFractionCmd = new G4UIcmdWithADouble("/gun/muonPolarizFraction",this);
|
||||
setMuonPolarizFractionCmd->SetGuidance(" Set the fraction of the muon polarisation (in the range of -1 to 1),");
|
||||
setMuonPolarizFractionCmd->SetGuidance(" where fraction = (N_up_spin - N_down_spin) / (N_up_spin + N_down_spin)");
|
||||
setMuonPolarizFractionCmd->SetParameterName("mes_polarisFraction",true);
|
||||
|
||||
setMuonDecayTimeCmd = new G4UIcmdWith3VectorAndUnit("/gun/decaytimelimits",this);
|
||||
setMuonDecayTimeCmd->SetGuidance(" Set minimum and maximum decay time and the muon mean life ");
|
||||
setMuonDecayTimeCmd->SetParameterName("decayMin","decayMax","decayTime",true,true);
|
||||
setMuonDecayTimeCmd->SetDefaultUnit("ns");
|
||||
|
||||
setTurtleCmd = new G4UIcmdWithAString("/gun/turtlefilename",this);
|
||||
setTurtleCmd->SetGuidance("Set the filename of the TURTLE input file.");
|
||||
setTurtleCmd->SetGuidance("If this varialble is set, TURTLE input will be used for initial muons");
|
||||
setTurtleCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
setTurtleZ0Cmd = new G4UIcmdWithADoubleAndUnit("/gun/turtleZ0position",this);
|
||||
setTurtleZ0Cmd->SetGuidance("Set the z0, with which the TURTLE input file has been generated.");
|
||||
setTurtleZ0Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
setTurtleZ0Cmd->SetParameterName("mes_z0Turtle",true);
|
||||
setTurtleZ0Cmd->SetDefaultUnit("mm");
|
||||
|
||||
setTurtleMomentumBite = new G4UIcmdWith3Vector("/gun/turtleMomentumBite",this);
|
||||
setTurtleMomentumBite->SetGuidance(" Modify smearing of the turtle momentum bite. The first value is the mean momentum in MeV/c,");
|
||||
setTurtleMomentumBite->SetGuidance(" the second value is the smearing factor in per cent, by which the momentum bite,");
|
||||
setTurtleMomentumBite->SetGuidance(" will be increased/decreased around the mean momemtum. 100 per cent correspond to no");
|
||||
setTurtleMomentumBite->SetGuidance(" change, 0 per cent will create monoenergetic beam, 200 per cent will create a two times");
|
||||
setTurtleMomentumBite->SetGuidance(" broader beam. The third parameter is dummy.");
|
||||
setTurtleMomentumBite->SetParameterName("mes_turtleMomentumP0","mes_turtleSmearingFactor","mes_turtleSmearingDummy",true,true);
|
||||
|
||||
|
||||
setTurtleEventNrCmd = new G4UIcmdWithAnInteger("/gun/turtleFirstEventNr",this);
|
||||
setTurtleEventNrCmd->SetGuidance("Set the line number that should be taken as the first event from the turtle input file.");
|
||||
setTurtleEventNrCmd->SetParameterName("mes_turtleFirstEvent",true);
|
||||
setTurtleEventNrCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
setTurtleEventNrCmd->SetDefaultValue(0) ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
musrPrimaryGeneratorMessenger::~musrPrimaryGeneratorMessenger()
|
||||
{
|
||||
delete setvertexCmd;
|
||||
delete setvertexSigmaCmd;
|
||||
delete setvertexBoundaryCmd;
|
||||
delete setKEnergyCmd;
|
||||
delete setMomentumCmd;
|
||||
delete setMomentumSmearingCmd;
|
||||
delete setMomentumBoundaryCmd;
|
||||
delete setTiltAngleCmd;
|
||||
delete setSigmaTiltAngleCmd;
|
||||
delete setPitchCmd;
|
||||
delete setMuonPolarizCmd;
|
||||
delete setMuonPolarizFractionCmd;
|
||||
delete setMuonDecayTimeCmd;
|
||||
delete setTurtleCmd;
|
||||
delete setTurtleZ0Cmd;
|
||||
delete setTurtleMomentumBite;
|
||||
delete setTurtleEventNrCmd;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void musrPrimaryGeneratorMessenger::SetNewValue(G4UIcommand * command,G4String newValue)
|
||||
{
|
||||
if( command == setvertexCmd)
|
||||
{ musrAction->Setvertex(setvertexCmd->GetNew3VectorValue(newValue));}
|
||||
if( command == setvertexSigmaCmd)
|
||||
{ musrAction->SetvertexSigma(setvertexSigmaCmd->GetNew3VectorValue(newValue));}
|
||||
if( command == setvertexBoundaryCmd)
|
||||
{ musrAction->SetvertexBoundary(setvertexBoundaryCmd->GetNew3VectorValue(newValue));}
|
||||
if( command == setKEnergyCmd)
|
||||
{ musrAction->SetKEnergy(setKEnergyCmd->GetNewDoubleValue(newValue));}
|
||||
if( command == setMomentumCmd)
|
||||
{ musrAction->SetMomentum(setMomentumCmd->GetNewDoubleValue(newValue));}
|
||||
if( command == setMomentumSmearingCmd)
|
||||
{ musrAction->SetMomentumSmearing(setMomentumSmearingCmd->GetNewDoubleValue(newValue));}
|
||||
if( command == setMomentumBoundaryCmd)
|
||||
{ musrAction->SetMomentumBoundary(setMomentumBoundaryCmd->GetNew3VectorValue(newValue));}
|
||||
if( command == setTiltAngleCmd)
|
||||
{ musrAction->SetTilt(setTiltAngleCmd->GetNew3VectorValue(newValue));}
|
||||
if( command == setSigmaTiltAngleCmd)
|
||||
{ musrAction->SetSigmaTilt(setSigmaTiltAngleCmd->GetNew3VectorValue(newValue));}
|
||||
if( command == setPitchCmd)
|
||||
{ musrAction->SetPitch(setPitchCmd->GetNewDoubleValue(newValue));}
|
||||
if( command == setMuonPolarizCmd)
|
||||
{ musrAction->SetInitialMuonPolariz(setMuonPolarizCmd->GetNew3VectorValue(newValue));}
|
||||
if( command == setMuonPolarizFractionCmd)
|
||||
{ musrAction->SetInitialPolarizFraction(setMuonPolarizFractionCmd->GetNewDoubleValue(newValue));}
|
||||
if( command == setMuonDecayTimeCmd)
|
||||
{ musrAction->SetMuonDecayTimeLimits(setMuonDecayTimeCmd->GetNew3VectorValue(newValue)); }
|
||||
if( command == setTurtleCmd)
|
||||
{ musrAction->SetTurtleInput(newValue); }
|
||||
if( command == setTurtleZ0Cmd)
|
||||
{ musrAction->SetTurtleZ0(setTurtleZ0Cmd->GetNewDoubleValue(newValue)); }
|
||||
if( command == setTurtleMomentumBite)
|
||||
{ musrAction-> SetTurtleMomentumBite(setTurtleMomentumBite->GetNew3VectorValue(newValue)); }
|
||||
if( command == setTurtleEventNrCmd)
|
||||
{ musrAction->SetTurtleInputFileToEventNo(setTurtleEventNrCmd->GetNewIntValue(newValue));}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
87
src/musrQuadrupole.cc
Normal file
87
src/musrQuadrupole.cc
Normal file
@ -0,0 +1,87 @@
|
||||
#include "musrQuadrupole.hh"
|
||||
#include "musrParameters.hh"
|
||||
|
||||
|
||||
musrQuadrupole::musrQuadrupole(G4double halflengthVal, G4double fieldRadiusVal, G4double gradientVal, G4double fringeFactorVal, G4LogicalVolume* logVolume, G4ThreeVector positionOfTheCenter) : F04ElementField(positionOfTheCenter, logVolume)
|
||||
{
|
||||
G4cout << "\n-----------------------------------------------------------"
|
||||
<< "\n Quadrupole field "
|
||||
<< "\n-----------------------------------------------------------"
|
||||
<< G4endl;
|
||||
|
||||
gradient = gradientVal; //*(tesla/m);
|
||||
fieldRadius = fieldRadiusVal; //*mm;
|
||||
halflength = halflengthVal; //*mm;
|
||||
enge = BLEngeFunction(ENGE_QUAD);
|
||||
|
||||
G4double fringeFactor = fringeFactorVal; // the default should be 1.
|
||||
G4bool fringe = true; if (fringeFactor==0.) {fringe=false;}
|
||||
fringeDepth = fringeFactor * fieldRadius * 2.0;
|
||||
|
||||
if (!fringe) {
|
||||
enge.set(0,0,0,0,0,0);
|
||||
fringeMaxZ = halflength;
|
||||
}
|
||||
else {
|
||||
for(int i=0; i<1000; ++i) {
|
||||
fringeMaxZ = i*fieldRadius/10.0 + halflength;
|
||||
if(enge((fringeMaxZ-halflength)/fringeDepth) < FRINGE_ACCURACY) break;
|
||||
}
|
||||
}
|
||||
|
||||
G4cout << " Field gradient set to "<< gradient/(tesla/m) << " T/m"<< G4endl;
|
||||
G4cout << " Field radius set to " << fieldRadius/mm << " mm"<< G4endl;
|
||||
G4cout << " Field halflength set to " << halflength/mm << " mm"<<G4endl;
|
||||
G4cout << " Field fringeDepth set to " << fringeDepth/mm << " mm"<<G4endl;
|
||||
G4cout << " Field fringeMaxZ set to " << fringeMaxZ/mm << " mm"<<G4endl;
|
||||
G4cout << "\n-----------------------------------------------------------" << G4endl;
|
||||
}
|
||||
|
||||
|
||||
void musrQuadrupole::addFieldValue(const G4double point[4], G4double *field ) const {
|
||||
G4ThreeVector global(point[0],point[1],point[2]);
|
||||
G4ThreeVector local;
|
||||
|
||||
local = global2local.TransformPoint(global);
|
||||
G4double r = sqrt(local[0]*local[0]+local[1]*local[1]);
|
||||
if (r > fieldRadius || fabs(local[2]) > fringeMaxZ) { return;}
|
||||
|
||||
// apply enge() to the scalar potential phi=-G0*x*y*enge(z);
|
||||
// B is minus its gradient. Handle both edges properly.
|
||||
G4double G0 = gradient;
|
||||
G4double f,fp;
|
||||
if (fringeDepth!=0) {
|
||||
double fringeZ = (fabs(local[2])-halflength)/fringeDepth;
|
||||
f = enge(fringeZ);
|
||||
fp = enge.prime(fringeZ)/fringeDepth;
|
||||
}
|
||||
else {
|
||||
f = ( fabs(local[2]) > halflength) ? 0:1;
|
||||
fp = 0;
|
||||
}
|
||||
G4ThreeVector B(G0*f*local[1],G0*f*local[0],G0*fp*local[0]*local[1]);
|
||||
if(local[2] < 0.0) B[2] = -B[2];
|
||||
|
||||
G4ThreeVector finalField(B[0],B[1],B[2]);
|
||||
finalField = global2local.Inverse().TransformAxis(finalField);
|
||||
|
||||
field[0] += finalField.x();
|
||||
field[1] += finalField.y();
|
||||
field[2] += finalField.z();
|
||||
|
||||
// G4cout<<"musrQuadrupole.cc: field: ("<<field[0]/tesla<<","<<field[1]/tesla<<","<<field[2]/tesla<<")"<<G4endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4double musrQuadrupole::GetNominalFieldValue() {
|
||||
return gradient;
|
||||
}
|
||||
|
||||
void musrQuadrupole::SetNominalFieldValue(G4double newFieldValue) {
|
||||
// // Rescale the magnetic field for a new value of the magnetic field
|
||||
gradient=newFieldValue;
|
||||
G4cout<<"musrQuadrupole.cc: gradient changed to="<< gradient/(tesla/m)<<" T/m"<<G4endl;
|
||||
}
|
||||
|
446
src/musrRootOutput.cc
Normal file
446
src/musrRootOutput.cc
Normal file
@ -0,0 +1,446 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "musrRootOutput.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4Run.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrRootOutput::musrRootOutput() {
|
||||
pointerToRoot=this;
|
||||
boolIsAnySpecialSaveVolumeDefined=false;
|
||||
nFieldNomVal=0;
|
||||
|
||||
ProcessIDMapping["DecayWithSpin"]=1;
|
||||
ProcessIDMapping["eIoni"]=2;
|
||||
ProcessIDMapping["eBrem"]=3;
|
||||
ProcessIDMapping["annihil"]=4;
|
||||
ProcessIDMapping["LowEnCompton"]=5;
|
||||
ProcessIDMapping["LowEnConversion"]=6;
|
||||
ProcessIDMapping["LowEnBrem"]=7;
|
||||
ProcessIDMapping["LowEnergyIoni"]=8;
|
||||
ProcessIDMapping["LowEnPhotoElec"]=9;
|
||||
ProcessIDMapping["RadioactiveDecay"]=10;
|
||||
ProcessIDMapping["muIoni"]=11;
|
||||
ProcessIDMapping["MuFormation"]=12;
|
||||
ProcessIDMapping["Decay"]=13;
|
||||
ProcessIDMapping["initialParticle"]=100;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrRootOutput::~musrRootOutput() {}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrRootOutput* musrRootOutput::pointerToRoot=0;
|
||||
musrRootOutput* musrRootOutput::GetRootInstance() {
|
||||
return pointerToRoot;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4bool musrRootOutput::store_runID = true;
|
||||
G4bool musrRootOutput::store_eventID = true;
|
||||
G4bool musrRootOutput::store_weight = true;
|
||||
G4bool musrRootOutput::store_BFieldAtDecay = true;
|
||||
G4bool musrRootOutput::store_muIniPosX = true;
|
||||
G4bool musrRootOutput::store_muIniPosY = true;
|
||||
G4bool musrRootOutput::store_muIniPosZ = true;
|
||||
G4bool musrRootOutput::store_muIniMomX = true;
|
||||
G4bool musrRootOutput::store_muIniMomY = true;
|
||||
G4bool musrRootOutput::store_muIniMomZ = true;
|
||||
G4bool musrRootOutput::store_muIniPolX = true;
|
||||
G4bool musrRootOutput::store_muIniPolY = true;
|
||||
G4bool musrRootOutput::store_muIniPolZ = true;
|
||||
G4bool musrRootOutput::store_muDecayDetID= true;
|
||||
G4bool musrRootOutput::store_muDecayPosX = true;
|
||||
G4bool musrRootOutput::store_muDecayPosY = true;
|
||||
G4bool musrRootOutput::store_muDecayPosZ = true;
|
||||
G4bool musrRootOutput::store_muDecayTime = true;
|
||||
G4bool musrRootOutput::store_muDecayPolX = true;
|
||||
G4bool musrRootOutput::store_muDecayPolY = true;
|
||||
G4bool musrRootOutput::store_muDecayPolZ = true;
|
||||
G4bool musrRootOutput::store_muTargetTime = false;
|
||||
G4bool musrRootOutput::store_muTargetPolX = false;
|
||||
G4bool musrRootOutput::store_muTargetPolY = false;
|
||||
G4bool musrRootOutput::store_muTargetPolZ = false;
|
||||
G4bool musrRootOutput::store_muM0Time = false;
|
||||
G4bool musrRootOutput::store_muM0PolX = false;
|
||||
G4bool musrRootOutput::store_muM0PolY = false;
|
||||
G4bool musrRootOutput::store_muM0PolZ = false;
|
||||
G4bool musrRootOutput::store_muM1Time = false;
|
||||
G4bool musrRootOutput::store_muM1PolX = false;
|
||||
G4bool musrRootOutput::store_muM1PolY = false;
|
||||
G4bool musrRootOutput::store_muM1PolZ = false;
|
||||
G4bool musrRootOutput::store_muM2Time = false;
|
||||
G4bool musrRootOutput::store_muM2PolX = false;
|
||||
G4bool musrRootOutput::store_muM2PolY = false;
|
||||
G4bool musrRootOutput::store_muM2PolZ = false;
|
||||
G4bool musrRootOutput::store_posIniMomX = true;
|
||||
G4bool musrRootOutput::store_posIniMomY = true;
|
||||
G4bool musrRootOutput::store_posIniMomZ = true;
|
||||
G4bool musrRootOutput::store_det_ID = true;
|
||||
G4bool musrRootOutput::store_det_edep = true;
|
||||
G4bool musrRootOutput::store_det_edep_el = true;
|
||||
G4bool musrRootOutput::store_det_edep_pos = true;
|
||||
G4bool musrRootOutput::store_det_edep_gam = true;
|
||||
G4bool musrRootOutput::store_det_edep_mup = true;
|
||||
G4bool musrRootOutput::store_det_nsteps = true;
|
||||
G4bool musrRootOutput::store_det_length = true;
|
||||
G4bool musrRootOutput::store_det_start = true;
|
||||
G4bool musrRootOutput::store_det_end = true;
|
||||
G4bool musrRootOutput::store_det_x = true;
|
||||
G4bool musrRootOutput::store_det_y = true;
|
||||
G4bool musrRootOutput::store_det_z = true;
|
||||
G4bool musrRootOutput::store_det_kine = true;
|
||||
G4bool musrRootOutput::store_det_VrtxKine = true;
|
||||
G4bool musrRootOutput::store_det_VrtxX = true;
|
||||
G4bool musrRootOutput::store_det_VrtxY = true;
|
||||
G4bool musrRootOutput::store_det_VrtxZ = true;
|
||||
G4bool musrRootOutput::store_det_VrtxVolID = true;
|
||||
G4bool musrRootOutput::store_det_VrtxProcID = true;
|
||||
G4bool musrRootOutput::store_det_VrtxTrackID = true;
|
||||
G4bool musrRootOutput::store_det_VrtxParticleID = true;
|
||||
G4bool musrRootOutput::store_det_VvvKine = true;
|
||||
G4bool musrRootOutput::store_det_VvvX = true;
|
||||
G4bool musrRootOutput::store_det_VvvY = true;
|
||||
G4bool musrRootOutput::store_det_VvvZ = true;
|
||||
G4bool musrRootOutput::store_det_VvvVolID = true;
|
||||
G4bool musrRootOutput::store_det_VvvProcID = true;
|
||||
G4bool musrRootOutput::store_det_VvvTrackID = true;
|
||||
G4bool musrRootOutput::store_det_VvvParticleID = true;
|
||||
G4bool musrRootOutput::store_fieldNomVal = true;
|
||||
G4bool musrRootOutput::store_fieldIntegralBx = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBy = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBz = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBz1 = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBz2 = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBz3 = false;
|
||||
|
||||
G4int musrRootOutput::oldEventNumberInG4EqEMFieldWithSpinFunction=-1;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrRootOutput::BeginOfRunAction() {
|
||||
G4cout << "musrRootOutput::BeginOfRunAction() Defining the Root tree and branches:"<<G4endl;
|
||||
G4int tmpRunNr=(G4RunManager::GetRunManager())->GetCurrentRun()->GetRunID();
|
||||
char RootOutputFileName[200];
|
||||
sprintf(RootOutputFileName, "data/musr_%i.root", tmpRunNr);
|
||||
rootFile=new TFile(RootOutputFileName,"recreate");
|
||||
rootTree=new TTree("t1","a simple Tree with simple variables");
|
||||
if (store_runID) {rootTree->Branch("runID",&runID_t,"runID/I");}
|
||||
if (store_eventID) {rootTree->Branch("eventID",&eventID_t,"eventID/I");}
|
||||
if (store_weight) {rootTree->Branch("weight",&weight_t,"weight/D");}
|
||||
if (store_BFieldAtDecay) {rootTree->Branch("BFieldAtDecay",&B_t,"Bx/D:By:Bz:B3:B4:B5");}
|
||||
if (store_muIniPosX) {rootTree->Branch("muIniPosX",&muIniPosX_t,"muIniPosX/D");}
|
||||
if (store_muIniPosY) {rootTree->Branch("muIniPosY",&muIniPosY_t,"muIniPosY/D");}
|
||||
if (store_muIniPosZ) {rootTree->Branch("muIniPosZ",&muIniPosZ_t,"muIniPosZ/D");}
|
||||
if (store_muIniMomX) {rootTree->Branch("muIniMomX",&muIniMomX_t,"muIniMomX/D");}
|
||||
if (store_muIniMomY) {rootTree->Branch("muIniMomY",&muIniMomY_t,"muIniMomY/D");}
|
||||
if (store_muIniMomZ) {rootTree->Branch("muIniMomZ",&muIniMomZ_t,"muIniMomZ/D");}
|
||||
if (store_muIniPolX) {rootTree->Branch("muIniPolX",&muIniPolX_t,"muIniPolX/D");}
|
||||
if (store_muIniPolY) {rootTree->Branch("muIniPolY",&muIniPolY_t,"muIniPolY/D");}
|
||||
if (store_muIniPolZ) {rootTree->Branch("muIniPolZ",&muIniPolZ_t,"muIniPolZ/D");}
|
||||
if (store_muDecayDetID) {rootTree->Branch("muDecayDetID",&muDecayDetID_t,"muDecayDetID/I");}
|
||||
if (store_muDecayPosX) {rootTree->Branch("muDecayPosX",&muDecayPosX_t,"muDecayPosX/D");}
|
||||
if (store_muDecayPosY) {rootTree->Branch("muDecayPosY",&muDecayPosY_t,"muDecayPosY/D");}
|
||||
if (store_muDecayPosZ) {rootTree->Branch("muDecayPosZ",&muDecayPosZ_t,"muDecayPosZ/D");}
|
||||
if (store_muDecayTime) {rootTree->Branch("muDecayTime",&muDecayTime_t,"muDecayTime/D");}
|
||||
if (store_muDecayPolX) {rootTree->Branch("muDecayPolX",&muDecayPolX_t,"muDecayPolX/D");}
|
||||
if (store_muDecayPolY) {rootTree->Branch("muDecayPolY",&muDecayPolY_t,"muDecayPolY/D");}
|
||||
if (store_muDecayPolZ) {rootTree->Branch("muDecayPolZ",&muDecayPolZ_t,"muDecayPolZ/D");}
|
||||
if (store_muTargetTime) {rootTree->Branch("muTargetTime",&muTargetTime_t,"muTargetTime/D");}
|
||||
if (store_muTargetPolX) {rootTree->Branch("muTargetPolX",&muTargetPolX_t,"muTargetPolX/D");}
|
||||
if (store_muTargetPolY) {rootTree->Branch("muTargetPolY",&muTargetPolY_t,"muTargetPolY/D");}
|
||||
if (store_muTargetPolZ) {rootTree->Branch("muTargetPolZ",&muTargetPolZ_t,"muTargetPolZ/D");}
|
||||
if (store_muM0Time) {rootTree->Branch("muM0Time",&muM0Time_t,"muM0Time/D");}
|
||||
if (store_muM0PolX) {rootTree->Branch("muM0PolX",&muM0PolX_t,"muM0PolX/D");}
|
||||
if (store_muM0PolY) {rootTree->Branch("muM0PolY",&muM0PolY_t,"muM0PolY/D");}
|
||||
if (store_muM0PolZ) {rootTree->Branch("muM0PolZ",&muM0PolZ_t,"muM0PolZ/D");}
|
||||
if (store_muM1Time) {rootTree->Branch("muM1Time",&muM1Time_t,"muM1Time/D");}
|
||||
if (store_muM1PolX) {rootTree->Branch("muM1PolX",&muM1PolX_t,"muM1PolX/D");}
|
||||
if (store_muM1PolY) {rootTree->Branch("muM1PolY",&muM1PolY_t,"muM1PolY/D");}
|
||||
if (store_muM1PolZ) {rootTree->Branch("muM1PolZ",&muM1PolZ_t,"muM1PolZ/D");}
|
||||
if (store_muM2Time) {rootTree->Branch("muM2Time",&muM2Time_t,"muM2Time/D");}
|
||||
if (store_muM2PolX) {rootTree->Branch("muM2PolX",&muM2PolX_t,"muM2PolX/D");}
|
||||
if (store_muM2PolY) {rootTree->Branch("muM2PolY",&muM2PolY_t,"muM2PolY/D");}
|
||||
if (store_muM2PolZ) {rootTree->Branch("muM2PolZ",&muM2PolZ_t,"muM2PolZ/D");}
|
||||
if (store_posIniMomX) {rootTree->Branch("posIniMomX",&posIniMomx_t,"posIniMomX/D");}
|
||||
if (store_posIniMomY) {rootTree->Branch("posIniMomY",&posIniMomy_t,"posIniMomY/D");}
|
||||
if (store_posIniMomZ) {rootTree->Branch("posIniMomZ",&posIniMomz_t,"posIniMomZ/D");}
|
||||
// if (store_globalTime) {rootTree->Branch("globalTime",&globalTime_t,"globalTime/D");}
|
||||
// if (store_fieldValue) {rootTree->Branch("fieldValue",&fieldValue_t,"fieldValue/D");}
|
||||
if (store_fieldNomVal) {
|
||||
rootTree->Branch("nFieldNomVal",&nFieldNomVal,"nFieldNomVal/I");
|
||||
rootTree->Branch("fieldNomVal",&fieldNomVal,"fieldNomVal[nFieldNomVal]/D");
|
||||
}
|
||||
if (store_fieldIntegralBx) {rootTree->Branch("BxIntegral",&BxIntegral_t,"BxIntegral/D");}
|
||||
if (store_fieldIntegralBy) {rootTree->Branch("ByIntegral",&ByIntegral_t,"ByIntegral/D");}
|
||||
if (store_fieldIntegralBz) {rootTree->Branch("BzIntegral",&BzIntegral_t,"BzIntegral/D");}
|
||||
if (store_fieldIntegralBz1) {rootTree->Branch("BzIntegral1",&BzIntegral1_t,"BzIntegral1/D");}
|
||||
if (store_fieldIntegralBz2) {rootTree->Branch("BzIntegral2",&BzIntegral2_t,"BzIntegral2/D");}
|
||||
if (store_fieldIntegralBz3) {rootTree->Branch("BzIntegral3",&BzIntegral3_t,"BzIntegral3/D");}
|
||||
|
||||
rootTree->Branch("det_n",&det_n,"det_n/I");
|
||||
if (store_det_ID) {rootTree->Branch("det_ID",&det_ID,"det_ID[det_n]/I");}
|
||||
if (store_det_edep) {rootTree->Branch("det_edep",&det_edep,"det_edep[det_n]/D");}
|
||||
if (store_det_edep_el) {rootTree->Branch("det_edep_el",&det_edep_el,"det_edep_el[det_n]/D");}
|
||||
if (store_det_edep_pos) {rootTree->Branch("det_edep_pos",&det_edep_pos,"det_edep_pos[det_n]/D");}
|
||||
if (store_det_edep_gam) {rootTree->Branch("det_edep_gam",&det_edep_gam,"det_edep_gam[det_n]/D");}
|
||||
if (store_det_edep_mup) {rootTree->Branch("det_edep_mup",&det_edep_mup,"det_edep_mup[det_n]/D");}
|
||||
if (store_det_nsteps) {rootTree->Branch("det_nsteps",&det_nsteps,"det_nsteps[det_n]/I");}
|
||||
if (store_det_length) {rootTree->Branch("det_length",&det_length,"det_length[det_n]/D");}
|
||||
if (store_det_start) {rootTree->Branch("det_time_start",&det_time_start,"det_time_start[det_n]/D");}
|
||||
if (store_det_end) {rootTree->Branch("det_time_end",&det_time_end,"det_time_end[det_n]/D");}
|
||||
if (store_det_x) {rootTree->Branch("det_x",&det_x,"det_x[det_n]/D");}
|
||||
if (store_det_y) {rootTree->Branch("det_y",&det_y,"det_y[det_n]/D");}
|
||||
if (store_det_z) {rootTree->Branch("det_z",&det_z,"det_z[det_n]/D");}
|
||||
if (store_det_kine) {rootTree->Branch("det_kine",&det_kine,"det_kine[det_n]/D");}
|
||||
if (store_det_VrtxKine) {rootTree->Branch("det_VrtxKine",&det_VrtxKine,"det_VrtxKine[det_n]/D");}
|
||||
if (store_det_VrtxX) {rootTree->Branch("det_VrtxX",&det_VrtxX,"det_VrtxX[det_n]/D");}
|
||||
if (store_det_VrtxY) {rootTree->Branch("det_VrtxY",&det_VrtxY,"det_VrtxY[det_n]/D");}
|
||||
if (store_det_VrtxZ) {rootTree->Branch("det_VrtxZ",&det_VrtxZ,"det_VrtxZ[det_n]/D");}
|
||||
if (store_det_VrtxVolID){rootTree->Branch("det_VrtxVolID",&det_VrtxVolID,"det_VrtxVolID[det_n]/I");}
|
||||
if (store_det_VrtxProcID){rootTree->Branch("det_VrtxProcID",&det_VrtxProcID,"det_VrtxProcID[det_n]/I");}
|
||||
if (store_det_VrtxTrackID){rootTree->Branch("det_VrtxTrackID",&det_VrtxTrackID,"det_VrtxTrackID[det_n]/I");}
|
||||
if (store_det_VrtxParticleID){rootTree->Branch("det_VrtxParticleID",&det_VrtxParticleID,"det_VrtxParticleID[det_n]/I");}
|
||||
if (store_det_VvvKine) {rootTree->Branch("det_VvvKine",&det_VvvKine,"det_VvvKine[det_n]/D");}
|
||||
if (store_det_VvvX) {rootTree->Branch("det_VvvX",&det_VvvX,"det_VvvX[det_n]/D");}
|
||||
if (store_det_VvvY) {rootTree->Branch("det_VvvY",&det_VvvY,"det_VvvY[det_n]/D");}
|
||||
if (store_det_VvvZ) {rootTree->Branch("det_VvvZ",&det_VvvZ,"det_VvvZ[det_n]/D");}
|
||||
if (store_det_VvvVolID){rootTree->Branch("det_VvvVolID",&det_VvvVolID,"det_VvvVolID[det_n]/I");}
|
||||
if (store_det_VvvProcID){rootTree->Branch("det_VvvProcID",&det_VvvProcID,"det_VvvProcID[det_n]/I");}
|
||||
if (store_det_VvvTrackID){rootTree->Branch("det_VvvTrackID",&det_VvvTrackID,"det_VvvTrackID[det_n]/I");}
|
||||
if (store_det_VvvParticleID){rootTree->Branch("det_VvvParticleID",&det_VvvParticleID,"det_VvvParticleID[det_n]/I");}
|
||||
|
||||
if (boolIsAnySpecialSaveVolumeDefined) {
|
||||
rootTree->Branch("save_n",&save_n,"save_n/I");
|
||||
rootTree->Branch("save_detID",&save_detID,"save_detID[save_n]/I");
|
||||
rootTree->Branch("save_particleID",&save_particleID,"save_particleID[save_n]/I");
|
||||
rootTree->Branch("save_ke",&save_ke,"save_ke[save_n]/D");
|
||||
rootTree->Branch("save_x",&save_x,"save_x[save_n]/D");
|
||||
rootTree->Branch("save_y",&save_y,"save_y[save_n]/D");
|
||||
rootTree->Branch("save_z",&save_z,"save_z[save_n]/D");
|
||||
rootTree->Branch("save_px",&save_px,"save_px[save_n]/D");
|
||||
rootTree->Branch("save_py",&save_py,"save_py[save_n]/D");
|
||||
rootTree->Branch("save_pz",&save_pz,"save_pz[save_n]/D");
|
||||
}
|
||||
|
||||
// htest1 = new TH1F("htest1","The debugging histogram 1",50,-4.,4.);
|
||||
// htest2 = new TH1F("htest2","The debugging histogram 2",50,0.,3.142);
|
||||
htest1 = new TH2F("htest1","x, y",50,-200.,200.,50,-200.,200.);
|
||||
htest2 = new TH2F("htest2","R, z",50,0.,250.,50,-150.,150.);
|
||||
htest3 = new TH1F("htest3","Energy in MeV",55,0.,55.);
|
||||
htest4 = new TH1F("htest4","Radioactive electron kinetic energy",250,0.,2.5);
|
||||
htest5 = new TH1F("htest5","The debugging histogram 5",50,-4.,4.);
|
||||
htest6 = new TH1F("htest6","The debugging histogram 6",50,0.,3.142);
|
||||
htest7 = new TH1F("htest7","The debugging histogram 7",50,-4.,4.);
|
||||
htest8 = new TH1F("htest8","The debugging histogram 8",50,0.,3.142);
|
||||
|
||||
G4cout << "musrRootOutput::BeginOfRunAction() The Root tree and branches were defined."<<G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
void musrRootOutput::EndOfRunAction() {
|
||||
G4cout << "musrRootOutput::EndOfRunAction() - Writing out the Root tree:"<<G4endl;
|
||||
rootTree->Write();
|
||||
htest1->Write();
|
||||
htest2->Write();
|
||||
htest3->Write();
|
||||
htest4->Write();
|
||||
htest5->Write();
|
||||
htest6->Write();
|
||||
htest7->Write();
|
||||
htest8->Write();
|
||||
// Variables exported from Geant simulation to the Root output
|
||||
// static const Int_t nGeantParamD=10;
|
||||
TVectorD TVector_GeantParametersD(maxNGeantParameters);
|
||||
for (Int_t i=0; i<maxNGeantParameters; i++) {
|
||||
TVector_GeantParametersD[i]=GeantParametersD[i];
|
||||
}
|
||||
TVector_GeantParametersD.Write("geantParametersD");
|
||||
rootFile->Close();
|
||||
G4cout<<"musrRootOutput::EndOfRunAction() - Root tree written out."<<G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrRootOutput::FillEvent() {
|
||||
htest5->Fill(atan2(posIniMomy_t,posIniMomx_t));
|
||||
htest6->Fill(atan2(sqrt(posIniMomx_t*posIniMomx_t+posIniMomy_t*posIniMomy_t),posIniMomz_t));
|
||||
if (weight_t>0.) {
|
||||
rootTree->Fill();
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrRootOutput::ClearAllRootVariables() {
|
||||
runID_t=-1000;
|
||||
eventID_t=-1000;
|
||||
weight_t=1.;
|
||||
B_t[0]=-1000.;B_t[1]=-1000.;B_t[2]=-1000.;B_t[3]=-1000.;B_t[4]=-1000.;B_t[5]=-1000.;
|
||||
muIniPosX_t=-1000; muIniPosY_t=-1000; muIniPosZ_t=-1000;
|
||||
muIniMomX_t=-1000; muIniMomY_t=-1000; muIniMomZ_t=-1000;
|
||||
muIniPolX_t=-1000; muIniPolY_t=-1000; muIniPolZ_t=-1000;
|
||||
muDecayDetID_t=-1000;
|
||||
muDecayPolX_t=-1000; muDecayPolY_t=-1000; muDecayPolZ_t=-1000;
|
||||
muTargetTime_t=-1000; muTargetPolX_t=-1000; muTargetPolY_t=-1000; muTargetPolZ_t=-1000;
|
||||
muM0Time_t=-1000; muM0PolX_t=-1000; muM0PolY_t=-1000; muM0PolZ_t=-1000;
|
||||
muM1Time_t=-1000; muM1PolX_t=-1000; muM1PolY_t=-1000; muM1PolZ_t=-1000;
|
||||
muM2Time_t=-1000; muM2PolX_t=-1000; muM2PolY_t=-1000; muM2PolZ_t=-1000;
|
||||
muDecayPosX_t=-1000;muDecayPosY_t=-1000;muDecayPosZ_t=-1000;
|
||||
muDecayTime_t=-1000;
|
||||
posIniMomx_t=-1000;posIniMomy_t=-1000;posIniMomz_t=-1000;
|
||||
BxIntegral_t = -1000; ByIntegral_t = -1000; BzIntegral_t = -1000;
|
||||
BzIntegral1_t = -1000; BzIntegral2_t = -1000; BzIntegral3_t = -1000;
|
||||
det_n=0;
|
||||
save_n=0;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
void musrRootOutput::SetVolumeIDMapping(std::string logivol, int volumeID) {
|
||||
// This function assigns a unique number to each sensitive detector name.
|
||||
// The numbers are used in the root tree, as it is easier to work with numbers
|
||||
// rather than with strings.
|
||||
if (SensDetectorMapping[logivol]) {
|
||||
char message[200];
|
||||
sprintf(message,"musrRootOutput::SetVolumeIDMapping: Sensitive volume %s already assigned",logivol.c_str());
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,message,false);
|
||||
}
|
||||
else{
|
||||
SensDetectorMapping[logivol]=volumeID;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int musrRootOutput::ConvertVolumeToID(std::string logivol) {
|
||||
G4int volumeID = SensDetectorMapping[logivol];
|
||||
if (volumeID==0) {
|
||||
char message[200];
|
||||
sprintf(message,"musrRootOutput::ConvertVolumeToID: No ID number assigned to sensitive volume %s .",logivol.c_str());
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,message,true);
|
||||
}
|
||||
return volumeID;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int musrRootOutput::ConvertProcessToID(std::string processName) {
|
||||
G4int processID = ProcessIDMapping[processName];
|
||||
if (processID==0) {
|
||||
char message[200];
|
||||
sprintf(message,"musrRootOutput::ConvertProcessToID: No ID number assigned to the process \"%s\" .",processName.c_str());
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,message,true);
|
||||
}
|
||||
return processID;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrRootOutput::SetSaveDetectorInfo (G4int ID, G4int particleID, G4double ke,
|
||||
G4double x, G4double y, G4double z, G4double px, G4double py, G4double pz) {
|
||||
if (save_n>=save_nMax) {
|
||||
char message[200];
|
||||
sprintf(message,"musrRootOutput.cc::SetSaveDetectorInfo(): more \"save\" hits then allowed: save_nMax=%i",save_nMax);
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,message,true);
|
||||
}
|
||||
else {
|
||||
save_detID[save_n]=ID;
|
||||
save_particleID[save_n]=particleID;
|
||||
save_ke[save_n]=ke/MeV;
|
||||
save_x[save_n]=x/mm;
|
||||
save_y[save_n]=y/mm;
|
||||
save_z[save_n]=z/mm;
|
||||
save_px[save_n]=px/MeV;
|
||||
save_py[save_n]=py/MeV;
|
||||
save_pz[save_n]=pz/MeV;
|
||||
|
||||
save_n++;
|
||||
}
|
||||
}
|
||||
|
||||
void musrRootOutput::SetFieldNomVal(G4int i, G4double value) {
|
||||
if (i<maxNFieldnNominalValues) {
|
||||
// cks the following will probably not be correct for electric field,
|
||||
// because the units are tesla. Should be modified.
|
||||
fieldNomVal[i]=value/tesla;
|
||||
}
|
||||
else {
|
||||
char message[200];
|
||||
sprintf(message,
|
||||
"musrRootOutput.cc::SetFieldNomVal(): more electromagnetic fields then allowed: maxNFieldnNominalValues=%i",
|
||||
maxNFieldnNominalValues);
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,message,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void musrRootOutput::SetDetectorInfo (G4int nDetectors, G4int ID, G4int particleID, G4double edep,
|
||||
G4double edep_el, G4double edep_pos,
|
||||
G4double edep_gam, G4double edep_mup,G4int nsteps, G4double length, G4double t1,
|
||||
G4double t2, G4double x, G4double y, G4double z,
|
||||
G4double ek, G4double ekVertex, G4double xVertex, G4double yVertex, G4double zVertex,
|
||||
G4int idVolVertex, G4int idProcVertex, G4int idTrackVertex)
|
||||
{
|
||||
if ((nDetectors<0)||(nDetectors>=(det_nMax-1))) {
|
||||
char message[200];
|
||||
sprintf(message,"musrRootOutput.cc::SetDetectorInfo: nDetectors %i is larger than det_nMax = %i",nDetectors,det_nMax);
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,message,false);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
det_n=nDetectors+1;
|
||||
det_ID[nDetectors]=ID;
|
||||
det_edep[nDetectors]=edep/MeV;
|
||||
det_edep_el[nDetectors]=edep_el/MeV;
|
||||
det_edep_pos[nDetectors]=edep_pos/MeV;
|
||||
det_edep_gam[nDetectors]=edep_gam/MeV;
|
||||
det_edep_mup[nDetectors]=edep_mup/MeV;
|
||||
det_nsteps[nDetectors]=nsteps;
|
||||
det_length[nDetectors]=length/mm;
|
||||
det_time_start[nDetectors]=t1/microsecond;
|
||||
det_time_end[nDetectors]=t2/microsecond;
|
||||
det_x[nDetectors]=x/mm;
|
||||
det_y[nDetectors]=y/mm;
|
||||
det_z[nDetectors]=z/mm;
|
||||
det_kine[nDetectors]=ek/MeV;
|
||||
det_VrtxKine[nDetectors]=ekVertex/MeV;
|
||||
det_VrtxX[nDetectors]=xVertex/mm;
|
||||
det_VrtxY[nDetectors]=yVertex/mm;
|
||||
det_VrtxZ[nDetectors]=zVertex/mm;
|
||||
det_VrtxVolID[nDetectors]=idVolVertex;
|
||||
det_VrtxProcID[nDetectors]=idProcVertex;
|
||||
det_VrtxTrackID[nDetectors]=idTrackVertex;
|
||||
det_VrtxParticleID[nDetectors]=particleID;
|
||||
}
|
||||
}
|
||||
|
||||
void musrRootOutput::SetDetectorInfoVvv (G4int nDetectors,
|
||||
G4double ekVertex, G4double xVertex, G4double yVertex, G4double zVertex,
|
||||
G4int idVolVertex, G4int idProcVertex, G4int idTrackVertex, G4int particleID) {
|
||||
if ((nDetectors<0)||(nDetectors>=(det_nMax-1))) {
|
||||
char message[200];
|
||||
sprintf(message,"musrRootOutput.cc::SetDetectorInfoVvv: nDetectors %i is larger than det_nMax = %i",nDetectors,det_nMax);
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,message,false);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
det_VvvKine[nDetectors]=ekVertex/MeV;
|
||||
det_VvvX[nDetectors]=xVertex/mm;
|
||||
det_VvvY[nDetectors]=yVertex/mm;
|
||||
det_VvvZ[nDetectors]=zVertex/mm;
|
||||
det_VvvVolID[nDetectors]=idVolVertex;
|
||||
det_VvvProcID[nDetectors]=idProcVertex;
|
||||
det_VvvTrackID[nDetectors]=idTrackVertex;
|
||||
det_VvvParticleID[nDetectors]=particleID;
|
||||
}
|
||||
}
|
100
src/musrRunAction.cc
Normal file
100
src/musrRunAction.cc
Normal file
@ -0,0 +1,100 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// Make G4Timer appear first!
|
||||
#include "G4Timer.hh"
|
||||
#include "musrRunAction.hh"
|
||||
#include "musrEventAction.hh"
|
||||
#include "musrSteppingAction.hh"
|
||||
#include "G4Run.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrRunAction::musrRunAction() {
|
||||
timer = new G4Timer;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrRunAction::~musrRunAction() {
|
||||
delete timer;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrRunAction::BeginOfRunAction(const G4Run* aRun) {
|
||||
timer->Start();
|
||||
G4int run_id= aRun->GetRunID();
|
||||
// if (run_id%100 == 0) {
|
||||
G4cout << "### Run " << run_id << G4endl;
|
||||
musrRootOutput::GetRootInstance()->StoreGeantParameter(6,run_id);
|
||||
musrRootOutput::GetRootInstance()->BeginOfRunAction();
|
||||
|
||||
// Initiate global electromagnetic field (if it exists):
|
||||
if (F04GlobalField::Exists()) {
|
||||
FieldList* fields = F04GlobalField::getObject()->getFields();
|
||||
|
||||
if (fields) {
|
||||
if (fields->size()>0) {
|
||||
G4int jjj=0;
|
||||
G4cout<<"\n------------ The following fields were defined: ----------------"<<G4endl;
|
||||
FieldList::iterator i;
|
||||
for (i=fields->begin(); i!=fields->end(); ++i) {
|
||||
(*i)->construct();
|
||||
// G4cout<<"\t==> "<<(*i)->GetElementFieldName()<<G4endl;
|
||||
// Get the nominal field value for the given field and store it in the Root output
|
||||
G4double nomFieldValue = (*i)->GetNominalFieldValue();
|
||||
musrRootOutput::GetRootInstance()->SetFieldNomVal(jjj,nomFieldValue);
|
||||
jjj++;
|
||||
}
|
||||
G4cout<<"-----------------------------------------------------------------"<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Print out the field values at the points user requested to be printed out:
|
||||
F04GlobalField::getObject()->PrintFieldAtRequestedPoints();
|
||||
}
|
||||
|
||||
// initialise the "boolIsVvvInfoRequested" variable in the musrSteppingAction.cc and musrScintSD.cc
|
||||
G4bool boolIsVvvInfoRequested = false;
|
||||
if ((musrRootOutput::store_det_VvvKine)||(musrRootOutput::store_det_VvvX)||
|
||||
(musrRootOutput::store_det_VvvY)||(musrRootOutput::store_det_VvvZ)||
|
||||
(musrRootOutput::store_det_VvvVolID)||(musrRootOutput::store_det_VvvProcID)||
|
||||
(musrRootOutput::store_det_VvvTrackID)||(musrRootOutput::store_det_VvvParticleID)) {
|
||||
boolIsVvvInfoRequested = true;
|
||||
}
|
||||
musrSteppingAction::GetInstance()->SetVvvInfoRequested(boolIsVvvInfoRequested);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrRunAction::EndOfRunAction(const G4Run* aRun) {
|
||||
musrRootOutput::GetRootInstance()->StoreGeantParameter(5,aRun->GetNumberOfEvent());
|
||||
musrRootOutput::GetRootInstance()->EndOfRunAction();
|
||||
|
||||
if (F04GlobalField::Exists()) {
|
||||
F04GlobalField* myGlobalField = F04GlobalField::getObject(); //Was causing seg. fault when called here
|
||||
if (myGlobalField!=NULL) {delete myGlobalField;}
|
||||
}
|
||||
|
||||
musrErrorMessage::GetInstance()->PrintErrorSummary();
|
||||
|
||||
timer->Stop();
|
||||
G4cout << "musrRunAction::EndOfRunAction:"<<G4endl;
|
||||
G4cout << " Number of events = " << aRun->GetNumberOfEvent()<<G4endl;
|
||||
// << " " << *timer << G4endl;
|
||||
G4cout << " User elapsed time = "<<timer->GetUserElapsed()/3600<<"h = "
|
||||
<<timer->GetUserElapsed()/60<<"min = "<<timer->GetUserElapsed()<<"s."<<G4endl;
|
||||
G4cout << " Real elapsed time = "<<timer->GetRealElapsed()/3600<<"h = "
|
||||
<<timer->GetRealElapsed()/60<<"min = "<<timer->GetRealElapsed()<<"s."<<G4endl;
|
||||
G4cout << " System elapsed time = "<<timer->GetSystemElapsed()/3600<<"h = "
|
||||
<<timer->GetSystemElapsed()/60<<"min = "<<timer->GetSystemElapsed()<<"s."<<G4endl;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
|
156
src/musrScintHit.cc
Normal file
156
src/musrScintHit.cc
Normal file
@ -0,0 +1,156 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "musrScintHit.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4VVisManager.hh"
|
||||
#include "G4Circle.hh"
|
||||
#include "G4Colour.hh"
|
||||
#include "G4VisAttributes.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4MagneticField.hh"
|
||||
#include "G4FieldManager.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Transform3D.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4Run.hh"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
G4Allocator<musrScintHit> musrScintHitAllocator;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrScintHit::musrScintHit() {
|
||||
}
|
||||
|
||||
G4int musrScintHit::ScintMultihit=0;
|
||||
G4int musrScintHit::runIDoldScint=-1;
|
||||
G4int musrScintHit::eventIDoldScint=-1;
|
||||
G4int musrScintHit::NIS=0;
|
||||
G4int musrScintHit::ScintChamberNbold=-1;
|
||||
G4int musrScintHit::verboseLevel=0;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrScintHit::~musrScintHit() {
|
||||
//save the Tree header. The file will be automatically closed
|
||||
//when going out of the function scope
|
||||
// rootTree->Write();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrScintHit::musrScintHit(const musrScintHit& right)
|
||||
: G4VHit()
|
||||
{
|
||||
particleName = right.particleName;
|
||||
trackID = right.trackID;
|
||||
edep = right.edep;
|
||||
pre_pos = right.pre_pos;
|
||||
pol = right.pol;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
const musrScintHit& musrScintHit::operator=(const musrScintHit& right)
|
||||
{
|
||||
particleName = right.particleName;
|
||||
trackID = right.trackID;
|
||||
edep = right.edep;
|
||||
pre_pos = right.pre_pos;
|
||||
pol = right.pol;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int musrScintHit::operator==(const musrScintHit& right) const
|
||||
{
|
||||
return (this==&right) ? 1 : 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrScintHit::Draw()
|
||||
{
|
||||
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
|
||||
if(pVVisManager)
|
||||
{
|
||||
G4Circle circle(pre_pos);
|
||||
circle.SetScreenSize(0.04);
|
||||
circle.SetFillStyle(G4Circle::filled);
|
||||
G4Colour colour(1.,0.,0.);
|
||||
G4VisAttributes attribs(colour);
|
||||
circle.SetVisAttributes(attribs);
|
||||
pVVisManager->Draw(circle);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrScintHit::Print()
|
||||
{
|
||||
if (verboseLevel>2) G4cout<<"VERBOSE 3: Kamil: musrScintHit::Print()"<<G4endl;
|
||||
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
eventID = fRunManager->GetCurrentEvent()->GetEventID();
|
||||
runID = fRunManager->GetCurrentRun()->GetRunID();
|
||||
G4int ScintMultihitSwitch=0;
|
||||
|
||||
if (runID != runIDoldScint) {
|
||||
NIS=0;
|
||||
ScintMultihit = 0;
|
||||
eventIDoldScint = -1;
|
||||
ScintChamberNbold = -1;
|
||||
}
|
||||
|
||||
//cks if (particleName== "e+" and (eventIDoldScint != eventID or ScintChamberNbold != IBchamberNb)) {
|
||||
if (particleName== "e+") {
|
||||
if (eventIDoldScint == eventID) {
|
||||
ScintMultihit++;
|
||||
ScintMultihitSwitch=1;
|
||||
}
|
||||
NIS++;
|
||||
|
||||
G4FieldManager *fMgr=G4TransportationManager::GetTransportationManager()->GetFieldManager();
|
||||
point[0]=0.;
|
||||
point[1]=0.;
|
||||
point[2]=0.;
|
||||
B[2]=0.0;
|
||||
if(!fMgr->DoesFieldChangeEnergy()) { //then we have a magnetic field
|
||||
mfield = fMgr->GetDetectorField();
|
||||
mfield->GetFieldValue(point,B);
|
||||
B[0]=B[0]/tesla;
|
||||
B[1]=B[1]/tesla;
|
||||
B[2]=B[2]/tesla;
|
||||
}
|
||||
// G4cout << " Segment: " << IBchamberNb << G4endl;
|
||||
// G4cout <<"Position " << pos.x()/cm<<" "<<pos.y()/cm <<" "<< pos.z()/cm <<G4endl;
|
||||
// G4cout << "Field is "<< B[2]<<G4endl;
|
||||
|
||||
std::ofstream posfile1;
|
||||
posfile1.open ("scint.dat", std::ios::out | std::ios::app);
|
||||
posfile1 << runID << " " << eventID
|
||||
<< " " << logicalVolume
|
||||
<< " " << ScintMultihitSwitch
|
||||
<<" " << edep
|
||||
<< " " << fabs(B[2])
|
||||
<<" "<< pre_pos.x()/cm<<" "<<pre_pos.y()/cm <<" "<< pre_pos.z()/cm
|
||||
<< " " << globalTime/s
|
||||
// << " " << IBchamberNb
|
||||
// << " first=" << firstStepInVolume << " last=" << lastStepInVolume
|
||||
<< G4endl;
|
||||
posfile1.close();
|
||||
}
|
||||
eventIDoldScint=eventID;
|
||||
runIDoldScint = runID;
|
||||
// ScintChamberNbold = IBchamberNb;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
359
src/musrScintSD.cc
Normal file
359
src/musrScintSD.cc
Normal file
@ -0,0 +1,359 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "musrScintSD.hh"
|
||||
#include "G4HCofThisEvent.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4ios.hh"
|
||||
#include <algorithm> // needed for the sort() function
|
||||
#include "G4VProcess.hh" // needed for the degugging message of the process name
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4Run.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "musrSteppingAction.hh"
|
||||
#include <vector>
|
||||
|
||||
//bool myREMOVEfunction (int i,int j) { return (i<j); }
|
||||
//bool timeOrdering (musrScintHit hit1, musrScintHit hit2) {
|
||||
// return (hit1.GetGlobalTime()<hit2.GetGlobalTime());
|
||||
//}
|
||||
//
|
||||
//bool timeOrdering2 (std::map<int,double>::iterator i1, std::map<int,double>::iterator m2) {
|
||||
// return ( (*i1).first()<(*i2).second() );
|
||||
//}
|
||||
//
|
||||
//bool timeOrdering2 (std::pair<int,double> p1, std::pair<int,double> p2) {
|
||||
// return ( p1.first()<p2.second() );
|
||||
//}
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrScintSD::musrScintSD(G4String name)
|
||||
:G4VSensitiveDetector(name)
|
||||
{
|
||||
G4String HCname;
|
||||
collectionName.insert(HCname="scintCollection");
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrScintSD::~musrScintSD(){ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrScintSD::Initialize(G4HCofThisEvent* HCE) {
|
||||
if (verboseLevel>1) G4cout<<"VERBOSE 2: musrScintSD::Initialize\n";
|
||||
scintCollection = new musrScintHitsCollection
|
||||
(SensitiveDetectorName,collectionName[0]);
|
||||
static G4int HCID = -1;
|
||||
if(HCID<0) {
|
||||
HCID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
|
||||
if (verboseLevel>1) G4cout<<"VERBOSE 2: musrScintSD::HCID was <0\n, now HCID="<<HCID<<"\n";
|
||||
}
|
||||
HCE->AddHitsCollection( HCID, scintCollection );
|
||||
myStoreOnlyEventsWithHits = musrParameters::storeOnlyEventsWithHits;
|
||||
mySignalSeparationTime = musrParameters::signalSeparationTime;
|
||||
myStoreOnlyTheFirstTimeHit= musrParameters::storeOnlyTheFirstTimeHit;
|
||||
myStoreOnlyEventsWithHitInDetID = musrParameters::storeOnlyEventsWithHitInDetID;
|
||||
musrSteppingAction* myMusrSteppingAction = musrSteppingAction::GetInstance();
|
||||
boolIsVvvInfoRequested = myMusrSteppingAction->IsVvvInfoRequested();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool musrScintSD::ProcessHits(G4Step* aStep,G4TouchableHistory*)
|
||||
{
|
||||
if (verboseLevel>1) G4cout<<"VERBOSE 2: musrScintSD::ProcessHits\n";
|
||||
G4double edep = aStep->GetTotalEnergyDeposit();
|
||||
if(edep==0.) {
|
||||
return false;
|
||||
}
|
||||
|
||||
G4Track* aTrack = aStep->GetTrack();
|
||||
G4String actualVolume=aTrack->GetVolume()->GetLogicalVolume()->GetName();
|
||||
|
||||
// If requested, store only the hit that happened first (usefull for some special studies, not for a serious simulation)
|
||||
if (myStoreOnlyTheFirstTimeHit) {
|
||||
G4int NbHits = scintCollection->entries();
|
||||
if (NbHits>0) {
|
||||
aTrack->SetTrackStatus(fStopAndKill);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
musrScintHit* newHit = new musrScintHit();
|
||||
newHit->SetParticleName (aTrack->GetDefinition()->GetParticleName());
|
||||
G4int particleID = aTrack->GetDefinition()->GetPDGEncoding();
|
||||
newHit->SetParticleID (particleID);
|
||||
newHit->SetEdep (edep);
|
||||
newHit->SetPrePos (aStep->GetPreStepPoint()->GetPosition());
|
||||
newHit->SetPostPos (aStep->GetPostStepPoint()->GetPosition());
|
||||
newHit->SetPol (aTrack->GetPolarization());
|
||||
G4LogicalVolume* hitLogicalVolume = aTrack->GetVolume()->GetLogicalVolume();
|
||||
newHit->SetLogVolName(hitLogicalVolume->GetName());
|
||||
newHit->SetGlobTime(aTrack->GetGlobalTime());
|
||||
// Warning - aStep->IsFirstStepInVolume() only available in Geant version >= 4.8.2 !
|
||||
// newHit->SetFirstStepInVolumeFlag(aStep->IsFirstStepInVolume());
|
||||
// newHit->SetLastStepInVolumeFlag(aStep->IsLastStepInVolume());
|
||||
newHit->SetKineticEnergy(aTrack->GetKineticEnergy());
|
||||
// newHit->SetKineticEnergy(aTrack->GetKineticEnergy()+edep);
|
||||
G4double vertexKineticEnergy = aTrack->GetVertexKineticEnergy();
|
||||
newHit->SetVertexKineticEnergy(vertexKineticEnergy);
|
||||
G4ThreeVector vertexPosition = aTrack->GetVertexPosition();
|
||||
newHit->SetVertexPosition(vertexPosition);
|
||||
const G4LogicalVolume* vertexLogicalVolume = aTrack->GetLogicalVolumeAtVertex();
|
||||
G4String vertexLogicalVolumeName = vertexLogicalVolume->GetName();
|
||||
newHit->SetLogicalVolumeAtVertex(vertexLogicalVolumeName);
|
||||
G4String processName;
|
||||
if ((aTrack->GetCreatorProcess())!=0) { processName=aTrack->GetCreatorProcess()->GetProcessName(); }
|
||||
else {processName="initialParticle";} //if no process found, the track comes from the generated particle
|
||||
newHit->SetCreatorProcessName(processName);
|
||||
G4int trackID = aTrack->GetTrackID();
|
||||
newHit->SetTrackID (trackID);
|
||||
newHit->SetStepLength (aStep->GetStepLength());
|
||||
|
||||
scintCollection->insert( newHit );
|
||||
// newHit->Print();
|
||||
newHit->Draw();
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrScintSD::EndOfEvent(G4HCofThisEvent*) {
|
||||
if (verboseLevel>1) {
|
||||
G4cout<<"VERBOSE 2: musrScintSD::EndOfEvent"<<G4endl;
|
||||
G4int NbHits = scintCollection->entries();
|
||||
G4cout << "\n-------->Hits Collection: in this event they are " << NbHits
|
||||
<< " hits in the scint chambers: " << G4endl;
|
||||
}
|
||||
|
||||
// Positron_momentum_already_stored=0;
|
||||
musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
myRootOutput->SetRunID(fRunManager->GetCurrentRun()->GetRunID());
|
||||
myRootOutput->SetEventID(fRunManager->GetCurrentEvent()->GetEventID());
|
||||
|
||||
G4int NbHits = scintCollection->entries();
|
||||
|
||||
if (myStoreOnlyEventsWithHits) {
|
||||
if (NbHits<=0) {
|
||||
return;
|
||||
}
|
||||
else if (myStoreOnlyEventsWithHitInDetID!=0) {
|
||||
for (G4int i=0; i<NbHits; i++) {
|
||||
musrScintHit* aHit = (*scintCollection)[i];
|
||||
G4String aHitVolumeName = aHit->GetLogVolName();
|
||||
G4int aHitVolumeID = myRootOutput->ConvertVolumeToID(aHitVolumeName);
|
||||
if (aHitVolumeID==myStoreOnlyEventsWithHitInDetID) break; // hit in the requested detector was identified
|
||||
if (i==(NbHits-1)) return; // no hit identified in the requested detector
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort out hits and fill them into root
|
||||
if (NbHits>0) {
|
||||
const G4int det_IDmax = musrRootOutput::det_nMax;
|
||||
G4double det_edep[det_IDmax];
|
||||
G4int det_nsteps[det_IDmax];
|
||||
G4double det_length[det_IDmax];
|
||||
G4int det_ID[det_IDmax];
|
||||
G4double det_edep_el[det_IDmax];
|
||||
G4double det_edep_pos[det_IDmax];
|
||||
G4double det_edep_gam[det_IDmax];
|
||||
G4double det_edep_mup[det_IDmax];
|
||||
G4double det_time_start[det_IDmax];
|
||||
G4double det_time_end[det_IDmax];
|
||||
G4double det_x[det_IDmax];
|
||||
G4double det_y[det_IDmax];
|
||||
G4double det_z[det_IDmax];
|
||||
G4double det_kine[det_IDmax];
|
||||
G4double det_VrtxKine[det_IDmax];
|
||||
G4double det_VrtxX[det_IDmax];
|
||||
G4double det_VrtxY[det_IDmax];
|
||||
G4double det_VrtxZ[det_IDmax];
|
||||
G4int det_VrtxVolID[det_IDmax];
|
||||
G4int det_VrtxProcID[det_IDmax];
|
||||
G4int det_VrtxTrackID[det_IDmax];
|
||||
G4int det_VrtxParticleID[det_IDmax];
|
||||
G4int det_VvvTrackSign[det_IDmax];
|
||||
|
||||
// Sort hits according to the time. Using std::map is convenient, because it sorts
|
||||
// its entries according to the key (the first variable of the pair).
|
||||
std::multimap<G4double,G4int> myHitTimeMapping; // "map" replaced by "multimap" (needed for radioactive decay,
|
||||
// in which case times are huge and due to the limited rounding
|
||||
// precision become equal --> map ignores the same "keys",
|
||||
// multimap does not.
|
||||
std::map<G4double,G4int>::iterator it;
|
||||
for (G4int i=0; i<NbHits; i++) {
|
||||
musrScintHit* aHit = (*scintCollection)[i];
|
||||
G4double tmptime=aHit->GetGlobalTime();
|
||||
// G4cout<<"Hit nr "<<i<<" at time="<<tmptime<<" with edep="<<aHit->GetEdep()/MeV
|
||||
// <<" detID="<<myRootOutput->ConvertVolumeToID(aHit->GetLogVolName())<< G4endl;
|
||||
myHitTimeMapping.insert ( std::pair<G4double,G4int>(tmptime,i) );
|
||||
}
|
||||
|
||||
// Loop over all hits (which are sorted according to their time):
|
||||
G4int nSignals=0;
|
||||
for (it=myHitTimeMapping.begin(); it!=myHitTimeMapping.end(); it++) {
|
||||
// G4cout << "Key:" << it->first;
|
||||
// G4cout << " Value:" << it->second << "\n";
|
||||
G4int ii = it->second; // ii is the index of the hits, which is sorted according to time
|
||||
musrScintHit* aHit = (*scintCollection)[ii];
|
||||
G4String aHitVolumeName = aHit->GetLogVolName();
|
||||
G4int aHitVolumeID = myRootOutput->ConvertVolumeToID(aHitVolumeName);
|
||||
G4double aHitTime = aHit->GetGlobalTime();
|
||||
G4int aHitTrackID = aHit->GetTrackID();
|
||||
|
||||
// Loop over all already defined signals and check whether the hit falls into any of them
|
||||
G4bool signalAssigned=false;
|
||||
for (G4int j=0; j<nSignals; j++) {
|
||||
if ( (aHitVolumeID==det_ID[j]) && ((aHitTime-det_time_end[j])<mySignalSeparationTime) ) {
|
||||
signalAssigned=true;
|
||||
det_edep[j] += aHit->GetEdep();
|
||||
det_nsteps[j]++;
|
||||
det_length[j] += aHit->GetStepLength();
|
||||
det_time_end[j] = aHitTime;
|
||||
G4String aParticleName = aHit->GetParticleName();
|
||||
if (aParticleName=="e-") {
|
||||
det_edep_el[j] += aHit->GetEdep();
|
||||
} else if (aParticleName=="e+") {
|
||||
det_edep_pos[j] += aHit->GetEdep();
|
||||
} else if (aParticleName=="gamma") {
|
||||
det_edep_gam[j] += aHit->GetEdep();
|
||||
} else if (aParticleName=="mu+") {
|
||||
det_edep_mup[j] += aHit->GetEdep();
|
||||
} else {
|
||||
char message[200];
|
||||
sprintf(message,"musrScintSD.cc::EndOfEvent(): untreated particle \"%s\" deposited energy.",aParticleName.c_str());
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,message,true);
|
||||
}
|
||||
// Check whether the signals consits of more then just one hit, in which case make the track ID negative:
|
||||
if (abs(det_VrtxTrackID[j])!=aHitTrackID) {
|
||||
det_VrtxTrackID[j]=-1*abs(det_VrtxTrackID[j]);
|
||||
if (boolIsVvvInfoRequested) {
|
||||
if (det_VvvTrackSign[j]==1) {
|
||||
musrSteppingAction* myMusrSteppingAction = musrSteppingAction::GetInstance();
|
||||
if (!(myMusrSteppingAction->AreTracksCommingFromSameParent(aHitTrackID,abs(det_VrtxTrackID[j]),aHitVolumeName))) {det_VvvTrackSign[j]=-1;}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!signalAssigned) { // The hit does not belong to any existing signal --> create a new signal.
|
||||
// Check, whether the maximum number of signals was not exceeded:
|
||||
if ( nSignals >= (det_IDmax-1) ) {
|
||||
char message[200];
|
||||
sprintf(message,"musrScintSD.cc::EndOfEvent(): number of signals exceeds maximal allowed value.");
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,message,true);
|
||||
}
|
||||
else {
|
||||
det_edep[nSignals] = aHit->GetEdep();
|
||||
det_nsteps[nSignals] = 1;
|
||||
det_length[nSignals] = aHit->GetStepLength();
|
||||
det_ID[nSignals] = aHitVolumeID;
|
||||
det_time_start[nSignals] = aHitTime;
|
||||
det_time_end[nSignals] = aHitTime;
|
||||
det_edep_el[nSignals] = 0;
|
||||
det_edep_pos[nSignals] = 0;
|
||||
det_edep_gam[nSignals] = 0;
|
||||
det_edep_mup[nSignals] = 0;
|
||||
G4String aParticleName = aHit->GetParticleName();
|
||||
if (aParticleName=="e-") {
|
||||
det_edep_el[nSignals] += aHit->GetEdep();
|
||||
} else if (aParticleName=="e+") {
|
||||
det_edep_pos[nSignals] += aHit->GetEdep();
|
||||
} else if (aParticleName=="gamma") {
|
||||
det_edep_gam[nSignals] += aHit->GetEdep();
|
||||
} else if (aParticleName=="mu+") {
|
||||
det_edep_mup[nSignals] += aHit->GetEdep();
|
||||
} else {
|
||||
char message[200];
|
||||
sprintf(message,"musrScintSD.cc::EndOfEvent(): UNTREATED PARTICLE \"%s\" deposited energy.",aParticleName.c_str());
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,message,true);
|
||||
}
|
||||
G4ThreeVector prePos = aHit->GetPrePos();
|
||||
det_x[nSignals]=prePos.x();
|
||||
det_y[nSignals]=prePos.y();
|
||||
det_z[nSignals]=prePos.z();
|
||||
det_kine[nSignals] = aHit->GetKineticEnergy();
|
||||
det_VrtxKine[nSignals] = aHit->GetVertexKineticEnergy();
|
||||
G4ThreeVector VrtxPos = aHit->GetVertexPosition();
|
||||
det_VrtxX[nSignals] = VrtxPos.x();
|
||||
det_VrtxY[nSignals] = VrtxPos.y();
|
||||
det_VrtxZ[nSignals] = VrtxPos.z();
|
||||
G4String logicalVolumeAtVertex = aHit->GetLogicalVolumeAtVertex();
|
||||
det_VrtxVolID[nSignals] = myRootOutput->ConvertVolumeToID(logicalVolumeAtVertex);
|
||||
G4String creatorProcessName = aHit->GetCreatorProcessName();
|
||||
det_VrtxProcID[nSignals] = myRootOutput->ConvertProcessToID(creatorProcessName);
|
||||
det_VrtxTrackID[nSignals] = aHit->GetTrackID();
|
||||
det_VrtxParticleID[nSignals] = aHit->GetParticleID();
|
||||
det_VvvTrackSign[nSignals] = 1;
|
||||
nSignals++;
|
||||
}
|
||||
} // end of "if (!signalAssigned)"
|
||||
} // end of the for loop over the hits
|
||||
|
||||
// Sort the signals according to the energy (in decreasing order)
|
||||
std::map<G4double,G4int> mySignalMapping;
|
||||
std::map<G4double,G4int>::iterator itt;
|
||||
for (G4int i=0; i<nSignals; i++) {
|
||||
mySignalMapping.insert ( std::pair<G4double,G4int>(-det_edep[i],i) );
|
||||
}
|
||||
|
||||
// Write out the signals (sorted according to energy) to the musrRootOutput class:
|
||||
G4int jj=-1;
|
||||
for (itt=mySignalMapping.begin(); itt!=mySignalMapping.end(); itt++) {
|
||||
jj++;
|
||||
G4int ii = itt->second;
|
||||
myRootOutput->SetDetectorInfo(jj,det_ID[ii],det_VrtxParticleID[ii],det_edep[ii],
|
||||
det_edep_el[ii],det_edep_pos[ii],
|
||||
det_edep_gam[ii],det_edep_mup[ii],det_nsteps[ii],det_length[ii],
|
||||
det_time_start[ii],det_time_end[ii],det_x[ii],det_y[ii],det_z[ii],
|
||||
det_kine[ii],det_VrtxKine[ii],det_VrtxX[ii],det_VrtxY[ii],det_VrtxZ[ii],
|
||||
det_VrtxVolID[ii],det_VrtxProcID[ii],det_VrtxTrackID[ii] );
|
||||
|
||||
if (boolIsVvvInfoRequested) {
|
||||
G4int oldTrackID = abs(det_VrtxTrackID[ii]);
|
||||
musrSteppingAction* myMusrSteppingAction = musrSteppingAction::GetInstance();
|
||||
G4int vvvParentTrackID= -1; G4int vvvPparticleID; G4double vvvKine; G4ThreeVector vvvPosition; G4String vvvLogVol; G4String vvvProcess;
|
||||
G4int vvvLogVolID=-999;
|
||||
G4bool oldTrackRetrievedOK;
|
||||
do {
|
||||
if (vvvParentTrackID>-1) {oldTrackID=vvvParentTrackID;}
|
||||
oldTrackRetrievedOK = myMusrSteppingAction->GetInfoAboutOldTrack(oldTrackID,
|
||||
vvvParentTrackID, vvvPparticleID, vvvKine, vvvPosition, vvvLogVol, vvvProcess);
|
||||
if (oldTrackRetrievedOK) {
|
||||
// G4cout<<"musrScintSD: Old Track seems to be achieved fine -> Lets save it to Root tree"<<G4endl;
|
||||
vvvLogVolID=myRootOutput->ConvertVolumeToID(vvvLogVol);
|
||||
}
|
||||
else {
|
||||
G4cout<<" oldTrackRetrievedOK is false"<<G4endl;
|
||||
oldTrackID = -999;
|
||||
vvvParentTrackID = -999;
|
||||
vvvPparticleID = -999;
|
||||
vvvKine = -999;
|
||||
vvvPosition = G4ThreeVector(-999,-999,-999);
|
||||
vvvLogVol = "undefined";
|
||||
vvvProcess = "undefined";
|
||||
}
|
||||
} while (oldTrackRetrievedOK && (vvvLogVolID==det_ID[ii]));
|
||||
|
||||
if (oldTrackRetrievedOK) {
|
||||
G4int vvvProcessID=myRootOutput->ConvertProcessToID(vvvProcess);
|
||||
myRootOutput->SetDetectorInfoVvv(jj,vvvKine,vvvPosition.x(),vvvPosition.y(),vvvPosition.z(),
|
||||
vvvLogVolID,vvvProcessID,oldTrackID*det_VvvTrackSign[ii],vvvPparticleID);
|
||||
}
|
||||
} //end "boolIsVvvInfoRequested"
|
||||
|
||||
}
|
||||
} //end "if (NbHits>0)"
|
||||
|
||||
myRootOutput->FillEvent();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
443
src/musrSteppingAction.cc
Normal file
443
src/musrSteppingAction.cc
Normal file
@ -0,0 +1,443 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
#include "musrSteppingAction.hh"
|
||||
#include "G4SteppingManager.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4RunManager.hh" // needed for the event nr. comparison
|
||||
#include "G4Run.hh" // ---------------||------------------
|
||||
#include "G4MagneticField.hh" // needed for storing the magnetic field to the Root class
|
||||
#include "G4FieldManager.hh" // ---------------||------------------
|
||||
#include "G4TransportationManager.hh" // ---------------||------------------
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrSteppingAction::musrSteppingAction() {
|
||||
pointer=this;
|
||||
|
||||
boolIsAnySpecialSaveVolumeDefined = false;
|
||||
boolIsVvvInfoRequested = false;
|
||||
boolMuonEventReweighting = false;
|
||||
boolCalculateFieldIntegral = false;
|
||||
myRootOutput = musrRootOutput::GetRootInstance();
|
||||
if (myRootOutput == NULL) {
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,
|
||||
"musrSteppingAction::musrSteppingAction(): pointer to the musrRootOutput class not found! ==> EXECUTION STOPPED",true);
|
||||
}
|
||||
lastActualVolume="Unset";
|
||||
}
|
||||
|
||||
musrSteppingAction::~musrSteppingAction() {
|
||||
}
|
||||
|
||||
|
||||
musrSteppingAction* musrSteppingAction::pointer=0;
|
||||
musrSteppingAction* musrSteppingAction::GetInstance()
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void musrSteppingAction::DoAtTheBeginningOfEvent() {
|
||||
// G4cout<<"musrSteppingAction::DoAtTheBeginningOfEvent: at the beginning"<<G4endl;
|
||||
radioactiveElectronAlreadySavedInThisEvent=false;
|
||||
muAlreadyWasInTargetInThisEvent=false;
|
||||
muAlreadyWasInM0InThisEvent=false;
|
||||
muAlreadyWasInM1InThisEvent=false;
|
||||
muAlreadyWasInM2InThisEvent=false;
|
||||
myOldTracksMap.clear();
|
||||
indexOfOldTrack = -1;
|
||||
realTimeWhenThisEventStarted=time(0);
|
||||
BxIntegral=0; ByIntegral=0; BzIntegral=0; BzIntegral1=0; BzIntegral2=0; BzIntegral3=0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
||||
|
||||
G4Track* aTrack = aStep->GetTrack();
|
||||
|
||||
// suspend the track if too many steps has already happened (relevant at high field)
|
||||
if (aTrack->GetCurrentStepNumber()>100000) {
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,
|
||||
"musrSteppingAction: Current number of steps for the track > 100000 ==> TRACK KILLED",true);
|
||||
G4double x=aStep->GetPostStepPoint()->GetPosition().x()/mm;
|
||||
G4double y=aStep->GetPostStepPoint()->GetPosition().y()/mm;
|
||||
G4double z=aStep->GetPostStepPoint()->GetPosition().z()/mm;
|
||||
G4double E=aTrack->GetVertexKineticEnergy()/MeV;
|
||||
myRootOutput->htest1->Fill(x,y);
|
||||
myRootOutput->htest2->Fill(sqrt(x*x+y*y),z);
|
||||
myRootOutput->htest3->Fill(E);
|
||||
aTrack->SetTrackStatus(fStopAndKill);
|
||||
}
|
||||
|
||||
// abort the event if it takes too long to finish (e.g. more than 60 seconds)
|
||||
if ((time(0) - realTimeWhenThisEventStarted)>60) {
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
G4cout<<"musrSteppingAction: event "<<fRunManager->GetCurrentEvent()->GetEventID()
|
||||
<<" aborted because calculation took already 60 seconds."<<G4endl;
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,
|
||||
"musrSteppingAction: event aborted because its calculation takes more than 60 seconds.",true);
|
||||
//delete musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
myRootOutput->SetEventWeight(0);
|
||||
fRunManager->AbortEvent();
|
||||
}
|
||||
|
||||
// Temporary fix to avoid crashes caused by particles with unphysically high energies
|
||||
// (probably corrupted event?)
|
||||
if ((aStep->GetPreStepPoint()->GetKineticEnergy()) > (1*GeV)) {
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,
|
||||
"musrSteppingAction: kinetic energy of a particle larger than 1GeV! STRANGE FOR muSR!",false);
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
G4cout<<" Event nr.:"<<fRunManager->GetCurrentEvent()->GetEventID()
|
||||
<<", the particle \""<< aTrack->GetDynamicParticle()->GetDefinition()->GetParticleName()
|
||||
<<"\" has energy of "<<(aStep->GetPreStepPoint()->GetKineticEnergy())/GeV<<" GeV."<<G4endl;
|
||||
G4cout<<" Deleting the event!"<<G4endl;
|
||||
G4cout.flush();
|
||||
myRootOutput->SetEventWeight(0);
|
||||
fRunManager->AbortEvent();
|
||||
}
|
||||
|
||||
if (aTrack->GetDefinition()) {
|
||||
G4ParticleDefinition* p_definition = aTrack->GetDynamicParticle()->GetDefinition();
|
||||
G4String p_name = p_definition->GetParticleName();
|
||||
// G4ProcessManager* p_manager = p_definition->GetProcessManager();
|
||||
G4LogicalVolume* actualLogicalVolume = aTrack->GetVolume()->GetLogicalVolume();
|
||||
G4String actualVolume = actualLogicalVolume->GetName();
|
||||
|
||||
// Delete track if the particle is in the "kill" volume.
|
||||
// There is an example how to delete the track in example/novice/N04.
|
||||
// It is done in a different way here, because the example/novice/N04 was not doing
|
||||
// exactly what I wanted.
|
||||
if((actualVolume(0,8)=="log_kill")||(actualVolume(0,8)=="log_Kill")) {
|
||||
aTrack->SetTrackStatus(fStopAndKill); // suspend the track
|
||||
}
|
||||
if ((p_name=="nu_mu")||(p_name=="anti_nu_mu")||(p_name=="nu_e")||(p_name=="anti_nu_e")) {
|
||||
//aTrack->SetTrackStatus(fStopAndKill); // suspend the tracks of neutrinos
|
||||
}
|
||||
|
||||
|
||||
// Save info about the old tracks, if the user wish to have Vvv info in the output Root Tree.
|
||||
if (boolIsVvvInfoRequested) {
|
||||
G4VPhysicalVolume* nextVolume = aTrack->GetNextVolume();
|
||||
if (nextVolume!=NULL) {
|
||||
if ((nextVolume->GetLogicalVolume()->GetSensitiveDetector()!=NULL)||(actualLogicalVolume->GetSensitiveDetector()!=NULL)) {
|
||||
G4int trackID = aTrack->GetTrackID();
|
||||
std::map<G4int,G4int>::iterator itr;
|
||||
itr = myOldTracksMap.find(trackID);
|
||||
if (itr==myOldTracksMap.end()) {
|
||||
// track with this trackID has not been found in the map (has not been saved yet) ==> save it
|
||||
indexOfOldTrack++;
|
||||
myOldTracksMap.insert( std::pair<G4int,G4int>(trackID,indexOfOldTrack) );
|
||||
if (indexOfOldTrack<maxNumberOfOldTracks) {
|
||||
particleID_oldTrack[indexOfOldTrack] = aTrack->GetDefinition()->GetPDGEncoding();
|
||||
parentTrackID_oldTrack[indexOfOldTrack] = aTrack->GetParentID();
|
||||
vertexKine_oldTrack[indexOfOldTrack] = aTrack->GetVertexKineticEnergy();
|
||||
vertexPosition_oldTrack[indexOfOldTrack] = aTrack->GetVertexPosition();
|
||||
vertexLogVol_oldTrack[indexOfOldTrack] = aTrack->GetLogicalVolumeAtVertex()->GetName();
|
||||
if ((aTrack->GetCreatorProcess())!=NULL) { vertexProcess_oldTrack[indexOfOldTrack] = aTrack->GetCreatorProcess()->GetProcessName();}
|
||||
else { vertexProcess_oldTrack[indexOfOldTrack] = "initialParticle";}
|
||||
}
|
||||
else {
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,
|
||||
"musrSteppingAction: Maximum number of oldTracks reached ==> det_VvvXXX variables might be affected.",true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This are the data just for the radioactive decay (when using the radioactive source):
|
||||
if ((musrParameters::boolG4GeneralParticleSource)) {
|
||||
// &&(!radioactiveElectronAlreadySavedInThisEvent)) {
|
||||
if (aTrack->GetTrackID() != 1 ){
|
||||
if (aTrack->GetCreatorProcess()->GetProcessName() == "RadioactiveDecay") {
|
||||
if (aTrack->GetDefinition()->GetParticleName()=="e-") {
|
||||
if (aTrack->GetCurrentStepNumber()==1) {
|
||||
G4double electron_kinetic_energy=aStep->GetPreStepPoint()->GetKineticEnergy();
|
||||
myRootOutput->htest4->Fill(electron_kinetic_energy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if particle comes to the special volume
|
||||
if (boolIsAnySpecialSaveVolumeDefined) {
|
||||
// G4bool isFirstStepInVolume=aStep->IsFirstStepInVolume();
|
||||
// This does not work!!! (aStep->IsFirstStepInVolume() is always zero.) I do not understand why!
|
||||
G4bool isFirstStepInVolume=false;
|
||||
if (actualVolume!=lastActualVolume) {
|
||||
lastActualVolume=actualVolume;
|
||||
isFirstStepInVolume=true;
|
||||
}
|
||||
|
||||
if (isFirstStepInVolume) {
|
||||
G4int tmpVolumeID=saveVolumeMapping[actualVolume];
|
||||
if (tmpVolumeID!=0) {
|
||||
G4int particle_id_save=p_definition->GetPDGEncoding();
|
||||
G4double ke_save=aStep->GetPreStepPoint()->GetKineticEnergy();
|
||||
G4double x_save=aStep->GetPreStepPoint()->GetPosition().x();
|
||||
G4double y_save=aStep->GetPreStepPoint()->GetPosition().y();
|
||||
G4double z_save=aStep->GetPreStepPoint()->GetPosition().z();
|
||||
G4double px_save=aStep->GetPreStepPoint()->GetMomentum().x();
|
||||
G4double py_save=aStep->GetPreStepPoint()->GetMomentum().y();
|
||||
G4double pz_save=aStep->GetPreStepPoint()->GetMomentum().z();
|
||||
myRootOutput->SetSaveDetectorInfo(tmpVolumeID,particle_id_save,ke_save,x_save,y_save,z_save,px_save,py_save,pz_save);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((p_name == "mu+")||(p_name == "mu-")||(p_name == "Mu")) {
|
||||
// Store the information about the muon when it enters the target, M0, M1 or M2 for the fist time
|
||||
// in a given event (i.e. the code has to be called just once during the event).
|
||||
if ((actualVolume=="log_target")||(actualVolume=="log_Target")) {
|
||||
if (!muAlreadyWasInTargetInThisEvent) {
|
||||
muAlreadyWasInTargetInThisEvent=true;
|
||||
myRootOutput->SetPolInTarget(aTrack->GetPolarization());
|
||||
myRootOutput->SetTimeInTarget(aTrack->GetGlobalTime());
|
||||
}
|
||||
}
|
||||
else if ((actualVolume=="log_M0")||(actualVolume=="log_m0")) {
|
||||
if (!muAlreadyWasInM0InThisEvent) {
|
||||
muAlreadyWasInM0InThisEvent=true;
|
||||
myRootOutput->SetPolInM0(aTrack->GetPolarization());
|
||||
myRootOutput->SetTimeInM0(aTrack->GetGlobalTime());
|
||||
}
|
||||
}
|
||||
else if ((actualVolume=="log_M1")||(actualVolume=="log_m1")) {
|
||||
if (!muAlreadyWasInM1InThisEvent) {
|
||||
muAlreadyWasInM1InThisEvent=true;
|
||||
myRootOutput->SetPolInM1(aTrack->GetPolarization());
|
||||
myRootOutput->SetTimeInM1(aTrack->GetGlobalTime());
|
||||
}
|
||||
}
|
||||
else if ((actualVolume=="log_M2")||(actualVolume=="log_m2")) {
|
||||
if (!muAlreadyWasInM2InThisEvent) {
|
||||
muAlreadyWasInM2InThisEvent=true;
|
||||
myRootOutput->SetPolInM2(aTrack->GetPolarization());
|
||||
myRootOutput->SetTimeInM2(aTrack->GetGlobalTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate the field integral along the muon path, if requested by the user.
|
||||
// (2008.10.20. - idea of Robert is to calculate the distribution of the field integral for different muon paths
|
||||
// to see what (delta_I/I) is still acceptable for hith field muSR. To calculate it properly, the user must
|
||||
// force Geant to use very small step size.
|
||||
if (boolCalculateFieldIntegral) {
|
||||
if (F04GlobalField::Exists()) {
|
||||
G4ThreeVector position_tmp = aStep->GetPostStepPoint()->GetPosition();
|
||||
CoordinateForFieldIntegral[0] = position_tmp.x();
|
||||
CoordinateForFieldIntegral[1] = position_tmp.y();
|
||||
CoordinateForFieldIntegral[2] = position_tmp.z();
|
||||
CoordinateForFieldIntegral[3] = aTrack->GetGlobalTime();
|
||||
F04GlobalField::getObject() -> GetFieldValue(CoordinateForFieldIntegral,FieldForFieldIntegral);
|
||||
G4double stepLength = aStep->GetStepLength();
|
||||
// BxIntegral += stepLength;
|
||||
// ByIntegral += stepLength;
|
||||
// BzIntegral += stepLength;
|
||||
BxIntegral += stepLength * FieldForFieldIntegral[0];
|
||||
ByIntegral += stepLength * FieldForFieldIntegral[1];
|
||||
BzIntegral += stepLength * FieldForFieldIntegral[2];
|
||||
BzIntegral1 += ( position_tmp.z() - aStep->GetPreStepPoint()->GetPosition().z() ) * FieldForFieldIntegral[2];
|
||||
BzIntegral2 += stepLength;
|
||||
BzIntegral3 += ( position_tmp.z() - aStep->GetPreStepPoint()->GetPosition().z() );
|
||||
// G4cout<<"BzIntegral="<<BzIntegral<<" stepLength="<<stepLength<<"FieldForFieldIntegral[2]="<<FieldForFieldIntegral[2]<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Pick up process "DecayWithSpin":
|
||||
const G4VProcess* process = aStep->GetPostStepPoint()->GetProcessDefinedStep();
|
||||
if (process!=NULL) {
|
||||
G4String processName = process->GetProcessName();
|
||||
if (processName=="DecayWithSpin") {
|
||||
// std::cout<<"musrSteppingAction: DecayWithSpin"<<std::endl;
|
||||
musrParameters::field_DecayWithSpin=true;
|
||||
|
||||
// Test whether the event reweighting is requeseted for this volume
|
||||
// (i.e. user may request reweighting of events depending on the volume,
|
||||
// in which the muon stops and decays).
|
||||
if (boolMuonEventReweighting) {
|
||||
G4int weight = volumeMuonWeightMapping[actualVolume];
|
||||
if (weight!=0) {
|
||||
G4double randomNumber = weight * G4UniformRand();
|
||||
if (randomNumber < (weight-1.)) {
|
||||
// G4cout<<"Event will be aborted"<<G4endl;
|
||||
musrErrorMessage::GetInstance()->musrError(INFO,
|
||||
"musrSteppingAction: event deleted because of the reweighting.",true);
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
weight=0;
|
||||
fRunManager->AbortEvent();
|
||||
}
|
||||
// else {
|
||||
// G4cout<<"Event will be reweighted"<<G4endl;
|
||||
// }
|
||||
myRootOutput->SetEventWeight(weight);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the information about the decaying muon and store it in the Root tree
|
||||
G4double timeOfDecay_tmp=aTrack->GetGlobalTime();
|
||||
G4ThreeVector positionOfDecay_tmp = aStep->GetPostStepPoint()->GetPosition();
|
||||
G4double BFieldAtOrigin[6] = {0.,0.,0.,0.,0.,0.};
|
||||
G4double PointOfDecay[4] ={positionOfDecay_tmp.x(),positionOfDecay_tmp.y(),positionOfDecay_tmp.z(),timeOfDecay_tmp};
|
||||
if (F04GlobalField::Exists()) {
|
||||
F04GlobalField* myGlobalField = F04GlobalField::getObject();
|
||||
myGlobalField->GetFieldValue(PointOfDecay,BFieldAtOrigin);
|
||||
}
|
||||
else {
|
||||
G4FieldManager *fMgr=G4TransportationManager::GetTransportationManager()->GetFieldManager();
|
||||
// G4cout<<"Debug 1"<<G4endl;
|
||||
if (fMgr!=NULL) {
|
||||
// G4cout<<"Debug 2"<<G4endl;
|
||||
if(!fMgr->DoesFieldChangeEnergy()) { //then we have a magnetic field
|
||||
// G4cout<<"Debug 3"<<G4endl;
|
||||
fMgr->GetDetectorField()->GetFieldValue(PointOfDecay,BFieldAtOrigin);
|
||||
}
|
||||
}
|
||||
}
|
||||
myRootOutput->SetDecayTime(timeOfDecay_tmp);
|
||||
myRootOutput->SetDecayPolarisation(aTrack->GetPolarization());
|
||||
myRootOutput->SetDecayPosition(positionOfDecay_tmp);
|
||||
myRootOutput->SetDecayDetectorID(actualVolume);
|
||||
myRootOutput->SetBField(BFieldAtOrigin);
|
||||
if (boolCalculateFieldIntegral) {
|
||||
myRootOutput->SetBFieldIntegral(BxIntegral,ByIntegral,BzIntegral,BzIntegral1,BzIntegral2,BzIntegral3);
|
||||
}
|
||||
// G4cout<<"================================================== BzIntegral = "<<BzIntegral<<G4endl;
|
||||
|
||||
// store the information about the emerging positron
|
||||
G4TrackVector* secondary = fpSteppingManager->GetSecondary();
|
||||
G4int n_secondaries= (*secondary).size();
|
||||
for (G4int i=0; i<n_secondaries; i++) {
|
||||
if ( ((*secondary)[i]->GetDefinition()->GetParticleName()) == "e+" ) {
|
||||
myRootOutput->SetInitialPositronMomentum((*secondary)[i]->GetMomentum());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// G4ThreeVector position = aStep->GetPostStepPoint()->GetPosition();
|
||||
// G4ThreeVector polarization=aTrack->GetDynamicParticle()->GetPolarization();
|
||||
}
|
||||
|
||||
else { // particle is not muon
|
||||
// Delete track if the particle is far away from the detector (i.e. in the "shield" volume).
|
||||
// There is an example how to delete the track in example/novice/N04.
|
||||
// It is done in a different way here, because the example/novice/N04 was not doing
|
||||
// exactly what I wanted.
|
||||
if ( ((musrParameters::killAllPositrons)&&(p_name == "e+")) ||
|
||||
((musrParameters::killAllGammas)&&(p_name == "gamma")) ||
|
||||
((musrParameters::killAllNeutrinos)&&((p_name == "nu_mu")||(p_name == "anti_nu_mu")||(p_name == "nu_e")||(p_name == "anti_nu_e"))) ){
|
||||
aTrack->SetTrackStatus(fStopAndKill); // suspend the track
|
||||
}
|
||||
if((actualVolume(0,10)=="log_shield")||(actualVolume(0,10)=="log_Shield")) {
|
||||
aTrack->SetTrackStatus(fStopAndKill); // suspend the track
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
void musrSteppingAction::SetLogicalVolumeAsSpecialSaveVolume(G4String logicName, G4int volumeID) {
|
||||
boolIsAnySpecialSaveVolumeDefined = true;
|
||||
saveVolumeMapping[logicName]=volumeID;
|
||||
}
|
||||
|
||||
|
||||
void musrSteppingAction::SetVolumeForMuonEventReweighting(G4String logicName, G4int weight) {
|
||||
boolMuonEventReweighting = true;
|
||||
volumeMuonWeightMapping[logicName]=weight;
|
||||
}
|
||||
|
||||
G4bool musrSteppingAction::GetInfoAboutOldTrack(G4int trackID, G4int& parentTrackID, G4int& particleID, G4double& vertexKine,
|
||||
G4ThreeVector& vertexPosition, G4String& vertexLogVol, G4String& vertexProcess) {
|
||||
// G4int ind = myOldTracksMap[trackID];
|
||||
// G4cout<<"musrSteppingAction::GetInfoAboutOldTrack: trackID="<<trackID<<"\t myOldTracksMap[trackID]="<<myOldTracksMap[trackID]<<G4endl;
|
||||
std::map<G4int,G4int>::iterator itr;
|
||||
itr = myOldTracksMap.find(trackID);
|
||||
if ( itr==myOldTracksMap.end() ) {
|
||||
// if ((ind==0)||(ind>=maxNumberOfOldTracks)) {
|
||||
char eMessage[200];
|
||||
sprintf(eMessage,"musrSteppingAction::GetInfoAboutOldTrack: trackID not found in myOldTracksMap, det_VvvXXX variables might be affected");
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,eMessage,false);
|
||||
G4cout<<" Requested trackID="<<trackID<<G4endl;
|
||||
// G4cout<<"Saved tracks:"<<G4endl;
|
||||
// for (itr=myOldTracksMap.begin(); itr!=myOldTracksMap.end(); itr++) {
|
||||
// G4cout<<"first="<<itr->first<<"\tsecond="<<itr->second<<G4endl;
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
G4int ind = itr->second;
|
||||
if (ind>=maxNumberOfOldTracks) {
|
||||
G4cout<<"musrSteppingAction::GetInfoAboutOldTrack: Problem! ind>maxNumberOfOldTracks! ("<<ind<<">"<<maxNumberOfOldTracks<<")"<<G4endl;
|
||||
G4cout<<" itr->first = "<<itr->first<<", trackID = "<<trackID<<G4endl;
|
||||
return false;
|
||||
}
|
||||
parentTrackID=parentTrackID_oldTrack[ind];
|
||||
if (trackID==parentTrackID) {
|
||||
G4cout<<"musrSteppingAction::GetInfoAboutOldTrack: Problem! trackID==parentTrackID! ("<<trackID<<"=="<<parentTrackID<<")"<<G4endl;
|
||||
return false;
|
||||
}
|
||||
particleID=particleID_oldTrack[ind];
|
||||
vertexKine=vertexKine_oldTrack[ind];
|
||||
vertexPosition= vertexPosition_oldTrack[ind];
|
||||
vertexLogVol=vertexLogVol_oldTrack[ind];
|
||||
vertexProcess=vertexProcess_oldTrack[ind];
|
||||
}
|
||||
// G4cout<<"GetInfoAboutOldTrack: trackID="<<trackID<<"\t parentTrackID="<<parentTrackID<<"\t particleID="<<particleID;
|
||||
// G4cout<<"\t vertexKine="<<vertexKine<<"\t vertexLogVol="<<vertexLogVol<<"\t vertexProcess="<<vertexProcess<<G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
G4bool musrSteppingAction::AreTracksCommingFromSameParent(G4int trackID1, G4int trackID2, G4String volumeName){
|
||||
// There are two tracks with different track IDs. This routine finds the parents of both of them,
|
||||
// which were created outside logical volume "volumeID". If both tracks have the same parent, the
|
||||
// functions returns "true".
|
||||
std::map<G4int,G4int>::iterator itr;
|
||||
G4int ind;
|
||||
|
||||
G4int track1;
|
||||
G4int trID = trackID1;
|
||||
do {
|
||||
track1=trID;
|
||||
itr = myOldTracksMap.find(trID);
|
||||
if ( itr==myOldTracksMap.end() ) {
|
||||
G4cout<<"musrSteppingAction::AreTracksCommingFromSameParent() Strange, trackID1 ="<<trackID1<<" not found"<<G4endl;
|
||||
return false;
|
||||
}
|
||||
ind = itr->second;
|
||||
trID = parentTrackID_oldTrack[ind];
|
||||
} while (vertexLogVol_oldTrack[ind]==volumeName);
|
||||
|
||||
G4int track2;
|
||||
trID = trackID2;
|
||||
do {
|
||||
track2=trID;
|
||||
itr = myOldTracksMap.find(trID);
|
||||
if ( itr==myOldTracksMap.end() ) {
|
||||
G4cout<<"musrSteppingAction::AreTracksCommingFromSameParent() Strange, trackID2 ="<<trackID2<<" not found"<<G4endl;
|
||||
return false;
|
||||
}
|
||||
ind = itr->second;
|
||||
trID = parentTrackID_oldTrack[ind];
|
||||
} while (vertexLogVol_oldTrack[ind]==volumeName);
|
||||
|
||||
|
||||
if (track1==track2) {return true;}
|
||||
//G4cout<<"track1="<<track1<<"\ttrack2="<<track2<<G4endl; return true;}
|
||||
// G4cout<<"\t\t\t\ttrack1="<<track1<<"\ttrack2="<<track2<<G4endl;
|
||||
return false;
|
||||
}
|
151
src/musrSteppingVerbose.cc
Normal file
151
src/musrSteppingVerbose.cc
Normal file
@ -0,0 +1,151 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "musrSteppingVerbose.hh"
|
||||
|
||||
#include "G4SteppingManager.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrSteppingVerbose::musrSteppingVerbose()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrSteppingVerbose::~musrSteppingVerbose()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrSteppingVerbose::StepInfo()
|
||||
{
|
||||
CopyState();
|
||||
|
||||
G4int prec = G4cout.precision(3);
|
||||
|
||||
if( verboseLevel >= 1 ){
|
||||
if( verboseLevel >= 4 ) VerboseTrack();
|
||||
if( verboseLevel >= 3 ){
|
||||
G4cout << G4endl;
|
||||
G4cout << std::setw( 5) << "#Step#" << " "
|
||||
<< std::setw( 6) << "X" << " "
|
||||
<< std::setw( 6) << "Y" << " "
|
||||
<< std::setw( 6) << "Z" << " "
|
||||
<< std::setw( 9) << "KineE" << " "
|
||||
<< std::setw( 9) << "dEStep" << " "
|
||||
<< std::setw(10) << "StepLeng"
|
||||
<< std::setw(10) << "TrakLeng"
|
||||
<< std::setw(10) << "Volume" << " "
|
||||
<< std::setw(10) << "Process" << G4endl;
|
||||
}
|
||||
|
||||
G4cout << std::setw(5) << fTrack->GetCurrentStepNumber() << " "
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetPosition().x(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetPosition().y(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetPosition().z(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetKineticEnergy(),"Energy")
|
||||
<< std::setw(6) << G4BestUnit(fStep->GetTotalEnergyDeposit(),"Energy")
|
||||
<< std::setw(6) << G4BestUnit(fStep->GetStepLength(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetTrackLength(),"Length")
|
||||
<< " ";
|
||||
|
||||
// if( fStepStatus != fWorldBoundary){
|
||||
if( fTrack->GetNextVolume() != 0 ) {
|
||||
G4cout << std::setw(10) << fTrack->GetVolume()->GetName();
|
||||
} else {
|
||||
G4cout << std::setw(10) << "OutOfWorld";
|
||||
}
|
||||
|
||||
if(fStep->GetPostStepPoint()->GetProcessDefinedStep() != NULL){
|
||||
G4cout << " "
|
||||
<< std::setw(10) << fStep->GetPostStepPoint()->GetProcessDefinedStep()
|
||||
->GetProcessName();
|
||||
} else {
|
||||
G4cout << " UserLimit";
|
||||
}
|
||||
|
||||
G4cout << G4endl;
|
||||
|
||||
if( verboseLevel == 2 ){
|
||||
G4int tN2ndariesTot = fN2ndariesAtRestDoIt +
|
||||
fN2ndariesAlongStepDoIt +
|
||||
fN2ndariesPostStepDoIt;
|
||||
if(tN2ndariesTot>0){
|
||||
G4cout << " :----- List of 2ndaries - "
|
||||
<< "#SpawnInStep=" << std::setw(3) << tN2ndariesTot
|
||||
<< "(Rest=" << std::setw(2) << fN2ndariesAtRestDoIt
|
||||
<< ",Along=" << std::setw(2) << fN2ndariesAlongStepDoIt
|
||||
<< ",Post=" << std::setw(2) << fN2ndariesPostStepDoIt
|
||||
<< "), "
|
||||
<< "#SpawnTotal=" << std::setw(3) << (*fSecondary).size()
|
||||
<< " ---------------"
|
||||
<< G4endl;
|
||||
|
||||
for(size_t lp1=(*fSecondary).size()-tN2ndariesTot;
|
||||
lp1<(*fSecondary).size(); lp1++){
|
||||
G4cout << " : "
|
||||
<< std::setw(6)
|
||||
<< G4BestUnit((*fSecondary)[lp1]->GetPosition().x(),"Length")
|
||||
<< std::setw(6)
|
||||
<< G4BestUnit((*fSecondary)[lp1]->GetPosition().y(),"Length")
|
||||
<< std::setw(6)
|
||||
<< G4BestUnit((*fSecondary)[lp1]->GetPosition().z(),"Length")
|
||||
<< std::setw(6)
|
||||
<< G4BestUnit((*fSecondary)[lp1]->GetKineticEnergy(),"Energy")
|
||||
<< std::setw(10)
|
||||
<< (*fSecondary)[lp1]->GetDefinition()->GetParticleName();
|
||||
G4cout << G4endl;
|
||||
}
|
||||
|
||||
G4cout << " :-----------------------------"
|
||||
<< "----------------------------------"
|
||||
<< "-- EndOf2ndaries Info ---------------"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrSteppingVerbose::TrackingStarted()
|
||||
{
|
||||
|
||||
CopyState();
|
||||
G4int prec = G4cout.precision(3);
|
||||
if( verboseLevel > 0 ){
|
||||
|
||||
G4cout << std::setw( 5) << "Step#" << " "
|
||||
<< std::setw( 6) << "X" << " "
|
||||
<< std::setw( 6) << "Y" << " "
|
||||
<< std::setw( 6) << "Z" << " "
|
||||
<< std::setw( 9) << "KineE" << " "
|
||||
<< std::setw( 9) << "dEStep" << " "
|
||||
<< std::setw(10) << "StepLeng"
|
||||
<< std::setw(10) << "TrakLeng"
|
||||
<< std::setw(10) << "Volume" << " "
|
||||
<< std::setw(10) << "Process" << G4endl;
|
||||
|
||||
G4cout << std::setw(5) << fTrack->GetCurrentStepNumber() << " "
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetPosition().x(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetPosition().y(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetPosition().z(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetKineticEnergy(),"Energy")
|
||||
<< std::setw(6) << G4BestUnit(fStep->GetTotalEnergyDeposit(),"Energy")
|
||||
<< std::setw(6) << G4BestUnit(fStep->GetStepLength(),"Length")
|
||||
<< std::setw(6) << G4BestUnit(fTrack->GetTrackLength(),"Length")
|
||||
<< " ";
|
||||
|
||||
if(fTrack->GetNextVolume()){
|
||||
G4cout << std::setw(10) << fTrack->GetVolume()->GetName();
|
||||
} else {
|
||||
G4cout << std::setw(10) << "OutOfWorld";
|
||||
}
|
||||
G4cout << " initStep" << G4endl;
|
||||
}
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
596
src/musrTabulatedElementField.cc
Normal file
596
src/musrTabulatedElementField.cc
Normal file
@ -0,0 +1,596 @@
|
||||
#include "musrTabulatedElementField.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
musrTabulatedElementField::musrTabulatedElementField( const char* filename, const char* fldTableType, G4double fieldValue, G4LogicalVolume* logVolume, G4ThreeVector positionOfTheCenter) : F04ElementField(positionOfTheCenter, logVolume),
|
||||
ffieldValue(fieldValue)
|
||||
{
|
||||
// The following posibilities of the format of the field map are distinguieshed:
|
||||
// 3DBOpera = 3D ... 3D field , magnetic, Opera format (Kamil-like)
|
||||
// 3DE ... 3D field , electric, Toni-like (3DE WAS TESTED)
|
||||
// 3DB ... 3D field , magnetic, Toni-like
|
||||
// 2DBOpera = 2D .... 2D field, magnetic, Opera format (Kamil-like), X and Z components (2D WAS TESTED)
|
||||
// 2DBOperaXY = 2D_OperaXY .... 2D field, magnetic, Opera format with (Kamil-like), X and Y components
|
||||
// 2DE ... 2D field , electric, Toni-like (2DE WAS TESTED)
|
||||
// 2DB ... 2D field , magnetic, Toni-like
|
||||
|
||||
G4double lenUnit = 1*m; // length unit of the field map grid coordinates
|
||||
G4double fieldNormalisation = 1.; // Normalisation factor by which the the field map has to be multiplied
|
||||
// in order to get 1T (in the case of magnetic field)
|
||||
// "lenUnit" and "fieldNormalisation" are needed only if not specified
|
||||
// inside the fieldmap file;
|
||||
strcpy(fieldTableType,fldTableType);
|
||||
fldType = 'B';
|
||||
fUnit = "T";
|
||||
fieUnit = tesla;
|
||||
if (fieldTableType[2]=='E') {
|
||||
fldType = 'E';
|
||||
fUnit = "kV/mm";
|
||||
fieUnit= kilovolt/mm;
|
||||
}
|
||||
|
||||
fldDim = (fieldTableType[0]=='3') ? 3:2;
|
||||
if (fldDim==2) ny=1;
|
||||
|
||||
G4cout << "\n-----------------------------------------------------------" << G4endl;
|
||||
G4cout << " Field (of type "<<fieldTableType<<") set to "<< fieldValue/fieUnit << " "<< fUnit << G4endl;
|
||||
G4cout << "\n ---> " "Reading the field grid from " << filename << " ... " << G4endl;
|
||||
std::ifstream file( filename ); // Open the file for reading.
|
||||
if (!(file.is_open())) {
|
||||
G4cout << "Fieldmap file \""<< filename << "\" not opened (found) !!!"<<G4endl;
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,"musrTabulatedElementField: Field map file not found !",false);
|
||||
}
|
||||
|
||||
char buffer[256];
|
||||
G4bool boolMinimaAndMaximaDefinedInTheFile = false;
|
||||
if (fldType=='E') G4cout<<" Electric field ";
|
||||
if (fldType=='B') G4cout<<" Magnetic field ";
|
||||
if ((strcmp(fieldTableType,"3DE")==0)||(strcmp(fieldTableType,"3DB")==0)) {
|
||||
// File is in Toni Shiroka format:
|
||||
// Read the number of arguments and decide filetype - 3 or 6 columns
|
||||
G4cout << "3D, field-map file format by Toni Shiroka" << G4endl;
|
||||
char lenUnitFromFile[50];
|
||||
double fieldNormalisationFromFile;
|
||||
file.getline(buffer,256);
|
||||
int n_arg = sscanf (buffer,"%d %d %d %s %lf %lf %lf %lf %lf %lf %lf",
|
||||
&nx, &ny, &nz, lenUnitFromFile, &fieldNormalisationFromFile,
|
||||
&minimumx, &maximumx, &minimumy, &maximumy, &minimumz, &maximumz);
|
||||
lenUnit = G4UnitDefinition::GetValueOf(lenUnitFromFile);
|
||||
fieldNormalisation = fieldNormalisationFromFile;
|
||||
if (n_arg==11) {
|
||||
// The length unit and norm. factor have to be manually added to the field-map file!
|
||||
G4cout << " ---> Assumed order (3 col.): "<<fldType<<"x, "<<fldType<<"y, "<<fldType<<"z"<<G4endl;
|
||||
boolMinimaAndMaximaDefinedInTheFile = true;
|
||||
minimumx = minimumx * lenUnit;
|
||||
minimumy = minimumy * lenUnit;
|
||||
minimumz = minimumz * lenUnit;
|
||||
maximumx = maximumx * lenUnit;
|
||||
maximumy = maximumy * lenUnit;
|
||||
maximumz = maximumz * lenUnit;
|
||||
}
|
||||
else {
|
||||
G4cout << " ---> Assumed order (6 col.): x, y, z, "<<fldType<<"x, "<<fldType<<"y, "<<fldType<<"z"<<G4endl;
|
||||
}
|
||||
|
||||
// Ignore header information. All lines whose first character
|
||||
// is '%' are considered to be part of the header.
|
||||
do {
|
||||
file.ignore(256, '\n');
|
||||
} while (file.peek() == '%');
|
||||
}
|
||||
else if ((strcmp(fieldTableType,"3D")==0)||(strcmp(fieldTableType,"3DBOpera")==0)) {
|
||||
// OPERA format of the input file:
|
||||
// Read table dimensions
|
||||
lenUnit = 1*m;
|
||||
fieldNormalisation = 1.;
|
||||
G4cout << "3D, field-map file format from OPERA (Kamil)" << G4endl;
|
||||
G4cout << " ---> Assumed order (7 col.): x, y, z, "<<fldType<<"x, "<<fldType<<"y, "<<fldType<<"z, Dummy"<<G4endl;
|
||||
|
||||
file.getline(buffer,256); // Skip the first empty line of the file
|
||||
file >> nx >> ny >> nz; // Note dodgy order
|
||||
|
||||
// Ignore other header information
|
||||
// The first line whose second character is '0' is considered to
|
||||
// be the last line of the header.
|
||||
do {
|
||||
file.getline(buffer,256);
|
||||
} while ( buffer[1]!='0');
|
||||
}
|
||||
else if ((strcmp(fieldTableType,"2DE")==0)||(strcmp(fieldTableType,"2DB")==0)||(strcmp(fieldTableType,"2DEf")==0)) {
|
||||
// File is in Toni Shiroka format:
|
||||
G4cout << "2D, field-map file format by Toni Shiroka" << G4endl;
|
||||
G4cout << " ---> Assumed order (4 col.): r, z, "<<fldType<<"r, "<<fldType<<"z"<<G4endl;
|
||||
char lenUnitFromFile[50];
|
||||
file >> nx >> nz >> lenUnitFromFile >> fieldNormalisation;
|
||||
lenUnit = G4UnitDefinition::GetValueOf(lenUnitFromFile);
|
||||
// Ignore header information. All lines whose first character
|
||||
// is '%' are considered to be part of the header.
|
||||
do {
|
||||
file.ignore(256, '\n');
|
||||
} while (file.peek() == '%');
|
||||
}
|
||||
else if ((strcmp(fieldTableType,"2D_OperaXY")==0)||(strcmp(fieldTableType,"2DBOperaXY")==0)) {
|
||||
int nDummy;
|
||||
lenUnit = 1*cm;
|
||||
fieldNormalisation = 0.00001;
|
||||
G4cout << "2D, field-map file format from OPERA with X,Y components (Kamil)" << G4endl;
|
||||
G4cout << " ---> Assumed order (6 col.): r, z, dummy, "<<fldType<<"r, "<<fldType<<"z, Dummy"<<G4endl;
|
||||
file >> nx >> nz >> nDummy;
|
||||
do {
|
||||
file.getline(buffer,256);
|
||||
} while ( buffer[1]!='0');
|
||||
}
|
||||
else if ((strcmp(fieldTableType,"2D")==0)||(strcmp(fieldTableType,"2DBOpera")==0)) {
|
||||
int nDummy;
|
||||
lenUnit = 1*cm;
|
||||
fieldNormalisation = 0.00001;
|
||||
G4cout << "2D, field-map file format from OPERA with X,Z components (Kamil)" << G4endl;
|
||||
G4cout << " ---> Assumed order (6 col.): r, dummy, z, "<<fldType<<"r, "<<fldType<<"z, Dummy"<<G4endl;
|
||||
file >> nx >> nDummy >> nz;
|
||||
// G4cout << nx <<" "<< nDummy <<" "<< nz<<G4endl;
|
||||
do {
|
||||
file.getline(buffer,256);
|
||||
} while ( buffer[1]!='0');
|
||||
}
|
||||
else {
|
||||
G4cout << " musrTabulatedElementField::musrTabulatedElementField: Unknown field required!"
|
||||
<< " ("<<fieldTableType<<")" << G4endl;
|
||||
G4cout << " =====> S T O P " << G4endl;
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,"musrTabulatedElementField: Unknown field required!",false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SET UP STORAGE SPACE FOR THE TABLE
|
||||
int ix, iy, iz;
|
||||
if (fldDim==3) {
|
||||
G4cout << " The grid consists of [" << nx << " x " << ny << " x " << nz << "] x, y, z values" << G4endl;
|
||||
G4cout << " Field map length unit = " << lenUnit/mm<<" mm"<< G4endl;
|
||||
G4cout << " Field map normalisation factor = " << fieldNormalisation << G4endl;
|
||||
// Set up storage space for the table
|
||||
xField.resize( nx );
|
||||
yField.resize( nx );
|
||||
zField.resize( nx );
|
||||
for (ix=0; ix<nx; ix++) {
|
||||
xField[ix].resize(ny);
|
||||
yField[ix].resize(ny);
|
||||
zField[ix].resize(ny);
|
||||
for (iy=0; iy<ny; iy++) {
|
||||
xField[ix][iy].resize(nz);
|
||||
yField[ix][iy].resize(nz);
|
||||
zField[ix][iy].resize(nz);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fldDim==2) {
|
||||
G4cout << " The grid consists of [" << nx << " x " << nz << "] R, z values" << G4endl;
|
||||
G4cout << " Field map normalisation factor = " << fieldNormalisation << G4endl;
|
||||
G4cout << " Field map length unit = " << lenUnit << G4endl;
|
||||
if ((nx<2)||(nz<2)) {
|
||||
char eMessage[200];
|
||||
sprintf(eMessage,"musrTabulatedElementField(): Strange Field table! nx=%i, nz=%i",nx,nz);
|
||||
musrErrorMessage::GetInstance()->musrError(WARNING,eMessage,false);
|
||||
}
|
||||
// Set up storage space for the table
|
||||
xField2D.resize( nx );
|
||||
zField2D.resize( nx );
|
||||
for (ix=0; ix<nx; ix++) {
|
||||
xField2D[ix].resize(nz);
|
||||
zField2D[ix].resize(nz);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Read in the data
|
||||
double xval,yval,zval,bx,by,bz;
|
||||
double permeability; // Not used in this example.
|
||||
for (ix=0; ix<nx; ix++) {
|
||||
for (iy=0; iy<ny; iy++) {
|
||||
for (iz=0; iz<nz; iz++) {
|
||||
if ((strcmp(fieldTableType,"3DE")==0)||(strcmp(fieldTableType,"3DB")==0)) {
|
||||
if (boolMinimaAndMaximaDefinedInTheFile) {
|
||||
file >> bx >> by >> bz; // Read ONLY field values
|
||||
}
|
||||
else {
|
||||
file >> xval >> yval >> zval >> bx >> by >> bz;
|
||||
}
|
||||
}
|
||||
else if ((strcmp(fieldTableType,"3D")==0)||(strcmp(fieldTableType,"3DBOpera")==0)) {
|
||||
file >> xval >> yval >> zval >> bx >> by >> bz >> permeability;
|
||||
}
|
||||
else if ((strcmp(fieldTableType,"2DE")==0)||(strcmp(fieldTableType,"2DB")==0)||(strcmp(fieldTableType,"2DEf")==0)) {
|
||||
file >> xval >> zval >> bx >> bz;
|
||||
}
|
||||
else if ((strcmp(fieldTableType,"2D")==0)||(strcmp(fieldTableType,"2DBOpera")==0)) {
|
||||
file >> xval >> yval >> zval >> bx >> bz >> permeability;
|
||||
// G4cout<< xval <<" "<< yval <<" "<< zval <<" "<< bx <<" "<< bz <<G4endl;
|
||||
}
|
||||
else if (strcmp(fieldTableType,"2D_OperaXY")==0) {
|
||||
file >> xval >> zval >> yval >> bx >> bz >> permeability;
|
||||
}
|
||||
else {
|
||||
G4cout << " musrTabulatedElementField::musrTabulatedElementField: Undefined field required!"
|
||||
<< " ("<<fieldTableType<<")" << G4endl;
|
||||
G4cout << " =====> S T O P " << G4endl;
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,"musrTabulatedElementField: Undefined field required!",false);
|
||||
}
|
||||
|
||||
|
||||
if (fldDim==3) { // 3D field
|
||||
if ((!boolMinimaAndMaximaDefinedInTheFile) && ( ix==0 && iy==0 && iz==0 ) ) {
|
||||
minimumx = xval * lenUnit;
|
||||
minimumy = yval * lenUnit;
|
||||
minimumz = zval * lenUnit;
|
||||
}
|
||||
xField[ix][iy][iz] = bx*fieldNormalisation;
|
||||
yField[ix][iy][iz] = by*fieldNormalisation;
|
||||
zField[ix][iy][iz] = bz*fieldNormalisation;
|
||||
}
|
||||
else { // 2D field
|
||||
if ((!boolMinimaAndMaximaDefinedInTheFile) && ( ix==0 && iz==0 ) ) {
|
||||
minimumx = xval * lenUnit;
|
||||
minimumz = zval * lenUnit;
|
||||
}
|
||||
xField2D[ix][iz] = bx*fieldNormalisation;
|
||||
zField2D[ix][iz] = bz*fieldNormalisation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
|
||||
if (!boolMinimaAndMaximaDefinedInTheFile) {
|
||||
maximumx = xval * lenUnit;
|
||||
maximumz = zval * lenUnit;
|
||||
if (fldDim==3) maximumy = yval * lenUnit;
|
||||
}
|
||||
|
||||
G4cout << " ---> ... reading of the field map finished." << G4endl;
|
||||
|
||||
if (fldDim==3) G4cout<<" ---> Min values of x,y,z: ";
|
||||
else G4cout<<" ---> Min values of R,z: ";
|
||||
G4cout << minimumx/cm << ", ";
|
||||
if (fldDim==3) G4cout<< minimumy/cm << ", " ;
|
||||
G4cout << minimumz/cm << " cm "<<G4endl;
|
||||
if (fldDim==3) G4cout<<" ---> Max values of x,y,z: ";
|
||||
else G4cout<<" ---> Max values of R,z: ";
|
||||
G4cout << maximumx/cm << ", ";
|
||||
if (fldDim==3) G4cout<< maximumy/cm << ", " ;
|
||||
G4cout << maximumz/cm << " cm " << G4endl;
|
||||
|
||||
|
||||
// Should really check that the limits are not the wrong way around.
|
||||
G4bool reorderingDone = false;
|
||||
if (maximumx < minimumx) {Invert("x"); reorderingDone=true;}
|
||||
if (fldDim==3) {if (maximumy < minimumy) {Invert("y"); reorderingDone=true;} }
|
||||
if (maximumz < minimumz) {Invert("z"); reorderingDone=true;}
|
||||
|
||||
if (reorderingDone) {
|
||||
G4cout << "\n Reordering of the field grid was neccessary - after reordering:"<<G4endl;
|
||||
if (fldDim==3) G4cout<<" ---> Min values of x,y,z: ";
|
||||
else G4cout<<" ---> Min values of R,z: ";
|
||||
G4cout << minimumx/cm << ", ";
|
||||
if (fldDim==3) G4cout<< minimumy/cm << ", " ;
|
||||
G4cout << minimumz/cm << " cm "<<G4endl;
|
||||
if (fldDim==3) G4cout<<" ---> Max values of x,y,z: ";
|
||||
else G4cout<<" ---> Max values of R,z: ";
|
||||
G4cout << maximumx/cm << ", ";
|
||||
if (fldDim==3) G4cout<< maximumy/cm << ", " ;
|
||||
G4cout << maximumz/cm << " cm " << G4endl;
|
||||
}
|
||||
|
||||
dx = maximumx - minimumx;
|
||||
if (fldDim==3) dy = maximumy - minimumy;
|
||||
dz = maximumz - minimumz;
|
||||
if (fldDim==3) G4cout << "\n ---> Dif values x,y,z (range): ";
|
||||
else G4cout << "\n ---> Dif values R,z (range): ";
|
||||
G4cout << dx/cm << ", ";
|
||||
if (fldDim==3) G4cout << dy/cm << ", ";
|
||||
G4cout << dz/cm << " cm."<<G4endl;
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
|
||||
|
||||
// Set maximum width, height and lenght of the field - very important! This
|
||||
// dimensions are used to decide whether the "addFieldValue" method will be
|
||||
// called at all for a given elementField.
|
||||
if (fldDim==2) {
|
||||
maximumWidth = 2*dx;
|
||||
maximumHeight = 2*dx;
|
||||
if ( (strcmp(fieldTableType,"2D")==0)||(strcmp(fieldTableType,"2DBOpera")==0)||(strcmp(fieldTableType,"2D_OperaXY")) ) {
|
||||
maximumLength = 2*dz;
|
||||
}
|
||||
else maximumLength = dz;
|
||||
}
|
||||
else {
|
||||
maximumWidth = dx;
|
||||
maximumHeight = dy;
|
||||
maximumLength = dz;
|
||||
}
|
||||
}
|
||||
|
||||
void musrTabulatedElementField::addFieldValue(const G4double point[4],
|
||||
G4double *field ) const
|
||||
{
|
||||
// G4cout<<"musrTabulatedElementField::addFieldValue"<<G4endl;
|
||||
if (fldDim==2) addFieldValue2D(point,field);
|
||||
else addFieldValue3D(point,field);
|
||||
}
|
||||
|
||||
void musrTabulatedElementField::addFieldValue3D(const G4double point[4],
|
||||
G4double *field ) const
|
||||
{
|
||||
G4double B[3]; // Field value obtained from the field table
|
||||
|
||||
G4ThreeVector global(point[0],point[1],point[2]);
|
||||
G4ThreeVector local;
|
||||
|
||||
local = global2local.TransformPoint(global);
|
||||
|
||||
double x = local.x();
|
||||
double y = local.y();
|
||||
double z = local.z();
|
||||
|
||||
// G4cout<<"Global points= "<<point[0]<<", "<<point[1]<<", "<<point[2]<<", Local point= "<<x<<", "<<y<<", "<<z<<G4endl;
|
||||
|
||||
|
||||
// Check that the point is within the defined region
|
||||
if ( x>minimumx && x<maximumx &&
|
||||
y>minimumy && y<maximumy &&
|
||||
z>minimumz && z<maximumz ) {
|
||||
|
||||
// Position of given point within region, normalized to the range
|
||||
// [0,1]
|
||||
double xfraction = (x - minimumx) / dx;
|
||||
double yfraction = (y - minimumy) / dy;
|
||||
double zfraction = (z - minimumz) / dz;
|
||||
|
||||
// Need addresses of these to pass to modf below.
|
||||
// modf uses its second argument as an OUTPUT argument.
|
||||
double xdindex, ydindex, zdindex;
|
||||
|
||||
// Position of the point within the cuboid defined by the
|
||||
// nearest surrounding tabulated points
|
||||
double xlocal = ( modf(xfraction*(nx-1), &xdindex));
|
||||
double ylocal = ( modf(yfraction*(ny-1), &ydindex));
|
||||
double zlocal = ( modf(zfraction*(nz-1), &zdindex));
|
||||
|
||||
// The indices of the nearest tabulated point whose coordinates
|
||||
// are all less than those of the given point
|
||||
int xindex = static_cast<int>(xdindex);
|
||||
int yindex = static_cast<int>(ydindex);
|
||||
int zindex = static_cast<int>(zdindex);
|
||||
|
||||
//cks The following check is necessary - even though xindex and zindex should never be out of range,
|
||||
// it may happen (due to some rounding error ?). It is better to leave the check here.
|
||||
if ((xindex<0)||(xindex>(nx-2))) {
|
||||
std::cout<<"SERIOUS PROBLEM: xindex out of range! xindex="<<xindex<<" x="<<x<<" xfraction="<<xfraction<<std::endl;
|
||||
if (xindex<0) xindex=0;
|
||||
else xindex=nx-2;
|
||||
}
|
||||
if ((yindex<0)||(yindex>(ny-2))) {
|
||||
std::cout<<"SERIOUS PROBLEM: yindex out of range! yindex="<<yindex<<" y="<<y<<" yfraction="<<yfraction<<std::endl;
|
||||
if (yindex<0) yindex=0;
|
||||
else yindex=ny-2;
|
||||
}
|
||||
if ((zindex<0)||(zindex>(nz-2))) {
|
||||
std::cout<<"SERIOUS PROBLEM: zindex out of range! zindex="<<zindex<<" z="<<z<<" zfraction="<<zfraction<<std::endl;
|
||||
if (zindex<0) zindex=0;
|
||||
else zindex=nz-2;
|
||||
}
|
||||
|
||||
// Full 3-dimensional version
|
||||
B[0] =
|
||||
xField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
|
||||
xField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
|
||||
xField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
|
||||
xField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
|
||||
xField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
|
||||
xField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
|
||||
xField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
|
||||
xField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal ;
|
||||
B[1] =
|
||||
yField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
|
||||
yField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
|
||||
yField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
|
||||
yField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
|
||||
yField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
|
||||
yField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
|
||||
yField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
|
||||
yField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal ;
|
||||
B[2] =
|
||||
zField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
|
||||
zField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
|
||||
zField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
|
||||
zField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
|
||||
zField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
|
||||
zField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
|
||||
zField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
|
||||
zField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal ;
|
||||
|
||||
B[0] *= ffieldValue;
|
||||
B[1] *= ffieldValue;
|
||||
B[2] *= ffieldValue;
|
||||
|
||||
G4ThreeVector finalField(B[0],B[1],B[2]);
|
||||
finalField = global2local.Inverse().TransformAxis(finalField);
|
||||
|
||||
if (fldType == 'E') {
|
||||
field[3] += finalField.x();
|
||||
field[4] += finalField.y();
|
||||
field[5] += finalField.z();
|
||||
}
|
||||
else {
|
||||
field[0] += finalField.x();
|
||||
field[1] += finalField.y();
|
||||
field[2] += finalField.z();
|
||||
}
|
||||
}
|
||||
// G4cout<<"Kamil: Field: ("<<field[0]/tesla<<","<<field[1]/tesla<<","<<field[2]/tesla<<")"<<G4endl;
|
||||
|
||||
}
|
||||
|
||||
void musrTabulatedElementField::addFieldValue2D(const G4double point[4],
|
||||
G4double *field ) const
|
||||
{
|
||||
G4double B[3]; // Field value obtained from the field table
|
||||
|
||||
G4ThreeVector global(point[0],point[1],point[2]);
|
||||
G4ThreeVector local;
|
||||
|
||||
local = global2local.TransformPoint(global);
|
||||
|
||||
double x, z, z_sign;
|
||||
if ((strcmp(fieldTableType,"2D")==0)||(strcmp(fieldTableType,"2DBOpera")==0)||
|
||||
(strcmp(fieldTableType,"2D_OperaXY"))||(strcmp(fieldTableType,"2DEf")==0)) {
|
||||
// Field is defined in just positive range of z; i.e. it is expected to be "symmetric"
|
||||
// and the field for negative z is calculated from the positive z half.
|
||||
x = sqrt(local.x()*local.x()+local.y()*local.y());
|
||||
z = fabs(local.z());
|
||||
z_sign = (local.z()>0) ? 1.:-1.;
|
||||
}
|
||||
else {
|
||||
// Field is defined along the whole range of the z axis (i.e. asymmetric field is expected)
|
||||
x = sqrt(local.x()*local.x()+local.y()*local.y());
|
||||
z = local.z();
|
||||
z_sign = 1;
|
||||
}
|
||||
// Check that the point is within the defined region
|
||||
if ( x<maximumx && z<maximumz ) {
|
||||
// if (evNr>evNrKriz) std::cout<<"bol som tu"<<std::endl;
|
||||
|
||||
// Position of given point within region, normalized to the range
|
||||
// [0,1]
|
||||
double xfraction = (x - minimumx) / dx;
|
||||
double zfraction = (z - minimumz) / dz;
|
||||
|
||||
// Need addresses of these to pass to modf below.
|
||||
// modf uses its second argument as an OUTPUT argument.
|
||||
double xdindex, zdindex;
|
||||
|
||||
// Position of the point within the cuboid defined by the
|
||||
// nearest surrounding tabulated points
|
||||
double xlocal = ( modf(xfraction*(nx-1), &xdindex));
|
||||
double zlocal = ( modf(zfraction*(nz-1), &zdindex));
|
||||
|
||||
// The indices of the nearest tabulated point whose coordinates
|
||||
// are all less than those of the given point
|
||||
int xindex = static_cast<int>(xdindex);
|
||||
int zindex = static_cast<int>(zdindex);
|
||||
|
||||
//cks The following check is necessary - even though xindex and zindex should never be out of range,
|
||||
// it may happen (due to some rounding error ?). It is better to leave the check here.
|
||||
if ((xindex<0)||(xindex>(nx-2))) {
|
||||
std::cout<<"SERIOUS PROBLEM: xindex out of range! xindex="<<xindex<<" x="<<x<<" xfraction="<<xfraction<<std::endl;
|
||||
if (xindex<0) xindex=0;
|
||||
else xindex=nx-2;
|
||||
}
|
||||
if ((zindex<0)||(zindex>(nz-2))) {
|
||||
std::cout<<"SERIOUS PROBLEM: zindex out of range! zindex="<<zindex<<" z="<<z<<" zfraction="<<zfraction<<std::endl;
|
||||
if (zindex<0) zindex=0;
|
||||
else zindex=nz-2;
|
||||
}
|
||||
|
||||
// G4cout<<"xField2D["<<xindex<<"]["<<zindex<<"]="<<xField2D[xindex ][zindex ]<<G4endl;
|
||||
// G4cout<<"zField2D["<<xindex<<"]["<<zindex<<"]="<<zField2D[xindex ][zindex ]<<G4endl;
|
||||
|
||||
// Interpolate between the neighbouring points
|
||||
double Bfield_R =
|
||||
xField2D[xindex ][zindex ] * (1-xlocal) * (1-zlocal) +
|
||||
xField2D[xindex ][zindex+1] * (1-xlocal) * zlocal +
|
||||
xField2D[xindex+1][zindex ] * xlocal * (1-zlocal) +
|
||||
xField2D[xindex+1][zindex+1] * xlocal * zlocal ;
|
||||
B[0] = (x>0) ? Bfield_R * (local.x() /x) : 0.;
|
||||
B[1] = (x>0) ? Bfield_R * (local.y() /x) : 0.;
|
||||
B[2] =
|
||||
zField2D[xindex ][zindex ] * (1-xlocal) * (1-zlocal) +
|
||||
zField2D[xindex ][zindex+1] * (1-xlocal) * zlocal +
|
||||
zField2D[xindex+1][zindex ] * xlocal * (1-zlocal) +
|
||||
zField2D[xindex+1][zindex+1] * xlocal * zlocal ;
|
||||
|
||||
if (fldType == 'E') { // Electric field
|
||||
B[0] *= ffieldValue;
|
||||
B[1] *= ffieldValue;
|
||||
B[2] *= ffieldValue * z_sign;
|
||||
}
|
||||
else { // Magnetic field
|
||||
B[0] *= ffieldValue * z_sign;
|
||||
B[1] *= ffieldValue * z_sign;
|
||||
B[2] *= ffieldValue;
|
||||
}
|
||||
|
||||
G4ThreeVector finalField(B[0],B[1],B[2]);
|
||||
finalField = global2local.Inverse().TransformAxis(finalField);
|
||||
|
||||
if (fldType == 'E') {
|
||||
field[3] += finalField.x();
|
||||
field[4] += finalField.y();
|
||||
field[5] += finalField.z();
|
||||
}
|
||||
else {
|
||||
field[0] += finalField.x();
|
||||
field[1] += finalField.y();
|
||||
field[2] += finalField.z();
|
||||
}
|
||||
// G4cout<<"F= "<<field[0]<<" "<<field[1]<<" "<<field[2]<<" "<<field[3]<<" "<<field[4]<<" "<<field[5]<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4double musrTabulatedElementField::GetNominalFieldValue() {
|
||||
return ffieldValue;
|
||||
}
|
||||
|
||||
void musrTabulatedElementField::SetNominalFieldValue(G4double newFieldValue) {
|
||||
// // Rescale the magnetic field for a new value of the magnetic field
|
||||
ffieldValue=newFieldValue;
|
||||
G4cout<<"musrTabulatedElementField.cc: ffieldValue changed to="<< ffieldValue/fieUnit<<" "<<fUnit<<G4endl;
|
||||
}
|
||||
|
||||
void musrTabulatedElementField::Invert(const char* indexToInvert) {
|
||||
// This function inverts the indexes of the field table for a given axis (x or z).
|
||||
// It should be called in the case when the x or z coordinate in the initial
|
||||
// field table is ordered in the decreasing order.
|
||||
std::vector< std::vector< std::vector< double > > > xFieldTemp(xField);
|
||||
std::vector< std::vector< std::vector< double > > > yFieldTemp(yField);
|
||||
std::vector< std::vector< std::vector< double > > > zFieldTemp(zField);
|
||||
G4bool invertX=false;
|
||||
G4bool invertY=false;
|
||||
G4bool invertZ=false;
|
||||
|
||||
G4cout<<"Check that the musrTabulatedElementField::Invert() function works properly!"<<G4endl;
|
||||
G4cout<<"It has not been tested yet!"<<G4endl;
|
||||
|
||||
if (strcmp(indexToInvert,"x")==0) {invertX=true; std::swap(maximumx,minimumx);}
|
||||
if (strcmp(indexToInvert,"y")==0) {invertY=true; std::swap(maximumx,minimumx);}
|
||||
if (strcmp(indexToInvert,"z")==0) {invertZ=true; std::swap(maximumz,minimumz);}
|
||||
|
||||
for (int ix=0; ix<nx; ix++) {
|
||||
for (int iy=0; iy<ny; iy++) {
|
||||
for (int iz=0; iz<nz; iz++) {
|
||||
if (invertX) {
|
||||
xField[ix][iy][iz] = xFieldTemp[nx-1-ix][iy][iz];
|
||||
yField[ix][iy][iz] = yFieldTemp[nx-1-ix][iy][iz];
|
||||
zField[ix][iy][iz] = zFieldTemp[nx-1-ix][iy][iz];
|
||||
}
|
||||
else if(invertY) {
|
||||
xField[ix][iy][iz] = xFieldTemp[ix][ny-1-iy][iz];
|
||||
yField[ix][iy][iz] = yFieldTemp[ix][ny-1-iy][iz];
|
||||
zField[ix][iy][iz] = zFieldTemp[ix][ny-1-iy][iz];
|
||||
}
|
||||
else if(invertZ) {
|
||||
xField[ix][iy][iz] = xFieldTemp[ix][iy][nz-1-iz];
|
||||
yField[ix][iy][iz] = yFieldTemp[ix][iy][nz-1-iz];
|
||||
zField[ix][iy][iz] = zFieldTemp[ix][iy][nz-1-iz];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
91
src/musrUniformField.cc
Normal file
91
src/musrUniformField.cc
Normal file
@ -0,0 +1,91 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4GeometryManager.hh"
|
||||
#include "musrUniformField.hh"
|
||||
|
||||
musrUniformField::musrUniformField(G4double EMF[6], G4double half_X, G4double half_Y, G4double half_Z, G4LogicalVolume* lv, G4ThreeVector c)
|
||||
: F04ElementField(c, lv) {
|
||||
// EMF[6] ... constant vector of the field: 3 components magnetic + 3 components electric field
|
||||
// half_X, half_Y, half_Z ... half dimenstions of the box, within which the field is defined
|
||||
|
||||
for (int i = 0; i < 6; i++){
|
||||
EMfield[i] = EMF[i];
|
||||
}
|
||||
|
||||
fieldLength = 2.*half_Z;
|
||||
fieldWidth = 2.*half_X;
|
||||
fieldHeight = 2.*half_Y;
|
||||
|
||||
G4cout << "\n-----------------------------------------------------------"
|
||||
<< "\n Uniform electromagnetic field"
|
||||
<< G4endl;
|
||||
|
||||
G4String volName = lv->GetName().substr(4);
|
||||
G4cout << "\n ---> EM field in volume " << volName << " set to:" << G4endl;
|
||||
printf (" B = (%0.3g, %0.3g, %0.3g) T, E = (%0.3g, %0.3g, %0.3g) kV/mm\n",
|
||||
EMF[0]/tesla, EMF[1]/tesla, EMF[2]/tesla,
|
||||
EMF[3]/(kilovolt/mm), EMF[4]/(kilovolt/mm), EMF[5]/(kilovolt/mm));
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void musrUniformField::addFieldValue(const G4double point[4],
|
||||
G4double field[6]) const
|
||||
{
|
||||
G4ThreeVector global(point[0],point[1],point[2]);
|
||||
G4ThreeVector local;
|
||||
|
||||
local = global2local.TransformPoint(global);
|
||||
|
||||
if (isOutside(local)) return;
|
||||
|
||||
G4ThreeVector B(EMfield[0],EMfield[1],EMfield[2]);
|
||||
G4ThreeVector E(EMfield[3],EMfield[4],EMfield[5]);
|
||||
|
||||
B = global2local.Inverse().TransformAxis(B);
|
||||
E = global2local.Inverse().TransformAxis(E);
|
||||
|
||||
field[0] += B[0];
|
||||
field[1] += B[1];
|
||||
field[2] += B[2];
|
||||
|
||||
field[3] += E[0];
|
||||
field[4] += E[1];
|
||||
field[5] += E[2];
|
||||
|
||||
//printf (" EM field components: B = (%0.3g, %0.3g, %0.3g) T, E = (%0.3g, %0.3g, %0.3g) kV/mm\n",
|
||||
//field[0]/tesla, field[1]/tesla, field[2]/tesla,
|
||||
//field[3]/(kilovolt/mm), field[4]/(kilovolt/mm), field[5]/(kilovolt/mm));
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4double musrUniformField::GetNominalFieldValue() {
|
||||
G4double val = std::sqrt(EMfield[0]*EMfield[0]+EMfield[1]*EMfield[1]+EMfield[2]*EMfield[2]+
|
||||
EMfield[3]*EMfield[3]+EMfield[4]*EMfield[4]+EMfield[5]*EMfield[5]);
|
||||
return val;
|
||||
}
|
||||
|
||||
void musrUniformField::SetNominalFieldValue(G4double newFieldValue){
|
||||
EMfield[0] *= newFieldValue;
|
||||
EMfield[1] *= newFieldValue;
|
||||
EMfield[2] *= newFieldValue;
|
||||
EMfield[3] *= newFieldValue;
|
||||
EMfield[4] *= newFieldValue;
|
||||
EMfield[5] *= newFieldValue;
|
||||
}
|
||||
|
||||
G4bool musrUniformField::isOutside(G4ThreeVector& local) const
|
||||
{
|
||||
return (std::fabs(local.z()) > fieldLength/2.0 || std::fabs(local.x()) > fieldWidth/2.0 || std::fabs(local.y()) > fieldHeight/2.0);
|
||||
}
|
||||
|
||||
G4bool musrUniformField::isWithin(G4ThreeVector& local) const
|
||||
{
|
||||
return (std::fabs(local.z()) < fieldLength/2.0 && std::fabs(local.x()) < fieldWidth/2.0 && std::fabs(local.y()) < fieldHeight/2.0);
|
||||
}
|
107
src/yields.cc
Normal file
107
src/yields.cc
Normal file
@ -0,0 +1,107 @@
|
||||
// Geant4 simulation for MuSR
|
||||
// AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI
|
||||
// DATE : 2008-05
|
||||
//
|
||||
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
// Muonium yields as a function of initial mu+ energies.
|
||||
// The method GetYields is used by MuFormation.
|
||||
// Id : yields.cc, v 1.1
|
||||
// Author: Taofiq PARAISO, T. Shiroka
|
||||
// Date : 2007-12
|
||||
// Notes : First implemented in Fortran by A. Hofer
|
||||
// C++ conversion by T.K. Paraiso 04-2005
|
||||
// Slight modifications by T. Shiroka
|
||||
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||
|
||||
#include "yields.hh"
|
||||
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
The Muonium Yield function as well as the parameters are taken from:
|
||||
M. Gonin, R. Kallenbach, P. Bochsler: "Charge exchange of hydrogen atoms
|
||||
in carbon foils at 0.4 - 120 keV", Rev.Sci.Instrum. 65 (3), March 1994
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
Yields:: Yields(){;}
|
||||
Yields::~Yields(){;}
|
||||
|
||||
void Yields::GetYields(
|
||||
double E, // kinetic energy in keV
|
||||
double mass, // mass in keV/c**2
|
||||
double yvector[3]) // pointer to the yields table
|
||||
|
||||
{
|
||||
// Parameter NAMES for the muonium yield function
|
||||
double a_zero, a_minus;
|
||||
double k_Fermi, k_zero, k_minus;
|
||||
double two_k_Fermi;
|
||||
double k_Fermi_Quad, k_zero_Quad, k_minus_Quad;
|
||||
double vc_minus, vc_plus, v_Bohr, v_rel;
|
||||
|
||||
// Parameter VALUES for the muonium yield function
|
||||
a_zero = 0.953;
|
||||
a_minus = 0.029;
|
||||
k_Fermi = 1.178; // [v_Bohr]
|
||||
k_Fermi_Quad = k_Fermi * k_Fermi;
|
||||
two_k_Fermi = 2. * k_Fermi;
|
||||
k_zero = 0.991*k_Fermi; // [v_Bohr]
|
||||
k_zero_Quad = k_zero * k_zero;
|
||||
k_minus = 0.989*k_Fermi; // [v_Bohr]
|
||||
k_minus_Quad = k_minus * k_minus;
|
||||
vc_minus = 0.284;
|
||||
vc_plus = 0.193; // [v_Bohr]
|
||||
v_Bohr = 7.2974E-3; // [c]
|
||||
|
||||
|
||||
// std::cout<<"E = "<< E <<std::endl;
|
||||
|
||||
// Abort in case of negative energies ---------------------------
|
||||
if (E < 0)
|
||||
{
|
||||
std::cout<< "Error in method ''Yields'':" <<std::endl;
|
||||
std::cout<< "E = "<< E <<" < 0!" <<std::endl;
|
||||
std::cout<< "-> ABORTED!" <<std::endl;
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Definition of variables (aux_n are some auxiliary variables)
|
||||
// Calculate energy in (classical) terms of speed (in units of v_Bohr):
|
||||
|
||||
v_rel = sqrt(2.*E/mass)/ v_Bohr;
|
||||
|
||||
aux1 = v_rel*v_rel;
|
||||
aux2 = two_k_Fermi*v_rel;
|
||||
Q_zero = 1. + (k_zero_Quad - k_Fermi_Quad - aux1) / aux2;
|
||||
Q_minus = 1. + (k_minus_Quad - k_Fermi_Quad - aux1) / aux2;
|
||||
|
||||
aux1 = a_zero * Q_zero;
|
||||
aux2 = a_minus * Q_minus;
|
||||
aux3 = (1.-Q_zero)*(1.-Q_minus);
|
||||
D = aux1*(aux2 + (1.-Q_minus)) + aux3;
|
||||
|
||||
Yield_minus = aux1*aux2 / D;
|
||||
Yield_plus = aux3 / D;
|
||||
|
||||
Yield_minus = Yield_minus* exp(-vc_minus/v_rel);
|
||||
Yield_plus = Yield_plus * exp(-vc_plus /v_rel);
|
||||
|
||||
if(Yield_minus > exp(-vc_minus/v_rel)) Yield_minus=exp(-vc_minus/v_rel);
|
||||
if(Yield_plus > exp(-vc_plus/v_rel)) Yield_plus=exp(-vc_plus/v_rel);
|
||||
|
||||
Yield_zero = 1. - (Yield_minus + Yield_plus);
|
||||
|
||||
yvector[0]=Yield_plus;
|
||||
yvector[1]=Yield_zero;
|
||||
yvector[2]=Yield_minus;
|
||||
|
||||
// std::cout<<"Y+ : "<< Yield_plus << std::endl;
|
||||
// std::cout<<"Y0 : "<< Yield_zero << std::endl;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user