Print

Print


Commit in lcsim/src/org/lcsim/recon/cluster/util on MAIN
SmallClusterFindMother.java+281added 1.1
attach smaller cluster to the nearby biggger one

lcsim/src/org/lcsim/recon/cluster/util
SmallClusterFindMother.java added at 1.1
diff -N SmallClusterFindMother.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SmallClusterFindMother.java	1 Apr 2008 01:21:14 -0000	1.1
@@ -0,0 +1,281 @@
+/*
+ * SmallClusterFindMother.java
+ *
+ * Created on February 17, 2008, 10:52 AM
+ *
+ * To attache the smaller cluster around a bigger one to the the bigger one
+ */
+
+package org.lcsim.recon.cluster.util;
+import java.util.List;
+import java.util.ArrayList;
+import org.lcsim.event.Cluster;
+import org.lcsim.recon.cluster.util.BasicCluster;
+import org.lcsim.recon.cluster.util.ClusterESort;
+import java.util.Collections;
+import org.lcsim.recon.cluster.util.ClusterIDCheater;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.CalorimeterHit;
+/**
+ *
+ * @author Qingmin Zhang
+ */
+public class SmallClusterFindMother {
+    double minDistanceDiff = 200.0;
+    double minAngle = .2;
+    double minERatio = .1;
+    int totalAttach = 0;
+    int effAttach = 0;
+    List<MCParticle> fsParticles = new ArrayList<MCParticle>();
+    /** Creates a new instance of SmallClusterFindMother */
+    public SmallClusterFindMother() 
+    {
+    }
+     public SmallClusterFindMother(List<MCParticle> fs) 
+    {
+         fsParticles = fs;
+    }
+     public SmallClusterFindMother(double dis,double angle,double eRatio)
+    {
+         minDistanceDiff = dis;
+         minAngle = angle;
+         minERatio = eRatio;
+    }
+      public SmallClusterFindMother(double dis) //for muon Detector especially near the boundary between endcap and barrel
+    {
+         minDistanceDiff = dis;
+    }
+    public List<Cluster> attachToMother(List<Cluster> originClusters)
+    {
+    
+    List<Cluster> startClusters = new ArrayList<Cluster>();
+    startClusters.addAll(originClusters);
+    List<Cluster> finalClusters = new ArrayList<Cluster>();
+    boolean continueFlag = true;
+    while(continueFlag){
+     finalClusters.clear();
+    //order by the energy of Cluster
+    Collections.sort(startClusters, new ClusterESort());
+    int size = startClusters.size();
+    boolean[] used = new boolean[size];
+    List<Integer> child = new ArrayList<Integer>();
+    List<Integer> mother = new ArrayList<Integer>();
+    for(int i =0 ;i<size;i++)
+        used[i] = false;
+   
+    for(int i=size-1;i>=0;i--)
+    {
+    if(!used[i]){
+        double complexIndex = 9999.0; // = angle*(E1/E)*d
+        int motherID = -1;
+      for(int j = 0;j<i;j++)
+      {
+        double a = angle(startClusters.get(i),startClusters.get(j));
+        double eRatio = startClusters.get(i).getEnergy()/startClusters.get(j).getEnergy();
+        double dis = distance(startClusters.get(i),startClusters.get(j));
+        if(a<=minAngle&&eRatio<=minERatio&&dis<=minDistanceDiff)
+        {
+            if(complexIndex >a*eRatio*dis)
+            { complexIndex = a*eRatio*dis;
+              motherID = j;
+            }
+        }
+      }
+        if(motherID!=-1)
+        {
+        child.add(i);
+        mother.add(motherID);
+        used[i] = true;
+        used[motherID] = true;
+        }
+     }
+    }
+    //process clusters without dependent and clusters not be depended
+     for(int i = 0;i<size;i++)
+        if(!used[i])
+            finalClusters.add(startClusters.get(i));
+    boolean[] pairUsed = new boolean[child.size()];
+    for(int i=0;i<child.size();i++)
+        pairUsed[i] = false;
+    //process related clusters: attach the smaller one to the bigger one
+    for(int i=0;i<child.size();i++)
+    {
+        if(!pairUsed[i]){
+        BasicCluster unite = (BasicCluster)startClusters.get(mother.get(i));
+        for(int j=0;j<mother.size();j++)
+          if(!pairUsed[j]&&mother.get(j)==mother.get(i))
+          {
+            Cluster childCluster = startClusters.get(child.get(i));
+            totalAttach++;
+            if(fromSameParticle(fsParticles,unite,childCluster))
+            effAttach++;
+            unite.addCluster(childCluster);
+            pairUsed[j]= true;
+            
+          }
+        finalClusters.add(unite);
+        }
+    }
+     if(startClusters.size()==finalClusters.size())
+            continueFlag = false;
+   //prepare for the next possible loop
+    startClusters.clear();
+    for(Cluster c: finalClusters)
+        startClusters.add(c);
+    }
+    return finalClusters;
+    }
+    
+    public double angle(Cluster c, Cluster c1)
+   {
+    double[] pos = c.getPosition();
+    double[] pos1 = c1.getPosition();
+    double[] vec = new double[3];
+     for(int i = 0;i<3;i++)
+     vec[i] = pos1[i];//pos1[i]-pos[i];
+   double dist1 = Math.sqrt(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]);
+   double dist2 = Math.sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
+   double dot = pos[0]*vec[0]+pos[1]*vec[1]+pos[2]*vec[2];
+   double angle = Math.acos(dot/(dist1*dist2));
+     return angle;  
+   }
+   public List<Cluster> attachToMotherForMuon(List<Cluster> originClusters,int minSize)
+    {
+    
+    List<Cluster> startClusters = new ArrayList<Cluster>();
+    startClusters.addAll(originClusters);
+    List<Cluster> finalClusters = new ArrayList<Cluster>();
+    boolean continueFlag = true;
+    while(continueFlag){
+     finalClusters.clear();
+    //order by the energy of Cluster
+    Collections.sort(startClusters, new ClusterESort());
+    int size = startClusters.size();
+    boolean[] used = new boolean[size];
+    List<Integer> child = new ArrayList<Integer>();
+    List<Integer> mother = new ArrayList<Integer>();
+    for(int i =0 ;i<size;i++)
+        used[i] = false;
+   
+    for(int i=size-1;i>=0;i--)
+    {
+    if(!used[i]){
+        double complexIndex = 9999.0; 
+        int motherID = -1;
+      for(int j = 0;j<i;j++)
+      {
+        double dis = minDistance(startClusters.get(i),startClusters.get(j));
+        if(dis < minDistanceDiff)
+        {
+            if(complexIndex >dis)
+            { complexIndex = dis;
+              motherID = j;
+            }
+        }
+      }
+        if(motherID!=-1)
+        {
+        child.add(i);
+        mother.add(motherID);
+        used[i] = true;
+        used[motherID] = true;
+        }
+     }
+    }
+    //process clusters without dependent and clusters not be depended
+     for(int i = 0;i<size;i++)
+        if(!used[i])
+            finalClusters.add(startClusters.get(i));
+    boolean[] pairUsed = new boolean[child.size()];
+    for(int i=0;i<child.size();i++)
+        pairUsed[i] = false;
+    //process related clusters: attach the smaller one to the bigger one
+    for(int i=0;i<child.size();i++)
+    {
+        if(!pairUsed[i]){
+        BasicCluster unite = (BasicCluster)startClusters.get(mother.get(i));
+        for(int j=0;j<mother.size();j++)
+          if(!pairUsed[j]&&mother.get(j)==mother.get(i))
+          {
+            Cluster childCluster = startClusters.get(child.get(i));
+            unite.addCluster(childCluster);
+            pairUsed[j]= true;
+            
+          }
+        finalClusters.add(unite);
+        }
+    }
+     if(startClusters.size()==finalClusters.size())
+            continueFlag = false;
+   //prepare for the next possible loop
+    startClusters.clear();
+    for(Cluster c: finalClusters)
+        startClusters.add(c);
+    }
+    List<Cluster> fClusters = new ArrayList<Cluster>();
+    for(Cluster c: finalClusters)
+    { if(c.getSize()>= minSize)
+          fClusters.add(c);
+    }
+    return fClusters;
+    }
+ public double distance(Cluster c, Cluster c1)
+   {
+    double[] pos = c.getPosition();
+    double[] pos1 = c1.getPosition();
+    double[] dis = new double[3];
+    for(int i =0;i<3;i++)
+     dis[i]= pos[i]-pos1[i];
+     double dist = Math.sqrt(dis[0]*dis[0]+dis[1]*dis[1]+dis[2]*dis[2]);
+     return dist;  
+ }
+  public double minDistance(Cluster c, Cluster c1)
+   {
+     double mindist = 9999.;
+      for(CalorimeterHit p:c1.getCalorimeterHits())
+    {  
+       double[] pos = p.getPosition();
+       for(CalorimeterHit h:c.getCalorimeterHits())
+       {
+          double[] hp = h.getPosition();
+          double d = Math.sqrt((hp[0]-pos[0])*(hp[0]-pos[0]) +(hp[1]-pos[1])*(hp[1]-pos[1]) +(hp[2]-pos[2])*(hp[2]-pos[2])); 
+          if(d < mindist)mindist = d;
+       }
+    }
+       return mindist;
+  }
+ public double minAngle(Cluster c, Cluster c1)
+  {
+   double minA = 99.;
+       for(CalorimeterHit p:c1.getCalorimeterHits())
+    {  
+       double[] pos = p.getPosition();
+       for(CalorimeterHit h:c.getCalorimeterHits())
+       {
+          double[] hp = h.getPosition();
+          double dist1 = Math.sqrt(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]);
+          double dist2 = Math.sqrt(hp[0]*hp[0]+hp[1]*hp[1]+hp[2]*hp[2]);
+          double dot = pos[0]*hp[0]+pos[1]*hp[1]+pos[2]*hp[2];
+          double angle = Math.acos(dot/(dist1*dist2));
+          if(angle < minA)  minA = angle;
+       }
+    }
+    return minA;
+  }
+public boolean fromSameParticle(List<MCParticle> fs,Cluster c1, Cluster c2)
+   {
+    ClusterIDCheater idCheater = new ClusterIDCheater();
+    if(idCheater.getMCID(fs,c1)==idCheater.getMCID(fs,c2))
+        return true;
+    else
+        return false;
+   }
+public int getTotalAttach()
+{
+  return totalAttach;
+}
+public int getEffAttach()
+{
+  return effAttach;
+}
+}
\ No newline at end of file
CVSspam 0.2.8