CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxRegistrationApplicator.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
13 
14 #include "cxData.h"
15 #include "cxTypeConversions.h"
16 #include "cxLogger.h"
17 
19 #include "cxFrameForest.h"
20 
21 
22 
23 namespace cx
24 {
25 
26 RegistrationApplicator::RegistrationApplicator(const std::map<QString, DataPtr> &source) :
27  mSource(source)
28 {
29 
30 }
31 
33 {
34 
35 }
36 
43 {
44  bool silent = delta_pre_rMd.mTemp;
45  FrameForest forest(mSource);
46  QDomNode moving = forest.getNode(delta_pre_rMd.mMoving);
47  DataPtr movingData = mSource[delta_pre_rMd.mMoving];
48  QDomNode fixed = forest.getNode(delta_pre_rMd.mFixed);
49 
50  // if no parent, assume this is an operation on the moving image, thus set fixed to its parent.
51  if (delta_pre_rMd.mFixed == "")
52  {
53  fixed = forest.getNode(movingData->getParentSpace());
54  }
55  QDomNode movingBase = forest.getOldestAncestorNotCommonToRef(moving, fixed);
56 
57  std::vector<DataPtr> allMovingData = forest.getDataFromDescendantsAndSelf(movingBase);
58 
59  if(!silent)
60  report(QString(""
61  "Update Registration using\n"
62  "\tFixed:\t%1\n"
63  "\tMoving:\t%2\n"
64  "\tDelta matrix (rMd'=Delta*rMd)\n"
65  "%3")
66  .arg(delta_pre_rMd.mFixed)
67  .arg(delta_pre_rMd.mMoving)
68  .arg(qstring_cast(delta_pre_rMd.mValue)));
69 
70  this->updateTransform(oldTime, allMovingData, delta_pre_rMd);
71 
72  // reconnect only if master and target are unconnected, i.e. doesnt share a common ancestor.
73  // If we are registrating inside an already connected tree we only want to change transforms,
74  // not change the topology of the tree.
75  if (forest.getOldestAncestor(moving) != forest.getOldestAncestor(fixed))
76  {
77  // connect the target to the master's ancestor, i.e. replace targetBase with masterAncestor:
78 
79  QDomNode fixedAncestor = forest.getOldestAncestor(fixed);
80  QString fixedAncestorUid = fixedAncestor.toElement().tagName();
81 
82  QString newFixedSpace = fixedAncestorUid;
83 
84  // if fixedAncestor is a data, insert a pure space above it
85  if (mSource.count(fixedAncestorUid) && mSource[fixedAncestorUid]->getParentSpace()=="")
86  {
87  newFixedSpace = this->generateNewSpaceUid();
88  ParentSpace newParentSpace(newFixedSpace, delta_pre_rMd.mTimestamp, delta_pre_rMd.mType);
89  this->changeParentSpace(oldTime, mSource[fixedAncestorUid], newParentSpace);
90  }
91 
92  QString movingBaseUid = movingBase.toElement().tagName();
93  // if movingBaseUid is a data, then move the space above it
94  if (mSource.count(movingBaseUid))
95  {
96  movingBaseUid = mSource[movingBaseUid]->getParentSpace();
97  }
98 
99  // change parent space of all moving spaces connected to base
100  ParentSpace newParentSpace(newFixedSpace, delta_pre_rMd.mTimestamp, delta_pre_rMd.mType);
101  this->changeParentSpace(oldTime, allMovingData, movingBaseUid, newParentSpace);
102  }
103 }
104 
105 QString RegistrationApplicator::generateNewSpaceUid() const
106 {
107  int max = 0;
108  std::map<QString, DataPtr>::const_iterator iter;
109  for (iter = mSource.begin(); iter != mSource.end(); ++iter)
110  {
111  QStringList parentList = qstring_cast(iter->second->getParentSpace()).split("_");
112  if (parentList.size() < 2)
113  continue;
114  max = std::max(max, parentList[1].toInt());
115  }
116  QString parentFrame = "frame_" + qstring_cast(max + 1);
117  return parentFrame;
118 }
119 
120 void RegistrationApplicator::updateTransform(QDateTime oldTime, std::vector<DataPtr> data, RegistrationTransform delta_pre_rMd)
121 {
122  bool silent = delta_pre_rMd.mTemp;
123  // update the transform on all target data:
124  for (unsigned i=0; i<data.size(); ++i)
125  {
126  RegistrationTransform newTransform = delta_pre_rMd;
127  newTransform.mValue = delta_pre_rMd.mValue * data[i]->get_rMd();
128  data[i]->get_rMd_History()->addOrUpdateRegistration(oldTime, newTransform);
129 
130  if(!silent)
131  report("Updated registration of data " + data[i]->getName());
132  }
133 }
134 
135 void RegistrationApplicator::changeParentSpace(QDateTime oldTime, std::vector<DataPtr> data, QString oldParentSpace, ParentSpace newParentSpace)
136 {
137  for (unsigned i=0; i<data.size(); ++i)
138  {
139  if (data[i]->getParentSpace() != oldParentSpace)
140  continue;
141  this->changeParentSpace(oldTime, data[i], newParentSpace);
142  }
143 }
144 
145 void RegistrationApplicator::changeParentSpace(QDateTime oldTime, DataPtr data, ParentSpace newParentSpace)
146 {
147  report(QString("Reset parent frame of %1 from [%2] to [%3].")
148  .arg(data->getName())
149  .arg(data->getParentSpace())
150  .arg(newParentSpace.mUid));
151 
152  data->get_rMd_History()->updateParentSpace(oldTime, newParentSpace);
153 }
154 
155 } // namespace cx
QString qstring_cast(const T &val)
QDomNode getOldestAncestor(QDomNode node)
Definition of a parent space event.
virtual void updateRegistration(QDateTime oldTime, RegistrationTransform deltaTransform)
A graph combining Space dependencies between all Data.Relations between coordinate spaces among Data ...
Definition: cxFrameForest.h:64
QString mUid
parent frame uid
std::vector< DataPtr > getDataFromDescendantsAndSelf(QDomNode node)
boost::shared_ptr< class Data > DataPtr
RegistrationApplicator(const std::map< QString, DataPtr > &source)
QDateTime mTimestamp
time the transform was registrated.
Transform3D mValue
value of transform
QDomNode getNode(QString frame)
QString mType
description of the kind if registration (manual, patient, landmark, coregistration etc) ...
A registration event and its transform.
void report(QString msg)
Definition: cxLogger.cpp:69
QDomNode getOldestAncestorNotCommonToRef(QDomNode child, QDomNode ref)
Namespace for all CustusX production code.