Print

Print


Commit in GeomConverter/src/org/lcsim/detector/converter/compact on MAIN
EcalBarrelConverter.java+362-31.1 -> 1.2
implementation of EcalBarrel java version; WORK IN PROGRESS; still needs sensor ids

GeomConverter/src/org/lcsim/detector/converter/compact
EcalBarrelConverter.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- EcalBarrelConverter.java	5 Feb 2009 21:43:23 -0000	1.1
+++ EcalBarrelConverter.java	18 Sep 2009 01:54:34 -0000	1.2
@@ -1,11 +1,38 @@
 package org.lcsim.detector.converter.compact;
 
-import hep.graphics.heprep.HepRep;
-import hep.graphics.heprep.HepRepFactory;
+import static java.lang.Math.PI;
+import static java.lang.Math.acos;
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+import static java.lang.Math.sqrt;
+import static java.lang.Math.tan;
 
+import java.util.Iterator;
+
+import org.jdom.Attribute;
+import org.jdom.Element;
+import org.lcsim.detector.DetectorElement;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.ITranslation3D;
+import org.lcsim.detector.LogicalVolume;
+import org.lcsim.detector.PhysicalVolume;
+import org.lcsim.detector.RotationGeant;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.material.IMaterial;
+import org.lcsim.detector.material.MaterialStore;
+import org.lcsim.detector.solids.Box;
+import org.lcsim.detector.solids.Trd;
 import org.lcsim.geometry.compact.Detector;
 import org.lcsim.geometry.compact.Subdetector;
+import org.lcsim.geometry.layer.LayerFromCompactCnv;
+import org.lcsim.geometry.layer.LayerStack;
+import org.lcsim.geometry.layer.Layering;
 import org.lcsim.geometry.subdetector.EcalBarrel;
+import org.lcsim.geometry.subdetector.PolyhedraBarrelCalorimeter;
 
 public class EcalBarrelConverter 
 extends AbstractSubdetectorConverter
@@ -13,7 +40,339 @@
 {
     // TODO: Implement this method!
     public void convert(Subdetector subdet, Detector detector)
-    {}
+    {
+    	Element node = subdet.getNode();
+    	int sysId = subdet.getSystemID();
+    	PolyhedraBarrelCalorimeter cal = (PolyhedraBarrelCalorimeter)subdet;
+    	int nsides = cal.getNumberOfSides();
+    	double innerR = cal.getInnerR();
+    	Layering layering = cal.getLayering();
+    	LayerStack layers = layering.getLayerStack();
+    	//double thickness = layering.getThickness();
+    	double z = cal.getZLength();
+    	String name = subdet.getName();
+    	
+    	// Compute the delta phi per section.
+		double dphiModule = PI * 2.0 / nsides;
+		double hphi = dphiModule / 2;
+		
+		double moduleY1 = z;
+		double moduleY2 = moduleY1;
+
+		// Compute the total thickness of the subdetector.
+		double moduleZ = 0.;
+		try 
+		{
+			moduleZ = LayerFromCompactCnv.computeDetectorTotalThickness(node);
+		}
+		catch (Exception x)
+		{
+			throw new RuntimeException(x);
+		}
+		
+		// Compute the center Y offset of a single module.
+		double moduleYOffset = innerR + moduleZ / 2;
+		
+		// Compute the outer radius.
+		double outerR = innerR + moduleZ;
+		
+		// Compute trapezoid measurements.
+		double bo = tan(hphi) * outerR;
+		double bi = tan(hphi) * innerR;
+
+		// Compute the dx per layer, using side 
+		// triangle calculations (from Norman Graf).
+		double gamma = (PI * 2) / nsides;
+		double dx = moduleZ / sin(gamma);
+
+		// The offset of a stave, derived from the dx term.
+		double moduleXOffset = dx / 2.0;
+
+		// Compute the top and bottom face measurements.
+		double moduleX2 = 2 * bo - dx;
+		double moduleX1 = 2 * bi + dx;
+    	
+		//System.out.println("moduleX1,moduleX2,moduleY1,moduleY2,moduleZ: " + moduleX1+","+moduleX2+","+moduleY1+","+moduleY2+","+moduleZ);
+		
+		// Create the trapezoid for the stave.
+		Trd moduleTrd = new Trd(
+				name + "_module_trd", 
+				moduleX1/2, // Outer side, i.e. the "short" X side.
+				moduleX2/2, // Inner side, i.e. the "long" X side.
+				moduleY1/2, // Corresponds to subdetector (or module) Z.
+				moduleY2/2, // "
+				moduleZ/2); // Thickness, in Y for top stave, when rotated.
+		
+		LogicalVolume moduleVolume = 
+			new LogicalVolume(
+				name + "_module",
+				moduleTrd,
+				MaterialStore.getInstance().get("Air"));
+		//
+		// Build module.
+		//
+		
+		double layerZ = moduleTrd.getYHalfLength1();
+		double trdZ = moduleTrd.getZHalfLength();
+
+		// ------
+		// Parameters for computing the layer X dimension, 
+		// e.g. trapezoid's X1 value.
+		// ------
+		
+		// Adjacent angle of triangle.
+		double adj = (moduleTrd.getXHalfLength1() - moduleTrd.getXHalfLength2()) / 2;
+		
+		// Hypotenuse of triangle.
+		double hyp = sqrt(trdZ * trdZ + adj * adj);
+		
+		// Lower-right angle of triangle.
+		double beta = acos(adj / hyp);
+		
+		// Primary coefficient for figuring X.
+		double tan_beta = tan(beta); 
+		
+		double subdetectorThickness = 0;
+		try 
+		{
+			subdetectorThickness = LayerFromCompactCnv.computeDetectorTotalThickness(node);
+		}
+		catch (Exception x)
+		{
+			throw new RuntimeException(x);
+		}
+
+		double layerPositionZ = -(subdetectorThickness / 2);
+			
+		// Delta phi.
+		double dphiLayer = PI * 2.0 / nsides;
+
+		// Half delta phi.
+		double hphiLayer = dphiLayer / 2;
+
+		// Starting X dimension for the layer.
+		double layerDimX = moduleTrd.getXHalfLength1();
+
+		//if (_debug)
+		//{
+		//System.out.println("slice start posZ=" + layerPositionZ);
+		//System.out.println("dphi=" + toDegrees(dphiLayer));
+		//System.out.println("hphi=" + toDegrees(hphi));
+		//System.out.println("starting slice X=" + layerDimX);
+		//System.out.println("adj=" + adj);
+		//System.out.println("beta=" + toDegrees(beta));
+		//System.out.println("");
+		//}
+		
+		int layerNumber = 0;
+		for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();)
+		{			
+			Element layer_element = (Element) i.next();
+			int repeat = 0;
+			try 
+			{
+				repeat = (int)layer_element.getAttribute("repeat").getDoubleValue();
+			}
+			catch (Exception x)
+			{
+				throw new RuntimeException(x);
+			}
+			
+			// Loop over number of repeats for this layer.
+			for (int j=0; j<repeat; j++)
+			{
+				// Compute this layer's thickness.
+				double layerThickness = layers.getLayer(layerNumber).getThickness();
+				
+				// Increment the Z position to place this layer.
+				layerPositionZ += layerThickness / 2;
+				
+				// Name of the layer.
+				String layerName = name + "_layer" + layerNumber;
+				
+				// Position of the layer.
+				Translation3D layerPosition = 
+					new Translation3D(0, 0, layerPositionZ);
+				
+				layerPositionZ += layerThickness / 2;
+					
+				// Compute the X dimension for this layer.
+				double xcut = (layerThickness / tan_beta);
+				layerDimX -= xcut; 
+				
+				Box layerBox = new Box(
+						layerName + "_box",
+						layerDimX,
+						z/2,
+						layerThickness/2);
+				
+				LogicalVolume layerVolume = 
+					new LogicalVolume(
+							layerName, 
+							layerBox, 
+							MaterialStore.getInstance().get("Air"));
+				
+				int sliceNumber = 0;
+				double slicePositionZ = -(layerThickness / 2);
+				for (Iterator k = layer_element.getChildren("slice").iterator(); k.hasNext();)
+				{
+					Element sliceElement = (Element) k.next();
+					
+					// Name of the slice.
+					String sliceName = layerName + "_slice" + sliceNumber;
+					
+					// Sensitivity.
+					Attribute s = sliceElement.getAttribute("sensitive");
+					boolean sensitive = false;
+					try 
+					{
+						sensitive = s != null && s.getBooleanValue();
+					}
+					catch (Exception x)
+					{
+						throw new RuntimeException(x);
+					}
+					
+					// Thickness of slice.
+					double sliceThickness = 0;
+					
+					try {
+						sliceThickness = sliceElement.getAttribute("thickness").getDoubleValue();
+					}
+					catch (Exception x)
+					{
+						throw new RuntimeException(x);
+					}
+					
+					// Increment Z position of slice.
+					slicePositionZ += sliceThickness / 2;
+					
+					Translation3D slicePosition = new Translation3D(0,0,slicePositionZ);
+					
+					slicePositionZ += sliceThickness / 2;
+					
+					Box sliceBox = new Box(sliceName + "_box", 
+							layerDimX, 
+							z/2, 
+							sliceThickness/2);
+					
+					IMaterial sliceMaterial = MaterialStore.getInstance().get(sliceElement.getAttributeValue("material"));
+					
+					LogicalVolume sliceVolume = new LogicalVolume(sliceName, sliceBox, sliceMaterial);
+					
+					PhysicalVolume slicePhysVol = new PhysicalVolume(
+							new Transform3D(slicePosition, new RotationGeant(0,0,0)),
+							sliceName, 
+							sliceVolume,
+							layerVolume,
+							sliceNumber);
+					if (sensitive)
+					{
+						System.out.println("sensor slice: " + slicePhysVol.getName());
+						slicePhysVol.setSensitive(true);
+					}
+															
+					++sliceNumber;					
+				}
+				
+				ITransform3D layerTransform = 
+					new Transform3D(layerPosition, new RotationGeant(0,0,0));
+				
+				PhysicalVolume layerPhysVol =
+					new PhysicalVolume(
+							layerTransform,
+							layerName,
+							layerVolume,
+							moduleVolume,
+							layerNumber);				
+												
+				++layerNumber;					
+			}
+			
+		}		
+		
+		//
+		// End build module.
+		//
+		
+		// 
+		// Start place modules.
+		//
+		
+		// Phi start for a stave.
+		double phi = ((PI) / nsides) - PI/8;
+		
+		//System.out.println("phi start: " + phi);
+		
+		// Create DetectorElements for modules.
+		for (int i=0; i<nsides; i++)
+		{
+			//System.out.println("phi " + i + " : " + phi);
+			
+			int moduleNumber = i;
+			
+			RotationGeant rotation = new RotationGeant(PI*0.5, phi, 0);
+			
+			double modulePositionX = moduleXOffset * cos(phi) - moduleYOffset * sin(phi);
+			double modulePositionY = moduleXOffset * sin(phi) + moduleYOffset * cos(phi);
+			double modulePositionZ = 0;
+			
+			ITranslation3D trans = new Translation3D(modulePositionX, modulePositionY, modulePositionZ);
+			ITransform3D transform = new Transform3D(trans,rotation); 
+			String moduleName = name + "_module" + i;
+			new PhysicalVolume(
+					transform,
+					moduleName,
+					moduleVolume,
+					detector.getDetectorElement().getGeometry().getLogicalVolume(),
+					moduleNumber);
+			new DetectorElement(moduleName,subdet.getDetectorElement(),"/"+moduleName);
+			
+			// increment phi
+			phi -= dphiLayer;	
+		}
+		
+		//
+		// End place modules.
+		//
+		
+		//
+		// Start build DetectorElements.
+		//				
+		for (IDetectorElement module : subdet.getDetectorElement().getChildren())
+		{
+			int sensorNum = 0;
+			//int sectNum = module.getGeometry().getPhysicalVolume().getCopyNumber();
+			for (IPhysicalVolume layer : module.getGeometry().getLogicalVolume().getDaughters())
+			{
+				//System.out.println("making DE for " + layer.getName());
+				IDetectorElement deLayer = new DetectorElement( 
+						name + "_module" + module.getGeometry().getPhysicalVolume().getCopyNumber() + "_layer" + layer.getCopyNumber(), 
+						module, 
+						"/" + module.getGeometry().getPhysicalVolume().getName() + "/" + layer.getName()
+						);	
+				for (IPhysicalVolume slice : layer.getLogicalVolume().getDaughters())
+                {
+					if (slice.isSensitive())
+					{
+						String sliceName = 
+                            module.getName() + "_layer" + layer.getCopyNumber() + "_sensor" + sensorNum;
+						IDetectorElement sensor = 
+							new DetectorElement(
+									sliceName, 
+									deLayer,
+									"/" + module.getName() + "/" + layer.getName() + "/" + slice.getName());
+						System.out.println("created sensor: " + sensor.getName());
+						++sensorNum;
+					}
+                }
+				
+			}
+		}
+		//
+		// End build DetectorElements.
+		//
+    }
                 
     public Class getSubdetectorType() 
     {
CVSspam 0.2.8