lcsim/src/org/lcsim/recon/cluster/fixedcone
diff -u -r1.9 -r1.10
--- FixedConeClusterer.java 1 Jul 2006 21:55:43 -0000 1.9
+++ FixedConeClusterer.java 1 Apr 2008 00:58:04 -0000 1.10
@@ -24,8 +24,17 @@
* This version of the ClusterBuilder splits overlapping clusters
* by assigning cells in the overlap region to the nearest cluster axis.
*
- * @author Norman A. Graf
- * @version 1.0
+ * @author Norman A. Graf, updated by Qingmin Zhang in 19 Dec,2007.
+---------------------------------------------------------------* Updates:---------------------------------------------------
+ * 1. Using it you can set the predicting function for cone size based on seed energy (The function format: A*log(Eseed)+B )
+ * 2. Using it you can apply the cluster energy cut(it varies frome cluster to cluster according to the seed energy )
+ * before the found cluster being added to the cluster List (function Format : A*Eseed+B*Eseed*Eseed)
+ * 3. not like last version, the cone sizes of found clusters are different, so admended the rosolve() function for the overlap hits
+ * using the cone size information
+ *Note: if Construction Fucntion without radius parameter is used, it means you will use predicting function.
+ * Meanwhile if you don't set the function, default values will be set.
+ * Otherwise, it's same to last version.
+------------------------------------------------------------------------------------------------------------------------------------
*/
public class FixedConeClusterer implements Clusterer
@@ -36,8 +45,9 @@
private int _numLayers;
private double _samplingFraction;
private double[] _layerEnergy;
-
-
+ private boolean _radiusSetFlag;//it determines which one is used, preset(ture) or calculated with seed energy(false)
+ private double[] _coneFunc;//(The function format: A*log(Eseed)+B )
+ private double[] _cutFunc;//(function Format : A*Eseed+B*Eseed*Eseed)
private static final double PI=Math.PI;
private static final double TWOPI = 2.*PI;
public FixedConeClusterPropertyCalculator _clusterPropertyCalculator;
@@ -60,14 +70,43 @@
* (backwards compatibility mode with old FixedConeClusterer implementation
* Anything else will be assumed to be 0.
*/
- public FixedConeClusterer(double radius, double seed, double minE, FixedConeDistanceMetric distMetric)
+ public FixedConeClusterer(double seed, double minE,double[] coneFunc,double[] cutFunc,FixedConeDistanceMetric distMetric)
+ {
+ // overwrite later with sampling fraction correction
+ _seedEnergy = seed;
+ _minEnergy = minE;
+ _dm = distMetric;//distMetric;
+ _coneFunc = coneFunc;
+ _cutFunc = cutFunc;
+ _radiusSetFlag = false;
+
+ }
+ public FixedConeClusterer(double seed, double minE,FixedConeDistanceMetric distMetric)
+ {
+ // overwrite later with sampling fraction correction
+ _seedEnergy = seed;
+ _minEnergy = minE;
+ _dm = distMetric;//distMetric;
+ //if the values aren't set, default value will be set as follows
+ _coneFunc = new double[2];
+ _coneFunc[0] = 0.011347;
+ _coneFunc[1] = 0.043117;
+ _cutFunc = new double[2];
+ _cutFunc[0] = 3.2;
+ _cutFunc[1] = 2.0;
+ _radiusSetFlag = false;
+
+ }
+ public FixedConeClusterer(double radius, double seed, double minE,FixedConeDistanceMetric distMetric)
{
_radius = radius;
// overwrite later with sampling fraction correction
_seedEnergy = seed;
_minEnergy = minE;
- _dm = distMetric;
+ _dm = distMetric;//distMetric;
+ _radiusSetFlag = true;
}
+
/**
* Constructor with default distance metric (dot-product method)
*
@@ -75,15 +114,20 @@
* @param seed The minimum energy for a cone seed cell (in GeV)
* @param minE The minimum energy for a cluster (in GeV)
*/
- public FixedConeClusterer(double radius, double seed, double minE)
+ public FixedConeClusterer(double radius, double seed, double minE)
{
- this(radius, seed, minE, FixedConeDistanceMetric.DOTPRODUCT);
+ this(radius, seed, minE,FixedConeDistanceMetric.DOTPRODUCT);
+ }
+ public void setPredictFunc(double[] coneFunc,double[] cutFunc)
+ {
+ _coneFunc = coneFunc;
+ _cutFunc = cutFunc;
+ _radiusSetFlag = false;
}
-
-/*
public void setRadius(double radius)
{
_radius = radius;
+ _radiusSetFlag = true;
}
public void setSeed(double seed)
{
@@ -93,7 +137,6 @@
{
_minEnergy = minE;
}
- */
/**
* Make clusters from the input map
@@ -110,9 +153,9 @@
{
IDDecoder decoder;
List<Cluster> out = new ArrayList<Cluster>();
+ List<Double> radius = new ArrayList<Double>();
_clusterPropertyCalculator = new FixedConeClusterPropertyCalculator();
- double rsquared = _radius*_radius;
// sort the vector in descending energy for efficiency
// this starts with the highest energy seeds.
Collections.sort(in, new CalorimeterHitEsort());
@@ -120,14 +163,27 @@
int nclus = 0;
int size = in.size();
boolean[] used = new boolean[size];
+
// outer loop finds a seed
for(int i =0; i<size; ++i)
{
if (!used[i])
{
CalorimeterHit p = in.get(i);
- if (p.getCorrectedEnergy()>_seedEnergy)
+ double Eseed = p.getCorrectedEnergy();
+ double clusterCut = 0.0;
+ if(!_radiusSetFlag)
+ clusterCut= _cutFunc[0]*Eseed+_cutFunc[1]*Eseed*Eseed;
+ if (p.getCorrectedEnergy()>_seedEnergy) // hit p as the seed of a new cluster
{
+ if(!_radiusSetFlag)
+ _radius = _coneFunc[0]*Math.log(p.getCorrectedEnergy())+_coneFunc[1];
+ //if predicted radius is less than zero, it won't be thought as a seed
+ if(_radius<0.0)
+ {
+ System.out.println("Engergy = "+p.getCorrectedEnergy()+",Radius = "+_radius);
+ break;}
+ double rsquared = _radius*_radius;
decoder = p.getIDDecoder();
decoder.setID(p.getCellID());
double cellE = p.getCorrectedEnergy();
@@ -145,7 +201,6 @@
for (int j = i+1; j<size; ++j)
{
- // if (in.get(j)!=null)
if(!used[j])
{
CalorimeterHit p2 = in.get(j);
@@ -202,7 +257,7 @@
// if energy of cluster is large enough add it to the list
- if(sum.E()>_minEnergy)
+ if(sum.E()>clusterCut) //_minEnergy)
{
BasicCluster clus = new BasicCluster();
clus.setPropertyCalculator(_clusterPropertyCalculator);
@@ -211,6 +266,7 @@
clus.addHit(hit);
}
out.add(clus);
+ radius.add(_radius);
nclus++;
}
@@ -229,9 +285,9 @@
for(int j=i+1; j<out.size(); ++j)
{
double dTheta = dTheta(out.get(i), out.get(j));
- if (dTheta<2*_radius)
+ if (dTheta<radius.get(i)+radius.get(j))
{
- resolve((BasicCluster) (out.get(i)),(BasicCluster) (out.get(j)));
+ resolve((BasicCluster) (out.get(i)),radius.get(i),(BasicCluster) (out.get(j)),radius.get(j));
}
}
}
@@ -269,7 +325,7 @@
* @param c2 Second Cluster
*/
- public void resolve(BasicCluster c1, BasicCluster c2)
+ public void resolve(BasicCluster c1,double coneR1, BasicCluster c2,double coneR2)
{
// do not recalculate cluster axis until all reshuffling is done
// do not want the cones to shift
@@ -309,10 +365,10 @@
double dtheta2 = theta-theta2;
double R2=dphi2*dphi2+(dtheta2)*(dtheta2);
- if (R2<R1)
+ if (R2/R1<coneR2/coneR1)
{
swap.add(p2);
- }
+ }
}
for(CalorimeterHit h:swap)
{
@@ -342,10 +398,10 @@
double dtheta2 = theta-theta2;
double R2=dphi2*dphi2+(dtheta2)*(dtheta2);
- if (R1<R2)
+ if (R1/R2<coneR1/coneR2)
{
swap.add(p2);
- }
+ }
}
for(CalorimeterHit h:swap)
{
@@ -357,9 +413,9 @@
c2.calculateProperties();
}
-
public String toString()
{
return "FixedConeClusterer with radius "+_radius+" seed Energy "+_seedEnergy+" minimum energy "+_minEnergy+"distance metric "+_dm;
}
-}
+ }
+