Print

Print


Commit in lcsim/src/org/lcsim/recon/cheater on MAIN
ReconCheater.java+270-1381.6 -> 1.7
Update.

lcsim/src/org/lcsim/recon/cheater
ReconCheater.java 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- ReconCheater.java	26 Oct 2005 19:04:03 -0000	1.6
+++ ReconCheater.java	1 Nov 2005 16:44:37 -0000	1.7
@@ -70,22 +70,19 @@
     double DecayDistance;
     double ECalResolution, HCalResolution;
     double ECalSampling,   HCalSampling,   HCalDigital;  // Hits/GeV
-    double pTrackMin, EClusterMin, NDigitalMin;
+    double pTrackMin, EClusterMin;
+    double ECalEnergyMin,  HCalEnergyMin,  NDigitalMin;
 
-    static boolean Hist = false;
+    boolean usePerfectEnergyFlow;
+
+    double Distance2XCluster, Distance4XCluster;
+
+    static boolean hist = false;
 
 
     /** */
     public ReconCheater()
     {
-	this(Hist);
-    }
-
-    public ReconCheater(boolean hist)
-    {
-	// super(hist);
-	this.hist = hist;
-
 	System.out.println("");
 	//String text = "ReconCheater  version 1.0"+"\n"+
 	//    "  Running hep.lcd version "+hep.lcd.Version.getVersion();
@@ -104,6 +101,8 @@
 	df.setMaximumFractionDigits(3);	
     }
 
+    public void setHist(boolean hist) { this.hist = hist; initHist(); }
+
 
     void init()
     {
@@ -133,14 +132,27 @@
 
 	pTrackMin = cheatingTable.getPTrackMin();
 	EClusterMin = cheatingTable.getEClusterMin();
+	ECalEnergyMin = cheatingTable.getECalEnergyMin();
+	HCalEnergyMin = cheatingTable.getHCalEnergyMin();
 	NDigitalMin = cheatingTable.getNDigitalMin();
 
+	usePerfectEnergyFlow = cheatingTable.usePerfectEnergyFlow();
+
+	Distance2XCluster = cheatingTable.getDistance2XCluster();
+	Distance4XCluster = cheatingTable.getDistance4XCluster();
+
+	initHist();
+    }
+
+    void initHist()
+    {
 	if (hist) {
 	    AIDA aida = AIDA.defaultInstance();
 	    ITree tree = aida.tree();
 	    try {
 		tree.mkdir("ReconCheater");
 		tree.cd("ReconCheater");
+		  tree.mkdir("Clusters");
 		  tree.mkdir("Lost"); tree.mkdir("Interacted"); tree.mkdir("Conversion");
 		tree.cd("..");
 	    }
@@ -151,8 +163,8 @@
 
     protected int nEvt = 0;
     boolean first = true, firstEvents = true;
-    boolean debug = false;
-    boolean hist;
+    boolean debug = true;
+    int imcp = -1;
 
     /** Reconstruct an event by using the Monte Carlo truth to cheat. */
     protected void process(EventHeader event)
@@ -194,7 +206,6 @@
 	init();
     }
 
-
     Map<MCParticle,CheatTrack> charged = null;    // Tracks from MCParticles
     Map<MCParticle,CheatCluster> neutrals = null; // and clusters.
     Map<MCParticle,MCParticle> primaryMCParents = null;
@@ -239,64 +250,65 @@
 	extraTrackList = new ArrayList<CheatTrack>();
 	List<CheatTrack> skippedTracks  = new ArrayList<CheatTrack>();
 
+	List<CheatTrack> trackList = null;
 	List<List<CheatTrack>> trackCollections = event.get(CheatTrack.class);
-	for (List<CheatTrack> trackList : trackCollections ) {
-	    String name = event.getMetaData(trackList).getName();
+	for (List<CheatTrack> collection : trackCollections ) {
+	    String name = event.getMetaData(collection).getName();
+	    if (name.equals("CombinedTracks")) trackList = collection;
+	}
+	if (trackList==null) return particles;
+
+	// Work through track list.
+	for (CheatTrack track : trackList) {
+	    MCParticle mcp = track.getMCParticle(); int PDGID = mcp.getPDGID();
+	    double p = Math.sqrt(mcp.getPX()*mcp.getPX()+mcp.getPY()*mcp.getPY()+mcp.getPZ()*mcp.getPZ());
+	    if (p<pTrackMin) continue;
 
-	    if (name.equals("CombinedTracks")) {
-		// Work through track list.
-		for (CheatTrack track : trackList) {
-		    MCParticle mcp = track.getMCParticle(); int PDGID = mcp.getPDGID();
-		    double p = Math.sqrt(mcp.getPX()*mcp.getPX()+mcp.getPY()*mcp.getPY()+mcp.getPZ()*mcp.getPZ());
-		    if (p<pTrackMin) continue;
-
-		    // Keep track of primary parentage.
-		    MCParticle primaryParent = findPrimaryParent(mcp);
-		    primaryMCParents.put(mcp,primaryParent);
-
-		    // Ignore radiation, compton scattering, ...
-		    if (!allowRadiation && mcp.getSimulatorStatus().vertexIsNotEndpointOfParent()) continue;
-		    if (!allowRadiation && checkRadiationParent(mcp)) continue;
-		    if (mcp.getSimulatorStatus().isBackscatter()) continue;
-		    // Ignore recoil nucleus.
-		    if (PDGID==0) continue;
-
-		    // Record particles that decay or interact.
-		    boolean decayed = checkDecay(mcp);
-		    boolean interacted = false;
-		    if (decayed) decayedParticles.add(mcp);
-		    else {
-			interacted = checkInteraction(mcp);
-			if (interacted) interactedParticles.add(mcp);
-		    }
-		    // Check for decay or interaction products.
-		    boolean decayProduct = checkDecay(primaryParent);
-		    boolean interactionProduct = checkInteractionParent(mcp);
-
-		    // Skip tracks from decaying or interacting particles.
-		    if ((allowDecays && decayed && hasNeutralDaughters(mcp)) ||  // But keep pi's from pi->mu decays, etc.
-			(allowNuclearInteractions && interacted) ||  // Assume interacting tracks will not be used.
-
-			// Skip decay and interaction products if switched off.
-			(!allowDecays && decayProduct && isLongLived(primaryParent)) ||
-			(!allowNuclearInteractions && interactionProduct)) {
-			skippedTracks.add(track);
-			continue;
-		    }
+	    // Keep track of primary parentage.
+	    MCParticle primaryParent = findPrimaryParent(mcp);
+	    primaryMCParents.put(mcp,primaryParent);
+
+	    // Ignore radiation, compton scattering, ...
+	    if (!allowRadiation && mcp.getSimulatorStatus().vertexIsNotEndpointOfParent()) continue;
+	    if (!allowRadiation && checkRadiationParent(mcp)) continue;
+	    if (mcp.getSimulatorStatus().isBackscatter()) continue;
+	    // Ignore recoil nucleus.
+	    if (PDGID==0) continue;
+
+	    // Record particles that decay or interact.
+	    boolean decayed = checkDecay(mcp);
+	    boolean interacted = false;
+	    if (decayed) decayedParticles.add(mcp);
+	    else {
+		interacted = checkInteraction(mcp);
+		if (interacted) interactedParticles.add(mcp);
+	    }
+	    // Check for decay or interaction products.
+	    boolean decayProduct = checkDecay(primaryParent);
+	    boolean interactionProduct = checkInteractionParent(mcp);
+
+	    // Skip tracks from decaying or interacting particles.
+	    if ((allowDecays && decayed && hasNeutralDaughters(mcp)) ||  // But keep pi's from pi->mu decays, etc.
+		(allowNuclearInteractions && interacted) ||  // Assume interacting tracks will not be used.
+
+		// Skip decay and interaction products if switched off.
+		(!allowDecays && decayProduct && isLongLived(primaryParent)) ||
+		(!allowNuclearInteractions && interactionProduct)) {
+		skippedTracks.add(track);
+		continue;
+	    }
 
-		    // Record charged particle tracks that were found
-		    if (chargedList.contains(mcp)) {
-			chargedList.remove(mcp);
-
-			// Add reconstructed track to charged list.
-			if (charged.get(mcp)==null) charged.put(mcp,track);
-			else System.err.println(ClassName+" track is already in map!");
-		    }
-		    // or add as an extra track.
-		    else
-			extraTrackList.add(track);
-		}
+	    // Record charged particle tracks that were found
+	    if (chargedList.contains(mcp)) {
+		chargedList.remove(mcp);
+
+		// Add reconstructed track to charged list.
+		if (charged.get(mcp)==null) charged.put(mcp,track);
+		else System.err.println(ClassName+" track is already in map!");
 	    }
+	    // or add as an extra track.
+	    else
+		extraTrackList.add(track);
 	}
 	// Remove secondaries if primary track has been reconstructed.
 	List<CheatTrack> secondaryTracks = new ArrayList<CheatTrack>();
@@ -332,7 +344,7 @@
 	List<CheatTrack> primaryTracks = new ArrayList<CheatTrack>();
 	for (CheatTrack track : extraTrackList) {
 	    MCParticle mcp = track.getMCParticle();
-	    if (getStatusCode(mcp).equals("GEN_PREDECAY") && !isLongLived(mcp)) {
+	    if (getStatusCode(mcp).equals("GEN_PREDECAY") && (allowDecays || !isLongLived(mcp))) {
 		primaryTracks.add(track); skippedTracks.add(track);
 	    }
 	}
@@ -360,73 +372,81 @@
 	extraClusterList = new ArrayList<CheatCluster>();
 	List<CheatCluster> skippedClusters  = new ArrayList<CheatCluster>();
 
+	List<CheatCluster> clusterList = null;
 	List<List<CheatCluster>> clusterCollections = event.get(CheatCluster.class);
-	for (List<CheatCluster> clusterList : clusterCollections ) {
-	    String name = event.getMetaData(clusterList).getName();
-
-	    if (name.equals("RefinedClusters")) {
-		for (CheatCluster cluster : clusterList) {
-		    MCParticle mcp = cluster.getMCParticle(); int PDGID = mcp.getPDGID();
-		    double charge  = mcp.getCharge();
-		    double p = Math.sqrt(mcp.getPX()*mcp.getPX()+mcp.getPY()*mcp.getPY()+mcp.getPZ()*mcp.getPZ());
-		    double eMeasured = getMeasuredEnergy(cluster);
-		    if (eMeasured<EClusterMin) continue;
-
-		    // Keep track of primary parentage.
-		    MCParticle primaryParent = findPrimaryParent(mcp);
-		    primaryMCParents.put(mcp,primaryParent);
-
-		    // Ignore radiation, compton scattering, ...
-		    if (!allowRadiation && mcp.getSimulatorStatus().vertexIsNotEndpointOfParent()) continue;
-		    if (!allowRadiation && checkRadiationParent(mcp)) continue;
-		    if (mcp.getSimulatorStatus().isBackscatter()) continue;
-		    // Ignore recoil nucleus.
-		    if (PDGID==0) continue;
-
-		    // Record particles that decay or interact.
-		    boolean decayed = checkDecay(mcp);
-		    boolean interacted = false;
-		    if (decayed && !decayedParticles.contains(mcp)) decayedParticles.add(mcp);
-		    else {
-			interacted = checkInteraction(mcp);
-			if (interacted && !interactedParticles.contains(mcp)) interactedParticles.add(mcp);
-		    }
-		    // Check for decay or interaction products.
-		    boolean decayProduct = checkDecay(primaryParent);
-		    boolean interactionProduct = checkInteractionParent(mcp);
-
-		    // Check if cluster is associated with a reconstructed track.
-		    boolean unAssociated = charge==0;
-		    if (!unAssociated) {
-			boolean found = charged.containsKey(mcp);
-			if (!found) for (CheatTrack t : extraTrackList) if (t.getMCParticle()==mcp) found = true;
-			if (!found) for (CheatTrack t : skippedTracks)  if (t.getMCParticle()==mcp) found = true;
-			if (!found && !checkForParent(getParent(mcp))) unAssociated = true;
-		    }
-		    if (!unAssociated) continue;
-
-		    // Skip decay and interaction products if switched off.
-		    if ((!allowDecays && decayProduct && isLongLived(primaryParent)) ||
-			(!allowNuclearInteractions && interactionProduct)) {
-			skippedClusters.add(cluster);
-			continue;
-		    }
+	for (List<CheatCluster> collection : clusterCollections ) {
+	    String name = event.getMetaData(collection).getName();
+	    if (name.equals("RefinedClusters")) clusterList = collection;
+	}
+	if (clusterList==null) return particles;
+
+	// Analyze clusters.
+	if (hist) analyzeReconstructedClusters(clusterList);
+
+	// Remove nearby clusters.
+	if (!usePerfectEnergyFlow) clusterList = getIsolatedClusters(clusterList);
+
+	// Work through cluster list.
+	for (CheatCluster cluster : clusterList) {
+	    MCParticle mcp = cluster.getMCParticle(); int PDGID = mcp.getPDGID();
+	    double charge  = mcp.getCharge();
+	    double p = Math.sqrt(mcp.getPX()*mcp.getPX()+mcp.getPY()*mcp.getPY()+mcp.getPZ()*mcp.getPZ());
+	    double eMeasured = getMeasuredEnergy(cluster);
+	    if (eMeasured<EClusterMin) continue;
+
+	    // Keep track of primary parentage.
+	    MCParticle primaryParent = findPrimaryParent(mcp);
+	    primaryMCParents.put(mcp,primaryParent);
+
+	    // Ignore radiation, compton scattering, ...
+	    if (!allowRadiation && mcp.getSimulatorStatus().vertexIsNotEndpointOfParent()) continue;
+	    if (!allowRadiation && checkRadiationParent(mcp)) continue;
+	    if (mcp.getSimulatorStatus().isBackscatter()) continue;
+	    // Ignore recoil nucleus.
+	    if (PDGID==0) continue;
+
+	    // Record particles that decay or interact.
+	    boolean decayed = checkDecay(mcp);
+	    boolean interacted = false;
+	    if (decayed && !decayedParticles.contains(mcp)) decayedParticles.add(mcp);
+	    else {
+		interacted = checkInteraction(mcp);
+		if (interacted && !interactedParticles.contains(mcp)) interactedParticles.add(mcp);
+	    }
+	    // Check for decay or interaction products.
+	    boolean decayProduct = checkDecay(primaryParent);
+	    boolean interactionProduct = checkInteractionParent(mcp);
+
+	    // Check if cluster is associated with a reconstructed track.
+	    boolean unAssociated = charge==0;
+	    if (!unAssociated) {
+		boolean found = charged.containsKey(mcp);
+		if (!found) for (CheatTrack t : extraTrackList) if (t.getMCParticle()==mcp) found = true;
+		if (!found) for (CheatTrack t : skippedTracks)  if (t.getMCParticle()==mcp) found = true;
+		if (!found && !checkForParent(getParent(mcp))) unAssociated = true;
+	    }
+	    if (!unAssociated) continue;
+
+	    // Skip decay and interaction products if switched off.
+	    if ((!allowDecays && decayProduct && isLongLived(primaryParent)) ||
+		(!allowNuclearInteractions && interactionProduct)) {
+		skippedClusters.add(cluster);
+		continue;
+	    }
 
-		    // Record neutral particle clusters that were found
-		    if (neutralList.contains(mcp)) {
-			neutralList.remove(mcp);
-
-			// Add reconstructed cluster to neutrals list.
-			if (neutrals.get(mcp)==null) neutrals.put(mcp,cluster);
-			else System.err.println(ClassName+" cluster is already in map!");
-		    }
-		    // or add as an extra (unexpected) cluster.
-		    else
-		    //if ((!decayProduct || acceptDecayNeutrals) &&
-			//(!interactionProduct || acceptNuclearInteractionNeutrals)) {
-			extraClusterList.add(cluster);
-		}
+	    // Record neutral particle clusters that were found
+	    if (neutralList.contains(mcp)) {
+		neutralList.remove(mcp);
+
+		// Add reconstructed cluster to neutrals list.
+		if (neutrals.get(mcp)==null) neutrals.put(mcp,cluster);
+		else System.err.println(ClassName+" cluster is already in map!");
 	    }
+	    // or add as an extra (unexpected) cluster.
+	    else
+		//if ((!decayProduct || acceptDecayNeutrals) &&
+		//(!interactionProduct || acceptNuclearInteractionNeutrals)) {
+		extraClusterList.add(cluster);
 	}
 	if (firstEvents) {
 	    text = "    Total of "+neutrals.keySet().size()+" neutral clusters found:";
@@ -661,6 +681,112 @@
 	return particles;
     }
 
+    List<CheatCluster> getIsolatedClusters(List<CheatCluster> clusterList)
+    {
+	List<CheatCluster> result = new ArrayList<CheatCluster>();
+
+	// Work through cluster list.
+	for (CheatCluster cluster : clusterList) {
+	    MCParticle mcp = cluster.getMCParticle(); int PDGID = mcp.getPDGID();
+	    boolean Klong = PDGID==130;
+	    boolean neutron = Math.abs(PDGID)==2112;
+	    if (Klong || neutron) {
+		Hep3Vector endPoint = mcp.getEndPoint();
+		double energy = getMeasuredEnergy(cluster);
+		if (energy<EClusterMin) continue;
+
+		// Check for decay or interaction products.
+		MCParticle primaryParent = findPrimaryParent(mcp); primaryMCParents.put(mcp,primaryParent);
+		boolean decayProduct = checkDecay(primaryParent);
+		boolean interactionProduct = checkInteractionParent(mcp);
+
+		// Skip decay and interaction products if switched off.
+		if ((!allowDecays && decayProduct && isLongLived(primaryParent)) ||
+		    (!allowNuclearInteractions && interactionProduct))
+		    continue;
+
+		// Determine distance to nearest large cluster.
+		double distanceLarge2XCluster = 1000., distanceLarge4XCluster = 1000.;
+		for (CheatCluster cluster2 : clusterList) {
+		    if (cluster2==cluster) continue;
+		    MCParticle mcp2 = cluster2.getMCParticle(); int PDGID2 = mcp2.getPDGID();
+		    Hep3Vector endPoint2 = mcp2.getEndPoint();
+		    double energy2 = getMeasuredEnergy(cluster2);
+		    if (energy2<EClusterMin) continue;
+
+		    double dx = endPoint2.x()-endPoint.x(), dy = endPoint2.y()-endPoint.y(), dz = endPoint2.z()-endPoint.z();
+		    double d = Math.sqrt(dx*dx + dy*dy + dz*dz);
+		    if ((energy2>(2.*energy)) && d<distanceLarge2XCluster) distanceLarge2XCluster = d;
+		    if ((energy2>(4.*energy)) && d<distanceLarge4XCluster) distanceLarge4XCluster = d;
+		}
+		if (distanceLarge2XCluster<Distance2XCluster) continue;
+		if (distanceLarge4XCluster<Distance4XCluster) continue;
+	    }
+	    result.add(cluster);
+	}
+	return result;
+    }
+
+
+    void analyzeReconstructedClusters(List<CheatCluster> clusterList)
+    {
+	AIDA aida = AIDA.defaultInstance();
+	ITree tree = aida.tree();
+	tree.cd("ReconCheater"); tree.cd("Clusters");
+
+	// Work through cluster list.
+	int nNeutrals = 0, nRemainingNeutrals = 0;
+	for (CheatCluster cluster : clusterList) {
+	    MCParticle mcp = cluster.getMCParticle(); int PDGID = mcp.getPDGID();
+	    boolean Klong = PDGID==130;
+	    boolean neutron = Math.abs(PDGID)==2112;
+	    if (!Klong && !neutron) continue;
+	    Hep3Vector endPoint = mcp.getEndPoint();
+	    double energy = getMeasuredEnergy(cluster);
+	    if (energy<EClusterMin) continue;
+
+	    // Check for decay or interaction products.
+	    MCParticle primaryParent = findPrimaryParent(mcp); primaryMCParents.put(mcp,primaryParent);
+	    boolean decayProduct = checkDecay(primaryParent);
+	    boolean interactionProduct = checkInteractionParent(mcp);
+
+	    // Skip decay and interaction products if switched off.
+	    if ((!allowDecays && decayProduct && isLongLived(primaryParent)) ||
+		(!allowNuclearInteractions && interactionProduct))
+		continue;
+	    nNeutrals++;
+
+	    // Plot distance to nearest large cluster.
+	    double distance = 1000., distanceLarge2XCluster = 1000., distanceLarge4XCluster = 1000.;
+	    for (CheatCluster cluster2 : clusterList) {
+		if (cluster2==cluster) continue;
+		MCParticle mcp2 = cluster2.getMCParticle(); int PDGID2 = mcp2.getPDGID();
+		Hep3Vector endPoint2 = mcp2.getEndPoint();
+		double energy2 = getMeasuredEnergy(cluster2);
+		if (energy2<EClusterMin) continue;
+
+		double dx = endPoint2.x()-endPoint.x(), dy = endPoint2.y()-endPoint.y(), dz = endPoint2.z()-endPoint.z();
+		double d = Math.sqrt(dx*dx + dy*dy + dz*dz);
+		if (d<100.) {
+		    aida.cloud1D("Nearby ratio").fill(energy2/energy);
+		}
+		if ((energy2>(energy/2.)) && d<distance) distance = d;
+		if ((energy2>(2.*energy)) && d<distanceLarge2XCluster) distanceLarge2XCluster = d;
+		if ((energy2>(4.*energy)) && d<distanceLarge4XCluster) distanceLarge4XCluster = d;
+	    }
+	    if (distance<1000.) aida.cloud1D("Nearest 0.5X cluster").fill(distance);
+	    if (distanceLarge2XCluster<1000.) aida.cloud1D("Nearest Large2X cluster").fill(distanceLarge2XCluster);
+	    if (distanceLarge4XCluster<1000.) aida.cloud1D("Nearest Large4X cluster").fill(distanceLarge4XCluster);
+
+	    // Apply isolation cuts.
+	    if (distanceLarge2XCluster<Distance2XCluster) continue;
+	    if (distanceLarge4XCluster<Distance4XCluster) continue;
+	    nRemainingNeutrals++;
+	}
+	aida.cloud1D("# neutral hadrons").fill(nNeutrals);
+	aida.cloud1D("# remaining neutrals").fill(nRemainingNeutrals);
+	tree.cd(".."); tree.cd("..");
+    }
     void analyzeReconstructedParticles(List<ReconstructedParticle> particles, List<MCParticle> chargedList,
 				       List<MCParticle> neutralList)
     {
@@ -1106,15 +1232,19 @@
 	boolean photon = mcp.getPDGID()==22;
 	if (photon) {
 	    energy = energy/ECalSampling;
+	    if (energy<ECalEnergyMin) energy = 0.;
 	}
 	else {
-	    if (HCalDigital==0) energy = energy/HCalSampling;
+	    if (HCalDigital==0) {
+		energy = energy/HCalSampling;
+		if (energy<HCalEnergyMin) energy = 0.;
+	    }
 	    else {
 		int nhits = 0;
 		for (CalorimeterHit hit : cluster.getCalorimeterHits())
 		    if (hit.getTime()<100.) nhits++;
 		energy = nhits/HCalDigital;
-		if (nhits<NDigitalMin) energy = 0.;
+		if (nhits<NDigitalMin || energy<HCalEnergyMin) energy = 0.;
 	    }
 	}
 	Hep3Vector pV = mcp.getMomentum();
@@ -1124,16 +1254,18 @@
 	    if (photon) {
 		if (useECalParameterization) {
 		    r = 1. - random.nextGaussian()*ECalResolution/Math.sqrt(mcp.getEnergy());
-		    if (r<0.1) r = 0.1;
+		    if (r<0.1) r = 0.1; energy = r * pV.magnitude();
+		    if (energy<ECalEnergyMin) energy = 0.;
 		}
 	    }
 	    else
 		if (useHCalParameterization) {
 		    r = 1. - random.nextGaussian()*HCalResolution/Math.sqrt(mcp.getEnergy());
-		    if (r<0.1) r = 0.1;
+		    if (r<0.1) r = 0.1; energy = r * pV.magnitude();
+		    if (energy<HCalEnergyMin) energy = 0.;
 		}
 	}
-	return r * pV.magnitude();
+	return energy;
     }
 
     Map<MCParticle,Integer> map = null;
@@ -1158,7 +1290,7 @@
     double totalEventEnergy;
 
     /** Get charged and neutral lists for MCParticles generated by the Pythia Monte Carlo. */
-    public void getPythiaMCParticles(EventHeader event, List<MCParticle> chargedList, List<MCParticle> neutralList)
+    void getPythiaMCParticles(EventHeader event, List<MCParticle> chargedList, List<MCParticle> neutralList)
     {
 	// Get Monte Carlo particles from LCSIM event.
 	String text = "   Get Pythia Monte Carlo charged and neutral lists.";
CVSspam 0.2.8