Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
CEPCSW
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dhb112358@mail.ustc.edu.cn
CEPCSW
Commits
332a75bf
Commit
332a75bf
authored
4 years ago
by
FU Chengdong
Browse files
Options
Downloads
Patches
Plain Diff
add Yoke05 from Mokka
parent
238ea508
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Detector/DetCEPCv4/src/calorimeter/Yoke05_Barrel.cpp
+429
-0
429 additions, 0 deletions
Detector/DetCEPCv4/src/calorimeter/Yoke05_Barrel.cpp
Detector/DetCEPCv4/src/calorimeter/Yoke05_Endcaps.cpp
+412
-0
412 additions, 0 deletions
Detector/DetCEPCv4/src/calorimeter/Yoke05_Endcaps.cpp
with
841 additions
and
0 deletions
Detector/DetCEPCv4/src/calorimeter/Yoke05_Barrel.cpp
0 → 100644
+
429
−
0
View file @
332a75bf
//====================================================================
// lcgeo - LC detector models in DD4hep
//--------------------------------------------------------------------
// DD4hep Geometry driver for YokeBarrel
// Ported from Mokka
//--------------------------------------------------------------------
// S.Lu, DESY
// $Id$
//====================================================================
// *********************************************************
// * Mokka *
// * -- A Detailed Geant 4 Simulation for the ILC -- *
// * *
// * polywww.in2p3.fr/geant4/tesla/www/mokka/mokka.html *
// *********************************************************
//
// $Id$
// $Name: $
//
// History:
// - first implementation P. Mora de Freitas (May 2001)
// - selectable symmetry, self-scaling, removed pole tips
// - Adrian Vogel, 2006-03-17
// - muon system plus
// instrumented pole tip back for TESLA models
// - Predrag Krstonosic , 2006-08-30
// - added barrelEndcapGap, gear parameters, made barrel
// and endcap same thickness, made plug insensitive,
// - F.Gaede, DESY 2008-10-04
//
#include
"DD4hep/DetFactoryHelper.h"
#include
"DD4hep/DetType.h"
#include
"XML/Layering.h"
#include
"TGeoTrd2.h"
#include
"XML/Utilities.h"
#include
"DDRec/DetectorData.h"
using
namespace
std
;
using
dd4hep
::
BUILD_ENVELOPE
;
using
dd4hep
::
Box
;
using
dd4hep
::
DetElement
;
using
dd4hep
::
DetType
;
using
dd4hep
::
Detector
;
using
dd4hep
::
Layering
;
using
dd4hep
::
Material
;
using
dd4hep
::
PlacedVolume
;
using
dd4hep
::
PolyhedraRegular
;
using
dd4hep
::
Position
;
using
dd4hep
::
Readout
;
using
dd4hep
::
Ref_t
;
using
dd4hep
::
Rotation3D
;
using
dd4hep
::
RotationZYX
;
using
dd4hep
::
Segmentation
;
using
dd4hep
::
SensitiveDetector
;
using
dd4hep
::
Transform3D
;
using
dd4hep
::
Volume
;
using
dd4hep
::
_toString
;
using
dd4hep
::
rec
::
LayeredCalorimeterData
;
#define VERBOSE 1
// workaround for DD4hep v00-14 (and older)
#ifndef DD4HEP_VERSION_GE
#define DD4HEP_VERSION_GE(a,b) 0
#endif
static
Ref_t
create_detector
(
Detector
&
theDetector
,
xml_h
element
,
SensitiveDetector
sens
)
{
static
double
tolerance
=
0e0
;
xml_det_t
x_det
=
element
;
string
det_name
=
x_det
.
nameStr
();
Layering
layering
(
element
);
xml_comp_t
x_dim
=
x_det
.
dimensions
();
int
nsides
=
x_dim
.
numsides
();
Material
air
=
theDetector
.
air
();
xml_comp_t
x_staves
=
x_det
.
staves
();
Material
yokeMaterial
=
theDetector
.
material
(
x_staves
.
materialStr
());
//unused: Material env_mat = theDetector.material(x_dim.materialStr());
xml_comp_t
env_pos
=
x_det
.
position
();
xml_comp_t
env_rot
=
x_det
.
rotation
();
Position
pos
(
env_pos
.
x
(),
env_pos
.
y
(),
env_pos
.
z
());
RotationZYX
rotZYX
(
env_rot
.
z
(),
env_rot
.
y
(),
env_rot
.
x
());
Transform3D
tr
(
rotZYX
,
pos
);
int
det_id
=
x_det
.
id
();
DetElement
sdet
(
det_name
,
det_id
);
// --- create an envelope volume and position it into the world ---------------------
Volume
envelope
=
dd4hep
::
xml
::
createPlacedEnvelope
(
theDetector
,
element
,
sdet
)
;
dd4hep
::
xml
::
setDetectorTypeFlag
(
element
,
sdet
)
;
if
(
theDetector
.
buildType
()
==
BUILD_ENVELOPE
)
return
sdet
;
//-----------------------------------------------------------------------------------
sens
.
setType
(
"calorimeter"
);
//====================================================================
//
// Read all the constant from ILD_o1_v05.xml
// Use them to build Yoke05Barrel
//
//====================================================================
double
Yoke_barrel_inner_radius
=
theDetector
.
constant
<
double
>
(
"Yoke_barrel_inner_radius"
);
//double Yoke_thickness = theDetector.constant<double>("Yoke_thickness");
//double Yoke_Barrel_Half_Z = theDetector.constant<double>("Yoke_Barrel_Half_Z");
double
Yoke_Z_start_endcaps
=
theDetector
.
constant
<
double
>
(
"Yoke_Z_start_endcaps"
);
//double Yoke_cells_size = theDetector.constant<double>("Yoke_cells_size");
//Database *db = new Database(env.GetDBName());
//db->exec("SELECT * FROM `yoke`;");
//db->getTuple();
////... Geometry parameters from the environment and from the database
//symmetry = db->fetchInt("symmetry");
//const G4double rInnerBarrel =
// env.GetParameterAsDouble("Yoke_barrel_inner_radius");
//const G4double rInnerEndcap =
// env.GetParameterAsDouble("Yoke_endcap_inner_radius");
//const G4double zStartEndcap =
// env.GetParameterAsDouble("Yoke_Z_start_endcaps");
//
//db->exec("SELECT * FROM `muon`;");
//db->getTuple();
//iron_thickness = db->fetchDouble("iron_thickness");
//G4double gap_thickness = db->fetchDouble("layer_thickness");
//number_of_layers = db->fetchInt("number_of_layers");
//G4double yokeBarrelEndcapGap = db->fetchInt("barrel_endcap_gap");
//G4double cell_dim_x = db->fetchDouble("cell_size");
//G4double cell_dim_z = db->fetchDouble("cell_size");
//G4double chamber_thickness = 10*mm;
double
yokeBarrelEndcapGap
=
2.5
;
// ?? theDetector.constant<double>("barrel_endcap_gap"); //25.0*mm
//====================================================================
//
// general calculated parameters
//
//====================================================================
//port from Mokka Yoke05, the following parameters used by Yoke05
int
symmetry
=
nsides
;
double
rInnerBarrel
=
Yoke_barrel_inner_radius
;
double
zStartEndcap
=
Yoke_Z_start_endcaps
;
// has been updated to 4072.0*mm by driver SCoil02
//TODO: put all magic numbers into ILD_o1_v05.xml file.
double
gap_thickness
=
4.0
;
double
iron_thickness
=
10.0
;
//10.0 cm
int
number_of_layers
=
10
;
//... Barrel parameters:
//... tolerance 1 mm
double
yokeBarrelThickness
=
gap_thickness
+
number_of_layers
*
(
iron_thickness
+
gap_thickness
)
+
3
*
(
5.6
*
iron_thickness
+
gap_thickness
)
+
0.1
;
// the tolerance 1 mm
double
rOuterBarrel
=
rInnerBarrel
+
yokeBarrelThickness
;
double
z_halfBarrel
=
zStartEndcap
-
yokeBarrelEndcapGap
;
// In this release the number of modules is fixed to 3
double
Yoke_Barrel_module_dim_z
=
2.0
*
(
zStartEndcap
-
yokeBarrelEndcapGap
)
/
3.0
;
//double Yoke_cell_dim_x = Yoke_cells_size;
//double Yoke_cell_dim_z = Yoke_Barrel_module_dim_z / floor (Yoke_Barrel_module_dim_z/Yoke_cell_dim_x);
cout
<<
" Build the yoke within this dimension "
<<
endl
;
cout
<<
" ...Yoke db: symmetry "
<<
symmetry
<<
endl
;
cout
<<
" ...Yoke db: rInnerBarrel "
<<
rInnerBarrel
<<
endl
;
cout
<<
" ...Yoke db: zStartEndcap "
<<
zStartEndcap
<<
endl
;
cout
<<
" ...Muon db: iron_thickness "
<<
iron_thickness
<<
endl
;
cout
<<
" ...Muon db: gap_thickness "
<<
gap_thickness
<<
endl
;
cout
<<
" ...Muon db: number_of_layers "
<<
number_of_layers
<<
endl
;
cout
<<
" ...Muon par: yokeBarrelThickness "
<<
yokeBarrelThickness
<<
endl
;
cout
<<
" ...Muon par: Barrel_half_z "
<<
z_halfBarrel
<<
endl
;
Readout
readout
=
sens
.
readout
();
Segmentation
seg
=
readout
.
segmentation
();
std
::
vector
<
double
>
cellSizeVector
=
seg
.
segmentation
()
->
cellDimensions
(
0
);
//Assume uniform cell sizes, provide dummy cellID
double
cell_sizeX
=
cellSizeVector
[
0
];
double
cell_sizeY
=
cellSizeVector
[
1
];
//========== fill data for reconstruction ============================
LayeredCalorimeterData
*
caloData
=
new
LayeredCalorimeterData
;
caloData
->
layoutType
=
LayeredCalorimeterData
::
BarrelLayout
;
caloData
->
inner_symmetry
=
symmetry
;
caloData
->
outer_symmetry
=
symmetry
;
caloData
->
phi0
=
0
;
// also hardcoded below
/// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
caloData
->
extent
[
0
]
=
rInnerBarrel
;
caloData
->
extent
[
1
]
=
rOuterBarrel
;
caloData
->
extent
[
2
]
=
0.
;
caloData
->
extent
[
3
]
=
z_halfBarrel
;
// ========= Create Yoke Barrel module ====================================
PolyhedraRegular
YokeBarrelSolid
(
symmetry
,
M_PI
/
2.0
-
M_PI
/
symmetry
,
rInnerBarrel
,
rOuterBarrel
,
Yoke_Barrel_module_dim_z
);
Volume
mod_vol
(
det_name
+
"_module"
,
YokeBarrelSolid
,
yokeMaterial
);
//Volume mod_vol(det_name+"_module", YokeBarrelSolid, air);
mod_vol
.
setVisAttributes
(
theDetector
.
visAttributes
(
x_det
.
visStr
()));
//====================================================================
// Build chamber volume
//====================================================================
//double gap_thickness = db->fetchDouble("layer_thickness");
//-------------------- start loop over Yoke layers ----------------------
// Loop over the sets of layer elements in the detector.
double
nRadiationLengths
=
0.
;
double
nInteractionLengths
=
0.
;
double
thickness_sum
=
0
;
int
l_num
=
1
;
for
(
xml_coll_t
li
(
x_det
,
_U
(
layer
));
li
;
++
li
)
{
xml_comp_t
x_layer
=
li
;
int
repeat
=
x_layer
.
repeat
();
// Loop over number of repeats for this layer.
for
(
int
i
=
0
;
i
<
repeat
;
i
++
)
{
//if(i>11) continue;
string
l_name
=
_toString
(
l_num
,
"layer%d"
);
//double l_thickness = layering.layer(l_num-1)->thickness(); // Layer's thickness.
double
l_thickness
=
layering
.
layer
(
i
)
->
thickness
();
// Layer's thickness.
//double gap_thickness = l_thickness;
//double iron_thickness = 10.0; //10.0 cm
double
radius_low
=
rInnerBarrel
+
0.05
+
i
*
gap_thickness
+
i
*
iron_thickness
;
//rInnerBarrel+ 0.5*mm + i*gap_thickness + i*iron_thickness;
//double radius_mid = radius_low+0.5*gap_thickness;
//double radius_sensitive = radius_mid;
if
(
i
>=
10
)
radius_low
=
rInnerBarrel
+
0.05
+
i
*
gap_thickness
+
(
i
+
(
i
-
10
)
*
4.6
)
*
iron_thickness
;
//{ radius_low =
// rInnerBarrel + 0.5*mm + i*gap_thickness
// + (i+(i-10)*4.6)*iron_thickness;
//radius_mid = radius_low+0.5*gap_thickness;
//radius_sensitive = radius_mid;
//}
//... safety margines of 0.1 mm for x,y of chambers
//double dx = radius_low*tan(Angle2)-0.1*mm;
//double dy = (zStartEndcap-yokeBarrelEndcapGap)/3.0-0.1*mm;
double
Angle2
=
M_PI
/
symmetry
;
double
dx
=
radius_low
*
tan
(
Angle2
)
-
0.01
;
double
dy
=
(
zStartEndcap
-
yokeBarrelEndcapGap
)
/
3.0
-
0.01
;
//Box ChamberSolid(dx,gap_thickness/2.,dy);
//Volume ChamberLog("muonSci",ChamberSolid,air);
LayeredCalorimeterData
::
Layer
caloLayer
;
caloLayer
.
cellSize0
=
cell_sizeX
;
caloLayer
.
cellSize1
=
cell_sizeY
;
Box
ChamberSolid
(
dx
,
l_thickness
/
2.0
,
dy
);
Volume
ChamberLog
(
det_name
+
"_"
+
l_name
,
ChamberSolid
,
air
);
DetElement
layer
(
l_name
,
det_id
);
ChamberLog
.
setVisAttributes
(
theDetector
.
visAttributes
(
x_layer
.
visStr
()));
// Loop over the sublayers or slices for this layer.
int
s_num
=
1
;
double
s_pos_y
=
-
(
l_thickness
/
2
);
//--------------------------------------------------------------------------------
// Build Layer, Sensitive Scintilator in the middle, and Air tolorance at two sides
//--------------------------------------------------------------------------------
double
radiator_thickness
=
0.05
;
// Yoke05 Barrel: No radiator before first sensitive layer.
if
(
i
>
0
)
radiator_thickness
=
gap_thickness
+
iron_thickness
-
l_thickness
;
if
(
i
>=
10
)
radiator_thickness
=
gap_thickness
+
5.6
*
iron_thickness
-
l_thickness
;
nRadiationLengths
=
radiator_thickness
/
(
yokeMaterial
.
radLength
());
nInteractionLengths
=
radiator_thickness
/
(
yokeMaterial
.
intLength
());
thickness_sum
=
radiator_thickness
;
for
(
xml_coll_t
si
(
x_layer
,
_U
(
slice
));
si
;
++
si
)
{
xml_comp_t
x_slice
=
si
;
string
s_name
=
_toString
(
s_num
,
"slice%d"
);
double
s_thickness
=
x_slice
.
thickness
();
Material
slice_material
=
theDetector
.
material
(
x_slice
.
materialStr
());
s_pos_y
+=
s_thickness
/
2.
;
double
slab_dim_x
=
dx
-
tolerance
;
double
slab_dim_y
=
s_thickness
/
2.
;
double
slab_dim_z
=
dy
-
tolerance
;
Box
s_box
(
slab_dim_x
,
slab_dim_y
,
slab_dim_z
);
Volume
s_vol
(
det_name
+
"_"
+
l_name
+
"_"
+
s_name
,
s_box
,
slice_material
);
DetElement
slice
(
layer
,
s_name
,
det_id
);
nRadiationLengths
+=
s_thickness
/
(
2.
*
slice_material
.
radLength
());
nInteractionLengths
+=
s_thickness
/
(
2.
*
slice_material
.
intLength
());
thickness_sum
+=
s_thickness
/
2
;
if
(
x_slice
.
isSensitive
()
)
{
s_vol
.
setSensitiveDetector
(
sens
);
std
::
cout
<<
" ...Barrel i, position: "
<<
i
<<
" "
<<
radius_low
+
l_thickness
/
2.0
+
s_pos_y
<<
std
::
endl
;
#if DD4HEP_VERSION_GE( 0, 15 )
//Store "inner" quantities
caloLayer
.
inner_nRadiationLengths
=
nRadiationLengths
;
caloLayer
.
inner_nInteractionLengths
=
nInteractionLengths
;
caloLayer
.
inner_thickness
=
thickness_sum
;
//Store scintillator thickness
caloLayer
.
sensitive_thickness
=
s_thickness
;
#endif
//Reset counters to measure "outside" quantitites
nRadiationLengths
=
0.
;
nInteractionLengths
=
0.
;
thickness_sum
=
0.
;
}
nRadiationLengths
+=
s_thickness
/
(
2.
*
slice_material
.
radLength
());
nInteractionLengths
+=
s_thickness
/
(
2.
*
slice_material
.
intLength
());
thickness_sum
+=
s_thickness
/
2
;
// Set region, limitset, and vis.
s_vol
.
setAttributes
(
theDetector
,
x_slice
.
regionStr
(),
x_slice
.
limitsStr
(),
x_slice
.
visStr
());
Position
s_pos
(
0
,
s_pos_y
,
0
);
// Position of the layer.
PlacedVolume
s_phv
=
ChamberLog
.
placeVolume
(
s_vol
,
s_pos
);
slice
.
setPlacement
(
s_phv
);
// Increment x position for next slice.
s_pos_y
+=
s_thickness
/
2.
;
++
s_num
;
}
#if DD4HEP_VERSION_GE( 0, 15 )
//Store "outer" quantities
caloLayer
.
outer_nRadiationLengths
=
nRadiationLengths
;
caloLayer
.
outer_nInteractionLengths
=
nInteractionLengths
;
caloLayer
.
outer_thickness
=
thickness_sum
;
#endif
++
l_num
;
double
phirot
=
0
;
for
(
int
j
=
0
;
j
<
symmetry
;
j
++
)
{
double
Y
=
radius_low
+
l_thickness
/
2.0
;
Position
xyzVec
(
-
Y
*
sin
(
phirot
),
Y
*
cos
(
phirot
),
0
);
RotationZYX
rot
(
phirot
,
0
,
0
);
Rotation3D
rot3D
(
rot
);
Transform3D
tran3D
(
rot3D
,
xyzVec
);
PlacedVolume
layer_phv
=
mod_vol
.
placeVolume
(
ChamberLog
,
tran3D
);
layer_phv
.
addPhysVolID
(
"layer"
,
l_num
).
addPhysVolID
(
"stave"
,
j
+
1
);
string
stave_name
=
_toString
(
j
+
1
,
"stave%d"
);
string
stave_layer_name
=
stave_name
+
_toString
(
l_num
,
"layer%d"
);
DetElement
stave
(
stave_layer_name
,
det_id
);;
stave
.
setPlacement
(
layer_phv
);
sdet
.
add
(
stave
);
phirot
-=
M_PI
/
symmetry
*
2.0
;
}
//-----------------------------------------------------------------------------------------
caloLayer
.
distance
=
radius_low
-
radiator_thickness
;
caloLayer
.
absorberThickness
=
radiator_thickness
;
caloData
->
layers
.
push_back
(
caloLayer
)
;
//-----------------------------------------------------------------------------------------
}
}
//====================================================================
// Place Yoke05 Barrel stave module into the world volume
//====================================================================
for
(
int
module_id
=
1
;
module_id
<
4
;
module_id
++
)
{
double
module_z_offset
=
(
module_id
-
2
)
*
Yoke_Barrel_module_dim_z
;
Position
mpos
(
0
,
0
,
module_z_offset
);
PlacedVolume
m_phv
=
envelope
.
placeVolume
(
mod_vol
,
mpos
);
m_phv
.
addPhysVolID
(
"module"
,
module_id
).
addPhysVolID
(
"system"
,
det_id
);
m_phv
.
addPhysVolID
(
"tower"
,
1
);
// Not used
string
m_name
=
_toString
(
module_id
,
"module%d"
);
DetElement
sd
(
m_name
,
det_id
);
sd
.
setPlacement
(
m_phv
);
sdet
.
add
(
sd
);
}
sdet
.
addExtension
<
LayeredCalorimeterData
>
(
caloData
)
;
return
sdet
;
}
DECLARE_DETELEMENT
(
Yoke05_Barrel
,
create_detector
)
This diff is collapsed.
Click to expand it.
Detector/DetCEPCv4/src/calorimeter/Yoke05_Endcaps.cpp
0 → 100644
+
412
−
0
View file @
332a75bf
//====================================================================
// lcgeo - LC detector models in DD4hep
//--------------------------------------------------------------------
// DD4hep Geometry driver for YokeEndcaps
// Ported from Mokka
//--------------------------------------------------------------------
// S.Lu, DESY
// $Id$
//====================================================================
// *********************************************************
// * Mokka *
// * -- A Detailed Geant 4 Simulation for the ILC -- *
// * *
// * polywww.in2p3.fr/geant4/tesla/www/mokka/mokka.html *
// *********************************************************
//
// $Id$
// $Name: $
//
// History:
// - first implementation P. Mora de Freitas (May 2001)
// - selectable symmetry, self-scaling, removed pole tips
// - Adrian Vogel, 2006-03-17
// - muon system plus
// instrumented pole tip back for TESLA models
// - Predrag Krstonosic , 2006-08-30
// - added barrelEndcapGap, gear parameters, made barrel
// and endcap same thickness, made plug insensitive,
// - F.Gaede, DESY 2008-10-04
//
#include
"DD4hep/DetFactoryHelper.h"
#include
"DD4hep/DetType.h"
#include
"XML/Layering.h"
#include
"XML/Utilities.h"
#include
"DDRec/DetectorData.h"
using
namespace
std
;
using
dd4hep
::
BUILD_ENVELOPE
;
using
dd4hep
::
DetElement
;
using
dd4hep
::
DetType
;
using
dd4hep
::
Detector
;
using
dd4hep
::
Layering
;
using
dd4hep
::
Material
;
using
dd4hep
::
PlacedVolume
;
using
dd4hep
::
PolyhedraRegular
;
using
dd4hep
::
Position
;
using
dd4hep
::
Readout
;
using
dd4hep
::
Ref_t
;
using
dd4hep
::
Rotation3D
;
using
dd4hep
::
RotationZYX
;
using
dd4hep
::
Segmentation
;
using
dd4hep
::
SensitiveDetector
;
using
dd4hep
::
Transform3D
;
using
dd4hep
::
Volume
;
using
dd4hep
::
_toString
;
using
dd4hep
::
rec
::
LayeredCalorimeterData
;
#define VERBOSE 1
// workaround for DD4hep v00-14 (and older)
#ifndef DD4HEP_VERSION_GE
#define DD4HEP_VERSION_GE(a,b) 0
#endif
static
Ref_t
create_detector
(
Detector
&
theDetector
,
xml_h
element
,
SensitiveDetector
sens
)
{
double
tolerance
=
0.1
;
xml_det_t
x_det
=
element
;
string
det_name
=
x_det
.
nameStr
();
Layering
layering
(
element
);
xml_comp_t
x_dim
=
x_det
.
dimensions
();
int
nsides
=
x_dim
.
numsides
();
Material
air
=
theDetector
.
air
();
//unused: Material vacuum = theDetector.vacuum();
Material
yokeMaterial
=
theDetector
.
material
(
x_det
.
materialStr
());;
int
det_id
=
x_det
.
id
();
DetElement
sdet
(
det_name
,
det_id
);
// --- create an envelope volume and position it into the world ---------------------
Volume
envelope
=
dd4hep
::
xml
::
createPlacedEnvelope
(
theDetector
,
element
,
sdet
)
;
dd4hep
::
xml
::
setDetectorTypeFlag
(
element
,
sdet
)
;
if
(
theDetector
.
buildType
()
==
BUILD_ENVELOPE
)
return
sdet
;
//-----------------------------------------------------------------------------------
sens
.
setType
(
"calorimeter"
);
//====================================================================
//
// Read all the constant from ILD_o1_v05.xml
// Use them to build Yoke05Endcaps
//
//====================================================================
double
Yoke_barrel_inner_radius
=
theDetector
.
constant
<
double
>
(
"Yoke_barrel_inner_radius"
);
double
Yoke_endcap_inner_radius
=
theDetector
.
constant
<
double
>
(
"Yoke_endcap_inner_radius"
);
double
Yoke_Z_start_endcaps
=
theDetector
.
constant
<
double
>
(
"Yoke_Z_start_endcaps"
);
double
HCAL_R_max
=
theDetector
.
constant
<
double
>
(
"Hcal_outer_radius"
);
//double Yoke_cells_size = theDetector.constant<double>("Yoke_cells_size");
double
yokeBarrelEndcapGap
=
2.5
;
// ?? theDetector.constant<double>("barrel_endcap_gap"); //25.0*mm
//====================================================================
//
// general calculated parameters
//
//====================================================================
//port from Mokka Yoke05, the following parameters used by Yoke05
int
symmetry
=
nsides
;
double
rInnerBarrel
=
Yoke_barrel_inner_radius
;
double
zStartEndcap
=
Yoke_Z_start_endcaps
;
// has been updated to 4072.0*mm by driver SCoil02
//TODO: put all magic numbers into ILD_o1_v05.xml file.
double
gap_thickness
=
4.0
;
double
iron_thickness
=
10.0
;
//10.0 cm
int
number_of_layers
=
10
;
//... Barrel parameters:
//... tolerance 1 mm
double
yokeBarrelThickness
=
gap_thickness
+
number_of_layers
*
(
iron_thickness
+
gap_thickness
)
+
3
*
(
5.6
*
iron_thickness
+
gap_thickness
)
+
0.1
;
// the tolerance 1 mm
double
yokeEndcapThickness
=
number_of_layers
*
(
iron_thickness
+
gap_thickness
)
+
2
*
(
5.6
*
iron_thickness
+
gap_thickness
);
// + gap_thickness;
double
rInnerEndcap
=
Yoke_endcap_inner_radius
;
double
rOuterEndcap
=
rInnerBarrel
+
yokeBarrelThickness
;
double
z_halfBarrel
=
zStartEndcap
-
yokeBarrelEndcapGap
;
//Port from Mokka:
// Endcap Thickness has no tolerance
// But the placement should shift_middle by -0.05 (0.5*mm) later
double
Yoke_Endcap_module_dim_z
=
yokeEndcapThickness
;
//double Yoke_cell_dim_x = rOuterEndcap*2.0 / floor (rOuterEndcap*2.0/Yoke_cells_size);
//double Yoke_cell_dim_y = Yoke_cell_dim_x;
cout
<<
" Build the yoke within this dimension "
<<
endl
;
cout
<<
" ...Yoke db: symmetry "
<<
symmetry
<<
endl
;
cout
<<
" ...Yoke db: rInnerEndcap "
<<
rInnerEndcap
<<
endl
;
cout
<<
" ...Yoke db: rOuterEndcap "
<<
rOuterEndcap
<<
endl
;
cout
<<
" ...Yoke db: zStartEndcap "
<<
zStartEndcap
<<
endl
;
cout
<<
" ...Muon db: iron_thickness "
<<
iron_thickness
<<
endl
;
cout
<<
" ...Muon db: gap_thickness "
<<
gap_thickness
<<
endl
;
cout
<<
" ...Muon db: number_of_layers "
<<
number_of_layers
<<
endl
;
cout
<<
" ...Muon par: yokeEndcapThickness "
<<
yokeEndcapThickness
<<
endl
;
cout
<<
" ...Muon par: Barrel_half_z "
<<
z_halfBarrel
<<
endl
;
Readout
readout
=
sens
.
readout
();
Segmentation
seg
=
readout
.
segmentation
();
std
::
vector
<
double
>
cellSizeVector
=
seg
.
segmentation
()
->
cellDimensions
(
0
);
//Assume uniform cell sizes, provide dummy cellID
double
cell_sizeX
=
cellSizeVector
[
0
];
double
cell_sizeY
=
cellSizeVector
[
1
];
//========== fill data for reconstruction ============================
LayeredCalorimeterData
*
caloData
=
new
LayeredCalorimeterData
;
caloData
->
layoutType
=
LayeredCalorimeterData
::
EndcapLayout
;
caloData
->
inner_symmetry
=
symmetry
;
caloData
->
outer_symmetry
=
symmetry
;
caloData
->
phi0
=
0
;
// hardcoded
/// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
caloData
->
extent
[
0
]
=
rInnerEndcap
;
caloData
->
extent
[
1
]
=
rOuterEndcap
;
caloData
->
extent
[
2
]
=
zStartEndcap
;
caloData
->
extent
[
3
]
=
zStartEndcap
+
Yoke_Endcap_module_dim_z
;
PolyhedraRegular
YokeEndcapSolid
(
symmetry
,
M_PI
/
symmetry
,
rInnerEndcap
,
rOuterEndcap
,
Yoke_Endcap_module_dim_z
);
Volume
mod_vol
(
det_name
+
"_module"
,
YokeEndcapSolid
,
yokeMaterial
);
mod_vol
.
setVisAttributes
(
theDetector
.
visAttributes
(
x_det
.
visStr
()));
//====================================================================
// Build chamber volume
//====================================================================
//double gap_thickness = db->fetchDouble("layer_thickness");
//-------------------- start loop over Yoke layers ----------------------
// Loop over the sets of layer elements in the detector.
double
nRadiationLengths
=
0.
;
double
nInteractionLengths
=
0.
;
double
thickness_sum
=
0
;
int
l_num
=
1
;
for
(
xml_coll_t
li
(
x_det
,
_U
(
layer
));
li
;
++
li
)
{
xml_comp_t
x_layer
=
li
;
int
repeat
=
x_layer
.
repeat
();
// Loop over number of repeats for this layer.
for
(
int
i
=
0
;
i
<
repeat
;
i
++
)
{
//if(i>11) continue;
string
l_name
=
_toString
(
l_num
,
"layer%d"
);
double
l_thickness
=
layering
.
layer
(
i
)
->
thickness
();
// Layer's thickness.
LayeredCalorimeterData
::
Layer
caloLayer
;
caloLayer
.
cellSize0
=
cell_sizeX
;
caloLayer
.
cellSize1
=
cell_sizeY
;
PolyhedraRegular
ChamberSolid
(
symmetry
,
M_PI
/
symmetry
,
rInnerEndcap
+
tolerance
,
rOuterEndcap
-
tolerance
,
l_thickness
);
Volume
ChamberLog
(
det_name
+
"_"
+
l_name
,
ChamberSolid
,
air
);
DetElement
layer
(
l_name
,
det_id
);
ChamberLog
.
setVisAttributes
(
theDetector
.
visAttributes
(
x_layer
.
visStr
()));
// Loop over the sublayers or slices for this layer.
int
s_num
=
1
;
double
s_pos_z
=
-
(
l_thickness
/
2
);
double
shift_middle
=
-
yokeEndcapThickness
/
2
-
0.05
//-0.5*mm since PolyhedraRegular from -Yoke_Endcap_module_dim_z/2 to Yoke_Endcap_module_dim_z/2
+
iron_thickness
*
(
i
+
1
)
+
(
i
+
0.5
)
*
gap_thickness
;
if
(
i
>=
10
){
shift_middle
=
-
yokeEndcapThickness
/
2
-
0.05
//0.5*mm
+
iron_thickness
*
(
i
+
1
+
(
i
-
9
)
*
4.6
)
+
(
i
+
0.5
)
*
gap_thickness
;
}
//--------------------------------------------------------------------------------
// Build Layer, Sensitive Scintilator in the middle, and Air tolorance at two sides
//--------------------------------------------------------------------------------
double
radiator_thickness
=
-
0.05
+
0.5
*
gap_thickness
+
iron_thickness
-
l_thickness
/
2.0
;
if
(
i
>
0
)
radiator_thickness
=
gap_thickness
+
iron_thickness
-
l_thickness
;
if
(
i
>=
10
)
radiator_thickness
=
gap_thickness
+
5.6
*
iron_thickness
-
l_thickness
;
nRadiationLengths
=
radiator_thickness
/
(
yokeMaterial
.
radLength
());
nInteractionLengths
=
radiator_thickness
/
(
yokeMaterial
.
intLength
());
thickness_sum
=
radiator_thickness
;
for
(
xml_coll_t
si
(
x_layer
,
_U
(
slice
));
si
;
++
si
)
{
xml_comp_t
x_slice
=
si
;
string
s_name
=
_toString
(
s_num
,
"slice%d"
);
double
s_thickness
=
x_slice
.
thickness
();
Material
slice_material
=
theDetector
.
material
(
x_slice
.
materialStr
());
s_pos_z
+=
s_thickness
/
2.
;
PolyhedraRegular
sliceSolid
(
symmetry
,
M_PI
/
symmetry
,
rInnerEndcap
+
tolerance
+
0.01
,
rOuterEndcap
-
tolerance
-
0.01
,
s_thickness
);
Volume
s_vol
(
det_name
+
"_"
+
l_name
+
"_"
+
s_name
,
sliceSolid
,
slice_material
);
DetElement
slice
(
layer
,
s_name
,
det_id
);
nRadiationLengths
+=
s_thickness
/
(
2.
*
slice_material
.
radLength
());
nInteractionLengths
+=
s_thickness
/
(
2.
*
slice_material
.
intLength
());
thickness_sum
+=
s_thickness
/
2
;
if
(
x_slice
.
isSensitive
()
)
{
s_vol
.
setSensitiveDetector
(
sens
);
cout
<<
" ...Endcap i, position: "
<<
i
<<
" "
<<
zStartEndcap
+
yokeEndcapThickness
/
2
+
shift_middle
+
l_thickness
/
2.0
+
s_pos_z
<<
endl
;
#if DD4HEP_VERSION_GE( 0, 15 )
//Store "inner" quantities
caloLayer
.
inner_nRadiationLengths
=
nRadiationLengths
;
caloLayer
.
inner_nInteractionLengths
=
nInteractionLengths
;
caloLayer
.
inner_thickness
=
thickness_sum
;
//Store scintillator thickness
caloLayer
.
sensitive_thickness
=
s_thickness
;
#endif
//Reset counters to measure "outside" quantitites
nRadiationLengths
=
0.
;
nInteractionLengths
=
0.
;
thickness_sum
=
0.
;
}
nRadiationLengths
+=
s_thickness
/
(
2.
*
slice_material
.
radLength
());
nInteractionLengths
+=
s_thickness
/
(
2.
*
slice_material
.
intLength
());
thickness_sum
+=
s_thickness
/
2
;
// Set region, limitset, and vis.
s_vol
.
setAttributes
(
theDetector
,
x_slice
.
regionStr
(),
x_slice
.
limitsStr
(),
x_slice
.
visStr
());
Position
s_pos
(
0
,
0
,
s_pos_z
);
// Position of the layer.
PlacedVolume
s_phv
=
ChamberLog
.
placeVolume
(
s_vol
,
s_pos
);
slice
.
setPlacement
(
s_phv
);
// Increment x position for next slice.
s_pos_z
+=
s_thickness
/
2.
;
++
s_num
;
}
#if DD4HEP_VERSION_GE( 0, 15 )
//Store "outer" quantities
caloLayer
.
outer_nRadiationLengths
=
nRadiationLengths
;
caloLayer
.
outer_nInteractionLengths
=
nInteractionLengths
;
caloLayer
.
outer_thickness
=
thickness_sum
;
#endif
++
l_num
;
Position
xyzVec
(
0
,
0
,
shift_middle
);
PlacedVolume
layer_phv
=
mod_vol
.
placeVolume
(
ChamberLog
,
xyzVec
);
layer_phv
.
addPhysVolID
(
"layer"
,
l_num
);
//string stave_name = "stave1";
string
stave_layer_name
=
"stave1"
+
_toString
(
l_num
,
"layer%d"
);
DetElement
stave
(
stave_layer_name
,
det_id
);;
stave
.
setPlacement
(
layer_phv
);
sdet
.
add
(
stave
);
//-----------------------------------------------------------------------------------------
caloLayer
.
distance
=
zStartEndcap
+
yokeEndcapThickness
/
2.0
+
shift_middle
-
caloLayer
.
inner_thickness
;
caloLayer
.
absorberThickness
=
radiator_thickness
;
caloData
->
layers
.
push_back
(
caloLayer
)
;
//-----------------------------------------------------------------------------------------
}
}
//====================================================================
// Check Yoke05 plug module
//====================================================================
bool
build_plug
=
false
;
double
HCAL_z
=
theDetector
.
constant
<
double
>
(
"HcalEndcap_max_z"
);;
double
HCAL_plug_gap
=
theDetector
.
constant
<
double
>
(
"Hcal_Yoke_plug_gap"
);
int
Hcal_endcap_outer_symmetry
=
theDetector
.
constant
<
int
>
(
"Hcal_endcap_outer_symmetry"
);
double
plug_thickness
=
zStartEndcap
-
HCAL_z
-
HCAL_plug_gap
;
double
rInnerPlug
=
Yoke_endcap_inner_radius
;
double
rOuterPlug
=
HCAL_R_max
*
cos
(
dd4hep
::
pi
/
16.
)
*
cos
(
dd4hep
::
pi
/
Hcal_endcap_outer_symmetry
);
double
Yoke_Plug_module_dim_z
=
plug_thickness
;
// Is there a space to build Yoke plug
if
(
Yoke_Plug_module_dim_z
>
0
)
{
build_plug
=
true
;
cout
<<
" ...Plug par: build_plug is true, there is space to build yoke plug"
<<
endl
;
cout
<<
" ...Plug par: HCAL_half_z "
<<
HCAL_z
<<
endl
;
cout
<<
" ...Plug par: HCAL_Plug_Gap "
<<
HCAL_plug_gap
<<
endl
;
cout
<<
" ...Plug par: Plug Thickness "
<<
plug_thickness
<<
endl
;
cout
<<
" ...Plug par: Plug Radius "
<<
rOuterPlug
<<
endl
;
}
//====================================================================
// Place Yoke05 Endcaps module into the world volume
//====================================================================
double
zEndcap
=
zStartEndcap
+
yokeEndcapThickness
/
2.0
+
0.1
;
// Need 0.1 (1.0*mm) according to the Mokka Yoke05 driver.
double
zPlug
=
zStartEndcap
-
plug_thickness
/
2.0
-
0.05
;
// Need 0.05 (0.5*mm) according to the Mokka Yoke05 driver.
for
(
int
module_num
=
0
;
module_num
<
2
;
module_num
++
)
{
int
module_id
=
(
module_num
==
0
)
?
0
:
6
;
double
this_module_z_offset
=
(
module_id
==
0
)
?
-
zEndcap
:
zEndcap
;
double
this_module_rotY
=
(
module_id
==
0
)
?
M_PI
:
0
;
Position
xyzVec
(
0
,
0
,
this_module_z_offset
);
RotationZYX
rot
(
0
,
this_module_rotY
,
0
);
Rotation3D
rot3D
(
rot
);
Transform3D
tran3D
(
rot3D
,
xyzVec
);
PlacedVolume
pv
=
envelope
.
placeVolume
(
mod_vol
,
tran3D
);
pv
.
addPhysVolID
(
"module"
,
module_id
);
// z: -/+ 0/6
string
m_name
=
_toString
(
module_id
,
"module%d"
);
DetElement
sd
(
m_name
,
det_id
);
sd
.
setPlacement
(
pv
);
sdet
.
add
(
sd
);
//====================================================================
// If build_plug is true, Place the plug module into the world volume
//====================================================================
if
(
build_plug
==
true
){
PolyhedraRegular
YokePlugSolid
(
symmetry
,
M_PI
/
symmetry
,
rInnerPlug
,
rOuterPlug
,
Yoke_Plug_module_dim_z
);
Volume
plug_vol
(
det_name
+
"_plug"
,
YokePlugSolid
,
yokeMaterial
);
plug_vol
.
setVisAttributes
(
theDetector
.
visAttributes
(
x_det
.
visStr
()));
double
this_plug_z_offset
=
(
module_id
==
0
)
?
-
zPlug
:
zPlug
;
Position
plug_pos
(
0
,
0
,
this_plug_z_offset
);
PlacedVolume
plug_phv
=
envelope
.
placeVolume
(
plug_vol
,
plug_pos
);
string
plug_name
=
_toString
(
module_id
,
"plug%d"
);
DetElement
plug
(
plug_name
,
det_id
);
plug
.
setPlacement
(
plug_phv
);
}
}
sdet
.
addExtension
<
LayeredCalorimeterData
>
(
caloData
)
;
return
sdet
;
}
DECLARE_DETELEMENT
(
Yoke05_Endcaps
,
create_detector
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment