GeomConverter/src/org/lcsim/detector
diff -u -r1.1 -r1.2
--- GeometryInfo.java 4 Mar 2007 05:03:00 -0000 1.1
+++ GeometryInfo.java 4 Mar 2007 12:08:15 -0000 1.2
@@ -81,7 +81,7 @@
}
// Set the support reference.
- this.support = support;
+ this.support = support;
// Cache a PhysicalVolumeNavigator.
navigator = new PhysicalVolumeNavigator(support.getTopVolume());
@@ -182,7 +182,7 @@
/* (non-Javadoc)
* @see org.lcsim.detector.IGeometryInfoTest#hasSupport()
*/
- public boolean hasSupport()
+ public boolean hasPhysicalVolumePath()
{
return support != null;
}
@@ -192,11 +192,16 @@
*/
public boolean isInside(Hep3Vector point)
{
+ //System.out.println("isInside: " + point.toString());
// Get the path from the navigator.
// If the returned path is not equal
// to this GeometryInfo's path, then
// we are not inside this GI's exact
// corresponding PhysicalVolume.
+ //IPhysicalVolumePath path = navigator.getPath(point);
+ //System.out.println("path at point : " + path.toString());
+ //System.out.println("this gi path : " + support.toString());
+ //System.out.println("equals : " + support.equals(navigator.getPath(point)));
return support.equals(navigator.getPath(point));
}
GeomConverter/src/org/lcsim/detector
diff -u -r1.4 -r1.5
--- IGeometryInfo.java 4 Mar 2007 05:03:00 -0000 1.4
+++ IGeometryInfo.java 4 Mar 2007 12:08:15 -0000 1.5
@@ -19,48 +19,146 @@
*
* Additionally, the isInside method will check whether
* a global point is inside the leaf PhysicalVolume in the
- * path.
+ * path, i.e. a specific geometry node associated with
+ * the IGeometryInfo's DetectorElement.
*
* @author Jeremy McCormick <[log in to unmask]>
- *
+ * @author Tim Nelson <[log in to unmask]>
*/
public interface IGeometryInfo
{
- public abstract IGeometryInfoContainer childIGeometryInfos();
-
- public abstract IPhysicalVolumePath getPhysicalVolumePath(
- Hep3Vector global_point);
-
- public abstract ILogicalVolume getLogicalVolume();
-
- public abstract String getLogicalVolumeName();
-
- public abstract IPhysicalVolume getPhysicalVolume(Hep3Vector globalPoint);
-
- public abstract Hep3Vector getPosition();
-
- public abstract IPhysicalVolumePath getPhysicalVolumePath();
-
- public abstract ICoordinateTransformation3D getGlobalToLocal();
-
- public abstract Hep3Vector transformGlobalToLocal(Hep3Vector global_point);
-
- public abstract boolean hasLogicalVolume();
-
- public abstract boolean hasSupport();
-
- public abstract boolean isInside(Hep3Vector point);
-
- public abstract ICoordinateTransformation3D getLocalToGlobal();
-
- public abstract Hep3Vector transformLocalToGlobal(Hep3Vector local_point);
-
- public abstract IGeometryInfo parentIGeometryInfo();
-
- public abstract ICoordinateTransformation3D getParentToLocal();
-
- public abstract Hep3Vector transformParentToLocal(Hep3Vector parentPoint);
+ /**
+ * Get an IGeometryInfoContainer with the child DetectorElement's IGeometryInfo objects.
+ * @return Container of IGeometryInfos from the child DetectorElements.
+ */
+ public IGeometryInfoContainer childIGeometryInfos();
+
+ /**
+ * Get the IPhysicalVolumePath from a global point @param globalPoint.
+ *
+ * @param global_point
+ * @return
+ */
+ public IPhysicalVolumePath getPhysicalVolumePath(
+ Hep3Vector globalPoint);
+
+ /**
+ * Get the associated LogicalVolume.
+ * @return
+ */
+ public ILogicalVolume getLogicalVolume();
+
+ /**
+ * Get the name of the associated LogicalVolume.
+ *
+ * @return
+ */
+ public String getLogicalVolumeName();
+
+ /**
+ * Get the PhysicalVolume at the point @param globalPoint
+ * using the IPhysicalVolumePath of this IGeometryInfo.
+ *
+ * @param globalPoint
+ * @return
+ */
+ public IPhysicalVolume getPhysicalVolume(Hep3Vector globalPoint);
+
+ /**
+ * Get the center position of the DetectorElement.
+ * @return
+ */
+ public Hep3Vector getPosition();
+
+ /**
+ * Get the IPhysicalVolumePath assigned to this GeometryInfo.
+ * This path points to a unique node in the geometry tree
+ * and determines the basic global to local transform
+ * of the DetectorElement.
+ *
+ * @return
+ */
+ public IPhysicalVolumePath getPhysicalVolumePath();
+
+ /**
+ * Get the combined global to local transform.
+ * @return
+ */
+ public ICoordinateTransformation3D getGlobalToLocal();
+
+ /**
+ * Transform the global point @param globalPoint from global
+ * coordinates to local.
+ *
+ * @param global_point
+ * @return
+ */
+ public Hep3Vector transformGlobalToLocal(Hep3Vector globalPoint);
+
+ /**
+ * True if this IGeometryInfo has an associated LogicalVolume.
+ * @return
+ */
+ public boolean hasLogicalVolume();
+
+ /**
+ * True if this IGeometryInfo has an associated full path
+ * or geometry node.
+ *
+ * @return
+ */
+ public boolean hasPhysicalVolumePath();
+
+ /**
+ * True if the @param globalPoint is inside the DetectorElement.
+ * @param point
+ * @return
+ */
+ public boolean isInside(Hep3Vector globalPoint);
+
+ /**
+ * Get the combined local to global transform.
+ * @return
+ */
+ public ICoordinateTransformation3D getLocalToGlobal();
+
+ /**
+ * Get the transformation from parent geometry
+ * into local geometry.
+ *
+ * @return
+ */
+ public ICoordinateTransformation3D getParentToLocal();
- public abstract void setSupport(IPhysicalVolumePath support);
-
+ /**
+ * Transform the local point @param localPoint from local
+ * to global coordinates.
+ *
+ * @param localPoint
+ * @return
+ */
+ public Hep3Vector transformLocalToGlobal(Hep3Vector localPoint);
+
+ /**
+ * Get the parent DetectorElement's IGeometryInfo.
+ * @return
+ */
+ public IGeometryInfo parentIGeometryInfo();
+
+ /**
+ * Transform point in parent geometry @parentPoint into
+ * local geometry.
+ *
+ * @param parentPoint
+ * @return
+ */
+ public Hep3Vector transformParentToLocal(Hep3Vector parentPoint);
+
+ /**
+ * Set the IPhysicalVolumePath with full geometry information
+ * for this DetectorElement.
+ *
+ * @param support
+ */
+ public void setSupport(IPhysicalVolumePath support);
}
\ No newline at end of file
GeomConverter/src/org/lcsim/detector
diff -u -r1.4 -r1.5
--- PhysicalVolumeNavigator.java 4 Mar 2007 05:03:00 -0000 1.4
+++ PhysicalVolumeNavigator.java 4 Mar 2007 12:08:15 -0000 1.5
@@ -2,23 +2,63 @@
import hep.physics.vec.Hep3Vector;
+/**
+ * Navigates from a top or "top" volume
+ * into daughter volumes using String
+ * paths of Physical Volume names. The
+ * returned information is a unique
+ * stack of PhysicalVolume objects, which
+ * is a new PhysicalVolumePath.
+ *
+ * String paths are a series of PhysicalVolume names.
+ *
+ * "/a/b/c"
+ *
+ * Paths do not include an explicit name of the top
+ * volume. The top volume can be addressed with
+ * a single slash, "/", which the getPath method will
+ * interpret to mean top volume of this navigator.
+ *
+ * The LogicalVolume class enforces unique naming of
+ * PhysicalVolume objects within its own daughter collection.
+ *
+ * Locates the deepest daughter volume containing a given
+ * global point within the top volume.
+ *
+ * Computes the combined transform of an IPhysicalVolumePath.
+ *
+ * In theory, the top PhysicalVolume need not be the world
+ * volume. It is referred to as the "top" volume to avoid
+ * confusion.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ *
+ */
public class PhysicalVolumeNavigator
implements IPhysicalVolumeNavigator
{
+ /**
+ * Find the full geometry path to the PhysicalVolume in the tree
+ * containing the global point @param globalPoint, relative to
+ * the top volume.
+ *
+ * @param globalPoint Point in top geometry system.
+ * @param level Depth to descend. -1 means to bottom.
+ */
public IPhysicalVolumePath getPath(Hep3Vector globalPoint, int level)
{
IPhysicalVolumePath path = new PhysicalVolumePath();
- IPhysicalVolume pvWorld = getTopPhysicalVolume();
- ILogicalVolume lvCurr = pvWorld.getLogicalVolume();
+ IPhysicalVolume pvtop = getTopPhysicalVolume();
+ ILogicalVolume lvCurr = pvtop.getLogicalVolume();
- // First time, this compares in world.
+ // First time, this compares in top.
if (lvCurr.getSolid().isInside(globalPoint))
{
- path.add(pvWorld);
+ path.add(pvtop);
}
else {
- // The point is outside the world!
- System.err.println("!!! Point " + globalPoint.v() + " is outside the top volume <"+pvWorld.getName()+">. !!!");
+ // The point is outside the top!
+ System.err.println("!!! Point " + globalPoint.v() + " is outside the top volume <"+pvtop.getName()+">. !!!");
// Return an empty path.
return path;
@@ -38,7 +78,7 @@
{
// Multiply the daughter by the combined
// transform up to this point to get the
- // combined global to local transform.
+ // combined transform.
// !!! Is this correct??? !!!
CoordinateTransformation3D combinedTransform
= CoordinateTransformation3D.multiply(
@@ -46,10 +86,12 @@
(CoordinateTransformation3D)
dau.getTransform());
+ //System.out.println("transformed globalPoint : " + combinedTransform.transformed(globalPoint));
+
// Check if the global point is inside the volume's solid.
// !!! Is this correct??? !!!
if (dau.getLogicalVolume().getSolid().isInside(
- dau.getTransform().transformed(globalPoint)))
+ combinedTransform.inverse().transformed(globalPoint)))
{
inDau=true;
@@ -80,16 +122,30 @@
return path;
}
+ /**
+ * Get the IPhysicalVolumePath to the deepest PhysicalVolume
+ * in the tree containing the global point @param globalPoint,
+ * relative to the top volume.
+ */
public IPhysicalVolumePath getPath(Hep3Vector globalPoint)
{
return getPath(globalPoint,-1);
}
+ /**
+ * Get the combined transform from a String path.
+ * @param path A valid path into the geometry tree.
+ */
public CoordinateTransformation3D getTransform(String path)
{
return getTransform(getPath(path));
}
+ /**
+ * Compute the combined global to local transform from a path of PhysicalVolumes.
+ *
+ * @param path The PhysicalVolumePath containing the unique geometry node.
+ */
public CoordinateTransformation3D getTransform(IPhysicalVolumePath path)
{
CoordinateTransformation3D theTransform = new CoordinateTransformation3D();
@@ -100,8 +156,25 @@
return theTransform;
}
+ /**
+ * Utility method for dealing with strings
+ * containing slash-delimited volume names.
+ * Returns an array containing the name
+ * components. The top volume name is not
+ * included. Single leading and trailing
+ * slashes are discarded to avoid empty
+ * array entries when splitting the path.
+ *
+ * @param path
+ * @return
+ */
private static String[] splitPath(String path)
{
+ if (path.equals("/"))
+ {
+ return new String[] {};
+ }
+
// Eat the first slash.
if (path.startsWith("/"))
{
@@ -111,7 +184,7 @@
// Eat the last slash.
if (path.endsWith("/"))
{
- path = path.substring(0,(path.length()-2));
+ path = path.substring(0,(path.length()-1));
}
//System.out.println("path after eating slashes: "+path);
@@ -120,16 +193,51 @@
return path.split("/");
}
+ /**
+ *
+ * This is the primary method for navigating
+ * using PhysicalVolume names. It looks for
+ * a stack of volumes in the geometry tree with
+ * names matching those in @param path.
+ * The match must be exact. Failure
+ * to find a match throws a RuntimeException.
+ * The top volume name is not included
+ * in the search, but it is added to
+ * the path so that the caller still has
+ * access to the complete geometric tree.
+ *
+ * @param path
+ * @return
+ */
public IPhysicalVolumePath getPath(String[] path)
{
+ //System.out.println("getPath");
+ //System.out.println("path: " + path.toString());
+
+ // The path to be returned to user.
IPhysicalVolumePath physvols = new PhysicalVolumePath();
- IPhysicalVolume pv = getTopPhysicalVolume();
- for (String name : path)
- {
- //System.out.println("looking for physvol = " + name);
+ // The top physical volume.
+ IPhysicalVolume pv = getTopPhysicalVolume();
+
+ // Always add the top volume.
+ physvols.add(pv);
+
+ // Loop over the names in the path.
+ for (String name : path)
+ {
+ //System.out.println("looking for physvol <" + name + "> in <"+pv.getLogicalVolume().getName()+">.");
+ //System.out.println("ndau : " + pv.getLogicalVolume().getNumberOfDaughters());
+
+ // DEBUG
+ //for (IPhysicalVolume dau : pv.getLogicalVolume().getDaughters())
+ //{
+ // System.out.println("dau : " + dau.getName());
+ //}
+
PhysicalVolumeContainer pvSearch =
- pv.getLogicalVolume().getDaughters().findByName(name);
+ pv.getLogicalVolume().getDaughters().findByName(name);
+
if (pvSearch.size() > 1)
{
throw new RuntimeException("Got multiple matches on name <"+name+"> in mom <"+pv.getName() + ">.");
@@ -138,7 +246,7 @@
{
throw new RuntimeException("Path component <"+name+"> was not found!");
}
- else {
+ else {
IPhysicalVolume pvFound = pvSearch.get(0);
//System.out.println("found match = " + pvFound.getName());
physvols.add(pvFound);
@@ -146,18 +254,29 @@
}
}
return physvols;
- }
+ }
+ /**
+ * Get the IPhysicalVolumePath from a String @param path argument.
+ */
public IPhysicalVolumePath getPath(String path)
- {
+ {
return getPath(splitPath(path));
}
+ /**
+ * Get the top volume of this navigator.
+ * @return The top volume's PhysicalVolume.
+ */
public IPhysicalVolume getTopPhysicalVolume()
{
return pvTop;
}
+ /**
+ * Set the top volume of this navigator.
+ * @param A PhysicalVolume that cannot be null.
+ */
public void setTopPhysicalVolume(IPhysicalVolume physvol)
{
if (physvol == null)
@@ -167,6 +286,12 @@
pvTop = physvol;
}
+ /**
+ * Sets the top volume of this navigator
+ * from the top node of an IPhysicalVolumePath.
+ *
+ * @param path
+ */
public void setTopPhysicalVolume(IPhysicalVolumePath path)
{
if (path == null)
@@ -184,11 +309,22 @@
private IPhysicalVolume pvTop;
+ /**
+ * Create a PhysicalVolumeNavigator with @param pvTop
+ * as the top level.
+ * @param pvTop
+ */
public PhysicalVolumeNavigator(IPhysicalVolume pvTop)
{
setTopPhysicalVolume(pvTop);
}
-
+
+ /**
+ * Create a PhysicalVolumeNavigator with the top volume
+ * of @param path as the navigator's top volume.
+ *
+ * @param path
+ */
public PhysicalVolumeNavigator(IPhysicalVolumePath path)
{
setTopPhysicalVolume(path);
GeomConverter/src/org/lcsim/detector
diff -u -r1.2 -r1.3
--- PhysicalVolumePath.java 4 Mar 2007 05:03:00 -0000 1.2
+++ PhysicalVolumePath.java 4 Mar 2007 12:08:15 -0000 1.3
@@ -2,10 +2,24 @@
import java.util.ArrayList;
+/**
+ * An ordered list of PhysicalVolume objects
+ * corresponding to a unique path in a
+ * geometry of LogicalVolumes and
+ * PhysicalVolumes. The first volume
+ * should be the world volume.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ *
+ */
public class PhysicalVolumePath
extends ArrayList<IPhysicalVolume>
implements IPhysicalVolumePath
{
+ /**
+ * Get the top or first volume which is the world volume.
+ * @return The top volume.
+ */
public IPhysicalVolume getTopVolume()
{
if (size()>0)
@@ -17,6 +31,10 @@
}
}
+ /**
+ * Get the bottom or last volume which is the leaf in this path.
+ * @return The leaf volume.
+ */
public IPhysicalVolume getLeafVolume()
{
if (size()>0)
@@ -28,11 +46,25 @@
}
}
+ /**
+ * True if this IPhysicalVolumePath contains no PhysicalVolumes.
+ * @return True if empty.
+ */
public boolean isEmpty()
{
return size()==0;
}
+ /**
+ * Compare with another IPhysicalVolumePath.
+ *
+ * False if path is null, if path is not the same
+ * size as this one, or if any of the PhysicalVolumes
+ * are different PhysicalVolume objects.
+ *
+ * @param path
+ * @return
+ */
public boolean equals(IPhysicalVolumePath path)
{
if (path == null)
@@ -57,12 +89,26 @@
}
public String toString()
- {
+ {
StringBuffer sb = new StringBuffer();
- for (IPhysicalVolume physvol : this)
- {
- sb.append("/"+physvol.getName());
+
+ if (getTopVolume() != null)
+ {
+ if (size() == 1)
+ {
+ sb.append("/");
+ }
+ else {
+ for (int i=1; i<size(); i++)
+ {
+ sb.append("/"+get(i).getName());
+ }
+ }
}
+ else {
+ sb.append("");
+ }
+
return sb.toString();
}
}
\ No newline at end of file