Commit 6da972d9 authored by Jussi Lindgren's avatar Jussi Lindgren

Plugins: Misc fixes related to classification

- Fixed problem with class count not specified when processing pairwise strategies
- Added tests for bad number of classes for pairwise strategies
- Added more error handling, e.g. classification processor now stops on failure, stats box checks filename,
  roc curve tests for empty matrix
- Changed Kappa and ROC boxes to have more reasonable default values
- Changed classification tutorial to use native LDA for simplicity
- Removed some obsolete PLDA identifiers
- Typographical fixes
parent c737fa98
......@@ -1726,7 +1726,7 @@ in which step the experiment is. It also triggers
the instructions given to the user.
The <b>Analog Server</b> provides the feedback value
computed by the classifier (distance to LDA hyperplan).</Text>
computed by the classifier (distance to LDA hyperplane).</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
......
......@@ -1415,7 +1415,7 @@
</Output>
<Output>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Hyperplan distance</Name>
<Name>Hyperplane distance</Name>
</Output>
<Output>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
......
......@@ -183,7 +183,7 @@ the modification of weights and biases to avoid oscillations. The learning stop
\par
Note that feature vectors are normalized between -1 and 1 (using the min/max of the training set) to avoid saturation of the hyperbolic tangent.
\par
This algorithm provides both hyperplan distance (identity of output layer) and probabilites (softmax function on output layer).
This algorithm provides both hyperplane distance (identity of output layer) and probabilites (softmax function on output layer).
Cross Validation
......
......@@ -113,7 +113,7 @@ boolean CAlgorithmClassifierOneVsOne::train(const IFeatureVectorSet& rFeatureVec
TParameterHandler <uint64> ip_pClassCount(m_pDecisionStrategyAlgorithm->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassCount));
ip_pClassCount = l_ui32ClassCount;
m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parametrize);
m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parameterize);
this->uninitializeExtraParameterMechanism();
......@@ -247,7 +247,11 @@ boolean CAlgorithmClassifierOneVsOne::classify(const IFeatureVector& rFeatureVec
ip_pClassificationInfos = &l_oClassificationList;
//Then ask to the startegy to make the decision
m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Compute);
if(!m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Compute))
{
this->getLogManager() << LogLevel_Error << "Decision strategy compute() failed.\n";
return false;
}
TParameterHandler<IMatrix*> op_pProbabilityVector = m_pDecisionStrategyAlgorithm->getOutputParameter(OVP_Algorithm_Classifier_OutputParameter_ProbabilityVector);
float64 l_f64MaxProb = -1;
......@@ -408,17 +412,30 @@ boolean CAlgorithmClassifierOneVsOne::loadConfiguration(XML::IXMLNode *pConfigur
TParameterHandler < CIdentifier *> ip_pClassificationAlgorithm(m_pDecisionStrategyAlgorithm->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameterId_AlgorithmIdentifier));
ip_pClassificationAlgorithm = &l_pAlgorithmIdentifier;
m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_LoadConfiguration);
m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parametrize);
l_pTempNode = pConfigurationNode->getChildByName(c_sSubClassifierCountNodeName);
std::stringstream l_sCountData(l_pTempNode->getPCData());
uint64 l_iClassCount;
l_sCountData >> l_iClassCount;
uint64 l_ui64ClassCount;
l_sCountData >> l_ui64ClassCount;
TParameterHandler<uint64> ip_pClassCount(m_pDecisionStrategyAlgorithm->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassCount));
ip_pClassCount = l_ui64ClassCount;
if(!m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_LoadConfiguration))
{
this->getLogManager() << LogLevel_Error << "Loading decision strategy configuration failed\n";
return false;
}
if(!m_pDecisionStrategyAlgorithm->process(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parameterize))
{
this->getLogManager() << LogLevel_Error << "Parameterizing decision strategy failed\n";
return false;
}
while(l_iClassCount != getClassCount())
while(l_ui64ClassCount != getClassCount())
{
if(l_iClassCount < getClassCount())
if(l_ui64ClassCount < getClassCount())
{
IAlgorithmProxy* l_pSubClassifier = m_oSubClassifierDescriptorList.back().m_pSubClassifierProxy;
l_pSubClassifier->uninitialize();
......
......@@ -12,6 +12,7 @@ using namespace OpenViBEToolkit;
boolean CAlgorithmPairwiseDecision::process()
{
// @note there is essentially no test that these are called in correct order. Caller be careful!
if(this->isInputTriggerActive(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Compute))
{
TParameterHandler<std::vector < SClassificationInfo > *> ip_pClassificationValues = this->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassificationOutputs);
......@@ -39,9 +40,9 @@ boolean CAlgorithmPairwiseDecision::process()
}
return false;
}
else if(this->isInputTriggerActive(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parametrize))
else if(this->isInputTriggerActive(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parameterize))
{
return this->parametrize();
return this->parameterize();
}
return true;
}
......@@ -8,25 +8,26 @@
#include <xml/IXMLNode.h>
#include "ovpCAlgorithmClassifierOneVsOne.h"
#define OVP_ClassId_Algorithm_PairwiseDecision OpenViBE::CIdentifier(0x26EF6DDA, 0xF137053C)
#define OVP_ClassId_Algorithm_PairwiseDecisionDesc OpenViBE::CIdentifier(0x191EB02A, 0x6866214A)
#define OVP_ClassId_Algorithm_PairwiseDecision OpenViBE::CIdentifier(0x26EF6DDA, 0xF137053C)
#define OVP_ClassId_Algorithm_PairwiseDecisionDesc OpenViBE::CIdentifier(0x191EB02A, 0x6866214A)
#define OVP_Algorithm_Classifier_InputParameter_ProbabilityMatrix OpenViBE::CIdentifier(0xF48D35AD, 0xB8EFF834)
#define OVP_Algorithm_Classifier_Pairwise_InputParameterId_Configuration OpenViBE::CIdentifier(0x10EBAC09, 0x80926A63)
#define OVP_Algorithm_Classifier_Pairwise_InputParameterId_AlgorithmIdentifier OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E017)
#define OVP_Algorithm_Classifier_Pairwise_InputParameterId_SetRepartition OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E018)
#define OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassificationOutputs OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E019)
#define OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassCount OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E01A)
#define OVP_Algorithm_Classifier_InputParameter_ProbabilityMatrix OpenViBE::CIdentifier(0xF48D35AD, 0xB8EFF834)
#define OVP_Algorithm_Classifier_Pairwise_InputParameterId_Configuration OpenViBE::CIdentifier(0x10EBAC09, 0x80926A63)
#define OVP_Algorithm_Classifier_Pairwise_InputParameterId_AlgorithmIdentifier OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E017)
#define OVP_Algorithm_Classifier_Pairwise_InputParameterId_SetRepartition OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E018)
#define OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassificationOutputs OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E019)
#define OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassCount OpenViBE::CIdentifier(0xBE71BE18, 0x82A0E01A)
#define OVP_Algorithm_Classifier_OutputParameter_ProbabilityVector OpenViBE::CIdentifier(0x883599FE, 0x2FDB32FF)
#define OVP_Algorithm_Classifier_Pairwise_OutputParameterId_Configuration OpenViBE::CIdentifier(0x69F05A61, 0x25C94515)
#define OVP_Algorithm_Classifier_OutputParameter_ProbabilityVector OpenViBE::CIdentifier(0x883599FE, 0x2FDB32FF)
#define OVP_Algorithm_Classifier_Pairwise_OutputParameterId_Configuration OpenViBE::CIdentifier(0x69F05A61, 0x25C94515)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Train OpenViBE::CIdentifier(0x32219D21, 0xD3BE6105)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parameterize OpenViBE::CIdentifier(0x32219D21, 0xD3BE6106)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Compute OpenViBE::CIdentifier(0x3637344B, 0x05D03D7E)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_SaveConfiguration OpenViBE::CIdentifier(0xF19574AD, 0x024045A7)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_LoadConfiguration OpenViBE::CIdentifier(0x97AF6C6C, 0x670A12E6)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Train OpenViBE::CIdentifier(0x32219D21, 0xD3BE6105)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parametrize OpenViBE::CIdentifier(0x32219D21, 0xD3BE6106)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Compute OpenViBE::CIdentifier(0x3637344B, 0x05D03D7E)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_SaveConfiguration OpenViBE::CIdentifier(0xF19574AD, 0x024045A7)
#define OVP_Algorithm_Classifier_Pairwise_InputTriggerId_LoadConfiguration OpenViBE::CIdentifier(0x97AF6C6C, 0x670A12E6)
namespace OpenViBEPlugins
{
......@@ -46,7 +47,7 @@ namespace OpenViBEPlugins
virtual OpenViBE::boolean initialize(void)=0;
virtual OpenViBE::boolean uninitialize(void)=0;
virtual OpenViBE::boolean parametrize(void)=0;
virtual OpenViBE::boolean parameterize(void)=0;
virtual OpenViBE::boolean compute(std::vector< SClassificationInfo >& pClassificationValueList, OpenViBE::IMatrix* pProbabilityVector) =0;
virtual XML::IXMLNode* saveConfiguration(void) = 0;
......@@ -77,7 +78,7 @@ namespace OpenViBEPlugins
rAlgorithmPrototype.addInputTrigger(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Compute, "Compute");
rAlgorithmPrototype.addInputTrigger(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parametrize, "Parametrize");
rAlgorithmPrototype.addInputTrigger(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_Parameterize, "Parametrize");
rAlgorithmPrototype.addInputTrigger(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_SaveConfiguration, "Save configuration");
rAlgorithmPrototype.addInputTrigger(OVP_Algorithm_Classifier_Pairwise_InputTriggerId_LoadConfiguration, "Load configuration");
return true;
......
......@@ -35,11 +35,17 @@ boolean CAlgorithmPairwiseDecisionHT::uninitialize()
return true;
}
boolean CAlgorithmPairwiseDecisionHT::parametrize()
boolean CAlgorithmPairwiseDecisionHT::parameterize()
{
TParameterHandler < uint64 > ip_pClassCount(this->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassCount));
m_ui32ClassCount = static_cast<uint32>(ip_pClassCount);
if(m_ui32ClassCount<2)
{
this->getLogManager() << LogLevel_Error << "Algorithm needs at least 2 classes.\n";
return false;
}
return true;
}
......@@ -47,6 +53,11 @@ boolean CAlgorithmPairwiseDecisionHT::parametrize()
boolean CAlgorithmPairwiseDecisionHT::compute(std::vector< SClassificationInfo >& pClassificationValueList, OpenViBE::IMatrix* pProbabilityVector)
{
if(m_ui32ClassCount<2) {
this->getLogManager() << LogLevel_Error << "Algorithm needs at least 2 classes. Has parameterize() been called?\n";
return false;
}
TParameterHandler<IMatrix*> ip_pRepartitionSetVector = this->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameterId_SetRepartition);
float64* l_pProbabilityMatrix = new float64[m_ui32ClassCount * m_ui32ClassCount];
......
......@@ -24,12 +24,14 @@ namespace OpenViBEPlugins
public:
CAlgorithmPairwiseDecisionHT() : m_ui32ClassCount(0) { };
virtual void release(void) { delete this; }
virtual OpenViBE::boolean initialize(void);
virtual OpenViBE::boolean uninitialize(void);
virtual OpenViBE::boolean parametrize(void);
virtual OpenViBE::boolean parameterize(void);
virtual OpenViBE::boolean compute(std::vector< SClassificationInfo >& pClassificationValueList, OpenViBE::IMatrix* pProbabilityVector);
virtual XML::IXMLNode* saveConfiguration(void);
......
......@@ -30,11 +30,17 @@ boolean CAlgorithmPairwiseDecisionVoting::uninitialize()
return true;
}
boolean CAlgorithmPairwiseDecisionVoting::parametrize()
boolean CAlgorithmPairwiseDecisionVoting::parameterize()
{
TParameterHandler < uint64 > ip_pClassCount(this->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassCount));
m_ui32ClassCount = static_cast<uint32>(ip_pClassCount);
if(m_ui32ClassCount<2)
{
this->getLogManager() << LogLevel_Error << "Algorithm needs at least 2 classes.\n";
return false;
}
return true;
}
......@@ -42,6 +48,11 @@ boolean CAlgorithmPairwiseDecisionVoting::parametrize()
boolean CAlgorithmPairwiseDecisionVoting::compute(std::vector< SClassificationInfo >& pClassificationValueList, OpenViBE::IMatrix* pProbabilityVector)
{
if(m_ui32ClassCount<2) {
this->getLogManager() << LogLevel_Error << "Algorithm needs at least 2 classes. Has parameterize() been called?\n";
return false;
}
#if VOTING_DEBUG
std::cout << pClassificationValueList.size() << std::endl;
......
......@@ -26,12 +26,14 @@ namespace OpenViBEPlugins
public:
CAlgorithmPairwiseDecisionVoting() : m_ui32ClassCount(0) { };
virtual void release(void) { delete this; }
virtual OpenViBE::boolean initialize(void);
virtual OpenViBE::boolean uninitialize(void);
virtual OpenViBE::boolean parametrize(void);
virtual OpenViBE::boolean parameterize(void);
virtual OpenViBE::boolean compute(std::vector< SClassificationInfo >& pClassificationValueList, OpenViBE::IMatrix* pProbabilityVector);
virtual XML::IXMLNode* saveConfiguration(void);
......
......@@ -31,11 +31,17 @@ boolean CAlgorithmPairwiseStrategyPKPD::uninitialize()
return true;
}
boolean CAlgorithmPairwiseStrategyPKPD::parametrize()
boolean CAlgorithmPairwiseStrategyPKPD::parameterize()
{
TParameterHandler < uint64 > ip_pClassCount(this->getInputParameter(OVP_Algorithm_Classifier_Pairwise_InputParameter_ClassCount));
m_ui32ClassCount = static_cast<uint32>(ip_pClassCount);
if(m_ui32ClassCount<2)
{
this->getLogManager() << LogLevel_Error << "Algorithm needs at least 2 classes.\n";
return false;
}
return true;
}
......@@ -43,6 +49,11 @@ boolean CAlgorithmPairwiseStrategyPKPD::parametrize()
boolean CAlgorithmPairwiseStrategyPKPD::compute(std::vector< SClassificationInfo >& pClassificationValueList, OpenViBE::IMatrix* pProbabilityVector)
{
if(m_ui32ClassCount<2) {
this->getLogManager() << LogLevel_Error << "Algorithm needs at least 2 classes. Has parameterize() been called?\n";
return false;
}
float64* l_pProbabilityMatrix = new float64[m_ui32ClassCount * m_ui32ClassCount];
//First we set the diagonal to 0
......
......@@ -25,12 +25,14 @@ namespace OpenViBEPlugins
public:
CAlgorithmPairwiseStrategyPKPD() : m_ui32ClassCount(0) { };
virtual void release(void) { delete this; }
virtual OpenViBE::boolean initialize(void);
virtual OpenViBE::boolean uninitialize(void);
virtual OpenViBE::boolean parametrize(void);
virtual OpenViBE::boolean parameterize(void);
virtual OpenViBE::boolean compute(std::vector< SClassificationInfo >& pClassificationValueList, OpenViBE::IMatrix* pProbabilityVector);
virtual XML::IXMLNode* saveConfiguration(void);
......
......@@ -272,8 +272,16 @@ boolean CBoxAlgorithmClassifierProcessor::process(void)
l_rDynamicBoxContext.markOutputAsReadyToSend(1, l_ui64StartTime, l_ui64EndTime);
l_rDynamicBoxContext.markOutputAsReadyToSend(2, l_ui64StartTime, l_ui64EndTime);
}
//else
// this->getLogManager() << LogLevel_Warning << "---Classification failed---\n";
else
{
// this->getLogManager() << LogLevel_Error << "Classification failed (success trigger not active).\n";
// return false;
}
}
else
{
this->getLogManager() << LogLevel_Error << "Classification algorithm failed.\n";
return false;
}
}
if(m_pFeaturesDecoder->isOutputTriggerActive(OVP_GD_Algorithm_FeatureVectorStreamDecoder_OutputTriggerId_ReceivedEnd))
......
......@@ -9,11 +9,6 @@
//___________________________________________________________________//
// //
#define OVP_Algorithm_ClassifierPLDA_InputParameterId_Shrinkage OpenViBE::CIdentifier(0x7FEFDCA9, 0x816ED903)
#define OVP_Algorithm_ClassifierPLDA_InputParameterId_Lambda OpenViBE::CIdentifier(0xEBAEB213, 0xDD4735A0)
#define OVP_Algorithm_ClassifierPLDA_InputParameterId_BufferSize OpenViBE::CIdentifier(0xB083614E, 0x26C6B4BD)
#define OVP_TypeId_ShrinkageType OpenViBE::CIdentifier(0x344A52F5, 0x489DB439)
enum { FULL=0, DIAG=1, SHRINK_TO_DIAG=2, SHRINK_TO_UNITY=3 };
//___________________________________________________________________//
// //
// Plugin Object Class Identifiers //
......
......@@ -39,7 +39,7 @@ boolean CBoxAlgorithmConfusionMatrix::initialize(void)
}
else
{
this->getLogManager() << LogLevel_Info << "Asking for percentage. The value of the setting \"Sums\" will be ignore.\n";
this->getLogManager() << LogLevel_Debug << "Asking for percentage. The value of the setting \"Sums\" will be ignored.\n";
ip_bSums = false;
}
......
......@@ -155,8 +155,8 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addOutput ("Confusion Matrix", OV_TypeId_StreamedMatrix);
rBoxAlgorithmPrototype.addSetting("Amount of class", OV_TypeId_Integer, "2");
rBoxAlgorithmPrototype.addSetting("Stimulation of class 1", OV_TypeId_Stimulation, "");
rBoxAlgorithmPrototype.addSetting("Stimulation of class 2", OV_TypeId_Stimulation, "");
rBoxAlgorithmPrototype.addSetting("Stimulation of class 1", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_01");
rBoxAlgorithmPrototype.addSetting("Stimulation of class 2", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_02");
rBoxAlgorithmPrototype.addFlag(OpenViBE::Kernel::BoxFlag_CanModifySetting);
rBoxAlgorithmPrototype.addFlag(OpenViBE::Kernel::BoxFlag_IsUnstable);
......
......@@ -126,7 +126,12 @@ boolean CBoxAlgorithmROCCurve::process(void)
//The matrix is suppose to have only one dimension
float64* l_pArrayValue;
if(l_pMatrixValue->getBufferElementCount() > 1)
if(l_pMatrixValue->getBufferElementCount() == 0)
{
this->getLogManager() << LogLevel_Error << "Received zero-sized buffer\n";
return false;
}
else if(l_pMatrixValue->getBufferElementCount() > 1)
{
l_pArrayValue = new float64[l_pMatrixValue->getBufferElementCount()];
for(size_t k = 0; k < l_pMatrixValue->getBufferElementCount() ; ++k)
......@@ -165,7 +170,7 @@ boolean CBoxAlgorithmROCCurve::computeROCCurves()
}
else{
//Impossible to find the corresponding stimulation
this->getLogManager() << LogLevel_Warning << "A result of classification cannot be connect to a class. The result will be discard\n";
this->getLogManager() << LogLevel_Warning << "A result of classification cannot be connected to a class. The result will be discarded.\n";
}
}
......@@ -179,7 +184,7 @@ boolean CBoxAlgorithmROCCurve::computeROCCurves()
const gint l_iCurrentPage = gtk_notebook_current_page(GTK_NOTEBOOK(m_pWidget));
if(l_iCurrentPage < 0)
{
this->getLogManager() << LogLevel_Trace << "No page is select. The designer is probably in no visualisation mode. Discard the drawing phase\n";
this->getLogManager() << LogLevel_Trace << "No page is selected. The designer is probably in no visualisation mode. Skipping the drawing phase\n";
}
else
{
......
......@@ -167,10 +167,10 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addInput("Expected label", OV_TypeId_Stimulations);
rBoxAlgorithmPrototype.addInput("Classification values", OV_TypeId_StreamedMatrix);
rBoxAlgorithmPrototype.addSetting("Computation trigger", OV_TypeId_Stimulation, "");
rBoxAlgorithmPrototype.addSetting("Computation trigger", OV_TypeId_Stimulation, "OVTK_StimulationId_ExperimentStop");
rBoxAlgorithmPrototype.addSetting("Amount of class", OV_TypeId_Integer, "2");
rBoxAlgorithmPrototype.addSetting("Class 1 identifier" , OV_TypeId_Stimulation, "");
rBoxAlgorithmPrototype.addSetting("Class 2 identifier" , OV_TypeId_Stimulation, "");
rBoxAlgorithmPrototype.addSetting("Class 1 identifier" , OV_TypeId_Stimulation, "OVTK_StimulationId_Label_01");
rBoxAlgorithmPrototype.addSetting("Class 2 identifier" , OV_TypeId_Stimulation, "OVTK_StimulationId_Label_02");
rBoxAlgorithmPrototype.addFlag(OpenViBE::Kernel::BoxFlag_CanModifySetting);
......
......@@ -41,11 +41,18 @@ boolean CBoxAlgorithmStatisticGenerator::initialize(void)
m_oFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
if(m_oFilename == CString(""))
{
this->getLogManager() << LogLevel_Error << "The filename is empty\n";
return false;
}
return true;
}
boolean CBoxAlgorithmStatisticGenerator::uninitialize(void)
{
boolean l_bReturnValue = true;
m_oSignalDecoder.uninitialize();
m_oStimulationDecoder.uninitialize();
......@@ -103,12 +110,15 @@ boolean CBoxAlgorithmStatisticGenerator::uninitialize(void)
l_pRootNode->addChild(l_pChannelsNode);
XML::IXMLHandler *l_pHandler = XML::createXMLHandler();
l_pHandler->writeXMLInFile(*l_pRootNode, m_oFilename.toASCIIString());
if(!l_pHandler->writeXMLInFile(*l_pRootNode, m_oFilename.toASCIIString()))
{
l_bReturnValue = false;
}
l_pHandler->release();
l_pRootNode->release();
}
return true;
return l_bReturnValue;
}
......
......@@ -90,7 +90,7 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addInput("Signal",OV_TypeId_Signal);
rBoxAlgorithmPrototype.addInput("Stimulations",OV_TypeId_Stimulations);
rBoxAlgorithmPrototype.addSetting("Filename for saving",OV_TypeId_Filename,"");
rBoxAlgorithmPrototype.addSetting("Filename for saving",OV_TypeId_Filename,"${Path_UserData}/statistics-dump.xml");
rBoxAlgorithmPrototype.addFlag(OpenViBE::Kernel::BoxFlag_CanModifySetting);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment