5 Creating Groups and Applications
This chapter describes how to extend map construction into more complex realms. It explains how to streamline maps by combining the functions of several modules into one, thus creating a group of functions. It covers:
types of groups
selecting modules for a group
using the Group Editor
editing input and output ports
creating a group control panel
compiling a group
creating an application
preparing an application for distribution
In a remarkably short time, maps tend to overflow the available space, even with micro control panels. To reduce the clutter and simplify the map, you can cluster related modules together under a single control panel, called a group. A group is an encapsulated collection of modules with its own module control panel.
When you have an elaborate map containing several opened control panels, it is possible to misplace some of them: they become hidden behind one another or behind other windows on the screen. To minimize the visual complexity of a map, you can group several related modules under one control panel, creating a more manageable network of modules. Even with a smaller number of modules, you will probably have more accessible controls than you really need for a specific map.
Frequently, the creator of a map is not the end user but is producing the map or application for a group of co-workers or customers. Such a map is created for a specific purpose, and many of the module parameters available to the map developer will not be needed by the end user. The developer can group modules in the Group Editor to reveal only those parameters relevant to the application at hand. This restricts the functionality of the map, but also streamlines its user interface.
You can use the Group Editor to promote specific widgets and their ports from individual modules to the group control panel. When you have placed the widgets on the group control panel, you can edit them using the Control Panel Editor, which runs from inside the Group Editor. Once you have established the group, those parameters from the original set of modules that are not connected to the group control panel cannot be changed without opening the group.
A group is a collection of modules that serve a common purpose, sharing a single control panel and having some of the parameters of the constituent modules raised to the group level. From the viewpoint of the operating system, the constituent modules are still separate processes: from the user's point of view, however, they behave as a single entity.
You create groups of modules that are frequently used in combination, or that together form a unit of computation. For example, you might want to create a map that processes an image using four different parameters, each of which resides in a different module. When you wire all the modules into the map, you get the parameters you want as well as several others you don't need.
In this case, you can simplify the map by creating a group for the four image-processing modules. This reduces the apparent number of modules, and thus wires, on screen, as well as reducing the number of control panels and widgets.
Groups have three forms, open, closed and compiled:
An open group retains much of the character of the constituent modules. All the modules and their wiring connections are visible, and their controls are operational. The constituent modules are outlined in red.
A closed group takes on a new character. It has a single control panel that contains selected widgets from the constituent modules, and only the widgets on this control panel work. None of the individual modules or the internal wiring is visible.
A compiled group is a closed group whose individual modules have been compiled into a single executable. Once the compilation of the group is complete, you are given the option of replacing the original group (containing separate modules) with the new compiled group. Because the control panel of the compiled group is the same as that of the old group, the interface is unaffected. However, an examination of the machine's process space will quickly reveal that the compiled group is running as a single process which uses less system memory and consumes less CPU time than the original separate modules. The compilation of the group thus results in improved performance owing to the more efficient use of system resources.
A group can contain several modules, and it can also contain other groups. You can therefore create a nested hierarchy of modules under a single control panel.
You must select each module before you can include it in a group.
To select several modules easily at one time, use the lasso technique: click the left mouse in the Map Editor background and sweep it around the modules; otherwise, hold down the <Shift> key and select individual modules one by one.
The selected modules are saved in the group with the exact relative placement they had when you selected them. It is a good idea to arrange modules in as compact a structure as possible before you group them. This eases the task of sorting them out if you ungroup them again.
Once you have grouped modules by selecting Group from the Group menu, the modules behave as a single entity and have a single control panel. If you select another module, then reselect one module in an open group, all the modules in the group are selected. Likewise, when you drag any module in the group, they all move together.
To create a new group or work with an existing group, follow these steps.
Select the modules you want to group together, and click on Group from the Group menu. A single control panel appears for the new group, which is closed.
Use the Group Editor (select Edit from the Group menu) to promote the ports and parameters you want visible in the group control panel. The Group Editor is described fully in Section 5.3.
Use the Control Panel Editor to provide widgets for parameters in the group control panel.
The name of the new group module defaults to Group. You can rename it anything you like in the Group Editor. Group control panels are colored differently from individual modules.
This example illustrates how to select three modules in a map and group them.
Figure 5-1 shows the original map with all the modules ungrouped. It is a typical map: it reads two images from disk using two ReadImg modules and filters both images. One image is sharpened and the other is edge-enhanced with a Sobel filter. The resulting images are blended together and sent to DisplayImg.
The center three modules, SobelEdgeImg, SharpenImg, and BlendImg, can be collapsed into a single group to simplify the map.
Select the modules and then select Group from the Group menu. The default group control panel is shown in Figure 5-2.
To open the group, select the group and then select Open from the Group menu. The original modules appear with a red border, indicating that they are part of a group (see Figure 5-3).
A group usually consists of several modules. Each module can have several input and output ports and numerous widgets. In the context of a group module, not all these ports and widgets make sense or are usable.
The Group Editor (see Figure 5-4) allows you to:
select the ports and widgets you want in the group
create a group control panel using the Control Panel Editor (described in Section 4.2)
The group control panel has ports, widgets, and a module pop-up menu, just like the module control panel. It is, however, a different color. The widgets on the control panel allow you to control the value of the module parameters directly.
You can reorder the module sequence in the Group Editor by grabbing the module title bar and dragging it to the desired location. This changes the sequence in which ports are shown on the group control panel's input and output port lists.
If you are creating a group or application control panel, you get a default widget setting. The Control Panel Editor allocates to each parameter in the new control panel the same widget type and properties as the parameter had in its module control panel.
For example, the SobelEdgeImg module has a slider for its Bias parameter. If you create a group containing SobelEdgeImg and promote the Bias parameter to the group control panel, the slider appears on the group control panel by default.
You can change this default to whatever suits your needs at the group level.
Selecting a port for the group control panel is called promoting the port. In deciding which ports and widgets to promote, you need to determine how you want to reuse this group and how your users (if any) will be using the group.
To select a port, click on the port button in the Group Editor.
Ports that are not promoted to the group level are not visible in the group control panel. The ports still exist, however, and widget-based parameter input ports retain the value they had when you first created the group. You can adjust the values of hidden parameters by opening the group, using Open on the Group menu.
Groups have two kinds of required input ports: those that are required at the module level and hence at the group level also, and those that are optional at the module level and have been promoted to the group.
Some module input ports must have data on them before the module will fire. These ports are also required at the group level, if there is no connection to them within the group, otherwise, the group will not fire. In the Group Editor, required ports are automatically promoted. They appear in the Group Editor as selected and you cannot deselect them.
For example, SharpenImg and SobelEdgeImg in Figure 5-4 both have required module input ports that also appear as required group input ports. Neither module will fire unless:
it has a connection to its Img In -- Lattice port
it has data on its Img In -- Lattice port
These ports will be promoted to the group level and appear on the input port menu of the group control panel. The group control panel will not fire unless both ports have data on them.
Port names are shown on the input and output port lists in the group control panel and on the parameter widgets, so it is important that each port have a unique name. However, group modules often contain two modules whose ports have identical names. For example, there are two Img In ports in Figure 5-4.
Sometimes you may want to rename a port even if the name does not conflict with another port in the group. The focus of the group and the intent of an individual module are different, and a new name may make more sense in the context of the group.
The Group Editor provides an alias text slot for each port so you can set up a unique name for it.
To change the name of a port, type a new name in the text type-in slot. Figure 5-5 shows the Group Editor after both the Img In ports have been renamed.
To complete the new group control panel, select these parameters in the Group Editor:
Sharpness from SharpenImg
Bias from SobelEdgeImg
Blend from BlendImg
You can change the parameter names if you wish.
For example, in the context of the group, Bias needs some clarification so it can be renamed Sobel Bias.
You can rename ports and parameters at any stage of the grouping process by entering the new name in the Group Editor.
Click on Apply or OK to apply the changes and set up the new control panel.
Some ports may not be required by an individual module, but must be promoted once the module is part of a group, because there are connections to other modules in the map outside the group at the time of creating the group.
Suppose you select ReadLat, Contour, and WireFrame to make a group. The group has one outside connection, a hookup from GenerateColormap to Contour. The Colormap -- Lattice input port on Contour is not intrinsically a required port, but in the context of the new group, it becomes required because of its link to GenerateColormap. Hence, it is automatically promoted to a group-level port.
This principle also holds true for output ports. If a connection exists downstream of the group, the port with that connection is automatically promoted and indicated as selected in the Group Editor.
You cannot promote loop controller capability from the loop controller to a group module. If you want to link a grouped loop into another loop, you must include a separate loop controller module in the new loop.
You can create a group control panel in two ways, by default and by conscious design.
Use the Group Editor to create a default layout.
To do this, click on the OK button at the bottom of the Group Editor window after you have selected the ports and parameters you want. This dismisses the Group Editor, applies the changes, and updates the Map Editor. In the process, it creates a default control panel for the group.
This is useful if the group does not have any parameters for which widgets are required, or if you can use all the default settings and layouts for selected parameters.
Use the Control Panel Editor, accessible from the Edit menu of the Group Editor, to lay out the control panel of the new group and customize it (see Chapter 4, "Editing Control Panels and Functions").
Figure 5-6 shows the control panel for the new group in the Map Editor, along with its maximized form. It is easily recognizable as a group module because it is a different color.
If you select the input port access pad of the new group, you see only those ports you selected in the Group Editor, with the names you chose for them.
Figure 5-7 shows a group control panel with a drawing area. It uses the collection of modules and maps from the previous examples, but adds some of the DisplayImg module's widgets, including its drawing area, promoted by selecting Window -- Parameter in the Group Editor.
Notice the difference in size between this map and the one in Figure 5-7. A considerable savings has been obtained by combining four of the original six modules into a single group.
To display the full-scale control panel, click on the Maximize button, just as you would an ordinary module.
To open a group again, select Open from the Group menu. The original modules reappear with each module outlined in red.
While a group is opened you can interact with any of the widgets of the constituent modules to change their parameter settings.
If you have a nested hierarchy of groups, you may open all groups in the hierarchy. However you can use Edit in the Group menu only on a top level group, you cannot edit a group within a group. Therefore you should have finalised selecting promoted ports before including it within another group.
Click on the background to deselect the open group. To select one or more modules in the group hold down the <Shift> key and click on each module to toggle selection on and off.To select one module in the group, deselecting all other modules currently selected, hold down the <Alt> key and click on the module.
To close the group and display the group control panel again, select Close from the Group menu.
You can create and destroy connections within the opened group, those between modules belonging to the group. Use the port menus to create and destroy a connection as usual. When creating a connection you will see that compatible ports are highlighted only on modules within the group.
If you use the Disconnect and Reconnect options on the Edit menu for these modules, only those connections between modules within the group are broken with Disconnect and recreated with Reconnect. Using Disconnect and Reconnect on a closed group breaks and recreates the connections from the promoted ports of the group, but not the connections internal to the group.
You cannot create a connection from inside the group to outside. You should promote the inside port to the group, using the Edit option on the Group menu on the closed group, and then connect selecting from the port menu of the closed group.
You will see when disconnecting to ports of modules within a group that the name of the module is preceeded by the name of the group to further identify the connection.
The modules within a group can be reselected, retaining the attributes of the edited group, using the Regroup option on the Group menu. Select modules from the open group, leaving as unselected those to be omitted from the redefined group; in addition, select modules not currently within a group to be added to the group. Then select Regroup.
The control panel of the original group is retained, except that widgets corresponding to parameters from omitted modules are removed.
Settings for promoted ports and alias names are also retained. There may be additional required ports that are promoted from the new modules within the group. Note that it is possible for a port that was required for the original group to no longer be so. For example, by adding a module into the group that has a connection to an originally required port, removes the need for that port to be promoted to the group. This port will still be marked as promoted in the Group Editor, but can now be deselected.
You can ungroup a closed or open group by selecting UnGroup from the Group menu. You are left with the original collection of separate modules. If the group is closed and only the group control panel is showing, it opens before it is ungrouped.
Although a closed group, at first glance, looks like a module, its underlying architecture is in fact the same as the original collection of separate modules. That is, grouping the modules together only changes their user interface; underneath this, they still run as individual executables, each appearing to the operating system as a separate process, passing data via shared memory or sockets. This can have some advantages over a monolithic process: for example, if one module in a map crashes, the remaining modules are, in general, unaffected. Nevertheless, the separate processes can sometimes represent a poor use of resources (such as memory and CPU use), and the communications between the modules can sometimes appear to add a significant overhead to the execution of the group, particularly if it is composed of a large number of small modules.
These problems are overcome by compiling the group. In effect, this allows a new module to be built by combining existing ones together. Once a closed group has been created and its control panel laid out, the separate modules may be compiled into a single module which can optionally replace the original group in the Map Editor. Because the control panel of the group is unchanged by the compilation process, the user interface is unaffected as well. However, because the compiled group runs as a single process, it consumes less system resources (such as CPU time and memory) than the original separate modules, leading to improved levels of performance.
Once a closed group has been created via the procedure described above, you can compile it by selecting it and choosing Compile from the Group menu. In the pop-up dialog box (see Figure 5-8) select the directory into which the compiled group will be placed. The compiled group consists of a module resource file and an executable (like any other module), together with a group resource file (extension .gres) which contains details of the composition of the original group, and which is used if the compiled group is to be uncompiled - see Section 5.5.1.
The Group Compiler then searches for the source files of all the modules within the group. An error message is displayed for the first source file it is unable to find, giving details of where it expected to find it.
Having found all the sources of all the modules in the group, the Group Compiler combines them together and resolves any conflict of names and symbols before compiling the combined source to create a new module. While this process is running, a dialog box is displayed (see Figure 5-9).
Once the compilation process has completed and the files have been saved in the target directory (see Figure 5-8), the Group Compiler gives you the option of replacing the original group in the Map Editor by the new compiled group (see Figure 5-10). Whether or not you choose to do so, you can launch the compiled group at a later point via the Open option on the Module Librarian File menu.
In Figure 5-11, the original group has been replaced with the compiled group.
The compiled group can be uncompiled back into the original group of separate modules by selecting Uncompile from the module's pop-up menu. Selecting this option deletes the compiled group from the Map Editor and launches the original group.
The compiled group's group resource (.gres) file is used to recreate the original group. Uncompiling the compiled group does not affect the files which were created by the original compilation – that is, the compiled group can still be launched in the Map Editor at a later time.
When you have created a group with its own control panel, you can run it as an application. An application is a module or map that runs in a special IRIS Explorer mode outside the Map Editor. You cannot change an ordinary IRIS Explorer session into an application-mode session.
Application mode operates on ordinary IRIS Explorer maps, which consist of one or more modules or groups. Usually, a map contains several modules, collected into one or more groups.
There is no special procedure for creating an application, since an application is simply a map run in a special mode.
In most applications, you will want a drawing area in order to visualize the results of the process that the application is performing on the incoming data.
When you are building an application, special attention should be given to the values of parameters in the application map.
When a map is run as an application, the parameters in the map will have whatever values they were set to when the map was saved. This matters particularly for parameter widgets associated with input and output filenames.
For example, suppose you are building an image processing application from a map that contains ReadImg. While testing the map, you typed the filename fish.rgb into ReadImg and then saved the map.
When you run the map as an application, ReadImg will be given the specific input filename fish.rgb and, therefore, will attempt to read in fish.rgb each time it starts up. In an image processing application for general use, this may not be the best behavior. However, for some parameters, setting the values in the map to default initial values may be the correct thing to do.
When you save a map that will be used as an application, be careful to set parameters to the start-up values that the application user expects.
You must make sure that any map saved for later use as an application has at least one open control panel, that is, maximized to its full size; otherwise, nothing will be visible when you run the application. In application mode, the mini control panels are not visible and there is no way to maximize a group control panel. You can save a map with more than one control panel maximized if you wish.
To save the map, select Save Selected from the File menu on the Module Librarian. Save each map with a name and the suffix .map or .app.
You can run an application using the command -app.
To open and use a standard application, at the shell prompt depending on the suffix of the filename, type:
explorer -app filename.map
explorer -app filename.app
When you run an application, only the application control panel is displayed on the screen. The IRIS Explorer window, the Map Editor window, and the Librarian are not displayed.
Applications generally have one or more windows acting as control panels; they must be visible for the application to work properly. The window manager Quit command is issued to a window when the user asks the window manager to close the window. For example, in the case of a Motif-style window manager, the user would either click on the left button of the title bar and select Close from the window manager's menu, or double-click on the left button to close the window immediately.
When IRIS Explorer is running normally (not in application mode), the double-click merely dismisses maximized control panels. The user can still access the corresponding mini control panel in the Map Editor and can re-maximize the control panel from there.
In application mode, double-clicking dismisses maximized control panels but it also terminates the application itself as its operation cannot continue. This is because there is no visible Map Editor and thus no way for a user to recover the maximized control panel.
It is a good idea to add Quit to the menu bar on the main group control panel in your application map, otherwise, the only way to quit an application is through the window manager.
In application mode, the Map Editor is not visible and so the user does not observe the usual signals that a map is executing, such as yellow highlighting and the Busy cursor.
Instead, IRIS Explorer displays a Busy cursor over all control panels when any module in an application is executing.
If you turn execution highlighting off, you disable the display of the Busy indicator.
To run an application so you can check its development and do debugging tasks, at the shell prompt depending on the filename extension type:
explorer -map filename.map
explorer -map filename.app
When you run IRIS Explorer in this way, the application is displayed, along with the IRIS Explorer window. The IRIS Explorer window gives you access to the Map Editor and the Module Librarian if you require it.
Having created and debugged your application, you may wish to share it with other users. One way of doing this would be to take the standard IRIS Explorer distribution (as installed on your machine, or from the original distribution media) and pass it to your intended user. In addition, you would have to give them your map file, together with any modules that were used in the map and which did not come from the standard distribution. These extra modules would include, for example, modules developed by you, or modules which you have obtained from repositories and used in the map. Finally, you would also have to include any sample data files used by the map.
Although this would work, it is probably not ideal. The IRIS Explorer distribution contains a lot of files which won't be required for your application. For example, it would probably make use of only a small proportion of the modules. Your intended user might well be surprised at the amount of disk space taken up by such a distribution, just in order to run a single application. The mixture of distribution media (from the original IRIS Explorer distribution, and the supplements provided by you) might also cause some confusion. Finally, the burden is on you to ensure that all relevant files get passed to the intended user.
The packmap utility is intended to help with this problem. Given a map file, packmap analyses it to build a self-contained distribution which contains only those parts of IRIS Explorer which are required for that map to run correctly. This minimal installation can represent a substantial saving in disk space when compared to the full distribution of IRIS Explorer. The distribution built by packmap consists of:
your map file
module executables and resource files for all modules used in the map, either from the original distribution or from elsewhere (i.e., including any of your own modules, as required)
sample data files used by the modules in the map. These are determined by parameter settings from when the map was saved
required system files from the original IRIS Explorer distribution. Some of these files will be required by all maps, while some will be dependent on the nature of the constituent modules. For example, some maps do not process geometry, and so will not require the IRIS Explorer geometry libraries.
packmap creates a distribution by copying the necessary files into a separate location, specified as a destination directory. It creates a directory structure at that location which mirrors that of the original distribution and of any other required files such as user-developed modules.
packmap is invoked from the UNIX shell. It has the following command line structure:
packmap [-v] map dest_dir
where map is the name of the file containing the map which is to be packaged, and dest_dir is the intended destination directory. If dest_dir doesn't exist, packmap creates it. The optional verbose flag (-v) causes packmap to list the files as they are copied. For example,
% packmap -v $EXPLORERHOME/maps/simple.map /usr/tmp/myDist copying /home/explorer/bin/explorer to /usr/tmp/myDist/bin/explorer copying /home/explorer/lib/gui to /usr/tmp/myDist/lib/gui copying /home/explorer/lib/gui.messages to /usr/tmp/myDist/lib/gui.messages ...
Having created the distribution in the destination directory, you can modify it if necessary by, for example, adding application-specific documentation or additional files which would not have been picked up by packmap (such as, say, additional data files). If required, the new distribution can be additionally tested by setting the environment variable EXPLORERHOME to point to the destination directory and running the copy of IRIS Explorer in that minimal installation. Thus,
% setenv EXPLORERHOME /usr/tmp/myDist % explorer -app $EXPLORERHOME/maps/simple.map
Finally, the whole directory can be packaged up for distribution using, for example, tar(1) or a similar archiving tool. This package is then a self-contained distribution of your application, which can be passed onto others for their use. Unpacking the distribution on the target machine will create a duplicate of the destination directory and its contents; all that is required is that the user set EXPLORERHOME to point to that directory, before running the application using the command given above.