Fraxinus  17.12-rc3
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxDicomModelNode.h"
34 
35 namespace cx
36 {
37 
39 
41 {
42  if (!NullNode)
43  {
44  NullNode.reset(new NullDicomModelNode);
45  NullNode->Parent = NullNode.get();
46 // NullNode->Row = -1;
47  }
48 
49  return NullNode;
50 }
51 
52 NodePtr DicomModelNode::createNode(int row, DicomModelNode* parent, QSharedPointer<ctkDICOMDatabase> dataBase)
53 {
54  if (!dataBase)
56 
57  NodePtr node;
58  if (row == -1)
59  {
60  node.reset(new RootDicomModelNode);
61  node->Parent = DicomModelNode::getNullNode().get();
62  }
63  else
64  {
66 
67  if (type==DICOMModel::PatientType)
68  node.reset(new PatientDicomModelNode);
69  if (type==DICOMModel::StudyType)
70  node.reset(new StudyDicomModelNode);
71  if (type==DICOMModel::SeriesType)
72  node.reset(new SeriesDicomModelNode);
73 
74  parent->FetchedChildren.push_back(node);
75  node->Parent = parent;
76  node->UID = parent->ChildrenUID[row];
77  }
78 
79 // node->Row = row;
80  node->DataBase = dataBase;
81 
82  node->fillChildrenUids();
83 
84  return node;
85 }
86 
88 // Row(-1),
89  Parent(0)
90 {
91 
92 }
93 
94 //---------------------------------------------------------
95 //---------------------------------------------------------
96 //---------------------------------------------------------
97 
98 QStringList DicomModelNode::getHeaders() const
99 {
100  QStringList retval;
101  retval << "Name";
102  retval << "Date";
103  retval << "Modality";
104  retval << "Images";
105 // retval << "Info";
106  return retval;
107 }
108 
110 {
111  return FetchedChildren.size() != ChildrenUID.size();
112 }
113 
115 {
116  return !ChildrenUID.empty();
117 }
118 
120 {
121  if (row < this->FetchedChildren.size())
122  return this->FetchedChildren[row];
124 }
125 
127 {
128  QString filename = this->getFirstDICOMFilename();
129  return DicomImageReader::createFromFile(filename);
130 }
131 
132 QVariant DicomModelNode::getValue(int column) const
133 {
134  if (!this->CachedValues.count(column))
135  {
136  QVariant value = this->getUncachedValue(column);
137  this->CachedValues[column] = value;
138  }
139 
140  return this->CachedValues[column];
141 }
142 
143 QVariant DicomModelNode::getUncachedValue(int column) const
144 {
145  if (column==0)
146  return this->getName();
147  if (column==1)
148  return this->getTimestamp();
149  if (column==2)
150  return this->getModality();
151  if (column==3)
152  return this->getImageCount();
153  return QVariant();
154 }
155 
157 {
158  if (index < ChildrenUID.size())
159  ChildrenUID.removeAt(index);
160  if (index < FetchedChildren.size())
161  {
162  std::vector<NodePtr>::iterator iter = FetchedChildren.begin();
163  std::advance(iter, index);
164  FetchedChildren.erase(iter);
165  }
166  CachedValues.erase(index);
167 }
168 
170 {
171  const std::vector<NodePtr>& siblings = Parent->getFetchedChildren();
172  for (int i=0; i<siblings.size(); ++i)
173  if (siblings[i].get()==this)
174  return i;
175  return -1;
176 }
177 
178 
179 //---------------------------------------------------------
180 //---------------------------------------------------------
181 //---------------------------------------------------------
182 
184 {
185 // qDebug() << "using db " << DataBase.data();
186 // qDebug() << "using patients " << DataBase->patients();
187 
188  this->ChildrenUID << DataBase->patients();
189 }
190 
191 //---------------------------------------------------------
192 //---------------------------------------------------------
193 //---------------------------------------------------------
194 
196 {
197  this->ChildrenUID << DataBase->studiesForPatient(this->UID);
198 }
199 
201 {
202  DicomImageReaderPtr reader = this->createReader();
203  if (!reader)
204  return QVariant();
205  QString retval = reader->getPatientName();
206  if (retval.isEmpty())
207  return this->getDefaultName();
208  return retval;
209 }
210 
212 {
213  DicomImageReaderPtr reader = this->createReader();
214  if (!reader)
215  return QVariant();
216  return reader->item()->GetElementAsDate(DCM_PatientBirthDate).toString(this->format_date());
217 }
218 
220 {
221  QStringList studies = DataBase->studiesForPatient(this->UID);
222  if (studies.empty())
223  return "";
224  QStringList series = DataBase->seriesForStudy(studies[0]);
225  if (series.empty())
226  return "";
227  QStringList files = DataBase->filesForSeries(series[0]);
228  if (files.empty())
229  return "";
230  return files[0];
231 }
232 
233 //---------------------------------------------------------
234 //---------------------------------------------------------
235 //---------------------------------------------------------
236 
238 {
239  this->ChildrenUID << DataBase->seriesForStudy(this->UID);
240 }
241 
243 {
244  DicomImageReaderPtr reader = this->createReader();
245  if (!reader)
246  return QVariant();
247  QString retval = reader->item()->GetElementAsString(DCM_StudyDescription);
248  if (retval.isEmpty())
249  return this->getDefaultName();
250  return retval;
251 }
252 
254 {
255  DicomImageReaderPtr reader = this->createReader();
256  if (!reader)
257  return QVariant();
258  QString date = reader->item()->GetElementAsDate(DCM_StudyDate).toString(this->format_date());
259  QString time = reader->item()->GetElementAsTime(DCM_StudyTime).toString(this->format_time());
260  return QString("%1 %2").arg(date).arg(time);
261 }
262 
264 {
265  QStringList series = DataBase->seriesForStudy(this->UID);
266  if (series.empty())
267  return "";
268  QStringList files = DataBase->filesForSeries(series[0]);
269  if (files.empty())
270  return "";
271  return files[0];
272 }
273 
274 //---------------------------------------------------------
275 //---------------------------------------------------------
276 //---------------------------------------------------------
277 
278 
280 {
281  DicomImageReaderPtr reader = this->createReader();
282  if (!reader)
283  return QVariant();
284  QString retval = reader->item()->GetElementAsString(DCM_SeriesDescription);
285  if (retval.isEmpty())
286  return this->getDefaultName();
287  return retval;
288 }
289 
291 {
292  DicomImageReaderPtr reader = this->createReader();
293  if (!reader)
294  return QVariant();
295  QString date = reader->item()->GetElementAsDate(DCM_SeriesDate).toString(this->format_date());
296  QString time = reader->item()->GetElementAsTime(DCM_SeriesTime).toString(this->format_time());
297  return QString("%1 %2").arg(date).arg(time);
298 }
299 
301 {
302  DicomImageReaderPtr reader = this->createReader();
303  if (!reader)
304  return QVariant();
305  return reader->item()->GetElementAsString(DCM_Modality);
306 }
307 
309 {
310  return QString("%1").arg(this->getFrameCountForSeries(this->UID));
311 }
312 
314 {
315  QStringList files = DataBase->filesForSeries(this->UID);
316  if (files.empty())
317  return "";
318  return files[0];
319 }
320 
322 {
323  QString seriesDescription;
324  int frameCount = 0;
325  QStringList files = DataBase->filesForSeries(series);
326  for (unsigned i=0; i<files.size(); ++i)
327  {
329  if (!reader)
330  continue;
331  frameCount += reader->getNumberOfFrames();
332  seriesDescription = reader->item()->GetElementAsString(DCM_SeriesDescription);
333  }
334  return frameCount;
335 }
336 
337 
338 } // namespace cx
339 
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