Newer
Older
//==========================================================================
// AIDA Detector description implementation
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author : M.Frank
//
//==========================================================================
//
// Specialized generic detector constructor
//==========================================================================
#include "DD4hep/DetFactoryHelper.h"
#include "Acts/Plugins/DD4hep/ActsExtension.hpp"
#include "Acts/Plugins/DD4hep/ConvertDD4hepMaterial.hpp"
using namespace std;
using namespace dd4hep;
using namespace dd4hep::detail;
static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)
{
xml_det_t x_det = e;
Material air = description.air();
string det_name = x_det.nameStr();
bool reflect = x_det.reflect();
DetElement sdet(det_name, x_det.id());
Assembly assembly(det_name);
PlacedVolume pv;
int l_num = 0;
xml::Component pos = x_det.position();
Acts::ActsExtension* detWorldExt = new Acts::ActsExtension();
detWorldExt->addType("endcap", "detector");
sdet.addExtension<Acts::ActsExtension>(detWorldExt);
for (xml_coll_t i(x_det, _U(layer)); i; ++i, ++l_num) {
xml_comp_t x_layer = i;
string l_nam = det_name + _toString(l_num, "_layer%d");
double zmin = x_layer.inner_z();
double rmin = x_layer.inner_r();
double rmax = x_layer.outer_r();
double z = zmin;
double layerWidth = 0.;
int s_num = 0;
for (xml_coll_t j(x_layer, _U(slice)); j; ++j) {
double thickness = xml_comp_t(j).thickness();
layerWidth += thickness;
}
Tube l_tub(rmin, rmax, layerWidth/2.0, 2 * M_PI);
Volume l_vol(l_nam, l_tub, air);
l_vol.setVisAttributes(description, x_layer.visStr());
if (!reflect) {
layer = DetElement(sdet, l_nam + "_pos", l_num);
layer_pv = assembly.placeVolume(l_vol, Position(0, 0, zmin + layerWidth / 2.));
layer_pv.addPhysVolID("barrel", 3).addPhysVolID("layer", l_num);
layer.setPlacement(layer_pv);
Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
layerExtension->addType("sensitive disk", "layer");
//layerExtension->addType("axes", "definitions", "XzY");
// need all four of these or else it is ignored.
//layerExtension->addValue(0, "r_min", "envelope");
//layerExtension->addValue(0, "r_max", "envelope");
//layerExtension->addValue(0, "z_min", "envelope");
//layerExtension->addValue(0, "z_max", "envelope");
// layerExtension->addType("axes", "definitions", "XZY");
layer.addExtension<Acts::ActsExtension>(layerExtension);
} else {
layer = DetElement(sdet, l_nam + "_neg", l_num);
layer_pv = assembly.placeVolume(l_vol, Transform3D(RotationY(M_PI), Position(0, 0, -zmin - layerWidth / 2)));
layer_pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_num);
layer.setPlacement(layer_pv);
// DetElement layerR = layer.clone(l_nam+"_neg");
// sdet.add(layerR.setPlacement(pv));
Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
layerExtension->addType("sensitive disk", "layer");
//layerExtension->addValue(0, "r_min", "envelope");
//layerExtension->addValue(0, "r_max", "envelope");
//layerExtension->addValue(0, "z_min", "envelope");
//layerExtension->addValue(0, "z_max", "envelope");
layer.addExtension<Acts::ActsExtension>(layerExtension);
double tot_thickness = -layerWidth / 2.0;
for (xml_coll_t j(x_layer, _U(slice)); j; ++j, ++s_num) {
double thick = x_slice.thickness();
Material mat = description.material(x_slice.materialStr());
string s_nam = l_nam + _toString(s_num, "_slice%d");
Volume s_vol(s_nam, Tube(rmin, rmax, thick/2.0), mat);
if(!reflect){
s_nam += "_pos";
} else {
s_nam += "_neg";
}
DetElement slice_de(layer, s_nam , s_num);
if (x_slice.isSensitive()) {
sens.setType("tracker");
s_vol.setSensitiveDetector(sens);
Acts::ActsExtension* sensorExtension = new Acts::ActsExtension();
//sensorExtension->addType("sensor", "detector");
slice_de.addExtension<Acts::ActsExtension>(sensorExtension);
s_vol.setAttributes(description, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
pv = l_vol.placeVolume(s_vol, Position(0, 0, tot_thickness + thick / 2));
pv.addPhysVolID("slice", s_num);
tot_thickness = tot_thickness + thick;
if (x_det.hasAttr(_U(combineHits))) {
sdet.setCombineHits(x_det.attr<bool>(_U(combineHits)), sens);
pv = description.pickMotherVolume(sdet).placeVolume(assembly, Position(pos.x(), pos.y(), pos.z()));
pv.addPhysVolID("system", x_det.id()); // Set the subdetector system ID.
sdet.setPlacement(pv);
return sdet;
}
DECLARE_DETELEMENT(athena_SimpleDiskTracker, create_detector)
DECLARE_DETELEMENT(ref_DiskTracker, create_detector)
DECLARE_DETELEMENT(ref_SolenoidEndcap, create_detector)