| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 | #include "qCTKDCMTKIndexer.h"////// DCMTK includes#ifndef WIN32  #define HAVE_CONFIG_H #endif#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 */#include <QSqlQuery>#include <QSqlRecord>#include <QVariant>#include <QDate>#define MITK_ERROR std::cout#define MITK_INFO std::coutclass qCTKDCMTKIndexerPrivate: public qCTKPrivate<qCTKDCMTKIndexer>{public:  qCTKDCMTKIndexerPrivate();  ~qCTKDCMTKIndexerPrivate();};qCTKDCMTKIndexerPrivate::qCTKDCMTKIndexerPrivate(){}qCTKDCMTKIndexerPrivate::~qCTKDCMTKIndexerPrivate(){}qCTKDCMTKIndexer::qCTKDCMTKIndexer(){}qCTKDCMTKIndexer::~qCTKDCMTKIndexer(){}void qCTKDCMTKIndexer::AddDirectory(QSqlDatabase database, const QString& directoryName)  {  QSqlDatabase db = database;  const std::string src_directory(directoryName.toStdString());  // db.transaction();  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);  /* iterate over all input filenames */  OFString lastPatientID = "", lastPatientsName = "", lastPatientsBirthDate = "", lastStudyInstanceUID = "", lastSeriesInstanceUID = "";  int lastPatientUID = -1;  while (iter != last)  {    std::string filename((*iter).c_str());    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 = "", performingPhysiciansName = "", referringPhysician = "", studyDescription = "";    OFString seriesInstanceUID = "", seriesDate = "", seriesTime = "",      seriesDescription = "", bodyPartExamined = "", frameOfReferenceUID = "",      contrastAgent = "", scanningSequence = "";    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;    }    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_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    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());      //check_exists_query_string.flush();      bool patientExists = false;      while (check_exists_query.next())      {        patientExists = true;        QString checkPatientsName = check_exists_query.value(check_exists_query.record().indexOf("PatientsName")).toString();        if(checkPatientsName.toStdString().compare(patientsName.c_str())) patientExists = false;        QString checkPatientsBirthDate = check_exists_query.value(check_exists_query.record().indexOf("PatientsBirthDate")).toString();        if(checkPatientsBirthDate.toStdString().compare(patientsBirthDate.c_str())) patientExists = false;        if(patientExists)        {          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 << "Query result: " << patientUID << "\n";      }    }    else patientUID = lastPatientUID;    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 << "','" << 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    //----------------------------------    /*    // This depends on Poco and should be converted to Qt code    Poco::File currentFile(filename);    Poco::Path currentFilePath(filename);    MITK_INFO << "currentFilePath.getFileName(): " << currentFilePath.getFileName() << "\n";    if(moveFiles)    {      std::stringstream destDirectoryPath;      if((dest_directory[dest_directory.length()-1] != '/') && (dest_directory[dest_directory.length()-1] != '\\'))        destDirectoryPath << dest_directory << Poco::Path::separator() << seriesInstanceUID.c_str();      else        destDirectoryPath << dest_directory << seriesInstanceUID.c_str();      MITK_INFO << "last symbol: " << dest_directory[dest_directory.length()-1]      << "\ndestDirectoryPath: " << destDirectoryPath.str() << "\n";      Poco::File directory(destDirectoryPath.str());      if (!directory.exists()) directory.createDirectory();      destDirectoryPath << Poco::Path::separator() << currentFilePath.getFileName();      currentFile.moveTo(destDirectoryPath.str());      //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 << "')";      query.exec(query_string.str().c_str());    }  }  // db.commit();  // db.close();}
 |