2.5 Advanced Visualization
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
McLennan, Michael
 Online simulation and more for nanotechnology. In this last section, I want to walk through some of the advanced visualization stuff that's built into Rapture because at this point you can build a pretty functional tool, but we haven't really done much with the output. We've looked at KERS, we've looked at histograms. There's a lot more that you can do on the output side. Suppose that your program produces a molecule. You simulate and part of the thing that it generates is a molecule. Maybe you're doing molecular dynamics calculations. There's a way to do that in Rapture. There's an element called structure and again this isn't built into the builder yet, so I'm again showing you advanced stuff that you can't just drag and drop really easily. But if you can create XML in the output section that looks like this, then you can get a molecule in Rapture, either as an input or as an output. Usually, I guess it could be either in this case. All you need to do is make the right XML. You start with something that's like a structure and it has a current and components and then molecule and then inside there basically atoms that have a symbol and an XYZ coordinate, another atom with a symbol and an XYZ coordinate and so forth. If you can generate that XML in your program, you've got a molecule and Rapture automatically knows how to draw molecules. It automatically connects to a rendering server, talks to a program called PyMol written in Python that does molecular visualization and it'll take your molecule and render it in 3D. There's another way too. After we created that, a lot of people said there's this PDB, Protein Data Bank format. I don't know if you guys know anything about that, but it's a real popular file format. There's a Protein Data Bank site where you can download all of these molecules. If you want the molecular configuration of aspirin, you can find it in the Protein Data Bank along with lots of other things. There's a PDB file format and a lot of people said, well, I don't want to have to convert from PDB into Rapture. We made a way that you can say structure, current, components, molecule and then you can just say PDB and inside the PDB section, you can put something from the Protein Data Bank in there and Rapture knows how to plot that too. If you get something from the Protein Data Bank, shove it in there, boom, you've got a molecule. So how do you do that? In your program, and now again, this is what your run.xml file would look like if you're successful and this is how you actually generate it. And suppose we have a Fortran program. I'm assuming Fortran. We've seen these calls already. The builder does this. The builder adds calls for like RPlib, put string and all that. There's an RPlib, put file command that you can use and you pass in as the first argument the thing that Rapture loads at the beginning. Could be called driver, could be called IO. It's the thing in your program. If we look at an example program, you guys are looking perplexed at me. I think it's the end of the day. So let me show you my example program. So in my Fortran program, if I look at what Rapture generated, in my example program, it was called IO in this program. See just like the builder says RPlib, put string and it automatically generated this text IO and then you put in a path and then you put in what you want to save at that path, the same kind of thing here. And it's called IO because somewhere near the top of your file, see this is RPlib command here that generates that name IO. So if you wanted to do a molecule, right here in your program in the output section, we could add like an RPlib, put file command and we could add in a path output dot, let me stop the example at this point and flip back to my slides. So in that Fortran program, this is what I would have typed. Call RPlib, put file, that same name IO, output dot, mall dot current components molecule dot PDB. Again, that's the way I reference things. It's in the output section. I'm creating this structure called mall. In the current section under components, under molecule, I want to tag PDB and I want to put all my data there. The RPlib, put file looks for a file in this case called data dot PDB. It reads the contents of that file and stuffs it in in your output. So if your program generates a file called data dot PDB, here's how you can take that file and suck it in to your Rapture program. And Rapture will read that file and stuff it in right where the PDB tag is. So if I looked at that file on disk, I'd see all that atom 1C blah blah blah, all that atom stuff that you see up there. That's what's in my file. My program generated that and when I call RPlib, put file and I give it the name of the file, it's going to read that file and stick it in just like you see it up there. If I look in the run dot XML, that's what it looks like after I'm all done. So that's the kind of Fortran code that you'd write to stick some protein data bank stuff in your tool. The one here means compress the data and the zero means overwrite as opposed to append. Oh, I guess if we set compress it wouldn't look exactly like that. It would look like a bunch of compressed gobbledygook. But if I made this zero so that I didn't compress the data, then you'd see it looking like that up there. So just remember, if you ever run across a case where you need to produce a molecule and if you've got that molecule in the protein data bank file format, just remember, oh yeah, there's a slide, I can go back and I'll grab that off the slide and put it in my program. Alright, moving on to show you another thing, another thing that's possible, you can create surface plots like this in your program. A lot of times you'll have a program that generates a bunch of data that you want to see as a mountain plot or a surface plot. And the way you do that, depending on what your data is, your data is usually composed of two things, a mesh and then a bunch of values that sit on the mesh. And a lot of times a mesh might be uniform and rectangular just because it's easy to generate a mesh that way. So Rapture has a thing called the Unirec 2D. It's a two dimensional uniform rectangular mesh, uniform in X or Y but it doesn't have to be uniform everywhere. It's just each axis is uniformly spaced. So this Unirec 2D means that I'm on a rectangular mesh and you can specify the sizes and everything in the mesh and then at each point on the mesh you have a value, a field value. And then if you give Rapture those two things, the field and the mesh, then it will generate the surface, the mountain plot as an output. Let me show you how you do that. Again, if you were looking in your run file at the end of your program in the run file, if you looked in the output section, you'd see something like what I'm showing here. You'd see for example this Unirec 2D with some name, my grid or whatever. It's got a label, energy grid. It's got an X axis section and a Y axis section. The X axis and the Y axis describe the two dimensions of your mesh. The X axis has a label and a min value goes from 0 to 1, max value 1 and it has 50 points. So imagine it starts at 0, it ends at 1 and you divide it into 50 points. Similarly, the Y axis goes from 0 to 1 and it's also got 50 points. It doesn't have to but it could. I mean, it might have 20 points or it might have 70 points but it's going from in this case 0 to 1 with 50 points in X and in Y. I have a label, Fermi Dirac factor and another label, energy and all that. So if I put that information in there in the output section, then you'll see at least a uniform rectangular mesh. I haven't gotten to the field yet but that defines the mesh. Now again, you can hard code this information in your tool.xml. If you know ahead of time everything about your mesh, if you know your mesh is going to always go from 0 to 1 and it's always going to have 50 points and it's always going to have this label and all that, all of this information that you see here, you can hard code into your tool.xml. But you may say, well I don't know how many points I'm going to have. If I simulate in one case I might have 100 points, if I simulate in another case I might have a thousand points, right? I don't know how many points I'm going to have. So you can put a lot of the information in the tool.xml and then you can change it in your program. This is how I would change it in a Python program. I would do the usual Python put command and I would say in the output section, look for a Unirec 2D with the name Migrid, look in the x-axis section for a parameter called Max and give it a value 1.0. So for this run of the program I leave 0 alone but it's going to go to 1.0, actually it didn't change but anyway. So I'm overwriting the value here, pen no. I'm also going into the output section in the Unirec 2D in the x-axis and I'm setting num points to 50 for example and append equals no. So I can hard code that information in the tool.xml and I can overwrite it in my program. Have my program put in the latest values for Max and num points or whatever. So there's kind of a duality between the tool.xml and these program statements that create things in the tool.xml. We saw that in one of the, not the last but the one before, the lab exercised before. We saw how you could create brand new things in the xml just by putting information in there and that's what we're doing here. You could start with most of that information defined and then overwrite selectively whatever values you want or you could create every single bit of one of those information. You could set the about label, you could set the x-axis label, the y-axis label, you could have all kinds of commands here to set all those different labels and set all the various values and that would create that structure. So that's how you define things in the xml like a Unirec 2D. In order to see the field plotted you also have to define a field and this is what the field looks like. The field has an about label, the field has component section and the component has a mesh and values. The mesh that you see here, this mesh right here, this statement in red, this defines that mesh that we were looking at a second ago. When you define a field you have to say which mesh it belongs to. This field goes to this mesh and the mesh says where all the points are in space. So inside the component section you have a mesh output Unirec 2D parentheses migrate. Now I know where all the points are in space and then you specify all the values. At the first mesh point it's this value, at the next mesh point it's this value. You can kind of see here, this is sort of how the values are laid out, v11, v12, v13 and so forth for x and y. And again the way that you would do that if you want to put program field values in, you might hard code a lot of this in your tool.xml, in your tool.xml you might have a field statement with about and label and component and mesh. You probably don't have the values though. The values are something that get generated at run time, right? So most of that information can be in your tool.xml but then your program has to do this. Your program can take a bunch of values, there's a reshape command, I took a matrix z in MATLAB, z tick is the transpose of it, the reshape kind of reshapes it and then the vales makes it so that it's a big long list of numbers. So I'm basically taking my MATLAB matrix and I'm converting it into a big long list of numbers and then I'm stuffing it in using the call rplibputstring in the output section, look for the field named z, see field id equals z right there and then in the component dot value section stick all those values. So this call in MATLAB takes my z matrix and makes a bunch of different numbers and then I put those into the values section to generate the code. So getting a little complicated, you have to kind of work for it. If you want to do all the advanced graphics it's not easy, you've got to work for it. But this is how you do it. You define a lot of the stuff in the tool.xml and then you override things in your program to set the values and kind of tweak it. There's also a way of handling an irregular mesh. Sometimes the world isn't so easy, not everything's on a rectangular mesh. So you might have a bunch of different points and there's something called a cloud mesh in Rapture where you can just specify all the different x, y points. So for the cloud mesh, again, all these things have an about section with the label so you can talk and you can say what that thing is. This is a 2D mesh. A cloud mesh also has units, I said microns. Hide yes, that means I don't want to see the mesh. Usually I just want to see the field. And then you can specify the points. X, Y, New Line. X, Y, New Line. X, Y, New Line. So these are all the points on the mesh. Each point here, each x and y value corresponds to one point on the mesh. So this first line is probably this point and this next line is like this point and so forth. So you can specify all the points on the mesh and then Rapture will read all those points and it will connect them all together and make triangles out of them. So if you have an irregular mesh that looks like this, then you do that in Rapture. And again, how would I do that? Well, in Python here, if I had an x vector and a y vector, there's a zip function that puts them together and for each x, y in x and y vector, it's going to go through and compute and create a string that's x and y and the New Line. So using x and y, substituting in and then I stick those things in. In the output.cloud.point section, I'm going to put in the x and the y and the New Line and append equals yes, which means each time I'm going through this loop, it's adding another x, y, x, y, x, y. So I'm converting x-vec and y-vec into a list of points that show up in the point section. That's what I'm doing. All right. And if I've defined that cloud mesh, I might have a field that goes with the cloud mesh, just like the field we saw a minute ago, except this one's using a different mesh. So there's a mesh line here that says mesh output.cloud m2d. That's the cloud that we defined right up here. I've got a cloud named m2d. So I set the mesh down here to output.cloud m2d. And then I give all the values. And the values are just in order with the mesh points. This is the first mesh point. This is the value for the mesh point. This is the next mesh point. This is the value for that mesh point. Next mesh point, value for that mesh point, so forth. So if you're doing finite element simulation, this stuff probably seems really familiar to you because you just have a bunch of x, y points and you have the value that you've computed at each point on your finite element mesh. Anyway, that's how you do fancy plots like the one that's shown up here. And notice it's really regular because wherever I have points, you can kind of see the triangles here. But over here I don't have any points, so there's nothing plotted. All right. There's another thing, completely different thing that you can do. There's a thing in Rapture called a sequence. And you can use a sequence to create something like a movie. The sequence you can use with the sequence of images and you get something like a movie. You can create a sequence of curves and you get something like a plot that acts like an animated plot. You can also create a sequence of molecules. And again, you get a molecule, for example, with molecular dynamics that may be jiggling around and doing different things. So a sequence has some kind of Rapture object as a function of time or index or something like that. And here's how you do it. Again, if you can create this XML in your program, then you're good to go. At the end of the day, if your run.xml file looks like this, you can load it up in Rapture and it'll show you a sequence. The way the sequence works, the sequence has an about label. That's the label that shows up at the top above the plot. It has an index. The index is, in this case it says parameter A. So down here there'll be a little movie control and it'll say parameter A for the movie control. You can actually move around on this movie control and set whatever frame you want or you can press the play button and it'll play through all the frames. And as it's doing it, it'll show you parameter A equals each of these indexes. Notice for each element, there's like index 1 and index 2 and all of that. So you'll see parameter A equals 1, parameter A equals 2. You can use those however you want. This may be a time point. It may be at 1 microsecond, at 2 microseconds, at 3 microseconds, or 1.7 microseconds, 1.8 microseconds. So in general, that index that you're using doesn't have to be an integer. It could be anything. It could be time, it could be day of the week, it could be whatever you want. So whatever index you label here and whatever index value you show here, Rapture will label it that way. And then for each element that you create, you can stick in a curve like this or an image or anything that we've created so far in Rapture, a molecule and all of that. So the sequences are pretty powerful. I don't know if they support every possible combination of Rapture objects, but the basic things like curves and images and stuff you can do inside of sequences. So if you look in your run.xml, that's what you'd see. And you just have to use commands like this kind of stuff, these put commands to kind of generate that stuff. All right, one last example, it's kind of neat. Suppose you have MATLAB and there's a really great picture that you can generate out of MATLAB. MATLAB can do all kinds of neat visualizations, 3D surfaces and crazy looking plots. And here's a little bit of MATLAB or octave code, for example. I set up a Bessel function and then I went ahead and surface plotted it with some shading. So you can type that code into MATLAB or octave and it'll generate a plot that looks like that. And you might say, ooh, ooh, I want that plot in Rapture and I actually like that plot better than the other one that Rapture does. I want that in Rapture. How do I get that? You can take any image that you can generate from any other program and you can always save it as an image in Rapture. Now you won't be able to interact with the plot. You won't be able to rotate the plot, zoom in and all of that. It's just an image. But anything that you can generate as an image, you can put into your program if you want to as output. So let me show you how to do that. Here's my little main program and here's my MATLAB or octave code. I'm generating a Bessel function and I'm doing all those commands that I showed you just a second ago to generate the surface plot. So this is just my straight up MATLAB code. I can also tell MATLAB to draw it and I can also tell MATLAB to save the output into a file called output.png. So all of that stuff tells MATLAB to very quietly in the background generate a drawing and save the result in a file called output.png. Now if I can get output.png into Rapture, I'm done. And the way I do that is with my friend putfile. Remember we saw putfile a couple of slides ago? Putfile will take any file, read the contents and stuff it in wherever you say to stuff it. So in this case we say RPlibputfile in the output section, look for an image called snapshot and set its current value to the contents of that file. And by the way, the one says compress the image and the zero says overwrite. Don't append. So that will take that output image, load it up, compress it and put it in as the current value for that image. So voila, now I have an image in Rapture. I could use the same thing for the sequence thing that I showed you a minute ago. I might have a sequence of images and I'd go through in a loop and for each output image in the sequence I'd do a putfile, take that image and put it into the sequence, take that image and put it into the sequence. So you can build really complicated things like that if your program has generated a bunch of images. Alright and there's examples too, a lot of example code and I should mention that. Let me do that right now. If we go into Rapture and we've shown you the documentation for all this stuff, when you're looking in the documentation and you go into the GUI XML elements and you're trying to figure out how do I do a Unirec 2D, at least you know it's there now, you can look at the documentation and see all the stuff in there and you can look at some of the examples and what's described here in terms of how it works and it'll show you what it looks like and all that. There's also examples in the code for Rapture. If you go into the code for Rapture there's an examples directory and the examples directory has a zoo of examples. You'll find this on Nano Hub too, I think there's even a menu entry to help you copy the examples. So for any one of these things, if you wanted to see, I want to see what an example of Unirec 2D looks like or something. Every one of these has a tool.xml file and then it has a little program that generates a mesh and all of that. So as you're doing more and more complicated things with Rapture, take a look at the zoo of examples. You can try out, you just run an example and see what it does and then if it does something kind of neat, you say, I wonder how they did that. You can go into the code and kind of look at it and figure out how it works. So there's a lot of different examples there in the zoo and there's the app Fermi stuff that I showed you before, all the different languages and so forth. So a lot of different good examples there to poke around with. So if you have any energy left in the day, this is the last thing that we can try to do today, maybe it's the first thing we'll finish up tomorrow morning. What you can do is play around with this function in MATLAB. If you get into Octave or MATLAB in your workspace and you type these commands, you'll be able to generate like a Bessel function. And then the question is, can you make a program where you can prompt the user for the max order, the max x and the number of grid points, which is these parameters here, end points, new max, x max. Basically I want to prompt the user for these values, I want to generate the Bessel function and I want to spit it out to Rapture as a Unirec 2D in a field. In order to do this, the way I'm showing it here, you have to do it as a field and a Unirec 2D. So you look back through the notes and you'd be looking at kind of this stuff right here, figuring out how do you generate a Unirec 2D in the output section that looks like that and how do I generate a field that looks like that and I want to take the values from MATLAB and kind of get them stuck in my XML, kind of like that. So if you're curious and you want to mess around, you could also try this route too. If you want to bag it with the field in the Unirec 2D, you could also try this route too where you're actually generating the image in MATLAB and then just doing a put file on the image in MATLAB to try it out. That's another way to do it too. So if you want to mess around a little bit with some of the advanced visualization, get started with this example and we'll pick it up in the morning and I'll go through the solution. Okay, so here's the solution that you got for this lab assignment. We wanted to take this little bit of octave code and kind of wrap it into a Rapture interface like that. So first thing, I can run the Rapture builder and I can at least get part of my interface going. The Rapture builder doesn't have some things like the Unirec 2D and all of that field and stuff like that. But at least I can get a number and an integer and a number. And if you wanted to have an image on the output side, you can get that far. So you can use the builder to do as much as you can and then save out the tool.xml. Let me open the tool.xml. Not going to save that. Let me open the one that I generated. Now again, the builder loads as much as it can understand. So again, it's got my definition for numacs and xmax and numpoints and it's got the image there and all that. So that all looks good. I've got the tool set to octave. That all looks good. Got some nice explanations in for each of my parameters. But you notice on the output side, the builder is not showing the Unirec 2D or the field. And I'm not going to save this. If I save this right now, it'll save exactly what you see here. It won't save anything else. What I did was I built my tool.xml as much as I could and then I went in and edited some stuff, added some stuff. So this is the stuff the builder added and then I went in and added some extra stuff into the tool.xml right here. I added the stuff that the builder doesn't know about by hand. So I define myself a Unirec 2D named grid. It's got an x-axis with a label and a min value and a y-axis with a label and a min value. There's a max value and min points too, but I'll set those later in my program. You could set them here, it wouldn't hurt, but you need to set them later inside your program for sure once you know what the user wants them to be. So that's my Unirec 2D, basically defining the x-axis and the y-axis as best I know it. And then I have this field here. And the field, by the way, you should always have a label on things so that Rapture can show them. But anyway, I've got a field here that I want Rapture to show, best of function surface. And I've got a component with a mesh and for the mesh, I at least want to say what mesh it belongs to. I set output.Unirec 2D, parentheses grid. That means look up there to the Unirec 2D, that's my grid. Some people were getting errors about, didn't know the dimensionality of your field. And that happens when there's no grid. Then Rapture doesn't know what dimensionality, what you're trying to apply. So again, in my tool.xml, none of this stuff is ever going to change. So I set all of this in the tool.xml. And then in my program, I can add the stuff that is going to change, the number of points, the min and the max values for the grid, and then also the values for the component. Obviously, the field values are the most important thing here that I need to add. I'm also going to add in. I've got this image here that I'm going to show you how to do that part too with putting the image in. And I didn't have any specific current value for the image. That comes later again in my program. But at least I've got the label there. If you ever forget about the label like this, you create an image, but you don't give it a label, it won't show up as an output. So you want to make sure, maybe that's a bug or a feature, I don't know. But the idea is if you don't label stuff, then Rapture figures you don't want to look at it. So if you're setting an image like this, make sure you at least give it a label. And the builder will do that if, when you're using the builder, it'll at least give it a label. All right. So I've got that tool.xml. Now I've got my octave program and I can run my test script. My test script didn't look like it did very much. It basically ran these functions and it did this plotting thing and it saves out an output.png. And then it quits. So it didn't look very spectacular, but if I Xload image now this output.png, you can see that's what my test script did. So what I want to do now is take that test script and integrate it into some kind of skeleton, maybe I generated a skeleton out of the builder for my main program. So here's my main program coming from the builder with my kind of skeleton code. And then I stick my code in here for my MATLAB script. So those are the three lines basically that I needed to generate two vectors for new and X and then the Bessel function, Z. Everything else now just becomes a matter, I mean all the computation is happening right here. Everything else now is just figuring out how to get the values and put them back out into Rapture. So let me show you that part. All right. So I want to save in the output section, I've got a thing called Unirec2D. And as I told you before, I need to update the X-axis num points and the Y-axis num points. And I do that according to the number of points, end points here that we've got. If I try to pass end points in there, then MATLAB or Octave is going to get mad because the function is wrong. It wants a string. It doesn't want an integer or a double or something like that. It wants a string value. So there's this handy function here. There's int to stir or num to stir that I can use to take an integer or a number and convert it into a string. So that's what I did here, I called int to stir to take my num points value and convert it into a string called num and then I use that string value there. So I'm setting the X-axis num points and the Y-axis num points according to this variable end points, just kind of converting to a string. Also on the grid, I want to set the X-axis max and the Y-axis max. And here I did it more in line. I set X-axis max to num to stir, X-max and Y-axis max, num to stir, num to max. So call the function in line and these are doubles. So I use num to stir instead of int to stir. And then finally I want to save out all the values. And to save all the values, I copied this stuff out of the notes. But just to explain, what I wanted to do, I wanted to go in the output section of my field and I wanted to set the component values. And whenever I do that, I'm supposed to set that to a big string. I suppose I could have set it point by point and done it pen to pen to pen, but in this case I just wanted to generate one gigantic string with all the values in it. So how do I generate one gigantic string with all the values? There's a trick in MATLAB, the sprintf function. If you give it a vector of values, if I have a vector of 2500 values, sprintf will take all of the 2500 values, substitute them into whatever format string I've got and generate me a gigantic string of all the results. And my format string here says percent 12g. That means some kind of double precision number that's about 12 digits wide. So double precision number followed by a new line. If any of you looked in your run.xml, you would have seen that, right? When you look in the field values section, you see a number and a new line and a number and number and number, they're put down like that on different lines, right? That's because right here we put the percent 12g black slash n for the new line and we stuck in the vector of values that's 2500 long and so it gives you 2500 lines of output. Now where did I get that 2500 wide vector? Because wait a minute, I've got a matrix up here. This gives me a matrix of 50 by 50. And I wanted a vector with 2500 points. So this is what that function does. The reshape function takes my vector, my matrix, z, and it reshapes it into a vector that is n points times n points long and one row tall. So it turns it into a vector of 2500 points basically. 2500 long and one tall or however many good points I have, right? And then one last wrinkle. When you do all of this and you look carefully at your results, you might notice, wait a minute, everything looks flipped. It looks wrong. My x-axis is my new axis and vice versa. And so in order to fix that problem, MATLAB versus Rapture, what I really need to do is use z transpose. Z transpose flips my matrix so that it matches the way Rapture expects the data and then I convert it to a vector of 2500 points and then I convert it to a string and then I put it out. So it's all a bunch of headaches, but basically I'm just trying to take the z matrix and get it out as a list of 2500 points in the right order. So all right, so that's the code. And if you do that, if you set the stuff in the tool.xml and then what this does is it fills in the values that are changing dynamically, then you get a nice interactive plot. There's one other thing here. If we, I'll show you the other solution. The other solution was to have MATLAB generate the plot. And so this is the code that we had in the notes that tells MATLAB to draw a surface plot, to do the shading, draw it, and then to save the output as a PNG file. It does it all without popping up on the screen. The visible off makes it so it doesn't pop up on the screen while it's writing. So all of that generates a file called output.png. I just need to take that image and stuff it in the output. And I do that with this line. This line, rpliv put file this time. Put file instead of put string. The put file thing is similar. It finds a path output.image called static.current. But instead of putting that string in there as the contents, it treats that string as a file name. It loads up the file and takes the contents of the file and puts that in. So it's going to open output.png, get the contents of that file and stuff it in as the current value for the image. And by the way, images are big and binary and all of that. So I set a flag for compression. So it'll compress the image and put it in. And then zero again always means overwrite the value. So this is the way I take the file output.png and stuff it in as the value of the current image. So I've got both outputs now. And then like any other program, I finish up with rpliv result and quit. So if I run this now, it asks me for some values and I can simulate. And it gives me a nice plot. And I can also look at the image. That's one generated by Matlab. The difference is that this one I can actually rotate and interact with. There's buttons over here to zoom in. I can move around on the plot like that. There's also other things I can do. Let me reset the view. I can fiddle with the contour lines, turn them on and off. I can make it a wireframe or not. I can turn the grid off. So there's all kinds of weird things that I can do with this interactive version of the plot. And I can't do any of that with the image that I got from Matlab. Matlab's not running anymore, it's done. So the only thing I can do with the image from Matlab is I can zoom in on the image. And when I zoom in, I can see the axes a little bit better. So I can zoom in and zoom out. But that's it. The image, if I try to drag on it, it doesn't rotate, doesn't change. So this one's slightly better because it's a little more interactive. And if I like that picture, I can always download it to my desktop. And now I can copy and paste and put it in my document or whatever. So that lets me kind of, maybe I want to zoom in on this peak and I'm trying to write a, maybe I'm writing a paper that talks about this particular peak and then I can download that and grab that image and put it into my report. That's what's a little nicer about it because I can fiddle with the image. All right. One other thing, just to mention real quick, if we fiddle with the values, say I set that to five and five and run it again. So now, let me turn my grid back on and everything sort of back to the way it was. Not wireframe. All right. So some people looked at that and thought, wow, that looks like really weird, right? Why is it so weird? My original plot looked like that and my new plot looks like that. Why is it so weird? Actually it's doing the right thing because the original plot was all the way from zero to 20 and zero to 10 in the new and the x-axis. So the original plot covered that whole space whereas the plot that I just did goes from zero to five. And if you look, it actually is doing that, right? It's going from zero to five in one axis and from zero to five on the other axis. So this new plot is much smaller than the original plot. And that's what this is showing you. Rapture, you know, when you have two results in Rapture, it always puts them on the same axis so that you can compare them. And that's useful here because otherwise you might not realize when you're flipping back and forth between results, you're actually zooming in on the axes. If it didn't do this, you might have thought at first it was okay, but it would have fooled you later because this is actually covering a much smaller space than the original function. So that's good to know. It keeps everything on consistent axes when you're plotting so that you can compare things when you're looking at them.
 Online simulation and more for nanotechnology.  In this last section, I want to walk through some of the advanced visualization stuff that's  built into Rapture because at this point you can build a pretty functional tool, but we  haven't really done much with the output.  We've looked at KERS, we've looked at histograms.  There's a lot more that you can do on the output side.  Suppose that your program produces a molecule.  You simulate and part of the thing that it generates is a molecule.  Maybe you're doing molecular dynamics calculations.  There's a way to do that in Rapture.  There's an element called structure and again this isn't built into the builder yet, so  I'm again showing you advanced stuff that you can't just drag and drop really easily.  But if you can create XML in the output section that looks like this, then you can get a molecule  in Rapture, either as an input or as an output.  Usually, I guess it could be either in this case.  All you need to do is make the right XML.  You start with something that's like a structure and it has a current and components and then  molecule and then inside there basically atoms that have a symbol and an XYZ coordinate,  another atom with a symbol and an XYZ coordinate and so forth.  If you can generate that XML in your program, you've got a molecule and Rapture automatically  knows how to draw molecules.  It automatically connects to a rendering server, talks to a program called PyMol written in  Python that does molecular visualization and it'll take your molecule and render it in  3D.  There's another way too.  After we created that, a lot of people said there's this PDB, Protein Data Bank format.  I don't know if you guys know anything about that, but it's a real popular file format.  There's a Protein Data Bank site where you can download all of these molecules.  If you want the molecular configuration of aspirin, you can find it in the Protein Data  Bank along with lots of other things.  There's a PDB file format and a lot of people said, well, I don't want to have to convert  from PDB into Rapture.  We made a way that you can say structure, current, components, molecule and then you  can just say PDB and inside the PDB section, you can put something from the Protein Data  Bank in there and Rapture knows how to plot that too.  If you get something from the Protein Data Bank, shove it in there, boom, you've got  a molecule.  So how do you do that?  In your program, and now again, this is what your run.xml file would look like if you're  successful and this is how you actually generate it.  And suppose we have a Fortran program.  I'm assuming Fortran.  We've seen these calls already.  The builder does this.  The builder adds calls for like RPlib, put string and all that.  There's an RPlib, put file command that you can use and you pass in as the first argument  the thing that Rapture loads at the beginning.  Could be called driver, could be called IO.  It's the thing in your program.  If we look at an example program, you guys are looking perplexed at me.  I think it's the end of the day.  So let me show you my example program.  So in my Fortran program, if I look at what Rapture generated, in my example program, it  was called IO in this program.  See just like the builder says RPlib, put string and it automatically generated this  text IO and then you put in a path and then you put in what you want to save at that path,  the same kind of thing here.  And it's called IO because somewhere near the top of your file, see this is RPlib command  here that generates that name IO.  So if you wanted to do a molecule, right here in your program in the output section, we  could add like an RPlib, put file command and we could add in a path output dot, let  me stop the example at this point and flip back to my slides.  So in that Fortran program, this is what I would have typed.  Call RPlib, put file, that same name IO, output dot, mall dot current components molecule  dot PDB.  Again, that's the way I reference things.  It's in the output section.  I'm creating this structure called mall.  In the current section under components, under molecule, I want to tag PDB and I want to  put all my data there.  The RPlib, put file looks for a file in this case called data dot PDB.  It reads the contents of that file and stuffs it in in your output.  So if your program generates a file called data dot PDB, here's how you can take that  file and suck it in to your Rapture program.  And Rapture will read that file and stuff it in right where the PDB tag is.  So if I looked at that file on disk, I'd see all that atom 1C blah blah blah, all that  atom stuff that you see up there.  That's what's in my file.  My program generated that and when I call RPlib, put file and I give it the name of  the file, it's going to read that file and stick it in just like you see it up there.  If I look in the run dot XML, that's what it looks like after I'm all done.  So that's the kind of Fortran code that you'd write to stick some protein data bank stuff  in your tool.  The one here means compress the data and the zero means overwrite as opposed to append.  Oh, I guess if we set compress it wouldn't look exactly like that.  It would look like a bunch of compressed gobbledygook.  But if I made this zero so that I didn't compress the data, then you'd see it looking  like that up there.  So just remember, if you ever run across a case where you need to produce a molecule  and if you've got that molecule in the protein data bank file format, just remember, oh yeah,  there's a slide, I can go back and I'll grab that off the slide and put it in my program.  Alright, moving on to show you another thing, another thing that's possible, you can create  surface plots like this in your program.  A lot of times you'll have a program that generates a bunch of data that you want to  see as a mountain plot or a surface plot.  And the way you do that, depending on what your data is, your data is usually composed  of two things, a mesh and then a bunch of values that sit on the mesh.  And a lot of times a mesh might be uniform and rectangular just because it's easy to  generate a mesh that way.  So Rapture has a thing called the Unirec 2D.  It's a two dimensional uniform rectangular mesh, uniform in X or Y but it doesn't have  to be uniform everywhere.  It's just each axis is uniformly spaced.  So this Unirec 2D means that I'm on a rectangular mesh and you can specify the sizes and everything  in the mesh and then at each point on the mesh you have a value, a field value.  And then if you give Rapture those two things, the field and the mesh, then it will generate  the surface, the mountain plot as an output.  Let me show you how you do that.  Again, if you were looking in your run file at the end of your program in the run file,  if you looked in the output section, you'd see something like what I'm showing here.  You'd see for example this Unirec 2D with some name, my grid or whatever.  It's got a label, energy grid.  It's got an X axis section and a Y axis section.  The X axis and the Y axis describe the two dimensions of your mesh.  The X axis has a label and a min value goes from 0 to 1, max value 1 and it has 50 points.  So imagine it starts at 0, it ends at 1 and you divide it into 50 points.  Similarly, the Y axis goes from 0 to 1 and it's also got 50 points.  It doesn't have to but it could.  I mean, it might have 20 points or it might have 70 points but it's going from in this  case 0 to 1 with 50 points in X and in Y.  I have a label, Fermi Dirac factor and another label, energy and all that.  So if I put that information in there in the output section, then you'll see at least a  uniform rectangular mesh.  I haven't gotten to the field yet but that defines the mesh.  Now again, you can hard code this information in your tool.xml.  If you know ahead of time everything about your mesh, if you know your mesh is going  to always go from 0 to 1 and it's always going to have 50 points and it's always going to  have this label and all that, all of this information that you see here, you can hard  code into your tool.xml.  But you may say, well I don't know how many points I'm going to have.  If I simulate in one case I might have 100 points, if I simulate in another case I might  have a thousand points, right?  I don't know how many points I'm going to have.  So you can put a lot of the information in the tool.xml and then you can change it in  your program.  This is how I would change it in a Python program.  I would do the usual Python put command and I would say in the output section, look for  a Unirec 2D with the name Migrid, look in the x-axis section for a parameter called Max  and give it a value 1.0.  So for this run of the program I leave 0 alone but it's going to go to 1.0, actually it didn't  change but anyway.  So I'm overwriting the value here, pen no.  I'm also going into the output section in the Unirec 2D in the x-axis and I'm setting  num points to 50 for example and append equals no.  So I can hard code that information in the tool.xml and I can overwrite it in my program.  Have my program put in the latest values for Max and num points or whatever.  So there's kind of a duality between the tool.xml and these program statements that create things  in the tool.xml.  We saw that in one of the, not the last but the one before, the lab exercised before.  We saw how you could create brand new things in the xml just by putting information in  there and that's what we're doing here.  You could start with most of that information defined and then overwrite selectively whatever  values you want or you could create every single bit of one of those information.  You could set the about label, you could set the x-axis label, the y-axis label, you could  have all kinds of commands here to set all those different labels and set all the various  values and that would create that structure.  So that's how you define things in the xml like a Unirec 2D.  In order to see the field plotted you also have to define a field and this is what the  field looks like.  The field has an about label, the field has component section and the component has a  mesh and values.  The mesh that you see here, this mesh right here, this statement in red, this defines  that mesh that we were looking at a second ago.  When you define a field you have to say which mesh it belongs to.  This field goes to this mesh and the mesh says where all the points are in space.  So inside the component section you have a mesh output Unirec 2D parentheses migrate.  Now I know where all the points are in space and then you specify all the values.  At the first mesh point it's this value, at the next mesh point it's this value.  You can kind of see here, this is sort of how the values are laid out, v11, v12, v13  and so forth for x and y.  And again the way that you would do that if you want to put program field values in, you  might hard code a lot of this in your tool.xml, in your tool.xml you might have a field statement  with about and label and component and mesh.  You probably don't have the values though.  The values are something that get generated at run time, right?  So most of that information can be in your tool.xml but then your program has to do this.  Your program can take a bunch of values, there's a reshape command, I took a matrix z in MATLAB,  z tick is the transpose of it, the reshape kind of reshapes it and then the vales makes  it so that it's a big long list of numbers.  So I'm basically taking my MATLAB matrix and I'm converting it into a big long list of  numbers and then I'm stuffing it in using the call rplibputstring in the output section,  look for the field named z, see field id equals z right there and then in the component dot  value section stick all those values.  So this call in MATLAB takes my z matrix and makes a bunch of different numbers and then  I put those into the values section to generate the code.  So getting a little complicated, you have to kind of work for it.  If you want to do all the advanced graphics it's not easy, you've got to work for it.  But this is how you do it.  You define a lot of the stuff in the tool.xml and then you override things in your program  to set the values and kind of tweak it.  There's also a way of handling an irregular mesh.  Sometimes the world isn't so easy, not everything's on a rectangular mesh.  So you might have a bunch of different points and there's something called a cloud mesh  in Rapture where you can just specify all the different x, y points.  So for the cloud mesh, again, all these things have an about section with the label so you  can talk and you can say what that thing is.  This is a 2D mesh.  A cloud mesh also has units, I said microns.  Hide yes, that means I don't want to see the mesh.  Usually I just want to see the field.  And then you can specify the points.  X, Y, New Line.  X, Y, New Line.  X, Y, New Line.  So these are all the points on the mesh.  Each point here, each x and y value corresponds to one point on the mesh.  So this first line is probably this point and this next line is like this point and so  forth.  So you can specify all the points on the mesh and then Rapture will read all those points  and it will connect them all together and make triangles out of them.  So if you have an irregular mesh that looks like this, then you do that in Rapture.  And again, how would I do that?  Well, in Python here, if I had an x vector and a y vector, there's a zip function that  puts them together and for each x, y in x and y vector, it's going to go through and  compute and create a string that's x and y and the New Line.  So using x and y, substituting in and then I stick those things in.  In the output.cloud.point section, I'm going to put in the x and the y and the New Line  and append equals yes, which means each time I'm going through this loop, it's adding another  x, y, x, y, x, y.  So I'm converting x-vec and y-vec into a list of points that show up in the point section.  That's what I'm doing.  All right.  And if I've defined that cloud mesh, I might have a field that goes with the cloud mesh,  just like the field we saw a minute ago, except this one's using a different mesh.  So there's a mesh line here that says mesh output.cloud m2d.  That's the cloud that we defined right up here.  I've got a cloud named m2d.  So I set the mesh down here to output.cloud m2d.  And then I give all the values.  And the values are just in order with the mesh points.  This is the first mesh point.  This is the value for the mesh point.  This is the next mesh point.  This is the value for that mesh point.  Next mesh point, value for that mesh point, so forth.  So if you're doing finite element simulation, this stuff probably seems really familiar  to you because you just have a bunch of x, y points and you have the value that you've  computed at each point on your finite element mesh.  Anyway, that's how you do fancy plots like the one that's shown up here.  And notice it's really regular because wherever I have points, you can kind of see the triangles  here.  But over here I don't have any points, so there's nothing plotted.  All right.  There's another thing, completely different thing that you can do.  There's a thing in Rapture called a sequence.  And you can use a sequence to create something like a movie.  The sequence you can use with the sequence of images and you get something like a movie.  You can create a sequence of curves and you get something like a plot that acts like an  animated plot.  You can also create a sequence of molecules.  And again, you get a molecule, for example, with molecular dynamics that may be jiggling  around and doing different things.  So a sequence has some kind of Rapture object as a function of time or index or something  like that.  And here's how you do it.  Again, if you can create this XML in your program, then you're good to go.  At the end of the day, if your run.xml file looks like this, you can load it up in Rapture  and it'll show you a sequence.  The way the sequence works, the sequence has an about label.  That's the label that shows up at the top above the plot.  It has an index.  The index is, in this case it says parameter A. So down here there'll be a little movie  control and it'll say parameter A for the movie control.  You can actually move around on this movie control and set whatever frame you want or  you can press the play button and it'll play through all the frames.  And as it's doing it, it'll show you parameter A equals each of these indexes.  Notice for each element, there's like index 1 and index 2 and all of that.  So you'll see parameter A equals 1, parameter A equals 2.  You can use those however you want.  This may be a time point.  It may be at 1 microsecond, at 2 microseconds, at 3 microseconds, or 1.7 microseconds, 1.8  microseconds.  So in general, that index that you're using doesn't have to be an integer.  It could be anything.  It could be time, it could be day of the week, it could be whatever you want.  So whatever index you label here and whatever index value you show here, Rapture will label  it that way.  And then for each element that you create, you can stick in a curve like this or an image  or anything that we've created so far in Rapture, a molecule and all of that.  So the sequences are pretty powerful.  I don't know if they support every possible combination of Rapture objects, but the basic  things like curves and images and stuff you can do inside of sequences.  So if you look in your run.xml, that's what you'd see.  And you just have to use commands like this kind of stuff, these put commands to kind  of generate that stuff.  All right, one last example, it's kind of neat.  Suppose you have MATLAB and there's a really great picture that you can generate out of  MATLAB.  MATLAB can do all kinds of neat visualizations, 3D surfaces and crazy looking plots.  And here's a little bit of MATLAB or octave code, for example.  I set up a Bessel function and then I went ahead and surface plotted it with some shading.  So you can type that code into MATLAB or octave and it'll generate a plot that looks  like that.  And you might say, ooh, ooh, I want that plot in Rapture and I actually like that plot  better than the other one that Rapture does.  I want that in Rapture.  How do I get that?  You can take any image that you can generate from any other program and you can always  save it as an image in Rapture.  Now you won't be able to interact with the plot.  You won't be able to rotate the plot, zoom in and all of that.  It's just an image.  But anything that you can generate as an image, you can put into your program if you want  to as output.  So let me show you how to do that.  Here's my little main program and here's my MATLAB or octave code.  I'm generating a Bessel function and I'm doing all those commands that I showed you just  a second ago to generate the surface plot.  So this is just my straight up MATLAB code.  I can also tell MATLAB to draw it and I can also tell MATLAB to save the output into a  file called output.png.  So all of that stuff tells MATLAB to very quietly in the background generate a drawing  and save the result in a file called output.png.  Now if I can get output.png into Rapture, I'm done.  And the way I do that is with my friend putfile.  Remember we saw putfile a couple of slides ago?  Putfile will take any file, read the contents and stuff it in wherever you say to stuff  it.  So in this case we say RPlibputfile in the output section, look for an image called snapshot  and set its current value to the contents of that file.  And by the way, the one says compress the image and the zero says overwrite.  Don't append.  So that will take that output image, load it up, compress it and put it in as the current  value for that image.  So voila, now I have an image in Rapture.  I could use the same thing for the sequence thing that I showed you a minute ago.  I might have a sequence of images and I'd go through in a loop and for each output image  in the sequence I'd do a putfile, take that image and put it into the sequence, take that  image and put it into the sequence.  So you can build really complicated things like that if your program has generated a  bunch of images.  Alright and there's examples too, a lot of example code and I should mention that.  Let me do that right now.  If we go into Rapture and we've shown you the documentation for all this stuff, when  you're looking in the documentation and you go into the GUI XML elements and you're trying  to figure out how do I do a Unirec 2D, at least you know it's there now, you can look  at the documentation and see all the stuff in there and you can look at some of the examples  and what's described here in terms of how it works and it'll show you what it looks  like and all that.  There's also examples in the code for Rapture.  If you go into the code for Rapture there's an examples directory and the examples directory  has a zoo of examples.  You'll find this on Nano Hub too, I think there's even a menu entry to help you copy  the examples.  So for any one of these things, if you wanted to see, I want to see what an example of Unirec  2D looks like or something.  Every one of these has a tool.xml file and then it has a little program that generates  a mesh and all of that.  So as you're doing more and more complicated things with Rapture, take a look at the zoo  of examples.  You can try out, you just run an example and see what it does and then if it does something  kind of neat, you say, I wonder how they did that.  You can go into the code and kind of look at it and figure out how it works.  So there's a lot of different examples there in the zoo and there's the app Fermi stuff  that I showed you before, all the different languages and so forth.  So a lot of different good examples there to poke around with.  So if you have any energy left in the day, this is the last thing that we can try to  do today, maybe it's the first thing we'll finish up tomorrow morning.  What you can do is play around with this function in MATLAB.  If you get into Octave or MATLAB in your workspace and you type these commands, you'll be able  to generate like a Bessel function.  And then the question is, can you make a program where you can prompt the user for the max  order, the max x and the number of grid points, which is these parameters here, end points,  new max, x max.  Basically I want to prompt the user for these values, I want to generate the Bessel function  and I want to spit it out to Rapture as a Unirec 2D in a field.  In order to do this, the way I'm showing it here, you have to do it as a field and a Unirec  2D.  So you look back through the notes and you'd be looking at kind of this stuff right here,  figuring out how do you generate a Unirec 2D in the output section that looks like that  and how do I generate a field that looks like that and I want to take the values from MATLAB  and kind of get them stuck in my XML, kind of like that.  So if you're curious and you want to mess around, you could also try this route too.  If you want to bag it with the field in the Unirec 2D, you could also try this route too  where you're actually generating the image in MATLAB and then just doing a put file on  the image in MATLAB to try it out.  That's another way to do it too.  So if you want to mess around a little bit with some of the advanced visualization, get  started with this example and we'll pick it up in the morning and I'll go through the  solution.  Okay, so here's the solution that you got for this lab assignment.  We wanted to take this little bit of octave code and kind of wrap it into a Rapture interface  like that.  So first thing, I can run the Rapture builder and I can at least get part of my interface  going.  The Rapture builder doesn't have some things like the Unirec 2D and all of that field and  stuff like that.  But at least I can get a number and an integer and a number.  And if you wanted to have an image on the output side, you can get that far.  So you can use the builder to do as much as you can and then save out the tool.xml.  Let me open the tool.xml.  Not going to save that.  Let me open the one that I generated.  Now again, the builder loads as much as it can understand.  So again, it's got my definition for numacs and xmax and numpoints and it's got the image  there and all that.  So that all looks good.  I've got the tool set to octave.  That all looks good.  Got some nice explanations in for each of my parameters.  But you notice on the output side, the builder is not showing the Unirec 2D or the field.  And I'm not going to save this.  If I save this right now, it'll save exactly what you see here.  It won't save anything else.  What I did was I built my tool.xml as much as I could and then I went in and edited some  stuff, added some stuff.  So this is the stuff the builder added and then I went in and added some extra stuff  into the tool.xml right here.  I added the stuff that the builder doesn't know about by hand.  So I define myself a Unirec 2D named grid.  It's got an x-axis with a label and a min value and a y-axis with a label and a min  value.  There's a max value and min points too, but I'll set those later in my program.  You could set them here, it wouldn't hurt, but you need to set them later inside your  program for sure once you know what the user wants them to be.  So that's my Unirec 2D, basically defining the x-axis and the y-axis as best I know it.  And then I have this field here.  And the field, by the way, you should always have a label on things so that Rapture can  show them.  But anyway, I've got a field here that I want Rapture to show, best of function surface.  And I've got a component with a mesh and for the mesh, I at least want to say what mesh  it belongs to.  I set output.Unirec 2D, parentheses grid.  That means look up there to the Unirec 2D, that's my grid.  Some people were getting errors about, didn't know the dimensionality of your field.  And that happens when there's no grid.  Then Rapture doesn't know what dimensionality, what you're trying to apply.  So again, in my tool.xml, none of this stuff is ever going to change.  So I set all of this in the tool.xml.  And then in my program, I can add the stuff that is going to change, the number of points,  the min and the max values for the grid, and then also the values for the component.  Obviously, the field values are the most important thing here that I need to add.  I'm also going to add in.  I've got this image here that I'm going to show you how to do that part too with putting  the image in.  And I didn't have any specific current value for the image.  That comes later again in my program.  But at least I've got the label there.  If you ever forget about the label like this, you create an image, but you don't give it  a label, it won't show up as an output.  So you want to make sure, maybe that's a bug or a feature, I don't know.  But the idea is if you don't label stuff, then Rapture figures you don't want to look  at it.  So if you're setting an image like this, make sure you at least give it a label.  And the builder will do that if, when you're using the builder, it'll at least give it  a label.  All right.  So I've got that tool.xml.  Now I've got my octave program and I can run my test script.  My test script didn't look like it did very much.  It basically ran these functions and it did this plotting thing and it saves out an output .png.  And then it quits.  So it didn't look very spectacular, but if I Xload image now this output.png, you can  see that's what my test script did.  So what I want to do now is take that test script and integrate it into some kind of  skeleton, maybe I generated a skeleton out of the builder for my main program.  So here's my main program coming from the builder with my kind of skeleton code.  And then I stick my code in here for my MATLAB script.  So those are the three lines basically that I needed to generate two vectors for new and  X and then the Bessel function, Z.  Everything else now just becomes a matter, I mean all the computation is happening right  here.  Everything else now is just figuring out how to get the values and put them back out into  Rapture.  So let me show you that part.  All right.  So I want to save in the output section, I've got a thing called Unirec2D.  And as I told you before, I need to update the X-axis num points and the Y-axis num points.  And I do that according to the number of points, end points here that we've got.  If I try to pass end points in there, then MATLAB or Octave is going to get mad because  the function is wrong.  It wants a string.  It doesn't want an integer or a double or something like that.  It wants a string value.  So there's this handy function here.  There's int to stir or num to stir that I can use to take an integer or a number and  convert it into a string.  So that's what I did here, I called int to stir to take my num points value and convert  it into a string called num and then I use that string value there.  So I'm setting the X-axis num points and the Y-axis num points according to this variable  end points, just kind of converting to a string.  Also on the grid, I want to set the X-axis max and the Y-axis max.  And here I did it more in line.  I set X-axis max to num to stir, X-max and Y-axis max, num to stir, num to max.  So call the function in line and these are doubles.  So I use num to stir instead of int to stir.  And then finally I want to save out all the values.  And to save all the values, I copied this stuff out of the notes.  But just to explain, what I wanted to do, I wanted to go in the output section of my  field and I wanted to set the component values.  And whenever I do that, I'm supposed to set that to a big string.  I suppose I could have set it point by point and done it pen to pen to pen, but in this  case I just wanted to generate one gigantic string with all the values in it.  So how do I generate one gigantic string with all the values?  There's a trick in MATLAB, the sprintf function.  If you give it a vector of values, if I have a vector of 2500 values, sprintf will take  all of the 2500 values, substitute them into whatever format string I've got and generate  me a gigantic string of all the results.  And my format string here says percent 12g.  That means some kind of double precision number that's about 12 digits wide.  So double precision number followed by a new line.  If any of you looked in your run.xml, you would have seen that, right?  When you look in the field values section, you see a number and a new line and a number  and number and number, they're put down like that on different lines, right?  That's because right here we put the percent 12g black slash n for the new line and we  stuck in the vector of values that's 2500 long and so it gives you 2500 lines of output.  Now where did I get that 2500 wide vector?  Because wait a minute, I've got a matrix up here.  This gives me a matrix of 50 by 50.  And I wanted a vector with 2500 points.  So this is what that function does.  The reshape function takes my vector, my matrix, z, and it reshapes it into a vector  that is n points times n points long and one row tall.  So it turns it into a vector of 2500 points basically.  2500 long and one tall or however many good points I have, right?  And then one last wrinkle.  When you do all of this and you look carefully at your results, you might notice, wait a  minute, everything looks flipped.  It looks wrong.  My x-axis is my new axis and vice versa.  And so in order to fix that problem, MATLAB versus Rapture, what I really need to do is  use z transpose.  Z transpose flips my matrix so that it matches the way Rapture expects the data and then  I convert it to a vector of 2500 points and then I convert it to a string and then I put  it out.  So it's all a bunch of headaches, but basically I'm just trying to take the z matrix and get  it out as a list of 2500 points in the right order.  So all right, so that's the code.  And if you do that, if you set the stuff in the tool.xml and then what this does is it  fills in the values that are changing dynamically, then you get a nice interactive plot.  There's one other thing here.  If we, I'll show you the other solution.  The other solution was to have MATLAB generate the plot.  And so this is the code that we had in the notes that tells MATLAB to draw a surface  plot, to do the shading, draw it, and then to save the output as a PNG file.  It does it all without popping up on the screen.  The visible off makes it so it doesn't pop up on the screen while it's writing.  So all of that generates a file called output.png.  I just need to take that image and stuff it in the output.  And I do that with this line.  This line, rpliv put file this time.  Put file instead of put string.  The put file thing is similar.  It finds a path output.image called static.current.  But instead of putting that string in there as the contents, it treats that string as  a file name.  It loads up the file and takes the contents of the file and puts that in.  So it's going to open output.png, get the contents of that file and stuff it in as the current  value for the image.  And by the way, images are big and binary and all of that.  So I set a flag for compression.  So it'll compress the image and put it in.  And then zero again always means overwrite the value.  So this is the way I take the file output.png and stuff it in as the value of the current  image.  So I've got both outputs now.  And then like any other program, I finish up with rpliv result and quit.  So if I run this now, it asks me for some values and I can simulate.  And it gives me a nice plot.  And I can also look at the image.  That's one generated by Matlab.  The difference is that this one I can actually rotate and interact with.  There's buttons over here to zoom in.  I can move around on the plot like that.  There's also other things I can do.  Let me reset the view.  I can fiddle with the contour lines, turn them on and off.  I can make it a wireframe or not.  I can turn the grid off.  So there's all kinds of weird things that I can do with this interactive version of the  plot.  And I can't do any of that with the image that I got from Matlab.  Matlab's not running anymore, it's done.  So the only thing I can do with the image from Matlab is I can zoom in on the image.  And when I zoom in, I can see the axes a little bit better.  So I can zoom in and zoom out.  But that's it.  The image, if I try to drag on it, it doesn't rotate, doesn't change.  So this one's slightly better because it's a little more interactive.  And if I like that picture, I can always download it to my desktop.  And now I can copy and paste and put it in my document or whatever.  So that lets me kind of, maybe I want to zoom in on this peak and I'm trying to write a,  maybe I'm writing a paper that talks about this particular peak and then I can download  that and grab that image and put it into my report.  That's what's a little nicer about it because I can fiddle with the image.  All right.  One other thing, just to mention real quick, if we fiddle with the values, say I set that  to five and five and run it again.  So now, let me turn my grid back on and everything sort of back to the way it was.  Not wireframe.  All right.  So some people looked at that and thought, wow, that looks like really weird, right?  Why is it so weird?  My original plot looked like that and my new plot looks like that.  Why is it so weird?  Actually it's doing the right thing because the original plot was all the way from zero  to 20 and zero to 10 in the new and the x-axis.  So the original plot covered that whole space whereas the plot that I just did goes from  zero to five.  And if you look, it actually is doing that, right?  It's going from zero to five in one axis and from zero to five on the other axis.  So this new plot is much smaller than the original plot.  And that's what this is showing you.  Rapture, you know, when you have two results in Rapture, it always puts them on the same  axis so that you can compare them.  And that's useful here because otherwise you might not realize when you're flipping back  and forth between results, you're actually zooming in on the axes.  If it didn't do this, you might have thought at first it was okay, but it would have fooled  you later because this is actually covering a much smaller space than the original function.  So that's good to know.  It keeps everything on consistent axes when you're plotting so that you can compare things  when you're looking at them.
Rappture_Bootcamp_2_5__Advanced_Visualization_0_215.png Rappture_Bootcamp_2_5__Advanced_Visualization_216_647.png Rappture_Bootcamp_2_5__Advanced_Visualization_648_2423.png Rappture_Bootcamp_2_5__Advanced_Visualization_2424_4607.png Rappture_Bootcamp_2_5__Advanced_Visualization_4608_6287.png Rappture_Bootcamp_2_5__Advanced_Visualization_6288_9203.png Rappture_Bootcamp_2_5__Advanced_Visualization_9204_10823.png Rappture_Bootcamp_2_5__Advanced_Visualization_10824_16007.png Rappture_Bootcamp_2_5__Advanced_Visualization_16008_19835.png Rappture_Bootcamp_2_5__Advanced_Visualization_19836_22727.png Rappture_Bootcamp_2_5__Advanced_Visualization_22728_24359.png Rappture_Bootcamp_2_5__Advanced_Visualization_24360_25307.png Rappture_Bootcamp_2_5__Advanced_Visualization_25308_28079.png Rappture_Bootcamp_2_5__Advanced_Visualization_28080_29471.png Rappture_Bootcamp_2_5__Advanced_Visualization_29472_29963.png Rappture_Bootcamp_2_5__Advanced_Visualization_29964_32591.png Rappture_Bootcamp_2_5__Advanced_Visualization_32592_36623.png Rappture_Bootcamp_2_5__Advanced_Visualization_36624_36779.png Rappture_Bootcamp_2_5__Advanced_Visualization_36780_37115.png Rappture_Bootcamp_2_5__Advanced_Visualization_37116_37607.png Rappture_Bootcamp_2_5__Advanced_Visualization_37608_38123.png Rappture_Bootcamp_2_5__Advanced_Visualization_38124_38375.png Rappture_Bootcamp_2_5__Advanced_Visualization_38376_38615.png Rappture_Bootcamp_2_5__Advanced_Visualization_38616_40067.png Rappture_Bootcamp_2_5__Advanced_Visualization_40068_40367.png Rappture_Bootcamp_2_5__Advanced_Visualization_40368_42839.png Rappture_Bootcamp_2_5__Advanced_Visualization_42840_43163.png Rappture_Bootcamp_2_5__Advanced_Visualization_43164_44627.png Rappture_Bootcamp_2_5__Advanced_Visualization_44628_44795.png Rappture_Bootcamp_2_5__Advanced_Visualization_44796_45695.png Rappture_Bootcamp_2_5__Advanced_Visualization_45696_45743.png Rappture_Bootcamp_2_5__Advanced_Visualization_45744_48107.png Rappture_Bootcamp_2_5__Advanced_Visualization_48108_48155.png Rappture_Bootcamp_2_5__Advanced_Visualization_48156_54395.png Rappture_Bootcamp_2_5__Advanced_Visualization_54396_54467.png Rappture_Bootcamp_2_5__Advanced_Visualization_54468_54551.png Rappture_Bootcamp_2_5__Advanced_Visualization_54552_54851.png Rappture_Bootcamp_2_5__Advanced_Visualization_54852_54947.png Rappture_Bootcamp_2_5__Advanced_Visualization_54948_55031.png Rappture_Bootcamp_2_5__Advanced_Visualization_55032_55163.png Rappture_Bootcamp_2_5__Advanced_Visualization_55164_55211.png Rappture_Bootcamp_2_5__Advanced_Visualization_55212_55343.png Rappture_Bootcamp_2_5__Advanced_Visualization_55344_55631.png Rappture_Bootcamp_2_5__Advanced_Visualization_55632_55775.png Rappture_Bootcamp_2_5__Advanced_Visualization_55776_55979.png Rappture_Bootcamp_2_5__Advanced_Visualization_55980_56051.png Rappture_Bootcamp_2_5__Advanced_Visualization_56052_56363.png Rappture_Bootcamp_2_5__Advanced_Visualization_56364_56579.png Rappture_Bootcamp_2_5__Advanced_Visualization_56580_56771.png Rappture_Bootcamp_2_5__Advanced_Visualization_56772_57167.png Rappture_Bootcamp_2_5__Advanced_Visualization_57168_57311.png Rappture_Bootcamp_2_5__Advanced_Visualization_57312_57371.png Rappture_Bootcamp_2_5__Advanced_Visualization_57372_57503.png Rappture_Bootcamp_2_5__Advanced_Visualization_57504_57623.png Rappture_Bootcamp_2_5__Advanced_Visualization_57624_57851.png Rappture_Bootcamp_2_5__Advanced_Visualization_57852_57911.png Rappture_Bootcamp_2_5__Advanced_Visualization_57912_57983.png Rappture_Bootcamp_2_5__Advanced_Visualization_57984_58175.png Rappture_Bootcamp_2_5__Advanced_Visualization_58176_60114.png