File indexing completed on 2025-01-30 09:16:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DD4HEP_DDCORE_PANDORACONVERTER_H
0014 #define DD4HEP_DDCORE_PANDORACONVERTER_H
0015
0016
0017 #include <DD4hep/Detector.h>
0018 #include <DD4hep/GeoHandler.h>
0019 #include <DD4hep/DetFactoryHelper.h>
0020
0021
0022
0023
0024 namespace dd4hep {
0025
0026
0027
0028
0029 namespace detail {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 struct PandoraConverter: public GeoHandler {
0040 protected:
0041
0042 struct GeometryInfo: public GeoHandler::GeometryInfo {
0043 xml_doc_t doc;
0044 xml_elt_t doc_root, doc_calorimeters, doc_detector, doc_coil, doc_tracking;
0045
0046 GeometryInfo();
0047 };
0048
0049
0050 Detector& m_detDesc;
0051
0052 GeometryInfo* m_dataPtr;
0053
0054 public:
0055
0056
0057 PandoraConverter(Detector& description);
0058
0059
0060 virtual ~PandoraConverter();
0061
0062
0063 xml_doc_t create(DetElement top);
0064
0065 };
0066 }
0067 }
0068
0069 #endif
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 #include <DD4hep/Detector.h>
0086 #include <DD4hep/GeoHandler.h>
0087 #include <DD4hep/DetFactoryHelper.h>
0088 #include <XML/DocumentHandler.h>
0089
0090
0091 #include <stdexcept>
0092
0093 using namespace dd4hep::detail;
0094 using namespace dd4hep;
0095 using namespace std;
0096
0097
0098 PandoraConverter::GeometryInfo::GeometryInfo()
0099 : doc(0), doc_root(0), doc_calorimeters(0), doc_detector(0), doc_coil(0), doc_tracking(0) {
0100 }
0101
0102
0103 PandoraConverter::PandoraConverter(Detector& description)
0104 : m_detDesc(description), m_dataPtr(0) {
0105 }
0106
0107
0108 PandoraConverter::~PandoraConverter() {
0109 if (m_dataPtr)
0110 delete m_dataPtr;
0111 m_dataPtr = 0;
0112 }
0113
0114
0115 xml_doc_t PandoraConverter::create(DetElement ) {
0116 const char empty_xml[] = "<?xml version=\"1.0\" encoding=\"UTF-8\">\n"
0117 "<!-- \n"
0118 " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
0119 " ++++ Linear collider detector description in C++ ++++\n"
0120 " ++++ dd4hep Detector description generator. ++++\n"
0121 " ++++ ++++\n"
0122 " ++++ M.Frank CERN/LHCb ++++\n"
0123 " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
0124 "-->\n"
0125 "<pandoraSetup>\n\0\0";
0126 xml::DocumentHandler docH;
0127 GeometryInfo& geo = *(m_dataPtr = new GeometryInfo);
0128
0129 xml_elt_t elt(0);
0130 Header hdr = m_detDesc.header();
0131 geo.doc = docH.parse(empty_xml, sizeof(empty_xml));
0132 geo.doc_root = geo.doc.root();
0133 geo.doc_root.append(geo.doc_calorimeters = xml_elt_t(geo.doc, _Unicode(calorimeters)));
0134 geo.doc_root.append(geo.doc_detector = xml_elt_t(geo.doc, _Unicode(detector)));
0135 geo.doc_root.append(geo.doc_coil = xml_elt_t(geo.doc, _Unicode(coil)));
0136 geo.doc_root.append(geo.doc_tracking = xml_elt_t(geo.doc, _Unicode(tracking)));
0137 geo.doc_detector.setAttr(_Unicode(name), hdr.name());
0138 geo.doc_tracking.setAttr(_Unicode(innerR), "");
0139 geo.doc_tracking.setAttr(_Unicode(outerR), "");
0140 geo.doc_tracking.setAttr(_Unicode(z), "");
0141
0142 return geo.doc;
0143 }
0144
0145 static long create_description(Detector& , int , char** ) {
0146 throw runtime_error("The pandora xml conversion plugin is not yet implemented");
0147 return 0;
0148 #if 0
0149
0150 package org.lcsim.geometry.compact.converter.pandora;
0151
0152 import static org.lcsim.geometry.Calorimeter.CalorimeterType.EM_BARREL;
0153 import static org.lcsim.geometry.Calorimeter.CalorimeterType.EM_ENDCAP;
0154 import static org.lcsim.geometry.Calorimeter.CalorimeterType.HAD_BARREL;
0155 import static org.lcsim.geometry.Calorimeter.CalorimeterType.HAD_ENDCAP;
0156 import static org.lcsim.geometry.Calorimeter.CalorimeterType.MUON_BARREL;
0157 import static org.lcsim.geometry.Calorimeter.CalorimeterType.MUON_ENDCAP;
0158 import hep.physics.particle.properties.ParticlePropertyManager;
0159 import hep.physics.particle.properties.ParticleType;
0160 import hep.physics.vec.BasicHep3Vector;
0161 import hep.physics.vec.Hep3Vector;
0162
0163 import java.io.InputStream;
0164 import java.io.OutputStream;
0165 import java.text.DecimalFormat;
0166 import java.util.ArrayList;
0167 import java.util.List;
0168 import java.util.StringTokenizer;
0169
0170 import javax.swing.filechooser.FileFilter;
0171
0172 import org.jdom.Document;
0173 import org.jdom.Element;
0174 import org.jdom.output.Format;
0175 import org.jdom.output.XMLOutputter;
0176 import org.lcsim.conditions.ConditionsManager;
0177 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
0178 import org.lcsim.conditions.ConditionsSet;
0179 import org.lcsim.detector.material.BetheBlochCalculator;
0180 import org.lcsim.detector.material.IMaterial;
0181 import org.lcsim.detector.material.MaterialStore;
0182 import org.lcsim.detector.solids.Tube;
0183 import org.lcsim.geometry.Calorimeter;
0184 import org.lcsim.geometry.Calorimeter.CalorimeterType;
0185 import org.lcsim.geometry.Detector;
0186 import org.lcsim.geometry.GeometryReader;
0187 import org.lcsim.geometry.compact.Subdetector;
0188 import org.lcsim.geometry.compact.converter.Converter;
0189 import org.lcsim.geometry.field.Solenoid;
0190 import org.lcsim.geometry.layer.Layer;
0191 import org.lcsim.geometry.layer.LayerSlice;
0192 import org.lcsim.geometry.layer.LayerStack;
0193 import org.lcsim.geometry.segmentation.AbstractCartesianGrid;
0194 import org.lcsim.geometry.subdetector.AbstractPolyhedraCalorimeter;
0195 import org.lcsim.geometry.subdetector.MultiLayerTracker;
0196 import org.lcsim.geometry.util.BaseIDDecoder;
0197 import org.lcsim.geometry.util.IDDescriptor;
0198 import org.lcsim.geometry.util.SamplingFractionManager;
0199
0200
0201
0202
0203
0204
0205
0206
0207 public class Main implements Converter
0208 {
0209 private final static boolean DEBUG = false;
0210
0211
0212 private ConditionsManager conditionsManager = ConditionsManager.defaultInstance();
0213
0214
0215 static final DecimalFormat xlen = new DecimalFormat("#.########");
0216 static final DecimalFormat xfrac = new DecimalFormat("#.########");
0217 static final DecimalFormat xthick = new DecimalFormat("#.######");
0218
0219
0220
0221
0222
0223
0224 static class SamplingLayerRange
0225 {
0226 int lowerLayer;
0227 int upperLayer;
0228 double em;
0229 double had;
0230
0231 SamplingLayerRange(int lowerLayer, int upperLayer, double em, double had)
0232 {
0233 this.lowerLayer = lowerLayer;
0234 this.upperLayer = upperLayer;
0235 this.em = em;
0236 this.had = had;
0237 }
0238
0239 public boolean inRange(int layerNumber)
0240 {
0241 return layerNumber >= lowerLayer && layerNumber <= upperLayer;
0242 }
0243
0244 public int getLowerLayer()
0245 {
0246 return lowerLayer;
0247 }
0248
0249 public int getUpperLayer()
0250 {
0251 return upperLayer;
0252 }
0253
0254 public double getEMSampling()
0255 {
0256 return em;
0257 }
0258
0259 public double getHADSampling()
0260 {
0261 return had;
0262 }
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272 static class SamplingLayers extends ArrayList<SamplingLayerRange>
0273 {
0274 public SamplingLayers()
0275 {
0276 }
0277
0278 public SamplingLayers(SamplingLayerRange range)
0279 {
0280 this.add(range);
0281 }
0282
0283 public SamplingLayers(List<SamplingLayerRange> ranges)
0284 {
0285 this.addAll(ranges);
0286 }
0287
0288 public SamplingLayerRange getSamplingLayerRange(int layern)
0289 {
0290 for (SamplingLayerRange range : this)
0291 {
0292 if (range.inRange(layern))
0293 return range;
0294 }
0295 return null;
0296 }
0297 }
0298
0299
0300
0301
0302
0303
0304 private static class CalorimeterConditions
0305 {
0306 SamplingLayers samplingLayers;
0307 String name;
0308 double mipEnergy;
0309 double mipSigma;
0310 double mipCut;
0311 double timeCut;
0312
0313 public String toString()
0314 {
0315 StringBuffer buff = new StringBuffer();
0316 buff.append(name + '\n');
0317 for (SamplingLayerRange range : samplingLayers)
0318 {
0319 buff.append("[" + range.getLowerLayer() + " - " + range.getUpperLayer() + "]" + '\n');
0320 buff.append(" em = " + range.getEMSampling() + '\n');
0321 buff.append(" had = " + range.getHADSampling() + '\n');
0322 }
0323
0324 return buff.toString();
0325 }
0326
0327 public SamplingLayers getSamplingLayers()
0328 {
0329 return samplingLayers;
0330 }
0331
0332
0333
0334
0335
0336
0337
0338
0339 protected CalorimeterConditions(Calorimeter calorimeter, ConditionsSet conditions)
0340 {
0341
0342 this.name = calorimeter.getName();
0343
0344
0345
0346 String layeringName = null;
0347 if (calorimeter.getCalorimeterType() == CalorimeterType.EM_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.EM_ENDCAP)
0348 {
0349 layeringName = "ECalLayering";
0350 }
0351 else if (calorimeter.getCalorimeterType() == CalorimeterType.HAD_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.HAD_ENDCAP)
0352 {
0353 layeringName = "HCalLayering";
0354 }
0355 else if (calorimeter.getCalorimeterType() == CalorimeterType.MUON_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.MUON_ENDCAP)
0356 {
0357 layeringName = "MuonLayering";
0358 }
0359 else
0360 {
0361 throw new RuntimeException("Don't know how to handle CalorimeterConditions for " + calorimeter.getName() + ".");
0362 }
0363
0364 String emName = null;
0365 String hadName = null;
0366 if (calorimeter.getCalorimeterType() == CalorimeterType.EM_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.HAD_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.MUON_BARREL)
0367 {
0368 emName = "EMBarrel_SF";
0369 hadName = "HadBarrel_SF";
0370 }
0371 else if (calorimeter.getCalorimeterType() == CalorimeterType.EM_ENDCAP || calorimeter.getCalorimeterType() == CalorimeterType.HAD_ENDCAP || calorimeter.getCalorimeterType() == CalorimeterType.MUON_ENDCAP)
0372 {
0373 emName = "EMEndcap_SF";
0374 hadName = "HadEndcap_SF";
0375 }
0376
0377 if (emName == null || hadName == null)
0378 {
0379 throw new RuntimeException("Sampling fractions not found for " + calorimeter.getName() + ".");
0380 }
0381
0382 String emSampling = conditions.getString(emName);
0383 String hadSampling = conditions.getString(hadName);
0384 List<Double> emSamplingFractions = new ArrayList<Double>();
0385 List<Double> hadSamplingFractions = new ArrayList<Double>();
0386 StringTokenizer tok = new StringTokenizer(emSampling, ",");
0387 while (tok.hasMoreTokens())
0388 {
0389 Double emSamplingFraction = Double.valueOf(tok.nextToken().trim());
0390 emSamplingFractions.add(emSamplingFraction);
0391 }
0392 tok = new StringTokenizer(hadSampling, ",");
0393 while (tok.hasMoreTokens())
0394 {
0395 Double hadSamplingFraction = Double.valueOf(tok.nextToken().trim());
0396 hadSamplingFractions.add(hadSamplingFraction);
0397 }
0398
0399 String layering = conditions.getString(layeringName);
0400 tok = new StringTokenizer(layering, ",");
0401 List<Integer> layers = new ArrayList<Integer>();
0402 int maxLayer = calorimeter.getLayering().getLayerCount() - 1;
0403 while (tok.hasMoreTokens())
0404 {
0405 String nextToken = tok.nextToken().trim();
0406 int nextLayer = Integer.valueOf(nextToken);
0407 layers.add(nextLayer);
0408 }
0409
0410
0411
0412 int samplingIndex = 0;
0413 if (calorimeter.getCalorimeterType() == HAD_BARREL || calorimeter.getCalorimeterType() == HAD_ENDCAP)
0414 {
0415 samplingIndex = (new StringTokenizer(conditions.getString("ECalLayering"), ",").countTokens());
0416 }
0417 if (calorimeter.getCalorimeterType() == MUON_BARREL || calorimeter.getCalorimeterType() == MUON_ENDCAP)
0418 {
0419 samplingIndex = (new StringTokenizer(conditions.getString("ECalLayering"), ",").countTokens());
0420 samplingIndex += (new StringTokenizer(conditions.getString("HCalLayering"), ",").countTokens());
0421 }
0422
0423
0424
0425
0426 samplingLayers = new SamplingLayers();
0427 for (int i = 0; i < layers.size(); i++)
0428 {
0429
0430 int lowerLayer = layers.get(i);
0431 int upperLayer = 0;
0432 if (i + 1 > layers.size() - 1)
0433 upperLayer = maxLayer;
0434 else
0435 upperLayer = layers.get(i + 1) - 1;
0436
0437
0438 double emSamplingFraction = emSamplingFractions.get(samplingIndex);
0439 double hadSamplingFraction = hadSamplingFractions.get(samplingIndex);
0440 SamplingLayerRange samplingLayerRange = new SamplingLayerRange(lowerLayer, upperLayer, emSamplingFraction, hadSamplingFraction);
0441
0442
0443
0444 samplingLayers.add(samplingLayerRange);
0445
0446 ++samplingIndex;
0447 }
0448
0449
0450 String mipCondition = null;
0451 String mipSigmaCondition = null;
0452 String mipCutCondition = null;
0453
0454
0455 if (calorimeter.getCalorimeterType() == CalorimeterType.EM_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.EM_ENDCAP)
0456 {
0457 mipCondition = "ECalMip_MPV";
0458 mipSigmaCondition = "ECalMip_sig";
0459 mipCutCondition = "ECalMip_Cut";
0460 }
0461 else if (calorimeter.getCalorimeterType() == CalorimeterType.HAD_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.HAD_ENDCAP)
0462 {
0463 mipCondition = "HCalMip_MPV";
0464 mipSigmaCondition = "HCalMip_sig";
0465 mipCutCondition = "HCalMip_Cut";
0466 }
0467 else if (calorimeter.getCalorimeterType() == CalorimeterType.MUON_BARREL || calorimeter.getCalorimeterType() == CalorimeterType.MUON_ENDCAP)
0468 {
0469 mipCondition = "MuonMip_MPV";
0470 mipSigmaCondition = "MuonMip_sig";
0471 mipCutCondition = "MuonMip_Cut";
0472 }
0473 mipEnergy = conditions.getDouble(mipCondition);
0474 mipSigma = conditions.getDouble(mipSigmaCondition);
0475 mipCut = conditions.getDouble(mipCutCondition);
0476 timeCut = conditions.getDouble("timeCut");
0477
0478
0479
0480
0481
0482
0483
0484 }
0485
0486 public SamplingLayerRange getSamplingLayerRange(int layer)
0487 {
0488 for (SamplingLayerRange layers : this.samplingLayers)
0489 {
0490 if (layers.inRange(layer))
0491 return layers;
0492 }
0493 return null;
0494 }
0495
0496 public double getMipEnergy()
0497 {
0498 return mipEnergy;
0499 }
0500
0501 public double getMipSigma()
0502 {
0503 return mipSigma;
0504 }
0505
0506 public double getMipCut()
0507 {
0508 return mipCut;
0509 }
0510
0511 public double getTimeCut()
0512 {
0513 return timeCut;
0514 }
0515 }
0516
0517 public void convert(String inputFileName, InputStream in, OutputStream out) throws Exception
0518 {
0519 GeometryReader reader = new GeometryReader();
0520 Detector det = reader.read(in);
0521 String detectorName = det.getDetectorName();
0522 try
0523 {
0524 conditionsManager.setDetector(detectorName, 0);
0525 }
0526 catch (ConditionsNotFoundException x)
0527 {
0528 throw new RuntimeException("Failed to setup conditions system for detector: " + detectorName, x);
0529 }
0530 Document doc = convertDetectorToPandora(det);
0531 XMLOutputter outputter = new XMLOutputter();
0532 if (out != null)
0533 {
0534 outputter.setFormat(Format.getPrettyFormat());
0535 outputter.output(doc, out);
0536 out.close();
0537 }
0538 }
0539
0540 public Document convertDetectorToPandora(Detector detector)
0541 {
0542
0543 Document outputDoc = new Document();
0544 Element root = new Element("pandoraSetup");
0545 outputDoc.setRootElement(root);
0546 Element calorimeters = new Element("calorimeters");
0547 root.addContent(calorimeters);
0548
0549
0550 Element detectorTag = new Element("detector");
0551 detectorTag.setAttribute("name", detector.getDetectorName());
0552 root.addContent(detectorTag);
0553
0554
0555 ConditionsSet calorimeterCalibration = null;
0556 try
0557 {
0558 calorimeterCalibration = conditionsManager.getConditions("CalorimeterCalibration");
0559 }
0560 catch (Exception x)
0561 {
0562 }
0563 boolean haveCalCalib = (calorimeterCalibration == null) ? false : true;
0564
0565
0566 for (Subdetector subdetector : detector.getSubdetectors().values())
0567 {
0568
0569
0570 if (subdetector instanceof AbstractPolyhedraCalorimeter)
0571 {
0572 Element calorimeter = new Element("calorimeter");
0573 AbstractPolyhedraCalorimeter polycal = (AbstractPolyhedraCalorimeter) subdetector;
0574
0575
0576
0577 Calorimeter.CalorimeterType calType = polycal.getCalorimeterType();
0578 if (calType.equals(HAD_BARREL) || calType.equals(HAD_ENDCAP) || calType.equals(EM_ENDCAP) || calType.equals(EM_BARREL) || calType.equals(MUON_BARREL) || calType.equals(MUON_ENDCAP))
0579 {
0580
0581 calorimeter.setAttribute("type", Calorimeter.CalorimeterType.toString(calType));
0582 calorimeter.setAttribute("innerR", Double.toString(polycal.getInnerRadius()));
0583 calorimeter.setAttribute("innerZ", Double.toString(polycal.getInnerZ()));
0584 calorimeter.setAttribute("innerPhi", Double.toString(polycal.getSectionPhi()));
0585 calorimeter.setAttribute("innerSymmetryOrder", Double.toString(polycal.getNumberOfSides()));
0586 calorimeter.setAttribute("outerR", Double.toString(polycal.getOuterRadius()));
0587 calorimeter.setAttribute("outerZ", Double.toString(polycal.getOuterZ()));
0588 calorimeter.setAttribute("outerPhi", Double.toString(polycal.getSectionPhi()));
0589 calorimeter.setAttribute("outerSymmetryOrder", Double.toString(polycal.getNumberOfSides()));
0590 calorimeter.setAttribute("collection", subdetector.getReadout().getName());
0591
0592
0593 List<Double> cellSizes = getCellSizes(subdetector);
0594
0595
0596 if (subdetector.isEndcap())
0597 {
0598 calorimeter.setAttribute("cellSizeU", Double.toString(cellSizes.get(0)));
0599 calorimeter.setAttribute("cellSizeV", Double.toString(cellSizes.get(1)));
0600 }
0601
0602 else if (subdetector.isBarrel())
0603 {
0604 calorimeter.setAttribute("cellSizeU", Double.toString(cellSizes.get(1)));
0605 calorimeter.setAttribute("cellSizeV", Double.toString(cellSizes.get(0)));
0606 }
0607
0608
0609 calorimeter.addContent(makeIdentifierDescription(polycal));
0610
0611
0612 calorimeters.addContent(calorimeter);
0613
0614 LayerStack layers = polycal.getLayering().getLayerStack();
0615
0616 Element layersElem = new Element("layers");
0617 layersElem.setAttribute("nlayers", Integer.toString(layers.getNumberOfLayers()));
0618
0619 calorimeter.addContent(layersElem);
0620
0621 double layerD = 0.;
0622
0623 if (polycal.isBarrel())
0624 {
0625 layerD = polycal.getInnerRadius();
0626 }
0627 else if (polycal.isEndcap())
0628 {
0629 layerD = polycal.getInnerZ();
0630 }
0631
0632 CalorimeterConditions subdetectorCalorimeterConditions = null;
0633
0634 if (haveCalCalib)
0635 {
0636 subdetectorCalorimeterConditions = new CalorimeterConditions((Calorimeter) subdetector, calorimeterCalibration);
0637 }
0638
0639
0640 if (haveCalCalib)
0641 {
0642 calorimeter.setAttribute("mipEnergy", xfrac.format(subdetectorCalorimeterConditions.getMipEnergy()));
0643 calorimeter.setAttribute("mipSigma", xfrac.format(subdetectorCalorimeterConditions.getMipSigma()));
0644 calorimeter.setAttribute("mipCut", xfrac.format(subdetectorCalorimeterConditions.getMipCut()));
0645 calorimeter.setAttribute("timeCut", xfrac.format(subdetectorCalorimeterConditions.getTimeCut()));
0646 }
0647
0648
0649 else
0650 {
0651 List<LayerSlice> sensors = subdetector.getLayering().getLayerStack().getLayer(0).getSensors();
0652 LayerSlice sensor = sensors.get(0);
0653 IMaterial sensorMaterial = MaterialStore.getInstance().get(sensor.getMaterial().getName());
0654
0655 ParticleType particleType = ParticlePropertyManager.getParticlePropertyProvider().get(13);
0656
0657 Hep3Vector p = new BasicHep3Vector(-6.8641, -7.2721, 1.2168e-7);
0658
0659 double emip = BetheBlochCalculator.computeBetheBloch(sensorMaterial, p, particleType.getMass(), particleType.getCharge(), sensor.getThickness());
0660
0661
0662 calorimeter.setAttribute("mipEnergy", xfrac.format(emip));
0663
0664
0665 calorimeter.setAttribute("mipSigma", "0");
0666 calorimeter.setAttribute("mipCut", "0");
0667 calorimeter.setAttribute("timeCut", xfrac.format(Double.MAX_VALUE));
0668 }
0669
0670 double totalX0 = 0;
0671
0672 for (int i = 0; i < layers.getNumberOfLayers(); i++)
0673 {
0674
0675 Layer layer = layers.getLayer(i);
0676
0677 Element layerElem = new Element("layer");
0678 layersElem.addContent(layerElem);
0679
0680
0681 double intLen = 0;
0682 double radLen = 0;
0683 for (int j = 0; j < layer.getNumberOfSlices(); j++)
0684 {
0685 LayerSlice slice = layer.getSlice(j);
0686
0687 double x0 = slice.getMaterial().getRadiationLength();
0688
0689
0690 radLen += slice.getThickness() / (x0*10);
0691
0692
0693 double lambda = slice.getMaterial().getNuclearInteractionLength();
0694 intLen += slice.getThickness() / (lambda*10);
0695 }
0696
0697
0698 totalX0 += radLen;
0699
0700
0701
0702 layerElem.setAttribute("radLen", xlen.format(radLen));
0703 layerElem.setAttribute("intLen", xlen.format(intLen));
0704
0705
0706 double layerD2 = layerD + layer.getThicknessToSensitiveMid();
0707 layerElem.setAttribute("distanceToIp", xthick.format(layerD2));
0708
0709
0710 layerElem.setAttribute("cellThickness", xthick.format(layer.getThickness()));
0711
0712
0713
0714 if (haveCalCalib)
0715 {
0716 SamplingLayerRange layerRange = subdetectorCalorimeterConditions.getSamplingLayerRange(i);
0717 if (calType == EM_BARREL || calType == EM_ENDCAP)
0718 {
0719 layerElem.setAttribute("samplingFraction", xfrac.format(layerRange.getEMSampling()));
0720 }
0721 if (calType == HAD_BARREL || calType == HAD_ENDCAP)
0722 {
0723 layerElem.setAttribute("samplingFraction", xfrac.format(layerRange.getHADSampling()));
0724 }
0725 if (calType == MUON_BARREL || calType == MUON_ENDCAP)
0726 {
0727 layerElem.setAttribute("samplingFraction", xfrac.format(layerRange.getHADSampling()));
0728 }
0729 layerElem.setAttribute("emSamplingFraction", xfrac.format(layerRange.getEMSampling()));
0730 layerElem.setAttribute("hadSamplingFraction", xfrac.format(layerRange.getHADSampling()));
0731 }
0732
0733
0734
0735 else
0736 {
0737 double samplingFraction = SamplingFractionManager.defaultInstance().getSamplingFraction(subdetector, i);
0738 layerElem.setAttribute("emSamplingFraction", xfrac.format(samplingFraction));
0739 layerElem.setAttribute("hadSamplingFraction", xfrac.format(samplingFraction));
0740 }
0741
0742
0743 layerD += layer.getThickness();
0744 }
0745
0746
0747 }
0748
0749
0750 try
0751 {
0752
0753 ConditionsSet conditions = conditionsManager.getConditions("SamplingFractions/" + subdetector.getName());
0754 boolean isDigital = conditions.getBoolean("digital");
0755 calorimeter.setAttribute("digital", String.valueOf(isDigital));
0756 }
0757 catch (Exception x)
0758 {
0759 calorimeter.setAttribute("digital", "false");
0760 }
0761 }
0762 }
0763
0764
0765 double coilRadLen = 0;
0766 double coilIntLen = 0;
0767 int coilLayers = 0;
0768 double coilInnerR = 0;
0769 double coilOuterR = 0;
0770 double bfield = 0;
0771 double coilMaxZ = 0;
0772 try
0773 {
0774 MultiLayerTracker c = (MultiLayerTracker) detector.getSubdetector("SolenoidCoilBarrel");
0775 if (c != null)
0776 {
0777 coilLayers = c.getNumberOfLayers();
0778 coilInnerR = c.getInnerR()[0];
0779 coilOuterR = c.getInnerR()[coilLayers-1] + c.getLayerThickness(coilLayers-1);
0780 for (int layern = 0; layern != c.getNumberOfLayers(); layern++)
0781 {
0782 for (LayerSlice slice : c.getLayer(layern).getSlices())
0783 {
0784 double x0 = slice.getMaterial().getRadiationLength();
0785 double sliceRadLen = slice.getThickness() / (x0*10);
0786 double lambda = slice.getMaterial().getNuclearInteractionLength();
0787 double sliceIntLen = slice.getThickness() / (lambda*10);
0788
0789 coilRadLen += sliceRadLen;
0790 coilIntLen += sliceIntLen;
0791 }
0792 }
0793
0794 coilRadLen = coilRadLen/(coilOuterR-coilInnerR);
0795 coilIntLen = coilIntLen/(coilOuterR-coilInnerR);
0796 }
0797 }
0798 catch (ClassCastException e)
0799 {
0800 throw new RuntimeException(e);
0801 }
0802 try
0803 {
0804 Solenoid s = (Solenoid) detector.getFields().get("GlobalSolenoid");
0805 if (s != null)
0806 {
0807 bfield = s.getField(new BasicHep3Vector(0, 0, 0)).z();
0808 coilMaxZ = s.getZMax();
0809 }
0810 }
0811 catch (ClassCastException e)
0812 {
0813 throw new RuntimeException(e);
0814 }
0815
0816 Element coil = new Element("coil");
0817 coil.setAttribute("radLen", xlen.format(coilRadLen));
0818 coil.setAttribute("intLen", xlen.format(coilIntLen));
0819 coil.setAttribute("innerR", Double.toString(coilInnerR));
0820 coil.setAttribute("outerR", Double.toString(coilOuterR));
0821 coil.setAttribute("z", Double.toString(coilMaxZ));
0822 coil.setAttribute("bfield", Double.toString(bfield));
0823 root.addContent(coil);
0824
0825 Tube tube = (Tube) detector.getTrackingVolume().getLogicalVolume().getSolid();
0826 Element tracking = new Element("tracking");
0827 tracking.setAttribute("innerR", Double.toString(tube.getInnerRadius()));
0828 tracking.setAttribute("outerR", Double.toString(tube.getOuterRadius()));
0829 tracking.setAttribute("z", Double.toString(tube.getZHalfLength()));
0830 root.addContent(tracking);
0831
0832 return outputDoc;
0833 }
0834
0835 Element makeIdentifierDescription(Subdetector subdet)
0836 {
0837 IDDescriptor descr = subdet.getIDDecoder().getIDDescription();
0838 Element id = new Element("id");
0839 for (int i = 0, j = descr.fieldCount(); i < j; i++)
0840 {
0841 Element field = new Element("field");
0842 field.setAttribute("name", descr.fieldName(i));
0843 field.setAttribute("length", Integer.toString(descr.fieldLength(i)));
0844 field.setAttribute("start", Integer.toString(descr.fieldStart(i)));
0845 field.setAttribute("signed", Boolean.toString(descr.isSigned(i)));
0846
0847 id.addContent(field);
0848 }
0849 return id;
0850 }
0851
0852 private List<Double> getCellSizes(Subdetector subdetector)
0853 {
0854 List<Double> cellSizes = new ArrayList<Double>();
0855 BaseIDDecoder dec = (BaseIDDecoder) subdetector.getReadout().getIDDecoder();
0856 if (dec instanceof AbstractCartesianGrid)
0857 {
0858 AbstractCartesianGrid cgrid = (AbstractCartesianGrid) dec;
0859 if (cgrid.getGridSizeX() != 0)
0860 {
0861 cellSizes.add(cgrid.getGridSizeX());
0862 }
0863 if (cgrid.getGridSizeY() != 0)
0864 {
0865 cellSizes.add(cgrid.getGridSizeY());
0866 }
0867 if (cgrid.getGridSizeZ() != 0)
0868 {
0869 cellSizes.add(cgrid.getGridSizeZ());
0870 }
0871 }
0872 if (cellSizes.size() != 2)
0873 throw new RuntimeException("Only 2 cell dimensions are allowed.");
0874 return cellSizes;
0875 }
0876
0877 public String getOutputFormat()
0878 {
0879 return "pandora";
0880 }
0881
0882 public FileFilter getFileFilter()
0883 {
0884 return new PandoraFileFilter();
0885 }
0886
0887 private static class PandoraFileFilter extends FileFilter
0888 {
0889
0890 public boolean accept(java.io.File file)
0891 {
0892 return file.getName().endsWith(".xml");
0893 }
0894
0895 public String getDescription()
0896 {
0897 return "Pandora Geometry file (*.xml)";
0898 }
0899 }
0900 }
0901 #endif
0902 }
0903 DECLARE_APPLY(DD4hepGeometry2PANDORA,create_description)