Commit ecc253b5 authored by Tyler Wilson's avatar Tyler Wilson
Browse files

Added Strategy class to base/objs. Ref #2408

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@6582 41f8697f-d340-4b68-9986-7bafba869bb8
parent cdb552dd
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
ifeq ($(ISISROOT), $(BLANK))
.SILENT:
error:
echo "Please set ISISROOT";
else
include $(ISISROOT)/make/isismake.objs
    GEOSLIB += -lgeos_c
endif
+1130 −0

File added.

Preview size limit exceeded, changes collapsed.

+276 −0
Original line number Diff line number Diff line
#ifndef Strategy_h
#define Strategy_h
/**
 * @file                                                                  
 * $Revision: 6513 $ 
 * $Date: 2016-01-14 16:04:44 -0700 (Thu, 14 Jan 2016) $ 
 * $Id: Strategy.h 6513 2016-01-14 23:04:44Z kbecker@GS.DOI.NET $
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are
 *   public domain. See individual third-party library and package descriptions
 *   for intellectual property information, user agreements, and related
 *   information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or
 *   implied, is made by the USGS as to the accuracy and functioning of such
 *   software and related material nor shall the fact of distribution
 *   constitute any such warranty, and no responsibility is assumed by the
 *   USGS in connection therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
 *   in a browser or see the Privacy & Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */

// Qt library
#include <QList>
#include <QPair>
#include <QScopedPointer>
#include <QSharedPointer>
#include <QString>

// SharedResource and ResourceList typedefs
#include "Resource.h"
#include "PvlObject.h"

class QStringList;

namespace Isis {

  class GisGeometry;
  class Progress;
//  class PvlObject;

  /**
   * @brief Strategy - Supports algorithm development Planning 
   *        Resource.
   *  
   * This base class provides a framework to develop strategic 
   * planning tools used to process and/or rank ISIS resources. 
   *  
   * The ISIS resource can be cubes, PVLs (e.g., PDS/EDRs, etc), 
   * CSV files or virtually any other resource type simply by 
   * adding support in the Resources type class.
   *  
   * This default implementation is simply a LessThan function for real data types
   * - likely on to the more heavily used function evaluators. 
   *  
   * The Users may provide values for the following influential keywords in the 
   * Pvl Stategy configuration: 
   *  
   * @code 
   * Object = Strategy 
   *   Name = Emission
   *   Type = Calculator
   *   Equation = "((EmissionAngle > 20) && (EmissionAngle < 80))"
   *   Result = EmissionCriteria
   * EndObject 
   * @endcode 
   *  
   * @author 2012-07-15 Kris Becker 
   * @internal 
   *   @history 2012-07-15 Kris Becker - Original version.
   *   @history 2015-03-18 Jeannie Backer - Brought class files closer to ISIS coding standards.
   *   @history 2015-04-07 Kristin Berry - Modified applytoIntserectedGeometry to deal
   *   @history 2015-03-26 Jeannie Backer - Updated documentation.
   *   @history 2015-03-28 Kris Becker - Added the composite(Resource, Resource)
   *                          method
   *   @history 2015-04-30 Kris Becker - Added setName() and setType() methods
   *   @history 2015-05-08 Kris Becker - Added new methods to provide better
   *                          support for keyword argument replacement with
   *                          global parameters: getGlobalDefaults(),
   *                          getGlobals(), getDefinition() and
   *                          getDefinitionMap(). Removed virtual designation
   *                          for apply() methods that do not take a globals
   *                          resource list.
   *  @history 2015-06-17 Kris Becker - Added ability for users to simplify
   *                          geometry such that topology is preserved. Keywords
   *                          that provide numbers of original points, points in
   *                          geoemtry size and tolerance used can optionally be
   *                          created in Resources that apply this feature.
   *  @history 2015-09-27 Kris Becker - Added copyList() and cloneList()
   *                          methods.
   *  @history 2015-10-12 Kris Becker - Fixed bug in how arguments are scanned
   *                          and replaced. Once the count of arguments reached
   *                          above 9, %1 was replaced for %10. Scan for
   *                          replacements in reverse order fixes this issue.
   *  
   *  
   *   @todo Test coverage - Unable to test constructors Strategy(),
   *         Strategy(name,type,globals) as a support class for isisminer.
   *  
   *   NOTE: Some of the following may be taken care of when we finish testing strategies.
   *   @todo Test coverge - Never called methods: resetProcessed(),
   *         assetResourceList(), propagateKeys(), activeList(),
   *         activateList(), deactivateList(), applyToIntersectedGeometry(),
   *         queryCallback()
   *  
   *   @todo Test coverage - empty resource list - apply(), countActive(),
   *         processArgs(), propagateKeys(), activateList(), deactivateList(),
   *         applyToIntersectedGeometry()
   *  
   *   @todo Test coverage - applyDiscarded=t - apply() 
   *  
   *   @todo Test coverage - keyBase+"Keyword" exists in PVL def - (1) keyBase
   *         exists, (2) keyBase DNE -  translateKeywordArgs()
   *  
   *   @todo Test coverage - def file has GisGeometryRef, GisGeometryKey,
   *         GisGeometryArgs, RemoveGisKeywordAfterImport - importGeometry()
   *  
   */
  class Strategy {
  
    public:
      Strategy();
      Strategy(const PvlObject &definition, const ResourceList &globals);
      virtual ~Strategy();
  
      QString name() const;
      QString type() const;
      QString description() const;
  
      // Not intended to be reimplemnented but available for direct calls
      int apply(ResourceList &resources);
      int apply(SharedResource &resource);

      // Inheriting strategies must reimplement either one  or both of these
      virtual int apply(ResourceList &resources, const ResourceList &globals);
      virtual int apply(SharedResource &resource, const ResourceList &globals);
  
      unsigned int totalProcessed() const;
  
   protected:
     //! Definition for a SharedPvlObject, a shared pointer to a PvlObject 
     typedef QSharedPointer<PvlObject> SharedPvlObject;
  
     // For default constructions
     Strategy(const QString &name, const QString &type);

     void setName(const QString &name);
     void setType(const QString &type);

     ResourceList getGlobalDefaults() const;
     ResourceList getGlobals(SharedResource &myGlobals, 
                             const ResourceList &globals) const;
     const PvlObject &getDefinition() const;
     PvlFlatMap getDefinitionMap() const;

  
     void setApplyToDiscarded();
     bool isApplyToDiscarded() const;
     void setDoNotApplyToDiscarded();  // default
  
     int applyToResources(ResourceList &resources, const ResourceList &globals);
     unsigned int processed();
     void resetProcessed();
  
     int countActive(const ResourceList &resources) const;
     int countDiscarded(const ResourceList &resources) const;
     ResourceList assetResourceList(const SharedResource &resource, 
                                       const QString &name) const;
  
     QString findReplacement(const QString &target, const ResourceList &globals,
                             const int &index = 0, 
                             const QString &defValue = "") const;
     QStringList qualifiers(const QString &keyspec, 
                               const QString &delimiter = "::") const;
     QString scanAndReplace(const QString &input, const QString &target, 
                            const QString &replacement) const;
     QString translateKeywordArgs(const QString &value,
                                  const ResourceList &globals,
                                  const QString &defValue = "") const; 
     QString processArgs(const QString &value, const QStringList &argKeys,
                         const ResourceList &globals,
                         const QString &defValue = "") const;
  
     void propagateKeys(SharedResource &source, SharedResource &target) const;
     SharedResource composite(SharedResource &resourceA, SharedResource &resourceB,
                              const QPair<QString, QString> &keySuffix = qMakePair(QString("A"),QString("B"))) 
                              const;
     bool importGeometry(SharedResource &resource, 
                         const ResourceList &globals) const;
  
     ResourceList activeList(ResourceList &resources) const;
     void activateList(ResourceList &resources) const;
     void deactivateList(ResourceList &resources) const;
     ResourceList copyList(const ResourceList &resources) const;
     ResourceList cloneList(const ResourceList &resources,
                            const bool &withAssets = false) const;

     int applyToIntersectedGeometry(ResourceList &resources, GisGeometry &geom,
                                    const ResourceList &globals);
     bool isDebug() const;

     bool doShowProgress() const;
     bool initProgress(const int &nsteps = 0, const QString &text = "");

     static void queryCallback(void *item, void *userdata);

     QStringList getObjectList(const PvlObject &object) const;

     template <class STRATEGYLIST, class STRATEGYFACTORY> 
       STRATEGYLIST LoadMinerStrategies(const QString &minerName, 
                                        const ResourceList &globals) const {
         STRATEGYFACTORY *factory = STRATEGYFACTORY::instance();

         STRATEGYLIST miner;
         QString config = translateKeywordArgs(minerName+"ConfigFile", globals);
         if ( !config.isEmpty() ) {
           miner = factory->buildRun(config, globals);
         }
         else if ( getDefinition().hasObject(minerName+"Miner") ) {
           miner = factory->buildRun(getDefinition().findObject(minerName+"Miner"), 
                                                globals);
       }
       
       return (miner);
     }

  private:
     ResourceList   m_globals;    /**< A shared pointer to the global Resource of keywords. 
                                        If not provided upon construction, it will be set to NULL.
                                        If a SharedResource is passed into the apply() method, 
                                        this member is temporarily set to the given SharedResource
                                        and then restored.  The apply() method can not be used as a 
                                        mutator for this variable.*/
     SharedPvlObject m_definition; /**< A shared pointer to the PvlObject that defines the strategy.
                                        If a definition PvlObject is not passed in on construction,
                                        then a pointer to an empty PvlObject is created using the
                                        strategy name. See class documentation for an example.*/

      QString      m_name;           /**< A string containing the name of the strategy. This name is
                                          passed into the constructor directly or found in the 
                                          Pvl definition object. If none is provided, the default
                                          name 'Strategy' is set.*/
      QString      m_type;           /**< A string containing the type of strategy. This type is
                                          passed into the constructor directly or found in the 
                                          Pvl definition object. If none is provided, the default
                                          type 'Counter' is set.*/
      unsigned int m_total;          /**< The total number of resources processed. This value is 
                                          initialized to zero, incremented by the applyToResources()
                                          or processed() methods, and can be reset to zero by
                                          calling resetProcessed().*/ 
      bool         m_applyDiscarded; /**< Indicates whether to apply strategy to discarded 
                                          resources.This value is initialized to false if not found
                                          in the Pvl definition object.*/
      bool         m_debug;          /**< Indicates whether to print debug messages. This value is
                                          initialized to false if not found in the Pvl definition
                                          object.*/
      QScopedPointer<Progress> m_progress; //!< Progress percentage monitor
  
  };
  
  //! Definition for a SharedStrategy, a shared pointer to a Strategy
  typedef QSharedPointer<Strategy> SharedStrategy;
  
  //! Definition for a StrategyList, a list of SharedStrategy types
  typedef QList<SharedStrategy> StrategyList;

} // Namespace Isis

Q_DECLARE_METATYPE(Isis::SharedStrategy);

#endif
+247 −0
Original line number Diff line number Diff line
Testing default constructor:   

Creating empty strategy: 
Name:          "Strategy" 
Type:          "Counter" 
Description:   "Strategy::Strategy is running a Counter algorithm." 
Testing constructors: 

Testing Strategy(const PvlObject &def,const ResourceList &globals) constructor: 
"**PROGRAMMER ERROR** Keyword Name does not exist!." 
"Elven Dictionary" 

"strat4" 

Name:          "Derived Strategy Name" 
Type:          "Derived Strategy Type" 
Testing getGlobalDefaults:   

Elven Word List 1
Elven Word List 2
************************************************ 


Testing getGlobals:   

Elven Word List 3
Elven Word List 1
Elven Word List 2
************************************************ 


Testing getDefinition:   

"Elven Dictionary" 

************************************************ 


Testing getDefinitionMap:   

	ApplyToDiscarded = false
	Debug = true
	Name = "Elven Dictionary"
	Type = Dictionary
************************************************ 


Testing setApplyToDiscarded(), isApplytToDiscarded(), setDoNotApplyToDiscarded() 

isApplyToDiscarded =  
false 

Testing setApplyToDiscarded:   

isApplyToDiscarded =  
true 

Testing setDoNotApplyToDiscarded:   

isApplyToDiscarded =  
false 

************************************************ 


Testing applyToResources(....) 

Number of resources processed =  2 

************************************************ 


************************************************ 


Testing processed/resetProcessed:   

Processed =  3 

Resetting Processed:   

Processed =  1 

************************************************ 


Testing countActive/countDiscard:   

Active Resources in lstA: 2 

Discarded Resources in lstA: 0 

************************************************ 

Testing findReplacement:   

Empty apply is called...
Empty apply is called...
Elven Word List 3
Elven Word List 1
Elven Word List 2
Searching for elvish word for demon (with default args):  balrog
Searching for value not in the ResourceList:  
Could not find fluffy bunny
************************************************ 

Testing qualifiers (more elvish words):   

Aaye
Aelin
Adan
Adanedhel
Aduial
Aglarond

Testing qualifiers with default delimiter (::):   

Aaye
Aelin
Adan
Adanedhel
Aduial
Aglarond
************************************************ 

Testing scanAndReplace:   

Original sentence:  Balrogs require much fnord love and fnord attention.
Fixed sentence:  Balrogs require much  love and  attention.
************************************************ 

Testing translateKeywordArgs:   

blah
************************************************ 

Testing processArgs:   

balrog
************************************************ 

Testing propagateKeys:   

	daisy = eirien
	Identity = "Elven Word List 3"
	pipe-weed = galena
	Sun = Anor
	daisy = eirien
	Identity = "Elven Word List 3"
	pipe-weed = galena
	Sun = Anor
************************************************ 

Testing activeList 

Elven Word List 3
Elven Word List 1
Elven Word List 2
Number of active resources =  3 

************************************************ 

Testing deactivateList 

Number of active resources =  0 

************************************************ 

Testing activateList 

Number of active resources =  3 

************************************************ 

Testing copyList (globals -> l5) 

Elven Word List 3
Elven Word List 1
Elven Word List 2
Decativating l5 Resources (global resources are active) 

Number of active resources in l5 =  0 

Number of active resources in global =  3 

************************************************ 

Testing cloneList (globals -> l6) 

Elven Word List 3
Elven Word List 1
Elven Word List 2
************************************************ 

Testing applyToIntersectedGeometry 

************************************************ 

Testing isDebug(): 

isDebug() =  true 

************************************************ 

Testing doShowProgress(): 

doShowProgress() =  false 

************************************************ 

Testing initProgress(): 

Calling with no args, initProgress =   false 

Calling:  initProgress(2,"some text") =  false 

************************************************ 

Testing composite(...): 

"Elven Word List 1_Elven Word List 3" 

************************************************ 

Testing importGeometry(...): 

importGeometry =  
true 

************************************************ 

getObjectList:   

************************************************ 

getObjectList:   

"O1" 

"O2" 

"O3" 

Testing applyToIntersected Geometry  
"**PROGRAMMER ERROR** Dictionary:Elven DictionaryCannot apply RTree search to bad geometry." 

  Dictionary:Elven Dictionary does not have a geometry!
+821 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading