/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #include "itkDCMTKSeriesFileNames.h" #include "itksys/SystemTools.hxx" #include "itkProgressReporter.h" #include "itkDCMTKFileReader.h" #include "itkPrintHelper.h" #include "itksys/Directory.hxx" #include namespace itk { DCMTKSeriesFileNames::DCMTKSeriesFileNames() { m_InputDirectory = ""; m_OutputDirectory = ""; m_UseSeriesDetails = true; m_Recursive = false; m_LoadSequences = false; m_LoadPrivateTags = false; } DCMTKSeriesFileNames::~DCMTKSeriesFileNames() = default; void DCMTKSeriesFileNames::SetInputDirectory(const char * name) { if (!name) { itkExceptionMacro("SetInputDirectory() received a nullptr string"); } std::string fname = name; this->SetInputDirectory(fname); } void DCMTKSeriesFileNames::SetInputDirectory(std::string const & name) { if (name.empty()) { itkWarningMacro("You need to specify a directory where " "the DICOM files are located"); return; } if (m_InputDirectory == name) { return; } if (!itksys::SystemTools::FileIsDirectory(name.c_str())) { itkWarningMacro(<< name << " is not a directory"); return; } m_InputDirectory = name; // as a side effect it also execute this->Modified(); } void DCMTKSeriesFileNames::GetDicomData(const std::string & series, bool saveFileNames) { if (saveFileNames) { this->m_InputFileNames.clear(); } this->m_SeriesUIDs.clear(); // make an absolute path from whatever is passed in std::string fullPath = itksys::SystemTools::CollapseFullPath(m_InputDirectory.c_str()); // work in Unix filename conventions, but convert to actually use filename itksys::SystemTools::ConvertToUnixSlashes(fullPath); std::string localFilePath = fullPath; // load the directory itksys::Directory directory; directory.Load(localFilePath.c_str()); unsigned int numFiles = directory.GetNumberOfFiles(); std::vector allHeaders; for (unsigned int i = 0; i < numFiles; ++i) { std::string curFile = directory.GetFile(i); if (curFile == "." || curFile == "..") { continue; } localFilePath = fullPath; localFilePath += '/'; localFilePath += curFile; if (!itksys::SystemTools::FileIsDirectory(localFilePath.c_str())) { if (!DCMTKFileReader::IsImageFile(localFilePath)) { continue; } auto * reader = new DCMTKFileReader; try { reader->SetFileName(localFilePath); reader->LoadFile(); } catch (...) { delete reader; continue; } std::string uid; reader->GetElementUI(0x0020, 0x000e, uid); // // if you've restricked it to a particular series instance ID if (series.empty() || series == uid) { allHeaders.push_back(reader); } else { delete reader; } // // save the UID at any rate this->m_SeriesUIDs.push_back(uid); } } if (saveFileNames) { std::sort(allHeaders.begin(), allHeaders.end(), CompareDCMTKFileReaders); } // // save the filenames, and delete the headers for (auto & allHeader : allHeaders) { if (saveFileNames) { m_InputFileNames.push_back(allHeader->GetFileName()); } delete allHeader; } } const DCMTKSeriesFileNames::FileNamesContainerType & DCMTKSeriesFileNames::GetFileNames(const std::string series) { this->GetDicomData(series, true); return m_InputFileNames; } const DCMTKSeriesFileNames::SeriesUIDContainerType & DCMTKSeriesFileNames::GetSeriesUIDs() { this->GetDicomData("", false); return this->m_SeriesUIDs; } const DCMTKSeriesFileNames::FileNamesContainerType & DCMTKSeriesFileNames::GetInputFileNames() { // Do not specify any UID this->GetDicomData("", true); return this->m_InputFileNames; } const DCMTKSeriesFileNames::FileNamesContainerType & DCMTKSeriesFileNames::GetOutputFileNames() { return m_OutputFileNames; } void DCMTKSeriesFileNames::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "InputDirectory: " << m_InputDirectory << std::endl; os << indent << "OutputDirectory: " << m_OutputDirectory << std::endl; for (unsigned int i = 0; i < m_InputFileNames.size(); ++i) { os << indent << "InputFileNames[" << i << "]: " << m_InputFileNames[i] << std::endl; } for (unsigned int i = 0; i < m_OutputFileNames.size(); ++i) { os << indent << "OutputFileNames[" << i << "]: " << m_OutputFileNames[i] << std::endl; } for (unsigned int i = 0; i < m_SeriesUIDs.size(); ++i) { os << indent << "SeriesUIDs[" << i << "]: " << m_SeriesUIDs[i] << std::endl; } if (m_UseSeriesDetails) { os << indent << "UseSeriesDetails: True" << std::endl; } else { os << indent << "UseSeriesDetails: False" << std::endl; } if (m_Recursive) { os << indent << "Recursive: True" << std::endl; } else { os << indent << "Recursive: False" << std::endl; } if (m_LoadSequences) { os << indent << "LoadSequences: True" << std::endl; } else { os << indent << "LoadSequences: False" << std::endl; } if (m_LoadPrivateTags) { os << indent << "LoadPrivateTags: True" << std::endl; } else { os << indent << "LoadPrivateTags: False" << std::endl; } } void DCMTKSeriesFileNames::SetUseSeriesDetails(bool useSeriesDetails) { m_UseSeriesDetails = useSeriesDetails; // m_SerieHelper->SetUseSeriesDetails(m_UseSeriesDetails); // m_SerieHelper->CreateDefaultUniqueSeriesIdentifier(); } } // namespace itk