Go to the documentation of this file.00001 #ifndef TrackerStablePhiSort_H
00002 #define TrackerStablePhiSort_H
00003
00004
00005 #include<iostream>
00006
00007 #include <utility>
00008 #include <vector>
00009 #include <algorithm>
00010
00011 #include <cmath>
00012
00013 #include<boost/bind.hpp>
00014
00015 namespace details {
00016 template<typename Object, typename Scalar>
00017 struct PhiSortElement {
00018 typedef PhiSortElement<Object,Scalar> self;
00019
00020 template<typename Extractor>
00021 static self
00022 build(Object & o, Extractor const & extr) {
00023 return self(&o, extr(o));
00024 }
00025
00026 PhiSortElement(){}
00027 PhiSortElement(Object * p, Scalar v):
00028 pointer(p),
00029 value(v) {}
00030
00031 Object * pointer;
00032 Scalar value;
00033
00034 bool operator<(self const & rh) const {
00035 return value<rh.value;
00036 }
00037 Object const &
00038 obj() const { return *pointer;}
00039 };
00040
00041
00042 }
00043
00044 template<typename RandomAccessIterator, typename Extractor>
00045 void TrackerStablePhiSort(RandomAccessIterator begin,
00046 RandomAccessIterator end,
00047 const Extractor& extr) {
00048
00049 typedef typename Extractor::result_type Scalar;
00050 typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
00051
00052 typedef details::PhiSortElement<value_type, Scalar> Element;
00053
00054
00055
00056 std::vector<Element> tmpvec(end-begin);
00057 std::transform(begin,end,tmpvec.begin(),
00058 boost::bind(Element::template build<Extractor>,_1, boost::cref(extr))
00059 );
00060
00061 std::vector<Element> tmpcop(end-begin);
00062
00063 std::sort(tmpvec.begin(), tmpvec.end());
00064
00065 const unsigned int vecSize = tmpvec.size();
00066
00067
00068
00069
00070
00071
00072 const unsigned int nMaxModulesPerRing = 5;
00073 bool phiZeroCase = true;
00074
00075 const double phiMin = M_PI_4;
00076 const double phiMax = 2*M_PI-phiMin;
00077
00078 if( vecSize > nMaxModulesPerRing ) {
00079
00080
00081 double tolerance = 0.000001;
00082 if( fabs(tmpvec.back().value - 0) < tolerance
00083 ||
00084 fabs(tmpvec.back().value - 2*M_PI) < tolerance ) {
00085
00086 tmpvec.insert(tmpvec.begin(),tmpvec.back());
00087 tmpvec.pop_back();
00088 }
00089 }
00090 else {
00091
00092
00093
00094 typename std::vector<Element>::iterator p =
00095 std::find_if(tmpvec.begin(),tmpvec.end(), boost::bind(&Element::value,_1) > phiMin);
00096 phiZeroCase = !(p!=tmpvec.end() && (*p).value<phiMax);
00097
00098
00099 if(phiZeroCase) {
00100
00101
00102 if(p!=tmpvec.end()) {
00103 tmpvec.insert(tmpvec.begin(),p,tmpvec.end());
00104 tmpvec.resize(vecSize);
00105 }
00106 }
00107 }
00108
00109
00110
00111 std::vector<value_type> tmpvecy(vecSize);
00112 std::transform(tmpvec.begin(),tmpvec.end(),tmpvecy.begin(),boost::bind(&Element::obj,_1));
00113 std::copy(tmpvecy.begin(),tmpvecy.end(),begin);
00114
00115 }
00116
00117 #endif
00118