15 added files
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N AllPassFilter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AllPassFilter.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,24 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+
+/**
+ *
+ * @author cozzy
+ */
+public class AllPassFilter implements IParticleFilter {
+
+ public boolean passes(MCParticle p) {
+ return true;
+ }
+
+ public void setEvent(EventHeader event){
+ return;
+ }
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N DefaultLayerWeight.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DefaultLayerWeight.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,48 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+/**
+ *The layer weighting scheme used by default by StrategyBuilder if no other is
+ * provided. It's loaded from a resource based on the name of the detector.
+ *
+ * After construction, the LayerWeight object may be accessed using getWeight();
+ *
+ * @author cozzy
+ */
+public class DefaultLayerWeight {
+
+ private static final String prefix = "default_weights_";
+ private static final String suffix = ".xml";
+
+ private LayerWeight weight;
+ public DefaultLayerWeight(String detectorName){
+ try {
+
+ // This is kind of screwy: if the detector name has a period in it,
+ // then loading the resource would normally throw an exception.
+ // We can fix this by replacing "." with "%2E" (URL encoding).
+ // It's probably best to avoid having periods in detector names
+ // though.
+
+ detectorName = detectorName.replace(".","%2E");
+ weight = LayerWeight.getLayerWeightFromResource(LayerWeight.getDefaultResourcePrefix()+prefix+detectorName+suffix);
+ } catch(Exception e) {
+ System.out.println("WARNING: could not find default layer weights for detector "+detectorName+". Falling back to empty layer weights with possibly insane default parameters.");
+ weight = new LayerWeight();
+ }
+ }
+ /**
+ * Return the constructed weight for the detector.
+ * @return The default weight for the detector name specified in the
+ * constructor, or, if nothing is found, then an unmodified LayerWeight
+ * object.
+ */
+ public LayerWeight getWeight(){
+ return weight;
+ }
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N DetectorMismatchException.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DetectorMismatchException.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,16 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+/**
+ *
+ * @author cozzy
+ */
+public class DetectorMismatchException extends RuntimeException {
+ public DetectorMismatchException(String expectedName, String actualName) {
+ super("Expected detector: "+expectedName+". Actual detector: "+actualName);
+ }
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N DumbLayer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DumbLayer.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,49 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
+
+/**Simple layer to uniquely define layers. Like SeedLayer but without
+ * information about layer type.
+ *
+ * @author cozzy
+ */
+public class DumbLayer{
+
+ String detectorName;
+ int layer;
+ BarrelEndcapFlag be;
+
+ public DumbLayer(String det, int lyr, BarrelEndcapFlag be){
+ detectorName = det;
+ layer = lyr;
+ this.be = be;
+ }
+
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if (! (other instanceof DumbLayer)) return false;
+ DumbLayer dl = (DumbLayer) other;
+ return ( this.be.equals(dl.be) &&
+ this.layer == dl.layer &&
+ this.detectorName.equals(dl.detectorName));
+ }
+
+ //dumb hash function...
+ @Override
+ public int hashCode() {
+ return 20*( be.ordinal() + 1) + layer + 500*(detectorName.hashCode() % 1000);
+ }
+
+ @Override
+ public String toString() {
+ return ("DumbLayer: det="+detectorName+" lyr="+layer+" be="+ be.toString());
+ }
+
+ }
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N ExampleDriver.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ExampleDriver.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,40 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import org.lcsim.util.Driver;
+
+/**
+ * Driver used to illustrate usage of StrategyBuilder w/out using the
+ * command line. (Look at RunStrategyBuilder to learn how to use Strategy
+ * Builder with the command line).
+ *
+ * @author cozzy
+ */
+public class ExampleDriver extends Driver {
+
+ //this will be the output file... this example outputs it in the
+ //system's temporary directory.
+ private String outputfile = System.getProperties().getProperty("java.io.tmpdir")+
+ System.getProperties().getProperty("file.separator")+
+ "ExampleStrategyList.xml";
+
+ public ExampleDriver(){
+
+ StrategyBuilder builder = new StrategyBuilder();
+
+ //set the output file
+ builder.setOutput(outputfile);
+ builder.setVerbose(true); //verbose output
+
+ //see the IStrategyBuilder interface for other settable options
+
+ add(builder);
+
+ }
+
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N IParticleFilter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IParticleFilter.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,38 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+
+/**
+ * A particle filter is applied to MCParticles in the training step. LayerSets
+ * are not generated by MCParticles which do not pass the filters. Note that
+ * a minimum number of layers hit is necessary in addition to passing the filter.
+ *
+ * The default behavior for StrategyBuilder is to use a StrategyBasedFilter, which
+ * gets cutoffs for DCA, z0 and pt based on prototype strategy.
+ *
+ *
+ * @author cozzy
+ */
+public interface IParticleFilter {
+
+ /**
+ * Returns true if the MCParticle passes the filter, false otherwise. Called
+ * for every MCParticle by StrategyBuilder.
+ *
+ * @param p The test MCParticle
+ * @return
+ */
+ public boolean passes(MCParticle p);
+
+ /**
+ * This method is called for each event by StrategyBuilder.
+ * @param event
+ */
+ public void setEvent(EventHeader event);
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N IStrategyBuilder.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ IStrategyBuilder.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,101 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import java.util.List;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+
+/**
+ *This interface is mainly written for documentation purposes (since StrategyBuilder
+ * is somewhat full of code).
+ *
+ * @author cozzy
+ */
+public interface IStrategyBuilder {
+
+ /**
+ * Sets the location of the output XML file of strategy lists
+ * @param filename
+ */
+ public void setOutput(String filename);
+
+ /**
+ * If symmetrize is true, then the Strategy will be force symmetrized between the two endcaps.
+ * @param symmetrize
+ */
+ public void setSymmetrize(boolean symmetrize);
+
+ /**
+ * Sets the minimum number of layers that an MCParticle must go through to be considered
+ * for strategy finidng
+ * @param min
+ */
+ public void setMinLayers(int min);
+
+ /**
+ * Sets the number of confirmation layers desired
+ * @param confirmed
+ */
+ public void setNumConfirmLayers(int confirmed);
+
+ /**
+ * Sets the number of seed layers desired
+ * @param seed
+ */
+ public void setNumSeedLayers(int seed);
+
+ /**
+ * Sets the LayerWeight object of the strategy builder. A layer weight is
+ * used to treat certain layers preferentially. If no layer weight specified,
+ * the default layer weight will be used.
+ * @param lw
+ */
+ public void setLayerWeight(LayerWeight lw);
+
+ /**
+ * Set the prototype for the generated strategies. The values for cutoffs
+ * and such will be copied from the prototype. If not prototype is specified,
+ * the default values for SeedStrategy will be used.
+ * @param strategy
+ */
+ public void setStrategyPrototype(SeedStrategy strategy);
+
+ /**
+ * Set a starting strategy list. New strategies will only be generated for
+ * particles not already found by the starting strategy list.
+ * @param startList
+ */
+ public void setStartingStrategyList(List<SeedStrategy> startList);
+
+ /**
+ * Enables extra output if verbose is true.
+ * @param verbose
+ */
+ public void setVerbose(boolean verbose);
+
+ /**
+ * Set the minimum unweighted score to create a strategy. This represents
+ * the minimum number of additional tracks in the test event that could
+ * theoretically be found if the strategy is included.
+ * @param score
+ */
+ public void setMinimumUnweightedScore(int score);
+
+ /**
+ * Sets the particle filter applied to MCParticles during the processing step.
+ * MCParticles which do not pass this filter will not be considered for
+ * strategy finding. Note that MCParticles must also pass the MinLayers
+ * requirement regardless of the filter.
+ *
+ * If no filter is specified, a filter will be generated from dca, z0 and
+ * pt cutoffs present in the prototype SeedStrategy.
+ *
+ * If no filter is desired, AllPassFilter may be used.
+ *
+ * @param filter
+ */
+ public void setParticleFilter(IParticleFilter filter);
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N LayerWeight.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LayerWeight.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,339 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
+import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
+import org.lcsim.util.xml.ClasspathEntityResolver;
+
+/**
+ *LayerWeights are used by SubsetScorer and to disambiguate between Seed and
+ * Confirm layers.
+ *
+ * @author cozzy
+ */
+public class LayerWeight {
+
+ private double default_weight = 1.0;
+ private double adjacence_constant = 2.0;
+ private double adjacence_exponent = 0.1;
+ private double adjacence_multiplier = 1.0;
+ private Map<DumbLayer, Double> weights;
+ private Map<String, Double> readout_efficiencies;
+ private double defaultEfficiency = 1.0;
+ private String targetDetector = "None Specified";
+ private boolean divideByTwo = false;
+
+ public LayerWeight(){
+ weights = new HashMap<DumbLayer,Double>();
+ readout_efficiencies = new HashMap<String,Double>();
+ }
+
+ public LayerWeight(LayerWeight lw){
+ this.default_weight = lw.default_weight;
+ this.weights = lw.weights;
+ this.readout_efficiencies = lw.readout_efficiencies;
+ }
+
+ public LayerWeight(DumbLayer[] layers, double[] wghts, String[] readoutNames, double[] readoutEfficiencies){
+ if (layers.length!=wghts.length || readoutNames.length!=readoutEfficiencies.length)
+ throw new RuntimeException("Array lengths don't match");
+
+
+ weights = new HashMap<DumbLayer,Double>();
+
+ for (int i = 0; i < layers.length; i++)
+ setWeight(layers[i], wghts[i]);
+
+ readout_efficiencies = new HashMap<String,Double>();
+ for (int i = 0 ; i < layers.length; i++)
+ setReadoutEfficiency(readoutNames[i],readoutEfficiencies[i]);
+ }
+
+ public void setDefaultWeight(double d){
+ default_weight = d;
+ }
+
+ public void setDefaultReadoutEfficiency(double d){
+ checkReadoutEfficiencyValid(d);
+ defaultEfficiency = d;
+ }
+
+ public void setWeight(DumbLayer lyr, double weight){
+ weights.put(lyr, weight);
+ }
+
+ public void setReadoutEfficiency(String readoutName, double eff){
+ checkReadoutEfficiencyValid(eff);
+ readout_efficiencies.put(readoutName, eff);
+
+ }
+ public void setTargetDetector(String name){
+ targetDetector = name;
+ }
+
+ public String getTargetDetector() {
+ return targetDetector;
+ }
+
+ public double getWeight(DumbLayer layer) {
+ if (weights.containsKey(layer)){
+ return weights.get(layer).doubleValue();
+ } else return default_weight;
+ }
+
+ public double getReadoutEfficiency(String readoutName) {
+ if (readout_efficiencies.containsKey(readoutName)) {
+ return readout_efficiencies.get(readoutName);
+ } else return defaultEfficiency;
+ }
+
+ public double getWeight(Set<DumbLayer> set) {
+ double ret = 0.0;
+
+ for (DumbLayer lyr : set) {
+ ret+=getWeight(lyr);
+ }
+
+ ret /= (double) set.size();
+ return ret;
+ }
+
+ public double getAdjacenceConstant() {
+ return adjacence_constant;
+ }
+
+ public double getAdjacenceMultiplier() {
+ return adjacence_multiplier;
+ }
+
+ public void setAdjacenceMultiplier(double adjacence_multiplier) {
+ this.adjacence_multiplier = adjacence_multiplier;
+ }
+
+ public void setAdjacenceConstant(double adjacence_constant) {
+ this.adjacence_constant = adjacence_constant;
+ }
+
+ public double getAdjacenceExponent() {
+ return adjacence_exponent;
+ }
+
+ public void setAdjacenceExponent(double adjacence_exponent) {
+ this.adjacence_exponent = adjacence_exponent;
+ }
+
+ public boolean isDivideByTwo() {
+ return divideByTwo;
+ }
+
+ public void setDivideByTwo(boolean divideByTwo) {
+ this.divideByTwo = divideByTwo;
+ }
+
+
+
+ /**
+ * Returns the prefix of the default resource path to where the
+ * layer weight XML files are stored.
+ * @return default resource path to XML weights
+ */
+ public static String getDefaultResourcePrefix(){
+ return "org/lcsim/contrib/seedtracker/strategybuilder/weights/";
+ }
+
+ /**
+ * Loads LayerWeight definitions from the resource with the specified name.
+ * The name should be something like /org/lcsim/contrib/seedtracker/strategybuilder/weights/weights.xml
+ *
+ * getDefaultResourcePrefix() may be helpful.
+ *
+ * @param resourceName the full name of the resource file to read
+ * @return the read LayerWeight definitions
+ */
+ public static LayerWeight getLayerWeightFromResource(String resourceName) {
+ return getLayerWeightFromInputStream(LayerWeight.class.getClassLoader().getResourceAsStream(resourceName));
+
+ }
+
+
+ public Comparator getComparator(){
+ return new Comparator(){
+ public int compare(Object o1, Object o2) {
+ DumbLayer dl1 = (DumbLayer) o1;
+ DumbLayer dl2 = (DumbLayer) o2;
+ double s1 = LayerWeight.this.getWeight(dl1);
+ double s2 = LayerWeight.this.getWeight(dl2);
+ return Double.compare(s1, s2);
+ }
+ };
+ }
+
+
+ /**
+ * Loads LayerWeight definitions from the specified input stream
+ * @param in an input stream corresponding to a valid XML file
+ * @return the read LayerWeight definitions
+ */
+ public static LayerWeight getLayerWeightFromInputStream(InputStream in){
+
+ Document doc;
+ SAXBuilder builder = new SAXBuilder();
+ builder.setValidation(true);
+ builder.setFeature("http://apache.org/xml/features/validation/schema", true);
+ builder.setEntityResolver(new ClasspathEntityResolver());
+ try {
+ doc = builder.build(in);
+ } catch (JDOMException jdom) {
+ jdom.printStackTrace();
+ throw new RuntimeException("JDOM exception occurred");
+ } catch (IOException io ) {
+ io.printStackTrace();
+ throw new RuntimeException("IO Exception occurred");
+ }
+
+ return getLayerWeightFromDocument(doc);
+
+ }
+ /**
+ * Loads LayerWeight definitions from the specified file.
+ * @param file a valid XML file specifying layer weights
+ * @return the read LayerWeight definitions
+ */
+ public static LayerWeight getLayerWeightFromFile(File file){
+
+ if (! file.exists() )
+ throw new RuntimeException("File "+file.toString()+" not found");
+
+ Document doc;
+ SAXBuilder builder = new SAXBuilder();
+ builder.setValidation(true);
+ builder.setFeature("http://apache.org/xml/features/validation/schema", true);
+ builder.setEntityResolver(new ClasspathEntityResolver());
+ try {
+ doc = builder.build(file);
+ } catch (JDOMException jdom) {
+ jdom.printStackTrace();
+ throw new RuntimeException("JDOM exception occurred");
+ } catch (IOException io ) {
+ io.printStackTrace();
+ throw new RuntimeException("IO Exception occurred");
+ }
+
+ return getLayerWeightFromDocument(doc);
+ }
+
+ private void checkReadoutEfficiencyValid(double d){
+ if (d < 0. || d > 1.00000001)
+ throw new RuntimeException("Readout Efficiency must be between 0 and 1");
+ }
+
+ private static LayerWeight getLayerWeightFromDocument(Document doc) {
+ Element root = doc.getRootElement();
+ LayerWeight lw = new LayerWeight();
+
+ try {
+ lw.setDefaultWeight(Double.valueOf(root.getChildText("DefaultWeight")).doubleValue());
+ lw.setDefaultReadoutEfficiency(Double.valueOf(root.getChildText("DefaultReadoutEfficiency")));
+ try {lw.setAdjacenceMultiplier(Double.valueOf(root.getChildText("AdjacenceMultiplier")).doubleValue());} catch(NullPointerException npe){}
+ try {lw.setAdjacenceConstant(Double.valueOf(root.getChildText("AdjacenceConstant")).doubleValue());} catch(NullPointerException npe){}
+ try {lw.setAdjacenceExponent(Double.valueOf(root.getChildText("AdjacenceExponent")).doubleValue());} catch(NullPointerException npe){}
+ try {lw.setTargetDetector(root.getChildText("TargetDetector"));} catch(NullPointerException npe){}
+ try {lw.setDivideByTwo(Boolean.valueOf(root.getChild("TargetDetector").getAttributeValue("divide_by_two_in_tracker_endcap")));} catch(NullPointerException npe){}
+ Element layers = root.getChild("Layers");
+ for (Object o : layers.getChildren("Layer")){
+
+ Element e = (Element) o;
+ String detName = e.getAttributeValue("detector_name");
+ int layer_number = Integer.valueOf(e.getAttributeValue("layer_number")).intValue();
+ BarrelEndcapFlag beflag = BarrelEndcapFlag.valueOf(e.getAttributeValue("be_flag"));
+ DumbLayer dl = new DumbLayer(detName, layer_number, beflag);
+ lw.setWeight(dl, Double.valueOf(e.getText()));
+ }
+
+ Element ro = root.getChild("ReadoutEfficiencies");
+
+ if (ro!=null) {
+ for (Object o : ro.getChildren("ReadoutEfficiency")){
+ Element e = (Element) o;
+ String readoutName = e.getAttributeValue("readout");
+ lw.setReadoutEfficiency(readoutName, Double.valueOf(e.getText()));
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("Something bad happened when parsing");
+ }
+
+ return lw;
+ }
+ /**
+ * Writes this LayerWeight to an XML file with a location specified
+ * by the given file object.
+ * @param file output File object
+ * @return true if succesful, false otherwise.
+ */
+ public boolean writeToFile(File file){
+ Element root = new Element("LayerWeight");
+ Document doc = new Document(root);
+ Namespace xs = Namespace.getNamespace("xs", "http://www.w3.org/2001/XMLSchema-instance");
+ root.addNamespaceDeclaration(xs);
+ root.setAttribute(new Attribute("noNamespaceSchemaLocation","http://lcsim.org/contrib/seedtracker/strategybuilder/strategies.xsd",xs));
+ root.addContent(new Element("DefaultWeight").addContent(String.valueOf(default_weight)));
+ root.addContent(new Element("DefaultReadoutEfficiency").addContent(String.valueOf(defaultEfficiency)));
+ root.addContent(new Element("TargetDetector").addContent(String.valueOf(targetDetector)).setAttribute("divide_by_two_in_tracker_endcap", String.valueOf(divideByTwo)));
+ root.addContent(new Element("AdjacenceConstant").addContent(String.valueOf(adjacence_constant)));
+ root.addContent(new Element("AdjacenceMultiplier").addContent(String.valueOf(adjacence_multiplier)));
+ root.addContent(new Element("AdjacenceExponent").addContent(String.valueOf(adjacence_exponent)));
+
+ Element ro = new Element("ReadoutEfficiencies");
+
+ for (String readout : readout_efficiencies.keySet()) {
+ Element re = new Element("ReadoutEfficiency");
+ re.setAttribute("readout",readout);
+ re.addContent(String.valueOf(readout_efficiencies.get(readout)));
+ ro.addContent(re);
+ }
+ root.addContent(ro);
+
+ Element layers = new Element("Layers");
+ for (DumbLayer lyr : weights.keySet()) {
+ Element layer = new Element("Layer");
+ layer.setAttribute("layer_number", String.valueOf(lyr.layer));
+ layer.setAttribute("detector_name", String.valueOf(lyr.detectorName));
+ layer.setAttribute("be_flag", lyr.be.toString());
+ layer.addContent(String.valueOf(weights.get(lyr)));
+ layers.addContent(layer);
+ }
+ root.addContent(layers);
+
+ try {
+ XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
+ FileWriter fw = new FileWriter(file);
+ out.output(doc, fw);
+ } catch (Exception e){
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+ }
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N NonPromptFilter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NonPromptFilter.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,35 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import org.lcsim.recon.tracking.seedtracker.analysis.HelixParamCalculator;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+
+/**
+ *
+ * @author cozzy
+ */
+public class NonPromptFilter implements IParticleFilter {
+
+ private EventHeader event;
+ private double minDist = 10.0;
+ private double minPT = 1.0;
+ public boolean passes(MCParticle p) {
+
+ HelixParamCalculator calc = new HelixParamCalculator(p, event);
+
+ if (calc.getDCA() < minDist && calc.getZ0() < minDist) return false;
+ if (calc.getMCTransverseMomentum() < minPT) return false;
+ return true;
+
+ }
+
+ public void setEvent(EventHeader event){
+ this.event = event;
+ }
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N RunStrategyBuilder.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ RunStrategyBuilder.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,195 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import java.io.File;
+import org.lcsim.recon.tracking.seedtracker.StrategyXMLUtils;
+import org.lcsim.util.Driver;
+import org.lcsim.util.loop.LCSimLoop;
+
+/**
+ * Class used to run StrategyBuilder from outside of Jas3.
+ *
+ * With Maven 2, it is possible to use the command (from inside the base lcsim directory):
+ *
+ * mvn exec:java -Dexec.mainClass="org.lcsim.contrib.seedtracker.strategybuilder.RunStrategyBuilder" -Dexec.args="arg1 arg2 etc..."
+ *
+ * A shell script to do this is provided in resources/org/lcsim/contrib/seedtracker/strategybuilder/,
+ * note that the script should be run from the base lcsim directory.
+ *
+ * If anybody wants to write a windows shell script, that would be great.
+ *
+ * @author cozzy
+ */
+public class RunStrategyBuilder {
+ public static void main(String[] args) {
+ String filename="";
+ String outFile = StrategyBuilder.defaultOutputFile;
+ int numEvents=-1;
+ String startingStrategies = "";
+ String prototypeFile = "";
+ int prototypeN = -1;
+ boolean verbose = StrategyBuilder.defaultVerbose;
+ boolean symmetrize = StrategyBuilder.defaultSymmetrize;
+ String lwfn = "";
+ int mintrks = StrategyBuilder.defaultMinUnweightedScore;
+ String filterClassName = "";
+ String altDriver = "";
+
+ //parse arguments.. if error print usage
+ try{
+ int no_flag_counter = 0;
+ for (int i = 0; i < args.length; i++){
+
+ String arg = args[i];
+
+ if (arg.equals("-h")) {
+ printUsage();
+ System.exit(0);
+ } else if (arg.equals("-o")) {
+ outFile = args[++i];
+ } else if (arg.equals("-e")) {
+ numEvents = Integer.valueOf(args[++i]);
+ } else if (arg.equals("-s")) {
+ startingStrategies = args[++i];
+ } else if (arg.equals("-p")) {
+ prototypeFile = args[++i];
+ prototypeN = Integer.valueOf(args[++i]);
+ } else if (arg.equals("-v")) {
+ verbose = !verbose;
+ } else if (arg.equals("-l")) {
+ lwfn = args[++i];
+ } else if (arg.equals("-m")) {
+ mintrks = Integer.valueOf(args[++i]);
+ } else if (arg.equals("-f")) {
+ filterClassName = args[++i];
+ } else if (arg.equals("-a")) {
+ altDriver = args[++i];
+ } else if (arg.equals("-y")) {
+ symmetrize = !symmetrize;
+ } else if (arg.startsWith("-")){
+ throw new Exception();
+ } else {
+ if (no_flag_counter > 0) throw new Exception();
+ no_flag_counter++;
+ filename = arg;
+ }
+ }
+ if (no_flag_counter == 0) throw new Exception();
+
+ } catch (Exception e){
+ printUsage();
+ System.exit(1);
+ }
+ IStrategyBuilder builder = new StrategyBuilder();
+
+ if (altDriver.length() > 0) {
+ try {
+ builder = (IStrategyBuilder) Class.forName(altDriver).newInstance();
+ } catch (ClassNotFoundException cfne) {
+ System.out.println("Class "+altDriver+ " not found :'( Exiting.");
+ System.exit(3);
+ } catch (InstantiationException ie) {
+ System.out.println("Class "+altDriver+ " could not be instantiated. Does the constructor take arguments? Exiting.");
+ System.exit(4);
+ } catch (IllegalAccessException iae) {
+ System.out.println("IllegalAccessException? WTF does that mean? Exiting.");
+ System.exit(5);
+ } catch (ClassCastException cce) {
+ System.out.println("Unable to cast "+altDriver+ " as a IStrategyBuilder. Exiting");
+ System.exit(6);
+ }
+
+ if (!(builder instanceof Driver)) {
+ System.out.println("Alternative driver must extend Driver. Exiting");
+ System.exit(14123);
+ }
+ }
+
+ builder.setVerbose(verbose);
+ builder.setMinimumUnweightedScore(mintrks);
+ builder.setOutput(outFile);
+ builder.setSymmetrize(symmetrize);
+
+ if (startingStrategies.length() > 0)
+ builder.setStartingStrategyList(StrategyXMLUtils.getStrategyListFromFile(new File(startingStrategies)));
+
+ if (prototypeFile.length() > 0)
+ builder.setStrategyPrototype(StrategyXMLUtils.getStrategyListFromFile(new File(prototypeFile)).get(prototypeN));
+
+ if (lwfn.length() > 0)
+ builder.setLayerWeight(LayerWeight.getLayerWeightFromFile(new File(lwfn)));
+
+
+ // if a non-default MCParticle Filter is set, then try to load it and assign it.
+ if (filterClassName.length() > 0){
+ try {
+ builder.setParticleFilter((IParticleFilter) Class.forName(filterClassName).newInstance());
+ } catch (ClassNotFoundException cfne) {
+ System.out.println("Class "+filterClassName+ " not found :'( Exiting.");
+ System.exit(123);
+ } catch (InstantiationException ie){
+ System.out.println("Class "+filterClassName+ " could not be instantiated. Does the constructor take arguments? Exiting.");
+ System.exit(234);
+ } catch (IllegalAccessException iae){
+ System.out.println("IllegalAccessException? WTF does that mean? Exiting.");
+ System.exit(345);
+ } catch (ClassCastException cce){
+ System.out.println("Unable to cast "+filterClassName+ " as a IParticleFilter. Exiting");
+ System.exit(456);
+ }
+ }
+
+ // check data file existence
+ File file = new File(filename);
+ if (!file.exists()) {
+ System.out.println("Cannot find data file "+file.toString()+". Exiting. ");
+ System.exit(7);
+ }
+
+
+ if(verbose){
+ System.out.println("Starting... Reading Geometry");
+ }
+
+
+ //load the driver and run it.
+ try {
+
+ LCSimLoop loop = new LCSimLoop();
+ loop.setLCIORecordSource(file);
+ loop.add( (Driver) builder );
+ loop.loop(numEvents, null);
+ loop.dispose();
+ } catch (Exception e){
+ e.printStackTrace();
+ throw new RuntimeException("oopsie");
+ }
+ }
+
+
+ private static void printUsage(){
+
+ System.out.println("Usage: RunStrategyBuilder INPUTRECORD [flags]");
+ System.out.println(" -h \t\t\t\tPrint this message");
+ System.out.println(" -v \t\t\t\tBe verbose");
+ System.out.println(" -y \t\t\t\tDon't auto-symmetrize north/south. \n\t\t\t\t You may want to do this is starting strategies\n\t\t\t\t aren't symmetric.");
+ System.out.println(" -o OUTPUTFILE \t\t\tset output XML file to OUTPUTFILE\n\t\t\t\t (default is in TEMP dir)");
+ System.out.println(" -e NUM_EVENTS \t\t\tRun only NUM_EVENTS events instead of all");
+ System.out.println(" -s STARTING_STRATEGY_FILE \tUse starting strategies in the specified file");
+ System.out.println(" -p PROTOTYPE_STRATEGY_FILE N\tUse the Nth strategy in the specified file\n\t\t\t\t as a prototype. N is 0-indexed.");
+ System.out.println(" -l LAYER_WEIGHTS_FILE\t\tUse the weights in the specified file");
+ System.out.println(" -m MIN_TRKS_FOR_STRATEGY \tMinimum number of tracks to \n\t\t\t\t that could theoretically be found" +
+ "\n\t\t\t\tnecessary to make a strategy\n\t\t\t\t (default: 3)");
+ System.out.println(" -f FILTER_CLASS\t\tSpecify an MCParticle filter by naming a " +
+ "\n\t\t\t\t fully qualified (i.e. org.lcsim.etc) class. \n\t\t\t\t By default, " +
+ "a filter based on the prototype \n\t\t\t\t strategy cutoffs is used.");
+ System.out.println(" -a ALTERNATIVE_DRIVER\t\tUse an alternative driver instead of \n\t\t\t\t the default StrategyBuilder. " +
+ "Must implement\n\t\t\t\t IStrategyBuilder and extend Driver. UNTESTED.\n\t\t\t\t " +
+ "Fully qualified class name must be used \n\t\t\t\t (i.e. org.lcsim.etc)");
+ }
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N StrategyBasedFilter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ StrategyBasedFilter.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,48 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.recon.tracking.seedtracker.analysis.HelixParamCalculator;
+
+/**
+ *A filter based on the cutoff values in a SeedStrategy.
+ * @author cozzy
+ */
+public class StrategyBasedFilter implements IParticleFilter {
+
+ double pt;
+ double dca;
+ double z0;
+ double b;
+ Hep3Vector ip = new BasicHep3Vector(0., 0., 0.);
+
+ public StrategyBasedFilter(SeedStrategy strategy){
+ pt = strategy.getMinPT();
+ dca = strategy.getMaxDCA();
+ z0 = strategy.getMaxZ0();
+
+ }
+
+
+ public boolean passes(MCParticle p) {
+ HelixParamCalculator calc = new HelixParamCalculator(p, b);
+ return (
+ Math.abs(calc.getDCA()) < dca &&
+ Math.abs(calc.getZ0()) < z0 &&
+ calc.getMCTransverseMomentum() > pt
+ );
+ }
+
+ public void setEvent(EventHeader event){
+ b = event.getDetector().getFieldMap().getField(ip).z();
+ }
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N StrategyBuilder.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ StrategyBuilder.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,506 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import org.lcsim.recon.tracking.seedtracker.SeedLayer;
+import org.lcsim.recon.tracking.seedtracker.SeedLayer.SeedType;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.recon.tracking.seedtracker.StrategyXMLMetadata;
+import org.lcsim.recon.tracking.seedtracker.StrategyXMLUtils;
+import org.lcsim.detector.DetectorElementStore;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IDetectorElementContainer;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.fit.helicaltrack.HitIdentifier;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
+import org.lcsim.util.Driver;
+
+/**
+ * StrategyBuilder automatically generates strategies for a detector by
+ * seeing what layers MCParticles tend to go through.
+ *
+ * See interface for public method doc.
+ *
+ * @author cozzy
+ */
+public class StrategyBuilder extends Driver implements IStrategyBuilder {
+
+ public static final String defaultOutputFile = System.getProperties().getProperty("java.io.tmpdir")+
+ System.getProperties().getProperty("file.separator")+
+ "BuiltStrategies.xml";
+
+ //these are defined separately because RunStrategyBuilder uses some of these too...
+ public static final boolean defaultVerbose = false;
+ public static final int defaultMinLayers = 7;
+ public static final int defaultConfirmLayers =1;
+ public static final int defaultSeedLayers =3;
+ public static final int defaultMinUnweightedScore = 1;
+ public static final boolean defaultSymmetrize = true;
+
+ private boolean verbose = defaultVerbose;
+ private boolean symmetrize = defaultSymmetrize;
+ private int min_layers = defaultMinLayers;
+ private int confirm_layers = defaultConfirmLayers;
+ private int seed_layers = defaultSeedLayers;
+ private String outputFile = defaultOutputFile;
+ private int minUnweightedScore = defaultMinUnweightedScore;
+ private boolean oldConfirm = false;
+ private List<SeedStrategy> startingStrategies = new ArrayList<SeedStrategy>();
+ private Set<Set<DumbLayer>> startingSet = new HashSet<Set<DumbLayer>>(); //this will be generated from startingStrategies
+ private SeedStrategy prototype = new SeedStrategy("null", new ArrayList<SeedLayer>());
+ private LayerWeight weighter = null;
+ private HitIdentifier ID = new HitIdentifier();
+ //this stores the list of all sets of layers
+ private List<Set<DumbLayer>> setlist = new ArrayList<Set<DumbLayer>>();
+ private String detectorName;
+ private IParticleFilter filter;
+ private List<List<DumbLayer>> adjacentlist = new ArrayList<List<DumbLayer>>();
+ //4:26
+ private Random random = new Random();
+
+
+ @Override
+ protected void startOfData(){
+ //Use default filter if none is specified
+ if (filter==null) {
+ filter = new StrategyBasedFilter(prototype);
+ }
+ }
+
+ //In the process step, we build two lists of collections:
+ // The set list is a list of the sets of layers hit by MCParticles hitting over min layers layers
+ // The adjacence list is a list of a list of hits that are determined to be adjacent based on MCParticle trajectory
+ @Override
+ protected void process(EventHeader event){
+
+ super.process(event);
+
+ if (verbose) {
+ if (event.getEventNumber() % 100 == 0)
+ System.out.println("Processed "+event.getEventNumber()+" events.");
+ }
+
+ filter.setEvent(event);
+
+ //Build MCMap from SimTrackerHits, including inefficiency modeling
+ Map<MCParticle, List<SimTrackerHit>> mcmap = buildMCMap(event);
+
+ //filter MCs
+ Iterator<MCParticle> mciter = mcmap.keySet().iterator();
+ while (mciter.hasNext()){
+ MCParticle next = mciter.next();
+ if (!filter.passes(next)){
+ mciter.remove();
+ }
+ }
+
+ //Build and add layer sets, as well as adjacent lists
+ for(List<SimTrackerHit> l : mcmap.values()) {
+ Set<DumbLayer> set = new HashSet<DumbLayer>();
+
+ //sort by time, which allows creation of adjacence lists.
+ Collections.sort(l, new Comparator() {
+
+ public int compare(Object o1, Object o2) {
+ SimTrackerHit h1 = (SimTrackerHit) o1;
+ SimTrackerHit h2 = (SimTrackerHit) o2;
+ return Double.compare(h1.getTime(), h2.getTime());
+ }
+ });
+
+ //this will store all the working adjacent lists
+ LinkedList<List<DumbLayer>> tempAdjacentLayersList = new LinkedList<List<DumbLayer>>();
+
+ for (SimTrackerHit h : l) {
+ IDetectorElementContainer cont = DetectorElementStore.getInstance().find(h.getIdentifier());
+ if(cont.isEmpty()) continue;
+ IDetectorElement de = cont.get(0);
+ String detname = ID.getName(de);
+ int lyr = ID.getLayer(de);
+ BarrelEndcapFlag be = ID.getBarrelEndcapFlag(de);
+
+ //kludgy divide by two thing
+ if (weighter.isDivideByTwo() && be.isEndcap() &&
+ (detname.indexOf("Tracker") > -1 || detname.indexOf("Tkr") > -1) ) {
+ lyr/=2; // sid01 doubles up on layer numbering in the endcap.
+ }
+
+ //if symmetrizing, we want to treat North and South layers equivalently.
+ if (symmetrize && be.isEndcap()) be = BarrelEndcapFlag.ENDCAP;
+ DumbLayer dl = new DumbLayer(detname, lyr, be);
+ set.add(dl);
+
+ //create a new adjacent list that starts with this layer if none already exists
+ //(This is necessary because of the doubling of SimTrackerHits in the tracker endcap)
+ if (tempAdjacentLayersList.isEmpty() || !tempAdjacentLayersList.getLast().contains(dl)) {
+ List<DumbLayer> adjacentLayers = new ArrayList<DumbLayer>();
+ tempAdjacentLayersList.addLast(adjacentLayers);
+ }
+
+ //see which adjacent lists already have enough layers, and add those to the list
+ Iterator<List<DumbLayer>> it = tempAdjacentLayersList.iterator();
+ while (it.hasNext()) {
+ List<DumbLayer> s = it.next();
+ if(!s.contains(dl)) s.add(dl); //otherwise we get doubled layers in the forward region of the tracker
+ if (s.size() == confirm_layers + seed_layers) {
+ adjacentlist.add(s);
+ it.remove();
+ }
+ }
+ }
+
+ //Ensure layer set has minimum number of layers
+ if (set.size() >= min_layers)
+ setlist.add(set);
+ }
+ }
+
+ @Override
+ protected void suspend(){
+
+ if (verbose) System.out.println("Finished processing. Beginning analysis.");
+ Set<DumbLayer> allLayers = new HashSet<DumbLayer>();
+
+ //Get all layers that are used at some point
+ for (Set<DumbLayer> set : setlist)
+ allLayers.addAll(set);
+ if (verbose) System.out.println(allLayers.size()+" total layers.");
+
+ //create startingSet... this will be used so that new strategies aren't extraneously generated
+ for (SeedStrategy strategy : startingStrategies){
+ Set<DumbLayer> subset = new HashSet<DumbLayer>();
+ for (SeedLayer lyr : strategy.getLayers(SeedLayer.SeedType.Seed))
+ subset.add(new DumbLayer(lyr.getDetName(), lyr.getLayer(), lyr.getBarrelEndcapFlag()));
+
+ for (SeedLayer lyr: strategy.getLayers(SeedLayer.SeedType.Confirm))
+ subset.add(new DumbLayer(lyr.getDetName(), lyr.getLayer(), lyr.getBarrelEndcapFlag()));
+ startingSet.add(subset);
+ }
+ if (verbose) System.out.println(startingStrategies.size()+" starting strategies defined.");
+
+ //If any of the starting strategies can find a set, discard it.
+ Iterator<Set<DumbLayer>> iter = setlist.iterator();
+ while (iter.hasNext()){
+ Set<DumbLayer> this_set = iter.next();
+ if (startingCanFind(this_set)){
+ iter.remove();
+ }
+ }
+
+ //Generate the scorer and assign its weighter
+ SubsetScorer scorer = new SubsetScorer(setlist,adjacentlist);
+ scorer.setLayerWeight(weighter);
+
+ //Generate all possible subsets of the right size of allLayers
+ List<Set<DumbLayer>> all_subsets = StrategyBuilderUtils.generateAllPossibleDumbLayerSubsetsList(allLayers, confirm_layers+seed_layers);
+ if (verbose) System.out.println(all_subsets.size() + " possible subsets of size "+(confirm_layers+seed_layers));
+
+ //convert setlist to set to eliminate duplicates...
+ Set<Set<DumbLayer>> setset = new HashSet<Set<DumbLayer>>(setlist.size());
+ setset.addAll(setlist);
+
+ //usedSets keeps track of what has been used already
+ Set<Set<DumbLayer>> usedSets = new HashSet<Set<DumbLayer>>(setset.size());
+
+ //final_sets will store the generated seed + confirm layers
+ Set<Set<DumbLayer>> final_sets = new HashSet<Set<DumbLayer>>();
+ if (verbose) System.out.println("Layer set has "+setset.size()+" entries.");
+ //map from a final_set to all other associated layers to generate extension layers
+ Map<Set<DumbLayer>, Set<DumbLayer>> extendmap = new HashMap<Set<DumbLayer>,Set<DumbLayer>>();
+
+ //Figure out a "good" set of four-layer combinations by brute force...
+ //We have a scoring algorithm and we find the maximal scoring one.
+ while (true){
+ if (usedSets.size() == setset.size()) break; //if we've used all sets, then we're done!
+
+ Set<DumbLayer> max = all_subsets.get(0);
+ double maxScore = 0;
+
+ //get the highest scoring strategy...
+ for (Set<DumbLayer> trial : all_subsets){
+ double score = scorer.getScore(trial);
+ if (score > maxScore) {
+ maxScore = score;
+ max = trial;
+ }
+ }
+
+ //ignore anything that has too few occurrences...
+ if (scorer.getUnweightedScore(max) <= minUnweightedScore) break;
+
+ scorer.markUsed(max);
+ final_sets.add(max);
+ extendmap.put(max, new HashSet<DumbLayer>());
+
+ for (Set<DumbLayer> this_set : setset) {
+ if (this_set.containsAll(max)) { //If this set contains all the layers in max, it should be findable!
+
+ //add extension layers to extendmap
+ Set<DumbLayer> nw = new HashSet<DumbLayer>();
+ for (DumbLayer dumb : this_set){
+ if(!max.contains(dumb)) nw.add(dumb);
+ }
+ Set<DumbLayer> old = extendmap.get(max);
+ old.addAll(nw);
+ extendmap.put(max, old);
+
+ //remove this set from consideration
+ usedSets.add(this_set);
+ }
+ }
+
+ if (verbose) System.out.println(setset.size() - usedSets.size() + " entries left to be covered.");
+ }
+ if(verbose) System.out.println("Done finding strategies");
+ if(verbose) System.out.println(final_sets.toString());
+
+ //Generate the StrategyList
+ int counter = 0;
+ List<SeedStrategy> strat_list = new ArrayList<SeedStrategy>();
+ strat_list.addAll(startingStrategies);
+
+
+ //create Strategies from final_sets... this part is klunky right now.
+ for (Set<DumbLayer> s : final_sets) {
+
+ List<DumbLayer> dlyrlst = new ArrayList<DumbLayer>();
+ dlyrlst.addAll(s);
+
+ /**
+ * Here we figure out which layers to use for seeding and which to use
+ * for confirming. Since it is highly advantageous for the seed layers
+ * to be adjacent, we will try to enforce that if possible.
+ */
+
+ //get adjacence info if set is adjacent.
+ List<DumbLayer> adjacenceInfo = null;
+ for (List<DumbLayer> l : adjacentlist) {
+ if (s.containsAll(l) && l.containsAll(s)) {
+ adjacenceInfo = l;
+ break;
+ }
+ }
+
+ //if not all layers are adjacent, then perhaps a subset of size seed_layers is...
+ if (adjacenceInfo == null) {
+ for (Set<DumbLayer> ss : StrategyBuilderUtils.generateAllPossibleDumbLayerSubsetsList(s, seed_layers)){
+ for (List<DumbLayer> l : adjacentlist) {
+ if (ss.containsAll(l) && l.containsAll(ss)) {
+ adjacenceInfo = l;
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * The following operations manipulate dlyrlst such that the first num_confirm items will be
+ * used for confirmation and the rest will be used for seeding.
+ *
+ * This is kind of kludgy and it might be less confusing if it were changed.
+ */
+
+ //if these layers aren't adjacent, just use the weights to figure out which layers to confirm with
+ if (adjacenceInfo == null || oldConfirm) {
+ //sort the list from smallest to largest weight. Use smallest weight(s) for confirmation layer(s).
+ Collections.sort(dlyrlst, weighter.getComparator());
+ }
+
+ //If all layers are adjacent, we use either the first or last layers to confirm, depending on the layer weights
+ else if (adjacenceInfo.size() == dlyrlst.size()) {
+ dlyrlst = adjacenceInfo;
+ if (weighter.getWeight(dlyrlst.get(0)) > weighter.getWeight(dlyrlst.get(dlyrlst.size()-1)))
+ Collections.reverse(dlyrlst);
+
+ //Otherwise, use the adjacent layers as seeds and not the others...
+ } else {
+ dlyrlst.removeAll(adjacenceInfo);
+ dlyrlst.addAll(adjacenceInfo);
+ }
+
+ int confirmed = 0; //add the first num_confirm as confirmed... the rest as seed.
+
+ List<SeedLayer> lyrlst = new ArrayList<SeedLayer>();
+
+ //get extension layers...sort from smallest weight to largest weight
+ // because the list will be reversed.
+ List<SeedLayer> extendlyr = new ArrayList<SeedLayer>();
+ List<DumbLayer> dumbextendlyr = new ArrayList<DumbLayer>();
+ dumbextendlyr.addAll(extendmap.get(s));
+ Collections.sort(dumbextendlyr, weighter.getComparator());
+
+ for (DumbLayer lyr : dumbextendlyr) {
+ extendlyr.add(new SeedLayer(lyr.detectorName, lyr.layer, lyr.be, SeedType.Extend));
+ }
+
+ lyrlst.addAll(extendlyr);
+ //get seed/confirmation layers
+ for (DumbLayer lyr : dlyrlst){
+ SeedType type;
+
+ if (confirmed < confirm_layers) {
+ type = SeedType.Confirm;
+ confirmed++;
+ }
+ else type = SeedType.Seed;
+ lyrlst.add(new SeedLayer(lyr.detectorName, lyr.layer, lyr.be, type));
+ }
+ Collections.reverse(lyrlst); // reverse so seed layers on top
+
+ String name = "AUTOGEN" + counter++ +"_"+lyrlst.hashCode();
+
+ //copy over cutoff info from prototype
+ SeedStrategy stgy = new SeedStrategy(name,lyrlst);
+ stgy.copyCutoffsFromStrategy(prototype);
+ strat_list.add(stgy);
+ }
+
+ StrategyXMLMetadata meta = new StrategyXMLMetadata();
+ String comment = "Strategy list Autogenerated by Strategy Builder on "+new Date()+".";
+ meta.targetDetector = detectorName;
+ meta.comment = comment;
+
+ //If symmetrizing, make Endcap Layers for both north and south
+ if (symmetrize) {
+ if (verbose) System.out.println("Symmetrizing...");
+ StrategyBuilderUtils.symmetrizeStrategies(strat_list);
+ }
+
+ StrategyXMLUtils.writeStrategyListToFile(strat_list, new File(outputFile), meta);
+ if (verbose) System.out.println(strat_list.size()+" strategies generated.");
+ if (verbose) System.out.println("Strategies XML file written at "+outputFile);
+ }
+
+ @Override
+ protected void detectorChanged(Detector detector){
+ detectorName = detector.getDetectorName();
+
+ //use default weighter if not specified... default depends on detector name
+ if (weighter==null) {
+ setLayerWeight(new DefaultLayerWeight(detectorName).getWeight());
+ }
+
+ //check that detectors match layer weights (unless the TargetDetector is unspecified)
+ if(!weighter.getTargetDetector().equals("None Specified") && !weighter.getTargetDetector().equals(detectorName)) {
+ throw new DetectorMismatchException(detectorName, weighter.getTargetDetector());
+ }
+ }
+
+
+ // ===============setters===============// documented in interface
+ public void setOutput(String filename){
+ outputFile = filename;
+ }
+
+ public void setLayerWeight(LayerWeight lw){
+ weighter = lw;
+ }
+
+ public void setMinLayers(int min){
+ min_layers = min;
+ }
+
+ public void setNumConfirmLayers(int clayers){
+ confirm_layers = clayers;
+ }
+
+ public void setNumSeedLayers(int slayers){
+ seed_layers = slayers;
+ }
+
+ public void setStrategyPrototype(SeedStrategy proto){
+ prototype = proto;
+ }
+
+ public void setStartingStrategyList(List<SeedStrategy> slist){
+ startingStrategies = slist;
+ }
+
+ public void setVerbose(boolean v){
+ verbose = true;
+ }
+
+ public void setMinimumUnweightedScore(int sc){
+ minUnweightedScore = sc;
+ }
+
+ public void setParticleFilter(IParticleFilter pfilter){
+ filter = pfilter;
+ }
+
+ public void setSymmetrize(boolean set){
+ symmetrize = set;
+ }
+
+ //========privates ============//
+ private Map<MCParticle, List<SimTrackerHit>> buildMCMap(EventHeader event) {
+
+ //Build MC Map from SimTrackerHits
+ Map<MCParticle, List<SimTrackerHit>> mcmap = new HashMap<MCParticle, List<SimTrackerHit>>();
+ List<SimTrackerHit> allhits = new ArrayList<SimTrackerHit>();
+
+
+ for (List<SimTrackerHit> l : event.get(SimTrackerHit.class)) {
+
+ /**
+ * We simulate inefficiency in SimTrackerHit => TrackerHit conversion,
+ * otherwise the strategies will miss certain classes of hits
+ */
+
+ EventHeader.LCMetaData meta = event.getMetaData(l);
+ String readout = meta.getName();
+ double efficiency = weighter.getReadoutEfficiency(readout);
+ for (SimTrackerHit h : l) {
+ if (random.nextDouble() < efficiency) {
+ allhits.add(h);
+ }
+ }
+ }
+
+ for (SimTrackerHit h : allhits) {
+ MCParticle p = h.getMCParticle();
+ List<SimTrackerHit> these_hits;
+ if (mcmap.containsKey(p)) {
+ these_hits = mcmap.get(p);
+ } else {
+ these_hits = new ArrayList<SimTrackerHit>();
+ }
+
+ these_hits.add(h);
+ mcmap.put(p, these_hits);
+ }
+
+ return mcmap;
+ }
+
+ private boolean startingCanFind(Set<DumbLayer> set){
+
+ for (Set<DumbLayer> s : startingSet){
+ if (set.containsAll(s))
+ return true;
+ }
+
+ return false;
+ }
+
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N StrategyBuilderUtils.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ StrategyBuilderUtils.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,169 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import org.lcsim.recon.tracking.seedtracker.SeedLayer;
+import org.lcsim.recon.tracking.seedtracker.SeedLayer.SeedType;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
+
+/**
+ * StrategyBuilder was getting too bloated, so some of the code has been moved here
+ * @author cozzy
+ */
+public class StrategyBuilderUtils {
+
+ private static final BarrelEndcapFlag[] beArray =
+ new BarrelEndcapFlag[]{BarrelEndcapFlag.ENDCAP_NORTH, BarrelEndcapFlag.ENDCAP_SOUTH};
+
+ /**
+ * Symmetrizes the given StrategyList... Modifies
+ * the original list rather than returning a new one.
+ *
+ * It is assumed that the input list uses the beflag ENDCAP rather
+ * than ENDCAP_NORTH or ENDCAP_SOUTH. Anything with ENDCAP_NORTH or
+ * ENDCAP_SOUTH won't be touched...
+ *
+ * @param strat_list
+ */
+ static void symmetrizeStrategies (List<SeedStrategy> strat_list) {
+
+ /**
+ * There are 3 interesting cases here:
+ *
+ * 1) None of the layers are in the endcap. Symmetrization unnecessary.
+ * 2) Only extension layers are in the endcap. In this case we should
+ * modify the extension layers so that both endcaps appear. We remove
+ * the old extension layer and replace it with two new ones.
+ * 3) Extension layers appear in the seeds or confirm layers.
+ * In this case, we remove the old strategy and replace it with
+ * two new ones.
+ *
+ *
+ * We can't tell the difference between (2) and (3) until after we have
+ * gone through the entire set, so the code keeps track of the changes
+ * that would be necessary for (2) and apply them only if (3) doesn't
+ * happen.
+ *
+ */
+
+ List<SeedStrategy> symmetrized = new ArrayList<SeedStrategy>();
+ Iterator<SeedStrategy> it = strat_list.iterator();
+ //this will store additional extension layers in the case that there are no endcap Seed/Confirm layers
+ List<SeedLayer> additionalExtendLayers = new ArrayList<SeedLayer>();
+ List<SeedLayer> removeLayers = new ArrayList<SeedLayer>();
+ while (it.hasNext()) {
+ SeedStrategy next = it.next();
+ boolean extendOnlyFlag = true; //If all the Seed/Confirm layers are BarrelOnly, then we can
+ //just have both endcaps in the extend layers without creating a new strategy.
+ additionalExtendLayers.clear();
+ removeLayers.clear();
+ for (SeedLayer l : next.getLayerList()) {
+ //Anything with BarrelEndcapFlag ENDCAP in seed or confirm should be mirrored for both sides
+ if (l.getBarrelEndcapFlag()==BarrelEndcapFlag.ENDCAP && l.getType()!=SeedType.Extend) {
+ it.remove(); //remove this strategy... we will replace it with the other two symmetrized ones
+ //loop through both north and south configurations
+ for (BarrelEndcapFlag be : beArray) {
+ SeedStrategy newstrat = makeMirroredLayer(next, be);
+ symmetrized.add(newstrat);
+ }
+ extendOnlyFlag = false;
+ break;
+
+ } else if (l.getBarrelEndcapFlag()==BarrelEndcapFlag.ENDCAP) {
+ removeLayers.add(l);
+ additionalExtendLayers.add(new SeedLayer(l.getDetName(), l.getLayer(), beArray[0], l.getType()));
+ additionalExtendLayers.add(new SeedLayer(l.getDetName(), l.getLayer(), beArray[1], l.getType()));
+ }
+ }
+
+ if (extendOnlyFlag) {
+ next.getLayerList().addAll(additionalExtendLayers);
+ next.getLayerList().removeAll(removeLayers);
+ }
+
+ }
+ strat_list.addAll(symmetrized);
+ }
+
+
+ private static SeedStrategy makeMirroredLayer(SeedStrategy next, BarrelEndcapFlag be) {
+ List<SeedLayer> symmlyrs = new ArrayList<SeedLayer>(); //store the new layers here
+ for (SeedLayer ll : next.getLayerList()) {
+ if (ll.getBarrelEndcapFlag().isBarrel()) {
+ // if it's a barrel layer, we can just add it
+ symmlyrs.add(ll);
+ } else {
+ //otherwise change from ENDCAP to either ENDCAP_NORTH or ENDCAP_SOUTH
+ SeedLayer newlyr = new SeedLayer(ll.getDetName(), ll.getLayer(), be, ll.getType());
+ symmlyrs.add(newlyr);
+ }
+ }
+ SeedStrategy newstrat = new SeedStrategy(next.getName() + be.toString(), symmlyrs); //create new strategy
+ newstrat.copyCutoffsFromStrategy(next); //copy parameters
+ return newstrat;
+ }
+
+
+ /**
+ * Returns a list of possible subsets of DumbLayers.... wrapper around generateAllPossibleSubsets
+ * @param allLayers
+ * @param subset_size
+ * @return
+ */
+ public static List<Set<DumbLayer>> generateAllPossibleDumbLayerSubsetsList(Set<DumbLayer> allLayers, int subset_size) {
+ Set<Object> set = new HashSet<Object>();
+ set.addAll(allLayers);
+ Set<Set> subsets = generateAllPossibleSubsets(set, subset_size);
+ List<Set<DumbLayer>> ret = new ArrayList<Set<DumbLayer>>();
+ for (Set<DumbLayer> subset : subsets) {
+ ret.add(subset);
+ }
+ return ret;
+ }
+
+
+ /**
+ * Returns all possible subsets of a given size of the set allObjects
+ * @param allObjects The set to find subsets of
+ * @param subset_size The size desired of subsets.
+ * @return A set of subsets, all of size sub_set size
+ */
+ public static Set<Set> generateAllPossibleSubsets(Set allObjects, int subset_size) {
+
+ assert(subset_size > 0 && subset_size <= allObjects.size());
+
+ if (subset_size == 1){
+ Set<Set> ret = new HashSet<Set>();
+ for (Object o : allObjects){
+ Set set = new HashSet();
+ set.add(o);
+ ret.add(set);
+ }
+ return ret;
+ }
+
+ else {
+ Set<Set> ret = new HashSet<Set>();
+ for(Object o : allObjects) {
+ Set newSet = new HashSet();
+ newSet.addAll(allObjects);
+ newSet.remove(o);
+ Set<Set> partial = generateAllPossibleSubsets(newSet, subset_size-1);
+ for (Set s : partial) s.add(o);
+ ret.addAll(partial);
+ }
+ return ret;
+ }
+ }
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N StrategyCombiner.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ StrategyCombiner.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,50 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.recon.tracking.seedtracker.StrategyXMLUtils;
+
+/**
+ *
+ * @author cozzy
+ */
+public class StrategyCombiner {
+
+ public static void main(String[] args){
+
+ if (args.length < 3){
+ printUsage();
+ System.exit(1);
+ }
+
+ String filename = args[0];
+
+ List<SeedStrategy> lst = new ArrayList<SeedStrategy>();
+
+ for (int i = 1; i < args.length; i++) {
+ List<SeedStrategy> portion = StrategyXMLUtils.getStrategyListFromFile(new File(args[i]));
+ for (SeedStrategy s : portion){
+ if (!lst.contains(s)) lst.add(s);
+ }
+ }
+
+ StrategyXMLUtils.writeStrategyListToFile(lst, new File(filename));
+ }
+
+
+
+
+ private static void printUsage(){
+ System.out.println("Usage:");
+ System.out.println("StrategyCombiner OUTPUT_FILE STRATEGY1 STRATEGY2 [STRATEGY3... ]");
+ System.out.println("\t\tWhere the different strategies are XML files");
+ }
+
+}
lcsim/src/org/lcsim/recon/tracking/seedtracker/strategybuilder
diff -N SubsetScorer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ SubsetScorer.java 27 Aug 2008 17:55:49 -0000 1.1
@@ -0,0 +1,94 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.recon.tracking.seedtracker.strategybuilder;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author cozzy
+ */
+public class SubsetScorer {
+
+ Map<Set<DumbLayer>,Integer> setmap = new HashMap<Set<DumbLayer>,Integer>();
+ LayerWeight weighter = new LayerWeight();
+ Map<Set<DumbLayer>,Integer> adjacencemap = new HashMap<Set<DumbLayer>,Integer>();
+
+ public SubsetScorer(List<Set<DumbLayer>> setlist, List<List<DumbLayer>> adjacentSets) {
+
+ for (Set<DumbLayer> set : setlist) {
+ if(setmap.containsKey(set)){
+ setmap.put(set,setmap.get(set).intValue()+1);
+ } else {
+ setmap.put(set,1);
+ }
+ }
+
+ for (List<DumbLayer> list : adjacentSets) {
+ //convert to a set because of faster lookup? (actually it might not be since the collection sizes are so small?)
+ Set<DumbLayer> set = new HashSet<DumbLayer>(list.size());
+ set.addAll(list);
+ if(adjacencemap.containsKey(set)){
+ adjacencemap.put(set,adjacencemap.get(set).intValue()+1);
+ } else {
+ adjacencemap.put(set,1);
+ }
+ }
+
+// System.out.println(adjacencemap.toString());
+ }
+
+ public void setLayerWeight(LayerWeight lw) {
+ weighter = lw;
+ }
+
+
+ //s * w * (a + b * adjacence ^ c)
+ //
+ public double getScore(Set<DumbLayer> testSet) {
+ return getUnweightedScore(testSet) * weighter.getWeight(testSet)
+ * ( weighter.getAdjacenceConstant() +
+ Math.pow(getAdjacence(testSet), weighter.getAdjacenceExponent())
+ * weighter.getAdjacenceMultiplier()
+ );
+
+
+
+ }
+
+ public double getUnweightedScore(Set<DumbLayer> testSet){
+
+ int ret = 0;
+ for (Set<DumbLayer> s : setmap.keySet()){
+ if (s.containsAll(testSet)) {
+ ret+= setmap.get(s).intValue();
+ }
+ }
+ return ret;
+ }
+
+ public int getAdjacence(Set<DumbLayer> testSet){
+ if (adjacencemap.containsKey(testSet)){
+ return adjacencemap.get(testSet);
+ }
+
+ return 0;
+ }
+
+ public void markUsed(Set<DumbLayer> testSet) {
+ for (Set<DumbLayer> s : setmap.keySet()){
+ if (s.containsAll(testSet)) {
+ setmap.put(s,0);
+ }
+ }
+ }
+
+
+ }
\ No newline at end of file
CVSspam 0.2.8