Example #1
0
 // 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");
   }
 }
Example #2
0
    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);
      }
    }
Example #3
0
 // 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);
     }
 }
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
    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;
    }
Example #7
0
    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;
    }
Example #8
0
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;
}
Example #9
0
    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);
        }
    }
Example #10
0
    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;
    }
Example #11
0
  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);
        }
      }
    }
  }
Example #12
0
    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";
    }
Example #13
0
//------------------------------------------------------------------------------
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;
  }
Example #14
0
    // 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;
}
Example #17
0
    /**
     * 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
        */
    }