Quellcode durchsuchen

Merge pull request #227 from Miluba154/bug-1-indexerImprovements

Indexer improved import operations
Marco Nolden vor 13 Jahren
Ursprung
Commit
45c7e8a826
2 geänderte Dateien mit 110 neuen und 37 gelöschten Zeilen
  1. 91 37
      Libs/DICOM/Core/ctkDICOMIndexer.cpp
  2. 19 0
      Libs/DICOM/Core/ctkDICOMIndexer.h

+ 91 - 37
Libs/DICOM/Core/ctkDICOMIndexer.cpp

@@ -148,56 +148,111 @@ void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& ctkDICOMDatabase,
 {
   Q_D(ctkDICOMIndexer);
 
-  // currently it is not supported to have multiple
-  // parallel directory imports so the second call blocks
-  //
-  d->DirectoryImportWatcher.waitForFinished();
+  QStringList listOfFiles;
+  QDir directory(directoryName);
 
-  const std::string src_directory(directoryName.toStdString());
-
-  OFList<OFString> originalDcmtkFileNames;
-  OFList<OFString> dcmtkFileNames;
-  OFStandard::searchDirectoryRecursively( QDir::toNativeSeparators(src_directory.c_str()).toAscii().data(), originalDcmtkFileNames, "", "");
-
-  int totalNumberOfFiles = originalDcmtkFileNames.size();
+  if(directory.exists("DICOMDIR"))
+  {
+    addDicomdir(ctkDICOMDatabase,directoryName,destinationDirectoryName);
+  }
+  else
+  {
+    QDirIterator it(directoryName,QDir::Files,QDirIterator::Subdirectories);
+    while(it.hasNext())
+    {
+      listOfFiles << it.next();
+    }
+    emit foundFilesToIndex(listOfFiles.count());
+    addListOfFiles(ctkDICOMDatabase,listOfFiles,destinationDirectoryName);
+  }
+}
 
-  // hack to reverse list of filenames (not neccessary when image loading works correctly)
-  for ( OFListIterator(OFString) iter = originalDcmtkFileNames.begin(); iter != originalDcmtkFileNames.end(); ++iter )
+//------------------------------------------------------------------------------
+void ctkDICOMIndexer::addListOfFiles(ctkDICOMDatabase& ctkDICOMDatabase,
+                                     const QStringList& listOfFiles,
+                                     const QString& destinationDirectoryName)
+{
+  Q_D(ctkDICOMIndexer);
+  if(!listOfFiles.isEmpty())
   {
-    dcmtkFileNames.push_front( *iter );
+    if(d->DirectoryImportWatcher.isRunning())
+    {
+      d->DirectoryImportWatcher.cancel();
+      d->DirectoryImportWatcher.waitForFinished();
+    }
+    d->FilesToIndex.append(listOfFiles);
+    d->DirectoryImportFuture = QtConcurrent::filter(d->FilesToIndex,AddFileFunctor(this,ctkDICOMDatabase,destinationDirectoryName));
+    d->DirectoryImportWatcher.setFuture(d->DirectoryImportFuture);
   }
+}
 
-  OFListIterator(OFString) iter = dcmtkFileNames.begin();
+//------------------------------------------------------------------------------
+void ctkDICOMIndexer::addDicomdir(ctkDICOMDatabase& ctkDICOMDatabase,
+                 const QString& directoryName,
+                 const QString& destinationDirectoryName
+                 )
+{
+  Q_D(ctkDICOMIndexer);
+
+  //Initialize dicomdir with directory path
+  QString dcmFilePath = directoryName;
+  dcmFilePath.append("/DICOMDIR");
+  DcmDicomDir* dicomDir = new DcmDicomDir(dcmFilePath.toStdString().c_str());
 
-  OFListIterator(OFString) last = dcmtkFileNames.end();
+  //Values to store records data at the moment only uid needed
+  OFString patientsName, studyInstanceUID, seriesInstanceUID, sopInstanceUID, referencedFileName ;
 
-  if(iter == last) return;
+  //Variables for progress operations
+  QString instanceFilePath;
+  QStringList listOfInstances;
 
-  emit foundFilesToIndex(totalNumberOfFiles);
+  DcmDirectoryRecord* rootRecord = &(dicomDir->getRootRecord());
+  DcmDirectoryRecord* patientRecord = NULL;
+  DcmDirectoryRecord* studyRecord = NULL;
+  DcmDirectoryRecord* seriesRecord = NULL;
+  DcmDirectoryRecord* fileRecord = NULL;
 
-  /* iterate over all input filenames */
-  int fileNumber = 0;
-  int currentProgress = -1;
-  d->Canceled = false;
-  while (iter != last)
+  /*Iterate over all records in dicomdir and setup path to the dataset of the filerecord
+  then insert. the filerecord into the database.
+  If any UID is missing the record and all of it's subelements won't be added to the database*/
+  if(rootRecord != NULL)
   {
-    if (d->Canceled)
+    while (((patientRecord = rootRecord->nextSub(patientRecord)) != NULL)
+      &&(patientRecord->findAndGetOFString(DCM_PatientName, patientsName).good()))
+    {
+      logger.debug( "Reading new Patients:" );
+      logger.debug( "Patient's Name: " + QString(patientsName.c_str()) );
+
+      while (((studyRecord = patientRecord->nextSub(studyRecord)) != NULL)
+        && (studyRecord->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).good()))
       {
-      break;
+        logger.debug( "Reading new Studys:" );
+        logger.debug( "Studies Name: " + QString(studyInstanceUID.c_str()) );
+
+        while (((seriesRecord = studyRecord->nextSub(seriesRecord)) != NULL)
+          &&(seriesRecord->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).good()))
+        {
+          logger.debug( "Reading new Series:" );
+          logger.debug( "Series Instance Name: " + QString(seriesInstanceUID.c_str()) );
+
+          while (((fileRecord = seriesRecord->nextSub(fileRecord)) != NULL)
+            &&(fileRecord->findAndGetOFStringArray(DCM_ReferencedSOPInstanceUIDInFile, sopInstanceUID).good())
+            &&(fileRecord->findAndGetOFStringArray(DCM_ReferencedFileID,referencedFileName).good()))
+          {
+
+            //Get the filepath of the instance and insert it into a list
+            instanceFilePath = directoryName;
+            instanceFilePath.append("/");
+            instanceFilePath.append(QString( referencedFileName.c_str() ));
+            instanceFilePath.replace("\\","/");
+            listOfInstances << instanceFilePath;
+          }
+        }
       }
-    emit indexingFileNumber(++fileNumber);
-    int newProgress = ( fileNumber * 100 ) / totalNumberOfFiles;
-    if (newProgress != currentProgress)
-    {
-      currentProgress = newProgress;
-      emit progress( currentProgress );
     }
-    QString filePath((*iter).c_str());
-    d->FilesToIndex << filePath;
-    ++iter;
+    emit foundFilesToIndex(listOfInstances.count());
+    addListOfFiles(ctkDICOMDatabase,listOfInstances,destinationDirectoryName);
   }
-  d->DirectoryImportFuture = QtConcurrent::filter(d->FilesToIndex,AddFileFunctor(this,ctkDICOMDatabase,destinationDirectoryName));
-  d->DirectoryImportWatcher.setFuture(d->DirectoryImportFuture);
 }
 
 //------------------------------------------------------------------------------
@@ -209,7 +264,6 @@ void ctkDICOMIndexer::refreshDatabase(ctkDICOMDatabase& dicomDatabase, const QSt
    * Probably this should go to the database class as well
    * Or we have to extend the interface to make possible what we do here
    * without using SQL directly
-   
 
   /// get all filenames from the database
   QSqlQuery allFilesQuery(dicomDatabase.database());

+ 19 - 0
Libs/DICOM/Core/ctkDICOMIndexer.h

@@ -52,6 +52,25 @@ public:
                     const QString& destinationDirectoryName = "");
 
   ///
+  /// \brief Adds directory to database by using DICOMDIR and optionally copies files to
+  /// destinationDirectory.
+  /// Scan the directory using Dcmtk and populate the database with all the
+  /// DICOM images accordingly.
+  ///
+  Q_INVOKABLE void addDicomdir(ctkDICOMDatabase& database, const QString& directoryName,
+                    const QString& destinationDirectoryName = "");
+
+  ///
+  /// \brief Adds a QStringList containing the file path to database and optionally copies files to
+  /// destinationDirectory.
+  ///
+  /// Scan the directory using Dcmtk and populate the database with all the
+  /// DICOM images accordingly.
+  ///
+  Q_INVOKABLE void addListOfFiles(ctkDICOMDatabase& database, const QStringList& listOfFiles,
+                    const QString& destinationDirectoryName = "");
+
+  ///
   /// \brief Adds a file to database and optionally copies the file to
   /// destinationDirectory.
   ///