Skip to content
Snippets Groups Projects
ZeroDegreeCalorimeterHcal_geo.cpp 3.19 KiB
Newer Older
Jihee Kim's avatar
Jihee Kim committed
#include "DDRec/Surface.h"
#include "DDRec/DetectorData.h"
#include "DD4hep/OpticalSurfaces.h"
#include "DD4hep/DetFactoryHelper.h"
#include "DD4hep/Printout.h"
#include <XML/Helper.h>
#include <XML/Layering.h>
//////////////////////////////////////////////////
// Far Forward Ion Zero Degree Calorimeter - Hcal
//////////////////////////////////////////////////

using namespace std;
using namespace dd4hep;

static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens)
{
  xml_det_t  x_det      = e;
  string     detName    = x_det.nameStr();
  int        detID      = x_det.id();

  xml_dim_t  dim        = x_det.dimensions();
  double     Width      = dim.x();
  double     Length     = dim.z();
  
  xml_dim_t  pos        = x_det.position();
  double     z          = pos.z();
  xml_dim_t  rot        = x_det.rotation();

  Material   Vacuum     = desc.material("Vacuum");

  int layer_num = 1;
  int slice_num = 1;

  double totWidth = Layering(x_det).totalThickness();
  
  Box envelope (Width/2.0, Width/2.0, totWidth/2.0);
  Volume envelopeVol(detName+"_envelope", envelope, Vacuum); 
  envelopeVol.setVisAttributes(desc.visAttributes(x_det.visStr()));
  PlacedVolume pv;
	
  xml_comp_t x_layer = x_det.child(_U(layer));

  // Read layers
  for(xml_coll_t c(x_det,_U(layer)); c; ++c) {
    xml_comp_t x_layer = c;
    int repeat = x_layer.repeat();
    double layerWidth = 0;
    
    for(xml_coll_t l(x_layer,_U(slice)); l; ++l)
      layerWidth += xml_comp_t(l).thickness();

    // Loop over repeat#
    for(int i=0; i< repeat; i++) {
      double zlayer = z;
      string layer_name = detName + _toString(layer_num,"_layer%d");
      Volume layer_vol(layer_name,Box(Width/2.0, Width/2.0,layerWidth/2.0), Vacuum);

      // Loop over slices
      for(xml_coll_t l(x_layer,_U(slice)); l; ++l) {
	xml_comp_t x_slice = l;
	double w = x_slice.thickness();
	string slice_name = layer_name + _toString(slice_num,"slice%d");
	Material slice_mat = desc.material(x_slice.materialStr());		
	Volume slice_vol (slice_name,Box(Width/2.0, Width/2.0,w/2.0),slice_mat);
	
	if(x_slice.isSensitive()) {
	  sens.setType("calorimeter");
	  slice_vol.setSensitiveDetector(sens);
	}
	
	slice_vol.setAttributes(desc,x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
	pv = layer_vol.placeVolume(slice_vol, Transform3D(RotationZYX(0, 0, 0),Position(0.0,0.0,z-zlayer-layerWidth/2.0+w/2.0)));
	pv.addPhysVolID("slice", slice_num);
	z += w;
	++slice_num;
	}
			
      string layer_vis = dd4hep::getAttrOrDefault(x_layer, _Unicode(vis), "InvisibleWithDaughters");
      layer_vol.setAttributes(desc, x_layer.regionStr(), x_layer.limitsStr(), layer_vis);
      pv = envelopeVol.placeVolume(layer_vol, Transform3D(RotationZYX(0, 0, 0), Position(0,0,zlayer-pos.z()-totWidth/2.0+layerWidth/2.0)));
      pv.addPhysVolID("layer", layer_num);
      ++layer_num;
      }
  }
  
  DetElement   det(detName, detID);  
  Volume motherVol = desc.pickMotherVolume(det);
  Transform3D  tr(RotationZYX(rot.z(), -rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z() + totWidth/2.0));
  PlacedVolume phv = motherVol.placeVolume(envelopeVol, tr);
  phv.addPhysVolID("system", detID);
  det.setPlacement(phv);

  return det;
}
DECLARE_DETELEMENT(ffi_ZDC_HCAL, createDetector)