Print

Print


Commit in lcsim/src/org/lcsim/contrib/RobKutschke/TRFSelfTest/geom on MAIN
RKGeom.java+414added 1.1
RKSurf.java+429added 1.1
+843
2 added files
First Release

lcsim/src/org/lcsim/contrib/RobKutschke/TRFSelfTest/geom
RKGeom.java added at 1.1
diff -N RKGeom.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ RKGeom.java	8 Jun 2009 06:04:03 -0000	1.1
@@ -0,0 +1,414 @@
+package org.lcsim.contrib.RobKutschke.TRFSelfTest.geom;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.compact.Field;
+import org.lcsim.geometry.field.Solenoid;
+
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IDetectorElementContainer;
+
+//import org.lcsim.recon.tracking.trfbase.PropDir;
+import org.lcsim.recon.tracking.trfbase.Propagator;
+import org.lcsim.recon.tracking.trfbase.PropDispatch;
+import org.lcsim.recon.tracking.trfcyl.PropCyl;
+import org.lcsim.recon.tracking.trfcylplane.PropZCyl;
+import org.lcsim.recon.tracking.trfdca.PropDCACyl;
+import org.lcsim.recon.tracking.trfzp.PropZZ;
+import org.lcsim.recon.tracking.trfdca.PropDCACyl;
+import org.lcsim.recon.tracking.trfdca.PropCylDCA;
+import org.lcsim.recon.tracking.trfcylplane.PropCylZ;
+import org.lcsim.recon.tracking.trfcylplane.PropZCyl;
+
+import org.lcsim.contrib.RobKutschke.TRF.trfdca.PropDCAZ;
+import org.lcsim.contrib.RobKutschke.TRF.trfdca.PropZDCA;
+
+import org.lcsim.recon.tracking.trfcyl.SurfCylinder;
+import org.lcsim.recon.tracking.trfdca.SurfDCA;
+import org.lcsim.recon.tracking.trfzp.SurfZPlane;
+
+import org.lcsim.contrib.RobKutschke.ToyConfig.*;
+
+/**
+ * 
+ * Extract needed information from the geometry system and serve it 
+ * to the callers in a convenient form.
+ *  
+ *
+ *@author $Author: kutschke $
+ *@version $Id: RKGeom.java,v 1.1 2009/06/08 06:04:03 kutschke Exp $
+ *
+ * Date $Date: 2009/06/08 06:04:03 $
+ *
+ */
+
+
+public class RKGeom {
+
+    // TRF wants distances in cm, not mm.
+    private double mmTocm = 0.1;
+
+    //    private Array radius = null;
+    private Subdetector sd_tbar  = null;
+    private Subdetector sd_vbar  = null;
+    private Subdetector sd_tec   = null;
+    private Subdetector sd_vec   = null;
+    private Subdetector sd_tfor  = null;
+    private Subdetector sd_bpipe = null;
+
+    private IDetectorElement de_tbar  = null;
+    private IDetectorElement de_vbar  = null;
+    private IDetectorElement de_tec   = null;
+    private IDetectorElement de_vec   = null;
+    private IDetectorElement de_tfor  = null;
+
+    // Nominal magnetic field.
+    public double bz = 0.;
+
+    // Lists of interesting surfaces.
+    public List<RKSurf> Surf = new ArrayList<RKSurf>();
+    public List<RKSurf> ZSurfplus  = new ArrayList<RKSurf>();
+    public List<RKSurf> ZSurfminus = new ArrayList<RKSurf>();
+    public List<RKSurf> ZSurfAll   = new ArrayList<RKSurf>();
+
+    // Specific surface type A to surface type B propagators.
+    private PropCyl propcyl       = null;
+    private PropZZ  propzz        = null;
+    private PropDCACyl propdcacyl = null;
+    private PropCylDCA propcyldca = null;
+    private PropZCyl propzcyl     = null;
+    private PropCylZ propcylz     = null;
+    private PropDCAZ propdcaz     = null;
+    private PropZDCA propzdca     = null;
+
+    // The master propagator that can go between any pair of surfaces.
+    private PropDispatch pDispatch = null;
+
+    // The run time configuration system.
+    //ToyConfig config;
+
+    // Information from the run time configuration system.
+    double  respixel;
+    double  resstrip;
+    boolean trackerbarrel2d;
+    double  zres2dTrackerBarrel;
+    boolean vtxFwdEquivStrips;
+
+    // Does this detector have forward tracking.
+    boolean hasforward = false;
+
+    public RKGeom ( Detector detector ){
+	
+	System.out.println("New detector: " + detector.getName() );
+	if ( detector.getName().compareTo("sid00") != 0 &&
+	     detector.getName().compareTo("sid02") != 0    ){
+	    System.out.println("This driver works only with sid00 or sid02." );
+	    System.exit(-1);
+	}
+
+	// Extract information from the run time configuration system.
+	try{
+	    ToyConfig config = ToyConfig.getInstance();
+	    respixel            = config.getDouble("respixel");
+	    resstrip            = config.getDouble("resstrip");
+	    trackerbarrel2d     = config.getBoolean("trackerbarrel2d");
+	    zres2dTrackerBarrel = config.getDouble("zres2dTrackerBarrel");
+	    vtxFwdEquivStrips   = config.getBoolean("vtxFwdEquivStrips");
+
+	} catch (ToyConfigException e){
+            System.out.println (e.getMessage() );
+            System.out.println ("Stopping now." );
+            System.exit(-1);
+        }
+
+
+
+	Map<String, Subdetector> subDetMap = detector.getSubdetectors();
+	
+	Subdetector sd_tbar = subDetMap.get("TrackerBarrel");
+	Subdetector sd_vbar = subDetMap.get("VertexBarrel");
+	Subdetector sd_tec  = subDetMap.get("TrackerEndcap");
+	Subdetector sd_vec  = subDetMap.get("VertexEndcap");
+	Subdetector sd_tfor = subDetMap.get("TrackerForward");
+	Subdetector sd_bpipe  = subDetMap.get("BeamPipe");
+	System.out.println ("Checking .... " + sd_tbar + " | " + sd_tfor);
+
+	// Check for forward tracking system.
+	if ( sd_tfor == null ) {
+	    System.out.println ("Checking 1 .... " );
+	    if ( detector.getName().compareTo("sid00") != 0 ){
+		System.out.println("Expected to find a TrackerForward Subdetector but did not!");
+		System.exit(-1);
+	    }
+	}else{
+	    System.out.println ("Checking 2  .... " );
+
+	    hasforward = true;
+	}
+
+	// Other parts must be present.
+	if ( sd_tbar == null ){
+	    System.out.println("Could not find TrackerBarrel Subdetector.");
+	    System.exit(-1);
+	}
+	if (sd_vbar == null ){
+	    System.out.println("Could not find VertexBarrel Subdetector.");
+	    System.exit(-1);
+	}
+	if ( sd_tec == null ){
+	    System.out.println("Could not find TrackerEndcap Subdetector.");
+	    System.exit(-1);
+	}
+	if ( sd_vec == null ){
+	    System.out.println("Could not find VertexEndcap Subdetector.");
+	    System.exit(-1);
+	}
+	if ( sd_bpipe == null ){
+	    System.out.println("Could not find BeamPipe Subdetector.");
+	    System.exit(-1);
+	}
+
+	de_tbar  = sd_tbar.getDetectorElement();
+	de_vbar  = sd_vbar.getDetectorElement();
+	de_tec   = sd_tec.getDetectorElement();
+	de_vec   = sd_vec.getDetectorElement();
+
+	if ( hasforward ){
+	    de_tfor = sd_tfor.getDetectorElement();
+	}
+
+	if ( de_tbar == null ){
+	    System.out.println("Could not find TrackerBarrel Detector Element.");
+	    System.exit(-1);
+	}
+	if (de_vbar == null ){
+	    System.out.println("Could not find VertexBarrel Detector Element.");
+	    System.exit(-1);
+	}
+	if ( de_tec == null ){
+	    System.out.println("Could not find TrackerEndcap Detector Element.");
+	    System.exit(-1);
+	}
+	if ( de_vec == null ){
+	    System.out.println("Could not find VertexEndcap Detector Element.");
+	    System.exit(-1);
+	}
+	if ( de_tfor == null && hasforward ){
+	    System.out.println("Could not find TrackerForward Detector Element.");
+	    System.exit(-1);
+	}
+
+
+	IDetectorElementContainer tbar_layers = de_tbar.getChildren();
+	IDetectorElementContainer vbar_layers = de_vbar.getChildren();
+	IDetectorElementContainer tec_layers  = de_tec.getChildren();
+	IDetectorElementContainer vec_layers  = de_vec.getChildren();
+	IDetectorElementContainer tfor_layers = de_tfor.getChildren();
+
+	// Add the beampipe to the list.
+	Surf.add( new RKSurf ( sd_bpipe ) );
+
+	// Add the vertex and tracker barrels to the list.
+	for ( IDetectorElement de: vbar_layers ){
+	    Surf.add( new RKSurf ( de, 2, RKSurf.ixy_Undef, respixel, respixel ) );
+	}
+	for ( IDetectorElement de: tbar_layers ){
+	    if ( trackerbarrel2d ) {
+		Surf.add( new RKSurf ( de, 2, RKSurf.ixy_phi, resstrip, zres2dTrackerBarrel ) );
+	    }else{
+		Surf.add( new RKSurf ( de, 1, RKSurf.ixy_phi, resstrip ) );
+	    }
+	}
+
+	System.out.println( "Number of surfaces: " + Surf.size() );
+	for ( RKSurf surf : Surf ){
+	    surf.Print();
+	}
+
+	if ( vec_layers.size() != 2 ){
+	    System.out.println ("Expected two z hemispheres for: " + de_vec.getName () );
+	    System.exit(-1);
+	}
+
+	if ( tec_layers.size() != 2 ){
+	    System.out.println ("Expected two z hemispheres for: " + de_vec.getName () );
+	    System.exit(-1);
+	}
+
+	if ( tfor_layers.size() != 2 ){
+	    System.out.println ("Expected two z hemispheres for: " + de_tfor.getName () );
+	    System.exit(-1);
+	}
+
+	for ( IDetectorElement de: vec_layers.get(0).getChildren() ){
+	    if ( vtxFwdEquivStrips ){
+		ZSurfplus.add( new RKSurf( de, 1, RKSurf.ixy_x, resstrip) );
+
+		//ZSurfplus.add( new RKSurf( de, 1, RKSurf.ixy_y, resstrip) );
+		RKSurf tmp = new RKSurf( de, 1, RKSurf.ixy_y, resstrip);
+		tmp.hackZc(-0.1);
+		ZSurfplus.add(tmp);
+
+	    }
+	    else{
+		ZSurfplus.add( new RKSurf( de, 2, RKSurf.ixy_Undef, respixel, respixel) );
+	    }
+
+	}
+
+	for ( IDetectorElement de: tfor_layers.get(0).getChildren() ){
+	    ZSurfplus.add( new RKSurf( de, 2, RKSurf.ixy_Undef, respixel, respixel) );
+	}
+
+	int xy = -1;
+	for ( IDetectorElement de: tec_layers.get(0).getChildren() ){
+	    if ( (++xy)%2 == 0 ){
+		ZSurfplus.add( new RKSurf( de, 1, RKSurf.ixy_x, resstrip) );
+	    }else{
+		ZSurfplus.add( new RKSurf( de, 1, RKSurf.ixy_y, resstrip) );
+	    }
+	}
+
+	for ( IDetectorElement de: vec_layers.get(1).getChildren() ){
+	    if ( vtxFwdEquivStrips ){
+		ZSurfminus.add( new RKSurf( de, 1, RKSurf.ixy_x, resstrip) );
+		//ZSurfminus.add( new RKSurf( de, 1, RKSurf.ixy_y, resstrip) );
+		RKSurf tmp = new RKSurf( de, 1, RKSurf.ixy_y, resstrip);
+		tmp.hackZc(+0.1);
+		ZSurfminus.add(tmp);
+	    }
+	    else{
+		ZSurfminus.add( new RKSurf( de, 2, RKSurf.ixy_Undef, respixel, respixel) );
+	    }
+	}
+
+	for ( IDetectorElement de: tfor_layers.get(1).getChildren() ){
+	    ZSurfminus.add( new RKSurf( de, 2, RKSurf.ixy_Undef, respixel, respixel) );
+	}
+
+
+	xy = -1;
+	for ( IDetectorElement de: tec_layers.get(1).getChildren() ){
+	    if ( (++xy)%2 == 0 ){
+		ZSurfminus.add( new RKSurf( de, 1, RKSurf.ixy_x, resstrip) );
+	    } else {
+		ZSurfminus.add( new RKSurf( de, 1, RKSurf.ixy_y, resstrip) );
+	    }
+	}
+
+	System.out.println( "Number of +Zsurfaces: " + ZSurfplus.size() );
+	for ( RKSurf surf : ZSurfplus ){
+	    surf.Print();
+	}
+
+	System.out.println( "Number of -Zsurfaces: " + ZSurfminus.size() );
+	for ( RKSurf surf : ZSurfminus ){
+	    surf.Print();
+	}
+
+	// List of all Z Surfaces.
+	for ( ListIterator ihit=ZSurfminus.listIterator(ZSurfminus.size());
+	      ihit.hasPrevious(); ){
+	    ZSurfAll.add((RKSurf)ihit.previous());
+	}
+	for ( Iterator ihit=ZSurfplus.iterator(); ihit.hasNext(); ){
+	    ZSurfAll.add((RKSurf)ihit.next());
+	}
+
+
+	double[] origin = {0.,0.,0.};
+
+	Map<String,Field> fields = detector.getFields();
+	Set<String> keys = fields.keySet();
+	for ( String key : keys ){
+	    Field field = fields.get(key);
+	    String classname = field.getClass().getName();
+	    String shortname = classname.replaceAll( "org.lcsim.geometry.field.", "");
+	    if ( shortname.compareTo("Solenoid") != 0 ){
+		System.out.println("Expected, but did not find, a solenoid: " + shortname );
+		System.exit(-1);
+	    }
+	    Solenoid s = (Solenoid)field;
+	    bz = s.getInnerField()[2];
+	    if ( bz == 0. ){
+		System.out.println("This code will not work with a magnetic field of 0: " + shortname );
+		System.exit(-1);
+	    }
+	    break;
+	}
+
+	// Instantiate surface-pair specific propagators.
+	propcyl    = new PropCyl(bz);
+	propzz     = new PropZZ(bz);
+	propdcacyl = new PropDCACyl(bz);
+	propcyldca = new PropCylDCA(bz);
+	propzcyl   = new PropZCyl(bz);
+	propcylz   = new PropCylZ(bz);
+	propdcaz   = new PropDCAZ(bz);
+	propzdca   = new PropZDCA(bz);
+
+	// Instantiate and configure the general purpose propagator.
+	pDispatch = new PropDispatch();
+	pDispatch.addPropagator( SurfZPlane.staticType(),   SurfZPlane.staticType(),   propzz);
+	pDispatch.addPropagator( SurfCylinder.staticType(), SurfCylinder.staticType(), propcyl);
+	pDispatch.addPropagator( SurfDCA.staticType(),      SurfCylinder.staticType(), propdcacyl);
+	pDispatch.addPropagator( SurfCylinder.staticType(), SurfDCA.staticType(),      propcyldca);
+	pDispatch.addPropagator( SurfZPlane.staticType(),   SurfCylinder.staticType(), propzcyl);
+	pDispatch.addPropagator( SurfCylinder.staticType(), SurfZPlane.staticType(),   propcylz);
+	pDispatch.addPropagator( SurfDCA.staticType(),      SurfZPlane.staticType(),   propdcaz);
+	pDispatch.addPropagator( SurfZPlane.staticType(),   SurfDCA.staticType(),      propzdca);
+
+    }
+
+    public Propagator newPropagator(){
+	// Clone not supported for pDispatch.
+	//return pDispatch.newPropagator();
+	return (Propagator)pDispatch;
+    }
+
+    public List<RKSurf> getCylinders(){
+	return Surf;
+    }
+    public List<RKSurf> getZplus(){
+	return ZSurfplus;
+    }
+    
+    public List<RKSurf> getZMinus(){
+	return ZSurfminus;
+    }
+
+    public double getBz(){
+	return bz;
+    }
+    
+
+    // Return a list of z surfaces, going foward along the track.
+    public List<RKSurf> getZ( double z0, double cz ){
+	List<RKSurf> zlist = new ArrayList<RKSurf>();
+	if ( cz > 0 ){
+	    for ( Iterator ihit=ZSurfAll.iterator(); ihit.hasNext(); ){
+		RKSurf s = (RKSurf) ihit.next();
+		if ( s.zc >= z0 ){
+		    zlist.add(s);
+		}
+	    }
+	} else if ( cz < 0 ){
+	    for ( ListIterator ihit=ZSurfAll.listIterator(ZSurfAll.size());
+		  ihit.hasPrevious(); ){
+		RKSurf s = (RKSurf) ihit.previous();
+		if ( s.zc <= z0 ){
+		    zlist.add(s);
+		}
+	    }
+	}
+
+	return zlist;
+    }
+}

lcsim/src/org/lcsim/contrib/RobKutschke/TRFSelfTest/geom
RKSurf.java added at 1.1
diff -N RKSurf.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ RKSurf.java	8 Jun 2009 06:04:03 -0000	1.1
@@ -0,0 +1,429 @@
+package org.lcsim.contrib.RobKutschke.TRFSelfTest.geom;
+
+import java.lang.Math;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.detector.IGeometryInfo;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.material.IMaterial;
+import org.lcsim.detector.solids.ISolid;
+import org.lcsim.detector.solids.Tube;
+
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.geometry.subdetector.PolyconeSupport;
+import org.lcsim.geometry.subdetector.PolyconeSupport.ZPlane;
+
+import org.lcsim.material.Material;
+
+import org.lcsim.recon.tracking.trfcyl.BSurfCylinder;
+import org.lcsim.recon.tracking.trfcyl.SurfCylinder;
+import org.lcsim.recon.tracking.trfcyl.ThinCylMs;
+import org.lcsim.recon.tracking.trfcyl.ThinCylMsSim;
+
+import org.lcsim.recon.tracking.trfzp.SurfZPlane;
+
+/**
+ * 
+ * Holds summary information about one sensitive surface.  The information
+ * is extracted from the org.lcsim geometry system.  This is a routine
+ * that needs to know that org.lcsim uses mm for distances but TRF uses cm.
+ *
+ *
+ *@author $Author: kutschke $
+ *@version $Id: RKSurf.java,v 1.1 2009/06/08 06:04:03 kutschke Exp $
+ *
+ * Date $Date: 2009/06/08 06:04:03 $
+ *
+ */
+
+public class RKSurf{
+
+    // TRF wants distances in cm, not mm.
+    private double mmTocm = 0.1;
+
+    // Name of this Subdetector.
+    public String name = "";
+
+    // Readout dimension:
+    // 0 = inactive
+    // 1 = strips
+    // 2 = pixels
+    public int rodim;
+
+    // References to subdetector and detector element info.
+    public Subdetector      sd = null;
+    public IDetectorElement de = null;
+
+    public double radius = 0.;
+    public double thick  = 0.;
+    public double zmin   = 0.;
+    public double zmax   = 0.;
+    public double zc     = 0.;
+    public double rmin   = 0.;
+    public double rmax   = 0.;
+
+    // Does a 1D measurement measure the first or second coordinate?
+    public int ixy = -1;
+    static public int ixy_Undef = -1;
+    static public int ixy_x   = 0;
+    static public int ixy_y   = 1;
+    static public int ixy_phi = 0;
+    static public int ixy_z   = 1;
+
+    private double[] resolutions;
+
+    // Different inputs have different places to find materials.
+    public Material   material = null;
+    public IMaterial imaterial = null;
+
+    // Name of the material.
+    public String matname = "Undefined";
+
+    // Radiation length of the material;
+    public double radl = 0;
+
+    // Thickness in units of radiation length.
+    public double thick_radl = 0.;
+
+    // Density.
+    public double density = 0.0;
+
+    // Tolerance for comparing floating point numbers.
+    private double tolerance = 1.e-4;
+
+    // Types
+    private int type;
+    // Types
+    static public int type_tube=0;
+    static public int type_zdisc=1;
+
+    public SurfCylinder getCylinder(){
+	if ( type != type_tube ){
+	    System.out.println("Cannot return a cylinder from a non-tube surface: " + name );
+	    System.exit(-1);
+	}
+	SurfCylinder s    = new SurfCylinder( radius*mmTocm );
+	ThinCylMs    scat = new ThinCylMs   ( thick_radl );
+	ThinCylMsSim sim  = new ThinCylMsSim( thick_radl );
+	s.setInteractor(scat);
+	s.setSimInteractor(sim);
+	return s;
+    }
+
+    public BSurfCylinder getBCylinder(){
+	if ( type != type_tube ){
+	    System.out.println("Cannot return a bounded cylinder from a non-tube surface: " + name );
+	    System.exit(-1);
+	}
+	return new BSurfCylinder( radius*mmTocm, zmin*mmTocm, zmax*mmTocm );
+    }
+
+    public boolean inBounds ( double trfarg ){
+	if ( type == type_tube ){
+	    double z = trfarg/mmTocm;
+	    return (z>=zmin)&&(z<=zmax);
+	} else if ( type == type_zdisc ){
+	    double r = trfarg/mmTocm;
+	    return (r>=rmin)&&(r<=rmax);
+	}
+	return false;
+    }
+
+    public int getType(){
+	return type;
+    }
+
+    public String getTypeAsString(){
+	if ( type == type_tube ){
+	    return "Tube ";
+	} else if ( type == type_zdisc ){
+	    return "Zdisc";
+	}
+	return "Unknown";
+    }
+
+    public SurfZPlane getZPlane(){
+	if ( type != type_zdisc ){
+	    System.out.println("Cannot return a ZPlane from a non-zplane surface: " + name );
+	    System.exit(-1);
+	}
+	return new SurfZPlane( zc*mmTocm );
+    }
+
+    public double[] getResolutions(){
+	return resolutions;
+    }
+
+    public double getResolution0(){
+	boolean ok = true;
+	if ( resolutions == null ){
+	    ok = false;
+	} else {
+	    if ( resolutions.length < 1 ){
+		ok = false;
+	    }
+	}
+	if ( !ok ){
+	    System.out.println ("RKSurf: Illegal request for getResolution0 " + name );
+	    return 0.;
+	}
+	return resolutions[0];
+    }
+
+    public double getResolution1(){
+	boolean ok = true;
+	if ( resolutions == null ){
+	    ok = false;
+	} else {
+	    if ( resolutions.length < 1 ){
+		ok = false;
+	    }
+	}
+	if ( !ok ){
+	    System.out.println ("RKSurf: Illegal request for getResolution1 " + name );
+	    return 0.;
+	}
+	return resolutions[1];
+    }
+
+
+    public RKSurf( IDetectorElement de, int rodim, int ixy, double[] res ){
+	if ( de == null ){
+	    System.out.println("RKSurf: Cannot instantiate RKSurf with null DetectorElement." );
+	    System.exit(-1);
+	}
+
+	this.name  = de.getName();
+	this.rodim = rodim;
+	this.ixy   = ixy;
+	resolutions = new double[res.length];
+	for ( int i=0; i<res.length; ++i){
+	    resolutions[i] = res[i]*mmTocm;
+	}
+	Build( de);
+    }
+
+    public RKSurf( IDetectorElement de, int rodim, int ixy, double res ){
+	if ( de == null ){
+	    System.out.println("RKSurf: Cannot instantiate RKSurf with null DetectorElement." );
+	    System.exit(-1);
+	}
+
+	this.name  = de.getName();
+	this.rodim = rodim;
+	this.ixy   = ixy;
+	resolutions = new double[1];
+	resolutions[0] = res*mmTocm;
+	Build( de);
+    }
+
+    public RKSurf( IDetectorElement de, int rodim, int ixy, double res0, double res1 ){
+	if ( de == null ){
+	    System.out.println("RKSurf: Cannot instantiate RKSurf with null DetectorElement." );
+	    System.exit(-1);
+	}
+
+	this.name  = de.getName();
+	this.rodim = rodim;
+	this.ixy   = ixy;
+	resolutions = new double[2];
+	resolutions[0] = res0*mmTocm;
+	resolutions[1] = res1*mmTocm;
+	Build( de);
+    }
+
+
+
+    public RKSurf( Subdetector sd ){
+	if ( sd == null ){
+	    System.out.println("RKSurf: Cannot instantiate RKSurf with null Subdetector." );
+	    System.exit(-1);
+	}
+
+	this.sd = sd;
+	rodim   = 0;
+	name    = sd.getName();
+	Build( sd );
+    }
+    
+    // Adjust z position.  Used in the equivstrips model.
+    public void hackZc( double dz){
+	zc+=dz;
+    }
+
+    public void Print(){
+	if ( type == type_tube ){
+	    System.out.printf ( "%-40s %1d %3d %10.2f %10.2f %10.2f %10.2f %-20s %10.2f %10.6f %10.6f\n",
+				name,
+				rodim, 
+				ixy,
+				radius,
+				thick,
+				zmin,
+				zmax,
+				matname,
+				radl,
+				thick_radl,
+				density
+				);
+	} else {
+	    System.out.printf ( "%-40s %1d %3d %10.2f %10.2f %10.2f %10.2f %-20s %10.2f %10.6f %10.6f\n",
+				name,
+				rodim, 
+				ixy,
+				zc,
+				thick,
+				rmin,
+				rmax,
+				matname,
+				radl,
+				thick_radl,
+				density
+				);
+	}
+    }
+
+
+    private void Build( Subdetector sd ){
+
+	String classname  = sd.getClass().getName();
+	String shortname  = classname.replaceAll("org.lcsim.geometry.subdetector.","");
+
+	if ( shortname.compareTo("PolyconeSupport") == 0 ) {
+	    PolyconeSupport pc = (PolyconeSupport) sd;
+	    AddPolycone(pc);
+
+	} else {
+	    System.out.println("RKSurf: Do not know how to add this subdetector: "
+			       + name + " " + classname);
+	    System.exit(-1);
+	}
+
+	matname = material.getName();
+	radl    = material.getRadiationLength();
+
+	thick_radl = thick/radl;
+
+    }
+
+    private void Build( IDetectorElement de ){
+	
+	//System.out.println ("Starting: " + name );
+	IGeometryInfo g   = de.getGeometry();
+	if ( g == null ){
+	    System.out.println("Missing geometry for detector element: " + name );
+	    System.exit(-1);
+	}
+	ILogicalVolume lv = g.getLogicalVolume();
+	if ( lv == null ){
+	    System.out.println("Missing logical volume for detector element: " + name );
+	    System.exit(-1);
+	}
+	IMaterial mat     = lv.getMaterial();
+	ISolid solid      = lv.getSolid();
+	Hep3Vector center = g.getPosition();
+
+	String solidname  = getSolidTypeName(solid);
+
+	if ( solidname.compareTo("Tube") == 0  ){
+	    Tube tube = (Tube) solid;
+	    if ( tube.getZHalfLength() > 1.0 ){
+		AddTube( tube, center );
+	    }else{
+		AddZDisc( tube, center);
+	    }
+	    
+	} else {
+	    System.out.println ( "RKSurf: Do not recognize this shape for this DetectorElement: "
+				 + solidname + " " + name );
+	    System.exit(-1);
+	}
+	matname = mat.getName();
+	radl    = mat.getRadiationLength();
+	density = mat.getDensity();
+
+	thick_radl = thick/radl;
+
+    }
+
+    private void AddPolycone ( PolyconeSupport pc ){
+	type = type_tube;
+	List<ZPlane> zplanes = pc.getZPlanes();
+	boolean ok = false;
+	for ( int i=1; i<zplanes.size(); ++i ){
+	    ZPlane zp1 = zplanes.get(i-1);
+	    ZPlane zp2 = zplanes.get(i);
+	    if ( zp1.getZ() < 0. && zp2.getZ() > 0. ){
+		if ( Math.abs(zp1.getRMax()-zp1.getRMax()) > tolerance ||
+		     Math.abs(zp1.getRMin()-zp1.getRMin()) > tolerance    ){
+		    System.out.println ("RKSurf: Mismatched radii in beampipe: "
+					+ name );
+		}
+		radius = 0.5*(zp1.getRMax() + zp1.getRMin());
+		thick  = zp1.getRMax() - zp1.getRMin();
+		zmin   = zp1.getZ();
+		zmax   = zp2.getZ();
+		ok = true;
+	    }
+	}
+
+	if ( !ok ){
+	    System.out.println( "RKSurf: Could not parse PolyconeSupport for subdetector"
+				+ name );
+	    System.exit(-1);
+	}
+
+	// Depracated but replacement appears not to be in place.
+	material = pc.getMaterial();
+
+	radl = material.getRadiationLength();
+	density = material.getDensity();
+
+    }
+
+    private void AddTube ( Tube tube, Hep3Vector center ){
+	type = type_tube;
+	if ( Math.abs( center.x()) > tolerance ||
+	     Math.abs( center.y()) > tolerance ||
+	     Math.abs( center.z()) > tolerance    ){
+	    System.out.println("RKSurf: Only do tubes centered on (0.0,0.0,0.) " );
+	    System.exit(-1);
+	}
+
+	zmin   = -tube.getZHalfLength();
+	zmax   = tube.getZHalfLength();
+	radius = 0.5*(tube.getOuterRadius()+tube.getInnerRadius());
+	thick  = tube.getOuterRadius()-tube.getInnerRadius();
+
+    }
+
+    private void AddZDisc ( Tube tube, Hep3Vector center ){
+	type   = type_zdisc;
+	zmin   = center.z()-tube.getZHalfLength();
+	zmax   = center.z()+tube.getZHalfLength();
+	radius = 0.5*(tube.getOuterRadius()+tube.getInnerRadius());
+	thick  = 2.*tube.getZHalfLength();
+	
+	zc     = center.z();
+	rmin   = tube.getInnerRadius();
+	rmax   = tube.getOuterRadius();
+    }
+
+
+
+    // Utility function to extract a short version of the class name. 
+    private String getSolidTypeName( ISolid s ){
+	String fullname = s.getClass().getName();
+	String name     = fullname.replaceAll( "org.lcsim.detector.solids.", "");
+	return name;
+    }
+
+}
CVSspam 0.2.8