Shapeworks Studio  2.1
Shape analysis software suite
itkPSMProject.cxx
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 
19 #include "itkPSMProject.h"
20 
21 namespace itk
22 {
23 
24 // Initialize reserved keywords for XML file tags
25 const std::string PSMProject::correspondences_tag = "correspondences";
26 const std::string PSMProject::cutting_plane_tag = "cutting_plane";
27 const std::string PSMProject::data_tag = "data";
28 const std::string PSMProject::distance_transform_tag = "distance_transform";
29 const std::string PSMProject::distance_transforms_tag = "distance_transforms";
30 const std::string PSMProject::domain_tag = "domain";
31 const std::string PSMProject::model_tag = "model";
32 const std::string PSMProject::name_tag = "name";
33 const std::string PSMProject::optimization_tag = "optimization";
34 const std::string PSMProject::number_of_scales_tag = "number_of_scales";
35 const std::string PSMProject::psm_project_tag = "psm_project";
36 const std::string PSMProject::preprocessing_tag = "preprocessing";
37 const std::string PSMProject::procrustes_tag = "procrustes_registration";
38 const std::string PSMProject::scale_tag = "scale";
39 const std::string PSMProject::scale_number_tag = "number";
40 const std::string PSMProject::variables_tag = "variables";
41 
43 {
44  if (dom->GetName() == psm_project_tag)
45  {
46  m_DOMNode = dom;
47  }
48  else
49  {
50  itkExceptionMacro( "DOM object does not appear to contain a valid PSM Project file." );
51  }
52 }
53 
54 
55 bool PSMProject
56 ::HasDomains() const
57 {
58  const PSMDOMNode *data = this->GetDataNode();
59 
60  // Search the data tree for nodes called domain_tag
61  DOMNode::ConstChildrenListType domains;
62  data->GetChildren(domain_tag, domains);
63 
64  // Did we find anything called a domain?
65  if (domains.size() == 0)
66  {
67  return false;
68  }
69  else return true;
70 
71 }
72 
73 const DOMNode *PSMProject
74 ::GetDomainNode(const std::string &name) const
75 {
76  // Look for the data section
77  const DOMNode *data = this->GetDataNode();
78 
79  // Compile the list of domains
80  DOMNode::ConstChildrenListType domains;
81  data->GetChildren(domain_tag, domains);
82 
83  for (unsigned int i = 0; i < domains.size(); i++)
84  {
85  // Look for the name
86  if (domains[i]->HasAttribute(name_tag))
87  {
88  if (domains[i]->GetAttribute(name_tag) == name)
89  {
90  return domains[i];
91  }
92  }
93  }
94 
95  // Didn't find the name!
96  itkExceptionMacro( "Could not find a domain called " + name );
97  return 0;
98 }
99 
100 bool PSMProject
101 ::HasDomainDistanceTransform(const std::string &name) const
102 {
103 
104  const DOMNode *domain = this->GetDomainNode(name);
105  const DOMNode *dt = domain->GetChild(distance_transform_tag);
106 
107  if (dt == 0)
108  {
109  return false;
110  }
111  else
112  {
113  return true;
114  }
115 }
116 
117 const std::vector<std::string > &PSMProject
118 ::GetDomainDistanceTransform(const std::string &name) const
119 {
120 
121  const DOMNode *domain = this->GetDomainNode(name);
122  const DOMNode *dt = domain->GetChild(distance_transform_tag);
123 
124  if (dt == 0)
125  {
126  itkExceptionMacro("No distance transform filename was found in the domain called " + name + " ");
127  }
128 
129  return ((dynamic_cast<const PSMDOMNode *>(dt))->GetText());
130 }
131 
132 std::vector<std::string>
134 {
135  const PSMDOMNode *data = this->GetDataNode();
136 
137  // Search the data tree for nodes called domain_tag
138  DOMNode::ConstChildrenListType domains;
139  data->GetChildren(domain_tag, domains);
140 
141  // Did we find anything called a domain?
142  if (domains.size() == 0)
143  {
144  itkExceptionMacro( "PSM Project file does not specify any elements called " + domain_tag );
145  }
146 
147  std::vector<std::string> s;
148 
149  // Compile the list of names of the domains
150  for (unsigned int i = 0; i < domains.size(); i++)
151  {
152  if (domains[i]->HasAttribute(name_tag))
153  {
154  s.push_back(domains[i]->GetAttribute(name_tag));
155  }
156  else
157  {
158  itkExceptionMacro( "The name attribute is missing from a PSM Project file" + model_tag + ".");
159  }
160  }
161  return s;
162 }
163 
164 bool PSMProject
165 ::HasDomainCuttingPlanes(const std::string &name) const
166 {
167  const DOMNode *domain = this->GetDomainNode(name);
168 
169  // Search the domain for nodes called cutting_plane
170  DOMNode::ConstChildrenListType p;
171  domain->GetChildren(cutting_plane_tag, p);
172 
173  // Did we find anything called a cutting plane?
174  if (p.size() > 0)
175  {
176  return true;
177  }
178  else
179  {
180  return false;
181  }
182 }
183 
184 std::vector<vnl_vector_fixed<double,3> > PSMProject
185 ::GetDomainCuttingPlanes(const std::string &name) const
186 {
187  const DOMNode *domain = this->GetDomainNode(name);
188 
189  // Search the domain for nodes called cutting_plane
190  DOMNode::ConstChildrenListType p;
191  domain->GetChildren(cutting_plane_tag, p);
192 
193  // Did we find anything called a cutting plane? If not, this is an
194  // error. Proper way is to check for cutting planes first using
195  // HasDomainCuttingPlanes.
196  if (p.size() == 0)
197  {
198  itkExceptionMacro("Did not find cutting planes in domain " + name + " ");
199  }
200 
201  std::vector<vnl_vector_fixed<double,3> > planes;
202 
203  for (unsigned int i = 0; i < p.size(); i++)
204  {
205  std::istringstream inputsBuffer;
206  std::vector<double> pts;
207  double pt;
208 
209  std::vector<std::string> txt
210  = dynamic_cast<const PSMDOMNode *>(p[i])->GetText();
211  for (unsigned int j = 0; j < txt.size(); j++)
212  {
213  inputsBuffer.str(txt[j]);
214 
215  while (inputsBuffer >> pt)
216  { pts.push_back(pt); }
217 
218  inputsBuffer.clear();
219  }
220 
221  // If we didn't get the right number of points, throw an
222  // exception.
223  if (pts.size() != 9)
224  {
225  itkExceptionMacro("Cutting plane data for " + name + " does not consist of three points.");
226  }
227 
228  vnl_vector_fixed<double,3> x;
229  vnl_vector_fixed<double,3> y;
230  vnl_vector_fixed<double,3> z;
231  x[0] = pts[0]; x[1] = pts[1]; x[2] = pts[2];
232  y[0] = pts[3]; y[1] = pts[4]; y[2] = pts[5];
233  z[0] = pts[6]; z[1] = pts[7]; z[2] = pts[8];
234 
235  planes.push_back(x);
236  planes.push_back(y);
237  planes.push_back(z);
238 
239  }
240 
241  return planes;
242 }
243 
244 unsigned int PSMProject
246 {
247  DOMNode *opt = m_DOMNode->GetChild(optimization_tag);
248 
249  if (opt != 0)
250  {
251  if (opt->HasAttribute(number_of_scales_tag))
252  {
253  return static_cast<unsigned int>(atoi(opt->GetAttribute(number_of_scales_tag).c_str()));
254  }
255  else
256  {
257  itkExceptionMacro("Number of scales not specified");
258  }
259  }
260 
261  itkExceptionMacro("No " + optimization_tag + " was found.");
262 }
263 
264 bool PSMProject
265 ::HasOptimizationAttribute(const std::string& name, unsigned int s) const
266 {
267  DOMNode *opt = m_DOMNode->GetChild(optimization_tag);
268  if (opt != 0) // found the optimization element
269  {
270  unsigned int nscales = 1;
271 
272  // Are there scale elements?
273  if (opt->HasAttribute(number_of_scales_tag))
274  {
275  nscales = static_cast<unsigned int>(atoi(opt->GetAttribute(number_of_scales_tag).c_str()));
276  // If the number_of_scales_tag is the one being checked
277  if(name == number_of_scales_tag) { return true; }
278  }
279 
280  // Did the user ask for a scale that isn't specified?
281  if (s+1 > nscales) { return false; }
282 
283  // If only one scale, then look in element attributes for name
284  if (nscales == 1)
285  {
286  if (opt->HasAttribute(name)) { return true; }
287  }
288 
289  // Finally, look for a scale element with name i
290  DOMNode::ChildrenListType children;
291  opt->GetAllChildren(children);
292 
293  for (unsigned i = 0; i < children.size(); i++)
294  {
295  if ( children[i]->GetName() == scale_tag
296  &&
297  static_cast<unsigned int>(atoi(children[i]->GetAttribute(scale_number_tag).c_str())) == s )
298  {
299  if (children[i]->HasAttribute(name)) { return true; }
300  else { return false; }
301  }
302  }
303  }
304  return false;
305 }
306 
307 double PSMProject
308 ::GetOptimizationAttribute(const std::string &name, unsigned int s) const
309 {
310  DOMNode *opt = m_DOMNode->GetChild(optimization_tag);
311  if (opt != 0) // found the optimization element
312  {
313  unsigned int nscales = 1;
314 
315  // Are there scale elements?
316  if (opt->HasAttribute(number_of_scales_tag))
317  {
318  nscales = static_cast<unsigned int>(atoi(opt->GetAttribute(number_of_scales_tag).c_str()));
319  }
320 
321  // Did the user ask for a scale that isn't specified?
322  if (s+1 > nscales)
323  {
324  itkExceptionMacro("Requested data for scale that was not specified.");
325  }
326 
327  // If only one scale, then look in element attributes for name
328  if (nscales == 1)
329  {
330  if (opt->HasAttribute(name))
331  {
332  return atof(opt->GetAttribute(name).c_str());
333  }
334  }
335 
336  // Finally, look for a scale element with name i
337  DOMNode::ChildrenListType children;
338  opt->GetAllChildren(children);
339 
340  for (unsigned i = 0; i < children.size(); i++)
341  {
342  if ( children[i]->GetName() == scale_tag
343  &&
344  static_cast<unsigned int>(atoi(children[i]->GetAttribute(scale_number_tag).c_str())) == s )
345  {
346  if (children[i]->HasAttribute(name))
347  {
348  return atof(children[i]->GetAttribute(name).c_str());
349  }
350  else
351  {
352  itkExceptionMacro("Found " + scale_tag + " element, but it does not have an attribute named " + name + ".");
353  }
354  }
355  }
356  }
357  itkExceptionMacro("File has no " + optimization_tag + " element");
358 }
359 
361 {
362  DOMNode *proc = m_DOMNode->GetChild(procrustes_tag);
363  if (proc != 0) // Found the procrustes element
364  {
365  if (proc->HasAttribute("value"))
366  {
367  if (atoi(proc->GetAttribute("value").c_str()) == 0)
368  return false;
369  else
370  return true;
371  }
372  }
373  return false;
374 }
375 
376 bool PSMProject::HasVariables(const std::string &name) const
377 {
378  const PSMDOMNode *data = this->GetDataNode();
379 
380  // Search the data tree for nodes called variables_tag
381  DOMNode::ConstChildrenListType variables;
382  data->GetChildren(variables_tag, variables);
383 
384  if (variables.size() == 0)
385  {
386  return false;
387  }
388 
389  // Search the list of variables for one with the correct name
390  for (unsigned int i = 0; i < variables.size(); i++)
391  {
392  if (variables[i]->HasAttribute(name_tag))
393  {
394  if (variables[i]->GetAttribute(name_tag) == name)
395  {
396  return true;
397  // return ((dynamic_cast<const PSMDOMNode *>(variables[i]))->GetText());
398  }
399  }
400  }
401  // itkExceptionMacro( "PSM Project file does not have any " + model_tag + " entries with name = " << name );
402  return false;
403 }
404 
405 std::vector<double> PSMProject::GetVariables(const std::string &name) const
406 {
407  const std::vector<std::string> &vartext = this->GetVariablesText(name);
408 
409  std::vector<double> ans;
410  for (unsigned int i = 0; i < vartext.size(); i++)
411  {
412  ans.push_back(atof(vartext[i].c_str()));
413  }
414  return ans;
415 }
416 
417 const std::vector<std::string > &PSMProject::GetVariablesText(const std::string &name) const
418 {
419  const PSMDOMNode *data = this->GetDataNode();
420 
421  // Search the data tree for nodes called variables_tag
422  DOMNode::ConstChildrenListType variables;
423  data->GetChildren(variables_tag, variables);
424 
425  if (variables.size() == 0)
426  {
427  itkExceptionMacro( "PSM Project file does not have any " + variables_tag + " entries with name = " << name );
428  }
429 
430  // Search the list of variables for one with the correct name
431  for (unsigned int i = 0; i < variables.size(); i++)
432  {
433  if (variables[i]->HasAttribute(name_tag))
434  {
435  if (variables[i]->GetAttribute(name_tag) == name)
436  {
437  return ((dynamic_cast<const PSMDOMNode *>(variables[i]))->GetText());
438  }
439  }
440  }
441  itkExceptionMacro( "PSM Project file does not have any " + variables_tag + " entries with name = " << name );
442 }
443 
445 {
446  // Look for the data section
447  const PSMDOMNode *data
448  = static_cast<const PSMDOMNode *>(m_DOMNode->GetChild(data_tag));
449 
450  if (data == 0) // data is not found
451  {
452  itkExceptionMacro( "PSM Project file does not specify " + data_tag );
453  }
454  else
455  {
456  return data;
457  }
458 }
459 
460 const std::vector<std::string> &
463 {
464  const PSMDOMNode *data = this->GetDataNode();
465 
466  const PSMDOMNode *dt = 0;
467  dt = static_cast<const PSMDOMNode *>(data->GetChild(distance_transforms_tag));
468  if (dt == 0)
469  {
470  itkExceptionMacro( "PSM Project file does not specify " + distance_transforms_tag );
471  }
472  else return dt->GetText();
473 }
474 
475 
476 const std::vector<std::string> &
477 PSMProject::GetModel(const std::string &name)
478 {
479  const PSMDOMNode *data = this->GetDataNode();
480 
481  // Search the data tree for nodes called model_tag
482  DOMNode::ConstChildrenListType models;
483  data->GetChildren(model_tag, models);
484 
485  if (models.size() == 0)
486  {
487  itkExceptionMacro( "PSM Project file does not specify any elements called " + model_tag );
488  }
489 
490  // Search the list of models for one with the correct name
491  for (unsigned int i = 0; i < models.size(); i++)
492  {
493  if (models[i]->HasAttribute(name_tag))
494  {
495  if (models[i]->GetAttribute(name_tag) == name)
496  {
497  return ((dynamic_cast<const PSMDOMNode *>(models[i]))->GetText());
498  }
499  }
500  }
501  itkExceptionMacro( "PSM Project file does not have any " + model_tag + " entries with name = " << name );
502 }
503 
504 
505 bool PSMProject::HasModel(const std::string &name) const
506 {
507  const PSMDOMNode *data = this->GetDataNode();
508 
509  // Search the data tree for nodes called model_tag
510  DOMNode::ConstChildrenListType models;
511  data->GetChildren(model_tag, models);
512 
513  if (models.size() == 0)
514  {
515  return false;
516  }
517 
518  // Search the list of variables for one with the correct name
519  for (unsigned int i = 0; i < models.size(); i++)
520  {
521  if (models[i]->HasAttribute(name_tag))
522  {
523  if (models[i]->GetAttribute(name_tag) == name)
524  {
525  return true;
526  }
527  }
528  }
529  return false;
530 }
531 
532 
533 void PSMProject::PrintSelf(std::ostream& os, Indent indent) const
534 {
535  Superclass::PrintSelf(os,indent);
536  // this->PrintChildren(m_DOMNode,os,indent);
537 
538 }
539 
540 void PSMProject::Stream(std::ostream &os)
541 {
542  Indent indent;
543 
544  this->StreamChildren(m_DOMNode,os,indent);
545 }
546 
547 void PSMProject::StreamChildren(PSMDOMNode *node,std::ostream &os, Indent indent)
548 {
549  // Print this node's name and attributes
550  os << indent << "<" << node->GetName();
551 
552  DOMNode::AttributesListType attr;
553  node->GetAllAttributes(attr);
554 
555  for (DOMNode::AttributesListType::const_iterator it = attr.begin();
556  it != attr.end(); it++)
557  {
558  os << " " << it->first << " = \"" << it->second << "\"";
559  }
560 
561 
562  os << ">" << std::endl;
563 
564  // Now print this node's text, line by line.
565  for (unsigned int i = 0; i < node->GetText().size(); i++)
566  {
567  os << indent.GetNextIndent() << node->GetText()[i] << std::endl;
568  }
569 
570  DOMNode::ChildrenListType children;
571  node->GetAllChildren(children);
572 
573  // Now print all of this node's children.
574  for (unsigned i = 0; i < children.size(); i++)
575  {
576  this->StreamChildren(static_cast<PSMDOMNode *>(children[i]),
577  os,indent.GetNextIndent());
578  }
579 
580  // Print the closing tag for this node.
581  os << indent << "<\\" << node->GetName() << ">" << std::endl;
582 }
583 
584 } // end namespace itk
static const std::string data_tag
Definition: itkPSMProject.h:63
bool HasDomainCuttingPlanes(const std::string &name) const
const std::vector< std::string > & GetVariablesText(const std::string &name) const
const std::vector< std::string > & GetText() const
Definition: itkPSMDOMNode.h:79
bool HasVariables(const std::string &name) const
const PSMDOMNode * GetDataNode() const
bool HasProcrustes() const
bool HasDomainDistanceTransform(const std::string &name) const
void SetDOMNode(PSMDOMNode *p)
std::vector< double > GetVariables(const std::string &name) const
std::vector< vnl_vector_fixed< double, 3 > > GetDomainCuttingPlanes(const std::string &name) const
Class to represent a node in the PSM Document Object Model (DOM) tree structure.
Definition: itkPSMDOMNode.h:46
const std::vector< std::string > & GetDomainDistanceTransform(const std::string &name) const
bool HasOptimizationAttribute(const std::string &name, unsigned int i=0) const
const std::vector< std::string > & GetModel(const std::string &name)
void StreamChildren(PSMDOMNode *, std::ostream &os, Indent indent)
const DOMNode * GetDomainNode(const std::string &name) const
void Stream(std::ostream &os)
const std::vector< std::string > & GetDistanceTransforms() const
bool HasDomains() const
double GetOptimizationAttribute(const std::string &name, unsigned int i=0) const
unsigned int GetNumberOfOptimizationScales() const
std::vector< std::string > GetDomainNames() const
bool HasModel(const std::string &name) const