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

Fixes and enhs for the visual dicom browser #1201

Merged
merged 24 commits into from
Apr 27, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
aaff5d7
STYLE: Group Settings and Jobs UI groupboxes into Advanced
Punzo Mar 25, 2024
c06b4d9
ENH: Wrap DCMTK abort and release SCU method to make them thread-safe
Punzo Apr 2, 2024
a813cd2
ENH: Hitting enter in a search field should run the query
Punzo Apr 2, 2024
ab76e20
ENH: Patient selection has to be kept when querying the visual DICOM …
Punzo Apr 2, 2024
cdda814
BUG: Fix the insertPatient method not using uids from uidsForDataSet …
Punzo Apr 2, 2024
de98fc7
ENH: Add previous/next patient (Ctrl-tab/Ctrl-shift-tab) shortcuts
Punzo Apr 2, 2024
b66295c
BUG: Fix import for multiple folders for the visual DICOM browser
Punzo Apr 2, 2024
9b37639
BUG: Fix release association when canceling operations for the scheduler
Punzo Apr 3, 2024
08258d0
ENH: Add log error when a patient has missing PatientsName/PatientID.
Punzo Apr 3, 2024
c87fdbb
BUG: Fix minimum value for the progress bar UI in the ctkDICOMJobList…
Punzo Apr 3, 2024
c8ac922
ENH: Add connectionNames table to ctkDICOMDatabase
Punzo Apr 4, 2024
e4093e2
ENH: Add UI to filter enabled servers on patient basis
Punzo Apr 4, 2024
c86e441
STYLE: Replace QMutex with QMutexLocker in the ctkJobScheduler
Punzo Apr 8, 2024
0c990d9
ENH: Use json design in the dicom database for storing connections
Punzo Apr 8, 2024
ed7f061
STYLE: Set prefered vertical size policy to SearchMenuButton
Punzo Apr 9, 2024
faf2d61
BUG: Import folder shpuld not reset filters
Punzo Apr 15, 2024
fb987c2
STYLE: Clean set/get methods and allow/deny servers API
Punzo Apr 16, 2024
00b8697
ENH: Add trusted property to ctkDICOMServer
Punzo Apr 16, 2024
bfb9f65
BUG: Fix visual dicom browser tests
Punzo Apr 16, 2024
176f272
BUG: Resolve exception in getDICOMCenterFrameFromInstances for absent…
Punzo Apr 16, 2024
9f725e2
BUG: Fix filtering for ctkDICOMQuery
Punzo Apr 16, 2024
91c23c1
BUG: Fix filtering date condition in DIMSE query
Punzo Apr 22, 2024
0955cca
ENH: Clean trusted servers API and GUI
Punzo Apr 22, 2024
6b3968a
BUG: Do not overwrite the full palette in ctkDICOMServerNodeWidget2
Punzo Apr 24, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,13 @@ int main(int argc, char** argv)
DICOMVisualBrowser.setMinimumSize(QSize(1000, 1000));
DICOMVisualBrowser.setDatabaseDirectory(databaseDirectory);

DICOMVisualBrowser.serverSettingsGroupBox()->setChecked(true);
QObject::connect(&directoryButton, SIGNAL(directoryChanged(const QString&)),
&DICOMVisualBrowser, SLOT(setDatabaseDirectory(const QString&)));

mainLayout.addWidget(&DICOMVisualBrowser);

mainWidget.setLayout(&mainLayout);

mainWidget.show();
DICOMVisualBrowser.onShowPatients();

return app.exec();
}
6 changes: 3 additions & 3 deletions Libs/Core/ctkAbstractJob.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ struct CTK_CORE_EXPORT ctkJobDetail {
{
this->JobClass = job.className();
this->JobUID = job.jobUID();
this->CreationDateTime = job.creationDateTime().toString("HH:mm:ss.zzz ddd MMM yyyy");
this->StartDateTime = job.startDateTime().toString("HH:mm:ss.zzz ddd MMM yyyy");
this->CompletionDateTime = job.completionDateTime().toString("HH:mm:ss.zzz ddd MMM yyyy");
this->CreationDateTime = job.creationDateTime().toString("HH:mm:ss.zzz ddd dd MMM yyyy");
this->StartDateTime = job.startDateTime().toString("HH:mm:ss.zzz ddd dd MMM yyyy");
this->CompletionDateTime = job.completionDateTime().toString("HH:mm:ss.zzz ddd dd MMM yyyy");
}
virtual ~ctkJobDetail() = default;

Expand Down
48 changes: 44 additions & 4 deletions Libs/Core/ctkJobScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <QSharedPointer>
#include <QThreadPool>
#include <QUuid>
#include <QDebug>
Punzo marked this conversation as resolved.
Show resolved Hide resolved

// CTK includes
#include "ctkAbstractJob.h"
Expand Down Expand Up @@ -219,6 +220,25 @@ void ctkJobSchedulerPrivate::removeJobs(const QStringList &jobUIDs)
}
}

//------------------------------------------------------------------------------
void ctkJobSchedulerPrivate::removeAllJobs()
{
Q_Q(ctkJobScheduler);

this->QueueMutex.lock();
Punzo marked this conversation as resolved.
Show resolved Hide resolved
foreach (QSharedPointer<ctkAbstractJob> job, this->JobsQueue)
{
Punzo marked this conversation as resolved.
Show resolved Hide resolved
QObject::disconnect(job.data(), SIGNAL(started()), q, SLOT(onJobStarted()));
QObject::disconnect(job.data(), SIGNAL(canceled()), q, SLOT(onJobCanceled()));
QObject::disconnect(job.data(), SIGNAL(failed()), q, SLOT(onJobFailed()));
QObject::disconnect(job.data(), SIGNAL(finished()), q, SLOT(onJobFinished()));
QObject::disconnect(job.data(), SIGNAL(progressJobDetail(QVariant)), q, SIGNAL(progressJobDetail(QVariant)));

this->JobsQueue.remove(job->jobUID());
}
this->QueueMutex.unlock();
Punzo marked this conversation as resolved.
Show resolved Hide resolved
}

//------------------------------------------------------------------------------
int ctkJobSchedulerPrivate::getSameTypeJobsInThreadPoolQueueOrRunning(QSharedPointer<ctkAbstractJob> job)
{
Expand Down Expand Up @@ -271,14 +291,15 @@ ctkJobScheduler::ctkJobScheduler(ctkJobSchedulerPrivate* pimpl, QObject* parent)
// --------------------------------------------------------------------------
ctkJobScheduler::~ctkJobScheduler()
{
Q_D(ctkJobScheduler);
this->setFreezeJobsScheduling(true);
this->stopAllJobs(true);
// stopAllJobs is not main thread blocking. Therefore we need actually
// to wait the jobs to end (either finished or stopped) before closing the application.
// Issue: waiting time for the jobs to stop vs waiting the application to close.
// We should avoid the application crash at exiting.
// Is 10 sec enough or too long?
this->waitForDone(10000);
// The job scheduler currently waits all the jobs to be properly stopped.
this->waitForFinish(true);
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -309,6 +330,25 @@ int ctkJobScheduler::numberOfPersistentJobs()
return numberOfPersistentJobs;
}

//----------------------------------------------------------------------------
int ctkJobScheduler::numberOfRunningJobs()
{
Q_D(ctkJobScheduler);

d->QueueMutex.lock();
Punzo marked this conversation as resolved.
Show resolved Hide resolved
int numberOfRunningJobs = 0;
foreach (QSharedPointer<ctkAbstractJob> job, d->JobsQueue)
{
Punzo marked this conversation as resolved.
Show resolved Hide resolved
if (job->status() == ctkAbstractJob::JobStatus::Running)
{
numberOfRunningJobs++;
}
}
d->QueueMutex.unlock();

return numberOfRunningJobs;
}

//----------------------------------------------------------------------------
void ctkJobScheduler::addJob(ctkAbstractJob* job)
{
Expand Down Expand Up @@ -378,9 +418,9 @@ void ctkJobScheduler::waitForFinish(bool waitForPersistentJobs)
{
numberOfPersistentJobs = 0;
}
while (this->numberOfJobs() > numberOfPersistentJobs)
while (this->numberOfRunningJobs() > numberOfPersistentJobs)
{
d->ThreadPool->waitForDone(300);
this->waitForDone(500);
}
}

Expand Down
1 change: 1 addition & 0 deletions Libs/Core/ctkJobScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class CTK_CORE_EXPORT ctkJobScheduler : public QObject
/// Jobs managment
Q_INVOKABLE int numberOfJobs();
Q_INVOKABLE int numberOfPersistentJobs();
Q_INVOKABLE int numberOfRunningJobs();

Q_INVOKABLE void addJob(ctkAbstractJob* job);

Expand Down
1 change: 1 addition & 0 deletions Libs/Core/ctkJobScheduler_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public Q_SLOTS:
virtual bool insertJob(QSharedPointer<ctkAbstractJob> job);
virtual bool removeJob(const QString& jobUID);
virtual void removeJobs(const QStringList& jobUIDs);
virtual void removeAllJobs();
int getSameTypeJobsInThreadPoolQueueOrRunning(QSharedPointer<ctkAbstractJob> job);
QString generateUniqueJobUID();

Expand Down
10 changes: 10 additions & 0 deletions Libs/DICOM/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ set(KIT_SRCS
ctkDICOMDisplayedFieldGenerator.h
ctkDICOMEcho.cpp
ctkDICOMEcho.h
ctkDICOMEchoJob.cpp
ctkDICOMEchoJob.h
ctkDICOMEchoJob_p.h
ctkDICOMEchoWorker.cpp
ctkDICOMEchoWorker.h
ctkDICOMEchoWorker_p.h
ctkDICOMFilterProxyModel.cpp
ctkDICOMFilterProxyModel.h
ctkDICOMIndexer.cpp
Expand Down Expand Up @@ -105,6 +111,10 @@ set(KIT_MOC_SRCS
ctkDICOMDisplayedFieldGenerator_p.h
ctkDICOMDisplayedFieldGeneratorRuleFactory.h
ctkDICOMEcho.h
ctkDICOMEchoJob.h
ctkDICOMEchoJob_p.h
ctkDICOMEchoWorker.h
ctkDICOMEchoWorker_p.h
ctkDICOMIndexer.h
ctkDICOMIndexer_p.h
ctkDICOMInserter.h
Expand Down
33 changes: 25 additions & 8 deletions Libs/DICOM/Core/Resources/dicom-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ DROP INDEX IF EXISTS 'SeriesStudyIndex' ;
DROP INDEX IF EXISTS 'StudiesPatientIndex' ;

CREATE TABLE 'SchemaInfo' ( 'Version' VARCHAR(1024) NOT NULL );
INSERT INTO 'SchemaInfo' VALUES('0.8.0');
INSERT INTO 'SchemaInfo' VALUES('0.8.1');

CREATE TABLE 'Images' (
'SOPInstanceUID' VARCHAR(64) NOT NULL,
Expand All @@ -32,7 +32,9 @@ CREATE TABLE 'Images' (
'SeriesInstanceUID' VARCHAR(64) NOT NULL ,
'InsertTimestamp' VARCHAR(20) NOT NULL ,
'DisplayedFieldsUpdatedTimestamp' DATETIME NULL ,
PRIMARY KEY ('SOPInstanceUID') );
PRIMARY KEY ('SOPInstanceUID')
);

CREATE TABLE 'Patients' (
'UID' INTEGER PRIMARY KEY AUTOINCREMENT,
'PatientsName' VARCHAR(255) NULL ,
Expand All @@ -46,7 +48,16 @@ CREATE TABLE 'Patients' (
'DisplayedPatientsName' VARCHAR(255) NULL ,
'DisplayedNumberOfStudies' INT NULL ,
'DisplayedLastStudyDate' DATE NULL ,
'DisplayedFieldsUpdatedTimestamp' DATETIME NULL );
'DisplayedFieldsUpdatedTimestamp' DATETIME NULL
);

CREATE TABLE 'ConnectionNames' (
'ConnectionID' INTEGER PRIMARY KEY AUTOINCREMENT,
'ConnectionName' VARCHAR(255) NOT NULL,
'PatientUID' INTEGER,
FOREIGN KEY('PatientUID') REFERENCES Patients('UID')
);

CREATE TABLE 'Studies' (
'StudyInstanceUID' VARCHAR(64) NOT NULL ,
'PatientsUID' INT NOT NULL ,
Expand All @@ -62,7 +73,9 @@ CREATE TABLE 'Studies' (
'InsertTimestamp' VARCHAR(20) NOT NULL ,
'DisplayedNumberOfSeries' INT NULL ,
'DisplayedFieldsUpdatedTimestamp' DATETIME NULL ,
PRIMARY KEY ('StudyInstanceUID') );
PRIMARY KEY ('StudyInstanceUID')
);

CREATE TABLE 'Series' (
'SeriesInstanceUID' VARCHAR(64) NOT NULL ,
'StudyInstanceUID' VARCHAR(64) NOT NULL ,
Expand All @@ -83,7 +96,8 @@ CREATE TABLE 'Series' (
'DisplayedSize' VARCHAR(20) NULL ,
'DisplayedNumberOfFrames' INT NULL ,
'DisplayedFieldsUpdatedTimestamp' DATETIME NULL ,
PRIMARY KEY ('SeriesInstanceUID') );
PRIMARY KEY ('SeriesInstanceUID')
);

CREATE INDEX IF NOT EXISTS 'ImagesFilenameIndex' ON 'Images' ('Filename');
CREATE INDEX IF NOT EXISTS 'ImagesFilenameIndex' ON 'Images' ('URL');
Expand All @@ -93,7 +107,8 @@ CREATE INDEX IF NOT EXISTS 'StudiesPatientIndex' ON 'Studies' ('PatientsUID');

CREATE TABLE 'Directories' (
'Dirname' VARCHAR(1024) ,
PRIMARY KEY ('Dirname') );
PRIMARY KEY ('Dirname')
);

CREATE TABLE 'ColumnDisplayProperties' (
'TableName' VARCHAR(64) NOT NULL,
Expand All @@ -102,7 +117,8 @@ CREATE TABLE 'ColumnDisplayProperties' (
'Visibility' INT NULL DEFAULT 1 ,
'Weight' INT NULL ,
'Format' VARCHAR(255) NULL ,
PRIMARY KEY ('TableName', 'FieldName') );
PRIMARY KEY ('TableName', 'FieldName')
);

INSERT INTO 'ColumnDisplayProperties' VALUES('Patients', 'UID', '', 0, 0, '');
INSERT INTO 'ColumnDisplayProperties' VALUES('Patients', 'PatientsName', 'Patient name', 0, 0, '');
Expand Down Expand Up @@ -157,4 +173,5 @@ CREATE TABLE 'DisplayedFieldGeneratorRules' (
'Name' VARCHAR(64) NOT NULL,
'Enabled' INT NULL DEFAULT 1 ,
'Options' VARCHAR(255) NULL ,
PRIMARY KEY ('Name') );
PRIMARY KEY ('Name')
);
2 changes: 1 addition & 1 deletion Libs/DICOM/Core/Testing/Cpp/ctkDICOMJobTest1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ int ctkDICOMJobTest1(int argc, char* argv[])
CHECK_INT(queryJob.maximumNumberOfRetry(), 3);
CHECK_INT(queryJob.maximumConcurrentJobsPerType(), 20);
CHECK_INT(queryJob.priority(), QThread::Priority::LowPriority);
CHECK_INT(queryJob.dicomLevel(), ctkDICOMJob::DICOMLevels::Patients);
CHECK_INT(queryJob.dicomLevel(), ctkDICOMJob::DICOMLevels::None);
CHECK_QSTRING(queryJob.patientID(), "");
CHECK_QSTRING(queryJob.studyInstanceUID(), "");
CHECK_QSTRING(queryJob.seriesInstanceUID(), "");
Expand Down
Loading
Loading