Skip to content

Commit

Permalink
add CaloPrototype_v03: simple calo stack using MultiSegmentation
Browse files Browse the repository at this point in the history
  • Loading branch information
danieljeans committed Aug 2, 2023
1 parent 8f5b7cf commit 02df810
Showing 1 changed file with 198 additions and 0 deletions.
198 changes: 198 additions & 0 deletions detector/CaloTB/CaloPrototype_v03.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
//====================================================================
// DD4hep Geometry driver for Sampling Calo BOX prototype
//--------------------------------------------------------------------
// S.Lu, DESY
// $Id: $
//
// Updated to use MultiSegmentation by D.Jeans (KEK) 08/2023
//====================================================================
#include "DD4hep/Printout.h"
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/TiledLayerGridXY.h"
#include "DDSegmentation/MultiSegmentation.h"
#include "LcgeoExceptions.h"

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

using dd4hep::BUILD_ENVELOPE;
using dd4hep::Box;
using dd4hep::DetElement;
using dd4hep::Detector;
using dd4hep::Layer;
using dd4hep::Layering;
using dd4hep::Material;
using dd4hep::PlacedVolume;
using dd4hep::Position;
using dd4hep::Readout;
using dd4hep::Ref_t;
using dd4hep::Segmentation;
using dd4hep::SensitiveDetector;
using dd4hep::Volume;
using dd4hep::_toString;

// 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) {

xml_det_t x_det = element;
string det_name = x_det.nameStr();
DetElement sdet( det_name,x_det.id() );

Layering layering(x_det);
xml_dim_t dim = x_det.dimensions();

// --- 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 ;

//-----------------------------------------------------------------------------------

Material air = theDetector.air();

sens.setType("calorimeter");

//====================================================================
//
// Read all the dimensions from compact.xml, user can update the value.
// Use them to build a calo box prototye.
//
//====================================================================

double Calo_dim_x = dim.x();
double Calo_dim_y = dim.y();
double Calo_dim_z = dim.z();

printout( dd4hep::DEBUG, "building SamplingCaloBoxPrototype_v03",
"Calo_dim_x : %e Calo_dim_y: %e Calo_dim_z: %e ",
Calo_dim_x, Calo_dim_y, Calo_dim_z) ;

Readout readout = sens.readout();
Segmentation seg = readout.segmentation();

dd4hep::DDSegmentation::MultiSegmentation* multiSeg = dynamic_cast< dd4hep::DDSegmentation::MultiSegmentation*>( seg.segmentation() ) ;
const dd4hep::DDSegmentation::MultiSegmentation::Segmentations segs = multiSeg->subSegmentations();
dd4hep::DDSegmentation::TiledLayerGridXY* layersubSeg;
std::map< int , dd4hep::DDSegmentation::TiledLayerGridXY* > layersubSegs;

for (size_t k=0; k<segs.size(); k++) {
dd4hep::DDSegmentation::MultiSegmentation::Entry entr = segs[k];
layersubSeg = dynamic_cast< dd4hep::DDSegmentation::TiledLayerGridXY*>( entr.segmentation );

// this probably implicitly assumes that key_min and key_max are the same
layersubSegs[ entr.key_min ] = layersubSeg;
}

//access the layer identifier via the segmentation.
//the layer identifier is defined in the compact xml file.
//and use it to set the volumeID layer value later here.
string identifierLayer = layersubSeg->fieldNameLayer(); // "K" or "layer" or "..."

//====================================================================
//
// general calculated parameters
//
//====================================================================

//calorimeter dimensions
double cal_hx = Calo_dim_x/2.0;
double cal_hy = Calo_dim_y/2.0;
double cal_hz = Calo_dim_z/2.0;

//====================================================================
//
// build sampling layers in the CaloBox
//
//====================================================================

int layer_num = 0;
int layerType = 0;

double layer_pos_z = - cal_hz;

for (xml_coll_t c(x_det, _U(layer)); c; ++c) {
xml_comp_t x_layer = c;
int repeat = x_layer.repeat(); // Get number of times to repeat this layer.
const Layer* lay = layering.layer(layer_num); // Get the layer from the layering engine.
double layer_thickness = lay->thickness();
string layer_type_name = _toString(layerType,"layerType%d");

// Loop over repeats for this layer.
for (int j = 0; j < repeat; j++) {
string layer_name = _toString(layer_num, "layer%d");
DetElement layer(layer_name, layer_num);

// Layer box & volume
Volume layer_vol(layer_type_name, Box(cal_hx, cal_hy, layer_thickness / 2), air);

// Create the slices (sublayers) within the layer.
double slice_pos_z = -(layer_thickness / 2);
int slice_number = 0;

for (xml_coll_t k(x_layer, _U(slice)); k; ++k) {
xml_comp_t x_slice = k;
string slice_name = _toString(slice_number, "slice%d");
double slice_thickness = x_slice.thickness();
Material slice_material = theDetector.material(x_slice.materialStr());
DetElement slice(layer, slice_name, slice_number);

slice_pos_z += slice_thickness / 2;
// Slice volume & box
Volume slice_vol(slice_name, Box(cal_hx, cal_hy, slice_thickness / 2), slice_material);

if (x_slice.isSensitive()) {
sens.setType("calorimeter");
slice_vol.setSensitiveDetector(sens);
}

// Set region, limitset, and vis.
slice_vol.setAttributes(theDetector, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
// slice PlacedVolume
PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol, Position(0, 0, slice_pos_z));
slice_phv.addPhysVolID("slice", slice_number);
slice.setPlacement(slice_phv);

// Increment Z position for next slice.
slice_pos_z += slice_thickness / 2;
// Increment slice number.
++slice_number;
}

// Set region, limitset, and vis.
layer_vol.setAttributes(theDetector, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());

// Layer position in Z within the stave.
layer_pos_z += layer_thickness / 2;
// Layer physical volume.
PlacedVolume layer_phv = envelope.placeVolume(layer_vol, Position(0, 0, layer_pos_z));
layer_phv.addPhysVolID(identifierLayer, layer_num);
layer.setPlacement(layer_phv);

// Increment the layer Z position.
layer_pos_z += layer_thickness / 2;
// Increment the layer number.
++layer_num;
}

++layerType;
}

return sdet;

}

DECLARE_DETELEMENT(CaloPrototype_v03, create_detector)

0 comments on commit 02df810

Please sign in to comment.