// copy element from dataset to directory record static void copyElement(DcmItem& dataset, const DcmTagKey &key, DcmDirectoryRecord& record, const OFBool optional, const OFBool copyEmpty) { /* check whether tag exists in source dataset (if optional) */ if (!optional || (copyEmpty && dataset.tagExists(key)) || dataset.tagExistsWithValue(key)) { DcmElement *delem = NULL; /* get copy of element from source dataset */ OFCondition status = dataset.findAndGetElement(key, delem, OFFalse /*searchIntoSub*/, OFTrue /*createCopy*/); if (status.good()) { /* ... and insert it into the destination dataset (record) */ status = record.insert(delem, OFTrue /*replaceOld*/); if (status.good()) { DcmTag tag(key); /* check for correct VR in the dataset */ if (delem->getVR() != tag.getEVR()) { /* create warning message */ LOG(WARNING) << "DICOMDIR: possibly wrong VR: " << tag.getTagName() << " " << key << " with " << DcmVR(delem->getVR()).getVRName() << " found, expected " << tag.getVRName() << " instead"; } } else delete delem; } else if (status == EC_TagNotFound) status = record.insertEmptyElement(key); printAttributeErrorMessage(key, status, "insert"); } }
void FillInstance(DcmDirectoryRecord& record, DcmItem& dicom, DcmMetaInfo& metaInfo, const char* path) { // cf. "DicomDirInterface::buildImageRecord()" /* copy attribute values from dataset to image record */ copyElementType1(dicom, DCM_InstanceNumber, record); //copyElementType1C(dicom, DCM_ImageType, record); copyElementType1C(dicom, DCM_ReferencedImageSequence, record); OFString tmp; DcmElement* item = record.remove(DCM_ReferencedImageSequence); if (item != NULL) { delete item; } if (record.putAndInsertString(DCM_ReferencedFileID, path).bad() || dicom.findAndGetOFStringArray(DCM_SOPClassUID, tmp).bad() || record.putAndInsertString(DCM_ReferencedSOPClassUIDInFile, tmp.c_str()).bad() || dicom.findAndGetOFStringArray(DCM_SOPInstanceUID, tmp).bad() || record.putAndInsertString(DCM_ReferencedSOPInstanceUIDInFile, tmp.c_str()).bad() || metaInfo.findAndGetOFStringArray(DCM_TransferSyntaxUID, tmp).bad() || record.putAndInsertString(DCM_ReferencedTransferSyntaxUIDInFile, tmp.c_str()).bad()) { throw OrthancException(ErrorCode_BadFileFormat); } }
// copy optional string value from dataset to directory record static void copyStringWithDefault(DcmItem& dataset, const DcmTagKey &key, DcmDirectoryRecord& record, const char *defaultValue, const OFBool printWarning) { OFCondition status; if (dataset.tagExistsWithValue(key)) { OFString stringValue; /* retrieve string value from source dataset and put it into the destination dataset */ status = dataset.findAndGetOFStringArray(key, stringValue); if (status.good()) status = record.putAndInsertString(key, stringValue.c_str()); } else { if (printWarning && (defaultValue != NULL)) { /* create warning message */ LOG(WARNING) << "DICOMDIR: " << DcmTag(key).getTagName() << " " << key << " missing, using alternative: " << defaultValue; } /* put default value */ status = record.putAndInsertString(key, defaultValue); } }
static HRESULT CreatePatientNode(DcmDirectoryRecord *patientRecord, MSXML2::IXMLDOMDocumentPtr &pXMLDom) { MSXML2::IXMLDOMElementPtr patient, wado; wado = pXMLDom->selectSingleNode("/wado_query"); if(wado == NULL) return CO_E_NOT_SUPPORTED; patient = pXMLDom->createNode(MSXML2::NODE_ELEMENT, "Patient", "http://www.weasis.org/xsd"); if(patient == NULL) return CO_E_NOT_SUPPORTED; const char *patientName = NULL, *patientID = NULL, *patientBirthDate = NULL, *patientBirthTime = NULL, *patientSex = NULL; if(patientRecord->findAndGetString(DCM_PatientsName, patientName).bad()) return CO_E_NOT_SUPPORTED; else patient->setAttribute("PatientName", patientName); if(patientRecord->findAndGetString(DCM_PatientID, patientID).bad()) return CO_E_NOT_SUPPORTED; else patient->setAttribute("PatientID", patientID); if(patientRecord->findAndGetString(DCM_PatientsBirthDate, patientBirthDate).good()) patient->setAttribute("PatientBirthDate", patientBirthDate); if(patientRecord->findAndGetString(DCM_PatientsBirthTime, patientBirthTime).good()) patient->setAttribute("PatientBirthTime", patientBirthTime); if(patientRecord->findAndGetString(DCM_PatientsSex, patientSex).good()) patient->setAttribute("PatientSex", patientSex); wado->appendChild(patient); DcmDirectoryRecord *studyRec = NULL; while(studyRec = patientRecord->nextSub(studyRec)) { if(studyRec->getRecordType() != ERT_Study) continue; CreateStudyNode(studyRec, patient, pXMLDom); } return S_OK; }
static HRESULT CreateStudyNode(DcmDirectoryRecord *studyRec, MSXML2::IXMLDOMElementPtr &patient, MSXML2::IXMLDOMDocumentPtr &pXMLDom) { MSXML2::IXMLDOMElementPtr study = pXMLDom->createNode(MSXML2::NODE_ELEMENT, "Study", "http://www.weasis.org/xsd"); if(study == NULL) return CO_E_NOT_SUPPORTED; const char *buff = NULL, *studyUID = NULL; if(studyRec->findAndGetString(DCM_StudyInstanceUID, studyUID).bad()) return CO_E_NOT_SUPPORTED; else study->setAttribute("StudyInstanceUID", studyUID); if(studyRec->findAndGetString(DCM_StudyDate, buff).bad()) return CO_E_NOT_SUPPORTED; else study->setAttribute("StudyDate", buff); if(studyRec->findAndGetString(DCM_StudyTime, buff).good()) study->setAttribute("StudyTime", buff); if(studyRec->findAndGetString(DCM_StudyID, buff).good()) study->setAttribute("StudyID", buff); if(studyRec->findAndGetString(DCM_AccessionNumber, buff).good()) study->setAttribute("AccessionNumber", buff); if(studyRec->findAndGetString(DCM_StudyDescription, buff).good()) study->setAttribute("StudyDescription", buff); if(studyRec->findAndGetString(DCM_ReferringPhysiciansName, buff).good()) study->setAttribute("ReferringPhysicianName", buff); patient->appendChild(study); DcmDirectoryRecord *seriesRec = NULL; while(seriesRec = studyRec->nextSub(seriesRec)) { if(seriesRec->getRecordType() != ERT_Series) continue; CreateSeriesNode(seriesRec, study, pXMLDom, studyUID); } return S_OK; }
static bool open_dicomdir_study(const Glib::ustring& dicomdir, DcmDirectoryRecord *patRec, DcmDirectoryRecord *studyRec, const sigc::slot< void, const Glib::RefPtr< ImagePool::Study >& >& resultslot) { bool seriesFound(false); DcmDirectoryRecord *subRec; assert(studyRec->getRecordType()==ERT_Study); subRec = studyRec->nextSub(NULL); while ( subRec && !seriesFound ) { switch ( subRec->getRecordType() ) { case ERT_Series: // Check if valid series (contains at least 1 image) seriesFound = true; break; case ERT_Private: break; default: std::cout << "WARNING: Bad DICOMDIR SubRecord type[" << subRec->getRecordType() << "] for Study found\n"; } subRec = studyRec->nextSub(subRec); } if ( seriesFound ) { DcmDataset study; DcmElement *el; if ( studyRec->findAndCopyElement(DCM_SpecificCharacterSet, el) == ECC_Normal ) study.insert(el); if ( studyRec->findAndCopyElement(DCM_StudyInstanceUID, el) == ECC_Normal ) study.insert(el); if ( studyRec->findAndCopyElement(DCM_StudyDate, el) == ECC_Normal ) study.insert(el); if ( studyRec->findAndCopyElement(DCM_StudyTime, el) == ECC_Normal ) study.insert(el); if ( studyRec->findAndCopyElement(DCM_StudyDescription, el) == ECC_Normal ) study.insert(el); if ( patRec->findAndCopyElement(DCM_PatientsName, el) == ECC_Normal ) study.insert(el); if ( patRec->findAndCopyElement(DCM_PatientsBirthDate, el) == ECC_Normal ) study.insert(el); if ( patRec->findAndCopyElement(DCM_PatientsSex, el) == ECC_Normal ) study.insert(el); resultslot(create_query_study(&study, std::string("DICOMDIR:") + dicomdir)); } return seriesFound; }
static bool open_dicomdir_patient(const Glib::ustring& dicomdir, DcmDirectoryRecord *patRec, const sigc::slot< void, const Glib::RefPtr< ImagePool::Study >& >& resultslot) { bool studyFound(false); DcmDirectoryRecord *subRec; assert(patRec->getRecordType()==ERT_Patient); subRec = patRec->nextSub(NULL); while ( subRec ) { switch ( subRec->getRecordType() ) { case ERT_Study: studyFound = open_dicomdir_study(dicomdir, patRec, subRec, resultslot); break; case ERT_Private: break; default: std::cout << "WARNING: Bad DICOMDIR SubRecord type[" << subRec->getRecordType() << "] for Patient found\n"; } subRec = patRec->nextSub(subRec); } return studyFound; }
static HRESULT CreateSeriesNode(DcmDirectoryRecord *seriesRec, MSXML2::IXMLDOMElementPtr &study, MSXML2::IXMLDOMDocumentPtr &pXMLDom, const char *studyUID) { MSXML2::IXMLDOMElementPtr series = pXMLDom->createNode(MSXML2::NODE_ELEMENT, "Series", "http://www.weasis.org/xsd"); if(series == NULL) return CO_E_NOT_SUPPORTED; const char *buff = NULL, *seriesUID = NULL; if(seriesRec->findAndGetString(DCM_SeriesInstanceUID, seriesUID).bad()) return CO_E_NOT_SUPPORTED; else series->setAttribute("SeriesInstanceUID", seriesUID); if(seriesRec->findAndGetString(DCM_Modality, buff).bad()) return CO_E_NOT_SUPPORTED; else series->setAttribute("Modality", buff); if(seriesRec->findAndGetString(DCM_SeriesDescription, buff).good()) series->setAttribute("SeriesDescription", buff); if(seriesRec->findAndGetString(DCM_SeriesNumber, buff).good()) series->setAttribute("SeriesNumber", buff); study->appendChild(series); DcmDirectoryRecord *instanceRec = NULL; while(instanceRec = seriesRec->nextSub(instanceRec)) { if(instanceRec->getRecordType() != ERT_Image) continue; CreateInstanceNode(instanceRec, series, pXMLDom, studyUID, seriesUID); } return S_OK; }
static void open_dicomdir_series_result(const Glib::ustring &dicomdir, DcmDirectoryRecord *patRec, DcmDirectoryRecord *studyRec, const sigc::slot< void, const Glib::RefPtr< ImagePool::Series >& >& resultslot) { DcmDirectoryRecord *seriesRec; DcmDirectoryRecord *sopRec; assert(studyRec->getRecordType()==ERT_Study); seriesRec = studyRec->nextSub(NULL); while ( seriesRec ) { DcmDataset series; DcmElement *el; if ( seriesRec->findAndCopyElement(DCM_SpecificCharacterSet, el) == ECC_Normal ) series.insert(el); if ( seriesRec->findAndCopyElement(DCM_SeriesDescription, el) == ECC_Normal ) series.insert(el); if ( seriesRec->findAndCopyElement(DCM_SeriesInstanceUID, el) == ECC_Normal ) series.insert(el); if ( seriesRec->findAndCopyElement(DCM_Modality, el) == ECC_Normal ) series.insert(el); if ( seriesRec->findAndCopyElement(DCM_SeriesDate, el) == ECC_Normal ) series.insert(el); if ( seriesRec->findAndCopyElement(DCM_SeriesTime, el) == ECC_Normal ) series.insert(el); if ( studyRec->findAndCopyElement(DCM_StudyDescription, el) == ECC_Normal ) series.insert(el); if ( studyRec->findAndCopyElement(DCM_StationName, el) == ECC_Normal ) series.insert(el); // Count Related SOP Instances int nSop=0; sopRec = seriesRec->nextSub(NULL); while (sopRec) { nSop++; sopRec = seriesRec->nextSub(sopRec); } series.putAndInsertUint16(DCM_NumberOfSeriesRelatedInstances, nSop); resultslot(create_query_series(&series)); seriesRec = studyRec->nextSub(seriesRec); } }
DcmDirectoryRecord* DicomdirLoader::find_study(const std::string &studyinstanceuid, class DcmDicomDir &dir) { DcmDirectoryRecord *patRec; DcmDirectoryRecord *studyRec; OFCondition ret; DcmDirectoryRecord &root = dir.getRootRecord(); for ( patRec = root.nextSub(NULL); patRec != NULL; patRec = root.nextSub(patRec) ) { if ( patRec->getRecordType() == ERT_Patient ) { for ( studyRec = patRec->nextSub(NULL); studyRec; studyRec = patRec->nextSub(studyRec) ) { if ( studyRec->getRecordType()==ERT_Study ) { OFString uid; if ( studyRec->findAndGetOFString(DCM_StudyInstanceUID, uid)==EC_Normal ) { if ( studyinstanceuid == uid.c_str() ) return studyRec; } } } } } return NULL; }
void DicomDirWriter::Add(const std::string& directory, const std::string& filename, ParsedDicomFile& dicom) { std::string path; if (directory.empty()) { path = filename; } else { if (directory[directory.length() - 1] == '/' || directory[directory.length() - 1] == '\\') { throw OrthancException(ErrorCode_ParameterOutOfRange); } path = directory + '\\' + filename; } DcmFileFormat& fileFormat = *reinterpret_cast<DcmFileFormat*>(dicom.GetDcmtkObject()); DcmDirectoryRecord* instance; bool isNewInstance = pimpl_->CreateResource(instance, ResourceType_Instance, fileFormat, filename.c_str(), path.c_str()); if (isNewInstance) { DcmDirectoryRecord* series; bool isNewSeries = pimpl_->CreateResource(series, ResourceType_Series, fileFormat, filename.c_str(), NULL); series->insertSub(instance); if (isNewSeries) { DcmDirectoryRecord* study; bool isNewStudy = pimpl_->CreateResource(study, ResourceType_Study, fileFormat, filename.c_str(), NULL); study->insertSub(series); if (isNewStudy) { DcmDirectoryRecord* patient; pimpl_->CreateResource(patient, ResourceType_Patient, fileFormat, filename.c_str(), NULL); patient->insertSub(study); } } } }
void open_dicomdir_series(const std::string& studyinstanceuid, const Glib::ustring& dicomdir, const sigc::slot< void, const Glib::RefPtr< ImagePool::Series >& >& resultslot) { DcmDicomDir dir(dicomdir.c_str()); DcmDirectoryRecord *patRec; DcmDirectoryRecord *studyRec; DcmDirectoryRecord *seriesRec; OFCondition ret; if ( dir.error() != ECC_Normal ) { std::cout << "DICOMDIR Error: " << ret.text() << std::endl; return; } DcmDirectoryRecord &root = dir.getRootRecord(); for ( patRec = root.nextSub(NULL); patRec!=NULL; patRec = root.nextSub(patRec) ) { switch ( patRec->getRecordType() ) { case ERT_Patient: for ( studyRec=patRec->nextSub(NULL); studyRec; studyRec = patRec->nextSub(studyRec) ) { if ( studyRec->getRecordType()==ERT_Study ) { OFString uid; if ( studyRec->findAndGetOFString(DCM_StudyInstanceUID, uid)==ECC_Normal ) { if ( studyinstanceuid == uid.c_str() ) { open_dicomdir_series_result(dicomdir, patRec, studyRec, resultslot); return; } } } } break; case ERT_HangingProtocol: // FALLTHROUGH case ERT_Private: break; default: break; } } std::cout << "WARNING: study[" << studyinstanceuid << "] not found in DICOMDIR\n"; }
//------------------------------------------------------------------------------ void ctkDICOMIndexer::addFromDICOMDIR(ctkDICOMDatabase& ctkDICOMDatabase, const QString& directoryName, const QString& destinationDirectoryName ) { logger.debug( "############## addFromDICOMDIR ####################" ); int fileNumber = 0; std::string dcmFilePath = directoryName.toStdString() + "/DICOMDIR"; const char* dcmDirFilePath = dcmFilePath.c_str(); // currently it is not supported to have multiple // parallel directory imports so the second call blocks // d->DirectoryImportWatcher.waitForFinished(); const std::string src_directory(directoryName.toStdString()); DcmDicomDir* dicomDir = new DcmDicomDir(dcmDirFilePath); DcmDirectoryRecord* rootRecord = &(dicomDir->getRootRecord()); DcmDirectoryRecord* patientRecord = NULL; DcmDirectoryRecord* studyRecord = NULL; DcmDirectoryRecord* seriesRecord = NULL; DcmDirectoryRecord* fileRecord = NULL; QString finalFilePath=destinationDirectoryName + "/dicom"; ////QDir destinationDir; ////QFile currentFile; ////Values to fill database //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, sopInstanceUID, referencedFileName ; //Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0; ////The patient UID is a unique number within the database, generated by the sqlite autoincrement ////Thus, this is _not_ the DICOM Patient ID. ////int patientUID(-1); ////int nrOfFiles(0); if(rootRecord != NULL) { //DcmDataset *patientDataset; while (((patientRecord = rootRecord->nextSub(patientRecord)) != NULL)) { //if (patientRecord->findAndGetOFString(DCM_PatientName, patientsName).good()) { // logger.debug( "Reading new Patients:" ); // logger.debug( "Patient's Name: " + QString(patientsName.c_str()) ); // patientDataset = new DcmDataset(); // patientRecord->findAndGetOFString(DCM_PatientID, patientID); // patientRecord->findAndGetOFString(DCM_PatientBirthDate, patientsBirthDate); // patientRecord->findAndGetOFString(DCM_PatientBirthTime, patientsBirthTime); // patientRecord->findAndGetOFString(DCM_PatientSex, patientsSex); // patientRecord->findAndGetOFString(DCM_PatientAge, patientsAge); // patientRecord->findAndGetOFString(DCM_PatientComments, patientComments); // patientDataset->putAndInsertOFStringArray(DCM_PatientName, patientsName); // patientDataset->putAndInsertOFStringArray(DCM_PatientID, patientID); // patientDataset->putAndInsertOFStringArray(DCM_PatientBirthDate, patientsBirthDate); // patientDataset->putAndInsertOFStringArray(DCM_PatientBirthTime, patientsBirthTime); // patientDataset->putAndInsertOFStringArray(DCM_PatientSex, patientsSex); // patientDataset->putAndInsertOFStringArray(DCM_PatientAge, patientsAge); // patientDataset->putAndInsertOFStringArray(DCM_PatientComments, patientComments); //} while (((studyRecord = patientRecord->nextSub(studyRecord)) != NULL)) { //if (studyRecord->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).good()) { // logger.debug( "Reading new Studys:" ); // logger.debug( "Studies Name: " + QString(studyInstanceUID.c_str()) ); // studyRecord->findAndGetOFString(DCM_StudyID, studyID); // studyRecord->findAndGetOFString(DCM_StudyDate, studyDate); // studyRecord->findAndGetOFString(DCM_StudyTime, studyTime); // studyRecord->findAndGetOFString(DCM_AccessionNumber, accessionNumber); // studyRecord->findAndGetOFString(DCM_ModalitiesInStudy, modalitiesInStudy); // studyRecord->findAndGetOFString(DCM_InstitutionName, institutionName); // studyRecord->findAndGetOFString(DCM_PerformingPhysicianName, performingPhysiciansName); // studyRecord->findAndGetOFString(DCM_ReferringPhysicianName, referringPhysician); // studyRecord->findAndGetOFString(DCM_StudyDescription, studyDescription); // patientDataset->putAndInsertOFStringArray(DCM_StudyInstanceUID, studyInstanceUID); // patientDataset->putAndInsertOFStringArray(DCM_StudyID, studyID); // patientDataset->putAndInsertOFStringArray(DCM_StudyDate, studyDate); // patientDataset->putAndInsertOFStringArray(DCM_StudyTime, studyTime); // patientDataset->putAndInsertOFStringArray(DCM_AccessionNumber, accessionNumber); // patientDataset->putAndInsertOFStringArray(DCM_ModalitiesInStudy, modalitiesInStudy); // patientDataset->putAndInsertOFStringArray(DCM_InstitutionName, institutionName); // patientDataset->putAndInsertOFStringArray(DCM_PerformingPhysicianName, performingPhysiciansName); // patientDataset->putAndInsertOFStringArray(DCM_ReferringPhysicianName, referringPhysician); // patientDataset->putAndInsertOFStringArray(DCM_StudyDescription, studyDescription); while (((seriesRecord = studyRecord->nextSub(seriesRecord)) != NULL)) { //if (seriesRecord->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).good()) { // logger.debug( "Reading new Series:" ); // logger.debug( "Series Instance Name: " + QString(seriesInstanceUID.c_str()) ); // seriesRecord->findAndGetOFString(DCM_SeriesDate, seriesDate); // seriesRecord->findAndGetOFString(DCM_SeriesTime, seriesTime); // seriesRecord->findAndGetOFString(DCM_SeriesDescription, seriesDescription); // seriesRecord->findAndGetOFString(DCM_BodyPartExamined, bodyPartExamined); // seriesRecord->findAndGetOFString(DCM_FrameOfReferenceUID, frameOfReferenceUID); // seriesRecord->findAndGetOFString(DCM_ContrastBolusAgent, contrastAgent); // seriesRecord->findAndGetOFString(DCM_ScanningSequence, scanningSequence); // seriesRecord->findAndGetSint32(DCM_SeriesNumber, seriesNumber); // seriesRecord->findAndGetSint32(DCM_AcquisitionNumber, acquisitionNumber); // seriesRecord->findAndGetSint32(DCM_EchoNumbers, echoNumber); // seriesRecord->findAndGetSint32(DCM_TemporalPositionIdentifier, temporalPosition); // patientDataset->putAndInsertOFStringArray(DCM_SeriesInstanceUID, seriesInstanceUID); // patientDataset->putAndInsertOFStringArray(DCM_SeriesDate, seriesDate); // patientDataset->putAndInsertOFStringArray(DCM_SeriesTime, seriesTime); // patientDataset->putAndInsertOFStringArray(DCM_SeriesDescription, seriesDescription); // patientDataset->putAndInsertOFStringArray(DCM_BodyPartExamined, bodyPartExamined); // patientDataset->putAndInsertOFStringArray(DCM_FrameOfReferenceUID, frameOfReferenceUID); // patientDataset->putAndInsertOFStringArray(DCM_ContrastBolusAgent, contrastAgent); // patientDataset->putAndInsertOFStringArray(DCM_ScanningSequence, scanningSequence); // patientDataset->putAndInsertSint16(DCM_SeriesNumber, seriesNumber); // patientDataset->putAndInsertSint16(DCM_AcquisitionNumber, acquisitionNumber); // patientDataset->putAndInsertSint16(DCM_EchoNumbers, echoNumber); // patientDataset->putAndInsertSint16(DCM_TemporalPositionIdentifier, temporalPosition); //} while (((fileRecord = seriesRecord->nextSub(fileRecord)) != NULL)) { //if (fileRecord->findAndGetOFStringArray(DCM_ReferencedSOPInstanceUIDInFile, sopInstanceUID).good()) { // fileRecord->findAndGetOFString(DCM_ReferencedFileID,referencedFileName); // patientDataset->putAndInsertOFStringArray(DCM_ReferencedSOPInstanceUIDInFile, sopInstanceUID); // patientDataset->putAndInsertOFStringArray(DCM_ReferencedFileID, referencedFileName); // const char* filename = fileRecord->getRecordsOriginFile(); // if(filename) // { // this->addFile(); // } //} emit indexingFileNumber(++fileNumber); //TODO insert Record into Database Info: the database.insert() interface must change. //it must be possible to add records and dataset //suggestion: change the interface to dcmItem } } } } emit foundFilesToIndex(fileNumber); } QString filePath((*iter).c_str()); d->FilesToIndex << filePath; ++iter; }
// Loads all dicom file in m_FileList // Initializes m_Cache // returns true if viewable files found, otherwise false bool DicomdirLoader::scan_study(const std::string &studyinstanceuid, class DcmDirectoryRecord *studyRec, const Glib::ustring &dicomdir) { DcmDirectoryRecord *seriesRec; DcmDirectoryRecord *sopRec; std::string path; std::string file; assert(studyRec->getRecordType()==ERT_Study); path = Glib::path_get_dirname(dicomdir); seriesRec = studyRec->nextSub(NULL); while ( seriesRec ) { OFString modality; if ( seriesRec->findAndGetOFString(DCM_Modality, modality) == EC_Normal ) { OFString seriesinstanceuid; if ( seriesRec->findAndGetOFString(DCM_SeriesInstanceUID, seriesinstanceuid) != EC_Normal ) { seriesRec = studyRec->nextSub(seriesRec); continue; } if ( ImageModalities.find(modality.c_str()) != std::string::npos ) { // Load Series... OFString fileID; int vm; int i; DcmElement *el; for (sopRec = seriesRec->nextSub(NULL); sopRec; sopRec = seriesRec->nextSub(sopRec) ) { switch ( sopRec->getRecordType() ) { case ERT_Image: case ERT_StoredPrint: if ( sopRec->findAndGetElement(DCM_ReferencedFileID, el, true)!=EC_Normal ) { sopRec = seriesRec->nextSub(sopRec); continue; } vm = el->getVM(); file = ""; for ( i=0; i<vm; i++ ) { el->getOFString(fileID, i); file = file + "/" + fileID.c_str(); } if ( file.size() > 0 ) { std::cout << "Loading DICOMDIR file [" << path.c_str() << file.c_str() << "]" << std::endl; m_filelist->push_back(path + file); std::string SeriesUID = seriesinstanceuid.c_str(); m_cache[studyinstanceuid].m_instancecount++; m_cache[studyinstanceuid].m_seriesuid.insert(SeriesUID); m_cache[studyinstanceuid].m_seriescount = m_cache[studyinstanceuid].m_seriesuid.size(); } break; default: break; } } } } seriesRec = studyRec->nextSub(seriesRec); } return true; }
inline DcmDirectoryRecord* GetSeriesRecord(const GNC::GCS::IHistoryController::StudyModel& studyModel, const GNC::GCS::IHistoryController::SeriesModel& seriesModel, std::map<std::string, DcmDirectoryRecord*>& dcmMapOfPatients, std::map<std::string, DcmDirectoryRecord*>& dcmMapOfStudies, std::map<std::string, DcmDirectoryRecord*>& dcmMapOfSeries, DcmDirectoryRecord * root) { DcmDirectoryRecord* PatientRecord; if (dcmMapOfPatients.find(studyModel.pat_id) == dcmMapOfPatients.end()) { PatientRecord = new DcmDirectoryRecord(); dcmMapOfPatients[studyModel.pat_id] = PatientRecord; root->insertSub(PatientRecord); InsertTagRecord(DCM_DirectoryRecordType, "PATIENT", PatientRecord); InsertTagRecord(DCM_SpecificCharacterSet, "ISO_IR 192", PatientRecord); InsertTagRecord(DCM_PatientID, studyModel.pat_id, PatientRecord); InsertTagRecord(DCM_PatientName, studyModel.pat_name, PatientRecord); { std::ostringstream ostr; ostr << studyModel.pat_sex; InsertTagRecord(DCM_PatientSex, ostr.str(), PatientRecord); } InsertTagRecord(DCM_PatientBirthDate, studyModel.pat_bithdate, PatientRecord); } else { PatientRecord = dcmMapOfPatients[studyModel.pat_id]; } DcmDirectoryRecord* StudyRecord; if (dcmMapOfStudies.find(studyModel.study_iuid) == dcmMapOfStudies.end()) { StudyRecord = new DcmDirectoryRecord(); dcmMapOfStudies[studyModel.study_iuid] = StudyRecord; PatientRecord->insertSub(StudyRecord); InsertTagRecord(DCM_DirectoryRecordType, "STUDY", StudyRecord); InsertTagRecord(DCM_SpecificCharacterSet, "ISO_IR 192", StudyRecord); InsertTagRecord(DCM_StudyInstanceUID, studyModel.study_iuid, StudyRecord); InsertTagRecord(DCM_StudyDescription, studyModel.study_desc, StudyRecord); wxDateTime date; date.ParseFormat(wxString::FromUTF8(studyModel.study_datetime.c_str()), wxT("%Y-%m-%dT%H:%M:%S")); if (date.IsValid()) { std::string tmp(date.Format(wxT("%Y%m%d")).ToUTF8()); InsertTagRecord(DCM_StudyDate, tmp, StudyRecord); tmp = date.Format(wxT("%H%M%S.%l")).ToUTF8(); InsertTagRecord(DCM_StudyTime, tmp, StudyRecord); } InsertTagRecord(DCM_AccessionNumber, studyModel.study_acc_no, StudyRecord); InsertTagRecord(DCM_StudyID, studyModel.study_id, StudyRecord); } else { StudyRecord = dcmMapOfStudies[studyModel.study_iuid]; } DcmDirectoryRecord* SeriesRecord; if (dcmMapOfSeries.find(studyModel.study_iuid) == dcmMapOfSeries.end()) { SeriesRecord = new DcmDirectoryRecord(); dcmMapOfSeries[seriesModel.series_iuid] = SeriesRecord; StudyRecord->insertSub(SeriesRecord); InsertTagRecord(DCM_DirectoryRecordType, "SERIES", SeriesRecord); InsertTagRecord(DCM_SpecificCharacterSet, "ISO_IR 192", SeriesRecord); InsertTagRecord(DCM_SeriesInstanceUID, seriesModel.series_iuid, SeriesRecord); InsertTagRecord(DCM_SeriesDescription, seriesModel.series_desc, SeriesRecord); wxDateTime date; date.ParseFormat(wxString::FromUTF8(seriesModel.series_datetime.c_str()), wxT("%Y-%m-%dT%H:%M:%S")); if (date.IsValid()) { std::string tmp(date.Format(wxT("%Y%m%d")).ToUTF8()); InsertTagRecord(DCM_SeriesDate, tmp, SeriesRecord); tmp = date.Format(wxT("%H%M%S.%l")).ToUTF8(); InsertTagRecord(DCM_SeriesTime, tmp, SeriesRecord); } InsertTagRecord(DCM_Modality, seriesModel.series_modality, SeriesRecord); InsertTagRecord(DCM_SeriesNumber, seriesModel.series_no, SeriesRecord); } else { SeriesRecord = dcmMapOfSeries[seriesModel.series_iuid]; } return SeriesRecord; }
void GADAPI::ExportToDicomDirCommand::Execute() { if (!NotificarProgreso(0.0, _Std("Exporting files...")) ) return; std::string pathOfDicomDir; { std::ostringstream ostr; ostr << m_pExportacionParams->m_destinationPath; ostr << (char)wxFileName::GetPathSeparator(); ostr << "DICOMDIR"; pathOfDicomDir = ostr.str(); } //clean dicomdir file and dicomdir directory if present... { std::ostringstream ostr; ostr << m_pExportacionParams->m_destinationPath; ostr << (char) wxFileName::GetPathSeparator(); ostr << "DICOM"; GNC::Entorno::Instance()->RemoveDirRecursive(ostr.str()); wxRemoveFile(FROMPATH(pathOfDicomDir)); } // std::map<std::string, int> mapOfPathPatients; std::map<std::string, int> mapOfPathStudies; std::map<std::string, int> mapOfPathSeries; std::map<std::string, int> mapOfPathImages; std::map<std::string, DcmDirectoryRecord*> dcmMapOfPatients; std::map<std::string, DcmDirectoryRecord*> dcmMapOfStudies; std::map<std::string, DcmDirectoryRecord*> dcmMapOfSeries; std::string pathOfPatient, pathOfStudy, pathOfSeries; int patientIndex=0, studyIndex=0, seriesIndex=0; int numberOfSeries = m_pExportacionParams->m_seriesList.size(); int actualSerie = 1; DcmDicomDir dicomDir(pathOfDicomDir.c_str(), "GINKGOCADXCD"); DcmDirectoryRecord * root = &(dicomDir.getRootRecord()); //FIRST OF ALL EXPORT WITHOUT ANONYMIZE if (m_pExportacionParams->m_seriesList.size() > 0 && m_pExportacionParams->m_anonymized.tags.empty() && m_pExportacionParams->m_includeGinkgoTags) { for (ExportToDicomDirCommandParams::TListOfPks::const_iterator itUids = m_pExportacionParams->m_seriesList.begin(); itUids != m_pExportacionParams->m_seriesList.end(); ++itUids) { wxString cadena = wxString::Format(_("Exporting series %d of %d"), (int)(actualSerie++), (int)(numberOfSeries)); if (!NotificarProgreso((float)actualSerie/numberOfSeries, std::string(cadena.ToUTF8()))) return; //find source paths and series model GNC::GCS::IHistoryController::SeriesModel seriesModel = GNC::GCS::HistoryController::Instance()->GetSeriesModel((*itUids)); GNC::GCS::IHistoryController::StudyModel studyModel = GNC::GCS::HistoryController::Instance()->GetStudyModel(seriesModel.study_fk); GNC::GCS::IHistoryController::FileModelList fileModels; GNC::GCS::HistoryController::Instance()->GetSeriesSortedFileModels((*itUids), fileModels); if (fileModels.empty()) { m_pExportacionParams->m_Error = _Std("Some of selected series has been deleted"); m_pExportacionParams->m_hasError = true; return; } //get path of series wxString fullPathWx; if (!CreatePathOfSeries(studyModel, seriesModel, mapOfPathPatients, mapOfPathStudies, mapOfPathSeries, patientIndex, studyIndex, seriesIndex, m_pExportacionParams->m_destinationPath, pathOfPatient, pathOfStudy, pathOfSeries, fullPathWx) ) { m_pExportacionParams->m_Error = _Std("There was an error creating directory"); m_pExportacionParams->m_hasError = true; return; } //dicomdir structure DcmDirectoryRecord* SeriesRecord = GetSeriesRecord(studyModel, seriesModel, dcmMapOfPatients, dcmMapOfStudies, dcmMapOfSeries, root); //path is created, now we are going to copy images... mapOfPathImages[seriesModel.series_iuid] = 0; for (GNC::GCS::IHistoryController::FileModelList::const_iterator itDCMModels = fileModels.begin(); itDCMModels != fileModels.end(); ++itDCMModels) { std::string pathOfImage; { std::ostringstream ostr; ostr << "IM"; ostr << mapOfPathImages[seriesModel.series_iuid]++; pathOfImage = ostr.str(); } wxString pathOfImageWx = fullPathWx + wxFileName::GetPathSeparator() + wxString::FromUTF8(pathOfImage.c_str()); std::string absolutepathFile = (*itDCMModels).real_path; if (!wxCopyFile(FROMPATH(absolutepathFile), pathOfImageWx)) { LOG_ERROR("ExportToDicomDirCommand", "Error copying file " << absolutepathFile << " TO " << pathOfImageWx.ToUTF8()); m_pExportacionParams->m_Error = _Std("There was an error writing file"); m_pExportacionParams->m_hasError = true; return; } DcmDirectoryRecord* ImageRecord = new DcmDirectoryRecord(); SeriesRecord->insertSub(ImageRecord); std::string fileId; { std::ostringstream ostr; ostr << "DICOM" << "\\" << pathOfPatient << "\\" << pathOfStudy << "\\" << pathOfSeries << "\\" << pathOfImage; fileId = ostr.str(); } InsertTagRecord(DCM_DirectoryRecordType, "IMAGE", ImageRecord); InsertTagRecord(DCM_ReferencedSOPInstanceUIDInFile, (*itDCMModels).sopiuid, ImageRecord); InsertTagRecord(DCM_ReferencedTransferSyntaxUIDInFile, (*itDCMModels).tsuid, ImageRecord); InsertTagRecord(DCM_ReferencedSOPClassUIDInFile, (*itDCMModels).sopcuid, ImageRecord); InsertTagRecord(DCM_SpecificCharacterSet, "ISO_IR 192", ImageRecord); InsertTagRecord(DCM_ImageComments, (*itDCMModels).file_desc, ImageRecord); std::string instanceNumber; { std::ostringstream ostr; ostr << (*itDCMModels).instance_number; instanceNumber = ostr.str(); } InsertTagRecord(DCM_InstanceNumber, instanceNumber, ImageRecord); InsertTagRecord(DCM_ReferencedFileID, fileId, ImageRecord); } } }///END EXPORT WITHOUT ANONYMIZE std::string m_TmpDir = GNC::Entorno::Instance()->CrearDirectorioTemporal(); //export series anonymizing... if (m_pExportacionParams->m_seriesList.size() > 0 && (!m_pExportacionParams->m_anonymized.tags.empty() || !m_pExportacionParams->m_includeGinkgoTags)) { for (ExportToDicomDirCommandParams::TListOfPks::const_iterator itUids = m_pExportacionParams->m_seriesList.begin(); itUids != m_pExportacionParams->m_seriesList.end(); ++itUids) { wxString cadena = wxString::Format(_("Exporting series %d of %d"), (int)(actualSerie++), (int)(numberOfSeries)); if (!NotificarProgreso((float)actualSerie/numberOfSeries, std::string(cadena.ToUTF8()))) return; //find source paths and series model GNC::GCS::IHistoryController::FileModelList fileModels; GNC::GCS::HistoryController::Instance()->GetSeriesSortedFileModels((*itUids), fileModels); for (GNC::GCS::IHistoryController::FileModelList::const_iterator itFileModel = fileModels.begin(); itFileModel != fileModels.end(); ++itFileModel) { GIL::DICOM::DICOMManager manager; manager.CargarFichero((*itFileModel).real_path); manager.ActualizarJerarquia(m_pExportacionParams->m_anonymized); if (!m_pExportacionParams->m_includeGinkgoTags) { manager.AnonimizarTagsPrivados(); } wxString targetFile = FROMPATH(m_TmpDir) + wxFileName::GetPathSeparator() + wxString::Format(wxT("%d"), (int)(rand())); while (wxFileExists(targetFile)) { targetFile = FROMPATH(m_TmpDir) + wxFileName::GetPathSeparator() + wxString::Format(wxT("%d"), (int)(rand())); } std::string targetFileStd(TOPATH(targetFile)); if (!manager.AlmacenarFichero(targetFileStd)) { m_pExportacionParams->m_Error = _Std("There was an error anonymizing files"); m_pExportacionParams->m_hasError = true; return; } } } } //read tmp directory and insert into dcmdir... { wxString tmpDirWx = FROMPATH(m_TmpDir); wxDir dir; if (dir.Open(tmpDirWx)) { wxString fileName; bool cont = dir.GetFirst(&fileName); while (cont) { fileName=dir.GetName()+ wxFileName::GetPathSeparator(wxPATH_NATIVE) +fileName; const std::string fileNameStd(TOPATH(fileName)); GNC::GCS::IHistoryController::DICOMFileModel dicomFile; GNC::GCS::IHistoryController::TAddErrorList foo; if (!GNC::GCS::HistoryController::Instance()->ReadFile(dicomFile, fileNameStd, foo)) { LOG_ERROR("ExportDICOMDir", "error reading " << fileNameStd); continue; } //create path wxString fullPathWx; if (!CreatePathOfSeries(dicomFile.study, dicomFile.series, mapOfPathPatients, mapOfPathStudies, mapOfPathSeries, patientIndex, studyIndex, seriesIndex, m_pExportacionParams->m_destinationPath, pathOfPatient, pathOfStudy, pathOfSeries, fullPathWx) ) { m_pExportacionParams->m_Error = _Std("There was an error creating directory"); m_pExportacionParams->m_hasError = true; return; } //dicomdir structure DcmDirectoryRecord* SeriesRecord = GetSeriesRecord(dicomFile.study, dicomFile.series, dcmMapOfPatients, dcmMapOfStudies, dcmMapOfSeries, root); //path is created, now we are going to copy images... if (mapOfPathImages.find(dicomFile.series.series_iuid) == mapOfPathImages.end()) { mapOfPathImages[dicomFile.series.series_iuid] = 0; } std::string pathOfImage; { std::ostringstream ostr; ostr << "IM"; ostr << mapOfPathImages[dicomFile.series.series_iuid]++; pathOfImage = ostr.str(); } wxString pathOfImageWx = fullPathWx + wxFileName::GetPathSeparator() + wxString::FromUTF8(pathOfImage.c_str()); //moving tmp files... if (!wxRenameFile(fileName, pathOfImageWx)) { m_pExportacionParams->m_Error = _Std("There was an error writing file"); m_pExportacionParams->m_hasError = true; return; } DcmDirectoryRecord* ImageRecord = new DcmDirectoryRecord(); SeriesRecord->insertSub(ImageRecord); std::string fileId; { std::ostringstream ostr; ostr << "DICOM" << "\\" << pathOfPatient << "\\" << pathOfStudy << "\\" << pathOfSeries << "\\" << pathOfImage; fileId = ostr.str(); } InsertTagRecord(DCM_ReferencedFileID, fileId, ImageRecord); InsertTagRecord(DCM_DirectoryRecordType, "IMAGE", ImageRecord); InsertTagRecord(DCM_ReferencedSOPInstanceUIDInFile, dicomFile.file.sopiuid, ImageRecord); InsertTagRecord(DCM_ReferencedTransferSyntaxUIDInFile, dicomFile.file.tsuid, ImageRecord); InsertTagRecord(DCM_ReferencedSOPClassUIDInFile, dicomFile.file.sopcuid, ImageRecord); { std::ostringstream ostr; ostr << dicomFile.file.instance_number; InsertTagRecord(DCM_InstanceNumber, ostr.str(), ImageRecord); } InsertTagRecord(DCM_ImageComments, dicomFile.file.file_desc, ImageRecord); InsertTagRecord(DCM_SpecificCharacterSet, "ISO_IR 192", ImageRecord); cont = dir.GetNext(&fileName); } } } OFCondition cond = dicomDir.write(); std::cout << cond.text() << std::endl; }
/** * Reads a dicomdir and signals every found study */ void open_dicomdir( const Glib::ustring &dicomdir, const sigc::slot< void, const Glib::RefPtr< ImagePool::Study >& >& resultslot) { DcmDicomDir dir(dicomdir.c_str()); OFCondition ret; if ( (ret=dir.error()) != ECC_Normal ) { std::cout << "DICOMDIR Error: " << ret.text() << std::endl; return; } DcmDirectoryRecord root = dir.getRootRecord(); DcmDirectoryRecord *rec = root.nextSub(NULL); std::cout << "Reading DICOMDIR from [" << dicomdir << "]\n"; while ( rec != NULL ) { switch ( rec->getRecordType() ) { case ERT_Patient: open_dicomdir_patient(dicomdir, rec, resultslot); break; case ERT_HangingProtocol: // FALLTHROUGH case ERT_Private: break; default: std::cout << "WARNING: Bad DICOMDIR Record type[" << rec->getRecordType() << "] found\n"; } rec = root.nextSub(rec); } /* // Leggo il root record, � un paziente ? { case ERT_root = 0, case ERT_Curve = 1, case ERT_FilmBox = 2, case ERT_FilmSession = 3, case ERT_Image = 4, case ERT_ImageBox = 5, case ERT_Interpretation = 6, ERT_ModalityLut = 7, ERT_Mrdr = 8, ERT_Overlay = 9, ERT_Patient = 10, ERT_PrintQueue = 11, ERT_Private = 12, ERT_Results = 13, ERT_Series = 14, ERT_Study = 15, ERT_StudyComponent = 16, ERT_Topic = 17, ERT_Visit = 18, ERT_VoiLut = 19, ERT_StructReport = 20, ERT_Presentation = 21, ERT_Waveform = 22, ERT_RTDose = 23, ERT_RTStructureSet = 24, ERT_RTPlan = 25, ERT_RTTreatRecord = 26, ERT_StoredPrint = 27, ERT_KeyObjectDoc = 28, ERT_Registration = 29, ERT_Fiducial = 30, ERT_RawData = 31, ERT_Spectroscopy = 32, ERT_EncapDoc = 33, ERT_ValueMap = 34, ERT_HangingProtocol = 35 */ }