120 views (last 30 days)

I have a script that loads a SimBiology model using the simbiology() command. Then I try to get a handle for the model

simbiology('mymodel.sbproj'); % There are reasons why I use simbiology and not sbioloadproject

sbr = sbioroot;

mdls = sbr.models;

nmdls = numel(mdls);

mc = mdls(nmdls);

The problem is when I first try to get mdls. I get an empty array. Apparently, the model is still loading when the sbr=sbioroot and mdls = sbr.models commands run.

In windows command line files, you can use

START /WAIT myprogram.exe

to force myprogram.exe to finish running before going on the next line. Is there a similar artifice in Matab/Simbiology? Something like

finish('simbiology('mymodel.sbproj')' ;

% or

whilerunning

simbiology('mymodel.sbproj');

end

I keep thinking that there's an easy way that I've forgotten...

The above is a general case. Of course, if simbiology() were re-written to return the model handle, and when the handle was requested, would not allow the script to proceed until the model was loaded, it would be great. Logical, too, because generally when you're loading a model you want to do something with that model before proceeding.

mc = simbiology('mymodel.sbproj'); % This solves the specific problem!

% or

mc = simbiology('mymodel.sbproj','WaitToComplete'); % or this

Arthur Goldsipe
on 19 Sep 2019

Hi Jim,

The previous responses are correct: The simbiology command returns before the desktop completely loads the project, because the desktop is operating on different threads. So, welcome to the world of multi-threaded / parallel / asynchronous / <insert buzzword> complexity! Believe me, it makes life harder for SimBiology's developers, too. But hopefully you're mostly seeing the benefits of us living in that complexity and hiding it from you as much as possible.

Right now, there's one-line command that does what you want, but I'll suggest a workaround below. But thinking longer term, we hope to eliminate the need to open a project in the desktop just to preserve the diagram. If you can think of other reasons why it's important to know when a project is fully loaded, let us know so we can address those workflows, too.

Anyway, if all you care about is whether the model is accessible from the MATLAB command prompt (and not whether the desktop has completely finished loading the project), I came up with a solution (pasted below) that uses timer objects to periodically check whether the models have been loaded.

Here's the function. It takes the name of a project, the name of a variable to assign models to in the base workspace, and an optional callback that you can use to execute tasks that take the models as input arguments. So here's an example usage that simulates the Lotka demo project as soon as it's loaded (assigning the result to the base workspace variable sd): simbiologyNotify('lotka.sbproj', 'models', @(m) assignin('base', 'sd', sbiosimulate(m)))

function simbiologyNotify(projectName, varName, callback)

if ~exist('callback', 'var')

callback = @(models) [];

end

root = sbioroot;

oldModels = root.Models;

t = timer('ExecutionMode', 'fixedSpacing');

t.TimerFcn = @(t,e) timerFcn(t, root, oldModels, varName, callback);

simbiology(projectName);

start(t);

end

function timerFcn(t, root, oldModels, varName, callback)

models = setdiff(root.Models, oldModels);

if isempty(models)

return

end

beep

fprintf('Models have been loaded. Assigning to base workspace variable "%s".\n', varName);

assignin('base', varName, models);

stop(t);

delete(t);

callback(models);

end

Note that you can't directly call this function from a script or function. If you do, you'll block the MATLAB interpreter, and that will prevent the desktop from loading the project. So you have to start thinking about asynchronous tasks the way we developers do: as a series of callback functions that get called as soon as their preconditions are met.

And one last note: If you really need to know whether the desktop has fully loaded the project into the GUI, I'll see if there's a way to get that information.

-Arthur

Arthur Goldsipe
on 19 Sep 2019

Hi Jim,

In case it helps you understand my example better, here's how you could adapt your "other_stuff" sample code to work with my function:

simbiologyNotify('mymodel.sbproj', 'model', @(model) other_stuff);

So the basic idea is that you put everything that needs to run after the model loads into another function, and that function is only called after the model loads. That avoids the problem you describe (which also occurs if you try to use "pause" to wait).

Walter Roberson
on 5 Oct 2019

When I sysadmin'd, I was a believer in The Rule Of Three for backups.

The first tape will be scanned by the automatic tape library, noticed that it has "expired", and promptly have its label overwritten because the backups have been sitting waiting for a writable tape to continue writing with.

You then cancel the backups and reconfirm that nothing is waiting to write on the tape drives. Put in the second backup tape, type in appropriate commands... and swear because you accidentally used a tape backup command instead of a tape restore command, so you just scribbled on the tape you were about to restore from.

You unmount that, and this time before putting in the third backup, you make #$@ sure that you enable the write-protect, and proceed to try to restore. Not everything will restore properly. You will start to whimper.

At this point you dig around and dig around, and after panicing a while, find that a three-year old backup got made and overlooked, and you retrieve the rest of the backup from that 4th tape.

Why call it the Rule Of Three? Because next time you remember the write-protect feature on the second tape, and so manage to get through it all in only three tapes.

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 10 Comments

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747732

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747732

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747736

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747736

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747760

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747760

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747764

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747764

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747767

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747767

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747771

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747771

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747804

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747804

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747811

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747811

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747825

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747825

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747886

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/481188-can-i-force-matlab-to-wait-til-it-finishes-one-command-to-run-another#comment_747886

Sign in to comment.