ESyS-Particle  4.0.1
SphereFitter.h
00001 
00002 //                                                         //
00003 // Copyright (c) 2003-2011 by The University of Queensland //
00004 // Earth Systems Science Computational Centre (ESSCC)      //
00005 // http://www.uq.edu.au/esscc                              //
00006 //                                                         //
00007 // Primary Business: Brisbane, Queensland, Australia       //
00008 // Licensed under the Open Software License version 3.0    //
00009 // http://www.opensource.org/licenses/osl-3.0.php          //
00010 //                                                         //
00012 
00013 
00014 #ifndef ESYS_LSMSPHEREFITTER_H
00015 #define ESYS_LSMSPHEREFITTER_H
00016 
00017 #include "Geometry/Sphere3d.h"
00018 #include "Geometry/Sphere2d.h"
00019 #include "Foundation/BoundingSphere.h"
00020 
00021 #include <stdexcept>
00022 #include <sstream>
00023 
00024 namespace esys
00025 {
00026   namespace lsm
00027   {
00028     template <typename TmplFitTraits>
00029     class SphereFitter
00030     {
00031     public:
00032       typedef TmplFitTraits                      FitTraits;
00033       typedef typename FitTraits::Validator      Validator;
00034       typedef typename FitTraits::Particle       Particle;
00035       typedef typename Validator::ParticleVector ParticleVector;
00036       typedef typename FitTraits::Plane          Plane;
00037 
00038       SphereFitter(const std::string &name, Validator &validator)
00039         : m_pValidator(&validator),
00040           m_successfulFitCount(0),
00041           m_getFitCount(0),
00042           m_failedFitCount(0),
00043           m_name(name)
00044       {
00045       }
00046 
00047       virtual ~SphereFitter()
00048       {
00049       }
00050 
00051       virtual Particle getFitParticle(
00052         const Particle &particle,
00053         const ParticleVector &neighbours,
00054         const Plane &plane
00055       ) = 0;
00056 
00057       static Particle getInvalidParticle()
00058       {
00059         return Particle::INVALID;
00060       }
00061 
00062       void incrGetFit()
00063       {
00064         m_getFitCount++;
00065       }
00066 
00067       void incrFailedFit()
00068       {
00069         m_failedFitCount++;
00070       }
00071 
00072       void incrSuccessfulFit()
00073       {
00074         m_successfulFitCount++;
00075       }
00076 
00077       const std::string &getName() const
00078       {
00079         return m_name;
00080       }
00081       
00082       void write(std::ostream &oStream) const
00083       {
00084         oStream
00085           << (getName() + ": ")
00086           << "fit count = " << m_getFitCount
00087           << ", success = " << m_successfulFitCount
00088           << ", fail    = " << m_failedFitCount;
00089       }
00090       
00091       std::string toString() const
00092       {
00093         std::stringstream sStream;
00094         write(sStream);
00095         return sStream.str();
00096       }
00097 
00098       bool particleIsValid(const Particle &particle) const
00099       {
00100         return getValidator().particleIsValid(particle);
00101       }
00102 
00103     protected:
00104       Validator &getValidator()
00105       {
00106         return *m_pValidator;
00107       }
00108 
00109       const Validator &getValidator() const
00110       {
00111         return *m_pValidator;
00112       }
00113     private:
00114       Validator   *m_pValidator;
00115       int         m_successfulFitCount;
00116       int         m_getFitCount;
00117       int         m_failedFitCount;
00118       std::string m_name;
00119     };
00120 
00121     template <typename TmplFitTraits>    
00122     inline std::ostream &operator<<(
00123       std::ostream &oStream,
00124       const SphereFitter<TmplFitTraits> &fitter
00125     )
00126     {
00127       fitter.write(oStream);
00128       return oStream;
00129     }
00130 
00131     template <typename TmplFitTraits>
00132     class MoveToSurfaceFitter : public SphereFitter<TmplFitTraits>
00133     {
00134     public:
00135       typedef SphereFitter<TmplFitTraits>        Inherited;
00136       typedef typename Inherited::Validator      Validator;
00137       typedef typename Inherited::Particle       Particle;
00138       typedef typename Inherited::ParticleVector ParticleVector;
00139       typedef typename Inherited::Plane          Plane;
00140       MoveToSurfaceFitter(Validator &validator)
00141         : Inherited("Mv to Surface", validator)
00142       {
00143       }
00144       
00145       Particle moveToSurface(
00146         const Particle &stationary,
00147         const Particle &movable
00148       )
00149       {
00150         Particle moved = movable;
00151         const Vec3 centreDiff = movable.getPos() - stationary.getPos();
00152         const double centreDist = centreDiff.norm();
00153         if (centreDist > 0.0) {
00154           const Vec3 newCentrePos = 
00155             stationary.getPos()
00156             +
00157             (centreDiff/(centreDist))*(stationary.getRad() + movable.getRad());
00158           moved.moveTo(newCentrePos);
00159         }
00160         return moved;
00161       }
00162       
00163       virtual Particle getFitParticle(
00164         const Particle &particle,
00165         const ParticleVector &neighbours,
00166         const Plane &plane
00167       )
00168       {
00169         this->incrGetFit();
00170         Particle newParticle = particle;
00171         if (neighbours.size() > 0) {
00172           if (
00173             (particle.getPos() - neighbours[0]->getPos()).norm()
00174             <
00175             (particle.getRad() + neighbours[0]->getRad())
00176           ) {
00177             newParticle = moveToSurface(*(neighbours[0]), particle);
00178           }
00179         }
00180         if (newParticle.isValid() && !particleIsValid(newParticle)) {
00181           newParticle = this->getInvalidParticle();
00182           this->incrFailedFit();
00183         } else if (newParticle.isValid()) {
00184           this->incrSuccessfulFit();
00185         }
00186         return newParticle;
00187       }
00188     };
00189 
00190     template <typename TmplFitTraits>
00191     class ThreeDSphereFitter : public SphereFitter<TmplFitTraits>
00192     {
00193     public:
00194       typedef SphereFitter<TmplFitTraits>        Inherited;
00195       typedef typename Inherited::Validator      Validator;
00196       typedef typename Inherited::Particle       Particle;
00197       typedef typename Inherited::ParticleVector ParticleVector;
00198       typedef typename Inherited::Plane          Plane;
00199 
00200       ThreeDSphereFitter(Validator &validator)
00201         : Inherited("    3D Fitter", validator)
00202       {
00203       }
00204 
00205       Particle findAFit(
00206         const Particle& Po,
00207         const ParticleVector &particleVector
00208       )
00209       {
00210         Particle fittedParticle = this->getInvalidParticle();
00211         Vec3 M;
00212         double r;
00213         int id=Po.getID();
00214         
00215         if (particleVector.size() > 3) {
00216           const bool foundFit = 
00217             Sphere3D::FillIn(
00218               particleVector[0]->getPos(),
00219               particleVector[1]->getPos(),
00220               particleVector[2]->getPos(),
00221               particleVector[3]->getPos(),
00222               particleVector[0]->getRad(),
00223               particleVector[1]->getRad(),
00224               particleVector[2]->getRad(),
00225               particleVector[3]->getRad(),
00226               M,
00227               r
00228             );
00229           if (foundFit) {
00230             fittedParticle = Particle(M, r, id);
00231           }  
00232         }  else {
00233           throw std::runtime_error("findAFit: particleVector argument has fewer than 4 elements.");
00234         }
00235         return fittedParticle;
00236       }      
00237       
00238       virtual Particle getFitParticle(
00239         const Particle &particle,
00240         const ParticleVector &neighbours,
00241         const Plane &plane
00242       )
00243       {
00244         this->incrGetFit();
00245         Particle newParticle = this->getInvalidParticle();
00246         if(neighbours.size() > 3){ // at least 4 neighbors 
00247           const Particle &Pi = *(neighbours[0]);
00248           const double ndist=(particle.getPos()-Pi.getPos()).norm();
00249           if (ndist > 0.0) {
00250             newParticle = particle;
00251             if (ndist < Pi.getRad()){ // if Po inside Pi -> move Po to the surface of Pi
00252               newParticle.moveTo(
00253                 Pi.getPos()+((particle.getPos()-Pi.getPos())*(Pi.getRad()/ndist))
00254               );
00255             }
00256             const double dist_p = plane.sep(newParticle.getPos());
00257             const double dist_3 = (newParticle.getPos()-neighbours[3]->getPos()).norm()-neighbours[3]->getRad();
00258             if (dist_p > dist_3) {  // 4th particle closer than plane -> fit 4 particles
00259               newParticle = findAFit(newParticle, neighbours);
00260             }
00261             else {
00262               newParticle = this->getInvalidParticle();
00263             }
00264           }
00265         }
00266         if (newParticle.isValid() && !particleIsValid(newParticle)) {
00267           newParticle = this->getInvalidParticle();
00268           this->incrFailedFit();
00269         } else if (newParticle.isValid()) {
00270           this->incrSuccessfulFit();
00271         }
00272         return newParticle;
00273       }      
00274     };
00275 
00276     template <typename TmplFitTraits>
00277     class TwoDSphereFitter : public SphereFitter<TmplFitTraits>
00278     {
00279     public:
00280       typedef SphereFitter<TmplFitTraits>        Inherited;
00281       typedef typename Inherited::Validator      Validator;
00282       typedef typename Inherited::Particle       Particle;
00283       typedef typename Inherited::ParticleVector ParticleVector;
00284       typedef typename Inherited::Plane          Plane;
00285 
00286       TwoDSphereFitter(Validator &validator)
00287         : Inherited("    2D Fitter", validator)
00288       {
00289       }
00290       
00291       Particle findAFit(
00292         const Particle& Po,
00293         const ParticleVector &particleVector
00294       )
00295       {
00296         Particle fittedParticle = this->getInvalidParticle();
00297         Vec3 M;
00298         double r;
00299         int id=Po.getID();
00300         
00301         if (particleVector.size() > 2) {
00302           const bool foundFit = 
00303             Sphere2D::FillIn(
00304               particleVector[0]->getPos(),
00305               particleVector[1]->getPos(),
00306               particleVector[2]->getPos(),
00307               particleVector[0]->getRad(),
00308               particleVector[1]->getRad(),
00309               particleVector[2]->getRad(),
00310               M,
00311               r
00312             );
00313           if (foundFit) {
00314             fittedParticle = Particle(M, r, id);
00315           }  
00316         }  else {
00317           throw std::runtime_error("findAFit: particleVector argument has fewer than 3 elements.");
00318         }
00319         return fittedParticle;
00320       }
00321 
00322       virtual Particle getFitParticle(
00323         const Particle &particle,
00324         const ParticleVector &neighbours,
00325         const Plane &plane
00326       )
00327       {
00328         this->incrGetFit();
00329         Particle newParticle = this->getInvalidParticle();
00330         if(neighbours.size() > 2){ // at least 3 neighbors
00331           const Particle &Pi = *(neighbours[0]);
00332           const double ndist=(particle.getPos()-Pi.getPos()).norm();
00333           if (ndist > 0.0) {
00334             newParticle = particle;
00335             if (ndist < Pi.getRad()){ // if Po inside Pi -> move Po to the surface of Pi
00336               newParticle.moveTo(
00337                 Pi.getPos()+((particle.getPos()-Pi.getPos())*(Pi.getRad()/ndist))
00338               );
00339             }
00340             const double dist_p = plane.sep(newParticle.getPos());
00341             const double dist_2 = (newParticle.getPos()-neighbours[2]->getPos()).norm()-neighbours[2]->getRad();
00342             if (dist_p > dist_2) {  // 3rd particle closer than plane -> fit 3 particles
00343               newParticle = findAFit(newParticle, neighbours);
00344             }
00345             else {
00346               newParticle = this->getInvalidParticle();
00347             }
00348           }
00349         }
00350         if (newParticle.isValid() && !particleIsValid(newParticle)) {
00351           newParticle = this->getInvalidParticle();
00352           this->incrFailedFit();
00353         } else if (newParticle.isValid()) {
00354           this->incrSuccessfulFit();
00355         }
00356         return newParticle;
00357       }      
00358     };
00359 
00360     template <typename TmplFitTraits>
00361     class TwoDSphereSphereFitter : public SphereFitter<TmplFitTraits>
00362     {
00363     public:
00364       typedef SphereFitter<TmplFitTraits>        Inherited;
00365       typedef typename Inherited::Validator      Validator;
00366       typedef typename Inherited::Particle       Particle;
00367       typedef typename Inherited::ParticleVector ParticleVector;
00368       typedef typename Inherited::Plane          Plane;
00369 
00370       TwoDSphereSphereFitter(
00371         Validator &validator,
00372         const BoundingSphere &sphere
00373       )
00374         : Inherited(" 2D Sph Fitter", validator),
00375           m_sphere(sphere)
00376       {
00377       }
00378       
00379       Particle findAFit(
00380         const Particle& Po,
00381         const ParticleVector &particleVector
00382       )
00383       {
00384         Particle fittedParticle = this->getInvalidParticle();
00385         Vec3 M;
00386         double r;
00387         int id=Po.getID();
00388         
00389         if (particleVector.size() >= 2) {
00390           const bool foundFit = 
00391             Sphere2D::FillIn(
00392               m_sphere.getCentre(),
00393               particleVector[0]->getPos(),
00394               particleVector[1]->getPos(),
00395               -m_sphere.getRadius(),
00396               particleVector[0]->getRad(),
00397               particleVector[1]->getRad(),
00398               M,
00399               r
00400             );
00401           if (foundFit) {
00402             fittedParticle = Particle(M, r, id);
00403           }
00404         }  else {
00405           throw std::runtime_error(
00406             "TwoDSphereSphereFitter::findAFit: particleVector "
00407             "argument has fewer than 2 elements."
00408           );
00409         }
00410         return fittedParticle;
00411       }
00412 
00413       virtual Particle getFitParticle(
00414         const Particle &particle,
00415         const ParticleVector &neighbours,
00416         const Plane &plane
00417       )
00418       {
00419         this->incrGetFit();
00420         Particle newParticle = this->getInvalidParticle();
00421         if (neighbours.size() >= 2) { // 2 neighbours: try  2 particles + bounding-sphere
00422           const Particle &Pi = *(neighbours[0]);
00423           const double ndist=(particle.getPos()-Pi.getPos()).norm();
00424           if (
00425             (ndist > 0.0)
00426             && 
00427             (
00428               (neighbours.size() == 2)
00429               ||
00430               (
00431                 fabs((m_sphere.getCentre()-particle.getPos()).norm()-m_sphere.getRadius())
00432                 <
00433                 (particle.getPos()-neighbours[2]->getPos()).norm()-neighbours[2]->getRad()
00434               )
00435             )
00436           ) {
00437             newParticle = particle;
00438             if (ndist < Pi.getRad()) { // if Po inside Pi -> move Po to the surface of Pi
00439               newParticle.moveTo(
00440                 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
00441               );
00442             }
00443             newParticle = findAFit(newParticle, neighbours);
00444           }
00445         }
00446         if (newParticle.isValid() && !particleIsValid(newParticle)) {
00447           newParticle = this->getInvalidParticle();
00448           this->incrFailedFit();
00449         } else if (newParticle.isValid()) {
00450           this->incrSuccessfulFit();
00451         }
00452         return newParticle;
00453       }
00454 
00455     private:
00456       BoundingSphere m_sphere;
00457     };
00458 
00459     template <typename TmplFitTraits>
00460     class ThreeDSphereSphereFitter : public SphereFitter<TmplFitTraits>
00461     {
00462     public:
00463       typedef SphereFitter<TmplFitTraits>        Inherited;
00464       typedef typename Inherited::Validator      Validator;
00465       typedef typename Inherited::Particle       Particle;
00466       typedef typename Inherited::ParticleVector ParticleVector;
00467       typedef typename Inherited::Plane          Plane;
00468 
00469       ThreeDSphereSphereFitter(
00470         Validator &validator,
00471         const BoundingSphere &sphere
00472       )
00473         : Inherited(" 3D Sph Fitter", validator),
00474           m_sphere(sphere)
00475       {
00476       }
00477       
00478       Particle findAFit(
00479         const Particle& Po,
00480         const ParticleVector &particleVector
00481       )
00482       {
00483         Particle fittedParticle = this->getInvalidParticle();
00484         Vec3 M;
00485         double r;
00486         int id=Po.getID();
00487         
00488         if (particleVector.size() > 2) {
00489           const bool foundFit = 
00490             Sphere3D::FillIn(
00491               m_sphere.getCentre(),
00492               particleVector[0]->getPos(),
00493               particleVector[1]->getPos(),
00494               particleVector[2]->getPos(),
00495               -m_sphere.getRadius(),
00496               particleVector[0]->getRad(),
00497               particleVector[1]->getRad(),
00498               particleVector[2]->getRad(),
00499               M,
00500               r
00501             );
00502           if (foundFit) {
00503             fittedParticle = Particle(M, r, id);
00504           }
00505         } else {
00506           throw
00507             std::runtime_error(
00508               "ThreeDSphereSphereFitter::findAFit: particleVector argument"
00509               " has fewer than 3 elements."
00510             );
00511         }
00512         return fittedParticle;
00513       }
00514 
00515       virtual Particle getFitParticle(
00516         const Particle &particle,
00517         const ParticleVector &neighbours,
00518         const Plane &plane
00519       )
00520       {
00521         this->incrGetFit();
00522         Particle newParticle = this->getInvalidParticle();
00523         if (neighbours.size() >= 3) { // 3 neighbours: try  3 particles + bounding-sphere
00524           const Particle &Pi = *(neighbours[0]);
00525           const double ndist=(particle.getPos()-Pi.getPos()).norm();
00526           if (
00527             (ndist > 0.0)
00528             && 
00529             (
00530               (neighbours.size() == 3)
00531               ||
00532               (
00533                 fabs((m_sphere.getCentre()-particle.getPos()).norm()-m_sphere.getRadius())
00534                 <
00535                 (particle.getPos()-neighbours[3]->getPos()).norm()-neighbours[3]->getRad()
00536               )
00537             )
00538           ) {
00539             newParticle = particle;
00540             if (ndist < Pi.getRad()) { // if Po inside Pi -> move Po to the surface of Pi
00541               newParticle.moveTo(
00542                 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
00543               );
00544             }
00545             newParticle = findAFit(newParticle, neighbours);
00546           }
00547         }
00548         if (newParticle.isValid() && !particleIsValid(newParticle)) {
00549           newParticle = this->getInvalidParticle();
00550           this->incrFailedFit();
00551         } else if (newParticle.isValid()) {
00552           this->incrSuccessfulFit();
00553         }
00554         return newParticle;
00555       }
00556 
00557     private:
00558       BoundingSphere m_sphere;
00559     };
00560 
00561     template <typename TmplFitTraits>
00562     class TwoDPlaneSphereFitter : public SphereFitter<TmplFitTraits>
00563     {
00564     public:
00565       typedef SphereFitter<TmplFitTraits>        Inherited;
00566       typedef typename Inherited::Validator      Validator;
00567       typedef typename Inherited::Particle       Particle;
00568       typedef typename Inherited::ParticleVector ParticleVector;
00569       typedef typename Inherited::Plane          Plane;
00570 
00571       TwoDPlaneSphereFitter(Validator &validator)
00572         : Inherited("     2D Plane", validator)
00573       {
00574       }
00575 
00576       Particle findAFit(
00577         const Particle& particle,
00578         const ParticleVector &particleVector,
00579         const Plane& plane
00580       )
00581       {
00582         Particle fittedParticle = this->getInvalidParticle();
00583         Vec3 M;
00584         double r;
00585         const int id = particle.getID();
00586   
00587         if (particleVector.size() > 1) {
00588           const bool foundFit =
00589             Sphere2D::FillInWP(
00590               particleVector[0]->getPos(),
00591               particleVector[1]->getPos(),
00592               plane.GetO(),
00593               plane.GetW(),
00594               particleVector[0]->getRad(),
00595               particleVector[1]->getRad(),
00596               M,
00597               r
00598           );
00599           if (foundFit) {
00600             fittedParticle = Particle(M, r, id);
00601           }
00602         } else {
00603           throw std::runtime_error("findAFit: particleVector vector contains less than 2 particles.");
00604         }
00605   
00606         return fittedParticle;   
00607       }
00608 
00609       virtual Particle getFitParticle(
00610         const Particle &particle,
00611         const ParticleVector &neighbours,
00612         const Plane &plane
00613       )
00614       {
00615         this->incrGetFit();
00616         Particle newParticle = this->getInvalidParticle();
00617         if (neighbours.size() >= 2) { // 2 neighbors  -> try  2 particles + plane
00618           const Particle &Pi = *(neighbours[0]);
00619           const double ndist=(particle.getPos()-Pi.getPos()).norm();
00620           if (
00621             (ndist > 0.0)
00622             && 
00623             (
00624               (neighbours.size() == 2)
00625               ||
00626               (
00627                 plane.sep(particle.getPos())
00628                 <
00629                 (particle.getPos()-neighbours[2]->getPos()).norm()-neighbours[2]->getRad()
00630               )
00631             )
00632           ) {
00633             newParticle = particle;
00634             if (ndist < Pi.getRad()) { // if Po inside Pi -> move Po to the surface of Pi
00635               newParticle.moveTo(
00636                 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
00637               );
00638             }
00639             newParticle = findAFit(newParticle, neighbours, plane);
00640           }
00641         }
00642         if (newParticle.isValid() && !particleIsValid(newParticle)) {
00643           newParticle = this->getInvalidParticle();
00644           this->incrFailedFit();
00645         } else if (newParticle.isValid()) {
00646           this->incrSuccessfulFit();
00647         }
00648         return newParticle;
00649       }
00650     };
00651 
00652     template <typename TmplFitTraits>
00653     class ThreeDPlaneSphereFitter : public SphereFitter<TmplFitTraits>
00654     {
00655     public:
00656       typedef SphereFitter<TmplFitTraits>        Inherited;
00657       typedef typename Inherited::Validator      Validator;
00658       typedef typename Inherited::Particle       Particle;
00659       typedef typename Inherited::ParticleVector ParticleVector;
00660       typedef typename Inherited::Plane          Plane;
00661 
00662       ThreeDPlaneSphereFitter(Validator &validator)
00663         : Inherited("     3D Plane", validator)
00664       {
00665       }
00666 
00667       Particle findAFit(
00668         const Particle& particle,
00669         const ParticleVector &particleVector,
00670         const Plane& plane
00671       )
00672       {
00673         Particle fittedParticle = this->getInvalidParticle();
00674         Vec3 M;
00675         double r;
00676         const int id = particle.getID();
00677   
00678         if (particleVector.size() > 2) {
00679           const bool foundFit =
00680             Sphere3D::FillInWP(
00681               particleVector[0]->getPos(),
00682               particleVector[1]->getPos(),
00683               particleVector[2]->getPos(),
00684               plane.GetO(),
00685               plane.GetW(),
00686               particleVector[0]->getRad(),
00687               particleVector[1]->getRad(),
00688               particleVector[2]->getRad(),
00689               M,
00690               r
00691           );
00692           if (foundFit) {          
00693             fittedParticle = Particle(M, r, id);
00694           }
00695         } else {
00696           throw std::runtime_error("findAFit: particleVector vector contains less than 3 particles.");
00697         }
00698   
00699         return fittedParticle;   
00700       }
00701 
00702       virtual Particle getFitParticle(
00703         const Particle &particle,
00704         const ParticleVector &neighbours,
00705         const Plane &plane
00706       )
00707       {
00708         this->incrGetFit();
00709         Particle newParticle = this->getInvalidParticle();
00710         if (neighbours.size() >= 3) { // 3 neighbors  -> try  3 particles + plane
00711           const Particle &Pi = *(neighbours[0]);
00712           const double ndist=(particle.getPos()-Pi.getPos()).norm();
00713           if (
00714             (ndist > 0.0)
00715             && 
00716             (
00717               (neighbours.size() == 3)
00718               || 
00719               (
00720                 plane.sep(particle.getPos())
00721                 <
00722                 (particle.getPos()-neighbours[3]->getPos()).norm()-neighbours[3]->getRad()
00723               )
00724             )
00725           ) {
00726             newParticle = particle;
00727             if (ndist < Pi.getRad()) { // if Po inside Pi -> move Po to the surface of Pi
00728               newParticle.moveTo(
00729                 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
00730               );
00731             }
00732             newParticle = findAFit(newParticle, neighbours, plane);
00733           }
00734         }
00735         if (newParticle.isValid() && !particleIsValid(newParticle)) {
00736           newParticle = this->getInvalidParticle();
00737           this->incrFailedFit();
00738         } else if (newParticle.isValid()) {
00739           this->incrSuccessfulFit();
00740         }
00741         return newParticle;
00742       }
00743     };
00744   };
00745 };
00746 
00747 #include "Geometry/SphereFitter.hpp"
00748 
00749 #endif