Skip to content

Commit

Permalink
Refs #4647 start of a unified processGroups
Browse files Browse the repository at this point in the history
  • Loading branch information
Janik Zikovsky committed Jan 25, 2012
1 parent 94bd3b9 commit 7347238
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 43 deletions.
78 changes: 36 additions & 42 deletions Code/Mantid/Framework/API/inc/MantidAPI/Algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag
//============================================================================
Algorithm();
virtual ~Algorithm();

/** @name Algorithm Information */
/// function to return a name of the algorithm, must be overridden in all algorithms
virtual const std::string name() const = 0;
/// function to return a version of the algorithm, must be overridden in all algorithms
Expand All @@ -195,63 +197,53 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag
virtual const std::string categorySeperator() const {return ";";}
/// function to return any aliases to the algorithm; A default implementation is provided
virtual const std::string alias() const {return "";}

/// Algorithm ID. Unmanaged algorithms return 0 (or NULL?) values. Managed ones have non-zero.
AlgorithmID getAlgorithmID()const{return m_algorithmID;}

// IAlgorithm methods
/** @name IAlgorithm methods */
void initialize();
bool execute();
void executeAsSubAlg();
virtual bool isInitialized() const;
virtual bool isExecuted() const;
// End of IAlgorithm methods
using Kernel::PropertyManagerOwner::getProperty;

/// To query whether algorithm is a child. Default to false
bool isChild() const;
void setChild(const bool isChild);

void setRethrows(const bool rethrow);

/// Asynchronous execution.
/** @name Asynchronous Execution */
Poco::ActiveResult<bool> executeAsync();
/// True if the algorithm is running asynchronously.
bool isRunningAsync(){return m_runningAsync;}
/// True if the algorithm is running.
bool isRunning(){return m_running;}

/// Set the maximum number of cores from Properties files
void getOpenMPCores();

/// Execute as a sub-algorithm
void executeAsSubAlg();

/// Add an observer for a notification
void addObserver(const Poco::AbstractObserver& observer)const;

/// Remove an observer
void removeObserver(const Poco::AbstractObserver& observer)const;

/// Raises the cancel flag. interuption_point() method if called inside exec() checks this flag
/// and if true terminates the algorithm.
virtual void cancel()const;
/// True if the algorithm is running asynchronously.
bool isRunningAsync(){return m_runningAsync;}
/// True if the algorithm is running.
bool isRunning(){return m_running;}
/// Raises the cancel flag.
virtual void cancel() const;
/// Returns the cancellation state
bool getCancel() const { return m_cancel; }

///Logging can be disabled by passing a value of false
void setLogging(const bool value){g_log.setEnabled(value);}
///returns the status of logging, True = enabled
bool isLogging() const {return g_log.getEnabled();}
/// Returns a reference to the logger.
Kernel::Logger& getLogger() const { return g_log; }
/// Returns the cancellation state
bool getCancel() const { return m_cancel; }

/// Sets documentation strings for this algorithm
virtual void initDocs() {};

/// function returns an optional message that will be displayed in the default GUI, at the top.
const std::string getOptionalMessage() const { return m_OptionalMessage;}

/// Set an optional message that will be displayed in the default GUI, at the top.
/// Set an optional message that will be displayed in the default GUI, at the top.
void setOptionalMessage(const std::string optionalMessage) { m_OptionalMessage = optionalMessage;}

/// Get a summary to be used in the wiki page.
Expand Down Expand Up @@ -281,39 +273,33 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag
static IAlgorithm_sptr fromHistory(const AlgorithmHistory & history);
//@}

//creates a sub algorithm for use in this algorithm
boost::shared_ptr<Algorithm> createSubAlgorithm(const std::string& name, const double startProgress = -1.,
const double endProgress = -1., const bool enableLogging=true, const int& version = -1);

protected:

// Equivalents of Gaudi's initialize & execute methods
/// Virtual method - must be overridden by concrete algorithm
virtual void init() = 0;
/// Virtual method - must be overridden by concrete algorithm
virtual void exec() = 0;
/// Method defining summary, optional
virtual void initDocs() {};

void cacheWorkspaceProperties();

friend class AlgorithmProxy;
/// Initialize with properties from an algorithm proxy
void initializeFromProxy(const AlgorithmProxy&);

void setInitialized();
void setExecuted(bool state);

void cacheWorkspaceProperties();

// // Make PropertyManager's declareProperty methods protected in Algorithm
// using Kernel::PropertyManagerOwner::declareProperty;

/// Sends notifications to observers. Observers can subscribe to notificationCenter
/// using Poco::NotificationCenter::addObserver(...);
mutable Poco::NotificationCenter m_notificationCenter;

/** @name Progress Reporting functions */
friend class Progress;
/// Sends ProgressNotification. p must be between 0 (just started) and 1 (finished)
void progress(double p, const std::string& msg = "", double estimatedTime = 0.0, int progressPrecision = 0);
/// Interrupts algorithm execution if Algorithm::cancel() has been called.
/// Does nothing otherwise.
void interruption_point();

///Observation slot for child algorithm progress notification messages, these are scaled and then signalled for this algorithm.
Expand All @@ -338,9 +324,12 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag
/// virtual method to set non workspace properties for an algorithm,it's useful for checking the period number when a member in a group workspace is executed
virtual void setOtherProperties(IAlgorithm* alg,const std::string & propertyName,const std::string &propertyValue,int perioidNum);

mutable bool m_cancel; ///< set to true to stop execution
bool m_parallelException; ///< Set if an exception is thrown, and not caught, within a parallel region
Kernel::Logger& g_log; ///< reference to the logger class
/// Set to true to stop execution
mutable bool m_cancel;
/// Set if an exception is thrown, and not caught, within a parallel region
bool m_parallelException;
/// Reference to the logger class
Kernel::Logger& g_log;

private:

Expand Down Expand Up @@ -372,12 +361,9 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag

/// Poco::ActiveMethod used to implement asynchronous execution.
Poco::ActiveMethod<bool, Poco::Void, Algorithm> m_executeAsync;
/** executeAsync() implementation.
@param i :: Unused argument
*/
bool executeAsyncImpl(const Poco::Void & i);


// --------------------- Private Members -----------------------------------
bool m_isInitialized; ///< Algorithm has been initialized flag
bool m_isExecuted; ///< Algorithm is executed flag
bool m_isChildAlgorithm; ///< Algorithm is a child algorithm
Expand All @@ -399,10 +385,18 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag
/// Vector of all the workspaces that have been write-locked
std::vector<Workspace_sptr> m_writeLockedWorkspaces;

/// All the WorkspaceProperties that are Input or InOut. Set in initialize()
/// All the WorkspaceProperties that are Input or InOut. Set in execute()
std::vector<IWorkspaceProperty *> m_inputWorkspaceProps;
/// All the WorkspaceProperties that are Output or InOut. Set in initialize()
/// All the WorkspaceProperties that are Output or InOut. Set in execute()
std::vector<IWorkspaceProperty *> m_outputWorkspaceProps;

// ------------------ For WorkspaceGroups ------------------------------------
bool checkGroups();
/// One vector of workspaces for each input workspace property
std::vector<std::vector<Workspace_sptr> > m_groups;
/// If only one input is a group, this is its index. -1 if they are all groups
int m_singleGroup;

};

///Typedef for a shared pointer to an Algorithm
Expand Down
83 changes: 82 additions & 1 deletion Code/Mantid/Framework/API/src/Algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Mantid
template MANTID_API_DLL bool Algorithm::isEmpty<std::size_t> (const std::size_t);

//=============================================================================================
//================================== Constructors/Destructors ===================================
//================================== Constructors/Destructors =================================
//=============================================================================================

/// Initialize static algorithm counter
Expand Down Expand Up @@ -910,6 +910,86 @@ namespace Mantid
//================================== WorkspaceGroup-related ===================================
//=============================================================================================

/** Check the input workspace properties for groups.
*
* If there are more than one input workspace properties, then:
* - All inputs should be groups of the same size
* - In this case, algorithms are processed in order
* - OR, only one input should be a group, the others being size of 1
*
* @return true if processGroups() should be called.
* @throw std::invalid_argument if the groups sizes are incompatible.
* @throw std::invalid_argument if a member is not found
*/
bool Algorithm::checkGroups()
{
// Start by checking if there are ANY groups
bool anyGroups = false;
for (size_t i=0; i<m_inputWorkspaceProps.size(); i++)
{
WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>
(m_inputWorkspaceProps[i]->getWorkspace());
if (wsGroup) anyGroups = true;
}
if (!anyGroups)
return false;

// Unroll the groups or single inputs into vectors of workspace
m_groups.clear();


for (size_t i=0; i<m_inputWorkspaceProps.size(); i++)
{
std::vector<Workspace_sptr> thisGroup;

Workspace_sptr ws = m_inputWorkspaceProps[i]->getWorkspace();
WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(ws);
if (wsGroup)
{
std::vector<std::string> names = wsGroup->getNames();
for (size_t j=0; j<names.size(); j++)
{
Workspace_sptr memberWS = AnalysisDataService::Instance().retrieve(names[j]);
if (!memberWS)
throw std::invalid_argument("One of the members of " + wsGroup->name() + ", " + names[j] + " was not found!.");
thisGroup.push_back(memberWS);
}
}
else
// "group" with only one member
thisGroup.push_back(ws);

// Add to the list of groups
m_groups.push_back(thisGroup);
//Property * prop = dynamic_cast<Property *>(m_inputWorkspaceProps[i]);
}

// ---- Confirm that all the groups are the same size -----
// Index of the single group
m_singleGroup = -1;
// Size of the single or of all the groups
size_t groupSize = 0;
for (size_t i=0; i<m_groups.size(); i++)
{
std::vector<Workspace_sptr> & thisGroup = m_groups[i];
if (thisGroup.size() == 0)
throw std::invalid_argument("Empty group passed as input");
if (thisGroup.size() > 1)
{
m_singleGroup = int(i);
// Check for matching group size
if (groupSize > 0)
if (thisGroup.size() != groupSize)
throw std::invalid_argument("Input WorkspaceGroups are not of the same size.");
// Save the size for the next group
groupSize = thisGroup.size();
}
} // end for each group

// If you get here, then the group si
return true;
}

//--------------------------------------------------------------------------------------------
/** To Process workspace groups.
* This runs the algorithm once for each workspace in the group.
Expand Down Expand Up @@ -1306,6 +1386,7 @@ namespace Mantid
}

/**Callback when an algorithm is executed asynchronously
* @param i :: Unused argument
* @return true if executed successfully.
*/
bool Algorithm::executeAsyncImpl(const Poco::Void&)
Expand Down

0 comments on commit 7347238

Please sign in to comment.