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
|