CrossMatch.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 CSIRO ICT Centre
00003  *
00004  * $Id: CrossMatch.cpp 1192 2005-09-20 15:21:27Z rsc $
00005  */
00006 
00007 #include "ActiveList.h"
00008 #include "CrossMatch.h"
00009 #include "Object.h"
00010 #include "ObjectConsumer.h"
00011 #include "ObjectPairConsumer.h"
00012 #include "ObjectProducer.h"
00013 #include "Profiler.h"
00014 #include "Matcher.h"
00015 
00016 
00017 String const CrossMatch::s_name("Cross Match");
00018 
00019 
00020 CrossMatch::CrossMatch(ObjectProducer * activeProd,
00021                        ObjectProducer * testProd,
00022                        ActiveList * aList,
00023                        ObjectPairConsumer * pairCons,
00024                        ObjectConsumer * uActiveCons,
00025                        ObjectConsumer * uTestCons)
00026     : Matcher(pairCons, true),
00027       activeProducer(activeProd),
00028       testProducer(testProd),
00029       uActiveConsumer(uActiveCons),
00030       uTestConsumer(uTestCons),
00031       activeList(aList)
00032 {
00033 }
00034 
00035 CrossMatch::~CrossMatch()
00036 {
00037   delete activeProducer;
00038   delete testProducer;
00039   delete activeList;
00040 }
00041 
00042 void CrossMatch::getReady()
00043 {
00044   Matcher::getReady();
00045 
00046 #ifdef PROFILE
00047 #ifdef PROFILE_ACTIVE_LIST
00048   activeList->setProfiler(profiler);
00049 #endif // PROFILE_ACTIVE_LIST
00050 #endif // PROFILE
00051 }
00052 
00053 void CrossMatch::finished()
00054 {
00055   /* tell the active list that we're finished, so that the active list
00056      can clean up any remaining objects, report them matched or unmatched
00057      as the case may be, and trigger completion of downstream refines. */
00058 
00059   activeList->finished(uActiveConsumer);
00060 
00061   uActiveConsumer->finished();
00062   uTestConsumer->finished();
00063 
00064   Matcher::finished();
00065 }
00066 
00067 /*
00068  * A faster filter for cross matching.
00069  */
00070 
00071 void CrossMatch::doFilter()
00072 {
00073   double lowerBound = 0.0;
00074   double upperBound = 0.0;
00075 
00076   Object const * activeObject = nextActiveObject();
00077   Object const * testObject = nextTestObject();
00078 
00079   if (testObject != 0)
00080   {
00081     lowerBound = getLowerBound(testObject);
00082     upperBound = getUpperBound(testObject);
00083   }
00084 
00085   while (testObject != 0)
00086   {
00087     if (activeObject == 0 && activeList->isEmpty())
00088     {
00089       /* There's nothing left to test our objects against. */
00090       raceThroughProducer(testProducer, testObject, uTestConsumer);
00091       break;
00092     }
00093 
00094     if (activeObject == 0)           // that the activeList isn't empty (see above test)
00095     {
00096       test(testObject, lowerBound, upperBound);
00097     }
00098     else
00099     {
00100       /* Both object producers have more objects to offer.  We need to
00101        * decide which object to handle next.
00102        */
00103       if (activeObject->getDec() <= upperBound)
00104       {
00105         /* The next active object could match the current test object.
00106          * Handle it first. */
00107         if (activeObject->getDec() >= lowerBound)
00108         {
00109           /* The next test object is reasonably close, so it is possible
00110            * for this active object to match something.
00111            * Add it to the active list.
00112            */
00113           activeList->pushBack(activeObject);
00114           activeObject = nextActiveObject();
00115         }
00116         else
00117         {
00118           /* The next test object is too far ahead.
00119            * The next active object cannot match anything, and the objects
00120            * currently in the active list cannot further match anything.
00121            * So lets clean up the active list, and then race through the
00122            * active objects until we reach a object that can match.
00123            */
00124 
00125           /* Empty the active list.  The active list will report its
00126            * objects as matched or unmatched as the case may be.
00127            */
00128           activeList->clear(uActiveConsumer);
00129 
00130           /* Now race through the active objects until we reach a object
00131            * that can match.
00132            */
00133           activeObject = raceThroughProducer(activeProducer, activeObject, lowerBound, uActiveConsumer);
00134         }
00135       }
00136       else
00137       {
00138         /* The next active object is too far ahead.
00139          * Handle the next test object first */
00140         test(testObject, lowerBound, upperBound);
00141       }
00142     }
00143   }
00144 
00145   flushActiveObjects(activeObject);
00146 }
00147 
00148 double CrossMatch::getLowerBound(Object const * testObject)
00149 {
00150   return testObject->getDec() -
00151          Object::computeDistanceBound(testProducer->getMaxSD(),
00152                                       activeProducer->getMaxSD());
00153 }
00154 
00155 double CrossMatch::getUpperBound(Object const * testObject)
00156 {
00157   return testObject->getDec() +
00158          Object::computeDistanceBound(testObject->getSD(),
00159                                       activeProducer->getMaxSD());
00160 }
00161 
00162 void CrossMatch::test(Object const * & testObject,
00163                       double & lowerBound,
00164                       double & upperBound)
00165 {
00166   /* delete those objects in the active list that cannot match this
00167    * or any subsequent test object. */
00168   activeList->deletePriorObjects(lowerBound, uActiveConsumer);
00169 
00170   test(testObject);
00171 
00172   // ready the next test object
00173   testObject = nextTestObject();
00174   if (testObject != 0)
00175   {
00176     lowerBound = getLowerBound(testObject);
00177     upperBound = getUpperBound(testObject);
00178   }
00179 }
00180 
00181 double CrossMatch::setAngularUpperLimit(Object const * testObject) const
00182 {
00183   return Object::computeDistanceBound(testObject->getSD(),
00184                                       activeProducer->getMaxSD());
00185 }
00186 
00187 void CrossMatch::test(Object const * testObject)
00188 {
00189   /* test this object against the active list.  This call causes
00190    * deletion of the test object, so there's no need to clean up. */
00191 
00192   // compute an upper bound on the angular distance away of a matching object
00193   double upperLimitOnDistance = setAngularUpperLimit(testObject);
00194 
00195   if (!activeList->testObject(testObject, upperLimitOnDistance, pairCons))
00196   {
00197     uTestConsumer->report(testObject);
00198   }
00199 
00200   delete testObject;
00201 }
00202 
00203 void CrossMatch::flushActiveObjects(double lowerBound)
00204 {
00205   activeList->deletePriorObjects(lowerBound, uActiveConsumer);
00206 }
00207 
00208 void CrossMatch::flushActiveObjects(Object const * activeObject)
00209 {
00210   /* Clear the active list. */
00211   activeList->clear(uActiveConsumer);
00212 
00213   raceThroughProducer(activeProducer, activeObject, uActiveConsumer);
00214 }
00215 
00216 void CrossMatch::raceThroughProducer(ObjectProducer * producer,
00217                                      Object const * currentObject,
00218                                      ObjectConsumer * uCons)
00219 {
00220   while (currentObject != 0)
00221   {
00222     currentObject = reportUnmatchedObject(producer, currentObject, uCons);
00223   }
00224 }
00225 
00226 Object const * CrossMatch::raceThroughProducer(ObjectProducer * producer,
00227                                                Object const * currentObject,
00228                                                double limit,
00229                                                ObjectConsumer * uCons)
00230 {
00231   while ((currentObject != 0) && (currentObject->getDec() < limit))
00232   {
00233     currentObject = reportUnmatchedObject(producer, currentObject, uCons);
00234   }
00235 
00236   return currentObject;
00237 }
00238 
00239 Object const * CrossMatch::reportUnmatchedObject(ObjectProducer * producer,
00240                                                  Object const * currentObject,
00241                                                  ObjectConsumer * uCons)
00242 {
00243   uCons->report(currentObject);
00244   delete currentObject;
00245 
00246   return nextObject(producer);
00247 }
Generated on Mon Oct 4 10:39:55 2010 for Matching.kdevelop by  doxygen 1.6.3