Print

Print


Author: [log in to unmask]
Date: Tue May  5 14:05:24 2015
New Revision: 2905

Log:
Create detector-model module on HPS Java branch.  HPSJAVA-499

Added:
    java/branches/HPSJAVA-499/detector-model/
    java/branches/HPSJAVA-499/detector-model/pom.xml
    java/branches/HPSJAVA-499/detector-model/src/
    java/branches/HPSJAVA-499/detector-model/src/main/
    java/branches/HPSJAVA-499/detector-model/src/main/java/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014v1Converter.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/AlignmentCorrection.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/CompactSurveyVolume.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014LCDDBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1JavaBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1LCDDBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleComponentParameters.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleParameters.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014Base.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014.java
    java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014v1.java
    java/branches/HPSJAVA-499/detector-model/src/test/
    java/branches/HPSJAVA-499/detector-model/src/test/java/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/hps/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/hps/detector/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/hps/detector/SvtAlignmentTest.java
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java
    java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java

Added: java/branches/HPSJAVA-499/detector-model/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/pom.xml	(added)
+++ java/branches/HPSJAVA-499/detector-model/pom.xml	Tue May  5 14:05:24 2015
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>hps-detector-model</artifactId>
+    <name>detector-model</name>
+    <description>detector modeling code based on lcsim framework</description>
+    <parent>
+        <groupId>org.hps</groupId>
+        <artifactId>hps-parent</artifactId>
+        <relativePath>../parent/pom.xml</relativePath>
+        <version>3.3.1-SNAPSHOT</version>
+    </parent>    
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <shadedArtifactAttached>true</shadedArtifactAttached>
+                            <shadedClassifierName>bin</shadedClassifierName>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>org.lcsim.geometry.compact.converter.Main</mainClass>
+                                </transformer>
+                            </transformers>
+                            <artifactSet>
+                                <excludes>
+                                    <exclude>hep.testdata.aida:*</exclude>
+                                </excludes>
+                            </artifactSet>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>       
+    </build>
+    <scm>
+        <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/detector-model/</url>
+        <connection>scm:svn:svn://svn.freehep.org/hps/java/trunk/detector-model/</connection>
+        <developerConnection>scm:svn:svn://svn.freehep.org/hps/java/trunk/detector-model/</developerConnection>
+    </scm>
+    <dependencies>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-conditions</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-detector-data</artifactId>
+        </dependency>
+    </dependencies>
+</project>

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,57 @@
+/**
+ * 
+ */
+package org.lcsim.detector.converter.compact;
+
+import org.jdom.Element;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.detector.tracker.silicon.HpsTestRunSiSensor;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014JavaBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerJavaBuilder;
+import org.lcsim.geometry.compact.converter.JavaSurveyVolume;
+import org.lcsim.geometry.subdetector.HPSTestRunTracker2014;
+
+/**
+ * Converts the HPSTestRunTracker2014 compact description into Java runtime objects
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class HPSTestRunTracker2014Converter extends HPSTracker2014ConverterBase {
+
+	public HPSTestRunTracker2014Converter() {
+		super();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#initializeBuilder(org.jdom.Element)
+	 */
+	protected HPSTrackerJavaBuilder initializeBuilder(Element node) {
+	     return new HPSTestRunTracker2014JavaBuilder(_debug,node);
+	 }
+    
+	/* (non-Javadoc)
+	 * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#getSubdetectorType()
+	 */
+	public Class getSubdetectorType() {
+        return HPSTestRunTracker2014.class;
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#createSiSensor(int, java.lang.String, org.lcsim.detector.IDetectorElement, java.lang.String, org.lcsim.detector.identifier.IIdentifier)
+     */
+    HpsSiSensor createSiSensor(int sensorid, String name,
+            IDetectorElement parent, String support, IIdentifier id) {
+        return new HpsTestRunSiSensor(sensorid, name, parent, support, id);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#getModuleNumber(org.lcsim.geometry.compact.converter.JavaSurveyVolume)
+     */
+    protected int getModuleNumber(String surveyVolume) {
+        return HPSTrackerBuilder.getHalfFromName(surveyVolume).equals("top") ? 0 : 1;
+    }
+	
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,88 @@
+package org.lcsim.detector.converter.compact;
+
+import org.jdom.Element;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.geometry.compact.converter.HPSTracker2014JavaBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerJavaBuilder;
+import org.lcsim.geometry.compact.converter.JavaSurveyVolume;
+import org.lcsim.geometry.subdetector.HPSTracker2014;
+
+
+/**
+ * Converts the HPSTracker2014 compact description into Java runtime objects
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class HPSTracker2014Converter extends HPSTracker2014ConverterBase {
+
+    public HPSTracker2014Converter() {
+        super();
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#initializeBuilder(org.jdom.Element)
+     */
+    protected HPSTrackerJavaBuilder initializeBuilder(Element node) {
+       return new HPSTracker2014JavaBuilder(_debug, node);
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#getSubdetectorType()
+     */
+    public Class getSubdetectorType() {
+        return HPSTracker2014.class;
+    }
+
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#createSiSensor(int, java.lang.String, org.lcsim.detector.IDetectorElement, java.lang.String, org.lcsim.detector.identifier.IIdentifier)
+     */
+    HpsSiSensor createSiSensor(int sensorid, String name,
+            IDetectorElement parent, String support, IIdentifier id) {
+       return new HpsSiSensor(sensorid, name, parent, support, id);
+    }
+
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#getModuleNumber(org.lcsim.geometry.compact.converter.JavaSurveyVolume)
+     */
+    protected int getModuleNumber(String surveyVolume) {
+        boolean isTopLayer = HPSTrackerBuilder.getHalfFromName(surveyVolume).equals("top") ? true : false;
+        int layer = HPSTrackerBuilder.getLayerFromVolumeName(surveyVolume);
+        int moduleNumber = -1;
+        if(isTopLayer) {
+            if(layer < 4 ) {
+                moduleNumber = 0;
+            } else {
+                if(HPSTrackerBuilder.isHoleFromName(surveyVolume)) {
+                    moduleNumber = 0;
+                } else {
+                    moduleNumber = 2;
+                }
+            }
+        } else {
+            if(layer < 4 ) {
+                moduleNumber = 1;
+            } else {
+                if(HPSTrackerBuilder.isHoleFromName(surveyVolume)) {
+                    moduleNumber = 1;
+                } else {
+                    moduleNumber = 3;
+                }
+            }
+        }
+
+        if(moduleNumber<0) throw new RuntimeException("Invalid module nr found for " + surveyVolume);
+
+                return moduleNumber;
+    }
+
+    
+
+
+    
+}
+

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,535 @@
+package org.lcsim.detector.converter.compact;
+
+import org.jdom.Element;
+import org.lcsim.detector.DetectorElement;
+import org.lcsim.detector.DetectorElementStore;
+import org.lcsim.detector.DetectorIdentifierHelper;
+import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IGeometryInfo;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.PhysicalVolume;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.converter.compact.subdetector.HpsTracker2;
+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.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+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.HPSTrackerBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerJavaBuilder;
+import org.lcsim.geometry.compact.converter.JavaGhostSurveyVolume;
+import org.lcsim.geometry.compact.converter.JavaSurveyVolume;
+
+/**
+ * Converts the compact description into Java runtime objects
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public abstract class HPSTracker2014ConverterBase extends AbstractSubdetectorConverter {
+
+    protected boolean _debug = false;
+    protected IMaterial trackingMaterial = null;
+    protected static HPSTrackerJavaBuilder builder;
+
+    /**
+     * Default constructor.
+     */
+    public HPSTracker2014ConverterBase() {
+        super();
+    }
+
+    /**
+     * Initialize builder for this converter.
+     * @param node
+     * @return builder.
+     */
+    abstract protected HPSTrackerJavaBuilder initializeBuilder(Element node);
+    
+    
+    /**
+     * Abstract method to create the correct type of {@link HpsSiSensor}.
+     * @param sensorid
+     * @param name
+     * @param parent
+     * @param support
+     * @param id
+     * @return the created sensor.
+     */
+    abstract HpsSiSensor createSiSensor(int sensorid, String name, IDetectorElement parent, String support, IIdentifier id);
+    
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#makeIdentifierHelper(org.lcsim.geometry.compact.Subdetector, org.lcsim.detector.DetectorIdentifierHelper.SystemMap)
+     */
+    public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap) {
+    	return new SiTrackerIdentifierHelper(subdetector.getDetectorElement(), makeIdentifierDictionary(subdetector), systemMap);
+    }
+
+    
+
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#convert(org.lcsim.geometry.compact.Subdetector, org.lcsim.geometry.compact.Detector)
+     */
+    public void convert(Subdetector subdet, Detector detector) {
+
+        if(_debug) System.out.printf("%s: convert %s \n", getClass().getSimpleName(), subdet.getName());
+
+
+        // check tracking material
+        trackingMaterial = MaterialStore.getInstance().get("Vacuum");
+        if(trackingMaterial==null) {
+            throw new RuntimeException("error the tracking material was not found!");
+        }
+
+        // Get XML node for this subdetector.
+        Element node = subdet.getNode();
+
+        // Get the tracking volume for module placement.
+        ILogicalVolume trackingVolume = detector.getTrackingVolume().getLogicalVolume();
+
+
+
+        // build the local geometry
+        builder = initializeBuilder(node);
+        //builder = new HPSTestRunTracker2014JavaBuilder(_debug,node);
+
+
+        // Set subdetector for later reference
+        builder.setSubdetector(subdet);
+
+        // Get ID helper and dictionary for subdetector.
+        builder.setDetectorIdentifierHelper( (DetectorIdentifierHelper) subdet.getDetectorElement().getIdentifierHelper());
+        builder.setIdentifierDictionary(subdet.getDetectorElement().getIdentifierHelper().getIdentifierDictionary());
+
+
+
+        // Build the detector here
+        // setup and build the LCDD geometry
+        if(_debug) System.out.printf("%s: setup and build the JAVA geometry\n", getClass().getSimpleName());
+
+        builder.build(trackingVolume);
+
+        if(_debug) System.out.printf("%s: DONE setup and build the JAVA geometry\n", getClass().getSimpleName());
+
+        if(_debug) System.out.printf("%s: setup physical volumes\n", getClass().getSimpleName());
+        
+        setupPhysicalVolumes();
+        
+        if(_debug) System.out.printf("%s: DONE setup physical volumes\n", getClass().getSimpleName());
+        
+        if(_debug) System.out.printf("%s: create stereo layers\n", getClass().getSimpleName());
+        
+        ((HpsTracker2) subdet.getDetectorElement()).createStereoLayers();
+       
+        if(_debug) System.out.printf("%s: DONE create stereo layers\n", getClass().getSimpleName());
+       
+        if(_debug) printDEs();
+        
+    }
+
+
+   
+
+    /**
+     * Setup physical volumes based on the top level {@link JavaSurveyVolume}.
+     */
+    private void setupPhysicalVolumes() {
+
+        if(_debug) System.out.printf("%s: setup the detector elements\n", getClass().getSimpleName());
+
+        setupPhysicalVolumes(builder.getBaseTrackerGeometry());
+
+        if(_debug) System.out.printf("%s: DONE setup the detector elements\n", getClass().getSimpleName());
+
+    }
+
+
+    /**
+     * Setup the physical volumes recursively
+     * @param surveyVolume - volume to process.
+     */
+    private void setupPhysicalVolumes(JavaSurveyVolume surveyVolume) {
+
+        if(_debug) System.out.printf("%s: setupDetectorElement for %s\n", getClass().getSimpleName(),surveyVolume.getName());
+
+        // Only certain objects are setup as detector elements
+        // Ghost volumes are never setup
+
+        // I do this recursively for daughters now as I wanted it to be generic
+        // but for now since I know what the daughters are I could manually 
+        // go and add:layer->module->sensor detector elements similar to 
+        // the old setup. I wanted this to be more generic in case more structures 
+        // are added so I keep track of all the elements in the builder in order 
+        // to build a hierarchy.
+
+        if( surveyVolume instanceof JavaGhostSurveyVolume) {
+
+            if(_debug) System.out.printf("%s: %s  is a ghost volume, dont create elements or physvol\n", getClass().getSimpleName(),surveyVolume.getName());
+
+        } else if(surveyVolume.getName().contains("tracking")) {
+            if(_debug) System.out.printf("%s: %s  is the tracking volume, dont create elements or physvol\n", getClass().getSimpleName(),surveyVolume.getName());
+        } else {
+
+            // build the physical volume
+            surveyVolume.buildPhysVolume();
+            
+            // create detector element
+            // create detector element
+            if(HPSTrackerBuilder.isBase(surveyVolume.getName())) {
+
+                if(_debug) System.out.printf("%s: create the base detector element\n", getClass().getSimpleName());
+
+                createBaseDetectorElement(surveyVolume);
+                
+                if(_debug) System.out.printf("%s: DONE create the base detector element\n", getClass().getSimpleName());
+
+
+            } else if(HPSTrackerBuilder.isHalfModule(surveyVolume.getName())) {
+
+                if(_debug) System.out.printf("%s: create the layer detector element\n", getClass().getSimpleName());
+
+                IDetectorElement layerDe = createLayerDetectorElement(surveyVolume);
+                
+                if(_debug) System.out.printf("%s: DONE create the layer detector element\n", getClass().getSimpleName());
+
+                if(_debug) System.out.printf("%s: create the module detector element\n", getClass().getSimpleName());
+                
+                createTrackerModuleDetectorElement(surveyVolume, layerDe);
+                
+                if(_debug) System.out.printf("%s: DONE create the module detector element\n", getClass().getSimpleName());
+
+
+            } else if(HPSTrackerBuilder.isSensor(surveyVolume.getName())) {
+
+                if(_debug) System.out.printf("%s: set sensitive volume for sensor %s\n", getClass().getSimpleName(),surveyVolume.getName());
+
+                createSensorDetectorElement(surveyVolume);
+
+                if(_debug) System.out.printf("%s: DONE set sensitive volume for sensor %s\n", getClass().getSimpleName(),surveyVolume.getName());
+
+
+            } else if(HPSTrackerBuilder.isActiveSensor(surveyVolume.getName())) {
+                
+                if(_debug) System.out.printf("%s: create the active sensor detector element\n", getClass().getSimpleName());
+
+                createActiveSensorDetectorElement(surveyVolume);
+                
+                if(_debug) System.out.printf("%s: DONE create the active sensor detector element\n", getClass().getSimpleName());
+
+            } else {
+                throw new RuntimeException("I don't think I should reach this? Should " + surveyVolume.getName() + " be a ghost?" );
+            }
+
+        }
+
+        // add daughters
+        if(_debug) System.out.printf("%s: add %d daughters to %s\n", this.getClass().getSimpleName(),surveyVolume.getDaughters().size(), surveyVolume.getName());
+        for(JavaSurveyVolume daughter : surveyVolume.getDaughters()) {
+            setupPhysicalVolumes(daughter);
+        }
+
+        if(_debug) System.out.printf("%s: DONE setup the detector element for %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+
+    }
+
+    
+       
+    
+    /**
+     * Find the module {@link DetectorElement} in a layer {@link DetectorElement} using the module number id.
+     * @param layerDe
+     * @param moduleNumber
+     * @return the found {@link DetectorElement} or {@code null} if not found.
+     */
+    private IDetectorElement getModuleDetectorElement(IDetectorElement layerDe, int moduleNumber) {
+      //Find the module by looping over the modules and checking module number
+        IDetectorElement moduleDe = null;
+        for(IDetectorElement e : layerDe.getChildren()) {
+            if(e instanceof SiTrackerModule) {
+                SiTrackerModule m = (SiTrackerModule)e;
+                if(m.getModuleId()==moduleNumber) {
+                    moduleDe = m;
+                }
+            }
+        }
+        return moduleDe;
+    }
+
+    /**
+     * Abstract method to find the module number.
+     * @param surveyVolume
+     * @return module number
+     */
+    abstract protected int getModuleNumber(String surveyVolume);
+
+    /**
+     * Find the layer {@link DetectorElement}.
+     * @param surveyVolume
+     * @return the {@link DetectorElement}.
+     */
+    private IDetectorElement getLayerDetectorElement(JavaSurveyVolume surveyVolume) {
+        // Helper
+        IIdentifierDictionary iddict = builder.getDetectorIdentifierHelper().getIdentifierDictionary();
+
+        // Find the mother: the module detector element
+        IExpandedIdentifier layerExpId = new ExpandedIdentifier(iddict.getNumberOfFields());
+        layerExpId.setValue(iddict.getFieldIndex("system"), builder.getSubdetector().getSystemID());
+        layerExpId.setValue(iddict.getFieldIndex("barrel"), builder.getDetectorIdentifierHelper().getBarrelValue());                            
+        //use the old definition of layer number to be consistent
+        //int layer = HPSTestRunTracker2014Builder.getLayerFromVolumeName(geometryObject.getName());
+        int layer = builder._builder.getOldGeomDefLayerFromVolumeName(surveyVolume.getName());
+        layerExpId.setValue(iddict.getFieldIndex("layer"), layer);
+        //Find the layer from the ID
+        return builder.getLayerDetectorElement(layerExpId);
+    }
+
+    
+    
+    /**
+     * Create the {@link HpsSiSensor} detector element.
+     * @param surveyVolume
+     */
+    private void createActiveSensorDetectorElement(JavaSurveyVolume surveyVolume) {
+     // Setup the active sensor element
+        // to be consistent with old converter I also add the sensor 
+        // in the path to the element even though it's not associated with 
+        // with a element. I'm not sure why this is done.
+
+        
+        if(_debug) System.out.printf("%s: find the active sensor phys vol\n", this.getClass().getSimpleName());             
+
+        // Find active Sensor physical volume.
+        // Keep name consistent with old converter
+        PhysicalVolume sensorPhysVol = (PhysicalVolume) surveyVolume.getPhysVolume();
+
+        if(sensorPhysVol==null) throw new RuntimeException("cannot find physVol for " + surveyVolume.getName());
+
+        if(_debug) System.out.printf("%s: found %s phys vol\n", this.getClass().getSimpleName(),sensorPhysVol.getName());               
+
+        // find the layer and module detector element
+        
+        IDetectorElement layerDe = getLayerDetectorElement(surveyVolume);
+        
+        if(layerDe==null) throw new RuntimeException("Cannot find layer DE");
+
+        //Find the module number
+        int moduleNumber = getModuleNumber(surveyVolume.getName());
+        
+        //Find the module detector element
+        IDetectorElement moduleDe = getModuleDetectorElement(layerDe, moduleNumber);
+        
+        if(moduleDe==null) throw new RuntimeException("Cannot find module DE for " + surveyVolume.getName());
+
+        // Setup SiSensor's identifier.
+        IIdentifierDictionary iddict = builder.getIdentifierDictionary();
+        IExpandedIdentifier expId = new ExpandedIdentifier(iddict.getNumberOfFields());
+        expId.setValue(iddict.getFieldIndex("system"), builder.getSubdetector().getSystemID());
+        expId.setValue(iddict.getFieldIndex("barrel"), 0);                            
+        expId.setValue(iddict.getFieldIndex("layer"), builder.getDetectorIdentifierHelper().getValue(layerDe.getIdentifier(), "layer"));
+        expId.setValue(iddict.getFieldIndex("module"), ((SiTrackerModule) moduleDe).getModuleId());
+        // The sensorNumber is always 0 in the old geometry. Keep it that way.
+        int sensorNumber = 0;
+        expId.setValue(iddict.getFieldIndex("sensor"), sensorNumber);
+        
+
+        // Packed identifier.
+        IIdentifier sensorId = iddict.pack(expId);
+
+        // Sensor paths.
+        String modulePath = moduleDe.getGeometry().getPathString();
+        IPhysicalVolume componentPhysVol = surveyVolume.getPhysMother().getPhysVolume();
+        String sensorPath = modulePath.toString() + "/" + componentPhysVol.getName() + "/" + sensorPhysVol.getName();
+        String sensorName = moduleDe.getName() + "_sensor" + sensorNumber;
+
+        if(_debug) {
+            System.out.printf("%s: create HpsSiSensor with old layer id %d with sensorNumber %d name %s moduleDe %s sensorPath %s sensor Id %d \n", getClass().getSimpleName(), 
+                                layerDe.getIdentifier(),sensorNumber, sensorName, moduleDe.getName(), sensorPath, sensorNumber);
+        }
+        System.out.printf("%s: HpsSiSensor old layer id %d and module nr %d and sensor nr %d <-> DE name %s \n", getClass().getSimpleName(), 
+                builder.getDetectorIdentifierHelper().getValue(layerDe.getIdentifier(), "layer"), ((SiTrackerModule) moduleDe).getModuleId(), sensorNumber,sensorName);
+        
+        // Create the sensor.
+        int millepedeLayer = builder._builder.getMillepedeLayer(sensorName);
+        HpsSiSensor sensor = createSiSensor(sensorNumber, sensorName, moduleDe, sensorPath, sensorId);
+        sensor.setMillepedeId(millepedeLayer);
+        //if(_debug) System.out.printf("%s: created sensor %s with id %d and expId %s \n", getClass().getSimpleName(), sensor.getName(), sensor.getIdentifier().getValue(), sensor.getExpandedIdentifier().toString());
+        if(_debug) System.out.printf("%s: created sensor %s with layer %d and MP layer %d\n", getClass().getSimpleName(), sensor.getName(), sensor.getLayerNumber(),sensor.getMillepedeId());
+    
+        
+    }
+    
+    
+    
+    /**
+     * Set the sensor {@link PhysicalVolume} to be sensitive.
+     * @param surveyVolume
+     */
+    private void createSensorDetectorElement(JavaSurveyVolume surveyVolume) {
+
+        // set the physical volume to be sensitive
+        // TODO this should go into the geometry definition?!
+        ((PhysicalVolume)surveyVolume.getPhysVolume()).setSensitive(true);
+        
+    }
+
+    /**
+     * Create the {@link SiTrackerModule}.
+     * @param surveyVolume
+     * @param layerDe - mother {@link DetectorElement}
+     */
+    protected void createTrackerModuleDetectorElement(JavaSurveyVolume surveyVolume, IDetectorElement layerDe) {
+        // create the "module" detector element 
+        // it's under the base element
+        
+        int moduleNumber = getModuleNumber(surveyVolume.getName());
+        
+        String modulePlacementName = surveyVolume.getName();// builder.getSubdetector().getName() + "_" + moduleName + "_layer" + layer + "_module" + moduleNumber;
+       
+        // find the base DE as mother
+        IDetectorElement baseDe = builder.getBaseDetectorElement();
+        if(baseDe==null) {
+            throw new RuntimeException("Base DE couldn't be found. Shouldn't happen!");
+        } 
+        
+        // use base as mother for physical volume
+        String modulePath = baseDe.getGeometry().getPathString() + "/" + modulePlacementName;
+
+        if(_debug) {
+            System.out.printf("%s: create SiTrackerModule with: placementname %s, modulePath %s, moduleNumber %d  \n", getClass().getSimpleName(),modulePlacementName, modulePath, moduleNumber);
+        }
+        
+        SiTrackerModule moduleDe = new SiTrackerModule(modulePlacementName, layerDe, modulePath, moduleNumber);
+
+        if(_debug) System.out.printf("%s: add module DE to existing ones  \n", getClass().getSimpleName(),modulePlacementName, modulePath, moduleNumber);
+
+
+        //keep track of the module detector element
+        builder.addModuleDetectorElement(moduleDe);
+        
+    }
+
+    
+    
+    
+    /**
+     * Create the layer {@link DetectorElement}
+     * @param surveyVolume
+     * @return the detector element.
+     */
+    protected IDetectorElement createLayerDetectorElement(JavaSurveyVolume surveyVolume) {
+        int nfields = builder.getDetectorIdentifierHelper().getIdentifierDictionary().getNumberOfFields();
+        IExpandedIdentifier layerPosId = new ExpandedIdentifier(nfields);
+        layerPosId.setValue(builder.getDetectorIdentifierHelper().getFieldIndex("system"), builder.getSubdetector().getSystemID());
+        layerPosId.setValue(builder.getDetectorIdentifierHelper().getFieldIndex("barrel"), builder.getDetectorIdentifierHelper().getBarrelValue());
+        //use the old definition of layer number to be consistent
+        //int layer = HPSTestRunTracker2014Builder.getLayerFromVolumeName(geometryObject.getName());
+        int layer = builder._builder.getOldGeomDefLayerFromVolumeName(surveyVolume.getName());
+        layerPosId.setValue(builder.getDetectorIdentifierHelper().getFieldIndex("layer"), layer);
+        if(_debug) System.out.printf("%s: layerPosId layer = %d (compare with new layer %d)\n", getClass().getSimpleName(),layer, HPSTrackerBuilder.getLayerFromVolumeName(surveyVolume.getName()));
+
+        // find the base DE as mother
+        IDetectorElement baseDe = builder.getBaseDetectorElement();
+        if(baseDe==null) {
+            throw new RuntimeException("Base DE couldn't be found. Shouldn't happen!");
+        } 
+
+
+        // create the layer detector element and keep track of it
+        //IDetectorElement layerDe = builder.getLayerDetectorElement(layerPosId);
+        IDetectorElement layerDe = builder.getLayerDetectorElement(layerPosId);
+
+        if(layerDe==null) {
+            //layerDe =  new DetectorElement(builder.getSubdetector().getName() + "_layer" + layer, builder.getSubdetector().getDetectorElement(), builder.getDetectorIdentifierHelper().pack(layerPosId));
+            layerDe =  new DetectorElement(builder.getSubdetector().getName() + "_layer" + layer, baseDe, builder.getDetectorIdentifierHelper().pack(layerPosId));
+            builder.addLayerDetectorElement(layerDe);
+        } else {
+            if(_debug) System.out.printf("%s: layerDE exists\n", getClass().getSimpleName());
+        }
+
+        if(_debug) System.out.printf("%s: created layerDE  %s  \n", getClass().getSimpleName(),layerDe.getName());
+        
+        return layerDe;
+    }
+    
+    
+    
+    /**
+     * Create the tracker base {@link DetectorElement}
+     * @param surveyVolume
+     */
+    void createBaseDetectorElement(JavaSurveyVolume surveyVolume) {
+
+        int nfields = builder.getDetectorIdentifierHelper().getIdentifierDictionary().getNumberOfFields();
+        IExpandedIdentifier layerPosId = new ExpandedIdentifier(nfields);
+        layerPosId.setValue(builder.getDetectorIdentifierHelper().getFieldIndex("system"), builder.getSubdetector().getSystemID());
+        layerPosId.setValue(builder.getDetectorIdentifierHelper().getFieldIndex("barrel"), builder.getDetectorIdentifierHelper().getBarrelValue());
+        int layer = 22; // dummy value
+        layerPosId.setValue(builder.getDetectorIdentifierHelper().getFieldIndex("layer"), layer);
+        IDetectorElement baseDe = builder.getBaseDetectorElement();
+        if(baseDe!=null) {
+            throw new RuntimeException("Base exists. Shouldn't happen!");
+        } 
+        ILogicalVolume trackingVolume = surveyVolume.getPhysMother().getVolume();
+        if(!trackingVolume.getName().contains("tracking")) {
+            throw new RuntimeException("base phys mother " + surveyVolume.getPhysMother().getName() + " is not tracking volume!?");
+        }
+        String physVolPath = trackingVolume.getName() + "/" + surveyVolume.getPhysVolume().getName();
+        baseDe = new DetectorElement(builder.getSubdetector().getName() + "_base", builder.getSubdetector().getDetectorElement(), physVolPath, builder.getIdentifierDictionary().pack(layerPosId));
+        builder.addBaseDetectorElement(baseDe);
+        
+        if(_debug) System.out.printf("%s: baseDE name %s  \n", getClass().getSimpleName(),baseDe.getName());
+    }
+
+    
+    public IDetectorElement makeSubdetectorDetectorElement(Detector detector, Subdetector subdetector) {
+        
+        if(_debug) System.out.printf("%s: makeSubdetectorDetectorElement for subdetector %s\n", getClass().getSimpleName(),subdetector.getName());
+        
+        IDetectorElement subdetectorDE =
+                new HpsTracker2(subdetector.getName(), detector.getDetectorElement());
+        subdetector.setDetectorElement(subdetectorDE);
+        return subdetectorDE;
+    }
+    
+    private void printDEs() {
+        System.out.printf("%s: Print all %d detector elements in store\n", getClass().getSimpleName(),DetectorElementStore.getInstance().size());
+        for(IDetectorElement e : DetectorElementStore.getInstance()) {
+            System.out.printf("%s: Name: %s \n", getClass().getSimpleName(),e.getName());
+           /*
+            if(e.getIdentifier()==null) {
+                System.out.printf("%s: no id found\n", getClass().getSimpleName());
+            } else {
+                if(e.getExpandedIdentifier()==null) 
+                    System.out.printf("%s: no exp id found\n", getClass().getSimpleName());
+                else 
+                    System.out.printf("%s: %s \n", getClass().getSimpleName(),e.getExpandedIdentifier().toString());
+            } 
+            */
+            if(e.hasGeometryInfo()) {
+                System.out.printf("%s: Position: %s \n", getClass().getSimpleName(),e.getGeometry().getPosition());
+                System.out.printf("%s: LocalToGlobal: \n%s \n", getClass().getSimpleName(),((Transform3D)e.getGeometry().getLocalToGlobal()).toString());
+                //System.out.printf("%s: GlobalToLocal: \n%s \n", getClass().getSimpleName(),((Transform3D)e.getGeometry().getGlobalToLocal()).toString());
+                IGeometryInfo info = e.getGeometry();
+                if(info!=null) {
+                    while((info=info.parentGeometry())!=null) {
+                        System.out.printf("%s: Parent geometry DE: %s \n", getClass().getSimpleName(),info.getDetectorElement().getName());
+                        System.out.printf("%s: Parent Position: %s \n", getClass().getSimpleName(),info.getPosition());
+                        System.out.printf("%s: Parent LocalToGlobal: \n%s \n", getClass().getSimpleName(),((Transform3D)info.getLocalToGlobal()).toString());
+
+                    }
+                }
+            }
+        }
+    }
+    
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014v1Converter.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014v1Converter.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014v1Converter.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,29 @@
+package org.lcsim.detector.converter.compact;
+
+import org.jdom.Element;
+import org.lcsim.geometry.compact.converter.HPSTracker2014v1JavaBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerJavaBuilder;
+import org.lcsim.geometry.subdetector.HPSTracker2014v1;
+
+public class HPSTracker2014v1Converter extends HPSTracker2014Converter {
+
+    public HPSTracker2014v1Converter() {
+        super();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#initializeBuilder(org.jdom.Element)
+     */
+    protected HPSTrackerJavaBuilder initializeBuilder(Element node) {
+       return new HPSTracker2014v1JavaBuilder(_debug, node);
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#getSubdetectorType()
+     */
+    public Class getSubdetectorType() {
+        return HPSTracker2014v1.class;
+    }
+
+    
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/AlignmentCorrection.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/AlignmentCorrection.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/AlignmentCorrection.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,48 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+
+/**
+ * Class containing the final translation and rotation correction from alignment.
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class AlignmentCorrection {
+    private Rotation rotation = null;
+    private Hep3Vector translation = null;
+    public AlignmentCorrection(double x, double y, double z, double rot_x, double rot_y, double rot_z) {
+        setTranslation(x, y, z);
+        setRotation(rot_x, rot_y, rot_z);
+    }
+    public AlignmentCorrection() {
+    }
+    public Rotation getRotation() {
+        return rotation;
+    }
+    public void setRotation(Rotation rotation) {
+        this.rotation = rotation;
+    }
+    public void setRotation(double rot_x, double rot_y, double rot_z) {
+        Rotation rx = new Rotation(new Vector3D(1,0,0),rot_x);
+        Rotation ry = new Rotation(new Vector3D(0,1,0),rot_y);
+        Rotation rz = new Rotation(new Vector3D(0,0,1),rot_z);
+        // Build full rotation
+        Rotation rzyx = rz.applyTo(ry.applyTo(rx));
+        setRotation(rzyx);
+    }
+    public Hep3Vector getTranslation() {
+        return translation;
+    }
+    public void setTranslation(Hep3Vector translation) {
+        this.translation = translation;
+    }
+    public void setTranslation(double x, double y, double z) {
+        setTranslation(new BasicHep3Vector(x,y,z));
+    }
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/CompactSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/CompactSurveyVolume.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/CompactSurveyVolume.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,223 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.List;
+
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+
+public abstract class CompactSurveyVolume extends SurveyVolume {
+    public static final String xmlTagNameTop = "SurveyVolumes";
+    public static final String xmlTagName = "SurveyVolume";
+    
+    Element node = null;
+    
+    public CompactSurveyVolume(String name, SurveyVolume m,
+            AlignmentCorrection alignmentCorrection, Element node2) {
+        super(name, m, alignmentCorrection);
+        node = node2;
+    }
+
+    public CompactSurveyVolume(String name, SurveyVolume m,
+            AlignmentCorrection alignmentCorrection, SurveyVolume ref, Element node2) {
+        super(name, m, alignmentCorrection, ref);
+        node = node2;
+    }
+
+
+    /**
+     * Extract survey positions from xml description
+     */
+    protected void setPos() {
+       
+        if(debug) System.out.printf("%s: getSurveyPosFromCompact for %s from %s\n",getClass().getSimpleName(), getName(), node.getAttributeValue("name"));
+     
+        Element eNameTop = node.getChild(xmlTagNameTop);
+        if(eNameTop==null) {
+            throw new RuntimeException("no eName for " + xmlTagNameTop + " found in compact file");
+        } 
+
+        List<Element> eNames = eNameTop.getChildren(xmlTagName);
+        if(eNames==null) {
+            throw new RuntimeException("no eNames for " + xmlTagName + " found in compact file");
+        } 
+
+        for(Element eName : eNames) {
+
+            if(eName.getAttributeValue("name").compareTo(getName())==0) {
+
+               
+                Element eCoord = eName.getChild("SurveyPos");
+
+                if(eCoord==null) {
+                    throw new RuntimeException("no eCoord for " + getName() + " found in compact file");
+                } 
+                
+//                Element eOrigin = eCoord.getChild("origin");
+//                
+//                if(eOrigin==null) {
+//                    throw new RuntimeException("no eOrigin for " + getName() + " found in compact file");
+//                } 
+
+//                origin = null;
+//                try {
+//                    double x,y,z;
+//                    x= eOrigin.getAttribute("x").getDoubleValue();
+//                    y= eOrigin.getAttribute("y").getDoubleValue();
+//                    z= eOrigin.getAttribute("z").getDoubleValue();
+//                    origin = new BasicHep3Vector(x, y, z);
+//                } catch (DataConversionException e) {
+//                    e.printStackTrace();
+//                }
+                
+                List<Element> eCoordComponents = eCoord.getChildren("point");
+
+                for(Element eUnitVec: eCoordComponents) {
+                    try {
+                        double x,y,z;
+                        if(eUnitVec.getAttributeValue("name").compareTo("ball") == 0) {
+                            x = eUnitVec.getAttribute("x").getDoubleValue();
+                            y = eUnitVec.getAttribute("y").getDoubleValue();
+                            z = eUnitVec.getAttribute("z").getDoubleValue();
+                            setBallPos(x, y, z);
+                        } else if(eUnitVec.getAttributeValue("name").compareTo("vee") == 0) {
+                            x = eUnitVec.getAttribute("x").getDoubleValue();
+                            y = eUnitVec.getAttribute("y").getDoubleValue();
+                            z = eUnitVec.getAttribute("z").getDoubleValue();
+                            setVeePos(x, y, z);
+                        } else if(eUnitVec.getAttributeValue("name").compareTo("flat") == 0) {
+                            x = eUnitVec.getAttribute("x").getDoubleValue();
+                            y = eUnitVec.getAttribute("y").getDoubleValue();
+                            z = eUnitVec.getAttribute("z").getDoubleValue();
+                            setFlatPos(x, y, z);
+                        } else {
+                            throw new RuntimeException("eUnitVec name " + eUnitVec.getAttributeValue("name") + " is ill-defined for " + getName() + " found in compact file");
+                        }
+                    } catch (DataConversionException e) {
+                        e.printStackTrace();
+                    }
+                }
+                
+                
+                
+                
+            }
+        }
+        if(debug) {
+            System.out.printf("%s: Extracted these survey constants from compact\n", this.getClass().getSimpleName());
+            System.out.printf("%s: ball %s \n", this.getClass().getSimpleName(),getBallPos().toString());
+            System.out.printf("%s: vee  %s \n", this.getClass().getSimpleName(),getVeePos().toString());
+            System.out.printf("%s: flat %s \n", this.getClass().getSimpleName(),getFlatPos().toString());
+        }
+
+    }
+    
+  
+    
+    /**
+     * Extract coordinate system from xml description
+     */
+    private void getCoordFromCompact() {
+
+        
+       
+        if(debug) System.out.printf("%s: getCoordFromCompact for %s from %s\n",getClass().getSimpleName(), getName(), node.getAttributeValue("name"));
+     
+        if(1==1)
+            throw new UnsupportedOperationException("Need to work on interface of a new coordinate system and the ball, vee, flat procedure to build coord system!");
+
+        
+        
+        Element eNameTop = node.getChild(xmlTagNameTop);
+        if(eNameTop==null) {
+            throw new RuntimeException("no eName for " + xmlTagNameTop + " found in compact file");
+        } 
+
+        List<Element> eNames = eNameTop.getChildren(xmlTagName);
+        if(eNames==null) {
+            throw new RuntimeException("no eNames for " + xmlTagName + " found in compact file");
+        } 
+
+        for(Element eName : eNames) {
+
+            if(eName.getAttributeValue("name").compareTo(getName())==0) {
+
+               
+                Element eCoord = eName.getChild("SurveyCoord");
+
+                if(eCoord==null) {
+                    throw new RuntimeException("no eCoord for " + getName() + " found in compact file");
+                } 
+                
+                Element eOrigin = eCoord.getChild("origin");
+                
+                if(eOrigin==null) {
+                    throw new RuntimeException("no eOrigin for " + getName() + " found in compact file");
+                } 
+
+                Hep3Vector coord_org = null;
+                Hep3Vector coord_unit_u = null;
+                Hep3Vector coord_unit_v = null;
+                Hep3Vector coord_unit_w = null;
+
+                
+                double x,y,z;
+                try {
+                    x= eOrigin.getAttribute("x").getDoubleValue();
+                    y= eOrigin.getAttribute("y").getDoubleValue();
+                    z= eOrigin.getAttribute("z").getDoubleValue();
+                    coord_org =new BasicHep3Vector(x, y, z);
+                } catch (DataConversionException e) {
+                    e.printStackTrace();
+                }
+               
+                
+                
+                
+                List<Element> eCoordComponents = eCoord.getChildren("unitVec");
+
+                for(Element eUnitVec: eCoordComponents) {
+                    try {
+                        double ux,uy,uz;
+                        double vx,vy,vz;
+                        double wx,wy,wz;
+                        if(eUnitVec.getAttributeValue("name").compareTo("u") == 0) {
+                            ux = eUnitVec.getAttribute("x").getDoubleValue();
+                            uy = eUnitVec.getAttribute("y").getDoubleValue();
+                            uz = eUnitVec.getAttribute("z").getDoubleValue();
+                            coord_unit_u = new BasicHep3Vector(ux, uy, uz);
+                        } else if(eUnitVec.getAttributeValue("name").compareTo("v") == 0) {
+                            vx = eUnitVec.getAttribute("x").getDoubleValue();
+                            vy = eUnitVec.getAttribute("y").getDoubleValue();
+                            vz = eUnitVec.getAttribute("z").getDoubleValue();
+                            coord_unit_v = new BasicHep3Vector(vx, vy, vz);
+                        } else if(eUnitVec.getAttributeValue("name").compareTo("w") == 0) {
+                            wx = eUnitVec.getAttribute("x").getDoubleValue();
+                            wy = eUnitVec.getAttribute("y").getDoubleValue();
+                            wz = eUnitVec.getAttribute("z").getDoubleValue();
+                            coord_unit_w = new BasicHep3Vector(wx, wy, wz);
+                        } else {
+                            throw new RuntimeException("eUnitVec name " + eUnitVec.getAttributeValue("name") + " is ill-defined for " + getName() + " found in compact file");
+                        }
+                    } catch (DataConversionException e) {
+                        e.printStackTrace();
+                    }
+                }
+                
+                throw new RuntimeException("need to work on this!");
+                //SurveyCoordinateSystem coord = new SurveyCoordinateSystem(coord_org, coord_unit_u, coord_unit_v, coord_unit_w);
+                //setCoord(coord);
+                
+            }
+        }
+        if(debug) {
+            System.out.printf("%s: found coord system\n%s\n", this.getClass().getSimpleName(),getCoord().toString());
+        }
+
+    }
+    
+
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,1841 @@
+/**
+ * 
+ */
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+
+import java.util.List;
+
+import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
+import org.apache.commons.math3.geometry.euclidean.threed.RotationOrder;
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+import org.jdom.Element;
+
+/**
+ * 
+ * Geometry information for the HPS Test run tracker
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class HPSTestRunTracker2014GeometryDefinition extends HPSTrackerGeometryDefinition {
+
+
+
+    
+    //General
+    protected static final boolean useSiStripsConvention = true;
+    protected static final boolean use30mradRotation = true;
+    protected static final boolean useFakeHalfModuleAxialPos = false;
+
+    // Global position references	
+    protected static final double target_pos_wrt_base_plate_x = 162.3; //from Marco's 3D model
+    protected static final double target_pos_wrt_base_plate_y = 80.55; //from Tim's sketchup //68.75; //from Marco's 3D model
+    protected static final double target_pos_wrt_base_plate_z = 926.59; //from Marco's 3D model
+    
+
+
+    public HPSTestRunTracker2014GeometryDefinition(boolean debug, Element node) {
+        super(debug, node);
+        doAxial = true;
+        doStereo = true;
+        doColdBlock = false;
+        doBottom = true;
+        doTop = true;
+        layerBitMask = 0x1F;    //0x1;//
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#build()
+     */
+    public void build() {
+
+        if(isDebug()) System.out.printf("%s: constructing the geometry objects\n", this.getClass().getSimpleName());
+
+        // Build the geometry from the basic building blocks in the geometry definition class
+        // Keep the order correct.
+        // Each item has knowledge of its mother but not its daughters
+        TrackingVolume tracking = new TrackingVolume("trackingVolume",null);
+        surveyVolumes.add(tracking);
+
+        TrackerEnvelope base = new TrackerEnvelope("base",tracking);
+        surveyVolumes.add(base);
+        
+        BasePlate basePlate = new BasePlate("baseplate",base, "Aluminum");
+        surveyVolumes.add(basePlate);
+        
+        CSupport cSupport = new CSupport("c_support", base);
+        surveyVolumes.add(cSupport);        
+        
+        AlignmentCorrection alignmentCorrectionSupportBottom = getSupportAlignmentCorrection(false);
+        SupportBottom supportBottom = new SupportBottom("support_bottom", base, alignmentCorrectionSupportBottom, cSupport);
+        surveyVolumes.add(supportBottom);
+        // The support survey positions are now with respect to its mother and not the reference coord. system.
+        // So to get the reference for the support plate I don't need to apply that extra transformation
+        
+        SupportPlateBottom supportPlateBottom = new SupportPlateBottom("support_plate_bottom", base, supportBottom, "Aluminum");
+        surveyVolumes.add(supportPlateBottom);        
+        
+        AlignmentCorrection alignmentCorrectionSupportTop = getSupportAlignmentCorrection(true);
+        SupportTop supportTop = new SupportTop("support_top", base, alignmentCorrectionSupportTop, cSupport);
+        surveyVolumes.add(supportTop);
+        
+        SupportPlateTop supportPlateTop = new SupportPlateTop("support_plate_top", base, supportTop, "Aluminum");
+        surveyVolumes.add(supportPlateTop);
+
+        for(int l=1; l<=5;++l) {
+            if(doLayer(l)) {
+                if(doBottom) makeModuleBundle(l,"bottom");
+                if(doTop)    makeModuleBundle(l,"top");
+            }
+        }       
+
+        if(isDebug()) {
+            System.out.printf("%s: DONE constructing the geometry objects\n", this.getClass().getSimpleName());
+            System.out.printf("%s: List of all the geometry objects built\n", this.getClass().getSimpleName());
+            for(SurveyVolume bg : surveyVolumes) {
+                System.out.printf("-------\n%s\n", bg.toString());
+            }
+        }
+
+    }
+
+    
+    
+    
+    /**
+     * Create the module. 
+     * @param layer - of the module
+     * @param half - top or bottom half of the tracker
+     */
+    protected void makeModuleBundle(int layer, String half) 
+    {
+
+        if(isDebug()) System.out.printf("%s: makeModule for layer %d %s \n", this.getClass().getSimpleName(), layer, half);
+
+
+        // build the module name
+        String volName = "module_L"+ layer + (half=="bottom"?"b":"t");      
+
+        boolean isL13 = ( layer >=1 && layer <=3 ) ? true : false;          
+
+        // find the mother and reference geometry
+        // Note that the reference geometry is the support plate and since that is assumed to be 
+        // created through it's references we don't need more than one reference to reach the mother coordinate system
+        final SurveyVolume mother;
+        final SurveyVolume ref;
+        if(half == "bottom") {
+            mother = getSurveyVolume(TrackerEnvelope.class);
+            ref = getSurveyVolume(SupportPlateBottom.class);
+        } else {
+            mother= getSurveyVolume(TrackerEnvelope.class);
+            ref = getSurveyVolume(SupportPlateTop.class);
+        }
+
+        //Create the module
+        TestRunModule module;
+        if(isL13) {
+            module = new TestRunModuleL13(volName, mother, ref, layer, half);
+        } else {
+            module = new TestRunModuleL45(volName, mother, ref, layer, half);
+        }
+
+
+        // create the bundle for this module
+        TestRunModuleBundle bundle = new TestRunModuleBundle(module);
+        addModuleBundle(bundle);
+
+        if(doAxial) makeHalfModule("axial", module);
+        if(doColdBlock) makeColdBlock(module);
+        if(doStereo) makeHalfModule("stereo", module);
+
+
+        if(isDebug()) {
+            System.out.printf("%s: created module bundle:\n", this.getClass().getSimpleName());
+            bundle.print();
+        }
+
+    }
+
+    /**
+     * Create the cold block object.
+     * @param mother to the cold block
+     */
+    protected void makeColdBlock(TestRunModule mother) { 
+    
+    
+        String moduleName = mother.getName();
+    
+        if(isDebug()) System.out.printf("%s: makeColdBlock for %s \n", this.getClass().getSimpleName(), moduleName);
+    
+    
+        String volName = moduleName + "_coldblock";
+    
+        // find layer
+        int layer = getLayerFromVolumeName(moduleName);
+    
+        // Build the half-module
+        TestRunColdBlock coldBlock;
+    
+        if(layer >= 1 && layer <=3) {
+            coldBlock = new TestRunColdBlockL13(volName, mother, layer);
+        } else if(layer >= 4 && layer <=5) {
+            coldBlock = new TestRunColdBlockL45(volName, mother, layer);
+        } else {
+            throw new RuntimeException("wrong layer for " + volName);
+        }
+    
+        TestRunModuleBundle bundle = (TestRunModuleBundle) getModuleBundle(mother);
+        bundle.coldBlock = coldBlock;
+    }
+    
+
+
+   
+    public static class TrackerEnvelope extends SurveyVolume {
+        // height of the dummy box holding the entire SVT: 
+        // this means the bottom of the base plate to the the inner surface of of the PS vac box for now
+        public static final double base_height = PS_vac_box_inner_height - BasePlate.base_plate_offset_height; 
+        public static final double base_width = BasePlate.base_plate_width;
+        public static final double base_length = BasePlate.base_plate_length;
+
+        public TrackerEnvelope(String name, SurveyVolume mother) {
+            super(name,mother, null);
+            init();
+        }
+        protected void setPos() {
+            final double ball_pos_base_x = -1.0*target_pos_wrt_base_plate_x;
+            final double ball_pos_base_y = -1.0*target_pos_wrt_base_plate_y;
+            final double ball_pos_base_z = target_pos_wrt_base_plate_z;		
+            final double vee_pos_base_x = ball_pos_base_x + BasePlate.base_plate_width;
+            final double vee_pos_base_y = ball_pos_base_y;
+            final double vee_pos_base_z = ball_pos_base_z;
+            final double flat_pos_base_x = ball_pos_base_x;
+            final double flat_pos_base_y = ball_pos_base_y;
+            final double flat_pos_base_z = ball_pos_base_z - BasePlate.base_plate_length;
+            setBallPos(ball_pos_base_x,ball_pos_base_y,ball_pos_base_z);
+            setVeePos(vee_pos_base_x,vee_pos_base_y,vee_pos_base_z);
+            setFlatPos(flat_pos_base_x, flat_pos_base_y, flat_pos_base_z);
+        }
+        protected void setCenter() {
+            setCenter(base_width/2.0, base_length/2.0, base_height/2.0 - BasePlate.base_plate_thickness);
+        }
+        protected void setBoxDim() {
+            setBoxDim(base_width,base_length,base_height);
+        }
+    }
+
+
+
+    public static class BasePlate extends SurveyVolume {
+        // Base plate references	
+        public static final double base_plate_thickness = 0.25*inch;
+        public static final double base_plate_width = 385.00;
+        public static final double base_plate_length = 1216.00;
+        //height from vacuum chamber surface
+        protected static final double base_plate_offset_height = 2.0; //from Marco's 3D model
+        public BasePlate(String name, SurveyVolume mother, String material) {
+            super(name,mother, null);
+            init();
+            setMaterial(material);
+        }
+        protected void setPos() {
+            setBallPos(0,0,0);
+            setVeePos(base_plate_width,ballPos.y(),ballPos.z());
+            setFlatPos(ballPos.x(),base_plate_length,ballPos.z());
+        }
+        protected void setCenter() {
+            setCenter(base_plate_width/2.0, base_plate_length/2.0, -base_plate_thickness/2.0);
+        }
+        protected void setBoxDim() {
+            setBoxDim(base_plate_width,base_plate_length, base_plate_thickness);
+        }
+    }
+
+
+
+
+    public static class CSupport extends SurveyVolume {
+        // This is the sequence of locating the support plate positions:
+        // The c-support pin positions are found
+        // the points on the axis of rotation are used as references for building the box surrounding the support plates (incl sensors).
+        // this should make it more straightforward when applying a tilt angle
+        // c-support:
+        // ball position is C-support pin position on electron side on the base plate surface
+        // vee position is C-support pin position on positron side on the base plate surface
+        // flat position is a randomly chosen point perpendicular to ball to vee vector and offset 10mm along the plate. 
+        // Note that the flat here sets the tilt angle of the support plates.
+
+        // c-support references
+        // pin position on base plate surface
+        private static final double ball_pos_csup_pin_bottom_x = 51.15;
+        private static final double ball_pos_csup_pin_bottom_y = 115.02;
+        private static final double ball_pos_csup_pin_bottom_z = 0.0;
+        private static final double vee_pos_csup_pin_bottom_x = 271.05;
+        private static  double vee_pos_csup_pin_bottom_y = 121.62;
+        private static  double vee_pos_csup_pin_bottom_z = 0.0;
+
+
+        public CSupport(String name, SurveyVolume mother) {
+            super(name,mother, null);
+            init();
+        }			
+        private void calcAndSetFlatPos() {
+            if(use30mradRotation) {
+                // find the rotation to place the flat point
+                Rotation rot1_csup = 
+                        new Rotation(
+                                new Vector3D(vee_pos_csup_pin_bottom_x-ball_pos_csup_pin_bottom_x,
+                                        vee_pos_csup_pin_bottom_y-ball_pos_csup_pin_bottom_y,
+                                        vee_pos_csup_pin_bottom_z-ball_pos_csup_pin_bottom_z),
+                                        new Vector3D(1,0,0));
+
+                Vector3D flat_pos_csup_pin_bottom_3D_rot = rot1_csup.applyTo(new Vector3D(0,10.0,0));
+                // translate
+                double flat_pos_csup_pin_bottom_x = ball_pos_csup_pin_bottom_x + flat_pos_csup_pin_bottom_3D_rot.getX();
+                double flat_pos_csup_pin_bottom_y = ball_pos_csup_pin_bottom_y + flat_pos_csup_pin_bottom_3D_rot.getY();
+                double flat_pos_csup_pin_bottom_z = ball_pos_csup_pin_bottom_z + flat_pos_csup_pin_bottom_3D_rot.getZ();
+
+                setFlatPos(flat_pos_csup_pin_bottom_x,flat_pos_csup_pin_bottom_y,flat_pos_csup_pin_bottom_z);
+                if(debug) System.out.println("rotated setPos for csupport: \n" + getFlatPos().toString());
+
+            } else {
+
+                //vee_pos_csup_pin_bottom_x = ball_pos_csup_pin_bottom_x + 0;
+                vee_pos_csup_pin_bottom_y = ball_pos_csup_pin_bottom_y;
+                vee_pos_csup_pin_bottom_z = ball_pos_csup_pin_bottom_z + 0;
+
+                double flat_pos_csup_pin_bottom_x = ball_pos_csup_pin_bottom_x + 0;
+                double flat_pos_csup_pin_bottom_y = ball_pos_csup_pin_bottom_y + 10.0;
+                double flat_pos_csup_pin_bottom_z = ball_pos_csup_pin_bottom_z + 0;
+
+                setFlatPos(flat_pos_csup_pin_bottom_x,flat_pos_csup_pin_bottom_y,flat_pos_csup_pin_bottom_z);
+                if(debug) System.out.println("setPos for csupport: \n" + getFlatPos().toString());
+
+            }
+        }
+        protected void setPos() {
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            calcAndSetFlatPos();
+            setBallPos(ball_pos_csup_pin_bottom_x,ball_pos_csup_pin_bottom_y,ball_pos_csup_pin_bottom_z);
+            setVeePos(vee_pos_csup_pin_bottom_x,vee_pos_csup_pin_bottom_y,vee_pos_csup_pin_bottom_z);
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        }
+        protected void setCenter() {
+            // this is never used since it's only a reference volume
+            setCenter(null);
+        }
+        protected void setBoxDim() {
+        }
+
+    }
+
+
+
+
+    public static class SupportTop extends SurveyVolume {
+        // Top only needs a vertical offset to be specified
+        private static final double ball_pos_csup_bearings_top_z = 146.4;
+        //these are for the box surrounding the whole support including modules
+        protected static final double support_top_length = SupportBottom.support_bottom_length;
+        protected static final double support_top_width = SupportBottom.support_bottom_width;
+        protected static final double support_top_height = SupportBottom.support_bottom_height;
+
+        public SupportTop(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
+            super(name,mother, alignmentCorrection);
+            init();
+        }
+        public SupportTop(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, SurveyVolume referenceGeom) {
+            super(name,mother,alignmentCorrection, referenceGeom);
+            init();
+        }
+        public SupportTop(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, List<SurveyVolume> referenceGeom) {
+            super(name,mother,alignmentCorrection, referenceGeom);
+            init();
+        }
+
+        protected void setPos() {
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            // the top has the same bearing positions as the bottom c-support except for the offset vertically from base plate
+            // the tilt angle is independent though.
+            setBallPos(SupportBottom.ball_pos_csup_bearings_bottom_x, SupportBottom.ball_pos_csup_bearings_bottom_y, ball_pos_csup_bearings_top_z);
+            setVeePos(SupportBottom.vee_pos_csup_bearings_bottom_x, SupportBottom.vee_pos_csup_bearings_bottom_y, ball_pos_csup_bearings_top_z);
+            // build the rotation to find the proper location of the flat
+            Rotation rot_csup_top = 
+                    new Rotation(RotationOrder.XYZ, 
+                            SupportPlateTop.support_plate_top_tilt_angle, 0.0, 0.0 );
+
+            // apply to flat local position (as for bottom it is an arbitrary offset)
+            Vector3D flat_pos_csup_bearings_top_3D_rot = 
+                    rot_csup_top.applyTo(new Vector3D(0.0,10.0,0.0));
+
+            // translate the flat position
+            final double flat_pos_csup_bearings_top_x = getBallPos().x() + flat_pos_csup_bearings_top_3D_rot.getX();
+            final double flat_pos_csup_bearings_top_y = getBallPos().y() + flat_pos_csup_bearings_top_3D_rot.getY();
+            final double flat_pos_csup_bearings_top_z = getBallPos().z() + flat_pos_csup_bearings_top_3D_rot.getZ();
+            setFlatPos(flat_pos_csup_bearings_top_x,flat_pos_csup_bearings_top_y,flat_pos_csup_bearings_top_z);
+
+            // since we don't care (no volume is built) about the local position of the bearings in the pin coord system we'll get rid of it
+            // and find the bearings position in the base coordinate system directly
+            if(referenceGeom==null) {
+                throw new RuntimeException("No ref found for " + getName());
+            }
+            /*
+            for(SurveyVolume ref : referenceGeom) {
+
+                if(debug) {
+                    System.out.printf("%s: survey positions before ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    printSurveyPos();
+                }
+
+                if(debug) System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+
+                ref.getCoord().getTransformation().transform(ballPos);
+                ref.getCoord().getTransformation().transform(veePos);
+                ref.getCoord().getTransformation().transform(flatPos);
+
+                if(debug) {
+                    System.out.printf("%s: survey positions after ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    printSurveyPos();
+                }
+            }
+            */
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        }
+        protected void setCenter() {
+            setCenter(support_top_width/2.0+1.0, support_top_length/2.0 + (17.00-10.50/2.0), -1.0 * (support_top_height/2.0 - (12.70-6.66-1.34)));
+        }
+        protected void setBoxDim() {
+            setBoxDim(support_top_width,support_top_length,support_top_height);
+        }
+        /*
+        protected void applyReferenceTransformation() {
+         
+            if(debug) {
+                System.out.printf("%s: coord system before ref transformations:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
+            }
+
+            for(SurveyVolume ref : referenceGeom) {
+
+                if(debug) {
+                    //System.out.printf("%s: survey positions before ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    //printSurveyPos();
+                    System.out.printf("%s: coord system before ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
+                }
+
+                if(debug) System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+                
+                getCoord().transform(ref.getCoord().getTransformation());
+                
+                //ref.getCoord().getTransformation().transform(ballPos);
+                //ref.getCoord().getTransformation().transform(veePos);
+                //ref.getCoord().getTransformation().transform(flatPos);
+
+                if(debug) {
+                    //System.out.printf("%s: survey positions after ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    //printSurveyPos();
+                    System.out.printf("%s: coord system after ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
+                }
+            }
+            
+            if(debug) {
+                System.out.printf("%s: coord system after ref transformations:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
+            }
+            
+            
+        }
+         */
+    }
+
+
+
+    public static class SupportBottom extends SurveyVolume {
+        // "bearings" are points on axis of rotation on the inside of the c-support frame where the insert get's attached
+        // this is referenced to the pin position of the c-support
+        private static final double ball_pos_csup_bearings_bottom_x = 240.0 - 265.0 + 14.0;
+        private static final double ball_pos_csup_bearings_bottom_y = (-6.0 + 22.0);
+        private static final double ball_pos_csup_bearings_bottom_z = 14.7;		
+        private static final double vee_pos_csup_bearings_bottom_x = 240.0- 129.0;
+        private static final double vee_pos_csup_bearings_bottom_y = (-6.0 + 22.0);
+        private static final double vee_pos_csup_bearings_bottom_z = 14.7;
+
+        //these are for the box surrounding the whole support including modules
+        protected static final double support_bottom_length = SupportPlateBottom.support_plate_bottom_length;
+        protected static final double support_bottom_width = (25.0-5.0) + TestRunModuleL13.module_box_L13_length;
+        protected static final double support_bottom_height = SupportPlateBottom.support_plate_bottom_height - SupportPlateBottom.support_plate_pocket_depth + TestRunModuleL13.module_box_L13_width + SupportPlateBottom.pedestal_height_L1;
+
+
+        public SupportBottom(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, SurveyVolume referenceGeom) {
+            super(name,mother,alignmentCorrection, referenceGeom);
+            init();
+        }
+
+        protected void setPos() {
+
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+            // now create the support box which will have it's coordinates at the rotation axis so that the flat determines the tilt of the plates
+            // it is referenced locally to the c-support pin coordinate system here
+
+            // build the rotation to find the proper location of the flat
+            Rotation rot_csup = 
+                    new Rotation(RotationOrder.XYZ, 
+                            SupportPlateBottom.support_plate_bottom_tilt_angle, 0.0, 0.0 );
+            // apply to flat local position
+            Vector3D flat_pos_csup_bearings_bottom_3D_rot = 
+                    rot_csup.applyTo(new Vector3D(0.0,10.0,0.0));
+            // translate
+            final double flat_pos_csup_bearings_bottom_x = ball_pos_csup_bearings_bottom_x + flat_pos_csup_bearings_bottom_3D_rot.getX();
+            final double flat_pos_csup_bearings_bottom_y = ball_pos_csup_bearings_bottom_y + flat_pos_csup_bearings_bottom_3D_rot.getY();
+            final double flat_pos_csup_bearings_bottom_z = ball_pos_csup_bearings_bottom_z + flat_pos_csup_bearings_bottom_3D_rot.getZ();
+
+            // make vectors
+            setBallPos(ball_pos_csup_bearings_bottom_x,ball_pos_csup_bearings_bottom_y,ball_pos_csup_bearings_bottom_z);
+            setVeePos(vee_pos_csup_bearings_bottom_x,vee_pos_csup_bearings_bottom_y,vee_pos_csup_bearings_bottom_z);	
+            setFlatPos(flat_pos_csup_bearings_bottom_x,flat_pos_csup_bearings_bottom_y,flat_pos_csup_bearings_bottom_z);
+
+
+            // create the coordinate system of the c-support bearings
+            //HPSTestRunTracker2014GeomDef.Coord csup_bearings_bottom_coord = new HPSTestRunTracker2014GeomDef.Coord(ball_pos_csup_bearings_bottom, vee_pos_csup_bearings_bottom, flat_pos_csup_bearings_bottom);		
+
+            // since we don't care (no volume is built) about the local position of the bearings in the pin coord system we'll get rid of it
+            // and find the bearings position in the base coordinate system directly
+            if(referenceGeom==null) {
+                throw new RuntimeException("No ref found for " + getName());
+            }
+            /*
+            for(SurveyVolume ref : referenceGeom) {
+
+                if(debug) {
+                    System.out.printf("%s: survey positions before ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    printSurveyPos();
+                }
+
+                if(debug) System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+
+                ref.getCoord().getTransformation().transform(ballPos);
+                ref.getCoord().getTransformation().transform(veePos);
+                ref.getCoord().getTransformation().transform(flatPos);
+
+                if(debug) {
+                    System.out.printf("%s: survey positions after ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    printSurveyPos();
+                }
+            }
+            */
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+
+        }
+        protected void setCenter() {
+            setCenter(support_bottom_width/2.0+1.0, support_bottom_length/2.0 + (17.00-10.50/2.0), support_bottom_height/2.0 - (12.70-6.66-1.34));
+        }
+        protected void setBoxDim() {
+            setBoxDim(support_bottom_width,support_bottom_length,support_bottom_height);
+        }
+
+    }
+
+
+    protected static abstract class SupportPlate extends SurveyVolume {
+        protected static final double support_plate_pocket_depth = 6.65; // Tim's sketchup, drawing says 6.66mm?
+        protected static final double pedestal_height_L1 = 11.00;
+        protected static final double pedestal_height_L2 = 9.50;
+        protected static final double pedestal_height_L3 = 8.00;
+        protected static final double pedestal_height_L4 = 10.00;
+        protected static final double pedestal_height_L5 = 7.00;
+        public SupportPlate(SurveyVolume mother, SurveyVolume referenceGeom, String name, String material) {
+            super(name,mother,null, referenceGeom);
+            setMaterial(material);
+        }
+        public SupportPlate(SurveyVolume mother, List<SurveyVolume> referenceGeom, String name, String material) {
+            super(name,mother,null, referenceGeom);
+            setMaterial(material);
+        }
+
+    }
+
+
+
+
+
+    public static class SupportPlateBottom extends SupportPlate {
+        // support plate references
+        // use a settable rotation to effectively determine the flat and therefore the tilt of the support 
+        protected static final double support_plate_bottom_tilt_angle = 0.0; 
+        protected static final double support_plate_bottom_height = 12.7;
+        protected static final double support_plate_bottom_length = 736.1;
+        protected static final double support_plate_bottom_width = 120.0;
+
+        public SupportPlateBottom(String name, SurveyVolume mother, SurveyVolume referenceGeom, String material) {
+            super(mother, referenceGeom, name, material);
+            init();				
+        }
+        public SupportPlateBottom(String name, SurveyVolume mother, List<SurveyVolume> referenceGeom, String material) {
+            super(mother, referenceGeom, name, material);
+            init();				
+        }
+        protected void setPos() {
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+            ballPos = new BasicHep3Vector(1.0, (17.0-5.0), 6.66+1.34); 
+            veePos = new BasicHep3Vector(ballPos.x() + support_plate_bottom_length, ballPos.y(),ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y() + support_plate_bottom_length,ballPos.z());
+
+            if(referenceGeom==null) {
+                throw new RuntimeException("No ref found for " + getName());
+            }
+            /*
+            for(SurveyVolume ref : referenceGeom) {
+
+                if(debug) {
+                    System.out.printf("%s: survey positions before ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    printSurveyPos();
+                }
+
+                if(debug) System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+
+                ref.getCoord().getTransformation().transform(ballPos);
+                ref.getCoord().getTransformation().transform(veePos);
+                ref.getCoord().getTransformation().transform(flatPos);
+
+                if(debug) {
+                    System.out.printf("%s: survey positions after ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                    printSurveyPos();
+                }
+            }
+            */
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        }
+        protected void setCenter() {
+            setCenter(support_plate_bottom_width/2.0, support_plate_bottom_length/2.0, -1.0 * support_plate_bottom_height/2.0);
+        }
+        @Override
+        protected void setBoxDim() {
+            setBoxDim(support_plate_bottom_width,support_plate_bottom_length,support_plate_bottom_height);
+        }
+    }
+
+
+    public static class SupportPlateTop extends SupportPlate {
+        // support plate references
+        // use a settable rotation to effectively determine the flat and therefore the tilt of the support 
+        protected static final double support_plate_top_tilt_angle = 0.0; 
+        protected static final double support_plate_top_length = SupportPlateBottom.support_plate_bottom_length;
+        protected static final double support_plate_top_width = SupportPlateBottom.support_plate_bottom_width;
+        protected static final double support_plate_top_height = SupportPlateBottom.support_plate_bottom_height;
+
+        public SupportPlateTop(String name, SurveyVolume mother, SurveyVolume referenceGeom, String material) {
+            super(mother,referenceGeom, name,material);
+            init();
+        }
+        protected void setPos() {
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+            ballPos = new BasicHep3Vector(1.0, (17.0-5.0), -1.0 * (6.66+1.34)); 
+            veePos = new BasicHep3Vector(ballPos.x() + support_plate_top_width, ballPos.y(),ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y() + support_plate_top_length,ballPos.z());
+
+            if(referenceGeom==null) {
+                throw new RuntimeException("No ref found for " + getName());
+            }
+            /*
+            for(SurveyVolume ref : referenceGeom) {
+
+                if(debug) System.out.printf("%s: survey positions before ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                if(debug) printSurveyPos();
+
+                if(debug) System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+
+                ref.getCoord().getTransformation().transform(ballPos);
+                ref.getCoord().getTransformation().transform(veePos);
+                ref.getCoord().getTransformation().transform(flatPos);
+
+                if(debug) System.out.printf("%s: survey positions after ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                if(debug) printSurveyPos();
+            }
+            */
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        }
+        protected void setCenter() {
+            setCenter(support_plate_top_width/2.0, support_plate_top_length/2.0,  support_plate_top_height/2.0);
+        }
+        @Override
+        protected void setBoxDim() {
+            setBoxDim(support_plate_top_width, support_plate_top_length, support_plate_top_height);
+        }
+    }
+
+
+
+
+    public static class TestRunModuleL45 extends TestRunModule {
+
+        protected static final double module_box_L45_length = 205.2 + box_extra_length; // includes lexan spacer and cold block
+        protected static final double module_box_L45_height = 12.5 + box_extra_height; // includes screws height
+        protected static final double module_box_L45_width = 65.3-12.0 +  box_extra_width; 
+        protected static final double dist_lower_sensor_edge_to_cold_block_mounting_surface = 7.662;
+
+
+        public TestRunModuleL45(String name, SurveyVolume mother, int layer,String half) {
+            super(name, mother, layer, half);
+        }
+        public TestRunModuleL45(String name, SurveyVolume mother, SurveyVolume ref, int layer, String half) {
+            super(name, mother, ref, layer, half);
+        }
+        protected double getColdBlockThickness() {
+            return TestRunColdBlockL45.coldblock_L45_thickness;
+        }
+        protected double getModuleBoxLength() {
+            return module_box_L45_length;
+        }
+        protected double getModuleBoxWidth() {
+            return module_box_L45_width;
+        }
+        protected double getModuleBoxHeight() {
+            return module_box_L45_height;
+        }
+        protected double get_dist_lower_sensor_edge_to_cold_block_mounting_surface() {
+            return dist_lower_sensor_edge_to_cold_block_mounting_surface;
+        }
+
+    }
+
+    public static class TestRunModuleL13 extends TestRunModule {
+        protected static final double module_box_L13_length = 205.2 + box_extra_length; // includes lexan spacer and cold block
+        protected static final double module_box_L13_height = 12.5 + box_extra_height; // includes screws height
+        protected static final double module_box_L13_width = 71.3 - 13.0 + box_extra_width; // height from cold block to encapsulate the whole module
+        protected static final double dist_lower_sensor_edge_to_cold_block_mounting_surface = 12.66;
+
+        public TestRunModuleL13(String name, SurveyVolume mother, int layer, String half) {
+            super(name, mother, layer, half);
+        }
+        public TestRunModuleL13(String name, SurveyVolume mother, SurveyVolume ref, int layer, String half) {
+            super(name, mother, ref, layer, half);
+        }
+        protected double getColdBlockThickness() {
+            return TestRunColdBlockL13.coldblock_L13_thickness;
+        }   
+        protected double getModuleBoxLength() {
+            return module_box_L13_length;
+        }
+        protected double getModuleBoxWidth() {
+            return module_box_L13_width;
+        }
+        protected double getModuleBoxHeight() {
+            return module_box_L13_height;
+        }
+        protected double get_dist_lower_sensor_edge_to_cold_block_mounting_surface() {
+            return dist_lower_sensor_edge_to_cold_block_mounting_surface;
+        }
+    }
+
+
+    public static abstract class TestRunModule extends BaseModule {
+        protected final static double box_extra_length = 10.0;// random at this point
+        protected final static double box_extra_width = 15.0;// random at this point
+        protected final static double box_extra_height = 1.0;// random at this point
+
+        public TestRunModule(String name, SurveyVolume mother, int layer, String half) {
+            super(name, mother,null,layer, half);
+            init();
+        }			
+        public TestRunModule(String name, SurveyVolume mother, SurveyVolume ref, int layer, String half) {
+            super(name, mother,null,ref,layer, half);
+            init();
+        }			
+        protected abstract double getColdBlockThickness();
+        protected abstract double getModuleBoxLength();
+        protected abstract double getModuleBoxWidth();
+        protected abstract double getModuleBoxHeight();
+        protected abstract double get_dist_lower_sensor_edge_to_cold_block_mounting_surface();
+
+        protected void setBoxDim() {
+            setBoxDim(getModuleBoxLength(),getModuleBoxHeight(),getModuleBoxWidth());
+        }
+        protected void setCenter() {
+            setCenter(getModuleBoxLength()/2.0-5.0, 0.0, getModuleBoxWidth()/2.0-box_extra_width/5.0); 
+        }			
+        protected void setPos() {
+
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+
+            if(isBottom()) {
+                switch (getLayer()) {
+                case 1:
+                    ballPos = new BasicHep3Vector(25.0, 661.1, SupportPlateBottom.pedestal_height_L1-SupportPlateBottom.support_plate_pocket_depth);
+                    veePos = new BasicHep3Vector(95.0, 661.1, SupportPlateBottom.pedestal_height_L1-SupportPlateBottom.support_plate_pocket_depth);
+                    flatPos = new BasicHep3Vector(60.0, 667.10, SupportPlateBottom.pedestal_height_L1-SupportPlateBottom.support_plate_pocket_depth);
+                    break;
+                case 2:
+                    ballPos = new BasicHep3Vector(25.0, 561.1, SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth);
+                    veePos = new BasicHep3Vector(95.0, 561.1, SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth);
+                    flatPos = new BasicHep3Vector(60.0, 567.10, SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth);	
+                    break;
+                case 3:
+                    ballPos = new BasicHep3Vector(25.0, 461.1, SupportPlateBottom.pedestal_height_L3-SupportPlateBottom.support_plate_pocket_depth);
+                    veePos = new BasicHep3Vector(95.0, 461.1, SupportPlateBottom.pedestal_height_L3-SupportPlateBottom.support_plate_pocket_depth);
+                    flatPos = new BasicHep3Vector(60.0, 467.10, SupportPlateBottom.pedestal_height_L3-SupportPlateBottom.support_plate_pocket_depth);
+                    break;
+                case 4:
+                    ballPos = new BasicHep3Vector(25.0, 261.1, SupportPlateBottom.pedestal_height_L4-SupportPlateBottom.support_plate_pocket_depth);
+                    veePos = new BasicHep3Vector(95.0, 261.1, SupportPlateBottom.pedestal_height_L4-SupportPlateBottom.support_plate_pocket_depth);
+                    flatPos = new BasicHep3Vector(60.0, 267.10, SupportPlateBottom.pedestal_height_L4-SupportPlateBottom.support_plate_pocket_depth);
+                    break;
+                case 5:
+                    ballPos = new BasicHep3Vector(25.0, 61.1, SupportPlateBottom.pedestal_height_L5-SupportPlateBottom.support_plate_pocket_depth);
+                    veePos = new BasicHep3Vector(95.0, 61.1, SupportPlateBottom.pedestal_height_L5-SupportPlateBottom.support_plate_pocket_depth);
+                    flatPos = new BasicHep3Vector(60.0, 67.10, SupportPlateBottom.pedestal_height_L5-SupportPlateBottom.support_plate_pocket_depth);
+                    break;
+                default:
+                    System.out.printf("ERROR invalid layer %d for half %s\n",getLayer(),getHalf());
+                    System.exit(1);
+                    break;
+                }
+
+            } else {
+                // top
+                // top has a fixed offset of 15mm along plate on module pocket positions w.r.t. bottom
+                // top local coordinates is rotation pi around u-vec so need to adjust pocket depth coordinate
+
+                switch (getLayer()) {
+                case 1:
+                    ballPos = new BasicHep3Vector(25.0, 676.1, -1.0 * (SupportPlateBottom.pedestal_height_L1-SupportPlateBottom.support_plate_pocket_depth));
+                    veePos = new BasicHep3Vector(95.0, 676.1, -1.0 * (SupportPlateBottom.pedestal_height_L1-SupportPlateBottom.support_plate_pocket_depth));
+                    flatPos = new BasicHep3Vector(60.0, 670.1, -1.0 * (SupportPlateBottom.pedestal_height_L1-SupportPlateBottom.support_plate_pocket_depth));
+                    break;
+                case 2:
+                    ballPos = new BasicHep3Vector(25.0, 576.1, -1.0 * (SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth));
+                    veePos = new BasicHep3Vector(95.0, 576.1, -1.0 * (SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth));
+                    flatPos = new BasicHep3Vector(60.0, 570.1, -1.0 * (SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth));
+                    break;
+                case 3:
+                    ballPos = new BasicHep3Vector(25.0, 476.1, -1.0 * (SupportPlateBottom.pedestal_height_L3-SupportPlateBottom.support_plate_pocket_depth));
+                    veePos = new BasicHep3Vector(95.0, 476.1, -1.0 * (SupportPlateBottom.pedestal_height_L3-SupportPlateBottom.support_plate_pocket_depth));
+                    flatPos =new BasicHep3Vector(60.0, 470.1, -1.0 * (SupportPlateBottom.pedestal_height_L3-SupportPlateBottom.support_plate_pocket_depth));
+                    break;
+                case 4:
+                    ballPos = new BasicHep3Vector(25.0, 276.1, -1.0 * (SupportPlateBottom.pedestal_height_L4-SupportPlateBottom.support_plate_pocket_depth));
+                    veePos = new BasicHep3Vector(95.0, 276.1, -1.0 * (SupportPlateBottom.pedestal_height_L4-SupportPlateBottom.support_plate_pocket_depth));
+                    flatPos = new BasicHep3Vector(60.0, 270.1, -1.0 * (SupportPlateBottom.pedestal_height_L4-SupportPlateBottom.support_plate_pocket_depth));
+                    break;
+                case 5:
+                    ballPos = new BasicHep3Vector(25.0, 76.1, -1.0 * (SupportPlateBottom.pedestal_height_L5-SupportPlateBottom.support_plate_pocket_depth));
+                    veePos = new BasicHep3Vector(95.0, 76.1, -1.0 * (SupportPlateBottom.pedestal_height_L5-SupportPlateBottom.support_plate_pocket_depth));
+                    flatPos = new BasicHep3Vector(60.0, 70.1, -1.0 * (SupportPlateBottom.pedestal_height_L5-SupportPlateBottom.support_plate_pocket_depth));
+                    break;
+                default:
+                    System.out.printf("ERROR invalid layer %d for half %s\n",getLayer(),getHalf());
+                    System.exit(1);
+                    break;
+                }
+            }
+
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+
+            /*
+            // walk through the reference volumes
+            if(referenceGeom!=null) {
+                for(SurveyVolume ref : referenceGeom) {
+
+                    if(debug) {
+                        System.out.printf("%s: survey positions before ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                        printSurveyPos();
+                    }
+
+                    if(debug) System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+
+                    ref.getCoord().getTransformation().transform(ballPos);
+                    ref.getCoord().getTransformation().transform(veePos);
+                    ref.getCoord().getTransformation().transform(flatPos);
+
+                    if(debug) {
+                        System.out.printf("%s: survey positions after ref %s transform\n",this.getClass().getSimpleName(),ref.getName());
+                        printSurveyPos();
+                    }
+                }
+            }
+            */
+
+        }
+
+    }
+
+
+    public static abstract class BaseModule extends SurveyVolume {
+        protected int layer;
+        protected String half;
+
+        public BaseModule(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name, mother, alignmentCorrection);
+            setLayer(layer);
+            setHalf(half);
+            isValid();
+        }
+        public BaseModule(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, SurveyVolume ref, int layer, String half) {
+            super(name, mother, alignmentCorrection, ref);
+            setLayer(layer);
+            setHalf(half);
+            isValid();
+        }
+        private void isValid() {
+            if(half!="bottom" && half!="top") {
+                System.out.printf("ERROR invalid half %s for BaseModule\n",half);
+                System.exit(1);
+            }
+        }
+        public int getLayer() {
+            return layer;
+        }
+        public void setLayer(int layer) {
+            this.layer = layer;
+        }
+
+        public String getHalf() {
+            return half;
+        }
+
+        public void setHalf(String half) {
+            this.half = half;
+        }
+
+        public boolean isBottom() {
+            return getHalf() == "bottom" ? true : false;
+        }
+
+    }
+
+
+
+    public abstract static class TestRunHalfModule extends BaseModule {
+
+        // Find the coordinate system of the half-modules w.r.t. to the module survey points
+        // We are going to know the sensor center position w.r.t. module coordinate system so the half-module 
+        // is really just a dummy volume to contain the daughters. Therefore place it at the same place 
+        // as where the sensor coordinate system will be to make things simpler.
+
+        // Distance from sensor to CF edge: 180mm
+        // Distance from CF edge to screw hole: 30mm
+        // Distance from screw hole to edge of cold block: 33.75mm
+        // Distance from edge of cold block to hole/ball position: 5mm
+        protected static final double dist_sensor_center_to_coldblock_hole_vdir = (180.0 - 30.0 + (33.75 - 5.0)) - Sensor.length/2.0;	
+        protected static final double half_module_thickness = TestRunHalfModule.getHybridThickness() + TestRunHalfModule.getCFThickness() + HalfModuleLamination.thickness;
+        protected static final double half_module_length = TestRunHalfModule.getCFLength();
+        protected static final double half_module_width = 6.83 + Sensor.width;
+
+        protected double stereo_angle = 0.0;
+
+        public TestRunHalfModule(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name,mother, alignmentCorrection, layer, half);
+        }
+
+        protected void setCenter() {
+            // Find distance to center in the local coordinate system 
+            // Note that this can be different between axial and stereo since the survey positions determine the local coordinate 
+            // system now.
+            // I'm not sure this feels good but this has to be done somewhere
+//            double box_center_local_x =  TestRunHalfModule.getLength()/2.0 - ( (170.00 + 10.00) - Sensor.getSensorLength()/2.0); 
+//            double box_center_local_y = -1.0*TestRunHalfModule.getThickness()/2.0 + (TestRunHalfModule.getCFThickness() + HalfModuleLamination.kapton_thickness + Sensor.getSensorThickness()/2.0);
+//            double box_center_local_z = TestRunHalfModule.getWidth()/2.0 - ( 12.66 - (8.83 -3.00) + Sensor.width/2.0 ); 
+            
+            double box_center_local_x =  TestRunHalfModule.getLength()/2.0 - ( (170.00 + 10.00) - Sensor.length/2.0); 
+            double box_center_local_y = - Sensor.getSensorThickness()/2.0 - HalfModuleLamination.thickness - CarbonFiber.thickness + half_module_thickness/2.0; 
+            double box_center_local_z = TestRunHalfModule.getWidth()/2.0 - ( 12.66 - (8.83 -3.00) + Sensor.width/2.0 ); 
+            
+            
+            if(useSiStripsConvention) {
+                //setCenter(box_center_local_z, box_center_local_x, box_center_local_y); 
+                setCenter(-1.0*box_center_local_z, box_center_local_x, box_center_local_y); 
+            } else {
+                setCenter(box_center_local_x, box_center_local_y, box_center_local_z); 
+            }
+        }
+        protected void setBoxDim() {
+            //setBoxDim(getLength(), getThickness(), getWidth());
+            
+            if(useSiStripsConvention) {
+                setBoxDim(getWidth(),getLength(),getThickness());
+                //setBoxDim(getSensorWidth(),getSensorLength(),getSensorThickness());
+            } else {
+                setBoxDim(getLength(), getThickness(), getWidth());
+                //setBoxDim(getSensorLength(),getSensorThickness(),getSensorWidth());
+            }
+            
+        }
+        protected double getStereoAngle() {
+            return stereo_angle;
+        }
+        protected void setStereoAngle(double stereo_angle) {
+            this.stereo_angle = stereo_angle;
+        }
+        public static double getCFThickness() {
+            return CarbonFiber.thickness;
+        }
+        public static double getCFLength() {
+            return CarbonFiber.length;
+        }
+        public static double getCFWidth() {
+            return CarbonFiber.width;
+        }
+        public static double getHybridLength() {
+            return Hybrid.hybrid_length;
+        }
+        public static double getHybridWidth() {
+            return Hybrid.hybrid_width;
+        }
+        public static double getHybridThickness() {
+            return Hybrid.hybrid_thickness;
+        }
+        public static double getThickness() {
+            return half_module_thickness;
+        }
+        public static double getLength() {
+            return half_module_length;
+        }
+        public static double getWidth() {
+            return half_module_width;
+        }
+
+
+    }
+
+
+    public static class TestRunHalfModuleAxial extends TestRunHalfModule {
+
+        public TestRunHalfModuleAxial(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+
+        protected void setPos() {
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+            final double coldBlockThick = getLayer() <=3 ? TestRunColdBlockL13.coldblock_L13_thickness : TestRunColdBlockL45.coldblock_L45_thickness;
+            final double dist_lower_sensor_edge_to_cold_block_mounting_surface = getLayer() <=3 ? TestRunModuleL13.dist_lower_sensor_edge_to_cold_block_mounting_surface : TestRunModuleL45.dist_lower_sensor_edge_to_cold_block_mounting_surface;
+
+            double ball_pos_halfmod_local_x =  dist_sensor_center_to_coldblock_hole_vdir;
+            double ball_pos_halfmod_local_y =  -1.0* (coldBlockThick/2.0 + TestRunHalfModule.getCFThickness() + HalfModuleLamination.thickness + Sensor.getSensorThickness()/2.0);
+            if(useFakeHalfModuleAxialPos) {
+                ball_pos_halfmod_local_x = ball_pos_halfmod_local_x*2.0;
+                ball_pos_halfmod_local_y = -2.0*ball_pos_halfmod_local_y;
+            }				
+            final double ball_pos_halfmod_local_z =  dist_lower_sensor_edge_to_cold_block_mounting_surface + Sensor.width/2.0;
+            
+            
+            double vee_pos_halfmod_local_x;
+            double vee_pos_halfmod_local_y;
+            double vee_pos_halfmod_local_z;
+            double flat_pos_halfmod_local_x;
+            double flat_pos_halfmod_local_y;
+            double flat_pos_halfmod_local_z;
+
+
+            if(useSiStripsConvention) {
+//                vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+//                vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+//                vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z + Sensor.width/2.0;
+//                flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.getSensorLength()/2.0;
+//                flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+//                flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;        
+                vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+                vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z - Sensor.width/2.0;
+                flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.length/2.0;
+                flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;        
+
+            } else {
+                vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.length/2.0;
+                vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z;
+                flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+                flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y + Sensor.getSensorThickness()/2.0;
+                flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;        
+            }
+            ballPos = new BasicHep3Vector(ball_pos_halfmod_local_x, ball_pos_halfmod_local_y, ball_pos_halfmod_local_z);
+            veePos = new BasicHep3Vector(vee_pos_halfmod_local_x, vee_pos_halfmod_local_y,vee_pos_halfmod_local_z);
+            flatPos = new BasicHep3Vector(flat_pos_halfmod_local_x, flat_pos_halfmod_local_y,flat_pos_halfmod_local_z);
+            
+            
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+
+        }
+        
+        
+        
+    }
+
+
+    public static class TestRunHalfModuleStereo extends TestRunHalfModule {
+
+        public TestRunHalfModuleStereo(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            if(layer<=3) stereo_angle = -0.1;
+            else if(layer>=4&&layer<=5) stereo_angle = -0.05;
+            else throw new RuntimeException("Layer " + layer + " is not defined.");
+            init();
+            //setExplicitRotation();
+        }
+
+        protected void setPos() {
+            
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+            //very similar to axial, see note below
+
+            final double coldBlockThick = getLayer() <=3 ? TestRunColdBlockL13.coldblock_L13_thickness : TestRunColdBlockL45.coldblock_L45_thickness;
+            final double dist_lower_sensor_edge_to_cold_block_mounting_surface = getLayer() <=3 ? TestRunModuleL13.dist_lower_sensor_edge_to_cold_block_mounting_surface : TestRunModuleL45.dist_lower_sensor_edge_to_cold_block_mounting_surface;
+
+//            final double ball_pos_halfmod_local_x =  dist_sensor_center_to_coldblock_hole_vdir;
+//            // note minus sign to separate from axial
+//            final double ball_pos_halfmod_local_y =  -1.0 * (-1.0* (coldBlockThick/2.0 + TestRunHalfModule.getCFThickness() + HalfModuleLamination.kapton_thickness + Sensor.getSensorThickness()/2.0));
+//            final double ball_pos_halfmod_local_z =  dist_lower_sensor_edge_to_cold_block_mounting_surface + Sensor.width/2.0;
+//            final double vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.getSensorLength()/2.0;
+//            final double vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+//            final double vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z;
+//            final double flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+//            final double flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y + Sensor.getSensorThickness()/2.0;
+//            final double flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;		
+//            ballPos = new BasicHep3Vector(ball_pos_halfmod_local_x, ball_pos_halfmod_local_y, ball_pos_halfmod_local_z);
+//            veePos = new BasicHep3Vector(vee_pos_halfmod_local_x, vee_pos_halfmod_local_y,vee_pos_halfmod_local_z);
+//            flatPos = new BasicHep3Vector(flat_pos_halfmod_local_x, flat_pos_halfmod_local_y,flat_pos_halfmod_local_z);
+            
+            double ball_pos_halfmod_local_x;
+            double ball_pos_halfmod_local_y;
+            double ball_pos_halfmod_local_z;
+            double vee_pos_halfmod_local_x;
+            double vee_pos_halfmod_local_y;
+            double vee_pos_halfmod_local_z;
+            double flat_pos_halfmod_local_x;
+            double flat_pos_halfmod_local_y;
+            double flat_pos_halfmod_local_z;
+
+            ball_pos_halfmod_local_x =  dist_sensor_center_to_coldblock_hole_vdir;
+            // note minus sign to separate from axial
+            ball_pos_halfmod_local_y =  -1.0 * (-1.0* (coldBlockThick/2.0 + TestRunHalfModule.getCFThickness() + HalfModuleLamination.thickness + Sensor.getSensorThickness()/2.0));
+            ball_pos_halfmod_local_z =  dist_lower_sensor_edge_to_cold_block_mounting_surface + Sensor.width/2.0;
+            
+            if(useSiStripsConvention) {
+
+//                vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x ;
+//                vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+//                vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z + Sensor.width/2.0;
+//                flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.getSensorLength()/2.0;
+//                flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+//                flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;      
+
+
+
+                //                vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+                //                vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                //                vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z - Sensor.width/2.0;
+                //                flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.getSensorLength()/2.0;
+                //                flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                //                flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;            
+
+                
+                vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+                vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z - Sensor.width/2.0;
+                flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.length/2.0;
+                flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;        
+                
+
+            } else {
+                
+                 vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.length/2.0;
+                 vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+                 vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z;
+                 flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+                 flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y + Sensor.getSensorThickness()/2.0;
+                 flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;      
+                
+                
+                
+//                
+//                vee_pos_halfmod_local_x =  ball_pos_halfmod_local_x + Sensor.getSensorLength()/2.0;
+//                vee_pos_halfmod_local_y =  ball_pos_halfmod_local_y;
+//                vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z;
+//                flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
+//                flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y + Sensor.getSensorThickness()/2.0;
+//                flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;        
+            }
+           
+            
+            
+            
+            
+            ballPos = new BasicHep3Vector(ball_pos_halfmod_local_x, ball_pos_halfmod_local_y, ball_pos_halfmod_local_z);
+            veePos = new BasicHep3Vector(vee_pos_halfmod_local_x, vee_pos_halfmod_local_y,vee_pos_halfmod_local_z);
+            flatPos = new BasicHep3Vector(flat_pos_halfmod_local_x, flat_pos_halfmod_local_y,flat_pos_halfmod_local_z);
+            
+            
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        
+        }
+
+
+
+
+
+        protected void applyGenericCoordinateSystemCorrections() {
+            // Apply whatever corrections we want to the final volume as created
+            // Maybe alignment corrections too but should be done in the top level
+
+            // Rotate these into the right place for the stereo
+            // My rotations here are active rotations in the mother coordinate system frame
+            // Sloppy description of the frame
+            // u: direction along long edge of half module i.e. along strips
+            // v: normal to sensor plane
+            // w: perpendicular to the sensor
+
+            // flip around u 
+            Rotation r1 = new Rotation(new Vector3D(1,0,0),Math.PI);
+            // apply stereo angle around v
+            Rotation r2 = new Rotation(new Vector3D(0,1,0),stereo_angle);
+            // Build full rotation
+            Rotation r = r2.applyTo(r1);
+            //Rotation r = r1;
+            if(debug) System.out.printf("%s: Coord before corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+            if(debug) System.out.printf("%s: box center before corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            getCoord().rotateApache(r);
+            if(debug) System.out.printf("%s: Coord after corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+            if(debug) System.out.printf("%s: box center after corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+
+
+        }
+
+
+    }
+
+    public static abstract class TestRunColdBlock extends SurveyVolume {		
+        private int layer;
+        public TestRunColdBlock(String name, SurveyVolume mother, int layer) {
+            super(name, mother, null);
+            setLayer(layer);
+            init();
+        }
+        protected abstract double getWidth();
+        protected abstract double getLength();
+        protected abstract double getHeight();
+        public int getLayer() {
+            return layer;
+        }
+        public void setLayer(int layer) {
+            this.layer = layer;
+        }
+        protected void setCenter() {
+            setCenter(getLength()/2.0, 0.0, getWidth()/2.0); 
+        }
+        protected void setPos() {
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+            // cold block position w.r.t. module box coordinate system
+            // this is a dummy coordinate system, make it simple
+            // edge of cold block on the mounting surface
+            final double ball_pos_coldblock_local_x =  -5.00; 
+            final double ball_pos_coldblock_local_y =  0.00;
+            final double ball_pos_coldblock_local_z =  0.00;
+            final double vee_pos_coldblock_local_x =  ball_pos_coldblock_local_x + 1.0; //arbitrary distance 
+            final double vee_pos_coldblock_local_y =  ball_pos_coldblock_local_y;  
+            final double vee_pos_coldblock_local_z =  ball_pos_coldblock_local_z;  
+            final double flat_pos_coldblock_local_x =  ball_pos_coldblock_local_x;  
+            final double flat_pos_coldblock_local_y =  ball_pos_coldblock_local_y + 1.0;  //arbitrary distance 
+            final double flat_pos_coldblock_local_z =  ball_pos_coldblock_local_z;  
+            setBallPos(ball_pos_coldblock_local_x, ball_pos_coldblock_local_y, ball_pos_coldblock_local_z);
+            setVeePos(vee_pos_coldblock_local_x, vee_pos_coldblock_local_y,vee_pos_coldblock_local_z);
+            setFlatPos(flat_pos_coldblock_local_x, flat_pos_coldblock_local_y,flat_pos_coldblock_local_z);
+            
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+            
+        }
+        protected void setBoxDim() {
+            setBoxDim(getLength(), getHeight(), getWidth());
+        }
+    }
+
+    public static class TestRunColdBlockL13 extends TestRunColdBlock {			
+        protected static final double coldblock_L13_length = 82.00;
+        protected static final double coldblock_L13_width = 52.50;
+        protected static final double coldblock_L13_thickness = 6.00;
+
+        public TestRunColdBlockL13(String name, SurveyVolume mother, int layer) {
+            super(name, mother, layer);
+        }
+        protected double getWidth() {
+            return coldblock_L13_width;
+        }
+        protected double getLength() {
+            return coldblock_L13_length;
+        }
+        protected double getHeight() {
+            return coldblock_L13_thickness;
+        }
+        protected double getThickness() {
+            return getHeight();
+        }
+    }
+
+    public static class TestRunColdBlockL45 extends TestRunColdBlock {			
+        protected static final double coldblock_L45_length = 82.00;
+        protected static final double coldblock_L45_width = 51.00;
+        protected static final double coldblock_L45_thickness = 6.00;
+
+        public TestRunColdBlockL45(String name, SurveyVolume mother, int layer) {
+            super(name, mother, layer);
+        }
+        protected double getWidth() {
+            return coldblock_L45_width;
+        }
+        protected double getLength() {
+            return coldblock_L45_length;
+        }
+        protected double getHeight() {
+            return coldblock_L45_thickness;
+        }
+        protected double getThickness() {
+            return getHeight();
+        }
+    }
+
+
+    /**
+     * Silicon sensor @SurveyVolume.
+     * The coordinate system is located at the same position and orientation as the half-module.
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class Sensor extends HalfModuleComponent {
+        static final double length= 100.00; 
+        static final double width = 40.34; 
+        static final double thickness = 0.32;
+        static final double height = thickness;
+        public Sensor(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, int id) {
+            super(name, mother, alignmentCorrection, id);
+            init();
+        }
+        public static double getSensorThickness() {
+            return height;
+        }
+        protected void setPos() {
+            
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+
+            setBallPos(0,0,0);
+            setVeePos(ballPos.x() + width/2.0, ballPos.y(), ballPos.z());
+            setFlatPos(ballPos.x(),ballPos.y() + length/2.0, ballPos.z());                   
+            
+//            if(useSiStripsConvention) {
+//                setBallPos(0,0,0);
+//                setVeePos(ballPos.x(), ballPos.y(), ballPos.z() + getSensorWidth()/2.0);
+//                setFlatPos(ballPos.x() + getSensorLength()/2.0,ballPos.y(), ballPos.z());					
+//            } else {
+//                setBallPos(0,0,0);
+//                setVeePos(ballPos.x() + getSensorLength()/2.0, ballPos.y(), ballPos.z());
+//                setFlatPos(ballPos.x(),ballPos.y() + getSensorThickness()/2.0, ballPos.z());
+//            }
+
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+            
+        }
+        protected void setCenter() {
+            setCenter(0,0,0);
+        }
+        protected void setBoxDim() {
+            if(useSiStripsConvention) {
+                setBoxDim(width,length,thickness);
+            } else {
+                setBoxDim(length,thickness,width);
+            }
+        }
+        protected double getThickness() {
+            return thickness;
+        }
+        protected double getHeigth() {
+            return thickness;
+        }
+        protected double getWidth() {
+            return width;
+        }
+        protected double getLength() {
+            return length;
+        }			
+    }
+
+    /**
+     * Active part of the @Sensor @SurveyVolume.
+     * The coordinate system is located at the same position and orientation as the sensor.
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class ActiveSensor extends SurveyVolume {
+        private static final double length= 98.33;
+        private static final double width = 38.3399;
+        private static final double thickness = Sensor.thickness;
+        public ActiveSensor(String name, SurveyVolume m) {
+            super(name, m, null);
+            init();
+        }
+        public static double getActiveSensorLength() {
+            return length;
+        }
+        public static double getActiveSensorWidth() {
+            return width;
+        }
+        public static double getActiveSensorHeight() {
+            return thickness;
+        }
+        public static double getActiveSensorThickness() {
+            return getActiveSensorHeight();
+        }
+        protected void setPos() {
+            
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+
+            ballPos = new BasicHep3Vector(0,0,0);
+            veePos = new BasicHep3Vector(getActiveSensorWidth()/2.0,0,0);
+            flatPos = new BasicHep3Vector(0,getActiveSensorLength()/2.0,0);
+
+//            if(useSiStripsConvention) {
+//                ballPos = new BasicHep3Vector(0,0,0);
+//                veePos = new BasicHep3Vector(getActiveSensorWidth()/2.0,0,0);
+//                flatPos = new BasicHep3Vector(0,getActiveSensorLength()/2.0,0);
+//            } else {
+//                ballPos = new BasicHep3Vector(0,0,0);
+//                veePos = new BasicHep3Vector(getActiveSensorWidth()/2.0,0,0);
+//                flatPos = new BasicHep3Vector(0,getActiveSensorLength()/2.0,0);
+//            }
+            
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        }
+        protected void setCenter() {
+            setCenter(0,0,0);
+        }
+        protected void setBoxDim() {
+
+            setBoxDim(getActiveSensorWidth(), getActiveSensorLength(), getActiveSensorThickness());
+
+//            if(useSiStripsConvention) {
+//                setBoxDim(getActiveSensorWidth(), getActiveSensorLength(), getActiveSensorThickness());
+//            } else {
+//                setBoxDim(getActiveSensorLength(),getActiveSensorThickness(),getActiveSensorWidth());
+//            }
+        }
+    }
+
+ 
+    /**
+     * Kapton insulation @SurveyVolume for the half-module
+     * The coordinate system is located at the same position and orientation as the sensor.
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class HalfModuleLamination extends HalfModuleComponent {
+        protected static final double length = 184.0;
+        protected static final double width = 40.0; // -2.0; // width under the sensor, 2mm wider under hybrid.
+        protected static final double thickness = 0.050;
+        public HalfModuleLamination(String name, SurveyVolume m, int id) {
+            super(name, m, null, id);
+            init();
+        }
+        protected void setPos() {
+
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+
+            //             double ball_pos_kapton_local_x =  -1 * (180.0 - Sensor.getSensorLength()/2.0) + 8.5;
+            //             double ball_pos_kapton_local_y =  (Sensor.getSensorThickness()/2.0 + HalfModuleLamination.kapton_thickness/2.0);
+            //             double ball_pos_kapton_local_z = -1 * (Sensor.width/2.0 + 12.66) + 8.83 - 3.00 + 6.00 ;
+            //             double vee_pos_kapton_local_x =  ball_pos_kapton_local_x + 1.0; // arbitrary distance
+            //             double vee_pos_kapton_local_y =  ball_pos_kapton_local_y;
+            //             double vee_pos_kapton_local_z =  ball_pos_kapton_local_z;
+            //             double flat_pos_kapton_local_x =  ball_pos_kapton_local_x;
+            //             double flat_pos_kapton_local_y =  ball_pos_kapton_local_y + HalfModuleLamination.kapton_thickness/2.0; // arbitrary distance
+            //             double flat_pos_kapton_local_z =  ball_pos_kapton_local_z;
+
+//            double ball_pos_kapton_local_x =  -1 * (Sensor.width/2.0 + 12.66) + 8.83 - 3.00 + 6.00;
+//            double ball_pos_kapton_local_y =  -1 * (180.0 - Sensor.getSensorLength()/2.0) + 8.5;
+//            double ball_pos_kapton_local_z = (Sensor.getSensorThickness()/2.0 + HalfModuleLamination.kapton_thickness/2.0);
+//            double vee_pos_kapton_local_x =  ball_pos_kapton_local_x + Sensor.width/2.0; // arbitrary distance
+//            double vee_pos_kapton_local_y =  ball_pos_kapton_local_y;
+//            double vee_pos_kapton_local_z =  ball_pos_kapton_local_z;
+//            double flat_pos_kapton_local_x =  ball_pos_kapton_local_x;
+//            double flat_pos_kapton_local_y =  ball_pos_kapton_local_y + Sensor.getSensorLength(); // arbitrary distance
+//            double flat_pos_kapton_local_z =  ball_pos_kapton_local_z;
+
+            double ball_pos_kapton_local_x =  Sensor.width/2.0 + 6.83 - 6.0 - width/2.0;
+            double ball_pos_kapton_local_y =  Sensor.length/2.0 - 170.0 - 10.0 + 8.5 + length/2.0;
+            double ball_pos_kapton_local_z = -1.0 * (Sensor.getSensorThickness()/2.0 + HalfModuleLamination.thickness/2.0);
+            
+            //ballPos = new BasicHep3Vector(ball_pos_kapton_local_x,ball_pos_kapton_local_y,ball_pos_kapton_local_z);
+            //veePos = new BasicHep3Vector(vee_pos_kapton_local_x,vee_pos_kapton_local_y,vee_pos_kapton_local_z);
+            //flatPos = new BasicHep3Vector(flat_pos_kapton_local_x,flat_pos_kapton_local_y,flat_pos_kapton_local_z);
+
+            ballPos = new BasicHep3Vector(ball_pos_kapton_local_x,ball_pos_kapton_local_y,ball_pos_kapton_local_z);
+            veePos = new BasicHep3Vector(ballPos.x() + 1.0,ballPos.y(),ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(),ballPos.y()+ 1.0,ballPos.z());
+            
+            
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        }
+        protected void setCenter() {
+            setCenter(0.0, 0.0, 0.0);
+            //setCenter(getWidth()/2.0, getLength()/2.0,0.0);
+            //setCenter(getWidth()/2.0, getLength()/2.0,0.0);
+        }
+        protected  double getThickness() {
+            return thickness;
+        }
+        protected  double getHeigth() {
+            return getThickness();
+        }
+        protected  double getWidth() {
+            return width;
+        }
+        protected  double getLength() {
+            return length;
+        }
+        protected void setBoxDim() {
+            setBoxDim(getWidth(),getLength(),getThickness());
+            //setBoxDim(getLength(),getThickness(),getWidth());
+        }
+    }
+
+    /**
+     * Carbon fiber backing @SurveyVolume for the half-module
+     * The coordinate system is located at the same position and orientation as the sensor.
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class CarbonFiber extends HalfModuleComponent {
+        protected static  final double length = 200.;
+        protected static  final double width = 45.;
+        protected static  final double thickness = 0.250;
+        public CarbonFiber(String name, SurveyVolume m, int id) {
+            super(name, m, null, id);
+            init();
+        }
+        protected void setPos() {
+            
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+//            final double ball_pos_cf_local_x =  -1 * (180.0 - Sensor.getSensorLength()/2.0);
+//            final double ball_pos_cf_local_y =  (Sensor.getSensorThickness()/2.0 + HalfModuleLamination.kapton_thickness + TestRunHalfModule.getCFThickness()/2.0);
+//            final double ball_pos_cf_local_z = -1 * (Sensor.width/2.0 + 12.66) + 8.83 - 3.00;
+//            final double vee_pos_cf_local_x =  ball_pos_cf_local_x + 1.0; // arbitrary distance
+//            final double vee_pos_cf_local_y =  ball_pos_cf_local_y;
+//            final double vee_pos_cf_local_z =  ball_pos_cf_local_z;
+//            final double flat_pos_cf_local_x =  ball_pos_cf_local_x;
+//            final double flat_pos_cf_local_y =  ball_pos_cf_local_y + TestRunHalfModule.getCFThickness()/2.0; // arbitrary distance
+//            final double flat_pos_cf_local_z =  ball_pos_cf_local_z;
+//            setBallPos(ball_pos_cf_local_x,ball_pos_cf_local_y,ball_pos_cf_local_z);
+//            setVeePos(vee_pos_cf_local_x,vee_pos_cf_local_y,vee_pos_cf_local_z);
+//            setFlatPos(flat_pos_cf_local_x,flat_pos_cf_local_y,flat_pos_cf_local_z);
+           
+//            final double ball_pos_cf_local_x =  -1 * (Sensor.width/2.0 + 12.66) + 8.83 - 3.00;
+//            final double ball_pos_cf_local_y =  -1 * (180.0 - Sensor.getSensorLength()/2.0);
+//            final double ball_pos_cf_local_z = (Sensor.getSensorThickness()/2.0 + HalfModuleLamination.kapton_thickness + TestRunHalfModule.getCFThickness()/2.0);
+//            final double vee_pos_cf_local_x =  ball_pos_cf_local_x + Sensor.width/2.0; // arbitrary distance
+//            final double vee_pos_cf_local_y =  ball_pos_cf_local_y;
+//            final double vee_pos_cf_local_z =  ball_pos_cf_local_z;
+//            final double flat_pos_cf_local_x =  ball_pos_cf_local_x;
+//            final double flat_pos_cf_local_y =  ball_pos_cf_local_y + Sensor.getSensorLength()/2.0; // arbitrary distance
+//            final double flat_pos_cf_local_z =  ball_pos_cf_local_z;
+//            setBallPos(ball_pos_cf_local_x,ball_pos_cf_local_y,ball_pos_cf_local_z);
+//            setVeePos(vee_pos_cf_local_x,vee_pos_cf_local_y,vee_pos_cf_local_z);
+//            setFlatPos(flat_pos_cf_local_x,flat_pos_cf_local_y,flat_pos_cf_local_z);
+ 
+            
+            final double ball_pos_cf_local_x =  Sensor.width/2.0 + 6.83 - width/2.0;
+            final double ball_pos_cf_local_y =  Sensor.length/2.0 - 170.0 - 10.0 + length/2.0;
+            final double ball_pos_cf_local_z =  -1 * ( Sensor.getSensorThickness()/2.0 + HalfModuleLamination.thickness + TestRunHalfModule.getCFThickness()/2.0 );
+            
+            ballPos = new BasicHep3Vector(ball_pos_cf_local_x, ball_pos_cf_local_y, ball_pos_cf_local_z);
+            veePos = new BasicHep3Vector(ballPos.x() + 1.0, ballPos.y(), ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y() + 1.0, ballPos.z());
+            
+            
+            
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+            
+        }
+        protected void setCenter() {
+            setCenter(0.0, 0.0, 0.0);
+            //setCenter(getWidth()/2.0, getLength()/2.0, 0.0);
+            //setCenter(getLength()/2.0, 0.0, getWidth()/2.0);
+        }
+        protected double getThickness() {
+            return thickness;
+        }
+        protected double getWidth() {
+            return width;
+        }
+        protected double getLength() {
+            return length;
+        }
+        protected double getHeigth() {
+            return getThickness();
+        }
+        protected void setBoxDim() {
+            setBoxDim(getWidth(),getLength(),getThickness());
+            //setBoxDim(getLength(),getThickness(),getWidth());
+        }
+    }
+
+    /**
+     * Hybrid @SurveyVolume for the half-module
+     * The coordinate system is located at the same position and orientation as the sensor.
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class Hybrid extends HalfModuleComponent {
+        protected static final double hybrid_length = 170.0 - Sensor.length; // sensor b-to-b with hybrid
+        protected static final double hybrid_width  = Sensor.width;
+        protected static final double hybrid_thickness = 4.0/64.0*inch;
+        public Hybrid(String name, SurveyVolume m, int id) {
+            super(name, m, null, id);
+            init();
+        }
+        protected void setPos() {
+            
+            if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
+            
+//            final double ball_pos_hybrid_local_x =  -1 * (170.0 - Sensor.getSensorLength()/2.0);
+//            final double ball_pos_hybrid_local_y =  (Sensor.getSensorThickness()/2.0 - TestRunHalfModule.getHybridThickness()/2.0);
+//            final double ball_pos_hybrid_local_z = -1 * (Sensor.width/2.0);
+//            final double vee_pos_hybrid_local_x =  ball_pos_hybrid_local_x + 1.0; // arbitrary distance
+//            final double vee_pos_hybrid_local_y =  ball_pos_hybrid_local_y;
+//            final double vee_pos_hybrid_local_z =  ball_pos_hybrid_local_z;
+//            final double flat_pos_hybrid_local_x =  ball_pos_hybrid_local_x;
+//            final double flat_pos_hybrid_local_y =  ball_pos_hybrid_local_y + TestRunHalfModule.getHybridThickness()/2.0; // arbitrary distance
+//            final double flat_pos_hybrid_local_z =  ball_pos_hybrid_local_z;
+//            setBallPos(ball_pos_hybrid_local_x,ball_pos_hybrid_local_y,ball_pos_hybrid_local_z);
+//            setVeePos(vee_pos_hybrid_local_x,vee_pos_hybrid_local_y,vee_pos_hybrid_local_z);
+//            setFlatPos(flat_pos_hybrid_local_x,flat_pos_hybrid_local_y,flat_pos_hybrid_local_z);
+            
+//            final double ball_pos_hybrid_local_x =  -1 * (Sensor.width/2.0);
+//            final double ball_pos_hybrid_local_y =  -1 * (170.0 - Sensor.getSensorLength()/2.0);
+//            final double ball_pos_hybrid_local_z = (Sensor.getSensorThickness()/2.0 - TestRunHalfModule.getHybridThickness()/2.0);
+//            final double vee_pos_hybrid_local_x =  ball_pos_hybrid_local_x + Sensor.width/2.0; // arbitrary distance
+//            final double vee_pos_hybrid_local_y =  ball_pos_hybrid_local_y;
+//            final double vee_pos_hybrid_local_z =  ball_pos_hybrid_local_z;
+//            final double flat_pos_hybrid_local_x =  ball_pos_hybrid_local_x;
+//            final double flat_pos_hybrid_local_y =  ball_pos_hybrid_local_y + Sensor.getSensorLength()/2.0; // arbitrary distance
+//            final double flat_pos_hybrid_local_z =  ball_pos_hybrid_local_z;
+//            setBallPos(ball_pos_hybrid_local_x,ball_pos_hybrid_local_y,ball_pos_hybrid_local_z);
+//            setVeePos(vee_pos_hybrid_local_x,vee_pos_hybrid_local_y,vee_pos_hybrid_local_z);
+//            setFlatPos(flat_pos_hybrid_local_x,flat_pos_hybrid_local_y,flat_pos_hybrid_local_z);
+            
+            final double ball_pos_hybrid_local_x =  0.0;
+            final double ball_pos_hybrid_local_y =  Sensor.length/2.0 - 170.0 + hybrid_length/2.0;
+            final double ball_pos_hybrid_local_z = -1.0*Sensor.getSensorThickness()/2.0 + hybrid_thickness/2.0;
+            
+            ballPos = new BasicHep3Vector(ball_pos_hybrid_local_x,ball_pos_hybrid_local_y, ball_pos_hybrid_local_z);
+            veePos = new BasicHep3Vector(ballPos.x() + 1.0, ballPos.y(), ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y() + 1.0, ballPos.z());
+            
+            
+            
+            if(debug) {
+                System.out.printf("%s: survey positions for %s\n",this.getClass().getSimpleName(),getName());
+                printSurveyPos();
+            }
+        }
+        protected void setCenter() {
+            setCenter(0.0, 0.0, 0.0);
+            //setCenter(getWidth()/2.0, getLength()/2.0, 0.0);
+            //setCenter(getLength()/2.0, 0.0, getWidth()/2.0);
+        }
+        protected double getThickness() {
+            return hybrid_thickness;
+        }
+        protected double getHeigth() {
+            return getThickness();
+        }
+        protected double getWidth() {
+            return hybrid_width;
+        }
+        protected double getLength() {
+            return hybrid_length;
+        }
+        protected void setBoxDim() {
+            setBoxDim(getWidth(), getLength(),getThickness());
+            //setBoxDim(getLength(),getThickness(), getWidth());
+        }
+    }
+
+
+    /**
+     * Base class for components of a half-module @SurveyVolume
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static abstract class HalfModuleComponent extends SurveyVolume {
+        int id = -1;
+        public HalfModuleComponent(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, int id) {
+            super(name, mother, alignmentCorrection);
+            this.id = id;
+        }
+        protected abstract double getThickness();
+        protected abstract double getHeigth();
+        protected abstract double getWidth();
+        protected abstract double getLength();
+        public int getId() {
+            return id;
+        }
+    }       
+
+    
+    
+   
+
+    public static class TestRunHalfModuleBundle extends HalfModuleBundle {
+        protected SurveyVolume carbonFiber = null;
+        protected SurveyVolume hybrid = null;
+        TestRunHalfModuleBundle(SurveyVolume hm) {         
+            super(hm);
+        }
+    }
+
+
+    protected TestRunHalfModuleAxial createTestRunHalfModuleAxial(String volName,
+            BaseModule mother, AlignmentCorrection alignmentCorrection,
+            int layer, String half) {
+      return new TestRunHalfModuleAxial(volName, mother, alignmentCorrection, layer, half);
+        
+    }
+
+
+    protected TestRunHalfModuleStereo createTestRunHalfModuleStereo(
+            String volName, BaseModule mother,
+            AlignmentCorrection alignmentCorrection, int layer, String half) {
+        return new TestRunHalfModuleStereo(volName, mother, alignmentCorrection, layer, half);
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition#getHalfModuleBundle(org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BaseModule, java.lang.String)
+     */
+    protected HalfModuleBundle getHalfModuleBundle(BaseModule module, String halfModuleName) {
+        BaseModuleBundle m = getModuleBundle(module.getLayer(), module.getHalf());
+        HalfModuleBundle hm = null;
+        // TODO this needs to change when I build quarter-modules for the long half-modules.
+        if(m!=null) {
+            if( m instanceof TestRunModuleBundle) {   
+                TestRunModuleBundle mtr = (TestRunModuleBundle) m;
+                if(halfModuleName.contains("axial")) {
+                    hm = mtr.halfModuleAxial;
+                }
+                else if(halfModuleName.contains("stereo")) {
+                    hm = mtr.halfModuleStereo;
+                }
+                else {
+                    throw new RuntimeException("No axial or stereo string found in half module bundle name " + halfModuleName);
+                }
+            }
+            else {
+                throw new RuntimeException("The type of this module bundle is incorrect. Should be a TestRunModuleBundle.");
+            }
+        } else {
+            throw new RuntimeException("No module found for " + module.getLayer() + " and half " + module.getHalf());
+        }
+        return hm;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#getOldGeomDefLayerFromVolumeName(java.lang.String)
+     */
+    public int getOldGeomDefLayerFromVolumeName(String name) {
+        
+        String half = getHalfFromName(name);
+        int l = getLayerFromVolumeName(name);
+        boolean isTopLayer = false;
+        if(half=="top") isTopLayer=true;
+        else if(half=="bottom") isTopLayer = false;
+        else throw new RuntimeException("no half found from " + name);
+        boolean isAxial = isAxialFromName(name);
+        return getOldLayerDefinition(isTopLayer, l, isAxial);
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#getOldLayerDefinition(boolean, int, boolean)
+     */
+    public int getOldLayerDefinition(boolean isTopLayer, int l, boolean isAxial) {
+        int layer=-1;
+        if(isAxial) {
+            if(isTopLayer) {
+                layer = 2*l-1;
+            }
+            else {
+                layer = 2*l;
+            }
+        } else {
+            if(isTopLayer) {
+                layer = 2*l;
+            } else {
+                layer = 2*l-1;
+            }
+        }
+        return layer;
+    }
+
+
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#getMillepedeLayer(java.lang.String)
+     */
+    public int getMillepedeLayer(String name) {
+       return getOldGeomDefLayerFromVolumeName(name);
+    }
+    
+
+
+
+
+}
+
+
+
+

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,213 @@
+/**
+ * 
+ */
+package org.lcsim.geometry.compact.converter;
+
+import java.util.ArrayList;
+
+import org.jdom.Element;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BasePlate;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.Sensor;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportBottom;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportPlateBottom;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportPlateTop;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportTop;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TestRunHalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder.BaseModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TestRunModuleBundle;
+
+
+/**
+ * Class used by java converter to build java run time objects for the detector
+ * It encapsulates and adds the LCDD specific information to the generic @HPSTestRunTracker2014Builder. 
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class HPSTestRunTracker2014JavaBuilder extends HPSTrackerJavaBuilder {
+
+	
+	
+	/**
+	 * Default constructor
+	 * @param node 
+	 */
+	public HPSTestRunTracker2014JavaBuilder(boolean debugFlag, Element node) {
+		super(debugFlag, node);
+	}
+	
+	
+	
+	/**
+	 * Build the JAVA geometry objects from the geometry definition.
+	 * @param trackingVolume - the reference volume.
+	 */
+	public void build(ILogicalVolume trackingVolume) {
+
+		// build geometry
+        setBuilder(createGeometryDefinition(_debug, node));
+		
+		if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
+
+		if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
+		
+		_builder.build();
+
+		if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
+
+		if(isDebug()) System.out.printf("%s: build the JAVA geometry objects\n", getClass().getSimpleName());
+		
+		// initialize the list to store a reference to each object
+		javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
+
+		// Go through the list of volumes to build that is created in the generic builder class
+		JavaSurveyVolume trackingGeometry = new JavaSurveyVolume(_builder.getSurveyVolume(org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume.class), trackingVolume);
+		add(trackingGeometry);
+		//setBaseTrackerGeometry(new GhostJavaBaseGeom(_builder.getBaseGeometry(Base.class), trackingGeometry));
+        setBaseTrackerGeometry(new JavaSurveyVolume(_builder.getSurveyVolume(TrackerEnvelope.class), trackingGeometry,1));
+        add(getBaseTrackerGeometry());
+		JavaSurveyVolume basePlateGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(BasePlate.class), getBaseTrackerGeometry());
+		add(basePlateGeometry);
+		// skip the c-support, this is purely a reference volume in the builder so should have no use here!?
+		//JavaBaseGeometry cSupportGeometry = new GhostJavaBaseGeom(_builder.getBaseGeometry(CSupport.class), baseTrackerGeometry);
+		//add(cSupportGeometry);
+		JavaSurveyVolume supportBottomGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportBottom.class), getBaseTrackerGeometry());
+		add(supportBottomGeometry);
+		JavaSurveyVolume supportPlateBottomGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportPlateBottom.class), getBaseTrackerGeometry());
+		add(supportPlateBottomGeometry);
+		JavaSurveyVolume supportTopGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportTop.class), getBaseTrackerGeometry());
+		add(supportTopGeometry);
+		JavaSurveyVolume supportPlateTopGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportPlateTop.class), getBaseTrackerGeometry());
+		add(supportPlateTopGeometry);
+
+		// build modules	
+		
+		if(isDebug()) System.out.printf("%s: build JAVA modules\n", getClass().getSimpleName());
+
+		// Loop over all modules created
+		for(BaseModuleBundle mod : _builder.modules) {
+			TestRunModuleBundle m = (TestRunModuleBundle) mod;
+		    if(isDebug()) { 
+				System.out.printf("%s: build module %s (layer %d half %s)\n", getClass().getSimpleName(),m.module.getName(),m.getLayer(),m.getHalf());
+				m.print();
+			}
+
+			// Find the mother among the objects using its name, should probably have a better way...
+			String name_mother = m.getMother().getName();
+			JavaSurveyVolume mother = null;
+			for(JavaSurveyVolume g : javaSurveyVolumes) {
+				if(g.getName().equals(name_mother)) {
+					mother = g;
+					break;
+				}
+			}
+			// Check that it had a mother
+			if(mother==null) throw new RuntimeException("Cound't find mother to module " + m.module.getName());
+
+			if(isDebug()) System.out.printf("%s: found mother %s to module %s\n", getClass().getSimpleName(),mother.getName(),m.module.getName());
+			
+			// put the module in the list of objects that will be added to LCDD
+			addTestRunModule(m, mother);
+			
+			if(isDebug()) System.out.printf("%s: DONE build module %s\n", getClass().getSimpleName(), m.module.getName());
+
+			
+		}
+		
+		if(isDebug()) System.out.printf("%s: DONE build JAVA modules\n", getClass().getSimpleName());
+
+		
+		if(isDebug()) System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
+		if(isDebug()) {
+		    System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
+		    System.out.printf("%s: List of all the JAVA geometry objects built\n", this.getClass().getSimpleName());
+		    for(JavaSurveyVolume bg : javaSurveyVolumes) {
+		        System.out.printf("-------\n%s\n", bg.toString());
+		    }
+		}
+
+
+		// Set visualization features
+		//setVis();
+
+
+	}
+
+	/**
+	 * Rules for adding the JAVA module geometry.
+	 * @param bundle - module to be added
+	 * @param mother - mother JAVA geometry object
+	 */
+	protected void addTestRunModule(TestRunModuleBundle bundle, JavaSurveyVolume mother) {
+		
+		if(isDebug()) {
+			System.out.printf("%s: addModule %s containing:\n",this.getClass().getSimpleName(), bundle.module.getName());
+			bundle.print();
+		}
+		
+		// Create the module
+		JavaSurveyVolume lcddM = new JavaGhostSurveyVolume(bundle.module, mother);
+		add(lcddM);
+		
+		// add half modules
+		if(bundle.halfModuleAxial!=null)  addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleAxial,lcddM);     
+        if(bundle.halfModuleStereo!=null) addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
+		
+		
+		if(isDebug()) {
+			System.out.printf("%s: DONE addModule %s \n",this.getClass().getSimpleName(), bundle.module.getName());
+		}
+		
+	}
+	
+	
+	/**
+	 * Rules for adding the JAVA half module geometry.
+	 * @param bundle - module to be added
+	 * @param mother - mother JAVA geometry object
+	 */
+	private void addHalfModule(TestRunHalfModuleBundle bundle, JavaSurveyVolume mother) {
+		// Create the half-module
+		// This is not a ghost element but reflects the module 
+		// concept in the old compact description
+		// TODO fix the layer IDs
+		int oldCompactModuleId = 0;
+		JavaSurveyVolume lcddHM = new JavaSurveyVolume(bundle.halfModule, mother,oldCompactModuleId);
+		add(lcddHM);
+		
+		// ComponentNumber is taken from old geometry where it is simply a counter when adding the xml daughters to the TestRunModule.
+		// It is simply 0 for sensor and 1 for carbon fiber in the old geometry 
+		int componentNumber = ((Sensor)bundle.sensor).getId();
+
+		// create the sensor
+		JavaSurveyVolume lcddS = new JavaSurveyVolume(bundle.sensor, lcddHM, componentNumber);
+		add(lcddS);
+
+		// create the active sensor
+		JavaSurveyVolume lcddAS = new JavaSurveyVolume(bundle.activeSensor, lcddS, componentNumber);
+		add(lcddAS);
+		
+//		if(isDebug()) {
+//			System.out.printf("%s: added sensor %s \n",this.getClass().getSimpleName(), lcddS.getName());
+//			System.out.printf("%s: local coordinate system\n%s\n",this.getClass().getSimpleName(), bundle.sensor.getCoord().toString());
+//			dsd
+//		}
+		
+		
+	}
+
+
+
+    @Override
+    public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node) {
+        return new HPSTestRunTracker2014GeometryDefinition(debug, node);
+    }
+
+
+	
+	
+	
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,182 @@
+package org.lcsim.geometry.compact.converter;
+
+import org.jdom.Element;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BasePlate;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.CSupport;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportBottom;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportPlateBottom;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportPlateTop;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.SupportTop;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TestRunHalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder.BaseModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder.HalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TestRunModuleBundle;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+
+/**
+ * Class used by LCDD converter to build detector for SLIC. 
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class HPSTestRunTracker2014LCDDBuilder extends HPSTrackerLCDDBuilder {
+
+
+	public HPSTestRunTracker2014LCDDBuilder(boolean debugFlag, Element node, LCDD lcdd, SensitiveDetector sens) {
+		super(debugFlag, node, lcdd, sens);
+	}
+
+	
+	public void setBuilder() {
+	    setBuilder();
+	}
+	
+	public void build(Volume worldVolume) {
+		
+		// set and build geometry
+        setBuilder(createGeometryDefinition(_debug, node));
+        
+		if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
+
+		if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
+
+		_builder.build();
+
+		if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
+
+
+		if(isDebug()) System.out.printf("%s: build the LCDD geometry objects\n", getClass().getSimpleName());
+
+		
+		// Go through the list of volumes to build that is created in the generic builder class
+		// TODO this is manual now since I don't have a way of knowing in the generic builder class what is a ghost volume at this point.
+		LCDDSurveyVolume trackingGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume.class), worldVolume);
+		add(trackingGeometry);
+		baseSurveyVolume = new LCDDSurveyVolume(_builder.getSurveyVolume(TrackerEnvelope.class), lcdd, trackingGeometry);
+		add(baseSurveyVolume);
+		LCDDSurveyVolume basePlateGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(BasePlate.class), lcdd, baseSurveyVolume);
+		add(basePlateGeometry);
+		// TODO I don't think this c-support has any use at all since the coordinates of it has been already used in the builder. Should remove?
+		LCDDSurveyVolume cSupportGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(CSupport.class), baseSurveyVolume);
+		add(cSupportGeometry);
+		LCDDSurveyVolume supportBottomGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(SupportBottom.class), baseSurveyVolume);
+		add(supportBottomGeometry);
+		LCDDSurveyVolume supportPlateBottomGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(SupportPlateBottom.class), lcdd, baseSurveyVolume);
+		add(supportPlateBottomGeometry);
+		LCDDSurveyVolume supportTopGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(SupportTop.class), baseSurveyVolume);
+		add(supportTopGeometry);
+		LCDDSurveyVolume supportPlateTopGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(SupportPlateTop.class), lcdd, baseSurveyVolume);
+		add(supportPlateTopGeometry);
+
+		// build modules	
+
+		if(isDebug()) System.out.printf("%s: build modules\n", getClass().getSimpleName());
+
+		// Loop over all modules created
+		for(BaseModuleBundle mod : _builder.modules) {
+		    TestRunModuleBundle m = (TestRunModuleBundle) mod;
+			if(isDebug()) { 
+				System.out.printf("%s: module layer %d half %s\n", getClass().getSimpleName(),m.getLayer(),m.getHalf());
+				m.print();
+			}
+
+			// Find the mother among the LCDD objects using its name, should probably have a better way...
+			String name_mother = m.getMother().getName();
+			LCDDSurveyVolume mother = null;
+			for(LCDDSurveyVolume g : lcddSurveyVolumes) {
+				if(g.getName().equals(name_mother)) {
+					mother = g;
+					break;
+				}
+			}
+			// Check that it had a mother
+			if(mother==null) throw new RuntimeException("Cound't find mother to module layer " + m.getLayer() + " half "+ m.getHalf());
+
+			if(isDebug()) System.out.printf("%s: found mother %s for module layer %d half %s\n", getClass().getSimpleName(),mother.getName(),m.getLayer(),m.getHalf());
+
+			// add the module to the list of objects that will be added to LCDD
+			addTestRunModule(m, mother);
+
+		}
+
+
+
+		if(isDebug()) {
+		    System.out.printf("%s: DONE building the LCDD geometry objects\n", getClass().getSimpleName());
+		    System.out.printf("%s: List of all %d LCDD geometry objects built\n", this.getClass().getSimpleName(), lcddSurveyVolumes.size());
+		    for(SurveyVolumeImpl bg : lcddSurveyVolumes) {
+		        System.out.printf("-------\n%s\n", bg.toString());
+		    }
+		}
+
+
+
+		// Set visualization features
+		setVisualization();
+
+
+	}
+
+
+	/**
+	 * Rules for adding the LCDD module geometry.
+	 * @param bundle - module to be added
+	 * @param mother - mother LCDD geometry object
+	 */
+	protected void addTestRunModule(TestRunModuleBundle bundle, LCDDSurveyVolume mother) {
+		// This could perhaps be fixed if there is a relation with daughters in geometry definition?
+		// create the module
+		LCDDSurveyVolume lcddM = new LCDDSurveyVolume(bundle.module, lcdd, mother);
+		add(lcddM);
+		if(bundle.halfModuleAxial!=null)  addTestRunHalfModule(bundle.halfModuleAxial,lcddM);
+		if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));		
+		if(bundle.halfModuleStereo!=null) addTestRunHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
+//        if(bundle.halfModuleAxial!=null)  addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleAxial,lcddM);
+//        if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));     
+//        if(bundle.halfModuleStereo!=null) addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
+
+	}
+
+	/**
+	 * Rules for adding the LCDD half module geometry.
+	 * @param bundle - module to be added
+	 * @param mother - mother LCDD geometry object
+	 */
+	protected void addTestRunHalfModule(HalfModuleBundle bundle2, LCDDSurveyVolume mother) {
+		// This could perhaps be fixed if there is a relation with daughters in geometry definition?
+	    TestRunHalfModuleBundle bundle = (TestRunHalfModuleBundle) bundle2;
+	    
+	    // create the half-module
+		LCDDSurveyVolume lcddHM = new LCDDSurveyVolume(bundle.halfModule, lcdd, mother);
+		add(lcddHM);
+		// create the sensor
+		LCDDSurveyVolume lcddS = new LCDDSurveyVolume(bundle.sensor, lcdd, lcddHM);
+		add(lcddS);
+		// create the active sensor
+		LCDDSurveyVolume lcddAS = new LCDDSurveyVolume(bundle.activeSensor, lcdd, lcddS);
+		add(lcddAS);
+		// create the lamination
+		LCDDSurveyVolume lcddL = new LCDDSurveyVolume(bundle.lamination, lcdd, lcddHM);
+		add(lcddL);
+		// create the carbon fiber frame
+		LCDDSurveyVolume lcddCF = new LCDDSurveyVolume(bundle.carbonFiber, lcdd, lcddHM);
+		add(lcddCF);
+		// create the hybrid frame
+		LCDDSurveyVolume lcddH = new LCDDSurveyVolume(bundle.hybrid, lcdd, lcddHM);
+		add(lcddH);
+
+	}
+
+
+    @Override
+    public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug,
+            Element node) {
+        return new HPSTestRunTracker2014GeometryDefinition(_debug, node);
+    }	
+
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,2396 @@
+/**
+ * 
+ */
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+import org.jdom.Element;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BaseModule;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.CarbonFiber;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.Sensor;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule;
+
+
+/**
+ * 
+ * Geometry information for the HPS tracker 2014
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+ public class HPSTracker2014GeometryDefinition extends HPSTrackerGeometryDefinition {
+
+
+
+    public HPSTracker2014GeometryDefinition(boolean debug, Element node) {
+        super(debug, node);
+        doAxial = true;
+        doStereo = true;
+        doColdBlock = false;
+        doBottom = true;
+        doTop = true;
+        layerBitMask = 0x3F;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#build()
+     */
+    public void build() {
+
+        if(isDebug()) System.out.printf("%s: constructing the geometry objects\n", this.getClass().getSimpleName());
+
+        // Build the geometry from the basic building blocks in the geometry definition class
+        // Keep the order correct.
+        // Each item has knowledge of its mother but not its daughters
+        HPSTrackerGeometryDefinition.TrackingVolume tracking = new HPSTrackerGeometryDefinition.TrackingVolume("trackingVolume",null);
+        surveyVolumes.add(tracking);
+
+        PSVacuumChamber chamber = new PSVacuumChamber("chamber", tracking, null);
+        surveyVolumes.add(chamber);
+        
+        SvtBox svtBox = new SvtBox("base",chamber, null);
+        surveyVolumes.add(svtBox);
+
+        SvtBoxBasePlate svtBoxBasePlate = new SvtBoxBasePlate("base_plate",svtBox,null);
+        surveyVolumes.add(svtBoxBasePlate);
+        
+        //SupportRing supportRing = new SupportRing("c_support", svtBox, null, svtBoxBasePlate); 
+        //surveyVolumes.add(supportRing);
+       
+//        AlignmentCorrection supBotCorr = this.getSupportAlignmentCorrection(false);
+//        SupportRingL13BottomKinMount supportRingKinL13Bottom = new SupportRingL13BottomKinMount("c_support_kin_L13b", svtBox, supBotCorr, supportRing); 
+//        surveyVolumes.add(supportRingKinL13Bottom);
+        
+        AlignmentCorrection supBotCorr = this.getSupportAlignmentCorrection(false);
+        SupportRingL13BottomKinMount supportRingKinL13Bottom = new SupportRingL13BottomKinMount("c_support_kin_L13b", svtBox, supBotCorr); 
+        surveyVolumes.add(supportRingKinL13Bottom);
+        
+        
+        UChannelL13 uChannelL13Bottom = new UChannelL13Bottom("support_bottom_L13", svtBox, null, supportRingKinL13Bottom); 
+        surveyVolumes.add(uChannelL13Bottom);
+        
+        UChannelL13Plate uChannelL13BottomPlate = new UChannelL13BottomPlate("support_plate_bottom_L13", svtBox, null, uChannelL13Bottom); 
+        surveyVolumes.add(uChannelL13BottomPlate);
+
+//        AlignmentCorrection supTopCorr = this.getSupportAlignmentCorrection(true);
+//        SupportRingL13TopKinMount supportRingKinL13Top = new SupportRingL13TopKinMount("c_support_kin_L13t", svtBox, supTopCorr, supportRing); 
+//        surveyVolumes.add(supportRingKinL13Top);
+
+        AlignmentCorrection supTopCorr = this.getSupportAlignmentCorrection(true);
+        SupportRingL13TopKinMount supportRingKinL13Top = new SupportRingL13TopKinMount("c_support_kin_L13t", svtBox, supTopCorr); 
+        surveyVolumes.add(supportRingKinL13Top);
+
+        
+        UChannelL13Top uChannelL13Top = new UChannelL13Top("support_top_L13", svtBox, null, supportRingKinL13Top); 
+        surveyVolumes.add(uChannelL13Top);
+        
+        UChannelL13Plate uChannelL13TopPlate = new UChannelL13TopPlate("support_plate_top_L13", svtBox, null, uChannelL13Top); 
+        surveyVolumes.add(uChannelL13TopPlate);
+        
+        UChannelL46 uChannelL46Bottom = new UChannelL46Bottom("support_bottom_L46", svtBox, null);
+        surveyVolumes.add(uChannelL46Bottom);
+        
+        UChannelL46Plate uChannelL46BottomPlate = new UChannelL46BottomPlate("support_plate_bottom_L46", svtBox, null, uChannelL46Bottom);
+        surveyVolumes.add(uChannelL46BottomPlate);
+
+        UChannelL46 uChannelL46Top = new UChannelL46Top("support_top_L46", svtBox, null);
+        surveyVolumes.add(uChannelL46Top);
+        
+        UChannelL46Plate uChannelL46TopPlate = new UChannelL46TopPlate("support_plate_top_L46", svtBox, null, uChannelL46Top);
+        surveyVolumes.add(uChannelL46TopPlate);
+
+        
+        for(int l=1; l<=6;++l) {
+            if(doLayer(l)) {
+                if(doBottom) makeModuleBundle(l,"bottom");
+                if(doTop)    makeModuleBundle(l,"top");
+            }
+        }       
+
+        System.out.printf("%s: Constructed %d geometry objects\n", this.getClass().getSimpleName(), surveyVolumes.size());
+        System.out.printf("%s: Constructed %d module bundles\n", this.getClass().getSimpleName(),modules.size());
+        
+
+        if(isDebug()) {
+            System.out.printf("%s: DONE constructing the geometry objects\n", this.getClass().getSimpleName());
+            System.out.printf("%s: List of the survey volumes built\n", this.getClass().getSimpleName());
+            for(SurveyVolume bg : surveyVolumes) {
+                System.out.printf("-------\n%s\n", bg.toString());
+            }
+            System.out.printf("%s: List of the module bundles built\n", this.getClass().getSimpleName());
+            for(BaseModuleBundle bundle : this.modules) {
+                bundle.print();
+            }
+            
+        }
+
+    }
+
+    
+    /**
+     * @SurveyVolume volume defining the pair spectrometer (PS) vacuum chamber
+     * Reference: tracking volume coordinate system
+     * Origin: same as reference
+     * Orientation:  u - points in x direction (towards positron side), v - points upstream
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class PSVacuumChamber extends SurveyVolume {
+        public static final double height = PS_vac_box_inner_height; 
+        public static final double width = PS_vac_box_inner_width;
+        public static final double length = PS_vac_box_inner_length;
+        
+        
+        
+        public PSVacuumChamber(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
+            super(name, mother, alignmentCorrection);
+            init();
+         }
+        
+        protected void setCenter() {
+            setCenter(0, 0, 0);
+        }
+        protected void setBoxDim() {
+            setBoxDim(width,length,height);
+        }
+        protected void setPos() {
+            ballPos = new BasicHep3Vector(SvtBox.center_to_target_x, SvtBox.center_to_target_y, SvtBox.center_to_target_z);
+            veePos = new BasicHep3Vector(ballPos.x() + 1, ballPos.y(), ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y(), ballPos.z()-1);
+            
+        }
+    }
+    
+    
+    /**
+     * @SurveyVolume volume defining the SVT box envelope 
+     * Reference: PS vacuum chamber coordinate system. Note that the PS vacuum chamber box is placed w.r.t. this box and the target positions.
+     * Origin: intersection of midplanes vertically and horizontally
+     * Orientation: same as reference
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class SvtBox extends SurveyVolume {
+        public static final double height = 6.740*inch;
+        public static final double width = SvtBoxBasePlate.width;
+        public static final double length = SvtBoxBasePlate.length;
+        
+        // position of the target w.r.t. center of this box. 
+        // the coordinate frame is the JLab coordinates..confusing.
+        public static final double center_to_target_z = 13.777*inch;
+        public static final double center_to_target_x = 0.84*inch;
+        public static final double center_to_target_y = 0.0;
+        
+        
+        
+        
+        public SvtBox(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
+            super(name, mother, alignmentCorrection);
+            init();
+         }
+        
+        protected void setCenter() {
+            setCenter(0,0,0);
+        }
+        protected void setBoxDim() {
+            setBoxDim(width,length,height);
+        }
+        protected void setPos() {
+            
+            ballPos = new BasicHep3Vector(0, 0, 0);
+            veePos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());
+            
+        }
+    }
+    
+    
+    /**
+     * @SurveyVolume volume defining the base plate of the SVT box.
+     * Reference: @SvtBox  coordinate system.
+     * Origin: surface of base plate intersection with center of hole for adjustment screw on positron side
+     * Orientation: same as reference
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class SvtBoxBasePlate extends SurveyVolume {
+        public static final double length = 50.5*inch;
+        public static final double width = 16.0*inch;
+        public static final double height = 0.25*inch;
+        public static final double kin_mount_to_edge_of_plate_x = (8.0-5.0)*inch; 
+        public static final double kin_mount_to_edge_of_plate_y = 0.375*inch;
+        public static final double adj_screw_height = 0.13*inch; // amount screw sticks out from plate
+        public static final double adj_screw_width = 0.13*inch; // amount screw sticks out on side
+        
+        
+        public SvtBoxBasePlate(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
+           super(name, mother, alignmentCorrection);
+           setMaterial("Aluminum");
+           init();
+        }
+        
+        protected void setCenter() {
+            final double x = -kin_mount_to_edge_of_plate_x + SvtBoxBasePlate.width/2.0;
+            final double y = -kin_mount_to_edge_of_plate_y + SvtBoxBasePlate.length/2.0;
+            final double z = -SvtBoxBasePlate.height/2.0;     
+            setCenter(new BasicHep3Vector(x, y, z));
+        }
+        protected void setBoxDim() {
+            setBoxDim(width, length, height);
+        }
+        protected void setPos() {
+            final double x = -width/2.0 + kin_mount_to_edge_of_plate_x;
+            final double y = -length/2.0 + kin_mount_to_edge_of_plate_y;
+            final double z = -SvtBox.height/2.0 + height;
+            ballPos = new BasicHep3Vector(x, y, z);
+            veePos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());
+        }
+        
+    }
+    
+    
+    
+    
+    /**
+     * @SurveyVolume volume defining the coordinate system of the support ring
+     *  Reference: @SvtBoxBasePlate
+     *  Origin: pin position of support ring (electron side)
+     *  Orientation: slot position is vee position (positron side) i.e u points towards the positron side and v in the upstream beam direction
+     *  
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class SupportRing extends SurveyVolume {
+        private static final double plateThickness = 0.35*inch; 
+
+        public SupportRing(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+           super(name, mother, alignmentCorrection, ref);
+           init();
+        }
+        protected void setCenter() {
+            setCenter(null); //dummy
+        }
+        protected void setBoxDim() {
+            // do nothing
+        }
+        protected void setPos() {
+
+            final double ball_pos_x = -SvtBoxBasePlate.kin_mount_to_edge_of_plate_x + SvtBoxBasePlate.width/2.0 - 6.997*inch;
+            final double ball_pos_y = -SvtBoxBasePlate.kin_mount_to_edge_of_plate_y + SvtBoxBasePlate.length -28.543*inch;
+            final double ball_pos_z = 0.0;
+
+            
+            final double vee_pos_x = -SvtBoxBasePlate.kin_mount_to_edge_of_plate_x + SvtBoxBasePlate.width/2.0 + 6.622*inch;
+            final double vee_pos_y = -SvtBoxBasePlate.kin_mount_to_edge_of_plate_y + SvtBoxBasePlate.length - 28.116*inch;
+            final double vee_pos_z = 0.0;
+            
+            
+            ballPos = new BasicHep3Vector(ball_pos_x, ball_pos_y, ball_pos_z);
+            veePos = new BasicHep3Vector(vee_pos_x, vee_pos_y, vee_pos_z);
+            flatPos = new BasicHep3Vector(0,0,0);
+
+            Hep3Vector uPrime = VecOp.unit(VecOp.sub(veePos, ballPos));
+            Rotation r = new Rotation(new Vector3D(1,0,0),new Vector3D(0,0,1), new Vector3D(uPrime.v()), new Vector3D(0,0,1));
+            Hep3Vector vPrime = new BasicHep3Vector(r.applyTo(new Vector3D(0, 1, 0)).toArray());
+            flatPos = VecOp.add(ballPos, vPrime);
+        }
+    }
+   
+    
+    
+    /**
+     * Abstract @SurveyVolume volume defining a coordinate system from the kinematic mount positions for support channels
+     *  
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public abstract static class SupportRingL13KinMount extends SurveyVolume {
+
+        public static final double kin_mount_offset_vertically = 0.093*inch; 
+        protected static final double kin_mount_pos_x = -138.665;
+        protected static final double kin_mount_pos_y =  -67.855;
+
+        public SupportRingL13KinMount(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
+           super(name, mother, alignmentCorrection);
+        }
+        protected void setCenter() {
+            setCenter(null); //dummy
+        }
+        protected void setBoxDim() {
+            // do nothing
+        }
+        protected void setPos() {
+            ballPos = new BasicHep3Vector(kin_mount_pos_x, kin_mount_pos_y, getKinMountVerticalPos());
+
+            final double vee_pos_x = ballPos.x()+1; // random positive offset
+            final double vee_pos_y = ballPos.y();
+            final double vee_pos_z = ballPos.z();
+            veePos = new BasicHep3Vector(vee_pos_x, vee_pos_y, vee_pos_z);
+
+            final double flat_pos_x = ballPos.x();
+            final double flat_pos_y = ballPos.y() + 1.0; // random positive offset
+            final double flat_pos_z = ballPos.z();
+            flatPos = new BasicHep3Vector(flat_pos_x,flat_pos_y,flat_pos_z);
+        }
+        abstract protected double getKinMountVerticalPos();
+    }
+    
+    /**
+     * @SurveyVolume volume defining a coordinate system from the kinematic mount positions for support channels
+     *  Reference: {@SvtBox} coordinate system
+     *  Origin: cone mount (it's on the electron side)
+     *  Orientation: ball is cone mount, slot mount is vee position and flat is along beamline pointing upstream
+     *  
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class SupportRingL13BottomKinMount extends SupportRingL13KinMount {
+
+        protected static final double kin_mount_pos_z =  -67.996;
+
+        public SupportRingL13BottomKinMount(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
+           super(name, mother, alignmentCorrection);
+           init();
+        }
+
+        @Override
+        protected double getKinMountVerticalPos() {
+            return kin_mount_pos_z;
+        }
+
+//        protected void setPos() {
+//            final double ball_pos_x = (7.0 - 5.444) *inch;
+//            final double ball_pos_y = 0.574*inch;
+//            final double ball_pos_z = SupportRing.plateThickness + kin_mount_offset_vertically;
+//            ballPos = new BasicHep3Vector(ball_pos_x, ball_pos_y, ball_pos_z);
+//            
+//            final double vee_pos_x = (2*7.0)*inch;
+//            final double vee_pos_y = ball_pos_y;
+//            final double vee_pos_z = ball_pos_z;
+//            veePos = new BasicHep3Vector(vee_pos_x, vee_pos_y, vee_pos_z);
+//            
+//            final double flat_pos_x = ball_pos_x;
+//            final double flat_pos_y = ball_pos_y + 1.0; // random distance
+//            final double flat_pos_z = ball_pos_z;
+//            flatPos = new BasicHep3Vector(flat_pos_x,flat_pos_y,flat_pos_z);
+//        }
+        
+    }
+    
+    /**
+     * @SurveyVolume volume defining a coordinate system from the kinematic mount positions for support channels
+     *  Reference: @SupportRing coordinate system
+     *  Origin: cone mount (it's on the electron side)
+     *  Orientation: ball is cone mount, slot mount is vee position and flat is along beamline pointing upstream
+     *  
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class SupportRingL13TopKinMount extends SupportRingL13KinMount {
+        //public static final double mount_surface_wrt_baseplate_vertically = 5.388*inch;
+        protected static final double kin_mount_pos_z =  56.857;
+
+        public SupportRingL13TopKinMount(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
+           super(name, mother, alignmentCorrection);
+           init();
+        }
+
+        @Override
+        protected double getKinMountVerticalPos() {
+            return kin_mount_pos_z;
+        }
+
+//        protected void setPos() {
+//            final double ball_pos_x = (7.0 - 5.444) *inch;
+//            final double ball_pos_y = 0.574*inch;
+//            final double ball_pos_z = mount_surface_wrt_baseplate_vertically + kin_mount_offset_vertically;
+//            ballPos = new BasicHep3Vector(ball_pos_x, ball_pos_y, ball_pos_z);
+//            
+//            final double vee_pos_x = (2*7.0)*inch;
+//            final double vee_pos_y = ball_pos_y;
+//            final double vee_pos_z = ball_pos_z;
+//            veePos = new BasicHep3Vector(vee_pos_x, vee_pos_y, vee_pos_z);
+//            
+//            final double flat_pos_x = ball_pos_x;
+//            final double flat_pos_y = ball_pos_y + 1.0; // random distance
+//            final double flat_pos_z = ball_pos_z;
+//            flatPos = new BasicHep3Vector(flat_pos_x,flat_pos_y,flat_pos_z);
+//        }
+    }
+    
+    
+    /**
+     * Abstract @SurveyVolume volume defining the coordinate system of the L1-3 u-channels 
+     *  
+     *  @author Per Hansson Adrian <[log in to unmask]>
+     */
+    public abstract static class UChannelL13 extends SurveyVolume {
+        public final static double length = UChannelL13Plate.length;
+        public static final double width = UChannelL13Plate.width;
+        public static final double height = 2.575*inch;
+        public static final double kin_mount_to_edge_of_plate_x = width/2.0-4.0*inch;
+        public static final double side_plate_cone_y = 2.0*inch;
+
+        public UChannelL13(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+        }
+
+        protected void setBoxDim() {
+            setBoxDim(getWidth(),getLength(),getHeight());
+        }
+        protected double getLength() {
+            return length;
+        }
+        protected double getWidth() {
+            return width;
+        }
+        protected double getHeight() {
+            return height;
+        }
+    }
+    
+    /**
+     * @SurveyVolume volume defining the coordinate system of the bottom L1-3 u-channel 
+     *  Reference: SupportRingL13BottomKinMount coordinate system
+     *  Origin: midpoint between upstream survey cones
+     *  Orientation: u - width pointing towards electron side, v - pointing along the U-channel in the beam direction
+     *  
+     *  @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL13Bottom extends UChannelL13 {
+        private final static double cone_to_edge_of_plate_y = 12.25*inch; 
+        private final static Hep3Vector ball_kinMount = new BasicHep3Vector(SupportRingL13BottomKinMount.kin_mount_pos_x,SupportRingL13BottomKinMount.kin_mount_pos_y,SupportRingL13BottomKinMount.kin_mount_pos_z);
+
+        public UChannelL13Bottom(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            init();
+        }
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = cone_to_edge_of_plate_y - length/2.0;
+            final double z = -side_plate_cone_y - UChannelL13Plate.height + height/2.0;
+            setCenter(x,y,z);
+        }
+        protected void setPos() {
+            ballPos = VecOp.sub(UChannelL13BottomSurveyBalls.ball_pos, ball_kinMount);
+            Hep3Vector veeOffset = UChannelL13BottomSurveyBalls.getVeeOffset();
+            veePos = VecOp.add(ballPos, veeOffset);
+            Hep3Vector flatOffset = UChannelL13BottomSurveyBalls.getFlatOffset();
+            flatPos = VecOp.add(ballPos, flatOffset);
+            
+//            ballPos = VecOp.sub(UChannelL13BottomSurveyBalls.ball_pos, ball_kinMount);
+//            veePos = new BasicHep3Vector(ballPos.x()-1, ballPos.y(), ballPos.z());
+//            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()-1, ballPos.z());
+        }
+    }
+    
+    
+    
+    /**
+     * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel. 
+     * This is at nominal position.
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    private static class UChannelL13BottomSurveyBalls  {
+        
+     // Shawn's calculated point at midpoint between two forward survey balls
+        protected final static Hep3Vector ball_pos = new BasicHep3Vector(-46.446, 241.184, -8.423);
+
+        //Nominal Design  FWD Right (x,y,z)   BWD Right (x,y,z)   FWD Left (x,y,z,)   BWD Left (x,y,z)
+        //
+        //Layer 1-3, Lower     -6.493, -.332, 9.353    -6.253, -.332, 1.483    2.836, -.332, 9.638     3.076, -.332, 1.767
+        //                
+        //Layer 1-3, Upper     -6.512, .332, 9.978     -6.272, .332, 2.107     2.817, .332, 10.262     3.057, .332, 2.392
+
+        
+        protected static final Hep3Vector fwd_right = new BasicHep3Vector(-6.493, 9.353,-.332);
+        protected static final Hep3Vector bwd_right = new BasicHep3Vector(-6.253, 1.483, -.332);
+        protected static final Hep3Vector fwd_left = new BasicHep3Vector( 2.836, 9.638, -.332);
+        protected static final Hep3Vector bwd_left = new BasicHep3Vector(3.076, 1.767, -.332);
+        
+        protected static Hep3Vector getVeeOffset() {
+            return  VecOp.mult(0.5,VecOp.sub(fwd_right, fwd_left));
+        }
+        protected static Hep3Vector getFlatOffset() {
+            return VecOp.sub(bwd_right, fwd_right);
+        }
+    }
+    
+    
+    
+    
+    
+    
+//    public static class UChannelL13Bottom extends UChannelL13 {
+//        private static final double kin_mount_to_edge_of_plate_y = length-15.8*inch;
+//        private final static double cone_to_edge_of_plate_y = 12.25*inch; 
+//        //private final static double cone_to_L1_hole_y = cone_to_edge_of_plate_y - kin_mount_to_edge_of_plate_y; 
+//        public UChannelL13Bottom(String name, SurveyVolume m,
+//                AlignmentCorrection alignmentCorrection,
+//                SurveyVolume ref) {
+//            super(name, m, alignmentCorrection, ref);
+//            init();
+//        }
+//        protected void setCenter() {
+//            final double x = 0.0;
+//            final double y = cone_to_edge_of_plate_y - length/2.0;
+//            final double z = -side_plate_cone_y - UChannelL13Plate.height + height/2.0;
+//            setCenter(x,y,z);
+//        }
+//        protected void setPos() {
+//            final double ball_pos_x = 4*inch;
+//            //final double ball_pos_y = (4.175 + 2*3.937) * inch; 
+//            final double ball_pos_y =  cone_to_edge_of_plate_y - kin_mount_to_edge_of_plate_y;
+//            final double ball_pos_z = -UChannelPlate.dist_from_plate_surface_to_pivot_point + UChannelL13Plate.height + side_plate_cone_y; 
+//            
+//            ballPos = new BasicHep3Vector(ball_pos_x, ball_pos_y, ball_pos_z);
+//            veePos = new BasicHep3Vector(ballPos.x()-1, ballPos.y(), ballPos.z());
+//            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()-1, ballPos.z());
+//        }
+//    }
+    
+    
+    /**
+     * @SurveyVolume volume defining the coordinate system of the top L1-3 u-channel 
+     *  Reference: SupportRingL13TopKinMount coordinate system
+     *  Origin: midpoint between upstream survey cones
+     *  Orientation: u - width pointing towards positron side, v - pointing along the U-channel in the beam direction
+     *  Note that this is flipped w.r.t. bottom support.
+     *  
+     *  @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL13Top extends UChannelL13 {
+        private final static Hep3Vector ball_kinMount = new BasicHep3Vector(SupportRingL13TopKinMount.kin_mount_pos_x,SupportRingL13TopKinMount.kin_mount_pos_y,SupportRingL13TopKinMount.kin_mount_pos_z);
+
+        private final static double length = UChannelL13.length;
+        //private static final double kin_mount_to_edge_of_plate_y = length-15.8*inch;
+        private final static double cone_to_side_plate_pin_y = (14.5-3.125)*inch; 
+        private final static double side_plate_pin_to_edge_of_plate_y = (16.0-14.5)*inch; 
+        private final static double cone_to_edge_of_plate_y = cone_to_side_plate_pin_y + side_plate_pin_to_edge_of_plate_y;
+        
+        public UChannelL13Top(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            init();
+        }
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = cone_to_edge_of_plate_y - length/2.0;
+            final double z = -side_plate_cone_y - UChannelL13Plate.height + height/2.0;
+            setCenter(x,y,z);
+        }
+        protected void setPos() {
+            ballPos = VecOp.sub(UChannelL13TopSurveyBalls.ball_pos, ball_kinMount);
+            Hep3Vector veeOffset = UChannelL13TopSurveyBalls.getVeeOffset();
+            veePos = VecOp.add(ballPos, veeOffset);
+            Hep3Vector flatOffset = UChannelL13TopSurveyBalls.getFlatOffset();
+            flatPos = VecOp.add(ballPos, flatOffset);
+            
+//            ballPos = VecOp.sub(UChannelL13TopSurveyBalls.ball_pos, ball_kinMount);
+//            veePos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+//            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()-1, ballPos.z());
+        }
+        protected double getLength() {
+           return length;
+        }
+    }
+
+    
+    
+    /**
+     * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel. 
+     * This is at nominal position.
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    private static class UChannelL13TopSurveyBalls  {
+        
+     // Shawn's calculated point at midpoint between two forward survey balls
+        protected final static Hep3Vector ball_pos = new BasicHep3Vector(-46.930, 257.052, 8.423);
+        
+        //Nominal Design  FWD Right (x,y,z)   BWD Right (x,y,z)   FWD Left (x,y,z,)   BWD Left (x,y,z)
+        //
+        //Layer 1-3, Lower     -6.493, -.332, 9.353    -6.253, -.332, 1.483    2.836, -.332, 9.638     3.076, -.332, 1.767
+        //                
+        //Layer 1-3, Upper     -6.512, .332, 9.978     -6.272, .332, 2.107     2.817, .332, 10.262     3.057, .332, 2.392
+
+        
+        protected static final Hep3Vector fwd_right = new BasicHep3Vector(-6.512, 9.978, .332);
+        protected static final Hep3Vector bwd_right = new BasicHep3Vector(-6.272, 2.107, .332);
+        protected static final Hep3Vector fwd_left = new BasicHep3Vector( 2.817, 10.262, .332);
+        protected static final Hep3Vector bwd_left = new BasicHep3Vector(3.057, 2.392, .332);
+        
+        protected static Hep3Vector getVeeOffset() {
+            return  VecOp.mult(0.5,VecOp.sub(fwd_left, fwd_right));
+        }
+        protected static Hep3Vector getFlatOffset() {
+            return VecOp.sub(bwd_left, fwd_left);
+        }
+    }
+    
+    
+    
+    
+    
+//    public static class UChannelL13Top extends UChannelL13 {
+//        private final static double length = UChannelL13.length;
+//        private static final double kin_mount_to_edge_of_plate_y = length-15.8*inch;
+//        private final static double cone_to_side_plate_pin_y = (14.5-3.125)*inch; 
+//        private final static double side_plate_pin_to_edge_of_plate_y = (16.0-14.5)*inch; 
+//        private final static double cone_to_edge_of_plate_y = cone_to_side_plate_pin_y + side_plate_pin_to_edge_of_plate_y;
+//        
+//        public UChannelL13Top(String name, SurveyVolume m,
+//                AlignmentCorrection alignmentCorrection,
+//                SurveyVolume ref) {
+//            super(name, m, alignmentCorrection, ref);
+//            init();
+//        }
+//        protected void setCenter() {
+//            final double x = 0.0;
+//            final double y = cone_to_edge_of_plate_y - length/2.0;
+//            final double z = -side_plate_cone_y - UChannelL13Plate.height + height/2.0;
+//            setCenter(x,y,z);
+//        }
+//        protected void setPos() {
+//            final double ball_pos_x = 4*inch;
+//            final double ball_pos_y = cone_to_edge_of_plate_y - kin_mount_to_edge_of_plate_y;
+//            final double ball_pos_z = SupportRingL13KinMount.kin_mount_offset_vertically - side_plate_cone_y; 
+//            // Note that this coordinate system is flipped pi compared to bottom
+//            ballPos = new BasicHep3Vector(ball_pos_x, ball_pos_y, ball_pos_z);
+//            veePos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+//            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()-1, ballPos.z());
+//        }
+//        protected double getLength() {
+//           return length;
+//        }
+//    }
+
+    
+
+    /**
+     * Abstract @SurveyVolume volume defining the coordinate system of the u-channel plate
+
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public abstract static class UChannelPlate extends SurveyVolume {
+        public UChannelPlate(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+        }
+
+        // the kin mount cone is recessed into the plate meaning that the effective pivot axis is 
+        // also recessed into the plate from the surface
+        public static final double dist_from_plate_surface_to_pivot_point = 0.0295*inch;
+    }
+
+    /**
+     * Abstract @SurveyVolume volume defining the coordinate system of the u-channel plate
+
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public abstract static class UChannelL13Plate extends UChannelPlate {
+        private final static double pocket_depth_L1 = 0.025;
+        private final static double pocket_depth_L2 = pocket_depth_L1 + 0.059;
+        private final static double pocket_depth_L3 = pocket_depth_L2 + 0.059;
+        private final static double module_mounting_hole_to_hole_x =3.937*inch;
+        private static final double width = 9.25*inch;
+        protected static final double height = 0.375*inch;
+        protected final static double length = 16.0*inch;
+        
+
+        
+        public UChannelL13Plate(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            setMaterial("Aluminum");
+        }
+        
+        /**
+         * Get pocket depth for this plate
+         * @param layer
+         * @return pocket depth
+         */
+        public static double getPocketDepth(int layer) {
+             if(layer==1) return pocket_depth_L1;
+             else if(layer==2) return pocket_depth_L2;
+             else if(layer==3) return pocket_depth_L3;
+             else {
+                 throw new RuntimeException("Trying to create a L1-3 module with invalid layer nr: " + layer);
+             }
+        }
+
+        protected void setBoxDim() {
+            setBoxDim(getWidth(), getLength(), getHeight());
+        }
+
+        protected void setPos() {
+           ballPos = new BasicHep3Vector(0, 0, 0);
+           veePos = new BasicHep3Vector(1, 0, 0);
+           flatPos = new BasicHep3Vector(0, 1, 0);
+        }
+        
+        public double getWidth() {
+            return width;
+        }
+        public double getLength() { 
+            return length;
+        }
+        public double getHeight() {
+            return height;
+        }
+        
+    }
+        
+    
+    /**
+     * @SurveyVolume volume defining the coordinate system of the bottom u-channel plate
+     * Reference:  @UChannelL13Bottom coordinate system
+     * Origin:  same as reference
+     * Orientation: same as reference
+     *
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL13BottomPlate extends UChannelL13Plate {
+        protected final static double L1_module_pin_to_edge_of_plate = (16.0-4.126)*inch;
+
+        public UChannelL13BottomPlate(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            init();
+        }
+
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = UChannelL13Bottom.cone_to_edge_of_plate_y - length/2.0;
+            final double z = -UChannelL13.side_plate_cone_y - height/2.0;
+            setCenter(x,y,z);
+        }
+
+    }
+    
+    /**
+     * @SurveyVolume volume defining the coordinate system of the bottom u-channel plate
+     * Reference:  @UChannelL13Bottom coordinate system
+     * Origin:  same as reference
+     * Orientation: same as reference
+     *
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL13TopPlate extends UChannelL13Plate {
+        protected final static double L1_module_pin_to_edge_of_plate = (16.0-2.75)*inch;
+
+        public UChannelL13TopPlate(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            init();
+        }
+
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = UChannelL13Top.cone_to_edge_of_plate_y - length/2.0;
+            final double z = -UChannelL13.side_plate_cone_y - height/2.0;
+            setCenter(x,y,z);
+        }
+       
+    }
+    
+    
+    /**
+     * Abstract @SurveyVolume volume defining the L4-6 u-channel volume
+     * 
+     *  @author Per Hansson Adrian <[log in to unmask]>
+     */
+    public abstract static class UChannelL46 extends SurveyVolume {
+
+        protected static final double width = UChannelL46Plate.width;
+        protected static final double length = UChannelL46Plate.length;
+        protected static final double height = 2.575*inch;
+        private static final double kin_mount_to_edge_of_plate_x = width/2.0-5.75*inch;
+        private static final double kin_mount_to_edge_of_plate_y = 0.2*inch;
+        protected static final double side_plate_cone_y = 2.0*inch;
+        
+        public UChannelL46(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection) {
+            super(name, m, alignmentCorrection);
+        }
+
+        protected void setBoxDim() {
+            setBoxDim(width,length,height);
+        }
+        
+    }
+    
+    
+   
+   
+    
+    /**
+     * @SurveyVolume volume defining the coordinate system of the u-channel 
+     *  Reference: SVTBox coordinate system
+     *  Origin: midpoint between upstream survey cones
+     *  Orientation: u - width pointing towards electron side, v - pointing along the U-channel in the beam direction
+     *  
+     *  @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL46Bottom extends UChannelL46 {
+        
+        
+        protected static final double cone_to_edge_of_plate_y = 2.75*inch;
+
+        public UChannelL46Bottom(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection) {
+            super(name, m, alignmentCorrection);
+            init();
+        }
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = -cone_to_edge_of_plate_y + length/2.0;
+            final double z = -side_plate_cone_y - UChannelL46Plate.height + height/2.0;
+            setCenter(x,y,z);
+        }
+        protected void setPos() {
+            ballPos = UChannelL46BottomSurveyBalls.ball_pos;
+            Hep3Vector veeOffset = UChannelL46BottomSurveyBalls.getVeeOffset();
+            veePos = VecOp.add(ballPos, veeOffset);
+            Hep3Vector flatOffset = UChannelL46BottomSurveyBalls.getFlatOffset();
+            flatPos = VecOp.add(ballPos, flatOffset);
+        }
+    }
+    
+    /**
+     * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel.
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    private static class UChannelL46BottomSurveyBalls  {
+        
+     // Shawn's calculated point at midpoint between two forward survey balls
+        protected final static Hep3Vector ball_pos = new BasicHep3Vector(-5.857, -157.776, -8.423);
+
+        
+        private static final double cone_fwd_right_x = -7.019*inch;
+        private static final double cone_fwd_right_y = -6.419*inch;
+        private static final double cone_fwd_right_z = -0.332*inch;
+
+        private static final double cone_bwd_right_x = -6.539*inch;
+        private static final double cone_bwd_right_y = -22.159*inch;
+        private static final double cone_bwd_right_z = -0.332*inch;
+
+        private static final double cone_fwd_left_x = 6.558*inch;
+        private static final double cone_fwd_left_y = -6.005*inch;
+        private static final double cone_fwd_left_z = -0.332*inch;
+
+        private static final double cone_bwd_left_x = 7.038*inch;
+        private static final double cone_bwd_left_y = -21.745*inch;
+        private static final double cone_bwd_left_z = -0.332*inch;
+        
+        protected static final Hep3Vector fwd_right = new BasicHep3Vector(cone_fwd_right_x, cone_fwd_right_y, cone_fwd_right_z);
+        protected static final Hep3Vector fwd_left = new BasicHep3Vector(cone_fwd_left_x, cone_fwd_left_y, cone_fwd_left_z);
+        protected static final Hep3Vector bwd_right = new BasicHep3Vector(cone_bwd_right_x, cone_bwd_right_y, cone_bwd_right_z);
+        protected static final Hep3Vector bwd_left = new BasicHep3Vector(cone_bwd_left_x, cone_bwd_left_y, cone_bwd_left_z);
+        
+        protected static Hep3Vector getVeeOffset() {
+            return  VecOp.mult(0.5,VecOp.sub(fwd_right, fwd_left));
+        }
+        protected static Hep3Vector getFlatOffset() {
+            return VecOp.sub(bwd_left, fwd_left);
+        }
+    }
+    
+    
+    
+    
+//  public static class UChannelL46Bottom extends UChannelL46 {
+//      // Coordinates of the survey ball engaging the machined features
+//      protected static final double cone_fwd_right_x = -7.019*inch;
+//      protected static final double cone_fwd_right_y = -6.419*inch;
+//      protected static final double cone_fwd_right_z = -0.332*inch;
+//
+//      protected static final double cone_bwd_right_x = -6.539*inch;
+//      protected static final double cone_bwd_right_y = -22.159*inch;
+//      protected static final double cone_bwd_right_z = -0.332*inch;
+//
+//      protected static final double cone_fwd_left_x = 6.558*inch;
+//      protected static final double cone_fwd_left_y = -6.005*inch;
+//      protected static final double cone_fwd_left_z = -0.332*inch;
+//
+//      protected static final double cone_bwd_left_x = 7.038*inch;
+//      protected static final double cone_bwd_left_y = -21.745*inch;
+//      protected static final double cone_bwd_left_z = -0.332*inch;
+//
+//      protected static final double cone_to_edge_of_plate_y = 2.75*inch;
+//
+//      public UChannelL46Bottom(String name, SurveyVolume m,
+//              AlignmentCorrection alignmentCorrection) {
+//          super(name, m, alignmentCorrection);
+//          init();
+//      }
+//      protected void setCenter() {
+//          final double x = 0.0;
+//          final double y = -cone_to_edge_of_plate_y + length/2.0;
+//          final double z = -side_plate_cone_y - UChannelL46Plate.height + height/2.0;
+//          setCenter(x,y,z);
+//      }
+//      protected void setPos() {
+//          //locate coordinate system from cone in mother coordinate system
+//          Hep3Vector fwd_right = new BasicHep3Vector(cone_fwd_right_x, cone_fwd_right_y, cone_fwd_right_z);
+//          Hep3Vector fwd_left = new BasicHep3Vector(cone_fwd_left_x, cone_fwd_left_y, cone_fwd_left_z);
+//          Hep3Vector bwd_right = new BasicHep3Vector(cone_bwd_right_x, cone_bwd_right_y, cone_bwd_right_z);
+//          Hep3Vector bwd_left = new BasicHep3Vector(cone_bwd_left_x, cone_bwd_left_y, cone_bwd_left_z);
+//          
+//          Hep3Vector d = VecOp.mult(0.5,VecOp.sub(fwd_left, fwd_right));
+//          ballPos = VecOp.add(fwd_right, d);
+//          veePos = fwd_right;
+//          d = VecOp.mult(0.5, VecOp.sub(bwd_left, bwd_right));
+//          flatPos = VecOp.add(bwd_right, d);
+//      }
+//  }
+  
+    
+    /**
+     * @SurveyVolume volume defining the coordinate system of the u-channel 
+     *  Reference: SVTBox coordinate system
+     *  Origin: midpoint between upstream survey cones
+     *  Orientation: u - width pointing towards electron side, v - pointing along the U-channel in the beam direction
+     *  
+     *  @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL46Top extends UChannelL46 {
+
+        
+        private static final double cone_to_side_plate_pin_y = (0.875-0.25)*inch;
+        private static final double side_plate_pin_to_edge_of_plate_y = 1.5*inch;
+        
+        protected static final double cone_to_edge_of_plate_y = cone_to_side_plate_pin_y + side_plate_pin_to_edge_of_plate_y;
+        
+        public UChannelL46Top(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection) {
+            super(name, m, alignmentCorrection);
+            init();
+        }
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = -cone_to_edge_of_plate_y + length/2.0;
+            final double z = -side_plate_cone_y - UChannelL46Plate.height + height/2.0;
+            setCenter(x,y,z);
+        }
+        protected void setPos() {
+            
+            ballPos = UChannelL46TopSurveyBalls.ball_pos;
+            Hep3Vector veeOffset = UChannelL46TopSurveyBalls.getVeeOffset();
+            veePos = VecOp.add(ballPos, veeOffset);
+            Hep3Vector flatOffset = UChannelL46TopSurveyBalls.getFlatOffset();
+            flatPos = VecOp.add(ballPos, flatOffset);
+            
+            //ballPos = ball_pos;
+            //veePos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z()); // note sign change on random offset w.r.t. bottom
+            //flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()-1, ballPos.z()); // random offset
+        }
+    }
+    
+    
+    /**
+     * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel.
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    private static class UChannelL46TopSurveyBalls  {
+
+        // Shawn's calculated point at midpoint between two forward survey balls
+        protected final static Hep3Vector ball_pos = new BasicHep3Vector(-6.341, -141.909, 8.423);
+
+
+        protected static final double cone_fwd_right_x = -7.038*inch;
+        protected static final double cone_fwd_right_y = -5.794*inch;
+        protected static final double cone_fwd_right_z = 0.332*inch;
+
+        protected static final double cone_bwd_right_x = -6.558*inch;
+        protected static final double cone_bwd_right_y = -21.535*inch;
+        protected static final double cone_bwd_right_z = 0.332*inch;
+
+        protected static final double cone_fwd_left_x = 6.539*inch;
+        protected static final double cone_fwd_left_y = -5.380*inch;
+        protected static final double cone_fwd_left_z = 0.332*inch;
+
+        protected static final double cone_bwd_left_x = 7.019*inch;
+        protected static final double cone_bwd_left_y = -21.121*inch;
+        protected static final double cone_bwd_left_z = 0.332*inch;
+
+        protected static final Hep3Vector fwd_right = new BasicHep3Vector(cone_fwd_right_x, cone_fwd_right_y, cone_fwd_right_z);
+        protected static final Hep3Vector fwd_left = new BasicHep3Vector(cone_fwd_left_x, cone_fwd_left_y, cone_fwd_left_z);
+        protected static final Hep3Vector bwd_right = new BasicHep3Vector(cone_bwd_right_x, cone_bwd_right_y, cone_bwd_right_z);
+        protected static final Hep3Vector bwd_left = new BasicHep3Vector(cone_bwd_left_x, cone_bwd_left_y, cone_bwd_left_z);
+
+        protected static Hep3Vector getVeeOffset() {
+            return  VecOp.mult(0.5,VecOp.sub(fwd_left, fwd_right));
+        }
+        protected static Hep3Vector getFlatOffset() {
+            return VecOp.sub(bwd_right, fwd_right);
+        }
+    }
+
+
+//    public static class UChannelL46Top extends UChannelL46 {
+//        // Coordinates of the survey ball engaging the machined features
+//        protected static final double cone_fwd_right_x = -7.038*inch;
+//        protected static final double cone_fwd_right_y = -5.794*inch;
+//        protected static final double cone_fwd_right_z = 0.332*inch;
+//
+//        protected static final double cone_bwd_right_x = -6.558*inch;
+//        protected static final double cone_bwd_right_y = -21.535*inch;
+//        protected static final double cone_bwd_right_z = 0.332*inch;
+//
+//        protected static final double cone_fwd_left_x = 6.539*inch;
+//        protected static final double cone_fwd_left_y = -5.380*inch;
+//        protected static final double cone_fwd_left_z = 0.332*inch;
+//
+//        protected static final double cone_bwd_left_x = 7.019*inch;
+//        protected static final double cone_bwd_left_y = -21.121*inch;
+//        protected static final double cone_bwd_left_z = 0.332*inch;
+//        
+//        private static final double cone_to_side_plate_pin_y = (0.875-0.25)*inch;
+//        private static final double side_plate_pin_to_edge_of_plate_y = 1.5*inch;
+//        
+//        protected static final double cone_to_edge_of_plate_y = cone_to_side_plate_pin_y + side_plate_pin_to_edge_of_plate_y;
+//        
+//        public UChannelL46Top(String name, SurveyVolume m,
+//                AlignmentCorrection alignmentCorrection) {
+//            super(name, m, alignmentCorrection);
+//            init();
+//        }
+//        protected void setCenter() {
+//            final double x = 0.0;
+//            final double y = -cone_to_edge_of_plate_y + length/2.0;
+//            final double z = -side_plate_cone_y - UChannelL46Plate.height + height/2.0;
+//            setCenter(x,y,z);
+//        }
+//        protected void setPos() {
+//            
+//          //locate coordinate system from cone in mother coordinate system
+//            Hep3Vector fwd_right = new BasicHep3Vector(cone_fwd_right_x, cone_fwd_right_y, cone_fwd_right_z);
+//            Hep3Vector fwd_left = new BasicHep3Vector(cone_fwd_left_x, cone_fwd_left_y, cone_fwd_left_z);
+//            Hep3Vector bwd_right = new BasicHep3Vector(cone_bwd_right_x, cone_bwd_right_y, cone_bwd_right_z);
+//            Hep3Vector bwd_left = new BasicHep3Vector(cone_bwd_left_x, cone_bwd_left_y, cone_bwd_left_z);
+//            
+//            Hep3Vector d = VecOp.mult(0.5,VecOp.sub(fwd_left, fwd_right));
+//            ballPos = VecOp.add(fwd_right, d);
+//            veePos = fwd_left;
+//            d = VecOp.mult(0.5, VecOp.sub(bwd_left, bwd_right));
+//            flatPos = VecOp.add(bwd_right, d);
+//            
+//        }
+//    }
+
+    
+    
+    /**
+     * Abstract @SurveyVolume  defining the coordinate system of the u-channel plates
+
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public abstract static class UChannelL46Plate extends UChannelPlate {
+        public final static double pocket_depth_L4 = 0.1;
+        public final static double pocket_depth_L5 = pocket_depth_L4 + 0.118;
+        public final static double pocket_depth_L6 = pocket_depth_L5 + 0.118;
+        public final static double module_mounting_hole_to_hole_x =7.874*inch;
+        public static final double width = 13.5*inch;
+        public static final double length = 21.0*inch;
+        public static final double height = 0.5*inch;
+        
+        public UChannelL46Plate(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            setMaterial("Aluminum");
+        }
+        
+        /**
+         * Get pocket depth for this plate
+         * @param layer
+         * @return pocket depth
+         */
+        public static double getPocketDepth(int layer) {
+             if(layer==4) return pocket_depth_L4;
+             else if(layer==5) return pocket_depth_L5;
+             else if(layer==6) return pocket_depth_L6;
+             else {
+                 throw new RuntimeException("Trying to create a L4-6 module with invalid layer nr: " + layer);
+             }
+        }
+
+        protected void setBoxDim() {
+            setBoxDim(getWidth(),getLength(),getHeight());
+        }
+
+        protected void setPos() {
+           ballPos = new BasicHep3Vector(0, 0, 0);
+           veePos = new BasicHep3Vector(1, 0, 0);
+           flatPos = new BasicHep3Vector(0, 1, 0);
+        }
+        
+        public double getWidth() {
+            return width;
+        }
+        
+        public double getLength() {
+            return length;
+        }
+        
+        public double getHeight() {
+            return height;
+        }
+    }
+    
+    /**
+     * @SurveyVolume  defining the coordinate system of the bottom u-channel plate
+     * Reference:  @UChannelL13Bottom coordinate system
+     * Origin:  same as reference
+     * Orientation: same as reference
+     *
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL46BottomPlate extends UChannelL46Plate {
+        protected final static double L4_module_pin_to_edge_of_plate = 3.125*inch;
+        
+        public UChannelL46BottomPlate(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            init();
+        }
+
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = -UChannelL46Bottom.cone_to_edge_of_plate_y + length/2.0;
+            final double z = -UChannelL46.side_plate_cone_y - height/2.0;
+            setCenter(x,y,z);
+        }
+       
+    }
+    
+    
+    /**
+     * @SurveyVolume defining the coordinate system of the top u-channel plate
+     * Reference:  @UChannelL13Top coordinate system
+     * Origin:  same as reference
+     * Orientation: same as reference
+     *
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class UChannelL46TopPlate extends UChannelL46Plate {
+        protected final static double L4_module_pin_to_edge_of_plate = 1.75*inch;
+
+        public UChannelL46TopPlate(String name, SurveyVolume m,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, m, alignmentCorrection, ref);
+            init();
+        }
+
+        protected void setCenter() {
+            final double x = 0.0;
+            final double y = -UChannelL46Top.cone_to_edge_of_plate_y + length/2.0;
+            final double z = -UChannelL46.side_plate_cone_y - height/2.0;
+            setCenter(x,y,z);
+        }
+       
+    }
+
+    
+
+    /**
+     * @SurveyVolume volume defining the coordinate system of module L1-3
+     * Reference:  @UChannelL13Bottom coordinate system
+     * Origin:  hole position on mounting surface (on electron side)
+     * Orientation: u - is normal to the surface pointing vertically down, v - points along module away from hybrid side (i.e. positron direction).
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public abstract static class ModuleL13 extends BaseModule {
+        private final static double box_extra_length = 10.0;// random at this point
+        private final static double box_extra_height = -0.45*inch;// random at this point
+        private final static double box_extra_width = 0.5*inch;// random at this point
+        
+        private static final double tension_lever_y = 2.5*inch;
+        // TODO the dimension of this volume is padded manually. Check if this can cause overlap problems
+        public static final double length = 8.0*inch + box_extra_length;  
+        public static final double height = 1.0*inch + box_extra_height;
+        private static final double width = tension_lever_y + 0.04*inch + box_extra_width;
+        //private static final double hole_to_end_of_module_x = 7.750*inch;
+        //private static final double hole_to_module_edge_height_dir = height - 0.875*inch;
+        protected static final double hole_to_center_of_plate_width_dir = 3.75*inch;
+        private static final double hole_to_module_edge_length_dir = 0.25*inch;
+        
+        public ModuleL13(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref, getLayerFromVolumeName(name), getHalfFromName(name));
+            
+        }
+        protected void setCenter() {
+            final double x = -width/2.0;
+            final double y = -hole_to_module_edge_length_dir + length/2.0;
+            //center this volume around the center of the module which is the same as the cone for L1
+            //final double z = hole_to_module_edge_height_dir - height/2.0;
+            final double z = -Math.abs(getHoleModuleCenterOffset());
+            setCenter(x,y,z);
+        }
+        protected void setBoxDim() {
+            setBoxDim(width, length, height);
+        }
+        protected abstract void setPos();
+        protected abstract double getHoleModuleCenterOffset();
+        protected abstract Hep3Vector getHolePosition();
+    }
+    
+    public abstract static class ModuleL13Top extends ModuleL13 {
+        public ModuleL13Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+        }
+        protected void setPos() {
+            ballPos = getHolePosition();
+            veePos = new BasicHep3Vector(ballPos.x(), ballPos.y(), ballPos.z()-1.0);
+            flatPos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+        }
+        protected double getHoleModuleCenterOffset() {
+            return UChannelL13Top.cone_to_edge_of_plate_y - UChannelL13TopPlate.L1_module_pin_to_edge_of_plate;
+        }
+
+    }
+    
+    public abstract static class ModuleL13Bot extends ModuleL13 {
+        public ModuleL13Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+        }
+        protected void setPos() {
+            ballPos = getHolePosition();
+            veePos = new BasicHep3Vector(ballPos.x(), ballPos.y(), ballPos.z()-1.0);
+            flatPos = new BasicHep3Vector(ballPos.x()-1, ballPos.y(), ballPos.z());
+        }
+        protected double getHoleModuleCenterOffset() {
+            return UChannelL13Bottom.cone_to_edge_of_plate_y - UChannelL13BottomPlate.L1_module_pin_to_edge_of_plate;
+        }
+    }
+    
+    
+    public static class ModuleL1Bot extends ModuleL13Bot {
+
+        public ModuleL1Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+        protected Hep3Vector getHolePosition() {
+            double x = 95.25;
+            double y = 9.525;
+            double z = -51.435;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+    
+   
+    public static class ModuleL1Top extends ModuleL13Top {
+
+        public ModuleL1Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+       
+        protected Hep3Vector getHolePosition() {
+            double x = -95.25; // note minus sign compared to bottom
+            double y = -9.525;
+            double z = -51.435;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+    
+    
+    
+    public static class ModuleL2Bot extends ModuleL13Bot {
+
+        public ModuleL2Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+        protected Hep3Vector getHolePosition() {
+            double x = 95.25;
+            double y = 109.525;
+            double z = -51.435 - 1.5;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+    
+    public static class ModuleL2Top extends ModuleL13Top {
+
+        public ModuleL2Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+       
+        protected Hep3Vector getHolePosition() {
+            double x = -95.25; // note minus sign compared to bottom
+            double y = 90.475;
+            double z = -51.435 - 1.5;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+    
+    
+    
+    
+    public static class ModuleL3Bot extends ModuleL13Bot {
+
+        public ModuleL3Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+        protected Hep3Vector getHolePosition() {
+            double x = 95.25;
+            double y = 209.525;
+            double z = -51.435 - 2*1.5;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+        
+    public static class ModuleL3Top extends ModuleL13Top {
+
+        public ModuleL3Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+       
+        protected Hep3Vector getHolePosition() {
+            double x = -95.25; // note minus sign compared to bottom
+            double y = 190.475;
+            double z = -51.435 - 2*1.5;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+    
+    
+    
+   
+    
+    /**
+     * Abstract @SurveyVolume volume defining the coordinate system of module L4-6
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public abstract static class ModuleL46 extends BaseModule {
+        protected final static double hole_to_center_of_plate_width_dir = 5.875*inch;
+        protected final static double hole_to_module_edge_height_dir = 0.875*inch;
+        protected static final double hole_to_module_edge_length_dir = 0.25*inch;
+        private final static double box_extra_length = 0.0;// random at this point
+        private final static double box_extra_height = -0.45*inch;// random at this point
+        private final static double box_extra_width = 0.5*inch;// random at this point
+        
+        private static final double tension_lever_y = 2.5*inch;
+        // TODO the dimension of the L4-6 module is completely made up
+        public static final double length = 12.25*inch + box_extra_length;
+        public static final double height = 1.0*inch + box_extra_height;
+        public static final double width = tension_lever_y + 0.04*inch + box_extra_width;
+        
+        public ModuleL46(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref, getLayerFromVolumeName(name), getHalfFromName(name));
+            
+        }
+        protected void setCenter() {
+            final double x = -width/2.0;
+            final double y = -hole_to_module_edge_length_dir + length/2.0;
+            final double z = -Math.abs(getHoleModuleCenterOffset());
+            //final double z = -hole_to_module_edge_height_dir + height/2.0;
+            setCenter(x,y,z);
+        }
+        protected void setBoxDim() {
+            setBoxDim(width, length, height);
+        }
+        protected abstract void setPos();
+        protected abstract double getHoleModuleCenterOffset();
+        protected abstract Hep3Vector getHole();
+    }
+    
+    
+    /**
+     * Abstract @SurveyVolume volume defining the coordinate system of bottom modules for L4-6
+     * Reference:  @UChannelL46Bottom coordinate system
+     * Origin:  hole position on mounting surface (electron side)
+     * Orientation: u - is normal to the mounting surface pointing vertically down, v - points along module towards positron side.
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static abstract class ModuleL46Bot extends ModuleL46 {
+
+        public ModuleL46Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+        }
+        protected void setPos() {
+            ballPos = getHole();
+            veePos = new BasicHep3Vector(ballPos.x(), ballPos.y(), ballPos.z()-1.0);
+            flatPos = new BasicHep3Vector(ballPos.x()-1.0, ballPos.y(), ballPos.z());
+        }
+        protected double getHoleModuleCenterOffset() {
+            return UChannelL46Bottom.cone_to_edge_of_plate_y - UChannelL46BottomPlate.L4_module_pin_to_edge_of_plate;
+        }
+    }
+    
+    /**
+     * Abstract @SurveyVolume volume defining the coordinate system of top modules for L4-6
+     * Reference:  @UChannelL46Top coordinate system
+     * Origin:  hole position on mounting surface (electron side when installed)
+     * Orientation: u - is normal to the mounting surface pointing vertically down, v - points along module towards electron side when installed.
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static abstract class ModuleL46Top extends ModuleL46 {
+
+        public ModuleL46Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+        }
+        protected void setPos() {
+            ballPos = getHole();
+            veePos = new BasicHep3Vector(ballPos.x(), ballPos.y(), ballPos.z()-1.0);
+            flatPos = new BasicHep3Vector(ballPos.x()+1.0, ballPos.y(), ballPos.z());
+        }
+        protected double getHoleModuleCenterOffset() {
+            return UChannelL46Top.cone_to_edge_of_plate_y - UChannelL46TopPlate.L4_module_pin_to_edge_of_plate;
+        }
+
+    }
+    
+    
+    public static class ModuleL4Bot extends ModuleL46Bot {
+
+        public ModuleL4Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+
+        protected Hep3Vector getHole() {
+            double x = 149.225;
+            double y = 9.525;
+            double z = -53.34;
+            //double x = hole_to_center_of_plate_width_dir;   
+            //double y = -getHoleModuleCenterOffset(); //Note minus sign compared to top
+            //double z = -UChannelL46.side_plate_cone_y - UChannelL46Plate.pocket_depth_L4;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+    
+    public static class ModuleL4Top extends ModuleL46Top {
+
+        public ModuleL4Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+
+        protected Hep3Vector getHole() {
+            double x = -149.225;
+            double y = -9.525;
+            double z = -53.34;
+//            double x = -1*hole_to_center_of_plate_width_dir;   
+//            double y = -getHoleModuleCenterOffset();
+//            double z = -UChannelL46.side_plate_cone_y - UChannelL46Plate.pocket_depth_L4;
+            return new BasicHep3Vector(x, y, z);
+        }
+        
+    }
+    
+    
+    public static class ModuleL5Bot extends ModuleL46Bot {
+
+        public ModuleL5Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+
+        protected Hep3Vector getHole() {
+            double x = 149.225;
+            double y = 209.525;
+            double z = -53.34 - 3.0;
+            return new BasicHep3Vector(x, y, z);
+        }
+
+    }
+    
+    public static class ModuleL5Top extends ModuleL46Top {
+
+        public ModuleL5Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+
+        protected Hep3Vector getHole() {
+            double x = -149.225;
+            double y = 190.475;
+            double z = -53.34 - 3.0;
+            return new BasicHep3Vector(x, y, z);
+        }
+
+    }
+
+    public static class ModuleL6Bot extends ModuleL46Bot {
+
+        public ModuleL6Bot(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+
+        protected Hep3Vector getHole() {
+            double x = 149.225;
+            double y = 409.525;
+            double z = -53.34 - 2*3.0;
+            return new BasicHep3Vector(x, y, z);
+        }
+
+    }
+    
+    public static class ModuleL6Top extends ModuleL46Top {
+
+        public ModuleL6Top(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+            super(name, mother, alignmentCorrection, ref);
+            init();
+        }
+
+        protected Hep3Vector getHole() {
+            double x = -149.225;
+            double y = 390.475;
+            double z = -53.34 - 2*3.0;
+            return new BasicHep3Vector(x, y, z);
+        }
+
+    }
+
+
+
+
+
+    public abstract static class LongHalfModule extends BaseModule {
+
+        //private static final double randomoffset = 5.0; 
+        public static final double width = Sensor.width; // + randomoffset;
+        public static final double length = Sensor.length;// + randomoffset/10.0;
+        public static final double height = Sensor.height + HalfLongModuleLamination.height;
+        protected final static double sensor_z = 0.23*inch;
+
+
+        public LongHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+        }
+
+        protected abstract Hep3Vector getSensorPosition();
+        
+        protected void setBoxDim() {
+            setBoxDim(width, length, height);
+        }
+
+        protected void setCenter() {
+            double x = 0.0;
+            double y = 0.0;
+            double z = +0.5*Sensor.height - height/2.0;;
+            setCenter(x,y,z);
+        }
+
+        protected void setPos() {
+            ballPos = getSensorPosition(); //TODO make this get each coordinate instead.
+            veePos  = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+            flatPos  = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());
+        }
+        
+    }
+
+
+
+    public static class LongAxialHoleHalfModule extends LongHalfModule {
+
+        private final static double sensor_x = 1.382*inch;
+        private final static double sensor_y = 3.887*inch;
+
+
+        public LongAxialHoleHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+
+        protected Hep3Vector getSensorPosition() {
+            return new BasicHep3Vector(-sensor_x, sensor_y, -sensor_z);
+        }
+        
+
+    }
+
+
+    
+    
+    public abstract static class LongAxialSlotHalfModuleBase extends LongHalfModule {
+
+        private final static double sensor_x = 1.382*inch;
+        private final static double sensor_y = 7.863*inch;
+
+        public LongAxialSlotHalfModuleBase(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+        }
+       
+        protected Hep3Vector getSensorPosition() {
+            return new BasicHep3Vector(-sensor_x, sensor_y, -sensor_z);
+        }
+
+    }
+
+    public static class LongAxialSlotHalfModule extends LongAxialSlotHalfModuleBase {
+
+        private final static double sensor_x = 1.382*inch;
+        private final static double sensor_y = 7.863*inch;
+
+
+        public LongAxialSlotHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+       
+        protected Hep3Vector getSensorPosition() {
+            return new BasicHep3Vector(-sensor_x, sensor_y, -sensor_z);
+        }
+    }
+    
+
+    public abstract static class LongStereoHalfModule extends LongHalfModule {
+
+        protected final static double sensor_z = 0.52*inch;
+        protected final static double stereo_angle = 0.05;
+        
+        public LongStereoHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+        }
+        
+        
+        protected void applyGenericCoordinateSystemCorrections() {
+
+            // Rotate these into the right place for the stereo
+            // My rotations here are active rotations in the mother coordinate system frame
+
+            // flip around v ~ along the strips
+            Rotation r1 = new Rotation(new Vector3D(0,1,0),Math.PI);
+            // apply stereo angle around w ~ normal to the sensor plane
+            Rotation r2 = new Rotation(new Vector3D(0,0,1),stereo_angle);
+            // Build full rotation
+            Rotation r = r2.applyTo(r1);
+            //Rotation r = r1;
+            if(debug) {
+                System.out.printf("%s: LongStereoHalfModule Generic Corrections\n", getClass().getSimpleName());
+                System.out.printf("%s: Coord before corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+                System.out.printf("%s: box center before corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            }
+            
+            getCoord().rotateApache(r);
+            
+            if(debug) {
+                System.out.printf("%s: Coord after corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+                System.out.printf("%s: box center after corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            }
+
+        }
+        
+        
+
+
+    }
+
+    
+    public static class LongStereoHoleHalfModule extends LongStereoHalfModule {
+
+        private final static double sensor_x = 1.282*inch;
+        private final static double sensor_y = 3.889*inch;
+
+        public LongStereoHoleHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+
+        protected Hep3Vector getSensorPosition() {
+           return new BasicHep3Vector(-sensor_x, sensor_y, -sensor_z);
+        }
+
+    }
+
+
+    
+    public static abstract class LongStereoSlotHalfModuleBase extends LongStereoHalfModule {
+
+        private final static double sensor_x = 1.481*inch;
+        private final static double sensor_y = 7.861*inch;
+        
+        public LongStereoSlotHalfModuleBase(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+        }
+
+        protected Hep3Vector getSensorPosition() {
+            return new BasicHep3Vector(-sensor_x, sensor_y, -sensor_z);
+        }
+    }
+
+    public static class LongStereoSlotHalfModule extends LongStereoSlotHalfModuleBase {
+        public LongStereoSlotHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+    }
+    
+
+    /**
+     * @SurveyVolume volume defining the coordinate system of the axial half-module in module L1-3
+     * Reference:  @ModuleL13Bot coordinate system
+     * Origin:  sensor center
+     * Orientation: w - is normal to the surface pointing from p-side to n-side, v - points along strips away from signal bond pads
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class HalfModuleAxial extends HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule {
+        // Sensor positions from Shawn's 3D model
+        public static final double sensor_x = -1.543*inch;
+        public static final double sensor_y = 4.868*inch;
+        public static final double sensor_z = -0.23*inch;
+        
+        public HalfModuleAxial(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+        protected void setPos() {
+            ballPos = getSensorPosition();
+            veePos  = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+            flatPos  = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());
+        }
+        protected Hep3Vector getSensorPosition() {
+            return new BasicHep3Vector(sensor_x, sensor_y, sensor_z);
+        }
+        protected void setCenter() {
+            double x = -1.0 * (TestRunHalfModule.getWidth()/2.0 - ( 12.66 - (8.83 -3.00) + Sensor.width/2.0 ) ); 
+            double y =  TestRunHalfModule.getLength()/2.0 - ( (170.00 + 10.00) - Sensor.length/2.0); 
+            double z = -Sensor.getSensorThickness()/2.0 - HPSTestRunTracker2014GeometryDefinition.HalfModuleLamination.thickness - CarbonFiber.thickness + half_module_thickness/2.0; 
+            setCenter(x, y, z); 
+        }
+    }
+    
+    
+    
+    
+   
+    /**
+     * @SurveyVolume volume defining the coordinate system of the stereo half-module in module L1-3
+     * Reference:  @ModuleL13Bot coordinate system
+     * Origin:  sensor center
+     * Orientation: same as axial - the module is rotated later.
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class HalfModuleStereo extends HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule {
+        
+        public static final double sensor_z = -0.52*inch;
+        
+        public HalfModuleStereo(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            if(layer>=1 && layer<=3) stereo_angle = 0.1;
+            else throw new RuntimeException("Layer " + layer + " is ill-defined for test run modules");
+            init();
+        }
+        protected void setPos() {
+            // Sensor positions from Shawn's 3D model
+            final double x = HalfModuleAxial.sensor_x;
+            final double y = HalfModuleAxial.sensor_y;
+            final double z = sensor_z;
+            ballPos = new BasicHep3Vector(x, y, z);
+            veePos  = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+            flatPos  = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());
+        }
+        protected void setCenter() {
+            double x = -1.0 * (TestRunHalfModule.getWidth()/2.0 - ( 12.66 - (8.83 -3.00) + Sensor.width/2.0 ) ); 
+            double y =  TestRunHalfModule.getLength()/2.0 - ( (170.00 + 10.00) - Sensor.length/2.0); 
+            double z = -Sensor.getSensorThickness()/2.0 - HPSTestRunTracker2014GeometryDefinition.HalfModuleLamination.thickness - CarbonFiber.thickness + half_module_thickness/2.0; 
+            setCenter(x, y, z); 
+        }
+        protected void applyGenericCoordinateSystemCorrections() {
+            
+            // Rotate into the right place for the stereo - just offset compared to axial before this.
+            // My rotations here are active rotations in the mother coordinate system frame
+            // Sloppy description of the frame:
+            // x: direction along strips towards the readout bonds/apv25's
+            // v: normal to sensor plane pointing from the back-plane (n-side) to strip side (p-side)
+            // w: measurement direction with direction from right hand-rule
+
+            // flip around strip direction - sign doesn't matter
+            Rotation r1 = new Rotation(new Vector3D(0,1,0),Math.PI);
+            // apply stereo angle around v
+            Rotation r2 = new Rotation(new Vector3D(0,0,1),stereo_angle);
+            // Build full rotation
+            Rotation r = r2.applyTo(r1);
+            //Rotation r = r1;
+            if(debug) System.out.printf("%s: Coord before corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+            if(debug) System.out.printf("%s: box center before corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            getCoord().rotateApache(r);
+            if(debug) System.out.printf("%s: Coord after corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+            if(debug) System.out.printf("%s: box center after corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+
+        }
+
+        
+    }
+    
+    
+    public static class HalfLongModuleLamination extends HPSTestRunTracker2014GeometryDefinition.HalfModuleComponent {
+        protected static final double width = Sensor.width;
+        protected static final double length = Sensor.length;
+        protected static final double height = 0.050;
+        
+        public HalfLongModuleLamination(String name, SurveyVolume mother, int id) {
+            super(name, mother, null, id);
+           init();
+        }
+
+        protected double getThickness() {
+            return height;
+        }
+        protected double getHeigth() {
+            return height;
+        }
+        protected double getWidth() {
+            return width;
+        }
+        protected double getLength() {
+            return length;
+        }
+        protected void setPos() {
+            //offset enough to make them face-to-face
+            ballPos = new BasicHep3Vector(0, 0, -(Sensor.getSensorThickness()/2.0 + height/2.0));
+            veePos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());
+        }
+        protected void setCenter() {
+            setCenter(0, 0, 0);            
+        }
+        protected void setBoxDim() {
+            setBoxDim(width, length, height);
+        }
+    }    
+    
+    
+    
+    /**
+     * Create the module. 
+     * @param layer - of the module
+     * @param half - top or bottom half of the tracker
+     */
+    protected void makeModuleBundle(int layer, String half) 
+    {
+
+        if(isDebug()) System.out.printf("%s: makeModule for layer %d %s \n", this.getClass().getSimpleName(), layer, half);
+
+
+        // build the module name
+        String volName = "module_L"+ layer + (half=="bottom"?"b":"t");      
+
+        // find the mother and reference geometry
+        // Note that the reference geometry is the support plate and since that is assumed to be 
+        // created through it's references we don't need more than one reference to reach the mother coordinate system
+        final SurveyVolume mother = getSurveyVolume(SvtBox.class);
+        final SurveyVolume ref;
+        AlignmentCorrection alignmentCorrection = null;
+        if(half == "bottom") {
+            if(layer < 4) {
+                ref = getSurveyVolume(UChannelL13Bottom.class);
+            } else {
+                ref = getSurveyVolume(UChannelL46Bottom.class);
+            }
+        } else {
+            if(layer < 4) {
+                ref = getSurveyVolume(UChannelL13Top.class);
+            } else {
+                ref = getSurveyVolume(UChannelL46Top.class);
+            }
+        }
+
+        //Create the module
+        BaseModule module;
+        if(half == "bottom") {
+            if(layer==1) {
+                module = new ModuleL1Bot(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==2) {
+                module = new ModuleL2Bot(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==3) {
+                module = new ModuleL3Bot(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==4) {
+                module = new ModuleL4Bot(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==5) {
+                module = new ModuleL5Bot(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==6) {
+                module = new ModuleL6Bot(volName, mother, alignmentCorrection, ref); 
+            } else {
+                throw new UnsupportedOperationException("Layer " + layer + " not implemented yet for bottom");
+            }
+        } else {
+            if(layer==1) {
+                module = new ModuleL1Top(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==2) {
+                module = new ModuleL2Top(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==3) {
+                module = new ModuleL3Top(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==4) {
+                module = new ModuleL4Top(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==5) {
+                module = new ModuleL5Top(volName, mother, alignmentCorrection, ref); 
+            } else if(layer==6) {
+                module = new ModuleL6Top(volName, mother, alignmentCorrection, ref); 
+            } else {
+                throw new UnsupportedOperationException("Layer " + layer + " not implemented yet for top");
+            }
+        }
+
+
+        // create the bundle for this module
+        // need to create it and add to list before half-module is created
+        // as it uses the list to find the bundle. Ugly. TODO fix this.
+        BaseModuleBundle bundle;
+        
+        if(layer<=3) {
+            bundle = new TestRunModuleBundle(module);
+            addModuleBundle(bundle);
+            if(doAxial) makeHalfModule("axial", module);
+            //        if(doColdBlock) makeColdBlock(module);
+            if(doStereo) makeHalfModule("stereo", module);
+        } else {
+            bundle = new LongModuleBundle(module);
+            addModuleBundle(bundle);
+            if(doAxial) {
+                makeLongHalfModule("axial","hole", module);
+                makeLongHalfModule("axial","slot", module);
+            }
+            //        if(doColdBlock) makeColdBlock(module);
+            if(doStereo) {
+                makeLongHalfModule("stereo","hole", module);
+                makeLongHalfModule("stereo","slot", module);
+            }
+        }
+
+
+
+        if(isDebug()) {
+            System.out.printf("%s: created module bundle:\n", this.getClass().getSimpleName());
+            bundle.print();
+            System.out.printf("%s: Now there are %d  modules\n", this.getClass().getSimpleName(),modules.size());
+        }
+
+        
+
+    }
+
+
+
+
+
+    /**
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class LongModuleBundle extends BaseModuleBundle {
+        public HalfModuleBundle halfModuleAxialHole = null;
+        public HalfModuleBundle halfModuleStereoHole = null;
+        public HalfModuleBundle halfModuleAxialSlot = null;
+        public HalfModuleBundle halfModuleStereoSlot = null;
+        protected SurveyVolume coldBlock = null;
+        public LongModuleBundle(BaseModule m) {
+            super(m);
+        }
+        public void print() {
+            if(module!=null) System.out.printf("%s: %s\n", this.getClass().getSimpleName(),module.toString());
+            if(halfModuleAxialHole!=null) halfModuleAxialHole.print();
+            if(halfModuleAxialSlot!=null) halfModuleAxialSlot.print();
+            if(coldBlock!=null)System.out.printf("%s: %s\n", this.getClass().getSimpleName(),coldBlock.getName());
+            if(halfModuleStereoHole!=null) halfModuleStereoHole.print();
+            if(halfModuleStereoSlot!=null) halfModuleStereoSlot.print();
+            }
+        }
+
+
+    /**
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class LongHalfModuleBundle extends HalfModuleBundle {
+        public LongHalfModuleBundle() {
+            super();
+        }
+        public LongHalfModuleBundle(SurveyVolume hm) {
+            super(hm);
+        }
+    }
+    
+    
+    
+    /**
+     * Create the half-module.
+     * @param side - stereo or axial
+     * @param type - hole or slot
+     * @param mother to the half-module
+     */
+    protected void makeLongHalfModule(String side, String type , BaseModule mother) {
+        
+        String moduleName = mother.getName();
+    
+        if(isDebug()) System.out.printf("%s: makeHalfModule for %s %s %s \n", this.getClass().getSimpleName(), moduleName, side, type);
+        
+        String volName = moduleName + "_halfmodule_" + side + "_" + type;
+    
+        // top or bottom?
+        String half = mother.getHalf();
+        boolean isTopLayer = !mother.isBottom();
+    
+        // find layer
+        int layer = mother.getLayer();
+    
+        // axial or stereo
+        boolean isAxial = isAxialFromName(volName);
+    
+        // hole or slot
+        boolean isHole = isHoleFromName(volName);
+        
+        // find layer according to Millepede layer definition
+        int millepedeLayer = getMillepedeLayer(isTopLayer, layer, isAxial, isHole);
+        
+        // find alignment correction to this volume
+        AlignmentCorrection alignmentCorrection =  getHalfModuleAlignmentCorrection(isTopLayer, millepedeLayer);
+        
+        
+        // find the module bundle that it will be added to
+        //TestRunModuleBundle bundle  = (TestRunModuleBundle)getModuleBundle(mother);
+        //TestRunHalfModuleBundle halfModuleBundle;
+        LongModuleBundle bundle  = (LongModuleBundle)getModuleBundle(mother);
+        
+       
+        
+        
+        // Build the half-module bundle and half-module
+        //TODO clean this up to a separate method
+        LongHalfModule halfModule;
+        HalfModuleBundle halfModuleBundle;
+        if(isAxial) {
+            halfModuleBundle = new LongHalfModuleBundle();
+            if(isHole) {
+                halfModule = new LongAxialHoleHalfModule(volName, mother, alignmentCorrection, layer, half);
+                bundle.halfModuleAxialHole = halfModuleBundle;
+            } else {
+                halfModule = createLongAxialSlotHalfModule(volName, mother, alignmentCorrection, layer, half);
+                bundle.halfModuleAxialSlot = halfModuleBundle;
+            }
+        } else {
+            halfModuleBundle = new LongHalfModuleBundle();
+            if(isHole) {
+                halfModule = new LongStereoHoleHalfModule(volName, mother, alignmentCorrection, layer, half);
+                bundle.halfModuleStereoHole = halfModuleBundle;
+            } else {
+                halfModule = createLongStereoSlotHalfModule(volName, mother, alignmentCorrection, layer, half);
+                bundle.halfModuleStereoSlot = halfModuleBundle;
+            }
+        } 
+        halfModuleBundle.halfModule = halfModule;
+        
+        
+    
+    
+        // create the half module components 
+        makeHalfModuleComponentSensor(halfModule);
+
+        makeLongHalfModuleComponentKapton(halfModule);
+
+        //makeHalfModuleComponentCF(halfModule);
+    
+        //makeHalfModuleComponentHybrid(halfModule);
+    
+    
+    
+    
+    }
+
+
+    protected void makeLongHalfModuleComponentKapton(BaseModule mother) {
+        
+        if(isDebug()) System.out.printf("%s: makeHalfModuleComponentKapton for %s \n", this.getClass().getSimpleName(), mother.getName());
+    
+        String volName = mother.getName() + "_lamination";
+    
+        // Build the half-module
+    
+        //  id is hard coded
+        int component_number = 2;
+    
+        HalfLongModuleLamination lamination = new HalfLongModuleLamination(volName,mother,component_number);
+        lamination.setMaterial("Kapton");
+    
+    
+        HalfModuleBundle hm = getHalfModuleBundle((BaseModule) mother.getMother(), mother.getName());
+        hm.lamination = lamination;
+    
+    }
+
+    
+    
+    
+    
+    protected HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule createTestRunHalfModuleAxial(String volName,
+            BaseModule mother, AlignmentCorrection alignmentCorrection,
+            int layer, String half) {
+        return new HalfModuleAxial(volName, mother, alignmentCorrection, layer, half);
+        
+    }
+    
+    protected HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule createTestRunHalfModuleStereo(String volName,
+            BaseModule mother, AlignmentCorrection alignmentCorrection,
+            int layer, String half) {
+        return new HalfModuleStereo(volName, mother, alignmentCorrection, layer, half);
+        
+    }
+    
+    /**
+     * Create {@link LongAxialSlotHalfModule} {@link SurveyVolume}. 
+     * @param name
+     * @param mother
+     * @param alignmentCorrection
+     * @param layer
+     * @param half
+     * @return
+     */
+    protected LongHalfModule createLongAxialSlotHalfModule(String name, SurveyVolume mother,
+            AlignmentCorrection alignmentCorrection, int layer,
+            String half) {
+        return new LongAxialSlotHalfModule(name, mother, alignmentCorrection, layer, half);
+    }
+
+    /**
+     * Create {@link LongStereoSlotHalfModule} {@link SurveyVolume}. 
+     * @param name
+     * @param mother
+     * @param alignmentCorrection
+     * @param layer
+     * @param half
+     * @return
+     */
+    protected LongHalfModule createLongStereoSlotHalfModule(String name, SurveyVolume mother,
+            AlignmentCorrection alignmentCorrection, int layer,
+            String half) {
+        return new LongStereoSlotHalfModule(name, mother, alignmentCorrection, layer, half);
+    }
+    
+    
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition#getHalfModuleBundle(org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BaseModule, java.lang.String)
+     */
+    protected HalfModuleBundle getHalfModuleBundle(BaseModule module, String halfModuleName) {
+        BaseModuleBundle moduleBundle = getModuleBundle(module);
+        HalfModuleBundle hm = null;
+        if(moduleBundle!=null) {
+            if( moduleBundle instanceof TestRunModuleBundle) {   
+                TestRunModuleBundle mtr = (TestRunModuleBundle) moduleBundle;
+                if(halfModuleName.contains("axial")) {
+                    hm = mtr.halfModuleAxial;
+                }
+                else if(halfModuleName.contains("stereo")) {
+                    hm = mtr.halfModuleStereo;
+                }
+                else {
+                    throw new RuntimeException("NO axial or stereo string found in half module bundle name " + halfModuleName);
+                }
+            } 
+            else if(moduleBundle instanceof LongModuleBundle) {
+                LongModuleBundle longModuleBundle = (LongModuleBundle) moduleBundle;
+                if(halfModuleName.contains("axial")) {
+                    if(halfModuleName.contains("hole")) {
+                        hm = longModuleBundle.halfModuleAxialHole;
+                    } else if(halfModuleName.contains("slot")) {
+                        hm = longModuleBundle.halfModuleAxialSlot;
+                    } else {
+                        throw new RuntimeException("This half-module name \"" + halfModuleName +  " \" is invalid. Need to contain hole or slot for this type.");
+                    }
+                } else if(halfModuleName.contains("stereo")) {
+                    if(halfModuleName.contains("hole")) {
+                        hm = longModuleBundle.halfModuleStereoHole;
+                    } else if(halfModuleName.contains("slot")) {
+                        hm = longModuleBundle.halfModuleStereoSlot;
+                    } else {
+                        throw new RuntimeException("This half-module name \"" + halfModuleName +  " \" is invalid. Need to contain hole or slot for this type.");
+                    }
+                } else {
+                    throw new RuntimeException("This half-module name \"" + halfModuleName +  " \" is invalid. Need to contain axial or stereo.");
+                }
+            }
+            else {
+                throw new NotImplementedException("This type of module bundle is not implemented!?");
+            }
+        } else {
+            throw new RuntimeException("Couldn't find module " + module.getName() + " and layer "  + module.getLayer() + " and half " + module.getHalf());
+        }
+        return hm;
+    }
+
+
+    
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#getMillepedeLayer(java.lang.String)
+     */
+    public int getMillepedeLayer(String name) {
+        
+        boolean isTopLayer = getHalfFromName(name).equals("top") ? true : false;
+    
+        // find layer
+        int layer = getLayerFromVolumeName(name);
+
+        // axial or stereo
+        boolean isAxial = isAxialFromName(name);
+
+        // use default layer numbering for L1-3    
+        if(layer<4) {
+            return  getOldLayerDefinition(isTopLayer, layer, isAxial);
+        }
+     
+        // hole or slot
+        boolean isHole = isHoleFromName(name);
+
+        return  getMillepedeLayer(isTopLayer, layer, isAxial, isHole);
+
+    }
+    
+    
+
+    /**
+     * Definition relating the sensors and layer number used in millepede for this detector.
+     * @param isTopLayer
+     * @param layer
+     * @param isAxial
+     * @param isHole
+     * @return
+     */
+    public int getMillepedeLayer(boolean isTopLayer, int layer, boolean isAxial, boolean isHole) {
+        int l = -1;
+        // use default layer numbering for L1-3
+        if(layer<4) {
+            l = getOldLayerDefinition(isTopLayer, layer, isAxial);
+        } else {
+            // Scheme: 
+            // For top modules axial layer is odd and stereo is even.
+            // Hole vs slot given by example below:
+            // e.g. top layer 4:
+            // axial -  hole: 7
+            // axial -  slot: 9
+            // stereo - hole: 8
+            // axial -  slot: 10
+            
+            l = 7 + (layer-4)*4;
+            int s = -1;
+            if(isTopLayer) {
+                s = 0;
+                if(isAxial) {
+                    s += 0;
+                } else {
+                    s += 1;
+                }
+                if(isHole) {
+                    s += 0;
+                } else {
+                    s += 2;
+                }
+            } else {
+                s = 0;
+                if(!isAxial) {
+                    s += 0;
+                } else {
+                    s += 1;
+                }
+                if(isHole) {
+                    s += 0;
+                } else {
+                    s += 2;
+                }
+            }
+            l = l + s;
+        }
+        
+        if(l<0) throw new RuntimeException("Error getting the millepede layer.");
+        
+        if(isDebug()) System.out.printf("%s: %s %d %s %s -> MP layer %d\n",getClass().getSimpleName(),isTopLayer?"top":"bottom", layer, isAxial?"axial":"stereo", isHole?"hole":"slot", l);
+
+        
+        return l;
+    }
+
+
+   
+
+}
+
+
+
+

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,202 @@
+/**
+ * 
+ */
+package org.lcsim.geometry.compact.converter;
+
+import java.util.ArrayList;
+
+import org.jdom.Element;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.Sensor;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.LongHalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.LongModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.PSVacuumChamber;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.SvtBox;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.SvtBoxBasePlate;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder.BaseModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder.HalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TestRunModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume;
+
+
+/**
+ * Class used by java converter to build java run time objects for the detector
+ * It encapsulates and adds the LCDD specific information to the generic @HPSTestRunTracker2014Builder. 
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class HPSTracker2014JavaBuilder extends HPSTestRunTracker2014JavaBuilder {
+
+	
+	
+	/**
+	 * Default constructor
+	 * @param node 
+	 */
+	public HPSTracker2014JavaBuilder(boolean debugFlag, Element node) {
+		super(debugFlag, node);
+	}
+	
+	
+	
+	
+	/**
+	 * Build the JAVA geometry objects from the geometry definition.
+	 * @param trackingVolume - the reference volume.
+	 */
+	public void build(ILogicalVolume trackingVolume) {
+
+		// build geometry
+        setBuilder(createGeometryDefinition(this._debug, node));
+		
+		if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
+
+		if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
+		
+		_builder.build();
+
+		if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
+
+		if(isDebug()) System.out.printf("%s: build the JAVA geometry objects\n", getClass().getSimpleName());
+		
+		// initialize the list to store a reference to each object
+		javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
+
+		// Go through the list of volumes to build that is created in the generic builder class
+		JavaSurveyVolume tracking = new JavaSurveyVolume(_builder.getSurveyVolume(TrackingVolume.class), trackingVolume);
+		add(tracking);
+		JavaSurveyVolume chamber = new JavaGhostSurveyVolume(_builder.getSurveyVolume(PSVacuumChamber.class), tracking);
+		add(chamber);
+		setBaseTrackerGeometry(new JavaSurveyVolume(_builder.getSurveyVolume(SvtBox.class), chamber,1));
+		add(getBaseTrackerGeometry());
+		JavaSurveyVolume svtBoxBasePlate = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SvtBoxBasePlate.class), getBaseTrackerGeometry());
+		add(svtBoxBasePlate);
+
+		
+		// build modules	
+		
+		if(isDebug()) System.out.printf("%s: build JAVA modules\n", getClass().getSimpleName());
+
+		// Loop over all modules created
+		for(BaseModuleBundle mod : _builder.modules) {
+			BaseModuleBundle m = mod;
+		    if(isDebug()) { 
+				System.out.printf("%s: build module %s (layer %d half %s)\n", getClass().getSimpleName(),m.module.getName(),m.getLayer(),m.getHalf());
+				m.print();
+			}
+
+			// Find the mother among the objects using its name, should probably have a better way...
+			String name_mother = m.getMother().getName();
+			JavaSurveyVolume mother = null;
+			for(JavaSurveyVolume g : javaSurveyVolumes) {
+				if(g.getName().equals(name_mother)) {
+					mother = g;
+					break;
+				}
+			}
+			// Check that it had a mother
+			if(mother==null) throw new RuntimeException("Cound't find mother to module " + m.module.getName());
+
+			if(isDebug()) System.out.printf("%s: found mother %s to module %s\n", getClass().getSimpleName(),mother.getName(),m.module.getName());
+			
+			// put the module in the list of objects that will be added to LCDD
+			addModule(m, mother);
+			
+			if(isDebug()) System.out.printf("%s: DONE build module %s\n", getClass().getSimpleName(), m.module.getName());
+
+			
+		}
+		
+		if(isDebug()) System.out.printf("%s: DONE build JAVA modules\n", getClass().getSimpleName());
+
+		
+		System.out.printf("%s: Built %d JAVA geometry objects\n", getClass().getSimpleName(),javaSurveyVolumes.size());
+		
+		if(isDebug()) {
+		    System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
+		    System.out.printf("%s: List of all the JAVA geometry objects built\n", this.getClass().getSimpleName());
+		    for(JavaSurveyVolume bg : javaSurveyVolumes) {
+		        System.out.printf("-------\n%s\n", bg.toString());
+		    }
+		}
+
+
+		// Set visualization features
+		//setVis();
+
+
+	}
+
+	/**
+	 * Rules for adding the JAVA module geometry.
+	 * @param bundle - module to be added
+	 * @param mother - mother JAVA geometry object
+	 */
+	private void addModule(BaseModuleBundle bundle, JavaSurveyVolume mother) {
+	    if(bundle instanceof TestRunModuleBundle) {
+	           addTestRunModule((TestRunModuleBundle) bundle, mother);
+	       } else if(bundle instanceof LongModuleBundle) {
+	           addLongModule((LongModuleBundle) bundle, mother);
+	       } else {
+	           throw new RuntimeException("The bundle is of unknown class type!");
+	       }
+	}
+	
+	/**
+     * Rules for adding the LCDD module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother LCDD geometry object
+     */
+    private void addLongModule(LongModuleBundle bundle, JavaSurveyVolume mother) {
+        // This could perhaps be fixed if there is a relation with daughters in geometry definition?
+        // create the module
+        JavaSurveyVolume lcddM = new JavaGhostSurveyVolume(bundle.module, mother);
+        add(lcddM);
+        if(bundle.halfModuleAxialHole!=null)  addLongHalfModule(bundle.halfModuleAxialHole,lcddM);
+        if(bundle.halfModuleAxialSlot!=null)  addLongHalfModule(bundle.halfModuleAxialSlot,lcddM);
+        //if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));     
+        if(bundle.halfModuleStereoHole!=null)  addLongHalfModule(bundle.halfModuleStereoHole,lcddM);
+        if(bundle.halfModuleStereoSlot!=null)  addLongHalfModule(bundle.halfModuleStereoSlot,lcddM);
+    }
+
+
+
+    private void addLongHalfModule(HalfModuleBundle bundle2, JavaSurveyVolume mother) {
+        LongHalfModuleBundle bundle = (LongHalfModuleBundle) bundle2;
+        // Create the half-module
+        // This is not a ghost element but reflects the module 
+        // concept in the old compact description
+        int oldCompactModuleId = 0;
+        JavaSurveyVolume lcddHM = new JavaSurveyVolume(bundle.halfModule, mother,oldCompactModuleId);
+        add(lcddHM);
+        
+        // ComponentNumber is taken from old geometry where it is simply a counter when adding the xml daughters to the TestRunModule.
+        // It is simply 0 for sensor and 1 for carbon fiber in the old geometry 
+        int componentNumber = ((Sensor)bundle.sensor).getId();
+
+        // create the sensor
+        JavaSurveyVolume lcddS = new JavaSurveyVolume(bundle.sensor, lcddHM, componentNumber);
+        add(lcddS);
+
+        // create the active sensor
+        JavaSurveyVolume lcddAS = new JavaSurveyVolume(bundle.activeSensor, lcddS, componentNumber);
+        add(lcddAS);
+        
+//      if(isDebug()) {
+//          System.out.printf("%s: added sensor %s \n",this.getClass().getSimpleName(), lcddS.getName());
+//          System.out.printf("%s: local coordinate system\n%s\n",this.getClass().getSimpleName(), bundle.sensor.getCoord().toString());
+//          dsd
+//      }
+        
+        
+    }
+	
+    @Override
+    public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node) {
+        return new HPSTracker2014GeometryDefinition(debug, node);
+    }
+	
+	
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014LCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014LCDDBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014LCDDBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,246 @@
+package org.lcsim.geometry.compact.converter;
+
+import org.jdom.Element;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TestRunHalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.LongHalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.LongModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.PSVacuumChamber;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.SvtBox;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.SvtBoxBasePlate;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL13Bottom;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL13BottomPlate;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL13Top;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL13TopPlate;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL46Bottom;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL46BottomPlate;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL46Top;
+import org.lcsim.geometry.compact.converter.HPSTracker2014GeometryDefinition.UChannelL46TopPlate;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder.BaseModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder.HalfModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TestRunModuleBundle;
+import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+public class HPSTracker2014LCDDBuilder extends HPSTestRunTracker2014LCDDBuilder {
+
+    public HPSTracker2014LCDDBuilder(boolean debugFlag, Element node,
+            LCDD lcdd, SensitiveDetector sens) {
+        
+        super(debugFlag, node, lcdd, sens);
+        
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTestRunTracker2014LCDDBuilder#setBuilder()
+     */
+    public void setBuilder() {
+        setBuilder(createGeometryDefinition(_debug, node));
+    }
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.HPSTestRunTracker2014LCDDBuilder#build(org.lcsim.geometry.compact.converter.lcdd.util.Volume)
+     */
+    public void build(Volume worldVolume) {
+
+        // set and build geometry
+        setBuilder();
+
+        if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
+
+        if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
+
+        _builder.build();
+
+        if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
+
+
+        if(isDebug()) System.out.printf("%s: build the LCDD geometry objects\n", getClass().getSimpleName());
+
+
+        LCDDSurveyVolume trackingGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(TrackingVolume.class), worldVolume);
+        add(trackingGeometry);
+
+//        baseSurveyVolume = new LCDDSurveyVolume(_builder.getSurveyVolume(PSVacuumChamber.class), lcdd, trackingGeometry);
+//        add(baseSurveyVolume); 
+        LCDDSurveyVolume vacuumChamberVolume = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(PSVacuumChamber.class), trackingGeometry);
+        add(vacuumChamberVolume); 
+
+//        LCDDSurveyVolume svtBox = new LCDDSurveyVolume(_builder.getSurveyVolume(SvtBox.class), lcdd, baseSurveyVolume);
+//        add(svtBox); 
+
+        LCDDSurveyVolume svtBox = new LCDDSurveyVolume(_builder.getSurveyVolume(SvtBox.class), lcdd, vacuumChamberVolume);
+        baseSurveyVolume = svtBox;
+        add(baseSurveyVolume); 
+
+       
+        LCDDSurveyVolume svtBoxBasePlate = new LCDDSurveyVolume(_builder.getSurveyVolume(SvtBoxBasePlate.class), lcdd, svtBox);
+        add(svtBoxBasePlate); 
+
+        
+        LCDDSurveyVolume uChannelL13Bottom = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(UChannelL13Bottom.class),  svtBox);
+        add(uChannelL13Bottom);
+        
+        LCDDSurveyVolume uChannelL13BottomPlate = new LCDDSurveyVolume(_builder.getSurveyVolume(UChannelL13BottomPlate.class), lcdd, svtBox);
+        add(uChannelL13BottomPlate);
+
+        LCDDSurveyVolume uChannelL13Top = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(UChannelL13Top.class), svtBox);
+        add(uChannelL13Top);
+        
+        LCDDSurveyVolume uChannelL13TopPlate = new LCDDSurveyVolume(_builder.getSurveyVolume(UChannelL13TopPlate.class), lcdd, svtBox);
+        add(uChannelL13TopPlate);
+        
+        LCDDSurveyVolume uChannelL46Bottom = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(UChannelL46Bottom.class), svtBox);
+        add(uChannelL46Bottom);        
+        
+        LCDDSurveyVolume uChannelL46BottomPlate = new LCDDSurveyVolume(_builder.getSurveyVolume(UChannelL46BottomPlate.class), lcdd, svtBox);
+        add(uChannelL46BottomPlate);        
+
+        LCDDSurveyVolume uChannelL46Top = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(UChannelL46Top.class), svtBox);
+        add(uChannelL46Top);        
+        
+        LCDDSurveyVolume uChannelL46TopPlate = new LCDDSurveyVolume(_builder.getSurveyVolume(UChannelL46TopPlate.class), lcdd, svtBox);
+        add(uChannelL46TopPlate);        
+
+        
+        // build modules    
+
+        if(isDebug()) System.out.printf("%s: build modules\n", getClass().getSimpleName());
+
+        // Loop over all modules created
+        for(BaseModuleBundle mod : _builder.modules) {
+            //SVTModuleBundle m = (SVTModuleBundle) mod;
+            BaseModuleBundle m = mod;
+            if(isDebug()) { 
+                System.out.printf("%s: module layer %d half %s\n", getClass().getSimpleName(),m.getLayer(),m.getHalf());
+                m.print();
+            }
+
+            // Find the mother among the LCDD objects using its name, should probably have a better way...
+            String name_mother = m.getMother().getName();
+            LCDDSurveyVolume mother = null;
+            for(LCDDSurveyVolume g : lcddSurveyVolumes) {
+                if(g.getName().equals(name_mother)) {
+                    mother = g;
+                    break;
+                }
+            }
+            // Check that it had a mother
+            if(mother==null) throw new RuntimeException("Cound't find mother to module layer " + m.getLayer() + " half "+ m.getHalf());
+
+            if(isDebug()) System.out.printf("%s: found mother %s for module layer %d half %s\n", getClass().getSimpleName(),mother.getName(),m.getLayer(),m.getHalf());
+
+            // add the module to the list of objects that will be added to LCDD
+            addModule(m, mother);
+
+        }
+
+
+       
+        
+        System.out.printf("%s: Built %d LCDD geometry objects\n", getClass().getSimpleName(), lcddSurveyVolumes.size());
+        
+        if(isDebug()) {
+            System.out.printf("%s: List of all %d LCDD geometry objects built\n", this.getClass().getSimpleName(), lcddSurveyVolumes.size());
+            for(SurveyVolumeImpl bg : lcddSurveyVolumes) {
+                System.out.printf("-------\n%s\n", bg.toString());
+            }
+        }
+
+
+
+        // Set visualization features
+        setVisualization();
+
+    }    
+    
+    /**
+     * Rules for adding the LCDD module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother LCDD geometry object
+     */
+    private void addModule(BaseModuleBundle bundle, LCDDSurveyVolume mother) {
+       if(bundle instanceof TestRunModuleBundle) {
+           addTestRunModule((TestRunModuleBundle) bundle, mother);
+       } else if(bundle instanceof LongModuleBundle) {
+           addLongModule((LongModuleBundle) bundle, mother);
+       } else {
+           throw new RuntimeException("The bundle is of unknown class type!");
+       }
+    }
+  
+    /**
+     * Rules for adding the LCDD module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother LCDD geometry object
+     */
+    protected void addLongModule(LongModuleBundle bundle, LCDDSurveyVolume mother) {
+        LCDDSurveyVolume lcddM = new LCDDGhostSurveyVolume(bundle.module, mother);
+        //LCDDSurveyVolume lcddM = new LCDDSurveyVolume(bundle.module, lcdd, mother);
+        add(lcddM);
+        if(bundle.halfModuleAxialHole!=null)  addLongHalfModule(bundle.halfModuleAxialHole,lcddM);
+        if(bundle.halfModuleAxialSlot!=null)  addLongHalfModule(bundle.halfModuleAxialSlot,lcddM);
+        if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));     
+        if(bundle.halfModuleStereoHole!=null)  addLongHalfModule(bundle.halfModuleStereoHole,lcddM);
+        if(bundle.halfModuleStereoSlot!=null)  addLongHalfModule(bundle.halfModuleStereoSlot,lcddM);
+    }
+    
+    
+    
+    /**
+     * Rules for adding the LCDD module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother LCDD geometry object
+     */
+    protected void addTestRunModule(TestRunModuleBundle bundle, LCDDSurveyVolume mother) {
+        // This could perhaps be fixed if there is a relation with daughters in geometry definition?
+        // create the module
+        LCDDSurveyVolume lcddM = new LCDDGhostSurveyVolume(bundle.module, mother);
+        //SurveyVolume(bundle.module, lcdd, mother);
+        add(lcddM);
+        if(bundle.halfModuleAxial!=null)  addTestRunHalfModule(bundle.halfModuleAxial,lcddM);
+        if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));     
+        if(bundle.halfModuleStereo!=null) addTestRunHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
+    }
+
+    
+    
+    /**
+     * Rules for adding the LCDD half module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother LCDD geometry object
+     */
+    private void addLongHalfModule(HalfModuleBundle bundle2, LCDDSurveyVolume mother) {
+        LongHalfModuleBundle bundle = (LongHalfModuleBundle) bundle2;
+        
+        // create the half-module
+        LCDDSurveyVolume lcddHM = new LCDDSurveyVolume(bundle.halfModule, lcdd, mother);
+        add(lcddHM);
+        // create the sensor
+        LCDDSurveyVolume lcddS = new LCDDSurveyVolume(bundle.sensor, lcdd, lcddHM);
+        add(lcddS);
+        // create the active sensor
+        LCDDSurveyVolume lcddAS = new LCDDSurveyVolume(bundle.activeSensor, lcdd, lcddS);
+        add(lcddAS);
+        // create the lamination
+        LCDDSurveyVolume lcddL = new LCDDSurveyVolume(bundle.lamination, lcdd, lcddHM);
+        add(lcddL);
+        /*
+        // create the carbon fiber frame
+        LCDDSurveyVolume lcddCF = new LCDDSurveyVolume(bundle.carbonFiber, lcdd, lcddHM);
+        add(lcddCF);
+        // create the hybrid frame
+        LCDDSurveyVolume lcddH = new LCDDSurveyVolume(bundle.hybrid, lcdd, lcddHM);
+        add(lcddH);
+*/
+    }   
+    
+    @Override
+    public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug,
+            Element node) {
+        return new HPSTracker2014GeometryDefinition(_debug, node);
+    }
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,105 @@
+package org.lcsim.geometry.compact.converter;
+
+import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+import org.jdom.Element;
+
+/**
+ * 
+ * Updated geometry information for the HPS tracker 2014
+
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class HPSTracker2014v1GeometryDefinition extends HPSTracker2014GeometryDefinition {
+
+    public HPSTracker2014v1GeometryDefinition(boolean debug, Element node) {
+        super(debug, node);
+    }
+
+    public static class LongAxialSlotHalfModule extends HPSTracker2014GeometryDefinition.LongAxialSlotHalfModuleBase  {
+
+        public LongAxialSlotHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer,
+                String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+       
+        @Override
+        protected void applyGenericCoordinateSystemCorrections() {
+            
+            super.applyGenericCoordinateSystemCorrections();
+            
+            // apply 180 degree rotation around w to get hybrid on the correct side
+            
+            if(debug) {
+                System.out.printf("%s: Coord before corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+                System.out.printf("%s: box center before corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            }
+            getCoord().rotateApache(getSlotRotation());
+
+            if(debug) {
+                System.out.printf("%s: Coord after corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+                System.out.printf("%s: box center after corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            }
+        }
+    }
+    
+    public static class LongStereoSlotHalfModule extends HPSTracker2014GeometryDefinition.LongStereoSlotHalfModuleBase {
+
+        public LongStereoSlotHalfModule(String name, SurveyVolume mother,
+                AlignmentCorrection alignmentCorrection, int layer, String half) {
+            super(name, mother, alignmentCorrection, layer, half);
+            init();
+        }
+        
+        @Override
+        protected void applyGenericCoordinateSystemCorrections() {
+            
+            super.applyGenericCoordinateSystemCorrections();
+
+            if(debug) {
+                System.out.printf("%s: v1 LongStereoSlotHalfModule Generic Corrections\n", getClass().getSimpleName());
+                System.out.printf("%s: Coord before corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+                System.out.printf("%s: box center before corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            }
+            
+            getCoord().rotateApache(getSlotRotation());
+            
+            if(debug) {
+                System.out.printf("%s: Coord after corrections\n%s\n", getClass().getSimpleName(),getCoord().toString());
+                System.out.printf("%s: box center after corrections\n%s\n", getClass().getSimpleName(),getBoxDim().toString());
+            }
+        }
+
+        
+    }
+
+    @Override
+    protected LongHalfModule createLongAxialSlotHalfModule(String name, SurveyVolume mother, 
+                                                            AlignmentCorrection alignmentCorrection, 
+                                                            int layer, String half) {
+        return new LongAxialSlotHalfModule(name, mother, alignmentCorrection, layer, half);
+    }
+    
+    @Override
+    protected LongHalfModule createLongStereoSlotHalfModule(String name,
+            SurveyVolume mother, AlignmentCorrection alignmentCorrection,
+            int layer, String half) {
+        
+        return new LongStereoSlotHalfModule(name, mother, alignmentCorrection, layer, half);
+    }
+
+    
+    /**
+     * PI rotation around generic z-axis
+     * @return
+     */
+    private static Rotation getSlotRotation() {
+        return new Rotation(new Vector3D(0,0,1),Math.PI);
+    }
+    
+
+    
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1JavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1JavaBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1JavaBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,17 @@
+package org.lcsim.geometry.compact.converter;
+
+import org.jdom.Element;
+
+public class HPSTracker2014v1JavaBuilder extends HPSTracker2014JavaBuilder {
+
+    public HPSTracker2014v1JavaBuilder(boolean debugFlag, Element node) {
+        super(debugFlag, node);
+    }
+
+    @Override
+    public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node) {
+        return new HPSTracker2014v1GeometryDefinition(debug, node);
+    }
+    
+    
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1LCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1LCDDBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1LCDDBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,23 @@
+package org.lcsim.geometry.compact.converter;
+
+import org.jdom.Element;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+
+public class HPSTracker2014v1LCDDBuilder extends HPSTracker2014LCDDBuilder {
+
+    public HPSTracker2014v1LCDDBuilder(boolean debugFlag, Element node,
+            LCDD lcdd, SensitiveDetector sens) {
+        super(debugFlag, node, lcdd, sens);
+    }
+
+    public void setBuilder() {
+        setBuilder(createGeometryDefinition(_debug, node));
+    }
+    
+    @Override
+    public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug,
+        Element node) {
+        return new HPSTracker2014v1GeometryDefinition(_debug, node);
+    }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,556 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BaseModule;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule;
+
+public abstract class HPSTrackerBuilder {
+
+	private boolean debug = true;
+	public List<BassModuleBundle> modules = new ArrayList<BassModuleBundle>();
+	protected List<SurveyVolume> surveyVolumes = new ArrayList<SurveyVolume>();
+    protected Element node;
+    protected List<MilleParameter> milleparameters = new ArrayList<MilleParameter>();
+	
+	
+
+	/**
+	 * Default constructor to create a geometry.
+	 * @param debug output flag
+	 * @param node to have access to compact xml
+	 */
+	public HPSTrackerBuilder(boolean debug, Element node) {
+        this.debug = debug;
+        this.node = node;
+        initAlignmentParameters();
+    }
+	
+	/**
+	 * Extract alignment constants from xml description
+	 */
+	private void initAlignmentParameters() {
+       
+        if(debug) System.out.printf("%s: initAlignmentParameters from %s\n",this.getClass().getSimpleName(),node.getAttributeValue("name"));
+        
+	 // Get alignment parameters.
+        int detId=-1;
+        try {
+            detId = node.getAttribute("id").getIntValue();
+        } catch (DataConversionException e) {
+            e.printStackTrace();
+        }
+        String detName = node.getAttributeValue("name");
+        String detType = node.getAttributeValue("type");
+        
+        Element constantsElement = node.getChild("millepede_constants");
+        if(constantsElement==null) {
+            throw new RuntimeException("no millepede constants found in compact file");
+        } 
+        
+        if(debug) System.out.printf("%s: %d alignment corrections for detId=%d detName=%s detType=%s\n",this.getClass().getSimpleName(),constantsElement.getChildren("millepede_constant").size(),detId,detName,detType);
+        
+        int id = -99999;
+        double value=-99999;
+        for(Iterator iConstant = constantsElement.getChildren("millepede_constant").iterator(); iConstant.hasNext();) {
+            Element constantElement = (Element)iConstant.next();
+            try {
+                id = constantElement.getAttribute("name").getIntValue();
+                value = constantElement.getAttribute("value").getDoubleValue();
+            } catch (DataConversionException e) {
+                e.printStackTrace();
+            }
+            //System.out.printf("%s: constant %d value %f\n",this.getClass().getSimpleName(),id,value);
+            
+            MilleParameter p = new MilleParameter(id,value,0.0);
+            //System.out.printf("%s: Milleparameter: %s\n", this.getClass().getSimpleName(),p.toString());
+            milleparameters.add(p);
+            
+        }
+        
+        if(debug) {
+            System.out.printf("%s: Initialized %d alignment parameters:\n",this.getClass().getSimpleName(),milleparameters.size());
+            for(MilleParameter p: milleparameters) {
+                System.out.printf("%s: %s \n",this.getClass().getSimpleName(),p.toString());                
+            }
+        }
+	    
+    }
+	
+	
+	/**
+	 * Extract @AlignmentCorrection for a half-module
+	 * @param isTopLayer - top or bottom layer
+	 * @param layer - to identify which sensor it is.
+	 * @return the alignment correction for this half-module
+	 */
+	protected AlignmentCorrection getHalfModuleAlignmentCorrection(boolean isTopLayer, int layer) {
+        int rFound = 0;
+        int tFound = 0;
+        double r[] = {0,0,0};
+        double t[] = {0,0,0};
+        for(MilleParameter p_loop: milleparameters) {
+            boolean paramIsTop = p_loop.getHalf()==1?true:false;
+            int paramLayer = p_loop.getSensor();
+            if(paramIsTop==isTopLayer && paramLayer==layer) {
+                if(p_loop.getType()==1) {
+                    t[p_loop.getDim()-1] = p_loop.getValue();
+                    tFound++;
+                } else if(p_loop.getType()==2) {
+                    r[p_loop.getDim()-1] = p_loop.getValue();
+                    rFound++;
+                } 
+            }
+        }
+        if(tFound!=3 || rFound!=3) {
+            throw new RuntimeException("Problem finding translation alignment parameters (found t " + tFound + " r " + rFound + ") for " + (isTopLayer?"top":"bottom") + " layer " + layer);
+        }
+        AlignmentCorrection c = new AlignmentCorrection();
+        c.setTranslation(new BasicHep3Vector(t));
+        c.setRotation(r[0],r[1],r[2]);
+        return c;
+    }
+	
+	/**
+     * Extract @AlignmentCorrection for the support
+     * @param isTopLayer - top or bottom layer
+     * @return the alignment correction
+     */
+    protected AlignmentCorrection getSupportAlignmentCorrection(boolean isTopLayer) {
+        double r[] = {0,0,0};
+        double t[] = {0,0,0};
+        for(MilleParameter p_loop: milleparameters) {
+            boolean paramIsTop = p_loop.getHalf()==1?true:false;
+            if(paramIsTop==isTopLayer && p_loop.getType()==3) {
+                //xcheck
+                if(p_loop.getSensor()!=0) throw new RuntimeException("sensor name is not zero for support plate param! " + p_loop.getSensor());
+                // get the correction
+                r[p_loop.getDim()-1] = p_loop.getValue();
+            }
+        }
+        AlignmentCorrection c = new AlignmentCorrection();
+        c.setTranslation(new BasicHep3Vector(t));
+        c.setRotation(r[0],r[1],r[2]);
+        return c;
+    }
+	
+	
+
+    /**
+	 * Build the local geometry
+	 * 
+	 */
+	public abstract void build();
+	
+	
+	
+    
+    
+    /**
+     * Bundle volumes into a module. 
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public abstract static class BaseModuleBundle {
+        public SurveyVolume module = null;
+        public BaseModuleBundle(BaseModule m) {
+            module = m;
+        }
+        public int getLayer() {
+            if(module==null) throw new RuntimeException("Need to add module to bundle first!");
+            return HPSTrackerBuilder.getLayerFromVolumeName(module.getName());
+        }
+        public String getHalf() {
+            if(module==null) throw new RuntimeException("Need to add module to bundle first!");
+            return HPSTrackerBuilder.getHalfFromName(module.getName()); 
+        }
+        public SurveyVolume getMother() {
+            if(module==null) throw new RuntimeException("Need to add module to bundle first!");
+            return module.getMother();
+        }
+        public abstract void print();
+    }
+    
+    /**
+     * Bundle volumes into a half-module. 
+     * TODO If the geometry definition has access to daughter information I could avoid this? 
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static abstract class HalfModuleBundle {
+        public SurveyVolume halfModule = null;
+        public SurveyVolume lamination = null;
+        public SurveyVolume sensor = null;
+        public SurveyVolume activeSensor = null;
+        public HalfModuleBundle(SurveyVolume hm) {
+            halfModule = hm;
+        }
+        public HalfModuleBundle() {
+        }
+        public void print() {
+            if(halfModule!=null) System.out.printf("%s: %s\n", this.getClass().getSimpleName(),halfModule.toString());
+            if(activeSensor!=null) System.out.printf("%s: %s\n", this.getClass().getSimpleName(),activeSensor.toString());
+        }
+    }
+	
+	
+	public static String getHalfFromName(String name) {
+		String half = "";
+		if(name.contains("bottom")) {
+			half = "bottom";
+		}
+		if(name.contains("top")) {
+			// check that both sides are not found
+			if(half.equals("bottom")) {
+				throw new RuntimeException("found both halfs from name  " + name);
+			} else {
+				half = "top";
+			}
+		}
+		// check for other signatures
+		if( half.isEmpty()) {
+			// 6 layers is arbitrary here
+			for(int layer=1;layer<=6;++layer) {
+				if(name.contains(String.format("L%db", layer))) {
+					half = "bottom";
+					break;
+				} 
+				if(name.contains(String.format("L%dt", layer))) {
+					if(half.equals("bottom")) {
+						throw new RuntimeException("found both halfs from name  " + name);
+					}
+					half = "top";
+					break;
+				}
+			}
+		}		
+		if( half.isEmpty()) {
+			System.out.println("found no half from " + name);
+			throw new RuntimeException("found no half from " + name);
+		} else {
+			return half;
+	
+		}
+	}
+
+	public static int getLayerFromVolumeName(String name) {
+		int layer = -1;
+		for(int i=1; i<= 6; ++i) {
+			if(name.contains(String.format("module_L%d", i))) {
+				layer = i;
+			}
+		}
+		if( layer == -1) {
+			System.out.println("cannot find layer from " + name);
+			System.exit(1);
+		}
+		return layer;
+	}
+
+	public static boolean isBase(String name) {
+		if(name.endsWith("base")) {
+			return true;
+		}
+		return false;
+	}
+
+	   public static boolean isHalfModule(String name) {
+	       if(name.endsWith("halfmodule_axial") || 
+	               name.endsWith("halfmodule_axial_slot") ||
+	               name.endsWith("halfmodule_axial_hole") ||
+	               name.endsWith("halfmodule_stereo") ||
+	               name.endsWith("halfmodule_stereo_slot") ||
+	               name.endsWith("halfmodule_stereo_hole"
+	                       )) {
+	           return true;
+	        }
+	        return false;
+	    }
+
+	public static boolean isSensor(String name) {
+		if(name.endsWith("sensor")) {
+			return true;
+		}
+		return false;
+	}
+
+	public static boolean isActiveSensor(String name) {
+		if(name.endsWith("sensor_active")) {
+			return true;
+		}
+		return false;
+	}
+
+	
+    
+    protected boolean isDebug() {
+		return debug;
+	}
+
+	protected void setDebug(boolean debug) {
+		this.debug = debug;
+	}
+
+	/**
+	 * Find geometry object by type.
+	 * @param c - class type to be found
+	 * @return the found type.
+	 */
+	public <T> T getSurveyVolume(Class<T> c) {
+		//if(isDebug()) System.out.printf("%s: get Item %s\n", this.getClass().getSimpleName(),c.getName());
+		
+		for(SurveyVolume item : surveyVolumes) {
+			//if(isDebug()) System.out.printf("%s: item %s\n", getClass().getSimpleName(),item.getClass().getName());
+			if(c.isInstance(item)) {
+				return (T)item;
+			}
+		}
+		throw new RuntimeException("Coulnd't find instance of " + c.getSimpleName() + " among the " + surveyVolumes.size() + " tracker items!");
+	}
+
+	protected List<BassModuleBundle> getModules() {
+		return modules;
+	}
+
+	/**
+	 * Find module among the existing bundles.
+	 * @param layer - layer id
+	 * @param half - top or bottom half
+	 * @return module or null if not found
+	 */
+	protected BaseModuleBundle getModuleBundle(int layer, String half) {
+		for(BaseModuleBundle m : modules) {
+			if(m.getLayer()==layer && m.getHalf().equals(half)) {
+				return m;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Find module among the existing bundles.
+	 * @param module - to find
+	 * @return bundle
+	 */
+	protected BaseModuleBundle getModuleBundle(BaseModule module) {
+		return getModuleBundle(module.getLayer(), module.getHalf());
+	}
+
+	
+	/**
+	 * Add module to list.
+	 * @param bundle - module to add.
+	 */
+	protected void addModuleBundle(BaseModuleBundle bundle) {
+		BaseModuleBundle b = getModuleBundle(bundle.getLayer(), bundle.getHalf());
+		if(b==null) {
+			modules.add(bundle);
+		} else {
+			throw new RuntimeException("There is already a module bundle with layer " + bundle.getLayer() + " and half " + bundle.getHalf());
+		}
+	}
+
+	/**
+	 * Checks if the orientation of the sensor is axial.
+	 * Uses the moduleId definition from the "old" geometry for 
+	 * consistency.
+	 * 
+	 *  @return true if it is, false if it is a stereo sensor
+	 */
+	public static boolean isAxial(boolean isTopLayer, int layer) {
+	    if (isTopLayer && layer % 2 == 1) {
+	        return true;
+	    } else if (!isTopLayer && layer % 2 == 0) {
+	        return true;
+	    }
+	    return false;
+	}
+
+	
+
+	/**
+	 * Find transform to parent volume coordinate system.
+	 * @param t - current transform to mother
+	 * @param mother - geometry object from current transform 
+	 * @param targetMotherName - parent volume defining new vector coordinate system
+	 * @return transform.
+	 */
+	public static Transform3D getTransform(Transform3D t, SurveyVolume mother, String targetMotherName) {
+		int debug=0;
+		if(debug>0) System.out.printf("getTransform mother %s target %s with current transform\n%s\n", mother.getName(), targetMotherName,t.toString());
+		if(mother==null) throw new RuntimeException("Trying to get mother transform but there is no mother?!");
+		if(mother.getName().equals(targetMotherName)) {
+			if(debug>0) System.out.printf("found the transform\n");
+			return t;
+		} else {
+			if(debug>0) System.out.printf("add mother transform\n%s\n",mother.getCoord().getTransformation().toString());
+			Transform3D trans = Transform3D.multiply(mother.getCoord().getTransformation(), t);
+			if(debug>0) System.out.printf("resulting transform\n%s\ncontinue searching\n",trans.toString());
+			return getTransform(trans, mother.getMother(), targetMotherName);
+		}
+		
+	}
+
+	/**
+	 * Find the vector in a parent volume coordinate system.
+	 * @param vec - vector to transform
+	 * @param geometry - geometry where vector is defined.
+	 * @param targetMotherName - parent volume defining new vector coordinate system
+	 * @return transformed vector.
+	 */
+	public static Hep3Vector transformToMotherCoord(Hep3Vector vec, SurveyVolume geometry, String targetMotherName) {
+	    int debug =0;
+	    SurveyVolume mother = geometry.getMother();
+	    if(debug>0) System.out.printf("transformToMotherCoord vec %s geomtry %s  mother %s target %s\n", vec.toString(), geometry.getName(), geometry.getMother().getName(), targetMotherName);
+
+	    Transform3D t = getTransform(geometry.getCoord().getTransformation(), mother, targetMotherName);
+
+	    Hep3Vector vec_t = t.transformed(vec);
+
+	    if(debug>0) {
+	        System.out.printf("transformToMotherCoord apply transform \n%s\n",t.toString());
+	        System.out.printf("transformToMotherCoord vec_t%s\n",vec_t.toString());
+	    }
+
+
+	    return vec_t;
+	}
+
+	/**
+	 * Find the vector in the tracking volume coordinate system.
+	 * @param vec - vector to transform
+	 * @param geometry - geometry where vector is defined.
+	 * @return transformed vector.
+	 */
+	public static Hep3Vector transformToTracking(Hep3Vector vec, SurveyVolume geometry) {
+		return transformToParent(vec, geometry, "trackingVolume");
+	}
+
+	/**
+     * Find the vector in a mother volume coordinate system.
+     * @param vec - vector to transform
+     * @param geometry - geometry where vector is defined.
+     * @return transformed vector.
+     */
+    public static Hep3Vector transformToParent(Hep3Vector vec, SurveyVolume geometry, String targetName) {
+        int debug = 0;
+        if(debug>0) System.out.printf("\ntransformToParent: vec %s in local coordiantes of %s\n", vec.toString(), geometry.getName());
+        if(geometry.getMother()==null) {
+            if(debug>0) System.out.printf("\ntransformToParent: no mother, return null\n", vec.toString(), geometry.getName());
+            return null;    
+        }
+        if(debug>0) System.out.printf("\ntransformToParent: vec %s in local coordiantes of %s with mother %s\n", vec.toString(), geometry.getName(), geometry.getMother().getName().toString());
+        SurveyCoordinateSystem coord = geometry.getCoord();
+        if(coord==null) {
+            throw new RuntimeException("transformToParent: no coordinate system found for %s, return null " + geometry.getName());
+        }
+        Hep3Vector vec_mother_coord = coord.getTransformation().transformed(vec);
+        if(debug>0) System.out.printf("vec_mother_coord %s\n",vec_mother_coord.toString());
+        if(geometry.getMother().getName().equals(targetName)) {
+            if(debug>0) System.out.printf("reached target \"%s\"tracking volume. Return \n", targetName);
+            return vec_mother_coord;
+        } else {
+            if(debug>0) System.out.printf("continue searching.\n");
+        }
+        return transformToParent(vec_mother_coord, geometry.getMother(), targetName);
+    }
+
+    
+	
+	
+	
+	
+	/**
+     * Get axial or stereo key name from string
+     * @param name
+     * @return axial or not boolean
+     */
+    public static boolean isAxialFromName(String name) {
+        boolean isAxial;
+        if(name.contains("axial")) isAxial=true;
+        else if(name.contains("stereo")) isAxial=false;
+        else throw new RuntimeException("no axial or stereo name found from " + name);
+        return isAxial;
+    }
+	
+    /**
+     * Get hole or slot key name from string
+     * @param name.
+     * @return hole or not boolean
+     */
+    public static boolean isHoleFromName(String name) {
+        boolean isHole;
+        if(name.contains("hole")) isHole=true;
+        else if(name.contains("slot")) isHole=false;
+        else throw new RuntimeException("no hole or slot keys found in name " + name);
+        return isHole;
+    }
+    
+	
+	/**
+	 * Extract old definition of Test Run sensor number.
+	 * @param isTopLayer - top or bottom layer
+	 * @param l - layer 
+	 * @param isAxial - axial or stereo sensor
+	 * @return
+	 */
+     public int getOldGeomDefLayerFromVolumeName(String name) {
+        
+        String half = getHalfFromName(name);
+        int l = getLayerFromVolumeName(name);
+        boolean isTopLayer = false;
+        if(half=="top") isTopLayer=true;
+        else if(half=="bottom") isTopLayer = false;
+        else throw new RuntimeException("no half found from " + name);
+        boolean isAxial = isAxialFromName(name);
+        return getOldLayerDefinition(isTopLayer, l, isAxial);
+    }
+     
+     
+     /**
+      * Get the layer number consistent with the old geometry definition. 
+      * @param module name that contains layer and half information.
+      * @return the layer.
+      */
+    public int getOldLayerDefinition(boolean isTopLayer, int l, boolean isAxial) {
+        int layer=-1;
+        if(isAxial) {
+            if(isTopLayer) {
+                layer = 2*l-1;
+            }
+            else {
+                layer = 2*l;
+            }
+        } else {
+            if(isTopLayer) {
+                layer = 2*l;
+            } else {
+                layer = 2*l-1;
+            }
+        }
+        return layer;
+    }
+
+    /**
+     * Definition of the millepede layer number.
+     * @param name of half-module or sensor
+     * @return millepede layer number.
+     */
+    abstract public int getMillepedeLayer(String name);
+    
+    
+
+	
+
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,311 @@
+/**
+ * 
+ */
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+
+import org.jdom.Element;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.ActiveSensor;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BaseModule;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.CarbonFiber;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.HalfModuleLamination;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.Hybrid;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.Sensor;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.TestRunHalfModuleBundle;
+
+/**
+ * 
+ * Common geometry information for the HPS trackers
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+abstract public class HPSTrackerGeometryDefinition extends HPSTrackerBuilder {
+
+
+
+    //steering
+    public boolean doAxial = true;
+    public boolean doStereo = true;
+    public boolean doColdBlock = false;
+    public boolean doBottom = true;
+    public boolean doTop = true;
+    public int layerBitMask =  0x1;    //0x1;//
+
+
+    //General
+    static final double inch = 25.4; //mm
+    protected static final boolean useSiStripsConvention = true;
+    protected static final boolean use30mradRotation = true;
+    protected static final boolean useFakeHalfModuleAxialPos = false;
+
+    // Global position references	
+    protected static final double target_pos_wrt_base_plate_x = 162.3; //from Marco's 3D model
+    protected static final double target_pos_wrt_base_plate_y = 80.55; //from Tim's sketchup //68.75; //from Marco's 3D model
+    protected static final double target_pos_wrt_base_plate_z = 926.59; //from Marco's 3D model
+    protected static final double PS_vac_box_inner_height = 7.0*inch;
+    protected static final double PS_vac_box_inner_width = 16.38*inch;
+    // Inner length of the vacuum box is defined here until the horizontal fan-out. 
+    // It's a little random as I'm actually not creating a volume for it here and thus
+    // it just needs to capture the SVT box.
+    protected static final double PS_vac_box_inner_length = 53.4*inch; 
+
+
+
+    public HPSTrackerGeometryDefinition(boolean debug, Element node) {
+        super(debug, node);
+    }
+
+    
+    protected abstract HalfModuleBundle getHalfModuleBundle(BaseModule module, String halfModuleName);
+    protected abstract void makeModuleBundle(int layer, String half);
+    protected abstract TestRunHalfModule createTestRunHalfModuleAxial(String volName, BaseModule mother, AlignmentCorrection alignmentCorrection, int layer, String half);
+    protected abstract TestRunHalfModule createTestRunHalfModuleStereo(String volName, BaseModule mother, AlignmentCorrection alignmentCorrection, int layer, String half);
+
+    
+    
+    
+    protected boolean doLayer(int layer) {
+        int a = (1<<(layer-1)) & layerBitMask;
+        return a!=0?true:false;
+    }
+
+    
+    
+
+    /**
+     * Create the half-module.
+     * @param side - stereo or axial
+     * @param mother to the half-module
+     */
+    protected void makeHalfModule(String side, BaseModule mother) {
+        
+        String moduleName = mother.getName();
+    
+        if(isDebug()) System.out.printf("%s: makeHalfModule for %s %s \n", this.getClass().getSimpleName(), moduleName, side);
+    
+        String volName = moduleName + "_halfmodule_" + side;
+    
+        // top or bottom?
+        String half = mother.getHalf();
+        boolean isTopLayer = !mother.isBottom();
+    
+        // find layer
+        int layer = mother.getLayer();
+    
+        // axial or stereo
+        boolean isAxial = isAxialFromName(volName);
+    
+        // find layer according to old definition
+        int millepedeLayer = getMillepedeLayer(volName);
+        
+        //if(isDebug()) System.out.printf("%s: half? %s layer %d oldlayer %d axial? %s\n", 
+        //        this.getClass().getSimpleName(), isTopLayer?"top":"bottom", layer,oldLayer,isAxial?"yes":"no");
+    
+        // find alignment correction to this volume
+        AlignmentCorrection alignmentCorrection =  getHalfModuleAlignmentCorrection(isTopLayer, millepedeLayer);
+        
+        
+        // find the module bundle that it will be added to
+        //TestRunModuleBundle bundle  = (TestRunModuleBundle)getModuleBundle(mother);
+        //TestRunHalfModuleBundle halfModuleBundle;
+        TestRunModuleBundle bundle  = (TestRunModuleBundle) getModuleBundle(mother);
+        if(bundle==null) {
+            throw new RuntimeException("Couldn't find bundle for " + volName + " from mother " + mother.getName());
+        }
+        
+        // Build the half-module bundle and add the half-module to it
+        HalfModuleBundle halfModuleBundle;
+        TestRunHalfModule halfModule;
+        if(isAxial) {
+            halfModule = createTestRunHalfModuleAxial(volName, mother, alignmentCorrection, layer, half);
+            halfModuleBundle = new TestRunHalfModuleBundle(halfModule);
+            bundle.halfModuleAxial = halfModuleBundle;
+        } else {
+            halfModule = createTestRunHalfModuleStereo(volName, mother, alignmentCorrection, layer, half);
+            halfModuleBundle = new TestRunHalfModuleBundle(halfModule);
+            bundle.halfModuleStereo = halfModuleBundle;
+        } 
+    
+    
+        // create the half module components 
+    
+        makeHalfModuleComponentSensor(halfModule);
+    
+        makeHalfModuleComponentKapton(halfModule);
+    
+        makeHalfModuleComponentCF(halfModule);
+    
+        makeHalfModuleComponentHybrid(halfModule);
+    
+    
+    
+    
+    }
+
+
+    
+
+    void makeHalfModuleComponentHybrid(TestRunHalfModule mother) {
+    
+        if(isDebug()) System.out.printf("%s: makeHalfModuleComponentHybrid for %s \n", this.getClass().getSimpleName(), mother.getName());
+    
+        String volName = mother.getName() + "_hybrid";
+    
+        // Build the half-module
+    
+        //  id is hard coded
+        int component_number = 3;
+    
+        Hybrid hybrid = new Hybrid(volName,mother,component_number);
+        hybrid.setMaterial("G10");
+    
+        TestRunHalfModuleBundle hm = (TestRunHalfModuleBundle) getHalfModuleBundle((BaseModule) mother.getMother(), mother.getName());
+        hm.hybrid = hybrid;
+    
+        if(isDebug()) System.out.printf("%s: added hybrid to half-module with name %s \n", this.getClass().getSimpleName(), hm.halfModule.getName());
+    
+    
+    }
+
+    void makeHalfModuleComponentCF(TestRunHalfModule mother) {
+    
+        if(isDebug()) System.out.printf("%s: makeHalfModuleComponentCF for %s \n", this.getClass().getSimpleName(), mother.getName());
+    
+    
+        String volName = mother.getName() + "_cf";
+    
+        // Build the half-module
+    
+        //  id is hard coded
+        int component_number = 1;
+    
+        CarbonFiber cf = new CarbonFiber(volName,mother,component_number);
+        cf.setMaterial("CarbonFiber");
+    
+        TestRunHalfModuleBundle hm = (TestRunHalfModuleBundle) getHalfModuleBundle((BaseModule) mother.getMother(), mother.getName());
+        hm.carbonFiber = cf;
+    
+    }
+
+    void makeHalfModuleComponentKapton(BaseModule mother) {
+    
+        if(isDebug()) System.out.printf("%s: makeHalfModuleComponentKapton for %s \n", this.getClass().getSimpleName(), mother.getName());
+    
+        String volName = mother.getName() + "_lamination";
+    
+        // Build the half-module
+    
+        //  id is hard coded
+        int component_number = 2;
+    
+        HalfModuleLamination lamination = new HalfModuleLamination(volName,mother,component_number);
+        lamination.setMaterial("Kapton");
+    
+    
+        HalfModuleBundle hm = getHalfModuleBundle((BaseModule) mother.getMother(), mother.getName());
+        hm.lamination = lamination;
+    
+    }
+
+   
+    
+    protected void makeHalfModuleComponentSensor(BaseModule mother) {
+    
+        if(isDebug()) System.out.printf("%s: makeHalfModuleComponentSensor for %s \n", this.getClass().getSimpleName(), mother.getName());
+    
+        String volName = mother.getName() + "_sensor";
+    
+        // sensor id is hard coded in old geometry to be zero by counting over the components of the module
+        int component_number = 0;
+    
+        //  
+        Sensor sensor = new Sensor(volName, mother, null, component_number);
+        sensor.setMaterial("Silicon");
+    
+        HalfModuleBundle hm = getHalfModuleBundle((BaseModule)mother.getMother(), mother.getName());
+        hm.sensor = sensor;
+    
+    
+        makeHalfModuleComponentActiveSensor(sensor);
+    
+    
+    }
+    
+    private void makeHalfModuleComponentActiveSensor(Sensor mother) {
+        
+        if(isDebug()) System.out.printf("%s: makeHalfModuleComponentActiveSensor for %s \n", this.getClass().getSimpleName(), mother.getName());
+    
+        String volName = mother.getName() + "_active";
+    
+        ActiveSensor active_sensor = new ActiveSensor(volName, mother);
+        active_sensor.setMaterial("Silicon");
+    
+        HalfModuleBundle hm = getHalfModuleBundle((BaseModule) mother.getMother().getMother(), mother.getMother().getName());
+        hm.activeSensor = active_sensor;
+    
+    }
+    
+    
+    
+
+    /**
+     * Tracking volume geometry definition. 
+     */
+    public static class TrackingVolume extends SurveyVolume {
+        public TrackingVolume(String name, SurveyVolume mother) {
+            super(name,mother, null);
+            init();
+        }
+        protected void setPos() {
+            // Dummy survey positions to setup a coordinate system
+            ballPos = new BasicHep3Vector(0,0,0);
+            veePos = new BasicHep3Vector(1,0,0);
+            flatPos = new BasicHep3Vector(0,1,0);
+        }
+        protected void setCenter() {
+            // at the origin
+            setCenter(new BasicHep3Vector(0,0,0));
+        }
+        protected void setBoxDim() {
+            // do nothing since we are not building a tracking volume
+        }
+    }
+
+    /**
+     * TODO This class is shared among geometry definitions but should really be in the test run class. Fix this. 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class TestRunModuleBundle extends BaseModuleBundle {
+        public HalfModuleBundle halfModuleAxial = null;
+        public HalfModuleBundle halfModuleStereo = null;
+        protected SurveyVolume coldBlock = null;
+        public TestRunModuleBundle(BaseModule m) {
+           super(m);
+        }
+        public void print() {
+            if(module!=null) System.out.printf("%s: %s\n", this.getClass().getSimpleName(),module.toString());
+            if(halfModuleAxial!=null) halfModuleAxial.print();
+            if(coldBlock!=null)System.out.printf("%s: %s\n", this.getClass().getSimpleName(),coldBlock.getName());
+            if(halfModuleStereo!=null) halfModuleStereo.print();
+        }
+     }
+    
+
+   
+
+
+
+
+
+
+
+
+}
+
+
+
+

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,172 @@
+package org.lcsim.geometry.compact.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jdom.Element;
+import org.lcsim.detector.DetectorIdentifierHelper;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.identifier.ExpandedIdentifier;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.tracker.silicon.SiTrackerModule;
+import org.lcsim.geometry.compact.Subdetector;
+
+public abstract class HPSTrackerJavaBuilder implements IHPSTrackerJavaBuilder {
+
+	protected boolean _debug = false;
+	private JavaSurveyVolume baseSurveyVolume;
+	protected List<JavaSurveyVolume> javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
+	protected DetectorIdentifierHelper detectorIdentifierHelper;
+	protected IIdentifierDictionary identifierDictionary;
+	protected Subdetector subdet;
+	protected List<IDetectorElement> layerDetectorElements = new ArrayList<IDetectorElement>();
+	protected List<IDetectorElement> moduleDetectorElements = new ArrayList<IDetectorElement>();
+	protected IDetectorElement baseDetectorElement = null;
+	public HPSTrackerBuilder _builder = null;
+    protected Element node = null;
+	
+	public HPSTrackerJavaBuilder(boolean debugFlag, Element node) {
+		this._debug=debugFlag;
+		this.node  = node;
+	}	
+	
+	public abstract void build(ILogicalVolume trackingVolume);
+	public abstract HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node);
+
+	
+	/**
+	 * Add to list of objects.
+	 * @param geom - object to add.
+	 */
+	public void add(JavaSurveyVolume geom) {
+		javaSurveyVolumes.add(geom);
+	}
+	
+	public void setBuilder(HPSTrackerBuilder b) {
+		_builder = b;
+	}
+	
+	public void build() {
+		_builder.build();
+	}
+	
+	public void setDebug(boolean debug) {
+		_debug = debug;
+	}
+	
+	public boolean isDebug() {
+		return _debug;
+	}
+
+
+	public DetectorIdentifierHelper getDetectorIdentifierHelper() {
+		return detectorIdentifierHelper;
+	}
+
+	public void setDetectorIdentifierHelper(
+			DetectorIdentifierHelper detectorIdentifierHelper) {
+		this.detectorIdentifierHelper = detectorIdentifierHelper;
+	}
+
+	public IIdentifierDictionary getIdentifierDictionary() {
+		return identifierDictionary;
+	}
+
+	public void setIdentifierDictionary(
+			IIdentifierDictionary identifierDictionary) {
+		this.identifierDictionary = identifierDictionary;
+	}
+
+
+	public void setSubdetector(Subdetector subdet) {
+		this.subdet = subdet;
+	}
+
+	public Subdetector getSubdetector() {
+		return this.subdet;
+	}
+
+	
+
+	
+
+	// This finds specific type. I would like to use the ID for this but can't, I think.
+	// TODO there must be a factory instance to do this
+	public SiTrackerModule getModuleDetectorElement(SiTrackerModule testElement) {
+		if(isDebug()) System.out.printf("%s: getModuleDetectorElement for module  %s path: \"%s\"\n", this.getClass().getSimpleName(),testElement.getName(),testElement.getGeometry().getPathString());
+		SiTrackerModule element = null;
+		for(IDetectorElement e : moduleDetectorElements) {
+			SiTrackerModule m = (SiTrackerModule) e;
+			if(isDebug()) System.out.printf("%s: compare with module  %s path: %s\"%s\" \n", this.getClass().getSimpleName(),m.getName(),m.getGeometry().getPathString());
+			if(m.getGeometry().getPathString().equals(testElement.getGeometry().getPathString())) {
+				if(element!=null) throw new RuntimeException("two DE sharing extended ID?");
+				if(isDebug()) System.out.printf("%s: found it\n", this.getClass().getSimpleName());
+				element = m;
+			}
+		}
+		return element;
+	}
+
+	
+	// Find detector elements
+	// TODO This should be using some global geometry code like DetectorElementStore?
+	public IDetectorElement getLayerDetectorElement(IExpandedIdentifier expId) {
+		IDetectorElement element = null;
+		if(isDebug()) System.out.printf("%s: search among %d layer DEs\n", this.getClass().getSimpleName(), layerDetectorElements.size());
+		for(IDetectorElement e : layerDetectorElements) {
+			if(isDebug()) System.out.printf("%s: test %s\n", this.getClass().getSimpleName(),e.getName());
+			ExpandedIdentifier eId = (ExpandedIdentifier) e.getExpandedIdentifier();
+			if(eId.equals(expId)) { // TODO order matters as expId is an interface without that function!?
+				//check that only one was found
+				if(element!=null) throw new RuntimeException("two DE sharing extended ID?");
+				if(isDebug()) System.out.printf("%s: found it\n", this.getClass().getSimpleName());
+				element = e;
+			}
+
+		}
+		return element;
+	}
+
+
+	public void addLayerDetectorElement(IDetectorElement e) {
+		IExpandedIdentifier expId = e.getExpandedIdentifier();
+		if(getLayerDetectorElement(expId) != null) 
+			throw new RuntimeException("Trying to add an existing layer detector element.");
+		layerDetectorElements.add(e);
+	}
+
+	public void addBaseDetectorElement(IDetectorElement e) {
+	    baseDetectorElement = e;
+	}
+
+	public IDetectorElement getBaseDetectorElement() {
+	    return baseDetectorElement;
+	}
+
+	public void addModuleDetectorElement(IDetectorElement e) {
+		if(!(e instanceof SiTrackerModule)) 
+			throw new RuntimeException("Trying to add an existing module of wrong type.");
+		if(getModuleDetectorElement((SiTrackerModule) e) != null) 
+			throw new RuntimeException("Trying to add an already existing module detector element.");
+		layerDetectorElements.add(e);
+	}
+	
+
+	/**
+	 * @return the baseTrackerGeometry
+	 */
+	public JavaSurveyVolume getBaseTrackerGeometry() {
+		return baseSurveyVolume;
+	}
+
+	/**
+	 * @param baseTrackerGeometry the baseTrackerGeometry to set
+	 */
+	public void setBaseTrackerGeometry(JavaSurveyVolume baseTrackerGeometry) {
+		this.baseSurveyVolume = baseTrackerGeometry;
+	}
+
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,129 @@
+package org.lcsim.geometry.compact.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jdom.Element;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+public abstract class HPSTrackerLCDDBuilder  implements IHPSTrackerLCDDBuilder {
+
+	public boolean _debug = true;
+	protected LCDD lcdd = null;
+	protected LCDDSurveyVolume baseSurveyVolume;
+	protected List<LCDDSurveyVolume> lcddSurveyVolumes = new ArrayList<LCDDSurveyVolume>();
+	private SensitiveDetector sensitiveDetector;
+	public HPSTrackerBuilder _builder = null;
+    protected Element node;
+
+	
+	
+	public HPSTrackerLCDDBuilder(boolean debugFlag, Element node, LCDD lcdd2, SensitiveDetector sens) {
+		setDebug(debugFlag);
+		setLCDD(lcdd2);
+		setSensitiveDetector(sens);
+		setNode(node);
+	}
+	
+	/**
+     * Build the LCDD geometry objects.
+     * @param worldVolume - the reference volume.
+     */
+    public abstract void build(Volume worldVolume);
+
+    
+    public abstract void setBuilder();
+    
+    public abstract HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node);
+	
+
+	public void setNode(Element node) {
+        this.node = node;
+	}
+	
+    public void setSensitiveDetector(SensitiveDetector sens) {
+		this.sensitiveDetector = sens;
+	}
+
+	public SensitiveDetector getSensitiveDetector() {
+		return this.sensitiveDetector;
+	}
+
+	public void setBuilder(HPSTrackerBuilder b) {
+		_builder = b;
+	}
+	
+	public HPSTrackerBuilder getBuilder() {
+	    return _builder;
+	}
+	
+	public void build() {
+		_builder.build();
+	}
+	
+	public void setDebug(boolean debug) {
+		_debug = debug;
+	}
+	
+	public boolean isDebug() {
+		return _debug;
+	}
+	
+	/**
+	 * Add to list of objects.
+	 * @param geom - object to add.
+	 */
+	public void add(LCDDSurveyVolume geom) {
+		lcddSurveyVolumes.add(geom);
+	}
+
+	
+	
+
+	public void setLCDD(LCDD lcdd) {
+		this.lcdd = lcdd;
+	}
+
+	public LCDD getLCDD() {
+		return lcdd;
+	}
+
+	public LCDDSurveyVolume getBaseLCDD() {
+		return baseSurveyVolume;
+	}
+
+	public void setVisualization() {
+	
+		if(isDebug()) System.out.printf("%s: Set LCDD visualization for %d LCDD geometry objects \n", getClass().getSimpleName(), lcddSurveyVolumes.size());
+		for(SurveyVolumeImpl g : lcddSurveyVolumes) {
+		    String name = g.getName();
+			if(isDebug()) System.out.printf("%s: Set LCDD vis for %s \n", getClass().getSimpleName(), name);			
+			if(name.contains("base_plate")) g.setVisName("BasePlateVis");
+            else if(name.equals("base")) g.setVisName("SvtBoxVis");
+			else if(name.contains("chamber")) g.setVisName("ChamberVis");
+			else if(name.contains("support_bottom") || name.contains("support_top")) g.setVisName("SupportVolumeVis");
+			else if(name.contains("support_plate")) g.setVisName("SupportPlateVis");
+			else if(name.startsWith("module_")) {
+			    if(name.endsWith("halfmodule_axial") || name.endsWith("halfmodule_stereo")) g.setVisName("HalfModuleVis");
+			    else if(name.endsWith("cold")) g.setVisName("ColdBlockVis");
+			    else if(name.endsWith("lamination")) g.setVisName("KaptonVis");
+			    else if(name.endsWith("sensor")) g.setVisName("SensorVis");
+			    else if(name.endsWith("sensor_active")) g.setVisName("SensorVis");
+			    else if(name.endsWith("cf")) g.setVisName("CarbonFiberVis");
+			    else if(name.endsWith("hybrid")) g.setVisName("HybridVis");
+			    else {
+			        //this must be a module then?
+			        g.setVisName("ModuleVis");
+			    }
+			}
+			else {
+				if(isDebug()) System.out.printf("%s: No LCDD vis for %s \n", getClass().getSimpleName(), name);
+			}
+		}
+		if(isDebug()) System.out.printf("%s: DONE Set LCDD vis \n", getClass().getSimpleName());
+	}
+	
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,31 @@
+package org.lcsim.geometry.compact.converter;
+
+import org.lcsim.detector.DetectorIdentifierHelper;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.geometry.compact.Subdetector;
+
+public interface IHPSTrackerJavaBuilder {
+
+	/**
+	 * Build the JAVA geometry objects from the geometry definition.
+	 * @param trackingVolume - the reference volume.
+	 */
+	public void build(ILogicalVolume trackingVolume);
+	
+	public DetectorIdentifierHelper getDetectorIdentifierHelper();
+
+	public void setDetectorIdentifierHelper(
+			DetectorIdentifierHelper detectorIdentifierHelper);
+
+	public IIdentifierDictionary getIdentifierDictionary();
+
+	public void setIdentifierDictionary(
+			IIdentifierDictionary identifierDictionary);
+
+
+	public void setSubdetector(Subdetector subdet);
+
+	public Subdetector getSubdetector();
+	
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,15 @@
+package org.lcsim.geometry.compact.converter;
+
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+import org.lcsim.geometry.compact.converter.lcdd.util.Volume;
+
+public interface IHPSTrackerLCDDBuilder {
+
+	public  void setSensitiveDetector(SensitiveDetector sens);
+
+	public  SensitiveDetector getSensitiveDetector();
+	
+	public void build(Volume worldVolume);
+
+	public void setVisualization();
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,28 @@
+package org.lcsim.geometry.compact.converter;
+
+/**
+ * 
+ *  Interface to the JAVA converter geometry for the geometry definition.   
+ *  In this case no volume is built but can be used as reference in building the geometry.
+ * @author Per Hansson Adrian <[log in to unmask]>
+ */
+public class JavaGhostSurveyVolume extends JavaSurveyVolume {
+	
+	/**
+	 * Initialize with base and mother. This is typically for a reference geometry object 
+	 * that is used for referencing coordinate systems but that doesn't have a volume itself.
+	 * @param surveyVolume - object used to get geometry definitions
+	 * @param mother - mother object
+	 */
+	public JavaGhostSurveyVolume(SurveyVolume surveyVolume, JavaSurveyVolume mother) {
+		super(surveyVolume);
+		if(isDebug()) System.out.printf("%s: constructing JAVA ghost object %s with mother %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),mother==null?"null":mother.getName());
+		setMother(mother);
+		mother.addDaughter(this);
+		setPositionAndRotation(surveyVolume);
+		if(isDebug()) System.out.printf("%s: DONE constructing JAVA object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+	}
+	
+
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,292 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.ITranslation3D;
+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.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.solids.Box;
+import org.lcsim.geometry.util.TransformationUtils;
+
+/**
+ *  Interface to the JAVA converter geometry for the geometry definition.  
+ * @author Per Hansson Adrian <[log in to unmask]>
+ */
+public class JavaSurveyVolume extends SurveyVolumeImpl {
+	private Box box= null;
+	private ILogicalVolume volume = null;
+	private ITranslation3D pos = null;
+	private IRotation3D rot = null;
+	private IPhysicalVolume physVolume = null;
+	private JavaSurveyVolume mother = null;
+	public List<JavaSurveyVolume> daughters = new ArrayList<JavaSurveyVolume>();
+	private int componentId = -1;
+	
+	/**
+	 *  Default constructor
+	 */
+	public JavaSurveyVolume(SurveyVolume surveyVolume) {
+	    super(surveyVolume);
+	}
+
+	/**
+	 * Construct a JAVA geometry object from its geometry definition and an already built logical volume. 
+	 * This is typically used by the tracking volume.
+	 * @param surveyVolume - input geometry definition
+	 * @param vol - logical volume
+	 */
+	public JavaSurveyVolume(SurveyVolume surveyVolume, ILogicalVolume vol) {
+	    super(surveyVolume);
+		if(isDebug()) System.out.printf("%s: JavaBaseGeometry %s (given logical volume %s)\n", this.getClass().getSimpleName(),surveyVolume.getName(),vol.getName());
+		// this must be tracking volume. May change in the future and is probably weird to make this requirement here. 
+		if(!surveyVolume.getName().contains("tracking")) throw new RuntimeException("this constructor is only used with the tracking volume!?");
+		setVolume(vol);
+		// since it's tracking volume, set the pos and rotation trivially
+		Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(surveyVolume.getCoord().v(), surveyVolume.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
+		setPos(new Translation3D(0,0,0));
+		setRot(new RotationGeant(lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+		if(isDebug()) System.out.printf("%s: DONE JavaBaseGeometry %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+	}
+	
+	/**
+	 * Construct a JAVA geometry object from its geometry definition. 
+	 * @param surveyVolume - input geometry definition
+	 * @param mother - reference to mother JAVA definition
+	 * @param volumeId - component id number 
+	 */
+	public JavaSurveyVolume(SurveyVolume surveyVolume, JavaSurveyVolume mother, int volumeId) {
+	    super(surveyVolume);
+        if(isDebug()) System.out.printf("%s: JavaBaseGeometry %s (volumeID %d, mother %s)\n", this.getClass().getSimpleName(),surveyVolume.getName(),volumeId,mother==null?"null":mother.getName());
+		setComponentId(volumeId);
+		setMother(mother);
+		mother.addDaughter(this);
+		buildBox();
+		buildVolume();
+		setPositionAndRotation(surveyVolume);
+		if(isDebug()) System.out.printf("%s: DONE JavaBaseGeometry %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+	}
+
+	protected boolean hasCoordinateSystemInfo() {
+		return pos!=null && rot!=null;
+	}
+	
+	
+	public void buildPhysVolume() {
+		if(isDebug()) System.out.printf("%s: build phys volume for %s with mother %s and physical mother %s\n", this.getClass().getSimpleName(),getName(),getMother().getName(),getPhysMother().getName());
+		JavaSurveyVolume physMother =  getPhysMother();
+		setPhysVolume(new PhysicalVolume(new Transform3D(getPos(), getRot()), getName(), volume, physMother.getVolume(),getComponentId()));
+	}
+	
+	public void buildBox() {
+		Hep3Vector b = VecOp.mult(0.5,getBoxDim());
+		if(isDebug()) System.out.printf("%s: build box for %s with dimensions %s \n", this.getClass().getSimpleName(),getName(), b);
+		setBox(new Box(getName() + "Box", b.x(), b.y(), b.z())); 
+	}
+	public void buildVolume() {
+		if(isDebug()) System.out.printf("%s: build volume for %s with material %s\n", this.getClass().getSimpleName(),getName(), MaterialStore.getInstance().get(getMaterial()));
+			setVolume(new LogicalVolume(getName() + "_volume", box, MaterialStore.getInstance().get(getMaterial())));
+		
+	}
+	public void setPositionAndRotation(SurveyVolume base) {
+		if(isDebug()) System.out.printf("%s: set position and rotation for volume %s\n", this.getClass().getSimpleName(),getName());
+		
+		// no mother, this must be the world/tracking volume!?
+		if(base.getMother()==null) throw new RuntimeException("trying to set coordinates w/o mother defined for "+base.getName());
+		
+		// Vector from origin to center of box locally 
+		Hep3Vector box_center_base_local = base.getCenter();
+		
+		// find the physical mother i.e. not a ghost volume and compound transformations to it
+		JavaSurveyVolume physMother =  getPhysMother();
+		if(isDebug()) System.out.printf("%s: physical mother to transform to is %s; find the transform to it\n", this.getClass().getSimpleName(),physMother.getName());
+		Transform3D trf = HPSTrackerBuilder.getTransform(base.getCoord().getTransformation(),base.getMother(),physMother.getName()); 
+		if(isDebug()) System.out.printf("%s: found transform to physical mother \n%s\n\n", this.getClass().getSimpleName(),trf.toString());
+		
+		// find the position of the center in the physical mother coord
+		Hep3Vector box_center_base = trf.transformed(box_center_base_local);
+		
+		// find the position of the center of the box in the mother coordinate system, make sure to use the physical mother coordinates
+		if(isDebug()) System.out.printf("%s: find center of box in physical mother coord %s \n", this.getClass().getSimpleName(),physMother.getName());
+		// hack since my getTransform function needs a mother TODO Fix this!
+		SurveyVolume gm = base;
+		if(isDebug()) System.out.printf("%s: look for physical mother %s starting from mother %s \n", this.getClass().getSimpleName(),physMother.getName(),gm.getMother()!=null?gm.getMother().getName():"-- no mother --");
+		while((gm=gm.getMother()).getName()!=physMother.getName()) {
+			if(isDebug()) System.out.printf("%s: gm is %s \n", this.getClass().getSimpleName(),gm.getName());
+			//gm = gm.getMother();
+		}
+		if(isDebug()) System.out.printf("%s: found physical mother %s with center at %s \n", this.getClass().getSimpleName(),gm.getName(), gm.getCenter());
+		
+		Hep3Vector mother_center = gm.getCenter();
+
+		// now calculate the position of this box center in the mother LCDD coordinates
+		Hep3Vector box_center = VecOp.sub(box_center_base, mother_center);
+
+		//Find LCDD Euler rotation angles from coordinate system unit vectors
+		//Note that this has to be rotation wrt to physical mother and not just mother as normally is the case
+		//Use apache lib to get angles, but in principle I should already have it from the trf above
+		//Hep3Vector lcdd_rot_angles = HPSTestRunTracker2014.getEulerAngles(base.getCoord().v(), base.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
+		if(isDebug()) System.out.printf("%s: find LCDD Cardan rotation angles - need to find mother to physical mother transform \n", this.getClass().getSimpleName(),physMother.getName());
+		Hep3Vector base_u = base.getCoord().u();
+        Hep3Vector base_v = base.getCoord().v();
+        Hep3Vector base_w = base.getCoord().w();
+        if(isDebug()) System.out.printf("%s: unit vectors in mother coord: %s, %s, %s\n", this.getClass().getSimpleName(),base_u.toString(),base_v.toString(),base_w.toString());
+        Hep3Vector unit_u = new BasicHep3Vector(1,0,0);
+        Hep3Vector unit_v = new BasicHep3Vector(0,1,0);
+        Hep3Vector unit_w = new BasicHep3Vector(0,0,1);
+        if(!base.getMother().getName().equals(physMother.getName())) {
+            if(isDebug()) System.out.printf("%s: Need to get unit vectors in physical mother %s coord system\n", this.getClass().getSimpleName(),physMother.getName());
+            Transform3D trf_mother = HPSTrackerBuilder.getTransform(base.getMother().getCoord().getTransformation(),base.getMother().getMother(),physMother.getName()); 
+            if(isDebug()) System.out.printf("%s: found transform from mother to physical mother \n%s\n", this.getClass().getSimpleName(),trf_mother.toString());
+            //unit_u = VecOp.unit(trf_mother.rotated(unit_u));
+            //unit_v = VecOp.unit(trf_mother.rotated(unit_v));
+            //unit_w = VecOp.unit(trf_mother.rotated(unit_w));
+            base_u = VecOp.unit(trf_mother.rotated(base_u));
+            base_v = VecOp.unit(trf_mother.rotated(base_v));
+            base_w = VecOp.unit(trf_mother.rotated(base_w));
+            
+        } else {
+            if(isDebug()) System.out.printf("%s: mother and physical mother is the same so unit vectors didn't change\n",getClass().getSimpleName());
+        }
+        
+        if(isDebug()) {
+            if(isDebug()) System.out.printf("%s: final unit vectors to get Cardan angles from : \n%s, %s, %s -> %s, %s, %s \n", 
+                                            this.getClass().getSimpleName(),
+                                            base_u.toString(),base_v.toString(),base_w.toString(),              
+                                            unit_u.toString(),unit_v.toString(),unit_w.toString());
+            //System.out.printf("%s: unit vectors u %s v %s w %s\n", this.getClass().getSimpleName(),base.getCoord().u().toString(),base.getCoord().v().toString(),base.getCoord().w().toString());
+        }
+        
+		Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(base_u, base_v, base_w, unit_u, unit_v, unit_w);
+
+
+		// Create the LCDD position
+		setPos(new Translation3D(box_center.x(), box_center.y(), box_center.z()));
+		setRot(new RotationGeant(lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+		
+		if(isDebug()) {
+			
+		    System.out.printf("%s: SurveyVolume information for %s:\n", this.getClass().getSimpleName(), base.getName());
+            System.out.printf("%s: box_center_base_local       %s\n", this.getClass().getSimpleName(), box_center_base_local.toString());
+			System.out.printf("%s: box_center_base             %s\n", this.getClass().getSimpleName(), box_center_base.toString());
+			System.out.printf("%s: mother center               %s\n", this.getClass().getSimpleName(), base.getMother()==null?" <no mother> ":mother_center.toString());
+			System.out.printf("%s: box_center                  %s\n", this.getClass().getSimpleName(), box_center.toString());
+			System.out.printf("%s: pos                         %s\n", this.getClass().getSimpleName(), getPos().toString());
+			Hep3Vector box_center_tracking_xcheck = HPSTrackerBuilder.transformToTracking(box_center_base_local, base);
+            System.out.printf("%s: box_center_tracking_xcheck  %s (for %s)\n", this.getClass().getSimpleName(), box_center_tracking_xcheck==null ? " <null> " : box_center_tracking_xcheck.toString(),base.getName());
+            Hep3Vector box_center_envelope_xcheck2 = HPSTrackerBuilder.transformToParent(box_center_base_local, base, "base");
+            System.out.printf("%s: box_center_base_xcheck2     %s (for %s)\n", this.getClass().getSimpleName(), box_center_envelope_xcheck2==null ? " <null> " : box_center_envelope_xcheck2.toString(),base.getName());
+            if(box_center_envelope_xcheck2!=null) {
+                Hep3Vector box_center_envelope_xcheck2_inch = VecOp.mult(0.0393701, box_center_envelope_xcheck2);
+                System.out.printf("%s: box_center_base_xcheck2_in  %s (for %s)\n", this.getClass().getSimpleName(), box_center_envelope_xcheck2_inch==null ? " <null> " : box_center_envelope_xcheck2_inch.toString(),base.getName());
+            }
+            Hep3Vector origin = base.getCoord().origin();
+            if(origin!=null) {
+                Hep3Vector origin_in = VecOp.mult(0.0393701, origin);
+                System.out.printf("%s: origin_in               %s (%s)\n", this.getClass().getSimpleName(), origin_in==null ? " <null> " : origin_in.toString(), base.getName());
+            }
+            Hep3Vector origin_base = HPSTrackerBuilder.transformToParent(base.getCoord().origin(), base, "base");
+            if(origin_base!=null) {   
+                Hep3Vector origin_base_in = VecOp.mult(0.0393701, origin_base);
+                System.out.printf("%s: origin_base_in          %s\n", this.getClass().getSimpleName(), origin_base_in==null ? " <null> " : origin_base_in.toString());
+            }
+            System.out.printf("%s: euler                       %s\n", this.getClass().getSimpleName(), lcdd_rot_angles.toString());
+			System.out.printf("%s: rot                         %s\n", this.getClass().getSimpleName(), getRot().toString());
+			
+		}
+		
+	}
+
+	/**
+	 * Find the first non-ghost volume among parents.  
+	 * @return mother object
+	 */
+	public JavaSurveyVolume getPhysMother() {
+		//if(isDebug()) System.out.printf("%s: finding physical mother to %s\n", this.getClass().getSimpleName(), getName());
+		if(mother==null) throw new RuntimeException("Trying to get phys mother but there is no mother!");
+		if(mother instanceof JavaGhostSurveyVolume) {
+			return mother.getPhysMother();
+		} else {
+			//if(isDebug()) System.out.printf("%s: found a non-ghost volume: %s\n", this.getClass().getSimpleName(), mother.getName());
+			return mother;
+		}
+	}
+	
+	
+	public ILogicalVolume getVolume() {
+		return volume;
+	}
+	protected void setVolume(ILogicalVolume volume) {
+		this.volume = volume;
+	}
+	protected Box getBox() {
+		return box;
+	}
+	protected void setBox(Box b) {
+		box = b;
+	}	
+	protected ITranslation3D getPos() {
+		return pos;
+	}
+	protected void setPos(ITranslation3D iTranslation3D) {
+		this.pos = iTranslation3D;
+	}
+	protected IRotation3D getRot() {
+		return rot;
+	}
+	protected void setRot(IRotation3D iRotation3D) {
+		this.rot = iRotation3D;
+	}
+	public JavaSurveyVolume getMother() {
+		return mother;
+	}
+	protected void setMother(JavaSurveyVolume mother) {
+		this.mother = mother;
+	}
+	public IPhysicalVolume getPhysVolume() {
+		return physVolume;
+	}
+	protected void setPhysVolume(PhysicalVolume physVolume) {
+		this.physVolume = physVolume;
+	}
+
+	public List<JavaSurveyVolume> getDaughters() {
+		return daughters;
+	}
+
+	protected void addDaughter(JavaSurveyVolume o) {
+		getDaughters().add(o);
+	}
+
+	public int getComponentId() {
+		return componentId;
+	}
+
+	public void setComponentId(int componentId) {
+		this.componentId = componentId;
+	}
+	
+	public String toString() {
+		String s = "JavaBaseGeometry " + getName() + "\n";
+		if(getPos()!=null && getRot()!=null) {
+			s += "Position: "  + getPos().toString() + "\n";
+			s += "Rotation: " + getRot().toString() + "\n";
+		} else {
+			s+= " - no position/rotation info -\n";
+		}
+		return s;
+	}
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,29 @@
+package org.lcsim.geometry.compact.converter;
+
+/**
+ * 
+ * Interface to the LCDD converter geometry for the geometry definition. 
+ * No volume is built but it can be used as reference in building the geometry.
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class LCDDGhostSurveyVolume extends LCDDSurveyVolume {
+
+	
+	
+	/**
+	 * Initialize with base and mother. This is typically for a reference geometry object 
+	 * that is used for referencing coordinate systems but that doesn't have a volume itself.
+	 * @param base - object used to get geometry definitions
+	 * @param mother - mother LCDD object
+	 */
+	public LCDDGhostSurveyVolume(SurveyVolume base, LCDDSurveyVolume mother) {
+		super(base);
+		if(isDebug()) System.out.printf("%s: constructing LCDD ghost object %s with mother %s\n", this.getClass().getSimpleName(),base.getName(),mother==null?"null":mother.getName());
+		setMother(mother);
+		mother.addDaughter(this);
+		if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),base.getName());
+	}
+	
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,270 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.jdom.JDOMException;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.geometry.compact.converter.lcdd.util.Box;
+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.Volume;
+import org.lcsim.geometry.util.TransformationUtils;
+
+/**
+ * Interface to the LCDD converter geometry for the geometry definition. 
+ *   
+ * @author Per Hansson Adrian <[log in to unmask]>
+ */
+public class LCDDSurveyVolume extends SurveyVolumeImpl  {
+	Box box= null;
+	Volume volume = null;
+	private Position pos = null;
+	private Rotation rot = null;
+	private PhysVol physVolume = null;
+	LCDD lcdd = null;
+	private LCDDSurveyVolume mother = null;
+	protected Map<String,Integer> physVolId = null;
+	public List<LCDDSurveyVolume> daughters = new ArrayList<LCDDSurveyVolume>();
+	/**
+	 *  Default constructor
+	 *  @param surveyVolume - core geometry definitions
+	 */
+	public LCDDSurveyVolume(SurveyVolume surveyVolume) {
+	   super(surveyVolume);
+	}
+	
+	/**
+	 * Initialize this object with a known volume and no mother. Typically the world volume would use this.
+	 * @param surveyVolume - core geometry definitions
+	 * @param vol - given volume
+	 */
+	public LCDDSurveyVolume(SurveyVolume surveyVolume, Volume volume) {
+		super(surveyVolume);
+		if(isDebug()) System.out.printf("%s: constructing LCDD object %s with volume name %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),volume.getName());
+		setVolume(volume);
+		if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+		Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(surveyVolume.getCoord().v(), surveyVolume.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
+		setPos(new Position(getName() + "_position", 0, 0, 0));
+		setRot(new Rotation(getName() + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+		if(isDebug()) System.out.printf("%s: DONE  %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+	}
+	
+	/**
+	 * Interface to the LCDD converter geometry for the geometry definition. 
+	 * @param surveyVolume - core geometry definition
+	 * @param lcdd - lcdd file 
+	 * @param mother - reference to mother LCDD definition
+	 */
+	public LCDDSurveyVolume(SurveyVolume surveyVolume, LCDD lcdd, LCDDSurveyVolume mother) {
+	    super(surveyVolume);
+	    if(isDebug()) System.out.printf("%s: constructing LCDD object %s with mother %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),mother==null?"null":mother.getName());
+		this.lcdd = lcdd;
+		setMother(mother);
+		mother.addDaughter(this);
+		buildBox();
+		buildVolume();
+		setPositionAndRotation(surveyVolume);
+		//buildPhysVolume(mother);
+		if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+	}
+
+	
+	public void buildPhysVolume() {
+
+	    if(isDebug()) System.out.printf("%s: build phys volume for %s with mother %s and physical mother %s\n", this.getClass().getSimpleName(),getName(),getMother().getName(),getPhysMother().getName());
+	    LCDDSurveyVolume physMother =  getPhysMother();
+	    setPhysVolume(new PhysVol(volume, physMother.getVolume(), getPos(), getRot()));
+	    //if(isDebug()) System.out.printf("%s: build phys volume for %s\n", this.getClass().getSimpleName(),getName());
+		//setPhysVolume(new PhysVol(volume, getMother().getVolume(), getPos(), getRot()));
+	}
+	public void buildBox() {
+		if(isDebug()) System.out.printf("%s: build box for %s\n", getClass().getSimpleName(),getName());
+		setBox(new Box(getName() + "Box", getBoxDim().x(), getBoxDim().y(), getBoxDim().z())); 
+	}
+	public void buildVolume() {
+		if(isDebug()) System.out.printf("%s: build volume for %s with material %s\n", this.getClass().getSimpleName(),getName(),getMaterial());
+		try {
+			Material mat = lcdd.getMaterial(getMaterial());
+			setVolume(new Volume(getName() + "_volume", box, mat));
+		} catch (JDOMException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	
+	public void setPositionAndRotation(SurveyVolume base) {
+		if(isDebug()) System.out.printf("%s: set position and rotation for volume %s\n", this.getClass().getSimpleName(),getName());
+		
+		// NOTE:
+		// This sets position and reference w.r.t. mother coordinate system. 
+		// If I'm not building that volume this will be wrong. 
+		// TODO Similar to in the JAVA converter this should be something like the physical mother.
+		
+		if(base.getMother()==null) throw new RuntimeException("trying to set coordinates w/o mother defined for "+base.getName());
+		
+		// Vector from origin to center of box locally 
+		Hep3Vector box_center_base_local = base.getCenter();
+		
+		//translate to the mother coordinate system
+		LCDDSurveyVolume physMother = getPhysMother();
+		if(isDebug()) System.out.printf("%s: physical mother to transform to is %s; find the transform to it\n", this.getClass().getSimpleName(),physMother.getName());
+		Transform3D trf = HPSTrackerBuilder.getTransform(base.getCoord().getTransformation(),base.getMother(),physMother.getName()); 
+		if(isDebug()) System.out.printf("%s: found transform to physical mother \n%s\n\n", this.getClass().getSimpleName(),trf.toString());
+		
+		// find the position of the center in the physical mother coord
+		Hep3Vector box_center_base = trf.transformed(box_center_base_local);
+		
+		// find the position of the center of the box in the mother coordinate system, make sure to use the physical mother coordinates
+		if(isDebug()) System.out.printf("%s: find center of box in physical mother coord %s \n", this.getClass().getSimpleName(),physMother.getName());
+		// hack since my getTransform function needs a mother TODO Fix this!
+		SurveyVolume gm = base;
+		if(isDebug()) System.out.printf("%s: look for physical mother %s starting from mother %s \n", this.getClass().getSimpleName(),physMother.getName(),gm.getMother()!=null?gm.getMother().getName():"-- no mother --");
+		while((gm=gm.getMother()).getName()!=physMother.getName()) {
+			if(isDebug()) System.out.printf("%s: gm is %s \n", this.getClass().getSimpleName(),gm.getName());
+			//gm = gm.getMother();
+		}
+		if(isDebug()) System.out.printf("%s: found physical mother %s with center at %s \n", this.getClass().getSimpleName(),gm.getName(), gm.getCenter());
+
+		Hep3Vector mother_center = gm.getCenter();
+		
+		// find the position of the center in the mother coord
+		Hep3Vector box_center = VecOp.sub(box_center_base, mother_center);
+		
+		//Find LCDD Euler rotation angles from coordinate system unit vectors
+		//Note that this has to be rotation wrt to physical mother and not just mother as normally is the case
+		if(isDebug()) System.out.printf("%s: find LCDD Cardan rotation angles - need to find mother to physical mother transform \n", this.getClass().getSimpleName(),physMother.getName());
+		Hep3Vector base_u = base.getCoord().u();
+		Hep3Vector base_v = base.getCoord().v();
+		Hep3Vector base_w = base.getCoord().w();
+        if(isDebug()) System.out.printf("%s: unit vectors in mother coord: %s, %s, %s\n", this.getClass().getSimpleName(),base_u.toString(),base_v.toString(),base_w.toString());
+		Hep3Vector unit_u = new BasicHep3Vector(1,0,0);
+		Hep3Vector unit_v = new BasicHep3Vector(0,1,0);
+		Hep3Vector unit_w = new BasicHep3Vector(0,0,1);
+		if(!base.getMother().getName().equals(physMother.getName())) {
+		    if(isDebug()) System.out.printf("%s: Need to get unit vectors in physical mother %s coord system\n", this.getClass().getSimpleName(),physMother.getName());
+            Transform3D trf_mother = HPSTrackerBuilder.getTransform(base.getMother().getCoord().getTransformation(),base.getMother().getMother(),physMother.getName()); 
+            if(isDebug()) System.out.printf("%s: found transform from mother to physical mother \n%s\n", this.getClass().getSimpleName(),trf_mother.toString());
+			//unit_u = VecOp.unit(trf_mother.rotated(unit_u));
+			//unit_v = VecOp.unit(trf_mother.rotated(unit_v));
+			//unit_w = VecOp.unit(trf_mother.rotated(unit_w));
+			base_u = VecOp.unit(trf_mother.rotated(base_u));
+            base_v = VecOp.unit(trf_mother.rotated(base_v));
+            base_w = VecOp.unit(trf_mother.rotated(base_w));
+            
+		} else {
+			if(isDebug()) System.out.printf("%s: mother and physical mother is the same so unit vectors didn't change\n",getClass().getSimpleName());
+		}
+		
+		if(isDebug()) {
+		    if(isDebug()) System.out.printf("%s: final unit vectors to get Cardan angles from : \n%s, %s, %s -> %s, %s, %s \n", 
+		                                    this.getClass().getSimpleName(),
+		                                    base_u.toString(),base_v.toString(),base_w.toString(),	            
+		                                    unit_u.toString(),unit_v.toString(),unit_w.toString());
+			//System.out.printf("%s: unit vectors u %s v %s w %s\n", this.getClass().getSimpleName(),base.getCoord().u().toString(),base.getCoord().v().toString(),base.getCoord().w().toString());
+		}
+        Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(base_u, base_v, base_w, unit_u, unit_v, unit_w);
+        
+		
+		// Create the LCDD position and rotation
+		setPos(new Position(getName() + "_position",box_center.x(), box_center.y(), box_center.z()));
+		setRot(new Rotation(getName() + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+		
+		if(isDebug()) {
+		    System.out.printf("%s: SurveyVolume information for %s:\n", this.getClass().getSimpleName(), base.getName());
+            System.out.printf("%s: box_center_base_local  %s\n", this.getClass().getSimpleName(), box_center_base_local.toString());
+			System.out.printf("%s: box_center_base        %s\n", this.getClass().getSimpleName(), box_center_base.toString());
+			System.out.printf("%s: mother center          %s\n", this.getClass().getSimpleName(), mother_center.toString());
+			System.out.printf("%s: box_center             %s\n", this.getClass().getSimpleName(), box_center.toString());
+			System.out.printf("%s: pos                    %s\n", this.getClass().getSimpleName(), getPos().toString());
+			System.out.printf("%s: euler                  %s\n", this.getClass().getSimpleName(), lcdd_rot_angles.toString());
+            System.out.printf("%s: rot                    %s\n", this.getClass().getSimpleName(), getRot().toString());
+			
+			//calculate the position in tracking volume separately as a xcheck
+			Hep3Vector box_center_tracking_xcheck = HPSTrackerBuilder.transformToTracking(box_center_base_local, base);
+			System.out.printf("%s: box_center_tracking_xcheck  %s (for %s)\n", this.getClass().getSimpleName(), box_center_tracking_xcheck.toString(), base.getName());
+		}
+		
+	}
+	/**
+	 * Find the first non-ghost volume among parents.  
+	 * @return mother object
+	 */
+	public LCDDSurveyVolume getPhysMother() {
+		//if(isDebug()) System.out.printf("%s: finding physical mother to %s\n", this.getClass().getSimpleName(), getName());
+		if(mother==null) throw new RuntimeException("Trying to get phys mother but there is no mother!");
+		if(mother instanceof LCDDGhostSurveyVolume) {
+			return mother.getPhysMother();
+		} else {
+			//if(isDebug()) System.out.printf("%s: found a non-ghost volume: %s\n", this.getClass().getSimpleName(), mother.getName());
+			return mother;
+		}
+	}
+	
+	public Volume getVolume() {
+		return volume;
+	}
+	public void setVolume(Volume volume) {
+		this.volume = volume;
+	}
+	public Box getBox() {
+		return box;
+	}
+	public void setBox(Box b) {
+		box = b;
+	}	
+	public Position getPos() {
+		return pos;
+	}
+	public void setPos(Position pos) {
+		this.pos = pos;
+	}
+	public Rotation getRot() {
+		return rot;
+	}
+	public void setRot(Rotation rot) {
+		this.rot = rot;
+	}
+	public LCDDSurveyVolume getMother() {
+		return mother;
+	}
+	public void setMother(LCDDSurveyVolume mother) {
+		this.mother = mother;
+	}
+	public PhysVol getPhysVolume() {
+		return physVolume;
+	}
+	public void setPhysVolume(PhysVol physVolume) {
+		this.physVolume = physVolume;
+	}
+	public List<LCDDSurveyVolume> getDaughters() {
+		return daughters;
+	}
+	public void addDaughter(LCDDSurveyVolume o) {
+		getDaughters().add(o);
+	}
+	 public String toString() {
+        String s = getClass().getSimpleName() +": " + getName() + "\n";
+        if(getPos()!=null && getRot()!=null)    {
+            double x = Double.valueOf(getPos().getAttributeValue("x"));
+            double y = Double.valueOf(getPos().getAttributeValue("y"));
+            double z = Double.valueOf(getPos().getAttributeValue("z"));
+            s += "Position: " + String.format("(%.4f %.4f %.4f)\n", x,y,z);
+            x = Double.valueOf(getRot().getAttributeValue("x"));
+            y = Double.valueOf(getRot().getAttributeValue("y"));
+            z = Double.valueOf(getRot().getAttributeValue("z"));
+            s += "Rotation: " + String.format("(%.4f %.4f %.4f)\n", x,y,z);
+        } else {
+            s += " - no position/rotation info -\n";
+        }
+        return s;
+    }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,115 @@
+package org.lcsim.geometry.compact.converter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+
+
+public class MilleParameter {
+    private static double corrScaleFactor = -1.;
+	private int id;
+	private double value; 
+	private double presigma;
+	private static final Map<Integer,String> dMap;
+	private static final Map<Integer,String> tMap;
+	private static final Map<Integer,String> hMap;
+	static {
+		dMap = new HashMap<Integer,String>();
+		dMap.put(1, "x");dMap.put(2, "y"); dMap.put(3, "z");
+		tMap = new HashMap<Integer,String>();
+		tMap.put(1, "");tMap.put(2, "r");
+		hMap = new HashMap<Integer,String>();
+		hMap.put(1, "t");hMap.put(2, "b");
+		}
+	public static final int half_offset = 10000;
+	public static final int type_offset = 1000; 
+	public static final int dimension_offset = 100;
+	
+	public MilleParameter(String line) {
+		String[] vals = StringUtils.split(line);// line.split("\\s+");
+		if(vals.length <3) {
+			System.out.println("this line is ill-formatted (" + vals.length + ")");
+			System.out.println(line);
+			System.exit(1);
+		}
+		try {
+		//for(String v : vals) System.out.println("\"" + v + "\"");
+		setId(Integer.parseInt(vals[0]));
+		setValue( corrScaleFactor * Double.parseDouble(vals[1]) );
+		setPresigma(Double.parseDouble(vals[2]));
+		
+		} catch (NumberFormatException e) {
+			System.out.println(vals[0] + " " + vals[1] + " " + vals[2]);
+			throw new RuntimeException("problem parsing string ", e);
+		}
+	}
+	
+	public MilleParameter(int id, double value, double presigma) {
+	    setId(id);
+	    setValue(value);
+	    setPresigma(presigma);
+	}
+	
+	public String getXMLName() {
+		String d = dMap.get(getDim());
+		String t = tMap.get(getType());
+		String h = hMap.get(getHalf());
+		int s = getSensor();
+		return String.format("%s%s%d%s_align", t,d,s,h);
+		
+	}
+
+	public int getDim() {
+		int h = (int) (getHalf() * half_offset);
+		int t = (int) (getType() * type_offset);
+		return (int) Math.floor((id- h -t)/(double)dimension_offset);
+	}
+	
+	public int getSensor() {
+		int h = (int) (getHalf() * half_offset);
+		int t = (int) (getType() * type_offset);
+		int d = (int) (getDim() * dimension_offset);
+		return (id - h - t -d);
+	}
+
+	public int getType() {
+		int h = (int) (getHalf() * half_offset);
+		return (int) Math.floor((id -h)/(double)type_offset);
+	}
+
+	public int getHalf() {
+		return (int)Math.floor(id/(double)half_offset);
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public double getValue() {
+		return value;
+	}
+
+	public void setValue(double value) {
+		this.value = value;
+	}
+
+	public double getPresigma() {
+		return presigma;
+	}
+
+	public void setPresigma(double presigma) {
+		this.presigma = presigma;
+	}
+	
+	public String toString() {
+	    return String.format("Milleparameter id=%d half=%d type=%d dim=%d sensor=%d value=%f", this.getId(), this.getHalf(), this.getType(), this.getDim(), this.getSensor(), this.getValue());
+	}
+
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleComponentParameters.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleComponentParameters.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleComponentParameters.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,45 @@
+package org.lcsim.geometry.compact.converter;
+
+// TODO: Move to different package.
+public class SiTrackerModuleComponentParameters
+{
+    String materialName;
+    double thickness;
+    boolean sensitive;
+    int componentNumber;
+    String vis;
+
+    public SiTrackerModuleComponentParameters(double thickness, String materialName, int componentNumber, boolean sensitive, String vis)
+    {
+        this.thickness = thickness;
+        this.materialName = materialName;
+        this.sensitive = sensitive;
+        this.componentNumber = componentNumber;
+        this.vis = vis;
+    }
+
+    public double getThickness()
+    {
+        return thickness;
+    }
+
+    public String getMaterialName()
+    {
+        return materialName;
+    }
+
+    public boolean isSensitive()
+    {
+        return sensitive;
+    }
+
+    public int getComponentNumber()
+    {
+        return componentNumber;
+    }
+    
+    public String getVis()
+    {
+    	return vis;
+    }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleParameters.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleParameters.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SiTrackerModuleParameters.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,101 @@
+package org.lcsim.geometry.compact.converter;
+
+import java.util.ArrayList;
+
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+
+// TODO: Move to different package.
+
+public class SiTrackerModuleParameters
+extends ArrayList<SiTrackerModuleComponentParameters>
+{
+    double thickness=0.;
+    String name;
+    double dimensions[] = new double[3];
+    String vis;
+    
+    public SiTrackerModuleParameters(Element element)
+    {
+        name = element.getAttributeValue("name");
+        
+        if (element.getAttribute("vis") != null)
+        	this.vis = element.getAttribute("vis").getValue();
+        
+        int cntr=0;
+        for (Object o : element.getChildren("module_component"))
+        {
+            try {
+
+                Element e = (Element)o;
+
+                double thickness = e.getAttribute("thickness").getDoubleValue();
+
+                String materialName = e.getAttributeValue("material");
+
+                boolean sensitive = false;
+                if (e.getAttribute("sensitive") != null)
+                    sensitive = e.getAttribute("sensitive").getBooleanValue();
+                String componentVis = null;
+                if (e.getAttribute("vis") != null)
+                	componentVis = e.getAttribute("vis").getValue();
+                add(new SiTrackerModuleComponentParameters(thickness, materialName, cntr, sensitive, componentVis));
+            }
+            catch (JDOMException x)
+            {
+                throw new RuntimeException(x);
+            }
+            ++cntr;
+        }
+        
+        // Optional dimension parameters (not always present).
+        if (element.getChild("trd") != null)
+        {
+            Element trd = element.getChild("trd");
+            try 
+            {
+                dimensions[0] = trd.getAttribute("x1").getDoubleValue();
+                dimensions[1] = trd.getAttribute("x2").getDoubleValue();
+                dimensions[2] = trd.getAttribute("z").getDoubleValue();
+            }
+            catch (DataConversionException x)
+            {
+                throw new RuntimeException(x);
+            }
+        }
+        
+        calculateThickness();
+    }
+
+    public void calculateThickness()
+    {
+        thickness = 0.; // reset thickness
+        for (SiTrackerModuleComponentParameters p : this)
+        {
+            thickness += p.getThickness();
+        }
+    }
+
+    public double getThickness()
+    {
+        return thickness;
+    }
+    
+    public String getName()
+    {
+        return name;
+    }
+    
+    public double getDimension(int i)
+    {
+        if (i > (dimensions.length - 1) || i < 0)
+            throw new RuntimeException("Invalid dimensions index: " + i);
+        return dimensions[i];
+    }
+    
+    public String getVis()
+    {
+    	return vis;
+    }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,155 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Matrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.Rotation3D;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+
+     /**
+	 * Class describing a simple coordinate system used to define the [log in to unmask]
+	 * 
+	 *    @author Per Hansson Adrian <[log in to unmask]>
+	 */
+	public class SurveyCoordinateSystem {
+	    private final boolean debug = false;
+		private Hep3Vector origin;
+		private Hep3Vector u;
+		private Hep3Vector v;
+		private Hep3Vector w;
+
+//		public SurveyCoordinateSystem(Hep3Vector org, Hep3Vector unit_x, Hep3Vector unit_y, Hep3Vector unit_z) {
+//			origin = org;
+//			u = unit_x;
+//			v = unit_y;
+//			w = unit_z;
+//		}
+
+		
+		public SurveyCoordinateSystem(Hep3Vector ball, Hep3Vector vee, Hep3Vector flat) {
+            origin = ball;
+            Hep3Vector ball_to_vee = VecOp.sub(vee, ball);
+            u = VecOp.unit(ball_to_vee);
+            Hep3Vector ball_to_flat = VecOp.sub(flat, ball);
+            w = VecOp.unit(VecOp.cross(ball_to_vee,ball_to_flat));
+            v = VecOp.cross(w, u);
+            check();
+        }
+		
+		private void check() {
+		    checkUnitLength();
+		    checkAngles();
+		}
+
+		private void checkUnitLength() {
+		    if(u.magnitude()-1>0.00001 || v.magnitude()-1>0.00001 || v.magnitude()-1>0.00001) {
+		        throw new RuntimeException("Error: the unit vectors of the  coordinate system is ill-defined " + toString());
+		    }
+		}
+
+		private void checkAngles() {
+		    if( (VecOp.dot(u, v)-1)>0.00001 ||  (VecOp.dot(u, w)-1)>0.00001 ||  (VecOp.dot(v, w)-1)>0.00001 ) {
+		        throw new RuntimeException("Error: the angles in coordinate system is ill-defined " + toString());
+		    }
+		}
+		
+		
+		/**
+		 * Transform this coordinate system to another one.
+		 * @param t
+		 */
+		public void transform(Transform3D t) {
+		    Transform3D t_this = getTransformation();
+		    Hep3Vector v = t_this.getTranslation().getTranslationVector();
+		    Hep3Vector vrot = t.rotated(v);
+		    Hep3Vector vrottrans = t.translated(vrot);
+		    origin = vrottrans;
+            rotate(t.getRotation());
+            //System.out.printf("monkey transform\n"); 
+            //System.out.printf("v %s\n",v.toString());
+            //System.out.printf("vrot %s\n",vrot.toString());
+            //System.out.printf("vrottrans %s\n",vrottrans.toString());
+		    check();
+		}
+		
+		public void rotate(IRotation3D r) {
+			r.rotate(u);
+			r.rotate(v);
+			r.rotate(w);
+		}
+
+		public void translate(Hep3Vector translation) {
+			// update origin with local translation in u,v,w
+		    //origin = VecOp.add(origin, translation);
+		    translate(new Translation3D(translation));
+		}
+
+		public void translate(Translation3D t) {
+		    origin = t.translated(getTransformation().getTranslation().getTranslationVector());
+		}
+
+		
+		public void rotateApache(Rotation r) {
+            if(debug) System.out.printf("%s: apply apache rotation to this coord system\n%s\n", getClass().getSimpleName(),toString());
+            this.u = new BasicHep3Vector(r.applyTo(new Vector3D(u.v())).toArray());
+            this.v = new BasicHep3Vector(r.applyTo(new Vector3D(v.v())).toArray());
+            this.w = new BasicHep3Vector(r.applyTo(new Vector3D(w.v())).toArray());
+            if(debug) System.out.printf("%s: new coord system after apache rotation to this coord system\n%s\n", getClass().getSimpleName(),toString());                
+        }
+        
+        public Hep3Vector origin() {
+			return origin;
+		}
+		public Hep3Vector u() {
+			return u;
+		}
+		public Hep3Vector v() {
+			return v;
+		}
+		public Hep3Vector w() {
+			return w;
+		}
+		public void u(Hep3Vector vec) {
+            u = vec;
+		}
+        public void v(Hep3Vector vec) {
+            v = vec;
+        }
+        public void w(Hep3Vector vec) {
+            w = vec;
+        }
+		
+        public String toString() {
+			String str = "origin " + origin.toString() + "\nu " + u.toString() + "\nv " + v.toString() + "\nw " + w.toString();
+			return str;
+        }
+	
+		
+		/**
+		 * Find @ITransform3D to the coordinate system defined by the input. 
+		 * @return resulting 3D transform 
+		 */
+		public Transform3D getTransformation() {
+			// Find the transform between the two frames - use transform classes here (not really needed)
+			Translation3D translation = new Translation3D(origin.x(), origin.y(), origin.z());
+			//RotationGeant trackingToEnvelopeRotation = new RotationGeant(0, 0, 0);
+			Rotation3D rotation = new Rotation3D(
+					new BasicHep3Matrix(
+							u.x(),v.x(),w.x(),
+							u.y(),v.y(),w.y(),
+							u.z(),v.z(),w.z()
+							));
+			Transform3D envelopeToSupportTransform = new Transform3D(translation, rotation);
+			return envelopeToSupportTransform;
+		}
+		
+		
+		
+		
+	}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,331 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+import org.lcsim.geometry.util.TransformationUtils;
+
+/**
+ * 
+ * Class containing the basic geometry information for building a volume based on survey positions.
+ * 
+ */
+public abstract class SurveyVolume {
+	protected boolean debug = false;
+	private String name;
+	private String material = "Vacuum";
+	private SurveyVolume mother = null;
+	protected List<SurveyVolume> referenceGeom = null;
+	private SurveyCoordinateSystem coord;
+	protected  Hep3Vector ballPos;
+	protected  Hep3Vector veePos;
+	protected  Hep3Vector flatPos;
+	private Hep3Vector center;
+	private Hep3Vector boxDim;
+	private AlignmentCorrection alignmentCorrections;
+	
+	public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection) {
+		setName(name);
+		setMother(m);
+		setAlignmentCorrection(alignmentCorrection);
+	}
+	
+	public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+		setName(name);
+		setMother(m);
+		setAlignmentCorrection(alignmentCorrection);
+		addReferenceGeom(ref);
+	}
+	
+	public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection, List<SurveyVolume> ref) {
+		setName(name);
+		setMother(m);
+		setAlignmentCorrection(alignmentCorrection);
+		addReferenceGeom(ref);
+	}
+	
+	protected abstract void setPos();
+	protected abstract void setCenter();
+	protected abstract void setBoxDim();
+
+	protected void init() {
+	    if(debug) System.out.printf("%s: init SurveyVolume %s\n",this.getClass().getSimpleName(),getName());
+        setPos();
+		setCoord();
+		applyReferenceTransformation();
+		setCenter();
+		setBoxDim();
+		applyGenericCoordinateSystemCorrections();
+		applyLocalAlignmentCorrections();
+		if(debug) {
+		    //printCoordInfo();
+		    System.out.printf("%s: init of SurveyVolume %s DONE\n",this.getClass().getSimpleName(),getName());            
+		}
+	}
+	
+
+    protected void applyGenericCoordinateSystemCorrections() {
+	    //do nothing here unless overridden
+	   
+	}
+	protected void applyReferenceTransformation() {
+
+	        	    
+	    if(referenceGeom!=null) {
+	        
+	        if(debug) System.out.printf("%s: apply reference transformation for %s\n",this.getClass().getSimpleName(),getName());
+	        
+
+	        if(debug) System.out.printf("%s: coord system before %d ref transformations:\n%s\n",this.getClass().getSimpleName(),referenceGeom.size(),getCoord().toString());
+	        
+	        for(SurveyVolume ref : referenceGeom) {
+
+	            if(debug) {
+	                System.out.printf("%s: coord system before ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
+	                System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+	            }
+	            
+	            getCoord().transform(ref.getCoord().getTransformation());
+
+	            if(debug) System.out.printf("%s: coord system after ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
+	            
+	        }
+
+	        if(debug) System.out.printf("%s: coord system after ref transformations:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
+	        
+	    } else {
+	        
+	        if(debug) System.out.printf("%s: no reference transformation exists for %s\n",this.getClass().getSimpleName(),getName());
+	        
+	    }
+
+	}
+	
+	private void applyLocalAlignmentCorrections() {
+	    // Apply alignment corrections to local coordinate system that is already built
+	    boolean debug_local = false;
+	    if(this.coord==null) 
+	        throw new RuntimeException("no coordinate system was set before trying to apply alignment corrections.");
+
+	    if(alignmentCorrections!=null) {
+
+	        if(debug_local || debug) System.out.printf("%s: Apply alignment corrections to %s\n",this.getClass().getSimpleName(),this.getName());
+
+	        // translate
+	        if(alignmentCorrections.getTranslation()!=null) {			    
+
+	            if(debug_local || debug) System.out.printf("%s: Apply local translation %s\n", this.getClass().getSimpleName(),alignmentCorrections.getTranslation().toString());			    
+	            
+	            // rotate into mother coordinate system
+	            Hep3Vector translation_mother = getCoord().getTransformation().rotated(alignmentCorrections.getTranslation());
+	            
+	            if(debug_local || debug) System.out.printf("%s: after rotation apply translation %s to coordinate system\n", this.getClass().getSimpleName(),translation_mother.toString());
+	            
+	            //apply translation
+	            getCoord().translate(translation_mother);
+
+	        } else {
+	            if(debug_local || debug) System.out.printf("%s: No translation to coordinate system\n", this.getClass().getSimpleName());
+	        }
+
+	        // rotate
+	        if(alignmentCorrections.getRotation()!=null) {  
+	            
+                if(debug_local || debug) {
+                    System.out.printf("%s: Apply rotation matrix:\n", this.getClass().getSimpleName());   
+                    TransformationUtils.printMatrix(alignmentCorrections.getRotation().getMatrix());
+                    System.out.printf("%s: coord system before:\n%s\n", this.getClass().getSimpleName(),getCoord().toString());   
+                }
+
+	            
+	            // correct rotation of the local unit vectors
+	            Vector3D u_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(1,0,0));
+	            Vector3D v_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(0,1,0));
+	            Vector3D w_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(0,0,1));
+
+	            // rotate the local unit vectors to the mother coordinates
+	            
+	            Hep3Vector u_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(u_rot_local.toArray()));
+	            Hep3Vector v_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(v_rot_local.toArray()));
+	            Hep3Vector w_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(w_rot_local.toArray()));
+               
+	            getCoord().u(u_rot);
+	            getCoord().v(v_rot);
+	            getCoord().w(w_rot);
+
+                if(debug_local || debug) {
+                    System.out.printf("%s: coord system after:\n%s\n", this.getClass().getSimpleName(),getCoord().toString());   
+                }
+
+	            
+	            // Do some gymnastics from Apache rotation to use the rotation class
+	            //double matMP_v[][] = alignmentCorrections.getRotation().getMatrix();
+                //Hep3Matrix matMP = new BasicHep3Matrix(matMP_v[0][0], matMP_v[0][1], matMP_v[0][2], 
+                //                                       matMP_v[1][0], matMP_v[1][1], matMP_v[1][2],
+                //                                       matMP_v[2][0], matMP_v[2][1], matMP_v[2][2]);
+                //
+                //Rotation3D rotMP = new Rotation3D(matMP);
+
+                // get the rotation correction in the mother coordinate system
+                //Rotation3D r = Rotation3D.multiply(getCoord().getTransformation().getRotation(),rotMP);
+	            
+//                if(debug_local || debug) {
+//	                System.out.printf("%s: Apply rotation matrix:\n", this.getClass().getSimpleName());             
+//	                double mat[][] = alignmentCorrections.getRotation().getMatrix();
+//	                TransformationUtils.printMatrix(mat);
+//	                System.out.printf("%s: corresponding Rotation3D object:\n%s\n",this.getClass().getSimpleName(), rotMP.toString());
+//	                // Get the Cardan angles of the rotation
+//	                double res[] = alignmentCorrections.getRotation().getAngles(RotationOrder.ZYX);
+//	                // Since the rotation was created based on active transformations convert to passive right here. 
+//	                // This conversion is simply to reverse the order of rotations.
+//	                Hep3Vector res_passive = new BasicHep3Vector(res[2],res[1],res[0]);
+//	                System.out.printf("%s: Corresponding LCDD Cardan angles: %s\n", this.getClass().getSimpleName(), res_passive.toString());             
+//	                System.out.printf("%s: Apply local to mother rotation\n%s\n",this.getClass().getSimpleName(), getCoord().getTransformation().getRotation().toString());
+//	                System.out.printf("%s: resulting rotation correction to apply\n%s\n",this.getClass().getSimpleName(), r.toString());
+//                    
+//	            }
+
+                // Apply correction to coordinate system
+	            //getCoord().rotateApache(alignmentCorrections.getRotation());
+                //getCoord().rotate(r);
+
+	        } else {
+	            if(debug_local || debug) System.out.printf("%s: No rotation to coordinate system\n", this.getClass().getSimpleName());
+	        }
+
+	        if(debug_local || debug) System.out.printf("%s: coordinate system after alignment corrections:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
+
+	    } else {
+            if(debug_local || debug) System.out.printf("%s: no alignment corrections exist for %s\n",this.getClass().getSimpleName(),this.getName());
+	    }
+
+	}
+	
+	private void setAlignmentCorrection(AlignmentCorrection alignmentCorrection) {
+        this.alignmentCorrections = alignmentCorrection;
+    }
+    public  void setBallPos(double x, double y, double z) {
+		ballPos = new BasicHep3Vector(x,y,z);
+	}
+	public  void setVeePos(double x, double y, double z) {
+		veePos = new BasicHep3Vector(x,y,z);
+	}
+	public  void setFlatPos(double x, double y, double z) {
+		flatPos = new BasicHep3Vector(x,y,z);
+	}
+	public  Hep3Vector getBallPos() {
+		return ballPos;
+	}
+	public  Hep3Vector getVeePos() {
+		return veePos;
+	}
+	public  Hep3Vector getFlatPos() {
+		return flatPos;
+	}
+	public void setCoord() {
+		if(ballPos==null || veePos==null || flatPos==null) {
+			throw new RuntimeException("Need to set ball, vee and flat before building coord system!");
+		}
+		
+		coord = new SurveyCoordinateSystem(ballPos, veePos, flatPos);					
+		
+		if(this.debug) {
+		    System.out.printf("%s: setCoord \n%s\n", this.getClass().getSimpleName(), coord.toString());
+		}
+	}
+	public SurveyCoordinateSystem getCoord() {
+		if(coord == null) {
+			throw new RuntimeException("Need to setCoord!");
+		}
+		return coord;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public Hep3Vector getCenter() {
+		return center;
+	}
+	public void setCenter(Hep3Vector center) {
+		this.center = center;
+	}
+	public void setCenter(double x, double y, double z) {
+		this.center = new BasicHep3Vector(x,y,z);
+	}
+	public Hep3Vector getBoxDim() {
+		return boxDim;
+	}
+	public void setBoxDim(double x, double y, double z) {
+		this.boxDim = new BasicHep3Vector(x,y,z);
+	}
+	public SurveyVolume getMother() {
+		return mother;
+	}
+	public void setMother(SurveyVolume mother) {
+		this.mother = mother;
+	}
+	public void addReferenceGeom(SurveyVolume refGeom) {
+	    if(refGeom!=null) { // check that it's not a dummy call
+	        if(referenceGeom == null) {
+	            referenceGeom = new ArrayList<SurveyVolume>();
+	        }
+	        referenceGeom.add(refGeom);
+	    }
+	}
+	public void addReferenceGeom(List<SurveyVolume> refGeomList) {
+		if(referenceGeom == null) {
+			referenceGeom = new ArrayList<SurveyVolume>();
+		}
+		referenceGeom.addAll(refGeomList);
+	}
+	public void printSurveyPos() {
+	    if(debug) {
+	        System.out.printf("%s: Survey pos for %s:\n",getClass().getSimpleName(),getName());
+	        System.out.printf("%s: ballPos   %s\n",getClass().getSimpleName(), ballPos.toString());
+	        System.out.printf("%s: veePos    %s\n",getClass().getSimpleName(), veePos.toString());
+	        System.out.printf("%s: flatPos   %s\n",getClass().getSimpleName(), flatPos.toString());
+	    }
+	}
+	public String getMaterial() {
+		return material;
+	}
+	public void setMaterial(String material) {
+		this.material = material;
+	}
+	public String toString() {
+		String s = "==\n" + getName() + " with mother " + (getMother()==null?"<no mother>":getMother().getName()) + ":\n";
+		if( getCenter()!=null) s += "Center of box: " + getCenter().toString() + "\n";
+        if( getBoxDim()!=null) s += "Box dimensions: " + getBoxDim().toString() + "\n";
+		if(this.coord==null)   s += " No coord system \n";
+		else s += "Coordinate system:" + getCoord().toString() + "\n";
+		SurveyVolume m = getMother();
+		while(m!=null) {    
+            Hep3Vector origin_m = HPSTrackerBuilder.transformToParent(new BasicHep3Vector(0, 0, 0), this, m.getName());
+            s += String.format("%s origin in %s : %s (mm)\n",getName(), m.getName(), origin_m.toString());            
+            origin_m = VecOp.mult(0.0393701, origin_m);
+            s += String.format("%s origin in %s : (%.4f %.4f %.4f) (inch)\n",getName(), m.getName(), origin_m.x(),origin_m.y(),origin_m.z());            
+            m = m.getMother();
+		}
+		
+		return s;
+	}
+	
+//	private void printCoordInfo() {
+//	    if(debug) {
+//	        SurveyVolume m = getMother();
+//	        while(m!=null) {    
+//	            Hep3Vector origin_m = HPSTrackerBuilder.transformToParent(getCoord().origin(), this, m.getName());
+//	            System.out.printf("%s: %s final coord system in %s : %s\n",this.getClass().getSimpleName(),getName(), getMother()==null?" <no mother> ":getMother().getName(),getCoord().toString());            
+//	        }
+//	        System.out.printf("%s: init of SurveyVolume %s DONE\n",this.getClass().getSimpleName(),getName());            
+//	    }
+//	}
+	
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,41 @@
+package org.lcsim.geometry.compact.converter;
+
+import hep.physics.vec.Hep3Vector;
+
+public abstract class SurveyVolumeImpl extends SurveyVolumeVisualization {
+
+    private boolean debug = false;
+    protected SurveyVolume surveyVolume = null;
+
+    public SurveyVolumeImpl(SurveyVolume surveyVolume) {
+        super();
+        this.surveyVolume = surveyVolume;
+    }
+
+    public abstract void buildPhysVolume();
+
+    public abstract void buildBox();
+
+    public abstract void buildVolume();
+
+    public abstract void setPositionAndRotation(SurveyVolume base);
+
+    public String getName() {
+    	return surveyVolume.getName();
+    }
+    
+    protected Hep3Vector getBoxDim() {
+        return surveyVolume.getBoxDim();
+    }
+    
+    protected String getMaterial() {
+        return surveyVolume.getMaterial();
+    }
+
+    public boolean isDebug() {
+    	return debug;
+    }
+
+    public abstract String toString();
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,20 @@
+package org.lcsim.geometry.compact.converter;
+
+/**
+ * 
+ * LCDD geometry visualization information
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ */
+public class SurveyVolumeVisualization {
+	protected String visName = "";
+	public SurveyVolumeVisualization() {}
+	public String getVisName() {
+		return visName;
+	}
+	protected void setVisName(String visName) {
+		this.visName = visName;
+	}
+	
+	
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,44 @@
+package org.lcsim.geometry.compact.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hps.conditions.database.DatabaseConditionsManager;
+import org.hps.conditions.svt.SvtAlignmentConstant;
+import org.hps.conditions.svt.SvtAlignmentConstant.SvtAlignmentConstantCollection;
+import org.lcsim.conditions.ConditionsManager;
+
+/**
+ * Reads in SVT alignment constants from the database and converts them to the {@link MilleParameter} class expected by
+ * the detector model.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+public class SvtAlignmentConstantsReader {
+
+    public List<MilleParameter> readMilleParameters() {
+
+        if (!ConditionsManager.isSetup()) {
+            throw new RuntimeException("Conditions system is not initialized.");
+        }
+
+        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
+
+        System.out.printf("loading alignment parameters with detector: %s; run: %d", manager.getDetector(),
+                manager.getRun());
+
+        final List<MilleParameter> milleParameters = new ArrayList<MilleParameter>();
+
+        final SvtAlignmentConstantCollection alignmentConstants = manager.getCachedConditions(
+                SvtAlignmentConstantCollection.class, "svt_alignments").getCachedData();
+
+        for (final SvtAlignmentConstant constant : alignmentConstants) {
+            final MilleParameter p = new MilleParameter(Integer.parseInt(constant.getParameter()), constant.getValue(),
+                    0.0);
+            milleParameters.add(p);
+            System.out.println("added " + p.toString());
+        }
+
+        return milleParameters;
+    }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,1444 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import static java.lang.Math.PI;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition;
+import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014LCDDBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition;
+import org.lcsim.geometry.compact.converter.HPSTrackerLCDDBuilder;
+import org.lcsim.geometry.compact.converter.lcdd.util.Box;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+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.Volume;
+import org.lcsim.geometry.util.TransformationUtils;
+
+
+/**
+ * 
+ * Convert the HPS Test run tracker 2014 to the LCDD format.
+ * 
+ * @author Per Hansson <[log in to unmask]>
+ *
+ */
+public class HPSTestRunTracker2014 extends HPSTracker2014Base
+{
+	public HPSTestRunTracker2014(Element node) throws JDOMException
+	{
+		super(node);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.lcsim.geometry.compact.converter.lcdd.HPSTracker2014Base#initializeBuilder(org.lcsim.geometry.compact.converter.lcdd.util.LCDD, org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector)
+	 */
+	protected HPSTrackerLCDDBuilder initializeBuilder(LCDD lcdd, SensitiveDetector sens) {
+	    HPSTrackerLCDDBuilder b = new HPSTestRunTracker2014LCDDBuilder(_debug,node,lcdd,sens);
+	    return b;
+	}
+	
+	
+
+	/* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#getModuleNumber(org.lcsim.geometry.compact.converter.JavaSurveyVolume)
+     */
+    protected int getModuleNumber(String surveyVolume) {
+        return HPSTrackerBuilder.getHalfFromName(surveyVolume).equals("top") ? 0 : 1;
+    }
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+	
+	
+	
+	private void makeExample(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+	
+	
+	if(_debug) {
+		System.out.println("--- makeExample ----");
+		
+	}
+
+	
+	
+	String volName = "example";
+	Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+	lcdd.add(box);
+	Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+	
+	
+	
+	 org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisX = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(1., 0., 0.);
+     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisY = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 1., 0.);
+     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZ = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 0., 1.);
+
+     double alpha1 = PI / 4.;
+     double alpha2 = PI / 4.;
+     double alpha3 = -PI / 4.;
+
+     //set up a rotation by alpha1 about the X axis
+     org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(axisX, alpha1);
+
+     // find y' and z'
+     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisYPrime = r1.applyTo(axisY);
+     //org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZPrime = r1.applyTo(axisZ);
+
+     if(_debug) System.out.println("axisYPrime: " + axisYPrime);
+     //if(_debug) System.out.println("axisZPrime: " + axisZPrime);
+
+     //set up a rotation by alpha2 about the Y' axis
+     org.apache.commons.math3.geometry.euclidean.threed.Rotation r2 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(axisYPrime, alpha2);
+
+     //find z''
+     //org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZPrimePrime = r2.applyTo(axisZPrime);
+     //if(_debug) System.out.println("axisZPrimePrime: " + axisZPrimePrime);
+
+     
+     
+     //set up a rotation by alpha3 about the Z'' axis
+     //org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(axisZPrimePrime, alpha3);
+     
+     if(_debug) System.out.println("r1 (XYZ): " + r1.toString());
+     
+     org.apache.commons.math3.geometry.euclidean.threed.Rotation r12 = r2.applyTo(r1);
+     
+     //find z''
+     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZPrimePrime = r12.applyTo(axisZ);
+     if(_debug) System.out.println("axisZPrimePrime: " + axisZPrimePrime);
+     org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(axisZPrimePrime, alpha3);
+     
+     
+     org.apache.commons.math3.geometry.euclidean.threed.Rotation r123 = r3.applyTo(r12);
+     
+     //double [] rotations = r12.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+     double [] rotations = r123.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+     
+     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5,0,0);
+     //Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+     Rotation rot = new Rotation(volName + "_rotation",0,0,0);
+     lcdd.add(pos);
+     lcdd.add(rot);
+	
+	
+     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+     if(_debug) {
+    	 System.out.println("Created physical vomume " + basePV.getName());
+     }
+     
+     
+     
+     
+     volName = volName + "_sub";
+     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+     lcdd.add(boxSub);
+     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+     lcdd.add(subPos);
+     lcdd.add(subRot);
+     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+     if(_debug) {
+    	 System.out.println("Created physical vomume " + subBasePV.getName());
+     }
+	
+     lcdd.add(volumeSub);
+     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+	
+     lcdd.add(volume);
+	
+	
+	
+	
+	}
+	
+	
+	private void makeExample2(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+		
+		
+		if(_debug) {
+			System.out.println("--- makeExample2 ----");
+			
+		}
+		
+		String volName = "example2";
+		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+		lcdd.add(box);
+		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+	    
+
+		
+		 org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisX = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(1., 0., 0.);
+	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisY = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 1., 0.);
+	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZ = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 0., 1.);
+
+	     double alpha1 = PI / 4.;
+	     double alpha2 = PI / 4.;
+	     double alpha3 = -PI / 4.;
+
+	     org.apache.commons.math3.geometry.euclidean.threed.Rotation r123 = 
+	    		 new org.apache.commons.math3.geometry.euclidean.threed.Rotation(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ, 
+	    				 alpha1, 
+	    				 alpha2, 
+	    				 alpha3);
+	     
+	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisXPrime = r123.applyTo(axisX);
+	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisYPrime = r123.applyTo(axisY);
+	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZPrime = r123.applyTo(axisZ);
+
+	     //if(_debug) System.out.println("axisYPrime: " + axisYPrime);
+	     //if(_debug) System.out.println("axisZPrime: " + axisZPrime);
+
+	     
+	     
+	     //double [] rotations = r123.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+	     
+	     
+	     //double [] rotations = r12.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+	     double [] rotations = r123.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+	     
+	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5,0,0);
+	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+	     lcdd.add(pos);
+	     lcdd.add(rot);
+		
+		
+	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + basePV.getName());
+	     }
+		
+	     
+	     
+	     volName = volName + "_sub";
+	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+	     lcdd.add(boxSub);
+	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+	     lcdd.add(subPos);
+	     lcdd.add(subRot);
+	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + subBasePV.getName());
+	     }
+		
+	     lcdd.add(volumeSub);
+	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+	     
+	     lcdd.add(volume);
+
+		
+		
+		
+		}
+		
+		
+		
+	private void makeExample3(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+		
+		
+		if(_debug) {
+			System.out.println("--- makeExample3 ----");
+			
+		}
+		
+		String volName = "example3";
+		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+		lcdd.add(box);
+		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+		
+		/*
+		
+		TestRunModuleL13: survey positions before ref support_plate_top transform
+		Survey pos for module_L1t:
+		ballPos   [      25.000,      676.10,     -4.3500]
+		veePos    [      95.000,      676.10,     -4.3500]
+		flatPos   [      60.000,      670.10,     -4.3500]
+		TestRunModuleL13: Ref support_plate_top coord
+		Coordinate system: 
+		origin [      40.314,      142.71,      138.40]
+		u [     0.99955,    0.030000,      0.0000]
+		v [   -0.030000,     0.99955,      0.0000]
+		w [      0.0000,     -0.0000,      1.0000]
+		TestRunModuleL13: survey positions after ref support_plate_top transform
+		Survey pos for module_L1t:
+		ballPos   [      45.020,      819.25,      134.05]
+		veePos    [      114.99,      821.35,      134.05]
+		flatPos   [      80.184,      814.31,      134.05]
+		TestRunModuleL13: coordinate system:
+		Coordinate system: 
+		origin [      45.020,      819.25,      134.05]
+		u [     0.99955,    0.030000,      0.0000]
+		v [    0.030000,    -0.99955,      0.0000]
+		w [      0.0000,      0.0000,     -1.0000]
+		TestRunModuleL13: translation:
+		[      45.020,      819.25,      134.05]
+		TestRunModuleL13: rotation:
+		[
+		0.999549894704642 0.030000133265350216 0.0
+		0.030000133265350216 -0.999549894704642 0.0
+		0.0 0.0 -1.0
+
+		]
+		
+		
+		
+		LCDDBaseGeom: set position and rotation for volume module_L1t
+getEulerAngles: u [    0.030000,    -0.99955,      0.0000] v[      0.0000,      0.0000,     -1.0000] -> [      0.0000,      1.0000,      0.0000] [      0.0000,      0.0000,      1.0000]
+Input: u {0.03; -1; 0} v {0; 0; -1} u' {0; 1; 0} v' {0; 0; 1}
+rot matrix:
+ 0.999550 0.030000 0.000000
+ 0.030000 -0.999550 0.000000
+ 0.000000 0.000000 -1.000000
+Resulting XYZ angles [     -3.1416,      0.0000,   -0.030005]
+LCDDBaseGeom: box_center_base_local  [      97.600,      0.0000,      29.150]
+LCDDBaseGeom: box_center_base        [      142.58,      822.18,      104.90]
+LCDDBaseGeom: mother center          [      192.50,      608.00,      81.550]
+LCDDBaseGeom: box_center             [     -49.924,      214.18,      23.350]
+LCDDBaseGeom: pos                    [Element: <position/>]
+LCDDBaseGeom: euler                  [     -3.1416,      0.0000,   -0.030005]
+LCDDBaseGeom: rot                    [Element: <rotation/>]
+LCDDBaseGeom: DONE constructing LCDD object module_L1t
+
+		
+
+		*/
+
+		Hep3Vector u = new BasicHep3Vector(1,0,0);
+		Hep3Vector v = new BasicHep3Vector(0,1,0);
+		Hep3Vector w = new BasicHep3Vector(0,0,1);
+		
+		Hep3Vector u_L1 = new BasicHep3Vector(0.99955,    0.030000,      0.0000);
+		Hep3Vector v_L1 = new BasicHep3Vector(0.030000,    -0.99955,      0.0000);
+		Hep3Vector w_L1 = new BasicHep3Vector(0.0000,      0.0000,     -1.0000);
+		
+		
+		
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u_L1.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v_L1.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w_L1.v());
+
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+		
+		Hep3Vector euler_angles = TransformationUtils.getCardanAngles(v_L1, w_L1, v, w);
+		
+		//Get the generic rotation
+		org.apache.commons.math3.geometry.euclidean.threed.Rotation r = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(v_3D_L1,w_3D_L1,v_3D, w_3D);
+		//Get the angles
+		double rotations[] = r.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+		
+		if(_debug) {
+			System.out.println("getEulerAngles gives euler_angles: " + euler_angles.toString());
+			System.out.println("manual          gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+		}
+			  
+		if((rotations[0]-euler_angles.x())>0.00001 || (rotations[1]-euler_angles.y())>0.00001 || (rotations[2]-euler_angles.z())>0.00001) {
+			//System.("closing the loop in apache rotation didn't work!");
+			//throw new RuntimeException("closing the loop in apache rotation didn't work!");
+		}
+		
+		   
+		
+		
+	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*4,0,0);
+	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+	     lcdd.add(pos);
+	     lcdd.add(rot);
+		
+		
+	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + basePV.getName());
+	     }
+		
+	     
+	     
+	     volName = volName + "_sub";
+	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+	     lcdd.add(boxSub);
+	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+	     lcdd.add(subPos);
+	     lcdd.add(subRot);
+	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + subBasePV.getName());
+	     }
+		
+	     lcdd.add(volumeSub);
+	     volumeSub.setVisAttributes(lcdd.getVisAttributes("HybridVis"));
+
+	     lcdd.add(volume);
+		
+		
+		
+		
+		}
+		
+	
+		private void makeExample4(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+		
+		
+		if(_debug) {
+			System.out.println("--- makeExample4 ----");
+			
+		}
+		
+		String volName = "example4";
+		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+		lcdd.add(box);
+		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+	
+		 
+
+		Hep3Vector u = new BasicHep3Vector(1,0,0);
+		Hep3Vector v = new BasicHep3Vector(0,1,0);
+		Hep3Vector w = new BasicHep3Vector(0,0,1);
+	
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+		
+		
+		
+		//set up a rotation about the X axis
+	    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -1.0*Math.PI);
+	     
+	    // find y' and z'
+	    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+	    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+	    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+	    
+	    
+	    double [] rotations = r1.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+	    
+	    
+	    if(_debug) {
+	    	System.out.println("u_3D:       " + u_3D.toString());
+			System.out.println("v_3D:       " + v_3D.toString());
+			System.out.println("w_3D:       " + w_3D.toString());
+			r1.toString();
+			System.out.println("u_3D_p: " + u_3D_p.toString());
+			System.out.println("v_3D_p: " + v_3D_p.toString());
+			System.out.println("w_3D_p: " + w_3D_p.toString());
+			
+			System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+	    }
+	    
+	 	 
+		
+		//apply to unit vector
+		
+	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*2,0,0);
+	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+	     lcdd.add(pos);
+	     lcdd.add(rot);
+		
+		
+	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + basePV.getName());
+	     }
+		
+	     
+	     
+	     
+	     volName = volName + "_sub";
+	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+	     lcdd.add(boxSub);
+	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+	     lcdd.add(subPos);
+	     lcdd.add(subRot);
+	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + subBasePV.getName());
+	     }
+		
+	     lcdd.add(volumeSub);
+	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+	     lcdd.add(volume);
+		
+		
+		
+		
+		}
+		
+	
+		private void makeExample5(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+			
+			
+			if(_debug) {
+				System.out.println("--- makeExample5 ----");
+				
+			}
+			
+			String volName = "example5";
+			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+			lcdd.add(box);
+			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+		
+			 
+
+			Hep3Vector u = new BasicHep3Vector(1,0,0);
+			Hep3Vector v = new BasicHep3Vector(0,1,0);
+			Hep3Vector w = new BasicHep3Vector(0,0,1);
+		
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+			
+			
+			
+			//set up a rotation about the X axis
+		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -1.0*Math.PI);
+		     
+		    // find y' and z'
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+		    
+		    // set up a rotation about the Z axis
+		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D_p, -0.03);
+		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r13 = r3.applyTo(r1);
+		    
+		    
+		    // find y' and z'
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D);
+		    //org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D_p);
+		    //org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D_p);
+		    //org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D_p);
+		    
+		    double [] rotations = r13.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+		    
+		    
+		    if(_debug) {
+		    	System.out.println("u_3D:       " + u_3D.toString());
+				System.out.println("v_3D:       " + v_3D.toString());
+				System.out.println("w_3D:       " + w_3D.toString());
+				r1.toString();
+				System.out.println("u_3D_p: " + u_3D_p.toString());
+				System.out.println("v_3D_p: " + v_3D_p.toString());
+				System.out.println("w_3D_p: " + w_3D_p.toString());
+				r13.toString();
+				System.out.println("u_3D_pp: " + u_3D_pp.toString());
+				System.out.println("v_3D_pp: " + v_3D_pp.toString());
+				System.out.println("w_3D_pp: " + w_3D_pp.toString());
+				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+		    }
+		    
+		 	 
+			
+			//apply to unit vector
+			
+		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*3,0,0);
+		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+		     lcdd.add(pos);
+		     lcdd.add(rot);
+			
+			
+		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + basePV.getName());
+		     }
+			
+		     
+		     volName = volName + "_sub";
+		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+		     lcdd.add(boxSub);
+		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+		     lcdd.add(subPos);
+		     lcdd.add(subRot);
+		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + subBasePV.getName());
+		     }
+			
+		     lcdd.add(volumeSub);
+		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+		     lcdd.add(volume);
+			
+			
+			
+			
+			}
+			
+		
+		
+
+		private void makeExample5b(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+			
+			
+			if(_debug) {
+				System.out.println("--- makeExample5b ----");
+				
+			}
+			
+			String volName = "example5b";
+			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+			lcdd.add(box);
+			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+		
+			 
+
+			Hep3Vector u = new BasicHep3Vector(1,0,0);
+			Hep3Vector v = new BasicHep3Vector(0,1,0);
+			Hep3Vector w = new BasicHep3Vector(0,0,1);
+		
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+			
+			
+			 // set up a rotation about the Z axis
+		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D, -0.03);
+		     
+		    // find y' and z'
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r3.applyTo(u_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r3.applyTo(v_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r3.applyTo(w_3D);
+		    
+		   
+		    
+		    double [] rotations = r3.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+		    
+		    
+		    if(_debug) {
+		    	System.out.println("u_3D:       " + u_3D.toString());
+				System.out.println("v_3D:       " + v_3D.toString());
+				System.out.println("w_3D:       " + w_3D.toString());
+				r3.toString();
+				System.out.println("u_3D_p: " + u_3D_p.toString());
+				System.out.println("v_3D_p: " + v_3D_p.toString());
+				System.out.println("w_3D_p: " + w_3D_p.toString());
+				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+		    }
+		    
+		 	 
+			
+			//apply to unit vector
+			
+		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*3,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1.5,0);
+		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+		     lcdd.add(pos);
+		     lcdd.add(rot);
+			
+			
+		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + basePV.getName());
+		     }
+			
+		     
+		     volName = volName + "_sub";
+		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+		     lcdd.add(boxSub);
+		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+		     lcdd.add(subPos);
+		     lcdd.add(subRot);
+		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + subBasePV.getName());
+		     }
+			
+		     lcdd.add(volumeSub);
+		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+		     lcdd.add(volume);
+			
+			
+			
+			
+			}
+			
+		private void makeExample3b(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+			
+			
+			if(_debug) {
+				System.out.println("--- makeExample3b ----");
+				
+			}
+			
+			String volName = "example3b";
+			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+			lcdd.add(box);
+			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+			
+			/*
+			
+			TestRunModuleL13: survey positions
+Survey pos for module_L1b:
+ballPos   [      25.000,      661.10,      4.3500]
+veePos    [      95.000,      661.10,      4.3500]
+flatPos   [      60.000,      667.10,      4.3500]
+TestRunModuleL13: survey positions before ref support_plate_bottom transform
+Survey pos for module_L1b:
+ballPos   [      25.000,      661.10,      4.3500]
+veePos    [      95.000,      661.10,      4.3500]
+flatPos   [      60.000,      667.10,      4.3500]
+TestRunModuleL13: Ref support_plate_bottom coord
+Coordinate system: 
+origin [      40.314,      142.71,      22.700]
+u [     0.99955,    0.030000,      0.0000]
+v [   -0.030000,     0.99955,      0.0000]
+w [      0.0000,     -0.0000,      1.0000]
+TestRunModuleL13: survey positions after ref support_plate_bottom transform
+Survey pos for module_L1b:
+ballPos   [      45.470,      804.26,      27.050]
+veePos    [      115.44,      806.36,      27.050]
+flatPos   [      80.274,      811.31,      27.050]
+TestRunModuleL13: coordinate system:
+Coordinate system: 
+origin [      45.470,      804.26,      27.050]
+u [     0.99955,    0.030000,      0.0000]
+v [   -0.030000,     0.99955,      0.0000]
+w [      0.0000,      0.0000,      1.0000]
+TestRunModuleL13: translation:
+[      45.470,      804.26,      27.050]
+TestRunModuleL13: rotation:
+[
+0.9995498947046422 -0.030000133265350216 0.0
+0.030000133265350216 0.9995498947046422 0.0
+0.0 0.0 1.0
+
+]
+
+			
+			
+			
+			
+			LCDDBaseGeom: set position and rotation for volume module_L1b
+getEulerAngles: u [   -0.030000,     0.99955,      0.0000] v[      0.0000,      0.0000,      1.0000] -> [      0.0000,      1.0000,      0.0000] [      0.0000,      0.0000,      1.0000]
+Input: u {-0.03; 1; 0} v {0; 0; 1} u' {0; 1; 0} v' {0; 0; 1}
+rot matrix:
+ 0.999550 0.030000 0.000000
+ -0.030000 0.999550 -0.000000
+ -0.000000 0.000000 1.000000
+Resulting XYZ angles [      0.0000,      0.0000,   -0.030005]
+LCDDBaseGeom: box_center_base_local  [      97.600,      0.0000,      29.150]
+LCDDBaseGeom: box_center_base        [      143.03,      807.19,      56.200]
+LCDDBaseGeom: mother center          [      192.50,      608.00,      81.550]
+LCDDBaseGeom: box_center             [     -49.474,      199.19,     -25.350]
+LCDDBaseGeom: pos                    [Element: <position/>]
+LCDDBaseGeom: euler                  [      0.0000,      0.0000,   -0.030005]
+LCDDBaseGeom: rot                    [Element: <rotation/>]
+LCDDBaseGeom: DONE constructing LCDD object module_L1b
+
+		
+
+			
+
+			*/
+
+			Hep3Vector u = new BasicHep3Vector(1,0,0);
+			Hep3Vector v = new BasicHep3Vector(0,1,0);
+			Hep3Vector w = new BasicHep3Vector(0,0,1);
+			
+			Hep3Vector u_L1 = new BasicHep3Vector(0.99955,    0.030000,      0.0000);
+			Hep3Vector v_L1 = new BasicHep3Vector(-0.030000,     0.99955,      0.0000);
+			Hep3Vector w_L1 = new BasicHep3Vector(0.0000,      0.0000,     1.0000);
+			
+			
+			
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u_L1.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v_L1.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w_L1.v());
+
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+			
+			Hep3Vector euler_angles = TransformationUtils.getCardanAngles(v_L1, w_L1, v, w);
+			
+			//Get the generic rotation
+			org.apache.commons.math3.geometry.euclidean.threed.Rotation r = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(v_3D_L1,w_3D_L1,v_3D, w_3D);
+			//Get the angles
+			double rotations[] = r.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+			
+			if(_debug) {
+				System.out.println("getEulerAngles gives euler_angles: " + euler_angles.toString());
+				System.out.println("manual          gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+			}
+				  
+			if((rotations[0]-euler_angles.x())>0.00001 || (rotations[1]-euler_angles.y())>0.00001 || (rotations[2]-euler_angles.z())>0.00001) {
+				//throw new RuntimeException("closing the loop in apache rotation didn't work!");
+			}
+			
+			   
+			
+			
+		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*4,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1.5,0);
+		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+		     lcdd.add(pos);
+		     lcdd.add(rot);
+			
+			
+		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + basePV.getName());
+		     }
+			
+		     
+		     
+		     volName = volName + "_sub";
+		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+		     lcdd.add(boxSub);
+		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+		     lcdd.add(subPos);
+		     lcdd.add(subRot);
+		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + subBasePV.getName());
+		     }
+			
+		     lcdd.add(volumeSub);
+		     volumeSub.setVisAttributes(lcdd.getVisAttributes("HybridVis"));
+
+		     lcdd.add(volume);
+			
+			
+			
+			
+			}
+			
+
+		private void makeExample6(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+		
+		
+		if(_debug) {
+			System.out.println("--- makeExample6 ----");
+			
+		}
+		
+		String volName = "example6";
+		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+		lcdd.add(box);
+		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+	    
+	    double [] rotations = {-0.5*Math.PI,0,0};
+	    
+	    
+	    if(_debug) {
+	
+			
+			System.out.println("manual set lcdd angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+	    }
+	    
+	 	 
+		
+		//apply to unit vector
+		
+	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,0,0);
+	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+	     lcdd.add(pos);
+	     lcdd.add(rot);
+		
+		
+	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + basePV.getName());
+	     }
+		
+	     
+	     
+	     
+	     volName = volName + "_sub";
+	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+	     lcdd.add(boxSub);
+	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+	     lcdd.add(subPos);
+	     lcdd.add(subRot);
+	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + subBasePV.getName());
+	     }
+		
+	     lcdd.add(volumeSub);
+	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+	     lcdd.add(volume);
+		
+		
+		
+		
+		}
+		
+		
+		
+		private void makeExample66(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+			
+			
+			if(_debug) {
+				System.out.println("--- makeExample66 ----");
+				
+			}
+			
+			String volName = "example66";
+			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+			lcdd.add(box);
+			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+		
+			 
+
+			Hep3Vector u = new BasicHep3Vector(1,0,0);
+			Hep3Vector v = new BasicHep3Vector(0,1,0);
+			Hep3Vector w = new BasicHep3Vector(0,0,1);
+		
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+			
+			
+			
+			//set up a rotation about the X axis
+		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -0.5*Math.PI);
+		     
+		    // find y' and z'
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+		    
+		    
+		    double [] rotations = r1.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+		    
+		    
+		    if(_debug) {
+		    	System.out.println("u_3D:       " + u_3D.toString());
+				System.out.println("v_3D:       " + v_3D.toString());
+				System.out.println("w_3D:       " + w_3D.toString());
+				r1.toString();
+				System.out.println("u_3D_p: " + u_3D_p.toString());
+				System.out.println("v_3D_p: " + v_3D_p.toString());
+				System.out.println("w_3D_p: " + w_3D_p.toString());
+				
+				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+		    }
+		    
+		 	 
+			
+			//apply to unit vector
+			
+		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-4,0,0);
+		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+		     lcdd.add(pos);
+		     lcdd.add(rot);
+			
+			
+		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + basePV.getName());
+		     }
+			
+		     
+		     
+		     
+		     volName = volName + "_sub";
+		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+		     lcdd.add(boxSub);
+		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+		     lcdd.add(subPos);
+		     lcdd.add(subRot);
+		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + subBasePV.getName());
+		     }
+			
+		     lcdd.add(volumeSub);
+		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+		     lcdd.add(volume);
+			
+			
+			
+			
+			}
+		
+		
+		
+		
+		
+
+		private void makeExample7(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+		
+		
+		if(_debug) {
+			System.out.println("--- makeExample7 ----");
+			
+		}
+		
+		String volName = "example7";
+		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+		lcdd.add(box);
+		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+	    
+	    double [] rotations = {-0.5*Math.PI,0,-0.25*Math.PI};
+	    
+	    
+	    if(_debug) {
+	
+			
+			System.out.println("manual set lcdd angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+	    }
+	    
+	 	 
+		
+		//apply to unit vector
+		
+	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1,0);
+	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+	     lcdd.add(pos);
+	     lcdd.add(rot);
+		
+		
+	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + basePV.getName());
+	     }
+		
+	     
+	     
+	     
+	     volName = volName + "_sub";
+	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+	     lcdd.add(boxSub);
+	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+	     lcdd.add(subPos);
+	     lcdd.add(subRot);
+	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + subBasePV.getName());
+	     }
+		
+	     lcdd.add(volumeSub);
+	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+	     lcdd.add(volume);
+		
+		
+		
+		
+		}
+		
+		
+		
+	private void makeExample77(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+			
+			
+			if(_debug) {
+				System.out.println("--- makeExample77 ----");
+				
+			}
+			
+			String volName = "example77";
+			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+			lcdd.add(box);
+			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+		
+			 
+
+			Hep3Vector u = new BasicHep3Vector(1,0,0);
+			Hep3Vector v = new BasicHep3Vector(0,1,0);
+			Hep3Vector w = new BasicHep3Vector(0,0,1);
+		
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+			
+			
+			
+			//set up a rotation about the X axis
+		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -0.5*Math.PI);
+		     
+		    // find y' and z'
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+		    
+		    
+		  //set up a rotation about the Z xis
+		   org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D_p, -0.25*Math.PI);
+		   
+		   org.apache.commons.math3.geometry.euclidean.threed.Rotation r13 = r3.applyTo(r1);
+		   
+		   // find y'' and z''
+		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D);
+		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D);
+		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D);
+		    
+		   // find y'' and z'' (cross-check)
+		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp_2 = r3.applyTo(u_3D_p);
+		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp_2 = r3.applyTo(v_3D_p);
+		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp_2 = r3.applyTo(w_3D_p);
+		    
+		    
+		    double [] rotations = r13.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+		    
+		    
+		    if(_debug) {
+		    	System.out.println("u_3D:       " + u_3D.toString());
+				System.out.println("v_3D:       " + v_3D.toString());
+				System.out.println("w_3D:       " + w_3D.toString());
+				r1.toString();
+				System.out.println("u_3D_p: " + u_3D_p.toString());
+				System.out.println("v_3D_p: " + v_3D_p.toString());
+				System.out.println("w_3D_p: " + w_3D_p.toString());
+				r13.toString();
+				System.out.println("u_3D_pp: " + u_3D_pp.toString());
+				System.out.println("v_3D_pp: " + v_3D_pp.toString());
+				System.out.println("w_3D_pp: " + w_3D_pp.toString());
+				
+				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+				
+				System.out.println("u_3D_pp_2: " + u_3D_pp_2.toString());
+				System.out.println("v_3D_pp_2: " + v_3D_pp_2.toString());
+				System.out.println("w_3D_pp_2: " + w_3D_pp_2.toString());
+		    }
+		    
+		 	 
+			
+			//apply to unit vector
+			
+		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-4,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1,0);
+		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+		     lcdd.add(pos);
+		     lcdd.add(rot);
+			
+			
+		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + basePV.getName());
+		     }
+			
+		     
+		     
+		     
+		     volName = volName + "_sub";
+		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+		     lcdd.add(boxSub);
+		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+		     lcdd.add(subPos);
+		     lcdd.add(subRot);
+		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+		     if(_debug) {
+		    	 System.out.println("Created physical vomume " + subBasePV.getName());
+		     }
+			
+		     lcdd.add(volumeSub);
+		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+		     lcdd.add(volume);
+			
+			
+			
+			
+			}
+		
+		
+		
+
+	private void makeExample8(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+	
+	
+	if(_debug) {
+		System.out.println("--- makeExample8 ----");
+		
+	}
+	
+	String volName = "example8";
+	Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+	lcdd.add(box);
+	Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+    
+	
+	Hep3Vector u = new BasicHep3Vector(1,0,0);
+	Hep3Vector v = new BasicHep3Vector(0,1,0);
+	Hep3Vector w = new BasicHep3Vector(0,0,1);
+
+	org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+	org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+	org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+	
+	Hep3Vector u_L1 = new BasicHep3Vector(1/Math.sqrt(2),0,1/Math.sqrt(2));
+	Hep3Vector v_L1 = new BasicHep3Vector(-1/Math.sqrt(2),0,1/Math.sqrt(2));
+	Hep3Vector w_L1 = new BasicHep3Vector(0,-1,0);
+	
+	Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
+	
+	
+    
+    
+    if(_debug) {
+
+		
+		System.out.println("euler angles " + euler_angles.toString());
+
+    }
+    
+ 	 
+	
+	//apply to unit vector
+	
+     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-1,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-3,0);
+     Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
+     lcdd.add(pos);
+     lcdd.add(rot);
+	
+	
+     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+     if(_debug) {
+    	 System.out.println("Created physical vomume " + basePV.getName());
+     }
+	
+     
+     
+     
+     volName = volName + "_sub";
+     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+     lcdd.add(boxSub);
+     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+     lcdd.add(subPos);
+     lcdd.add(subRot);
+     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+     if(_debug) {
+    	 System.out.println("Created physical vomume " + subBasePV.getName());
+     }
+	
+     lcdd.add(volumeSub);
+     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+     lcdd.add(volume);
+	
+	
+	
+	
+	}
+	
+		
+		
+	private void makeExample9(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+		
+		
+		if(_debug) {
+			System.out.println("--- makeExample9 ----");
+			
+		}
+		
+		String volName = "example9";
+		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+		lcdd.add(box);
+		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+	    
+		
+		Hep3Vector u = new BasicHep3Vector(1,0,0);
+		Hep3Vector v = new BasicHep3Vector(0,1,0);
+		Hep3Vector w = new BasicHep3Vector(0,0,1);
+
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+		
+		Hep3Vector u_L1 = new BasicHep3Vector(1,0,0);
+		Hep3Vector v_L1 = new BasicHep3Vector(0,0,1);
+		Hep3Vector w_L1 = new BasicHep3Vector(0,-1,0);
+		
+		Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
+		
+		
+	    
+	    
+	    if(_debug) {
+
+			
+			System.out.println("euler angles " + euler_angles.toString());
+
+	    }
+	    
+	 	 
+		
+		//apply to unit vector
+		
+	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-1,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-2,0);
+	     Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
+	     lcdd.add(pos);
+	     lcdd.add(rot);
+		
+		
+	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + basePV.getName());
+	     }
+		
+	     
+	     
+	     
+	     volName = volName + "_sub";
+	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+	     lcdd.add(boxSub);
+	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+	     lcdd.add(subPos);
+	     lcdd.add(subRot);
+	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + subBasePV.getName());
+	     }
+		
+	     lcdd.add(volumeSub);
+	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+	     lcdd.add(volume);
+		
+		
+		
+		
+		}
+		
+			
+	
+	
+	
+	private void makeExample10(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+		
+		
+		if(_debug) {
+			System.out.println("--- makeExample10 ----");
+			
+		}
+		
+		String volName = "example10";
+		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+		lcdd.add(box);
+		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+	    
+		
+		Hep3Vector u = new BasicHep3Vector(1,0,0);
+		Hep3Vector v = new BasicHep3Vector(0,1,0);
+		Hep3Vector w = new BasicHep3Vector(0,0,1);
+
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+		
+		Hep3Vector u_L1 = new BasicHep3Vector(1/Math.sqrt(2),1/Math.sqrt(2),0);
+		Hep3Vector v_L1 = new BasicHep3Vector(0,0,1);
+		Hep3Vector w_L1 = new BasicHep3Vector(1/Math.sqrt(2),-1/Math.sqrt(2),0);
+		
+		Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
+		
+		
+	    
+	    
+	    if(_debug) {
+
+			
+			System.out.println("euler angles " + euler_angles.toString());
+
+	    }
+	    
+	 	 
+		
+		//apply to unit vector
+		
+	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-2,0);
+	     Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
+	     lcdd.add(pos);
+	     lcdd.add(rot);
+		
+		
+	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + basePV.getName());
+	     }
+		
+	     
+	     
+	     
+	     volName = volName + "_sub";
+	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+	     lcdd.add(boxSub);
+	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+	     lcdd.add(subPos);
+	     lcdd.add(subRot);
+	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+	     if(_debug) {
+	    	 System.out.println("Created physical vomume " + subBasePV.getName());
+	     }
+		
+	     lcdd.add(volumeSub);
+	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+	     lcdd.add(volume);
+		
+		
+		
+		
+		}
+
+   
+			
+	
+	
+			
+	
+
+	
+	
+
+	
+	
+	
+	
+
+}
+
+
+
+
+

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,71 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.geometry.compact.converter.HPSTracker2014LCDDBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerLCDDBuilder;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+
+/**
+ * 
+ * Convert the HPS Test run tracker 2014 to the LCDD format.
+ * 
+ * @author Per Hansson <[log in to unmask]>
+ *
+ */
+public class HPSTracker2014 extends HPSTracker2014Base
+{
+    public HPSTracker2014(Element node) throws JDOMException
+    {
+        super(node);
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.lcdd.HPSTracker2014Base#initializeBuilder(org.lcsim.geometry.compact.converter.lcdd.util.LCDD, org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector)
+     */
+    protected HPSTrackerLCDDBuilder initializeBuilder(LCDD lcdd, SensitiveDetector sens) {
+        HPSTrackerLCDDBuilder b = new HPSTracker2014LCDDBuilder(_debug,node,lcdd,sens);
+        return b;
+    }
+
+    protected int getModuleNumber(String surveyVolume) {
+        boolean isTopLayer = HPSTrackerBuilder.getHalfFromName(surveyVolume).equals("top") ? true : false;
+        int layer = HPSTrackerBuilder.getLayerFromVolumeName(surveyVolume);
+        int moduleNumber = -1;
+        if(isTopLayer) {
+            if(layer < 4 ) {
+                moduleNumber = 0;
+            } else {
+                if(HPSTrackerBuilder.isHoleFromName(surveyVolume)) {
+                    moduleNumber = 2;
+                } else {
+                    moduleNumber = 0;
+                }
+            }
+        } else {
+            if(layer < 4 ) {
+                moduleNumber = 1;
+            } else {
+                if(HPSTrackerBuilder.isHoleFromName(surveyVolume)) {
+                    moduleNumber = 1;
+                } else {
+                    moduleNumber = 3;
+                }
+            }
+        }
+
+        if(moduleNumber<0) throw new RuntimeException("Invalid module nr found for " + surveyVolume);
+
+                return moduleNumber;
+    }
+
+    	
+
+}
+
+
+
+
+

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014Base.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014Base.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014Base.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,383 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.Iterator;
+
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerLCDDBuilder;
+import org.lcsim.geometry.compact.converter.LCDDGhostSurveyVolume;
+import org.lcsim.geometry.compact.converter.LCDDSurveyVolume;
+import org.lcsim.geometry.compact.converter.SurveyCoordinateSystem;
+import org.lcsim.geometry.compact.converter.lcdd.util.Box;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+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.Volume;
+import org.lcsim.geometry.util.TransformationUtils;
+
+/**
+ * 
+ * Convert an HPS tracker "2014" to the LCDD format.
+ * 
+ * @author Per Hansson <[log in to unmask]>
+ *
+ */
+public abstract class HPSTracker2014Base extends LCDDSubdetector {
+
+    protected boolean _debug = true;
+    protected static HPSTrackerLCDDBuilder builder;
+    private final boolean buildBeamPlane = false;
+    private final double beamPlaneWidth = 385.00;
+    private final double beamPlaneLength = 1216.00;
+    private final double beamPlaneThickness = 0.00000001;
+
+    public HPSTracker2014Base(Element c) throws JDOMException {
+        super(c);
+    }
+    
+    
+    /**
+     * Set the @HPSTrackerLCDDBuilder for this converter.
+     * @param lcdd
+     * @param sens
+     * @return the builder.
+     */
+    abstract protected HPSTrackerLCDDBuilder initializeBuilder(LCDD lcdd, SensitiveDetector sens);
+    
+    
+    public boolean isTracker() {
+        return true;
+    }
+    
+    /**
+     * Build the LCDD for the subdetector.
+     * @param lcdd - the LCDD file being created.
+     * @param sens - the SD for this subdetector.
+     */
+    
+    public void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException
+    {
+        
+        
+        
+        /// General comments
+        // Roll: rotation around x
+        // pitch: rotation around y
+        // yaw: rotation around z
+        
+        // kinematic mounts:
+        // ball (constraints x,y,z)
+        // vee  (constraints pitch & yaw)
+        // flat (constraints roll)
+        ///
+        
+        
+        
+        // ID of the detector.
+        int id = node.getAttribute("id").getIntValue();
+
+        // Name of the detector.
+        String detector_name = node.getAttributeValue("name");
+
+        if(_debug) System.out.printf("%s: detector id %d name %s",getClass().getSimpleName(), id,detector_name);
+        
+        
+        // Pick the mother volume (tracking volume).
+        Volume trackingVolume = lcdd.pickMotherVolume(this);
+
+        
+        if(_debug) System.out.printf("%s: setup and build the LCDD geometry\n", getClass().getSimpleName());
+
+        // setup and build the LCDD geometry
+        builder = initializeBuilder(lcdd, sens);
+        //builder = new HPSTestRunTracker2014LCDDBuilder(_debug,node,lcdd,sens);
+        
+        //builder.setLCDD(lcdd);
+        //builder.setSensitiveDetector(sens);
+        builder.build(trackingVolume);
+        
+        if(_debug) System.out.printf("%s: DONE setup and build the LCDD geometry\n", getClass().getSimpleName());
+        
+   
+
+        if(buildBeamPlane ) {
+           makeBeamPlane(trackingVolume, lcdd, sens);
+        }
+        
+        
+        // Actually build the LCDD
+        setupPhysicalVolumes();
+        
+        
+    }
+    
+
+    
+    
+    /**
+     *  Top function to add objects to the LCDD file using the geometry builder class. 
+     */
+    protected void setupPhysicalVolumes() {
+        
+        if(_debug) System.out.printf("%s: buildLCDD\n", getClass().getSimpleName());
+        
+        // Get a reference to the LCDD
+        LCDD lcdd  = builder.getLCDD();
+        SensitiveDetector sd  = builder.getSensitiveDetector();
+
+        // Reference to the top level object in the builder class
+        // In this case it is the base volume holding the entire tracker
+        LCDDSurveyVolume lcddObj  = (LCDDSurveyVolume) builder.getBaseLCDD();
+        
+        // Add the base volume and all its daughters to the LCDD
+        setupPhysicalVolumes(lcddObj,lcdd,sd);
+        
+        if(_debug) System.out.printf("%s: buildLCDD DONE\n", getClass().getSimpleName());
+        
+    }
+    
+   
+
+    /**
+     * Add a @LCDDBaseGeom geometry object to the LCDD file.
+     * @param lcddObj to add
+     * @param lcdd file
+     */
+    private void setupPhysicalVolumes(LCDDSurveyVolume lcddObj, LCDD lcdd, SensitiveDetector sd) {
+        
+        if(_debug) System.out.printf("%s: adding %s to LCDD\n", getClass().getSimpleName(),lcddObj.getName());
+
+        boolean validLCDD = true;
+        
+        if(lcddObj instanceof LCDDGhostSurveyVolume) {
+        
+            if(_debug) System.out.printf("%s: %s is a ghost volume, don't add to LCDD\n", getClass().getSimpleName(),lcddObj.getName());
+            validLCDD = false;
+            
+        } else {
+
+            // Special case for top level volume which is a non-ghost but is already there.
+            if(lcddObj.getName().contains("tracking")) {
+            
+                if(_debug) System.out.printf("%s: %s is the tracking volume, don't add to LCDD\n", getClass().getSimpleName(),lcddObj.getName());
+                validLCDD = false;
+                    
+            } else {
+
+                //X-check
+                if(lcddObj instanceof LCDDGhostSurveyVolume )
+                    throw new RuntimeException("trying to add a ghost volume (" + lcddObj.getName() + ") to LCDD!?");
+                
+                // add box, pos, rotation and create phys volume
+                lcdd.add(lcddObj.getBox());
+                lcdd.add(lcddObj.getPos());
+                lcdd.add(lcddObj.getRot());
+                lcddObj.buildPhysVolume();
+
+                // setup the properties of the phys volume
+                try {
+                    setPhysicalVolumeProperties(lcddObj, sd);
+                } catch (DataConversionException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        
+        // add daughters to this volume
+        
+        if(_debug) System.out.printf("%s: add %d daughters to %s\n", getClass().getSimpleName(),lcddObj.getDaughters().size(),lcddObj.getName());
+
+        for(LCDDSurveyVolume daughter : lcddObj.getDaughters()) {
+            setupPhysicalVolumes(daughter,lcdd, sd);
+        }
+        
+        // finally add volume
+        if(validLCDD) {
+            if(_debug) 
+                System.out.printf("%s: adding volume %s\n", getClass().getSimpleName(),lcddObj.getName());
+            if(!lcddObj.getVisName().isEmpty()) {
+              if(_debug) 
+                System.out.printf("%s: set vis %s for volume %s\n", getClass().getSimpleName(), lcddObj.getVisName(),lcddObj.getName());
+                lcddObj.getVolume().setVisAttributes(lcdd.getVisAttributes(lcddObj.getVisName()));
+              if(_debug) 
+                if(lcdd.getVisAttributes(lcddObj.getVisName())!=null) {
+                    System.out.printf("%s: found vis %s\n", getClass().getSimpleName(), lcdd.getVisAttributes(lcddObj.getVisName()).getAttributeValue("name"));
+                } else {
+                    System.out.printf("%s: vis not found\n", getClass().getSimpleName());
+                }
+            }
+            lcdd.add(lcddObj.getVolume());
+        } else {
+            if(_debug) System.out.printf("%s: don't add volume %s\n", getClass().getSimpleName(),lcddObj.getName());
+        }
+        if(_debug) System.out.printf("%s: DONE adding %s\n", getClass().getSimpleName(),lcddObj.getName());
+    }
+    
+    
+    /**
+     * Set properties of the physical volume.
+     * @param surveyVolume
+     */
+    private void setPhysicalVolumeProperties(LCDDSurveyVolume surveyVolume, SensitiveDetector sd) throws DataConversionException {
+        
+        if(_debug) System.out.printf("%s: setPhysVolumeProperties for name %s\n", getClass().getSimpleName(),surveyVolume.getName());
+        
+        String name = surveyVolume.getName();
+        if(HPSTrackerBuilder.isHalfModule(surveyVolume.getName())) {
+            setHalfModulePhysicalVolumeProperties(surveyVolume);
+        }
+        else if(HPSTrackerBuilder.isActiveSensor(surveyVolume.getName())) {
+            setActiveSensorPhysicalVolumeProperties(surveyVolume, sd);
+        }
+        else if(HPSTrackerBuilder.isSensor(surveyVolume.getName())) {
+            setSensorPhysicalVolumeProperties(surveyVolume);
+        }
+        else if(name.endsWith("lamination")) {
+            surveyVolume.getPhysVolume().addPhysVolID("component", 2);
+        }
+        else if(name.endsWith("cf")) {
+            surveyVolume.getPhysVolume().addPhysVolID("component", 1);
+        }
+        else if(name.endsWith("hybrid")) {
+            surveyVolume.getPhysVolume().addPhysVolID("component", 3);
+        }
+
+        if(_debug) {
+            System.out.printf("%s: %d physvolid's\n", getClass().getSimpleName(),surveyVolume.getPhysVolume().getChildren("physvolid").size());
+            //geomObj.getPhysVolume().getChildren("physvolid field_name="sensor" value="0"")
+            for (Iterator i = surveyVolume.getPhysVolume().getChildren("physvolid").iterator(); i.hasNext();) {        
+                Element e = (Element)i.next();
+                System.out.printf("%s: %s %d\n", getClass().getSimpleName(),e.getAttributeValue("field_name"),e.getAttribute("value").getIntValue());
+            }
+        
+        if(_debug) System.out.printf("%s: DONE setPhysVolumeProperties for name %s\n", getClass().getSimpleName(),surveyVolume.getName());
+            
+        }
+
+        
+    }
+
+    private void setSensorPhysicalVolumeProperties(LCDDSurveyVolume surveyVolume) {
+            surveyVolume.getPhysVolume().addPhysVolID("component", 0);
+    }
+
+
+    private void setActiveSensorPhysicalVolumeProperties(LCDDSurveyVolume surveyVolume, SensitiveDetector sd) {
+        surveyVolume.getPhysVolume().addPhysVolID("sensor", 0);
+        surveyVolume.getVolume().setSensitiveDetector(sd);
+    }
+
+    abstract protected int getModuleNumber(String surveyVolume);
+        
+   
+    
+    
+    private void setHalfModulePhysicalVolumeProperties(LCDDSurveyVolume surveyVolume) throws DataConversionException {
+            PhysVol physVol = surveyVolume.getPhysVolume();
+            int sysId = node.getAttribute("id").getIntValue();
+            
+            //use the old definition of layer number to be consistent
+            int layer = builder._builder.getOldGeomDefLayerFromVolumeName(surveyVolume.getName());
+            if(_debug) System.out.printf("%s: physVolId layer = %d (compare with new layer %d)\n", getClass().getSimpleName(),layer, HPSTrackerBuilder.getLayerFromVolumeName(surveyVolume.getName()));
+            
+            //Find the module number
+            int moduleNumber = getModuleNumber(surveyVolume.getName());
+            
+            physVol.addPhysVolID("system", sysId);
+            physVol.addPhysVolID("barrel", 0);
+            surveyVolume.getPhysVolume().addPhysVolID("layer", layer);
+            surveyVolume.getPhysVolume().addPhysVolID("module", moduleNumber);
+            
+
+    }
+
+
+    protected void makeBeamPlane(Volume motherVolume,  LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        Hep3Vector ball_pos_beamplane = new BasicHep3Vector(-1.0*beamPlaneWidth/2.0,0.0,beamPlaneLength/2.0);
+        Hep3Vector vee_pos_beamplane = new BasicHep3Vector(ball_pos_beamplane.x()+beamPlaneWidth,ball_pos_beamplane.y(),ball_pos_beamplane.z());
+        Hep3Vector flat_pos_beamplane = new BasicHep3Vector(ball_pos_beamplane.x(), ball_pos_beamplane.y(), ball_pos_beamplane.z()-beamPlaneLength/2.0);
+        makeBeamPlane(motherVolume, ball_pos_beamplane, vee_pos_beamplane, flat_pos_beamplane, lcdd, sens);
+    }
+
+    
+    
+    protected void makeBeamPlane(Volume motherVolume, Hep3Vector ball_pos_base_plate, Hep3Vector vee_pos_base_plate,Hep3Vector flat_pos_base_plate, LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+    
+    
+    if(_debug) {
+        System.out.println("--- makeBeamPlane ----");
+        
+    }
+    
+    // create the coordinate system of the beam plane in the tracking volume
+    // since this is a dummy volume it is based on the position of the base plate coordinate system
+    // width - u
+    // length - v
+    // thickness - w
+    Hep3Vector ball_pos_beamplane = ball_pos_base_plate;
+    Hep3Vector vee_pos_beamplane = vee_pos_base_plate; 
+    Hep3Vector flat_pos_beamplane = flat_pos_base_plate;        
+    SurveyCoordinateSystem beamplane_coord = new SurveyCoordinateSystem(ball_pos_beamplane, vee_pos_beamplane, flat_pos_beamplane);     
+    Transform3D trans_beamplane_to_tracking = beamplane_coord.getTransformation();
+    
+    String volName = "beamPlaneVol";
+    //Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*2, beamPlaneThickness);
+    Box box = new Box(volName + "Box", beamPlaneWidth, beamPlaneLength*2, beamPlaneThickness);
+    lcdd.add(box);
+    Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+    
+    
+    if(_debug) {
+        System.out.println(String.format("ball_pos_beamplane %s", ball_pos_beamplane.toString()));
+        System.out.println(String.format("vee_pos_beamplane %s", vee_pos_beamplane.toString()));
+        System.out.println(String.format("flat_pos_beamplane %s", flat_pos_beamplane.toString()));
+        System.out.println(String.format("beamplane_coord:\n%s", beamplane_coord.toString()));
+    }
+
+    
+    // Find distance to center in the local coordinate system 
+    Hep3Vector box_center_base_local = new BasicHep3Vector(beamPlaneWidth/2.0, beamPlaneLength/2.0, beamPlaneThickness/2.0);
+    
+    //translate to the mother coordinate system
+    Hep3Vector box_center_base = trans_beamplane_to_tracking.transformed(box_center_base_local);
+    
+    if(_debug) {
+        System.out.println(String.format("box_center_base_local  %s", box_center_base_local.toString()));
+        System.out.println(String.format("box_center_base        %s", box_center_base.toString()));
+    }
+    
+    // Create the LCDD position
+    Position pos = new Position(volName + "_position",box_center_base.x(), box_center_base.y(), box_center_base.z());
+    
+    //Find LCDD Euler rotation angles from coordinate system unit vectors
+    Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(beamplane_coord.v(), beamplane_coord.w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
+    Rotation rot = new Rotation(volName + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z());
+    lcdd.add(pos);
+    lcdd.add(rot);
+    
+    // Create the physical volume
+    PhysVol basePV = new PhysVol(volume, motherVolume, pos, rot);
+    if(_debug) {
+         System.out.println("Created physical vomume " + basePV.getName());
+     }
+    
+     volume.setVisAttributes(lcdd.getVisAttributes("BeamPlaneVis"));
+
+     lcdd.add(volume);
+    
+    }
+    
+    
+   
+    
+    
+    
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,26 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.geometry.compact.converter.HPSTracker2014v1LCDDBuilder;
+import org.lcsim.geometry.compact.converter.HPSTrackerLCDDBuilder;
+import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
+import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector;
+
+public class HPSTracker2014v1 extends HPSTracker2014
+{
+    public HPSTracker2014v1(Element node) throws JDOMException
+    {
+        super(node);
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.lcdd.HPSTracker2014Base#initializeBuilder(org.lcsim.geometry.compact.converter.lcdd.util.LCDD, org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector)
+     */
+    protected HPSTrackerLCDDBuilder initializeBuilder(LCDD lcdd, SensitiveDetector sens) {
+        return new HPSTracker2014v1LCDDBuilder(_debug,node,lcdd,sens);
+    }
+
+    
+    
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,29 @@
+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 HPSTestRunTracker2014 extends AbstractTracker {
+
+	public HPSTestRunTracker2014(Element node) throws JDOMException 
+	{
+		super(node);
+	}
+
+	public void appendHepRep(HepRepFactory factory, HepRep heprep) 
+	{
+        DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, -1, false, getVisAttributes().getColor());
+	}
+	
+	public boolean isEndcap() {
+		return false;
+	}
+	
+	public boolean isBarrel() {
+		return true;
+	}
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,30 @@
+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 HPSTracker2014 extends AbstractTracker {
+    
+    public HPSTracker2014(Element node) throws JDOMException 
+    {
+        super(node);
+    }
+
+    public void appendHepRep(HepRepFactory factory, HepRep heprep) 
+    {
+        DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, -1, false, getVisAttributes().getColor());
+    }
+    
+    public boolean isEndcap() {
+        return false;
+    }
+    
+    public boolean isBarrel() {
+        return true;
+    }
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014v1.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014v1.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014v1.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,30 @@
+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 HPSTracker2014v1 extends AbstractTracker {
+    
+    public HPSTracker2014v1(Element node) throws JDOMException 
+    {
+        super(node);
+    }
+
+    public void appendHepRep(HepRepFactory factory, HepRep heprep) 
+    {
+        DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, -1, false, getVisAttributes().getColor());
+    }
+    
+    public boolean isEndcap() {
+        return false;
+    }
+    
+    public boolean isBarrel() {
+        return true;
+    }
+
+}

Added: java/branches/HPSJAVA-499/detector-model/src/test/java/org/hps/detector/SvtAlignmentTest.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/test/java/org/hps/detector/SvtAlignmentTest.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/test/java/org/hps/detector/SvtAlignmentTest.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,19 @@
+package org.hps.detector;
+
+import junit.framework.TestCase;
+
+import org.hps.conditions.database.DatabaseConditionsManager;
+
+/**
+ * Test loading SVT alignment constants into the Java detector model.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+public class SvtAlignmentTest extends TestCase {
+
+    public void testSvtAlignment() throws Exception {
+        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
+        // manager.setDetector("HPS-EngRun2015-1_5mm-v1", 5259);
+        manager.setDetector("HPS-EngRun2015-1_5mm-v1", 0);
+    }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,35 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.lcsim.util.test.TestUtil.TestOutputFile;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+*
+* @author Per Hansson Adrian <[log in to unmask]>
+*/
+public class HPSTestRunTracker2014LCDDTest extends TestCase
+{    
+   public HPSTestRunTracker2014LCDDTest(String name)
+   {
+   	super(name);
+   }
+   
+   public static TestSuite suite()
+   {
+       return new TestSuite(HPSTestRunTracker2014LCDDTest.class);
+   }
+   
+   public void test_converter() throws Exception
+   {
+       InputStream in = HPSTestRunTracker2014.class.getResourceAsStream("/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.xml");
+       OutputStream out = new BufferedOutputStream(new FileOutputStream(new TestOutputFile("HPSTestRunTracker2014.lcdd")));
+       new Main().convert("HPSTestRunTracker2014",in,out);
+   }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,35 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.lcsim.util.test.TestUtil.TestOutputFile;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+*
+* @author Per Hansson Adrian <[log in to unmask]>
+*/
+public class HPSTracker2014LCDDTest extends TestCase
+{    
+   public HPSTracker2014LCDDTest(String name)
+   {
+   	super(name);
+   }
+   
+   public static TestSuite suite()
+   {
+       return new TestSuite(HPSTracker2014LCDDTest.class);
+   }
+   
+   public void test_converter() throws Exception
+   {
+       InputStream in = HPSTracker2014.class.getResourceAsStream("/org/lcsim/geometry/subdetector/HPSTracker2014.xml");
+       OutputStream out = new BufferedOutputStream(new FileOutputStream(new TestOutputFile("HPSTracker2014.lcdd")));
+       new Main().convert("HPSTracker2014",in,out);
+   }
+}

Added: java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java
 =============================================================================
--- java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java	(added)
+++ java/branches/HPSJAVA-499/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java	Tue May  5 14:05:24 2015
@@ -0,0 +1,35 @@
+package org.lcsim.geometry.compact.converter.lcdd;
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.lcsim.util.test.TestUtil.TestOutputFile;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+*
+* @author Per Hansson Adrian <[log in to unmask]>
+*/
+public class HPSTracker2014v1LCDDTest extends TestCase
+{    
+   public HPSTracker2014v1LCDDTest(String name)
+   {
+   	super(name);
+   }
+   
+   public static TestSuite suite()
+   {
+       return new TestSuite(HPSTracker2014v1LCDDTest.class);
+   }
+   
+   public void test_converter() throws Exception
+   {
+       InputStream in = HPSTracker2014v1.class.getResourceAsStream("/org/lcsim/geometry/subdetector/HPSTracker2014v1.xml");
+       OutputStream out = new BufferedOutputStream(new FileOutputStream(new TestOutputFile("HPSTracker2014v1.lcdd")));
+       new Main().convert("HPSTracker2014v1",in,out);
+   }
+}