Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add method to import selected files into DICOM browser #914

Merged
merged 3 commits into from
May 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions Libs/DICOM/Core/Testing/Cpp/ctkDICOMIndexerTest1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,25 @@ int ctkDICOMIndexerTest1( int argc, char * argv [] )
{
QCoreApplication app(argc, argv);

// Get data directory from environment
QDir dataDir = QDir(QProcessEnvironment::systemEnvironment().value("CTKData_DIR", ""));
QString dicomDir = dataDir.filePath("Data/DICOM");
if (!QDir(dicomDir).exists())
{
std::cerr << "Directory does not exist: " << qPrintable(dicomDir) << std::endl;
std::cerr << "Make sure CTKData_DIR environment variable is set correctly" << std::endl;
}

ctkDICOMDatabase database;
database.openDatabase(":memory:");
ctkDICOMIndexer indexer;

// Test ctkDICOMIndexer::addDirectory()
// just check if it doesn't crash
// Create block to test batch indexing using indexingBatch helper class.
{
indexer.addDirectory(&database, QString());
// might work (if there are some DCM images in temp
indexer.addDirectory(&database, QDir::tempPath());
// give an invalid destination name
indexer.addDirectory(&database, QDir::tempPath(), true);
indexer.addDirectory(&database, dicomDir, false);
indexer.addDirectory(&database, dicomDir, true);
}

// ensure all concurrent inserts are complete
Expand Down
2 changes: 2 additions & 0 deletions Libs/DICOM/Core/ctkDICOMDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,7 @@ ctkDICOMDatabase::ctkDICOMDatabase(QObject* parent)
//------------------------------------------------------------------------------
ctkDICOMDatabase::~ctkDICOMDatabase()
{
this->closeDatabase();
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -2891,6 +2892,7 @@ bool ctkDICOMDatabase::cleanup(bool vacuum/*=false*/)
QSqlQuery tagcacheCleanup(d->TagCacheDatabase);
seriesCleanup.exec("VACUUM;");
}
d->resetLastInsertedValues();
return true;
}

Expand Down
74 changes: 43 additions & 31 deletions Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMBrowserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ private slots:
private:
void _testImportCommon(ctkDICOMBrowser& browser);

QString DatabaseDirectoryName;
QString TemporaryDatabaseDirectoryName;

QDir DICOMDir;
Expand All @@ -67,47 +68,46 @@ private slots:
// ----------------------------------------------------------------------------
void ctkDICOMBrowserTester::initTestCase()
{
QApplication::instance()->setOrganizationName("commontk");
QApplication::instance()->setOrganizationDomain("commontk.org");
QApplication::instance()->setApplicationName("ctkDICOM");

// Get data directory from environment
QDir dataDir = QDir(
QProcessEnvironment::systemEnvironment().value("CTKData_DIR", ""));
QDir dataDir = QDir(QProcessEnvironment::systemEnvironment().value("CTKData_DIR", ""));
QVERIFY(dataDir.exists());

this->DICOMDir = dataDir.filePath("Data/DICOM");
QVERIFY(this->DICOMDir.exists());

this->DatabaseDirectoryName = QDir::tempPath() + "/ctkDICOMBrowserTest-Database";
this->TemporaryDatabaseDirectoryName =
QString("ctkDICOMBrowserTest.%1.DICOM-Database").arg(QTime::currentTime().toString("hhmmsszzz"));
}

// ----------------------------------------------------------------------------
void ctkDICOMBrowserTester::init()
{
// If any, remove default ./ctkDICOM-Database directory
{
ctkScopedCurrentDir scopedCurrentDir(QDir::tempPath());
ctk::removeDirRecursively("./ctkDICOM-Database");
QCOMPARE(QFileInfo("./ctkDICOM-Database").isDir(), false);
}

// Generate a new database directory name
this->TemporaryDatabaseDirectoryName =
QString("ctkDICOMBrowserTest.%1.DICOM-Database").arg(QTime::currentTime().toString("hhmmsszzz"));
// If any, remove default database directory
ctk::removeDirRecursively(this->DatabaseDirectoryName);
QCOMPARE(QFileInfo(this->DatabaseDirectoryName).isDir(), false);
}

// ----------------------------------------------------------------------------
void ctkDICOMBrowserTester::testDefaults()
{
// Clear left over settings
QSettings().remove("DatabaseDirectory");

ctkDICOMBrowser browser;
browser.setDatabaseDirectory(this->DatabaseDirectoryName);
browser.createNewDatabaseDirectory();

QVERIFY(QFileInfo("./ctkDICOM-Database").isDir());
QVERIFY(QFileInfo("./ctkDICOM-Database/ctkDICOM.sql").isFile());
QVERIFY(QFileInfo("./ctkDICOM-Database/ctkDICOMTagCache.sql").isFile());
QVERIFY(QFileInfo(this->DatabaseDirectoryName).isDir());
QVERIFY(QFileInfo(this->DatabaseDirectoryName+"/ctkDICOM.sql").isFile());
QVERIFY(QFileInfo(this->DatabaseDirectoryName+"/ctkDICOMTagCache.sql").isFile());

QCOMPARE(browser.databaseDirectory(), QString("./ctkDICOM-Database"));
QCOMPARE(browser.databaseDirectory(), this->DatabaseDirectoryName);
QVERIFY(browser.database() != 0);

QCOMPARE(browser.tagsToPrecache(), QStringList());

QVERIFY(browser.dicomTableManager() != 0);

QCOMPARE(browser.displayImportSummary(), true);
Expand All @@ -124,10 +124,12 @@ void ctkDICOMBrowserTester::testDatabaseDirectory()
{
// Check that value from setting is picked up
{
QSettings().setValue("DatabaseDirectory", this->TemporaryDatabaseDirectoryName);
QSettings().setValue("TempDatabaseDirectory", this->TemporaryDatabaseDirectoryName);
QCOMPARE(QFileInfo(this->TemporaryDatabaseDirectoryName).isDir(), false);

ctkDICOMBrowser browser;
browser.setDatabaseDirectorySettingsKey("TempDatabaseDirectory");
browser.createNewDatabaseDirectory();

QCOMPARE(QFileInfo(browser.databaseDirectory()).absoluteFilePath(),
QFileInfo(this->TemporaryDatabaseDirectoryName).absoluteFilePath());
Expand All @@ -138,9 +140,8 @@ void ctkDICOMBrowserTester::testDatabaseDirectory()
// ----------------------------------------------------------------------------
void ctkDICOMBrowserTester::testImportDirectoryMode()
{
QSettings().setValue("DatabaseDirectory", this->TemporaryDatabaseDirectoryName);

ctkDICOMBrowser browser;
browser.setDatabaseDirectory(this->TemporaryDatabaseDirectoryName);

browser.setImportDirectoryMode(ctkDICOMBrowser::ImportDirectoryCopy);
QCOMPARE(browser.importDirectoryMode(), ctkDICOMBrowser::ImportDirectoryCopy);
Expand All @@ -163,11 +164,14 @@ void ctkDICOMBrowserTester::testImportDirectories()
QFETCH(QStringList, directories);
QFETCH(ctkDICOMBrowser::ImportDirectoryMode, importDirectoryMode);

QSettings().setValue("DatabaseDirectory", this->TemporaryDatabaseDirectoryName);

ctkDICOMBrowser browser;
browser.setDatabaseDirectory(this->TemporaryDatabaseDirectoryName);

browser.setDisplayImportSummary(false);
// clear database because if an image is already imported
// then it is not imported again
browser.database()->initializeDatabase();

//browser.setDisplayImportSummary(false);
browser.importDirectories(directories, /* mode= */ importDirectoryMode);

this->_testImportCommon(browser);
Expand All @@ -176,6 +180,8 @@ void ctkDICOMBrowserTester::testImportDirectories()
// ----------------------------------------------------------------------------
void ctkDICOMBrowserTester::_testImportCommon(ctkDICOMBrowser& browser)
{
browser.waitForImportFinished();

QFETCH(int, expectedImporedPatients);
QFETCH(int, expectedImporedStudies);
QFETCH(int, expectedImporedSeries);
Expand Down Expand Up @@ -232,11 +238,14 @@ void ctkDICOMBrowserTester::testImportDirectory()
QFETCH(QStringList, directories);
QFETCH(ctkDICOMBrowser::ImportDirectoryMode, importDirectoryMode);

QSettings().setValue("DatabaseDirectory", this->TemporaryDatabaseDirectoryName);

ctkDICOMBrowser browser;
browser.setDatabaseDirectory(this->TemporaryDatabaseDirectoryName);

// clear database because if an image is already imported
// then it is not imported again
browser.database()->initializeDatabase();

browser.setDisplayImportSummary(false);
//browser.setDisplayImportSummary(false);
browser.importDirectory(directories[0], /* mode= */ importDirectoryMode);

this->_testImportCommon(browser);
Expand Down Expand Up @@ -275,11 +284,14 @@ void ctkDICOMBrowserTester::testOnImportDirectory()
QFETCH(QStringList, directories);
QFETCH(ctkDICOMBrowser::ImportDirectoryMode, importDirectoryMode);

QSettings().setValue("DatabaseDirectory", this->TemporaryDatabaseDirectoryName);

ctkDICOMBrowser browser;
browser.setDatabaseDirectory(this->TemporaryDatabaseDirectoryName);

// clear database because if an image is already imported
// then it is not imported again
browser.database()->initializeDatabase();

browser.setDisplayImportSummary(false);
//browser.setDisplayImportSummary(false);
browser.onImportDirectory(directories[0], /* mode= */ importDirectoryMode);

this->_testImportCommon(browser);
Expand Down
30 changes: 29 additions & 1 deletion Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMBrowserTest1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,45 @@ int ctkDICOMBrowserTest1( int argc, char * argv [] )

// [Deprecated]
// make sure copy/link dialog doesn't pop up, always copy on import
/*
QSettings settings;
QString settingsString = settings.value("MainWindow/DontConfirmCopyOnImport").toString();
settings.setValue("MainWindow/DontConfirmCopyOnImport", QString("0")); // QMessageBox::AcceptRole
CHECK_INT(browser.importDirectoryMode(), static_cast<int>(ctkDICOMBrowser::ImportDirectoryCopy));
*/
// [/Deprecated]

// Test import of a few specific files
QDirIterator it(argv[1], QStringList() << "*.IMA", QDir::Files, QDirIterator::Subdirectories);
// Skip a few files
it.next();
it.next();
// Add 3 files
QStringList files;
files << it.next();
files << it.next();
files << it.next();
browser.importFiles(files);
browser.waitForImportFinished();

qDebug() << browser.patientsAddedDuringImport()
<< " " << browser.studiesAddedDuringImport()
<< " " << browser.seriesAddedDuringImport()
<< " " << browser.instancesAddedDuringImport();

CHECK_INT(browser.patientsAddedDuringImport(), 1);
CHECK_INT(browser.studiesAddedDuringImport(), 1);
CHECK_INT(browser.seriesAddedDuringImport(), 1);
CHECK_INT(browser.instancesAddedDuringImport(), 3);

browser.importDirectories(QStringList() << argv[1]);
browser.waitForImportFinished();

qDebug() << "\n\nAdded to database directory: " << files;

// [Deprecated]
// reset to the original copy/import setting
settings.setValue("MainWindow/DontConfirmCopyOnImport", settingsString);
//settings.setValue("MainWindow/DontConfirmCopyOnImport", settingsString);
// [/Deprecated]

CHECK_INT(browser.patientsAddedDuringImport(), 1);
Expand Down
32 changes: 22 additions & 10 deletions Libs/DICOM/Widgets/ctkDICOMAppWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ void ctkDICOMAppWidgetPrivate::showUpdateSchemaDialog()
UpdateSchemaProgress->setMinimumDuration(0);
UpdateSchemaProgress->setValue(0);

//q->connect(UpdateSchemaProgress, SIGNAL(canceled()),
//q->connect(UpdateSchemaProgress, SIGNAL(canceled()),
// DICOMIndexer.data(), SLOT(cancel()));

q->connect(DICOMDatabase.data(), SIGNAL(schemaUpdateStarted(int)),
Expand All @@ -173,7 +173,7 @@ void ctkDICOMAppWidgetPrivate::showUpdateSchemaDialog()
q->connect(DICOMDatabase.data(), SIGNAL(schemaUpdated()),
&DICOMModel, SLOT(reset()));
// reset the database if canceled
q->connect(UpdateSchemaProgress, SIGNAL(canceled()),
q->connect(UpdateSchemaProgress, SIGNAL(canceled()),
&DICOMModel, SLOT(reset()));
}
UpdateSchemaProgress->show();
Expand All @@ -198,11 +198,17 @@ void ctkDICOMAppWidgetPrivate::showIndexerDialog()
IndexerProgress->setMinimumDuration(0);
IndexerProgress->setValue(0);

q->connect(IndexerProgress, SIGNAL(canceled()),
q->connect(IndexerProgress, SIGNAL(canceled()),
DICOMIndexer.data(), SLOT(cancel()));

q->connect(DICOMIndexer.data(), SIGNAL(progress(int)),
IndexerProgress, SLOT(setValue(int)));
// QProgressDialog requires a rate limiter when used from another thread,
// otherwise it crashes with stack overflow
// (see https://bugreports.qt.io/browse/QTBUG-83265).
// Since this feature is obsolete anyway (since ctkDICOMBrowser can now
// has built-in progress reporting of background data import), we just disable it.
// q->connect(DICOMIndexer.data(), SIGNAL(progress(int)),
// IndexerProgress, SLOT(setValue(int)));

q->connect(DICOMIndexer.data(), SIGNAL(progressDetail(QString)),
progressLabel, SLOT(setText(QString)));
q->connect(DICOMIndexer.data(), SIGNAL(progressDetail(QString)),
Expand All @@ -215,13 +221,13 @@ void ctkDICOMAppWidgetPrivate::showIndexerDialog()
q->connect(DICOMIndexer.data(), SIGNAL(indexingComplete(int, int, int, int)),
&DICOMModel, SLOT(reset()));
// stop indexing and reset the database if canceled
q->connect(IndexerProgress, SIGNAL(canceled()),
q->connect(IndexerProgress, SIGNAL(canceled()),
DICOMIndexer.data(), SLOT(cancel()));
q->connect(IndexerProgress, SIGNAL(canceled()),
q->connect(IndexerProgress, SIGNAL(canceled()),
&DICOMModel, SLOT(reset()));

// allow users of this widget to know that the process has finished
q->connect(IndexerProgress, SIGNAL(canceled()),
q->connect(IndexerProgress, SIGNAL(canceled()),
q, SIGNAL(directoryImported()));
q->connect(DICOMIndexer.data(), SIGNAL(indexingComplete(int, int, int, int)),
q, SIGNAL(directoryImported()));
Expand Down Expand Up @@ -490,9 +496,15 @@ void ctkDICOMAppWidget::onFileIndexed(const QString& filePath)
{
// Update the progress dialog when the file name changes
// - also allows for cancel button
QCoreApplication::instance()->processEvents();

// QProgressDialog requires a rate limiter when used from another thread,
// otherwise it crashes with stack overflow
// (see https://bugreports.qt.io/browse/QTBUG-83265).
// Since this feature is obsolete anyway (since ctkDICOMBrowser can now
// has built-in progress reporting of background data import), we just disable it.
//QCoreApplication::instance()->processEvents();

qDebug() << "Indexing \n\n\n\n" << filePath <<"\n\n\n";

}

//----------------------------------------------------------------------------
Expand Down
Loading