Medical Imaging Interaction Toolkit  2018.4.99-dfa0c14e
Medical Imaging Interaction Toolkit
mitkModelFitInfo.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkModelFitInfo.h"
14 
16 #include <mitkNodePredicateAnd.h>
17 #include <mitkUIDGenerator.h>
18 #include "mitkDataNode.h"
19 #include "mitkDataStorage.h"
20 
22 #include "mitkModelFitException.h"
24 
26 {
27  if (p.IsNull())
28  {
29  mitkThrow() << "Given parameter must not be NULL";
30  }
31 
32  if (GetParameter(p->name, p->type).IsNull())
33  {
34  MITK_DEBUG << "Adding parameter '" << p->name << "with type " << p->type
35  << "' to modelFit '" << uid << "'.";
36 
37  LockType lock(mutex);
38  parameterList.push_back(p);
39  }
40  else
41  {
42  MITK_DEBUG << "Parameter '" << p->name << "' of modelFit '" << uid
43  << "' already exists. Aborting.";
44  }
45 }
46 
47 mitk::modelFit::Parameter::ConstPointer
49  const Parameter::Type& type) const
50 {
51  for (ConstIterType iter = parameterList.begin(); iter != parameterList.end(); ++iter)
52  {
53  Parameter::ConstPointer p = static_cast<Parameter::ConstPointer>(*iter);
54 
55  if (p->name == name && p->type == type)
56  {
57  return p;
58  }
59  }
60 
61  return nullptr;
62 }
63 
64 
66 const
67 {
68  return this->parameterList;
69 };
70 
71 void mitk::modelFit::ModelFitInfo::DeleteParameter(const std::string& name,
72  const Parameter::Type& type)
73 {
74  for (IterType iter = parameterList.begin(); iter != parameterList.end(); ++iter)
75  {
76  Parameter::ConstPointer p = static_cast<Parameter::ConstPointer>(*iter);
77 
78  if (p->name == name && p->type == type)
79  {
80  MITK_DEBUG << "Deleting parameter '" << name << " with type " << type
81  << "' from modelFit '" << uid << "'.";
82 
83  LockType lock(mutex);
84  parameterList.erase(iter);
85  return;
86  }
87  }
88 }
89 
90 
92  const std::string& prop)
93 {
94  std::string result;
95 
96  if (!node || !node->GetData() ||
97  !node->GetData()->GetPropertyList()->GetStringProperty(prop.c_str(), result) || result.empty())
98  {
100  << " is lacking the required "
101  << "property '" << prop
102  << "' or contains an empty string.";
103  }
104 
105  return result;
106 }
107 
109  const std::string& prop)
110 {
111  std::string result;
112 
113  if (!data || !data->GetPropertyList()->GetStringProperty(prop.c_str(), result) || result.empty())
114  {
115  mitkThrowException(mitk::modelFit::ModelFitException) << "Data is lacking the required "
116  << "property '" << prop
117  << "' or contains an empty string.";
118  }
119 
120  return result;
121 }
122 
123 mitk::modelFit::ModelFitInfo::Pointer
125  const mitk::DataStorage* storage)
126 {
127  if (!storage)
128  {
129  return nullptr;
130  }
131 
132  mitk::DataStorage::SetOfObjects::ConstPointer nodes = GetNodesOfFit(uid, storage);
133 
134  if (nodes.IsNull() || nodes->empty())
135  {
136  return nullptr;
137  }
138 
139  mitk::DataNode::ConstPointer node = nodes->GetElement(
140  0).GetPointer(); //take one of the nodes as template
141 
142  if (!node->GetData())
143  {
144  return nullptr;
145  }
146 
147  ModelFitInfo::Pointer fit = ModelFitInfo::New();
148  fit->uid = uid;
149 
150  // Mandatory properties
151  try
152  {
156  }
157  catch (const ModelFitException& e)
158  {
159  MITK_ERROR << e.what();
160  return nullptr;
161  }
162 
163  // Either a function string or a function class must exist
164  if (!node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::MODEL_FUNCTION_PROPERTY_NAME().c_str(),
165  fit->function))
166  {
167  fit->function = "";
168  }
169 
170  try
171  {
172  fit->functionClassID =
174  }
175  catch (const ModelFitException&)
176  {
177  if (fit->function.empty())
178  {
179  MITK_ERROR << "The properties '"
182  << "' are both empty or missing. One of these is required.";
183  return nullptr;
184  }
185  }
186 
187  node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::FIT_NAME_PROPERTY_NAME().c_str(), fit->fitName);
188  node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::MODEL_X_PROPERTY_NAME().c_str(), fit->x);
189  node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::XAXIS_NAME_PROPERTY_NAME().c_str(), fit->xAxisName);
190  node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::XAXIS_UNIT_PROPERTY_NAME().c_str(), fit->xAxisUnit);
191  node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::YAXIS_NAME_PROPERTY_NAME().c_str(), fit->yAxisName);
192  node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::YAXIS_UNIT_PROPERTY_NAME().c_str(), fit->yAxisUnit);
193 
194  // Parameter
195  for (DataStorage::SetOfObjects::ConstIterator pos = nodes->Begin(); pos != nodes->End(); ++pos)
196  {
197  modelFit::Parameter::Pointer param = ExtractParameterFromData(pos->Value()->GetData());
198 
199  if (param.IsNotNull())
200  {
201  fit->AddParameter(param);
202  }
203  }
204 
205  // Static parameters
206  mitk::ScalarListLookupTableProperty::ConstPointer varProp = dynamic_cast<const mitk::ScalarListLookupTableProperty*>(node->GetData()->GetProperty(mitk::ModelFitConstants::FIT_STATIC_PARAMETERS_PROPERTY_NAME().c_str()).GetPointer());
207 
208  if (varProp.IsNotNull())
209  {
210  const mitk::ScalarListLookupTable lut = varProp->GetValue();
212 
213  for (mitk::ScalarListLookupTable::LookupTableType::const_iterator mapIter =
214  varMap.begin(); mapIter != varMap.end(); ++mapIter)
215  {
216  fit->staticParamMap.Add(mapIter->first, mapIter->second);
217  }
218  }
219 
220  //fit input and ROI
221  if (storage)
222  {
223  auto inputRule = ModelFitResultRelationRule::New();
224  auto inputPredicate = inputRule->GetDestinationsDetector(node);
225  auto inputNodes = storage->GetSubset(inputPredicate);
226  if (inputNodes->empty())
227  {
228  MITK_ERROR << "Cannot create valid model fit info. Input node cannot be found.";
229  return nullptr;
230  }
231  if (inputNodes->size()>1)
232  {
233  MITK_WARN << "More then one node found as input node. This could indicate an invalid state as only one input node should be present. Used first found input node.";
234  }
235 
236  auto inputNode = inputNodes->front();
237 
238  mitk::Image::ConstPointer inputImage = dynamic_cast<const mitk::Image*>(inputNode->GetData());
239 
240  if (inputImage.IsNull())
241  {
242  MITK_ERROR << "Cannot create valid model fit info. input node does not contain an image.";
243  return nullptr;
244  }
245 
246  fit->inputImage = inputImage;
247  }
248 
249  node->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::FIT_INPUT_ROIUID_PROPERTY_NAME().c_str(),
250  fit->roiUID);
251 
252  mitk::ScalarListLookupTableProperty::ConstPointer inputDataProp = dynamic_cast<const mitk::ScalarListLookupTableProperty*>(node->GetData()->GetProperty(mitk::ModelFitConstants::FIT_INPUT_DATA_PROPERTY_NAME().c_str()).GetPointer());
253  if (inputDataProp.IsNotNull())
254  {
255  fit->inputData = inputDataProp->GetValue();
256  }
257 
258  return fit;
259 }
260 
261 mitk::modelFit::ModelFitInfo::Pointer
263 mitk::BaseData* inputImage, const std::string& fitType, const std::string& fitName,
265 {
266  if (!usedParameterizer)
267  {
268  return nullptr;
269  }
270 
271  UIDGenerator generator("FitUID_");
272  std::string uid = generator.GetUID();
273 
274  ModelFitInfo::Pointer fit = ModelFitInfo::New();
275  fit->uid = uid;
276  fit->fitType = fitType;
277  fit->fitName = fitName;
278  fit->inputImage = dynamic_cast<Image*>(inputImage);
279 
280  if (fit->inputImage.IsNull())
281  {
282  mitkThrow() << "Cannot generate model fit info. Input node does not contain an image.";
283  }
284 
285  fit->modelType = usedParameterizer->GetModelType();
286  fit->modelName = usedParameterizer->GetModelDisplayName();
287 
288  fit->function = usedParameterizer->GetFunctionString();
289  fit->x = usedParameterizer->GetXName();
290  fit->functionClassID = usedParameterizer->GetClassID();
291 
292  fit->xAxisName = usedParameterizer->GetXAxisName();
293  fit->xAxisUnit = usedParameterizer->GetXAxisUnit();
294  fit->yAxisName = usedParameterizer->GetYAxisName();
295  fit->yAxisUnit = usedParameterizer->GetYAxisUnit();
296 
297  // Parameter
298  ModelTraitsInterface::ParameterNamesType paramNames = usedParameterizer->GetParameterNames();
299  ModelTraitsInterface::ParamterScaleMapType paramScales = usedParameterizer->GetParameterScales();
300  ModelTraitsInterface::ParamterUnitMapType paramUnits = usedParameterizer->GetParameterUnits();
301 
302  for (ModelTraitsInterface::ParameterNamesType::iterator pos = paramNames.begin();
303  pos != paramNames.end(); ++pos)
304  {
305  modelFit::Parameter::Pointer param = modelFit::Parameter::New();
306  param->name = *pos;
307  param->type = Parameter::ParameterType;
308 
309  if (paramScales.find(*pos) == paramScales.end())
310  {
311  mitkThrow() <<
312  "Cannot generate model fit info. Model traits invalid (scales do not include parameter). Parameter name: "
313  << *pos;
314  }
315 
316  if (paramUnits.find(*pos) == paramUnits.end())
317  {
318  mitkThrow() <<
319  "Cannot generate model fit info. Model traits invalid (units do not include parameter). Parameter name: "
320  << *pos;
321  }
322 
323  param->scale = paramScales[*pos];
324  param->unit = paramUnits[*pos];
325  fit->AddParameter(param);
326  }
327 
328  //derived parameter
330  usedParameterizer->GetDerivedParameterNames();
332  usedParameterizer->GetDerivedParameterScales();
334  usedParameterizer->GetDerivedParameterUnits();
335 
336  for (ModelTraitsInterface::ParameterNamesType::iterator pos = derivedNames.begin();
337  pos != derivedNames.end(); ++pos)
338  {
339  modelFit::Parameter::Pointer param = modelFit::Parameter::New();
340  param->name = *pos;
341  param->type = Parameter::DerivedType;
342 
343  if (derivedScales.find(*pos) == derivedScales.end())
344  {
345  mitkThrow() <<
346  "Cannot generate model fit info. Model traits invalid (scales do not include parameter). Parameter name: "
347  << *pos;
348  }
349 
350  if (derivedUnits.find(*pos) == derivedUnits.end())
351  {
352  mitkThrow() <<
353  "Cannot generate model fit info. Model traits invalid (units do not include parameter). Parameter name: "
354  << *pos;
355  }
356 
357  param->scale = derivedScales[*pos];
358  param->unit = derivedUnits[*pos];
359  fit->AddParameter(param);
360  }
361 
362  // Static parameters (but transfer only the global ones)
364  usedParameterizer->GetGlobalStaticParameters();
365 
366  for (ModelParameterizerBase::StaticParameterMapType::const_iterator pos = staticParamMap.begin();
367  pos != staticParamMap.end(); ++pos)
368  {
369  fit->staticParamMap.Add(pos->first, pos->second);
370  }
371 
372 
373  fit->roiUID = roiUID;
374 
375  return fit;
376 }
377 
378 mitk::modelFit::ModelFitInfo::Pointer
381 const std::string& fitName, const ModelFitInfo::UIDType& roiUID)
382 {
383  mitk::modelFit::ModelFitInfo::Pointer info = CreateFitInfoFromModelParameterizer(usedParameterizer,
384  inputImage, fitType, fitName, roiUID);
385 
386  info->inputData = inputData;
387 
388  return info;
389 }
390 
391 mitk::DataStorage::SetOfObjects::ConstPointer
393 {
394  if (!storage)
395  {
396  return nullptr;
397  }
398 
401  return storage->GetSubset(predicate);
402 };
403 
404 
407 {
408  auto rule = ModelFitResultRelationRule::New();
410 
411  if (node && storage)
412  {
413  auto fitUIDPredicate = mitk::NodePredicateDataProperty::New(
415  auto rulePredicate = rule->GetSourcesDetector(node);
416  auto predicate = NodePredicateAnd::New(fitUIDPredicate, rulePredicate);
417  mitk::DataStorage::SetOfObjects::ConstPointer nodes = storage->GetSubset(predicate);
418 
419  for (mitk::DataStorage::SetOfObjects::ConstIterator pos = nodes->Begin(); pos != nodes->End();
420  ++pos)
421  {
423  pos->Value()->GetData()->GetPropertyList()->GetStringProperty(mitk::ModelFitConstants::FIT_UID_PROPERTY_NAME().c_str(), uid);
424 
425  result.insert(uid);
426  }
427 
428  }
429 
430  return result;
431 };
MITKMODELFIT_EXPORT NodeUIDSetType GetFitUIDsOfNode(const mitk::DataNode *node, const mitk::DataStorage *storage)
void DeleteParameter(const std::string &name, const Parameter::Type &type)
Searches for the parameter with the given name and type in the fit&#39;s parameter list and deletes it if...
virtual StaticParameterMapType GetGlobalStaticParameters() const =0
virtual DerivedParamterScaleMapType GetDerivedParameterScales() const =0
static const std::string FIT_TYPE_PROPERTY_NAME()
Data management class that handles &#39;was created by&#39; relations.
static Pointer New()
MITKMODELFIT_EXPORT DataStorage::SetOfObjects::ConstPointer GetNodesOfFit(const ModelFitInfo::UIDType &fitUID, const mitk::DataStorage *storage)
virtual ModellClassIDType GetClassID() const =0
Generated unique IDs.
mitk::Image::ConstPointer inputImage
Base of all data objects.
Definition: mitkBaseData.h:42
std::map< ParameterNameType, double > DerivedParamterScaleMapType
virtual ParamterUnitMapType GetParameterUnits() const =0
static const std::string MODEL_TYPE_PROPERTY_NAME()
#define MITK_ERROR
Definition: mitkLogMacros.h:20
virtual std::string GetXAxisUnit() const =0
static const std::string YAXIS_NAME_PROPERTY_NAME()
std::map< ParameterNameType, double > ParamterScaleMapType
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
Parameter::ConstPointer GetParameter(const std::string &name, const Parameter::Type &type) const
Searches for the parameter with the given name and type in the fit&#39;s parameter list and returns it...
static const std::string MODEL_NAME_PROPERTY_NAME()
MITKMODELFIT_EXPORT Parameter::Pointer ExtractParameterFromData(const mitk::BaseData *data)
MITKMODELFIT_EXPORT ModelFitInfo::Pointer CreateFitInfoFromModelParameterizer(const ModelParameterizerBase *usedParameterizer, mitk::BaseData *inputImage, const std::string &fitType, const std::string &fitName="", const ModelFitInfo::UIDType &roiUID="")
Data class for modelfit properties that store a map of lists (e.g. static parameters).
StaticParameterMap staticParamMap
static void info(const char *fmt,...)
Definition: svm.cpp:86
static const std::string FIT_UID_PROPERTY_NAME()
static const std::string MODEL_FUNCTION_PROPERTY_NAME()
void AddParameter(Parameter::Pointer p)
Adds the given parameter to this fit&#39;s parameter list if it doesn&#39;t exist already.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
std::vector< ParameterNameType > ParameterNamesType
#define MITK_WARN
Definition: mitkLogMacros.h:19
ParameterNamesType DerivedParameterNamesType
static const std::string FIT_INPUT_DATA_PROPERTY_NAME()
virtual ParameterNamesType GetParameterNames() const =0
static const std::string XAXIS_NAME_PROPERTY_NAME()
#define mitkThrow()
SetOfObjects::ConstPointer GetSubset(const NodePredicateBase *condition) const
returns a set of data objects that meet the given condition(s)
virtual ParamterScaleMapType GetParameterScales() const =0
Image class for storing images.
Definition: mitkImage.h:72
static Pointer New(const char *_arg)
virtual std::string GetYAxisName() const =0
MITKMODELFIT_EXPORT ModelFitInfo::Pointer CreateFitInfoFromNode(const ModelFitInfo::UIDType &uid, const mitk::DataStorage *storage)
Creates a new ModelFitInfo instance from the nodes in the passed storage. The fit will be identified ...
virtual std::string GetXName() const =0
static const std::string MODEL_X_PROPERTY_NAME()
const LookupTableType & GetLookupTable() const
Returns the map of lists.
mitk::PropertyList::Pointer GetPropertyList() const
Get the data&#39;s property list.
static const std::string MODEL_FUNCTION_CLASS_PROPERTY_NAME()
virtual std::string GetXAxisName() const =0
virtual FunctionStringType GetFunctionString() const =0
#define mitkThrowException(classname)
virtual std::string GetModelDisplayName() const =0
static const std::string FIT_INPUT_ROIUID_PROPERTY_NAME()
static const std::string YAXIS_UNIT_PROPERTY_NAME()
Class-specific exception for modelfits.
ScalarListLookupTable inputData
static const std::string FIT_STATIC_PARAMETERS_PROPERTY_NAME()
std::set< ModelFitInfo::UIDType > NodeUIDSetType
ParamListType::const_iterator ConstIterType
static const std::string FIT_NAME_PROPERTY_NAME()
const ParamListType & GetParameters() const
static const std::string XAXIS_UNIT_PROPERTY_NAME()
ModelBaseType::StaticParameterMapType StaticParameterMapType
virtual std::string GetModelType() const =0
std::vector< Parameter::Pointer > ParamListType
MITKMODELFIT_EXPORT const std::string GetMandatoryProperty(const mitk::DataNode *node, const std::string &prop)
Reads the string property with the given name from the data of the given node and returns its value...
std::map< ParameterNameType, std::string > ParamterUnitMapType
std::map< KeyType, ValueType > LookupTableType
virtual std::string GetYAxisUnit() const =0
static Pointer New()
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="name") const
Convenience access method for accessing the name of an object (instance of StringProperty with proper...
Definition: mitkDataNode.h:368
std::map< ParameterNameType, std::string > DerivedParamterUnitMapType
virtual DerivedParameterNamesType GetDerivedParameterNames() const =0
virtual DerivedParamterUnitMapType GetDerivedParameterUnits() const =0