ImFusion SDK 4.3
Scanner Class Reference

#include <ImFusion/Dicom/GUI/Scanner.h>

Scan different locations for DICOM files. More...

+ Inheritance diagram for Scanner:

Detailed Description

Scan different locations for DICOM files.

Currently supports scanning of folder, DICOMDIRs and PACS.

Each found DICOM file is automatically split into a Patient -> Study -> Series -> Image hierarchy. When a new DICOM file is found, it will be merged into the existing hierarchy. E.g. two series of the same patient will result in a single Patient object containing two Series objects. Patients are merged if their id and name are identical, Studies and Series are merged when their instanceUIDs are identical. Be aware that empty ids do not receive any special treatment. This means that all DICOMs without valid patient information will be merged into one patient.

This class is limited thread-safe: the scan methods can be called from one thread while takePatients or cancel are called from another. Calling multiple scan methods simultaneously from different threads is not supported! The scan methods already try to parallelize their work as best as possible. To run a scan in the background, std::async can be used:

Dicom::Scanner scanner(cache);
std::future<std::vector<Patient*>> patients = std::async(std::launch::async, [&scanner]() {
scanner.scanDirectory("/some/dir", true, false, true);
return scanner.takePatients();
});
T async(T... args)
Scan different locations for DICOM files.
Definition Scanner.h:200
const std::vector< Patient * > & patients() const
Return the patients found by the last scan.
T make_shared(T... args)

Internally the Scanner uses Dicom::DatasetCache for loading DICOMs.

Public Member Functions

 Scanner (Dicom::SharedDatasetCache cache)
 
void setPacs (DicomPacsCommunication *pacs)
 Sets the PACS instance to use for scanning.
 
void setDatasetCache (Dicom::SharedDatasetCache cache)
 
Dicom::SharedDatasetCache datasetCache () const
 
void setNumberOfThreads (int threads)
 Sets the number of threads used internally.
 
int numberOfThreads () const
 
void scanDirectory (const QString &directory, bool recursive, bool useDicomdirOnly, bool checkDicomHeader)
 Scan a directory for Dicom files.
 
void scanDicomDir (const QString &dicomDirFile)
 Scan a DICOMDIR file.
 
void scanPacs (const DcmDataset &requestedTags)
 Retrieve patients from a PACS with a C-FIND.
 
void scanPacs (const QString &patientNameFilter, const QString &studyFilter)
 Retrieve patients from a PACS by requesting the default tags.
 
void scanPacsSeries (PacsSeriesProxy *psp)
 Retrieve a series from a PACS with a C-MOVE.
 
std::optional< Network::HttpErrorscanWeb (const Filesystem::Url &url)
 Scans a DICOMweb server for patients.
 
void cancel ()
 Cancel any scanning.
 
const std::vector< Patient * > & patients () const
 Return the patients found by the last scan.
 
std::vector< std::unique_ptr< Patient > > takePatients ()
 Retrieve the patients found by the last scan.
 

Protected Member Functions

virtual void addPatient (Patient *patient)
 Add a new patient to the scan results.
 
virtual void removePacsProxy (PacsSeriesProxy *psp)
 Remove a series proxy from the scan results.
 
virtual void updateProgress (int val, int max)
 Called by the scan methods to report the current progress.
 
virtual void updateProgressText (const std::string &text)
 Called by the scan methods to report the current progress.
 
void scanDicomDirImpl (const QString &dicomDirFile, bool callUpdateProgress)
 
QFileInfoList retrieveFileList (const QDir &directory, bool recursive, bool dicomdirOnly, int depth)
 

Protected Attributes

Dicom::SharedDatasetCache m_cache
 
DicomPacsCommunicationm_pacs
 
std::atomic< bool > m_wasCancelled
 
int m_numThreads
 Number of threads used internally by scanDirectory.
 
std::mutex m_patientsLock
 
std::vector< Patient * > m_patients
 

Member Function Documentation

◆ setNumberOfThreads()

void setNumberOfThreads ( int threads)

Sets the number of threads used internally.

By default omp_get_max_threads() * 3 / 4 threads are used. Currently only used by scanDirectory. Using multiple threads usually speeds up scanning large folders on HDDs and SSDs, but might have the opposite effect on slow USB or CD-ROM drives.

◆ scanDirectory()

void scanDirectory ( const QString & directory,
bool recursive,
bool useDicomdirOnly,
bool checkDicomHeader )

Scan a directory for Dicom files.

This method is blocking.

Parameters
recursiveSpecifies whether to recursively scan sub-directories as well
useDicomdirOnlyOnly load a DICOMDIR contained in this folder or load nothing.
checkDicomHeaderSpecifies whether to only load files containing a valid DICOM header.

◆ scanDicomDir()

void scanDicomDir ( const QString & dicomDirFile)

Scan a DICOMDIR file.

This method is blocking.

◆ scanPacs() [1/2]

void scanPacs ( const DcmDataset & requestedTags)

Retrieve patients from a PACS with a C-FIND.

This requires a valid DicomPacsCommunication being set with setPacs. Contrary to the other scan method, the scan result will only contain Patients and Studies but no concrete Series.

Downloading each series from the PACS directly would be too time consuming in general, so instead of Series each Study only contains a PacsSeriesProxy that needs to be resolved into a real Series by calling scanPacsSeries.

The patients found by this method, will only contain the tags that are also present in the given DcmDataset. See scanPacs(QString, QString) for tags that should be contained in this DcmDataset. If the tags contain a value, the value will be used for filtering the result on the server. For example a PatientID of "510*" would match all patients with an ID starting with "510".

This method is blocking.

◆ scanPacs() [2/2]

void scanPacs ( const QString & patientNameFilter,
const QString & studyFilter )

Retrieve patients from a PACS by requesting the default tags.

The default tags are:

  • StudyInstanceUID
  • StudyID
  • StudyTime
  • StudyDate
  • StudyDescription
  • PatientID
  • PatientName
  • PatientSex
  • PatientBirthDate
  • PatientComments
Parameters
patientNameFilterOnly retrieve patients with a matching PatientName. An empty string retrieves all patients.
studyFilterOnly retrieve studies with a matching StudyDescription. An empty string retrieves all studies.

◆ scanPacsSeries()

void scanPacsSeries ( PacsSeriesProxy * psp)

Retrieve a series from a PACS with a C-MOVE.

This transfers the complete DICOM for a series proxy from the PACS. Note that a single series proxy can lead to multiple series to be downloaded.

◆ scanWeb()

Scans a DICOMweb server for patients.

The server must implement QIDO-RS. The URL must be to the DICOMweb endpoint of the server (e.g. https://example.com/dicom-web). and can contain query parameters. The query parameters are passed to the initial /studies request. If authentication is required, it can be set through Dicom::DatasetCache::setAuthorizationProvider. If an error occurs it is returned. The scan is not cancelled after an error.

◆ cancel()

void cancel ( )

Cancel any scanning.

This method is thread-safe.

◆ patients()

const std::vector< Patient * > & patients ( ) const

Return the patients found by the last scan.

No ownership is transfered. Triggering a new scan will delete the patients. This method is not thread-safe.

◆ takePatients()

std::vector< std::unique_ptr< Patient > > takePatients ( )

Retrieve the patients found by the last scan.

Ownership is transfered of the patients to the caller. After calling this method patients will return an empty list. This method is thread-safe.

◆ addPatient()

virtual void addPatient ( Patient * patient)
protectedvirtual

Add a new patient to the scan results.

The given patient is automatically merged with the existing patients. All scan methods call this method internally. This method is thread-safe and derived method must be thread-safe as well.

Reimplemented in ScannerQt.

◆ removePacsProxy()

virtual void removePacsProxy ( PacsSeriesProxy * psp)
protectedvirtual

Remove a series proxy from the scan results.

It is called by scanPacsSeries once all series of a PacsSeriesProxy were received. This method is thread-safe and derived method must be thread-safe as well.

Reimplemented in ScannerQt.

◆ updateProgress()

virtual void updateProgress ( int val,
int max )
protectedvirtual

Called by the scan methods to report the current progress.

The default implementation doesn't do anything. This method is thread-safe and derived method must be thread-safe as well.

Reimplemented in ScannerQt.

◆ updateProgressText()

virtual void updateProgressText ( const std::string & text)
protectedvirtual

Called by the scan methods to report the current progress.

The default implementation doesn't do anything. This method is thread-safe and derived method must be thread-safe as well.

Reimplemented in ScannerQt.


The documentation for this class was generated from the following file:
Search Tab / S to search, Esc to close