Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:04

0001 #ifndef _Cluster1DCleaner_H_
0002 #define _Cluster1DCleaner_H_
0003 
0004 #include "CommonTools/Clustering1D/interface/Cluster1D.h"
0005 
0006 /*
0007  * given a vector<Cluster1D<T> >, erase Cluster1D further away than 
0008  * ZOffeSet from the average position, then 
0009  * recompute the vertex position. The ZOffeSet is taken as 
0010  * an aurgument
0011 */
0012 template <class T>
0013 class Cluster1DCleaner {
0014 public:
0015   Cluster1DCleaner(const float zoffset, bool useErr) : theZOffSet(zoffset), theUseError(useErr) {
0016     theCleanedCluster1Ds.clear();
0017     theDiscardedCluster1Ds.clear();
0018   }
0019   // return the compatible clusters
0020   std::vector<Cluster1D<T> > clusters(const std::vector<Cluster1D<T> >&);
0021   /*
0022        return the vector of discarded Cluster1Ds
0023        it should be called after Cluster1DCleaner::clusters
0024        otherwise return an empty vector
0025     */
0026   std::vector<Cluster1D<T> > discardedCluster1Ds() const { return theDiscardedCluster1Ds; }
0027 
0028 private:
0029   void cleanCluster1Ds(const std::vector<Cluster1D<T> >&);
0030   float average(const std::vector<Cluster1D<T> >&);
0031   std::vector<Cluster1D<T> > theCleanedCluster1Ds;
0032   std::vector<Cluster1D<T> > theDiscardedCluster1Ds;
0033   float theZOffSet;
0034   bool theUseError;
0035 };
0036 
0037 /*
0038  *                                implementation
0039  */
0040 
0041 template <class T>
0042 std::vector<Cluster1D<T> > Cluster1DCleaner<T>::clusters(const std::vector<Cluster1D<T> >& _clust) {
0043   std::vector<Cluster1D<T> > clust = _clust;
0044   cleanCluster1Ds(clust);
0045   return theCleanedCluster1Ds;
0046 }
0047 
0048 template <class T>
0049 void Cluster1DCleaner<T>::cleanCluster1Ds(const std::vector<Cluster1D<T> >& _clust) {
0050   std::vector<Cluster1D<T> > clust = _clust;
0051   theCleanedCluster1Ds.clear();
0052   theDiscardedCluster1Ds.clear();
0053   if (clust.empty())
0054     return;
0055   float oldPos = average(clust);
0056   for (typename std::vector<Cluster1D<T> >::const_iterator ic = clust.begin(); ic != clust.end(); ic++) {
0057     float discr = theUseError ? fabs(((*ic).position().value() - oldPos) / (*ic).position().error())
0058                               : fabs(((*ic).position().value() - oldPos));
0059     if (discr < theZOffSet) {
0060       theCleanedCluster1Ds.push_back(*ic);
0061     } else {
0062       theDiscardedCluster1Ds.push_back(*ic);
0063     }
0064   }
0065   return;
0066 }
0067 
0068 //I could use the Cluster1DMerger...
0069 template <class T>
0070 float Cluster1DCleaner<T>::average(const std::vector<Cluster1D<T> >& clust) {
0071   float ave = clust.front().position().value();
0072   float err = clust.front().position().error();
0073   for (typename std::vector<Cluster1D<T> >::const_iterator ic = (clust.begin()) + 1; ic != clust.end(); ic++) {
0074     float oldave = ave;
0075     float olderr = err;
0076     ave = (oldave / olderr / olderr + ic->position().value() / ic->position().error() / ic->position().error()) /
0077           (1. / olderr / olderr + 1. / ic->position().error() / ic->position().error());
0078     err = sqrt(olderr * olderr + ic->position().error() * ic->position().error());
0079   }
0080   return ave;
0081 }
0082 
0083 #endif