lcsim/src/org/lcsim/contrib/uiowa
diff -u -r1.24 -r1.25
--- ReclusterDriver.java 2 Jul 2008 20:49:42 -0000 1.24
+++ ReclusterDriver.java 8 Jul 2008 16:34:19 -0000 1.25
@@ -37,7 +37,7 @@
*
* This version is PRELIMINARY.
*
- * @version $Id: ReclusterDriver.java,v 1.24 2008/07/02 20:49:42 mcharles Exp $
+ * @version $Id: ReclusterDriver.java,v 1.25 2008/07/08 16:34:19 mcharles Exp $
* @author Mat Charles
*/
@@ -1008,6 +1008,111 @@
}
}
+ // Special!
+ // May over-ride some previous links, giving them a better score
+ protected void initPotentialLinks_Cone(Collection<Cluster> seeds, Collection<Cluster> linkableClusters, Map<Cluster, Track> clustersMatchedToTweakedTracks, double scaleOK, double scaleMin) {
+ SteveMipWrapper tmpWrapper = new SteveMipWrapper();
+ tmpWrapper.process(m_event);
+ SteveMIPReassignmentAlgorithm mipAlg = new SteveMIPReassignmentAlgorithm(m_event, 1.0);
+ for (Cluster seed : seeds) {
+ // Setup: Find what track the seed is connected to.
+ Track tr = clustersMatchedToTweakedTracks.get(seed);
+ if (tr == null) {
+ throw new AssertionError("Seed with "+seed.getCalorimeterHits().size()+" hits (from list of "+seeds.size()+" seeds) has a null track!");
+ }
+ if (tr.getTracks() == null) {
+ throw new AssertionError("Track.getTracks() is null!");
+ }
+ // Now loop over other clusters and assign scores if they're in a tight downstream cone
+ for (Cluster clus : linkableClusters) {
+ if (seeds.contains(clus)) {
+ // Don't link seeds to themselves or to other seeds
+ continue;
+ }
+
+ // Check if a link already exists, and if so with what score
+ ScoredLink previousLink = null;
+ boolean linkAlreadyExists = checkForLink(seed, clus);
+ if (linkAlreadyExists) {
+ List<ScoredLink> linksForSeed = m_potentialLinks.get(seed);
+ for (ScoredLink link : linksForSeed) {
+ Cluster candidate = link.counterpart(seed);
+ if (candidate == clus) {
+ // Found it
+ previousLink = link;
+ break;
+ }
+ }
+ }
+
+ // Compute cone and score it
+ Double coneAngle = mipAlg.computeFigureOfMerit(tr, clus);
+ if (coneAngle == null) {
+ // Extrapolation failed or angle way too large
+ // Skip this link
+ continue;
+ } else {
+ double coneAngleCosTheta = Math.cos(coneAngle);
+ // Compute score based on scales
+ // Score drops linearly from (1.0 to 0.7) over the range (1.0, scaleOK)
+ // Score drops linearly from (0.7 to 0.0) over the range (scaleOK, scaleMin)
+ // Anything below scaleMin has zero score
+ double score = 0.0;
+ boolean newLinkValid = false;
+ if (coneAngleCosTheta <= 1.0 && coneAngleCosTheta > scaleOK) {
+ // In "good" region, scoring 1.0 to 0.7
+ double offset = (1.0 - coneAngleCosTheta);
+ double normalizedOffset = offset / (1.0 - scaleOK);
+ score = 1.0 - 0.3*normalizedOffset;
+ if (score > 1.0 || score < 0.7) { throw new AssertionError("Calculation error"); }
+ newLinkValid = true;
+ } else if (coneAngleCosTheta >= scaleOK && coneAngleCosTheta < scaleMin) {
+ // In "poor" region, scoring 0.7 to 0.0
+ double offset = (scaleOK - coneAngleCosTheta);
+ double normalizedOffset = offset / (scaleOK - scaleMin);
+ score = 0.7 - 0.7*normalizedOffset;
+ if (score > 0.7 || score < 0.0) { throw new AssertionError("Calculation error"); }
+ newLinkValid = true;
+ } else {
+ // Angle too large to score
+ newLinkValid = false;
+ }
+
+ // Make link if needed
+ if (newLinkValid) {
+ if (!linkAlreadyExists) {
+ // No pre-existing link
+ addPotentialLink(seed, clus, score);
+ } else {
+ // Pre-existing link
+ double oldScore = previousLink.score();
+ if (score > oldScore) {
+ // New link is better!
+ // Replace old one.
+ List<ScoredLink> list1 = m_potentialLinks.get(seed);
+ List<ScoredLink> list2 = m_potentialLinks.get(clus);
+ list1.remove(previousLink);
+ list2.remove(previousLink);
+ // Check that it was removed OK
+ boolean linkExistsAfterRemove1 = checkForLink(seed, clus);
+ boolean linkExistsAfterRemove2 = checkForLink(clus, seed);
+ if (linkExistsAfterRemove1) { throw new AssertionError("Book-keeping error!"); }
+ if (linkExistsAfterRemove2) { throw new AssertionError("Book-keeping error!"); }
+ // Add new link
+ addPotentialLink(clus, seed, score);
+ // Check that it was added OK
+ boolean linkExistsAfterAdd1 = checkForLink(seed, clus);
+ boolean linkExistsAfterAdd2 = checkForLink(clus, seed);
+ if (!linkExistsAfterAdd1) { throw new AssertionError("Book-keeping error!"); }
+ if (!linkExistsAfterAdd2) { throw new AssertionError("Book-keeping error!"); }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
protected void initPotentialLinks_MipMip(List<Cluster> mips, double scaleFactorTrackToTrack, boolean applyPenaltyFactor)
{
for (int i=0; i<mips.size(); i++) {
@@ -2290,6 +2395,8 @@
Map<Cluster, List<ScoredLink>> m_potentialLinks = null;
protected void resetPotentialLinks() { m_potentialLinks = new HashMap<Cluster, List<ScoredLink>>(); }
private void addPotentialLink(Cluster clus1, Cluster clus2, double score) {
+ boolean linkAlreadyExists = checkForLink(clus1, clus2);
+ if (linkAlreadyExists) { throw new AssertionError("Book-keeping error"); }
List<ScoredLink> linksForClus1 = m_potentialLinks.get(clus1);
List<ScoredLink> linksForClus2 = m_potentialLinks.get(clus2);
if (linksForClus1 == null) { linksForClus1 = new Vector<ScoredLink>(); m_potentialLinks.put(clus1, linksForClus1); }