Commit in lcsim-contrib/src/main/java/org/lcsim/contrib/onoprien/performance on MAIN | |||
AnalysisDriver.java | +297 | added 1.1 | |
Definition.java | +18 | -4 | 1.1 -> 1.2 |
IDefinition.java | +21 | -1 | 1.1 -> 1.2 |
TrackingAnalysisDriver.java | -169 | 1.1 removed | |
+336 | -174 |
Machinery for fake rate study Selective filling of performance histograms
diff -N AnalysisDriver.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ AnalysisDriver.java 10 Jul 2009 19:25:05 -0000 1.1 @@ -0,0 +1,297 @@
+package org.lcsim.contrib.onoprien.performance; + +import org.lcsim.contrib.onoprien.data.mctruth.RecType; +import java.util.*; +import java.util.logging.Level; + +import hep.aida.IHistogram1D; +import hep.physics.vec.Hep3Vector; +import org.lcsim.event.EventHeader; +import org.lcsim.event.MCParticle; +import org.lcsim.util.aida.AIDA; + +import org.lcsim.contrib.onoprien.util.job.NoSuchParameterException; +import org.lcsim.contrib.onoprien.util.constants.Units; +import org.lcsim.contrib.onoprien.util.job.Driver; +import org.lcsim.contrib.onoprien.util.job.JobEvent; +import org.lcsim.contrib.onoprien.util.job.JobEventListener; +import org.lcsim.contrib.onoprien.util.job.JobManager; + +/** + * Driver for testing calorimeter assisted tracking performance. + * + * @author D. Onoprienko + * @version $Id: AnalysisDriver.java,v 1.1 2009/07/10 19:25:05 onoprien Exp $ + */ +public class AnalysisDriver extends Driver implements JobEventListener { + +// -- Enumeration of histogram types: ----------------------------------------- + + public enum Hist { + EFF_ALL, + EFF_Pt, + EFF_PtZoom, + EFF_Theta, + EFF_CosTheta, + FAKE + } + + private static EnumSet<Hist> _effHistSet = EnumSet.of(Hist.EFF_Pt, Hist.EFF_PtZoom, Hist.EFF_Theta, Hist.EFF_CosTheta); + + +// -- Private parts : --------------------------------------------------------- + + protected AIDA _aida = JobManager.defaultInstance().getAIDA(); + + protected double _histPtLow = 0.; + protected double _histPtHigh = 20.*Units.GeV; + + ArrayList<Test> _tests = new ArrayList<Test>(1); + + +// -- Constructors and initialization : --------------------------------------- + + public AnalysisDriver() { + JobManager.defaultInstance().addListener(this); + } + + public void detectorChanged(JobEvent jEvent) { + + if (_tests.isEmpty()) { + throw new IllegalStateException(ERR_NS); + } + + _tests.trimToSize(); + for (Test test : _tests) test.init(); + } + + +// -- Setters : --------------------------------------------------------------- + + /** + * + * Set any parameter. + * The following parameters can be set with this method: + * <p><dl> + * <dt>"HIST_PT_RANGE"</dt> <dd>Two double values used to define Pt range for histogramming.<br> + * Default: 0 - 20 GeV.</dd> + * <dt>"DEFINITION"</dt> <dd>One or more {@link IDefinition} objects defining tests to be performed. + * Each definition (or a group of definitions) may optionally be followed by parameters telling + * this driver what histograms have to be filled for that definition. For example,<br> + * <tt>set("DEFINITION", def1, def2, RecType.TRACK, RecType.TRACK_SEED, AnalysisDriver.Hist.EFF_Pt, + * RecType.PARTICLE, AnalysisDriver.Hist.EFF_Pt, AnalysisDriver.Hist.EFF_Theta)</tt> + * will ask this driver to use definitions <tt>def1</tt> and <tt>def1</tt> to fill + * "Efficiency vs Pt" histograms for tracks and track seeds, "Efficiency vs Pt" + * and "Efficiency vs Theta" histograms for reconstructed particles. + * This method may be called several times.<br> + * No default definitions (must be specified before this driver can be used). + * If reconstructed object type is omitted when specifying what histograms need to be filled, + * all object types active for the supplied definition are used. If no histograms are specified, + * all histograms are filled.</dd> + * </dl> + * + * + * @param name Name of parameter to be set. Case is ignored. + * @param values List of values to be used for setting the parameter. + * @throws NoSuchParameterException Thrown if the supplied parameter name is unknown. + * @throws IllegalArgumentException Thrown if incorrect number of values, or a value + * of incorrect type is supplied. + */ + public void set(String name, Object... values) { + try { + if (name.equalsIgnoreCase("HIST_PT_RANGE")) { + if (values.length != 2) throw new IllegalArgumentException(ERR_INV + name); + _histPtLow = (Double) values[0]; + _histPtHigh = (Double) values[1]; + } else if (name.equalsIgnoreCase("DEFINITION")) { + if (values.length < 1) throw new IllegalArgumentException(ERR_INV + name); + List<IDefinition> defList = new ArrayList<IDefinition>(); + EnumSet<RecType> typeList = EnumSet.noneOf(RecType.class); + EnumSet<Hist> histList = EnumSet.noneOf(Hist.class); + EnumMap<RecType, EnumSet<Hist>> par = null; + int status = 0; // 0 - starting, 1 - collecting definitions, 2 - collecting recTypes, 3 - collecting Hists + for (Object o : values) { + if (o instanceof IDefinition) { + IDefinition def = (IDefinition)o; + if (status == 0 || status == 1) { + defList.add(def); + } else { + makeTests(defList, typeList, histList, par); + defList.clear(); + defList.add(def); + typeList.clear(); + histList = EnumSet.noneOf(Hist.class); + par = null; + } + status = 1; + } else if (o instanceof RecType) { + RecType type = (RecType)o; + if (status == 0) { + throw new IllegalArgumentException(ERR_VIT + name); + } else { + if (status == 3) { + par = new EnumMap<RecType, EnumSet<Hist>>(RecType.class); + for (RecType t : typeList) par.put(t, histList); + typeList.clear(); + histList = EnumSet.noneOf(Hist.class); + } + typeList.add(type); + } + status = 2; + } else { + Hist hist = (Hist)o; + if (status == 0) { + throw new IllegalArgumentException(ERR_VIT + name); + } else { + histList.add(hist); + } + status = 3; + } + } + makeTests(defList, typeList, histList, par); + } else { + super.set(name, values); + } + } catch (ClassCastException x) { + throw new IllegalArgumentException(ERR_VIT + name, x); + } + } + + private void makeTests(List<IDefinition> defList, EnumSet<RecType> typeList, EnumSet<Hist> histList, + EnumMap<RecType, EnumSet<Hist>> par) { + if (defList.isEmpty()) return; + if (histList.isEmpty()) histList = EnumSet.allOf(Hist.class); + if (!typeList.isEmpty()) { + if (par == null) par = new EnumMap<RecType, EnumSet<Hist>>(RecType.class); + for (RecType type : typeList) par.put(type, histList); + } + for (IDefinition def : defList) { + if (par == null) { + par = new EnumMap<RecType, EnumSet<Hist>>(RecType.class); + for (RecType type : def.getActiveTypes()) par.put(type, histList); + _tests.add(new Test(def, par)); + par = null; + } else { + _tests.add(new Test(def, par)); + } + } + } + + +// -- Processing event : ------------------------------------------------------ + + public void process(EventHeader event) { + + log("TrackingAnalysisDriver is starting event processing", Level.FINER); + + // Process children if any + + super.process(event); + + // Set event in definitions + + for (Test test : _tests) test.def.startEvent(event); + + // Fill efficiency histograms + + for (MCParticle mc : event.getMCParticles()) { + + Hep3Vector p = mc.getMomentum(); + double pT = Math.hypot(p.x(), p.y()); + double cosTheta = p.z() / p.magnitude(); + double theta = Math.acos(cosTheta); +// Hep3Vector origin = mc.getOrigin(); +// double r = Math.hypot(origin.x(), origin.y()); +// double z = origin.z(); + + for (Test test : _tests) { + for (RecType rec : test.h.keySet()) { + EnumMap<Hist,IHistogram1D> hst = test.h.get(rec); + if (hst.containsKey(Hist.EFF_ALL)) { + if (test.def.isFindable(rec, mc)) { + int eff = (test.def.isFound(rec, mc)) ? 1 : 0; + hst.get(Hist.EFF_ALL).fill(.5, eff); + IHistogram1D h; + h = hst.get(Hist.EFF_Pt); if (h!=null) h.fill(pT, eff); + h = hst.get(Hist.EFF_PtZoom); if (h!=null) h.fill(pT, eff); + h = hst.get(Hist.EFF_Theta); if (h!=null) h.fill(theta * Units.degree, eff); + h = hst.get(Hist.EFF_CosTheta); if (h!=null) h.fill(cosTheta, eff); + } + } + } + } + + } + + // Fill fake rate histograms + + for (Test test : _tests) { + for (RecType rec : test.h.keySet()) { + List<String> colNames = test.def.getCollectionName(rec); + EnumMap<Hist,IHistogram1D> hst = test.h.get(rec); + if (colNames != null && hst.containsKey(Hist.FAKE)) { + HashSet<Object> recObjectSet = new HashSet<Object>(); + for (String colName : colNames) { + try { + Collection<Object> col = (Collection<Object>) event.get(colName); + recObjectSet.addAll(col); + } catch (IllegalArgumentException x) {} + } + for (Object recObject : recObjectSet) { + int eff = (test.def.isFake(rec, recObject)) ? 1 : 0; + hst.get(Hist.FAKE).fill(.5, eff); + } + } + } + } + + // Cleanup + + for (Test test : _tests) test.def.endEvent(); + log("TrackingAnalysisDriver has finished event processing", Level.FINER); + } + + +// -- Class that keeps objects related to analysis by particular definition : -- + + private class Test { + + Test(IDefinition definition, EnumMap<RecType, EnumSet<Hist>> par) { + def = definition; + _par = par; + } + + void init() { + h = new EnumMap<RecType, EnumMap<Hist,IHistogram1D>>(RecType.class); + for (RecType rec : _par.keySet()) { + EnumMap<Hist,IHistogram1D> hm = new EnumMap<Hist,IHistogram1D>(Hist.class); + h.put(rec, hm); + EnumSet<Hist> hs = _par.get(rec); + boolean hasEff = hs.contains(Hist.EFF_ALL); + if (!hasEff) { + for (Hist hh : _effHistSet) { + if (hs.contains(hh)) { + hasEff = true; + break; + } + } + } + if (hasEff) { + hm.put(Hist.EFF_ALL, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency", "", 1, 0., 1., "type=efficiency")); + if (hs.contains(Hist.EFF_ALL) || hs.contains(Hist.EFF_Pt)) hm.put(Hist.EFF_Pt, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs Pt", "", 50, _histPtLow, _histPtHigh, "type=efficiency")); + if (hs.contains(Hist.EFF_ALL) || hs.contains(Hist.EFF_PtZoom)) hm.put(Hist.EFF_PtZoom, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs Pt zoom", "", 50, 0., 5.*Units.GeV, "type=efficiency")); + if (hs.contains(Hist.EFF_ALL) || hs.contains(Hist.EFF_Theta)) hm.put(Hist.EFF_Theta, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs theta", "", 180, 0., 180., "type=efficiency")); + if (hs.contains(Hist.EFF_ALL) || hs.contains(Hist.EFF_CosTheta)) hm.put(Hist.EFF_CosTheta, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs cos(theta)", "", 100, -1., 1., "type=efficiency")); + } + if (hs.contains(Hist.FAKE)) { + hm.put(Hist.FAKE, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Fake rate", "", 1, 0., 1., "type=efficiency")); + } + } + _par = null; + } + + IDefinition def; + EnumMap< RecType, EnumMap<Hist,IHistogram1D> > h; + private EnumMap<RecType, EnumSet<Hist>> _par; + } +}
diff -u -r1.1 -r1.2 --- Definition.java 8 Jul 2009 15:59:34 -0000 1.1 +++ Definition.java 10 Jul 2009 19:25:05 -0000 1.2 @@ -31,7 +31,7 @@
* {@link #isFound isFound}, and {@link #isFake isFake} methods. * * @author D. Onoprienko
- * @version $Id: Definition.java,v 1.1 2009/07/08 15:59:34 onoprien Exp $
+ * @version $Id: Definition.java,v 1.2 2009/07/10 19:25:05 onoprien Exp $
*/ public class Definition implements IDefinition {
@@ -84,12 +84,26 @@
}
-// -- Definition name : -------------------------------------------------------
+// -- Getters : ---------------------------------------------------------------
+ /** Returns the name of this definition. */
public String getName() { return _name; }
-
+ + /** + * Returns names under which relevant collections of reconstructed objects of the + * specified type are saved into the event record. Only objects from these collections + * are taken into consideration when deciding whether a particular <tt>MCParticle</tt> + * has been reconstructed. Returns <tt>null</tt> + * if the collection names have not been set for the specified reconstructed object type. + */ + public List<String> getCollectionName(RecType type) { + String[] names = _colNames.get(type); + return (names == null) ? null : Collections.unmodifiableList(Arrays.asList(names)); + } + +
// -- Setters : --------------------------------------------------------------- /**
@@ -372,7 +386,7 @@
* a particular type has been successfully reconstructed. If names are not set, default * names supplied through {@link MCTruthDriver} will be used. */
- public void setCollections(RecType type, String... collectionName) {
+ public void setCollectionName(RecType type, String... collectionName) {
_colNames.put(type, collectionName); }
diff -u -r1.1 -r1.2 --- IDefinition.java 8 Jul 2009 15:59:34 -0000 1.1 +++ IDefinition.java 10 Jul 2009 19:25:05 -0000 1.2 @@ -17,7 +17,7 @@
* definitions and call their <tt>startEvent</tt> methods should also call <tt>endEvent()</tt>. * * @author D. Onoprienko
- * @version $Id: IDefinition.java,v 1.1 2009/07/08 15:59:34 onoprien Exp $
+ * @version $Id: IDefinition.java,v 1.2 2009/07/10 19:25:05 onoprien Exp $
*/ public interface IDefinition {
@@ -72,6 +72,26 @@
void setActiveTypes(RecType... types);
+// -- Reconstructed object collections names : -------------------------------- + + /** + * Returns names under which relevant collections of reconstructed objects of the + * specified type are saved into the event record. Only objects from these collections + * should be taken into consideration when deciding whether a particular <tt>MCParticle</tt> + * has been reconstructed, or when calculating fake rates. Returns <tt>null</tt> + * if the collection names have not been set for the specified reconstructed object type. + */ + List<String> getCollectionName(RecType type); + + /** + * Sets names under which relevant collections of reconstructed objects of the + * specified type are saved into the event record. Only objects from these collections + * should be taken into consideration when deciding whether a particular <tt>MCParticle</tt> + * has been reconstructed, or when calculating fake rates. + */ + void setCollectionName(RecType type, String... collectionName); + +
// -- Per-event data initialization and clean-up : ---------------------------- /**
diff -N TrackingAnalysisDriver.java --- TrackingAnalysisDriver.java 8 Jul 2009 15:59:34 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,169 +0,0 @@
-package org.lcsim.contrib.onoprien.performance; - -import org.lcsim.contrib.onoprien.data.mctruth.RecType; -import java.util.*; -import java.util.logging.Level; - -import hep.aida.IHistogram1D; -import hep.physics.vec.Hep3Vector; -import org.lcsim.event.EventHeader; -import org.lcsim.event.MCParticle; -import org.lcsim.util.aida.AIDA; - -import org.lcsim.contrib.onoprien.util.job.NoSuchParameterException; -import org.lcsim.contrib.onoprien.util.constants.Units; -import org.lcsim.contrib.onoprien.util.job.Driver; -import org.lcsim.contrib.onoprien.util.job.JobEvent; -import org.lcsim.contrib.onoprien.util.job.JobEventListener; -import org.lcsim.contrib.onoprien.util.job.JobManager; - -/** - * Driver for testing calorimeter assisted tracking performance. - * - * @author D. Onoprienko - * @version $Id: TrackingAnalysisDriver.java,v 1.1 2009/07/08 15:59:34 onoprien Exp $ - */ -public class TrackingAnalysisDriver extends Driver implements JobEventListener { - -// -- Private parts : --------------------------------------------------------- - - protected AIDA _aida = JobManager.defaultInstance().getAIDA(); - - protected double _histPtLow = 0.; - protected double _histPtHigh = 20.*Units.GeV; - - ArrayList<Test> _tests = new ArrayList<Test>(1); - - -// -- Constructors and initialization : --------------------------------------- - - public TrackingAnalysisDriver() { - JobManager.defaultInstance().addListener(this); - } - - public void detectorChanged(JobEvent jEvent) { - - if (_tests.isEmpty()) { - throw new IllegalStateException(ERR_NS); - } - - _tests.trimToSize(); - for (Test test : _tests) test.init(); - } - - -// -- Setters : --------------------------------------------------------------- - - /** - * - * Set any parameter. - * The following parameters can be set with this method: - * <p><dl> - * <dt>"HIST_PT_RANGE"</dt> <dd>Two double values used to define Pt range for histogramming.<br> - * Default: 0 - 20 GeV.</dd> - * <dt>"DEFINITION"</dt> <dd>One or more {@link IDefinition} objects defining tests to be performed.<br> - * No default (must be specified before this driver can be used).</dd> - * </dl> - * - * - * @param name Name of parameter to be set. Case is ignored. - * @param values List of values to be used for setting the parameter. - * @throws NoSuchParameterException Thrown if the supplied parameter name is unknown. - * @throws IllegalArgumentException Thrown if incorrect number of values, or a value - * of incorrect type is supplied. - */ - public void set(String name, Object... values) { - try { - if (name.equalsIgnoreCase("HIST_PT_RANGE")) { - if (values.length != 2) throw new IllegalArgumentException(ERR_INV + name); - _histPtLow = (Double) values[0]; - _histPtHigh = (Double) values[1]; - } else if (name.equalsIgnoreCase("DEFINITION")) { - for (Object def : values) { - _tests.add(new Test((IDefinition)def)); - } - } else { - super.set(name, values); - } - } catch (ClassCastException x) { - throw new IllegalArgumentException(ERR_VIT + name, x); - } - } - - -// -- Processing event : ------------------------------------------------------ - - public void process(EventHeader event) { - - log("TrackingAnalysisDriver is starting event processing", Level.FINER); - - // Process children if any - - super.process(event); - - // Set event in definitions - - for (Test test : _tests) test.def.startEvent(event); - - // Fill histograms - - for (MCParticle mc : event.getMCParticles()) { - - Hep3Vector p = mc.getMomentum(); - double pT = Math.hypot(p.x(), p.y()); - double cosTheta = p.z() / p.magnitude(); - double theta = Math.acos(cosTheta); -// Hep3Vector origin = mc.getOrigin(); -// double r = Math.hypot(origin.x(), origin.y()); -// double z = origin.z(); - - for (Test test : _tests) { - for (RecType rec : test.def.getActiveTypes()) { - if (test.def.isFindable(rec, mc)) { - int eff = (test.def.isFound(rec, mc)) ? 1 : 0 ; - test.hEff_Pt1.get(rec).fill(pT, eff); - test.hEff_Pt2.get(rec).fill(pT, eff); - test.hEff_Theta.get(rec).fill(theta*Units.degree, eff); - test.hEff_CosTheta.get(rec).fill(cosTheta, eff); - } - - } - } - - } - - // Cleanup - - for (Test test : _tests) test.def.endEvent(); - log("TrackingAnalysisDriver has finished event processing", Level.FINER); - } - - -// -- Class that keeps objects related to analysis by particular definition : -- - - private class Test { - - Test(IDefinition definition) { - - def = definition; - - hEff_Pt1 = new EnumMap<RecType,IHistogram1D>(RecType.class); - hEff_Pt2 = new EnumMap<RecType,IHistogram1D>(RecType.class); - hEff_Theta = new EnumMap<RecType,IHistogram1D>(RecType.class); - hEff_CosTheta = new EnumMap<RecType,IHistogram1D>(RecType.class); - } - - void init() { - for (RecType rec : def.getActiveTypes()) { - hEff_Pt1.put(rec, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs Pt", "", 50, _histPtLow, _histPtHigh, "type=efficiency")); - hEff_Pt2.put(rec, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs Pt zoom", "", 50, 0., 5.*Units.GeV, "type=efficiency")); - hEff_Theta.put(rec, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs theta", "", 180, 0., 180., "type=efficiency")); - hEff_CosTheta.put(rec, _aida.histogramFactory().createHistogram1D(def.getName()+" : "+rec+" : Efficiency vs cos(theta)", "", 100, -1., 1., "type=efficiency")); - } - } - - IDefinition def; - - EnumMap<RecType,IHistogram1D> hEff_Pt1, hEff_Pt2, hEff_Theta, hEff_CosTheta; - } -}