 So welcome all to this new bias Academy course on image day in Fiji macro language. My name is Anna Clem. I'm working at the Bioimage Informatics Facility at SyLive Lab in Sweden and Before I start I would like to thank Fabrice Caudlier who contributed a lot to this material and also to Giovanni Cadone and Ophragualani. So in this session what we will do is to first have a look on the biological data set and the image analysis problem that we would like to solve and Then I will introduce you to how can you talk at all to Fiji? So what is the macro recorder and what are the building macro functions? And then the core part of the lecture will be to create step-by-step a workflow that Automizes this image analysis workflow. So the image that we are working with are images from the cell atlas or the human protein atlas and the aim of this project is and Was to determine for each cell a protein where in the cell it is look localized So what they did was they generated antibodies against 12,000 human proteins and then didn't immunostanings using 22 cell lines and Then after automatic confocal microscopy they resulted in 82,000 images and you can see some of these images here on the right So you can see they have three channels one is the nuclear in blue Then they have the microtubes in magenta and then they have the protein of interest Which is marked by the antibody and which is labeled in green now And then the question is to know for all of these proteins like where is this protein? So for example here in the upper left image the protein is everywhere in the nucleus Whereas in this image here the this protein seems to be only in nuclear membrane and For the session of today That's I thought we will focus on exactly that one subset of probe of problem So let's say we would like to automatic to ask and automatically quantify whether a protein is low accumulated in the nuclear membrane yes or no and Then what we could do is to automatically Find where is the nucleus and then to automatically find where is the nuclear membrane then to measure the mean intensity in the nucleus and the mean intensity only in the nuclear membrane and then you could calculate a ratio out of these two values and Because this is a course on image a macro writing and not so much on this workflow What I would like to do in this course is to just focus on this part on how do we Automatically get an outline of the nuclear membrane and then when we have this outline How can we measure the mean intensity within this selection? Before we really dive into scripting I ask you to do your first exercise and the exercise is that in Fiji Try to find a workflow that allows you to measure the mean intensity in nuclei and then also the mean intensity just in the nuclear band and The way you could do this or the way I imagine you to do this is First try to get the selection of a single nuclear I'm so for this you need to threshold your image You need to do a connected component analysis for the analyst particles command and then for one single Nuclear I try to get this rim Covering selection so for this you can use the make bands command and yeah, try to play around with this a bit So let's have a look on the workflow together So that is my image. It's a three channel stack So first channel are the nuclei the second channel is the signal and then the third channel are the micatubules and Then the first thing that I want to do is to split this stack into three individual images so I run split channels and this creates then three individual images and I actually do not need the microtubule image so I close this and Then these two I would like to rename so that it's easier to know what's inside So I want to rename the format channel one. I Want to rename to nuclei and The former channel to I would like to rename to signal and Then we will continue working with the nuclear image since this is our market and What I want to do now is to smoothen the image and then to threshold the image to get a binarized image So to smoothen I'm using a median filter Because that's a yeah, it's an edge preserving filter goes very well and I take a radius of 8 pixel. That's what I just tried out before and As you can see this value. Yeah, it looks quite nice because the nuclei get quite nice smooth But the overall shape is not changed too much then I can Set a threshold intensity threshold And I will use one of these Automated methods to determine threshold So as you can see the default method is not so great because there are quite many holes and here even like at the border They are whole so that is not perfect so I try to find a different method that is appropriate for this data set and Yeah, this one method seems to be good because yeah We have only one hole all other nuclear seem to be detected quite well Then I press apply to really create the binarized image then we have the binary image and I would like to fill this little hole So I'm running the fill holds command and then it's gone and Yeah, this looks to me like a quite good mask. So I see all the nuclei they look Yeah, correctly detected and Now the next step I would like to get the outlines of all the nuclei. So one single outline for each nucleus and I do this running a connected component analysis, which is the analyze particles command in Fiji and Here what I need to do is I need to tell Fiji to add the Royston to the Roy manager And I also added a minimum size in pixels So I would like to exclude particles that are smaller than 2,000 pixels Because knowing basic biology of my sample, I know that 2,000 pixels cannot be a nucleus in these specific images Okay so no, we have now all the Roy's and the Roy manager and I would like to First change a bit the properties only that's not Crucial, that's only that you can see it better Okay, and then Yeah, we can see now this Single outlines. That's quite nice and then now I zoom in into that one here And here I said, let's pick one and for this one Let's do this outline that just picks the outer border of the nucleus So I do two steps. I first shrink it and then I make a band so to shrink I used a large command and I use a negative number. So I using I'm using minus 10 pixels To slightly shrink the nuclei selection and then I'm using the make band command By 10 pixels and then you get a second line and our selection is really only what's in between these two lines Last thing I urgently need to do is to update the right So this will replace the formal right that there was this was the right detecting the nucleus by this new band shaped selection and Yeah, just want to show it to you again So this is now the final Roy now that we have the right. We of course want to measure with it and we want to do this in that signal image and So first I want to set what I would like to measure. So I go to analyze set measurements and then I Tell fidget. I want to measure the mean gray value and I want to display the labels So then when this is set, I make sure that the signal image is active I make sure my Roy is active and then once I've done this I press M for measure and Then it opens up the results window where we see the label and the mean intensity in the signal image But in this Roy of the band So this session is about how to automate these kind of work so basically want to move away from clicking and we want to teach Fiji of how to do this automatically and Probably the most important command that you need for this of today is the recorder So there's the command record and Then it opens up the recorder and the recorder Records whatever we do or most of things we can do in Fiji and translates it into the Language for Fiji So important is to check that we have the image a macro language. So it will record workflows or steps in to them image a micro language and This is actually also the default and Then once we made this sure we can just do something and see what the recorder is recording so Think it's good to show you this with a command that is not within our workflow a montage so the montage is starting now three images of our stack and Creates one image that has all these three channel next to each other and what we would like to do is We want to have three columns in one row and I would like to indeed have a scaling factor of one Actually, probably you have different values and you can change them and Let's have a slide border and The border then should have a color of White so I will use the fork on color in my case because my foreground color is white at the moment okay, and Then let's move to the recorder So we can see that the recorder was recording this command of making montage But and this is very important that also records all the parameters that I was setting So for example that I had these three columns one row Scaling of one and the border width of two Okay, so what can I do with this? I can now press the create button and then the same command will open up in what's called the script editor and We will see why this script editor so convenient later on but for now what we could now do is basically Open a new image and Then just press run and it would do the montage now for this new image Now obviously for one single command This might be not so attractive, but I guess it's very easy to imagine that it gets much more attractive as more commands you have and then Okay That's already nice and the last thing that I would like to show you also now Which we also will not use in the following workflow But which is super good to know is the batch processing so What you can do is to go under process batch and macro and Then this window Helps you to run a command on all images of one folder and then automatically Generates output and will save it to whatever folder you choose So we can try this out so we can now choose this command and copy it here and Then you can Choose Input folders, I will use to set out last subset all the image that we have here and an output folder and And then it will what it basically do it's will Automatically open images, but then run this make montage command and then automatically save the montage to the output folder So let's do this So it's actually doing all this in the background so we cannot see so much and but it looks like it's already done So we'll go there And then you can already see in the preview that it made all these nice montages And it also looks like they are different images Where it was doing this? Yeah Okay Very important thing to know about the batch processor is You I mean super nice super easy to use But you have not full control with this So let's say you would use the split channels Command as first command that is the first one that we use in our workflow And you would use this in this batch processor then yeah What would like how do you choose which of the split channels will it save will save all and I can tell you But not save all which a save only the first channel and so on so you Batch processor is nice, but you need more skills to really Determine what it should do precisely Good, but let's move back to our workflow so of course what you could do now is to do all the steps for our workflow which were like Splitting the channels renaming them filtering thresholding and so on you could now record them so you do all the steps and leave the recorder open in the background and To save a bit of time I was doing this for you and You can find these files under these ketchup files. So there's this recorded IGM So What I did was basically recording the workflow press create Then the audience commands were showing up in my script editor and then I was saving them and Importantly when you save your workflows, you need to have this dot IGM ending So maybe let's clean up first and now I'm opening it So for opening it just drag and drop it into Fiji. I Again will change a bit the font size Good and Let's have a look on these commands together So What I was doing is I was splitting the channels Then I was renaming the channel one or the image of channel one I was renaming it to nuclei and the image of the channel two of the former channel two I was renaming signal and Then I selected the nuclei image. I was doing a medium filter with the radius eight. So all of this was recorded. I Chose the one dark auto threshold methods and then I pressed apply and when you press apply then basically These two commands are automatically recorded Then I was saying Phil holds I was analyzing the particles again our parameter of 2000 and the fact that we want to add it to the raw manager were recorded and Then I was selecting one particular nucleus I Was shrinking it by 10 pixels and then I made this band shaped a selection with a bandwidth of 10 pixels and Then importantly I was updating this particular Roy, which was before the nuclei Roy And so I was updating it so that it's replaced with the Roy that is now covering only the Nokia memory And then for measuring I was first setting the measurements Saying I would like to have the mean intensity value Measured and then also I would like to have the label of the image displayed Then I was choosing the image that way I want to do the measurement I was activating the Roy that I would like to measure and then I was finally pressing measure Good and with this I would like to go to my slides so What I was showing you here was how basically the main message was that there is to record and how can you use it and Because we need the recorder to just cover the commands that we need for our workflow and What I would also like to point out is that You can always use the recorder and then save your workflow and like even if you don't want to go a lot into scripting in the future the recorder and then Creating a document in the script editor and saving it is super important for yourself for your documentation and for our reproducibility So in this exercise, I would like to ask you to try out the recorder So you should open the recorder and record the workflow that we discussed or at least some steps of it and Then press the create button and then this will open up in the script editor and the script editor Press the run button on an on the original image to see that. It's how it's running through all your work flow Let's go back to the recording workflow so what we can do is to open again the image and Then we can run it and I find it always pretty fascinating how can fall these windows P and that's all this measurement and Yeah, and then the final results shows up. So I think that's that's pretty cool But now of course Our enthusiasm basically is is stopped quite fast when we try to do this for another image So let's try this out for another image. Let's close everything and open another image So let's see a maybe this one So this has a different name and then when we try to run it Then it splits the channels, but then yeah, there's this error and it says no window with the title 7c1 711 d6 1 found and And So why is this happening? So in our workflow? We were splitting the channel. This is done But then it searches for this very particular file name which contains obviously the name of this old image and then When we look at these three images then obviously they contain the new file name and then The like Fiji cannot find this particular image and then it gives this error that we have just shown So to repair this and to work on this we need to use variables I would now do a super basic introduction into variables and for this I open a new script So I go into my script editor and say new and then very important you need to also here determine the language, so we want to do this in the image a macro language and I Double check the font size. Okay, so What you need to know is a variable always has a name and some content so let's say your variable is Name is my variable and then the content would be a number. Let's say 500 and Then very importantly in the image a macro language since Java based every line needs to be end up with a semicolon So this variable contains now the number for 500 and we could do a second variable and Let's say this would be two and then what we could do is some calculations with these variables So I could say I could create even a third variable and say the content of this third variable is My variable number Hasn't doesn't have a number my variable plus second one and Do this calculation? So this should be 500 times two and Then my variable three should contain the value of one thousand and I can See what is in the my variable three? What is the content by printing it? So I will close a bit what is in the background and So let's see what how this looks like so I'm printing it now and to to execute what is now in my script I need to again press the run button and Indeed so We see the number one thousand in our lock window. So one thousand is the content of my variable three, okay, so Also very important to know is what are comments so you can comment something out with these two slashes Meaning everything that becomes behind these two slashes will not be executed So if I try to do this again and run it again Then it runs and the science these variables So it kind of creates them and fills them with the values But it doesn't print it because the print command is behind the two slashes And you can also see that the color changes to green. So that's called the color coding color and coding code Okay, and so we use actually these commands very often to document what we are doing to explain a bit better What we are doing? So I would like to now introduce you to what's called string variables So here we had numbers and Like variables that are filled with numbers and now we will look at variables that contain strings So maybe it's called my string and a string is any kind of text. So it could be a single letter or It could be a word Or it could be an entire sentence like an entire sentence including spaces and symbols and whatever so the Standard sentence is this and then again to See this in the lock window. We need to print it so we could And now print out the string number three And run all of this so we see still the old printing the 1000 and then we see the printing of the my string three, which is hell word and So to mini summarize this when you have a string So some text content you always need to have these quotation marks So whenever you have quotation marks, then Fiji knows this variable contains a string And just a side remark like compared to other languages You do not need to specify what kind of variable what kind of type your variable is so here This variable would contain a string and here it would contain a number And in as you can see here in Fiji in the image-day macro language You can just assign these variables and don't you don't need to specify before that it will contain a string Okay, then Maybe we can just comment these things out and Next Thing that I would like to show you is the plus operator when you have strings So when you have strings and you use the plus sign Then the strings are kind of glued together. I mean obviously when you have a plus sign with the numbers then they are added up But when you have the strings, they are simply glued together. So let's try this We can have a new string And this would be my string plus my string two And we print it out Then it will glue together a and dark to And as you can see it really glues them together directly. So it's no space and nothing So if you would like to have a space what you could do is for example include one So this basically now glues together Plus an empty like a space a string Containing only a space plus and so again gluing together the content of my string two Let's try this out So now we have the space between a and dark And something that I would also like to show you is that you can do this print clear And then the lock window is always cleaned up before you. Um, yeah, it was always cleaned up Mm-hmm. So final things that I would like to show you is Let's say you would like to do um The following so in image a micro language what you can do is kind of dirty um Gluing together numbers and texts So we could do we could print out for example my variable Or let's say dark my string Plus my variable So basically you are what what this doing is Is gluing together the dark with a 500 and what is um to point out here is that My string is a string obviously and my variable is a five fun. It's the 500 is a number and What's happening is that the my variable is now basically Translated into a string and then both of them are glued together So this would be string plus number and this is something that would not is a bit dirty it would not work in other languages Okay, let's do small exercise. So let's say you would do something like that We would say a equals three and b equals Five and now we want to print out a plus b Then you can guess what is the output of that And the output will be 35 Because we have the quotation marks here. So whatever is inside quotation marks is a string is treated as a string and we said when we have a string then the plus symbol is a concatenating it's called the glute together it's gluing together these two strings and Maybe another last point, which is a popular mistake. So let's say We would now we have our string A variable called my string for And then somebody does this Then what would the output Be here So the output would be not the content of the my string for variable, but really typing out my string for so let's see this So indeed it just prints this to the lock window So our next exercise would be that you try out variables And so the way I imagine this is We saw that we have these two lines and in these two lines You are expected to now use a variable instead of typing in the name directly so first step is that you create a variable with the name title and you assign the string of your image name And then the task of the exercise is That you replace these two yellow parts with the using the variable title And what I will do now is to first copy These two lines these few lines in a new Window, so I open the new script under find new And then when I have the new script I change the language jm jmacle And then I copy it now these lines And I also want to directly save this So I would like to save this Yeah, maybe I know workflow new bias And then when I save as I said you need to do it a igm So before I do anything I want to Create a variable that contains the file name we So this is the file name from our example image and I close with a semicolon so that variable called title contains now a string We can see this with the quotation marks that contains our image name And then what we could do now is to use this variable Here in these two lines So let's try this out. So I will just that you can see this better. I will copy that line Maybe already Inactivated by commenting it out And then see what we can do So this line contains this one string which says channel one and then the trial name And this would be exactly the same as writing This one so we basically dissected our string and gluing glue glue them glue it together with a plus sign So that would be exactly this line and this would be exactly the same And then obviously instead of entering here the file name we could use the variable title And then for the channel two we could do exactly the same thing. So again Now I am jumping over this because we have seen this So I'm using again the variable called title So let's try this out with our file So I'm using now again the same the image and run it And I did a typo so We will talk about a bit about errors in a second, but it's pointing me to line seven And it says it's missing Uh-huh. So it has some problems here and indeed I forgot to enter the plus sign. So let's do this So we wanted to glue together these two strings for the plus Good So we can try it again and let's see Yeah, so I was splitting the channels and was re-naming them successfully. So nuclear signal And then obviously What we should be able to do is now If we have a new image with a different name Then at least what we can do is Uh to change the variable that contains the image name to the right name So at least we had now to change it only once and not in these two lines But yeah, we will work on an ultimate way obviously in a few moments Good, so I adjusted the content of the variable title and then my little code snippet is also working now for the new image So it's nice that we need to change now the name of the image only once and then we can use this in these two lines here But of course what we would really like is that fiji tells us automatically the name of an active image And of course this is possible So to know how we can do this What you need to know is that there are these what's called built-in micro functions So the built-in micro functions are all available functions in the in the image in macro language And we have seen while using the recorder We can get some of these commands and some of the functions, but we cannot get all of them And then this website lists all So what we need for our problem is a function that is called title So the title function it says it returns the title of the current image And that is exactly what you need of course you need to know that the title is the image name But then we can use this So in our workflow what we can do is to Introduce now Just get title function And then also what I haven't pointed out yet But while you are typing Then you can see that these windows open. So this is the code code auto completion And We would like start typing this get title and then Here's the get title function that appears Then you can also see that there's the same documentation as there was online appears also in this little window So we can double click here to insert it And what we would now do is we would take the function And Place it here So the get title function then gets the image name and the output of the function would be saved in our variable title We can now try this so let's open an image and Then we just run it And as you can see it is successfully Splitting the channels, but then also renaming them Let's talk a bit more about this built-in macro functions So we've seen the get title function, which gives us the image name But there are also other functions or types of functions. So for example, there's the stack set channel function And we give it the parameter one and then it activates the channel number one in a stack So it does not have an output a real output And in our get title function, we had an output which was the image name and then we saved it in a variable Then there are also functions that look like this like the get dimension function And here this get dimension functions has output, which is the width the height the number of channels number of slices and the number of frames And we would save it in variables that we pass on as parameters within these brackets So we could name them in any way we want But the order of how get dimensions outputs this information is in this order and also, of course the common source of mistakes So when you use such a function, then of course you could use the wrong spelling and so on But then also what's quite popular is to use extra brackets that you don't need or use the wrong kind of brackets And luckily We get errors quite good error messages in an image j macro language and When you look more precisely at the error, then You can see that Would get you the error in which line would you find this error and then also Using these kind of brackets. It shows you where it expects the error to be So in that example it Says something is wrong with this bracket and indeed that's the example where we had the second bracket So important message here is yeah, I really read the error messages before clicking. Okay Yeah, and we also had a look at the auto completion So actually when you use this and double click then at the right command Then you already avoid these stupid spelling errors So in this exercise, I would like you to simply catch up with the script and Include the get title function And then I would also ask you to try out what happens when you run this function here The get dimensions channels hide with sizes and frames So you can use the print function to Control what is inside of these variables And then I asked you to look in the slides or on the building macro function websites or in the auto completion How the correct use of the get the get dimension functions is and what do you what we are doing wrong here? For now, what we have done was to split the channels and rename them And then the price before we were now normalizing these file names that we do not need to enter the one specific file name And then the next steps of our workflows are that we take the nuclear image filter it set a threshold Binarize it and then fill the holes And then we use the analyze particles command to get the outlines of the nuclei and add them to the raw manager And these steps I would like to now include in the script so I can go back to my script editor and go to the recorded workflow and then Basically what we can do is just copy these lines until that the point where we really select a specific row So I just copy them and paste them And then this is also a good This is a good moment to annotate our workflow so we could say the first step was to split the channels and normalize The image names And then here what we are doing now in the new steps is to filter the nuclei image and threshold Set a threshold set a threshold And then the last step is I mean the last step for now is to Get the Roy's of all nuclei in the raw manager using this analyze particles command And let's also save it Good and However, I would like to do one thing and this is um I would like to give the user the opportunity to change this parameter of 2000 pixels So imagine The user now have has new images of a new cell line and in this cell line the nuclei are much smaller And then it could happen that we exclude nuclei because we have the size limit so what we will do is to Again copy this line that you can see what is happening but we will Use a built-in micro function that is called get number And then we can have a look at the documentation and it says get number It displays a dialog box and returns the number entered by the user So that's good and use it so um It has a prompt that is the text that is displayed when we have When we ask the user for the number and then it has a default value So let's try this out. So we could ask the user to enter minimum size of the nuclei And then as a default value we could use these 2000 and We so this will open a dialog box. I will show it in a second and then We need to save whatever the user enters in a new variable. Now we call it min size And this will save the output of this dialog window So let's have a look. So what you can do is to select only that one line Go to run and then run selected code So this will execute only this one line and then okay, we get this dialog window Here's our prompt where we say enter min size of nuclei and here are our 2000 pixels default value so What happens now? If I press okay, then the value of 2000 will be saved in the variable min size And if the user changes this value to a different number, let's say 700 then This 700 pixels will be saved in the min size Okay So Now this is already nice. We got the number from the user. We saved it And obviously we now need to use this variable in our analyze particles command as it was recorded So this I prepared before I copied it just for you to Compare it. So the original line was this And then again as a first step we could dissect This um long string Into three strings So again, um in the command basically we have two strings one is here And one is here and we are working now on the second string And the second string I now dissect it into three parts, which is one string Glued together with a number glued together with a second string Okay, so that would be this in this line would be exactly the same as in that line and then Obviously what we still want to do is now to exchange this 2000 by the minimum size variable So we can have a look and We first save it We'll open again one of the images And then run it So it's now asking us for the minimum size of nuclei And we could maybe really Enter a very low value and see whether these small particles are included. So I will do two And then so these are my Roy's and we can For now show them all Yeah, and then you can see that these two particles are not excluded Because the minimum size entered was very small So now we are already gotten quite far So we spitted the channels and renamed them We created the binary image and We run the analyze particles command And we gave also the user the opportunity to enter minimum size of the nuclei So for the next step what I did when I was recording it was that I selected one specific nuclei Roy I Shrunk it by 10 pixels and then I made this band shaped like selection with a width of 10 pixels And then finally I was updating this one Roy and by that replacing the nuclear Roy with a nuclear membrane Roy And obviously what we want to do is We want to Repeat these steps not only for this one specific Roy the idea seven, but we want to repeat it for all Roy's that are in the Roy manager So what we need is to loop our code and we need something that's called for loops So this is now to introduce you to for loops. And so what are they and how are they used in the image they micro language And let's have the following example. Let's say you would like to Express your enthusiasm for a new bias academy. So you could write not new bias academy Is great And since you're so enthusiastic you want to do this not only once But several times Let's do it three times Okay, of course now if you print this Then it will repeat this statement But obviously this is not a very good way of doing this. So we want something automatically that is repeating pieces of code in a controlled way So to do that Um, there's something called for loop. So when we start typing for you already get the template of such a for loop So let's use this template And if you press return, you also get a second curly bracket So what do we have here? So this is Basically a statement that helps us repeating code In the round brackets, you can see how The code is repeated some rules And then in the curly bracket, you will put what you want to repeat So we want to repeat this new bias academy is great statement So what I did now was just copying it inside the curly brackets So this part of the code will now Repeat it 10 times. So if we run this will be 10 times And I will also Use again this print clear statement in the very beginning to always clear the lock window Okay, so let's have a look on this part of the for loop so This one tells you where we start our loop This one is how long will we get going with our loop? And this is a step size. So we start And basically it's a bit fancy way of counting So we start by setting i to zero Then we ask is i smaller than 10 If yes, this will be printed Then we will increase i by a certain step step size And this way of saying i plus plus is the same as writing i plus equals one So i plus is our step size and our step is one Um, so this is how we are counting But we can also use our i so we could for example just print it That is actually helpful for understanding the loop So let's run this again And then you can see, okay, we started with i equals zero And we have a step size of one So the next time i is one two three four five and so on We end up with nine the next one step one would be i equals 10 Then i is not smaller than 10 anymore and this will not be printed anymore Just as another example, let's say we would increase the step size to two Then obviously you will only get five steps zero two four six eight When we go back with this new knowledge about for loops to our workflow Then we said, okay, we need to look now these four lines In such a way that they are valid for all roys in the raw dimension. So what i'm doing is Copying these four lines for now to my newly built workflow And so this is still not good because we are selecting this one specific row and then do everything on this So we what we want to do is basically to create Roy or Roy's For the nuclear membrane and we'd want to do this For each nucleus So we somehow need a for loop obviously And we need to do to know several things. So we need to know how many Roy's Do we have in the Roy manager? So how do I get this information? and we also then Need to know how to select the different Roy's in the Roy manager So to get the number of Roy's in the Roy manager They are these Roy manager functions and they're like These are is a group of functions that all have to do something with the Roy manager and there's this one Which is called Roy manager count and then the documentation says it returns the number of Roy's in the Roy manager list So that is that is exactly what we want because we want the number of Roy's Okay, so I double click to get it and again to kind of save this Number I want to create a Variable and I call it and Roy's And then We need our for loop. So I start with the template press return and start moving everything in inside the curly brackets and What I do is to indent the code. So everything that is Inside my for loop is indented And that is something that you do not need to do in Fiji. So it's not mandatory, but it's It's still very important to do so because it increases readability of the code Okay, so this is Already looking quite nicely. So we start at I Is equal zero because When we use this Roy manager select function to select the very first Roy Then we need to say select zero because the very first Roy has the idea of zero And then so of course then in the in the for loop what we would do is then to use the I which starts by being equal to zero And then so this is good for the start and then the step size is fine So I told you I plus plus means we are increasing I every time by one by one by one step and then We just need to tell where to stop And here we are using our n Roy's variable So again a number of Roy's let's say you have 10 Roy's in your Roy manager Then n Roy's would be 10 But since the last Roy's or the 10th Roy will have the id number nine We need to stop When we are smaller than n Roy's Okay, so let's try this out I will open the file again And then I will run everything And so it asks me again for the minimum size of the nuclei And now you can see nicely how it is looping to the Roy manager And we can just open anyone And have a look Okay, so we are now at the final steps of our core workflow And what we want to do is basically to measure Like the mean gray intensity in our nuclear membrane Roy's Using the image that we call signal So this is the main thing that we want to do and then obviously would like to also save these kind of measurements And do some preparation steps and this is all what I would like to show you now And okay to do the measurement Uh, obviously to do one single measurement of one Roy what you could do is to activate the Roy and then press measure However, there's a little trick if you want to measure measure all Roy's and that is if you make sure that all Roy's Are deselected so that no single Roy is selected And then you can press this measure from the Roy manager and then automatically all Roy's will be measured So we can try this out So we can go to our workflow and Say we would like to measure something measure within signal image And then if you remember in the recorded workflow What we did was to first set the measurement and say We would like to measure the mean intensity and we would like to display the label So this is important to do and then obviously also we would like to select the signal window Because that's the image that we want to measure in So I just copy these two lines and copy here Okay And now we can do these two the kind of this trick of saying we want to deselect whatever there is in the Roy manager I mean we want to not have any Roy selected. That's what it means And then once we have done this we can run the measure command to measure all Roy's of the Roy manager Let's have a look on this Okay, so I'm opening an image And it should ask me for the minimum size It's looping over all Roy's and it's doing the measurement for all 14 Roy's Okay, that's nice and Then let's continue with the preparation steps. So I go back to my slides Okay, so This is quite nice and Of course now we would like to save the measurement And this is really now the the time to think of okay Are we doing everything correct and are we preparing our macro in the right way? And in particular, let's have a look on the Roy manager Let's say you have done this measurement now for one image and you open up a new image then Inside the Roy manager, there will still be the Roy's of the old image And it will do then the measurements also for that Roy's that are from the old image also for the new image And that is something that of course we don't want at all So before we do anything we want to In our workflow we want to clean up the Roy manager And then now in this last step what we did was measuring something And then we would also like To make sure that before we do anything in our macro We want to make sure that there are no no old measurements in the result window So basically you could just copy these two lines from the slides And say okay, I would like to Um prepare my And like prepare for new evaluations By doing these two steps So now we are sure that whatever we measure and whatever we have in the end is really from that image that we had opened and we can Then run everything get our final result table which only contains measurements of that particular image And then finally we can save the result now that we are sure that results are clean So for saving anything in figi, there's the save s Come out So you can see that it has a format and a path And the format is in this case So we want to save at that moment. We want to save a result our result window So we need to tell it that the format should be results as a string And then we enter the path So let's use this. Uh-huh. I'm opening the documentation instead I want to double click here so We are want to save in the You want to save the results and then For the path we can basically just copy here And the only thing that you need to be careful When you enter a path is okay first We need to say this is a string Then we need to say this is what is the complete path. So we could call results csv And if you're attentive, you see that somehow is is a string, but the color coding is not magenta And the reason is that we have these slashes and you cannot have a single slash in it within a string So what you need to do and this is a bit dependent on whether you're on a mac on a windows Is that you Either you use two two back slashes Or what I could have also done is instead of two back slashes to use one slash So I'm using two back slashes And then we can have a look whether all of this is working Actually, I think I will leave these open because then we can have a look whether Results window and the rhymes are properly cleaned And I will open an image And then now I will run Okay So in theory, we should still have only 14 measurements. Yes And we should have only 14 rows in the rhyme engine Okay And then now the exciting part is to check whether we have our results and that was already So we you can drag drop such a result file just in figi and then you get The measurements in figi Um, what we will do next is some extra steps and the first one is that we have For now we have a workflow that runs on your active image So we were opening an image and then we press run and then string these things very nicely But in our image folder, we have I don't know how many but we have uh several images And we would like Now that it opens automatically an image does all of this saves everything opens the next image and so on So we need a basically a for loop that works over all of our images And what you need to know for this are Some essential commands and one is the get directory command So the get directory is a user input And the user selects a directory and then the output of this function is a path to this directory And then once you have the path as a stream You enter it to the To the function get file list And then the get file list gives a list An array of all your images and we will talk in a second about what are arrays And then once you we have this kind of list of images we can do a for loop One over the next images in this list and Do our workflow So let's have a look on arrays. So we have seen before variables were containing one number of one kind of string And the special thing about arrays is that they can have the several values So they have basically different compartments where you can save individual values So let's have an example of this. So this is a array with the name fruit and it has four compartments And then you can fill out these compartments. So you could say the first compartment Contains the string apple the second orange and so on And also here I want to point out that the index of the first compartment is zero So a bit like in the row manager. The first row was zero And very useful functions are If you want to print such an array, you cannot just say print fruit. This would not work What you need to do is to use the array print function. So it's a array array print fruit And especially important for looping over such an array is the dot length function So if you say fruit dot length, it will give you How many compartments there are in your array and then you can loop over it So now let's see how we can use this knowledge about arrays for our workflow and So I go back to this example And here what I told you was we can ask the user to to choose the directory where the files And then using the file list function We get an array which lists all the images. So it lists all the image names of all the images in that directory So this is an array and every compartment in each compartment. You have one file name And then we can loop over this file list array and The first image will have the idea of zero because we start indexing with zero And then to know how many images are in our directory. We use this dot length function To go back to our workflow This is how it would look like so We again also would use this to be asked to user we get the file list And then basically we will take all our of our code and loop over it for all our files Ideally you would use a function and make it a bit more clean, but this is just an introduction of image macro writing Okay, what else do we need to consider? So Maybe first the saving When we were saving before I was just calling the files results plus in file ending and This of course now would result in that we every time we have an image we will we would overwrite it We would create a new file called results every time we run over an image And that's of course not nice. And so what we could do is we could Insert the name of the image in our file part for saving And by that we will have one specific file for each image And then Also, what we need to consider is the preparation So we Already had included that we cleaned the raw manager and that we clear the results Also, what we need to include now is that we first close everything that is open And this is obvious because when we have like the first image then In the end we still have kind of these split channels open And then these would be still open when we open up the next image. So that's bad We can close all open images using this command And then finally We indeed need to open our image. So when we were not doing dispatch processing We were always opening an image that we had an active image And then we were pressing run and the script editor to run our workflow But here now we need to also automate that the image is opened And then what it's nice to do Is to print out which image are we working on? So to include this in our workflow, I will now switch back to my desktop Okay, so to use this now in the workflow what I could do is To be a bit lazy and just copy it from the slides So I copy these two lines or actually these three lines until the curly bracket So asking the user for the directory getting the file list and starting the loop I will just copy it inside my code And then you can see there's the curly bracket open Then I want to really have all of this inside my curly bracket And I make sure I indent it To really know where to close the curly bracket and then while closing you can also see in the script editor It shows you which curly bracket are you closing here? That's very helpful And then also I would like to save now this workflow under a different name So always use the dot igm ending Okay, so that is now the looping And let's look at the other steps that we need So we said we need to Also close all images not only clean the rowing manager and to clean the results And then obviously we should do this before we Open any image and before we get any image names. So I will move this down And then we need to now open the image and again The open path is The part of the directory plus so concatenate together with the first element or the element in the in our file list array So the first one would be zero And then it's also nice as I said to display which file we are processing So again, we want to do this before we get any image name And let's also document it a bit Open Image That maybe is a bit obvious Okay, so we are opening it. We are printing it out Then once it is open, we are getting the title and we are splitting the channels and we are doing everything And then until the very end there we said we need to Save it now under a specific name So again, this is a string from here to here. That is our path and we would like to now Insert our variable holding the image name. So What we can do is We can use the title Variable also we could use the file list f very um, we are variable And then let's do an underscore here that we get a beautiful file name Okay, and with this I added everything that we need I would like to point out one more thing before I start this And this is that we have now with um nest for loops so we have One for loop here that is looping over all our images and we have one for loop inside that for loop Which is looping our overall our voice And here it's really super important to use different counter variables. So here we have an i And here we have an f so I like to have f for file And because otherwise you really mess it up. So you you would start then Um with a f setting f or if you would have an i here you would start setting i equals zero Do some steps and then here you start modifying the i so that is messing it up. So And it's a very popular mistake Okay and then So then my output path. I was this folder. I cleaned it now for demonstration And we can now run this And I would need to go to my files which here and here So I'm picking the directory and now it's working on the first image in my folder and it's asking for the minimum size of the nuclei And It was doing something with results, but it's so fast and cleaning it immediately But you can see them the results appearing very quickly And then as you can see It's now working to all of these files in the directory But it is asking for the minimum size of the nuclei for each image And this will be the last thing that we will work on in this workflow So I will Actually now not clicked over all files. I think these were 12 files or so But I will cancel it now because Since we are saving already for each single file For each single image. We should have something in our output folder already And we have it So you can see that every csv file has now the name of the image plus results And you can just drag and drop them into pg also to to reopen them Again, ideally you would get rid of this dot tiff file ending you can do this very easily in fiji, but Yeah, there's an introduction into image in macros. So we want to be a bit fast I guess everyone was slightly annoyed that when we were running our macro over all images in the folder Then for each image it asks, um, what is the minimum size of the nuclei? And this is actually not only annoying, but it's probably also wrong because when you consider In one folder you have probably all images of one experiment And recorded under the same using the same settings of the microscope and then You you don't want to use different parameters for your analysis of for each single image But you want to have one set of parameters that you use for all images of your folder So ideally what we would like to do is to ask for the minimum size of the nuclei in the very beginning for the very first image and then to use the same parameter for all images And So what we want to do is what's called a conditional Statement. So we want to ask this. So this was the line where we're asking the user to enter the number And we want to do this only for the very first image in the folder So what you need to know for this is what's called an if statement or conditional statements So conditional statements are parts of the codes that are That are executed Only if certain conditions are true So you could ask so you have in this example here you have a variable called i And uh, this is zero And you could ask is the variable i bigger than 10 And if this is the case then the lines that are in the curly brackets are executed If this is not the case the lines inside the curly brackets would not be executed You can also of course ask if something is smaller smaller or equal And then very important if you can ask is Something equal then you would need to use two equation marks And you can also ask if something is not equal then you would use the exclamation mark and the equation sign This is basically all that you need to know for this workflow, but of course For your future scripting It is very important to know that you can Also have like basically different cases. So you can ask if Something is true And then to execute something else if this is not true Or you can ask for different alternatives So if i is has a certain value do this and if it has a certain other value do that and so on and So let's do this for our Workflow So this is very simple so we have This min size we are asking for this and We want to only ask if it's basically the first run of our loop And we if we go up again We get remembered reminded that The first run has then the f This counter variable f equals to zero And then we could go back and say if f Equals to zero And again, I'm telling you that to ask if something is equal. You need these two equation marks and then We need the curly bracket and inside the curly bracket We move whatever we want to have executed only in this specific case So for the first run it will ask for the min size And save this and for the other runs This will be saved and then or like already before and then used So we can test this again Safe So I should not need to close anything because everything should be closed within our workflow So i'm picking the right directory And I should be asked only once now And then for the next images it should just run Yeah, and it does this So that's good So with this we've reached the end of the session So I hope if you learned that there's the macro recorder There the building macro functions you've seen what variables are and you've seen how to ask for user input We have looked at the looping Overcode and we've also looked at how to loop over several images in a folder And we've used the areas for this and then in the final step We have seen the conditional statements in form of if statement Last points that I would like to point out is the bit of general good practice when coding so What I tried to use was Using meaningful variable names. So if you use for example the min size when I was asking for the minimum size of the nooklai Then if you have variables that you use more often in your script Then it's good to assign it in the very top of the script And Also, what we have done is to use comments. So we documented What we are doing using the comments and this is good for you When you come back to your script like after two weeks or so or after two years and of course also for others Then Forward reproducibility It's really very important to have this initialization or preparation code that we also had So to close the windows to clean the raw manager to clean the results table and so on We have not saved quality control files But you should do this actually so you can quite easily save the raw manager Or you can also create overlays of the roys over your images and save them under a new name And then we have used file names that refer to the original files So when we were saving the result windows in the end Then we were taking the original file name of the image for saving the result csv file Then what we have not done and what is also very important Is to save the parameters used with Other results so we you can see this now in the next slide actually. I've done this in the end so In our example We are asking the user to enter a minimum size of the nucleus So and if this one this is changed, this will not be documented at all in the marker as it is for now This would be very bad Okay, and also save the macro itself and document its version And then also consider sharing a marker when you publish something You can share it probably as supplementary information So Where to continue from here? So first you can look a bit more detailed on the slide. So I have not covered everything that is in the slides and then um You can also check out what I called a sneak preview igm So I have one macro that is the continuation of the workflow that we have until now And I told you in the very beginning that it would be nice to not only measure the mean intense need nuclear membrane But also in the nucleus and then to calculate the ratio. So this is what I tried to do then in these added steps And from the scripting side, what I tried to do is to Show you how to customize the result window How to get basic statistics of Roy's using the get statistics command? And then I also included the wait for user command just to show it to you So this is basically very simple. So it just opens up a small checkbox Where or a small Dialogue where you need to say okay as a user and then until then The macro is is stopping And that is quite easy way of debugging your code or wait for user interactions And then further of course you can continue With the resources that are online. So there are many resources online. There are of course other youtube videos and they are On the image.net there's an introduction into macro programming And there is the forum On the image dot s c So there there will be a threat linked to this video And of course you can also ask questions there and it's a very active forum And then there is the bio image data analysis book which you can freely download And they are the chapter three is only about image j macro language And with this I come to the data resources. So we got the images from the human protein atlas And you can find more information in the paper and also online Good and with this I would like to thank you all for your attention and I hope you had fun