Beispiel #1
0
    def copy_contours(self):
        '''
        copy contours to rs
        :param self:
        :return:
        '''
        ROIContourSequence  = Sequence()
        #ContourSequence     = Sequence()

        StructureSetROISequence = Sequence()
        for i in range( len( self.contours)):
            StructureSetROI = Dataset()
            StructureSetROI.ROINumber    = self.contours[i]['number']
            StructureSetROI.ROIName      = self.contours[i]['name']
            StructureSetROI.ROIGenerationAlgorithm = 'MANUAL'
            StructureSetROI.ReferencedFrameOfReferenceUID = ''
            StructureSetROISequence.append(StructureSetROI)

            ContourSequence = Sequence()
            for k in range( len( self.contours[i]['contour'])):
                contour_slice = Dataset()
                contour_slice.ContourData = MultiValue( dicom.valuerep.DSfloat, self.contours[i]['contour'][k])
                contour_slice.ContourGeometricType = 'CLOSED_PLANAR'
                contour_slice.NumberOfContourPoints = len( contour_slice.ContourData) /3 ########wrong

                contour_slice.ContourImageSequence = Sequence()

                ContourSequence.append( contour_slice)

            ROIContour = Dataset()
            ROIContour.ContourSequence = ContourSequence
            ROIContour.ROIDisplayColor = self.rs_generic.structure.ROIContourSequence[i].ROIDisplayColor
            ROIContour.ReferencedROINumber = self.rs_generic.structure.ROIContourSequence[i].ReferencedROINumber
            ROIContourSequence.append( ROIContour)


        self.rs.structure.ROIContourSequence = ROIContourSequence
        self.rs.structure.StructureSetROISequence = StructureSetROISequence

        return 0
def build_functional_groups(dcm, cfg):
    """ all values are hard coded to ensure they are present in the final file """
    ds1 = Dataset()
    ds2 = Dataset()

    pv = cfg.get('OnTheFly').get('PixelSpacing')
    ds1.PixelSpacing = [float(x) for x in pv]
    ds1.SliceThickness = 1
    ds2.PixelMeasuresSequence = Sequence([ds1])

    ds3 = Dataset()
    ds3.OpticalPathIdentifier = '1'
    ds2.OpticalPathIdentificationSequence = Sequence([ds3])

    ds4 = Dataset()
    ds4.FrameType = cfg['BaseAttributes']['ImageType']
    ds2.WholeSlideMicroscopyImageFrameTypeSequence = Sequence([ds4])

    dcm.SharedFunctionalGroupsSequence = Sequence([ds2])

    del ds1, ds2, ds3
    return dcm
Beispiel #3
0
    def setUp(self):
        # Create simple dataset for all tests
        ds = Dataset()
        ds.PatientName = "Name^Patient"

        # Set up a simple nested sequence
        # first, the innermost sequence
        subitem1 = Dataset()
        subitem1.ContourNumber = 1
        subitem1.ContourData = ['2', '4', '8', '16']
        subitem2 = Dataset()
        subitem2.ContourNumber = 2
        subitem2.ContourData = ['32', '64', '128', '196']

        sub_ds = Dataset()
        sub_ds.ContourSequence = Sequence((subitem1, subitem2))

        # Now the top-level sequence
        ds.ROIContourSequence = Sequence((sub_ds, ))  # Comma to make one-tuple

        # Store so each test can use it
        self.ds = ds
def generate_reference_segmentation_tags(dataset_segm,
                                         ReferencedSeriesInstanceUID_segm,
                                         ReferencedSOPInstanceUID_src,
                                         StudyInstanceUID_src, segment_label,
                                         lesion_number):
    """
    Add Reference to the tumour/ablation and source img in the DICOM segmentation metatags.
    :param dataset_segm: dcm file read with pydicom library
    :param ReferencedSOPInstanceUID_segm: SeriesInstanceUID of the related segmentation file (tumour or ablation)
    :param ReferencedSOPInstanceUID_src: SeriesInstanceUID of the source image
    :param StudyInstanceUID_src: StudyInstanceUID of the source image
    :param segment_label: text describing whether is tumor or ablation
    :param: lesion_number: a int identifying which lesion was this
    :return: dicom single file/slice with new General Reference Sequence Tags
    """

    if segment_label == "Lession":
        dataset_segm.SegmentLabel = "Tumor"
    elif segment_label == "AblationZone":
        dataset_segm.SegmentLabel = "Ablation"

    dataset_segm.StudyInstanceUID = StudyInstanceUID_src
    dataset_segm.SegmentationType = "BINARY"
    dataset_segm.SegmentAlgorithmType = "SEMIAUTOMATIC"
    dataset_segm.DerivationDescription = "CasOneIR"
    dataset_segm.ImageType = "DERIVED\PRIMARY"

    Segm_ds = Dataset()
    Segm_ds.ReferencedSOPInstanceUID = ReferencedSeriesInstanceUID_segm
    Segm_ds.ReferencedSOPClassUID = dataset_segm.SOPClassUID
    Segm_ds.ReferencedSegmentNumber = lesion_number

    Source_ds = Dataset()
    Source_ds.ReferencedSOPInstanceUID = ReferencedSOPInstanceUID_src

    dataset_segm.ReferencedImageSequence = Sequence([Segm_ds])
    dataset_segm.SourceImageSequence = Sequence([Source_ds])

    return dataset_segm
Beispiel #5
0
    def testValidInitialization(self):
        """Sequence: Ensure valid creation of Sequences using Dataset inputs"""
        inputs = {
            'PatientPosition': 'HFS',
            'PatientSetupNumber': '1',
            'SetupTechniqueDescription': ''
        }
        patientSetups = Dataset()
        patientSetups.update(inputs)

        # Construct the sequence
        seq = Sequence((patientSetups, ))
        assert isinstance(seq[0], Dataset)
Beispiel #6
0
def __write_roi_contour_sequence(ds, roi_list):
    ds.ROIContourSequence = Sequence()
    roi_nums = len(roi_list)
    for i in range(roi_nums):
        ROIContourSequenceItem = Dataset()
        ds.ROIContourSequence.append(ROIContourSequenceItem)
        ROIContourSequenceItem.ROIDisplayColor = roi_list[i][
            3]  # roi_display_color
        ROIContourSequenceItem.ContourSequence = Sequence()
        contour_list = roi_list[i][5]
        contour_nums = len(contour_list)
        for j in range(contour_nums):
            contour = contour_list[j]
            ContourSequenceItem = Dataset()
            ROIContourSequenceItem.ContourSequence.append(ContourSequenceItem)
            ContourSequenceItem.ContourImageSequence = Sequence()
            ContourImageSequenceItem = Dataset()
            ContourSequenceItem.ContourImageSequence.append(
                ContourImageSequenceItem)
            ContourImageSequenceItem.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
            ContourImageSequenceItem.ReferencedSOPInstanceUID = contour[0]
            ContourSequenceItem.ContourGeometricType = 'CLOSED_PLANAR'
            #point_nums = len(contour_item[2][0])
            point_nums = len(contour[1])
            ContourSequenceItem.NumberOfContourPoints = point_nums
            ContourSequenceItem.ContourNumber = j + 1
            result_point_list = contour[1]
            point_list_string = ''
            for k in range(point_nums):
                point_list_string += '%f\\%f\\%f' % (
                    result_point_list[k][0, 0], result_point_list[k][0, 1],
                    result_point_list[k][0, 2])
                if k != point_nums - 1:
                    point_list_string += '\\'
            #ContourSequenceItem.ContourData = '29.420486\\13.750359\\-265.5\\29.271103\\15.171627\\-265.5\\29.085907\\15.862774\\-265.5\\28.114929\\17.768417\\-265.5\\27.664627\\18.324493\\-265.5\\26.602615\\19.280743\\-265.5\\26.002518\\19.670452\\-265.5\\24.005814\\20.436909\\-265.5\\23.299103\\20.548843\\-265.5\\21.86998\\20.548843\\-265.5\\21.163269\\20.436909\\-265.5\\19.16658\\19.670452\\-265.5\\18.566467\\19.280746\\-265.5\\17.054153\\17.768417\\-265.5\\16.664444\\17.168327\\-265.5\\15.897995\\15.171627\\-265.5\\15.786057\\14.464905\\-265.5\\15.786057\\13.035805\\-265.5\\15.897995\\12.329084\\-265.5\\16.664444\\10.332386\\-265.5\\17.054153\\9.7322922\\-265.5\\18.010406\\8.6702652\\-265.5\\18.566467\\8.219965\\-265.5\\19.16658\\7.8302593\\-265.5\\19.804123\\7.5054169\\-265.5\\21.163269\\7.0638008\\-265.5\\21.86998\\6.9518661\\-265.5\\23.299103\\6.9518661\\-265.5\\24.005814\\7.0638008\\-265.5\\26.002518\\7.8302593\\-265.5\\26.602615\\8.2199688\\-265.5\\28.114929\\9.7322941\\-265.5\\28.504639\\10.332388\\-265.5\\28.829483\\10.969931\\-265.5\\29.085907\\11.637936\\-265.5\\29.383026\\13.035809\\-265.5'
            ContourSequenceItem.ContourData = point_list_string
        ROIContourSequenceItem.ReferencedROINumber = roi_list[i][
            1]  # roi_number
Beispiel #7
0
def add_rt_roi_observations_sequence(ds):
    # RT ROI Observations Sequence
    rtroi_observations_sequence = Sequence()
    ds.RTROIObservationsSequence = rtroi_observations_sequence

    # RT ROI Observations Sequence: RT ROI Observations 1
    rtroi_observations1 = Dataset()
    rtroi_observations1.ObservationNumber = "27"
    rtroi_observations1.ReferencedROINumber = "27"
    rtroi_observations1.RTROIInterpretedType = "ORGAN"
    rtroi_observations1.ROIInterpreter = ""
    rtroi_observations_sequence.append(rtroi_observations1)

    return ds
def derive_image_sequence(sop_class_uid, sop_instance_uid):
    source_image = Dataset()
    source_image.ReferencedSOPClassUID = sop_class_uid
    source_image.ReferencedSOPInstanceUID = sop_instance_uid

    purpose_of_reference = Dataset()
    purpose_of_reference.CodeValue = '113130'
    purpose_of_reference.CodingSchemeDesignator = 'DCM'
    purpose_of_reference.CodeMeaning = \
            'Predecessor containing group of imaging subjects'
    source_image.PurposeOfReferenceCodeSequence = \
            Sequence([purpose_of_reference])
    derivation_image = Dataset()
    derivation_image.SourceImageSequence = Sequence([source_image])
    derivation_code = Dataset()
    derivation_code.CodeValue = '113131'
    derivation_code.CodingSchemeDesignator = 'DCM'
    derivation_code.CodeMeaning = \
            'Extraction of individual subject from group'
    derivation_image.DerivationCodeSequence = Sequence([derivation_code])
    derivation_image_sequence = Sequence([derivation_image])

    return derivation_image_sequence
Beispiel #9
0
def build_seq(df, index, parent_path, seq_attr):
    """
  Builds and returns a pydicom sequence and : 0 for a basic sequence | 1 for an
  empty sequence that needs to be represented even if it is empty.
  """
    seq = Sequence()

    for ds_attr in get_ds_attr(df, parent_path, seq_attr):
        ds = build_dicom(df, index, parent_path + seq_attr + ds_attr)
        if ds != None:
            seq.append(ds)
        else:
            return [], 1
    return seq, 0
Beispiel #10
0
def add_structure_set_roi_sequence(ds):
    # Structure Set ROI Sequence
    structure_set_roi_sequence = Sequence()
    ds.StructureSetROISequence = structure_set_roi_sequence

    # Structure Set ROI Sequence: Structure Set ROI 1
    structure_set_roi1 = Dataset()
    structure_set_roi1.ROINumber = "27"
    structure_set_roi1.ReferencedFrameOfReferenceUID = dcm.FrameOfReferenceUID
    structure_set_roi1.ROIName = "Vacbag"
    structure_set_roi1.ROIGenerationAlgorithm = "AUTOMATIC"
    structure_set_roi_sequence.append(structure_set_roi1)

    return ds
Beispiel #11
0
def get_idis_code_sequence(ruleset_names: List[str]) -> DataElement:
    """Create the element (0012,0064) - DeIdentificationMethodCodeSequence

    This sequence specifies what kind of anonymization has been performed. It is
    quite free form. This implementation uses the following format:

    DeIdentificationMethodCodeSequence will contain the code of each official
    DICOM deidentification profile that was used. Codes are taken from
    Table CID 7050

    Parameters
    ----------
    ruleset_names: List[str]
        list of names as defined in nema.E1_1_METHOD_INFO

    Returns
    -------
    DataElement
        Sequence element (0012,0064) - DeIdentificationMethodCodeSequence. Will
         contain the code of each official DICOM deidentification profile passed

    Raises
    ------
    ValueError
        When any name in ruleset_names is not recognized as a standard DICOM
        rule set
    """
    code_per_name = {x.full_name: x for x in E1_1_METHOD_INFO}
    codes = []
    for name in ruleset_names:
        try:  # check whether we know this ruleset as a standard DICOM one
            ruleset_info = code_per_name[name]
        except KeyError:
            raise ValueError(
                f'Could not find the code for rule set "{name}". I do'
                f" not know this ruleset")
        # Create the required designation for this dataset
        code_dataset = Dataset()
        code_dataset.CodeValue = ruleset_info.code
        code_dataset.CodingSchemeDesignator = "DCM"
        code_dataset.CodeMeaning = ruleset_info.full_name
        codes.append(code_dataset)

    element = DataElement(
        tag=Tag("DeidentificationMethodCodeSequence"),
        VR=VRs.Sequence.short_name,
        value=Sequence(codes),
    )
    return element
Beispiel #12
0
def create_contour_sequence(roi_data: ROIData, series_data):
    contour_sequence = Sequence()
    for i, series_slice in enumerate(series_data):
        mask_slice = roi_data.mask[:, :, i]
        # Do not add ROI's for blank slices
        if np.sum(mask_slice) == 0:
            print("Skipping empty mask layer")
            continue

        contour_coords = get_contours_coords(mask_slice, series_slice,
                                             roi_data.use_pin_hole)
        for contour_data in contour_coords:
            contour = create_contour(series_slice, contour_data)
            contour_sequence.append(contour)
    return contour_sequence
Beispiel #13
0
def generate_rtplan(field_list, save_path):

    # Generate new pydicom Dataset containing main DICOM RT PLan file info
    ds = generate_rtplan_skeleton()

    # Fraction Group Sequence & Fraction Group
    frxn_gp_sequence = Sequence()

    frxn_gp = Dataset()
    frxn_gp.FractionGroupNumber = "1"
    frxn_gp.NumberOfFractionsPlanned = "1"
    frxn_gp.NumberOfBeams = len(field_list)
    frxn_gp.NumberOfBrachyApplicationSetups = "0"

    # Beam Sequence & Referenced Beam Sequence
    beam_sequence = Sequence()
    refd_beam_sequence = Sequence()

    # Generate beams to add to Beam & Refd Beam Sequences
    for field in field_list:

        beam_data, refd_beam_data = generate_rtplan_beam(field)

        beam_sequence.append(beam_data)
        refd_beam_sequence.append(refd_beam_data)

    # Assign Sequences to Dataset
    frxn_gp.ReferencedBeamSequence = refd_beam_sequence
    frxn_gp_sequence.append(frxn_gp)
    ds.FractionGroupSequence = frxn_gp_sequence
    ds.BeamSequence = beam_sequence

    #
    ds.is_implicit_VR = True
    ds.is_little_endian = True
    ds.save_as(save_path, write_like_original=False)
Beispiel #14
0
    def add_referenced_frame_of_reference_sequence(self):
        """Fill the frame of reference module."""
        self.ds_rs.ReferencedFrameOfReferenceSequence.append(Dataset())
        referenced_frame_of_reference_sequence = self.ds_rs.ReferencedFrameOfReferenceSequence[-1]
        referenced_frame_of_reference_sequence.FrameOfReferenceUID = self.ds_rs.FrameOfReferenceUID

        referenced_frame_of_reference_sequence.add_new('RTReferencedStudySequence', 'SQ', Sequence())
        referenced_frame_of_reference_sequence.RTReferencedStudySequence.append(Dataset())
        rt_referenced_study_sequence = referenced_frame_of_reference_sequence.RTReferencedStudySequence[-1]
        rt_referenced_study_sequence.ReferencedSOPClassUID = UID('1.2.840.10008.3.1.2.3.1')
        rt_referenced_study_sequence.ReferencedSOPInstanceUID = self.ds_ct_reference.SeriesInstanceUID

        rt_referenced_study_sequence.add_new('RTReferencedSeriesSequence', 'SQ', Sequence())
        rt_referenced_study_sequence.RTReferencedSeriesSequence.append(Dataset())
        rt_referenced_series_sequence = rt_referenced_study_sequence.RTReferencedSeriesSequence[-1]
        rt_referenced_series_sequence.SeriesInstanceUID = self.ds_ct_reference.SeriesInstanceUID

        rt_referenced_series_sequence.add_new('ContourImageSequence', 'SQ', Sequence())

        for i, sop_instance_uid in enumerate(self.ds_ct_sop_instance_uid):
            rt_referenced_series_sequence.ContourImageSequence.append(Dataset())
            contour_image_sequence = rt_referenced_series_sequence.ContourImageSequence[i]
            contour_image_sequence.ReferencedSOPClassUID = UID('1.2.840.10008.5.1.4.1.1.2')
            contour_image_sequence.ReferencedSOPInstanceUID = sop_instance_uid
Beispiel #15
0
    def add_teeth(self, teeth):
        logging.debug("Adding teeth")
        if teeth == defaults.ADD_MAX_ALLOWED_TEETH:
            logging.debug("Setting all possibly allowed teeth.")
            teeth = ALLOWED_TEETH[self.image_type]

        if len(teeth) > 0:
            if not hasattr(self._ds, 'PrimaryAnatomicStructureSequence'):
                self._ds.PrimaryAnatomicStructureSequence = Sequence([])

            for tooth in teeth:
                if ToothCodes.is_valid_tooth_number(tooth):
                    self._ds.PrimaryAnatomicStructureSequence.append(
                        _get_sct_code_dataset(
                            *ToothCodes.SCT_TOOTH_CODES[tooth]))
Beispiel #16
0
def create_contour_sequence(roi_data: ROIData, series_data) -> Sequence:
    """
    Iterate through each slice of the mask
    For each connected segment within a slice, create a contour
    """

    contour_sequence = Sequence()

    contours_coords = get_contours_coords(roi_data, series_data)

    for series_slice, slice_contours in zip(series_data, contours_coords):
        for contour_data in slice_contours:
            contour = create_contour(series_slice, contour_data)
            contour_sequence.append(contour)

    return contour_sequence
Beispiel #17
0
def create_contour(series_slice: Dataset, contour_data: np.ndarray):
    contour_image = Dataset()
    contour_image.ReferencedSOPClassUID = series_slice.file_meta.MediaStorageSOPClassUID
    contour_image.ReferencedSOPInstanceUID = series_slice.file_meta.MediaStorageSOPInstanceUID

    # Contour Image Sequence
    contour_image_sequence = Sequence()
    contour_image_sequence.append(contour_image)

    contour = Dataset()
    contour.ContourImageSequence = contour_image_sequence
    contour.ContourGeometricType = 'CLOSED_PLANAR'  # TODO figure out how to get this value
    contour.NumberOfContourPoints = len(
        contour_data) / 3  # Each point has an x, y, and z value
    contour.ContourData = contour_data
    return contour
def put_attribute_in_path(ds: Dataset, path: list, a: DataElementX):
    if not path:
        if a.tag not in ds:
            ds[a.tag] = a
    else:
        kw = path.pop(0)
        tg = Dictionary.tag_for_keyword(kw)
        vr = Dictionary.dictionary_VR(tg)
        if vr == 'SQ':
            if tg in ds and ds[tg].VM > 0:
                inner_sq = ds[tg]
                item = inner_sq.value[0]
            else:
                item = Dataset()
                new_element = DataElementX(tg, vr, Sequence([item]))
                ds[tg] = new_element
            put_attribute_in_path(item, path, a)
def get_patient(patient_name,
                patient_id,
                n,
                patient_names=None,
                patient_ids=None,
                order=None):
    name_trailing, id_trailing = '', ''
    if patient_names is None:
        patient_names, name_trailing = parse_patient(patient_name)
    if patient_ids is None:
        patient_ids, id_trailing = parse_patient(patient_name)
        # in case patient id format is different
        # patient_ids, id_trailing = parse_patient(patient_id)
    # print(patient_names)
    if len(patient_names) != n:
        tmpName = 3 * ['blank']
        for i in range(len(order)):
            if int(order[i]) != 0:
                try:
                    tmpName[i] = patient_names.pop(0)
                except:
                    continue
        patient_names = tmpName
        warnings.warn('failed to parse PatientName %s, append a blank' %
                      patient_name)
    if len(patient_ids) != n:
        tmpId = 3 * ['blank']
        for i in range(len(order)):
            if int(order[i]) != 0:
                try:
                    tmpId[i] = patient_ids.pop(0)
                except:
                    continue
        patient_ids = tmpId
        warnings.warn('failed to parse PatientID %s, append a blank' %
                      patient_id)
    source_patient = Dataset()
    # FIXME: remove '_1'?
    source_patient.PatientName = patient_name
    source_patient.PatientID = patient_id

    return (patient_names, patient_ids), Sequence([source_patient
                                                   ]), (name_trailing,
                                                        id_trailing)
Beispiel #20
0
    def _convert_value(self, val):
        """Convert `val` to an appropriate type and return the result.

        Uses the element's VR in order to determine the conversion method and
        resulting type.
        """
        if self.VR == 'SQ':  # a sequence - leave it alone
            from pydicom.sequence import Sequence
            if isinstance(val, Sequence):
                return val
            else:
                return Sequence(val)

        # if the value is a list, convert each element
        try:
            val.append
        except AttributeError:  # not a list
            return self._convert(val)
        else:
            return MultiValue(lambda x: self._convert(x), val)
Beispiel #21
0
    def _convert_value(self, val):
        """Convert Dicom string values if possible to e.g. numbers. Handle the case
        of multiple value data_elements"""
        if self.VR == 'SQ':  # a sequence - leave it alone
            from pydicom.sequence import Sequence
            if isinstance(val, Sequence):
                return val
            else:
                return Sequence(val)

        # if the value is a list, convert each element
        try:
            val.append
        except AttributeError:  # not a list
            return self._convert(val)
        else:
            returnvalue = []
            for subval in val:
                returnvalue.append(self._convert(subval))
            return returnvalue
Beispiel #22
0
def add_dicom_sequence(ds, seq_keyword, data_set_dict):
    """Add a sequence to a data set.

    Parameters
    ----------
    ds : pydicom Dataset
        The pydicom dataset for the sequence to be added to.
    seq_keyword : str
        The DICOM keyword for the sequence.
    data_set_dict : dict
        Dictionary of tags and values for the sequence element.
    """
    seq_ds = Dataset()
    for tag, value in data_set_dict.items():
        set_dicom_tag_value(seq_ds, tag, value)

    if hasattr(ds, seq_keyword):
        getattr(ds, seq_keyword).append(seq_ds)
    else:
        setattr(ds, seq_keyword, Sequence([seq_ds]))
Beispiel #23
0
 def create_new_contour(self, roi_id, extents, z):
     """Create a new contour sequence for the given ROI id."""
     roic = self.rtss.ds.ROIContourSequence[roi_id - 1]
     new_contour = Dataset()
     # Create a ContourImageSequence for the referenced Image
     new_contour.ContourImageSequence = Sequence([])
     contour_image = Dataset()
     last_contour = roic.ContourSequence[-1].ContourImageSequence[-1]
     contour_image.ReferencedSOPClassUID = \
         last_contour.ReferencedSOPClassUID
     contour_image.ReferencedSOPInstanceUID = \
         last_contour.ReferencedSOPInstanceUID
     new_contour.ContourImageSequence.append(contour_image)
     new_contour.ContourGeometricType = 'CLOSED_PLANAR'
     new_contour.NumberOfContourPoints = 4
     xmin, ymin, xmax, ymax = extents
     new_contour.ContourData = [
         xmin, ymin, z, xmax, ymin, z, xmax, ymax, z, xmin, ymax, z
     ]
     roic.ContourSequence.append(new_contour)
Beispiel #24
0
def create_contour_sequence(roi_data: ROIData, series_data) -> Sequence:
    """
    Iterate through each slice of the mask
    For each connected segment within a slice, create a contour
    """

    contour_sequence = Sequence()
    for i, series_slice in enumerate(series_data):
        mask_slice = roi_data.mask[:,:,i]
        # Do not add ROI's for blank slices
        if np.sum(mask_slice) == 0:
            print("Skipping empty mask layer")
            continue

        contour_coords = get_contours_coords(mask_slice, series_slice, roi_data)
        for contour_data in contour_coords:
            contour = create_contour(series_slice, contour_data)
            contour_sequence.append(contour)

    return contour_sequence
Beispiel #25
0
def __add_circles(dataset, circles):
    circle_objects = []
    for circle in circles:
        ds_cir_object = Dataset()
        cir_pos_x = circle["x"]
        cir_pos_y = circle["y"]
        cir_rad = circle["radius"]
        ds_cir_object.GraphicAnnotationUnits = "PIXEL"
        ds_cir_object.GraphicDimensions = 2
        ds_cir_object.NumberOfGraphicPoints = 2
        ds_cir_object.GraphicData = [
            cir_pos_x,  # x coordinate of middle of circle
            cir_pos_y,  # y coordinate of middle of circle
            cir_pos_x,  # x coordinate of point on circumference
            cir_pos_y + cir_rad
        ]  # y coordinate of point on circumference
        ds_cir_object.GraphicType = "CIRCLE"
        ds_cir_object.GraphicFilled = "N"
        circle_objects.append(ds_cir_object)
    dataset.GraphicObjectSequence = Sequence(circle_objects)
    return dataset
Beispiel #26
0
    def test_adding_datasets(self):
        """Tests for adding datasets to the Sequence"""
        ds_a = Dataset()
        ds_a.Rows = 1
        ds_b = Dataset()
        ds_b.Rows = 2
        ds_c = Dataset()
        ds_c.Rows = 3
        ds_d = Dataset()
        ds_d.Rows = 4
        ds_e = Dataset()
        ds_e.Rows = 5

        parent = Dataset()
        parent.PatientName = "Parent"

        seq = Sequence()
        seq.parent = parent
        assert isinstance(seq.parent, weakref.ReferenceType)
        seq.append(ds_a)
        seq.append(ds_c)
        seq.insert(1, ds_b)
        assert 3 == len(seq)
        for ds in seq:
            assert isinstance(ds.parent, weakref.ReferenceType)

        seq[1] = ds_e
        assert ds_e == seq[1]
        assert [ds_a, ds_e, ds_c] == seq
        seq[1:1] = [ds_d]
        assert [ds_a, ds_d, ds_e, ds_c] == seq
        seq[1:2] = [ds_c, ds_e]
        assert [ds_a, ds_c, ds_e, ds_e, ds_c] == seq
        for ds in seq:
            assert isinstance(ds.parent, weakref.ReferenceType)

        msg = r"Can only assign an iterable of 'Dataset'"
        with pytest.raises(TypeError, match=msg):
            seq[1:1] = ds_d
Beispiel #27
0
def read_sequence(fp, is_implicit_VR, is_little_endian, bytelength, encoding,
                  offset=0):
    """Read and return a Sequence -- i.e. a list of Datasets"""

    seq = []  # use builtin list to start for speed, convert to Sequence at end
    is_undefined_length = False
    if bytelength != 0:  # SQ of length 0 possible (PS 3.5-2008 7.5.1a (p.40)
        if bytelength == 0xffffffff:
            is_undefined_length = True
            bytelength = None
        fp_tell = fp.tell  # for speed in loop
        fpStart = fp_tell()
        while (not bytelength) or (fp_tell() - fpStart < bytelength):
            file_tell = fp.tell()
            dataset = read_sequence_item(fp, is_implicit_VR, is_little_endian,
                                         encoding, offset)
            if dataset is None:  # None is returned if hit Sequence Delimiter
                break
            dataset.file_tell = file_tell + offset
            seq.append(dataset)
    seq = Sequence(seq)
    seq.is_undefined_length = is_undefined_length
    return seq
Beispiel #28
0
    def _convert_value(self, val: Any) -> Any:
        """Convert `val` to an appropriate type and return the result.

        Uses the element's VR in order to determine the conversion method and
        resulting type.
        """
        if self.VR == VR_.SQ:  # a sequence - leave it alone
            from pydicom.sequence import Sequence
            if isinstance(val, Sequence):
                return val

            return Sequence(val)

        # if the value is a list, convert each element
        try:
            val.append
        except AttributeError:  # not a list
            return self._convert(val)
        if len(val) == 1:
            return self._convert(val[0])
        return MultiValue(self._convert,
                          val,
                          validation_mode=self.validation_mode)
Beispiel #29
0
    def apply_rules(self, rules: RuleSet, dataset: Dataset) -> Dataset:
        """Apply rules to each element in dataset, recursing into sequence elements

        This creates a deep copy of the input dataset. Except for PixelData, which
        will be a reference. PixelData is not copied because it can take up a lot
        of memory
        """
        deidentified = Dataset()
        pixel_data_tag = 0x7FE00010

        for element in dataset:
            if element.tag == pixel_data_tag:
                deidentified.add(
                    element)  # add pixel data as reference to save mem
            elif element.VR == VRs.Sequence.short_name:  # recurse into sequences
                deidentified.add(
                    DataElement(
                        tag=element.tag,
                        VR=element.VR,
                        value=Sequence([
                            self.apply_rules(rules, sub_dataset)
                            for sub_dataset in element
                        ]),
                    ))
            elif rule := rules.get_rule(element):
                if type(rule.operation) == Remove:
                    continue  # special handling. should be removed, do not add
                try:
                    new = rule.operation.apply(element, dataset)
                    deidentified.add(new)
                except ElementShouldBeRemoved:  # Operators signals removal
                    continue
            else:  # no rule found. Just copy the element over
                deidentified.add(
                    DataElement(tag=element.tag,
                                VR=element.VR,
                                value=element.value))
Beispiel #30
0
 def testDefaultInitialization(self):
     """Sequence: Ensure a valid Sequence is created"""
     empty = Sequence()
     assert 0 == len(empty)