LISTSERV mailing list manager LISTSERV 16.5

Help for LCDET-SVN Archives


LCDET-SVN Archives

LCDET-SVN Archives


LCDET-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

LCDET-SVN Home

LCDET-SVN Home

LCDET-SVN  October 2015

LCDET-SVN October 2015

Subject:

r3668 - /projects/lcsim/trunk/tracking/src/main/java/org/lcsim/recon/tracking/seedtracker/MaterialManager.java

From:

[log in to unmask]

Reply-To:

Notification of commits to the lcdet svn repository <[log in to unmask]>

Date:

Tue, 6 Oct 2015 18:38:06 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1448 lines)

Author: [log in to unmask]
Date: Tue Oct  6 11:38:04 2015
New Revision: 3668

Log:
Changes to MaterialManager from classes being moved to HPS.

Modified:
    projects/lcsim/trunk/tracking/src/main/java/org/lcsim/recon/tracking/seedtracker/MaterialManager.java

Modified: projects/lcsim/trunk/tracking/src/main/java/org/lcsim/recon/tracking/seedtracker/MaterialManager.java
 =============================================================================
--- projects/lcsim/trunk/tracking/src/main/java/org/lcsim/recon/tracking/seedtracker/MaterialManager.java	(original)
+++ projects/lcsim/trunk/tracking/src/main/java/org/lcsim/recon/tracking/seedtracker/MaterialManager.java	Tue Oct  6 11:38:04 2015
@@ -26,8 +26,6 @@
 import org.lcsim.geometry.Detector;
 import org.lcsim.geometry.Subdetector;
 import org.lcsim.geometry.subdetector.DiskTracker;
-import org.lcsim.geometry.subdetector.HPSTracker;
-import org.lcsim.geometry.subdetector.HPSTracker2;
 import org.lcsim.geometry.subdetector.MultiLayerTracker;
 import org.lcsim.geometry.subdetector.PolyconeSupport;
 import org.lcsim.geometry.subdetector.SiTrackerBarrel;
@@ -37,57 +35,28 @@
 import org.lcsim.geometry.subdetector.SiTrackerSpectrometer;
 
 /**
- * Rewrite and refactor of Rich's {@link MaterialManager} class to handle Subdetector types. 
- * This class should now group together SiTrackerEndcap2 layers correctly.
- * 
+ * Rewrite and refactor of Rich's {@link MaterialManager} class to handle Subdetector types. This class should now group
+ * together SiTrackerEndcap2 layers correctly.
+ *
  * @author Rich Partridge
  * @author Jeremy McCormick
  * @author Matt Graham
- *
  * @version $Id: MaterialManager.java,v 1.21 2013/07/12 20:47:35 phansson Exp $
  */
-public class MaterialManager
-{
-    // Variables from original MaterialManager class.
-    protected boolean DEBUG = false; // enable debug output to System.out
-    private static final boolean TUBE_ONLY = false; // only use Tube elements
-    // for calculating volume.
-    private List<MaterialPolyconeSegment> _matpc = new ArrayList<MaterialPolyconeSegment>();
-    private List<MaterialCylinder> _matcyl = new ArrayList<MaterialCylinder>();
-    private List<MaterialDisk> _matdsk = new ArrayList<MaterialDisk>();
-    private List<MaterialXPlane> _matxpl = new ArrayList<MaterialXPlane>();
-    private HashMap<ISolid, Double> solid_vol_map = new HashMap<ISolid, Double>(400);
-    private static double _rmax;
-    private static double _zmax = 1800.;
-    private static ITransform3D _detToTrk;
-    
-    private boolean _useDefaultXPlanes = true;
-    /**
-     * VolumeGroup handlers for Subdetector types.
-     */
-    private Map<Class, SubdetectorVolumeGrouper> subdetGroups = new HashMap<Class, SubdetectorVolumeGrouper>();
-
-    /**
-     * Interface for getting the path groupings for different Subdetector types.
-     */
-    private interface SubdetectorVolumeGrouper
-    {
-        List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol);
-    }
+public class MaterialManager {
 
     /**
      * Get the path groupings for barrel Subdetectors with physical layers one level below top. This will handle
      * SiTrackerBarrel and MultiLayerTracker Subdetector types.
      */
-    static private class BarrelLayerVolumeGroup implements SubdetectorVolumeGrouper
-    {
-        public List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol)
-        {
-            List<List<String>> pathGroups = new ArrayList<List<String>>();
-            for (IDetectorElement layer : subdet.getDetectorElement().getChildren())
-            {
-                List<String> layerPaths = new ArrayList<String>();
-                String path = "";
+    public static final class BarrelLayerVolumeGroup implements SubdetectorVolumeGrouper {
+
+        @Override
+        public List<List<String>> getPathGroups(final Subdetector subdet, final IPhysicalVolume topVol) {
+            final List<List<String>> pathGroups = new ArrayList<List<String>>();
+            for (final IDetectorElement layer : subdet.getDetectorElement().getChildren()) {
+                final List<String> layerPaths = new ArrayList<String>();
+                final String path = "";
                 PhysicalVolumeNavigator.getLeafPaths(layerPaths, layer.getGeometry().getPhysicalVolume(), path);
                 pathGroups.add(layerPaths);
             }
@@ -96,78 +65,71 @@
     }
 
     /**
+     * Default VolumeGroup for endcaps with physical layers.
+     */
+    public static final class EndcapVolumeGrouper implements SubdetectorVolumeGrouper {
+
+        @Override
+        public List<List<String>> getPathGroups(final Subdetector subdet, final IPhysicalVolume topVol) {
+            final List<List<String>> pathGroups = new ArrayList<List<String>>();
+            // Positive and negative endcap loop.
+            for (final IDetectorElement endcaps : subdet.getDetectorElement().getChildren()) {
+                // Layer loop.
+                for (final IDetectorElement layer : endcaps.getChildren()) {
+                    final List<String> layerPaths = new ArrayList<String>();
+                    final String path = "";
+                    PhysicalVolumeNavigator.getLeafPaths(layerPaths, layer.getGeometry().getPhysicalVolume(), path);
+                    pathGroups.add(layerPaths);
+                }
+            }
+            return pathGroups;
+        }
+
+    }
+
+    /**
      * Get the path groups for a PolyconeSupport, which is a single path.
      */
-    static private class PolyconeSupportVolumeGrouper implements SubdetectorVolumeGrouper
-    {
-        public List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol)
-        {
-            List<List<String>> pathGroups = new ArrayList<List<String>>();
-            String path = "";
-            List<String> supportPath = new ArrayList<String>();
-            IPhysicalVolume supportPV =
-                    subdet.getDetectorElement().getChildren().get(0).getGeometry().getPhysicalVolume();
+    public static final class PolyconeSupportVolumeGrouper implements SubdetectorVolumeGrouper {
+
+        @Override
+        public List<List<String>> getPathGroups(final Subdetector subdet, final IPhysicalVolume topVol) {
+            final List<List<String>> pathGroups = new ArrayList<List<String>>();
+            final String path = "";
+            final List<String> supportPath = new ArrayList<String>();
+            final IPhysicalVolume supportPV = subdet.getDetectorElement().getChildren().get(0).getGeometry()
+                    .getPhysicalVolume();
             PhysicalVolumeNavigator.getLeafPaths(supportPath, supportPV, path);
             pathGroups.add(supportPath);
             return pathGroups;
         }
     }
-    
+
     /**
      * Get the path groups for SiTrackerEndcap2, which has modules placed directly in the tracking volume.
      */
-    static private class HPSTracker2VolumeGrouper implements SubdetectorVolumeGrouper
-    {
-        public List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol)
-        {
-            System.out.println(this.getClass().getSimpleName() + ".getPathGroups()");
-            List<List<String>> pathGroups = new ArrayList<List<String>>();
-            // Layer loop.
-            for (IDetectorElement layer : subdet.getDetectorElement().getChildren())
-            {
-                List<String> modulePaths = new ArrayList<String>();
-
-                // Module loop.
-                for (IDetectorElement module : layer.getChildren())
-                {
-                    String path = "";
-                    PhysicalVolumeNavigator.getLeafPaths(modulePaths, module.getGeometry().getPhysicalVolume(), path);
-                }
-
-                // Add module paths to this layer.
-                pathGroups.add(modulePaths);
-            }
-            return pathGroups;
-        }
-    }
-
-    /**
-     * Get the path groups for SiTrackerEndcap2, which has modules placed directly in the tracking volume.
-     */
-    static private class SiTrackerEndap2VolumeGrouper implements SubdetectorVolumeGrouper
-    {
-        public List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol)
-        {
-            List<List<String>> pathGroups = new ArrayList<List<String>>();
+    public static final class SiTrackerEndap2VolumeGrouper implements SubdetectorVolumeGrouper {
+
+        @Override
+        public List<List<String>> getPathGroups(final Subdetector subdet, final IPhysicalVolume topVol) {
+            final List<List<String>> pathGroups = new ArrayList<List<String>>();
             // Positive and negative endcap loop.
-            for (IDetectorElement endcaps : subdet.getDetectorElement().getChildren())
-            {
+            for (final IDetectorElement endcaps : subdet.getDetectorElement().getChildren()) {
                 // Layer loop.
-                for (IDetectorElement layer : endcaps.getChildren())
-                {
-                    List<String> modulePaths = new ArrayList<String>();
+                for (final IDetectorElement layer : endcaps.getChildren()) {
+                    final List<String> modulePaths = new ArrayList<String>();
 
                     // Module loop.
-                    for (IDetectorElement module : layer.getChildren())
-                    {
-                        String path = "";
-                        PhysicalVolumeNavigator.getLeafPaths(modulePaths, module.getGeometry().getPhysicalVolume(), path);
+                    for (final IDetectorElement module : layer.getChildren()) {
+                        final String path = "";
+                        PhysicalVolumeNavigator.getLeafPaths(modulePaths, module.getGeometry().getPhysicalVolume(),
+                                path);
                     }
-                    
-                    //for (String p : modulePaths) {
-                    //    System.out.println("adding path: " + p);
-                    //}
-                    
+
+                    // for (String p : modulePaths) {
+                    // System.out.println("adding path: " + p);
+                    // }
+
                     // Add module paths to this layer.
                     pathGroups.add(modulePaths);
                 }
@@ -179,24 +141,21 @@
     /**
      * Get the path groups for SiTrackerFixedTarget2
      */
-    static private class SiTrackerFixedTarget2VolumeGrouper implements SubdetectorVolumeGrouper
-    {
-        public List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol)
-        {
-            List<List<String>> pathGroups = new ArrayList<List<String>>();
+    public static final class SiTrackerFixedTarget2VolumeGrouper implements SubdetectorVolumeGrouper {
+
+        @Override
+        public List<List<String>> getPathGroups(final Subdetector subdet, final IPhysicalVolume topVol) {
+            final List<List<String>> pathGroups = new ArrayList<List<String>>();
             // Positive and negative endcap loop.
-            for (IDetectorElement endcaps : subdet.getDetectorElement().getChildren())
-            {
+            for (final IDetectorElement endcaps : subdet.getDetectorElement().getChildren()) {
                 // Layer loop.
-                for (IDetectorElement layer : endcaps.getChildren())
-                {
-                    List<String> modulePaths = new ArrayList<String>();
+                for (final IDetectorElement layer : endcaps.getChildren()) {
+                    final List<String> modulePaths = new ArrayList<String>();
                     // System.out.println(layer.getName());
 
                     // Module loop.
-                    for (IDetectorElement module : layer.getChildren())
-                    {
-                        String path = "";
+                    for (final IDetectorElement module : layer.getChildren()) {
+                        final String path = "";
                         PhysicalVolumeNavigator.getLeafPaths(modulePaths, module.getGeometry().getPhysicalVolume(),
                                 path);
                     }
@@ -208,54 +167,215 @@
         }
     }
 
-
-    /**
-     * Default VolumeGroup for endcaps with physical layers.
-     */
-    static private class EndcapVolumeGrouper implements SubdetectorVolumeGrouper
-    {
-        public List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol)
-        {
-            List<List<String>> pathGroups = new ArrayList<List<String>>();
-            // Positive and negative endcap loop.
-            for (IDetectorElement endcaps : subdet.getDetectorElement().getChildren())
-            {
-                // Layer loop.
-                for (IDetectorElement layer : endcaps.getChildren())
-                {
-                    List<String> layerPaths = new ArrayList<String>();
-                    String path = "";
-                    PhysicalVolumeNavigator.getLeafPaths(layerPaths, layer.getGeometry().getPhysicalVolume(), path);
-                    pathGroups.add(layerPaths);
-                }
-            }
-            return pathGroups;
-        }
-
-    }
+    /**
+     * Interface for getting the path groupings for different Subdetector types.
+     */
+    public interface SubdetectorVolumeGrouper {
+
+        List<List<String>> getPathGroups(Subdetector subdet, IPhysicalVolume topVol);
+    }
+
+    /**
+     * A UniquePV is a wrapper around IPhysicalVolumePath which provides some convenience methods and caches
+     * transformations.
+     */
+    static class UniquePV {
+
+        IPhysicalVolumeNavigator nav;
+        IPhysicalVolumePath path;
+        ITransform3D transform = null;
+
+        /**
+         * Generates a top-level UniquePV.
+         *
+         * @param root The top-level IPhysicalVolume
+         * @param navigator The IPhysicalVolumeNavigator associated with the detector
+         */
+        public UniquePV(final IPhysicalVolume root, final IPhysicalVolumeNavigator navigator) {
+            path = new PhysicalVolumePath();
+            nav = navigator;
+            path.add(root);
+        }
+
+        /**
+         * Generates a UniquePV from a path. (Shallow copy of path)
+         *
+         * @param path
+         * @param navigator
+         */
+        public UniquePV(final IPhysicalVolumePath path, final IPhysicalVolumeNavigator navigator) {
+            this.path = path;
+            nav = navigator;
+        }
+
+        /**
+         * Creates a UniquePV that is a daughter of the current UniquePV (deep copy made)
+         *
+         * @param daughter
+         * @return
+         */
+        public UniquePV createDaughterUniquePV(final IPhysicalVolume daughter) {
+            final IPhysicalVolumePath np = new PhysicalVolumePath();
+            np.addAll(path);
+            np.add(daughter);
+            return new UniquePV(np, nav);
+        }
+
+        /**
+         * Returns the local-to-global transform
+         *
+         * @return an ITransform3D from local coordinates to global coordinates.
+         */
+        public ITransform3D getLtoGTransform() {
+            if (transform == null) {
+                transform = nav.getTransform(path);
+            }
+            return transform;
+        }
+
+        /**
+         * Returns the IPhysicalVolume (the last element of the path)
+         */
+        public IPhysicalVolume getPV() {
+            return path.getLeafVolume();
+        }
+
+        /**
+         * Returns the solid associated with the physical volume.
+         *
+         * @return
+         */
+        public ISolid getSolid() {
+            return this.getPV().getLogicalVolume().getSolid();
+        }
+
+        /**
+         * Transforms the given vector from local to global coords.
+         *
+         * @param v the untransformed local Hep3Vector
+         * @return the transformed global Hep3Vector
+         */
+        public Hep3Vector localToGlobal(final Hep3Vector v) {
+
+            return this.getLtoGTransform().transformed(v);
+        }
+
+        @Override
+        public String toString() {
+            return path.toString();
+        }
+    }
+
+    /**
+     * A "struct" holding geometry information about lists of physical volumes
+     */
+    class VolumeGroupInfo {
+
+        double rmax = 0.0;
+        double rmin = 1.e10;
+        double vtot = 0.0;
+        double vtot_tube_only = 0.;
+        double weighted_r = 0.0;
+        double weighted_y = 0.0;
+        double weighted_z = 0.0;
+        double X0 = 0.0;
+        double xmax = -1.e10;
+        double xmin = 1.e10;
+        double ymax = -1.e10;
+        // mg 3/14/11 MaterialXPlane info
+        double ymin = 1.e10;
+        double zmax = -1.e10;
+        double zmin = 1.e10;
+
+    }
+
+    /**
+     * A "struct" holding geometry information about a single physical volume
+     */
+    class VolumeInfo {
+
+        double rmax = 0.0;
+        double rmin = 1.e10;
+        double xmax = -1.e10;
+        double xmin = 1.e10;
+        double ymax = -1.e10;
+        // mg 3/14/11 MaterialXPlane info
+        double ymin = 1.e10;
+        double zmax = -1.e10;
+        double zmin = 1.e10;
+    }
+
+    private static ITransform3D _detToTrk;
+    private static double _rmax;
+
+    private static double _zmax = 1800.;
+
+    private static final boolean TUBE_ONLY = false; // only use Tube elements
+
+    public static double getRMax() {
+        return _rmax;
+    }
+
+    public static double getZMax() {
+        return _zmax;
+    }
+
+    private static List<UniquePV> makeUniquePVList(final IPhysicalVolumeNavigator nav,
+            final IPhysicalVolume trackingVol, final List<String> paths) {
+        final List<UniquePV> uniqPVs = new ArrayList<UniquePV>();
+        for (final String path : paths) {
+            /**
+             * Create the path object, prepending tracking volume name, as the paths are relative to Subdetector.
+             */
+            final IPhysicalVolumePath pvPath = nav.getPath("/" + trackingVol.getName() + path);
+
+            /**
+             * Create the UniquePV for MaterialManager.
+             */
+            uniqPVs.add(new UniquePV(pvPath, nav));
+        }
+        return uniqPVs;
+    }
+
+    private final List<MaterialCylinder> _matcyl = new ArrayList<MaterialCylinder>();
+
+    private final List<MaterialDisk> _matdsk = new ArrayList<MaterialDisk>();
+
+    // for calculating volume.
+    private final List<MaterialPolyconeSegment> _matpc = new ArrayList<MaterialPolyconeSegment>();
+
+    private final List<MaterialXPlane> _matxpl = new ArrayList<MaterialXPlane>();
+
+    private boolean _useDefaultXPlanes = true;
+
+    // Variables from original MaterialManager class.
+    protected boolean DEBUG = false; // enable debug output to System.out
+
+    private final HashMap<ISolid, Double> solid_vol_map = new HashMap<ISolid, Double>(400);
+
+    /**
+     * VolumeGroup handlers for Subdetector types.
+     */
+    protected final Map<Class, SubdetectorVolumeGrouper> subdetGroups = new HashMap<Class, SubdetectorVolumeGrouper>();
 
     /**
      * Creates a new instance of MaterialManager
      */
-    public MaterialManager()
-    {
+    public MaterialManager() {
         // Barrels.
-        SubdetectorVolumeGrouper barrelGrouper = new BarrelLayerVolumeGroup();
+        final SubdetectorVolumeGrouper barrelGrouper = new BarrelLayerVolumeGroup();
         subdetGroups.put(SiTrackerBarrel.class, barrelGrouper);
         subdetGroups.put(MultiLayerTracker.class, barrelGrouper);
 
         // Endcaps.
-        SubdetectorVolumeGrouper endcapGrouper = new EndcapVolumeGrouper();
+        final SubdetectorVolumeGrouper endcapGrouper = new EndcapVolumeGrouper();
         subdetGroups.put(SiTrackerEndcap.class, endcapGrouper);
         subdetGroups.put(DiskTracker.class, endcapGrouper);
 
         // SiTrackerEndcap2.
-        SubdetectorVolumeGrouper endcap2Grouper = new SiTrackerEndap2VolumeGrouper();
+        final SubdetectorVolumeGrouper endcap2Grouper = new SiTrackerEndap2VolumeGrouper();
         subdetGroups.put(SiTrackerEndcap2.class, endcap2Grouper);
         subdetGroups.put(SiTrackerSpectrometer.class, endcap2Grouper);
-        subdetGroups.put(HPSTracker.class, endcap2Grouper);
-        
-        subdetGroups.put(HPSTracker2.class, new HPSTracker2VolumeGrouper());
 
         // SiTrackerFixedTarget2.
         subdetGroups.put(SiTrackerFixedTarget2.class, new SiTrackerFixedTarget2VolumeGrouper());
@@ -265,37 +385,73 @@
     }
 
     /**
-     * Turn on/off debugging output.
-     * @param debug True if debugging should be enabled; false if not.
-     */
-    public void setDebug(boolean debug)
-    {
-        this.DEBUG = debug;
-    }
-    
-    public void setDefaultXPlaneUsage(boolean useDefault)
-    {
-        _useDefaultXPlanes = useDefault;
-    }
-
-    /**
-     * Setup tracking volume parameters.
-     * 
-     * @param det The Detector.
-     */
-    private void setupTrackingVolume(Detector det)
-    {
-        // Find the envelope of the tracking volume
-        ISolid trkvol = det.getTrackingVolume().getLogicalVolume().getSolid();
-        if (trkvol instanceof Tube)
-        {
-            Tube trktube = (Tube)trkvol;
-            _rmax = trktube.getOuterRadius();
-            _zmax = trktube.getZHalfLength();
-            if (DEBUG)
-            {
-                System.out.println("Ecal radius = " + _rmax);
-                System.out.println("ECal inner Z = " + _zmax);
+     * Calculates the VolumeGroupInfo for a set of {@link UniquePV} objects.
+     *
+     * @param uniqPVs
+     * @param vgi
+     */
+    private void addVolumeGroupInfo(final List<UniquePV> uniqPVs, final VolumeGroupInfo vgi) {
+        double vtot;
+        if (TUBE_ONLY) {
+            vtot = vgi.vtot_tube_only;
+        } else {
+            vtot = vgi.vtot;
+        }
+
+        // Handle Polycone.
+        if (uniqPVs.get(0).getPV().getLogicalVolume().getSolid() instanceof Polycone) {
+            this.handlePolycone(uniqPVs.get(0).getPV());
+        }
+
+        if (vtot > 0.) {
+
+            // Calculate the average radiation length for this volume
+
+            // Determine if this volume should be modeled as barrel or disk
+            if (this.isXPlane(vgi.xmin, vgi.xmax)) {
+                // Calculate the weighted radius of the elements
+                final double zlen = vgi.zmax - vgi.zmin;
+                final double ylen = vgi.ymax - vgi.ymin;
+                final double thickness = vtot / (ylen * zlen * vgi.X0);
+                final double x = (vgi.xmax + vgi.xmin) / 2;
+
+                if (DEBUG) {
+                    System.out.println("Treating as a XPlane...x0: " + vgi.X0 + "| zmin: " + vgi.zmin + "| zmax: "
+                            + vgi.zmax + "| vtot: " + vtot + "| thickness: " + thickness + "| rmin: " + vgi.rmin
+                            + "| rmax: " + vgi.rmax + "| xmin: " + vgi.xmin + "| xmax: " + vgi.xmax);
+                    System.out.println();
+                }
+                if (!_useDefaultXPlanes) {
+                    if (x > 0.1) {
+                        _matxpl.add(new MaterialXPlane(vgi.ymin, vgi.ymax, vgi.zmin, vgi.zmax, x, thickness));
+                    }
+                } else {
+                    _matxpl.add(new MaterialXPlane(vgi.ymin, vgi.ymax, vgi.zmin, vgi.zmax, x, thickness));
+                }
+            } else if (this.isCylinder(vgi.rmin, vgi.rmax, vgi.zmin, vgi.zmax)) {
+                // Calculate the weighted radius of the elements
+                final double zlen = vgi.zmax - vgi.zmin;
+                final double thickness = vtot / (2. * Math.PI * vgi.weighted_r * zlen * vgi.X0);
+
+                if (DEBUG) {
+                    System.out.println("Treating as a Cylinder...x0: " + vgi.X0 + "| zmin: " + vgi.zmin + "| zmax: "
+                            + vgi.zmax + "| vtot: " + vtot + "| thickness: " + thickness + "| rmin: " + vgi.rmin
+                            + "| rmax: " + vgi.rmax);
+                    System.out.println();
+                }
+
+                _matcyl.add(new MaterialCylinder(null, vgi.weighted_r, vgi.zmin, vgi.zmax, thickness));
+            } else {
+
+                final double thickness = vtot / (Math.PI * (vgi.rmax * vgi.rmax - vgi.rmin * vgi.rmin) * vgi.X0);
+
+                if (DEBUG) {
+                    System.out.println("x0: " + vgi.X0 + "| zmin: " + vgi.zmin + "| zmax: " + vgi.zmax + "| vtot: "
+                            + vtot + "| thickness: " + thickness + "| rmin: " + vgi.rmin + "| rmax: " + vgi.rmax);
+                    System.out.println();
+                }
+
+                _matdsk.add(new MaterialDisk(null, vgi.rmin, vgi.rmax, vgi.weighted_z, thickness));
             }
         }
     }
@@ -303,67 +459,55 @@
     /**
      * Build model using new VolumeGroup interface for each Subdetector type.
      */
-    public void buildModel(Detector det)
-    {
+    public void buildModel(final Detector det) {
         // Get the default navigator.
-        IPhysicalVolumeNavigator nav = PhysicalVolumeNavigatorStore.getInstance().getDefaultNavigator();
+        final IPhysicalVolumeNavigator nav = PhysicalVolumeNavigatorStore.getInstance().getDefaultNavigator();
 
         // Get the tracking volume.
-        IPhysicalVolume trackingVol = det.getTrackingVolume();
+        final IPhysicalVolume trackingVol = det.getTrackingVolume();
 
         // Loop over subdetectors.
-        for (Subdetector subdet : det.getSubdetectorList())
-        {
+        for (final Subdetector subdet : det.getSubdetectorList()) {
             // Only look at Subdetectors in the tracking region.
-            if (subdet.isInsideTrackingVolume())
-            {
-                if (DEBUG)
-                {
+            if (subdet.isInsideTrackingVolume()) {
+                if (DEBUG) {
                     System.out.println();
                     System.out.println(">>>> " + subdet.getName() + " >>>>");
                 }
 
                 // Get the VolumeGrouper for this type.
-                SubdetectorVolumeGrouper subdetGrouper = subdetGroups.get(subdet.getClass());
+                final SubdetectorVolumeGrouper subdetGrouper = subdetGroups.get(subdet.getClass());
 
                 // Can't handle this type.
-                if (subdetGrouper == null)
-                {
+                if (subdetGrouper == null) {
                     System.out.println("WARNING: Can't handle Subdetector of type <"
                             + subdet.getClass().getCanonicalName() + ">.");
-                }
-                else
-                {
-                    if (DEBUG)
-                    {
+                } else {
+                    if (DEBUG) {
                         System.out.println("Found VolumeGrouper <" + subdetGrouper.getClass().getName() + ">.");
                     }
 
                     // Make the list of path groups for this Subdetector.
-                    List<List<String>> pathGroups = subdetGrouper.getPathGroups(subdet, trackingVol);
-
-                    if (DEBUG)
-                    {
+                    final List<List<String>> pathGroups = subdetGrouper.getPathGroups(subdet, trackingVol);
+
+                    if (DEBUG) {
                         System.out.println("Got " + pathGroups.size() + " path groups.");
                     }
 
                     // Loop over path groups.
-                    for (List<String> pathGroup : pathGroups)
-                    {
-                        if (DEBUG)
-                        {
+                    for (final List<String> pathGroup : pathGroups) {
+                        if (DEBUG) {
                             System.out.println("Adding next " + pathGroup.size() + " paths.");
                         }
 
                         // Make the UniquePV list expected by MaterialManager.
-                        List<UniquePV> uniqPVs = makeUniquePVList(nav, trackingVol, pathGroup);
+                        final List<UniquePV> uniqPVs = makeUniquePVList(nav, trackingVol, pathGroup);
 
                         // Calculate VolumeGroupInfo for this path group.
-                        VolumeGroupInfo vgi = performVolumeGroupCalculations(uniqPVs);
+                        final VolumeGroupInfo vgi = this.performVolumeGroupCalculations(uniqPVs);
 
                         // Debug print.
-                        if (DEBUG)
-                        {
+                        if (DEBUG) {
                             System.out.println("VolumeGroupInfo ...");
                             System.out.println("    rmax = " + vgi.rmax);
                             System.out.println("    rmin = " + vgi.rmin);
@@ -383,215 +527,81 @@
 
                         // Add the VolumeGroupInfo, which will setup the
                         // material representation for this set of volumes.
-                        addVolumeGroupInfo(uniqPVs, vgi);
+                        this.addVolumeGroupInfo(uniqPVs, vgi);
                     }
                 }
             }
         }
 
         // Setup the tracking volume.
-        setupTrackingVolume(det);
-    }
-
-    /**
-     * Calculates the VolumeGroupInfo for a set of {@link UniquePV} objects.
-     * @param uniqPVs
-     * @param vgi
-     */
-    private void addVolumeGroupInfo(List<UniquePV> uniqPVs, VolumeGroupInfo vgi)
-    {
-        double vtot;
-        if (TUBE_ONLY)
-        {
-            vtot = vgi.vtot_tube_only;
-        }
-        else
-        {
-            vtot = vgi.vtot;
-        }
-
-        // Handle Polycone.
-        if (uniqPVs.get(0).getPV().getLogicalVolume().getSolid() instanceof Polycone)
-        {
-            handlePolycone(uniqPVs.get(0).getPV());
-        }
-
-        if (vtot > 0.)
-        {
-
-            // Calculate the average radiation length for this volume
-
-            // Determine if this volume should be modeled as barrel or disk
-            if (isXPlane(vgi.xmin, vgi.xmax))
-            {
-                // Calculate the weighted radius of the elements
-                double zlen = vgi.zmax - vgi.zmin;
-                double ylen = vgi.ymax - vgi.ymin;
-                double thickness = vtot / (ylen * zlen * vgi.X0);
-                double x=(vgi.xmax+vgi.xmin)/2;
-
+        this.setupTrackingVolume(det);
+    }
+
+    public List<MaterialCylinder> getMaterialCylinders() {
+        return _matcyl;
+    }
+
+    public List<MaterialDisk> getMaterialDisks() {
+        return _matdsk;
+    }
+
+    public List<MaterialPolyconeSegment> getMaterialPolyconeSegments() {
+        return _matpc;
+    }
+
+    public List<MaterialXPlane> getMaterialXPlanes() {
+        return _matxpl;
+    }
+
+    private double getVolumeOfSolid(final ISolid solid) {
+        if (solid_vol_map.containsKey(solid)) {
+            return solid_vol_map.get(solid).doubleValue();
+        } else {
+            double vol;
+            try {
+                vol = solid.getCubicVolume();
+            } catch (final Exception e) {
+                vol = 0.0;
+            }
+
+            solid_vol_map.put(solid, vol);
+            return vol;
+        }
+
+    }
+
+    // special handling for Polycone...
+    private void handlePolycone(final IPhysicalVolume pv) {
+        final Polycone pc = (Polycone) pv.getLogicalVolume().getSolid();
+        final IMaterial mat = pv.getLogicalVolume().getMaterial();
+
+        // Loop through each segment
+        for (int i = 0; i < pc.getNumberOfZPlanes() - 1; i++) {
+            final ZPlane zp1 = pc.getZPlane(i);
+            final ZPlane zp2 = pc.getZPlane(i + 1);
+
+            final double z1 = zp1.getZ();
+            final double z2 = zp2.getZ();
+            final double vol = Polycone.getSegmentVolume(zp1, zp2);
+            final double zlen = Math.abs(z2 - z1);
+            final double ravg = 0.25 * (zp1.getRMax() + zp1.getRMin() + zp2.getRMax() + zp2.getRMin());
+            final double ang = Math.atan2(0.5 * (zp1.getRMax() + zp1.getRMin() - zp2.getRMax() - zp2.getRMin()), zlen);
+            final double X0 = 10 * mat.getRadiationLength() / mat.getDensity();
+            final double thickness = Math.cos(ang) * vol / (2 * Math.PI * ravg * zlen * X0);
+
+            // This is a cylinder
+            if (zp1.getRMax() == zp2.getRMax() && zp1.getRMin() == zp2.getRMin()) {
+                _matcyl.add(new MaterialCylinder(pv, ravg, Math.min(z1, z2), Math.max(z1, z2), thickness));
                 if (DEBUG) {
-                    System.out.println("Treating as a XPlane...x0: " + vgi.X0 + "| zmin: " + vgi.zmin +
-                            "| zmax: " + vgi.zmax + "| vtot: " + vtot +
-                            "| thickness: " + thickness + "| rmin: " + vgi.rmin +
-                            "| rmax: " + vgi.rmax+
-                            "| xmin: "+vgi.xmin+"| xmax: "+vgi.xmax);
-                    System.out.println();
-                }
-                if(!_useDefaultXPlanes)
-                {
-                if(x>0.1)
-                    _matxpl.add(new MaterialXPlane(vgi.ymin,vgi.ymax, vgi.zmin, vgi.zmax, x, thickness));
-                }
-                else
-                {
-                   _matxpl.add(new MaterialXPlane(vgi.ymin,vgi.ymax, vgi.zmin, vgi.zmax, x, thickness)); 
-                }
-            }
-            else if(isCylinder(vgi.rmin, vgi.rmax, vgi.zmin, vgi.zmax))
-            {
-                // Calculate the weighted radius of the elements
-                double zlen = vgi.zmax - vgi.zmin;
-                double thickness = vtot / (2. * Math.PI * vgi.weighted_r * zlen * vgi.X0);
-
+                    System.out.println("Cylindrical segment of " + pv.getName());
+                    System.out.println("zmin = " + z1 + "| zmax = " + z2 + "| ravg = " + ravg + "| thickness = "
+                            + thickness);
+                }
+
+            } // Otherwise this is a non-cylindrical polycone segment
+            else {
+                _matpc.add(new MaterialPolyconeSegment(pv, zp1, zp2, thickness, ang));
                 if (DEBUG) {
-                    System.out.println("Treating as a Cylinder...x0: " + vgi.X0 + "| zmin: " + vgi.zmin +
-                            "| zmax: " + vgi.zmax + "| vtot: " + vtot +
-                            "| thickness: " + thickness + "| rmin: " + vgi.rmin +
-                            "| rmax: " + vgi.rmax);
-                    System.out.println();
-                }
-
-                _matcyl.add(new MaterialCylinder(null, vgi.weighted_r, vgi.zmin, vgi.zmax, thickness));
-            }
-            else
-            {
-
-                double thickness = vtot / (Math.PI * (vgi.rmax * vgi.rmax - vgi.rmin * vgi.rmin) * vgi.X0);
-
-                if (DEBUG) {
-                    System.out.println("x0: " + vgi.X0 + "| zmin: " + vgi.zmin +
-                            "| zmax: " + vgi.zmax + "| vtot: " + vtot +
-                            "| thickness: " + thickness + "| rmin: " + vgi.rmin +
-                            "| rmax: " + vgi.rmax);
-                    System.out.println();
-                }
-
-                _matdsk.add(new MaterialDisk(null, vgi.rmin, vgi.rmax, vgi.weighted_z, thickness));
-            }
-        }
-    }
-
-    private static List<UniquePV> makeUniquePVList(IPhysicalVolumeNavigator nav, IPhysicalVolume trackingVol,
-            List<String> paths)
-    {
-        List<UniquePV> uniqPVs = new ArrayList<UniquePV>();
-        for (String path : paths)
-        {
-            /**
-             * Create the path object, prepending tracking volume name, as the paths are relative to Subdetector.
-             */
-            IPhysicalVolumePath pvPath = nav.getPath("/" + trackingVol.getName() + path);
-
-            /**
-             * Create the UniquePV for MaterialManager.
-             */
-            uniqPVs.add(new UniquePV(pvPath, nav));
-        }
-        return uniqPVs;
-    }
-
-    public List<MaterialCylinder> getMaterialCylinders()
-    {
-        return _matcyl;
-    }
-
-    public List<MaterialDisk> getMaterialDisks()
-    {
-        return _matdsk;
-    }
-    public List<MaterialXPlane> getMaterialXPlanes()
-    {
-        return _matxpl;
-    }
-
-    public List<MaterialPolyconeSegment> getMaterialPolyconeSegments()
-    {
-        return _matpc;
-    }
-
-    public static double getRMax()
-    {
-        return _rmax;
-    }
-
-    public static double getZMax()
-    {
-        return _zmax;
-    }
-
-    private boolean isCylinder(double rmin, double rmax, double zmin, double zmax)
-    {
-        return (rmax - rmin) * Math.abs(zmax + zmin) < (zmax - zmin) * (rmax + rmin);
-    }
-
-    private boolean isXPlane(double xmin, double xmax)
-    {
-        if(!_useDefaultXPlanes)
-        {
-	if(xmax-xmin<0)
-	    return false; //be default xmax is negative, xmin is positive
-	if(xmax+xmin<50)
-	    return false; //catch short modules...
-	return (xmax-xmin)<50.0;//5cm...
-        }
-        else
-        {
-            return (xmax-xmin)<1.0;//1mm
-        }
-    }
-
-    public void setTransform(ITransform3D transform) {
-        _detToTrk = transform;
-    }
-    // special handling for Polycone...
-    private void handlePolycone(IPhysicalVolume pv)
-    {
-        Polycone pc = (Polycone)pv.getLogicalVolume().getSolid();
-        IMaterial mat = pv.getLogicalVolume().getMaterial();
-
-        // Loop through each segment
-        for (int i = 0; i < pc.getNumberOfZPlanes() - 1; i++ )
-        {
-            ZPlane zp1 = pc.getZPlane(i);
-            ZPlane zp2 = pc.getZPlane(i + 1);
-
-            double z1 = zp1.getZ();
-            double z2 = zp2.getZ();
-            double vol = Polycone.getSegmentVolume(zp1, zp2);
-            double zlen = Math.abs(z2 - z1);
-            double ravg = 0.25 * (zp1.getRMax() + zp1.getRMin() + zp2.getRMax() + zp2.getRMin());
-            double ang = Math.atan2(0.5 * (zp1.getRMax() + zp1.getRMin() - zp2.getRMax() - zp2.getRMin()), zlen);
-            double X0 = 10 * mat.getRadiationLength() / mat.getDensity();
-            double thickness = Math.cos(ang) * vol / (2 * Math.PI * ravg * zlen * X0);
-
-            // This is a cylinder
-            if (zp1.getRMax() == zp2.getRMax() && zp1.getRMin() == zp2.getRMin())
-            {
-                _matcyl.add(new MaterialCylinder(pv, ravg, Math.min(z1, z2), Math.max(z1, z2), thickness));
-                if (DEBUG)
-                {
-                    System.out.println("Cylindrical segment of " + pv.getName());
-                    System.out.println("zmin = " + z1 + "| zmax = " + z2 + "| ravg = " + ravg +
-                            "| thickness = " + thickness);
-                }
-
-            } // Otherwise this is a non-cylindrical polycone segment
-            else
-            {
-                _matpc.add(new MaterialPolyconeSegment(pv, zp1, zp2, thickness, ang));
-                if (DEBUG)
-                {
                     System.out.println("Non-Cylindrical segment of " + pv.getName());
                     System.out.println("ZPlane 1: " + zp1.toString() + "| ZPlane 2: " + zp2.toString()
                             + "| thickness = " + thickness);
@@ -601,165 +611,50 @@
         }
     }
 
-    /**
-     * A "struct" holding geometry information about a single physical volume
-     */
-    class VolumeInfo
-    {
-        double rmax = 0.0;
-        double rmin = 1.e10;
-        double zmin = 1.e10;
-        double zmax = -1.e10;
-        //mg 3/14/11   MaterialXPlane info
-        double ymin = 1.e10;
-        double ymax=-1.e10;
-        double xmin = 1.e10;
-        double xmax=-1.e10;
-    }
-
-    /**
-     * A "struct" holding geometry information about lists of physical volumes
-     */
-    class VolumeGroupInfo
-    {
-        double rmax = 0.0;
-        double rmin = 1.e10;
-        double zmin = 1.e10;
-        double zmax = -1.e10;
-        double X0 = 0.0;
-        double weighted_r = 0.0;
-        double weighted_z = 0.0;
-        double vtot_tube_only = 0.;
-        double vtot = 0.0;
-        //mg 3/14/11   MaterialXPlane info
-        double ymin = 1.e10;
-        double ymax=-1.e10;
-        double xmin = 1.e10;
-        double xmax=-1.e10;
-        double weighted_y = 0.0;
-
-    }
-
-    // This function performs all the calculations on lists of physical volumes
-    private VolumeGroupInfo performVolumeGroupCalculations(List<UniquePV> volgroup)
-    {
-
-        VolumeGroupInfo vgi = new VolumeGroupInfo();
-
-        // If we have a top-level polycone, don't bother doing anything, because
-        // it'll be handled specially
-        if (volgroup.size() == 1 && volgroup.get(0).getSolid() instanceof Polycone)
-        {
-            return vgi;
-        }
-
-        // The normal case
-        double totwgt = 0.0;
-        if (DEBUG && volgroup.isEmpty())
-        {
-            System.out.println("Empty volume group...");
-        }
-        for (UniquePV pv : volgroup)
-        {
-
-            // increment total volume
-            double vol = this.getVolumeOfSolid(pv.getSolid());
-            if (pv.getSolid() instanceof Tube)
-            {
-                vgi.vtot_tube_only += vol;
-            }
-            vgi.vtot += vol;
-            // calculate weighted R / Z / Radiation Length
-            VolumeInfo vi = performVolumeCalculations(pv);
-            IMaterial mat = pv.getPV().getLogicalVolume().getMaterial();
-            double matX0 = 10.0 * mat.getRadiationLength() / mat.getDensity();
-            double wgt = vol / matX0;
-            double z0 = pv.getLtoGTransform().getTranslation().z();
-            vgi.weighted_r += 0.5 * (vi.rmin + vi.rmax) * wgt;
-            vgi.weighted_z += z0 * wgt;
-            totwgt += wgt;
-
-            // grab (z/r)(mins/maxes)
-            vgi.zmin = Math.min(vi.zmin, vgi.zmin);
-            vgi.zmax = Math.max(vi.zmax, vgi.zmax);
-            vgi.rmin = Math.min(vi.rmin, vgi.rmin);
-            vgi.rmax = Math.max(vi.rmax, vgi.rmax);
-            //mg 3/14/11  also store y,x information
-            vgi.ymin = Math.min(vi.ymin, vgi.ymin);
-            vgi.ymax = Math.max(vi.ymax, vgi.ymax);
-            double y0 = pv.getLtoGTransform().getTranslation().y();
-            vgi.weighted_y += y0 * wgt;
-            vgi.xmin = Math.min(vi.xmin, vgi.xmin);
-            vgi.xmax = Math.max(vi.xmax, vgi.xmax);
-        }
-
-        // finish weighted R/Z calculations + perform X0 calculation
-        if (totwgt > 0.)
-        {
-            vgi.weighted_r /= totwgt;
-            vgi.weighted_z /= totwgt;
-            vgi.X0 = vgi.vtot / totwgt;
-            //mg 3/14/11  also y info
-            vgi.weighted_y/=totwgt;
-        }
-
-        return vgi;
-    }
-
-    private double getVolumeOfSolid(ISolid solid)
-    {
-        if (solid_vol_map.containsKey(solid))
-        {
-            return solid_vol_map.get(solid).doubleValue();
-        }
-        else
-        {
-            double vol;
-            try
-            {
-                vol = solid.getCubicVolume();
-            }
-            catch (Exception e)
-            {
-                vol = 0.0;
-            }
-
-            solid_vol_map.put(solid, vol);
-            return vol;
-        }
-
-    }
-
-    private VolumeInfo performVolumeCalculations(UniquePV pv)
-    {
-
-        VolumeInfo vi = new VolumeInfo();
-        ISolid solid = pv.getSolid();
+    private boolean isCylinder(final double rmin, final double rmax, final double zmin, final double zmax) {
+        return (rmax - rmin) * Math.abs(zmax + zmin) < (zmax - zmin) * (rmax + rmin);
+    }
+
+    private boolean isXPlane(final double xmin, final double xmax) {
+        if (!_useDefaultXPlanes) {
+            if (xmax - xmin < 0) {
+                return false; // be default xmax is negative, xmin is positive
+            }
+            if (xmax + xmin < 50) {
+                return false; // catch short modules...
+            }
+            return xmax - xmin < 50.0;// 5cm...
+        } else {
+            return xmax - xmin < 1.0;// 1mm
+        }
+    }
+
+    private VolumeInfo performVolumeCalculations(final UniquePV pv) {
+
+        final VolumeInfo vi = new VolumeInfo();
+        final ISolid solid = pv.getSolid();
 
         // ASSUMPTION: tube is along z-axis and has center at r = 0
-        if (solid instanceof Tube)
-        {
-            Tube tube = (Tube)solid;
-            double z0 = pv.getLtoGTransform().getTranslation().z();
+        if (solid instanceof Tube) {
+            final Tube tube = (Tube) solid;
+            final double z0 = pv.getLtoGTransform().getTranslation().z();
             vi.zmax = z0 + tube.getZHalfLength();
             vi.zmin = z0 - tube.getZHalfLength();
             vi.rmin = tube.getInnerRadius();
             vi.rmax = tube.getOuterRadius();
-        }
-        else if (solid instanceof Box)
-        {
-            Box box = (Box)solid;
-            for (Point3D p : box.getVertices())
-            {
-                Hep3Vector transformed = pv.localToGlobal(p.getHep3Vector());
-                if (_detToTrk != null)
+        } else if (solid instanceof Box) {
+            final Box box = (Box) solid;
+            for (final Point3D p : box.getVertices()) {
+                final Hep3Vector transformed = pv.localToGlobal(p.getHep3Vector());
+                if (_detToTrk != null) {
                     _detToTrk.transform(transformed);
+                }
                 vi.zmin = Math.min(transformed.z(), vi.zmin);
                 vi.zmax = Math.max(transformed.z(), vi.zmax);
-                double r = Math.sqrt(transformed.x() * transformed.x() + transformed.y() * transformed.y());
+                final double r = Math.sqrt(transformed.x() * transformed.x() + transformed.y() * transformed.y());
                 vi.rmin = Math.min(vi.rmin, r);
                 vi.rmax = Math.max(vi.rmax, r);
-                 //mg 1/23/12  also store ymin,ymax
+                // mg 1/23/12 also store ymin,ymax
                 vi.ymin = Math.min(transformed.y(), vi.ymin);
                 vi.ymax = Math.max(transformed.y(), vi.ymax);
                 vi.xmin = Math.min(transformed.x(), vi.xmin);
@@ -767,21 +662,19 @@
 
             }
 
-        }
-        else if (solid instanceof Trd)
-        {
-            Trd box = (Trd)solid;
-            for (Point3D p : box.getVertices())
-            {
-                Hep3Vector transformed = pv.localToGlobal(p.getHep3Vector());
-                if (_detToTrk != null)
+        } else if (solid instanceof Trd) {
+            final Trd box = (Trd) solid;
+            for (final Point3D p : box.getVertices()) {
+                final Hep3Vector transformed = pv.localToGlobal(p.getHep3Vector());
+                if (_detToTrk != null) {
                     _detToTrk.transform(transformed);
+                }
                 vi.zmin = Math.min(transformed.z(), vi.zmin);
                 vi.zmax = Math.max(transformed.z(), vi.zmax);
-                double r = Math.sqrt(transformed.x() * transformed.x() + transformed.y() * transformed.y());
+                final double r = Math.sqrt(transformed.x() * transformed.x() + transformed.y() * transformed.y());
                 vi.rmin = Math.min(vi.rmin, r);
                 vi.rmax = Math.max(vi.rmax, r);
-                //mg 3/14/11  also store ymin,ymax
+                // mg 3/14/11 also store ymin,ymax
                 vi.ymin = Math.min(transformed.y(), vi.ymin);
                 vi.ymax = Math.max(transformed.y(), vi.ymax);
                 vi.xmin = Math.min(transformed.x(), vi.xmin);
@@ -793,16 +686,13 @@
         // The information here will only be used in case a top-level element
         // has a subelement that is a Polycone, in which case it'll be
         // approximated as the smallest possible cylinder.
-        else if (solid instanceof Polycone)
-        {
-            Polycone pc = (Polycone)solid;
-            List<Polycone.ZPlane> zplanes = pc.getZPlanes();
+        else if (solid instanceof Polycone) {
+            final Polycone pc = (Polycone) solid;
+            final List<Polycone.ZPlane> zplanes = pc.getZPlanes();
 
             // For now, just take the minimum rmin and rmax of the polycone
-            for (Polycone.ZPlane z : zplanes)
-            {
-                if (z.getRMax() > 0 && z.getRMin() > 0)
-                {
+            for (final Polycone.ZPlane z : zplanes) {
+                if (z.getRMax() > 0 && z.getRMin() > 0) {
                     vi.rmin = Math.min(vi.rmin, z.getRMin());
                     vi.rmax = vi.rmax > 0. ? Math.min(vi.rmax, z.getRMax()) : z.getRMax();
                 }
@@ -813,9 +703,8 @@
             vi.zmax = pc.getZPlanes().get(pc.getZPlanes().size() - 1).getZ();
 
             // check for wrong order
-            if (vi.zmin > vi.zmax)
-            {
-                double temp = vi.zmin;
+            if (vi.zmin > vi.zmax) {
+                final double temp = vi.zmin;
                 vi.zmin = vi.zmax;
                 vi.zmax = temp;
             }
@@ -825,104 +714,99 @@
         return vi;
     }
 
-    /**
-     * A UniquePV is a wrapper around IPhysicalVolumePath which provides some convenience methods and caches
-     * transformations.
-     */
-    static class UniquePV
-    {
-
-        IPhysicalVolumePath path;
-        IPhysicalVolumeNavigator nav;
-        ITransform3D transform = null;
-
-        /**
-         * Generates a top-level UniquePV.
-         * 
-         * @param root The top-level IPhysicalVolume
-         * @param navigator The IPhysicalVolumeNavigator associated with the detector
-         */
-        public UniquePV(IPhysicalVolume root, IPhysicalVolumeNavigator navigator)
-        {
-            path = new PhysicalVolumePath();
-            nav = navigator;
-            path.add(root);
-        }
-
-        /**
-         * Generates a UniquePV from a path. (Shallow copy of path)
-         * 
-         * @param path
-         * @param navigator
-         */
-        public UniquePV(IPhysicalVolumePath path, IPhysicalVolumeNavigator navigator)
-        {
-            this.path = path;
-            nav = navigator;
-        }
-
-        /**
-         * Returns the IPhysicalVolume (the last element of the path)
-         */
-        public IPhysicalVolume getPV()
-        {
-            return path.getLeafVolume();
-        }
-
-        /**
-         * Creates a UniquePV that is a daughter of the current UniquePV (deep copy made)
-         * 
-         * @param daughter
-         * @return
-         */
-        public UniquePV createDaughterUniquePV(IPhysicalVolume daughter)
-        {
-            IPhysicalVolumePath np = new PhysicalVolumePath();
-            np.addAll(path);
-            np.add(daughter);
-            return new UniquePV(np, nav);
-        }
-
-        /**
-         * Transforms the given vector from local to global coords.
-         * 
-         * @param v the untransformed local Hep3Vector
-         * @return the transformed global Hep3Vector
-         */
-        public Hep3Vector localToGlobal(Hep3Vector v)
-        {
-
-            return getLtoGTransform().transformed(v);
-        }
-
-        /**
-         * Returns the solid associated with the physical volume.
-         * 
-         * @return
-         */
-        public ISolid getSolid()
-        {
-            return this.getPV().getLogicalVolume().getSolid();
-        }
-
-        /**
-         * Returns the local-to-global transform
-         * 
-         * @return an ITransform3D from local coordinates to global coordinates.
-         */
-        public ITransform3D getLtoGTransform()
-        {
-            if (transform == null)
-            {
-                transform = nav.getTransform(path);
-            }
-            return transform;
-        }
-
-        @Override
-        public String toString()
-        {
-            return path.toString();
+    // This function performs all the calculations on lists of physical volumes
+    private VolumeGroupInfo performVolumeGroupCalculations(final List<UniquePV> volgroup) {
+
+        final VolumeGroupInfo vgi = new VolumeGroupInfo();
+
+        // If we have a top-level polycone, don't bother doing anything, because
+        // it'll be handled specially
+        if (volgroup.size() == 1 && volgroup.get(0).getSolid() instanceof Polycone) {
+            return vgi;
+        }
+
+        // The normal case
+        double totwgt = 0.0;
+        if (DEBUG && volgroup.isEmpty()) {
+            System.out.println("Empty volume group...");
+        }
+        for (final UniquePV pv : volgroup) {
+
+            // increment total volume
+            final double vol = this.getVolumeOfSolid(pv.getSolid());
+            if (pv.getSolid() instanceof Tube) {
+                vgi.vtot_tube_only += vol;
+            }
+            vgi.vtot += vol;
+            // calculate weighted R / Z / Radiation Length
+            final VolumeInfo vi = this.performVolumeCalculations(pv);
+            final IMaterial mat = pv.getPV().getLogicalVolume().getMaterial();
+            final double matX0 = 10.0 * mat.getRadiationLength() / mat.getDensity();
+            final double wgt = vol / matX0;
+            final double z0 = pv.getLtoGTransform().getTranslation().z();
+            vgi.weighted_r += 0.5 * (vi.rmin + vi.rmax) * wgt;
+            vgi.weighted_z += z0 * wgt;
+            totwgt += wgt;
+
+            // grab (z/r)(mins/maxes)
+            vgi.zmin = Math.min(vi.zmin, vgi.zmin);
+            vgi.zmax = Math.max(vi.zmax, vgi.zmax);
+            vgi.rmin = Math.min(vi.rmin, vgi.rmin);
+            vgi.rmax = Math.max(vi.rmax, vgi.rmax);
+            // mg 3/14/11 also store y,x information
+            vgi.ymin = Math.min(vi.ymin, vgi.ymin);
+            vgi.ymax = Math.max(vi.ymax, vgi.ymax);
+            final double y0 = pv.getLtoGTransform().getTranslation().y();
+            vgi.weighted_y += y0 * wgt;
+            vgi.xmin = Math.min(vi.xmin, vgi.xmin);
+            vgi.xmax = Math.max(vi.xmax, vgi.xmax);
+        }
+
+        // finish weighted R/Z calculations + perform X0 calculation
+        if (totwgt > 0.) {
+            vgi.weighted_r /= totwgt;
+            vgi.weighted_z /= totwgt;
+            vgi.X0 = vgi.vtot / totwgt;
+            // mg 3/14/11 also y info
+            vgi.weighted_y /= totwgt;
+        }
+
+        return vgi;
+    }
+
+    /**
+     * Turn on/off debugging output.
+     *
+     * @param debug True if debugging should be enabled; false if not.
+     */
+    public void setDebug(final boolean debug) {
+        this.DEBUG = debug;
+    }
+
+    public void setDefaultXPlaneUsage(final boolean useDefault) {
+        _useDefaultXPlanes = useDefault;
+    }
+
+    public void setTransform(final ITransform3D transform) {
+        _detToTrk = transform;
+    }
+
+    /**
+     * Setup tracking volume parameters.
+     *
+     * @param det The Detector.
+     */
+    private void setupTrackingVolume(final Detector det) {
+        // Find the envelope of the tracking volume
+        final ISolid trkvol = det.getTrackingVolume().getLogicalVolume().getSolid();
+        if (trkvol instanceof Tube) {
+            final Tube trktube = (Tube) trkvol;
+            _rmax = trktube.getOuterRadius();
+            _zmax = trktube.getZHalfLength();
+            if (DEBUG) {
+                System.out.println("Ecal radius = " + _rmax);
+                System.out.println("ECal inner Z = " + _zmax);
+            }
         }
     }
 }

########################################################################
Use REPLY-ALL to reply to list

To unsubscribe from the LCDET-SVN list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCDET-SVN&A=1

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use