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  February 2015

LCDET-SVN February 2015

Subject:

r3553 - in /projects/lcsim/trunk/detector-framework: ./ src/main/java/org/lcsim/detector/converter/compact/ src/test/java/org/lcsim/detector/converter/compact/ src/test/java/org/lcsim/geometry/subdetector/ src/test/resources/org/lcsim/geometry/subdetector/

From:

[log in to unmask]

Reply-To:

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

Date:

Tue, 24 Feb 2015 01:39:06 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (792 lines)

Author: [log in to unmask]
Date: Mon Feb 23 17:38:59 2015
New Revision: 3553

Log:
Add HPS ECAL geometry API including crystal neighboring.  HPSJAVA-417, LCSIM-243

Added:
    projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalAPI.java
    projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalDetectorElement.java
    projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/detector/converter/compact/HPSEcalAPITest.java
Modified:
    projects/lcsim/trunk/detector-framework/pom.xml
    projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/EcalCrystal.java
    projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcal3Converter.java
    projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/geometry/subdetector/HPSEcal3Test.java
    projects/lcsim/trunk/detector-framework/src/test/resources/org/lcsim/geometry/subdetector/HPSEcal3Test.xml

Modified: projects/lcsim/trunk/detector-framework/pom.xml
 =============================================================================
--- projects/lcsim/trunk/detector-framework/pom.xml	(original)
+++ projects/lcsim/trunk/detector-framework/pom.xml	Mon Feb 23 17:38:59 2015
@@ -28,6 +28,8 @@
                         <exclude>org/lcsim/detector/converter/compact/MultiLayerTrackerTest.java</exclude>
                         <exclude>org/lcsim/material/NuclearInteractionLengthTest.java</exclude>
                         <exclude>org/lcsim/material/BetheBlockTest.java</exclude>
+                        <exclude>org/lcsim/geometry/subdetector/HPSEcal3Test.java</exclude>
+                        <exclude>org/lcsim/detector/converter/compact/HPSEcalAPITest.java</exclude>
                     </excludes>
                 </configuration>
             </plugin>

Modified: projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/EcalCrystal.java
 =============================================================================
--- projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/EcalCrystal.java	(original)
+++ projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/EcalCrystal.java	Mon Feb 23 17:38:59 2015
@@ -15,8 +15,6 @@
  * which includes access to time dependent conditions as well as DAQ setup information.
  * @author Jeremy McCormick <[log in to unmask]>
  */
-// TODO: Add method for getting an EcalCrystal objects neighbors.
-// FIXME: Remove conditions.  These should come directly from conditions objects instead.
 public class EcalCrystal extends DetectorElement {
     
     Hep3Vector positionFront;
@@ -47,11 +45,12 @@
     public int getY() {
         return getIdentifierHelper().getValue(getIdentifier(), "iy");
     }
-           
+               
     /**
      * Get the global center position of the XY plane in the front of the crystal.
-     * This is used in the recon clustering algorithm for the "corrected"
-     * hit position, so it is best to cache it once used for performance purposes.
+     * This is used in the reconstruction clustering algorithm for determining the 
+     * "corrected" hit position, so it is best to cache it once used, for performance 
+     * purposes.
      * @return The center position of the XY plane in the front of the crystal.
      */
     public Hep3Vector getPositionFront() {

Modified: projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcal3Converter.java
 =============================================================================
--- projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcal3Converter.java	(original)
+++ projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcal3Converter.java	Mon Feb 23 17:38:59 2015
@@ -10,6 +10,7 @@
 
 import org.jdom.DataConversionException;
 import org.jdom.Element;
+import org.lcsim.detector.IDetectorElement;
 import org.lcsim.detector.ILogicalVolume;
 import org.lcsim.detector.IPhysicalVolume;
 import org.lcsim.detector.IRotation3D;
@@ -47,35 +48,36 @@
     IIdentifierHelper helper;
     IIdentifierDictionary dict;
 
-    private static class CrystalRange {
-        int ixmin;
-        int ixmax;
-        int iymin;
-        int iymax;
+    static class CrystalRange {
+        
+        int xIndexMin;
+        int xIndexMax;
+        int yIndexMin;
+        int yIndexMax;
 
         CrystalRange(Element elem) throws Exception {
-            ixmin = ixmax = iymin = iymax = 0;
+            xIndexMin = xIndexMax = yIndexMin = yIndexMax = 0;
 
             if (elem.getAttribute("ixmin") != null) {
-                ixmin = elem.getAttribute("ixmin").getIntValue();
+                xIndexMin = elem.getAttribute("ixmin").getIntValue();
             } else {
                 throw new RuntimeException("Missing ixmin parameter.");
             }
 
             if (elem.getAttribute("ixmax") != null) {
-                ixmax = elem.getAttribute("ixmax").getIntValue();
+                xIndexMax = elem.getAttribute("ixmax").getIntValue();
             } else {
                 throw new RuntimeException("Missing ixmax parameter.");
             }
 
             if (elem.getAttribute("iymin") != null) {
-                iymin = elem.getAttribute("iymin").getIntValue();
+                yIndexMin = elem.getAttribute("iymin").getIntValue();
             } else {
                 throw new RuntimeException("Missing ixmax parameter.");
             }
 
             if (elem.getAttribute("iymax") != null) {
-                iymax = elem.getAttribute("iymax").getIntValue();
+                yIndexMax = elem.getAttribute("iymax").getIntValue();
             } else {
                 throw new RuntimeException("Missing iymax parameter.");
             }
@@ -86,7 +88,7 @@
         if (ranges.size() == 0)
             return true;
         for (CrystalRange range : ranges) {
-            if ((ix >= range.ixmin && ix <= range.ixmax) && ((iy >= range.iymin) && (iy <= range.iymax))) {
+            if ((ix >= range.xIndexMin && ix <= range.xIndexMax) && ((iy >= range.yIndexMin) && (iy <= range.yIndexMax))) {
                 return false;
             }
 
@@ -175,6 +177,11 @@
                 throw new RuntimeException(x);
             }
         }
+        
+        if (!ranges.isEmpty()) {
+            // FIXME: Assumes single range of removed crystals.
+            ((HPSEcalDetectorElement)subdet.getDetectorElement()).setBeamGapIndices(ranges.get(0));
+        }
 
         // Setup crystal logical volume.
         Trd crystalTrap = new Trd("crystal_trap", dx1, dx2, dy1, dy2, dz);
@@ -321,7 +328,7 @@
             // Increment running Y totals.
             ycorrtot += ycorr;
             zcorrtoty += zcorry;
-        }
+        }        
     }
 
     /**
@@ -346,4 +353,10 @@
     public Class getSubdetectorType() {
         return HPSEcal3.class;
     }
+    
+    public IDetectorElement makeSubdetectorDetectorElement(Detector detector, Subdetector subdetector) {
+        IDetectorElement subdetectorDE = new HPSEcalDetectorElement(subdetector.getName(), detector.getDetectorElement());
+        subdetector.setDetectorElement(subdetectorDE);
+        return subdetectorDE;
+    }    
 }

Added: projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalAPI.java
 =============================================================================
--- projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalAPI.java	(added)
+++ projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalAPI.java	Mon Feb 23 17:38:59 2015
@@ -0,0 +1,110 @@
+package org.lcsim.detector.converter.compact;
+
+import hep.physics.vec.Hep3Vector;
+
+import java.util.List;
+
+import org.lcsim.detector.identifier.IIdentifier;
+
+/**
+ * This is a geometry API for the HPS ECAL detector.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public interface HPSEcalAPI {
+    
+    /**
+     * Get the maximum X index of the crystals.
+     * @return The maximum X index of the crystals.
+     */
+    int getXIndexMax();
+    
+    /**
+     * Get the minimum X index of the crystals.
+     * @return The minimum X index of the crystals.
+     */
+    int getXIndexMin();
+    
+    /**
+     * Get the maximum Y index of the crystals.
+     * @return The maximum Y index of the crystals.
+     */
+    int getYIndexMax();
+    
+    /**
+     * Get the minimum Y index of the crystals.
+     * @return The minimum Y index of the crystals.
+     */
+    int getYIndexMin();
+    
+    /**
+     * Get an array with all the valid X indices.
+     * @return An array with the X indices.
+     */
+    List<Integer> getXIndices();
+    
+    /**
+     * Get an array with all the valid Y indices.
+     * @return An array with the Y indices.
+     */
+    List<Integer> getYIndices();
+    
+    /**
+     * True if the given indices are located in the beam gap
+     * and so do not have crystals associated with them.
+     * @param x The X index.
+     * @param y The Y index.
+     * @return True if indices reference a position in the beam gap.
+     */
+    boolean isInBeamGap(int x, int y);
+       
+    /**
+     * Get the crystal at the given indices or null if it does not exist.
+     * @param x The X index.
+     * @param y The Y index.
+     * @return The crystal at the given indices or null if it does not exist.
+     */
+    EcalCrystal getCrystal(int x, int y);
+       
+    /**
+     * Get the crystal with the given ID or null if it does not exist
+     * @param id The packed ID of the crystal.
+     * @return The packed ID of the crystal.
+     */
+    EcalCrystal getCrystal(IIdentifier id);
+    
+    /**
+     * Get the crystal at the given position in global coordinates or null if position
+     * is not inside a crystal's volume.
+     * @param position The position of the crystal.
+     * @return The crystal at the given position or null if position is not inside crystal.
+     */
+    EcalCrystal getCrystal(Hep3Vector position);
+    
+    /**
+     * Get the list of crystal objects.
+     * @return The list of crystal objects.
+     */
+    List<EcalCrystal> getCrystals();
+    
+    /**
+     * Get a row of crystals from the Y index.
+     * @param y The Y index.
+     * @return The row of crystals.
+     */
+    List<EcalCrystal> getRow(int y);
+    
+    /**
+     * Get a column of crystals from the X index.
+     * @param x The X index. 
+     * @return The column of crystals.
+     */
+    List<EcalCrystal> getColumn(int x);
+            
+    /**
+     * Get the neighbors of a crystal.
+     * @param crystal A crystal object.
+     * @return The list of neighbor objects.
+     */
+    List<EcalCrystal> getNeighbors(EcalCrystal crystal);
+}

Added: projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalDetectorElement.java
 =============================================================================
--- projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalDetectorElement.java	(added)
+++ projects/lcsim/trunk/detector-framework/src/main/java/org/lcsim/detector/converter/compact/HPSEcalDetectorElement.java	Mon Feb 23 17:38:59 2015
@@ -0,0 +1,299 @@
+package org.lcsim.detector.converter.compact;
+
+import hep.physics.vec.Hep3Vector;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IDetectorElementContainer;
+import org.lcsim.detector.converter.compact.HPSEcal3Converter.CrystalRange;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierHelper;
+
+/**
+ * <p>
+ * This is an implementation of a basic geometry API for the HPS ECAL.
+ * <p>
+ * The neighboring API and conventions are based on the page 7 diagram from the 
+ * <a href="https://wiki.jlab.org/hps-run/images/f/f4/Ecal_manual_annex.pdf">ECAL Manual Annex</a>
+ * in which the viewpoint is from the beam towards the detector.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ * 
+ * @see HPSEcalAPI
+ * @see EcalCrystal
+ * @see org.lcsim.detector.IDetectorElement
+ * @see SubdetectorDetectorElement
+ */
+public final class HPSEcalDetectorElement extends SubdetectorDetectorElement implements HPSEcalAPI {
+        
+    Map<EcalCrystal, List<EcalCrystal>> neighborMap;
+    
+    int xIndexMax = Integer.MIN_VALUE;
+    int xIndexMin = Integer.MAX_VALUE;
+    int yIndexMax = Integer.MIN_VALUE;
+    int yIndexMin = Integer.MAX_VALUE;
+    
+    List<Integer> xIndices;
+    List<Integer> yIndices;
+    
+    CrystalRange beamGap;
+                         
+    public HPSEcalDetectorElement(String name, IDetectorElement parent) {
+        super(name, parent);
+    }
+    
+    /**
+     * Set the index range for the beam gap.
+     * @param beamGap The beam gap index range.
+     */
+    void setBeamGapIndices(CrystalRange beamGap) {
+        this.beamGap = beamGap;
+    }
+    
+    @Override
+    public int getXIndexMax() {
+        return xIndexMax;
+    }
+
+    @Override
+    public int getXIndexMin() {
+        return xIndexMin;
+    }
+
+    @Override
+    public int getYIndexMax() {
+        return yIndexMax;
+    }
+
+    @Override
+    public int getYIndexMin() {
+        return yIndexMin;
+    }
+    
+    @Override
+    public List<Integer> getXIndices() {
+        return Collections.unmodifiableList(xIndices);
+    }
+
+    @Override
+    public List<Integer> getYIndices() {
+        return Collections.unmodifiableList(yIndices);
+    }
+    
+    @Override
+    public boolean isInBeamGap(int xIndex, int yIndex) {
+        if((xIndex >= beamGap.xIndexMin && xIndex <= beamGap.xIndexMax) && 
+                (yIndex >= beamGap.yIndexMin && yIndex <= beamGap.yIndexMax)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    @Override
+    public List<EcalCrystal> getRow(int yIndex) {
+        List<EcalCrystal> row = new ArrayList<EcalCrystal>();
+        for (int ix = xIndexMin; ix <= xIndexMax; ix++) {
+            if (ix == 0)
+                continue;
+            EcalCrystal crystal = getCrystal(ix, yIndex);
+            if (crystal != null) {
+                row.add(crystal);
+            }
+        }
+        return row;
+    }
+    
+    @Override
+    public List<EcalCrystal> getColumn(int xIndex) {
+        List<EcalCrystal> column = new ArrayList<EcalCrystal>();
+        for (int iy = yIndexMin; iy <= yIndexMax; iy++) {
+            if (iy == 0)
+                continue;
+            EcalCrystal crystal = getCrystal(xIndex, iy);
+            if (crystal != null) {
+                column.add(crystal);
+            }           
+        }
+        return column;
+    }
+                                         
+    @Override
+    public EcalCrystal getCrystal(int xIndex, int yIndex) {
+        IIdentifierHelper helper = getIdentifierHelper();
+        IExpandedIdentifier expId = helper.createExpandedIdentifier();
+        expId.setValue(helper.getFieldIndex("ix"), xIndex);
+        expId.setValue(helper.getFieldIndex("iy"), yIndex);
+        expId.setValue(helper.getFieldIndex("system"), getSystemID());
+        return getCrystal(helper.pack(expId));
+    }
+
+    @Override
+    public EcalCrystal getCrystal(IIdentifier id) {
+        IDetectorElementContainer de = findDetectorElement(id);
+        if (de == null || de.isEmpty()) {
+            return null;
+        } else {
+            return (EcalCrystal) de.get(0);
+        }
+    }    
+          
+    @Override
+    public EcalCrystal getCrystal(Hep3Vector position) {
+        IDetectorElement de = findDetectorElement(position);
+        if (de instanceof EcalCrystal) {
+            return (EcalCrystal) de;        
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public List<EcalCrystal> getNeighbors(EcalCrystal crystal) {
+        return neighborMap.get(crystal);
+    }
+           
+    @Override
+    public List<EcalCrystal> getCrystals() {
+        return findDescendants(EcalCrystal.class);
+    }
+            
+    @Override
+    public void initialize() {
+        computeIndexRanges();
+        createNeighborMap();
+    }
+    
+    void computeIndexRanges() {
+        for (EcalCrystal crystal : getCrystals()) {
+            if (crystal.getX() > xIndexMax) {
+                xIndexMax = crystal.getX();
+            }
+            if (crystal.getX() < xIndexMin) {
+                xIndexMin = crystal.getX();
+            }
+            if (crystal.getY() > yIndexMax) {
+                yIndexMax = crystal.getY();
+            }
+            if (crystal.getY() < yIndexMin) {
+                yIndexMin = crystal.getY();
+            }
+        }
+        //System.out.println("computed index boundaries ...");
+        //System.out.println("maxIndexX = " + xIndexMax);
+        //System.out.println("minIndexX = " + xIndexMin);
+        //System.out.println("maxIndexY = " + yIndexMax);
+        //System.out.println("minIndexY = " + yIndexMin);
+        
+        xIndices = new ArrayList<Integer>();
+        for (int ix = xIndexMin; ix <= xIndexMax; ix++) {
+            if (ix == 0)
+                continue;
+            //System.out.println("adding ix = " + ix);
+            xIndices.add(ix);
+        }
+        
+        yIndices = new ArrayList<Integer>();
+        for (int iy = yIndexMin; iy <= yIndexMax; iy++) {
+            if (iy == 0)
+                continue;
+            //System.out.println("adding iy = " + iy);
+            yIndices.add(iy);
+        }
+    }
+    
+    // Constants for neighboring, relative to the beam direction as per diagram.
+    enum NeighborDirection {
+        NORTH,
+        NORTHEAST,
+        EAST,
+        SOUTHEAST,
+        SOUTH,
+        SOUTHWEST,
+        WEST,
+        NORTHWEST
+    }   
+    
+    /**
+     * Create a map of a crystal to its adjacent neighbors in all eight cardinal directions.
+     * Non-existent crystals are filtered out if the the geometry object does not exist, 
+     * which automatically takes care of edge crystals and missing crystals from the beam gap
+     * without explicitly needing to check those indices for validity.
+     */
+    void createNeighborMap() {
+        neighborMap = new HashMap<EcalCrystal, List<EcalCrystal>>();
+        for (EcalCrystal crystal : getCrystals()) {            
+            //System.out.println("find neighbors for " + crystal.getName() + " @ " + crystal.getX() + " " + crystal.getY());            
+            List<EcalCrystal> neighborCrystals = new ArrayList<EcalCrystal>();                        
+            for (NeighborDirection neighborDirection : NeighborDirection.values()) {
+                int[] xy = getNeighborIndices(crystal, neighborDirection);
+                EcalCrystal neighborCrystal = getCrystal(xy[0], xy[1]);
+                if (neighborCrystal != null) {
+                    //System.out.println("  adding neighbor @ " + neighborCrystal.getX() + " " + neighborCrystal.getY());
+                    neighborCrystals.add(neighborCrystal);
+                } 
+            }            
+            neighborMap.put(crystal, neighborCrystals);            
+        }
+    }
+              
+    /**     
+     * Get the neighbor indices of a crystal.
+     * @param crystal The ECAL crystal geometry object.
+     * @param direction The direction of the neighbor from integer encoding.
+     * @return The neighbor indices.
+     */   
+    int[] getNeighborIndices(EcalCrystal crystal, NeighborDirection direction) {
+        int[] xy = new int[2];
+        int ix = crystal.getX();
+        int iy = crystal.getY();
+        switch (direction) {
+            case NORTH:
+                xy[0] = ix;
+                xy[1] = iy + 1;
+                break;
+            case NORTHEAST:
+                xy[0] = ix - 1;
+                if (xy[0] == 0) xy[0] = -1;
+                xy[1] = iy + 1;
+                break;          
+            case EAST:
+                xy[0] = ix - 1;
+                if (xy[0] == 0) xy[0] = -1;
+                xy[1] = iy;                
+                break;
+            case SOUTHEAST:
+                xy[0] = ix - 1;
+                if (xy[0] == 0) xy[0] = -1;
+                xy[1] = iy - 1;
+                break;
+            case SOUTH:
+                xy[0] = ix;
+                xy[1] = iy - 1;
+                break;
+            case SOUTHWEST:
+                xy[0] = ix + 1;
+                if (xy[0] == 0) xy[0] = 1;
+                xy[1] = iy - 1;
+                break;
+            case WEST:
+                xy[0] = ix + 1;
+                if (xy[0] == 0) xy[0] = 1;
+                xy[1] = iy;
+                break;
+            case NORTHWEST:
+                xy[0] = ix + 1;
+                if (xy[0] == 0) xy[0] = 1;
+                xy[1] = iy + 1;
+                break;
+        }
+        return xy;
+    }
+  
+}

Added: projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/detector/converter/compact/HPSEcalAPITest.java
 =============================================================================
--- projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/detector/converter/compact/HPSEcalAPITest.java	(added)
+++ projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/detector/converter/compact/HPSEcalAPITest.java	Mon Feb 23 17:38:59 2015
@@ -0,0 +1,73 @@
+package org.lcsim.detector.converter.compact;
+
+import java.io.InputStream;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.GeometryReader;
+
+/**
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class HPSEcalAPITest extends TestCase {
+                  
+    public void testHPSEcalAPI() throws Exception {
+        GeometryReader geometryReader = new GeometryReader();
+        InputStream in = getClass().getResourceAsStream("/org/lcsim/geometry/subdetector/HPSEcal3Test.xml");
+        Detector detector = geometryReader.read(in);
+        
+        HPSEcalDetectorElement ecal = (HPSEcalDetectorElement)detector.getSubdetector("Ecal").getDetectorElement();
+        
+        HPSEcalAPI api = (HPSEcalAPI) ecal;
+        
+        assertEquals("The max X index is wrong.", 23, api.getXIndexMax());
+        assertEquals("The min X index is wrong.", -23, api.getXIndexMin());
+        assertEquals("The max Y index is wrong.", 5, api.getYIndexMax());
+        assertEquals("The min Y index is wrong.", -5, api.getYIndexMin());
+        
+        for (Integer yIndex : api.getYIndices()) {
+            if (yIndex == 0) {
+                System.out.println("skipping yIndex = 0");
+                continue;
+            } 
+            for (Integer xIndex : api.getXIndices()) {
+                System.out.println("checking crystal " + xIndex + ", " + yIndex);
+                if (xIndex == 0) {
+                    System.out.println("skipping xIndex = 0");
+                    continue;
+                }                
+                if((yIndex == 1 || yIndex == -1) && (xIndex <= -2 && xIndex >= -10)) {
+                    System.out.println("crystal " + xIndex + ", " + yIndex + " should be in the gap");
+                    assertTrue("Indices should be in gap: " + xIndex + ", " + yIndex, api.isInBeamGap(xIndex, yIndex));
+                    // Crystal is in the beam gap.
+                    continue;
+                }
+                EcalCrystal crystal = api.getCrystal(xIndex, yIndex);
+                assertNotNull("Failed to find crystal at ix = " + xIndex + ", iy = " + yIndex, crystal);
+            }
+        }
+        
+        for (Integer yIndex : api.getYIndices()) {
+            List<EcalCrystal> row = api.getRow(yIndex);
+            System.out.println("found " + row.size() + " crystals in row " + yIndex);
+            if (Math.abs(yIndex) != 1) {
+                assertEquals("Wrong number of crystals in row.", 46, row.size());
+            } else {
+                assertEquals("Wrong number of crystals in row.", 37, row.size());
+            }                        
+        }
+        
+        for (Integer xIndex : api.getXIndices()) {            
+            List<EcalCrystal> column = api.getColumn(xIndex);
+            System.out.println("found " + column.size() + " crystals in column " + xIndex);
+            if (xIndex > -2 || xIndex < -10) {
+                assertEquals("Wrong number of crystals in column.", 10, column.size());
+            } else {
+                assertEquals("Wrong number of crystals in column.", 8, column.size());
+            }                        
+        }
+    }                   
+}

Modified: projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/geometry/subdetector/HPSEcal3Test.java
 =============================================================================
--- projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/geometry/subdetector/HPSEcal3Test.java	(original)
+++ projects/lcsim/trunk/detector-framework/src/test/java/org/lcsim/geometry/subdetector/HPSEcal3Test.java	Mon Feb 23 17:38:59 2015
@@ -9,6 +9,8 @@
 
 import org.lcsim.detector.IDetectorElement;
 import org.lcsim.detector.IGeometryInfo;
+import org.lcsim.detector.converter.compact.EcalCrystal;
+import org.lcsim.detector.converter.compact.HPSEcalDetectorElement;
 import org.lcsim.detector.identifier.IIdentifierHelper;
 import org.lcsim.geometry.Detector;
 import org.lcsim.geometry.GeometryReader;
@@ -16,8 +18,11 @@
 import org.lcsim.util.test.TestUtil.TestOutputFile;
 
 /**
+ * <p>
  * Test conversion of detector type {@link org.lcsim.geometry.subdetector.HPSEcal3} 
  * to LCDD, Heprep, and in-memory Java objects.
+ * <p>
+ * Also do a basic check of crystal object neighboring.  
  * 
  * @author Jeremy McCormick <[log in to unmask]>
  */
@@ -45,13 +50,45 @@
         Detector detector = geometryReader.read(in);
         System.out.println("built detector " + detector.getName());
         
-        IDetectorElement de = detector.getSubdetector("ECAL").getDetectorElement();
+        IDetectorElement de = detector.getSubdetector("Ecal").getDetectorElement();
         System.out.println("ECAL has " + de.getChildren().size() + " crystals.");
         IIdentifierHelper helper = de.getIdentifierHelper();
         for (IDetectorElement crystal : de.getChildren()) {
             IGeometryInfo geometry = crystal.getGeometry();
             System.out.println(crystal.getName() + " - " + helper.unpack(crystal.getIdentifier()) + " @ " + geometry.getPosition());
+        }        
+    }
+        
+    public void testNeighbors() throws Exception {
+        GeometryReader geometryReader = new GeometryReader();
+        InputStream in = getClass().getResourceAsStream("/org/lcsim/geometry/subdetector/HPSEcal3Test.xml");
+        Detector detector = geometryReader.read(in);
+        
+        HPSEcalDetectorElement ecal = (HPSEcalDetectorElement)detector.getSubdetector("Ecal").getDetectorElement();
+        
+        for (EcalCrystal crystal : ecal.getCrystals()) {
+            System.out.println(crystal.getName() + " @ " + crystal.getX() + " " + crystal.getY() + " has neighbors ...");
+            // Check this crystal object is valid.
+            checkValid(crystal);
+            for (EcalCrystal neighbor : ecal.getNeighbors(crystal)) {
+                System.out.println("  " + neighbor.getX() + " " + neighbor.getY());
+                // Check that each neighbor is valid.
+                checkValid(neighbor);
+            }
         }
-        
+    }      
+             
+    void checkValid(EcalCrystal crystal) {
+        int ix = crystal.getX();
+        int iy = crystal.getY();
+        if (Math.abs(ix) > 23) throw new RuntimeException("ix is invalid: " + ix);
+        if (Math.abs(iy) > 5) throw new RuntimeException("iy is invalid: " + iy);
+        if (ix == 0) throw new RuntimeException("ix is zero");
+        if (iy == 0) throw new RuntimeException("iy is zero");            
+        if (Math.abs(iy) == 1) {
+            if (ix <= -2 && ix >= -10) {
+                throw new RuntimeException("crystal " + ix + " " + iy + " is in beam gap!");
+            }
+        }
     }
 }

Modified: projects/lcsim/trunk/detector-framework/src/test/resources/org/lcsim/geometry/subdetector/HPSEcal3Test.xml
 =============================================================================
--- projects/lcsim/trunk/detector-framework/src/test/resources/org/lcsim/geometry/subdetector/HPSEcal3Test.xml	(original)
+++ projects/lcsim/trunk/detector-framework/src/test/resources/org/lcsim/geometry/subdetector/HPSEcal3Test.xml	Mon Feb 23 17:38:59 2015
@@ -11,9 +11,11 @@
         <constant name="tracking_region_min" value="5.0*cm" />
         <constant name="tracking_region_zmax" value="100.0*cm" />
         <!-- ECal placement parameters -->
-        <constant name="ecal_front" value="13.3/2*mm" />
+        <constant name="beam_angle" value="0.03052"/>
+         <constant name="ecal_front" value="13.3/2*mm" />
         <constant name="ecal_back" value="16/2*mm" />
         <constant name="ecal_z" value="160/2*mm" />
+        <constant name="ecal_dface" value="139.3*cm"/>
     </define>
     <materials>
         <material name="LeadTungstate">
@@ -24,6 +26,18 @@
         </material>
     </materials>
     <detectors>
+    
+    <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits">
+        <comment>The crystal ECal</comment>
+        <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="ecal_dface">
+                <remove ixmin="-10" ixmax="-2" iymin="-1" iymax="1" />
+                <top dx="ecal_dface*tan(beam_angle)" dy="0." dz="0."/>
+                <bottom dx="ecal_dface*tan(beam_angle)" dy="0." dz="0."/>
+            </layout>
+        </detector>
+<!--     
         <detector id="2" name="ECAL" type="HPSEcal3" insideTrackingVolume="false" readout="ECAL_HITS">
             <material name="LeadTungstate" />
             <dimensions x1="ecal_front" y1="ecal_front" x2="ecal_back" y2="ecal_back" z="ecal_z" />
@@ -31,9 +45,10 @@
                 <remove ixmin="2" ixmax="7" iymin="-1" iymax="1" />
             </layout>
         </detector>
+ -->        
     </detectors>
     <readouts>
-        <readout name="ECAL_HITS">
+        <readout name="EcalHits">
             <segmentation type="GridXYZ" gridSizeX="0.0" gridSizeY="0.0" gridSizeZ="0.0" />
             <id>system:6,side:-2,layer:4,ix:-8,iy:-6</id>
         </readout>

########################################################################
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