예제 #1
0
def _write_log_pass_content_in_html(
        logical_file: LogicalFile.LogicalFile,
        xhtml_stream: XmlWrite.XhtmlStream,
        # Used for anchor
        logical_file_index: int,
        number_of_preceeding_eflrs: int,
        *,
        frame_slice: Slice.Slice) -> typing.Tuple[HTMLFrameArraySummary]:
    assert logical_file.has_log_pass
    ret = []
    lp: LogPass.LogPass = logical_file.log_pass
    frame_array: LogPass.FrameArray
    for fa, frame_array in enumerate(lp.frame_arrays):
        anchor = _anchor(logical_file_index, number_of_preceeding_eflrs, fa)
        with XmlWrite.Element(xhtml_stream, 'a', {'id': anchor}):
            pass
        with XmlWrite.Element(xhtml_stream, 'h3'):
            xhtml_stream.characters(
                f'Frame Array: {stringify.stringify_object_by_type(frame_array.ident)} [{fa}/{len(lp.frame_arrays)}]'
            )
        ret.append(
            _write_frame_array_in_html(
                logical_file,
                frame_array,
                frame_slice,
                anchor,
                xhtml_stream,
            ))
    return tuple(ret)
예제 #2
0
def html_write_file_info(path_in: str,
                         xhtml_stream: XmlWrite.XhtmlStream) -> None:
    with XmlWrite.Element(xhtml_stream, 'h2'):
        xhtml_stream.characters('File information')
    table = [
        ['KEY', 'VALUE'],
        ['File Path:', path_in],
        ['File size:', f'{os.path.getsize(path_in):,d}'],
    ]
    html_write_table(table, xhtml_stream, class_style='monospace')
예제 #3
0
def _write_x_axis_summary(x_axis: XAxis.XAxis,
                          xhtml_stream: XmlWrite.XhtmlStream) -> None:
    # Parent section is heading h3

    # with XmlWrite.Element(xhtml_stream, 'h4'):
    #     xhtml_stream.characters('X Axis summary (all IFLRs)')
    with XmlWrite.Element(xhtml_stream, 'h4'):
        xhtml_stream.characters('X Axis')
    units = x_axis.units.decode('ascii')
    x_axis_table = [
        ['X Axis', 'Value'],
        ['Channel', f'{x_axis.ident}'],
        ['Long Name', f'{x_axis.long_name.decode("ascii")}'],
        ['Minimum', f'{x_axis.summary.min} [{units}]'],
        ['Maximum', f'{x_axis.summary.max} [{units}]'],
        ['Frame Count', f'{x_axis.summary.count}'],
    ]
    html_write_table(x_axis_table, xhtml_stream, class_style='monospace')
    with XmlWrite.Element(xhtml_stream, 'h4'):
        xhtml_stream.characters('X Axis Spacing')
    with XmlWrite.Element(xhtml_stream, 'p'):
        xhtml_stream.characters(f'Definitions: {XAxis.SPACING_DEFINITIONS}')
    x_spacing_table = [
        ['X Axis Spacing', 'Value'],
    ]
    if x_axis.summary.spacing is not None:
        spacing = x_axis.summary.spacing
        x_spacing_table.append(['Minimum', f'{spacing.min} [{units}]'])
        x_spacing_table.append(['Mean', f'{spacing.mean} [{units}]'])
        x_spacing_table.append(['Median', f'{spacing.median} [{units}]'])
        x_spacing_table.append(['Maximum', f'{spacing.max} [{units}]'])
        if spacing.median != 0:
            x_spacing_table.append([
                'Range',
                f'{spacing.max - spacing.min} ({(spacing.max - spacing.min) / spacing.median:%}) [{units}]'
            ])
        else:
            x_spacing_table.append(
                ['Range', f'{spacing.max - spacing.min} [{units}]'])
        x_spacing_table.append(['Std. Dev.', f'{spacing.std} [{units}]'])
        x_spacing_table.append(
            ['Count of Normal', f'{spacing.counts.norm:,d}'])
        x_spacing_table.append(
            ['Count of Duplicate', f'{spacing.counts.dupe:,d}'])
        x_spacing_table.append(
            ['Count of Skipped', f'{spacing.counts.skip:,d}'])
        x_spacing_table.append(['Count of Back', f'{spacing.counts.back:,d}'])
    html_write_table(x_spacing_table, xhtml_stream, class_style='monospace')
    if x_axis.summary.spacing is not None:
        with XmlWrite.Element(xhtml_stream, 'p'):
            xhtml_stream.characters('Frame spacing frequency:')
        with XmlWrite.Element(xhtml_stream, 'pre'):
            xhtml_stream.characters(x_axis.summary.spacing.histogram_str())
예제 #4
0
def html_write_table(table_as_strings: typing.List[typing.List[str]],
                     xhtml_stream: XmlWrite.XhtmlStream, class_style) -> None:
    if len(table_as_strings):
        with XmlWrite.Element(xhtml_stream, 'table', {'class': class_style}):
            with XmlWrite.Element(xhtml_stream, 'tr', {}):
                for cell in table_as_strings[0]:
                    with XmlWrite.Element(xhtml_stream, 'th',
                                          {'class': class_style}):
                        xhtml_stream.characters(cell)
            for row in table_as_strings[1:]:
                with XmlWrite.Element(xhtml_stream, 'tr', {}):
                    for cell in row:
                        with XmlWrite.Element(xhtml_stream, 'td',
                                              {'class': class_style}):
                            assert isinstance(
                                cell, str
                            ), f'{cell} is not a string but {type(cell)}'
                            xhtml_stream.charactersWithBr(cell)
예제 #5
0
def html_write_storage_unit_label(sul: StorageUnitLabel.StorageUnitLabel,
                                  xhtml_stream: XmlWrite.XhtmlStream) -> None:
    with XmlWrite.Element(xhtml_stream, 'h2'):
        xhtml_stream.characters('Storage Unit Label')
    table = [
        ['KEY', 'VALUE'],
        [
            'Storage Unit Sequence Number:',
            f'{sul.storage_unit_sequence_number:d}'
        ],
        ['DLIS Version:', f'{sul.dlis_version.decode("ascii")}'],
        [
            'Storage Unit Structure:',
            f'{sul.storage_unit_structure.decode("ascii")}'
        ],
        ['Maximum Record Length:', f'{sul.maximum_record_length:d}'],
        [
            'Storage Set Identifier:',
            f'{sul.storage_set_identifier.decode("ascii")}'
        ],
    ]
    html_write_table(table, xhtml_stream, class_style='sul')
예제 #6
0
def _write_top_level_index_table_body(
        index_file_path: str, dict_tree: DictTree.DictTreeHtmlTable,
        xhtml_stream: XmlWrite.XhtmlStream) -> None:
    strip_out_path = len(os.path.dirname(index_file_path)) + 1
    for event in dict_tree.genColRowEvents():
        if event == dict_tree.ROW_OPEN:
            # Write out the '<tr>' element
            xhtml_stream.startElement('tr', {'class': 'filetable'})
        elif event == dict_tree.ROW_CLOSE:
            # Write out the '</tr>' element
            xhtml_stream.endElement('tr')
        else:
            td_attrs = {'class': 'filetable'}
            if event.row_span > 1:
                td_attrs['rowspan'] = f'{event.row_span:d}'
            if event.col_span > 1:
                td_attrs['colspan'] = f'{event.col_span:d}'
            if event.node is None:
                with XmlWrite.Element(xhtml_stream, 'td', td_attrs):
                    possible_index_file = os.path.join(
                        *event.branch) + os.sep + INDEX_FILE
                    if os.path.exists(possible_index_file):
                        xhtml_stream.comment(
                            f' Writing event branch[-1] with link to {INDEX_FILE} '
                        )
                        with XmlWrite.Element(
                                xhtml_stream, 'a',
                            {'href': possible_index_file[strip_out_path:]}):
                            xhtml_stream.characters(f'{str(event.branch[-1])}')
                    else:
                        xhtml_stream.comment(
                            f' Writing event branch[-1] without link to absent {possible_index_file}'
                        )
                        xhtml_stream.characters(f'{str(event.branch[-1])}')
            else:
                node: HTMLResult = event.node
                with XmlWrite.Element(xhtml_stream, 'td', td_attrs):
                    xhtml_stream.comment(' Writing event.node with link ')
                    with XmlWrite.Element(
                            xhtml_stream, 'a',
                        {'href': f'{node.path_output[strip_out_path:]}'}):
                        xhtml_stream.characters(str(event.branch[-1]))
예제 #7
0
def html_write_body(
    logical_file_sequence: LogicalFile.LogicalIndex,
    frame_slice: Slice.Slice,
    xhtml_stream: XmlWrite.XhtmlStream,
) -> HTMLBodySummary:
    """Write out the <body> of the document."""
    with XmlWrite.Element(xhtml_stream, 'h1'):
        xhtml_stream.characters('RP66V1 File Data Summary')
    html_write_file_info(logical_file_sequence.id, xhtml_stream)
    html_write_storage_unit_label(logical_file_sequence.storage_unit_label,
                                  xhtml_stream)
    html_write_table_of_contents(logical_file_sequence, xhtml_stream)
    logical_file_summaries: typing.List[HTMLLogicalFileSummary] = []
    logical_file: LogicalFile.LogicalFile
    for lf, logical_file in enumerate(logical_file_sequence.logical_files):
        eflr_types: typing.List[bytes] = []
        with XmlWrite.Element(xhtml_stream, 'h2'):
            xhtml_stream.characters(
                f'Logical File [{lf}/{len(logical_file_sequence.logical_files)}]'
            )
        eflr_position: LogicalFile.PositionEFLR
        for e, eflr_position in enumerate(logical_file.eflrs):
            eflr_types.append(eflr_position.eflr.set.type)
            header = [
                f'EFLR: {eflr_position.eflr.set.type.decode("ascii")}',
                f'Shape: {eflr_position.eflr.shape}'
            ]
            with XmlWrite.Element(xhtml_stream, 'a',
                                  {'id': f'{_anchor(lf, e)}'}):
                pass
            with XmlWrite.Element(xhtml_stream, 'h3'):
                xhtml_stream.characters(' '.join(header))
            with XmlWrite.Element(xhtml_stream, 'p'):
                xhtml_stream.characters(
                    f'Location: {eflr_position.lrsh_position}')
            if eflr_position.eflr.set.type == b'FILE-HEADER':
                obj = eflr_position.eflr.objects[0]
                with XmlWrite.Element(xhtml_stream, 'p'):
                    xhtml_stream.characters(
                        f'File-Header Object "{obj.name.I.decode("ascii")}" O: {obj.name.O} C: {obj.name.C}:'
                    )
            elif eflr_position.eflr.set.type == b'ORIGIN':
                # Slightly special case with ORIGIN records as they contain the Defining Origin of the Logical File.
                # [RP66V1 Section 5.2.1 Origin Objects]
                obj = eflr_position.eflr.objects[0]
                with XmlWrite.Element(xhtml_stream, 'p'):
                    xhtml_stream.characters(
                        f'Logical File Defining Origin "{obj.name.I.decode("ascii")}" O: {obj.name.O} C: {obj.name.C}:'
                    )
            html_write_EFLR_as_table(eflr_position.eflr, xhtml_stream)
        with XmlWrite.Element(xhtml_stream, 'h3'):
            xhtml_stream.characters('Log Pass')
        if logical_file.has_log_pass:
            with XmlWrite.Element(
                    xhtml_stream, 'a',
                {'id': f'{_anchor(lf, len(logical_file.eflrs))}'}):
                pass
            frame_array_summary = _write_log_pass_content_in_html(
                logical_file,
                xhtml_stream,
                lf,
                len(logical_file.eflrs),
                frame_slice=frame_slice,
            )
            logical_file_summaries.append(
                (HTMLLogicalFileSummary(tuple(eflr_types),
                                        frame_array_summary)))
        else:
            with XmlWrite.Element(xhtml_stream, 'p'):
                xhtml_stream.characters('NO Log Pass for this Logical Record')
            logical_file_summaries.append(
                (HTMLLogicalFileSummary(tuple(eflr_types), tuple())))
    return HTMLBodySummary(
        logical_file_sequence.storage_unit_label.storage_set_identifier.decode(
            'ascii'),
        tuple(logical_file_summaries),
    )
예제 #8
0
def html_write_table_of_contents(
        logical_file_sequence: LogicalFile.LogicalIndex,
        xhtml_stream: XmlWrite.XhtmlStream) -> None:
    """Write out the table of contents."""
    with XmlWrite.Element(xhtml_stream, 'h2'):
        xhtml_stream.characters('Table of Contents')
    with XmlWrite.Element(xhtml_stream, 'ol'):
        logical_file: LogicalFile.LogicalFile
        for index_lf, logical_file in enumerate(
                logical_file_sequence.logical_files):
            with XmlWrite.Element(xhtml_stream, 'li'):
                xhtml_stream.characters(
                    f'Logical File [{index_lf}/{len(logical_file_sequence.logical_files)}]'
                )
            with XmlWrite.Element(xhtml_stream, 'ol'):
                lrsh_position: File.LogicalRecordPosition
                eflr: EFLR.ExplicitlyFormattedLogicalRecord
                for index_eflr, (lrsh_position,
                                 eflr) in enumerate(logical_file.eflrs):
                    with XmlWrite.Element(xhtml_stream, 'li'):
                        with XmlWrite.Element(
                                xhtml_stream, 'a',
                            {'href': f'#{_anchor(index_lf, index_eflr)}'}):
                            xhtml_stream.characters(
                                f'{eflr.set.type.decode("ascii")}')
                        xhtml_stream.literal('&nbsp;')
                        xhtml_stream.characters(f'Shape: {eflr.shape}')
                if logical_file.has_log_pass:
                    with XmlWrite.Element(xhtml_stream, 'li'):
                        with XmlWrite.Element(
                                xhtml_stream, 'a',
                            {
                                'href':
                                f'#{_anchor(index_lf, len(logical_file.eflrs))}'
                            }):
                            xhtml_stream.characters(
                                f'Log Pass with {len(logical_file.log_pass)} Frame Arrays'
                            )
                        with XmlWrite.Element(xhtml_stream, 'ol'):
                            for index_fa, frame_array in enumerate(
                                    logical_file.log_pass):
                                with XmlWrite.Element(xhtml_stream, 'li'):
                                    attrs = {
                                        'href':
                                        f'#{_anchor(index_lf, len(logical_file.eflrs), index_fa)}'
                                    }
                                    # xhtml_stream.characters(f'Frame Array:')
                                    with XmlWrite.Element(
                                            xhtml_stream, 'a', attrs):
                                        xhtml_stream.characters(
                                            f'{stringify.stringify_object_by_type(frame_array.ident)}'
                                        )
                                    xhtml_stream.characters(
                                        f' with {len(frame_array.channels)} channels'
                                    )
                                    xhtml_stream.characters(
                                        f' and {len(logical_file.iflr_position_map[frame_array.ident])} frames'
                                    )
예제 #9
0
def _write_frame_array_in_html(
    logical_file: LogicalFile.LogicalFile,
    frame_array: LogPass.FrameArray,
    frame_slice: typing.Union[Slice.Slice, Slice.Sample],
    anchor: str,
    xhtml_stream: XmlWrite.XhtmlStream,
) -> HTMLFrameArraySummary:
    # Parent section is heading h3

    # with XmlWrite.Element(xhtml_stream, 'h4'):
    #     xhtml_stream.characters('Frame Data')
    iflrs: typing.List[XAxis.IFLRReference] = logical_file.iflr_position_map[
        frame_array.ident]
    if len(iflrs):
        num_frames = logical_file.populate_frame_array(
            frame_array,
            frame_slice,
            None,
        )
        x_axis: XAxis.XAxis = logical_file.iflr_position_map[frame_array.ident]
        _write_x_axis_summary(x_axis, xhtml_stream)

        with XmlWrite.Element(xhtml_stream, 'h4'):
            xhtml_stream.characters('Frame Analysis')
        with XmlWrite.Element(xhtml_stream, 'p'):
            if x_axis.summary.spacing is not None:
                interval = f'{x_axis.summary.spacing.median:0.3f}'
            else:
                interval = 'N/A'
            xhtml_stream.characters(
                f'Available frames: {len(iflrs)}'
                f' X axis from {float(iflrs[0].x_axis):0.3f}'
                f' to {float(iflrs[-1].x_axis):0.3f}'
                f' interval {interval}'
                f' [{stringify.stringify_object_by_type(frame_array.x_axis.units)}]'
            )
        with XmlWrite.Element(xhtml_stream, 'p'):
            xhtml_stream.characters(
                f'Frame analysis on {frame_slice.long_str(len(iflrs))} frame(s).'
                f' Number of frames created: {num_frames}'
                f' Numpy total memory: {frame_array.sizeof_array:,d} bytes')
        with XmlWrite.Element(xhtml_stream, 'p'):
            xhtml_stream.characters(
                f'RP66V1 Frame size {frame_array.len_input_bytes} (bytes/frame))'
                f' represented internally as {frame_array.sizeof_frame} (bytes/frame).'
            )
        frame_table = [
            [
                'Channel', 'O', 'C', 'Rep Code', 'Dims', 'Count', 'Units',
                'Long Name', 'Size', 'Absent', 'Min', 'Mean', 'Std.Dev.',
                'Max', 'dtype'
            ],
        ]
        for channel in frame_array.channels:
            # arr = channel.array
            arr = AbsentValue.mask_absent_values(channel.array)
            frame_table.append([
                channel.ident.I.decode("ascii"),
                f'{channel.ident.O}',
                f'{channel.ident.C}',
                f'{channel.rep_code:d} ({RepCode.REP_CODE_INT_TO_STR[channel.rep_code]})',
                stringify.stringify_object_by_type(channel.dimensions),
                stringify.stringify_object_by_type(channel.count),
                stringify.stringify_object_by_type(channel.units),
                stringify.stringify_object_by_type(channel.long_name),
                f'{arr.size:d}',
                # NOTE: Not the masked array!
                f'{AbsentValue.count_of_absent_values(channel.array):d}',
                f'{arr.min():.3f}',
                f'{arr.mean():.3f}',
                f'{arr.std():.3f}',
                f'{arr.max():.3f}',
                f'{arr.dtype}',
            ])
        html_write_table(frame_table, xhtml_stream, class_style='monospace')
        x_axis_start = iflrs[0].x_axis
        x_axis_stop = iflrs[-1].x_axis
    else:
        with XmlWrite.Element(xhtml_stream, 'p'):
            xhtml_stream.characters('No frames.')
        x_axis_start = x_axis_stop = 0.0
    return HTMLFrameArraySummary(
        frame_array.ident.I,
        len(iflrs),
        tuple(c.ident.I for c in frame_array.channels),
        x_axis_start,
        x_axis_stop,
        frame_array.x_axis.units,
        anchor,
    )