Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def composite_layer_menu(self, menu, lbox: QTreeView, selected_uuids: list, *args):
"""
provide common options for RGB or other composite layers, eventually with option to go to a compositing dialog
"""
actions = {}
requests = {}
if len(selected_uuids) > 3 or \
any(self.doc[u][Info.KIND] not in [Kind.IMAGE, Kind.COMPOSITE] for u in selected_uuids):
LOG.warning('Need 3 image layers to create a composite')
return {}
def _make_rgb_composite(action, requests=requests):
request = requests.get(action, None)
if request is not None:
LOG.debug('RGB creation using {0!r:s}'.format(request))
self.didRequestRGBCreation.emit(request)
rgb_menu = QMenu("Create RGB From Selections...", menu)
for rgb in sorted(set(x[:len(selected_uuids)] for x in ['RGB', 'RBG', 'GRB', 'GBR', 'BRG', 'BGR']),
reverse=True):
# Only include the number of channels selected
rgb = rgb[:len(selected_uuids)]
action = rgb_menu.addAction(rgb)
request = dict((channel.lower(), uuid) for (channel, uuid) in zip(rgb, selected_uuids))
def get_metadata(source_path=None, source_uri=None, pug=None, **kwargs):
# yield successive levels of detail as we load
if source_uri is not None:
raise NotImplementedError("GoesRPUGImporter cannot read from URIs yet")
#
# step 1: get any additional metadata and an overview tile
#
d = {}
# nc = nc4.Dataset(source_path)
pug = pug or GoesRPUGImporter.pug_factory(source_path)
d.update(GoesRPUGImporter._basic_pug_metadata(pug))
# d[Info.DATASET_NAME] = os.path.split(source_path)[-1]
d[Info.KIND] = Kind.IMAGE
# FUTURE: this is Content metadata and not Product metadata:
d[Info.PROJ] = pug.proj4_string
# get nadir-meter-ish projection coordinate vectors to be used by proj4
y, x = pug.proj_y, pug.proj_x
d[Info.ORIGIN_X] = x[0]
d[Info.ORIGIN_Y] = y[0]
# midyi, midxi = int(y.shape[0] / 2), int(x.shape[0] / 2)
# PUG states radiance at index [0,0] extends between coordinates [0,0] to [1,1] on a quadrille
# centers of pixels are therefore at +0.5, +0.5
# for a (e.g.) H x W image this means [H/2,W/2] coordinates are image center
# for now assume all scenes are even-dimensioned (e.g. 5424x5424)
# given that coordinates are evenly spaced in angular -> nadir-meters space,
# technically this should work with any two neighbor values
# d[Info.CELL_WIDTH] = x[midxi+1] - x[midxi]
def _product_overview_content(self, session, prod: Product = None, uuid: UUID = None,
kind: Kind = Kind.IMAGE) -> Content:
if prod is None and uuid is not None:
# Get Product object
try:
prod = session.query(Product).filter(Product.uuid_str == str(uuid)).one()
except NoResultFound:
LOG.error("No product with UUID {} found".format(uuid))
return None
contents = session.query(Content).filter(Content.product_id == prod.id).order_by(Content.lod).all()
contents = [c for c in contents if c.info.get(Info.KIND, Kind.IMAGE) == kind]
return None if 0 == len(contents) else contents[0]
def set_possible_layers(self, uuid_list, do_rebuild_plot=False):
"""Given a list of layer UUIDs, set the names and UUIDs in the drop downs
"""
# make a uuid map because the mapping in a combo box doesn't work with objects
self.uuidMap = {}
# clear out the current lists
self.xDropDown.clear()
self.yDropDown.clear()
# fill up our lists of layers
for uuid in uuid_list:
layer = self.document[uuid]
layer_name = layer.get(Info.DISPLAY_NAME, "??unknown layer??")
if layer.get(Info.KIND, None) == Kind.RGB: # skip RGB layers
continue
uuid_string = str(uuid)
self.xDropDown.addItem(layer_name, uuid_string)
self.yDropDown.addItem(layer_name, uuid_string)
self.uuidMap[uuid_string] = uuid
# if possible, set the selections back to the way they were
need_rebuild = False
xIndex = self.xDropDown.findData(str(self.xSelectedUUID))
if xIndex >= 0:
# Selection didn't change
self.xDropDown.setCurrentIndex(xIndex)
elif self.xDropDown.count() > 0:
# Setting to a new layer
need_rebuild = True
self.ui.buttons.clicked.connect(self._clicked)
close_button = self.ui.buttons.button(QtWidgets.QDialogButtonBox.Close)
close_button.setAutoDefault(True)
reset_button = self.ui.buttons.button(QtWidgets.QDialogButtonBox.Reset)
reset_button.setAutoDefault(False)
self.ui.buttons.accepted.disconnect()
self.ui.buttons.rejected.disconnect()
self.ui.cmap_combobox.currentIndexChanged.connect(self._cmap_changed)
self.ui.vmin_slider.sliderReleased.connect(partial(self._slider_changed, is_max=False))
self.ui.vmax_slider.sliderReleased.connect(partial(self._slider_changed, is_max=True))
self.ui.vmin_edit.editingFinished.connect(partial(self._edit_changed, is_max=False))
self.ui.vmax_edit.editingFinished.connect(partial(self._edit_changed, is_max=True))
if layer[Info.KIND] in [Kind.CONTOUR]:
self.ui.gammaSpinBox.setDisabled(True)
else:
self.ui.gammaSpinBox.valueChanged.connect(self._gamma_changed)
def family_for_product_or_layer(self, uuid_or_layer):
if isinstance(uuid_or_layer, UUID):
with self._workspace.metadatabase as s:
fam = s.query(Product.family).filter_by(uuid_str=str(uuid_or_layer)).first()
if fam:
return fam[0]
uuid_or_layer = self[uuid_or_layer]
if Info.FAMILY in uuid_or_layer:
LOG.debug('using pre-existing family {}'.format(uuid_or_layer[Info.FAMILY]))
return uuid_or_layer[Info.FAMILY]
# kind:pointofreference:measurement:wavelength
kind = uuid_or_layer[Info.KIND]
refpoint = 'unknown' # FUTURE: geo/leo
measurement = uuid_or_layer.get(Info.STANDARD_NAME)
if uuid_or_layer.get('recipe'):
# RGB
subcat = uuid_or_layer['recipe'].name
elif uuid_or_layer.get(Info.CENTRAL_WAVELENGTH):
# basic band
subcat = uuid_or_layer[Info.CENTRAL_WAVELENGTH]
else:
# higher level product or algebraic layer
subcat = uuid_or_layer[Info.DATASET_NAME]
return "{}:{}:{}:{}".format(kind.name, refpoint, measurement, subcat)
def kind(self):
"""
which kind of layer it is - RGB, Algebraic, etc. This can also be tested by the class of the layer typically.
We may deprecate this eventually?
:return:
"""
return self[Info.KIND]
from collections import ChainMap
# FUTURE deprecate this
if isinstance(dsi_or_uuid, str):
uuid = UUID(dsi_or_uuid)
elif not isinstance(dsi_or_uuid, UUID):
uuid = dsi_or_uuid[Info.UUID]
else:
uuid = dsi_or_uuid
with self._inventory as s:
# look up the product for that uuid
prod = self._product_with_uuid(s, uuid)
if not prod: # then it hasn't had its metadata scraped
LOG.error('no info available for UUID {}'.format(dsi_or_uuid))
LOG.error("known products: {}".format(repr(self._all_product_uuids())))
return None
kind = prod.info[Info.KIND]
native_content = self._product_native_content(s, prod=prod, kind=kind)
if native_content is not None:
# FUTURE: this is especially saddening; upgrade to finer grained query and/or deprecate .get_info
# once upon a time...
# our old model was that product == content and shares a UUID with the layer
# if content is available, we want to provide native content metadata along with the product metadata
# specifically a lot of client code assumes that resource == product == content and
# that singular navigation (e.g. cell_size) is norm
assert (native_content.info[Info.CELL_WIDTH] is not None) # FIXME DEBUG
return frozendict(ChainMap(native_content.info, prod.info))
# mapping semantics for database fields, as well as key-value fields;
# flatten to one namespace and read-only
return frozendict(prod.info)
def _get_shared_color_limits(self, shared_info: defaultdict, layer_info: DocBasicLayer, this_prez: Presentation):
new_clims = ""
if this_prez is not None:
new_clims = np.array(this_prez.climits)
unit_info = self.document[this_prez.uuid][Info.UNIT_CONVERSION]
new_clims = unit_info[1](new_clims, inverse=False)
try:
if layer_info[Info.KIND] in [Kind.IMAGE, Kind.COMPOSITE, Kind.CONTOUR]:
min_str = layer_info[Info.UNIT_CONVERSION][2](new_clims[0], include_units=False)
max_str = layer_info[Info.UNIT_CONVERSION][2](new_clims[1])
new_clims = '{} ~ {}'.format(min_str, max_str)
elif layer_info[Info.KIND] in [Kind.RGB]:
# FUTURE: Other layer types
deps = (layer_info.r, layer_info.g, layer_info.b)
tmp_clims = []
for i, dep in enumerate(deps):
if dep is None:
tmp_clims.append('N/A')
continue
min_str = dep[Info.UNIT_CONVERSION][2](new_clims[i][0], include_units=False)
max_str = dep[Info.UNIT_CONVERSION][2](new_clims[i][1])
tmp_clims.append('{} ~ {}'.format(min_str, max_str))
def __init__(self, doc, recipe, info, *args, **kwargs):
self.layers = [None, None, None, None] # RGBA upstream layers
self.mins = [None, None, None, None] # RGBA minimum value from upstream layers
self.maxs = [None, None, None, None] # RGBA maximum value from upstream layers
self.recipe = recipe
info.setdefault(Info.KIND, Kind.RGB)
super().__init__(doc, info, *args, **kwargs)