Medical Imaging Interaction Toolkit  2018.4.99-3e3f1a6e
Medical Imaging Interaction Toolkit
QmitkStatisticsTreeModel.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 // semantic relations UI module
15 
16 // semantic relations module
18 #include <mitkLesionManager.h>
21 #include <mitkRelationStorage.h>
22 
25  , m_RootItem(std::make_shared<QmitkLesionTreeItem>(mitk::LesionData()))
26 {
27  m_StatisticsCalculator = std::make_unique<QmitkStatisticsCalculator>();
28 }
29 
31 // overridden virtual functions from QAbstractItemModel
33 QModelIndex QmitkStatisticsTreeModel::index(int row, int column, const QModelIndex& itemIndex) const
34 {
35  if (!hasIndex(row, column, itemIndex))
36  {
37  return QModelIndex();
38  }
39 
40  auto childItem = GetItemByIndex(itemIndex)->GetChildInRow(row);
41  if (nullptr == childItem)
42  {
43  return QModelIndex();
44  }
45 
46  return createIndex(row, column, childItem.get());
47 }
48 
49 QModelIndex QmitkStatisticsTreeModel::parent(const QModelIndex& itemIndex) const
50 {
51  if (!itemIndex.isValid())
52  {
53  return QModelIndex();
54  }
55 
56  auto parentItemWeakPtr = GetItemByIndex(itemIndex)->GetParent();
57  if (parentItemWeakPtr.expired())
58  {
59  return QModelIndex();
60  }
61 
62  auto parentItem = parentItemWeakPtr.lock();
63  if (parentItem == m_RootItem)
64  {
65  return QModelIndex();
66  }
67 
68  return createIndex(parentItem->GetRow(), 0, parentItem.get());
69 }
70 
71 int QmitkStatisticsTreeModel::rowCount(const QModelIndex& itemIndex/* = QModelIndex()*/) const
72 {
73  return GetItemByIndex(itemIndex)->ChildCount();
74 }
75 
76 int QmitkStatisticsTreeModel::columnCount(const QModelIndex&/* itemIndex = QModelIndex() */) const
77 {
78  if (0 == m_RootItem->ChildCount())
79  {
80  // no lesion items stored, no need to display columns
81  return 0;
82  }
83 
84  return m_ControlPoints.size() + 1;
85 }
86 
87 QVariant QmitkStatisticsTreeModel::data(const QModelIndex& index, int role) const
88 {
89  if (!index.isValid())
90  {
91  return QVariant();
92  }
93 
94  if (index.column() < 0 || index.column() > static_cast<int>(m_ControlPoints.size()))
95  {
96  return QVariant();
97  }
98 
99  QmitkLesionTreeItem* currentItem = GetItemByIndex(index);
100  if (Qt::DisplayRole == role)
101  {
102  if (currentItem->GetParent().expired())
103  {
104  return QVariant();
105  }
106 
107  auto parentItem = currentItem->GetParent().lock();
108  // parent exists and is the root item -> top level item
109  if (m_RootItem == parentItem)
110  {
111  // display role fills the first columns with the lesion UID / name
112  if (0 == index.column())
113  {
114  std::string itemString = currentItem->GetData().GetLesionName();
115  if (itemString.empty())
116  {
117  itemString = currentItem->GetData().GetLesionUID();
118  }
119  return QString::fromStdString(itemString);
120  }
121  }
122  // parent is not the root item -> volume item
123  else
124  {
125  // display role fills the first columns with the information type
126  if (0 == index.column())
127  {
128  if (index.row() < static_cast<int>(m_InformationTypes.size()))
129  {
130  return QString::fromStdString(m_InformationTypes.at(index.row()));
131  }
132  return "N/A";
133  }
134  else
135  {
136  // display role fills other columns with the lesion volume info
137  const auto lesionVolume = currentItem->GetData().GetLesionVolume();
138  if ((index.column() - 1) * index.row() < static_cast<int>(lesionVolume.size()))
139  {
140  return QVariant(lesionVolume.at(index.row()*m_ControlPoints.size() + (index.column() - 1)));
141  }
142  return "N/A";
143  }
144  }
145  }
146 
147  return QVariant();
148 }
149 
150 QVariant QmitkStatisticsTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
151 {
152  if (0 == m_RootItem->ChildCount())
153  {
154  // no lesion items stored, no need to display the header
155  return QVariant();
156  }
157 
158  if (Qt::Horizontal == orientation && Qt::DisplayRole == role)
159  {
160  if (0 == section)
161  {
162  return QVariant("Lesion");
163  }
164 
165  if (static_cast<int>(m_ControlPoints.size()) >= section)
166  {
167  mitk::SemanticTypes::ControlPoint currentControlPoint = m_ControlPoints.at(section-1);
168  return QVariant(QString::fromStdString(currentControlPoint.ToString()));
169  }
170  }
171 
172  return QVariant();
173 }
174 
176 {
177  if (!m_DataStorage.IsExpired())
178  {
179  auto dataStorage = m_DataStorage.Lock();
180  m_SemanticRelationsDataStorageAccess = std::make_unique<mitk::SemanticRelationsDataStorageAccess>(dataStorage);
181  m_StatisticsCalculator->SetDataStorage(dataStorage);
182  UpdateModelData();
183  }
184 }
185 
187 {
188  emit beginResetModel();
189  UpdateModelData();
190  emit endResetModel();
191 }
192 
194 {
195  emit beginResetModel();
196  UpdateModelData();
197  emit endResetModel();
198 }
199 
201 {
202  emit beginResetModel();
203  UpdateModelData();
204  emit endResetModel();
205 }
206 
208 {
209  m_RootItem = std::make_shared<QmitkLesionTreeItem>(mitk::LesionData());
210 
211  // get all control points of current case
213  // sort the vector of control points for the timeline
214  std::sort(m_ControlPoints.begin(), m_ControlPoints.end());
215 
216  // get all information types points of current case
218 
219  SetLesionData();
220 }
221 
222 void QmitkStatisticsTreeModel::SetLesionData()
223 {
225  for (auto& lesion : m_CurrentLesions)
226  {
227  AddLesion(lesion);
228  }
229 }
230 
231 void QmitkStatisticsTreeModel::AddLesion(const mitk::SemanticTypes::Lesion& lesion)
232 {
233  if (m_DataStorage.IsExpired())
234  {
235  return;
236  }
237 
238  auto dataStorage = m_DataStorage.Lock();
239 
240  // create new lesion tree item data and modify it according to the control point data
241  mitk::LesionData lesionData(lesion);
242  m_StatisticsCalculator->ComputeLesionVolume(lesionData, m_CaseID);
243 
244  // add the 1. level lesion item to the root item
245  std::shared_ptr<QmitkLesionTreeItem> newLesionTreeItem = std::make_shared<QmitkLesionTreeItem>(lesionData);
246  m_RootItem->AddChild(newLesionTreeItem);
247 
248  for (size_t i = 0; i < m_InformationTypes.size(); ++i)
249  {
250  std::shared_ptr<QmitkLesionTreeItem> volumeItem = std::make_shared<QmitkLesionTreeItem>(lesionData);
251  newLesionTreeItem->AddChild(volumeItem);
252  }
253 }
254 
255 QmitkLesionTreeItem* QmitkStatisticsTreeModel::GetItemByIndex(const QModelIndex& index) const
256 {
257  if (index.isValid())
258  {
259  auto item = static_cast<QmitkLesionTreeItem*>(index.internalPointer());
260  if (nullptr != item)
261  {
262  return item;
263  }
264  }
265 
266  return m_RootItem.get();
267 }
int columnCount(const QModelIndex &itemIndex=QModelIndex()) const override
QModelIndex parent(const QModelIndex &itemIndex) const override
itk::SmartPointer< T > Lock() const
void NodeChanged(const mitk::DataNode *) override
void SetData() override
Overridden from &#39;QmitkAbstractSemanticRelationsStorageModel&#39;: This function retrieves all control poi...
std::string GetLesionName() const
mitk::LesionData & GetData()
Return the item data, which contains ...
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
STL namespace.
DataCollection - Class to facilitate loading/accessing structured data.
QmitkStatisticsTreeModel(QObject *parent=nullptr)
Initialize the root item of the model. The root item does not have a parent item. ...
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::InformationTypeVector GetAllInformationTypesOfCase(const SemanticTypes::CaseID &caseID)
void DataStorageChanged() override
Create a new &#39;SemanticRelationsDataStorageAccess&#39; instance with the new data storage and update the m...
std::unique_ptr< mitk::SemanticRelationsDataStorageAccess > m_SemanticRelationsDataStorageAccess
ChildPointer GetChildInRow(int row) const
Return the child of this item at a specific position.
int rowCount(const QModelIndex &itemIndex=QModelIndex()) const override
ParentPointer GetParent() const
Return the parent item.
bool IsExpired() const noexcept
This class holds the data of each lesion in the lesion tree view. The data is the lesion itself with ...
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::LesionVector GetAllLesionsOfCase(const SemanticTypes::CaseID &caseID)
const std::vector< double > & GetLesionVolume() const
SemanticTypes::ID GetLesionUID() const
QModelIndex index(int row, int column, const QModelIndex &itemIndex=QModelIndex()) const override
void NodeAdded(const mitk::DataNode *) override
vcl_size_t ChildCount() const
Return the number of child items.
void NodeRemoved(const mitk::DataNode *) override
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
mitk::WeakPointer< mitk::DataStorage > m_DataStorage
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ControlPointVector GetAllControlPointsOfCase(const SemanticTypes::CaseID &caseID)