-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
simple truth efficiency calculator (#396)
* update URL * truth efficiency matrix calculator * cleanup, add warning printout * rename, cleanup, add json * merge scripts * use an array * parallelize * cleanup * actually loop * now it works * use gemc files with truth-matching enabled * cleanup, run truth efficiency * bugfix * cleanup and bugfix * bugfix, now it works * avoid unnecessary lookups * more convenient JSON structure * cleanup for thread safety * make adding threadsafe
- Loading branch information
Showing
7 changed files
with
279 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/bin/bash | ||
|
||
. `dirname $0`/../libexec/env.sh | ||
|
||
export MALLOC_ARENA_MAX=1 | ||
|
||
java -Xmx1536m -Xms1024m -XX:+UseSerialGC \ | ||
-cp "$CLAS12DIR/lib/clas/*:$CLAS12DIR/lib/services/*:$CLAS12DIR/lib/utils/*" \ | ||
org.jlab.analysis.efficiency.Truth \ | ||
$* |
183 changes: 183 additions & 0 deletions
183
common-tools/clas-analysis/src/main/java/org/jlab/analysis/efficiency/Truth.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
package org.jlab.analysis.efficiency; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.TreeMap; | ||
import org.jlab.jnp.hipo4.data.Bank; | ||
import org.jlab.jnp.hipo4.data.Event; | ||
import org.jlab.jnp.hipo4.data.Schema; | ||
import org.jlab.jnp.hipo4.data.SchemaFactory; | ||
import org.jlab.jnp.hipo4.io.HipoReader; | ||
import org.jlab.jnp.utils.json.JsonArray; | ||
import org.jlab.jnp.utils.json.JsonObject; | ||
import org.jlab.utils.options.OptionParser; | ||
|
||
/** | ||
* Efficiency matrix calculator based solely on the MC::GenMatch truth-matching | ||
* bank (which is purely hit-based), and a pid assignment match in MC::Particle | ||
* and REC::Particle. | ||
* | ||
* @author baltzell | ||
*/ | ||
public class Truth { | ||
|
||
static final int UDF = 0; | ||
static final List<Integer> NEGATIVES = Arrays.asList(11, -211, -321, -2212); | ||
static final List<Integer> POSITIVES = Arrays.asList(-11, 211, 321, 2212, 45); | ||
static final List<Integer> NEUTRALS = Arrays.asList(22, 2112); | ||
|
||
List<Integer> validPids; | ||
Schema mcGenMatch; | ||
Schema mcParticle; | ||
Schema recParticle; | ||
long[][] recTallies; | ||
long[] mcTallies; | ||
|
||
public static void main(String[] args) { | ||
OptionParser o = new OptionParser("trutheff"); | ||
o.setRequiresInputList(true); | ||
o.parse(args); | ||
Truth t = new Truth(o.getInputList().get(0)); | ||
t.add(o.getInputList()); | ||
System.out.println(t.toTable()); | ||
System.out.println(t.toJson()); | ||
} | ||
|
||
public Truth(SchemaFactory s) { | ||
init(s); | ||
} | ||
|
||
public Truth(HipoReader r) { | ||
init(r.getSchemaFactory()); | ||
} | ||
|
||
public Truth(String filename) { | ||
HipoReader r = new HipoReader(); | ||
r.open(filename); | ||
init(r.getSchemaFactory()); | ||
} | ||
|
||
private void init(SchemaFactory schema) { | ||
validPids = new ArrayList(NEGATIVES); | ||
validPids.addAll(POSITIVES); | ||
validPids.addAll(NEUTRALS); | ||
validPids.add(UDF); | ||
mcTallies = new long[validPids.size()]; | ||
recTallies = new long[validPids.size()][validPids.size()]; | ||
mcGenMatch = schema.getSchema("MC::GenMatch"); | ||
mcParticle = schema.getSchema("MC::Particle"); | ||
recParticle = schema.getSchema("REC::Particle"); | ||
} | ||
|
||
/** | ||
* Get one element of the efficiency matrix. | ||
* @param truth true PID | ||
* @param rec reconstructed PID | ||
* @return probability | ||
*/ | ||
public float get(int truth, int rec) { | ||
long sum = mcTallies[validPids.indexOf(truth)]; | ||
return sum>0 ? ((float)recTallies[validPids.indexOf(truth)][validPids.indexOf(rec)])/sum : 0; | ||
} | ||
|
||
/** | ||
* Add an event in the form of truth and reconstructed particle species. | ||
* @param truth truth PID | ||
* @param rec reconstructed PID | ||
*/ | ||
public synchronized void add(int truth, int rec) { | ||
final int t = validPids.indexOf(truth); | ||
if (t < 0) return; | ||
final int r = validPids.indexOf(rec); | ||
mcTallies[t]++; | ||
if (r < 0) recTallies[t][UDF]++; | ||
else recTallies[t][r]++; | ||
} | ||
|
||
/** | ||
* Add a HIPO event. | ||
* @param e | ||
*/ | ||
public void add(Event e) { | ||
Bank bm = new Bank(mcParticle); | ||
Bank br = new Bank(recParticle); | ||
e.read(bm); | ||
e.read(br); | ||
TreeMap<Short,Short> good = getMapping(e); | ||
for (short row=0; row<bm.getRows(); ++row) { | ||
if (!good.containsKey(row)) add(bm.getInt("pid",row), UDF); | ||
else add(bm.getInt("pid",row), br.getInt("pid",good.get(row))); | ||
} | ||
} | ||
|
||
/** | ||
* Add input HIPO files by path. | ||
* @param filenames | ||
*/ | ||
public void add(List<String> filenames) { | ||
Event e = new Event(); | ||
for (String f : filenames) { | ||
HipoReader r = new HipoReader(); | ||
r.open(f); | ||
while (r.hasNext()) { | ||
r.nextEvent(e); | ||
add(e); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Truth-matching banks contain pointers to MC::Particle and REC::Particle, | ||
* and here we cache that mapping to avoid nested loops. | ||
*/ | ||
private TreeMap getMapping(Event e) { | ||
Bank b = new Bank(mcGenMatch); | ||
e.read(b); | ||
TreeMap<Short,Short> m = new TreeMap<>(); | ||
for (int row=0; row<b.getRows(); ++row) | ||
m.put(b.getShort("mcindex", row), b.getShort("pindex",row)); | ||
return m; | ||
} | ||
|
||
/** | ||
* Get efficiencies as a human-readable table. | ||
* @return | ||
*/ | ||
public String toTable() { | ||
StringBuilder s = new StringBuilder(); | ||
s.append(" "); | ||
for (int i=0; i<validPids.size(); ++i) { | ||
s.append(String.format("%7d",validPids.get(i))); | ||
if (validPids.size()==i+1) s.append("\n"); | ||
} | ||
for (int i=0; i<validPids.size(); ++i) { | ||
s.append(String.format("%6d",validPids.get(i))); | ||
for (int j=0; j<validPids.size(); ++j) { | ||
s.append(String.format("%7.4f",get(validPids.get(i),validPids.get(j)))); | ||
if (validPids.size()==j+1) s.append("\n"); | ||
} | ||
} | ||
return s.toString(); | ||
} | ||
|
||
/** | ||
* Get efficiencies as a JSON object. | ||
* @return | ||
*/ | ||
public JsonObject toJson() { | ||
JsonObject effs = new JsonObject(); | ||
JsonArray pids = new JsonArray(); | ||
for (int i=0; i<validPids.size(); ++i) { | ||
pids.add(validPids.get(i)); | ||
JsonArray a = new JsonArray(); | ||
for (int j=0; j<validPids.size(); ++j) | ||
a.add(get(validPids.get(i),validPids.get(j))); | ||
effs.add(Integer.toString(validPids.get(i)),a); | ||
} | ||
JsonObject ret = new JsonObject(); | ||
ret.add("pids", pids); | ||
ret.add("effs", effs); | ||
return ret; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.