CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxDicomModelNode.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 
12 #include "cxDicomModelNode.h"
13 
14 namespace cx
15 {
16 
18 
20 {
21  if (!NullNode)
22  {
23  NullNode.reset(new NullDicomModelNode);
24  NullNode->Parent = NullNode.get();
25 // NullNode->Row = -1;
26  }
27 
28  return NullNode;
29 }
30 
31 NodePtr DicomModelNode::createNode(int row, DicomModelNode* parent, QSharedPointer<ctkDICOMDatabase> dataBase)
32 {
33  if (!dataBase)
35 
36  NodePtr node;
37  if (row == -1)
38  {
39  node.reset(new RootDicomModelNode);
40  node->Parent = DicomModelNode::getNullNode().get();
41  }
42  else
43  {
45 
46  if (type==DICOMModel::PatientType)
47  node.reset(new PatientDicomModelNode);
48  if (type==DICOMModel::StudyType)
49  node.reset(new StudyDicomModelNode);
50  if (type==DICOMModel::SeriesType)
51  node.reset(new SeriesDicomModelNode);
52 
53  parent->FetchedChildren.push_back(node);
54  node->Parent = parent;
55  node->UID = parent->ChildrenUID[row];
56  }
57 
58 // node->Row = row;
59  node->DataBase = dataBase;
60 
61  node->fillChildrenUids();
62 
63  return node;
64 }
65 
67 // Row(-1),
68  Parent(0)
69 {
70 
71 }
72 
73 //---------------------------------------------------------
74 //---------------------------------------------------------
75 //---------------------------------------------------------
76 
77 QStringList DicomModelNode::getHeaders() const
78 {
79  QStringList retval;
80  retval << "Name";
81  retval << "Date";
82  retval << "Modality";
83  retval << "Images";
84 // retval << "Info";
85  return retval;
86 }
87 
89 {
90  return FetchedChildren.size() != ChildrenUID.size();
91 }
92 
94 {
95  return !ChildrenUID.empty();
96 }
97 
99 {
100  if (row < this->FetchedChildren.size())
101  return this->FetchedChildren[row];
103 }
104 
106 {
107  QString filename = this->getFirstDICOMFilename();
108  return DicomImageReader::createFromFile(filename);
109 }
110 
111 QVariant DicomModelNode::getValue(int column) const
112 {
113  if (!this->CachedValues.count(column))
114  {
115  QVariant value = this->getUncachedValue(column);
116  this->CachedValues[column] = value;
117  }
118 
119  return this->CachedValues[column];
120 }
121 
122 QVariant DicomModelNode::getUncachedValue(int column) const
123 {
124  if (column==0)
125  return this->getName();
126  if (column==1)
127  return this->getTimestamp();
128  if (column==2)
129  return this->getModality();
130  if (column==3)
131  return this->getImageCount();
132  return QVariant();
133 }
134 
136 {
137  if (index < ChildrenUID.size())
138  ChildrenUID.removeAt(index);
139  if (index < FetchedChildren.size())
140  {
141  std::vector<NodePtr>::iterator iter = FetchedChildren.begin();
142  std::advance(iter, index);
143  FetchedChildren.erase(iter);
144  }
145  CachedValues.erase(index);
146 }
147 
149 {
150  const std::vector<NodePtr>& siblings = Parent->getFetchedChildren();
151  for (int i=0; i<siblings.size(); ++i)
152  if (siblings[i].get()==this)
153  return i;
154  return -1;
155 }
156 
157 
158 //---------------------------------------------------------
159 //---------------------------------------------------------
160 //---------------------------------------------------------
161 
163 {
164 // qDebug() << "using db " << DataBase.data();
165 // qDebug() << "using patients " << DataBase->patients();
166 
167  this->ChildrenUID << DataBase->patients();
168 }
169 
170 //---------------------------------------------------------
171 //---------------------------------------------------------
172 //---------------------------------------------------------
173 
175 {
176  this->ChildrenUID << DataBase->studiesForPatient(this->UID);
177 }
178 
180 {
181  DicomImageReaderPtr reader = this->createReader();
182  if (!reader)
183  return QVariant();
184  QString retval = reader->getPatientName();
185  if (retval.isEmpty())
186  return this->getDefaultName();
187  return retval;
188 }
189 
191 {
192  DicomImageReaderPtr reader = this->createReader();
193  if (!reader)
194  return QVariant();
195  return reader->item()->GetElementAsDate(DCM_PatientBirthDate).toString(this->format_date());
196 }
197 
199 {
200  QStringList studies = DataBase->studiesForPatient(this->UID);
201  if (studies.empty())
202  return "";
203  QStringList series = DataBase->seriesForStudy(studies[0]);
204  if (series.empty())
205  return "";
206  QStringList files = DataBase->filesForSeries(series[0]);
207  if (files.empty())
208  return "";
209  return files[0];
210 }
211 
212 //---------------------------------------------------------
213 //---------------------------------------------------------
214 //---------------------------------------------------------
215 
217 {
218  this->ChildrenUID << DataBase->seriesForStudy(this->UID);
219 }
220 
222 {
223  DicomImageReaderPtr reader = this->createReader();
224  if (!reader)
225  return QVariant();
226  QString retval = reader->item()->GetElementAsString(DCM_StudyDescription);
227  if (retval.isEmpty())
228  return this->getDefaultName();
229  return retval;
230 }
231 
233 {
234  DicomImageReaderPtr reader = this->createReader();
235  if (!reader)
236  return QVariant();
237  QString date = reader->item()->GetElementAsDate(DCM_StudyDate).toString(this->format_date());
238  QString time = reader->item()->GetElementAsTime(DCM_StudyTime).toString(this->format_time());
239  return QString("%1 %2").arg(date).arg(time);
240 }
241 
243 {
244  QStringList series = DataBase->seriesForStudy(this->UID);
245  if (series.empty())
246  return "";
247  QStringList files = DataBase->filesForSeries(series[0]);
248  if (files.empty())
249  return "";
250  return files[0];
251 }
252 
253 //---------------------------------------------------------
254 //---------------------------------------------------------
255 //---------------------------------------------------------
256 
257 
259 {
260  DicomImageReaderPtr reader = this->createReader();
261  if (!reader)
262  return QVariant();
263  QString retval = reader->item()->GetElementAsString(DCM_SeriesDescription);
264  if (retval.isEmpty())
265  return this->getDefaultName();
266  return retval;
267 }
268 
270 {
271  DicomImageReaderPtr reader = this->createReader();
272  if (!reader)
273  return QVariant();
274  QString date = reader->item()->GetElementAsDate(DCM_SeriesDate).toString(this->format_date());
275  QString time = reader->item()->GetElementAsTime(DCM_SeriesTime).toString(this->format_time());
276  return QString("%1 %2").arg(date).arg(time);
277 }
278 
280 {
281  DicomImageReaderPtr reader = this->createReader();
282  if (!reader)
283  return QVariant();
284  return reader->item()->GetElementAsString(DCM_Modality);
285 }
286 
288 {
289  return QString("%1").arg(this->getFrameCountForSeries(this->UID));
290 }
291 
293 {
294  QStringList files = DataBase->filesForSeries(this->UID);
295  if (files.empty())
296  return "";
297  return files[0];
298 }
299 
301 {
302  QString seriesDescription;
303  int frameCount = 0;
304  QStringList files = DataBase->filesForSeries(series);
305  for (unsigned i=0; i<files.size(); ++i)
306  {
308  if (!reader)
309  continue;
310  frameCount += reader->getNumberOfFrames();
311  seriesDescription = reader->item()->GetElementAsString(DCM_SeriesDescription);
312  }
313  return frameCount;
314 }
315 
316 
317 } // namespace cx
318 
static DicomImageReaderPtr createFromFile(QString filename)
std::vector< NodePtr > FetchedChildren
all children currently loaded (filled by fetchMore())
QString format_time() const
QSharedPointer< ctkDICOMDatabase > DataBase
boost::shared_ptr< class DicomModelNode > NodePtr
virtual QVariant getModality() const
virtual QString getFirstDICOMFilename() const
void removeChild(int index)
DicomModelNode * Parent
virtual QVariant getImageCount() const
DicomImageReaderPtr createReader() const
QStringList getHeaders() const
QVariant getDefaultName() const
virtual QVariant getName() const
QVariant getUncachedValue(int column) const
virtual QString getFirstDICOMFilename() const
QStringList ChildrenUID
uids of all loaded and unloaded children.
virtual void fillChildrenUids()
static NodePtr NullNode
bool hasChildren() const
const std::vector< NodePtr > & getFetchedChildren() const
all children currently loaded (filled by fetchMore())
static NodePtr createNode(int row, DicomModelNode *parent, QSharedPointer< ctkDICOMDatabase > dataBase)
virtual QVariant getTimestamp() const
virtual DICOMModel::IndexType getType() const =0
boost::shared_ptr< class DicomImageReader > DicomImageReaderPtr
virtual QVariant getTimestamp() const
virtual QVariant getTimestamp() const
virtual QVariant getName() const
static NodePtr getNullNode()
virtual QVariant getImageCount() const
int getFrameCountForSeries(QString series) const
virtual QVariant getName() const
std::map< int, QVariant > CachedValues
virtual QString getFirstDICOMFilename() const
virtual QString getFirstDICOMFilename() const
NodePtr getFetchedChildForRow(int row) const
virtual QVariant getName() const
QString format_date() const
bool canFetchMore() const
QVariant getValue(int column) const
virtual QVariant getModality() const
Namespace for all CustusX production code.
virtual QVariant getTimestamp() const