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; }
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 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"; }
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; }
/** * 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 */ }
// 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; }