Преглед на файлове

Merge pull request #740 from jcfr/dicom-speedup-import

Dicom speedup import
Jean-Christophe Fillion-Robin преди 7 години
родител
ревизия
6c5a63fe42
променени са 3 файла, в които са добавени 70 реда и са изтрити 40 реда
  1. 55 36
      Libs/DICOM/Core/ctkDICOMDatabase.cpp
  2. 15 0
      Libs/DICOM/Core/ctkDICOMIndexer.cpp
  3. 0 4
      Libs/DICOM/Widgets/ctkDICOMBrowser.cpp

+ 55 - 36
Libs/DICOM/Core/ctkDICOMDatabase.cpp

@@ -141,6 +141,7 @@ public:
   QSqlDatabase TagCacheDatabase;
   QSqlDatabase TagCacheDatabase;
   QString TagCacheDatabaseFilename;
   QString TagCacheDatabaseFilename;
   QStringList TagsToPrecache;
   QStringList TagsToPrecache;
+  bool openTagCacheDatabase();
   void precacheTags( const QString sopInstanceUID );
   void precacheTags( const QString sopInstanceUID );
 
 
   int insertPatient(const ctkDICOMItem& ctkDataset);
   int insertPatient(const ctkDICOMItem& ctkDataset);
@@ -332,8 +333,6 @@ void ctkDICOMDatabase::openDatabase(const QString databaseFile, const QString& c
     }
     }
 }
 }
 
 
-
-
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 // ctkDICOMDatabase methods
 // ctkDICOMDatabase methods
 
 
@@ -1044,13 +1043,14 @@ void ctkDICOMDatabase::insert( DcmItem *item, bool storeFile, bool generateThumb
   ctkDataset.InitializeFromItem(item, false /* do not take ownership */);
   ctkDataset.InitializeFromItem(item, false /* do not take ownership */);
   this->insert(ctkDataset,storeFile,generateThumbnail);
   this->insert(ctkDataset,storeFile,generateThumbnail);
 }
 }
+
+//------------------------------------------------------------------------------
 void ctkDICOMDatabase::insert( const ctkDICOMItem& ctkDataset, bool storeFile, bool generateThumbnail)
 void ctkDICOMDatabase::insert( const ctkDICOMItem& ctkDataset, bool storeFile, bool generateThumbnail)
 {
 {
   Q_D(ctkDICOMDatabase);
   Q_D(ctkDICOMDatabase);
   d->insert(ctkDataset, QString(), storeFile, generateThumbnail);
   d->insert(ctkDataset, QString(), storeFile, generateThumbnail);
 }
 }
 
 
-
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 void ctkDICOMDatabase::insert ( const QString& filePath, bool storeFile, bool generateThumbnail, bool createHierarchy, const QString& destinationDirectoryName)
 void ctkDICOMDatabase::insert ( const QString& filePath, bool storeFile, bool generateThumbnail, bool createHierarchy, const QString& destinationDirectoryName)
 {
 {
@@ -1067,9 +1067,6 @@ void ctkDICOMDatabase::insert ( const QString& filePath, bool storeFile, bool ge
 
 
   logger.debug( "Processing " + filePath );
   logger.debug( "Processing " + filePath );
 
 
-  std::string filename = filePath.toStdString();
-
-  DcmFileFormat fileformat;
   ctkDICOMItem ctkDataset;
   ctkDICOMItem ctkDataset;
 
 
   ctkDataset.InitializeFromFile(filePath);
   ctkDataset.InitializeFromFile(filePath);
@@ -1259,6 +1256,32 @@ const QStringList ctkDICOMDatabase::tagsToPrecache()
 }
 }
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
+bool ctkDICOMDatabasePrivate::openTagCacheDatabase()
+{
+  // try to open the database if it's not already open
+  if ( this->TagCacheDatabase.isOpen() )
+    {
+    return true;
+    }
+  this->TagCacheDatabase = QSqlDatabase::addDatabase(
+        "QSQLITE", this->Database.connectionName() + "TagCache");
+  this->TagCacheDatabase.setDatabaseName(this->TagCacheDatabaseFilename);
+  if ( !this->TagCacheDatabase.open() )
+    {
+    qDebug() << "TagCacheDatabase would not open!\n";
+    qDebug() << "TagCacheDatabaseFilename is: " << this->TagCacheDatabaseFilename << "\n";
+    return false;
+    }
+
+  // Disable synchronous writing to make modifications faster
+  QSqlQuery pragmaSyncQuery(this->TagCacheDatabase);
+  pragmaSyncQuery.exec("PRAGMA synchronous = OFF");
+  pragmaSyncQuery.finish();
+
+  return true;
+}
+
+//------------------------------------------------------------------------------
 void ctkDICOMDatabasePrivate::precacheTags( const QString sopInstanceUID )
 void ctkDICOMDatabasePrivate::precacheTags( const QString sopInstanceUID )
 {
 {
   Q_Q(ctkDICOMDatabase);
   Q_Q(ctkDICOMDatabase);
@@ -1280,9 +1303,15 @@ void ctkDICOMDatabasePrivate::precacheTags( const QString sopInstanceUID )
     values << value;
     values << value;
     }
     }
 
 
-  this->beginTransaction();
+  QSqlQuery transaction( this->TagCacheDatabase );
+  transaction.prepare( "BEGIN TRANSACTION" );
+  transaction.exec();
+
   q->cacheTags(sopInstanceUIDs, tags, values);
   q->cacheTags(sopInstanceUIDs, tags, values);
-  this->endTransaction();
+
+  transaction = QSqlQuery( this->TagCacheDatabase );
+  transaction.prepare( "END TRANSACTION" );
+  transaction.exec();
 }
 }
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
@@ -1312,19 +1341,18 @@ void ctkDICOMDatabasePrivate::insert( const ctkDICOMItem& ctkDataset, const QStr
       logger.error("SQLITE ERROR: " + fileExistsQuery.lastError().driverText());
       logger.error("SQLITE ERROR: " + fileExistsQuery.lastError().driverText());
       return;
       return;
     }
     }
-  fileExistsQuery.next();
-
-  QString databaseFilename(fileExistsQuery.value(1).toString());
-  QDateTime fileLastModified(QFileInfo(databaseFilename).lastModified());
-  QDateTime databaseInsertTimestamp(QDateTime::fromString(fileExistsQuery.value(0).toString(),Qt::ISODate));
-
+  bool found = fileExistsQuery.next();
   qDebug() << "inserting filePath: " << filePath;
   qDebug() << "inserting filePath: " << filePath;
-  if (databaseFilename == "")
+  if (!found)
     {
     {
       qDebug() << "database filename for " << sopInstanceUID << " is empty - we should insert on top of it";
       qDebug() << "database filename for " << sopInstanceUID << " is empty - we should insert on top of it";
     }
     }
   else
   else
     {
     {
+      QString databaseFilename(fileExistsQuery.value(1).toString());
+      QDateTime fileLastModified(QFileInfo(databaseFilename).lastModified());
+      QDateTime databaseInsertTimestamp(QDateTime::fromString(fileExistsQuery.value(0).toString(),Qt::ISODate));
+
       if ( databaseFilename == filePath && fileLastModified < databaseInsertTimestamp )
       if ( databaseFilename == filePath && fileLastModified < databaseInsertTimestamp )
         {
         {
           logger.debug ( "File " + databaseFilename + " already added" );
           logger.debug ( "File " + databaseFilename + " already added" );
@@ -1419,8 +1447,7 @@ void ctkDICOMDatabasePrivate::insert( const ctkDICOMItem& ctkDataset, const QStr
       if ( LastPatientID != patientID
       if ( LastPatientID != patientID
            || LastPatientsBirthDate != patientsBirthDate
            || LastPatientsBirthDate != patientsBirthDate
            || LastPatientsName != patientsName )
            || LastPatientsName != patientsName )
-        {  QString seriesInstanceUID(ctkDataset.GetElementAsString(DCM_SeriesInstanceUID) );
-
+        {
           qDebug() << "This looks like a different patient from last insert: " << patientID;
           qDebug() << "This looks like a different patient from last insert: " << patientID;
           // Ok, something is different from last insert, let's insert him if he's not
           // Ok, something is different from last insert, let's insert him if he's not
           // already in the db.
           // already in the db.
@@ -1707,23 +1734,14 @@ bool ctkDICOMDatabase::tagCacheExists()
     return true;
     return true;
     }
     }
 
 
-  // try to open the database if it's not already open
-  if ( !(d->TagCacheDatabase.isOpen()) )
+  if (!d->openTagCacheDatabase())
     {
     {
-    d->TagCacheDatabase = QSqlDatabase::addDatabase("QSQLITE", d->Database.connectionName() + "TagCache");
-    d->TagCacheDatabase.setDatabaseName(d->TagCacheDatabaseFilename);
-    if ( !(d->TagCacheDatabase.open()) )
-      {
-      qDebug() << "TagCacheDatabase would not open!\n";
-      qDebug() << "TagCacheDatabaseFilename is: " << d->TagCacheDatabaseFilename << "\n";
-      return false;
-      }
-
-    //Disable synchronous writing to make modifications faster
-    QSqlQuery pragmaSyncQuery(d->TagCacheDatabase);
-    pragmaSyncQuery.exec("PRAGMA synchronous = OFF");
-    pragmaSyncQuery.finish();
+    return false;
+    }
 
 
+  if (d->TagCacheDatabase.tables().count() == 0)
+    {
+    return false;
     }
     }
 
 
   // check that the table exists
   // check that the table exists
@@ -1759,12 +1777,13 @@ bool ctkDICOMDatabase::initializeTagCache()
   createCacheTable.prepare(
   createCacheTable.prepare(
     "CREATE TABLE TagCache (SOPInstanceUID, Tag, Value, PRIMARY KEY (SOPInstanceUID, Tag))" );
     "CREATE TABLE TagCache (SOPInstanceUID, Tag, Value, PRIMARY KEY (SOPInstanceUID, Tag))" );
   bool success = d->loggedExec(createCacheTable);
   bool success = d->loggedExec(createCacheTable);
-  if (success)
+  if (!success)
     {
     {
-    d->TagCacheVerified = true;
-    return true;
+    return false;
     }
     }
-  return false;
+
+  d->TagCacheVerified = true;
+  return true;
 }
 }
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------

+ 15 - 0
Libs/DICOM/Core/ctkDICOMIndexer.cpp

@@ -130,6 +130,8 @@ void ctkDICOMIndexer::addListOfFiles(ctkDICOMDatabase& ctkDICOMDatabase,
                                      const QString& destinationDirectoryName)
                                      const QString& destinationDirectoryName)
 {
 {
   Q_D(ctkDICOMIndexer);
   Q_D(ctkDICOMIndexer);
+  QTime timeProbe;
+  timeProbe.start();
   d->Canceled = false;
   d->Canceled = false;
   int CurrentFileIndex = 0;
   int CurrentFileIndex = 0;
   foreach(QString filePath, listOfFiles)
   foreach(QString filePath, listOfFiles)
@@ -144,6 +146,11 @@ void ctkDICOMIndexer::addListOfFiles(ctkDICOMDatabase& ctkDICOMDatabase,
       break;
       break;
       }
       }
   }
   }
+  float elapsedTimeInSeconds = timeProbe.elapsed() / 1000.0;
+  qDebug()
+      << QString("DICOM indexer has successfully processed %1 files [%2s]")
+         .arg(CurrentFileIndex)
+         .arg(QString::number(elapsedTimeInSeconds,'f', 2));
   emit this->indexingComplete();
   emit this->indexingComplete();
 }
 }
 
 
@@ -171,6 +178,9 @@ bool ctkDICOMIndexer::addDicomdir(ctkDICOMDatabase& ctkDICOMDatabase,
   DcmDirectoryRecord* seriesRecord = NULL;
   DcmDirectoryRecord* seriesRecord = NULL;
   DcmDirectoryRecord* fileRecord = NULL;
   DcmDirectoryRecord* fileRecord = NULL;
 
 
+  QTime timeProbe;
+  timeProbe.start();
+
   /*Iterate over all records in dicomdir and setup path to the dataset of the filerecord
   /*Iterate over all records in dicomdir and setup path to the dataset of the filerecord
   then insert. the filerecord into the database.
   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 any UID is missing the record and all of it's subelements won't be added to the database*/
@@ -231,6 +241,11 @@ bool ctkDICOMIndexer::addDicomdir(ctkDICOMDatabase& ctkDICOMDatabase,
         }
         }
       }
       }
     }
     }
+    float elapsedTimeInSeconds = timeProbe.elapsed() / 1000.0;
+    qDebug()
+        << QString("DICOM indexer has successfully processed DICOMDIR in %1 [%2s]")
+           .arg(directoryName)
+           .arg(QString::number(elapsedTimeInSeconds,'f', 2));
     emit foundFilesToIndex(listOfInstances.count());
     emit foundFilesToIndex(listOfInstances.count());
     addListOfFiles(ctkDICOMDatabase,listOfInstances,destinationDirectoryName);
     addListOfFiles(ctkDICOMDatabase,listOfInstances,destinationDirectoryName);
   }
   }

+ 0 - 4
Libs/DICOM/Widgets/ctkDICOMBrowser.cpp

@@ -423,11 +423,7 @@ ctkDICOMTableManager* ctkDICOMBrowser::dicomTableManager()
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void ctkDICOMBrowser::onFileIndexed(const QString& filePath)
 void ctkDICOMBrowser::onFileIndexed(const QString& filePath)
 {
 {
-  // Update the progress dialog when the file name changes
-  // - also allows for cancel button
-  QCoreApplication::instance()->processEvents();
   qDebug() << "Indexing \n\n\n\n" << filePath <<"\n\n\n";
   qDebug() << "Indexing \n\n\n\n" << filePath <<"\n\n\n";
-  
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------