1.4 Adding Rappture to MATLAB Applications
McLennan, Michael
 Online simulation and more for nanotechnology. All right. This last section now we're going to put everything all together. So you've learned a little bit about Rapture. You've learned a little bit about MATLAB. Now I'm going to show you how to build a MATLAB application that has a Rapture interface on it. So suppose you already have a MATLAB program that somebody else wrote, your advisor wrote. I wouldn't be surprised if he hands you a.m file tomorrow and says, here's the program. Put it up on Nano Hub. You might run it like this. If I had this Fermi.m script, I could run matlab-no-display-rfermi. And it might do all that stuff. Remember I showed you a few minutes ago the disk function to display a prompt input, all that stuff. So that's what this program is going to do. It's going to ask me to enter a Fermi level and I'm going to type in 2.4 and it's going to tell me to enter the temperature and I'm going to type in 77. And then it's going to run and when it's all done, this program produces a file called out.dat that has all this data in it. So that's like the program that your advisor is going to give you or you're cell, whoever's in the next cubicle, that's the program they have. And what you want to do is take that program and turn it into a Rapture interface. If we do it in Rapture, it'll look like this. Instead of some 1970s looking thing like this, it'll have a nice graphical interface with some input controls and some curves and you'll be able to plot multiple cases and all of that. And by the way, this example that we're going to be walking through is actually in the Rapture examples directory. If you look in the Rapture project on Nano Hub, you can find all these different examples. In fact, this Fermi example, we do in all the languages. So if you want to see what the Fermi function looks in Python and how it looks in C language and Fortran, in this case we're looking at the version that's all in MATLAB. So let's walk through it. If you go into that directory and you take a look at the Fermi.m script, it looks like this. This is a standard kind of MATLAB thing. It starts out with the DISP function and the INPUT function because you got to get a value in for EF. And then the DISP and the INPUT function for T because you need a value for T. And then at the end of it, you can see it does some stuff in the middle and at the bottom, it opens up the file and it writes out a bunch of stuff and then it quits. So basically the top is where it's getting all its input values. The bottom was where it's writing out all the results and in between, there's a little bit of physics. Just about any program that you look at, you can kind of see that way. So those first two lines are that number, these next two lines are that number, and this bottom part basically is sort of like the curve that you would get in Rapture. So there's sort of one-to-one correspondence. Whenever I look at a program like this, it's always funny to me because usually about half the code in the program is related to the inputs and the outputs. People spend all the time trying to come up with fancy parsers and all their own plotting routines and all of that stuff, which is great if you guys like GUI programming. But if you just want to make a tool that works, you really want to focus all your effort on the middle part, which is where the physics is. So the little bit of code in the middle is where the action is, and you can really help Rapture use Rapture to take care of the rest of the stuff. Alright, so that's what we're going to do. Suppose we go into the Rapture builder and we want to do the same thing, but that instead of using input and output and all that stuff, we'll go into Rapture and we'll grab a number control off the left-hand side, drag and drop that into the input section. And if you look at the number, we can give it a label of ambient temperature, we can give it a nice description for the tool tip, a default value, remember everything should have a good default value. A number control in Rapture is like a double precision value, so I can set 297.5 degrees Kelvin. A number also has units. See the units of measurement right there. You can set the default units to be Kelvin, Fahrenheit, Centigrade, whatever, and Rapture's smart about units. It knows that Kelvin and Fahrenheit and Centigrade are all temperature, so it knows how to do units conversion. So you can say, well, I prefer Kelvin, but my user can type in whatever they want, whatever their favorite units are. So we're going to go ahead and make Kelvin the standard units, but again, any temperature units will work. And you can also set min-max values on that. So for example, you guys know, you might know from physics, you can't go below zero degrees Kelvin. Zero degrees Kelvin is absolute zero. It's the coldest possible temperature. I don't know what happens. I think the whole universe like rewinds if you go lower than zero degrees Kelvin. It's not allowed. So we can't let our users simulate lower than zero degrees Kelvin either because the simulator undoubtedly will core dump. So we can set a minimum value of zero degrees Kelvin, and Rapture will enforce that. If someone tries to type in negative five, Rapture stops them right up front. You can also set a maximum value. 500 Kelvin is pretty hot. It's not a million degrees Kelvin, which is like the sun or something, but it's pretty hot. And there's a good chance that above 500 Kelvin, my simulator is going to core dump. So I want to make sure my simulator doesn't core dump. I'll just put in a maximum of 500 Kelvin there. If there is no maximum for your simulator, then don't specify a max. You don't have to have a min or a max value. Those just help you guard against bad values. So I can define the temperature that way. That's one control. I can define the next one. The next one is my Fermi energy. I'll label it Fermi level. That's what the physicists call it. It's the energy at the center of the Fermi distribution. If you know what the heck that is, it's all this statistical probability quantum mechanics stuff. I give it a good default value, zero electron volts. And the units in this case are units of energy. Electron volts are joules, are units of energy. And Rapture knows about both of them. So I'll set EV is pretty good. Most people are comfortable with that. I'll set EV as the units of measurement. And again, I can set a min and a max value. I can say it really doesn't make sense to go lower than 10, minus 10 EV, or higher than 10 EV. But if it does make sense, then just leave those off. You notice there's a few other options. You can set an icon and there's stuff like that if you want to mess around with it. Kind of dress up your interface. All right. Now last but not least, I take the curve object and I drag that over onto the output side. And then I specify everything I know about it. So what is this curve? The curve that I'm producing is the Fermi-Dirac factor. It's really great to give a good description to these things. Because when your user hits the program, they're going to be like, what the heck is the Fermi-Dirac factor? Like how many of you guys, come on, fess up, how many of you actually knew what the Fermi-Dirac factor was? Nobody, right? See, I know you're telling the truth now. It's not just that it's after lunch and you're shy about raising your hand. Because yeah, of course you don't know what the Fermi-Dirac factor is. It's a very esoteric concept. When you build tools, everything you put in your tool is going to be confusing to some user. Because they haven't spent any time learning your area. It's not that they're stupid, but they just don't know anything about this, right? So this Fermi thing, there are even physicists out there, I might use a different nomenclature. You know, I may say Fermi function and they say, well, which one? Fermi-Dirac factor of order one half or what? Right? So you got to be specific about this stuff so that people can understand what you're simulating and what it means. So you should always have some pretty good description that goes along with all your parts. Also, we can specify the axes. The x-axis is going to be the Fermi function, actually, and the y-axis here is energy. That's a little weird compared to most of your x-y plots, but that's the way I'm plotting it here. So kind of tilted the way you might think of it otherwise. And you can specify descriptions and everything for the x and the y-axis. And you notice units, you notice my y-axis has units of electron volts. You can specify the units and all that. So that all goes to the plot. All right, now on the tool side, there are a few more things to set. Remember in the builder, we always set a title and some description and then the language, octave. So I'm going to use octave for this example. All right, now let's take a look. Remember when I save out of the builder, it's going to automatically generate my skeleton file, my main.m. And if I take a look at the main.m that got generated, what I really want to do where it says, add your code here for the main body of your program. I want to go back to that script I showed you at the beginning. I want to take that chunk of code and stick it in there. That's relevant. So there's my chunk of physics code. That's what I want to stick in the middle there. And if you look at that physics code, it's using variables called EF and T. Those are my inputs. So if I'm clever about naming things or figuring out how it gets hooked up, when I created the control inside my Rapture builder, I called it temperature. So temperature is the same as what I was calling T in my other script. I have to kind of figure that out. The variable that I'm calling it in the builder versus what I'm calling it in my code, I've got to make sure those are matched up. And similarly, on the output side, my program produces vectors E and F. And down here, the builder was calling it X and Y. So I've got to match that up. Somehow I've got to say X equals E and Y equals F, or I've got to substitute E and F in there or something. I've got to match that up to make it fit. So if I take that code and stick it in the middle of my skeleton program, and if I change the variable names to match one place or the other, to make it all match up, then everything will work. So this is the way I'm doing it here. I basically stuck the code in and I renamed the T there to temperature, and I stuck in F and E on the X, Y data. And everything else then fits. Everything else will work. So now you remember how this works. I've got a tool.xml, and when I run Rapture, Rapture reads the tool.xml, and in this case, creates the two inputs, the temperature and the Fermi level. And when I click on simulate, it produces the driver file. Driver file is a copy of the tool.xml, but it has the current values. It runs my code, which has the physics in there, and then produces a run file. And the run file has a curve in it, and you can see all the X, Y values in the curve. That's the data that I generated. So that's how it works, right? And then it plots it. And then it whisks that file away and stores it in your results directory, right? All right, one last thing I'll tell you before we get you going on your next lab assignment. Every once in a while, MATLAB, when it goes wrong, it kind of does weird things. If something goes wrong inside your script, you might see it looking, it like kind of hang here and kind of freeze, and you'll see something weird like the backslash A and the greater than or greater than or something weird like that. Usually what happens, MATLAB at this point hit an error and is now waiting, goes into interactive mode and it's waiting for you to type something. And Rapture is waiting for MATLAB to finish, and MATLAB is waiting for you to type something, right? So you're kind of stuck in a deadlock. So if you see something like this, if you're running and it seems like it's taking forever, and it's like, looks weird, it could be that MATLAB is kind of broken and is waiting in this deadlock. I think Octave is slightly better behaved. The other thing about MATLAB is that sometimes it does weird things to your terminal. When this happens and then you go back to your X term and you try to type, nothing types anymore on your terminal. MATLAB does screwy things to your terminal. So anyway, before warned, if you see something weird like that, you can click abort and it may or may not give you some error information. But anyway, at that point you're going to have a driver file, you can get into MATLAB, you can go through and run everything by hand, like we were talking about earlier, right? So when you encounter an error, which you're likely to, in your MATLAB script, then you need to get in and try to run it with a driver file by hand and figure out what's wrong. If you can get it to run properly with the driver file just like this morning, then you're home free. Then you go back to Rapture and try it and everything should work fine. If you want to run it by hand, when you have a driver file, make sure you say use Rapture, make sure you've got use matlab or use Octave, and then you can type in something like this. You can type matlab-r, setting the variable in file equal to the driver file, this is sort of like the way Rapture would run it if you looked inside the tool.xml, or you could fire up matlab, you could set the variable in file equals to the name of the driver file, and then you could just run it by hand, either way. But what we're trying to do is we're trying to set this in file equal to the driver file, and then we're trying to run the script. So if you need to debug, that's how you do it. In Octave, you do something similar. You'd say Octave and set the in file to the driver file, and then keep going from there. That in file thing that I'm telling you about, if you look back in your script, in this script near the top of this main.m, you'll see that it's looking for a variable called in file, that's the name of the driver file. So there's no magic, you can look in the skeleton file and see that. Alright. So, here is your next lab assignment. You guys are experts now in Spirograph theory. So you have the code for the Spirograph. What we want to do is we want to build a Rapture interface for Spirograph, and this Spirograph is going to take three numbers, N1, N2, and N3. Use numbers, not integers, because you might want to type in a value like 13.2 in this case, and it's actually allowed. You can type in any real number. It doesn't have to be an integer. So use three numbers, and then those will be your N1, N2, and N3, and then at the end you're going to produce a curve for the output. So your first step is to get into the builder, to put in three numbers and an output curve, to save all that as the tool.xml, generate your main skeleton script, and then you're going to go back to the skeleton script, and you're going to stick this code right in the middle of the skeleton script. And if you do everything right, it'll work like a dream. All right, well let me show you the solution now that I have for this assignment number four. We want to build a tool in Rapture that takes this MATLAB octave code that we're showing here, and we want to build it into a tool with Rapture, where you can have the user specify inputs and generate the curves. So let me show you. Here we are in the workspace, and I can start up octave, and I can run my spirograph script, and it pops up a little plot, and I use these values for N1 and N2 and N3. If we look at the script, again, no big magic, I'm just setting N1, N2, N3, and then I'm using the three lines of code that I showed you for the lab exercise to do the plot. So the trick now is to take that script and convert it into a Rapture tool. So I'm going to make a directory EX4, and CD to that directory, and then I'm going to run the builder, Rapture-builder. And for this particular tool, it takes three numbers, so I'm going to drag the number control over three times for the three different numbers. So it takes the three numbers, N1, N2, N3, and then I'm going to produce a curve as the output result. All right, so those are the things I need in Rapture. And now I just fix up all the controls. I'm going to rename this number N1, because that's the variable I want to call it in the program. In fact, I'm even going to label it N1, and I'll call it first coefficient. And I'll give it a default value, for example, of 13. Then I'll go to the next number, and I'll rename it to N2, and I'll set the label on the screen also to N2, and I'll call it second coefficient. COFFC-IENT. And then negative six, and the third element, label N3. Call it N3 on the screen. Give it a number N3. That's the third coefficient, and give it a default value of six, I guess, or something. And then on the output side, I'll call this one Z, and I'll give it a label Spirograph. And give it a description. For the x-axis label, I'll call it real of Z, and if I scroll down, there's also a y-axis label for image of Z. And now let's take a look at the preview. Preview says, ah, dang, there's five warnings for the current tool definition. Examine and resolve yes, and it'll walk me through and show me everything I forgot or I should set. It's telling me I should have a title for this tool, so I'll call it Spirograph tool. And then I say next. It tells me I need a description for the tool too, yeah. Solution for, oops, for lab number four, and then next. And then it tells me I have to choose the program. This is sort of a MATLAB thing. I'm going to use the active GNU free clone of MATLAB instead. Alright, so I've fixed those things. I'll say preview. There's still two more warnings. Oh, dang. I think they're just axis label warnings. Yeah, it's bugging me about the x-axis description and about the y-axis description. Really, I should fill those in. But I'll just flip to preview and ignore them and looks pretty good overall. So I'm going to go ahead and save this now, even though there are two warnings. That's okay. I'll save the tool.xml and I'll save a skeleton program that I want to generate in Octave. No need for a make file with Octave. So I'll save those two files from the builder. Now you can see I've got the two files. Now the trick is I go into the main program, main.m. This is generated by the Rapture builder. And I have these three numbers, n1, n2, and n3 all set up there. And it says add your code here for the main body of the program. So I'm going to go ahead and add that code in from my previous script. So I'll get rid of these progress statements. My program won't take long to run. And I'm going to load in that Spyro.m script that we were running just a minute ago. All right, so that's the script. That script had n1, n2, and n3 hard coded. But now I'm going to get n1 and n2 and n3 from Rapture. So I don't need those three statements. I'll just delete those. And fortunately, I was smart enough to call my Rapture inputs n1 and n2 and n3. So we're all set to go there. My script also had a plot statement. And I don't need that. Instead of a plot statement, I'm going to do the output thing in Rapture. And you can see here there's this variable x, y data composed of x and y. So really, I just need to define what x and y is. I'm going to say x equals real of z and y equals image of z. And then now I don't need the plot statement and everything connects up. So that's pretty good. Now I've got my output here that's all connected up. Actually, if I didn't want those extra variables x and y, I could also just do this. I could just say real of z like that and image of z like that. I could plug those in right directly in place of x and y. And now I don't need those two vectors. It's a little shorter that way. So I've got my t and my z. That's basically the meat of my program. And then the z vector is being converted into the real part and the imaginary part, which goes into the output curve that I want to generate. So I'm going to save that now. And now if I run it in Rapture, it'll bring up the interface that I just created. It'll have some default values. And I can click simulate and it'll generate a case. I can try something different, minus 7, and simulate. It'll generate another case. And I can try 2 and 18 and minus 3 and set those values and simulate. And I get yet another case. So now I can use Rapture to call my program with all these different values, getting kind of interesting shapes along the way. So now anyone can run my script and they can plug in lots of different values for Spirograph. Thank you.
 Online simulation and more for nanotechnology.  All right.  This last section now we're going to put everything all together.  So you've learned a little bit about Rapture.  You've learned a little bit about MATLAB.  Now I'm going to show you how to build a MATLAB application that has a Rapture interface on it.  So suppose you already have a MATLAB program that somebody else wrote, your advisor wrote.  I wouldn't be surprised if he hands you a.m file tomorrow and says,  here's the program. Put it up on Nano Hub.  You might run it like this. If I had this Fermi.m script, I could run matlab-no-display-rfermi.  And it might do all that stuff.  Remember I showed you a few minutes ago the disk function to display a prompt input, all that stuff.  So that's what this program is going to do.  It's going to ask me to enter a Fermi level and I'm going to type in 2.4  and it's going to tell me to enter the temperature and I'm going to type in 77.  And then it's going to run and when it's all done, this program produces a file called out.dat  that has all this data in it.  So that's like the program that your advisor is going to give you or you're cell,  whoever's in the next cubicle, that's the program they have.  And what you want to do is take that program and turn it into a Rapture interface.  If we do it in Rapture, it'll look like this.  Instead of some 1970s looking thing like this, it'll have a nice graphical interface with some input controls  and some curves and you'll be able to plot multiple cases and all of that.  And by the way, this example that we're going to be walking through is actually in the Rapture examples directory.  If you look in the Rapture project on Nano Hub, you can find all these different examples.  In fact, this Fermi example, we do in all the languages.  So if you want to see what the Fermi function looks in Python and how it looks in C language and Fortran,  in this case we're looking at the version that's all in MATLAB.  So let's walk through it.  If you go into that directory and you take a look at the Fermi.m script, it looks like this.  This is a standard kind of MATLAB thing.  It starts out with the DISP function and the INPUT function because you got to get a value in for EF.  And then the DISP and the INPUT function for T because you need a value for T.  And then at the end of it, you can see it does some stuff in the middle and at the bottom,  it opens up the file and it writes out a bunch of stuff and then it quits.  So basically the top is where it's getting all its input values.  The bottom was where it's writing out all the results and in between, there's a little bit of physics.  Just about any program that you look at, you can kind of see that way.  So those first two lines are that number, these next two lines are that number,  and this bottom part basically is sort of like the curve that you would get in Rapture.  So there's sort of one-to-one correspondence.  Whenever I look at a program like this, it's always funny to me because usually about half the code  in the program is related to the inputs and the outputs.  People spend all the time trying to come up with fancy parsers and all their own plotting routines and all of that stuff,  which is great if you guys like GUI programming.  But if you just want to make a tool that works, you really want to focus all your effort on the middle part,  which is where the physics is.  So the little bit of code in the middle is where the action is,  and you can really help Rapture use Rapture to take care of the rest of the stuff.  Alright, so that's what we're going to do.  Suppose we go into the Rapture builder and we want to do the same thing,  but that instead of using input and output and all that stuff,  we'll go into Rapture and we'll grab a number control off the left-hand side,  drag and drop that into the input section.  And if you look at the number, we can give it a label of ambient temperature,  we can give it a nice description for the tool tip, a default value,  remember everything should have a good default value.  A number control in Rapture is like a double precision value,  so I can set 297.5 degrees Kelvin.  A number also has units.  See the units of measurement right there.  You can set the default units to be Kelvin, Fahrenheit, Centigrade, whatever,  and Rapture's smart about units.  It knows that Kelvin and Fahrenheit and Centigrade are all temperature,  so it knows how to do units conversion.  So you can say, well, I prefer Kelvin, but my user can type in whatever they want,  whatever their favorite units are.  So we're going to go ahead and make Kelvin the standard units,  but again, any temperature units will work.  And you can also set min-max values on that.  So for example, you guys know, you might know from physics,  you can't go below zero degrees Kelvin.  Zero degrees Kelvin is absolute zero.  It's the coldest possible temperature.  I don't know what happens.  I think the whole universe like rewinds if you go lower than zero degrees Kelvin.  It's not allowed.  So we can't let our users simulate lower than zero degrees Kelvin either  because the simulator undoubtedly will core dump.  So we can set a minimum value of zero degrees Kelvin,  and Rapture will enforce that.  If someone tries to type in negative five, Rapture stops them right up front.  You can also set a maximum value.  500 Kelvin is pretty hot.  It's not a million degrees Kelvin, which is like the sun or something,  but it's pretty hot.  And there's a good chance that above 500 Kelvin, my simulator is going to core dump.  So I want to make sure my simulator doesn't core dump.  I'll just put in a maximum of 500 Kelvin there.  If there is no maximum for your simulator, then don't specify a max.  You don't have to have a min or a max value.  Those just help you guard against bad values.  So I can define the temperature that way.  That's one control.  I can define the next one.  The next one is my Fermi energy.  I'll label it Fermi level.  That's what the physicists call it.  It's the energy at the center of the Fermi distribution.  If you know what the heck that is, it's all this statistical probability quantum mechanics stuff.  I give it a good default value, zero electron volts.  And the units in this case are units of energy.  Electron volts are joules, are units of energy.  And Rapture knows about both of them.  So I'll set EV is pretty good.  Most people are comfortable with that.  I'll set EV as the units of measurement.  And again, I can set a min and a max value.  I can say it really doesn't make sense to go lower than 10, minus 10 EV, or higher than 10 EV.  But if it does make sense, then just leave those off.  You notice there's a few other options.  You can set an icon and there's stuff like that if you want to mess around with it.  Kind of dress up your interface.  All right.  Now last but not least, I take the curve object and I drag that over onto the output side.  And then I specify everything I know about it.  So what is this curve?  The curve that I'm producing is the Fermi-Dirac factor.  It's really great to give a good description to these things.  Because when your user hits the program, they're going to be like, what the heck is the Fermi-Dirac factor?  Like how many of you guys, come on, fess up, how many of you actually knew what the Fermi-Dirac factor was?  Nobody, right?  See, I know you're telling the truth now.  It's not just that it's after lunch and you're shy about raising your hand.  Because yeah, of course you don't know what the Fermi-Dirac factor is.  It's a very esoteric concept.  When you build tools, everything you put in your tool is going to be confusing to some user.  Because they haven't spent any time learning your area.  It's not that they're stupid, but they just don't know anything about this, right?  So this Fermi thing, there are even physicists out there, I might use a different nomenclature.  You know, I may say Fermi function and they say, well, which one?  Fermi-Dirac factor of order one half or what?  Right?  So you got to be specific about this stuff so that people can understand what you're simulating and what it means.  So you should always have some pretty good description that goes along with all your parts.  Also, we can specify the axes.  The x-axis is going to be the Fermi function, actually, and the y-axis here is energy.  That's a little weird compared to most of your x-y plots, but that's the way I'm plotting it here.  So kind of tilted the way you might think of it otherwise.  And you can specify descriptions and everything for the x and the y-axis.  And you notice units, you notice my y-axis has units of electron volts.  You can specify the units and all that.  So that all goes to the plot.  All right, now on the tool side, there are a few more things to set.  Remember in the builder, we always set a title and some description and then the language, octave.  So I'm going to use octave for this example.  All right, now let's take a look.  Remember when I save out of the builder, it's going to automatically generate my skeleton file, my main.m.  And if I take a look at the main.m that got generated, what I really want to do where it says,  add your code here for the main body of your program.  I want to go back to that script I showed you at the beginning.  I want to take that chunk of code and stick it in there.  That's relevant.  So there's my chunk of physics code.  That's what I want to stick in the middle there.  And if you look at that physics code, it's using variables called EF and T.  Those are my inputs.  So if I'm clever about naming things or figuring out how it gets hooked up,  when I created the control inside my Rapture builder, I called it temperature.  So temperature is the same as what I was calling T in my other script.  I have to kind of figure that out.  The variable that I'm calling it in the builder versus what I'm calling it in my code,  I've got to make sure those are matched up.  And similarly, on the output side, my program produces vectors E and F.  And down here, the builder was calling it X and Y.  So I've got to match that up.  Somehow I've got to say X equals E and Y equals F,  or I've got to substitute E and F in there or something.  I've got to match that up to make it fit.  So if I take that code and stick it in the middle of my skeleton program,  and if I change the variable names to match one place or the other,  to make it all match up, then everything will work.  So this is the way I'm doing it here.  I basically stuck the code in and I renamed the T there to temperature,  and I stuck in F and E on the X, Y data.  And everything else then fits.  Everything else will work.  So now you remember how this works.  I've got a tool.xml, and when I run Rapture,  Rapture reads the tool.xml, and in this case, creates the two inputs,  the temperature and the Fermi level.  And when I click on simulate, it produces the driver file.  Driver file is a copy of the tool.xml, but it has the current values.  It runs my code, which has the physics in there,  and then produces a run file.  And the run file has a curve in it, and you can see all the X, Y values in the curve.  That's the data that I generated.  So that's how it works, right?  And then it plots it.  And then it whisks that file away and stores it in your results directory, right?  All right, one last thing I'll tell you before we get you going on your next lab assignment.  Every once in a while, MATLAB, when it goes wrong, it kind of does weird things.  If something goes wrong inside your script, you might see it looking,  it like kind of hang here and kind of freeze,  and you'll see something weird like the backslash A and the greater than or greater than  or something weird like that.  Usually what happens, MATLAB at this point hit an error and is now waiting,  goes into interactive mode and it's waiting for you to type something.  And Rapture is waiting for MATLAB to finish,  and MATLAB is waiting for you to type something, right?  So you're kind of stuck in a deadlock.  So if you see something like this, if you're running and it seems like it's taking forever,  and it's like, looks weird, it could be that MATLAB is kind of broken and is waiting in this deadlock.  I think Octave is slightly better behaved.  The other thing about MATLAB is that sometimes it does weird things to your terminal.  When this happens and then you go back to your X term and you try to type,  nothing types anymore on your terminal.  MATLAB does screwy things to your terminal.  So anyway, before warned, if you see something weird like that,  you can click abort and it may or may not give you some error information.  But anyway, at that point you're going to have a driver file,  you can get into MATLAB, you can go through and run everything by hand,  like we were talking about earlier, right?  So when you encounter an error, which you're likely to, in your MATLAB script,  then you need to get in and try to run it with a driver file by hand and figure out what's wrong.  If you can get it to run properly with the driver file just like this morning,  then you're home free. Then you go back to Rapture and try it and everything should work fine.  If you want to run it by hand, when you have a driver file,  make sure you say use Rapture, make sure you've got use matlab or use Octave,  and then you can type in something like this.  You can type matlab-r, setting the variable in file equal to the driver file,  this is sort of like the way Rapture would run it if you looked inside the tool.xml,  or you could fire up matlab, you could set the variable in file equals to the name of the driver file,  and then you could just run it by hand, either way.  But what we're trying to do is we're trying to set this in file equal to the driver file,  and then we're trying to run the script.  So if you need to debug, that's how you do it.  In Octave, you do something similar. You'd say Octave and set the in file to the driver file,  and then keep going from there.  That in file thing that I'm telling you about, if you look back in your script,  in this script near the top of this main.m, you'll see that it's looking for a variable called in file,  that's the name of the driver file.  So there's no magic, you can look in the skeleton file and see that.  Alright.  So, here is your next lab assignment.  You guys are experts now in Spirograph theory.  So you have the code for the Spirograph.  What we want to do is we want to build a Rapture interface for Spirograph,  and this Spirograph is going to take three numbers, N1, N2, and N3.  Use numbers, not integers, because you might want to type in a value like 13.2 in this case,  and it's actually allowed.  You can type in any real number. It doesn't have to be an integer.  So use three numbers, and then those will be your N1, N2, and N3,  and then at the end you're going to produce a curve for the output.  So your first step is to get into the builder, to put in three numbers and an output curve,  to save all that as the tool.xml, generate your main skeleton script,  and then you're going to go back to the skeleton script,  and you're going to stick this code right in the middle of the skeleton script.  And if you do everything right, it'll work like a dream.  All right, well let me show you the solution now that I have for this assignment number four.  We want to build a tool in Rapture that takes this MATLAB octave code that we're showing here,  and we want to build it into a tool with Rapture, where you can have the user specify inputs  and generate the curves.  So let me show you.  Here we are in the workspace, and I can start up octave,  and I can run my spirograph script,  and it pops up a little plot, and I use these values for N1 and N2 and N3.  If we look at the script, again, no big magic, I'm just setting N1, N2, N3,  and then I'm using the three lines of code that I showed you for the lab exercise to do the plot.  So the trick now is to take that script and convert it into a Rapture tool.  So I'm going to make a directory EX4, and CD to that directory,  and then I'm going to run the builder, Rapture-builder.  And for this particular tool, it takes three numbers,  so I'm going to drag the number control over three times for the three different numbers.  So it takes the three numbers, N1, N2, N3, and then I'm going to produce a curve as the output result.  All right, so those are the things I need in Rapture.  And now I just fix up all the controls.  I'm going to rename this number N1, because that's the variable I want to call it in the program.  In fact, I'm even going to label it N1, and I'll call it first coefficient.  And I'll give it a default value, for example, of 13.  Then I'll go to the next number, and I'll rename it to N2,  and I'll set the label on the screen also to N2, and I'll call it second coefficient.  COFFC-IENT.  And then negative six, and the third element, label N3.  Call it N3 on the screen. Give it a number N3.  That's the third coefficient, and give it a default value of six, I guess, or something.  And then on the output side, I'll call this one Z, and I'll give it a label Spirograph.  And give it a description.  For the x-axis label, I'll call it real of Z, and if I scroll down, there's also a y-axis label for image of Z.  And now let's take a look at the preview.  Preview says, ah, dang, there's five warnings for the current tool definition.  Examine and resolve yes, and it'll walk me through and show me everything I forgot or I should set.  It's telling me I should have a title for this tool, so I'll call it Spirograph tool.  And then I say next. It tells me I need a description for the tool too, yeah.  Solution for, oops, for lab number four, and then next.  And then it tells me I have to choose the program.  This is sort of a MATLAB thing. I'm going to use the active GNU free clone of MATLAB instead.  Alright, so I've fixed those things. I'll say preview. There's still two more warnings.  Oh, dang. I think they're just axis label warnings.  Yeah, it's bugging me about the x-axis description and about the y-axis description.  Really, I should fill those in.  But I'll just flip to preview and ignore them and looks pretty good overall.  So I'm going to go ahead and save this now, even though there are two warnings. That's okay.  I'll save the tool.xml and I'll save a skeleton program that I want to generate in Octave.  No need for a make file with Octave.  So I'll save those two files from the builder.  Now you can see I've got the two files.  Now the trick is I go into the main program, main.m.  This is generated by the Rapture builder.  And I have these three numbers, n1, n2, and n3 all set up there.  And it says add your code here for the main body of the program.  So I'm going to go ahead and add that code in from my previous script.  So I'll get rid of these progress statements.  My program won't take long to run.  And I'm going to load in that Spyro.m script that we were running just a minute ago.  All right, so that's the script. That script had n1, n2, and n3 hard coded.  But now I'm going to get n1 and n2 and n3 from Rapture.  So I don't need those three statements.  I'll just delete those.  And fortunately, I was smart enough to call my Rapture inputs n1 and n2 and n3.  So we're all set to go there.  My script also had a plot statement.  And I don't need that.  Instead of a plot statement, I'm going to do the output thing in Rapture.  And you can see here there's this variable x, y data composed of x and y.  So really, I just need to define what x and y is.  I'm going to say x equals real of z and y equals image of z.  And then now I don't need the plot statement and everything connects up.  So that's pretty good.  Now I've got my output here that's all connected up.  Actually, if I didn't want those extra variables x and y, I could also just do this.  I could just say real of z like that and image of z like that.  I could plug those in right directly in place of x and y.  And now I don't need those two vectors.  It's a little shorter that way.  So I've got my t and my z.  That's basically the meat of my program.  And then the z vector is being converted into the real part and the imaginary part,  which goes into the output curve that I want to generate.  So I'm going to save that now.  And now if I run it in Rapture, it'll bring up the interface that I just created.  It'll have some default values.  And I can click simulate and it'll generate a case.  I can try something different, minus 7, and simulate.  It'll generate another case.  And I can try 2 and 18 and minus 3 and set those values and simulate.  And I get yet another case.  So now I can use Rapture to call my program with all these different values,  getting kind of interesting shapes along the way.  So now anyone can run my script and they can plug in lots of different values for Spirograph.  Thank you.
Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_0_215.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_216_623.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_624_2219.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_2220_3167.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_3168_4079.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_4080_4295.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_4296_5303.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_5304_12191.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_12192_12527.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_12528_15251.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_15252_15659.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_15660_15791.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_15792_15863.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_15864_16415.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_16416_18827.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_18828_18935.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_18936_20039.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_20040_20495.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_20496_21887.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_21888_22391.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_22392_23015.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_23016_23075.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_23076_23471.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_23472_26483.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_26484_27359.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_27360_27455.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_27456_27671.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_27672_29279.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_29280_29339.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_29340_30347.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_30348_30407.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_30408_31295.png Rappture_Bootcamp_1_4__Adding_Rappture_to_MATLAB_Applications_31296_32465.png
Online simulation and more for nanotechnology. All right. This last section now we're going to put everything all together. So you've learned a little bit about Rapture. You've learned a little bit about MATLAB. Now I'm going to show you how to build a MATLAB application that has a Rapture interface on it. So suppose you already have a MATLAB program that somebody else wrote, your advisor wrote. I wouldn't be surprised if he hands you a.m file tomorrow and says, here's the program. Put it up on Nano Hub. You might run it like this. If I had this Fermi.m script, I could run matlab-no-display-rfermi. And it might do all that stuff. Remember I showed you a few minutes ago the disk function to display a prompt input, all that stuff. So that's what this program is going to do. It's going to ask me to enter a Fermi level and I'm going to type in 2.4 and it's going to tell me to enter the temperature and I'm going to type in 77. And then it's going to run and when it's all done, this program produces a file called out.dat that has all this data in it. So that's like the program that your advisor is going to give you or you're cell, whoever's in the next cubicle, that's the program they have. And what you want to do is take that program and turn it into a Rapture interface. If we do it in Rapture, it'll look like this. Instead of some 1970s looking thing like this, it'll have a nice graphical interface with some input controls and some curves and you'll be able to plot multiple cases and all of that. And by the way, this example that we're going to be walking through is actually in the Rapture examples directory. If you look in the Rapture project on Nano Hub, you can find all these different examples. In fact, this Fermi example, we do in all the languages. So if you want to see what the Fermi function looks in Python and how it looks in C language and Fortran, in this case we're looking at the version that's all in MATLAB. So let's walk through it. If you go into that directory and you take a look at the Fermi.m script, it looks like this. This is a standard kind of MATLAB thing. It starts out with the DISP function and the INPUT function because you got to get a value in for EF. And then the DISP and the INPUT function for T because you need a value for T. And then at the end of it, you can see it does some stuff in the middle and at the bottom, it opens up the file and it writes out a bunch of stuff and then it quits. So basically the top is where it's getting all its input values. The bottom was where it's writing out all the results and in between, there's a little bit of physics. Just about any program that you look at, you can kind of see that way. So those first two lines are that number, these next two lines are that number, and this bottom part basically is sort of like the curve that you would get in Rapture. So there's sort of one-to-one correspondence. Whenever I look at a program like this, it's always funny to me because usually about half the code in the program is related to the inputs and the outputs. People spend all the time trying to come up with fancy parsers and all their own plotting routines and all of that stuff, which is great if you guys like GUI programming. But if you just want to make a tool that works, you really want to focus all your effort on the middle part, which is where the physics is. So the little bit of code in the middle is where the action is, and you can really help Rapture use Rapture to take care of the rest of the stuff. Alright, so that's what we're going to do. Suppose we go into the Rapture builder and we want to do the same thing, but that instead of using input and output and all that stuff, we'll go into Rapture and we'll grab a number control off the left-hand side, drag and drop that into the input section. And if you look at the number, we can give it a label of ambient temperature, we can give it a nice description for the tool tip, a default value, remember everything should have a good default value. A number control in Rapture is like a double precision value, so I can set 297.5 degrees Kelvin. A number also has units. See the units of measurement right there. You can set the default units to be Kelvin, Fahrenheit, Centigrade, whatever, and Rapture's smart about units. It knows that Kelvin and Fahrenheit and Centigrade are all temperature, so it knows how to do units conversion. So you can say, well, I prefer Kelvin, but my user can type in whatever they want, whatever their favorite units are. So we're going to go ahead and make Kelvin the standard units, but again, any temperature units will work. And you can also set min-max values on that. So for example, you guys know, you might know from physics, you can't go below zero degrees Kelvin. Zero degrees Kelvin is absolute zero. It's the coldest possible temperature. I don't know what happens. I think the whole universe like rewinds if you go lower than zero degrees Kelvin. It's not allowed. So we can't let our users simulate lower than zero degrees Kelvin either because the simulator undoubtedly will core dump. So we can set a minimum value of zero degrees Kelvin, and Rapture will enforce that. If someone tries to type in negative five, Rapture stops them right up front. You can also set a maximum value. 500 Kelvin is pretty hot. It's not a million degrees Kelvin, which is like the sun or something, but it's pretty hot. And there's a good chance that above 500 Kelvin, my simulator is going to core dump. So I want to make sure my simulator doesn't core dump. I'll just put in a maximum of 500 Kelvin there. If there is no maximum for your simulator, then don't specify a max. You don't have to have a min or a max value. Those just help you guard against bad values. So I can define the temperature that way. That's one control. I can define the next one. The next one is my Fermi energy. I'll label it Fermi level. That's what the physicists call it. It's the energy at the center of the Fermi distribution. If you know what the heck that is, it's all this statistical probability quantum mechanics stuff. I give it a good default value, zero electron volts. And the units in this case are units of energy. Electron volts are joules, are units of energy. And Rapture knows about both of them. So I'll set EV is pretty good. Most people are comfortable with that. I'll set EV as the units of measurement. And again, I can set a min and a max value. I can say it really doesn't make sense to go lower than 10, minus 10 EV, or higher than 10 EV. But if it does make sense, then just leave those off. You notice there's a few other options. You can set an icon and there's stuff like that if you want to mess around with it. Kind of dress up your interface. All right. Now last but not least, I take the curve object and I drag that over onto the output side. And then I specify everything I know about it. So what is this curve? The curve that I'm producing is the Fermi-Dirac factor. It's really great to give a good description to these things. Because when your user hits the program, they're going to be like, what the heck is the Fermi-Dirac factor? Like how many of you guys, come on, fess up, how many of you actually knew what the Fermi-Dirac factor was? Nobody, right? See, I know you're telling the truth now. It's not just that it's after lunch and you're shy about raising your hand. Because yeah, of course you don't know what the Fermi-Dirac factor is. It's a very esoteric concept. When you build tools, everything you put in your tool is going to be confusing to some user. Because they haven't spent any time learning your area. It's not that they're stupid, but they just don't know anything about this, right? So this Fermi thing, there are even physicists out there, I might use a different nomenclature. You know, I may say Fermi function and they say, well, which one? Fermi-Dirac factor of order one half or what? Right? So you got to be specific about this stuff so that people can understand what you're simulating and what it means. So you should always have some pretty good description that goes along with all your parts. Also, we can specify the axes. The x-axis is going to be the Fermi function, actually, and the y-axis here is energy. That's a little weird compared to most of your x-y plots, but that's the way I'm plotting it here. So kind of tilted the way you might think of it otherwise. And you can specify descriptions and everything for the x and the y-axis. And you notice units, you notice my y-axis has units of electron volts. You can specify the units and all that. So that all goes to the plot. All right, now on the tool side, there are a few more things to set. Remember in the builder, we always set a title and some description and then the language, octave. So I'm going to use octave for this example. All right, now let's take a look. Remember when I save out of the builder, it's going to automatically generate my skeleton file, my main.m. And if I take a look at the main.m that got generated, what I really want to do where it says, add your code here for the main body of your program. I want to go back to that script I showed you at the beginning. I want to take that chunk of code and stick it in there. That's relevant. So there's my chunk of physics code. That's what I want to stick in the middle there. And if you look at that physics code, it's using variables called EF and T. Those are my inputs. So if I'm clever about naming things or figuring out how it gets hooked up, when I created the control inside my Rapture builder, I called it temperature. So temperature is the same as what I was calling T in my other script. I have to kind of figure that out. The variable that I'm calling it in the builder versus what I'm calling it in my code, I've got to make sure those are matched up. And similarly, on the output side, my program produces vectors E and F. And down here, the builder was calling it X and Y. So I've got to match that up. Somehow I've got to say X equals E and Y equals F, or I've got to substitute E and F in there or something. I've got to match that up to make it fit. So if I take that code and stick it in the middle of my skeleton program, and if I change the variable names to match one place or the other, to make it all match up, then everything will work. So this is the way I'm doing it here. I basically stuck the code in and I renamed the T there to temperature, and I stuck in F and E on the X, Y data. And everything else then fits. Everything else will work. So now you remember how this works. I've got a tool.xml, and when I run Rapture, Rapture reads the tool.xml, and in this case, creates the two inputs, the temperature and the Fermi level. And when I click on simulate, it produces the driver file. Driver file is a copy of the tool.xml, but it has the current values. It runs my code, which has the physics in there, and then produces a run file. And the run file has a curve in it, and you can see all the X, Y values in the curve. That's the data that I generated. So that's how it works, right? And then it plots it. And then it whisks that file away and stores it in your results directory, right? All right, one last thing I'll tell you before we get you going on your next lab assignment. Every once in a while, MATLAB, when it goes wrong, it kind of does weird things. If something goes wrong inside your script, you might see it looking, it like kind of hang here and kind of freeze, and you'll see something weird like the backslash A and the greater than or greater than or something weird like that. Usually what happens, MATLAB at this point hit an error and is now waiting, goes into interactive mode and it's waiting for you to type something. And Rapture is waiting for MATLAB to finish, and MATLAB is waiting for you to type something, right? So you're kind of stuck in a deadlock. So if you see something like this, if you're running and it seems like it's taking forever, and it's like, looks weird, it could be that MATLAB is kind of broken and is waiting in this deadlock. I think Octave is slightly better behaved. The other thing about MATLAB is that sometimes it does weird things to your terminal. When this happens and then you go back to your X term and you try to type, nothing types anymore on your terminal. MATLAB does screwy things to your terminal. So anyway, before warned, if you see something weird like that, you can click abort and it may or may not give you some error information. But anyway, at that point you're going to have a driver file, you can get into MATLAB, you can go through and run everything by hand, like we were talking about earlier, right? So when you encounter an error, which you're likely to, in your MATLAB script, then you need to get in and try to run it with a driver file by hand and figure out what's wrong. If you can get it to run properly with the driver file just like this morning, then you're home free. Then you go back to Rapture and try it and everything should work fine. If you want to run it by hand, when you have a driver file, make sure you say use Rapture, make sure you've got use matlab or use Octave, and then you can type in something like this. You can type matlab-r, setting the variable in file equal to the driver file, this is sort of like the way Rapture would run it if you looked inside the tool.xml, or you could fire up matlab, you could set the variable in file equals to the name of the driver file, and then you could just run it by hand, either way. But what we're trying to do is we're trying to set this in file equal to the driver file, and then we're trying to run the script. So if you need to debug, that's how you do it. In Octave, you do something similar. You'd say Octave and set the in file to the driver file, and then keep going from there. That in file thing that I'm telling you about, if you look back in your script, in this script near the top of this main.m, you'll see that it's looking for a variable called in file, that's the name of the driver file. So there's no magic, you can look in the skeleton file and see that. Alright. So, here is your next lab assignment. You guys are experts now in Spirograph theory. So you have the code for the Spirograph. What we want to do is we want to build a Rapture interface for Spirograph, and this Spirograph is going to take three numbers, N1, N2, and N3. Use numbers, not integers, because you might want to type in a value like 13.2 in this case, and it's actually allowed. You can type in any real number. It doesn't have to be an integer. So use three numbers, and then those will be your N1, N2, and N3, and then at the end you're going to produce a curve for the output. So your first step is to get into the builder, to put in three numbers and an output curve, to save all that as the tool.xml, generate your main skeleton script, and then you're going to go back to the skeleton script, and you're going to stick this code right in the middle of the skeleton script. And if you do everything right, it'll work like a dream. All right, well let me show you the solution now that I have for this assignment number four. We want to build a tool in Rapture that takes this MATLAB octave code that we're showing here, and we want to build it into a tool with Rapture, where you can have the user specify inputs and generate the curves. So let me show you. Here we are in the workspace, and I can start up octave, and I can run my spirograph script, and it pops up a little plot, and I use these values for N1 and N2 and N3. If we look at the script, again, no big magic, I'm just setting N1, N2, N3, and then I'm using the three lines of code that I showed you for the lab exercise to do the plot. So the trick now is to take that script and convert it into a Rapture tool. So I'm going to make a directory EX4, and CD to that directory, and then I'm going to run the builder, Rapture-builder. And for this particular tool, it takes three numbers, so I'm going to drag the number control over three times for the three different numbers. So it takes the three numbers, N1, N2, N3, and then I'm going to produce a curve as the output result. All right, so those are the things I need in Rapture. And now I just fix up all the controls. I'm going to rename this number N1, because that's the variable I want to call it in the program. In fact, I'm even going to label it N1, and I'll call it first coefficient. And I'll give it a default value, for example, of 13. Then I'll go to the next number, and I'll rename it to N2, and I'll set the label on the screen also to N2, and I'll call it second coefficient. COFFC-IENT. And then negative six, and the third element, label N3. Call it N3 on the screen. Give it a number N3. That's the third coefficient, and give it a default value of six, I guess, or something. And then on the output side, I'll call this one Z, and I'll give it a label Spirograph. And give it a description. For the x-axis label, I'll call it real of Z, and if I scroll down, there's also a y-axis label for image of Z. And now let's take a look at the preview. Preview says, ah, dang, there's five warnings for the current tool definition. Examine and resolve yes, and it'll walk me through and show me everything I forgot or I should set. It's telling me I should have a title for this tool, so I'll call it Spirograph tool. And then I say next. It tells me I need a description for the tool too, yeah. Solution for, oops, for lab number four, and then next. And then it tells me I have to choose the program. This is sort of a MATLAB thing. I'm going to use the active GNU free clone of MATLAB instead. Alright, so I've fixed those things. I'll say preview. There's still two more warnings. Oh, dang. I think they're just axis label warnings. Yeah, it's bugging me about the x-axis description and about the y-axis description. Really, I should fill those in. But I'll just flip to preview and ignore them and looks pretty good overall. So I'm going to go ahead and save this now, even though there are two warnings. That's okay. I'll save the tool.xml and I'll save a skeleton program that I want to generate in Octave. No need for a make file with Octave. So I'll save those two files from the builder. Now you can see I've got the two files. Now the trick is I go into the main program, main.m. This is generated by the Rapture builder. And I have these three numbers, n1, n2, and n3 all set up there. And it says add your code here for the main body of the program. So I'm going to go ahead and add that code in from my previous script. So I'll get rid of these progress statements. My program won't take long to run. And I'm going to load in that Spyro.m script that we were running just a minute ago. All right, so that's the script. That script had n1, n2, and n3 hard coded. But now I'm going to get n1 and n2 and n3 from Rapture. So I don't need those three statements. I'll just delete those. And fortunately, I was smart enough to call my Rapture inputs n1 and n2 and n3. So we're all set to go there. My script also had a plot statement. And I don't need that. Instead of a plot statement, I'm going to do the output thing in Rapture. And you can see here there's this variable x, y data composed of x and y. So really, I just need to define what x and y is. I'm going to say x equals real of z and y equals image of z. And then now I don't need the plot statement and everything connects up. So that's pretty good. Now I've got my output here that's all connected up. Actually, if I didn't want those extra variables x and y, I could also just do this. I could just say real of z like that and image of z like that. I could plug those in right directly in place of x and y. And now I don't need those two vectors. It's a little shorter that way. So I've got my t and my z. That's basically the meat of my program. And then the z vector is being converted into the real part and the imaginary part, which goes into the output curve that I want to generate. So I'm going to save that now. And now if I run it in Rapture, it'll bring up the interface that I just created. It'll have some default values. And I can click simulate and it'll generate a case. I can try something different, minus 7, and simulate. It'll generate another case. And I can try 2 and 18 and minus 3 and set those values and simulate. And I get yet another case. So now I can use Rapture to call my program with all these different values, getting kind of interesting shapes along the way. So now anyone can run my script and they can plug in lots of different values for Spirograph. Thank you.