Skip to content

Commit

Permalink
Added two CALICE testbeam drivers, which implemented by E.Brianne fo…
Browse files Browse the repository at this point in the history
…r TBModel2015.
  • Loading branch information
shaojunlu committed Feb 29, 2016
1 parent 36c0d85 commit bf7fd97
Show file tree
Hide file tree
Showing 2 changed files with 443 additions and 0 deletions.
184 changes: 184 additions & 0 deletions detector/CaloTB/TBecal4d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
//====================================================================
// DD4hep Geometry driver for TB ECAL 2015 prototype
//--------------------------------------------------------------------
// E.Brianne, DESY
// $Id: $
//====================================================================
#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 "LcgeoExceptions.h"

#include <iostream>
#include <vector>

using namespace std;
using namespace DD4hep;
using namespace DD4hep::Geometry;
using namespace lcgeo ;

// workaround for DD4hep v00-14 (and older)
#ifndef DD4HEP_VERSION_GE
#define DD4HEP_VERSION_GE(a,b) 0
#endif


static Ref_t create_detector(LCDD& lcdd, 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);

// --- create an envelope volume and position it into the world ---------------------

Volume envelope = XML::createPlacedEnvelope( lcdd, element , sdet ) ;

XML::setDetectorTypeFlag( element, sdet ) ;

if( lcdd.buildType() == BUILD_ENVELOPE ) return sdet ;

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

Material air = lcdd.air();

sens.setType("calorimeter");

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

double EBU_half_x = lcdd.constant<double>("EBU_dim_x")/2.0;
double EBU_half_y = lcdd.constant<double>("EBU_dim_y")/2.0;

int ECAL_ncell_x = lcdd.constant<int>("ECAL_ncell_x");
int ECAL_ncell_y = lcdd.constant<int>("ECAL_ncell_y");

int ECAL_nlayers = lcdd.constant<int>("ECAL_nlayers");
double Ecal_layer_thickness = lcdd.constant<double>("Ecal_layer_thickness");

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

std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0);
double cell_sizeX = cellSizeVector[0];
double cell_sizeY = cellSizeVector[1];

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

//calorimeter dimensions
double cal_hx = (double) (ECAL_ncell_x * cell_sizeX)/2.;
double cal_hy = (double) (ECAL_ncell_y * cell_sizeY)/2.;
double cal_hz = (double) (Ecal_layer_thickness * ECAL_nlayers)/2;

//====================================================================
//
// Chambers 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*4, cal_hy*8, 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 = lcdd.material(x_slice.materialStr());

slice_pos_z += slice_thickness / 2;

//Case of absorber make it bigger than the actual layer (*4 for EBU)
if(slice_number == 0)
{
// Slice volume & box
Volume slice_vol(slice_name, Box(cal_hx*4, cal_hy*8, slice_thickness / 2), slice_material);

// Set region, limitset, and vis.
slice_vol.setAttributes(lcdd, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
// slice PlacedVolume
layer_vol.placeVolume(slice_vol, Position(0, 0, slice_pos_z));
}
else
{
// 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(lcdd, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
// slice PlacedVolume
layer_vol.placeVolume(slice_vol, Position(0, 0, slice_pos_z));
}

// 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(lcdd, 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("layer", layer_num);
layer_phv.addPhysVolID("K", 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(TBecal4d, create_detector)
Loading

0 comments on commit bf7fd97

Please sign in to comment.