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"
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;
string det_name = x_det.nameStr();
Material air = description.air();
DetElement sdet (det_name,x_det.id());
Assembly assembly (det_name+"_assembly");
PlacedVolume pv;
int n = 0;
xml::Component pos = x_det.position();
for(xml_coll_t i(x_det,_U(layer)); i; ++i, ++n) {
xml_comp_t x_layer = i;
string l_name = det_name+_toString(n,"_layer%d");
double outer_z = x_layer.outer_z();
double rmin = x_layer.inner_r();
double r = rmin;
DetElement layer(sdet,_toString(n,"layer%d"),x_layer.id());
Tube l_tub (rmin,2*rmin,outer_z);
Volume l_vol(l_name,l_tub,air);
int im = 0;
for(xml_coll_t j(x_layer,_U(slice)); j; ++j, ++im) {
// If slices are only given a thickness attribute, they are radially concentric slices
// If slices are given an inner_z attribute, they are longitudinal slices with equal rmin
xml_comp_t x_slice = j;
Material mat = description.material(x_slice.materialStr());
string s_name= l_name+_toString(im,"_slice%d");
double thickness = x_slice.thickness();
double s_outer_z = dd4hep::getAttrOrDefault(x_slice, _Unicode(outer_z), outer_z);
double s_inner_z = dd4hep::getAttrOrDefault(x_slice, _Unicode(inner_z), 0.0*dd4hep::cm);
Tube s_tub(r,r+thickness,(s_inner_z > 0? 0.5*(s_outer_z-s_inner_z): s_outer_z),2*M_PI);
Volume s_vol(s_name, s_tub, mat);
if ( x_slice.isSensitive() ) {
sens.setType("tracker");
s_vol.setSensitiveDetector(sens);
}
// Set Attributes
s_vol.setAttributes(description,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
if (s_inner_z > 0) {
// Place off-center volumes twice
Position s_pos(0, 0, 0.5*(s_outer_z+s_inner_z));
pv = l_vol.placeVolume(s_vol, -s_pos);
pv = l_vol.placeVolume(s_vol, +s_pos);
} else {
r += thickness;
pv = l_vol.placeVolume(s_vol);
}
// Slices have no extra id. Take the ID of the layer!
pv.addPhysVolID("slice",im);
}
l_tub.setDimensions(rmin,r,outer_z);
//cout << l_name << " " << rmin << " " << r << " " << z << endl;
l_vol.setVisAttributes(description,x_layer.visStr());
pv = assembly.placeVolume(l_vol);
pv.addPhysVolID("layer",n);
layer.setPlacement(pv);
}
if ( x_det.hasAttr(_U(combineHits)) ) {
sdet.setCombineHits(x_det.combineHits(),sens);
}
pv = description.pickMotherVolume(sdet).placeVolume(assembly,Position(pos.x(),pos.y(),pos.z()));
pv.addPhysVolID("system",sdet.id()).addPhysVolID("barrel",0);
sdet.setPlacement(pv);
return sdet;
}
DECLARE_DETELEMENT(athena_SolenoidCoil,create_detector)