|
@@ -60,15 +60,18 @@ class ctkDICOMQueryPrivate
|
|
|
public:
|
|
|
ctkDICOMQueryPrivate();
|
|
|
~ctkDICOMQueryPrivate();
|
|
|
- QString CallingAETitle;
|
|
|
- QString CalledAETitle;
|
|
|
- QString Host;
|
|
|
- int Port;
|
|
|
- QMap<QString,QVariant> Filters;
|
|
|
- DcmSCU SCU;
|
|
|
- DcmDataset* query;
|
|
|
- QStringList StudyInstanceUIDList;
|
|
|
|
|
|
+ /// Add a StudyInstanceUID to be queried
|
|
|
+ void addStudyInstanceUID(const QString& StudyInstanceUID );
|
|
|
+
|
|
|
+ QString CallingAETitle;
|
|
|
+ QString CalledAETitle;
|
|
|
+ QString Host;
|
|
|
+ int Port;
|
|
|
+ QMap<QString,QVariant> Filters;
|
|
|
+ DcmSCU SCU;
|
|
|
+ DcmDataset* Query;
|
|
|
+ QStringList StudyInstanceUIDList;
|
|
|
};
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
@@ -77,22 +80,29 @@ public:
|
|
|
//------------------------------------------------------------------------------
|
|
|
ctkDICOMQueryPrivate::ctkDICOMQueryPrivate()
|
|
|
{
|
|
|
- query = new DcmDataset();
|
|
|
+ this->Query = new DcmDataset();
|
|
|
+ this->Port = 0;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
ctkDICOMQueryPrivate::~ctkDICOMQueryPrivate()
|
|
|
{
|
|
|
- delete query;
|
|
|
+ delete this->Query;
|
|
|
}
|
|
|
|
|
|
+//------------------------------------------------------------------------------
|
|
|
+void ctkDICOMQueryPrivate::addStudyInstanceUID( const QString& s )
|
|
|
+{
|
|
|
+ this->StudyInstanceUIDList.append ( s );
|
|
|
+}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
// ctkDICOMQuery methods
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-ctkDICOMQuery::ctkDICOMQuery()
|
|
|
- : d_ptr(new ctkDICOMQueryPrivate)
|
|
|
+ctkDICOMQuery::ctkDICOMQuery(QObject* parentObject)
|
|
|
+ : QObject(parentObject)
|
|
|
+ , d_ptr(new ctkDICOMQueryPrivate)
|
|
|
{
|
|
|
}
|
|
|
|
|
@@ -101,53 +111,46 @@ ctkDICOMQuery::~ctkDICOMQuery()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-void ctkDICOMQuery::addStudyInstanceUID ( QString s )
|
|
|
-{
|
|
|
- Q_D(ctkDICOMQuery);
|
|
|
- d->StudyInstanceUIDList.append ( s );
|
|
|
-}
|
|
|
-
|
|
|
/// Set methods for connectivity
|
|
|
//------------------------------------------------------------------------------
|
|
|
-void ctkDICOMQuery::setCallingAETitle ( QString callingAETitle )
|
|
|
+void ctkDICOMQuery::setCallingAETitle( const QString& callingAETitle )
|
|
|
{
|
|
|
Q_D(ctkDICOMQuery);
|
|
|
d->CallingAETitle = callingAETitle;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-const QString& ctkDICOMQuery::callingAETitle()
|
|
|
+QString ctkDICOMQuery::callingAETitle() const
|
|
|
{
|
|
|
- Q_D(ctkDICOMQuery);
|
|
|
+ Q_D(const ctkDICOMQuery);
|
|
|
return d->CallingAETitle;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-void ctkDICOMQuery::setCalledAETitle ( QString calledAETitle )
|
|
|
+void ctkDICOMQuery::setCalledAETitle( const QString& calledAETitle )
|
|
|
{
|
|
|
Q_D(ctkDICOMQuery);
|
|
|
d->CalledAETitle = calledAETitle;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-const QString& ctkDICOMQuery::calledAETitle()
|
|
|
+QString ctkDICOMQuery::calledAETitle()const
|
|
|
{
|
|
|
- Q_D(ctkDICOMQuery);
|
|
|
+ Q_D(const ctkDICOMQuery);
|
|
|
return d->CalledAETitle;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-void ctkDICOMQuery::setHost ( QString host )
|
|
|
+void ctkDICOMQuery::setHost( const QString& host )
|
|
|
{
|
|
|
Q_D(ctkDICOMQuery);
|
|
|
d->Host = host;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-const QString& ctkDICOMQuery::host()
|
|
|
+QString ctkDICOMQuery::host() const
|
|
|
{
|
|
|
- Q_D(ctkDICOMQuery);
|
|
|
+ Q_D(const ctkDICOMQuery);
|
|
|
return d->Host;
|
|
|
}
|
|
|
|
|
@@ -159,30 +162,30 @@ void ctkDICOMQuery::setPort ( int port )
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-int ctkDICOMQuery::port()
|
|
|
+int ctkDICOMQuery::port()const
|
|
|
{
|
|
|
- Q_D(ctkDICOMQuery);
|
|
|
+ Q_D(const ctkDICOMQuery);
|
|
|
return d->Port;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-void ctkDICOMQuery::setFilters ( QMap<QString,QVariant> filters )
|
|
|
+void ctkDICOMQuery::setFilters( const QMap<QString,QVariant>& filters )
|
|
|
{
|
|
|
Q_D(ctkDICOMQuery);
|
|
|
d->Filters = filters;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-QMap<QString,QVariant> ctkDICOMQuery::filters()
|
|
|
+QMap<QString,QVariant> ctkDICOMQuery::filters()const
|
|
|
{
|
|
|
- Q_D(ctkDICOMQuery);
|
|
|
+ Q_D(const ctkDICOMQuery);
|
|
|
return d->Filters;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
-QStringList ctkDICOMQuery::studyInstanceUIDQueried()
|
|
|
+QStringList ctkDICOMQuery::studyInstanceUIDQueried()const
|
|
|
{
|
|
|
- Q_D(ctkDICOMQuery);
|
|
|
+ Q_D(const ctkDICOMQuery);
|
|
|
return d->StudyInstanceUIDList;
|
|
|
}
|
|
|
|
|
@@ -191,6 +194,9 @@ void ctkDICOMQuery::query(ctkDICOMDatabase& database )
|
|
|
{
|
|
|
// ctkDICOMDatabase::setDatabase ( database );
|
|
|
Q_D(ctkDICOMQuery);
|
|
|
+ // In the following, we emit progress(int) after progress(QString), this
|
|
|
+ // is in case the connected object doesn't refresh its ui when the progress
|
|
|
+ // message is updated but only if the progress value is (e.g. QProgressDialog)
|
|
|
if ( database.database().isOpen() )
|
|
|
{
|
|
|
logger.debug ( "DB open in Query" );
|
|
@@ -234,82 +240,82 @@ void ctkDICOMQuery::query(ctkDICOMDatabase& database )
|
|
|
d->SCU.negotiateAssociation();
|
|
|
|
|
|
// Clear the query
|
|
|
- unsigned long elements = d->query->card();
|
|
|
+ unsigned long elements = d->Query->card();
|
|
|
// Clean it out
|
|
|
for ( unsigned long i = 0; i < elements; i++ )
|
|
|
{
|
|
|
- d->query->remove ( 0ul );
|
|
|
+ d->Query->remove ( 0ul );
|
|
|
}
|
|
|
- d->query->insertEmptyElement ( DCM_PatientID );
|
|
|
- d->query->insertEmptyElement ( DCM_PatientsName );
|
|
|
- d->query->insertEmptyElement ( DCM_PatientsBirthDate );
|
|
|
- d->query->insertEmptyElement ( DCM_StudyID );
|
|
|
- d->query->insertEmptyElement ( DCM_StudyInstanceUID );
|
|
|
- d->query->insertEmptyElement ( DCM_StudyDescription );
|
|
|
- d->query->insertEmptyElement ( DCM_StudyDate );
|
|
|
- d->query->insertEmptyElement ( DCM_SeriesNumber );
|
|
|
- d->query->insertEmptyElement ( DCM_SeriesDescription );
|
|
|
- d->query->insertEmptyElement ( DCM_SeriesInstanceUID );
|
|
|
- d->query->insertEmptyElement ( DCM_StudyTime );
|
|
|
- d->query->insertEmptyElement ( DCM_SeriesDate );
|
|
|
- d->query->insertEmptyElement ( DCM_SeriesTime );
|
|
|
- d->query->insertEmptyElement ( DCM_Modality );
|
|
|
- d->query->insertEmptyElement ( DCM_ModalitiesInStudy );
|
|
|
- d->query->insertEmptyElement ( DCM_AccessionNumber );
|
|
|
- d->query->insertEmptyElement ( DCM_NumberOfSeriesRelatedInstances ); // Number of images in the series
|
|
|
- d->query->insertEmptyElement ( DCM_NumberOfStudyRelatedInstances ); // Number of images in the series
|
|
|
- d->query->insertEmptyElement ( DCM_NumberOfStudyRelatedSeries ); // Number of images in the series
|
|
|
-
|
|
|
- d->query->putAndInsertString ( DCM_QueryRetrieveLevel, "STUDY" );
|
|
|
+ d->Query->insertEmptyElement ( DCM_PatientID );
|
|
|
+ d->Query->insertEmptyElement ( DCM_PatientsName );
|
|
|
+ d->Query->insertEmptyElement ( DCM_PatientsBirthDate );
|
|
|
+ d->Query->insertEmptyElement ( DCM_StudyID );
|
|
|
+ d->Query->insertEmptyElement ( DCM_StudyInstanceUID );
|
|
|
+ d->Query->insertEmptyElement ( DCM_StudyDescription );
|
|
|
+ d->Query->insertEmptyElement ( DCM_StudyDate );
|
|
|
+ d->Query->insertEmptyElement ( DCM_SeriesNumber );
|
|
|
+ d->Query->insertEmptyElement ( DCM_SeriesDescription );
|
|
|
+ d->Query->insertEmptyElement ( DCM_SeriesInstanceUID );
|
|
|
+ d->Query->insertEmptyElement ( DCM_StudyTime );
|
|
|
+ d->Query->insertEmptyElement ( DCM_SeriesDate );
|
|
|
+ d->Query->insertEmptyElement ( DCM_SeriesTime );
|
|
|
+ d->Query->insertEmptyElement ( DCM_Modality );
|
|
|
+ d->Query->insertEmptyElement ( DCM_ModalitiesInStudy );
|
|
|
+ d->Query->insertEmptyElement ( DCM_AccessionNumber );
|
|
|
+ d->Query->insertEmptyElement ( DCM_NumberOfSeriesRelatedInstances ); // Number of images in the series
|
|
|
+ d->Query->insertEmptyElement ( DCM_NumberOfStudyRelatedInstances ); // Number of images in the series
|
|
|
+ d->Query->insertEmptyElement ( DCM_NumberOfStudyRelatedSeries ); // Number of images in the series
|
|
|
+
|
|
|
+ d->Query->putAndInsertString ( DCM_QueryRetrieveLevel, "STUDY" );
|
|
|
|
|
|
foreach( QString key, d->Filters.keys() )
|
|
|
- {
|
|
|
- if ( key == QString("Name") )
|
|
|
{
|
|
|
+ if ( key == QString("Name") )
|
|
|
+ {
|
|
|
// make the filter a wildcard in dicom style
|
|
|
- d->query->putAndInsertString( DCM_PatientsName,
|
|
|
+ d->Query->putAndInsertString( DCM_PatientsName,
|
|
|
(QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
|
|
|
- }
|
|
|
+ }
|
|
|
if ( key == QString("Study") )
|
|
|
- {
|
|
|
+ {
|
|
|
// make the filter a wildcard in dicom style
|
|
|
- d->query->putAndInsertString( DCM_StudyDescription,
|
|
|
+ d->Query->putAndInsertString( DCM_StudyDescription,
|
|
|
(QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
|
|
|
- }
|
|
|
+ }
|
|
|
if ( key == QString("Series") )
|
|
|
- {
|
|
|
+ {
|
|
|
// make the filter a wildcard in dicom style
|
|
|
- d->query->putAndInsertString( DCM_SeriesDescription,
|
|
|
+ d->Query->putAndInsertString( DCM_SeriesDescription,
|
|
|
(QString("*") + d->Filters[key].toString() + QString("*")).toAscii().data());
|
|
|
- }
|
|
|
+ }
|
|
|
if ( key == QString("ID") )
|
|
|
- {
|
|
|
+ {
|
|
|
// make the filter a wildcard in dicom style
|
|
|
- d->query->putAndInsertString( DCM_PatientID,
|
|
|
+ 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())
|
|
|
- {
|
|
|
+ foreach (const 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() );
|
|
|
+ d->Query->putAndInsertString( DCM_ModalitiesInStudy, modalitySearch.toAscii().data() );
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
if ( d->Filters.keys().contains("StartDate") && d->Filters.keys().contains("EndDate") )
|
|
|
- {
|
|
|
+ {
|
|
|
QString dateRange = d->Filters["StartDate"].toString() +
|
|
|
QString("-") +
|
|
|
d->Filters["EndDate"].toString();
|
|
|
- d->query->putAndInsertString ( DCM_StudyDate, dateRange.toAscii().data() );
|
|
|
+ d->Query->putAndInsertString ( DCM_StudyDate, dateRange.toAscii().data() );
|
|
|
logger.debug("Query on study time " + dateRange);
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
emit progress(30);
|
|
|
|
|
@@ -319,7 +325,7 @@ void ctkDICOMQuery::query(ctkDICOMDatabase& database )
|
|
|
presentationContex = d->SCU.findPresentationContextID ( UID_FINDStudyRootQueryRetrieveInformationModel, UID_LittleEndianExplicitTransferSyntax );
|
|
|
if ( presentationContex == 0 )
|
|
|
{
|
|
|
- presentationContex = d->SCU.findPresentationContextID ( UID_FINDStudyRootQueryRetrieveInformationModel, UID_BigEndianExplicitTransferSyntax );
|
|
|
+ presentationContex = d->SCU.findPresentationContextID ( UID_FINDStudyRootQueryRetrieveInformationModel, UID_BigEndianExplicitTransferSyntax );
|
|
|
}
|
|
|
if ( presentationContex == 0 )
|
|
|
{
|
|
@@ -338,7 +344,7 @@ void ctkDICOMQuery::query(ctkDICOMDatabase& database )
|
|
|
}
|
|
|
emit progress(40);
|
|
|
|
|
|
- OFCondition status = d->SCU.sendFINDRequest ( presentationContex, d->query, responses );
|
|
|
+ OFCondition status = d->SCU.sendFINDRequest ( presentationContex, d->Query, responses );
|
|
|
if ( status.good() )
|
|
|
{
|
|
|
logger.debug ( "Find succeded" );
|
|
@@ -359,13 +365,13 @@ void ctkDICOMQuery::query(ctkDICOMDatabase& database )
|
|
|
database.insert ( dataset );
|
|
|
OFString StudyInstanceUID;
|
|
|
dataset->findAndGetOFString ( DCM_StudyInstanceUID, StudyInstanceUID );
|
|
|
- this->addStudyInstanceUID ( QString ( StudyInstanceUID.c_str() ) );
|
|
|
+ d->addStudyInstanceUID ( QString ( StudyInstanceUID.c_str() ) );
|
|
|
}
|
|
|
}
|
|
|
delete responses;
|
|
|
|
|
|
// Now search each Study
|
|
|
- d->query->putAndInsertString ( DCM_QueryRetrieveLevel, "SERIES" );
|
|
|
+ d->Query->putAndInsertString ( DCM_QueryRetrieveLevel, "SERIES" );
|
|
|
float progressRatio = 25. / d->StudyInstanceUIDList.count();
|
|
|
int i = 0;
|
|
|
foreach ( QString StudyInstanceUID, d->StudyInstanceUIDList )
|
|
@@ -374,9 +380,9 @@ void ctkDICOMQuery::query(ctkDICOMDatabase& database )
|
|
|
emit progress(QString("Starting Series C-FIND for Series: ") + StudyInstanceUID);
|
|
|
emit progress(50 + (progressRatio * i++));
|
|
|
|
|
|
- d->query->putAndInsertString ( DCM_StudyInstanceUID, StudyInstanceUID.toStdString().c_str() );
|
|
|
+ d->Query->putAndInsertString ( DCM_StudyInstanceUID, StudyInstanceUID.toStdString().c_str() );
|
|
|
responses = new FINDResponses();
|
|
|
- status = d->SCU.sendFINDRequest ( 0, d->query, responses );
|
|
|
+ status = d->SCU.sendFINDRequest ( 0, d->Query, responses );
|
|
|
if ( status.good() )
|
|
|
{
|
|
|
for ( OFListIterator(FINDResponse*) it = responses->begin(); it != responses->end(); it++ )
|