| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 | 
							- // Qt includes
 
- #include <QSqlQuery>
 
- #include <QSqlRecord>
 
- #include <QVariant>
 
- #include <QDate>
 
- #include <QStringList>
 
- #include <QSet>
 
- #include <QFile>
 
- #include <QDirIterator>
 
- #include <QFileInfo>
 
- #include <QDebug>
 
- // CTKDCMTK includes
 
- #include "qCTKDCMTKIndexer.h"
 
- // DCMTK includes
 
- #ifndef WIN32
 
-   #define HAVE_CONFIG_H 
 
- #endif
 
- #include <dcmtk/dcmdata/dcfilefo.h>
 
- #include <dcmtk/dcmdata/dcfilefo.h>
 
- #include <dcmtk/dcmdata/dcdeftag.h>
 
- #include <dcmtk/dcmdata/dcdatset.h>
 
- #include <dcmtk/ofstd/ofcond.h>
 
- #include <dcmtk/ofstd/ofstring.h>
 
- #include <dcmtk/ofstd/ofstd.h>        /* for class OFStandard */
 
- #include <dcmtk/dcmdata/dcddirif.h>   /* for class DicomDirInterface */
 
- #define MITK_ERROR std::cout
 
- #define MITK_INFO std::cout
 
- //------------------------------------------------------------------------------
 
- class qCTKDCMTKIndexerPrivate: public qCTKPrivate<qCTKDCMTKIndexer>
 
- {
 
- public:
 
-   qCTKDCMTKIndexerPrivate();
 
-   ~qCTKDCMTKIndexerPrivate();
 
- };
 
- //------------------------------------------------------------------------------
 
- // qCTKDCMTKIndexerPrivate methods
 
- //------------------------------------------------------------------------------
 
- qCTKDCMTKIndexerPrivate::qCTKDCMTKIndexerPrivate()
 
- {
 
- }
 
- //------------------------------------------------------------------------------
 
- qCTKDCMTKIndexerPrivate::~qCTKDCMTKIndexerPrivate()
 
- {
 
- }
 
- //------------------------------------------------------------------------------
 
- // qCTKDCMTKIndexer methods
 
- //------------------------------------------------------------------------------
 
- qCTKDCMTKIndexer::qCTKDCMTKIndexer()
 
- {
 
- }
 
- //------------------------------------------------------------------------------
 
- qCTKDCMTKIndexer::~qCTKDCMTKIndexer()
 
- {
 
- }
 
- //------------------------------------------------------------------------------
 
- void qCTKDCMTKIndexer::addDirectory(QSqlDatabase database, const QString& directoryName,const QString& destinationDirectoryName)  
 
- {
 
-   QSqlDatabase db = database;
 
-   const std::string src_directory(directoryName.toStdString());
 
-   OFList<OFString> originalDcmtkFileNames;
 
-   OFList<OFString> dcmtkFileNames;
 
-   OFStandard::searchDirectoryRecursively(src_directory.c_str(), originalDcmtkFileNames, NULL, NULL);
 
-   // hack to reverse list of filenames (not neccessary when image loading works correctly)
 
-   for ( OFListIterator(OFString) iter = originalDcmtkFileNames.begin(); iter != originalDcmtkFileNames.end(); ++iter )
 
-   {
 
-     dcmtkFileNames.push_front( *iter );
 
-   }
 
-   DcmFileFormat fileformat;
 
-   OFListIterator(OFString) iter = dcmtkFileNames.begin();
 
-   OFListIterator(OFString) last = dcmtkFileNames.end();
 
-   if(iter == last) return;
 
-   QSqlQuery query(database);
 
-   /// these are for optimizing the import of image sequences
 
-   /// since most information are identical for all slices
 
-   OFString lastPatientID = "";
 
-   OFString lastPatientsName = "";
 
-   OFString lastPatientsBirthDate = "";
 
-   OFString lastStudyInstanceUID = "";
 
-   OFString lastSeriesInstanceUID = "";
 
-   int lastPatientUID = -1;
 
-   /* iterate over all input filenames */
 
-   while (iter != last)
 
-   {
 
-     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);
 
-     fileExists.prepare("SELECT InsertTimestamp FROM Images WHERE Filename == ?"); 
 
-     fileExists.bindValue(0,qfilename);
 
-     fileExists.exec();
 
-     if (
 
-       fileExists.next() && 
 
-       QFileInfo(qfilename).lastModified() < QDateTime::fromString(fileExists.value(0).toString(),Qt::ISODate)      
 
-       )
 
-       {
 
-       MITK_INFO << "File " << filename << " already added.";
 
-       continue;
 
-       }
 
-     MITK_INFO << filename << "\n";
 
-     OFCondition status = fileformat.loadFile(filename.c_str());
 
-     ++iter;
 
-     if (!status.good())
 
-     {
 
-       MITK_ERROR << "Could not load " << filename << "\nDCMTK says: " << status.text();
 
-       continue;
 
-     }
 
-     OFString patientsName, patientID, patientsBirthDate, patientsBirthTime, patientsSex,
 
-       patientComments, patientsAge;
 
-     OFString studyInstanceUID, studyID, studyDate, studyTime,
 
-       accessionNumber, modalitiesInStudy, institutionName, performingPhysiciansName, referringPhysician, studyDescription;
 
-     OFString seriesInstanceUID, seriesDate, seriesTime,
 
-       seriesDescription, bodyPartExamined, frameOfReferenceUID,
 
-       contrastAgent, scanningSequence;
 
-     OFString instanceNumber;
 
-     Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0;
 
-     //The patient UID is a unique number within the database, generated by the sqlite autoincrement
 
-     int patientUID = -1;
 
-     //If the following fields can not be evaluated, cancel evaluation of the DICOM file
 
-     if (!fileformat.getDataset()->findAndGetOFString(DCM_PatientsName, patientsName).good())
 
-     {
 
-       MITK_ERROR << "Could not read DCM_PatientsName from " << filename;
 
-       continue;
 
-     }
 
-     if (!fileformat.getDataset()->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).good())
 
-     {
 
-       MITK_ERROR << "Could not read DCM_StudyInstanceUID from " << filename;
 
-       continue;
 
-     }
 
-     if (!fileformat.getDataset()->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).good())
 
-     {
 
-       MITK_ERROR << "Could not read DCM_SeriesInstanceUID from " << filename;
 
-       continue;
 
-     }
 
-     if (!fileformat.getDataset()->findAndGetOFString(DCM_InstanceNumber, instanceNumber).good())
 
-     {
 
-       MITK_ERROR << "Could not read DCM_InstanceNumber from " << filename;
 
-       continue;
 
-     }
 
-     fileformat.getDataset()->findAndGetOFString(DCM_PatientID, patientID);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_PatientsBirthDate, patientsBirthDate);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_PatientsBirthTime, patientsBirthTime);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_PatientsSex, patientsSex);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_PatientsAge, patientsAge);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_PatientComments, patientComments);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_StudyID, studyID);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_StudyDate, studyDate);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_StudyTime, studyTime);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_AccessionNumber, accessionNumber);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_ModalitiesInStudy, modalitiesInStudy);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_InstitutionName, institutionName);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_PerformingPhysiciansName, performingPhysiciansName);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_ReferringPhysiciansName, referringPhysician);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_StudyDescription, studyDescription);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_SeriesDate, seriesDate);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_SeriesTime, seriesTime);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_SeriesDescription, seriesDescription);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_BodyPartExamined, bodyPartExamined);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_FrameOfReferenceUID, frameOfReferenceUID);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_ContrastBolusAgent, contrastAgent);
 
-     fileformat.getDataset()->findAndGetOFString(DCM_ScanningSequence, scanningSequence);
 
-     fileformat.getDataset()->findAndGetSint32(DCM_SeriesNumber, seriesNumber);
 
-     fileformat.getDataset()->findAndGetSint32(DCM_AcquisitionNumber, acquisitionNumber);
 
-     fileformat.getDataset()->findAndGetSint32(DCM_EchoNumbers, echoNumber);
 
-     fileformat.getDataset()->findAndGetSint32(DCM_TemporalPositionIdentifier, temporalPosition);
 
-     MITK_INFO << "Adding new items to database:";
 
-     MITK_INFO << "studyID: " << studyID;
 
-     MITK_INFO << "seriesInstanceUID: " << seriesInstanceUID;
 
-     MITK_INFO << "Patient's Name: " << patientsName;
 
-     //-----------------------
 
-     //Add Patient to Database
 
-     //-----------------------
 
-     //Speed up: Check if patient is the same as in last file; very probable, as all images belonging to a study have the same patient
 
-     bool patientExists = false;
 
-     if(lastPatientID.compare(patientID) || lastPatientsBirthDate.compare(patientsBirthDate) || lastPatientsName.compare(patientsName))
 
-     {
 
-       //Check if patient is already present in the db
 
-       QSqlQuery check_exists_query(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());
 
-       /// we check only patients with the same PatientID
 
-       /// PatientID is not unique in DICOM, so we also compare Name and BirthDate
 
-       /// and assume this is sufficient
 
-       while (check_exists_query.next())
 
-       {
 
-         if (
 
-             check_exists_query.record().value("PatientsName").toString() == patientsName.c_str() &&
 
-             check_exists_query.record().value("PatientsBirthDate").toString() == patientsBirthDate.c_str()
 
-            )
 
-         {
 
-           /// found it
 
-           patientUID = check_exists_query.value(check_exists_query.record().indexOf("UID")).toInt();
 
-           break;
 
-         }
 
-       }
 
-       if(!patientExists)
 
-       {
 
-         std::stringstream query_string;
 
-         query_string << "INSERT INTO Patients VALUES( NULL,'" 
 
-         << patientsName << "','" 
 
-         << patientID << "','" 
 
-         << patientsBirthDate << "','"
 
-         << patientsBirthTime << "','" 
 
-         << patientsSex << "','" 
 
-         << patientsAge << "','" 
 
-         << patientComments << "')";
 
-         query.exec(query_string.str().c_str());
 
-         patientUID = query.lastInsertId().toInt();
 
-         MITK_INFO << "New patient inserted: " << patientUID << "\n";
 
-       }
 
-     }
 
-     else 
 
-       {
 
-       patientUID = lastPatientUID;
 
-       }     
 
-     
 
-     /// keep this for the next image
 
-     lastPatientUID = patientUID;
 
-     lastPatientID = patientID;
 
-     lastPatientsBirthDate = patientsBirthDate;
 
-     lastPatientsName = patientsName;
 
-     //---------------------
 
-     //Add Study to Database
 
-     //---------------------
 
-     if(lastStudyInstanceUID.compare(studyInstanceUID))
 
-     {
 
-       QSqlQuery check_exists_query(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());
 
-       if(!check_exists_query.next())
 
-       {
 
-         std::stringstream query_string;
 
-         query_string << "INSERT INTO Studies VALUES('"
 
-           << studyInstanceUID << "','" 
 
-           << patientUID << "','" 
 
-           << studyID << "','"
 
-           << QDate::fromString(studyDate.c_str(), "yyyyMMdd").toString("yyyy-MM-dd").toStdString() << "','"
 
-           << studyTime << "','" 
 
-           << accessionNumber << "','" 
 
-           << modalitiesInStudy << "','" 
 
-           << institutionName << "','" 
 
-           << referringPhysician << "','" 
 
-           << performingPhysiciansName << "','" 
 
-           << studyDescription << "')";
 
-         query.exec(query_string.str().c_str());
 
-       }
 
-     }
 
-     lastStudyInstanceUID = studyInstanceUID;
 
-     //----------------------
 
-     //Add Series to Database
 
-     //----------------------
 
-     if(lastSeriesInstanceUID.compare(seriesInstanceUID))
 
-     {
 
-       QSqlQuery check_exists_query(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());
 
-       if(!check_exists_query.next())
 
-       {
 
-         std::stringstream query_string;
 
-         query_string << "INSERT INTO Series VALUES('"
 
-           << seriesInstanceUID << "','" << studyInstanceUID << "','" << (int) seriesNumber << "','"
 
-           << QDate::fromString(seriesDate.c_str(), "yyyyMMdd").toString("yyyy-MM-dd").toStdString() << "','"
 
-           << seriesTime << "','" << seriesDescription << "','" << bodyPartExamined << "','"
 
-           << frameOfReferenceUID << "','" << (int) acquisitionNumber << "','" << contrastAgent << "','"
 
-           << scanningSequence << "','" << (int) echoNumber << "','" << (int) temporalPosition << "')";
 
-         query.exec(query_string.str().c_str());
 
-       }
 
-     }
 
-     lastSeriesInstanceUID = seriesInstanceUID;
 
-     //----------------------------------
 
-     //Move file to destination directory
 
-     //----------------------------------
 
-     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;
 
-       currentFile.copy(destFileName);
 
-       //for testing only: copy file instead of moving
 
-       //currentFile.copyTo(destDirectoryPath.str());
 
-     }
 
-     // */
 
-     //------------------------
 
-     //Add Filename to Database
 
-     //------------------------
 
- //    std::stringstream relativeFilePath;
 
- //    relativeFilePath << seriesInstanceUID.c_str() << "/" << currentFilePath.getFileName();
 
-     QSqlQuery check_exists_query(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 << "'";
 
-     check_exists_query.exec(check_exists_query_string.str().c_str());
 
-     if(!check_exists_query.next())
 
-     {
 
-       std::stringstream query_string;
 
-       //To save absolute path: destDirectoryPath.str()
 
-       query_string << "INSERT INTO Images VALUES('"
 
-         << /*relativeFilePath.str()*/ filename << "','" << seriesInstanceUID << "','" << QDateTime::currentDateTime().toString(Qt::ISODate).toStdString() << "')";
 
-       query.exec(query_string.str().c_str());
 
-     }
 
-   }
 
-   // db.commit();
 
-   // db.close();
 
- }
 
- //------------------------------------------------------------------------------
 
- void qCTKDCMTKIndexer::refreshDatabase(QSqlDatabase database, const QString& directoryName)
 
- {
 
-   /// get all filenames from the database
 
-   QSqlQuery allFilesQuery(database);
 
-   QStringList databaseFileNames;
 
-   QStringList filesToRemove;
 
-   allFilesQuery.exec("SELECT Filename from Images;");
 
-   while (allFilesQuery.next())
 
-     {
 
-     QString fileName = allFilesQuery.value(0).toString();
 
-     databaseFileNames.append(fileName);
 
-     if (! QFile::exists(fileName) ) 
 
-       {
 
-       filesToRemove.append(fileName);
 
-       }
 
-     }
 
-   QSet<QString> filesytemFiles;
 
-   QDirIterator dirIt(directoryName);
 
-   while (dirIt.hasNext()) 
 
-     {
 
-     filesytemFiles.insert(dirIt.next());
 
-     }
 
- }
 
 
  |