13.5: A2.5 Debugging Scripts by Performing Experiments and Collecting Data
-
- Last updated
- Save as PDF
Earlier, I said that you should act like a scientist when debugging code, which include performing experiments and collecting data. In this section, I’ll describe some simple methods for doing this.
Scripting is all about storing information in variables and applying operations to those variables (e.g., addition, subtraction). When there is a runtime error or logical error, some variable probably has an incorrect value. A key aspect of debugging is therefore assessing the values of the variables at different points in the execution of the script. This is much like monitoring the representations of the brain at different time points following the onset of a stimulus while a participant performs a task.
There are a couple ways to monitor variables. The simplest is to print their values to the command window at key points during the execution of the script. To see how this works, let’s use this approach to understand what is wrong with the Test_Case_4.m script.
Exercise A2.5: Displaying Variable Values
Open the script (if it’s not already open) and take a look at it. The goal of the script is to load a dataset named 1_N170.set that is located in the current folder (the same folder as the script). To achieve this, we start by getting the path to the current folder with the pwd ( print working directory ) function and store the result in a variable named DIR . We then concatenate this value with ‘1_N170.set’ to create the full path to the file, and we store the result in a variable named Dataset_filename . We then send Dataset_filename to the pop_loadset function. But we’re getting an error message indicating that Matlab can’t find the file that we’ve specified in this manner.
To figure out the source of the error, let’s examine the values of the DIR and Dataset_filename variables. To accomplish this, add the following two lines to the script, right after line 5 (i.e., after the lines of code that set the values of these variables):
display(DIR);
display(Dataset_filename);
These commands will display the values of the DIR and Dataset_filename variables to the Command Window. To see this, run the script. You should see the same error message in the Command Window as before, but prior to that you should see something like this:
DIR =
'/Users/luck/ERP_Analysis_Book/Appendix_2_Troubleshooting/Exercises'
Dataset_filename =
'/Users/luck/ERP_Analysis_Book/Appendix_2_Troubleshooting/Exercises1_N170.set'
The value of DIR will be different on your computer because your current folder is not the same as mine. However, if you look closely at it, it should be correct.
If you look at the value of Dataset_filename , you should see the error: there is no slash (or backslash) between Exercises and 1_N170.set . In other words, the script is telling Matlab to look for a file named Exercises1_N170.set instead of a file named 1_N170.set inside the Exercises folder.
To fix this problem, change Line 5 from this:
Dataset_filename = [DIR '1_N170.set'];
to this:
Dataset_filename = [DIR filesep '/' '1_N170.set'];
(but use '\' instead of '/' if you are on a Windows machine). Now run the code. You will see that the Dataset_filename variable now has a slash (or backslash) between the folder name and the file name, and everything now works correctly.
By the way, I recommend learning how to use the fprintf command to display the values of variables. It’s much more powerful than the display command. It’s explained briefly in Chapter 10, and you can Google it to find more details. Very worth knowing!
Exercise A2.6: The Workspace Pane and the Variables Pane
Once a script has stopped running, you can see the valuable of a variable by simply typing the name of the variable in the Matlab command window. Try this by typing Dataset_filename . You can also see the value of a variable by looking at the Workspace pane in the Matlab GUI (which is probably at the right side of the GUI). This pane should look something like Screenshot A2.1.
This pane shows all the variables that Matlab knows about. For example, I currently have four datasets loaded, and the fourth dataset is currently active, so CURRENTSET has a value of 4. For more complicated variables, the dimensions of the variable are shown instead of the value. For example, ALLEEG is a data structure that holds all of the datasets, and it is listed as a 1x4 struct to indicate that it is a structure that is 1 row high by 4 columns wide (because I have 4 datasets loaded).
You can see that the Workspace pane in Screenshot A2.1 also contains the DIR and Dataset_filename variables that were created by the last script I ran, Test_Case_4.m . You should also have these variables listed; if you don’t, run Test_Case_4.m again (after fixing the bug). The strings stored in these variables are too long to be seen well in the Workspace pane, but Matlab has a Variables pane that you can use to inspect variables more carefully.
To see this, double-click on the Dataset_filename variable in the Workspace pane. You should see the Variables pane open up in the Matlab GUI (probably above the command window). It should look something like Screenshot A2.2.
The value of the Dataset_filename variable is now shown (in the little box with “1” to the left and “1” to the right). However, the box is too small to see much of the variable. If you place your mouse over the right edge of the box with the “1” above the variable value and drag rightward, the box will expand, and you’ll be able to see the whole variable (as in Screenshot A2.3).
If you’ve fixed the bug in Test_Case_4.m , you should be able to see the slash (or backslash) between Exercises and 1_N170.set . This might seem like a lot of work to see the contents of a variable, but once you’re practiced at this approach, it will become very efficient. Also, it’s a great way to look at more complex variables.
For example, double-click on the EEG variable in the Workspace. The Variables pane should now look something like Screenshot A2.4. You can easily see the various fields of this complex data structure, such as the number of channels (the nbchan field) and the number of time points (the pnts field). The actual voltage values are stored in the data field, and you can see that this field is 33 rows high (one row for each of the 33 channels) and 170750 columns wide (one column for each of the 170750 time points). Double-click on the data field, and now you can see the actual voltage values for each combination of channel and time point. Try double-clicking on other fields as well to get a sense of what information is held in the EEG variable.
Exercise A2.7: Interrupting a Script to View Variable Values
The Workspace and Variables panes are great ways to see the values of variables, but you can ordinarily use this approach only after a script is finished. But Matlab also contains a debugger that allows you to pause the operation of a script at various times so that you can examine the values of the variables at those times.
To see this in action, load the Test_Case_5.m script. This script is much more complicated than the previous test cases, but it is actually a simplified version of the Step1_pre_ICA_processing.m script from Chapter 10. It loops through the data from the first five subjects in the N170 experiment, loading each subject’s dataset, filtering it, adding channel location information, renaming it, and then saving the new dataset to the disk.
There isn’t a bug in this script, but let’s imagine that there was a problem and that you suspected that the problem arose in the loop that starts on Line 14 and ends on Line 32. If you just start running the script, you won’t be able to inspect the values of the variables using the Workspace and Variable panes until the script ends. However, you can set a breakpoint that causes the program to pause at the end of each time the program runs through the loop.
To set a breakpoint at a given line, you simply click the corresponding line number in the editor window for the script (but make sure that the script has been saved first if you’ve made any changes). For example, Screenshot A2.5 shows what happened when I clicked on the 32 corresponding to the line number for the end statement at the end of the loop (Line 32). This line number is now highlighted in a red box.
Go ahead and click on the line number for Line 32 in the Test_Case_5.m script. It should now have a red box around it, as in Screenshot A2.5. Now run the script. You should see that the script runs, printing a bunch of information in the command window. However, it has only run through the loop once and has paused. You can tell that it has paused because the command window prompt is now K>> instead of just >> . You can also see a green arrow next to the end statement in the editor window for the script. And if you look at the Workspace, you can see that the subject variable (which loops from 1 to 5 in this script) is set to 1 .
Now let’s look at the current value of the EEG data structure. You may already be showing EEG in the Variables pane, in which case you are looking at the current value of this variable. If it’s not already showing, you can double-click EEG in the Workspace pane to look at it in the Variables pane. You can see that the set name has been correctly updated to 1_N170_filt_chanlocs (although seeing the full name of this field may require double-clicking on the setname field in the Variable pane.
You can resume execution of the script by clicking the Continue button in the toolbar along the top of the editor window for Test_Case_5.m . When you do that, the script resumes and runs through the loop one more time. If you now look at the value of the setname field of EEG in the Variables pane, you’ll see that it has been updated to 2_N170_filt_chanlocs . You can click the Stop button in the editor window’s toolbar to quit from the script.
This feature of Matlab is very useful for debugging. You can read more about it in the Matlab documentation for breakpoints . Other related tools are described in Matlab’s general debugging documentation .