freSetupParameterTraitsGenerator.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freSetupParameterTraitsGenerator.cxx,v $
00007   Language:  C++
00008 
00009 
00010 
00011   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00012   Institute for Medical Biometry and Informatics, University of Heidelberg,
00013   Germany). All rights reserved.
00014   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00015   for details.
00016 
00017      This software is distributed WITHOUT ANY WARRANTY; without even 
00018      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00019      PURPOSE.  See the above copyright notices for more information.
00020 
00021 =========================================================================*/
00022 
00023 #include "freSetupParameterTraitsGenerator.h"
00024 #include "freExceptions.h"
00025 #include "freComponentSetupBrowser.h"
00026 
00027 #include <map>
00028 
00029 #include "muParser.h"
00030 
00031 namespace FREE
00032 {
00033 
00037 
00038 
00039 
00040 void
00041 SetupParameterTraitsGenerator::
00042 ResetParameterConstraints()
00043 {
00044   this->m_Constraints.Reset();
00045   this->m_bTraitsInitialized = false;
00046 };
00047 
00048 void
00049 SetupParameterTraitsGenerator::
00050 AddParameterConstraint(const SetupParameterConstraint& constraint)
00051 {
00052   this->m_Constraints.AddElement(constraint);
00053   this->m_bTraitsInitialized = false;
00054 };
00055 
00056 void
00057 SetupParameterTraitsGenerator::
00058 AddParameterConstraints(const SetupParameterConstraints& constraints)
00059 {
00060   this->m_Constraints.AddElements(constraints);
00061   this->m_bTraitsInitialized = false;
00062 };
00063 
00064 
00065 SetupParameterTraitsGenerator::
00066 SetupParameterTraitsGenerator()
00067 {
00068         this->m_bTraitsInitialized = false;
00069   this->m_Constraints.Reset();
00070 };
00071 
00072 void
00073 SetupParameterTraitsGenerator::
00074 AddParameterTypes(const ParameterTypeList& typeList)
00075 {
00076         this->m_ParameterTypes = typeList;
00077 };
00078 
00079 
00080 SetupParameterTraitsGenerator::ParameterTraitsList
00081 SetupParameterTraitsGenerator::
00082 ComputeParametersTraits( const ParametersType & p, ParametersType& validP) const
00083 {
00084         if (m_ParameterTypes.size()!=p.size()) throwExceptionMacro("Size of the saved parameter type list and the passed value vector are not equal. Ensure same size to allow a proper computation; check if type list was properly initialized befor calling this function.");
00085         return ComputeParametersTraits(this->m_ParameterTypes,p,validP);
00086 }
00087 
00088 SetupParameterTraitsGenerator::ParameterTraitsList
00089 SetupParameterTraitsGenerator::
00090 ComputeParametersTraits( const ParameterTypeList& typeList, const ParametersType & p,
00091                                                                                                  ParametersType& validP) const
00092 {
00093   ParameterTraitsList result;
00094         m_iNumberOfParameters = typeList.size();
00095         
00096         if (m_iNumberOfParameters!=p.size()) throwExceptionMacro("Size of the parameter type list and the value vector are not equal. Ensure same size to allow a proper computation.");
00097 
00098   if (!m_bTraitsInitialized)
00099   {  //compute sequence of the parameter
00100     m_ParameterOrder = GetParameterOrder();
00101     this->m_bTraitsInitialized = true;
00102   }
00103 
00104   m_TempParamValues = p;
00105 
00106   for (ParameterIDsType::const_iterator pos = m_ParameterOrder.begin(); pos!=m_ParameterOrder.end(); ++pos)
00107   { //search
00108     SetupParameterConstraintList paramCnstr= m_Constraints.GetElementsByDestination(*pos);
00109 
00110     SetupParameterTraits traits = ComputeTraits(*pos, typeList[*pos], m_TempParamValues[*pos], paramCnstr);
00111 
00112     result.push_back(traits);
00113 
00114     m_TempParamValues[*pos] = traits.InitialValue();
00115   }
00116 
00117   validP = m_TempParamValues;
00118   return result;
00119 };
00120 
00121 SetupParameterTraitsGenerator::ParameterIDsType
00122 SetupParameterTraitsGenerator::
00123 GetParameterOrder() const
00124 {
00125   ParameterIDsType list;
00126   ParameterIDsType sortedList;
00127 
00128   for (unsigned int iIndex=0; iIndex<m_iNumberOfParameters; iIndex++)
00129   {
00130     list.push_back(iIndex);
00131   }
00132 
00133   typedef std::pair<int,int> LookUpPair;
00134   typedef std::multimap<int,int> LookUpList;
00135   LookUpList cnstrLookUp;
00136 
00137   // break up constraints to every contributing constraint parameter
00138   for (unsigned int iIndex=0; iIndex<this->m_Constraints.Size(); iIndex++)
00139   {
00140     const SetupParameterConstraint* pConstraint = m_Constraints.GetElement(iIndex);
00141     const SetupParameterConstraint::ParameterIDsType& constraintParams = pConstraint->GetConstraintParameters();
00142     for (unsigned int iIndex2=0; iIndex2<constraintParams.size(); iIndex2++)
00143     {
00144       cnstrLookUp.insert(LookUpPair(pConstraint->GetDestinationID(), constraintParams[iIndex2]));
00145     }
00146   }
00147 
00148   //begin with the order computation
00149   while (list.size())
00150   {
00151     bool bIndependetFound = false;
00152 
00153     for (unsigned int iIndex = 0; iIndex<list.size(); iIndex++)
00154     {
00155       if (cnstrLookUp.find(list[iIndex]) == cnstrLookUp.end())
00156       { //there is no constraint for this parameter, so it will
00157         //be the next independent parameter
00158         bIndependetFound = true;
00159         int cnstrID = list[iIndex]; 
00160         sortedList.push_back(cnstrID);
00161         list.erase(list.begin()+iIndex);
00162 
00163         //remove every element from the look up where this parameter
00164         // is the constraint element, because now it has a value, so
00165         // parameters depending, can also be evaluated.
00166         //
00167         // Would be faster if set pos to the return of cnstrLookUp.erease(pos)
00168         // but cygwin gcc had problems compiling, so choosen a statement that
00169         // could be compiled by gcc and vc++, even if it lacks performance and
00170         // elegance *sigh*}
00171         LookUpList::iterator pos = cnstrLookUp.begin();
00172         while (pos != cnstrLookUp.end())
00173         {
00174           if (pos->second == cnstrID)
00175           {
00176             cnstrLookUp.erase(pos);
00177             pos = cnstrLookUp.begin();
00178           }
00179           else
00180           {
00181             ++pos;
00182           }
00183         }
00184 
00185         break; //skip for loop start all over again
00186       }
00187     }
00188 
00189     if (!bIndependetFound) throwExceptionMacro("Error. Constraints for parameters are circular dependent.");
00190   }
00191 
00192   return sortedList;
00193 };
00194 
00195 SetupParameterTraits
00196 SetupParameterTraitsGenerator::
00197 ComputeTraits(const int& iParamID, const Parameter::ParameterValueType& parameterType,
00198                                                         const double& dValue, const SetupParameterConstraintList& constraints) const
00199 {
00200   double dInitialValue = dValue;
00201   double dLowerBound = itk::NumericTraits< double >::NonpositiveMin();
00202   bool bBoundedBelow = false;
00203   double dUpperBound = itk::NumericTraits< double >::max();
00204   bool bBoundedAbove = false;
00205   double dQuantisation = 0.0;
00206 
00207   if (parameterType == Parameter::PVTInteger) dQuantisation = 1.0;
00208 
00209   //Check the constraints
00210 
00211   for (SetupParameterConstraintList::const_iterator pos = constraints.begin(); pos!=constraints.end(); ++pos)
00212   {
00213     //evaluate constraint term
00214     double dConstraintValue = 0.0;
00215 
00216     mu::Parser parser;
00217     //define variable for parser
00218     const SetupParameterConstraint::ParameterIDsType& sourceIDs = (*pos)->GetConstraintParameters();
00219     
00220     for (unsigned int iIndex = 0; iIndex<sourceIDs.size(); iIndex++)
00221     {
00222       if ((sourceIDs[iIndex]<0) || (sourceIDs[iIndex]>=m_iNumberOfParameters))
00223         throwExceptionMacro("Error. Invalid parameter ID. ID in constraint term is out of bound. Invalid ID: " << sourceIDs[iIndex] <<"; number of available parameters: " << this->m_iNumberOfParameters);
00224       
00225       parser.DefineVar("_"+Convert::ToStr(sourceIDs[iIndex]),&(m_TempParamValues[sourceIDs[iIndex]]));
00226     }
00227 
00228     parser.SetExpr((*pos)->GetConstraintTerm());
00229 
00230     try
00231     {
00232       dConstraintValue = parser.Eval();
00233     }
00234     catch(mu::Parser::exception_type &e)
00235     {
00236       std::string sE = e.GetMsg();
00237                   std::string sLocation;
00238                   GetClassLocationMacro( sLocation );
00239       FREE::LogException("muParser based exception", sE, sLocation); \
00240                   throw FREE::ExceptionBase( "muParser exception", "Error: "+sE, sLocation, __FILE__, __LINE__); \
00241     }
00242     catchAllNPassMacro("Error while evaluating constrained term by muParser");
00243 
00244     //evaluate constraint
00245     if ((*pos)->GetRelationType() == SetupParameterConstraint::RTEqual)
00246     {
00247       dInitialValue = dConstraintValue;
00248     }
00249     else if ((*pos)->GetRelationType() == SetupParameterConstraint::RTGreaterOrEqual)
00250     {
00251       if (dLowerBound < dConstraintValue)
00252       {
00253         dLowerBound = dConstraintValue;
00254         bBoundedBelow = true;
00255       }
00256     }
00257     else if ((*pos)->GetRelationType() == SetupParameterConstraint::RTLesserOrEqual)
00258     {
00259       if (dUpperBound > dConstraintValue)
00260       {
00261         dUpperBound = dConstraintValue;
00262         bBoundedAbove = true;
00263       }
00264     }
00265   }
00266 
00267   //check value for bound violation
00268   unsigned int iBoundViolation = 0;
00269   if (dInitialValue < dLowerBound)
00270   {
00271     dInitialValue = dLowerBound;
00272     iBoundViolation++;
00273   }
00274   if (dInitialValue > dUpperBound)
00275   {
00276     dInitialValue = dUpperBound;
00277     iBoundViolation++;
00278   }
00279 
00280   if (iBoundViolation>1) throwExceptionMacro("Error. Both parameter bound overlap. Parameter ID: "<<iParamID<<"; lower bound: "<<dLowerBound<<"; upper bound: "<<dUpperBound);
00281 
00282         if ((parameterType == Parameter::PVTInteger) || (parameterType == Parameter::PVTLong) || (parameterType == Parameter::PVTULong)) dInitialValue = floor(dInitialValue);
00283 
00284   return SetupParameterTraits(dInitialValue, parameterType, dLowerBound, bBoundedBelow,
00285                               dUpperBound, bBoundedAbove, dQuantisation);
00286 };
00287 
00288 }//End of Namespace free

Generated at Sat Oct 13 17:27:43 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000