Commit in GeomConverter/sandbox on MAIN | |||
HPSMuonCalorimeter.java | +226 | added 1.1 |
sandbox old and overly complicated muon cal driver
diff -N HPSMuonCalorimeter.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ HPSMuonCalorimeter.java 4 Dec 2012 01:11:54 -0000 1.1 @@ -0,0 +1,226 @@
+package org.lcsim.geometry.compact.converter.lcdd; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.jdom.Element; +import org.jdom.JDOMException; +import org.lcsim.geometry.compact.converter.lcdd.util.Box; +import org.lcsim.geometry.compact.converter.lcdd.util.LCDD; +import org.lcsim.geometry.compact.converter.lcdd.util.Material; +import org.lcsim.geometry.compact.converter.lcdd.util.PhysVol; +import org.lcsim.geometry.compact.converter.lcdd.util.Position; +import org.lcsim.geometry.compact.converter.lcdd.util.Rotation; +import org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector; +import org.lcsim.geometry.compact.converter.lcdd.util.Trap; +import org.lcsim.geometry.compact.converter.lcdd.util.Volume; + +/** + * + * To build: + * + * cd GeomConverter + * mvn clean install -DskipTests=true + * + * To generate LCDD from test geometry: + * + * java -jar ./target/GeomConverter-2.5-SNAPSHOT-bin.jar -o lcdd ./testResources/org/lcsim/geometry/subdetector/HPSMuonCalorimeterTest.xml ./HPSMuonCalorimeterTest.lcdd + * + * Parameters (initially from python): + * + * vertseg_gap <= vertical gaps between hodoscopes e.g. scintillator strips + * vertseg_num <= number of readout strips in first layer + * vertseg_size <= vertical dimension of strip + * from_target <= distance from front face to target + * absorber_layers <= how many absorber layers? + * absorber_thicknesses <= thickness of each absorber layer + * gaps <= horizontal gap between each strips and absorber + * sensor_thickness <= thickness of absorber + * theta1 <= fan out angle in y of the vacuum box (?) + * absorber_width <= 1st layer absorber width + * fan_out <= make absorbers all the same width or fan them out as depth increases + * connecting_width <= when fan_out is false then set how far in the connecting iron piece goes (?) + * theta4 <= fan out angle + * alum_plate_width <= width of the aluminum plate + * alum_side_width <= width of the side wall of the vacuum system + * alum_airgap <= gap between alum plate and iron chunks + * al_extra[1-3] <= see diagram (???) + * vac_pullz <= how far to extend the vacuum (-z) towards ecal + * vac_pushz <= how far to extend the vacuum (+z) beyond muon detector + * + * Example XML: + * <parameters vertseg_gap="0.01*cm" vertseg_num="8" vertseg_size="3.0*cm" from_target="185.0*cm" gap="0.2*cm" + * sensor_thickness="1.0*cm" theta1="0.025" absorber_width="50.0*cm" fan_out="true" + * connecting_width="40.0*cm" theta4="0.0873" /> + * <absorber_thicknesses>68.0 68.0 68.0 68.0 150.0 150.0 150.0</absorber_thicknesses> + * <vacuum alum_plate_width="1.0*cm" alum_side_width="1.0*cm" alum_airgap="0.01*cm" al_extra1="35.0*cm" + * al_extra2="20.0*cm" al_extra3="5.0*cm" /> + * + * @author jeremym + * @version $Id: HPSMuonCalorimeter.java,v 1.1 2012/12/04 01:11:54 jeremy Exp $ + */ +public class HPSMuonCalorimeter extends LCDDSubdetector { + + HPSMuonCalorimeter(Element node) throws JDOMException { + super(node); + } + + void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException { + + String name = node.getAttributeValue("name"); + int id = node.getAttribute("id").getIntValue(); + + // Get muon calorimeter parameters. + Element parameters = node.getChild("parameters"); + double vertseg_gap = parameters.getAttribute("vertseg_gap").getDoubleValue(); + int vertseg_num = parameters.getAttribute("vertseg_num").getIntValue(); + double vertseg_size = parameters.getAttribute("vertseg_size").getDoubleValue(); + double from_target = parameters.getAttribute("from_target").getDoubleValue(); + double gap = parameters.getAttribute("gap").getDoubleValue(); + double sensor_thickness = parameters.getAttribute("sensor_thickness").getDoubleValue(); + double theta1 = parameters.getAttribute("theta1").getDoubleValue(); + double absorber_width = parameters.getAttribute("absorber_width").getDoubleValue(); + boolean fan_out = parameters.getAttribute("fan_out").getBooleanValue(); + double connecting_width = parameters.getAttribute("connecting_width").getDoubleValue(); + double theta4 = parameters.getAttribute("theta4").getDoubleValue(); + + // Get the absorber thicknesses. These are hard-coded to be in mm because I don't know + // how to convert the array on the fly to arbitrary units. + String s = node.getChild("absorber_thicknesses").getText(); + StringTokenizer st = new StringTokenizer(s); + List<Double> depth = new ArrayList<Double>(); + while (st.hasMoreElements()) { + depth.add(Double.parseDouble((String)st.nextElement())); + } + + // Get vacuum box parameters. + Element vacuum = node.getChild("vacuum"); + double alum_plate_width = vacuum.getAttribute("alum_plate_width").getDoubleValue(); + double alum_side_width = vacuum.getAttribute("alum_side_width").getDoubleValue(); + double alum_airgap = vacuum.getAttribute("alum_airgap").getDoubleValue(); + double al_extra1 = vacuum.getAttribute("al_extra1").getDoubleValue(); + double al_extra2 = vacuum.getAttribute("al_extra2").getDoubleValue(); + double al_extra3 = vacuum.getAttribute("al_extra3").getDoubleValue(); + + // Computed values. + int nabsorbers = depth.size(); + double absorber_total_depth = 0.; + for (Double a : depth) { + absorber_total_depth += a; + } + double gaps_total_depth = (nabsorbers)*gap; + + //System.out.println("absorber_total_depth="+absorber_total_depth); + //System.out.println("gaps_total_depth="+gaps_total_depth); + + // Total detector depth. + double md_depth = absorber_total_depth + 2*gaps_total_depth - gap + nabsorbers*sensor_thickness; + //System.out.println("md_depth="+md_depth); + + // Z position of muon detector. + double vac_pullz = al_extra3; + double vac_pushz = al_extra1; + double muon_box_z = from_target + 0.5*md_depth - 0.5*Math.max(vac_pullz, al_extra3) + 0.5*Math.max(vac_pushz,al_extra1); + + //System.out.println("muon_box_z = " + muon_box_z); + + double md_mid = from_target - muon_box_z + 0.5*md_depth; + //System.out.println("muon_mid = " + md_mid); + + double z = from_target - muon_box_z + depth.get(0)/2; + //System.out.println("z="+z); + + double theta2 = Math.atan( (vertseg_num*vertseg_size+(vertseg_num-1)*vertseg_gap+(from_target+depth.get(0)+gap)*Math.tan(theta1) )/ (from_target+depth.get(0)+gap)); + double theta3 = Math.atan(absorber_width/(from_target)); + double theta = 0.5*(theta1+theta2); + + //System.out.println("theta2="+theta2); + //System.out.println("theta3="+theta3); + //System.out.println("theta="+theta); + + double tt1 = Math.tan(theta1); + double tt2 = Math.tan(theta2); + //System.out.println("theta3="+theta3); + double tt3 = Math.tan(theta3); + double tt4 = Math.tan(theta4); + double tt34 = Math.tan( (theta3+theta4)/2 ); + double tt = Math.tan(theta); + + // Place crystals in world volume. + Volume world = lcdd.pickMotherVolume(this); + + // Position of mother volume in the world. + Position md_pos = new Position(name + "_pos", 0, 0, muon_box_z); + lcdd.add(md_pos); + + // Compute dimensions of mother box. + double md_x, md_y, md_z; + double spacing = 20.; + //System.out.println("tt3="+tt3); + //System.out.println("md_x1="+((from_target+md_depth+al_extra1)*tt3+al_extra2)); + //System.out.println("md_x2="+(from_target+md_depth+vac_pushz)*tt3); + md_x = Math.max((from_target+md_depth+al_extra1)*tt3+al_extra2,(from_target+md_depth+vac_pushz)*tt3)+spacing; + md_y = (from_target+md_depth)*tt2+spacing; + md_z = .5*md_depth+.5*Math.max(al_extra1,vac_pushz)+.5*Math.max(al_extra3,vac_pullz); + + //System.out.println("md_x = " + md_x); + //System.out.println("md_y = " + md_y); + //System.out.println("md_z = " + md_z); + + // Create mother box. + Box muonBox = new Box(name + "_box", md_x*2, md_y*2, md_z*2); + lcdd.add(muonBox); + + Material air = lcdd.getMaterial("Air"); + + Volume md_vol = new Volume(name + "_vol", muonBox, air); + + Material iron = lcdd.getMaterial("Iron"); + + Rotation rot = new Rotation(name+"_absorber_rot", 0, 0, Math.PI/2); + lcdd.add(rot); + for (int i=0; i<nabsorbers; i++) { + + double gz = z + muon_box_z; + //System.out.println("gz="+gz); + + String base_name = name + "_layer" + i; + String abs_base_name = base_name + "_abs_"; + + Position top_pos = new Position(abs_base_name+"top_pos", 0, gz*tt, z); + lcdd.add(top_pos); + + Trap abs_top_trap = new Trap(abs_base_name+"top_trap", + .5*depth.get(i), + -theta, + 0., + ((gz-depth.get(i)/2)*tt3), + .5*(gz-depth.get(i)/2)*(tt2-tt1), + .5*(gz-depth.get(i)/2)*(tt2-tt1), + 0., + ((gz+depth.get(i)/2)*tt3), + .5*(gz+depth.get(i)/2)*(tt2-tt1), + .5*(gz+depth.get(i)/2)*(tt2-tt1), + 0); + lcdd.add(abs_top_trap); + Volume abs_top_vol = new Volume(abs_base_name+"vol", abs_top_trap, iron); + lcdd.add(abs_top_vol); + PhysVol abs_top_pv = new PhysVol(abs_top_vol, md_vol, top_pos, rot); + + // CONTINUE CODING HERE + + if (i != (nabsorbers - 1)) + z = z + .5*depth.get(i)+.5*depth.get(i+1)+2*gap+sensor_thickness; + } // nabsorbers loop + + lcdd.add(md_vol); + Rotation md_rot = new Rotation(name + "_rot"); + lcdd.add(md_rot); + PhysVol md_pv = new PhysVol(md_vol, world, md_pos, md_rot); + } + + public boolean isCalorimeter() { + return true; + } +}
\ No newline at end of file
Use REPLY-ALL to reply to list
To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1