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 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; }
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; }