GeomConverter/src/org/lcsim/detector/converter/compact
diff -u -r1.52 -r1.53
--- DetectorConverter.java 18 Jul 2011 21:01:53 -0000 1.52
+++ DetectorConverter.java 1 Sep 2011 23:58:41 -0000 1.53
@@ -110,6 +110,7 @@
// HPS
addSubdetectorConverter(new HPSEcalConverter());
addSubdetectorConverter(new HPSEcal2Converter());
+ addSubdetectorConverter(new HPSEcal3Converter());
// Support structures.
addSubdetectorConverter(new PolyconeSupportConverter());
GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
diff -u -r1.2 -r1.3
--- HPSEcal3.java 29 Aug 2011 23:06:07 -0000 1.2
+++ HPSEcal3.java 1 Sep 2011 23:58:41 -0000 1.3
@@ -57,7 +57,7 @@
* @author Jeremy McCormick
* @author Tim Nelson
*
- * @version $Id: HPSEcal3.java,v 1.2 2011/08/29 23:06:07 jeremy Exp $
+ * @version $Id: HPSEcal3.java,v 1.3 2011/09/01 23:58:41 jeremy Exp $
*/
public class HPSEcal3 extends LCDDSubdetector
{
@@ -154,7 +154,9 @@
double dy1 = dimensions.getAttribute("y1").getDoubleValue();
double dy2 = dimensions.getAttribute("y2").getDoubleValue();
double dz = dimensions.getAttribute("z").getDoubleValue();
-
+
+ int system = this.getSystemID();
+
// Crystal material.
Element mat = node.getChild("material");
String materialName = mat.getAttributeValue("name");
@@ -298,6 +300,7 @@
PhysVol posCrystalPlacementBot = new PhysVol(crystalLogVol, world, iposBot, irotBot);
// Add volume IDs.
+ posCrystalPlacementBot.addPhysVolID("system", system);
posCrystalPlacementBot.addPhysVolID("ix", ix);
posCrystalPlacementBot.addPhysVolID("iy", -iy);
}
@@ -320,6 +323,7 @@
PhysVol negCrystalPlacementBot = new PhysVol(crystalLogVol, world, iposnegBot, irotnegBot);
// Add volume IDs.
+ negCrystalPlacementBot.addPhysVolID("system", system);
negCrystalPlacementBot.addPhysVolID("ix", -ix);
negCrystalPlacementBot.addPhysVolID("iy", -iy);
}
@@ -338,7 +342,8 @@
// Place positive top crystal.
PhysVol posCrystalPlacementTop = new PhysVol(crystalLogVol, world, iposTop, irotTop);
- // Add volume IDs.
+ // Add volume IDs.
+ posCrystalPlacementTop.addPhysVolID("system", system);
posCrystalPlacementTop.addPhysVolID("ix", ix);
posCrystalPlacementTop.addPhysVolID("iy", iy);
}
@@ -361,6 +366,7 @@
PhysVol negCrystalPlacementTop = new PhysVol(crystalLogVol, world, iposnegTop, irotnegTop);
// Add volume IDs.
+ negCrystalPlacementTop.addPhysVolID("system", system);
negCrystalPlacementTop.addPhysVolID("ix", -ix);
negCrystalPlacementTop.addPhysVolID("iy", iy);
}
GeomConverter/src/org/lcsim/geometry/subdetector
diff -N HPSEcal3.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ HPSEcal3.java 1 Sep 2011 23:58:41 -0000 1.1
@@ -0,0 +1,362 @@
+package org.lcsim.geometry.subdetector;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.lcsim.detector.identifier.IIdentifierHelper;
+import org.lcsim.detector.identifier.Identifier;
+import org.lcsim.geometry.IDDecoder;
+import org.lcsim.geometry.util.IDEncoder;
+
+/**
+ * Reconstruction version of HPS ECal with crystal array.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @author Timothy Nelson <[log in to unmask]>
+ * @version $Id: HPSEcal3.java,v 1.1 2011/09/01 23:58:41 jeremy Exp $
+ */
+public class HPSEcal3 extends AbstractSubdetector
+{
+ private int nx;
+ private int ny;
+ private double beamgap;
+ private double dface;
+ private boolean oddX;
+
+ public static class NeighborMap extends HashMap<Long,Set<Long>>
+ {
+ IIdentifierHelper helper;
+ public NeighborMap(IIdentifierHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ public String toString()
+ {
+ System.out.println("NeighborMap has " + this.size() + " entries.");
+ StringBuffer buff = new StringBuffer();
+ for (long id : this.keySet())
+ {
+ buff.append(helper.unpack(new Identifier(id)))
+ .append("\n");
+ Set<Long> nei = this.get(id);
+ for (long nid : nei)
+ {
+ buff.append(" " + helper.unpack(new Identifier(nid)))
+ .append("\n");
+ }
+ }
+ return buff.toString();
+ }
+ }
+
+ private NeighborMap neighborMap = null;
+
+ HPSEcal3(Element node) throws JDOMException
+ {
+ super(node);
+
+ Element layout = node.getChild("layout");
+
+ nx = layout.getAttribute("nx").getIntValue();
+ ny = layout.getAttribute("ny").getIntValue();
+ beamgap = layout.getAttribute("beamgap").getDoubleValue();
+ dface = layout.getAttribute("dface").getDoubleValue();
+
+ if (nx % 2 != 0)
+ oddX = true;
+ }
+
+ public double distanceToFace()
+ {
+ return dface;
+ }
+
+ public double beamGap()
+ {
+ return beamgap;
+ }
+
+ /**
+ * The number of crystals in X in one section.
+ * @return
+ */
+ public double nx()
+ {
+ return nx;
+ }
+
+ /**
+ * The number of crystals in y in one section.
+ * @return
+ */
+ public double ny()
+ {
+ return ny;
+ }
+
+ // Class for storing neighbor incides in XY and side.
+ static class XY implements Comparator<XY>
+ {
+ int x;
+ int y;
+
+ public XY(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ public int x()
+ {
+ return x;
+ }
+
+ public int y()
+ {
+ return y;
+ }
+
+ public boolean equals(Object o)
+ {
+ XY xy = (XY)o;
+ return xy.x() == x && xy.y() == y;
+ }
+
+ public int compare(XY o1, XY o2)
+ {
+ if (o1.equals(o2))
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ }
+
+ /**
+ * Get the neighbors for a given cell ID. Each crystal not on an edge
+ * has 8 neighbors. Edge crystals have fewer.
+ * @param id The cell ID.
+ * @return A <code>Set</code> containing the cell's neighbors.
+ */
+ Set<Long> getNeighbors(Long id)
+ {
+ // Get the IDDecoder.
+ IDDecoder dec = getIDDecoder();
+
+ // Set the ID.
+ dec.setID(id);
+
+ // Get ID field values.
+ int x = dec.getValue("ix");
+ int y = dec.getValue("iy");
+
+ // Get field indices.
+ int ix = dec.getFieldIndex("ix");
+ int iy = dec.getFieldIndex("iy");
+
+ // Get X, Y, & side neighbor data for this crystal.
+ Set<XY> neighbors = getNeighbors(x, y);
+
+ // Get buffer with values from current ID.
+ int[] buffer = new int[dec.getFieldCount()];
+ dec.getValues(buffer);
+
+ // Create an encoder to make neighbor IDs.
+ IDEncoder enc = new IDEncoder(dec.getIDDescription());
+
+ // Set to hold neighbor IDs.
+ Set<Long> ids = new HashSet<Long>();
+
+ // Loop over neighbor objects to make IDs.
+ for (XY xyside : neighbors)
+ {
+ buffer[ix] = xyside.x;
+ buffer[iy] = xyside.y;
+ long nId = enc.setValues(buffer);
+ ids.add(nId);
+ }
+
+ return ids;
+ }
+
+ Set<XY> getNeighbors(int ix, int iy)
+ {
+ Set<Integer> xneighbors = getXNeighbors(ix);
+ Set<Integer> yneighbors = getYNeighbors(iy);
+
+ Set<XY> neighbors = new HashSet<XY>();
+
+ for (Integer jx : xneighbors)
+ {
+ for (Integer jy : yneighbors)
+ {
+ // Filter out self.
+ if (jx == ix && jy == iy)
+ {
+ continue;
+ }
+
+ neighbors.add(new XY(jx,jy));
+ }
+ }
+
+ return neighbors;
+ }
+
+ Set<Integer> getXNeighbors(int ix)
+ {
+ Set<Integer> neighbors = new HashSet<Integer>();
+
+ // Add self.
+ neighbors.add(ix);
+
+ // Left neighbor.
+ if (isValidX(ix - 1))
+ {
+ neighbors.add(ix - 1);
+ }
+ else if (isValidX(ix - 2))
+ {
+ neighbors.add(ix - 2);
+ }
+
+ // Right neighbor.
+ if (isValidX(ix + 1))
+ {
+ neighbors.add(ix + 1);
+ }
+ else if (isValidX(ix + 2))
+ {
+ neighbors.add(ix + 2);
+ }
+
+ return neighbors;
+ }
+
+ Set<Integer> getYNeighbors(int iy)
+ {
+ Set<Integer> neighbors = new HashSet<Integer>();
+
+ // Add self.
+ neighbors.add(iy);
+
+ // Lower neighbor.
+ if (isValidY(iy - 1))
+ {
+ neighbors.add(iy - 1);
+ }
+
+ // Upper neighbor.
+ if (isValidY(iy + 1))
+ {
+ neighbors.add(iy + 1);
+ }
+
+ return neighbors;
+ }
+
+ boolean isValidY(int iy)
+ {
+ // Zero is not valid because ID scheme goes from 1.
+ return iy >= -ny && iy <= ny && iy != 0;
+ }
+
+ boolean isValidX(int ix)
+ {
+ // Even case.
+ if (!oddX)
+ {
+ return ix >= -nx/2 && ix <= nx/2 && ix != 0;
+ }
+ // Odd case.
+ else
+ {
+ return ix >= (-nx-1)/2 && ix <= (nx+1)/2;
+ }
+ }
+
+ /**
+ * Create a map of crystal IDs to the <code>Set</code> of neighbor crystal IDs.
+ * @return A map of neighbors for each crystal ID.
+ */
+ public NeighborMap getNeighborMap()
+ {
+ if (neighborMap != null)
+ {
+ return neighborMap;
+ }
+
+ // Setup the private instance of the map.
+ neighborMap = new NeighborMap(this.getDetectorElement().getIdentifierHelper());
+
+ IDDecoder dec = getIDDecoder();
+ IDEncoder enc = new IDEncoder(dec.getIDDescription());
+
+ int nfields = dec.getFieldCount();
+ int[] vals = new int[nfields];
+
+ vals[dec.getFieldIndex("system")] = getSystemID();
+
+ int idxx = dec.getFieldIndex("ix");
+ int idxy = dec.getFieldIndex("iy");
+
+ int hnx = nx;
+
+ // Calculate number of X for loop. (from LCDD conv)
+ if (oddX)
+ {
+ hnx -= 1;
+ hnx /= 2;
+ }
+ else
+ {
+ hnx /= 2;
+ }
+
+ //for (int side=-1; side <=1; side++)
+ //{
+ // if (side == 0) continue;
+ // vals[dec.getFieldIndex("side")] = side;
+ // Loop over y.
+ for (int iy = -ny; iy <= ny; iy++)
+ {
+ if (!isValidY(iy))
+ continue;
+
+ int loopx = (int)Math.floor(nx/2);
+ // Loop over x.
+ for (int ix = -loopx; ix <= loopx; ix++)
+ {
+ // Loop for positive and negative x.
+ //for (int j=-1; j<=1; j++)
+ //{
+ // if (j == 0)
+ // continue;
+
+ //System.out.println();
+ if (!isValidX(ix))
+ continue;
+
+ vals[idxx] = ix;
+ vals[idxy] = iy;
+
+ Long id = enc.setValues(vals);
+ Set<Long> neighbors = getNeighbors(id);
+
+ neighborMap.put(id, neighbors);
+ //}
+ }
+ }
+ //}
+
+ return neighborMap;
+ }
+}
\ No newline at end of file
GeomConverter/testResources/org/lcsim/geometry/subdetector
diff -u -r1.1 -r1.2
--- HPSEcal3Test.xml 29 Aug 2011 23:06:28 -0000 1.1
+++ HPSEcal3Test.xml 1 Sep 2011 23:58:42 -0000 1.2
@@ -95,7 +95,7 @@
<material name="LeadTungstate" />
<dimensions x1="ecal_front" y1="ecal_front" x2="ecal_back" y2="ecal_back" z="ecal_z" />
<layout beamgap="20.0*mm" nx="46" ny="5" dface="120.0*cm">
- <remove ixmin="-1" ixmax="4" iymin="-1" iymax="1" />
+ <remove ixmin="2" ixmax="7" iymin="-1" iymax="1" />
</layout>
</detector>
@@ -253,4 +253,8 @@
/>
</fields>
+ <includes>
+ <gdmlFile ref="file:///u1/projects/GeomConverter/HEAD/vacuumChamber.gdml"/>
+ </includes>
+
</lccdd>