Beispiel #1
0
/*
	ErrorMsg
*/
void __cdecl ErrorMsg(const char* fmt, ...)
{
	static FILE*	pFile = NULL;
	DWORD			dwWritten;
	char			buf[5000];
	char			buf2[5000];
	va_list 		va;

	va_start(va, fmt);

	vsprintf(buf, fmt, va);

	MessageBox(GetActiveWindow(), _Unicode(buf), TEXT_MAMEUINAME, MB_OK | MB_ICONERROR);

	strcpy(buf2, MAMEUINAME ": ");
	strcat(buf2,buf);
	strcat(buf2, "\n");

	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), _Unicode(buf2), strlen(buf2), &dwWritten, NULL);

	if (pFile == NULL)
		pFile = fopen("debug.txt", "wt");

	if (pFile != NULL)
	{
		fprintf(pFile, "%s", buf2);
		fflush(pFile);
	}

	va_end(va);
}
Beispiel #2
0
double getAttrValueWithFallback(const DD4hep::XML::Component& node, const std::string& attrName,
                                const double& defaultValue) {
  if (node.hasAttr(_Unicode(attrName.c_str()))) {
    return node.attr<double>(attrName.c_str());
  } else {
    return defaultValue;
  }
}
/**
  Simple cone using dimensions to be used to define cone composed of 1 single material
  @author Clement Helsens
**/
static DD4hep::Geometry::Ref_t
createSimpleCone(DD4hep::Geometry::LCDD& lcdd, xml_h e, DD4hep::Geometry::SensitiveDetector sensDet) {
  xml_det_t x_det = e;
  std::string name = x_det.nameStr();
  DD4hep::Geometry::DetElement coneDet(name, x_det.id());

  DD4hep::Geometry::Volume experimentalHall = lcdd.pickMotherVolume(coneDet);

  xml_comp_t coneDim(x_det.child(_U(dimensions)));
  DD4hep::Geometry::Cone cone(coneDim.dz(), coneDim.rmin1(), coneDim.rmax1(), coneDim.rmin2(), coneDim.rmax2());

  DD4hep::Geometry::Volume coneVol(x_det.nameStr() + "_SimpleCone", cone, lcdd.material(coneDim.materialStr()));

  if (x_det.isSensitive()) {
    DD4hep::XML::Dimension sdType(x_det.child(_U(sensitive)));
    coneVol.setSensitiveDetector(sensDet);
    sensDet.setType(sdType.typeStr());  
  }

  DD4hep::Geometry::PlacedVolume conePhys;

  double zoff = coneDim.z_offset();
  if (fabs(zoff) > 0.000000000001) {
    double reflectionAngle = 0.;
    if (coneDim.hasAttr(_Unicode(reflect))) {
      if (coneDim.reflect()) {
        reflectionAngle = M_PI;
        }
    }
    DD4hep::Geometry::Position trans(0., 0., zoff);
    conePhys =
        experimentalHall.placeVolume(coneVol, DD4hep::Geometry::Transform3D(DD4hep::Geometry::RotationX(reflectionAngle), trans));
  } else
    conePhys = experimentalHall.placeVolume(coneVol);

  conePhys.addPhysVolID("system", x_det.id());

  coneDet.setPlacement(conePhys);

  coneDet.setVisAttributes(lcdd, x_det.visStr(), coneVol);
  return coneDet;
}
static DD4hep::Geometry::Ref_t createTkLayoutTrackerBarrel(DD4hep::Geometry::LCDD& lcdd,
                                                           DD4hep::XML::Handle_t xmlElement,
                                                           DD4hep::Geometry::SensitiveDetector sensDet) {
  // shorthands
  DD4hep::XML::DetElement xmlDet = static_cast<DD4hep::XML::DetElement>(xmlElement);
  Dimension dimensions(xmlDet.dimensions());
  // get sensitive detector type from xml
  DD4hep::XML::Dimension sdTyp = xmlElement.child(_Unicode(sensitive));
  // sensitive detector used for all sensitive parts of this detector
  sensDet.setType(sdTyp.typeStr());

  // definition of top volume
  // has min/max dimensions of tracker for visualization etc.
  std::string detectorName = xmlDet.nameStr();
  DetElement topDetElement(detectorName, xmlDet.id());
  Acts::ActsExtension::Config barrelConfig;
  barrelConfig.isBarrel = true;
  // detElement owns extension
  Acts::ActsExtension* detWorldExt = new Acts::ActsExtension(barrelConfig);
  topDetElement.addExtension<Acts::IActsExtension>(detWorldExt);
  DD4hep::Geometry::Tube topVolumeShape(
      dimensions.rmin(), dimensions.rmax(), (dimensions.zmax() - dimensions.zmin()) * 0.5);
  Volume topVolume(detectorName, topVolumeShape, lcdd.air());
  topVolume.setVisAttributes(lcdd.invisible());

  // counts all layers - incremented in the inner loop over repeat - tags
  unsigned int layerCounter = 0;
  double integratedModuleComponentThickness = 0;
  double phi = 0;
  // loop over 'layer' nodes in xml
  DD4hep::XML::Component xLayers = xmlElement.child(_Unicode(layers));
  for (DD4hep::XML::Collection_t xLayerColl(xLayers, _U(layer)); nullptr != xLayerColl; ++xLayerColl) {
    DD4hep::XML::Component xLayer = static_cast<DD4hep::XML::Component>(xLayerColl);
    DD4hep::XML::Component xRods = xLayer.child("rods");
    DD4hep::XML::Component xRodEven = xRods.child("rodOdd");
    DD4hep::XML::Component xRodOdd = xRods.child("rodEven");
    DD4hep::XML::Component xModulesEven = xRodEven.child("modules");
    DD4hep::XML::Component xModulePropertiesOdd = xRodOdd.child("moduleProperties");
    DD4hep::XML::Component xModulesOdd = xRodOdd.child("modules");
    DD4hep::Geometry::Tube layerShape(xLayer.rmin(), xLayer.rmax(), dimensions.zmax());
    Volume layerVolume("layer", layerShape, lcdd.material("Air"));
    layerVolume.setVisAttributes(lcdd.invisible());
    PlacedVolume placedLayerVolume = topVolume.placeVolume(layerVolume);
    placedLayerVolume.addPhysVolID("layer", layerCounter);
    DetElement lay_det(topDetElement, "layer" + std::to_string(layerCounter), layerCounter);
    Acts::ActsExtension::Config layConfig;
    layConfig.isLayer = true;
    // the local coordinate systems of modules in dd4hep and acts differ
    // see http://acts.web.cern.ch/ACTS/latest/doc/group__DD4hepPlugins.html
    layConfig.axes = "XzY"; // correct translation of local x axis in dd4hep to local x axis in acts
    // detElement owns extension
    Acts::ActsExtension* layerExtension = new Acts::ActsExtension(layConfig);
    lay_det.addExtension<Acts::IActsExtension>(layerExtension);
    lay_det.setPlacement(placedLayerVolume);
    DD4hep::XML::Component xModuleComponentsOdd = xModulePropertiesOdd.child("components");
    integratedModuleComponentThickness = 0;
    int moduleCounter = 0;
    Volume moduleVolume;
    for (DD4hep::XML::Collection_t xModuleComponentOddColl(xModuleComponentsOdd, _U(component));
         nullptr != xModuleComponentOddColl;
         ++xModuleComponentOddColl) {
      DD4hep::XML::Component xModuleComponentOdd = static_cast<DD4hep::XML::Component>(xModuleComponentOddColl);
      moduleVolume = Volume("module",
                            DD4hep::Geometry::Box(0.5 * xModulePropertiesOdd.attr<double>("modWidth"),
                                                  0.5 * xModuleComponentOdd.thickness(),
                                                  0.5 * xModulePropertiesOdd.attr<double>("modLength")),
                            lcdd.material(xModuleComponentOdd.materialStr()));
      unsigned int nPhi = xRods.repeat();
      DD4hep::XML::Handle_t currentComp;
      for (unsigned int phiIndex = 0; phiIndex < nPhi; ++phiIndex) {
        double lX = 0;
        double lY = 0;
        double lZ = 0;
        if (0 == phiIndex % 2) {
          phi = 2 * M_PI * static_cast<double>(phiIndex) / static_cast<double>(nPhi);
          currentComp = xModulesEven;
        } else {
          currentComp = xModulesOdd;
        }
        for (DD4hep::XML::Collection_t xModuleColl(currentComp, _U(module)); nullptr != xModuleColl; ++xModuleColl) {
          DD4hep::XML::Component xModule = static_cast<DD4hep::XML::Component>(xModuleColl);
          double currentPhi = atan2(xModule.Y(), xModule.X());
          double componentOffset =  integratedModuleComponentThickness - 0.5 * xModulePropertiesOdd.attr<double>("modThickness") + 0.5 * xModuleComponentOdd.thickness();
          lX = xModule.X() + cos(currentPhi) * componentOffset;
          lY = xModule.Y() + sin(currentPhi) * componentOffset;
          lZ = xModule.Z();
          DD4hep::Geometry::Translation3D moduleOffset(lX, lY, lZ);
          DD4hep::Geometry::Transform3D lTrafo(DD4hep::Geometry::RotationZ(atan2(lY,  lX) + 0.5 * M_PI), moduleOffset);
          DD4hep::Geometry::RotationZ lRotation(phi);
          PlacedVolume placedModuleVolume = layerVolume.placeVolume(moduleVolume, lRotation * lTrafo);
          if (xModuleComponentOdd.isSensitive()) {
            placedModuleVolume.addPhysVolID("module", moduleCounter);
            moduleVolume.setSensitiveDetector(sensDet);
            DetElement mod_det(lay_det, "module" + std::to_string(moduleCounter), moduleCounter);
            mod_det.setPlacement(placedModuleVolume);
            ++moduleCounter;
          }
        }
      }
      integratedModuleComponentThickness += xModuleComponentOdd.thickness();
    }
    ++layerCounter;
  }
  Volume motherVol = lcdd.pickMotherVolume(topDetElement);
  PlacedVolume placedGenericTrackerBarrel = motherVol.placeVolume(topVolume);
  placedGenericTrackerBarrel.addPhysVolID("system", topDetElement.id());
  topDetElement.setPlacement(placedGenericTrackerBarrel);
  return topDetElement;
}
void buildOneSide(MsgStream& lLog, DD4hep::Geometry::LCDD& aLcdd, DD4hep::Geometry::SensitiveDetector& aSensDet,
                    DD4hep::Geometry::Volume& aEnvelope, DD4hep::XML::Handle_t& aXmlElement, int sign) {

  DD4hep::XML::Dimension dim(aXmlElement.child(_Unicode(dimensions)));

  DD4hep::XML::DetElement active = aXmlElement.child(_Unicode(active));
  std::string activeMaterial = active.materialStr();
  double activeThickness = active.thickness();

  DD4hep::XML::DetElement readout = aXmlElement.child(_Unicode(readout));
  std::string readoutMaterial = readout.materialStr();
  double readoutThickness = readout.thickness();

  DD4hep::XML::DetElement passive = aXmlElement.child(_Unicode(passive));
  DD4hep::XML::DetElement passiveInner = passive.child(_Unicode(inner));
  DD4hep::XML::DetElement passiveOuter = passive.child(_Unicode(outer));
  DD4hep::XML::DetElement passiveGlue = passive.child(_Unicode(glue));
  double passiveInnerThickness = passiveInner.thickness();
  double passiveOuterThickness = passiveOuter.thickness();
  double passiveGlueThickness = passiveGlue.thickness();
  double passiveThickness = passiveInnerThickness + passiveOuterThickness + passiveGlueThickness;
  std::string passiveInnerMaterial = passiveInner.materialStr();
  std::string passiveOuterMaterial = passiveOuter.materialStr();
  std::string passiveGlueMaterial = passiveGlue.materialStr();
  std::string passiveMaterial;
  if (passiveInnerThickness < passiveThickness) {
    passiveMaterial = "Air";
  } else {
    passiveMaterial = passiveInnerMaterial;
  }

  DD4hep::Geometry::SensitiveDetector sensDet = aSensDet;
  DD4hep::XML::Dimension sensDetType = aXmlElement.child(_U(sensitive));
  sensDet.setType(sensDetType.typeStr());
  lLog << MSG::INFO << " rmin (cm) = " << dim.rmin1() << " rmin (cm) = " << dim.rmin2() << " rmax (cm) = " << dim.rmax()
       << " length (cm) = " << dim.dz() << " Sensitive volume of type: " << sensDetType.typeStr() << endmsg;
  double length = dim.dz() * 2;
  // First disc set is different: readout is first (HV), then half of active material, then absorber (GND)
  // Next disc sets have active material on both sides
  double lengthWithoutFirst = length - readoutThickness - activeThickness / 2. - passiveThickness;
  uint numDiscs = floor(lengthWithoutFirst / (activeThickness + readoutThickness + passiveThickness));
  double marginOutside = (lengthWithoutFirst - numDiscs * (activeThickness + readoutThickness + passiveThickness)) / 2.;
  // add the first disc set to the number of all discs
  numDiscs += 1;
  lLog << MSG::INFO << "Thickness of active material in between absorbers (cm) = " << activeThickness
       << "\nThickness of absorber discs (cm) = " << passiveThickness
       << "\nThickness of readout disc placed in between absorber plates (cm) = " << readoutThickness
       << "\nNumber of absorber/readout discs: " << numDiscs
       << "\nMargin outside first readout disc and last absorber disc, filled with non-sensitive active medium (cm) = "
       << marginOutside << endmsg;
  lLog << MSG::INFO << "Detector length: (cm) " << length << endmsg;
  // Place components starting from closer to the collision-point
  double zOffset = (length / 2. - marginOutside) * -sign;
  double rMax = dim.rmax();
  // First disc to place is readout
  zOffset += sign * (readoutThickness / 2.);
  double nonAbsorberRmin = std::min(dim.rmin1(), dim.rmin2());
  double tanTheta = fabs(dim.rmin2() - dim.rmin1()) / (2 * dim.dz());
  nonAbsorberRmin +=
      (marginOutside + readoutThickness + activeThickness / 2.) * tanTheta;         // for first readout position
  double dR1 = passiveThickness * tanTheta;                                         // between readout and passive
  double dR2 = (activeThickness + readoutThickness + passiveThickness) * tanTheta;  // between two readout discs
  DD4hep::Geometry::Tube readoutShapePre(nonAbsorberRmin, rMax, readoutThickness / 2.);
  DD4hep::Geometry::Tube activeShapePre(nonAbsorberRmin, rMax, activeThickness / 4.);
  DD4hep::Geometry::Volume readoutVolPre("readoutPre", readoutShapePre, aLcdd.material(readoutMaterial));
  if (readout.isSensitive()) {
    lLog << MSG::INFO << "Readout volume set as sensitive" << endmsg;
    readoutVolPre.setSensitiveDetector(aSensDet);
  }
  DD4hep::Geometry::Volume activeVolPre("activePre", activeShapePre, aLcdd.material(activeMaterial));
  activeVolPre.setSensitiveDetector(sensDet);
  DD4hep::Geometry::PlacedVolume readoutPhysVolPre =
      aEnvelope.placeVolume(readoutVolPre, DD4hep::Geometry::Position(0, 0, zOffset));
  readoutPhysVolPre.addPhysVolID("layer", 0);
  readoutPhysVolPre.addPhysVolID("type", 2);  // 0 = active, 1 = passive, 2 = readout
  std::vector<DD4hep::Geometry::PlacedVolume> activePhysVols;
  activePhysVols.reserve(numDiscs * 2);
  activePhysVols.push_back(aEnvelope.placeVolume(
      activeVolPre, DD4hep::Geometry::Position(0, 0, zOffset + sign * (readoutThickness / 2. + activeThickness / 4.))));
  lLog << MSG::DEBUG << "Placing first readout at " << zOffset
       << " and active at z= " << zOffset + sign * (activeThickness / 4. + readoutThickness / 2.) << endmsg;
  // Now place complete sets of discs: absorber|active|readout|active
  zOffset += sign * (readoutThickness / 2. + activeThickness / 2. + passiveThickness / 2.);
  // Loop placing readout, active and passive discs
  for (uint iDiscs = 0; iDiscs < numDiscs - 1; iDiscs++) {
    nonAbsorberRmin += dR2;
    // readout and active discs have the same radius, but different thickness
    DD4hep::Geometry::Tube activeShapeBeforeSubtraction(nonAbsorberRmin, rMax,
                                                        activeThickness / 2. + readoutThickness / 2.);
    DD4hep::Geometry::Tube readoutShape(nonAbsorberRmin, rMax, readoutThickness / 2.);
    DD4hep::Geometry::SubtractionSolid activeShape(activeShapeBeforeSubtraction, readoutShape);
    DD4hep::Geometry::Tube passiveShape(nonAbsorberRmin + dR1, rMax, passiveThickness / 2.);
    DD4hep::Geometry::Volume activeVol("active", activeShape, aLcdd.material(activeMaterial));
    DD4hep::Geometry::Volume readoutVol("readout", readoutShape, aLcdd.material(readoutMaterial));
    DD4hep::Geometry::Volume passiveVol("passive", passiveShape, aLcdd.material(passiveMaterial));
    activeVol.setSensitiveDetector(sensDet);
    if (readout.isSensitive()) {
      lLog << MSG::DEBUG << "Passive inner volume set as sensitive" << endmsg;
      readoutVol.setSensitiveDetector(aSensDet);
    }
    if (passive.isSensitive()) {
      lLog << MSG::DEBUG << "Passive volume set as sensitive" << endmsg;
      passiveVol.setSensitiveDetector(aSensDet);
    }
    // absorber may consist of inner and outer material
    if (passiveInnerThickness < passiveThickness) {
      // create shapes
      DD4hep::Geometry::Tube passiveInnerShape(nonAbsorberRmin + dR1, rMax, passiveInnerThickness / 2.);
      DD4hep::Geometry::Tube passiveGlueShape(nonAbsorberRmin + dR1, rMax, passiveGlueThickness / 4.);
      DD4hep::Geometry::Tube passiveOuterShape(nonAbsorberRmin + dR1, rMax, passiveOuterThickness / 4.);
      // create volumes
      DD4hep::Geometry::Volume passiveInnerVol(passiveInnerMaterial + "_passive", passiveInnerShape,
                                               aLcdd.material(passiveInnerMaterial));
      DD4hep::Geometry::Volume passiveOuterVol(passiveOuterMaterial + "_passive", passiveOuterShape,
                                               aLcdd.material(passiveOuterMaterial));
      DD4hep::Geometry::Volume passiveGlueVol(passiveGlueMaterial + "_passive", passiveGlueShape,
                                              aLcdd.material(passiveGlueMaterial));
      if (passive.isSensitive()) {
        lLog << MSG::INFO << "Passive volumes (inner, outer, glue) set as sensitive" << endmsg;
        passiveInnerVol.setSensitiveDetector(aSensDet);
        passiveOuterVol.setSensitiveDetector(aSensDet);
        passiveGlueVol.setSensitiveDetector(aSensDet);
      }
      // place volumes
      DD4hep::Geometry::PlacedVolume passiveInnerPhysVol =
          passiveVol.placeVolume(passiveInnerVol, DD4hep::Geometry::Position(0, 0, 0));
      DD4hep::Geometry::PlacedVolume passiveOuterPhysVolBelow = passiveVol.placeVolume(
          passiveOuterVol,
          DD4hep::Geometry::Position(0, 0, passiveInnerThickness / 2. + passiveGlueThickness / 2. +
                                         passiveOuterThickness / 4.));
      DD4hep::Geometry::PlacedVolume passiveOuterPhysVolAbove = passiveVol.placeVolume(
          passiveOuterVol,
          DD4hep::Geometry::Position(0, 0, -passiveInnerThickness / 2. - passiveGlueThickness / 2. -
                                         passiveOuterThickness / 4.));
      DD4hep::Geometry::PlacedVolume passiveGluePhysVolBelow = passiveVol.placeVolume(
          passiveGlueVol, DD4hep::Geometry::Position(0, 0, -passiveInnerThickness / 2. - passiveGlueThickness / 4.));
      DD4hep::Geometry::PlacedVolume passiveGluePhysVolAbove = passiveVol.placeVolume(
          passiveGlueVol, DD4hep::Geometry::Position(0, 0, passiveInnerThickness / 2. + passiveGlueThickness / 4.));
      passiveInnerPhysVol.addPhysVolID("subtype", 0);
      passiveOuterPhysVolBelow.addPhysVolID("subtype", 1);
      passiveOuterPhysVolAbove.addPhysVolID("subtype", 2);
      passiveGluePhysVolBelow.addPhysVolID("subtype", 3);
      passiveGluePhysVolAbove.addPhysVolID("subtype", 4);
    }
    DD4hep::Geometry::PlacedVolume passivePhysVol =
        aEnvelope.placeVolume(passiveVol, DD4hep::Geometry::Position(0, 0, zOffset));
    passivePhysVol.addPhysVolID("layer", iDiscs);
    passivePhysVol.addPhysVolID("type", 1);  // 0 = active, 1 = passive, 2 = readout
    DD4hep::Geometry::PlacedVolume readoutPhysVol = aEnvelope.placeVolume(
        readoutVol,
        DD4hep::Geometry::Position(0, 0, zOffset +
                                       sign * (passiveThickness / 2. + activeThickness / 2. + readoutThickness / 2.)));
    readoutPhysVol.addPhysVolID("layer", iDiscs + 1);  // +1 because first readout is placed before that loop
    readoutPhysVol.addPhysVolID("type", 2);            // 0 = active, 1 = passive, 2 = readout
    activePhysVols.push_back(aEnvelope.placeVolume(
        activeVol,
        DD4hep::Geometry::Position(0, 0, zOffset +
                                       sign * (passiveThickness / 2. + activeThickness / 2. + readoutThickness / 2.))));
    lLog << MSG::DEBUG << "Placing passive at z= " << zOffset
         << " readout at z= " << zOffset + sign * (passiveThickness / 2. + activeThickness / 2. + readoutThickness / 2.)
         << " active at " << zOffset + sign * (passiveThickness / 2. + activeThickness / 2. + readoutThickness / 2.)
         << endmsg;
    zOffset += sign * (readoutThickness + activeThickness + passiveThickness);
    if (iDiscs == numDiscs - 2) {
      // finish detector with the last disc of abosrber (for GND layer)
      DD4hep::Geometry::PlacedVolume passivePhysVolPost =
          aEnvelope.placeVolume(passiveVol, DD4hep::Geometry::Position(0, 0, zOffset));
      passivePhysVolPost.addPhysVolID("layer", iDiscs + 1);
      passivePhysVolPost.addPhysVolID("type", 2);  // 0 = active, 1 = passive, 2 = readout
      lLog << MSG::DEBUG << "Placing last passive disc at z= " << zOffset << endmsg;
    }
    for (uint iActive = 0; iActive < activePhysVols.size(); iActive++) {
      activePhysVols[iActive].addPhysVolID("layer", iActive + 1);  // +1 because first active is placed before that loop
      activePhysVols[iActive].addPhysVolID("type", 0);             // 0 = active, 1 = passive, 2 = readout
    }
  }
  return;
}