GeomConverter/src/org/lcsim/geometry/compact/converter/GODL
diff -N Main.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Main.java 23 Jul 2005 00:43:46 -0000 1.1
@@ -0,0 +1,723 @@
+package org.lcsim.geometry.compact.converter.GODL;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+import javax.swing.filechooser.FileFilter;
+import org.lcsim.geometry.compact.Header;
+import org.lcsim.geometry.compact.Constant;
+import org.lcsim.geometry.compact.Detector;
+import org.lcsim.geometry.GeometryReader;
+import org.lcsim.geometry.compact.Field;
+import org.lcsim.geometry.compact.Readout;
+import org.lcsim.geometry.compact.Segmentation;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.compact.converter.Converter;
+import org.lcsim.geometry.field.Solenoid;
+import org.lcsim.geometry.layer.Layer;
+import org.lcsim.geometry.layer.LayerSlice;
+import org.lcsim.geometry.layer.LayerStack;
+import org.lcsim.geometry.segmentation.GridXYZ;
+import org.lcsim.geometry.segmentation.NonprojectiveCylinder;
+import org.lcsim.geometry.segmentation.ProjectiveCylinder;
+import org.lcsim.geometry.segmentation.ProjectiveZPlane;
+import org.lcsim.geometry.subdetector.CylindricalBarrelCalorimeter;
+import org.lcsim.geometry.subdetector.CylindricalEndcapCalorimeter;
+import org.lcsim.geometry.subdetector.DiskTracker;
+import org.lcsim.geometry.subdetector.MultiLayerTracker;
+import org.lcsim.geometry.util.IDDescriptor;
+import org.lcsim.material.Material;
+import org.lcsim.material.MaterialElement;
+import org.lcsim.material.MaterialManager;
+/**
+ *
+ * @author Willy Langeveld
+ */
+public class Main implements Converter
+{
+ private HashSet materials;
+ private boolean existsMaterial(String mat)
+ {
+ return(materials.contains(mat));
+ }
+ private void addMaterial(String mat)
+ {
+ materials.add(mat);
+ return;
+ }
+ private static boolean validateDefault = true;
+ private boolean validate;
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) throws Exception
+ {
+ if (args.length < 1 || args.length >2) usage();
+ String fn = args[0];
+ InputStream in = new BufferedInputStream(new FileInputStream(args[0]));
+ OutputStream out = (args.length == 1 ? System.out : new BufferedOutputStream(new FileOutputStream(args[1])));
+ //String fn = "C:/cygwin/home/wglp09/GeomConverter/test/org/lcsim/geometry/compact/sdjan03_compact.xml";
+ //InputStream in = new BufferedInputStream(new FileInputStream(fn));
+ //OutputStream out = new BufferedOutputStream(new FileOutputStream("C:/cygwin/home/wglp09/lelaps/lelaps/foo.godl"));
+ new Main(validateDefault).convert(fn,in,out);
+ }
+ Main(boolean validate) throws Exception
+ {
+ materials = new HashSet();
+ this.validate = validate;
+ }
+ public Main() throws Exception
+ {
+ this(validateDefault);
+ }
+ public void val(PrintStream p, String s, String t)
+ {
+ if (t != null) p.println(s + " = \"" + t + "\";");
+ else p.println(s + " = \"\";");
+ return;
+ }
+ public void vald(PrintStream p, String s, String t)
+ {
+ if (t != null) p.println(s + " = " + t + ";");
+ else p.println(s + " = 0;");
+ return;
+ }
+ public void valdc(PrintStream p, String s, String t)
+ {
+ if (t != null) p.println(s + " = " + t);
+ else p.println(s + " = 0;");
+ return;
+ }
+ public void val(PrintStream p, String s, double t)
+ {
+ p.println(s + " = " + t + ";");
+ return;
+ }
+ public void pval(PrintStream p, String s, String t)
+ {
+ if (t != null) p.println(s + " += \"" + t + "\";");
+ return;
+ }
+ public void pvald(PrintStream p, String s, String t)
+ {
+ if (t != null) p.println(s + " += " + t + ";");
+ return;
+ }
+ public void pval(PrintStream p, String s, double t)
+ {
+ p.println(s + " += " + t + ";");
+ return;
+ }
+ public void line(PrintStream p, String s)
+ {
+ if (s != null) p.println(s);
+ else p.println("");
+ return;
+ }
+ public void line(PrintStream p)
+ {
+ p.println("");
+ return;
+ }
+ public void preamble(PrintStream p, String inputFileName, Detector det)
+ {
+ line(p, "###");
+ line(p);
+ line(p, "# GeomConverter-generated GODL output");
+ line(p, "# -- GODL converter version 1.0 --");
+ line(p, "# From: " + inputFileName);
+ line(p);
+ line(p, "###");
+ line(p, "cm = 0.01 _meter;");
+ line(p, "m = _meter;");
+ line(p, "g = _gram;");
+ line(p, "atm = _atmosphere;");
+ line(p, "K = _kelvin;");
+ line(p, "T = _tesla;");
+ line(p, "deg = _degree;");
+ line(p, "unit(\"cm\", \"m\", \"g\", \"atm\", \"K\", \"T\", \"deg\");");
+ return;
+ }
+ public void header(PrintStream p, Detector det)
+ {
+ line(p, "#");
+ line(p, "# Header");
+ line(p, "#");
+
+ Header h = det.getHeader();
+ val(p, "detectorName ", h.getDetectorName());
+ val(p, "author ", h.getAuthor());
+ val(p, "detectorURL ", h.getURL());
+ val(p, "comment ", h.getComment());
+ val(p, "detectorVersion", h.getVersion());
+ return;
+ }
+ public void constants(PrintStream p, Detector det)
+ {
+ line(p, "#");
+ line(p, "# Constants");
+ line(p, "#");
+
+ Map<String,Constant> cl = det.getConstants();
+ Set<Map.Entry<String, Constant>> set = cl.entrySet();
+ for (Map.Entry<String, Constant> i: set)
+ {
+ val(p, "data_" + i.getKey(), i.getValue().getValue());
+ }
+ return;
+ }
+ public void materials(PrintStream p, Detector det)
+ {
+ line(p, "#");
+ line(p, "# Materials");
+ line(p, "#");
+ line(p, "vacuum = element(\"vacuum\");");
+ addMaterial("vacuum");
+ MaterialManager mm = MaterialManager.instance();
+ Map<String, Material> mmap = mm.materials();
+ for (Material i: mmap.values())
+ {
+ List<MaterialElement> el = i.getElements();
+ List<Double> elf = i.getMassFractions();
+ String formula = "";
+ if (el.size() == 1)
+ {
+ formula += el.get(0).getName();
+ vald(p, "mat_" + i.getName(), "element(\"" + formula + "\")");
+ }
+ else
+ {
+ for (int j = 0; j < el.size(); j++)
+ {
+ formula += el.get(j).getName();
+ formula += "" + elf.get(j);
+ }
+ vald(p, "mat_" + i.getName(), "compound(formula(\"" + formula + "\"), density("
+ + i.getRadiationLength()/i.getRadiationLengthWithDensity() + " g/cm3))");
+ }
+ addMaterial("mat_" + i.getName());
+ }
+ return;
+ }
+ public void fields(PrintStream p, Detector det)
+ {
+ line(p, "#");
+ line(p, "# Magnetic field");
+ line(p, "#");
+
+ Map<String, Field> fl = det.getFields();
+ for (Field f: fl.values())
+ {
+ double[] fi = {0., 0., 5.0};
+ double[] fo = {0., 0., -0.6};
+ double or = 5000.0;
+ double zm = 2810.0;
+ if (f instanceof Solenoid)
+ {
+ fi = ((Solenoid) f).getInnerField();
+ fo = ((Solenoid) f).getOuterField();
+ or = Math.sqrt(((Solenoid) f).getOuterRadius2());
+ zm = ((Solenoid) f).getZMax();
+ }
+ else
+ {
+ System.err.println(" -- Ignoring field " + f.getName() + ", GeomConverter doesn't support fields properly.");
+ System.err.println(" -- Using standard 5 tesla field");
+ }
+ line(p, "Field = cylinder(name(\"Secondary BField\"),");
+ line(p, " innerRadius(0.0 cm), outerRadius(" + or * 1.5 + " mm), length(" + 2 * zm + " mm),");
+ line(p, " bfield(" + fo[0] + " T, "+ fo[1] + " T, " + fo[2] + " T));");
+ line(p, "Field2 = cylinder(name(\"Main BField\"),");
+ line(p, " innerRadius(0.0), outerRadius(" + or + " mm), length(" + 2 * zm + " mm),");
+ line(p, " bfield(" + fi[0] + " T, "+ fi[1] + " T, " + fi[2] + " T));");
+ line(p, "Field += placement(@Field2);");
+ }
+ return;
+ }
+ public void readouts(PrintStream p, Detector det)
+ {
+ line(p, "#");
+ line(p, "# ID Codes (Readouts)");
+ line(p, "#");
+
+ Map<String, Readout> rl = det.getReadouts();
+ for (Readout r: rl.values())
+ {
+ IDDescriptor id = r.getIDDescriptor();
+ Segmentation seg = r.getSegmentation();
+ int theta_seg = 0;
+ int phi_seg = 0;
+ double x_seg = 0;
+ double y_seg = 0;
+ double z_seg = 0;
+ if (seg instanceof ProjectiveCylinder)
+ {
+ theta_seg = ((ProjectiveCylinder) seg).getThetaBins();
+ phi_seg = ((ProjectiveCylinder) seg).getPhiBins();
+ }
+ else if (seg instanceof NonprojectiveCylinder)
+ {
+ z_seg = ((NonprojectiveCylinder) seg).getGridSizeZ();
+ phi_seg = (int) (2 * Math.PI / ((NonprojectiveCylinder) seg).getGridSizePhi());
+ }
+ else if (seg instanceof ProjectiveZPlane)
+ {
+ theta_seg = ((ProjectiveZPlane) seg).getThetaBins();
+ phi_seg = ((ProjectiveZPlane) seg).getPhiBins();
+ }
+ else if (seg instanceof GridXYZ)
+ {
+ x_seg = ((GridXYZ) seg).getGridSizeX();
+ y_seg = ((GridXYZ) seg).getGridSizeY();
+ z_seg = ((GridXYZ) seg).getGridSizeZ();
+ }
+
+ String rname = r.getName();
+ val(p, rname, "x: fp0 y: fp1 z: fp2 layer: d3 0 0");
+ boolean usingfirst = true;
+ int rotations = 0;
+ for (int i = 0; i < id.fieldCount(); i++)
+ {
+ String name = id.fieldName(i);
+ int start = id.fieldStart(i);
+ int length = id.fieldLength(i);
+ if (length < 0)
+ {
+ length = - length;
+ }
+ String code = "";
+ if (name.equals("layer"))
+ {
+ code = " layer 1 " + length + " bitshift 1 sub and";
+ }
+ else if (name.equals("system"))
+ {
+ code = " system 1 " + length + " bitshift 1 sub and";
+ }
+ else if (name.equals("barrel"))
+ {
+ //
+ // Note that barrel may be one or zero. If 1, then we make it 2 if z < 0.
+ //
+ code = " barrel barrel z neg H truncate mul add 1 " + length + " bitshift 1 sub and";
+ }
+ else if(name.equals("theta"))
+ {
+ code = " x x mul y y mul add sqrt z atan2 " + theta_seg +
+ " mul _pi div truncate 1 " + length + " bitshift 1 sub and";
+ }
+ else if(name.equals("phi"))
+ {
+ code = " y x atan2m " + phi_seg +
+ " mul 0.5 mul _pi div truncate 1 " + length +
+ " bitshift 1 sub and";
+ }
+ else if(name.equals("x"))
+ {
+ code = " x " + x_seg + " div truncate 1 " + length + " bitshift 1 sub and";
+ }
+ else if(name.equals("y"))
+ {
+ code = " y " + y_seg + " div truncate 1 " + length + " bitshift 1 sub and";
+ }
+ else if(name.equals("z"))
+ {
+ code = " z " + z_seg + " div truncate 1 " + length + " bitshift 1 sub and";
+ }
+ if (start > 31)
+ {
+ code = " exch" + code;
+ usingfirst = false;
+ start -= 32;
+ }
+ if (start > 0) code += " " + start + " bitshift";
+ code += " or";
+ if (!usingfirst)
+ {
+ usingfirst = true;
+ code += " exch";
+ }
+ pval(p, rname, code);
+ }
+ }
+ return;
+ }
+ String findMaterial(PrintStream p, Layer layer)
+ {
+ List<LayerSlice> lslist = layer.getSlices();
+ String material = "mat_";
+ int nslices = 0;
+ for (LayerSlice lsl: lslist)
+ {
+ String partname = lsl.getMaterial().getName();
+ material += partname;
+ nslices++;
+ }
+ //
+ // Make a new material if this one doesn't exist yet
+ //
+ if (nslices > 1 && !existsMaterial(material))
+ {
+ valdc(p, material, "mixture(name(\"" + material + "\"),");
+ for (LayerSlice lsl: lslist)
+ {
+ double t = lsl.getThickness();
+ String partname = lsl.getMaterial().getName();
+ line(p, " part(@mat_" + partname + ", fraction(" + t + ")),");
+ }
+ line(p, " by(\"volume\")");
+ line(p, ");");
+ addMaterial(material);
+ }
+ return(material);
+ }
+ public void beampipe(PrintStream p, Detector det)
+ {
+ line(p, "#");
+ line(p, "# Since the GODL converter does not yet support polycone beampipes,");
+ line(p, "# we supply here a generic beampipe plus various masks");
+ line(p, "# These were taken from the SiDMay05.xml compact description,");
+ line(p, "#");
+ vald(p, "Be", "element(\"Be\");");
+ vald(p, "Ti", "element(\"Ti\");");
+ vald(p, "W", "element(\"W\");");
+ // Beam pipe:
+ //<constant name="tracking_region_zmax" value="167.9*cm" />
+ vald(p, "tracking_region_zmax", "167.9 cm");
+ //<zplane rmin="tracking_region_zmax*17./351" rmax="(tracking_region_zmax*17./351+.1)" z="-tracking_region_zmax" />
+ //<zplane rmin="1.2*cm" rmax="1.3*cm" z="-6.251*cm" />
+ line(p, "zmin = -tracking_region_zmax;");
+ line(p, "zmax = -6.251 cm;");
+ line(p, "length = zmax - zmin;");
+ line(p, "offset = zmin + 0.5 * length;");
+ line(p, "Pipe1 = cone(name(\"Pipe1\"),");
+ line(p, " innerBottomRadius(tracking_region_zmax * 17.0/351.0),");
+ line(p, " outerBottomRadius(tracking_region_zmax * 17.0/351.0 + 0.1 cm),");
+ line(p, " innerTopRadius(1.2 cm),");
+ line(p, " outerTopRadius(1.3 cm),");
+ line(p, " length(length), @Be);");
+ line(p, "World += placement(@Pipe1);");
+ //<zplane rmin="1.2*cm" rmax="1.225*cm" z="-6.25*cm" />
+ line(p, "zmin = zmax;");
+ line(p, "zmax = -6.25 cm;");
+ line(p, "length = zmax - zmin;");
+ line(p, "offset = zmin + 0.5 * length;");
+ line(p, "Pipe2 = cone(name(\"Pipe2\"),");
+ line(p, " innerBottomRadius(1.2 cm),");
+ line(p, " outerBottomRadius(1.3 cm),");
+ line(p, " innerTopRadius(1.2 cm),");
+ line(p, " outerTopRadius(1.225 cm),");
+ line(p, " length(length), @Be);");
+ line(p, "World += placement(@Pipe2);");
+ //<zplane rmin="1.2*cm" rmax="1.225*cm" z="6.25*cm" />
+ line(p, "zmin = zmax;");
+ line(p, "zmax = 6.25 cm;");
+ line(p, "length = zmax - zmin;");
+ line(p, "offset = zmin + 0.5 * length;");
+ line(p, "Pipe3 = cylinder(name(\"Pipe3\"),");
+ line(p, " innerRadius(1.2 cm),");
+ line(p, " outerRadius(1.225 cm),");
+ line(p, " length(length), @Be);");
+ line(p, "World += placement(@Pipe3);");
+ //<zplane rmin="1.2*cm" rmax="1.3*cm" z="6.251*cm" />
+ line(p, "zmin = zmax;");
+ line(p, "zmax = 6.251 cm;");
+ line(p, "length = zmax - zmin;");
+ line(p, "offset = zmin + 0.5 * length;");
+ line(p, "Pipe4 = cone(name(\"Pipe4\"),");
+ line(p, " innerBottomRadius(1.2 cm),");
+ line(p, " outerBottomRadius(1.225 cm),");
+ line(p, " innerTopRadius(1.2 cm),");
+ line(p, " outerTopRadius(1.3 cm),");
+ line(p, " length(length), @Be);");
+ line(p, "World += placement(@Pipe4);");
+ //<zplane rmin="tracking_region_zmax*17./351" rmax="(tracking_region_zmax*17./351+.1)" z="tracking_region_zmax" />
+ line(p, "zmin = zmax;");
+ line(p, "zmax = tracking_region_zmax;");
+ line(p, "length = zmax - zmin;");
+ line(p, "offset = zmin + 0.5 * length;");
+ line(p, "Pipe5 = cone(name(\"Pipe5\"),");
+ line(p, " innerBottomRadius(1.2 cm),");
+ line(p, " outerBottomRadius(1.3 cm),");
+ line(p, " innerTopRadius(tracking_region_zmax * 17.0/351.0),");
+ line(p, " outerTopRadius(tracking_region_zmax * 17.0/351.0 + 0.1 cm),");
+ line(p, " length(length), @Be);");
+ line(p, "World += placement(@Pipe5);");
+ // Liner:
+ //<zplane z="-6.25*cm" rmin="1.195*cm" rmax="1.20*cm" />
+ //<zplane z="6.25*cm" rmin="1.195*cm" rmax="1.20*cm" />
+ line(p, "zmin = -6.25 cm;");
+ line(p, "zmax = 6.25 cm;");
+ line(p, "length = zmax - zmin;");
+ line(p, "offset = zmin + 0.5 * length;");
+ line(p, "Pipe_Inner_Shield = cylinder(name(\"Pipe inner shield\"),");
+ line(p, " innerRadius(1.195 cm), outerRadius(1.2 cm),");
+ line(p, " length(length), @Ti);");
+ line(p, "World += placement(@Pipe_Inner_Shield, translate(0, 0, offset));");
+ line(p, "#");
+ line(p, "# Masks");
+ line(p, "#");
+ //<zplane rmin="8.0*cm" rmax="19.0*cm" z="200.0*cm" />
+ //<zplane rmin="15.0*cm" rmax="19.0*cm" z="315.0*cm" />
+ line(p, "zmin = 200.0 cm;");
+ line(p, "zmax = 315.0 cm;");
+ line(p, "length = zmax - zmin;");
+ line(p, "offset = zmin + 0.5 * length;");
+ line(p, "Mask_Cone = cone(name(\"Mask cone\"),");
+ line(p, " innerBottomRadius(8.0 cm), outerBottomRadius(19.0 cm),");
+ line(p, " innerTopRadius(15 cm), outerTopRadius(19.0 cm),");
+ line(p, " length(length), @W, type(\"mask\"));");
+ line(p, "World += placement(@Mask_Cone, translate(0, 0, offset));");
+ line(p, "World += placement(@Mask_Cone, rotate(axis(\"x\"), angle(180 deg)), translate(0, 0, -offset));");
+ return;
+ }
+ public void detectors(PrintStream p, Detector det)
+ {
+ line(p, "#");
+ line(p, "# Detector and subdetectors");
+ line(p, "# First create a world cylinder from the box coordinates already specified");
+ line(p, "#");
+ line(p, "data_world_r = sqrt(data_world_x * data_world_x + data_world_y * data_world_y) / 4.0;");
+ line(p, "World = cylinder(name(detectorName), radius(data_world_r mm), length(data_world_z mm), @vacuum);");
+ line(p, "#");
+ line(p, "# Now create other detectors and add them to the world");
+ line(p, "#");
+ Map<String, Subdetector> dl = det.getSubdetectors();
+ for (Subdetector s: dl.values())
+ {
+ if (s instanceof CylindricalBarrelCalorimeter)
+ {
+ CylindricalBarrelCalorimeter m = (CylindricalBarrelCalorimeter) s;
+ String name = m.getName();
+ int sysid = m.getSystemID();
+ String rname = m.getReadout().getName();
+ double innerR = m.getInnerRadius();
+ double outerR = m.getOuterRadius();
+ double zmin = m.getZMin();
+ double zmax = m.getZMax();
+ LayerStack ls = m.getLayering().getLayerStack();
+ int nlayers = ls.getNumberOfLayers();
+
+ Layer layer = ls.getLayer(0);
+ boolean sensitive = layer.findIndexOfFirstSensitiveSlice() != -1;
+ String material = findMaterial(p, layer);
+
+ valdc(p, name, "cylinder(name(\"" + name + "\"), ");
+ line(p, " length(" + (zmax - zmin) + " mm), ");
+ line(p, " innerRadius(" + innerR + " mm),");
+ line(p, " outerRadius(" + outerR + " mm),");
+ line(p, " nLayers(" + nlayers + "),");
+ String comma = "";
+ if (sensitive) comma = ",";
+ String type = "hadcal";
+ if (name.startsWith("EM") || name.startsWith("LUM")) type = "emcal";
+ line(p, " @" + material + ", type(\"" + type + "\")" + comma);
+ if (sensitive)
+ {
+ line(p, " idCode(code(" + rname + "),");
+ line(p, " data(\"system\", " + sysid + "),");
+ line(p, " data(\"barrel\", 0)");
+ line(p, " )");
+ }
+ line(p, ");");
+ line(p, "World += placement(@" + name + ", translate(0, 0, " + (0.5 * (zmax + zmin)) + " mm));");
+ }
+ else if (s instanceof CylindricalEndcapCalorimeter)
+ {
+ CylindricalEndcapCalorimeter m = (CylindricalEndcapCalorimeter) s;
+ String name = m.getName();
+ int sysid = m.getSystemID();
+ boolean reflect = m.getReflect();
+ String rname = m.getReadout().getName();
+ double innerR = m.getInnerRadius();
+ double outerR = m.getOuterRadius();
+ double zmin = m.getZMin();
+ double zmax = m.getZMax();
+ LayerStack ls = m.getLayering().getLayerStack();
+ int nlayers = ls.getNumberOfLayers();
+
+ Layer layer = ls.getLayer(0);
+ boolean sensitive = layer.findIndexOfFirstSensitiveSlice() != -1;
+ String material = findMaterial(p, layer);
+
+ valdc(p, name, "cylinder(name(\"" + name + "\"), ");
+ line(p, " length(" + (zmax - zmin) + " mm), ");
+ line(p, " innerRadius(" + innerR + " mm),");
+ line(p, " outerRadius(" + outerR + " mm),");
+ line(p, " nSlices(" + nlayers + "),");
+ String comma = "";
+ if (sensitive) comma = ",";
+ String type = "hadcal";
+ if (name.startsWith("EM") || name.startsWith("LUM")) type = "emcal";
+ line(p, " @" + material + ", type(\"" + type + "\")" + comma);
+ if (sensitive)
+ {
+ line(p, " idCode(code(" + rname + "),");
+ line(p, " data(\"system\", " + sysid + "),");
+ line(p, " data(\"barrel\", 1)");
+ line(p, " )");
+ }
+ line(p, ");");
+ line(p, "World += placement(@" + name + ", translate(0, 0, " + (0.5 * (zmax + zmin)) + " mm));");
+ if (reflect)
+ {
+ line(p, "World += placement(@" + name
+ + ", rotate(axis(\"x\"), angle(180 deg)), translate(0, 0, "
+ + (- 0.5 * (zmax + zmin)) + " mm));");
+ }
+ }
+ else if (s instanceof DiskTracker)
+ {
+ DiskTracker m = (DiskTracker) s;
+ String name = m.getName();
+ int sysid = m.getSystemID();
+ boolean reflect = m.getReflect();
+ String rname = m.getReadout().getName();
+ double[] innerR = m.getInnerR();
+ double[] outerR = m.getOuterR();
+ double[] innerZ = m.getInnerZ();
+ LayerStack ls = m.getLayering().getLayerStack();
+ int nlayers = ls.getNumberOfLayers();
+
+ for (int i = 0; i < nlayers; i++)
+ {
+ Layer layer = ls.getLayer(i);
+ double thickness = layer.getThickness();
+ boolean sensitive = layer.findIndexOfFirstSensitiveSlice() != -1;
+ String material = findMaterial(p, layer);
+
+ String detname = name;
+ if (nlayers > 1) detname += "." + i;
+
+ valdc(p, detname, "cylinder(name(\"" + name + "\"), ");
+ line(p, " length(" + thickness + " mm), ");
+ line(p, " innerRadius(" + innerR[i] + " mm),");
+ line(p, " outerRadius(" + outerR[i] + " mm),");
+ String comma = "";
+ if (sensitive) comma = ", ";
+ line(p, " @" + material + ", type(\"tracker\")" + comma);
+ if (sensitive)
+ {
+ line(p, " idCode(code(" + rname + "),");
+ line(p, " data(\"layer\", " + i + "),");
+ line(p, " data(\"system\", " + sysid + "),");
+ line(p, " data(\"barrel\", 1)");
+ line(p, " )");
+ }
+ line(p, ");");
+ line(p, "World += placement(@" + detname + ", translate(0, 0, " + (innerZ[i] + 0.5 * thickness) + " mm));");
+ if (reflect)
+ {
+ line(p, "World += placement(@" + detname
+ + ", rotate(axis(\"x\"), angle(180 deg)), translate(0, 0, "
+ + (- innerZ[i] - 0.5 * thickness) + " mm));");
+ }
+ }
+ }
+ else if (s instanceof MultiLayerTracker)
+ {
+ MultiLayerTracker m = (MultiLayerTracker) s;
+ String name = m.getName();
+ int sysid = m.getSystemID();
+ String rname = m.getReadout().getName();
+ double[] innerR = m.getInnerR();
+ double[] outerZ = m.getOuterZ();
+ LayerStack ls = m.getLayering().getLayerStack();
+ int nlayers = ls.getNumberOfLayers();
+
+ for (int i = 0; i < nlayers; i++)
+ {
+ Layer layer = ls.getLayer(i);
+ double thickness = layer.getThickness();
+ boolean sensitive = layer.findIndexOfFirstSensitiveSlice() != -1;
+ String material = findMaterial(p, layer);
+
+ String detname = name;
+ if (nlayers > 1) detname += "." + i;
+
+ valdc(p, detname, "cylinder(name(\"" + name + "\"), ");
+ line(p, " length(" + outerZ[i] * 2 + " mm), ");
+ line(p, " innerRadius(" + innerR[i] + " mm),");
+ line(p, " outerRadius(" + (innerR[i] + thickness) + " mm),");
+ String comma = "";
+ if (sensitive) comma = ", ";
+ line(p, " @" + material + ", type(\"tracker\")" + comma);
+ if (sensitive)
+ {
+ line(p, " idCode(code(" + rname + "),");
+ line(p, " data(\"layer\", " + i + "),");
+ line(p, " data(\"system\", " + sysid + "),");
+ line(p, " data(\"barrel\", 0)");
+ line(p, " )");
+ }
+ line(p, ");");
+ line(p, "World += placement(@" + detname + ");");
+ }
+ }
+ }
+ return;
+ }
+
+ public void convert(String inputFileName, InputStream in, OutputStream out) throws Exception
+ {
+ if ( out != null )
+ {
+ GeometryReader reader = new GeometryReader();
+ Detector det = reader.read(in);
+ PrintStream p = new PrintStream(out);
+
+ preamble(p, inputFileName, det);
+ header(p, det);
+ constants(p, det);
+ materials(p, det);
+ fields(p, det);
+ readouts(p, det);
+ detectors(p, det);
+ beampipe(p, det);
+
+ line(p, "#");
+ line(p, "# End of file");
+ line(p, "#");
+
+ out.close();
+ }
+ return;
+ }
+
+ private static void usage()
+ {
+ System.out.println("java "+Main.class.getName()+" <compact> [<GODL>]");
+ System.exit(0);
+ }
+
+ public String getOutputFormat()
+ {
+ return "GODL";
+ }
+
+ public FileFilter getFileFilter()
+ {
+ return new GODLFileFilter();
+ }
+
+ private static class GODLFileFilter extends FileFilter
+ {
+ public boolean accept(java.io.File file)
+ {
+ return file.isDirectory() || file.getName().endsWith(".godl");
+ }
+
+ public String getDescription()
+ {
+ return "GODL file (*.godl)";
+ }
+ }
+}
\ No newline at end of file