class DirectTile(StrictHasTraits, object): name = traitlets.Bytes() urltemplate = traitlets.Bytes() opacity = traitlets.CFloat(max=1.0, min=0.0, default_value=1.0) @property def storage_key(self): return self.name @ndb.tasklet def render_async(self, tile): tile_url = self.urltemplate.format(**tile) context = ndb.get_context() result = yield context.urlfetch(tile_url) if result.status_code != 200: logging.error("error fetching: %r result: %s", tile_url, result) raise ValueError("error fetching: %r result: %s" % (tile_url, result)) raise ndb.Return( Image.open(io.BytesIO(result.content)).convert("RGBA")) def render(self, tile): tile_url = self.urltemplate.format(**tile) result = requests.get(tile_url) if result.status_code != 200: logging.error("error fetching: %r result: %s", tile_url, result) raise ValueError("error fetching: %r result: %s" % (tile_url, result)) return Image.open(io.BytesIO(result.content)).convert("RGBA")
class VariableMeshModel(ipywidgets.Widget): _model_name = traitlets.Unicode("VariableMeshModel").tag(sync=True) _model_module = traitlets.Unicode("@yt-project/yt-widgets").tag(sync=True) _model_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) px = traitlets.Bytes(allow_none=False).tag(sync=True, **bytes_serialization) py = traitlets.Bytes(allow_none=False).tag(sync=True, **bytes_serialization) pdx = traitlets.Bytes(allow_none=False).tag(sync=True, **bytes_serialization) pdy = traitlets.Bytes(allow_none=False).tag(sync=True, **bytes_serialization) data_source = traitlets.Any(allow_none=True).tag(sync=False) field_values = traitlets.List( trait=traitlets.Instance(FieldArrayModel)).tag(sync=True, **widget_serialization) @property def _px(self): return np.frombuffer(self.px, dtype="f8") @property def _py(self): return np.frombuffer(self.py, dtype="f8") @property def _pdx(self): return np.frombuffer(self.pdx, dtype="f8") @property def _pdy(self): return np.frombuffer(self.pdy, dtype="f8") def add_field(self, field_name): if (any(_.field_name == field_name for _ in self.field_values) or self.data_source is None): return v = self.data_source[field_name] new_field = FieldArrayModel(field_name=field_name, array=v.tobytes()) new_field_values = self.field_values + [new_field] # Do an update of the trait! self.field_values = new_field_values mi, ma = v.min(), v.max() return mi, ma
class HexViewerModel(ipywidgets.DOMWidget): _model_name = traitlets.Unicode('HexViewerModel').tag(sync=True) _model_module = traitlets.Unicode('jupyterlab_kaitai').tag(sync=True) _model_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) _view_name = traitlets.Unicode('HexViewerView').tag(sync=True) _view_module = traitlets.Unicode('jupyterlab_kaitai').tag(sync=True) _view_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) buffer = traitlets.Bytes(allow_none=False).tag(sync=True, **bytes_serialization)
class FieldArrayModel(ipywidgets.Widget): _model_name = traitlets.Unicode("FieldArrayModel").tag(sync=True) _model_module = traitlets.Unicode("@yt-project/yt-widgets").tag(sync=True) _model_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) field_name = traitlets.Unicode("").tag(sync=True) array = traitlets.Bytes(allow_none=False).tag(sync=True, **bytes_serialization) @property def _array(self): return np.frombuffer(self.array, dtype="f8")
class HexViewer(ipywidgets.DOMWidget): _model_name = traitlets.Unicode("HexViewerModel").tag(sync=True) _model_module = traitlets.Unicode("jupyterlab_kaitai").tag(sync=True) _model_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) _view_name = traitlets.Unicode("HexViewerView").tag(sync=True) _view_module = traitlets.Unicode("jupyterlab_kaitai").tag(sync=True) _view_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) buffer = traitlets.Bytes(allow_none=False).tag(sync=True, **bytes_serialization) selectionStart = traitlets.CInt().tag(sync=True) selectionEnd = traitlets.CInt().tag(sync=True) def __init__(self, buffer=None, *args, **kwargs): kwargs["buffer"] = buffer if buffer is not None else b"" super().__init__(*args, **kwargs)
class ImageOutput(Output): """Output an image in RAM Attributes ---------- format : TYPE Description image : TYPE Description vmax : TYPE Description vmin : TYPE Description """ format = tl.CaselessStrEnum(values=['png'], default_value='png').tag(attr=True) mode = tl.Unicode(default_value="image").tag(attr=True) vmin = tl.CFloat(allow_none=True, default_value=np.nan).tag(attr=True) vmax = tl.CFloat(allow_none=True, default_value=np.nan).tag(attr=True) image = tl.Bytes(allow_none=True, default_value=None) def __init__(self, node, name, format=None, mode=None, vmin=None, vmax=None): kwargs = {} if format is not None: kwargs['format'] = format if mode is not None: kwargs['mode'] = mode if vmin is not None: kwargs['vmin'] = vmin if vmax is not None: kwargs['vmax'] = vmax super(ImageOutput, self).__init__(node=node, name=name, **kwargs) # TODO: docstring? def write(self, output, coordinates): self.image = get_image(output, format=self.format, vmin=self.vmin, vmax=self.vmax)
class VideoStream(MediaStream): """Represents a media source by a video.""" _model_name = Unicode('VideoStreamModel').tag(sync=True) url = Unicode('https://webrtc.github.io/samples/src/video/chrome.mp4').tag( sync=True) data = traitlets.Bytes( None, allow_none=True, help="The image data as a byte string.").tag(sync=True) play = traitlets.Bool(True).tag(sync=True) loop = traitlets.Bool(True).tag(sync=True) filename = traitlets.Unicode( help="The image filename (will set the .data property)") @traitlets.observe('filename') def _propagate_filename(self, change): with open(change.new, 'rb') as f: self.data = f.read()
class FileUploadWidget(ipywidgets.DOMWidget): '''File Upload Widget. This widget provides file upload using `FileReader`. ''' _view_name = traitlets.Unicode('FileUploadView').tag(sync=True) _view_module = traitlets.Unicode('fileupload').tag(sync=True) label = traitlets.Unicode(help='Label on button.').tag(sync=True) filename = traitlets.Unicode(help='Filename of `data`.').tag(sync=True) data_base64 = traitlets.Unicode(help='File content, base64 encoded.').tag( sync=True) data = traitlets.Bytes(help='File content.') def __init__(self, label="Browse", *args, **kwargs): super(FileUploadWidget, self).__init__(*args, **kwargs) self._dom_classes += ('widget_item', 'btn-group') self.label = label def _data_base64_changed(self, *args): self.data = base64.b64decode(self.data_base64.split(',', 1)[1])
class SelectableImageWidget(ipywidgets.DOMWidget, traitlets.HasTraits): # Metadata _view_name = traitlets.Unicode('SelectableImageView').tag(sync=True) _model_name = traitlets.Unicode('SelectableImageModel').tag(sync=True) _view_module = traitlets.Unicode('xdswidgets').tag(sync=True) _model_module = traitlets.Unicode('xdswidgets').tag(sync=True) _view_module_version = traitlets.Unicode('^0.1.0').tag(sync=True) _model_module_version = traitlets.Unicode('^0.1.0').tag(sync=True) # Model img_bytes = traitlets.Bytes(help="Image data bytes").tag(sync=True) img_fmt = traitlets.Unicode('null').tag(sync=True) select_rects = traitlets.Bool(True).tag(sync=True) # If True, selected_rects = traitlets.List([]).tag(sync=True) last_click_xy = traitlets.List([]).tag(sync=True) last_click_xy_1 = traitlets.List([]).tag( sync=True) # Lags last_click_xy by 1 # Python backend only #js_loaded = False def __init__(self): super(ipywidgets.DOMWidget, self).__init__() self._mouse_move_callback_dispatcher = ipywidgets.CallbackDispatcher() #if not SelectableImageWidget.js_loaded: # SelectableImageWidget.load_js() # SelectableImageWidget.js_loaded = True self.on_msg(self._handle_msg_sub) #@classmethod #def load_js(cls): # fname = pkg_resources.resource_filename(__name__,'dist/xds-bluenose-widget.js') # js = open(fname).read() # IPython.core.display.display(IPython.core.display.Javascript(data=js)) def on_mouse_move(self, callback, remove=False): self._mouse_move_callback_dispatcher.register_callback(callback, remove=remove) def _handle_msg_sub(this, widget, content, buffers): # content = {'event': 'mousedown', 'x': 365, 'y': 28} if content['event'] == 'mousemove': this._mouse_move_callback_dispatcher(content) def set_to_np_cmap(self, np_2darr, colormap_name="jet", normalize=True): amin, amax = np.min(np_2darr), np.max(np_2darr) np_2darr = (np_2darr - amin) / max(.001, (amax - amin)) cm = plt.get_cmap(colormap_name) XYrgb = cm(np_2darr) r = XYrgb[:, :, 0] g = XYrgb[:, :, 1] b = XYrgb[:, :, 2] self.set_to_np_rgb(r, g, b, normalize=False) def set_to_np_rgb(this, r_2darr, g_2darr, b_2darr, normalize=False): """ [rgb]_2darr should be normalized s.t. the elements in [0,1]. Only one is required non-None. """ shapes = [ arr.shape for arr in (r_2darr, g_2darr, b_2darr) if arr is not None ] h = shapes[0][0] w = shapes[0][1] np_rgb = [ arr if arr is not None else np.zeros((h, w)) for arr in (r_2darr, g_2darr, b_2darr) ] np.seterr(divide='ignore', invalid='ignore') if normalize: np_rgb = [arr / np.max(arr) for arr in np_rgb] pil_rgb = [ PIL.Image.fromarray((arr * 255).astype('uint8')) for arr in np_rgb ] pil_im = PIL.Image.merge('RGB', pil_rgb) imPngBytesIO = io.BytesIO() pil_im.save(imPngBytesIO, format='png') imPngBytes = imPngBytesIO.getvalue() this.img_bytes = imPngBytes this.img_fmt = 'png' imPngBytes = imPngBytesIO.getvalue()
class Widget(DOMWidget): _view_name = traitlets.Unicode('ReboundView').tag(sync=True) _view_module = traitlets.Unicode('rebound').tag(sync=True) count = traitlets.Int(0).tag(sync=True) t = traitlets.Float().tag(sync=True) N = traitlets.Int().tag(sync=True) width = traitlets.Float().tag(sync=True) height = traitlets.Float().tag(sync=True) scale = traitlets.Float().tag(sync=True) particle_data = traitlets.Bytes().tag(sync=True) orbit_data = traitlets.Bytes().tag(sync=True) orientation = traitlets.Tuple().tag(sync=True) orbits = traitlets.Int().tag(sync=True) def __init__(self, simulation, size=(200, 200), orientation=(0., 0., 0., 1.), scale=None, autorefresh=True, orbits=True): """ Initializes a Widget. Widgets provide real-time 3D interactive visualizations for REBOUND simulations within Jupyter Notebooks. To use widgets, the ipywidgets package needs to be installed and enabled in your Jupyter notebook server. Parameters ---------- size : (int, int), optional Specify the size of the widget in pixels. The default is 200 times 200 pixels. orientation : (float, float, float, float), optional Specify the initial orientation of the view. The four floats correspond to the x, y, z, and w components of a quaternion. The quaternion will be normalized. scale : float, optional Set the initial scale of the view. If not set, the widget will determine the scale automatically based on current particle positions. autorefresh : bool, optional The default value if True. The view is updated whenever a particle is added, removed and every 100th of a second while a simulation is running. If set to False, then the user needs to manually call the refresh() function on the widget. This might be useful if performance is an issue. orbits : bool, optional The default value for this is True and the widget will draw the instantaneous orbits of the particles. For simulations in which particles are not on Keplerian orbits, the orbits shown will not be accurate. """ self.width, self.height = size self.t, self.N = simulation.t, simulation.N self.orientation = orientation self.autorefresh = autorefresh self.orbits = orbits self.simp = pointer(simulation) clibrebound.reb_display_copy_data.restype = c_int if scale is None: self.scale = simulation.display_data.contents.scale else: self.scale = scale self.count += 1 super(Widget, self).__init__() def refresh(self, simp=None, isauto=0): """ Manually refreshes a widget. Note that this function can also be called using the wrapper function of the Simulation object: sim.refreshWidgets(). """ if simp == None: simp = self.simp if self.autorefresh == 0 and isauto == 1: return sim = simp.contents size_changed = clibrebound.reb_display_copy_data(simp) clibrebound.reb_display_prepare_data(simp, c_int(self.orbits)) if sim.N > 0: self.particle_data = (c_char * (4 * 7 * sim.N)).from_address( sim.display_data.contents.particle_data).raw if self.orbits: self.orbit_data = ( c_char * (4 * 9 * (sim.N - 1))).from_address( sim.display_data.contents.orbit_data).raw if size_changed: #TODO: Implement better GPU size change pass self.N = sim.N self.t = sim.t self.count += 1 @staticmethod def getClientCode(): return shader_code + js_code