00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 {
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 {
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
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
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 {
00157
00158 bIndependetFound = true;
00159 int cnstrID = list[iIndex];
00160 sortedList.push_back(cnstrID);
00161 list.erase(list.begin()+iIndex);
00162
00163
00164
00165
00166
00167
00168
00169
00170
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;
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
00210
00211 for (SetupParameterConstraintList::const_iterator pos = constraints.begin(); pos!=constraints.end(); ++pos)
00212 {
00213
00214 double dConstraintValue = 0.0;
00215
00216 mu::Parser parser;
00217
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
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
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 }