Exemplo n.º 1
0
class AppVariables(object):
    browse_directory = StringDescriptor(
        'browse_directory',
        default_value=os.path.expanduser('~'),
        docstring='The directory for browsing for file selection.'
    )  # type: str
    remap_type = StringDescriptor('remap_type',
                                  default_value='density',
                                  docstring='')  # type: str
    image_reader = TypedDescriptor('image_reader',
                                   ComplexImageReader,
                                   docstring='')  # type: ComplexImageReader

    row_fourier_reader = TypedDescriptor(
        'row_fourier_reader',
        ComplexImageReader,
        docstring='The row deskewed fourier transformed reader'
    )  # type: ComplexImageReader
    row_fourier_file = StringDescriptor(
        'row_fourier_file',
        docstring='The row deskewed fourier transformed reader file'
    )  # type: str
    # NB: we are saving this state in order to properly clean up
    column_fourier_reader = TypedDescriptor(
        'column_fourier_reader',
        ComplexImageReader,
        docstring='The column deskewed fourier transformed reader'
    )  # type: ComplexImageReader
    column_fourier_file = StringDescriptor(
        'row_fourier_file',
        docstring='The column deskewed fourier transformed reader file'
    )  # type: str
    # NB: we are saving this state in order to properly clean up

    derived_row_weights = None  # the derived weights for the row
    scaled_row_mean = None  # the scaled mean Fourier transform of the row deskewed data
    derived_column_weights = None  # the derived weights for the column
    scaled_column_mean = None  # the scaled mean Fourier transform of the column deskewed data

    def __del__(self):
        # clean up files, because we might need to do so
        if self.row_fourier_file is not None \
                and os.path.exists(self.row_fourier_file):
            os.remove(self.row_fourier_file)
            logger.debug('(variables) Removing temp file % s' %
                         self.row_fourier_file)
            self.row_fourier_file = None

        if self.column_fourier_file is not None and \
                os.path.exists(self.column_fourier_file):
            os.remove(self.column_fourier_file)
            logger.debug('(variables)  Removing temp file % s' %
                         self.column_fourier_file)
            self.column_fourier_file = None
Exemplo n.º 2
0
class AppVariables(object):
    browse_directory = StringDescriptor(
        'browse_directory', default_value=os.path.expanduser('~'),
        docstring='The directory for browsing for file selection.')  # type: str
    remap_type = StringDescriptor(
        'remap_type', default_value='density', docstring='')  # type: str
    image_reader = TypedDescriptor(
        'image_reader', ComplexImageReader, docstring='')  # type: ComplexImageReader
    row_line_low = IntegerDescriptor(
        'row_line_low',
        docstring='The id of the frequency_panel of the lower row bandwidth line.')  # type: Union[None, int]
    row_line_high = IntegerDescriptor(
        'row_line_high',
        docstring='The id of the frequency_panel of the upper row bandwidth line.')  # type: Union[None, int]
    col_line_low = IntegerDescriptor(
        'col_line_low',
        docstring='The id of the frequency_panel of the lower column bandwidth line.')  # type: Union[None, int]
    col_line_high = IntegerDescriptor(
        'col_line_high',
        docstring='The id of the frequency_panel of the upper column bandwidth line.')  # type: Union[None, int]
    row_deltak1 = IntegerDescriptor(
        'row_deltak1',
        docstring='The id of the frequency_panel of the row deltak1 line.')  # type: Union[None, int]
    row_deltak2 = IntegerDescriptor(
        'row_deltak2',
        docstring='The id of the frequency_panel of the row deltak2 line.')  # type: Union[None, int]
    col_deltak1 = IntegerDescriptor(
        'col_deltak1',
        docstring='The id of the frequency_panel of the column deltak1.')  # type: Union[None, int]
    col_deltak2 = IntegerDescriptor(
        'col_deltak2',
        docstring='The id of the frequency_panel of the column deltak2.')  # type: Union[None, int]
Exemplo n.º 3
0
class AppVariables(object):
    """
    App variables for the aperture tool.
    """

    browse_directory = StringDescriptor(
        'browse_directory',
        default_value=os.path.expanduser('~'),
        docstring='The directory for browsing for file selection.'
    )  # type: str
    image_reader = TypedDescriptor(
        'image_reader',
        STFTCanvasImageReader,
        docstring='The crsd type canvas image reader object.'
    )  # type: STFTCanvasImageReader
    animating = BooleanDescriptor(
        'animating',
        default_value=False,
        docstring='Are we currently looping through pulses?')  # type: bool
    animation_delay = IntegerDescriptor(
        'animation_delay',
        default_value=30,
        docstring='Animation delay in milliseconds')  # type: int
    vmin = FloatDescriptor('vmin', default_value=0)  # type: float
    vmax = FloatDescriptor('vmax', default_value=0)  # type: float
    vcount = IntegerDescriptor('vcount', default_value=0)  # type: int
Exemplo n.º 4
0
class AppVariables(AppVariables_Annotate):
    file_annotation_collection = TypedDescriptor(
        'file_annotation_collection',
        FileLabelCollection,
        docstring='The file annotation collection.'
    )  # type: FileLabelCollection

    @property
    def label_schema(self):
        """
        None|LabelSchema: The label schema.
        """

        return None if self.file_annotation_collection is None else \
            self.file_annotation_collection.label_schema

    def get_label(self, label_id):
        if self.file_annotation_collection is None or label_id is None:
            return None
        return self.file_annotation_collection.label_schema.labels[label_id]

    def get_current_annotation_object(self):
        """
        Gets the current annotation object

        Returns
        -------
        None|LabelFeature
        """

        if self._current_feature_id is None:
            return None
        return self.file_annotation_collection.annotations[
            self._current_feature_id]
Exemplo n.º 5
0
class AppVariables(object):
    browse_directory = StringDescriptor(
        'browse_directory',
        default_value=os.path.expanduser('~'),
        docstring='The directory for browsing for file selection.'
    )  # type: str
    image_reader = TypedDescriptor(
        'image_reader', SICDTypeCanvasImageReader,
        docstring='')  # type: SICDTypeCanvasImageReader
Exemplo n.º 6
0
class AppVariables(object):
    current_id = StringDescriptor('current_id',
                                  default_value=None)  # type: Union[None, str]
    unsaved_edits = BooleanDescriptor('unsaved_edits',
                                      default_value=False)  # type: bool
    browse_directory = StringDescriptor(
        'browse_directory',
        default_value=os.path.expanduser('~'),
        docstring='The directory for browsing for file selection.'
    )  # type: str
    label_file_name = StringDescriptor(
        'label_file_name', default_value=None)  # type: Union[None, str]
    label_schema = TypedDescriptor('label_schema',
                                   LabelSchema)  # type: LabelSchema
Exemplo n.º 7
0
class AppVariables(AppVariables_Annotate):
    file_annotation_collection = TypedDescriptor(
        'file_annotation_collection',
        FileRCSCollection,
        docstring='The file annotation collection.')  # type: FileRCSCollection
    image_reader = TypedDescriptor(
        'image_reader', SICDTypeCanvasImageReader,
        docstring='')  # type: SICDTypeCanvasImageReader
    rcs_viewer_units = StringDescriptor('rcs_viewer_units',
                                        default_value='')  # type: str

    def get_current_annotation_object(self):
        """
        Gets the current annotation object

        Returns
        -------
        None|RCSFeature
        """

        if self._current_feature_id is None:
            return None
        return self.file_annotation_collection.annotations[
            self._current_feature_id]

    def get_rcs_units(self):
        if self.image_reader is None:
            return []

        sicd = self.image_reader.get_sicd()
        if sicd.Radiometric is None:
            return ['TotalPixelPower', 'PixelPower']
        else:
            return [
                'TotalRCS', 'PixelPower', 'RCS', 'BetaZero', 'GammaZero',
                'SigmaZero'
            ]
Exemplo n.º 8
0
class AppVariables(object):
    """
    The canvas demo app variables.
    """

    browse_directory = StringDescriptor(
        'browse_directory', default_value=os.path.expanduser('~'))  # type: str
    selection_rect_id = IntegerDescriptor('selection_rect_id',
                                          docstring='')  # type: int
    image_reader = TypedDescriptor('image_reader',
                                   ComplexImageReader,
                                   docstring='')  # type: ComplexImageReader

    def __init__(self):
        self.shapes_in_selector = []
Exemplo n.º 9
0
class AppVariables(object):
    browse_directory = StringDescriptor(
        'browse_directory', default_value=os.path.expanduser('~'),
        docstring='The initial opening directory. This will get updated on chosen file.')  # type: str
    image_reader = TypedDescriptor(
        'image_reader', ComplexImageReader, docstring='')  # type: ComplexImageReader
    arrow_id = IntegerDescriptor(
        'arrow_id', docstring='')  # type: int
    point_id = IntegerDescriptor(
        'point_id', docstring='')  # type: int
    horizontal_line_id = IntegerDescriptor(
        'horizontal_line_id', docstring='')  # type: int
    line_width = IntegerDescriptor(
        'line_width', default_value=3, docstring='')  # type: int
    horizontal_line_width = IntegerDescriptor(
        'horizontal_line_width', default_value=3, docstring='')  # type: int
    horizontal_line_color = StringDescriptor(
        'horizontal_line_color', default_value='green',
        docstring='A hexidecimal or named color.')  # type: str
Exemplo n.º 10
0
class ValidationTool(tkinter.PanedWindow, WidgetWithMetadata):
    _widget_list = ("button_panel", "text_log_widget")
    button_panel = TypedDescriptor(
        'button_panel', _Buttons,
        docstring='the button panel')  # type: _Buttons
    text_log_widget = TypedDescriptor(
        'text_log_widget', ScrolledText,
        docstring='the log display')  # type: ScrolledText

    def __init__(self, primary, reader=None, **kwargs):
        """

        Parameters
        ----------
        primary : tkinter.Toplevel|tkinter.Tk
        reader : None|str|SICDTypeReader|SICDTypeCanvasImageReader
        """

        self.variables = AppVariables()

        if 'sashrelief' not in kwargs:
            kwargs['sashrelief'] = tkinter.RIDGE
        if 'orient' not in kwargs:
            kwargs['orient'] = tkinter.VERTICAL

        tkinter.PanedWindow.__init__(self, primary, **kwargs)
        WidgetWithMetadata.__init__(self, primary)
        self.pack(expand=tkinter.TRUE, fill=tkinter.BOTH)

        # handle packing manually
        self.button_panel = _Buttons(self)
        self.add(self.button_panel,
                 width=700,
                 height=300,
                 padx=5,
                 pady=5,
                 sticky=tkinter.NSEW)

        # create the scrolled text widget for logging output
        self.text_log_widget = ScrolledText(self)  # TODO: other configuration?
        self.add(self.text_log_widget,
                 width=700,
                 height=400,
                 padx=5,
                 pady=5,
                 sticky=tkinter.NSEW)

        # set the logging handler for the validation logger to log to our widget
        self.log_handler = TextHandler(
            self.text_log_widget)  # type: TextHandler
        self.log_handler.setFormatter(
            logging.Formatter('%(levelname)s:%(asctime)s - %(message)s',
                              '%Y-%m-%dT%H:%M:%S'))
        # attach this handler to the validation logger
        self.logger = logging.getLogger('validation')
        self.logger.setLevel('INFO')
        self.logger.addHandler(self.log_handler)

        self.set_title()

        # define menus
        self.menu_bar = tkinter.Menu()
        # file menu
        self.file_menu = tkinter.Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="Open Image",
                                   command=self.callback_select_file)
        self.file_menu.add_command(label="Open Directory",
                                   command=self.callback_select_directory)
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Save Log", command=self.save_log)
        self.file_menu.add_command(label="Exit", command=self.exit)
        # menus for informational popups
        self.metadata_menu = tkinter.Menu(self.menu_bar, tearoff=0)
        self.metadata_menu.add_command(label="Metaicon",
                                       command=self.metaicon_popup)
        self.metadata_menu.add_command(label="Metaviewer",
                                       command=self.metaviewer_popup)
        # ensure menus cascade
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)
        self.menu_bar.add_cascade(label="Metadata", menu=self.metadata_menu)

        self.master.config(menu=self.menu_bar)

        # set the callbacks for the button panel
        self.button_panel.local_fs_button.config(
            command=self.callback_local_fs)
        self.button_panel.full_fs_button.config(command=self.callback_full_fs)
        self.button_panel.sign_button.config(command=self.callback_sign)
        self.button_panel.noise_button.config(command=self.callback_noise)
        self.button_panel.geolocation_button.config(
            command=self.callback_geolocation)

        self.update_reader(reader)

    def _verify_reader(self):
        # type: () -> bool
        if self.variables.image_reader is not None:
            return True

        showinfo(
            'No complex image selected',
            message='First, select a complex image for this functionality.')
        return False

    def _get_and_log_feedback(self, title_text):
        # type: (str) -> None
        feedback = FeedbackPopup(self.master, title_text)
        feedback.root.grab_set()
        feedback.root.wait_window()
        if not feedback.use_feedback:
            return

        feedback_text = feedback.feedback_text.strip()
        if feedback_text != '':
            feedback_text += '\n'
        if feedback.acceptable:
            self.logger.info('{} acceptable\n{}'.format(
                title_text, feedback_text))
        else:
            self.logger.error('{} unacceptable\n{}'.format(
                title_text, feedback_text))

    def set_title(self):
        """
        Sets the window title.
        """

        file_name = None if self.variables.image_reader is None else self.variables.image_reader.file_name
        if file_name is None:
            the_title = "Validation Tool"
        else:
            the_title = "Image Viewer for {}".format(
                os.path.split(file_name)[1])
        self.winfo_toplevel().title(the_title)

    def exit(self):
        self.master.destroy()

    def save_log(self):
        if self.variables.image_reader is None or self.log_handler is None:
            return

        save_fname = asksaveasfilename(
            initialdir=self.variables.browse_directory,
            title="Save validation log output to location?",
            initialfile='{}.validation.txt'.format(
                os.path.splitext(self.variables.image_reader.file_name)[0]),
            filetypes=[
                create_filter_entry('Log files', '.log .txt'), all_files
            ])
        if save_fname is None or save_fname in ['', ()]:
            return
        if os.path.splitext(save_fname)[1] == '':
            save_fname += '.validation.txt'
        self.log_handler.save_to_file(save_fname)

    def perform_basic_validation(self):
        if self.variables.image_reader is None:
            return

        the_reader = self.variables.image_reader.base_reader
        if isinstance(the_reader, SICDReader):
            msg_id = 'SICD structure for file {}'.format(the_reader.file_name)
            self.logger.info('Starting validation of {}'.format(msg_id))
            # noinspection PyUnresolvedReferences
            result = check_file(the_reader.nitf_details)
            if result:
                self.logger.info('***{} appears to be valid***'.format(msg_id))
            self.logger.info('Completed validation for {}\n'.format(msg_id))
        else:
            # noinspection PyUnresolvedReferences
            the_sicds = the_reader.get_sicds_as_tuple()
            for the_index, the_sicd in enumerate(the_sicds):
                msg_id = 'SICD structure at index {}'.format(
                    the_index) if len(the_sicds) > 1 else 'SICD structure'
                self.logger.info('Starting validation of {}'.format(msg_id))
                result = the_sicd.is_valid(
                    recursive=True,
                    stack=False)  # this implicitly logs things of note
                if result:
                    self.logger.info(
                        '***{} appears to be valid***'.format(msg_id))
                self.logger.info(
                    'Completed validation for {}\n'.format(msg_id))

    def update_reader(self, the_reader, update_browse=None):
        """
        Update the reader.

        Parameters
        ----------
        the_reader : None|str|SICDTypeReader|SICDTypeCanvasImageReader
        update_browse : None|str
        """

        if the_reader is None:
            return

        if update_browse is not None:
            self.variables.browse_directory = update_browse
        elif isinstance(the_reader, str):
            self.variables.browse_directory = os.path.split(the_reader)[0]

        if isinstance(the_reader, str):
            the_reader = SICDTypeCanvasImageReader(the_reader)

        if isinstance(the_reader, SICDTypeReader):
            the_reader = SICDTypeCanvasImageReader(the_reader)

        if not isinstance(the_reader, SICDTypeCanvasImageReader):
            raise TypeError('Got unexpected input for the reader')

        # update the reader
        self.variables.image_reader = the_reader
        self.set_title()
        # refresh appropriate GUI elements
        self.my_populate_metaicon()
        self.my_populate_metaviewer()
        self.log_handler.clear()
        # perform the initial validation
        self.logger.info('Preparing validation for file {}\n'.format(
            os.path.abspath(self.variables.image_reader.file_name)))
        self.perform_basic_validation()

    def _disconnect_logging(self):
        if self.log_handler is None:
            return

        logger = logging.getLogger('validation')
        logger.removeHandler(self.log_handler)
        self.log_handler = None

    def callback_select_file(self):
        fname = askopenfilename(initialdir=self.variables.browse_directory,
                                filetypes=common_use_collection)
        if fname is None or fname in ['', ()]:
            return

        try:
            the_reader = SICDTypeCanvasImageReader(fname)
        except SarpyIOError:
            showinfo(
                'Opener not found',
                message='File {} was not successfully opened as a SICD type.'.
                format(fname))
            return
        self.update_reader(the_reader, update_browse=os.path.split(fname)[0])

    def callback_select_directory(self):
        dirname = askdirectory(initialdir=self.variables.browse_directory,
                               mustexist=True)
        if dirname is None or dirname in [(), '']:
            return

        try:
            the_reader = SICDTypeCanvasImageReader(dirname)
        except SarpyIOError:
            showinfo(
                'Opener not found',
                message=
                'Directory {} was not successfully opened as a SICD type.'.
                format(dirname))
            return
        self.update_reader(the_reader, update_browse=os.path.split(dirname)[0])

    def callback_local_fs(self):
        """
        Enable the local frequency support analysis
        """

        if not self._verify_reader():
            return

        # create a complex image reader - don't pass the same one around, so no hidden state
        reader = SICDTypeCanvasImageReader(
            self.variables.image_reader.base_reader)
        # open the frequency support tool based on this reader
        root = tkinter.Toplevel(
            self.master
        )  # create a new toplevel with its own mainloop, so it's blocking
        tool = LocalFrequencySupportTool(root, reader=reader)
        root.grab_set()
        root.wait_window()

        self._get_and_log_feedback('Local Frequency Support (DeltaKCOAPoly)')

    def callback_full_fs(self):
        """
        Enable the full image frequency analysis
        """

        if not self._verify_reader():
            return

        # create a complex image reader - don't pass the same one around, so no hidden state
        reader = SICDTypeCanvasImageReader(
            self.variables.image_reader.base_reader)
        # open the frequency support tool based on this reader
        root = tkinter.Toplevel(
            self.master
        )  # create a new toplevel with its own mainloop, so it's blocking
        tool = FullFrequencySupportTool(root, reader=reader)
        root.grab_set()
        root.wait_window()

        self._get_and_log_feedback('Full Image Frequency Support')

    def callback_sign(self):
        """
        Enable Fourier sign analysis
        """

        if not self._verify_reader():
            return

        # create a complex image reader - don't pass the same one around, so no hidden state
        reader = SICDTypeCanvasImageReader(
            self.variables.image_reader.base_reader)
        # open the aperture tool based on this reader
        root = tkinter.Toplevel(
            self.master
        )  # create a new toplevel with its own mainloop, so it's blocking
        tool = RegionSelection(root, reader=reader)
        root.grab_set()
        root.wait_window()

        self._get_and_log_feedback('Fourier Sign')

    def callback_noise(self):
        """
        Enable noise analysis
        """

        if not self._verify_reader():
            return

        # create a complex image reader - don't pass the same one around, so no hidden state
        reader = SICDTypeCanvasImageReader(
            self.variables.image_reader.base_reader)
        # open the rcs tool based on this reader
        root = tkinter.Toplevel(
        )  # create a new toplevel with its own mainloop, so it's blocking
        tool = RCSTool(root, reader=reader)
        root.grab_set()
        root.wait_window()

        self._get_and_log_feedback('Noise Value')

    def callback_geolocation(self):
        """
        Enable basic geolocation comparison
        """

        if not self._verify_reader():
            return

        # find a place to save the overlay, then produce it
        initialdir, fstem = os.path.split(
            os.path.abspath(self.variables.image_reader.file_name))
        dirname = askdirectory(initialdir=initialdir, mustexist=True)
        if dirname is None or dirname in [(), '']:
            return

        fstem_part = os.path.splitext(fstem)[0]
        kmz_file_stem = 'View-{}'.format(fstem_part)
        showinfo('KMZ creation',
                 message='This may be somewhat time consuming.\n'
                 'KMZ file(s) being created in directory {}\n'
                 'The created filename will begin with {}\n'
                 'Once the file(s) are created, review and provide feedback.'.
                 format(dirname, kmz_file_stem))
        create_kmz_view(self.variables.image_reader.base_reader,
                        dirname,
                        inc_scp=True,
                        inc_collection_wedge=True,
                        file_stem=kmz_file_stem,
                        pixel_limit=3072)
        showinfo('KMZ creation complete',
                 message='KMZ file(s) created in directory {}\n'
                 'The created filename(s) begin with {}\n'
                 'Review and provide feedback.'.format(dirname, kmz_file_stem))

        self._get_and_log_feedback('Geolocation')

    def my_populate_metaicon(self):
        """
        Populate the metaicon.
        """

        self.populate_metaicon(self.variables.image_reader)

    def my_populate_metaviewer(self):
        """
        Populate the metaviewer.
        """

        self.populate_metaviewer(self.variables.image_reader)

    def destroy(self):
        self._disconnect_logging()
        # noinspection PyBroadException
        try:
            super(ValidationTool, self).destroy()
        except Exception:
            pass