Просмотр исходного кода

Merge branch 'dicom-queries' of github.com:commontk/CTK into dicom-queries

nherlambang лет назад: 14
Родитель
Сommit
f87a23b53c

+ 2 - 2
Applications/ctkDICOMIndexer/ctkDICOMIndexerMain.cpp

@@ -74,11 +74,11 @@ int main(int argc, char** argv)
         myCTK.openDatabase( argv[2] );
         if (argc > 4)
         {
-          idx.addDirectory(myCTK.database(),argv[3],argv[4]);
+          idx.addDirectory(myCTK,argv[3],argv[4]);
         }
         else
         {
-          idx.addDirectory(myCTK.database(),argv[3]);
+          idx.addDirectory(myCTK,argv[3]);
         }
       }
     }

+ 7 - 1
Libs/DICOM/Core/ctkDICOMDatabase.cpp

@@ -137,12 +137,18 @@ ctkDICOMDatabase::~ctkDICOMDatabase()
 //----------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-const QString& ctkDICOMDatabase::GetLastError() const {
+const QString ctkDICOMDatabase::GetLastError() const {
   Q_D(const ctkDICOMDatabase);
   return d->LastError;
 }
 
 //------------------------------------------------------------------------------
+const QString ctkDICOMDatabase::GetDatabaseFilename() const {
+  Q_D(const ctkDICOMDatabase);
+  return d->DatabaseFileName;
+}
+
+//------------------------------------------------------------------------------
 const QSqlDatabase& ctkDICOMDatabase::database() const {
   Q_D(const ctkDICOMDatabase);
   return d->Database;

+ 2 - 1
Libs/DICOM/Core/ctkDICOMDatabase.h

@@ -39,7 +39,8 @@ public:
   virtual ~ctkDICOMDatabase();
 
   const QSqlDatabase& database() const;
-  const QString& GetLastError() const;
+  const QString GetLastError() const;
+  const QString GetDatabaseFilename() const;
 
   ///
   /// open the SQLite database in @param file. If the file does not

+ 28 - 22
Libs/DICOM/Core/ctkDICOMIndexer.cpp

@@ -85,9 +85,9 @@ ctkDICOMIndexer::~ctkDICOMIndexer()
 }
 
 //------------------------------------------------------------------------------
-void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directoryName,const QString& destinationDirectoryName)
+void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& database, const QString& directoryName,const QString& destinationDirectoryName, bool createHierarchy)
 {
-  QSqlDatabase db = database;
+  QSqlDatabase db = database.database();
   const std::string src_directory(directoryName.toStdString());
 
   OFList<OFString> originalDcmtkFileNames;
@@ -108,7 +108,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
 
   if(iter == last) return;
 
-  QSqlQuery query(database);
+  QSqlQuery query(database.database());
 
 
   /// these are for optimizing the import of image sequences
@@ -126,7 +126,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
     std::string filename((*iter).c_str());
     QString qfilename(filename.c_str()); 
     /// first we check if the file is already in the database
-    QSqlQuery fileExists(database);
+    QSqlQuery fileExists(database.database());
     fileExists.prepare("SELECT InsertTimestamp FROM Images WHERE Filename == ?"); 
     fileExists.bindValue(0,qfilename);
     fileExists.exec();
@@ -160,7 +160,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
     OFString seriesInstanceUID, seriesDate, seriesTime,
       seriesDescription, bodyPartExamined, frameOfReferenceUID,
       contrastAgent, scanningSequence;
-    OFString instanceNumber;
+    OFString instanceNumber, sopInstanceUID ;
 
     Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0;
 
@@ -185,6 +185,13 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
       MITK_ERROR << "Could not read DCM_SeriesInstanceUID from " << filename;
       continue;
     }
+
+    if (!dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID).good())
+    {
+      MITK_ERROR << "Could not read DCM_SOPInstanceUID from " << filename;
+      continue;
+    }
+
     if (!dataset->findAndGetOFString(DCM_InstanceNumber, instanceNumber).good())
     {
       MITK_ERROR << "Could not read DCM_InstanceNumber from " << filename;
@@ -235,7 +242,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
     if(lastPatientID.compare(patientID) || lastPatientsBirthDate.compare(patientsBirthDate) || lastPatientsName.compare(patientsName))
     {
       //Check if patient is already present in the db
-      QSqlQuery check_exists_query(database);
+      QSqlQuery check_exists_query(database.database());
       std::stringstream check_exists_query_string;
       check_exists_query_string << "SELECT * FROM Patients WHERE PatientID = '" << patientID << "'";
       check_exists_query.exec(check_exists_query_string.str().c_str());
@@ -293,7 +300,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
 
     if(lastStudyInstanceUID.compare(studyInstanceUID))
     {
-      QSqlQuery check_exists_query(database);
+      QSqlQuery check_exists_query(database.database());
       std::stringstream check_exists_query_string;
       check_exists_query_string << "SELECT * FROM Studies WHERE StudyInstanceUID = '" << studyInstanceUID << "'";
       check_exists_query.exec(check_exists_query_string.str().c_str());
@@ -329,7 +336,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
     if(lastSeriesInstanceUID.compare(seriesInstanceUID))
     {
 
-      QSqlQuery check_exists_query(database);
+      QSqlQuery check_exists_query(database.database());
       std::stringstream check_exists_query_string;
       check_exists_query_string << "SELECT * FROM Series WHERE SeriesInstanceUID = '" << seriesInstanceUID << "'";
       check_exists_query.exec(check_exists_query_string.str().c_str());
@@ -360,7 +367,6 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
 
     lastSeriesInstanceUID = seriesInstanceUID;
 
-
     //----------------------------------
     //Move file to destination directory
     //----------------------------------
@@ -368,16 +374,16 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
     if (!destinationDirectoryName.isEmpty())
       {
       QFile currentFile( qfilename );
-      QDir destinationDir(destinationDirectoryName);
-
-      QString uniqueDirName = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str();
-      qDebug() << "MKPath: " << uniqueDirName;
-      destinationDir.mkpath(uniqueDirName);
-      QString destFileName = destinationDir.absolutePath().append("/").append(instanceNumber.c_str());
-      qDebug() << "Copy: " << qfilename << " -> " << destFileName;
+      QDir destinationDir(destinationDirectoryName + "/dicom");
+      QString destFileName = seriesInstanceUID.c_str();
+      if (createHierarchy)
+      {
+        QString uniqueDirName = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str();
+        destinationDir.mkpath(uniqueDirName);
+        destFileName.prepend( destinationDir.absolutePath() + "/"  + uniqueDirName + "/" );
+      }
       currentFile.copy(destFileName);
-      //for testing only: copy file instead of moving
-      //currentFile.copyTo(destDirectoryPath.str());
+      qfilename = destFileName;
     }
     // */
     //------------------------
@@ -387,7 +393,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
 //    std::stringstream relativeFilePath;
 //    relativeFilePath << seriesInstanceUID.c_str() << "/" << currentFilePath.getFileName();
 
-    QSqlQuery check_exists_query(database);
+    QSqlQuery check_exists_query(database.database());
     std::stringstream check_exists_query_string;
 //    check_exists_query_string << "SELECT * FROM Images WHERE Filename = '" << relativeFilePath.str() << "'";
     check_exists_query_string << "SELECT * FROM Images WHERE Filename = '" << filename << "'";
@@ -399,7 +405,7 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
 
       //To save absolute path: destDirectoryPath.str()
       query_string << "INSERT INTO Images VALUES('"
-        << /*relativeFilePath.str()*/ filename << "','" << seriesInstanceUID << "','" << QDateTime::currentDateTime().toString(Qt::ISODate).toStdString() << "')";
+        << qfilename.toStdString() << "','" << seriesInstanceUID << "','" << QDateTime::currentDateTime().toString(Qt::ISODate).toStdString() << "')";
 
       query.exec(query_string.str().c_str());
     }
@@ -411,10 +417,10 @@ void ctkDICOMIndexer::addDirectory(QSqlDatabase database, const QString& directo
 }
 
 //------------------------------------------------------------------------------
-void ctkDICOMIndexer::refreshDatabase(QSqlDatabase database, const QString& directoryName)
+void ctkDICOMIndexer::refreshDatabase(ctkDICOMDatabase& database, const QString& directoryName)
 {
   /// get all filenames from the database
-  QSqlQuery allFilesQuery(database);
+  QSqlQuery allFilesQuery(database.database());
   QStringList databaseFileNames;
   QStringList filesToRemove;
   allFilesQuery.exec("SELECT Filename from Images;");

+ 3 - 2
Libs/DICOM/Core/ctkDICOMIndexer.h

@@ -25,6 +25,7 @@
 #include <QSqlDatabase>
 
 #include "ctkDICOMCoreExport.h"
+#include "ctkDICOMDatabase.h"
 
 class ctkDICOMIndexerPrivate;
 class CTK_DICOM_CORE_EXPORT ctkDICOMIndexer
@@ -33,8 +34,8 @@ public:
   explicit ctkDICOMIndexer();
   virtual ~ctkDICOMIndexer();
   /// add directory to database and optionally copy files to destinationDirectory
-  void addDirectory(QSqlDatabase database, const QString& directoryName, const QString& destinationDirectoryName = "");
-  void refreshDatabase(QSqlDatabase database, const QString& directoryName);
+  void addDirectory(ctkDICOMDatabase& database, const QString& directoryName, const QString& destinationDirectoryName = "", bool createHierarchy = true);
+  void refreshDatabase(ctkDICOMDatabase& database, const QString& directoryName);
 
 protected:
   QScopedPointer<ctkDICOMIndexerPrivate> d_ptr;

+ 12 - 0
Libs/DICOM/Core/ctkDICOMQuery.cpp

@@ -250,6 +250,18 @@ void ctkDICOMQuery::query(ctkDICOMDatabase& database )
       d->query->putAndInsertString( DCM_PatientID,
         (QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
     }
+    if ( key == QString("Modalities") )
+    {
+      // make the filter be an "OR" of modalities using backslash (dicom-style)
+      QString modalitySearch("");
+      foreach (QString modality, d->Filters[key].toStringList())
+      {
+        modalitySearch += modality + QString("\\");
+      }
+      modalitySearch.chop(1); // remove final backslash
+      logger.debug("modalitySearch " + modalitySearch);
+      d->query->putAndInsertString( DCM_ModalitiesInStudy, modalitySearch.toAscii().data() );
+    }
   }
 
   FINDResponses *responses = new FINDResponses();

+ 10 - 1
Libs/DICOM/Widgets/Resources/UI/ctkDICOMAppWidget.ui

@@ -124,7 +124,7 @@
      <x>0</x>
      <y>0</y>
      <width>739</width>
-     <height>21</height>
+     <height>25</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -151,6 +151,7 @@
    <addaction name="actionImport"/>
    <addaction name="actionExport"/>
    <addaction name="actionQuery"/>
+   <addaction name="actionSend"/>
   </widget>
   <action name="actionImport">
    <property name="text">
@@ -176,6 +177,14 @@
     <string>Query and Retrieve DICOM studies from a DICOM node</string>
    </property>
   </action>
+  <action name="actionSend">
+   <property name="text">
+    <string>Send</string>
+   </property>
+   <property name="toolTip">
+    <string>Send DIOCM studies to a DICOM node</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>

+ 7 - 0
Libs/DICOM/Widgets/ctkDICOMQueryRetrieveWidget.cpp

@@ -74,6 +74,8 @@ void ctkDICOMQueryRetrieveWidget::setRetrieveDatabaseFileName(const QString& fil
 void ctkDICOMQueryRetrieveWidget::processQuery()
 {
   Q_D(ctkDICOMQueryRetrieveWidget);
+
+  d->RetrieveButton->setEnabled(false);
   
   ctkDICOMDatabase queryResultDatabase;
 
@@ -128,4 +130,9 @@ void ctkDICOMQueryRetrieveWidget::processQuery()
 
   d->model.setDatabase(queryResultDatabase.database());
   d->results->setModel(&d->model);
+
+  if ( d->model.rowCount() > 0 )
+  {
+    d->RetrieveButton->setEnabled(true);
+  }
 }

+ 6 - 1
Libs/DICOM/Widgets/ctkDICOMQueryWidget.cpp

@@ -48,7 +48,12 @@ QMap<QString,QVariant> ctkDICOMQueryWidget::parameters()
   parameters["Series"] = d->SeriesSearch->text();
   parameters["ID"] = d->IdSearch->text();
 
-  parameters["Modalities"] = d->ModalityWidget->selectedModalities();
+  if ( !d->ModalityWidget->areAllModalitiesSelected() )
+  { // some PACS (conquest) don't seem to accept list of modalities,
+    // so don't include the list at all when all modalities are desired
+    // TODO: think about how to fix this for conquest at the query level
+    parameters["Modalities"] = d->ModalityWidget->selectedModalities();
+  }
 
   return parameters;
 }