1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #ifndef VVDICOMSERIESSELECTOR_CXX
19 #define VVDICOMSERIESSELECTOR_CXX
20 #include <itkGDCMImageIO.h>
21 #include <itkGDCMSeriesFileNames.h>
23 #if GDCM_MAJOR_VERSION == 2
24 #include <gdcmImageReader.h>
25 #include <gdcmDataSetHelper.h>
26 #include <gdcmStringFilter.h>
27 #include <gdcmImageHelper.h>
29 #include <gdcmDocEntry.h>
32 #include "vvQDicomSeriesSelector.h"
33 //#include "vvUserConfig.h"
35 //====================================================================
36 vvDicomSeriesSelector::vvDicomSeriesSelector(QWidget* parent)
41 // Correct GUI for splitter ...
42 // QSplitter * splitter = new QSplitter(this);
43 // splitter->setOrientation(Qt::Horizontal);
44 // ui.gridLayout1->addWidget(splitter, 0, 0, 1, 1);
45 // ui.mFrameLeft->setParent(splitter);
46 // ui.mFrameRight->setParent(splitter);
47 // ui.toolBox->setCurrentIndex(0);
51 ui.mButtonBox->button(QDialogButtonBox::Open)->setEnabled(false);
53 connect(ui.mBrowseButton, SIGNAL(released()),
54 this, SLOT(BrowseButtonRelease()));
55 connect(ui.mSearchButton, SIGNAL(released()),
56 this, SLOT(SearchButtonRelease()));
57 connect(ui.mListWidget, SIGNAL(itemSelectionChanged()),
58 this, SLOT(itemSelectionChanged()));
59 connect(ui.mDicomDetailsListWidget, SIGNAL(itemSelectionChanged()),
60 this, SLOT(itemDetailsSelectionChanged()));
61 connect(ui.mIsMatrixCheckBox, SIGNAL(stateChanged(int)),
62 this, SLOT(itemMatrixSelectionChanged(int)));
65 /* if (config::get_current_path() != QString(0))
66 mFoldername = config::get_current_path();
68 mFoldername = QFileInfo("./").absolutePath();
70 mPreviousPath = mFoldername;
71 ui.mFolderLineEdit->setText(mFoldername);
72 ui.mIsMatrixCheckBox->setChecked(0);
73 mPatientCoordinateSystem = false;
74 // ui.mTableWidget->setRowCount(0);
76 //====================================================================
78 //====================================================================
79 void vvDicomSeriesSelector::show()
83 // ui.mListWidget->grabKeyboard();
84 // ui.mDicomDetailsListWidget->grabKeyboard();
86 //====================================================================
88 //====================================================================
89 void vvDicomSeriesSelector::close()
92 // ui.mListWidget->releaseKeyboard()
95 //====================================================================
97 //====================================================================
98 void vvDicomSeriesSelector::BrowseButtonRelease()
100 QFileDialog dialog(this);
102 filters << "DICOM files (*.dcm)"
104 dialog.setFileMode(QFileDialog::AnyFile);
105 dialog.setNameFilters(filters);
106 //dialog.setFilter(tr("DICOM files (*.dcm); All files (*)"));
107 mFoldername = dialog.getExistingDirectory(this,
108 "Select a folder to find DICOM image",
110 ui.mFolderLineEdit->setText(mFoldername);
111 mPreviousPath = QFileInfo(mFoldername).absolutePath();
112 // config::set_current_path(mPreviousPath);
114 //====================================================================
116 //====================================================================
117 void vvDicomSeriesSelector::SearchButtonRelease()
119 typedef itk::GDCMSeriesFileNames NamesGeneratorType;
120 NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
121 nameGenerator->SetUseSeriesDetails(true);
122 //nameGenerator->SetDirectory(mFoldername.toStdString());
123 nameGenerator->SetRecursive(ui.mIsRecursiveCheckBox->checkState() == Qt::Checked);
125 //ds gérer recursive moi-meme pour progress ...
126 nameGenerator->SetInputDirectory(mFoldername.toStdString());
129 typedef std::vector<std::string> SeriesIdContainer;
130 const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
132 for (unsigned int i=0; i<seriesUID.size(); i++) {
133 // std::cout << seriesUID[i] << std::endl; //ds verif existe pas déja
135 if (mListOfSeriesFilenames[seriesUID[i]]) {
136 std::cout << seriesUID[i] << " exist" << std::endl;
139 std::vector<std::string> * filenames = new std::vector<std::string>;
140 const std::vector<std::string> & temp = nameGenerator->GetFileNames(seriesUID[i]);
141 for (unsigned int j=0; j<temp.size(); j++) {
142 filenames->push_back(temp[j]);
144 mListOfSeriesFilenames[seriesUID[i]] = filenames;
146 // store first header
147 #if GDCM_MAJOR_VERSION == 2
148 mDicomHeader[seriesUID[i]].SetFileName( (*filenames)[0].c_str() );
149 mDicomHeader[seriesUID[i]].Read();
151 gdcm::File *header = new gdcm::File();
152 header->SetFileName((*filenames)[0]);
153 header->SetMaxSizeLoadEntry(16384);
154 header->SetLoadMode(gdcm::LD_NOSHADOW);// don't load shadow tags (in order to save memory)
159 DD(header->GetEntryValue(0x0028,0x0030).c_str());
162 DD(header->GetXSize());
163 DD(header->GetYSize());
164 DD(header->GetZSize());
165 DD(header->GetXSpacing());
166 DD(header->GetYSpacing());
167 DD(header->GetZSpacing());
168 DD(header->GetXOrigin());
169 DD(header->GetYOrigin());
170 DD(header->GetZOrigin());
173 QString size = QString("%1x%2x%3")
174 .arg(header->GetXSize())
175 .arg(header->GetYSize())
176 .arg(header->GetZSize());
177 QString spacing = QString("%1x%2x%3")
178 .arg(header->GetXSpacing())
179 .arg(header->GetYSpacing())
180 .arg(header->GetZSpacing());
181 QString origin = QString("%1x%2x%3")
182 .arg(header->GetXOrigin())
183 .arg(header->GetYOrigin())
184 .arg(header->GetZOrigin());
188 mDicomHeader[seriesUID[i]] = header;
192 QListWidgetItem *newItem = new QListWidgetItem;
193 newItem->setText(seriesUID[i].c_str());
194 ui.mListWidget->insertItem(i, newItem);
196 //AddSerieToTheTable(i, *filenames);
200 //====================================================================
202 //====================================================================
203 void vvDicomSeriesSelector::itemSelectionChanged()
205 // mLabelSelected.setText(
206 mCurrentSerie = ui.mListWidget->selectedItems()[0]->text().toStdString();
207 mFilenames = mListOfSeriesFilenames[mCurrentSerie];
208 ui.mButtonBox->button(QDialogButtonBox::Open)->setEnabled(true);
210 if (mDicomInfo[mCurrentSerie] == "") {
212 // m = QString("Patient : <font color=\"blue\">%1</font><br>").arg(mDicomHeader[s]->GetEntryValue(0x0010,0x0010).c_str()); // Patient's name
214 mDicomInfo[mCurrentSerie] = MakeDicomInfo(mCurrentSerie, mDicomHeader[mCurrentSerie]);
216 ui.mDicomInfoPanel->setText(mDicomInfo[mCurrentSerie]);
219 ui.mDicomDetailsListWidget->clear();
220 for (unsigned int i=0; i<mFilenames->size(); i++) {
221 QListWidgetItem * newItem = new QListWidgetItem;
222 newItem->setText(QFileInfo((*mFilenames)[i].c_str()).fileName());
223 ui.mDicomDetailsListWidget->insertItem(i, newItem);
227 //====================================================================
229 //====================================================================
230 void vvDicomSeriesSelector::itemDetailsSelectionChanged()
232 unsigned int i = ui.mDicomDetailsListWidget->currentRow();
233 if (i<mFilenames->size()) {
234 if (mDicomDetails[(*mFilenames)[i]] == "") {
235 std::ostringstream s;
238 #if GDCM_MAJOR_VERSION == 2
239 mDicomHeader[mCurrentSerie].GetFile().Print(s);
240 const gdcm::File& header = mDicomHeader[mCurrentSerie].GetFile();
241 gdcm::StringFilter sf;
242 sf.SetFile( header );
243 const gdcm::DataSet &ds = header.GetDataSet();
244 gdcm::DataSet::ConstIterator it = ds.Begin();
245 for (; it != ds.End(); ++it )
247 const gdcm::DataElement & ref = *it;
248 const gdcm::Tag & tag = ref.GetTag();
249 gdcm::VR vr = gdcm::DataSetHelper::ComputeVR(header, ds, tag);
250 if ( vr & ( gdcm::VR::OB | gdcm::VR::OF | gdcm::VR::OW | gdcm::VR::SQ | gdcm::VR::UN ) )
252 // What is the behavior for binary stuff ?
254 else /* if ( vr & gdcm::VR::VRASCII ) */
256 if ( tag.IsPublic() )
258 std::pair<std::string, std::string> p = sf.ToStringPair(tag);
259 l += QString("%1 : %2\n")
260 .arg( p.first.c_str() )
261 .arg( p.second.c_str() );
266 mDicomHeader[mCurrentSerie]->Print(s);
267 gdcm::File * header = mDicomHeader[mCurrentSerie];
268 gdcm::DocEntry * e = header->GetFirstEntry();
270 if (e->GetName() != "gdcm::Unknown") {
271 l += QString("%1 : %2\n")
272 .arg(e->GetName().c_str())
273 .arg((header->GetEntryValue(e->GetGroup(), e->GetElement())).c_str());
275 e = header->GetNextEntry();
279 mDicomDetails[(*mFilenames)[i]] = l.toStdString();
281 ui.mDicomDetailsLabel->setText(mDicomDetails[(*mFilenames)[i]].c_str());
284 //====================================================================
286 //====================================================================
287 #if GDCM_MAJOR_VERSION == 2
288 QString vvDicomSeriesSelector::MakeDicomInfo(std::string & s, const gdcm::Reader& header)
290 QString n = QString("%1").arg(mListOfSeriesFilenames[s]->size());
291 const gdcm::File &f = header.GetFile();
292 std::vector<double> thespacing = gdcm::ImageHelper::GetSpacingValue(f);
293 std::vector<double> theorigin = gdcm::ImageHelper::GetOriginValue(f);
295 QString size = QString("%1x%2x%3")
299 QString spacing = QString("%1x%2x%3")
303 QString origin = QString("%1x%2x%3")
309 //AddInfo( "Serie ID : ", s)+
310 AddInfo(&header.GetFile(), "Patient : ", 0x0010,0x0010)+
311 AddInfo( "Folder : ", QFileInfo((*mFilenames)[0].c_str()).canonicalPath().toStdString())+
312 AddInfo(&header.GetFile(), "Series Description : ", 0x0008,0x103e)+
313 AddInfo(&header.GetFile(), "Modality : ", 0x0008,0x0060)+
314 AddInfo(&header.GetFile(), "# images : ", 0x0020,0x0013)+
315 AddInfo( "# files : ", n.toStdString())+
316 AddInfo( "Size : ", size.toStdString())+
317 AddInfo( "Spacing : ", spacing.toStdString())+
318 AddInfo( "Origin : ", origin.toStdString())+
319 AddInfo(&header.GetFile(), "Pixel size : ", 0x0028,0x0100)+
320 AddInfo( "Pixel type : ", "");
324 QString vvDicomSeriesSelector::MakeDicomInfo(std::string & s, gdcm::File *header)
326 QString n = QString("%1").arg(mListOfSeriesFilenames[s]->size());
327 QString size = QString("%1x%2x%3")
328 .arg(header->GetXSize())
329 .arg(header->GetYSize())
330 .arg(header->GetZSize());
331 QString spacing = QString("%1x%2x%3")
332 .arg(header->GetXSpacing())
333 .arg(header->GetYSpacing())
334 .arg(header->GetZSpacing());
335 QString origin = QString("%1x%2x%3")
336 .arg(header->GetXOrigin())
337 .arg(header->GetYOrigin())
338 .arg(header->GetZOrigin());
340 //AddInfo( "Serie ID : ", s)+
341 AddInfo(header, "Patient : ", 0x0010,0x0010)+
342 AddInfo( "Folder : ", QFileInfo((*mFilenames)[0].c_str()).canonicalPath().toStdString())+
343 AddInfo(header, "Series Description : ", 0x0008,0x103e)+
344 AddInfo(header, "Modality : ", 0x0008,0x0060)+
345 AddInfo(header, "# images : ", 0x0020,0x0013)+
346 AddInfo( "# files : ", n.toStdString())+
347 AddInfo( "Size : ", size.toStdString())+
348 AddInfo( "Spacing : ", spacing.toStdString())+
349 AddInfo( "Origin : ", origin.toStdString())+
350 AddInfo(header, "Pixel size : ", 0x0028,0x0100)+
351 AddInfo( "Pixel type : ", header->GetPixelType());
355 //====================================================================
357 //====================================================================
358 QString vvDicomSeriesSelector::AddInfo(const gdcm::File *header, QString n, uint16_t group, uint16_t elem)
360 #if GDCM_MAJOR_VERSION == 2
361 gdcm::StringFilter sf;
362 sf.SetFile( *header );
363 gdcm::Tag t( group, elem );
364 std::string s = sf.ToString( t );
365 return AddInfo(n.toStdString(), s);
367 return AddInfo(n.toStdString(), const_cast<gdcm::File*>(header)->GetEntryValue(group, elem));
370 //====================================================================
372 //====================================================================
373 QString vvDicomSeriesSelector::AddInfo(std::string n, std::string m)
375 QString s = QString("%1 <font color=\"blue\">%2</font><br>").
376 arg(n.c_str()).arg(m.c_str());
379 //====================================================================
381 //====================================================================
382 void vvDicomSeriesSelector::AddSerieToTheTable(int i, std::vector<std::string> & filenames)
384 #if GDCM_MAJOR_VERSION == 2
386 gdcm::File *header = new gdcm::File();
387 header->SetFileName(filenames[0]);
388 header->SetMaxSizeLoadEntry(16384);
389 header->SetLoadMode(gdcm::LD_NOSHADOW);// don't load shadow tags (in order to save memory)
391 //header->Print(cout);
393 // mDicomHeader[] = header;
397 QTableWidgetItem *newItem = new
398 QTableWidgetItem(QString("# images = %1").arg(header->GetImageNumber()));
399 // newItem->setCheckState(Qt::Checked);
400 //newItem->setFlags(!Qt::ItemIsEditable);
401 DD(ui.mTableWidget->rowCount());
402 ui.mTableWidget->setItem(i, 0, newItem);
406 //====================================================================
409 //====================================================================
410 void vvDicomSeriesSelector::itemMatrixSelectionChanged(int state)
412 mPatientCoordinateSystem = state;
414 //====================================================================
417 #endif // VVDICOMSERIESSELECTOR_CXX