Commit 1e65711f authored by Andrea Lorenzon's avatar Andrea Lorenzon 💬
Browse files

type annotation

parent 14149183
import sys
import os
from typing import *
from flask import Flask
import settings
from h5ceric import extractDatabase, plot_dispatcher
from h5decorators import nocache
import flask
sys.path.insert(0,'./modules')
sys.path.insert(0, './modules')
if not os.path.exists("./data"):
try:
......@@ -14,17 +20,14 @@ if not os.path.exists("./data"):
print("Could not find nor create data directory: ", e)
from flask import Flask
import settings
from h5ceric import extractDatabase, plot_dispatcher
from h5decorators import nocache
deploymentType = settings.deploy
app = Flask(__name__)
########################## helper function ##################
def splitURL(path):
def splitURL(path: str) -> Tuple[str, str]:
"""helper function to split a flask path
This helper function accept as input a string, in the format "<fileName>,dataset=<datasetName>",
......@@ -43,7 +46,7 @@ def splitURL(path):
############################# homepage ###########################
@app.route('/')
@nocache
def hello():
def hello() -> Any:
""" main flask web page renderer
Called when accessing the root URL of the website, in returns the index.html page, populating it.
......@@ -55,7 +58,7 @@ def hello():
print("deployment type: ", settings.deploy)
from jsTreeCeric import JSON_from_folder
folderDictionary = JSON_from_folder(settings.fileFolder[deploymentType])
print("folder dict : ", folderDictionary)
# print("folder dict : ", folderDictionary)
import json
folderTree = json.dumps(folderDictionary)
......@@ -67,7 +70,7 @@ def hello():
########################### hdf5 tree ############################
@app.route('/openhdf5/<path:path>')
@nocache
def openhdf5(path):
def openhdf5(path: str) -> str:
""" Route to access hdf5 file content
Opens a hdf5 file, get a dictionary of groups and datasets, converts it in
......@@ -86,7 +89,7 @@ def openhdf5(path):
######################### bokeh visualization ######################
@app.route('/visualize/')
@nocache
def send_js():
def send_js() -> Any:
"""plots a hdf5 dataset
:return: plot the dataset with Bokeh, and renders the template template.html with the plot
......@@ -129,7 +132,7 @@ def send_js():
######################### get file info ######################
@app.route('/file_info/<path:path>')
@nocache
def file_info(path):
def file_info(path: str) -> flask.Response:
"""
return mimetype and URL of a file
:param path: file path
......@@ -152,7 +155,7 @@ def file_info(path):
######################### read file content ######################
@app.route('/get_file/<path:path>')
@nocache
def get_file(path):
def get_file(path: str) -> Any:
"""
return an header with correct mime_type and file content.
......@@ -175,7 +178,7 @@ def get_file(path):
######################### read file content ######################
@app.route('/display_report/')
def display_report():
def display_report() -> str:
"""
receiving a request with all the elements to be visualized, compiles the HTML of
the report
......@@ -205,7 +208,7 @@ def display_report():
# get type of item["dataset"] in item["filename"]
if filename.split(".")[-1] in ["nxs", "h5", "hdf5", "nexus"]:
with h5py.File(settings.fileFolder[deploymentType]+"/"+filename,'r') as f:
with h5py.File(settings.fileFolder[deploymentType] + "/" + filename, 'r') as f:
# dispatch plotting javascript
if len(f[item['dataset']].shape) == 0:
......@@ -216,32 +219,36 @@ def display_report():
html += '</ul>\n'
# if it's a 2D dataset...
elif len(f[item['dataset']].shape)==2:
elif len(f[item['dataset']].shape) == 2:
html += '<ul>\n'
html += '<li><strong>2D Dataset:</strong> '+str(item["dataset"])+'</li>\n'
html += '<li><strong>Image:</strong><br>\n<img src="'+ str(item["image"]).replace(" ", "+") + '"></li>\n'
html += '<li><strong>2D Dataset:</strong> ' + str(item["dataset"]) + '</li>\n'
html += '<li><strong>Image:</strong><br>\n<img src="' + str(item["image"]).replace(" ",
"+") + '"></li>\n'
html += '</ul>\n'
# if it's a 3D dataset, get the current slice.
elif len(f[item['dataset']].shape)==3:
elif len(f[item['dataset']].shape) == 3:
html += '<ul>\n'
html += '<li><strong>3D Dataset:</strong> '+str(item["dataset"])+'</li>\n'
html += '<li><strong>Z:</strong> '+str(item["z"])+'</li>\n'
html += '<li><strong>Image:</strong><br>\n<img src="'+str(item["image"]).replace(" ", "+") + '"></li>\n'
html += '<li><strong>3D Dataset:</strong> ' + str(item["dataset"]) + '</li>\n'
html += '<li><strong>Z:</strong> ' + str(item["z"]) + '</li>\n'
html += '<li><strong>Image:</strong><br>\n<img src="' + str(item["image"]).replace(" ",
"+") + '"></li>\n'
html += '</ul>\n'
else:
displayCode = ''
if "image" in item["mime"]:
displayCode = '<img class="img-responsive" style="height: 75vh; max-width: 100%;" src="' + item["url"]+'" >'
elif "video" in item["mime"]:
displayCode = '<video class="img-responsive" style="height: 75vh; max-width: 100%;" video-element" controls><source type="'+item['mime']+'" src="'+item['url']+'"></video>'
elif "text" in item["mime"]:
displayCode = '<iframe src="'+item["url"]+'" style="height: 75vh; max-width: 100%;">'
html += '<ul>\n'
html += displayCode
html += '</ul>\n'
displayCode = ''
if "image" in item["mime"]:
displayCode = '<img class="img-responsive" style="height: 75vh; max-width: 100%;" src="' + item[
"url"] + '" >'
elif "video" in item["mime"]:
displayCode = '<video class="img-responsive" style="height: 75vh; max-width: 100%;" video-element" controls><source type="' + \
item['mime'] + '" src="' + item['url'] + '"></video>'
elif "text" in item["mime"]:
displayCode = '<iframe src="' + item["url"] + '" style="height: 75vh; max-width: 100%;">'
html += '<ul>\n'
html += displayCode
html += '</ul>\n'
html += '</body>\n</html>\n'
# embed in html
......
__name__ = "h5ceric"
from typing import Dict, Any
import h5py
import numpy
############################ helper function: hdf5 generator from iterator ############################
def traverse_datasets(hdf_file):
def traverse_datasets(hdf_file: str):
""" Generator for hdf5 folder traversal
Yields a generator that iterates the datasets included in an hdf5 file.
......@@ -19,7 +21,7 @@ def traverse_datasets(hdf_file):
############################ debug tools: hdf5 dataset printer ############################
def list_datasets(name, prefix=''):
def list_datasets(name: str, prefix: str = '') -> Dict:
"""List all datasets in an hdf5 file
:param name: path of the file
......@@ -30,7 +32,7 @@ def list_datasets(name, prefix=''):
output = {"core": {"data": []}}
d = []
def iterate_hdf5(h5file):
def iterate_hdf5(h5file : h5py.File) -> Any:
""" hdf5 file iterator
Iterates an hdf5 file, returning a JSON formatted to be used in JSTree visualization
......@@ -67,7 +69,7 @@ def list_datasets(name, prefix=''):
############################ debug tools: hdf5 dataset string repr ############################
def dict_datasets(name: str):
def dict_datasets(name: str) -> None:
"""Prints hdf5 datasets.
Honestly, h5glance.H5Glance works better in notebooks.
......@@ -84,7 +86,7 @@ def dict_datasets(name: str):
############################ helper: hdf5 iterator ############################
def h5py_dataset_iterator(file, prefix: str = ''):
def h5py_dataset_iterator(file: h5py.File, prefix: object = '') -> object:
"""Hdf5 dataset iterator
Recursively iterates a dataset, returns an iterator over all datasets
......@@ -133,7 +135,7 @@ def extractDatabase(folder: str, filename: str, required_dataset: str):
########################### bokeh plot creation ############################
def plot_dispatcher(arr: numpy.ndarray, ds_name: str, pos=0):
def plot_dispatcher(arr: numpy.ndarray, ds_name: str, pos: int = 0):
"""Creates a bokeh plot from a numpy 1D or 2D array
If array order > 2, a 2D slice of arr[0] will be considered.
......
def plotSingleValues(arr, ds_name):
import numpy
def plotSingleValues(arr: numpy.ndarray, ds_name: str) -> dict:
"""
create a canvas with a single value (will be showed in plot title).
......@@ -10,7 +13,7 @@ def plotSingleValues(arr, ds_name):
p = figure(title=ds_name + " = " + str(arr),
toolbar_location="above",
x_range=(0,0), y_range=(0,0),
x_range=(0, 0), y_range=(0, 0),
match_aspect=True,
sizing_mode='stretch_both'
)
......@@ -20,7 +23,7 @@ def plotSingleValues(arr, ds_name):
return {"plot": p}
def plot1dBokeh(arr, ds_name):
def plot1dBokeh(arr: numpy.ndarray, ds_name: str) -> dict:
""" creates a bokeh plot from a 1D time series
creates a bokeh plot from a 1D time series
......@@ -65,7 +68,7 @@ def plot1dBokeh(arr, ds_name):
return {"plot": p}
def plot2dBokeh(arr, ds_name):
def plot2dBokeh(arr: numpy.ndarray, ds_name: str) -> dict:
""" creates a bokeh plot from a 2D figure
creates a bokeh plot from a 2D figure
......@@ -99,83 +102,85 @@ def plot2dBokeh(arr, ds_name):
return {"plot": p}
def plot2dSeries(X,Y, ds_name):
""" creates a bokeh plot from a 2D figure
creates a bokeh plot from a 2D figure
def plot2dSeries(X: numpy.ndarray, Y: numpy.ndarray, ds_name: str) -> dict:
""" creates a bokeh plot from a 2D figure
:param Y: values of the series
:param X: x axis of the serie (time?)
:param arr: 2D numpy ndarray
:param ds_name: string, plot title
:return: a bokeh figure
"""
# from bokeh.plotting import figure, gridplot
# from bokeh.models import DataRange1d
# from bokeh.models import HoverTool
#
# size_x, size_y = X.shape, Y.shape
#
# x_range = DataRange1d(range_padding=0, range_padding_units='percent')
# y_range = DataRange1d(range_padding=0, range_padding_units='percent')
#
# # generate and return bokeh plot
# p = figure(title=ds_name,
# toolbar_location="above",
# x_range=x_range, y_range=y_range,
# match_aspect=True,
# sizing_mode='stretch_both'
# )
#
# p.grid.grid_line_width = 0.2
#
# p = figure(title="Hexbin for max 5K points", match_aspect=True,
# tools="pan,wheel_zoom,box_zoom,reset,", background_fill_color='#440154')
# p.grid.visible = False
# import numpy as np
#
# nHexs = 30
# hexsize = max(np.amax(X)-np.amin(X), np.amax(Y)-np.amin(Y))/nHexs
#
# r, bins = p.hexbin(X, Y, size=hexsize, hover_color="pink", hover_alpha=0.8)
#
# p.circle(X, Y, color="white", size=1, alpha=0.2)
#
# p.add_tools(HoverTool(
# tooltips=[("count", "@c"), ("(q,r)", "(@q, @r)")],
# mode="mouse", point_policy="follow_mouse", renderers=[r]
# ))
#
# h1 = figure(title="hist1", match_aspect=True,
# tools="pan,wheel_zoom,box_zoom,reset", background_fill_color='#440154',
# x_range=x_range, y_range=y_range, plot_width=150)
#
#
# histY,edgesY= np.histogram(Y, density=True, bins=50)
# h1.grid.visible = False
# h1.quad(top=histY, bottom=0, left=edgesY[:-1], right=edgesY[1:],
# fill_color="#036564", line_color="#033649",\
# )
# q= gridplot(children=([[p,h1],[None,None]]))
#
#
# from bokeh.plotting import figure, gridplot
# from bokeh.models import DataRange1d
# from bokeh.models import HoverTool
#
# size_x, size_y = X.shape, Y.shape
#
# x_range = DataRange1d(range_padding=0, range_padding_units='percent')
# y_range = DataRange1d(range_padding=0, range_padding_units='percent')
#
# # generate and return bokeh plot
# p = figure(title=ds_name,
# toolbar_location="above",
# x_range=x_range, y_range=y_range,
# match_aspect=True,
# sizing_mode='stretch_both'
# )
#
# p.grid.grid_line_width = 0.2
#
# p = figure(title="Hexbin for max 5K points", match_aspect=True,
# tools="pan,wheel_zoom,box_zoom,reset,", background_fill_color='#440154')
# p.grid.visible = False
# import numpy as np
#
# nHexs = 30
# hexsize = max(np.amax(X)-np.amin(X), np.amax(Y)-np.amin(Y))/nHexs
#
# r, bins = p.hexbin(X, Y, size=hexsize, hover_color="pink", hover_alpha=0.8)
#
# p.circle(X, Y, color="white", size=1, alpha=0.2)
#
# p.add_tools(HoverTool(
# tooltips=[("count", "@c"), ("(q,r)", "(@q, @r)")],
# mode="mouse", point_policy="follow_mouse", renderers=[r]
# ))
#
# h1 = figure(title="hist1", match_aspect=True,
# tools="pan,wheel_zoom,box_zoom,reset", background_fill_color='#440154',
# x_range=x_range, y_range=y_range, plot_width=150)
#
#
# histY,edgesY= np.histogram(Y, density=True, bins=50)
# h1.grid.visible = False
# h1.quad(top=histY, bottom=0, left=edgesY[:-1], right=edgesY[1:],
# fill_color="#036564", line_color="#033649",\
# )
# q= gridplot(children=([[p,h1],[None,None]]))
#
#
import holoviews as hv
hv.extension('bokeh')
import numpy as np
arr = np.stack((X,Y),axis=0).T
arr = np.stack((X, Y), axis=0).T
points = hv.Points(arr)
points = points.hist(num_bins=51, dimension=['x', 'y'])
print(type(points.right))
points.main.opts(width=500,height=500, size=0.8)
print(dir(points.top))
# print(type(points.right))
points.main.opts(width=500, height=500, size=0.8)
# print(dir(points.top))
return {"plot": hv.render(points, backend='bokeh')}
def plot3dBokeh(arr, ds_name, y):
def plot3dBokeh(arr: numpy.ndarray, ds_name:str, y: int) -> dict:
""" creates a bokeh plot from a 3D matrix
creates a bokeh plot from a 3D matrix
:param y: slice position
:param arr: 3D numpy ndarray
:param ds_name: string, plot title
:return: a bokeh figure
......@@ -188,7 +193,7 @@ def plot3dBokeh(arr, ds_name, y):
size_x, size_y, size_z = arr.shape
from numpy import rot90
arr = rot90(arr, 3, (0,2))
arr = rot90(arr, 3, (0, 2))
if y > 0:
slice_y = y
......@@ -199,7 +204,6 @@ def plot3dBokeh(arr, ds_name, y):
x_range = DataRange1d(range_padding=0, range_padding_units='percent')
y_range = DataRange1d(range_padding=0, range_padding_units='percent')
# generate and return bokeh plot
from bokeh.plotting import figure
p = figure(title=ds_name,
......@@ -232,7 +236,7 @@ def plot3dBokeh(arr, ds_name, y):
)
from bokeh.models import Slider
z_slider = Slider(start=0, end=size_y-1, value=slice_y, step=1, title="Z")
z_slider = Slider(start=0, end=size_y - 1, value=slice_y, step=1, title="Z")
from bokeh.models import CustomJS
callback = CustomJS(args=dict(slider=z_slider),
......@@ -245,4 +249,3 @@ def plot3dBokeh(arr, ds_name, y):
p.add_layout(color_bar, 'right')
return {"plot": p, "slider": z_slider}
from functools import reduce
from typing import List
def JSON_from_folder(rootDir):
def JSON_from_folder(rootDir: str) -> List[dict]:
""" Creates jsTree JSON from file path
From a given path, returns a JSON of its subfolders and files, ready as input for jsTree
......@@ -24,7 +26,7 @@ def JSON_from_folder(rootDir):
return DictToJsTree(d[settings.fileFolderName[settings.deploy]])
def DictToJsTree(dic):
def DictToJsTree(dic : dict) -> List[dict]:
""" converts a dictionary in the expected output for JSTree:
documentation: https://www.jstree.com/docs/json/
......
import os
# deploy type ["local", "VUO", "K8S"]
deploy = "K8S"
deploy = "local"
# paths
fileFolderPath = {"local" : os.getenv('H5NUVOLA_PATH', "/home/andrea/PycharmProjects/"),
"VUO" : "/",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment