Commit in GeomConverter/src/org/lcsim on MAIN
geometry/subdetector/SiTrackerFixedTarget2.java+32added 1.1
                    /SiTrackerFixedTarget.java+32added 1.1
detector/converter/compact/SiTrackerFixedTarget2ConverterBarrel.java+565added 1.1
                          /SiTrackerFixedTarget2Converter.java+343added 1.1
                          /SiTrackerFixedTargetConverter.java+339added 1.1
                          /DetectorConverter.java+21.47 -> 1.48
geometry/compact/converter/lcdd/SiTrackerFixedTarget.java+219added 1.1
                               /SiTrackerFixedTarget2.java+222added 1.1
+1754
7 added + 1 modified, total 8 files
FixedTarget geometries

GeomConverter/src/org/lcsim/geometry/subdetector
SiTrackerFixedTarget2.java added at 1.1
diff -N SiTrackerFixedTarget2.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SiTrackerFixedTarget2.java	21 Jan 2010 21:26:31 -0000	1.1
@@ -0,0 +1,32 @@
+package org.lcsim.geometry.subdetector;
+
+import hep.graphics.heprep.HepRep;
+import hep.graphics.heprep.HepRepFactory;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.detector.converter.heprep.DetectorElementToHepRepConverter;
+
+public class SiTrackerFixedTarget2 extends AbstractTracker
+{
+    SiTrackerFixedTarget2(Element node) throws JDOMException
+    {
+        super(node);
+    }
+
+    public void appendHepRep(HepRepFactory factory, HepRep heprep)
+    {
+//        System.out.println("Have a FixedTarget element");
+    	DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, 0, 4);
+    }
+    
+    public boolean isEndcap()
+    {
+        return false;
+    }  
+    public boolean isBarrel()
+    {
+        return true;
+    }
+
+}
\ No newline at end of file

GeomConverter/src/org/lcsim/geometry/subdetector
SiTrackerFixedTarget.java added at 1.1
diff -N SiTrackerFixedTarget.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SiTrackerFixedTarget.java	21 Jan 2010 21:26:31 -0000	1.1
@@ -0,0 +1,32 @@
+package org.lcsim.geometry.subdetector;
+
+import hep.graphics.heprep.HepRep;
+import hep.graphics.heprep.HepRepFactory;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.detector.converter.heprep.DetectorElementToHepRepConverter;
+
+public class SiTrackerFixedTarget extends AbstractTracker
+{
+    SiTrackerFixedTarget(Element node) throws JDOMException
+    {
+        super(node);
+    }
+
+    public void appendHepRep(HepRepFactory factory, HepRep heprep)
+    {
+//        System.out.println("Have a FixedTarget element");
+    	DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, 0, 4);
+    }
+    
+    public boolean isEndcap()
+    {
+        return false;
+    }  
+    public boolean isBarrel()
+    {
+        return true;
+    }
+
+}
\ No newline at end of file

GeomConverter/src/org/lcsim/detector/converter/compact
SiTrackerFixedTarget2ConverterBarrel.java added at 1.1
diff -N SiTrackerFixedTarget2ConverterBarrel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SiTrackerFixedTarget2ConverterBarrel.java	21 Jan 2010 21:26:31 -0000	1.1
@@ -0,0 +1,565 @@
+package org.lcsim.detector.converter.compact;
+
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IPhysicalVolumePath;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.ITranslation3D;
+import org.lcsim.detector.LogicalVolume;
+import org.lcsim.detector.PhysicalVolume;
+import org.lcsim.detector.RotationPassiveXYZ;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
+import org.lcsim.detector.RotationGeant;
+import org.lcsim.detector.identifier.ExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.identifier.IIdentifierHelper;
+import org.lcsim.detector.identifier.IdentifierDictionaryManager;
+import org.lcsim.detector.identifier.IdentifierUtil;
+import org.lcsim.detector.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.solids.Box;
+import org.lcsim.detector.solids.ISolid;
+import org.lcsim.detector.solids.Trd;
+import org.lcsim.detector.solids.Tube;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
+import org.lcsim.detector.tracker.silicon.SiTrackerLayer;
+import org.lcsim.detector.tracker.silicon.SiTrackerModule;
+import org.lcsim.geometry.compact.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.subdetector.SiTrackerBarrel;
+
+public class SiTrackerFixedTarget2ConverterBarrel
+        extends AbstractSubdetectorConverter
+        implements ISubdetectorConverter {
+
+    public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap) {
+        return new SiTrackerIdentifierHelper(
+                subdetector.getDetectorElement(),
+                makeIdentifierDictionary(subdetector),
+                systemMap);
+    }
+
+    public void convert(Subdetector subdet, Detector detector) {
+        Map<String, ILogicalVolume> modules = buildModules(subdet);
+
+        try {
+            buildLayers(detector, subdet, modules);
+        } catch (DataConversionException x) {
+            throw new RuntimeException(x);
+        }
+
+        setupSensorDetectorElements(subdet);
+    }
+
+    private Map<String, ILogicalVolume> buildModules(Subdetector subdet) {
+        Map<String, ILogicalVolume> modules = new HashMap<String, ILogicalVolume>();
+
+        Element subdetElement = subdet.getNode();
+
+        for (Iterator i = subdetElement.getChildren("module").iterator(); i.hasNext();) {
+            Element module = (Element) i.next();
+            String module_name = module.getAttributeValue("name");
+            ILogicalVolume module_envelope;
+            try {
+                module_envelope = buildModule(subdetElement, module_name);
+                modules.put(module_name, module_envelope);
+            } catch (Exception x) {
+                throw new RuntimeException(x);
+            }
+        }
+
+        return modules;
+    }
+
+    private ILogicalVolume buildModule(Element subdetElement, String module_name) throws Exception {
+        String subdetName = subdetElement.getAttributeValue("name");
+        ILogicalVolume moduleLogVol = null;
+
+        Element moduleElement = null;
+        for (Iterator i = subdetElement.getChildren("module").iterator(); i.hasNext();) {
+            Element moduleCheck = (Element) i.next();
+            if (moduleCheck.getAttributeValue("name").compareTo(module_name) == 0) {
+                moduleElement = moduleCheck;
+            }
+        }
+        if (moduleElement == null) {
+            throw new RuntimeException("module <" + module_name + " was not found");
+        }
+
+        Element moduleEnvelopeElement = moduleElement.getChild("module_envelope");
+
+        // Create the module box.
+        double moduleLength = moduleEnvelopeElement.getAttribute("length").getDoubleValue();
+        double moduleWidth = moduleEnvelopeElement.getAttribute("width").getDoubleValue();
+        double moduleThickness = moduleEnvelopeElement.getAttribute("thickness").getDoubleValue();
+        ISolid moduleBox =
+                new Box(module_name + "_box",
+                moduleWidth / 2,
+                moduleLength / 2,
+                moduleThickness / 2);
+
+        // Create the module logical volume.
+        IMaterial air = MaterialStore.getInstance().get("Air");
+        moduleLogVol = new LogicalVolume(module_name, moduleBox, air);
+
+        int componentNumber = 0;
+        for (Iterator j = moduleElement.getChildren("module_component").iterator(); j.hasNext(); ++componentNumber) {
+            Element componentElement = (Element) j.next();
+
+            boolean sensitive = ((componentElement.getAttribute("sensitive") == null) ? false : componentElement.getAttribute("sensitive").getBooleanValue());
+
+            String componentName = module_name + "_component" + componentNumber;
+
+            // Create the box solid for the module component.
+            double componentLength = componentElement.getAttribute("length").getDoubleValue();
+            double componentWidth = componentElement.getAttribute("width").getDoubleValue();
+            double componentThickness = componentElement.getAttribute("thickness").getDoubleValue();
+            ISolid componentBox =
+                    new Box(componentName,
+                    componentWidth / 2,
+                    componentLength / 2,
+                    componentThickness / 2);
+
+            IMaterial componentMaterial =
+                    MaterialStore.getInstance().get(componentElement.getAttributeValue("material"));
+
+            // Create the volume for the module component.
+            ILogicalVolume componentLogVol =
+                    new LogicalVolume(componentName, componentBox, componentMaterial);
+
+            // Set component position.
+            double px = 0, py = 0, pz = 0;
+
+            if (componentElement.getChild("position") != null) {
+                Element pos_elem = componentElement.getChild("position");
+
+                if (pos_elem.getAttribute("x") != null) {
+                    px = pos_elem.getAttribute("x").getDoubleValue();
+                }
+
+                if (pos_elem.getAttribute("y") != null) {
+                    py = pos_elem.getAttribute("y").getDoubleValue();
+                }
+
+                if (pos_elem.getAttribute("z") != null) {
+                    pz = pos_elem.getAttribute("z").getDoubleValue();
+                }
+            }
+
+            ITranslation3D pos = new Translation3D(px, py, pz);
+
+            // Set component rotation.
+            double rx = 0, ry = 0, rz = 0;
+
+            if (componentElement.getChild("rotation") != null) {
+                Element rot_elem = componentElement.getChild("rotation");
+
+                if (rot_elem.getAttribute("x") != null) {
+                    rx = rot_elem.getAttribute("x").getDoubleValue();
+                }
+
+                if (rot_elem.getAttribute("y") != null) {
+                    ry = rot_elem.getAttribute("y").getDoubleValue();
+                }
+
+                if (rot_elem.getAttribute("z") != null) {
+                    rz = rot_elem.getAttribute("z").getDoubleValue();
+                }
+            }
+
+            IRotation3D rot = new RotationPassiveXYZ(rx, ry, rz);
+
+            // Make transform
+            Transform3D componentTransform = new Transform3D(pos, rot);
+
+            PhysicalVolume componentPhysVol =
+                    new PhysicalVolume(
+                    componentTransform,
+                    componentName,
+                    componentLogVol,
+                    moduleLogVol,
+                    componentNumber);
+
+            if (sensitive) {
+                componentPhysVol.setSensitive(true);
+            }
+
+            ++componentNumber;
+        }
+
+        return moduleLogVol;
+    }
+
+    private void buildLayers(
+            Detector detector,
+            Subdetector subdet,
+            Map<String, ILogicalVolume> modules) throws DataConversionException {
+        Element node = subdet.getNode();
+        String detector_name = subdet.getName();
+
+//      Build the layers.
+        //int nlayer = 0;        
+        for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {
+            // Get the next layer element.
+            Element layer_element = (Element) i.next();
+
+            int layern = layer_element.getAttribute("id").getIntValue();
+
+            // Get the reference to the module from the layer.
+            String module_name = layer_element.getAttributeValue("module");
+
+            // Get the logical volume for the module.
+            ILogicalVolume moduleEnvelope = modules.get(module_name);
+
+            // Get the barrel_envelope for this layer.
+            Element barrel_envelope = layer_element.getChild("barrel_envelope");
+
+            // Inner radius of layer.
+            double ir = barrel_envelope.getAttribute("inner_x").getDoubleValue();
+
+            // Outer radius of layer.
+            double or = barrel_envelope.getAttribute("outer_x").getDoubleValue();
+
+            // Full length in z of layer.
+            double oz = barrel_envelope.getAttribute("z_length").getDoubleValue();
+            double oy = barrel_envelope.getAttribute("y_length").getDoubleValue();
+
+            // Name of this layer including layer number.
+            String layer_name = detector_name + "_layer" + layern;
+
+            //System.out.println("layer_name=" + layer_name);
+            // make the trapazoid...
+            double dx1, dx2;
+            dx1 = dx2 = (or - ir) / 2;
+            Trd layer_trd= new Trd(layer_name + "_trd", dx1, dx2, oy, oy, oz);
+            Translation3D p = new Translation3D(ir, 0, 0);
+            RotationGeant rot = new RotationGeant(0, 0, -Math.PI / 2);
+           Transform3D trans=         new Transform3D(p, rot);
+            Tube layer_tube = new Tube(
+                    layer_name + "_tube",
+                    ir,
+                    or,
+                    oz / 2);
+
+            // Create the layer envelope volume.
+            IMaterial air = MaterialStore.getInstance().get("Air");
+            ILogicalVolume layer_volume =
+                    new LogicalVolume(layer_name, layer_trd, air);
+
+            // Layer PhysicalVolume.
+            IPhysicalVolume layer_envelope_physvol =
+                    new PhysicalVolume(
+                    trans,
+                    layer_name,
+                    layer_volume,
+                    detector.getTrackingVolume().getLogicalVolume(),
+                    layern);
+
+            // Layer DE.
+            String layerPath = "/tracking_region/" + layer_name;
+            IDetectorElement layerDE =
+                    new SiTrackerLayer(layer_name, subdet.getDetectorElement(), layerPath, layern);
+
+            // Get the layout element.
+            Element layout = layer_element.getChild("layout");
+
+            // angle with respect to x (beam) axis of first module.
+            double xTilt = layout.getAttribute("xTilt").getDoubleValue();
+
+            // Number of modules in y.
+            int ny = layout.getAttribute("ny").getIntValue();
+            assert (ny > 0);
+             // Number of modules in z.
+            int nz = layout.getAttribute("nz").getIntValue();
+            assert (nz > 0);
+
+            // Radius of the module center.
+            double xCent = layout.getAttribute("xCent").getDoubleValue();
+
+             // Radius of the module center.
+            double zGap = layout.getAttribute("zgap").getDoubleValue();
+
+            // The delta radius of every other module.
+            double dx = 0.0;
+            if (layout.getAttribute("dx") != null) {
+                dx = layout.getAttribute("dx").getDoubleValue();
+            }
+
+            // y increment for one module.
+//            double phi_incr = (Math.PI * 2) / nphi;
+
+            // Phi of the module center.
+            double phic = 0;
+//            phic += phi0;
+
+     
+
+            // Z increment for module placement along Z axis.
+            // Adjust for z0 at center of module rather than
+            // the end of cylindrical envelope.
+//            double z_incr = (2.0 * z0) / (nz - 1);
+
+            // Starting z for module placement along Z axis.
+//            double module_z = -z0;
+
+            // DEBUG
+            //System.out.println("layer ir=" + ir);
+            //System.out.println("layer or=" + or);
+            //System.out.println("layer oz=" + oz);
+            //System.out.println("phi_tilt=" + phi_tilt);
+            //System.out.println("rc=" + rc);
+            //System.out.println("phi0=" + phi0);
+            //System.out.println("module z_incr=" + z_incr);
+            //System.out.println("module z0=" + z0);
+            //System.out.println("module nz=" + nz);
+            //System.out.println("module dr=" + dr);
+            //
+
+            //String module_lkp_name = layer.getAttributeValue("module");
+
+            int moduleId = 0;
+
+            // Loop over the number of modules in phi.
+ //           for (int phicount = 0; phicount < nphi; phicount++) {
+                // Delta x of module position.
+ ///               double dx = z_dr * cos(phic + phi_tilt);
+
+                // Delta y of module position.
+   //             double dy = z_dr * sin(phic + phi_tilt);
+
+                // Basic x module position.
+//                double x = rc * cos(phic);
+
+                // Basic y module position.
+  //              double y = rc * sin(phic);
+
+                // Loop over the number of modules in z.
+                for (int zcount = 0; zcount < nz; zcount++) {
+                    // Create a unique name for the module in this logical volume, layer, phi, and z.
+   //                 String module_place_name = detector_name + "_layer" + layern + "_phi" + phicount + "_z" + zcount;
+
+     //               double z = module_z;
+
+                    // DEBUG
+                    //System.out.println("module build...");
+                    //System.out.println("module nphi=" + ii);
+                    //System.out.println("module nz" + j);
+                    //System.out.println("module x=" + x);
+                    //System.out.println("module y=" + y);
+                    //System.out.println("module z=" + z);
+                    // DEBUG
+/*
+                    // Position of module.
+                    //Position module_position = new Position(module_place_name + "_position");
+                    ITranslation3D module_position = new Translation3D(x, y, z);
+
+                    /*
+                    from the LCDD converter
+
+                    double rotx = Math.PI / 2;
+                    double roty = -((Math.PI / 2) - phic - phi_tilt);
+                    double rotz = 0;
+
+                     /*
+
+                    // Rotation of module.
+
+                    // FIXME:  The Y and Z rotations are switched around from
+                    //         the LCDD / Geant4 convention.  Seems like an
+                    //         active versus passive problem.
+                    double rotx = Math.PI / 2;
+                    double roty = 0;
+                    double rotz = ((Math.PI / 2) - phic - phi_tilt);
+
+
+                    IRotation3D module_rotation = new RotationPassiveXYZ(rotx, roty, rotz);
+
+                    //System.out.println("module rotx=" + rotx);
+                    //System.out.println("module roty=" + roty);
+                    //System.out.println("module rotz=" + rotz);
+
+                    Transform3D moduleTransform = new Transform3D(module_position, module_rotation);
+
+                    // Module PhysicalVolume.
+                    IPhysicalVolume module_physvol =
+                            new PhysicalVolume(
+                            moduleTransform,
+                            module_place_name,
+                            moduleEnvelope,
+                            layer_volume,
+                            moduleId);
+
+                    String modulePath =
+                            "/tracking_region/" + layer_name + "/" + module_place_name;
+
+                    new SiTrackerModule(
+                            module_place_name,
+                            layerDE,
+                            modulePath,
+                            moduleId);
+
+                    // Increment the by-layer module number.
+                    ++moduleId;
+
+                    // Adjust the x and y coordinates of the module.
+                    x += dx;
+                    y += dy;
+
+                    // Flip sign of x and y adjustments.
+                    dx *= -1;
+                    dy *= -1;
+
+                    // Add z increment to get next z placement pos.
+                    module_z += z_incr;
+
+                //System.out.println();
+                }
+
+                // Increment the phi placement of module.
+                phic += phi_incr;
+
+                // Increment the center radius according to dr parameter.
+                rc += rphi_dr;
+
+                // Flip sign of dr parameter.
+                rphi_dr *= -1;
+
+                // Reset the Z placement parameter for module.
+                module_z = -z0;
+  */
+        }
+        }
+    }
+
+    public Class getSubdetectorType() {
+        return SiTrackerBarrel.class;
+    }
+
+    private void setupSensorDetectorElements(Subdetector subdet) {
+        int moduleId = 0;
+        for (IDetectorElement layer : subdet.getDetectorElement().getChildren()) {
+            for (IDetectorElement module : layer.getChildren()) {
+                IPhysicalVolumePath modulePath =
+                        module.getGeometry().getPath();
+
+                IPhysicalVolume modulePhysVol =
+                        modulePath.getLeafVolume();
+
+                int sensorId = 0;
+                for (IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters()) {
+                    // Create the identifier for this sensor.
+                    if (pv.isSensitive()) {
+                        IIdentifierDictionary iddict =
+                                IdentifierDictionaryManager.getInstance().
+                                getIdentifierDictionary(subdet.getReadout().getName());
+
+                        ExpandedIdentifier expId = new ExpandedIdentifier(iddict.getNumberOfFields());
+
+                        // Set the System ID.
+                        expId.setValue(iddict.getFieldIndex("system"), subdet.getSystemID());
+
+                        // Set the barrel-endcap flag.
+                        expId.setValue(iddict.getFieldIndex("barrel"), 0);
+
+                        // Set the layer number.
+                        expId.setValue(iddict.getFieldIndex("layer"), layer.getGeometry().getPath().getLeafVolume().getCopyNumber());
+
+                        // Set the module id from the DetectorElement.
+                        expId.setValue(iddict.getFieldIndex("module"), ((SiTrackerModule) module).getModuleId());
+
+                        // Set the sensor id for double-sided.
+                        expId.setValue(iddict.getFieldIndex("sensor"), sensorId);
+
+                        // Create the packed id using util method.
+                        // No IdentifierHelper is available yet.
+                        IIdentifier id = IdentifierUtil.pack(iddict, expId);
+
+                        //System.out.println(pv.getName() + " is sens");
+                        //System.out.println("path : " + modulePath.toString() + "/" + pv.getName());
+                        String sensorPath = modulePath.toString() + "/" + pv.getName();
+                        //String sensorName = subdet.getName() + "_layer" + layer.getGeometry().getPhysicalVolume().getCopyNumber() + "_module" + moduleId + "_sensor" + sensorId;
+                        String sensorName = subdet.getName() + "_layer" + layer.getGeometry().getPhysicalVolume().getCopyNumber() + "_module" + ((SiTrackerModule) module).getModuleId() + "_sensor" + sensorId;
+
+                        SiSensor sensor = new SiSensor(sensorId, sensorName, module, sensorPath, id);
+                        sensor.setIdentifier(id);
+
+                        /*
+
+                        Comment out sensor setup and use lcsim Driver.
+
+                        // Set up SiStrips for the sensors
+                        IPolyhedron sensor_solid = (IPolyhedron)sensor.getGeometry().getLogicalVolume().getSolid();
+                        
+                        // Bias the sensor
+                        Polygon3D p_side = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,0,1)).get(0);
+                        //                        System.out.println("Plane of p_side polygon has... ");
+                        //                        System.out.println("                        normal: "+p_side.getNormal());
+                        //                        System.out.println("                        distance: "+p_side.getDistance());
+                        //                        for (Point3D point : p_side.getClosedVertices())
+                        //                        {
+                        //                            System.out.println("      Vertex: "+point);
+                        //                        }
+                        
+                        
+                        Polygon3D n_side = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,0,-1)).get(0);
+                        //                        System.out.println("Plane of n_side polygon has... ");
+                        //                        System.out.println("                        normal: "+n_side.getNormal());
+                        //                        System.out.println("                        distance: "+n_side.getDistance());
+                        
+                        sensor.setBiasSurface(ChargeCarrier.HOLE,p_side);
+                        sensor.setBiasSurface(ChargeCarrier.ELECTRON,n_side);
+                        
+                        // Add sense and readout electrodes
+                        ITranslation3D electrodes_position = new Translation3D(VecOp.mult(-p_side.getDistance(),p_side.getNormal()));  // translate to p_side
+                        IRotation3D electrodes_rotation = new RotationPassiveXYZ(0.0,0.0,0.0);                                      // no rotation (global x-y = local x-y for axial strips)
+                        Transform3D electrodes_transform = new Transform3D(electrodes_position, electrodes_rotation);
+                        
+                        // Free calculation of readout electrodes, sense electrodes determined thereon
+                        SiSensorElectrodes readout_electrodes = new SiStrips(ChargeCarrier.HOLE,0.050,sensor,electrodes_transform);
+                        SiSensorElectrodes sense_electrodes = new SiStrips(ChargeCarrier.HOLE,0.025,(readout_electrodes.getNCells()*2-1),sensor,electrodes_transform);
+
+                        // Free calculation of sense electrodes, readout electrodes determined thereon
+                        //                        SiSensorElectrodes sense_electrodes = new SiStrips(ChargeCarrier.HOLE,0.025,sensor,electrodes_transform);
+                        //                        SiSensorElectrodes readout_electrodes = new SiStrips(ChargeCarrier.HOLE,0.050,(sense_electrodes.getNCells()+1)/2,sensor,electrodes_transform);
+                        
+                        sensor.setSenseElectrodes(sense_electrodes);
+                        sensor.setReadoutElectrodes(readout_electrodes);
+                        
+                        double[][] transfer_efficiencies = { {0.986,0.419} };
+                        sensor.setTransferEfficiencies(ChargeCarrier.HOLE,new BasicMatrix(transfer_efficiencies));
+                         */
+
+                        // Incremenet sensorID for double-sided.
+                        ++sensorId;
+
+
+//                        SiSensorElectrodes sense_electrodes = new SiStrips(3679,0.025,sensor,electrodes_transform);
+//                        SiSensorElectrodes readout_electrodes = new SiStrips(1840,0.050,sensor,electrodes_transform);
+//
+//                        double[][] transfer_efficiencies = { {0.986,0.419} };
+//                        sensor.setSenseElectrodes(ChargeCarrier.HOLE,sense_electrodes);
+//                        sensor.setReadoutElectrodes(ChargeCarrier.HOLE,readout_electrodes);
+//                        sensor.setTransferEfficiencies(ChargeCarrier.HOLE,new BasicMatrix(transfer_efficiencies));
+
+                    }
+                }
+
+                ++moduleId;
+            }
+        }
+    }
+}

GeomConverter/src/org/lcsim/detector/converter/compact
SiTrackerFixedTarget2Converter.java added at 1.1
diff -N SiTrackerFixedTarget2Converter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SiTrackerFixedTarget2Converter.java	21 Jan 2010 21:26:31 -0000	1.1
@@ -0,0 +1,343 @@
+package org.lcsim.detector.converter.compact;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.detector.DetectorElement;
+import org.lcsim.detector.DetectorIdentifierHelper;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IPhysicalVolumePath;
+import org.lcsim.detector.LogicalVolume;
+import org.lcsim.detector.PhysicalVolume;
+import org.lcsim.detector.RotationGeant;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
+import org.lcsim.detector.identifier.ExpandedIdentifier;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.identifier.IIdentifierHelper;
+import org.lcsim.detector.identifier.IdentifierUtil;
+import org.lcsim.detector.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.solids.Trd;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
+import org.lcsim.detector.tracker.silicon.SiTrackerModule;
+import org.lcsim.geometry.compact.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleComponentParameters;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleParameters;
+import org.lcsim.geometry.subdetector.SiTrackerFixedTarget2;
+
+/**
+ * An LCDD converter for a Silicon  tracker model for a  fixed target...based off of SiTrackerEndcap2
+ * @author mgraham
+ */
+public class SiTrackerFixedTarget2Converter
+        extends AbstractSubdetectorConverter
+        implements ISubdetectorConverter {
+
+    Map<String, SiTrackerModuleParameters> moduleParameters = new HashMap<String, SiTrackerModuleParameters>();
+    Map<String, LogicalVolume> modules = new HashMap<String, LogicalVolume>();
+    IMaterial vacuum;
+
+    public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap) {
+        return new SiTrackerIdentifierHelper(
+                subdetector.getDetectorElement(),
+                makeIdentifierDictionary(subdetector),
+                systemMap);
+    }
+
+    public void convert(Subdetector subdet, Detector detector) {
+        try {
+            Element node = subdet.getNode();
+            String subdetName = node.getAttributeValue("name");
+            vacuum = MaterialStore.getInstance().get("Air");
+
+            boolean reflect;
+            if (node.getAttribute("reflect") != null) {
+                reflect = node.getAttribute("reflect").getBooleanValue();
+            } else {
+                reflect = true;
+            }
+
+            IDetectorElement subdetDetElem = subdet.getDetectorElement();
+            DetectorIdentifierHelper helper = (DetectorIdentifierHelper) subdetDetElem.getIdentifierHelper();
+            int nfields = helper.getIdentifierDictionary().getNumberOfFields();
+            IDetectorElement endcapPos = null;
+            IDetectorElement endcapNeg = null;
+            try {
+                // Positive endcap DE
+                IExpandedIdentifier endcapPosId = new ExpandedIdentifier(nfields);
+                endcapPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+                endcapPosId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue());
+                endcapPos = new DetectorElement(subdet.getName() + "_positive", subdetDetElem);
+                endcapPos.setIdentifier(helper.pack(endcapPosId));
+                if (reflect) {
+                    IExpandedIdentifier endcapNegId = new ExpandedIdentifier(nfields);
+                    endcapNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+                    endcapNegId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue());
+                    endcapNeg = new DetectorElement(subdet.getName() + "_negative", subdetDetElem);
+                    endcapNeg.setIdentifier(helper.pack(endcapNegId));
+                }
+            } catch (Exception x) {
+                throw new RuntimeException(x);
+            }
+
+            for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) {
+                Element module = (Element) i.next();
+                String moduleName = module.getAttributeValue("name");
+                moduleParameters.put(moduleName, new SiTrackerModuleParameters(module));
+                modules.put(moduleName, makeModule(moduleParameters.get(moduleName)));
+            }
+
+            for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {
+                Element layerElement = (Element) i.next();
+
+                int layerId = layerElement.getAttribute("id").getIntValue();
+
+                // Positive endcap layer.
+                IExpandedIdentifier layerPosId = new ExpandedIdentifier(nfields);
+                layerPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+//                layerPosId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
+                layerPosId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue());
+                layerPosId.setValue(helper.getFieldIndex("layer"), layerId);
+                IDetectorElement layerPos = new DetectorElement(endcapPos.getName() + "_layer" + layerId, endcapPos, helper.pack(layerPosId));
+
+                // Negative endcap layer.
+                IDetectorElement layerNeg = null;
+                if (reflect) {
+                    IExpandedIdentifier layerNegId = new ExpandedIdentifier(nfields);
+                    layerNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+                    layerNegId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue());
+                    layerNegId.setValue(helper.getFieldIndex("layer"), layerId);
+                    layerNeg = new DetectorElement(endcapNeg.getName() + "_layer_reflected" + layerId, endcapNeg, helper.pack(layerNegId));
+                }
+
+                int moduleNumber = 0;
+                for (Iterator j = layerElement.getChildren("quadrant").iterator(); j.hasNext();) {
+                    Element ringElement = (Element) j.next();
+                    double xLayer = ringElement.getAttribute("x").getDoubleValue();
+                    double dx = ringElement.getAttribute("dx").getDoubleValue();
+                    double yStart = ringElement.getAttribute("yStart").getDoubleValue();
+                    double yStep = ringElement.getAttribute("yStep").getDoubleValue();
+                    int ny = ringElement.getAttribute("ny").getIntValue();
+                    double zStart = ringElement.getAttribute("zStart").getDoubleValue();
+                    int nz = ringElement.getAttribute("nz").getIntValue();
+                    double zStep = ringElement.getAttribute("zStep").getDoubleValue();
+
+                    double phi0 = 0;
+                    if (ringElement.getAttribute("phi0") != null) {
+                        phi0 = ringElement.getAttribute("phi0").getDoubleValue();
+                    }
+                    String module = ringElement.getAttributeValue("module");
+                    LogicalVolume moduleVolume = modules.get(module);
+                    if (moduleVolume == null) {
+                        throw new RuntimeException("Module " + module + " was not found.");
+                    }
+
+                    SiTrackerModuleParameters modPars = moduleParameters.get(module);
+
+                    double x, y, z;
+                    x = xLayer;
+                    y = yStart;
+
+                    for (int k = 0; k < ny; k++) {
+                        z = zStart;
+                        for (int kk = 0; kk < nz; kk++) {
+                            String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
+
+
+
+                            // Positive endcap module.
+                            Translation3D p = new Translation3D(x + dx, y, z);
+                            RotationGeant rot = new RotationGeant(Math.PI / 2 + phi0, 0, -Math.PI / 2);
+                            new PhysicalVolume(new Transform3D(p, rot), moduleBaseName, moduleVolume, detector.getTrackingVolume().getLogicalVolume(), 0);
+                            String path = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName;
+                            IDetectorElement modulePos = new SiTrackerModule(moduleBaseName, layerPos, path, moduleNumber);
+                            ++moduleNumber;
+                            System.out.println("Making module " + moduleBaseName + "  @ " + layerPos.toString());
+                            // Negative endcap module.
+                            if (reflect) {
+                                Translation3D pr = new Translation3D(x + dx, y, -z);
+                                RotationGeant rotr = new RotationGeant(Math.PI / 2 + phi0, 0, -Math.PI / 2);
+
+                                String path2 = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName + "_reflected";
+                                new PhysicalVolume(new Transform3D(pr, rotr), moduleBaseName + "_reflected", moduleVolume, detector.getTrackingVolume().getLogicalVolume(), k);
+                                new SiTrackerModule(moduleBaseName + "_reflected", layerNeg, path2, moduleNumber);
+                                System.out.println("Making module " + moduleBaseName + "  @ " + layerNeg.toString());
+                            }
+
+                            dx = -dx;
+                            z += zStep;
+                            ++moduleNumber;
+                        }
+                        y += yStep;
+                    }
+                }
+            }
+        } catch (JDOMException except) {
+            throw new RuntimeException(except);
+        }
+
+        // Create DetectorElements for the sensors.
+        setupSensorDetectorElements(subdet);
+    }
+
+    private LogicalVolume makeModule(SiTrackerModuleParameters params) {
+        double thickness = params.getThickness();
+        double dx1, dx2, dy1, dy2, dz;
+        dy1 = dy2 = thickness / 2;
+        dx1 = params.getDimension(0);
+        dx2 = params.getDimension(1);
+        dz = params.getDimension(2);
+        Trd envelope = new Trd(params.getName() + "Trd", dx1, dx2, dy1, dy2, dz);
+        LogicalVolume volume = new LogicalVolume(params.getName() + "Volume", envelope, vacuum);
+        makeModuleComponents(volume, params);
+        return volume;
+    }
+
+    private void makeModuleComponents(LogicalVolume moduleVolume, SiTrackerModuleParameters moduleParameters) {
+        Trd trd = (Trd) moduleVolume.getSolid();
+
+        double x1 = trd.getXHalfLength1();
+        double x2 = trd.getXHalfLength2();
+        double y1 = trd.getYHalfLength1();
+        double z = trd.getZHalfLength();
+
+        double posY = -y1;
+
+        String moduleName = moduleVolume.getName();
+
+        int sensor = 0;
+        for (SiTrackerModuleComponentParameters component : moduleParameters) {
+            double thickness = component.getThickness();
+
+            IMaterial material = MaterialStore.getInstance().get(component.getMaterialName());
+            if (material == null) {
+                throw new RuntimeException("The material " + component.getMaterialName() + " does not exist in the materials database.");
+            }
+            boolean sensitive = component.isSensitive();
+            int componentNumber = component.getComponentNumber();
+
+            posY += thickness / 2;
+
+            String componentName = moduleName + "_component" + componentNumber;
+
+            Trd sliceTrd = new Trd(componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z);
+
+            LogicalVolume volume = new LogicalVolume(componentName, sliceTrd, material);
+
+            double zrot = 0;
+            if (sensitive) {
+                if (sensor > 1) {
+                    throw new RuntimeException("Exceeded maximum of 2 sensors per module.");
+                }
+                // Flip 180 deg for 1st sensor.
+                if (sensor == 0) {
+                    zrot = Math.PI;
+                }
+                ++sensor;
+            }
+            Translation3D position = new Translation3D(0., posY, 0);
+            RotationGeant rotation = new RotationGeant(0, 0, zrot);
+            PhysicalVolume pv = new PhysicalVolume(new Transform3D(position, rotation), componentName, volume, moduleVolume, componentNumber);
+            pv.setSensitive(sensitive);
+
+            posY += thickness / 2;
+        }
+    }
+
+    private void setupSensorDetectorElements(Subdetector subdet) {
+        SiTrackerIdentifierHelper helper = (SiTrackerIdentifierHelper) subdet.getDetectorElement().getIdentifierHelper();
+
+        for (IDetectorElement endcap : subdet.getDetectorElement().getChildren()) {
+            for (IDetectorElement layer : endcap.getChildren()) {
+                for (IDetectorElement module : layer.getChildren()) {
+                    IPhysicalVolume modulePhysVol = module.getGeometry().getPhysicalVolume();
+                    IPhysicalVolumePath modulePath = module.getGeometry().getPath();
+                    int sensorId = 0;
+                    for (IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters()) {
+                        if (pv.isSensitive()) {
+                            IIdentifierDictionary iddict = subdet.getDetectorElement().getIdentifierHelper().getIdentifierDictionary();
+
+                            ExpandedIdentifier expId = new ExpandedIdentifier(iddict.getNumberOfFields());
+                            expId.setValue(iddict.getFieldIndex("system"), subdet.getSystemID());
+
+                            if (helper.isEndcapPositive(endcap.getIdentifier())) {
+                                expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
+                            } else if (helper.isEndcapNegative(endcap.getIdentifier())) {
+                                expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapNegativeValue());
+                            } else if (helper.isBarrel(endcap.getIdentifier())) {
+                                expId.setValue(iddict.getFieldIndex("barrel"), helper.getBarrelValue());
+                            } else {
+                                throw new RuntimeException(endcap.getName() + " is not a positive or negative endcap!");
+                            }
+                            expId.setValue(iddict.getFieldIndex("layer"), layer.getIdentifierHelper().getValue(layer.getIdentifier(), "layer"));
+                            expId.setValue(iddict.getFieldIndex("module"), ((SiTrackerModule) module).getModuleId());
+                            expId.setValue(iddict.getFieldIndex("sensor"), sensorId);
+
+                            IIdentifier id = IdentifierUtil.pack(iddict, expId);
+
+                            String sensorPath = modulePath.toString() + "/" + pv.getName();
+                            String sensorName = module.getName() + "_sensor" + sensorId;
+
+                            SiSensor sensor = new SiSensor(sensorId, sensorName, module, sensorPath, id);
+
+                            // Set up SiStrips for the sensors
+                            /*
+                            Trd sensor_solid = (Trd)sensor.getGeometry().getLogicalVolume().getSolid();
+                            
+                            Polygon3D n_side = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,-1,0)).get(0);
+                            Polygon3D p_side = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,1,0)).get(0);
+
+                            //System.out.println("Plane of p_side polygon has... ");
+                            //System.out.println("                        normal: "+p_side.getNormal());
+                            //System.out.println("                        distance: "+p_side.getDistance());
+                            //for (Point3D point : p_side.getVertices())
+                            //{
+                            //    System.out.println("      Vertex: "+point);
+                            //}
+                            
+                            //System.out.println("Plane of n_side polygon has... ");
+                            //System.out.println("                        normal: "+n_side.getNormal());
+                            //System.out.println("                        distance: "+n_side.getDistance());
+                            
+                            // Bias the sensor
+                            sensor.setBiasSurface(ChargeCarrier.HOLE,p_side);
+                            sensor.setBiasSurface(ChargeCarrier.ELECTRON,n_side);
+
+                            double strip_angle = Math.atan2(sensor_solid.getXHalfLength2() - sensor_solid.getXHalfLength1(), sensor_solid.getZHalfLength() * 2);
+
+                            ITranslation3D electrodes_position = new Translation3D(VecOp.mult(-p_side.getDistance(),new BasicHep3Vector(0,0,1)));  // translate to outside of polygon
+                            IRotation3D electrodes_rotation = new RotationPassiveXYZ(-Math.PI/2,0,strip_angle);
+                            Transform3D electrodes_transform = new Transform3D(electrodes_position, electrodes_rotation);                                
+                            
+                            // Free calculation of readout electrodes, sense electrodes determined thereon
+                            SiSensorElectrodes readout_electrodes = new SiStrips(ChargeCarrier.HOLE,0.050,sensor,electrodes_transform);
+                            SiSensorElectrodes sense_electrodes = new SiStrips(ChargeCarrier.HOLE,0.025,(readout_electrodes.getNCells()*2-1),sensor,electrodes_transform);                                                                
+                            
+                            sensor.setSenseElectrodes(sense_electrodes);
+                            sensor.setReadoutElectrodes(readout_electrodes);
+                            
+                            double[][] transfer_efficiencies = { {0.986,0.419} };
+                            sensor.setTransferEfficiencies(ChargeCarrier.HOLE,new BasicMatrix(transfer_efficiencies));
+                             */
+                            ++sensorId;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public Class getSubdetectorType() {
+        return SiTrackerFixedTarget2.class;
+    }
+}

GeomConverter/src/org/lcsim/detector/converter/compact
SiTrackerFixedTargetConverter.java added at 1.1
diff -N SiTrackerFixedTargetConverter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SiTrackerFixedTargetConverter.java	21 Jan 2010 21:26:31 -0000	1.1
@@ -0,0 +1,339 @@
+package org.lcsim.detector.converter.compact;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.detector.DetectorElement;
+import org.lcsim.detector.DetectorIdentifierHelper;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IPhysicalVolumePath;
+import org.lcsim.detector.LogicalVolume;
+import org.lcsim.detector.PhysicalVolume;
+import org.lcsim.detector.RotationGeant;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
+import org.lcsim.detector.identifier.ExpandedIdentifier;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.identifier.IIdentifierHelper;
+import org.lcsim.detector.identifier.IdentifierUtil;
+import org.lcsim.detector.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.solids.Trd;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
+import org.lcsim.detector.tracker.silicon.SiTrackerModule;
+import org.lcsim.geometry.compact.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleComponentParameters;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleParameters;
+import org.lcsim.geometry.subdetector.SiTrackerFixedTarget;
+
+/**
+ * An LCDD converter for a Silicon  tracker model for a  fixed target...based off of SiTrackerEndcap2
+ * @author mgraham
+ */
+public class SiTrackerFixedTargetConverter
+        extends AbstractSubdetectorConverter
+        implements ISubdetectorConverter {
+
+    Map<String, SiTrackerModuleParameters> moduleParameters = new HashMap<String, SiTrackerModuleParameters>();
+    Map<String, LogicalVolume> modules = new HashMap<String, LogicalVolume>();
+    IMaterial vacuum;
+
+    public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap) {
+        return new SiTrackerIdentifierHelper(
+                subdetector.getDetectorElement(),
+                makeIdentifierDictionary(subdetector),
+                systemMap);
+    }
+
+    public void convert(Subdetector subdet, Detector detector) {
+        try {
+            Element node = subdet.getNode();
+            String subdetName = node.getAttributeValue("name");
+            vacuum = MaterialStore.getInstance().get("Air");
+
+            boolean reflect;
+//            if (node.getAttribute("reflect") != null)
+//                reflect = node.getAttribute("reflect").getBooleanValue();
+//            else
+//                reflect = true;
+
+            IDetectorElement subdetDetElem = subdet.getDetectorElement();
+            DetectorIdentifierHelper helper = (DetectorIdentifierHelper) subdetDetElem.getIdentifierHelper();
+            int nfields = helper.getIdentifierDictionary().getNumberOfFields();
+            IDetectorElement endcapPos = null;
+            IDetectorElement endcapNeg = null;
+            try {
+                // Positive endcap DE
+                IExpandedIdentifier endcapPosId = new ExpandedIdentifier(nfields);
+                endcapPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+               // endcapPosId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
+                endcapPosId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue());
+                endcapPos = new DetectorElement(subdet.getName() + "_positive", subdetDetElem);
+                endcapPos.setIdentifier(helper.pack(endcapPosId));
+
+            // Negative endcap DE.
+//                if (reflect)
+//                {
+//                    IExpandedIdentifier endcapNegId = new ExpandedIdentifier(nfields);
+//                    endcapNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+//                    endcapNegId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapNegativeValue());
+//                    endcapNeg = new DetectorElement(subdet.getName() + "_negative", subdetDetElem);
+//                    endcapNeg.setIdentifier(helper.pack(endcapNegId));
+//                }
+
+            } catch (Exception x) {
+                throw new RuntimeException(x);
+            }
+
+            for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) {
+                Element module = (Element) i.next();
+                String moduleName = module.getAttributeValue("name");
+                moduleParameters.put(moduleName, new SiTrackerModuleParameters(module));
+                modules.put(moduleName, makeModule(moduleParameters.get(moduleName)));
+            }
+
+            for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {
+                Element layerElement = (Element) i.next();
+
+                int layerId = layerElement.getAttribute("id").getIntValue();
+
+                // Positive endcap layer.
+                IExpandedIdentifier layerPosId = new ExpandedIdentifier(nfields);
+                layerPosId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+//                layerPosId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
+                   layerPosId.setValue(helper.getFieldIndex("barrel"), helper.getBarrelValue());
+                layerPosId.setValue(helper.getFieldIndex("layer"), layerId);
+                IDetectorElement layerPos = new DetectorElement(endcapPos.getName() + "_layer" + layerId, endcapPos, helper.pack(layerPosId));
+
+                // Negative endcap layer.
+//                IDetectorElement layerNeg = null;
+//                if (reflect)
+//                {
+//                    IExpandedIdentifier layerNegId = new ExpandedIdentifier(nfields);
+//                    layerNegId.setValue(helper.getFieldIndex("system"), subdet.getSystemID());
+//                    layerNegId.setValue(helper.getFieldIndex("barrel"), helper.getEndcapNegativeValue());
+//                    layerNegId.setValue(helper.getFieldIndex("layer"), layerId);
+//                    layerNeg = new DetectorElement(endcapNeg.getName() + "_layer" + layerId, endcapNeg, helper.pack(layerNegId));
+//                }
+
+                int moduleNumber = 0;
+                for (Iterator j = layerElement.getChildren("quadrant").iterator(); j.hasNext();) {
+                    Element ringElement = (Element) j.next();
+//                    double r = ringElement.getAttribute("r").getDoubleValue();
+                    double x = ringElement.getAttribute("x").getDoubleValue();
+                    double y = ringElement.getAttribute("y").getDoubleValue();
+                    double phi0 = 0;
+                    if (ringElement.getAttribute("phi0") != null) {
+                        phi0 = ringElement.getAttribute("phi0").getDoubleValue();
+                    }
+                    double zstart = ringElement.getAttribute("zstart").getDoubleValue();
+                    //  double dz = Math.abs(ringElement.getAttribute("dz").getDoubleValue());
+                    //int nmodules = ringElement.getAttribute("nmodules").getIntValue();
+                    String module = ringElement.getAttributeValue("module");
+                    LogicalVolume moduleVolume = modules.get(module);
+                    if (moduleVolume == null) {
+                        throw new RuntimeException("Module " + module + " was not found.");
+                    }
+                    //double iphi = (2 * Math.PI) / nmodules;
+                    //double phi = phi0;
+                    //for (int k = 0; k < nmodules; k++)
+                    //{
+                    String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
+
+
+
+                    // Positive endcap module.
+//                    Translation3D p = new Translation3D(x, y, zstart);
+                    Translation3D p = new Translation3D(zstart, y, x);
+ //                   RotationGeant rot = new RotationGeant(-Math.PI / 2, -Math.PI / 2 - phi0, 0);
+//                        RotationGeant rot = new RotationGeant(0, -Math.PI / 2 - phi0, -Math.PI / 2);
+                      RotationGeant rot = new RotationGeant(0, 0, -Math.PI / 2);
+                    new PhysicalVolume(new Transform3D(p, rot), moduleBaseName, moduleVolume, detector.getTrackingVolume().getLogicalVolume(), 0);
+                    String path = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName;
+                    IDetectorElement modulePos = new SiTrackerModule(moduleBaseName, layerPos, path, moduleNumber);
+
+                    // Negative endcap module.
+//                        if (reflect)
+//                        {
+//                            Translation3D pr = new Translation3D(x,y,-zstart-dz);
+//                            RotationGeant rotr = new RotationGeant(-Math.PI/2, -Math.PI/2 - phi, Math.PI);
+
+//                            String path2 = "/" + detector.getTrackingVolume().getName() + "/" + moduleBaseName+"_reflected";
+                    //                           new PhysicalVolume(new Transform3D(pr, rotr), moduleBaseName+"_reflected", moduleVolume, detector.getTrackingVolume().getLogicalVolume(), k);
+                    //                           new SiTrackerModule(moduleBaseName+"_reflected", layerNeg, path2, moduleNumber);
+//                        }
+
+//                        dz = -dz;
+//                        phi += iphi;
+                    ++moduleNumber;
+                //}
+                }
+            }
+        } catch (JDOMException except) {
+            throw new RuntimeException(except);
+        }
+
+        // Create DetectorElements for the sensors.
+        setupSensorDetectorElements(subdet);
+    }
+
+    private LogicalVolume makeModule(SiTrackerModuleParameters params) {
+        double thickness = params.getThickness();
+        double dx1, dx2, dy1, dy2, dz;
+        dy1 = dy2 = thickness / 2;
+        dx1 = params.getDimension(0);
+        dx2 = params.getDimension(1);
+        dz = params.getDimension(2);
+        Trd envelope = new Trd(params.getName() + "Trd", dx1, dx2, dy1, dy2, dz);
+        LogicalVolume volume = new LogicalVolume(params.getName() + "Volume", envelope, vacuum);
+        makeModuleComponents(volume, params);
+        return volume;
+    }
+
+    private void makeModuleComponents(LogicalVolume moduleVolume, SiTrackerModuleParameters moduleParameters) {
+        Trd trd = (Trd) moduleVolume.getSolid();
+
+        double x1 = trd.getXHalfLength1();
+        double x2 = trd.getXHalfLength2();
+        double y1 = trd.getYHalfLength1();
+        double z = trd.getZHalfLength();
+
+        double posY = -y1;
+
+        String moduleName = moduleVolume.getName();
+
+        int sensor = 0;
+        for (SiTrackerModuleComponentParameters component : moduleParameters) {
+            double thickness = component.getThickness();
+
+            IMaterial material = MaterialStore.getInstance().get(component.getMaterialName());
+            if (material == null) {
+                throw new RuntimeException("The material " + component.getMaterialName() + " does not exist in the materials database.");
+            }
+            boolean sensitive = component.isSensitive();
+            int componentNumber = component.getComponentNumber();
+
+            posY += thickness / 2;
+
+            String componentName = moduleName + "_component" + componentNumber;
+
+            Trd sliceTrd = new Trd(componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z);
+
+            LogicalVolume volume = new LogicalVolume(componentName, sliceTrd, material);
+
+            double zrot = 0;
+            if (sensitive) {
+                if (sensor > 1) {
+                    throw new RuntimeException("Exceeded maximum of 2 sensors per module.");
+                }
+                // Flip 180 deg for 1st sensor.
+                if (sensor == 0) {
+                    zrot = Math.PI;
+                }
+                ++sensor;
+            }
+            Translation3D position = new Translation3D(0., posY, 0);
+            RotationGeant rotation = new RotationGeant(0, 0, zrot);
+            PhysicalVolume pv = new PhysicalVolume(new Transform3D(position, rotation), componentName, volume, moduleVolume, componentNumber);
+            pv.setSensitive(sensitive);
+
+            posY += thickness / 2;
+        }
+    }
+
+    private void setupSensorDetectorElements(Subdetector subdet) {
+        SiTrackerIdentifierHelper helper = (SiTrackerIdentifierHelper) subdet.getDetectorElement().getIdentifierHelper();
+
+        for (IDetectorElement endcap : subdet.getDetectorElement().getChildren()) {
+            for (IDetectorElement layer : endcap.getChildren()) {
+                for (IDetectorElement module : layer.getChildren()) {
+                    IPhysicalVolume modulePhysVol = module.getGeometry().getPhysicalVolume();
+                    IPhysicalVolumePath modulePath = module.getGeometry().getPath();
+                    int sensorId = 0;
+                    for (IPhysicalVolume pv : modulePhysVol.getLogicalVolume().getDaughters()) {
+                        if (pv.isSensitive()) {
+                            IIdentifierDictionary iddict = subdet.getDetectorElement().getIdentifierHelper().getIdentifierDictionary();
+
+                            ExpandedIdentifier expId = new ExpandedIdentifier(iddict.getNumberOfFields());
+                            expId.setValue(iddict.getFieldIndex("system"), subdet.getSystemID());
+
+                            if (helper.isEndcapPositive(endcap.getIdentifier())) {
+                                expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapPositiveValue());
+                            } else if (helper.isEndcapNegative(endcap.getIdentifier())) {
+                                expId.setValue(iddict.getFieldIndex("barrel"), helper.getEndcapNegativeValue());
+                            } else if(helper.isBarrel(endcap.getIdentifier())){
+                                expId.setValue(iddict.getFieldIndex("barrel"), helper.getBarrelValue());
+                            }else {
+                                throw new RuntimeException(endcap.getName() + " is not a positive or negative endcap!");
+                            }
+                            expId.setValue(iddict.getFieldIndex("layer"), layer.getIdentifierHelper().getValue(layer.getIdentifier(), "layer"));
+                            expId.setValue(iddict.getFieldIndex("module"), ((SiTrackerModule) module).getModuleId());
+                            expId.setValue(iddict.getFieldIndex("sensor"), sensorId);
+
+                            IIdentifier id = IdentifierUtil.pack(iddict, expId);
+
+                            String sensorPath = modulePath.toString() + "/" + pv.getName();
+                            String sensorName = module.getName() + "_sensor" + sensorId;
+
+                            SiSensor sensor = new SiSensor(sensorId, sensorName, module, sensorPath, id);
+
+                            // Set up SiStrips for the sensors
+                            /*
+                            Trd sensor_solid = (Trd)sensor.getGeometry().getLogicalVolume().getSolid();
+                            
+                            Polygon3D n_side = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,-1,0)).get(0);
+                            Polygon3D p_side = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0,1,0)).get(0);
+
+                            //System.out.println("Plane of p_side polygon has... ");
+                            //System.out.println("                        normal: "+p_side.getNormal());
+                            //System.out.println("                        distance: "+p_side.getDistance());
+                            //for (Point3D point : p_side.getVertices())
+                            //{
+                            //    System.out.println("      Vertex: "+point);
+                            //}
+                            
+                            //System.out.println("Plane of n_side polygon has... ");
+                            //System.out.println("                        normal: "+n_side.getNormal());
+                            //System.out.println("                        distance: "+n_side.getDistance());
+                            
+                            // Bias the sensor
+                            sensor.setBiasSurface(ChargeCarrier.HOLE,p_side);
+                            sensor.setBiasSurface(ChargeCarrier.ELECTRON,n_side);
+
+                            double strip_angle = Math.atan2(sensor_solid.getXHalfLength2() - sensor_solid.getXHalfLength1(), sensor_solid.getZHalfLength() * 2);
+
+                            ITranslation3D electrodes_position = new Translation3D(VecOp.mult(-p_side.getDistance(),new BasicHep3Vector(0,0,1)));  // translate to outside of polygon
+                            IRotation3D electrodes_rotation = new RotationPassiveXYZ(-Math.PI/2,0,strip_angle);
+                            Transform3D electrodes_transform = new Transform3D(electrodes_position, electrodes_rotation);                                
+                            
+                            // Free calculation of readout electrodes, sense electrodes determined thereon
+                            SiSensorElectrodes readout_electrodes = new SiStrips(ChargeCarrier.HOLE,0.050,sensor,electrodes_transform);
+                            SiSensorElectrodes sense_electrodes = new SiStrips(ChargeCarrier.HOLE,0.025,(readout_electrodes.getNCells()*2-1),sensor,electrodes_transform);                                                                
+                            
+                            sensor.setSenseElectrodes(sense_electrodes);
+                            sensor.setReadoutElectrodes(readout_electrodes);
+                            
+                            double[][] transfer_efficiencies = { {0.986,0.419} };
+                            sensor.setTransferEfficiencies(ChargeCarrier.HOLE,new BasicMatrix(transfer_efficiencies));
+                             */
+                            ++sensorId;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public Class getSubdetectorType() {
+        return SiTrackerFixedTarget.class;
+    }
+}

GeomConverter/src/org/lcsim/detector/converter/compact
DetectorConverter.java 1.47 -> 1.48
diff -u -r1.47 -r1.48
--- DetectorConverter.java	15 Dec 2009 23:47:00 -0000	1.47
+++ DetectorConverter.java	21 Jan 2010 21:26:31 -0000	1.48
@@ -95,6 +95,8 @@
         addSubdetectorConverter(new PolyconeSupportConverter());
         addSubdetectorConverter(new SiTrackerEndcapConverter());
         addSubdetectorConverter(new SiTrackerEndcap2Converter());
+        addSubdetectorConverter(new SiTrackerFixedTargetConverter());
+        addSubdetectorConverter(new SiTrackerFixedTarget2Converter());
         addSubdetectorConverter(new PolyhedraBarrelCalorimeterConverter());
         addSubdetectorConverter(new PolyhedraEndcapCalorimeter2Converter());
         addSubdetectorConverter(new PolyhedraEndcapCalorimeterConverter());

GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
SiTrackerFixedTarget.java added at 1.1
diff -N SiTrackerFixedTarget.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SiTrackerFixedTarget.java	21 Jan 2010 21:26:32 -0000	1.1
@@ -0,0 +1,219 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleComponentParameters;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleParameters;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.Material;
+import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
+import org.lcsim.geometry.compact.converter.lcdd.util.Position;
+import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+import org.lcsim.geometry.compact.converter.lcdd.util.Trapezoid;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+/**
+ * An LCDD converter for a Silicon endcap tracker model based on Bill Cooper's design from
+ * <a href="http://ilcagenda.linearcollider.org/materialDisplay.py?contribId=58&sessionId=1&materialId=slides&confId=2784">Boulder SiD Workshop 2008</a>.
+ * 
+ * @author jeremym 
+ */
+public class SiTrackerFixedTarget extends LCDDSubdetector {
+
+    Map<String, SiTrackerModuleParameters> moduleParameters = new HashMap<String, SiTrackerModuleParameters>();
+    Map<String, Volume> modules = new HashMap<String, Volume>();
+    Material vacuum;
+
+    public SiTrackerFixedTarget(Element node) throws JDOMException {
+        super(node);
+    }
+
+    void addToLCDD(LCDD lcdd, SensitiveDetector sd) throws JDOMException {
+        int sysId = node.getAttribute("id").getIntValue();
+        String subdetName = node.getAttributeValue("name");
+        vacuum = lcdd.getMaterial("Vacuum");
+//        boolean reflect;
+//        if (node.getAttribute("reflect") != null)
+//            reflect = node.getAttribute("reflect").getBooleanValue();
+//        else
+//            reflect = true;
+
+        for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) {
+            Element module = (Element) i.next();
+            String moduleName = module.getAttributeValue("name");
+            moduleParameters.put(moduleName, new SiTrackerModuleParameters(module));
+            modules.put(moduleName, makeModule(moduleParameters.get(moduleName), sd, lcdd));
+        }
+
+        for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {
+            Element layerElement = (Element) i.next();
+            int layerId = layerElement.getAttribute("id").getIntValue();
+            int ringCount = 0;
+            int moduleNumber = 0;
+            for (Iterator j = layerElement.getChildren("quadrant").iterator(); j.hasNext();) {
+                Element ringElement = (Element) j.next();
+//                double r = ringElement.getAttribute("r").getDoubleValue();
+                double x = ringElement.getAttribute("x").getDoubleValue();
+                double y = ringElement.getAttribute("y").getDoubleValue();
+                double phi0 = 0;
+                if (ringElement.getAttribute("phi0") != null) {
+                    phi0 = ringElement.getAttribute("phi0").getDoubleValue();
+                }
+                double zstart = ringElement.getAttribute("zstart").getDoubleValue();
+//                double dz = 0;
+//                if (ringElement.getAttribute("dz") != null) {
+//                    dz = Math.abs(ringElement.getAttribute("dz").getDoubleValue());
+//                }
+//                int nmodules = ringElement.getAttribute("nmodules").getIntValue();
+                String module = ringElement.getAttributeValue("module");
+                Volume moduleVolume = modules.get(module);
+                if (moduleVolume == null) {
+                    throw new RuntimeException("Module " + module + " was not found.");
+                }
+//                double iphi = (2 * Math.PI) / nmodules;
+                double phi = phi0;
+//                for (int k = 0; k < nmodules; k++) {
+                String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
+
+//                    double x = r * Math.cos(phi);
+//                    double y = r * Math.sin(phi);
+
+                Position p = new Position(moduleBaseName + "_position");
+//                p.setX(x);
+//                p.setY(y);
+//                p.setZ(zstart);
+                p.setX(zstart);
+                p.setY(y);
+                p.setZ(x);
+                Rotation rot = new Rotation(moduleBaseName + "_rotation");
+//                rot.setX(-Math.PI / 2);
+                  rot.setZ(-Math.PI / 2);
+//                rot.setY(-Math.PI / 2 - phi);
+
+                lcdd.add(p);
+                lcdd.add(rot);
+
+                PhysVol pv = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), p, rot);
+                pv.addPhysVolID("system", sysId);
+//                pv.addPhysVolID("barrel", 1); // positive endcap
+                        pv.addPhysVolID("barrel", 0); // positive endcap
+                pv.addPhysVolID("layer", layerId);
+                pv.addPhysVolID("module", moduleNumber);
+
+//                    if (reflect) {
+//                        Position pr = new Position(moduleBaseName + "_reflect_position");
+//                        pr.setX(x);
+//                        pr.setY(y);
+//                        pr.setZ(-zstart - dz);
+//                        Rotation rotr = new Rotation(moduleBaseName + "_reflect_rotation");
+//                        rotr.setX(-Math.PI / 2);
+//                        rotr.setY(-Math.PI / 2 - phi);
+//                        rotr.setZ(Math.PI);
+
+//                        lcdd.add(pr);
+//                        lcdd.add(rotr);
+
+//                        PhysVol pvr = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), pr, rotr);
+//                        pvr.addPhysVolID("system", sysId);
+//                        pvr.addPhysVolID("barrel", 2);
+//                        pvr.addPhysVolID("layer", layerId);
+//                        pvr.addPhysVolID("module", moduleNumber);
+//                    }
+
+//                    dz = -dz;
+//                    phi += iphi;
+                ++ringCount;
+                ++moduleNumber;
+//                }
+            }
+        }
+        setCombineHits(node, sd);
+    }
+
+    private Volume makeModule(SiTrackerModuleParameters params, SensitiveDetector sd, LCDD lcdd) {
+        double thickness = params.getThickness();
+        double dx1, dx2, dy1, dy2, dz;
+        dy1 = dy2 = thickness / 2;
+        dx1 = params.getDimension(0);
+        dx2 = params.getDimension(1);
+        dz = params.getDimension(2);
+        Trapezoid envelope = new Trapezoid(params.getName() + "Trd", dx1, dx2, dy1, dy2, dz);
+        lcdd.add(envelope);
+        Volume volume = new Volume(params.getName() + "Volume", envelope, vacuum);
+        makeModuleComponents(volume, params, sd, lcdd);
+        if (params.getVis() != null) {
+            volume.setVisAttributes(lcdd.getVisAttributes(params.getVis()));
+        }
+        lcdd.add(volume);
+        return volume;
+    }
+
+    private void makeModuleComponents(Volume moduleVolume, SiTrackerModuleParameters moduleParameters, SensitiveDetector sd, LCDD lcdd) {
+        Trapezoid trd = (Trapezoid) lcdd.getSolid(moduleVolume.getSolidRef());
+
+        double x1 = trd.x1();
+        double x2 = trd.x2();
+        double y1 = trd.y1();
+        double z = trd.z();
+
+        double posY = -y1;
+
+        String moduleName = moduleVolume.getVolumeName();
+
+        int sensor = 0;
+        for (SiTrackerModuleComponentParameters component : moduleParameters) {
+            double thickness = component.getThickness();
+
+            Material material = null;
+            try {
+                material = lcdd.getMaterial(component.getMaterialName());
+            } catch (JDOMException x) {
+                throw new RuntimeException(x);
+            }
+            boolean sensitive = component.isSensitive();
+            int componentNumber = component.getComponentNumber();
+
+            posY += thickness / 2;
+
+            String componentName = moduleName + "_component" + componentNumber;
+
+            Trapezoid sliceTrd = new Trapezoid(componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z);
+            lcdd.add(sliceTrd);
+
+            Volume volume = new Volume(componentName, sliceTrd, material);
+            lcdd.add(volume);
+
+            Position position = new Position(componentName + "_position", 0., posY, 0);
+            lcdd.add(position);
+            Rotation rotation = new Rotation(componentName + "_rotation");
+            lcdd.add(rotation);
+
+            PhysVol pv = new PhysVol(volume, moduleVolume, position, rotation);
+            pv.addPhysVolID("component", componentNumber);
+
+            if (sensitive) {
+                if (sensor > 1) {
+                    throw new RuntimeException("Maximum of 2 sensors per module.");
+                }
+                pv.addPhysVolID("sensor", sensor);
+                volume.setSensitiveDetector(sd);
+                ++sensor;
+            }
+
+            if (component.getVis() != null) {
+                volume.setVisAttributes(lcdd.getVisAttributes(component.getVis()));
+            }
+
+            posY += thickness / 2;
+        }
+    }
+
+    public boolean isTracker() {
+        return true;
+    }
+}

GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
SiTrackerFixedTarget2.java added at 1.1
diff -N SiTrackerFixedTarget2.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SiTrackerFixedTarget2.java	21 Jan 2010 21:26:32 -0000	1.1
@@ -0,0 +1,222 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleComponentParameters;
+import org.lcsim.geometry.compact.converter.SiTrackerModuleParameters;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.Material;
+import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol;
+import org.lcsim.geometry.compact.converter.lcdd.util.Position;
+import org.lcsim.geometry.compact.converter.lcdd.util.Rotation;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+import org.lcsim.geometry.compact.converter.lcdd.util.Trapezoid;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+/**
+ * An LCDD converter for a Silicon endcap tracker model based on Bill Cooper's design from
+ * <a href="http://ilcagenda.linearcollider.org/materialDisplay.py?contribId=58&sessionId=1&materialId=slides&confId=2784">Boulder SiD Workshop 2008</a>.
+ * 
+ * @author jeremym 
+ */
+public class SiTrackerFixedTarget2 extends LCDDSubdetector {
+
+    Map<String, SiTrackerModuleParameters> moduleParameters = new HashMap<String, SiTrackerModuleParameters>();
+    Map<String, Volume> modules = new HashMap<String, Volume>();
+    Material vacuum;
+
+    public SiTrackerFixedTarget2(Element node) throws JDOMException {
+        super(node);
+    }
+
+    void addToLCDD(LCDD lcdd, SensitiveDetector sd) throws JDOMException {
+        int sysId = node.getAttribute("id").getIntValue();
+        String subdetName = node.getAttributeValue("name");
+        vacuum = lcdd.getMaterial("Vacuum");
+        boolean reflect;
+        if (node.getAttribute("reflect") != null) {
+            reflect = node.getAttribute("reflect").getBooleanValue();
+        } else {
+            reflect = true;
+        }
+
+        for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) {
+            Element module = (Element) i.next();
+            String moduleName = module.getAttributeValue("name");
+            moduleParameters.put(moduleName, new SiTrackerModuleParameters(module));
+            modules.put(moduleName, makeModule(moduleParameters.get(moduleName), sd, lcdd));
+        }
+
+        for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {
+            Element layerElement = (Element) i.next();
+            int layerId = layerElement.getAttribute("id").getIntValue();
+            int ringCount = 0;
+            int moduleNumber = 0;
+            for (Iterator j = layerElement.getChildren("quadrant").iterator(); j.hasNext();) {
+                Element ringElement = (Element) j.next();
+                double xLayer = ringElement.getAttribute("x").getDoubleValue();
+                double dx = ringElement.getAttribute("dx").getDoubleValue();
+                double yStart = ringElement.getAttribute("yStart").getDoubleValue();
+                 double yStep = ringElement.getAttribute("yStep").getDoubleValue();
+                int ny = ringElement.getAttribute("ny").getIntValue();
+                double zStart = ringElement.getAttribute("zStart").getDoubleValue();
+                int nz = ringElement.getAttribute("nz").getIntValue();
+                double zStep = ringElement.getAttribute("zStep").getDoubleValue();
+                double phi0 = 0;
+                if (ringElement.getAttribute("phi0") != null) {
+                    phi0 = ringElement.getAttribute("phi0").getDoubleValue();
+                }
+                String module = ringElement.getAttributeValue("module");
+
+                Volume moduleVolume = modules.get(module);
+                if (moduleVolume == null) {
+                    throw new RuntimeException("Module " + module + " was not found.");
+                }
+
+             
+                double x, y, z;
+                x = xLayer;
+                y = yStart;
+
+                for (int k = 0; k < ny; k++) {
+                    z = zStart;
+                    for (int kk = 0; kk < nz; kk++) {
+                        String moduleBaseName = subdetName + "_layer" + layerId + "_module" + moduleNumber;
+
+                        Position p = new Position(moduleBaseName + "_position");
+
+                        p.setX(x + dx);
+                        p.setY(y);
+                        p.setZ(z);
+                        Rotation rot = new Rotation(moduleBaseName + "_rotation");
+                        rot.setX(Math.PI / 2+phi0);
+                        rot.setY(0);
+                        rot.setZ(-Math.PI / 2);
+
+
+                        lcdd.add(p);
+                        lcdd.add(rot);
+
+                        PhysVol pv = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), p, rot);
+                        pv.addPhysVolID("system", sysId);
+
+                        pv.addPhysVolID("barrel", 0);
+                        pv.addPhysVolID("layer", layerId);
+                        pv.addPhysVolID("module", moduleNumber);
+                         ++moduleNumber;
+                        if (reflect) {
+                            Position pr = new Position(moduleBaseName + "_reflect_position");
+                            pr.setX(x + dx);
+                            pr.setY(y);
+                            pr.setZ(-z);
+                            Rotation rotr = new Rotation(moduleBaseName + "_reflect_rotation");
+                            rotr.setX(Math.PI / 2+phi0);
+                            rotr.setY(0);
+                            rotr.setZ(-Math.PI / 2);
+
+                            lcdd.add(pr);
+                            lcdd.add(rotr);
+                            System.out.println("Reflecting "+ x+"  "+y+"  "+z);
+                            PhysVol pvr = new PhysVol(moduleVolume, lcdd.getTrackingVolume(), pr, rotr);
+                            pvr.addPhysVolID("system", sysId);
+                            pvr.addPhysVolID("barrel", 0);
+                            pvr.addPhysVolID("layer", layerId);
+                            pvr.addPhysVolID("module", moduleNumber);
+                           
+                        }
+                        dx = -dx;
+                        z += zStep;
+                        ++moduleNumber;
+                    }
+                    y += yStep;
+                }
+            }
+        }
+    }
+
+    private Volume makeModule(SiTrackerModuleParameters params, SensitiveDetector sd, LCDD lcdd) {
+        double thickness = params.getThickness();
+        double dx1, dx2, dy1, dy2, dz;
+        dy1 = dy2 = thickness / 2;
+        dx1 = params.getDimension(0);
+        dx2 = params.getDimension(1);
+        dz = params.getDimension(2);
+        Trapezoid envelope = new Trapezoid(params.getName() + "Trd", dx1, dx2, dy1, dy2, dz);
+        lcdd.add(envelope);
+        Volume volume = new Volume(params.getName() + "Volume", envelope, vacuum);
+        makeModuleComponents(volume, params, sd, lcdd);
+        if (params.getVis() != null) {
+            volume.setVisAttributes(lcdd.getVisAttributes(params.getVis()));
+        }
+        lcdd.add(volume);
+        return volume;
+    }
+
+    private void makeModuleComponents(Volume moduleVolume, SiTrackerModuleParameters moduleParameters, SensitiveDetector sd, LCDD lcdd) {
+        Trapezoid trd = (Trapezoid) lcdd.getSolid(moduleVolume.getSolidRef());
+
+        double x1 = trd.x1();
+        double x2 = trd.x2();
+        double y1 = trd.y1();
+        double z = trd.z();
+
+        double posY = -y1;
+
+        String moduleName = moduleVolume.getVolumeName();
+
+        int sensor = 0;
+        for (SiTrackerModuleComponentParameters component : moduleParameters) {
+            double thickness = component.getThickness();
+
+            Material material = null;
+            try {
+                material = lcdd.getMaterial(component.getMaterialName());
+            } catch (JDOMException x) {
+                throw new RuntimeException(x);
+            }
+            boolean sensitive = component.isSensitive();
+            int componentNumber = component.getComponentNumber();
+
+            posY += thickness / 2;
+
+            String componentName = moduleName + "_component" + componentNumber;
+
+            Trapezoid sliceTrd = new Trapezoid(componentName + "_trd", x1, x2, thickness / 2, thickness / 2, z);
+            lcdd.add(sliceTrd);
+
+            Volume volume = new Volume(componentName, sliceTrd, material);
+            lcdd.add(volume);
+
+            Position position = new Position(componentName + "_position", 0., posY, 0);
+            lcdd.add(position);
+            Rotation rotation = new Rotation(componentName + "_rotation");
+            lcdd.add(rotation);
+
+            PhysVol pv = new PhysVol(volume, moduleVolume, position, rotation);
+            pv.addPhysVolID("component", componentNumber);
+
+            if (sensitive) {
+                if (sensor > 1) {
+                    throw new RuntimeException("Maximum of 2 sensors per module.");
+                }
+                pv.addPhysVolID("sensor", sensor);
+                volume.setSensitiveDetector(sd);
+                ++sensor;
+            }
+
+            if (component.getVis() != null) {
+                volume.setVisAttributes(lcdd.getVisAttributes(component.getVis()));
+            }
+
+            posY += thickness / 2;
+        }
+    }
+
+    public boolean isTracker() {
+        return true;
+    }
+}
CVSspam 0.2.8