diff --git a/docs/source/shape_editor_install.rst b/docs/source/shape_editor_install.rst index 232278cb..b568ddf5 100644 --- a/docs/source/shape_editor_install.rst +++ b/docs/source/shape_editor_install.rst @@ -87,6 +87,7 @@ https://blfauger.gitlabpages.inria.fr/nice/install.html. cp Makefile.TEMPLATE Makefile make -j make nice_imas_inv_muscle3 + make nice_imas_dir_muscle3 -If this was successful, you should find the program ``nice_imas_inv_muscle3`` in the -``nice/run`` folder. +If this was successful, you should find the programs ``nice_imas_inv_muscle3`` and +``nice_imas_dir_muscle3`` in the ``nice/run`` folder. diff --git a/waveform_editor/gui/shape_editor.py b/waveform_editor/gui/shape_editor.py index e7b6228f..20001580 100644 --- a/waveform_editor/gui/shape_editor.py +++ b/waveform_editor/gui/shape_editor.py @@ -1,4 +1,5 @@ import importlib.resources +import logging import xml.etree.ElementTree as ET import imas @@ -14,6 +15,8 @@ from waveform_editor.shape_editor.plasma_properties import PlasmaProperties from waveform_editor.shape_editor.plasma_shape import PlasmaShape +logger = logging.getLogger(__name__) + def _reactive_title(title, is_valid): return title if is_valid else f"{title} ⚠️" @@ -37,40 +40,52 @@ def __init__(self): self.plasma_properties = PlasmaProperties() self.coil_currents = CoilCurrents() self.nice_plotter = NicePlotter( - self.communicator, self.plasma_shape, self.plasma_properties + communicator=self.communicator, + plasma_shape=self.plasma_shape, + plasma_properties=self.plasma_properties, ) self.nice_settings = settings.nice - self.xml_params = ET.fromstring( + self.xml_params_inv = ET.fromstring( + importlib.resources.files("waveform_editor.shape_editor.xml_param") + .joinpath("inverse_param.xml") + .read_text() + ) + self.xml_params_dir = ET.fromstring( importlib.resources.files("waveform_editor.shape_editor.xml_param") - .joinpath("param.xml") + .joinpath("direct_param.xml") .read_text() ) # UI Configuration button_start = pn.widgets.Button(name="Run", on_click=self.submit) button_start.disabled = ( - self.plasma_shape.param.has_shape.rx.not_() + ( + self.plasma_shape.param.has_shape.rx.not_() + & self.nice_settings.param.is_inverse_mode.rx() + ) | self.plasma_properties.param.has_properties.rx.not_() - | param.rx(self.nice_settings.required_params_filled).rx.not_() + | self.nice_settings.param.are_required_filled.rx.not_() ) button_stop = pn.widgets.Button(name="Stop", on_click=self.stop_nice) - buttons = pn.Row(button_start, button_stop) + nice_mode_radio = pn.widgets.RadioBoxGroup.from_param( + self.nice_settings.param.mode, inline=True, margin=(15, 20, 0, 20) + ) + buttons = pn.Row(button_start, button_stop, nice_mode_radio) # Accordion does not allow dynamic titles, so use separate card for each option options = pn.Column( self._create_card( self.nice_settings.panel, "NICE Configuration", - is_valid=param.rx(self.nice_settings.required_params_filled), - ), - self._create_card( - pn.Param(self.nice_plotter, show_name=False), "Plotting Parameters" + is_valid=self.nice_settings.param.are_required_filled.rx(), ), + self._create_card(self.nice_plotter, "Plotting Parameters"), self._create_card( self.plasma_shape, "Plasma Shape", is_valid=self.plasma_shape.param.has_shape, + visible=self.nice_settings.param.is_inverse_mode.rx(), ), self._create_card( pn.Column(self.plasma_properties, self.nice_plotter.profiles_pane), @@ -91,7 +106,7 @@ def __init__(self): ), ) - def _create_card(self, panel_object, title, is_valid=None): + def _create_card(self, panel_object, title, is_valid=None, visible=True): """Create a collapsed card containing a panel object and a title. Args: @@ -99,6 +114,7 @@ def _create_card(self, panel_object, title, is_valid=None): title: The title to give the card. is_valid: If supplied, binds the card title to update reactively using `_reactive_title`. + visible: Whether the card is visible. """ if is_valid: title = param.bind(_reactive_title, title=title, is_valid=is_valid) @@ -107,6 +123,7 @@ def _create_card(self, panel_object, title, is_valid=None): title=title, sizing_mode="stretch_width", collapsed=True, + visible=visible, ) return card @@ -169,9 +186,10 @@ def _create_equilibrium(self): equilibrium.time_slice.resize(1) equilibrium.vacuum_toroidal_field.b0.resize(1) - # Fill plasma shape - equilibrium.time_slice[0].boundary.outline.r = self.plasma_shape.outline_r - equilibrium.time_slice[0].boundary.outline.z = self.plasma_shape.outline_z + # Only fill plasma shape for NICE inverse mode + if self.nice_settings.is_inverse_mode: + equilibrium.time_slice[0].boundary.outline.r = self.plasma_shape.outline_r + equilibrium.time_slice[0].boundary.outline.z = self.plasma_shape.outline_z # Fill plasma properties equilibrium.vacuum_toroidal_field.r0 = self.plasma_properties.r0 @@ -194,14 +212,21 @@ async def submit(self, event=None): description IDSs and an input equilibrium IDS.""" self.coil_currents.fill_pf_active(self.pf_active) + if self.nice_settings.is_direct_mode: + xml_params = self.xml_params_dir + else: + xml_params = self.xml_params_inv + self.coil_currents.update_fixed_coils_in_xml(xml_params) + # Update XML parameters: - self.coil_currents.update_fixed_coils_in_xml(self.xml_params) - self.xml_params.find("verbose").text = str(self.nice_settings.verbose) + xml_params.find("verbose").text = str(self.nice_settings.verbose) equilibrium = self._create_equilibrium() if not self.communicator.running: - await self.communicator.run() + await self.communicator.run( + is_direct_mode=self.nice_settings.is_direct_mode + ) await self.communicator.submit( - ET.tostring(self.xml_params, encoding="unicode"), + ET.tostring(xml_params, encoding="unicode"), equilibrium.serialize(), self.pf_active.serialize(), self.pf_passive.serialize(), @@ -210,7 +235,9 @@ async def submit(self, event=None): ) self.coil_currents.sync_ui_with_pf_active(self.communicator.pf_active) - async def stop_nice(self, event): + @param.depends("nice_settings.mode", watch=True) + async def stop_nice(self, event=None): + logger.info("Stopping NICE...") await self.communicator.close() def __panel__(self): diff --git a/waveform_editor/settings.py b/waveform_editor/settings.py index ab09f606..ce030efa 100644 --- a/waveform_editor/settings.py +++ b/waveform_editor/settings.py @@ -16,17 +16,23 @@ class NiceSettings(param.Parameterized): - REQUIRED = ( - "executable", + INVERSE_MODE = "NICE Inverse" + DIRECT_MODE = "NICE Direct" + + BASE_REQUIRED = ( "md_pf_active", "md_pf_passive", "md_wall", "md_iron_core", ) - executable = param.String( - label="NICE executable path", + inv_executable = param.String( + label="NICE inverse executable path", doc="Path to NICE inverse IMAS MUSCLE3 executable", ) + dir_executable = param.String( + label="NICE direct executable path", + doc="Path to NICE direct IMAS MUSCLE3 executable", + ) environment = param.Dict( default={}, label="NICE environment variables", @@ -37,10 +43,32 @@ class NiceSettings(param.Parameterized): md_wall = param.String(label="'wall' machine description URI") md_iron_core = param.String(label="'iron_core' machine description URI") verbose = param.Integer(label="NICE verbosity (set to 1 for more verbose output)") + mode = param.Selector( + objects=[INVERSE_MODE, DIRECT_MODE], default=INVERSE_MODE, precedence=-1 + ) + are_required_filled = param.Boolean(precedence=-1) + is_direct_mode = param.Boolean(precedence=-1) + is_inverse_mode = param.Boolean(precedence=-1) + + @param.depends("mode", watch=True, on_init=True) + def set_mode_flags(self): + self.is_direct_mode = self.mode == self.DIRECT_MODE + self.is_inverse_mode = self.mode == self.INVERSE_MODE + + @param.depends( + *BASE_REQUIRED, "inv_executable", "dir_executable", "mode", watch=True + ) + def check_required_params_filled(self): + base_ready = all(getattr(self, p) for p in self.BASE_REQUIRED) - @param.depends(*REQUIRED) - def required_params_filled(self): - return all(getattr(self, required) for required in self.REQUIRED) + if not base_ready: + self.are_required_filled = False + return + + if self.mode == self.INVERSE_MODE: + self.are_required_filled = bool(self.inv_executable) + else: + self.are_required_filled = bool(self.dir_executable) def apply_settings(self, params): """Update parameters from a dictionary, skipping unknown keys.""" @@ -51,24 +79,33 @@ def apply_settings(self, params): self.param.update(**params) def to_dict(self): - """Returns a dictionary representation of current parameter values.""" - return {p: getattr(self, p) for p in self.param if p != "name"} + """Returns a dictionary representation of current parameter values, excluding + params with a precendence of -1.""" + result = {} + for p in self.param: + param_obj = self.param[p] + if p != "name" and param_obj.precedence != -1: + result[p] = getattr(self, p) + return result def panel(self): items = [] for p in self.param: if p == "name": - pass - elif p in self.REQUIRED: - items.append( - pn.Row( - pn.Param(self.param[p], show_name=False), - WarningIndicator(visible=self.param[p].rx.not_()), - ) - ) - else: - items.append(pn.Param(self.param[p], show_name=False)) + continue + + # Add warning indicator if required parameter is not filled + is_inv_required = p == "inv_executable" and self.is_inverse_mode + is_dir_required = p == "dir_executable" and self.is_direct_mode + is_base_required = p in self.BASE_REQUIRED + + row_content = [pn.Param(self.param[p], show_name=False)] + if is_inv_required or is_dir_required or is_base_required: + warning = WarningIndicator(visible=self.param[p].rx.not_()) + row_content.append(warning) + + items.append(pn.Row(*row_content)) return pn.Column(*items) diff --git a/waveform_editor/shape_editor/coil_currents.py b/waveform_editor/shape_editor/coil_currents.py index d561b3e5..0f009d14 100644 --- a/waveform_editor/shape_editor/coil_currents.py +++ b/waveform_editor/shape_editor/coil_currents.py @@ -5,14 +5,17 @@ import param from panel.viewable import Viewer +from waveform_editor.settings import settings + class CoilCurrents(Viewer): coil_ui = param.List( doc="List of tuples containing the checkboxes and sliders for the coil currents" ) - def __init__(self): - super().__init__() + def __init__(self, **params): + super().__init__(**params) + self.nice_settings = settings.nice self.sliders_ui = pn.Column(visible=self.param.coil_ui.rx.bool()) guide_message = pn.pane.Markdown( "_To fix a coil to a specific current, enable the checkbox and provide " @@ -44,13 +47,15 @@ def create_ui(self, pf_active): new_coil_ui = [] for coil in pf_active.coil: coil_current = coil.current - checkbox = pn.widgets.Checkbox(value=False, margin=(30, 10, 10, 10)) + checkbox = pn.widgets.Checkbox( + margin=(30, 10, 10, 10), + disabled=self.nice_settings.param.is_direct_mode, + ) slider = pn.widgets.EditableFloatSlider( name=f"{coil.name} Current [{coil_current.metadata.units}]", value=coil_current.data[0] if coil_current.data.has_value else 0.0, start=-5e4, end=5e4, - disabled=checkbox.param.value.rx.not_(), format="0", width=450, ) @@ -67,9 +72,8 @@ def fill_pf_active(self, pf_active): pf_active: pf_active IDS to update the coil currents for. """ for i, coil_ui in enumerate(self.coil_ui): - checkbox, slider = coil_ui.objects - if checkbox.value: - pf_active.coil[i].current.data = np.array([slider.value]) + _, slider = coil_ui.objects + pf_active.coil[i].current.data = np.array([slider.value]) def sync_ui_with_pf_active(self, pf_active): """Synchronize UI sliders with the current values from the pf_active IDS. diff --git a/waveform_editor/shape_editor/nice_integration.py b/waveform_editor/shape_editor/nice_integration.py index f117171c..d4345ce8 100644 --- a/waveform_editor/shape_editor/nice_integration.py +++ b/waveform_editor/shape_editor/nice_integration.py @@ -1,4 +1,4 @@ -"""Module that enables running the NICE inverse equilibrium solver through MUSCLE3.""" +"""Module that enables running the NICE equilibrium solver through MUSCLE3.""" import asyncio import multiprocessing @@ -18,7 +18,8 @@ from waveform_editor.settings import settings -_muscle3_configuration = """ +# YMMSL configuration for NICE inverse mode +_muscle3_inv_configuration = """ ymmsl_version: v0.1 model: name: shape_editor @@ -42,9 +43,33 @@ nice_inv.xml_path: {xml_path} """ +# YMMSL configuration for NICE direct mode +_muscle3_dir_configuration = """ +ymmsl_version: v0.1 +model: + name: shape_editor + components: + shape_editor: + implementation: shape_editor + nice_dir: + implementation: nice_dir + + conduits: + shape_editor.equilibrium_out: nice_dir.equilibrium_in + shape_editor.pf_passive_out: nice_dir.pf_passive_in + shape_editor.pf_active_out: nice_dir.pf_active_in + shape_editor.iron_core_out: nice_dir.iron_core_in + shape_editor.wall_out: nice_dir.wall_in + nice_dir.equilibrium_out: shape_editor.equilibrium_in + +settings: + muscle_profile_level: none # Disable profiling + nice_dir.xml_path: {xml_path} +""" + class NiceIntegration(param.Parameterized): - """Main API for running NICE, submitting inverse problems and getting the resulting + """Main API for running NICE, submitting problems and getting the resulting equilibrium back. """ @@ -118,7 +143,7 @@ async def close(self): self.closing = self.running = False self._update_state() - async def run(self): + async def run(self, is_direct_mode=False): """Start NICE and the controlling processes.""" if self.running: raise RuntimeError("Already running!") @@ -130,7 +155,7 @@ async def run(self): self.manager_pipe, pipe = multiprocessing.Pipe() self.manager = multiprocessing.Process( target=run_muscle_manager, - args=[pipe, self.xml_config_file.name], + args=[pipe, self.xml_config_file.name, is_direct_mode], name="MUSCLE Manager", ) self.manager.start() @@ -140,7 +165,7 @@ async def run(self): self.communicator_pipe, pipe = multiprocessing.Pipe() self.communicator = multiprocessing.Process( target=run_muscle3_communicator, - args=[manager_location, pipe], + args=[manager_location, pipe, is_direct_mode], name="NICE Communicator", ) self.communicator.start() @@ -148,15 +173,22 @@ async def run(self): # NICE nice_env = os.environ.copy() nice_env.update(settings.nice.environment) - nice_env["MUSCLE_INSTANCE"] = "nice_inv" nice_env["MUSCLE_MANAGER"] = manager_location - self.terminal.write(f"{os.getcwd()}$ {settings.nice.executable}\n") + if is_direct_mode: + executable = settings.nice.dir_executable + nice_env["MUSCLE_INSTANCE"] = "nice_dir" + else: + executable = settings.nice.inv_executable + nice_env["MUSCLE_INSTANCE"] = "nice_inv" + + self.terminal.write(f"{os.getcwd()}$ {executable}\n") + loop = asyncio.get_running_loop() try: self.nice_transport, self.nice_protocol = await loop.subprocess_exec( self.create_communicator_protocol, - settings.nice.executable, + executable, env=nice_env, stdin=subprocess.DEVNULL, ) @@ -267,6 +299,7 @@ def pipe_data_received(self, fd, data): def run_muscle3_communicator( server_location: str, pipe: multiprocessing.connection.Connection, + is_direct_mode: bool, ): """Run MUSCLE3 actor for communicating with NICE.""" os.environ["MUSCLE_INSTANCE"] = "shape_editor" @@ -280,8 +313,11 @@ def run_muscle3_communicator( "wall_out", "iron_core_out", ], - Operator.S: ["equilibrium_in", "pf_active_in"], + Operator.S: ["equilibrium_in"], } + if not is_direct_mode: + ports[Operator.S].append("pf_active_in") + instance = Instance(ports) while instance.reuse_instance(): @@ -299,13 +335,19 @@ def run_muscle3_communicator( # Wait for nice to process eq = instance.receive("equilibrium_in").data - pfa = instance.receive("pf_active_in").data + if not is_direct_mode: + pfa = instance.receive("pf_active_in").data pipe.send((eq, pfa)) -def run_muscle_manager(pipe: multiprocessing.connection.Connection, xml_path: str): - """Run the muscle_manager""" - config = ymmsl.load(_muscle3_configuration.format(xml_path=xml_path)) +def run_muscle_manager( + pipe: multiprocessing.connection.Connection, xml_path: str, is_direct_mode: bool +): + """Run the muscle_manager with a given configuration.""" + config_str = ( + _muscle3_dir_configuration if is_direct_mode else _muscle3_inv_configuration + ) + config = ymmsl.load(config_str.format(xml_path=xml_path)) manager = Manager(config) server_location = manager.get_server_location() pipe.send(server_location) diff --git a/waveform_editor/shape_editor/nice_plotter.py b/waveform_editor/shape_editor/nice_plotter.py index d96caaec..f9f2b021 100644 --- a/waveform_editor/shape_editor/nice_plotter.py +++ b/waveform_editor/shape_editor/nice_plotter.py @@ -8,7 +8,9 @@ import param import scipy from imas.ids_toplevel import IDSToplevel +from panel.viewable import Viewer +from waveform_editor.settings import NiceSettings, settings from waveform_editor.shape_editor.nice_integration import NiceIntegration from waveform_editor.shape_editor.plasma_properties import PlasmaProperties from waveform_editor.shape_editor.plasma_shape import PlasmaShape @@ -17,13 +19,14 @@ logger = logging.getLogger(__name__) -class NicePlotter(param.Parameterized): +class NicePlotter(Viewer): # Input data, use negative precedence to hide from the UI communicator = param.ClassSelector(class_=NiceIntegration, precedence=-1) wall = param.ClassSelector(class_=IDSToplevel, precedence=-1) pf_active = param.ClassSelector(class_=IDSToplevel, precedence=-1) plasma_shape = param.ClassSelector(class_=PlasmaShape, precedence=-1) plasma_properties = param.ClassSelector(class_=PlasmaProperties, precedence=-1) + nice_settings = param.ClassSelector(class_=NiceSettings, precedence=-1) # Plot parameters show_contour = param.Boolean(default=True, label="Show contour lines") @@ -45,13 +48,8 @@ class NicePlotter(param.Parameterized): PROFILE_WIDTH = 350 PROFILE_HEIGHT = 350 - def __init__(self, communicator, plasma_shape, plasma_properties, **params): - super().__init__( - **params, - communicator=communicator, - plasma_shape=plasma_shape, - plasma_properties=plasma_properties, - ) + def __init__(self, **params): + super().__init__(**params) self.DEFAULT_OPTS = hv.opts.Overlay( xlim=(0, 13), ylim=(-10, 10), @@ -59,6 +57,7 @@ def __init__(self, communicator, plasma_shape, plasma_properties, **params): xlabel="r [m]", ylabel="z [m]", ) + self.nice_settings = settings.nice self.CONTOUR_OPTS = hv.opts.Contours( cmap="viridis", colorbar=True, @@ -90,6 +89,15 @@ def __init__(self, communicator, plasma_shape, plasma_properties, **params): self.profiles_pane = pn.pane.HoloViews( profiles_plot, width=self.PROFILE_WIDTH, height=self.PROFILE_HEIGHT ) + self.panel_layout = pn.Param( + self.param, + show_name=False, + widgets={ + "show_desired_shape": { + "visible": self.nice_settings.param.is_inverse_mode + } + }, + ) @pn.depends("plasma_properties.profile_updated") def _plot_profiles(self): @@ -124,9 +132,15 @@ def _plot_profiles(self): hv.opts.Overlay(title="Plasma Profiles"), hv.opts.Curve(framewise=True) ) - @pn.depends("plasma_shape.shape_updated", "show_desired_shape") + @pn.depends( + "plasma_shape.shape_updated", "show_desired_shape", "nice_settings.mode" + ) def _plot_plasma_shape(self): - if not self.show_desired_shape or not self.plasma_shape.has_shape: + if ( + self.nice_settings.is_direct_mode + or not self.show_desired_shape + or not self.plasma_shape.has_shape + ): return hv.Overlay([hv.Curve([]).opts(self.DESIRED_SHAPE_OPTS)]) r = self.plasma_shape.outline_r @@ -388,3 +402,6 @@ def _plot_xo_points(self): hover_tooltips=[("", "X-point")], ) return o_scatter * x_scatter + + def __panel__(self): + return self.panel_layout diff --git a/waveform_editor/shape_editor/xml_param/direct_param.xml b/waveform_editor/shape_editor/xml_param/direct_param.xml new file mode 100644 index 00000000..2bb5615d --- /dev/null +++ b/waveform_editor/shape_editor/xml_param/direct_param.xml @@ -0,0 +1,262 @@ + + + + 1 + + 0 + 0 + 11 + 2 + 0 + 0 + 1 + 0 + 2 + 1 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 1 + 40 + 1.0e-10 + 2 + 0 + 20 + 1.0e-10 + 40 + 1.0e-10 + 50 + 1.0e-10 + 1 + 2.25 + 6.2 + 0.0 + 0 + 1 + 4 + 4.45 5.39 5.78 4.70 + -3.5 -3.86 -3.20 -2.81 + 5.1 + -3.3 + 0.0005 + 0 + 4 + 2.44 1.91 1.94 2.44 + 0.79 0.573 0.49 0.66 + 2.18 + 0.6 + 0.00003 + 1 + 10 + 6.0 6.2 6.2 6.4 6.6 6.6 6.4 6.4 6.2 6.0 + 0.2 0.2 0.4 0.2 0.2 1.0 1.0 0.8 1.0 1.0 + 6.1 + 0.3 + 0.0005 + 0.002 + 0.04 + 0.01 + 0.005 + 0.005 + 0.005 + 0.005 + 1 + 17 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 17 + 17 + 50 + 0 + 6.2 + + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 2 0.6 1.4 + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 2 0.4 1.4 + 1 + + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 1e20 + 4 + 3 1 0 1 + + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 25 + 1 1.5 0 1 + + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 + 1.0e12 + 0.0e10 + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 + 1.0e12 + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 + 1.0e12 + 1.0e3 1.0e3 1.0e0 1.0e12 1.0e0 + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 0.0e20 + 0.0e0 + + 0.1 + 1e-3 + 0.01 + 0 + 0 + 0 + 0 + 0.01 + 0.01 + 0 + 0 + 0 + 0 + 0 + + 0.01 + 0 + 1e18 + 0.1 + 0 + 0 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + + 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 + + + 0.195 + 2.42e-20 + 5.23e-19 + 0.001 + 0.1 + 0 + 0 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + + 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 + 0.001 + 0.1 + 0 + 0 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + + + 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 + + + 1 1 1 + + 1.0e3 + 0.1 + 0 + 0 + 0 + 0 + + 0.001 + 0.1 + 0 + 25 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 + 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 0 + + 13 + + + 3.88 4.00 5.55 7.36 8.0 8.45 8.66 8.44 7.62 5.80 4.87 4.18 3.88 + -2.53 -3.92 -4.65 -2.45 -1.4 -0.47 0.66 1.65 3.21 4.65 4.85 4.39 3.58 + 0.05 + 0 + 0.15 + 0.15 + 0.05 + 1 + 0 + 8 + 0 1 2 3 4 5 6 7 + 7 + 1 2 3 4 5 6 7 + 8 + 0 1 2 3 4 5 6 7 + 7 + 1 2 3 4 5 6 7 + 1 + 0.05 + 3 + 0.1 + 1.0e-6 + 1.0e-3 + 1 + 60 + 1 + + 0 + 1.9 + 6.2 + 0.545 + 1.8 + 0.43 + 5.089 + -3.346 + 96 + 0 + + 3e7 + 0 + 14 + 0 1 2 2 3 4 5 6 7 8 9 10 11 12 + 13 + 0 1 2 4 5 6 7 8 9 10 11 12 13 + 2 + 11 12 + 0 + 0 1 2 3 4 5 6 7 8 9 10 + + + 2 + 6 + 0 0.2 0.4 0.6 0.8 1 + 1.0 + 1.0e-3 + 0.0e12 + 0.0e12 + 1.0e-3 + + 0 + 5 + + 0 + 2 + 10 + 1 + 20 +
1.0e-3
+ + 101 +
diff --git a/waveform_editor/shape_editor/xml_param/inverse_param.xml b/waveform_editor/shape_editor/xml_param/inverse_param.xml new file mode 100644 index 00000000..864f91a5 --- /dev/null +++ b/waveform_editor/shape_editor/xml_param/inverse_param.xml @@ -0,0 +1,267 @@ + + + + 1 + + 0 + 0 + 31 + 2 + 0 + 0 + 1 + 0 + 2 + 1 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 1 + 40 + 1.0e-10 + 2 + 0 + 20 + 1.0e-10 + 40 + 1.0e-10 + 50 + 1.0e-10 + 1 + 2.25 + 6.2 + 0.0 + 0 + 1 + 4 + 4.45 5.39 5.78 4.70 + -3.5 -3.86 -3.20 -2.81 + 5.1 + -3.3 + 0.0005 + 0 + 4 + 2.44 1.91 1.94 2.44 + 0.79 0.573 0.49 0.66 + 2.18 + 0.6 + 0.00003 + 1 + 10 + 6.0 6.2 6.2 6.4 6.6 6.6 6.4 6.4 6.2 6.0 + 0.2 0.2 0.4 0.2 0.2 1.0 1.0 0.8 1.0 1.0 + 6.1 + 0.3 + 0.0005 + 0.002 + 0.04 + 0.01 + 0.005 + 0.005 + 0.005 + 0.005 + 1 + 17 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 17 + 17 + 1 + 50 + 0 + 6.2 + + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 2 0.6 1.4 + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 2 0.4 1.4 + 1 + + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 1e20 + 4 + 3 1 0 1 + + 0 + 11 + 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 + 25 + 1 1.5 0 1 + + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 + 1.0e12 + 0.0e10 + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 + 1.0e12 + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 + 1.0e12 + 1.0e3 1.0e3 1.0e0 1.0e12 1.0e0 + 1.0e-1 + 1 1 1 1 1 1 1 1 1 1 1 1 + 0.0e20 + 0.0e0 + + 0.1 + 1e-3 + 0.01 + 0 + 0 + 0 + 0 + 0.01 + 0.01 + 0 + 0 + 0 + 0 + 0 + + 0.01 + 0 + 1e18 + 0.1 + 0 + 0 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + + 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 + + + 0.195 + 2.42e-20 + 5.23e-19 + 0.001 + 0.1 + 0 + 0 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + + 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 + 0.001 + 0.1 + 0 + 0 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + + + 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 + + + 1 1 1 + + 1.0e3 + 0.1 + 0 + 0 + 0 + 0 + + 0.001 + 0.1 + 0 + 25 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 + 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 0 + + 13 + + + 3.88 4.00 5.55 7.36 8.0 8.45 8.66 8.44 7.62 5.80 4.87 4.18 3.88 + -2.53 -3.92 -4.65 -2.45 -1.4 -0.47 0.66 1.65 3.21 4.65 4.85 4.39 3.58 + 0.05 + 0 + 0.15 + 0.15 + 0.05 + 1 + 0 + 8 + 0 1 2 3 4 5 6 7 + 7 + 1 2 3 4 5 6 7 + 8 + 0 1 2 3 4 5 6 7 + 7 + 1 2 3 4 5 6 7 + 1 + 0.05 + 3 + 0.1 + 1.0e-6 + 1.0e-3 + 1 + 60 + 1 + + 0 + 1.9 + 6.2 + 0.545 + 1.8 + 0.43 + 5.089 + -3.346 + 96 + 0 + + + + + 3e5 + 0 + 14 + 0 1 2 2 3 4 5 6 7 8 9 10 11 12 + 13 + 0 1 2 4 5 6 7 8 9 10 11 12 13 + + 2 + 11 12 + 0 + 0 1 2 3 4 5 6 7 8 9 10 + + + 2 + 6 + 0 0.2 0.4 0.6 0.8 1 + 1.0 + 1.0e-3 + 0.0e12 + 0.0e12 + 1.0e-3 + + 0 + 5 + + 0 + 2 + 10 + 1 + 20 +
1.0e-3
+ + 101 +
diff --git a/waveform_editor/shape_editor/xml_param/param.xml b/waveform_editor/shape_editor/xml_param/param.xml deleted file mode 100644 index d8a25eb8..00000000 --- a/waveform_editor/shape_editor/xml_param/param.xml +++ /dev/null @@ -1,323 +0,0 @@ - - - - 1 - 0 - 0 - 31 - 2 - 0 - 0 - 1 - 0 - 2 - 1 - 0 - 0 - 0 - 0 - 1 - 1 - 0 - 1 - 40 - 1.0e-10 - 2 - 0 - 20 - 1.0e-10 - 40 - 1.0e-10 - 50 - 1.0e-10 - 1 - 2.25 - 6.2 - 0.0 - - 0 - - 1 - 4 - 4.45 5.39 5.78 4.70 - -3.5 -3.86 -3.20 -2.81 - 5.1 - -3.3 - 0.0005 - - 0 - 4 - 2.44 1.91 1.94 2.44 - 0.79 0.573 0.49 0.66 - 2.18 - 0.6 - 0.00003 - - 1 - 10 - 6.0 6.2 6.2 6.4 6.6 6.6 6.4 6.4 6.2 6.0 - 0.2 0.2 0.4 0.2 0.2 1.0 1.0 0.8 1.0 1.0 - 6.1 - 0.3 - 0.0005 - - 0.002 - 0.04 - 0.01 - 0.005 - 0.005 - 0.005 - 0.005 - - 1 - 17 - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - 17 - 17 - - 1 - - 50 - 0 - - 6.2 - - - 0 - 11 - 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 - 2 0.6 1.4 - - 0 - 11 - 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 - 2 0.4 1.4 - - 1 - - - 0 - 11 - 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 - 1e20 - 4 - 3 1 0 1 - - - 0 - 11 - 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 - 25 - 1 1.5 0 1 - - - - 1.0e-1 - 1 1 1 1 1 1 1 1 1 1 1 - 1.0e12 - 0.0e10 - - 1.0e-1 - 1 1 1 1 1 1 1 1 1 1 1 - 1.0e12 - - 1.0e-1 - 1 1 1 1 1 1 1 1 1 1 1 - 1.0e12 - 1.0e3 1.0e3 1.0e0 1.0e12 1.0e0 - - 1.0e-1 - 1 1 1 1 1 1 1 1 1 1 1 1 - 0.0e20 - 0.0e0 - - - 0.1 - - 1e-3 - 0.01 - 0 - 0 - 0 - 0 - - 0.01 - 0.01 - 0 - 0 - 0 - 0 - 0 - - - - 0.01 - 0 - - 1e18 - 0.1 - 0 - 0 - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - - 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 - - - - 0.195 - 2.42e-20 - 5.23e-19 - - 0.001 - 0.1 - 0 - 0 - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - - 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 - - 0.001 - 0.1 - 0 - 0 - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - - - 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 - - - 1 1 1 - - - 1.0e3 - 0.1 - 0 - 0 - 0 - 0 - - - 0.001 - 0.1 - 0 - 25 - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 0 - - - - - 13 - - - 3.88 4.00 5.55 7.36 8.0 8.45 8.66 8.44 7.62 5.80 4.87 4.18 3.88 - -2.53 -3.92 -4.65 -2.45 -1.4 -0.47 0.66 1.65 3.21 4.65 4.85 4.39 3.58 - - 0.05 - 0 - - 0.15 - 0.15 - 0.05 - - 1 - - 0 - 8 - 0 1 2 3 4 5 6 7 - 7 - 1 2 3 4 5 6 7 - 8 - 0 1 2 3 4 5 6 7 - 7 - 1 2 3 4 5 6 7 - 1 - 0.05 - - 3 - 0.1 - 1.0e-6 - 1.0e-3 - - 1 - 60 - 1 - - - 0 - 1.9 - 6.2 - 0.545 - 1.8 - 0.43 - 5.089 - -3.346 - 96 - - 0 - - - - - - 3e5 - 0 - 14 - 0 1 2 2 3 4 5 6 7 8 9 10 11 12 - 13 - 0 1 2 4 5 6 7 8 9 10 11 12 13 - - - 2 - 11 12 - - 0 - 0 1 2 3 4 5 6 7 8 9 10 - - - - - - 2 - 6 - 0 0.2 0.4 0.6 0.8 1 - - 1.0 - 1.0e-3 - 0.0e12 - 0.0e12 - 1.0e-3 - - - 0 - 5 - - - 0 - - 2 - 10 - 1 - 20 - -
1.0e-3
- - - 101 - -
-