def test_load_partial(self): # Test loading of partial files. mpath = os.path.join(DIR_DATA, 'beeler-1977-model.mmt') ppath = os.path.join(DIR_DATA, 'beeler-1977-protocol.mmt') spath = os.path.join(DIR_DATA, 'beeler-1977-script.mmt') m, p, x = myokit.load(mpath) self.assertIsInstance(m, myokit.Model) self.assertIsNone(p) self.assertIsNone(x) m, p, x = myokit.load(ppath) self.assertIsNone(m) self.assertIsInstance(p, myokit.Protocol) self.assertIsNone(x) m, p, x = myokit.load(spath) self.assertIsNone(m) self.assertIsNone(p) self.assertTrue(isinstance(x, basestring)) self.assertRaises(myokit.SectionNotFoundError, myokit.load_model, ppath) self.assertRaises(myokit.SectionNotFoundError, myokit.load_model, spath) self.assertRaises(myokit.SectionNotFoundError, myokit.load_protocol, mpath) self.assertRaises(myokit.SectionNotFoundError, myokit.load_protocol, spath) self.assertRaises(myokit.SectionNotFoundError, myokit.load_script, mpath) self.assertRaises(myokit.SectionNotFoundError, myokit.load_script, ppath)
def test_simulate(self): """Tests whether the simulate method works as expected. Tests implicitly also whether the _set_parameters method works properly. """ # Test Case I: Linear Growth Model # define parameters and times parameters = [1, 2] times = np.arange(25) # expected # init model in myokit model, protocol, _ = myokit.load(self.file_linear_growth_model) # set inital state of model model.set_state([parameters[0]]) # set linear growth constant model.set_value('central_compartment.lambda', parameters[1]) # instantiate and run simulation simulation = myokit.Simulation(model, protocol) myokit_result = simulation.run(duration=times[-1] + 1, log=['central_compartment.drug'], log_times=times) expected_result = myokit_result.get('central_compartment.drug') # assert that Model.simulate returns the same result. model_result = self.linear_model.simulate(parameters, times) assert np.array_equal(expected_result, model_result) # Test case II: One Compartment Model (checks whether access of # correct output works) # define parameters and times parameters = [0, 2, 4] times = np.arange(25) # expected # init model in myokit model, protocol, _ = myokit.load(self.file_one_comp_model) # set inital state of model model.set_state([parameters[0]]) # set clearance and volume model.set_value('central_compartment.CL', parameters[1]) model.set_value('central_compartment.V', parameters[2]) # instantiate and run simulation simulation = myokit.Simulation(model, protocol) state_name = 'central_compartment.drug_concentration' myokit_result = simulation.run(duration=times[-1] + 1, log=[state_name], log_times=times) expected_result = myokit_result.get(state_name) # assert that Model.simulate returns the same result. model_result = self.one_comp_model.simulate(parameters, times) assert np.array_equal(expected_result, model_result)
def set_state(self): m, p, x = myokit.load(os.path.join(myotest.DIR_DATA, 'lr-1991.mmt')) n = 4 s = myokit.Simulation1d(m, p, n) sm = m.state() ss = [s.state(x) for x in xrange(n)] for si in ss: self.assertEqual(sm, si) # Test setting a single, global state sx = [0] * 8 self.assertNotEqual(sm, sx) s.set_state(sx) for i in xrange(n): self.assertEqual(sx, s.state(i)) self.assertEqual(sx * n, s.state()) s.set_state(sm) self.assertEqual(sm * n, s.state()) # Test setting a single state j = 1 s.set_state(sx, j) for i in xrange(n): if i == j: self.assertEqual(s.state(i), sx) else: self.assertEqual(s.state(i), sm)
def run_simple(self): # Load model m = os.path.join(myotest.DIR_DATA, 'lr-1991.mmt') m, p, x = myokit.load(m) # Run a simple simulation c = myokit.JacobianCalculator(m) x, f, j, e = c.newton_root(damping=0.01, max_iter=50)
def test_set_state_1d(self): # Test the set_state method in 1d m, p, _ = myokit.load('example') n = 10 s = myokit.SimulationOpenCL(m, p, n) sm = m.state() ss = [s.state(x) for x in range(n)] for si in ss: self.assertEqual(sm, si) # Test setting a single, global state sx = [0.0] * 8 self.assertNotEqual(sm, sx) s.set_state(sx) for i in range(n): self.assertEqual(sx, s.state(i)) self.assertEqual(sx * n, s.state()) s.set_state(sm) self.assertEqual(sm * n, s.state()) # Test setting a single state j = 1 s.set_state(sx, j) for i in range(n): if i == j: self.assertEqual(s.state(i), sx) else: self.assertEqual(s.state(i), sm)
def test_set_constant(self): # Test :meth:`PSimulation.set_constant()` and # :meth:`PSimulation.set_parameters()` m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) with WarningCollector() as c: s = myokit.PSimulation(m, p, variables=['membrane.V'], parameters=['ina.gNa']) s.set_constant('ica.gCa', 1) s.set_constant(m.get('ica.gCa'), 1) # Variable is not a literal self.assertRaisesRegex(ValueError, 'literal', s.set_constant, 'membrane.V', 1) # Variable is in parameters list self.assertRaisesRegex(ValueError, 'parameter', s.set_constant, 'ina.gNa', 1) # Set parameter values s.set_parameters([1]) self.assertRaisesRegex(ValueError, '1 values', s.set_parameters, [1, 2]) s.set_parameters({'ina.gNa': 1}) s.set_parameters({m.get('ina.gNa'): 1}) self.assertRaisesRegex(ValueError, 'Unknown', s.set_parameters, {'bert': 2}) self.assertRaisesRegex(ValueError, 'parameter', s.set_parameters, {'ica.gCa': 2})
def test_progress_reporter(self): # Test running with a progress reporter. m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) with WarningCollector() as c: s = myokit.PSimulation(m, p, variables=['membrane.V'], parameters=['ina.gNa']) with myokit.tools.capture() as c: s.run(2, progress=myokit.ProgressPrinter()) c = c.text().splitlines() self.assertEqual(len(c), 2) self.assertEqual( c[0], '[0.0 minutes] 50.0 % done, estimated 0 seconds remaining') self.assertEqual( c[1], '[0.0 minutes] 100.0 % done, estimated 0 seconds remaining') # Not a progress reporter self.assertRaisesRegex(ValueError, 'ProgressReporter', s.run, 1, progress=12) # Cancel from reporter self.assertRaises(myokit.SimulationCancelledError, s.run, 1, progress=CancellingReporter(0))
def setUpClass(cls): # Test simulation creation. m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) cls.model = m cls.protocol = p cls.sim = myokit.LegacySimulation(cls.model, cls.protocol)
def test_current_arrows(self): # Test the current arrows plot. # Select matplotlib backend that doesn't require a screen import matplotlib matplotlib.use('template') import matplotlib.pyplot as plt # Run simulation, get currents m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) # Add dummy current, that never carries much charge and should be # ignored c = m.add_component('dummy') x = c.add_variable('IDummy') x.set_rhs('0 * membrane.V') s = myokit.Simulation(m, p) currents = ['ina.INa', 'ik1.IK1', 'ica.ICa', 'dummy.IDummy'] d = s.run(600, log=['engine.time', 'membrane.V'] + currents) fig = plt.figure() plots.current_arrows(d, 'membrane.V', currents) plt.close(fig) plt.show() # Massive peak at final point d = d.npview() d['dummy.IDummy'][-1] = 100 fig = plt.figure() plots.current_arrows(d, 'membrane.V', currents) plt.close(fig) plt.show()
def test_pickling(self): # Test pickling a simulation # Test with myokit.Protocol m, p, _ = myokit.load('example') s1 = myokit.LegacySimulation(m, p) s1.pre(123) s_bytes = pickle.dumps(s1) s2 = pickle.loads(s_bytes) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state()) self.assertEqual(s1.default_state(), s2.default_state()) s1.run(123, log=myokit.LOG_NONE) s2.run(123, log=myokit.LOG_NONE) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state()) # Test simulation properties s1.set_tolerance(1e-8, 1e-8) s1.set_min_step_size(1e-2) s1.set_max_step_size(0.1) s2 = pickle.loads(pickle.dumps(s1)) s1.run(23, log=myokit.LOG_NONE) s2.run(23, log=myokit.LOG_NONE) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state()) # Test changed constants s1.set_constant('membrane.C', 1.1) s2 = pickle.loads(pickle.dumps(s1)) s1.run(17, log=myokit.LOG_NONE) s2.run(17, log=myokit.LOG_NONE) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state())
def __init__(self, mmtfile: str) -> None: """Initialises the model class. Arguments: mmtfile {str} -- Path to the mmtfile defining the model and the protocol. """ # load model and protocol model, protocol, _ = myokit.load(mmtfile) # get dose events from protocol self.mmt_dose_events = self._get_mmt_dose_events(protocol) # get state, parameter and output names self.state_names = [state.qname() for state in model.states()] self.state_dimension = model.count_states() self.output_names = [] self.output_dimension = None self.parameter_names = self._get_parameter_names(model) self.number_parameters_to_fit = model.count_variables(inter=False, bound=False ) # instantiate the simulation self.simulation = myokit.Simulation(model, protocol) self.model = model
def test_simulate(self): """Tests whether the simulate method works as expected. Tests implicitly also whether the _set_parameters method works properly. """ # Test case I: 1-compartment model parameters = [0, 2, 4] # different from initialised parameters times = np.arange(25) # expected model, protocol, _ = myokit.load(self.file_name) model.set_state([parameters[0]]) model.set_value('central_compartment.CL', parameters[1]) model.set_value('central_compartment.V', parameters[2]) simulation = myokit.Simulation(model, protocol) myokit_result = simulation.run( duration=times[-1] + 1, log=['central_compartment.drug_concentration'], log_times=times) expected_result = myokit_result.get( 'central_compartment.drug_concentration') # assert that Model.simulate returns the same result. model_result = self.one_comp_model.simulate(parameters, times) assert np.array_equal(expected_result, model_result)
def setUpClass(self): """ Test simulation creation. """ m, p, x = myokit.load(os.path.join(myotest.DIR_DATA, 'lr-1991.mmt')) self.model = m self.protocol = p self.sim = myokit.Simulation(self.model, self.protocol)
def test_myokit_import(): """Test that Myokit can be loaded. Uses the Myokit builtin example. """ m, p, x = myokit.load('example') s = myokit.Simulation(m, p) assert isinstance(s, myokit.Simulation) assert True
def test_periodic(self): # Test periodic logging. m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) with WarningCollector(): s = myokit.PSimulation( m, p, variables=['membrane.V'], parameters=['ina.gNa']) # Set tolerance for equality testing emax = 1e-2 # Time steps for logging are approximate # Test 1: Simple 5 ms simulation, log_interval 0.5 ms d, e = s.run(5, log=['engine.time'], log_interval=0.5) d = d.npview() t = d['engine.time'] q = np.arange(0, 5, 0.5) if debug: print(t) print(q) print('- ' * 10) self.assertEqual(len(t), len(q)) self.assertTrue(np.max(np.abs(t - q)) < emax) # Test 2: Very short simulation s.reset() d, e = s.run(1, log=['engine.time'], log_interval=0.5) d = d.npview() t = d['engine.time'] q = np.arange(0, 1, 0.5) if debug: print(t) print(q) print('- ' * 10) self.assertEqual(len(t), len(q)) self.assertTrue(np.max(np.abs(t - q)) < emax) # Test 3: Stop and start a simulation s.reset() d, e = s.run(1, log=['engine.time'], log_interval=0.5) d, e = s.run(2, log=d, log_interval=0.5) d, e = s.run(2, log=d, log_interval=0.5) d = d.npview() t = d['engine.time'] q = np.arange(0, 5, 0.5) if debug: print(t) print(q) print('- ' * 10) self.assertEqual(len(t), len(q)) self.assertTrue(np.max(np.abs(t - q)) < emax) # Negative or 0 log interval --> Log every step s.set_step_size(0.01) d, dp = s.run(1, log_interval=0) self.assertEqual(len(d.time()), 101) d, dp = s.run(1, log_interval=-1) self.assertEqual(len(d.time()), 101)
def test_timeout_progress_reporter(self): m, p, x = myokit.load('example') s = myokit.Simulation(m, p) t = myokit.Timeout(0.1) with self.assertRaises(myokit.SimulationCancelledError): s.run(100000, progress=t) t = myokit.Timeout(3600) s.run(100, progress=t)
def run_simple(self): # Load model m = os.path.join(myotest.DIR_DATA, 'lr-1991.mmt') m, p, x = myokit.load(m) # Run a tiny simulation s = myokit.PSimulation(m, p, variables=['membrane.V'], parameters=['ina.gNa', 'ica.gCa']) s.set_step_size(0.002) d, dp = s.run(10, log_interval=2)
def simulation(name='plain'): # Load model and protocol m, p, _ = myokit.load('example') sens = ( ('ina.m', 'dot(ina.m)', 'ina.INa'), ('ina.gNa', 'init(ina.m)') ) if name == 'plain': s = myokit.Simulation(m, p) def c(): s.run(100) elif name == 'sens': s = myokit.Simulation(m, p, sens) def c(): s.run(100) elif name == 'realtime': # Realtime tracking # Note: This doesn't show much: Python re-uses strings etc. so can # delete some decrefs without seeing it here! v = m.get('engine').add_variable('realtime') v.set_rhs(0) v.set_binding('realtime') s = myokit.Simulation(m, p) def c(): s.run(100) elif name == 'apd': # APD measuring # Note: Can remove some decrefs without seeing results here... s = myokit.Simulation(m, p) def c(): s.run(1000, apd_variable='membrane.V', apd_threshold=-1) elif name == 'log_times': # Point-list logging s = myokit.Simulation(m, p, sens) def c(): s.reset() s.run(1000, log_times=[0, 100, 500]) else: raise ValueError(f'Unknown test: simulation {name}') print(f'Testing simulation: {name}') test(c)
def run_simple(self): # Load model m = os.path.join(myotest.DIR_DATA, 'lr-1991.mmt') m, p, x = myokit.load(m) # Run a simulation s = myokit.ICSimulation(m, p) d, e = s.run(20, log_interval=5) # Create a datablock from the simulation log b = s.block(d, e) del (d, e) # Calculate eigenvalues b.eigenvalues('derivatives')
def test(self): """ Test the export functions for this exporter type. """ # Load model, protocol m, p, x = myokit.load('example') # Get exporter e = formats.exporter(self._exporter) # Ok? Then update class name for nice error message (!) self.__class__.__name__ = 'ExportTest' + e.__class__.__name__ # Create empty output directory as subdirectory of DIR_OUT path = os.path.join(myotest.DIR_OUT, self._exporter) if os.path.exists(path): shutil.rmtree(path) os.makedirs(path) try: # Try exports exports = 0 # Try model export if e.supports_model(): exports += 1 fpath = os.path.join(path, 'model.txt') ret = e.model(fpath, m) self.assertIsNone(ret) self.assertTrue(os.path.isfile(fpath)) else: self.assertRaises(NotImplementedError, e.model, path, m) # Try runnable export if e.supports_runnable(): exports += 1 # Check without protocol dpath = os.path.join(path, 'runnable1') ret = e.runnable(dpath, m) self.assertIsNone(ret) self.assertTrue(os.path.isdir(dpath)) self.assertTrue(len(os.listdir(dpath)) > 0) # Check with protocol dpath = os.path.join(path, 'runnable2') ret = e.runnable(dpath, m, p) self.assertIsNone(ret) self.assertTrue(os.path.isdir(dpath)) self.assertTrue(len(os.listdir(dpath)) > 0) else: self.assertRaises(NotImplementedError, e.runnable, path, m, p) # Test if any exports were available if exports == 0: raise Exception( 'No types of export supported by: ' + self._exporter) finally: if os.path.exists(path) and os.path.isdir(path): if not myotest.DEBUG: shutil.rmtree(path)
def periodic(self): """ Test periodic logging. """ m, p, x = myokit.load(os.path.join(myotest.DIR_DATA, 'lr-1991.mmt')) s = myokit.FiberTissueSimulation( m, m, p, ncells_fiber=(1, 1), ncells_tissue=(1, 1)) if DEBUG: print('= ' + s.__class__.__name__ + ' :: Periodic logging =') # Set tolerance for equality testing emax = 1e-2 # Time steps for logging are approximate # Test 1: Simple 5 ms simulation, log_interval 0.5 ms d, e = s.run( 5, logf=['engine.time'], logt=myokit.LOG_NONE, log_interval=0.5) d = d.npview() t = d['engine.time'] q = np.arange(0, 5, 0.5) if DEBUG: print(t) print(q) print('- ' * 10) self.assertEqual(len(t), len(q)) self.assertTrue(np.max(np.abs(t - q)) < emax) # Test 2: Very short simulation s.reset() d, e = s.run( 1, logf=['engine.time'], logt=myokit.LOG_NONE, log_interval=0.5) d = d.npview() t = d['engine.time'] q = np.arange(0, 1, 0.5) if DEBUG: print(t) print(q) print('- ' * 10) self.assertEqual(len(t), len(q)) self.assertTrue(np.max(np.abs(t - q)) < emax) # Test 3: Stop and start a simulation s.reset() d, e = s.run( 1, logf=['engine.time'], logt=myokit.LOG_NONE, log_interval=0.5) d, e = s.run(2, logf=d, logt=myokit.LOG_NONE, log_interval=0.5) d, e = s.run(2, logf=d, logt=myokit.LOG_NONE, log_interval=0.5) d = d.npview() t = d['engine.time'] q = np.arange(0, 5, 0.5) if DEBUG: print(t) print(q) print('- ' * 10) self.assertEqual(len(t), len(q)) self.assertTrue(np.max(np.abs(t - q)) < emax)
def get_parameter_vals(self, parameters: List[str]) -> Dict[str, float]: """Get the value of current model parameters. Args: parameters (List[str]): Names of parameter values to retrieve. """ m, _, _ = myokit.load(self.modelfile) parameter_values = {} for p in parameters: if m.has_variable(p): parameter_values[p] = m.get(p).value() else: parameter_values[p] = np.nan return parameter_values
def run(path, filename=None): """ Run all the mmt files in a given directory `path`. If `filename` is given, only the file with that name from `path` is run. """ # Get absolute path path = os.path.abspath(path) # Change to dir os.chdir(path) # Run all glob = '*.mmt' found = False for fn in fnmatch.filter(os.listdir(path), glob): # Real file? if filename is not None: if fn != filename: continue else: found = True # Load and run try: print('Loading ' + fn) m, p, x = myokit.load(os.path.join(path, fn)) try: print('Running...') myokit.run(m, p, x) except Exception: print(traceback.format_exc()) except Exception: print('Unable to load.') print(traceback.format_exc()) try: pl.close('all') except Exception: pass # Tidy up del (m, p, x) gc.collect() print('-' * 70) if filename is not None and not found: print('Unable to find file: ' + str(filename)) else: print('Done!')
def test_load_save_state_bin(self): # Test loading/saving state in binary format. m, p, x = myokit.load('example') with TemporaryDirectory() as d: # Test save and load with double precision f = d.path('state.bin') myokit.save_state_bin(f, m.state()) self.assertEqual(myokit.load_state_bin(f), m.state()) # Test save and load with single precision f = d.path('state.bin') myokit.save_state_bin(f, m.state(), myokit.SINGLE_PRECISION) d = np.array(myokit.load_state_bin(f)) - np.array(m.state()) self.assertTrue(np.all(np.abs(d) < 1e-5)) # Not very precise!
def test_set_constant(self): # Test :meth:`Simulation.set_constant()`. # Literal self.sim.set_constant('cell.Na_i', 11) self.assertRaises(KeyError, self.sim.set_constant, 'cell.Bert', 11) # Parameter (needs sensitivies set) m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) sim = myokit.Simulation(m, p, (['ib.Ib'], ['ib.gb'])) sim.set_constant('ib.gb', 20) # Calculated constant self.assertRaisesRegex(ValueError, 'not a literal', self.sim.set_constant, 'ina.ENa', 11)
def test_basic(self): # Test basic usage. # Load model m, p, _ = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) n = m.count_states() # Run a simulation with WarningCollector() as c: s = myokit.ICSimulation(m, p) self.assertIn('`ICSimulation` is deprecated', c.text()) self.assertEqual(s.time(), 0) self.assertEqual(s.state(), m.state()) self.assertEqual(s.default_state(), m.state()) self.assertTrue(np.all(s.derivatives() == np.eye(n))) d, e = s.run(20, log_interval=5) self.assertEqual(s.time(), 20) self.assertNotEqual(s.state(), m.state()) self.assertEqual(s.default_state(), m.state()) self.assertFalse(np.all(s.derivatives() == np.eye(n))) # Create a datablock from the simulation log b = s.block(d, e) # Calculate eigenvalues b.eigenvalues('derivatives') # Log with missing time value d2 = d.clone() del(d2['engine.time']) self.assertRaisesRegex(ValueError, 'time', s.block, d2, e) # Wrong size derivatives array self.assertRaisesRegex(ValueError, 'shape', s.block, d, e[:-1]) # Time can't be negative self.assertRaises(ValueError, s.run, -1) # Test running without a protocol s.set_protocol(None) s.run(1) # Test step size is > 0 self.assertRaises(ValueError, s.set_step_size, 0) # Test negative log interval is ignored s.run(1, log_interval=-1)
def iterdir(path, guarantee_model_names=True): """ Iterates over a directory yielding tuples ``(model, protocol)`` where ``model`` is a :class:`myokit.Model` and ``protocol`` is a :class:`myokit.Protocol`. Depending on the contents of the found files, some entries might not have a protocol. Files without a model are skipped. The results will be yielded ordered by filename. The method does not descend into child directories. If ``guarantee_model_names`` is ``True`` (default), models that do not specify a ``name`` meta-attribute will be given their filename as name. This ensures every model read by this method has a name meta-property. """ # Fix path path = os.path.expanduser(os.path.abspath(path)) if not os.path.isdir(path): raise ValueError('Given path is not a directory.') # Scan files for fname in sorted(os.listdir(path)): fpath = os.path.join(path, fname) # Check if it's a model file if not os.path.isfile(fpath): continue base, ext = os.path.splitext(fname) if ext != '.mmt': continue # Read model & protocol model, protocol, x = myokit.load(fpath) # Skip files without model if model is None: continue # Set name attribute if guarantee_model_names: if not model.name(): model.meta['name'] = base # Yield yield model, protocol
def run_simple(self): # Load model m = os.path.join(myotest.DIR_DATA, 'lr-1991.mmt') m, p, x = myokit.load(m) v = m.binding('diffusion_current') if v is not None: v.set_binding(None) # Run a simulation, save all states & bound values s = myokit.Simulation(m, p) s.pre(10) s.reset() d = s.run(20, log=myokit.LOG_STATE + myokit.LOG_BOUND) # Calculate the dominant eigenvalues for each log position g = myokit.JacobianTracer(m) b = g.jacobians(d) b.dominant_eigenvalues('jacobians') b.largest_eigenvalues('jacobians')
def _build_simulation(self): """Creates a class instance of myokit.Model and myokit.Simulation. Raises: ValueError: Cannot find voltage parameter in model. """ m, _, _ = myokit.load(self.modelfile) try: v = m.get(self.vvar) except: raise ValueError('Model does not have vvar: {}' .format(self.vvar)) if v.is_state(): v.demote() v.set_rhs(0) v.set_binding(None) self._sim = myokit.Simulation(m)
def mmt_export(exporter, source, target): """ Exports a myokit model. """ import sys import myokit import myokit.formats # Get exporter exporter = myokit.formats.exporter(exporter) # Set to auto-print logger = exporter.logger() logger.set_live(True) logger.log_flair(str(exporter.__class__.__name__)) # Parse input file try: logger.log('Reading model from ' + myokit.format_path(source)) model, protocol, script = myokit.load(source) except myokit.ParseError as ex: logger.log(myokit.format_parse_error(ex, source)) sys.exit(1) # Must have model if model is None: logger.log('Error: Imported file must contain model definition.') sys.exit(1) else: logger.log('Model read successfully') # Export model or runnable if exporter.supports_model(): # Export model logger.log('Exporting model') exporter.model(target, model) else: # Export runnable logger.log('Exporting runnable') if protocol is None: logger.log('No protocol found.') else: logger.log('Using embedded protocol.') exporter.runnable(target, model, protocol) logger.log_flair('Export successful') logger.log(exporter.info())