GeomConverter/src/org/lcsim/geometry/compact/converter/pandora
diff -u -r1.8 -r1.9
--- Main.java 22 Mar 2010 21:40:51 -0000 1.8
+++ Main.java 19 May 2010 20:39:12 -0000 1.9
@@ -11,6 +11,7 @@
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
+import java.util.StringTokenizer;
import javax.swing.filechooser.FileFilter;
@@ -25,6 +26,7 @@
import org.lcsim.geometry.Calorimeter;
import org.lcsim.geometry.Detector;
import org.lcsim.geometry.GeometryReader;
+import org.lcsim.geometry.Calorimeter.CalorimeterType;
import org.lcsim.geometry.compact.Field;
import org.lcsim.geometry.compact.Subdetector;
import org.lcsim.geometry.compact.converter.Converter;
@@ -39,51 +41,252 @@
import org.lcsim.geometry.util.SamplingFractionManager;
/**
- * This class converts from a compact detector description to a format
- * suitable for reading the geometry into the new Pandora PFA API.
- *
- * @author jeremym
+ * This class converts from a compact detector description into slicPandora's
+ * geometry input format.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: Main.java,v 1.9 2010/05/19 20:39:12 jeremy Exp $
*/
public class Main implements Converter
-{
+{
+ // ConditionsManager instance.
private ConditionsManager conditionsManager = ConditionsManager.defaultInstance();
+
+ // Numerical formatting.
static final DecimalFormat xlen = new DecimalFormat("#.########");
static final DecimalFormat xfrac = new DecimalFormat("#.########");
- static final DecimalFormat xthick = new DecimalFormat("#.######");
-
+ static final DecimalFormat xthick = new DecimalFormat("#.######");
+
+ /**
+ * Represents CalorimeterConditions for a single subdetector.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+ private static class CalorimeterConditions
+ {
+ SamplingLayers samplingLayers;
+ String name;
+
+ public String toString()
+ {
+ StringBuffer buff = new StringBuffer();
+ buff.append(name + '\n');
+ for (SamplingLayerRange range : samplingLayers)
+ {
+ buff.append("[" + range.getLowerLayer() + " - " + range.getUpperLayer() + "]" + '\n');
+ buff.append(" em = " + range.getEMSampling() + '\n');
+ buff.append(" had = " + range.getHADSampling() + '\n');
+ }
+
+ return buff.toString();
+ }
+
+ public SamplingLayers getSamplingLayers()
+ {
+ return samplingLayers;
+ }
+
+ private static class SamplingLayerRange
+ {
+ int lowerLayer;
+ int upperLayer;
+ double em;
+ double had;
+
+ SamplingLayerRange(int lowerLayer, int upperLayer, double em, double had)
+ {
+ this.lowerLayer = lowerLayer;
+ this.upperLayer = upperLayer;
+ this.em = em;
+ this.had = had;
+ }
+
+ public boolean inRange(int layerNumber)
+ {
+ return layerNumber >= lowerLayer && layerNumber <= upperLayer;
+ }
+
+ public int getLowerLayer()
+ {
+ return lowerLayer;
+ }
+
+ public int getUpperLayer()
+ {
+ return upperLayer;
+ }
+
+ public double getEMSampling()
+ {
+ return em;
+ }
+
+ public double getHADSampling()
+ {
+ return had;
+ }
+ }
+
+ private static class SamplingLayers extends ArrayList<SamplingLayerRange>
+ {}
+
+ /**
+ * Constructor that parses raw CalorimeterCalibration conditions for a single subdetector.
+ * @param calorimeter
+ * @param conditions
+ */
+ protected CalorimeterConditions(Calorimeter calorimeter, ConditionsSet conditions)
+ {
+ this.name = calorimeter.getName();
+
+ // Figure out which layering conditions to use based on the CalorimeterType.
+ String layeringName = null;
+ if (calorimeter.getCalorimeterType() == CalorimeterType.EM_BARREL
+ || calorimeter.getCalorimeterType() == CalorimeterType.EM_ENDCAP)
+ {
+ layeringName = "ECalLayering";
+ }
+ else if (calorimeter.getCalorimeterType() == CalorimeterType.HAD_BARREL
+ || calorimeter.getCalorimeterType() == CalorimeterType.HAD_ENDCAP)
+ {
+ layeringName = "HCalLayering";
+ }
+ else
+ {
+ throw new RuntimeException("Don't know how to handle CalorimeterConditions for " + calorimeter.getName() + ".");
+ }
+
+ String emName = null;
+ String hadName = null;
+ if (calorimeter.getCalorimeterType() == CalorimeterType.EM_BARREL ||
+ calorimeter.getCalorimeterType() == CalorimeterType.HAD_BARREL)
+ {
+ emName = "EMBarrel_SF";
+ hadName = "HadBarrel_SF";
+ }
+ else if (calorimeter.getCalorimeterType() == CalorimeterType.EM_ENDCAP ||
+ calorimeter.getCalorimeterType() == CalorimeterType.HAD_ENDCAP)
+ {
+ emName = "EMEndcap_SF";
+ hadName = "HadEndcap_SF";
+ }
+
+ if (emName == null || hadName == null)
+ {
+ throw new RuntimeException("Sampling fractions not found for " + calorimeter.getName() + ".");
+ }
+
+ String emSampling = conditions.getString(emName);
+ String hadSampling = conditions.getString(hadName);
+ List<Double> emSamplingFractions = new ArrayList<Double>();
+ List<Double> hadSamplingFractions = new ArrayList<Double>();
+ StringTokenizer tok = new StringTokenizer(emSampling, ",");
+ while (tok.hasMoreTokens())
+ {
+ Double emSamplingFraction = Double.valueOf(tok.nextToken().trim());
+ emSamplingFractions.add(emSamplingFraction);
+ }
+ tok = new StringTokenizer(hadSampling, ",");
+ while (tok.hasMoreTokens())
+ {
+ Double hadSamplingFraction = Double.valueOf(tok.nextToken().trim());
+ hadSamplingFractions.add(hadSamplingFraction);
+ }
+
+ String layering = conditions.getString(layeringName);
+ tok = new StringTokenizer(layering, ",");
+ List<Integer> layers = new ArrayList<Integer>();
+ int maxLayer = calorimeter.getLayering().getLayerCount() - 1;
+ while (tok.hasMoreTokens())
+ {
+ String nextToken = tok.nextToken().trim();
+ int nextLayer = Integer.valueOf(nextToken);
+ layers.add(nextLayer);
+ }
+ for (int i=0; i<layers.size(); i++)
+ {
+ int l = layers.get(i);
+ }
+
+ // FIXME Hack to get the correct starting index for the sampling fractions. Ideally, the sampling fractions
+ // should be separated by subdetector name.
+ int samplingIndex = 0;
+ if (calorimeter.getCalorimeterType() == HAD_BARREL || calorimeter.getCalorimeterType() == HAD_ENDCAP)
+ {
+ samplingIndex = (new StringTokenizer(conditions.getString("ECalLayering"), ",").countTokens() - 1);
+ }
+
+ // Create the SamplingLayerRange list.
+ samplingLayers = new SamplingLayers();
+ for (int i=0; i<layers.size(); i++)
+ {
+ // Figure out the layer range.
+ int lowerLayer = layers.get(i);
+ int upperLayer = 0;
+ if (i + 1 > layers.size() - 1)
+ upperLayer = maxLayer;
+ else
+ upperLayer = layers.get(i+1) - 1;
+
+ // Create the sampling layer range.
+ double emSamplingFraction = emSamplingFractions.get(samplingIndex);
+ double hadSamplingFraction = hadSamplingFractions.get(samplingIndex);
+ SamplingLayerRange samplingLayerRange = new SamplingLayerRange(lowerLayer, upperLayer, emSamplingFraction, hadSamplingFraction);
+ samplingLayers.add(samplingLayerRange);
+
+ ++samplingIndex;
+ }
+ }
+
+ public SamplingLayerRange getSamplingLayerRange(int layer)
+ {
+ for (SamplingLayerRange layers : this.samplingLayers)
+ {
+ if (layers.inRange(layer))
+ return layers;
+ }
+ return null;
+ }
+ }
+
public void convert(String inputFileName, InputStream in, OutputStream out) throws Exception
{
GeometryReader reader = new GeometryReader();
- Detector det = reader.read(in);
+ Detector det = reader.read(in);
String detectorName = det.getDetectorName();
- try
+ try
{
- conditionsManager.setDetector(detectorName,0);
+ conditionsManager.setDetector(detectorName, 0);
}
catch (ConditionsNotFoundException x)
{
- throw new RuntimeException("Failed to setup conditions system for detector: " + detectorName, x);
- }
- Document doc = convertDetectorToPandora(det);
- XMLOutputter outputter = new XMLOutputter();
+ throw new RuntimeException("Failed to setup conditions system for detector: " + detectorName, x);
+ }
+ Document doc = convertDetectorToPandora(det);
+ XMLOutputter outputter = new XMLOutputter();
if (out != null)
{
- outputter.setFormat(Format.getPrettyFormat());
- outputter.output(doc,out);
- out.close();
- }
+ outputter.setFormat(Format.getPrettyFormat());
+ outputter.output(doc, out);
+ out.close();
+ }
}
-
+
public Document convertDetectorToPandora(Detector detector)
{
Document outputDoc = new Document();
Element root = new Element("pandoraSetup");
- outputDoc.setRootElement(root);
-
+ outputDoc.setRootElement(root);
+
Element calorimeters = new Element("calorimeters");
root.addContent(calorimeters);
-
- for ( Subdetector subdetector : detector.getSubdetectors().values() )
+
+ ConditionsSet calorimeterCalibration =
+ conditionsManager.getConditions("CalorimeterCalibration");
+
+ if (calorimeterCalibration == null)
+ throw new RuntimeException("Missing CalorimeterCalibration.properties for " + detector.getDetectorName() + ".");
+
+ for (Subdetector subdetector : detector.getSubdetectors().values())
{
// Only handle polyhedra calorimeters for now.
if (subdetector instanceof AbstractPolyhedraCalorimeter)
@@ -91,48 +294,42 @@
Element calorimeter = new Element("calorimeter");
AbstractPolyhedraCalorimeter polycal = (AbstractPolyhedraCalorimeter) subdetector;
Calorimeter.CalorimeterType calType = polycal.getCalorimeterType();
- if (calType.equals(HAD_BARREL) ||
- calType.equals(HAD_ENDCAP) ||
- calType.equals(EM_ENDCAP) ||
- calType.equals(EM_BARREL))
+ if (calType.equals(HAD_BARREL) || calType.equals(HAD_ENDCAP) || calType.equals(EM_ENDCAP) || calType
+ .equals(EM_BARREL))
{
- calorimeter.setAttribute(
- "type",
- Calorimeter.CalorimeterType.toString( calType )
- );
-
- calorimeter.setAttribute("innerR", Double.toString( polycal.getInnerR()));
- calorimeter.setAttribute("innerZ", Double.toString( polycal.getInnerZ()));
- calorimeter.setAttribute("innerPhi", Double.toString( polycal.getInnerPhi()));
- calorimeter.setAttribute("innerSymmetryOrder", Double.toString(polycal.getInnerNumberOfSides()));
+ calorimeter.setAttribute("type", Calorimeter.CalorimeterType.toString(calType));
+
+ calorimeter.setAttribute("innerR", Double.toString(polycal.getInnerR()));
+ calorimeter.setAttribute("innerZ", Double.toString(polycal.getInnerZ()));
+ calorimeter.setAttribute("innerPhi", Double.toString(polycal.getInnerPhi()));
+ calorimeter.setAttribute("innerSymmetryOrder", Double.toString(polycal
+ .getInnerNumberOfSides()));
calorimeter.setAttribute("outerR", Double.toString(polycal.getOuterR()));
calorimeter.setAttribute("outerZ", Double.toString(polycal.getOuterZ()));
calorimeter.setAttribute("outerPhi", Double.toString(polycal.getOuterPhi()));
- calorimeter.setAttribute("outerSymmetryOrder", Double.toString(polycal.getOuterNumberOfSides()));
-
+ calorimeter.setAttribute("outerSymmetryOrder", Double.toString(polycal
+ .getOuterNumberOfSides()));
+
calorimeter.setAttribute("collection", subdetector.getReadout().getName());
-
+
List<Double> cellSizes = getCellSizes(subdetector);
calorimeter.setAttribute("cellSizeU", Double.toString(cellSizes.get(0)));
calorimeter.setAttribute("cellSizeV", Double.toString(cellSizes.get(1)));
-
- //Element iddesc = new Element("id");
- //iddesc.setText(polycal.getReadout().getIDDescriptor().toString());
-
+
// Create identifier description and add to subdet.
calorimeter.addContent(makeIdentifierDescription(polycal));
-
+
calorimeters.addContent(calorimeter);
-
+
LayerStack layers = polycal.getLayering().getLayerStack();
-
+
Element layersElem = new Element("layers");
layersElem.setAttribute("nlayers", Integer.toString(layers.getNumberOfLayers()));
-
+
calorimeter.addContent(layersElem);
-
+
double layerD = 0.;
-
+
if (polycal.isBarrel())
{
layerD = polycal.getInnerR();
@@ -140,43 +337,53 @@
else if (polycal.isEndcap())
{
layerD = polycal.getInnerZ();
- }
+ }
- for (int i=0; i<layers.getNumberOfLayers(); i++)
+
+ CalorimeterConditions subdetectorCalorimeterConditions =
+ new CalorimeterConditions((Calorimeter)subdetector, calorimeterCalibration);
+
+ System.out.println(subdetectorCalorimeterConditions.toString());
+
+ for (int i = 0; i < layers.getNumberOfLayers(); i++)
{
Layer layer = layers.getLayer(i);
-
+
Element layerElem = new Element("layer");
layersElem.addContent(layerElem);
-
+
double intLen = 0;
- double radLen = 0;
-
- for (int j=0; j<layer.getNumberOfSlices(); j++)
+ double radLen = 0;
+
+ for (int j = 0; j < layer.getNumberOfSlices(); j++)
{
LayerSlice slice = layer.getSlice(j);
radLen += slice.getThickness() / slice.getMaterial().getRadiationLength();
- intLen += slice.getThickness() / slice.getMaterial().getNuclearInteractionLength();
+ intLen += slice.getThickness() / slice.getMaterial()
+ .getNuclearInteractionLength();
}
-
+
double layerD2 = layerD + layer.getThicknessToSensitiveMid();
-
+
layerElem.setAttribute("distanceToIp", xthick.format(layerD2));
layerElem.setAttribute("radLen", xlen.format(radLen));
layerElem.setAttribute("intLen", xlen.format(intLen));
layerElem.setAttribute("cellThickness", xthick.format(layer.getSensorThickness()));
-
- double samplingFraction = SamplingFractionManager.defaultInstance().getSamplingFraction(subdetector,i);
+
+ double samplingFraction = SamplingFractionManager.defaultInstance()
+ .getSamplingFraction(subdetector, i);
layerElem.setAttribute("samplingFraction", xfrac.format(samplingFraction));
- // TODO: Add separate EM + HAD sampling fractions here.
+
+ // TODO Add separate EM + HAD sampling fractions here.
layerD += layer.getThickness();
}
- }
-
+ }
+
// Set digital attribute from conditions.
- ConditionsSet conditions = conditionsManager.getConditions("SamplingFractions/" + subdetector.getName());
- try
+ ConditionsSet conditions = conditionsManager.getConditions("SamplingFractions/" + subdetector
+ .getName());
+ try
{
boolean isDigital = conditions.getBoolean("digital");
calorimeter.setAttribute("digital", String.valueOf(isDigital));
@@ -186,58 +393,58 @@
//System.out.println("No digital attribute for " + subdetector.getName());
calorimeter.setAttribute("digital", "false");
}
- }
+ }
}
-
+
for (Field f : detector.getFields().values())
{
if (f instanceof Solenoid)
{
- Solenoid s = (Solenoid)f;
+ Solenoid s = (Solenoid) f;
Element coil = new Element("coil");
- coil.setAttribute("bfield", Double.toString(s.getField(new BasicHep3Vector(0,0,0)).z()));
+ coil.setAttribute("bfield", Double.toString(s.getField(new BasicHep3Vector(0, 0, 0)).z()));
coil.setAttribute("innerR", Double.toString(0.));
coil.setAttribute("z", Double.toString(s.getZMax()));
- coil.setAttribute("outerR", Double.toString(Math.sqrt(s.getOuterRadius2())));
+ coil.setAttribute("outerR", Double.toString(Math.sqrt(s.getOuterRadius2())));
root.addContent(coil);
}
break;
- }
-
- Tube tube = (Tube)detector.getTrackingVolume().getLogicalVolume().getSolid();
+ }
+
+ Tube tube = (Tube) detector.getTrackingVolume().getLogicalVolume().getSolid();
Element tracking = new Element("tracking");
tracking.setAttribute("innerR", Double.toString(tube.getInnerRadius()));
tracking.setAttribute("outerR", Double.toString(tube.getOuterRadius()));
tracking.setAttribute("z", Double.toString(tube.getZHalfLength()));
root.addContent(tracking);
-
- return outputDoc;
+
+ return outputDoc;
}
-
+
Element makeIdentifierDescription(Subdetector subdet)
{
IDDescriptor descr = subdet.getIDDecoder().getIDDescription();
Element id = new Element("id");
- for (int i=0, j=descr.fieldCount(); i<j; i++)
+ for (int i = 0, j = descr.fieldCount(); i < j; i++)
{
Element field = new Element("field");
field.setAttribute("name", descr.fieldName(i));
field.setAttribute("length", Integer.toString(descr.fieldLength(i)));
field.setAttribute("start", Integer.toString(descr.fieldStart(i)));
field.setAttribute("signed", Boolean.toString(descr.isSigned(i)));
-
+
id.addContent(field);
}
return id;
}
-
+
private List<Double> getCellSizes(Subdetector subdetector)
{
List<Double> cellSizes = new ArrayList<Double>();
- BaseIDDecoder dec = (BaseIDDecoder)subdetector.getReadout().getIDDecoder();
+ BaseIDDecoder dec = (BaseIDDecoder) subdetector.getReadout().getIDDecoder();
if (dec instanceof AbstractCartesianGrid)
{
- AbstractCartesianGrid cgrid = (AbstractCartesianGrid)dec;
+ AbstractCartesianGrid cgrid = (AbstractCartesianGrid) dec;
if (cgrid.getGridSizeX() != 0)
{
cellSizes.add(cgrid.getGridSizeX());
@@ -249,7 +456,7 @@
if (cgrid.getGridSizeZ() != 0)
{
cellSizes.add(cgrid.getGridSizeZ());
- }
+ }
}
if (cellSizes.size() != 2)
throw new RuntimeException("Only 2 cell dimensions are allowed.");
@@ -270,7 +477,7 @@
{
public boolean accept(java.io.File file)
{
- return file.isDirectory() || file.getName().endsWith( ".xml" );
+ return file.isDirectory() || file.getName().endsWith(".xml");
}
public String getDescription()
@@ -278,4 +485,6 @@
return "Pandora Geometry file (*.xml)";
}
}
+
+
}