%% Time to convert from find_system to Simulink.findBlocks
% If you are creating, editing or analyzing Simulink models programmatically, you are probably familiar with find_system.
% While there is nothing fundamentally wrong with find_system, in this post I want to highlight a set of functions that provide similar capabilities with improved usability.
% In MATLAB R2018a, we introduced:
% Simulink.findBlocks: Find blocks in Simulink models
% Simulink.findBlocksOfType: Find specified type of block in Simulink models
% Simulink.allBlockDiagrams: Find loaded Simulink models and libraries
% Simulink.FindOptions: Specify options for finding blocks in models and subsystems
% Let's examine why I believe these newer APIs offer a an improved usability.
%% Two Equivalent Queries
% Let's first look at a typical example. Using the example sldemo_fuelsys, let's compare the code to find the only Math Function block in this model:
%

mdl = 'sldemo_fuelsys';
load_system(mdl);

% Using find_system:

blksFindSystem = find_system(mdl,'LookUnderMasks','all','FollowLinks','on','BlockType','Math')

% Using Simulink.findBlocksOfType:

opts = Simulink.FindOptions;
opts.FollowLinks = true;
blksFindBlocks = Simulink.findBlocksOfType(mdl,'Math',opts);
getfullname(blksFindBlocks)

% When looking at this code, you are probably wondering why I consider the second option better in terms of usability. After all, it's 3 lines of code instead of 1.
% Let's look into that in more details.
%% find_system - Step by Step
% Let's go through my thought process when I write the line of code with find_system. I will first type the return variable, the equal sign and start typing "find_" until the suggestion mechanism offers find_system:
%
% Once I accept that, I type the model name and see the next suggestions:
%
% With the function-style of find_system, the MATLAB Editor is able to list the different syntaxes, but not the argument values. As first guess, I'll probably go with:

blksFindSystem = find_system(mdl,'BlockType','Math')

% Since it returns nothing, I look at the find_system documentation for more details. The first thing I determine is that the block I am looking for is inside a library link, so I add the FollowLinks option.
%
% I copy the option name from the documentation and paste it in my line of code

blksFindSystem = find_system(mdl,'FollowLinks','on','BlockType','Math')

% Still nothing. Back to the documentation, I find the LookUnderMasks option
%
% This time, I am successful:

blksFindSystem = find_system(mdl,'FollowLinks','on','LookUnderMasks','all','BlockType','Math')

% One thing to admit: even after writing code with find_system for 20 years, even if I know exactly the options I need, I always open the documentation and copy the option names from there. The reason is probably a mix of having made typos too often and a preference to copy and paste versus typing everything.
%% Simulink.findBlocksOfType - Step by Step
% Let's go through the same thought process for Simulink.findBlocksOfType. As in the previous case, I begin typing the first line
%
% I accept the suggestion.

opts = Simulink.FindOptions;

% Once this is done, I can hover the mouse over "opts" and immediately see the options:
%
% Quickly scanning them, I can see that LookUnderMasks is already set to "All", but FollowLinks is not enabled, so I start typing:
%
% I accept the suggestion and finish the line:

opts.FollowLinks = true;

% I start typing the last line, accompanied by the code suggestions all the way:
%

blksFindBlocks = Simulink.findBlocksOfType(mdl,'Math',opts)

% What I receive is a block handle, which can be passed to other functions like set_param, get_param, hilite_system, etc. If you want to see the block path as find_system returns, use getfullname:

getfullname(blksFindBlocks)

%% Final Comparison
% I hope I illustrated how, thanks to the latest enhancements to tab-completion and code suggestions in the MATLAB Editor, Simulink.FindBlocks and related functions can improve the coding experience. It's 3 lines of code instead of 1, but they are easier to write and as easy to understand at first look.
% One more advantage is when I need to call Simulink.findBlocks multiple times. In most cases, I will be able to create the Simulink.FindOptions object only once and reuse it many times in my code, simplifying things even more.
%% Now it's your turn
% It took me longer than it should have to realize how Simulink.findBlocks and related functions improve my workflow compared to find_system. At first, I was sort of turned off by the need to call the additional function Simulink.findOptions. However, after forcing myself to use them a few times, I quickly changed my mind and abandoned find_system.
% Give a try to Simulink.finBlocks and related functions and let us know what you think in the comments below.