diff --git a/beat/editor/templates/plotter.jinja2 b/beat/editor/templates/plotter.jinja2 new file mode 100644 index 0000000000000000000000000000000000000000..e055a91b606e7c8fe2f50405d74386a197711dfc --- /dev/null +++ b/beat/editor/templates/plotter.jinja2 @@ -0,0 +1,36 @@ +# You may import any python packages that will be available in the environment you will run this plotter in +# Environments can change based on the experiment's settings +{% for ref, lib in uses.uses.items() %}# Library "{{ lib }}" is available under "{{ ref }}" +{% endfor %} + +# Makes sure we won't require an X11 connection +import matplotlib +matplotlib.use('Agg') + +import numpy +import itertools + +class Plotter(baselib.Plotter): +{% if uses.parameters %} + # do initial setup work with the given parameters for the plotter + def setup(self, parameters): + super(Plotter, self).setup(parameters) + # Parameters available: + {% for p_name, param in uses.parameters.items() %}# Parameter "{{ p_name }}" with type "{{ param.type }}" + {% endfor %} + # get a parameter like: + # param1_value = parameters.get('param_1', self.param1_default) + return True +{% endif %} + # this will be called each time the sync'd input has more data available to be processed + def process(self, inputs): + fig, ax = super(Plotter, self).prepare_canvas() + # apply at the beginning of this function or before returning for needed modifications + super(Plotter, self).apply_parameters(ax) + # ax.set_title(self.title, fontdict={'fontsize':self.title_fontsize}) + + # ax.set_xlabel(self.xlabel, fontdict={'fontsize':self.axis_fontsize}) + # ax.set_ylabel(self.ylabel, fontdict={'fontsize':self.axis_fontsize}) + # ax.set_xlim((self.xlim_left,self.xlim_right)) + # ax.set_ylim((self.ylim_bottom,self.ylim_top)) + return super(Plotter, self).encode_figure(fig) diff --git a/beat/editor/utils.py b/beat/editor/utils.py index 79eaef964ed8e9dc05783343101846a1810e458b..97917e8e3cb8714f71cf3459db2548ffb41b9f20 100644 --- a/beat/editor/utils.py +++ b/beat/editor/utils.py @@ -101,11 +101,33 @@ def generate_algorithm(contents): return template.render(contents=contents) +def generate_plotter(uses): + """Generates a valid BEAT plotter from our stored template + + + Parameters: + + contents (:py:class:`dict`): The plotter's JSON metadata + + + Returns: + + str: The rendered template as a string + + """ + + uses = uses or {} + template = ENV.get_template('plotter.jinja2') + return template.render(uses=uses) + + TEMPLATE_FUNCTION = dict( databases=generate_database, libraries=generate_library, algorithms=generate_algorithm, + plotters=generate_plotter, ) + """Functions for template instantiation within beat.editor""" class PythonFileAlreadyExistsError(Exception): diff --git a/conda/js/src/components/EntityTemplateGenerationButton.jsx b/conda/js/src/components/EntityTemplateGenerationButton.jsx index 954e4ad64ad40342a36545c95d5a7830bf119a74..e74ae2e6032fd467897453e7e238518d11bdb49d 100644 --- a/conda/js/src/components/EntityTemplateGenerationButton.jsx +++ b/conda/js/src/components/EntityTemplateGenerationButton.jsx @@ -11,6 +11,7 @@ import { generateDatabaseTemplate, generateAlgorithmTemplate, generateLibraryTemplate, + generatePlotterTemplate, } from '@helpers/api'; import { copyObj } from '@helpers'; import type { BeatEntity, BeatObject } from '@helpers/beat'; @@ -71,6 +72,11 @@ export default class EntityTemplateGenerationButton extends React.Component<Prop uses = copyObj(this.props.data.contents.uses); res = await generateLibraryTemplate(this.props.data.name, confirm, uses); break; + case('plotter'): + // find the used libraries and parameters + uses = copyObj(this.props.data.contents.parameters); + res = await generatePlotterTemplate(this.props.data.name, confirm, this.props.data.contents); + break; default: throw new Error(`Cannot generate template for entity "${ this.props.entity }"`); } diff --git a/conda/js/src/components/plotter/PlotterEditor.jsx b/conda/js/src/components/plotter/PlotterEditor.jsx index ec3c3c67fdb71dd88264c5d3dcd04f94176d6956..910b35865af17caee52286934452cf7f1f339ec1 100644 --- a/conda/js/src/components/plotter/PlotterEditor.jsx +++ b/conda/js/src/components/plotter/PlotterEditor.jsx @@ -98,12 +98,10 @@ export class PlotterEditor extends React.Component<Props, State> { > Save Changes (Changes are <ValidSchemaBadge entity='plotter' obj={this.props.data} />) </Button> - {/* <TemplateButton data={this.props.data} entity={'plotter'} /> - */} </div> <Form> <FormGroup tag='fieldset'> diff --git a/conda/js/src/helpers/api.js b/conda/js/src/helpers/api.js index 4fbb33a4cb85e2f65dd5d37a5af870a918948db7..d2100101da524a4f825aae152e200e742287cce3 100644 --- a/conda/js/src/helpers/api.js +++ b/conda/js/src/helpers/api.js @@ -108,3 +108,7 @@ export const generateAlgorithmTemplate = async (name: string, confirm: boolean, export const generateLibraryTemplate = async (name: string, confirm: boolean, uses: StringObject) => { return generateTemplate('libraries', {name, uses, confirm}); }; + +export const generatePlotterTemplate = async (name: string, confirm: boolean, uses: StringObject) => { + return generateTemplate('plotters', {name, uses, confirm}); +}; diff --git a/doc/install.rst b/doc/install.rst index fe2e22468f6f0753eaf4b5eec978849d2eb82cbe..4d37d5720be12983f01b56bc1723364064128225 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -108,6 +108,11 @@ Installation Steps $ conda activate beatedit $ buildout +#. Note for development mode: Add the line ``dependent-scripts = true`` then use the ``buildout`` command to ensure to generate all the executables in the ``bin/`` + folder even ``beat`` for ``beat.editor``: :: + + $ buildout + #. In ``bin/`` you should several new executables for the project. The Python setup part is done. #. Go into the root folder for the Javascript and install the dependencies via NPM: ::