text:
# Chapter 2 Day one of R and RStudio

Motivating scenario: Motivating scenario: You have heard about R and RStudio, and maybe used them, but want a foundation so you can know whats going on as you do more and more with it.

Learning goals: By the end of this chapter you should be able to

• Explain why we are using R and RStudio.
• Describe the five tips for writing code like a pro.
• Install R and RStudio (or have access to them on RStudio cloud).
• Set up RStudio preferences.
• Install the tidyverse package.
• Open and save an R script.
• Explain vectors, classes of variables, doing math, and asking logical questions in R.
There is no external reading for this chapter, but watch the required video embeded in the text (Fig. 2.1), complete the RStudio primer on programming basics embeded below (Fig. 2.7). Then go to canvas to complete the survey for this content.

## 2.1 What is R and why / how do we use it?

R is a computer program, which is the go to language for most statisticians and data scientists (although some prefer python or julia). R makes it possible to conduct complex statistical analyses, make nice figures, and write this book, all in one environment.

As opposed to GUI’s, like Excel, or click-based stats programs, R is focused around writing and sharing scripts. This allows analyses to be shared and replicated, ensures that data manipulation occurs in a script, preserving the integrity of the original data, and allows for tremendous flexibility.

## 2.2 Why use R?

• R is free.
• There are many “packages” in R for specialized analyses.
• R can make nice graphics.
• While learning R is not easy, inexperienced programmers can quite quickly do useful things. You will be able to make nice plots and summarize data by next week!
• Using R (or any scripting based analysis) allows us to save all the steps of our analysis, making our work easy to reproduce, describe, and build off of.

Figure 2.1: Watch this video about why and how to R (6 min and 10 sec), from STAT 545 – a grad level data science class at the University of British Columbia. We will borrow from this course occasionally.

### 2.2.1 What is RStudio?

More precisely, R is a programming language that runs computations, while RStudio is an integrated development environment (IDE) that provides an interface by adding many convenient features and tools. So just as the way of having access to a speedometer, rearview mirrors, and a navigation system makes driving much easier, using RStudio’s interface makes using R much easier as well.

In addition to being a great place to use R, RStudio is a Certified B corporation, which offers many great resources we will rely on over this term. RStudio has a freemium business model, and you will not need to pay for any of RStudio’s products this term.

### 2.2.2 What is the tidyverse?

A great part about R is that many people have written packages to help with specific tasks.

The tidyverse refers to both a set of packages, and a way to do things in R. The tidyverse packages we use the most in this course are:

We will use the tibble, stringr, and purrr packages less often if at all (although I use them often). If you are using your computer, rather than RStudio Cloud, you will need to install tidyverse (see 3.2.3) the first time you use it.

You will see that there are many ways to do things in R. Over years of teaching this course I have switched to teaching predominantly using tidyverse tools.

One major reason for this is that the focus on a shared and coherent philosophy, grammar and data structure makes the tidyverse easier to teach and learn than base R. However, there are still challenges to learning and teaching the tidyverse, the two major challenges are

1. It takes time to learn and appreciate the shared philosophy and data structure.
2. Many people first learned R using base R, so it can be frustrating to start to learn again.

Overcoming challenge (1) takes time but is helped by reflecting on why and how code works when it works, and fails when it fails (rather than copying and pasting code that works), and continually asking questions.

Overcoming challenge (2) can be tough, but I believe it’s well worth it. Amelia McNamara’s R syntax comparison cheat sheet (Fig: 2.3) can help .

## 2.3 3.2 Installing R and tidyverse (or not)

We use R version 4.0.0 or above, and tidyverse version 1.3.0 or above.
You can either download and install R, RStudio, and tidyverse onto your computer (see Installing RStudio for more info), or you can do all the coursework with RStudio Cloud without installing anything on your computer (see Getting on RStudio Cloud for more info). Which option is right for you? It depends (see below). I suggest doing both and seeing which you prefer.

### 2.3.1 Getting on RStudio Cloud

Using RStudio Cloud allows you to use R and RStudio without installing anything on your computer. Additionally, if you log into our course project on RStudio Cloud you will not need to install any packages or load any files except those you want for fun or for your independent project at the end of term.

• From my experiencing teaching this course, about 5% of students have computers or computer systems where installing R is challenging, now you don’t have to.

• Some students have older computers with limited computation. For them, a few class exercises (involving large-scale permutation or simulation) go super slow, and they can get justifiably frustrated.

• Some computer setups make installing tidyverse or other specific R packages somewhat painful. RStudio Cloud removes this pain.

• Using the course project guarantees that you’ll get the same environment as the prof and TA, making it easier for them to help you.

• The biggest disadvantage of RStudio cloud is that it’s expensive if we all use it and I only paid for a certain amount of usage, so please use it only if you’re having issues using R on your computer. Please e-mail me if you would like to use it!
• Sometimes the system can get overwhelmed. This is pretty rare, but once a student was trying to use RStudioCloud during the international RStudio convention. The RStudio Cloud could not handle all the traffic and went down that day.
• You need an internet connection to use R. This can be a bummer if you don’t always have a reliable one.
• Some people (🖐) like having everything on their computer and struggle thinking about / working with folders on a cloud.
• Using the course project on RStudio Cloud might prevent you from learning how to load data, download packages etc.

### 2.3.2 Installing RStudio

1. First download/update R from here, be sure to download the version compatible with your computer, and pick any CRAN mirror you like (I usually do Iowa). If you installed R a while ago, be sure you’re using R version 4.0.0 or above.

2. Then download/update RStudio from here. Be sure to select the free version (RStudio Desktop, Open Source License), and as above, be sure to download the version compatible with your computer. If you installed RStudio a while ago, be sure you’re using RStudio version 1.3.0 or above.

• You can do a bunch without stable internet.
• You are not reliant on a cloud service which could go down.
• Everything is on your computer.
• You learn the joys (and frustrations, and how to overcome them) of dealing with packages, loading data etc… .

### 2.3.3 Installing tidyverse

Open RStudio and type install.packages("tidyverse") into the console, and then library(tidyverse) to ensure this worked.

## 2.4 The RStudio IDE

### 2.4.1 A tour of the RStudio IDE.

If you are unfamiliar with the RStudio environment you should watch this video on the RStudio webpage.

Figure 2.4: The RStudio IDE Overview (2min and 45 sec)

### 2.4.2 A tour of the Rstudio environmenmt

#### Customize settings and preferences in the RStudio IDE.

Suggested preferences for RStudio IDE.

After you open RStudio, navigate to Preferences under the RStudio tab. Set yours to be like mine (Fig: 2.5), below and then click apply.

Feel free to set Code, Appearance, Pane Layout etc to however you like!

## 2.5 Intro to R

### 2.5.1 Using R as a calculator and for logical questions

We can use R for doing math. For example:

• 1 + 1 will return 2,
• 3 * 2 will return 6,
• 3 / 2 will return 1.5,
• 3^2 will return 9, etc… .

We can also use R for asking logical questions. For example:

• ‘Is one greater than two?’ like this 1 > 2, which returns FALSE.
• ‘Does four divided by four equal one?’ like this 4/4 == 1 (note the two equals signs), which returns TRUE.
• ‘Does four divided by four not equal one?’ like this 4/4 != 1 (note an exclamation point, then an equals sign), which returns FALSE.
• ‘Is four divided by four less than or equal to one?’ like this 4/4 <= 1 (note a less than sign followed by the equals sign), which returns TRUE.
• ‘Is four divided by four greater than or equal to one?’ like this 4/4 >= 1 (note a greater then sign, then an equals sign), which returns TRUE.

### 2.5.2 Vectors in R

Most of what we do in R starts with a vectors – a combination of simple entities. We already came across a few simple vectors of length one – for example, the number, 1 and the logical statement, TRUE, above.

Vectors are often longer than length one, for example, we can make a vector with the numbers one, five, and two with the c()oncatenate function as follows c(1, 5, 2) which returns 1, 5, 2.

#### Classes of Vectors in R

All entries in a vector must be of the same class. The three most relevant classes are:

• numeric – Contains numbers which can take any value. For example c(1, 2, 3) returns 1, 2, 3.
logical – Contains logical statements. For example, c(TRUE, FALSE, FALSE) returns TRUE, FALSE, FALSE.
• character – Contains letters, words, and/or phrases. For example c("The dog", "jumped", "over", "the moon") returns The dog, jumped, over, the moon.

You may also come across two other classes of vectors:

• factor – This is a lot like a character, with the caveat that they are coded by numbers in R’s brain (see below). This can sometimes make things tough, so be careful, and consider when things are not working right that maybe you have factor when you thought you had a character.
• integer – A number that must take an integer value. For example as.integer(c(1, 2.1, 3)) returns 1, 2, 3.

#### Using math and/or logical operations on vectors

In R you can add, subtract etc. two vectors. When doing so make sure vectors are of the same length, or one is of length one, otherwise you can get weird results.

• To add one to the vector 1, 2, 3, type 1 + c(1, 2, 3) to get 2, 3, 4.
• Similarly, to multiply the vector 1, 2, 3, by two, type 2 * c(1, 2, 3) to get 2, 4, 6.
• To divide the vector 1, 2, 3 by the vector 2, 4, 1, type c(1, 2, 3) / c(2,4,1), which returns 0.5, 0.5, 3.
• To ask, for each element in the vector 1, 2, 3, if it equals one, type c(1, 2, 3) == 1, which returns TRUE, FALSE, FALSE.
• To ask, for each element in the vector 1, 2, 3, if it equals the corresponding element in the vector 3, 2, 1, type c(1, 2, 3) == c(3, 2, 1), which returns FALSE, TRUE, FALSE.

### 2.5.3 Using functions in R

Only so much can be done with simple math. We can do more complex analyses in R with functions. Functions take in arguments and return some output. Here are some simple examples:

• To get the mean of a vector, use the mean() function. For example, mean(x = c(1, 2, 3)) returns 2.
• To get the length of a vector, use the length() function. For example, length(x = c(1, 2, 3)) returns 3.
• Use the help() function to learn more about a given function. For example help(length) will return this (Fig: 2.6).

Throughout the text, I include a hyperlink to the help for every function I introduce. There is no need to look into all of these, but it is a good practice to look at the when you are confused. Unfortunately it takes a bit of practice / knowledge to make sense of R’s help. So, check out this reference to figure out how to get the most from R’s help.

The tab button is very useful when we deal with functions. Hitting tab as you begin to type a function’s name will give suggested functions, with a brief description, while hitting tab inside the parentheses of a function will show the arguments the function takes.

You do not need to give the arguments name if we don’t want – by default R processes arguments by the order it expects them. So sqrt(x = 4), returns 2, as does sqrt(4). But it’s usually a good practice to do so, especially when there are more than two arguments as this makes it easier to understand your code and harder to mess up.

### 2.5.4 Assigning variables in R

Use the assignment operator <- to assign values to a variable. For example

num_vec <- c(4, 9, 16)

With these variables assigned, we can do simple math, ask logical questions , use them as arguments for functions. For example sqrt(x = num_vec) returns 2, 3, 4. Note, this is the same as typing sqrt(num_vec) and with just one argument (x) for the function, this is totally unnecessary. When there are more arguments it is good practice to include the argument name and the equals sign, as this makes code easier to read, and more likely to work (otherwise R assumes we put things in a specific order).

All variables assigned should be in your environment window, or you can use the ls() function to ask R for them.

#### Converting between types of vectors

• logical to numeric – A convenient trick in R is that TRUE equals one and FALSE equals zero. So sum(c(TRUE, FALSE)) returns 1, and mean(c(TRUE, FALSE)) returns 0.5.
• factor to character (and vice versa) – This usually works without incident, so you can convert a factor, factor_vec <- factor(c("a","x")), to a character like this: char_vec <- as.character(factor_vec).
• factor to numeric – This will return the numeric ID associated with levels, so as.numeric(factor_vec) returns 1, 2.
• numeric to factorDON’T DO THIS, UNEXPECTEDLY BAD THINGS WILL HAPPEN.

### 2.5.5 Writing R scripts and beyond

A great thing about R is that you can remember and share exactly what you have done by saving your work as a script. In doing so it’s best practice to type your name, date and the goal of the analysis at the top (with a # to tell R this isn’t code), plus a description of your goals. Regular comments throughout, help make your code more usable.

To make a new R Script, click on File, then New File, and then R Script.

In Section 2.2.2 we introduced the idea that people have developed packages to extend R to do a bunch of stuff, and in Section 3.2.3, we saw that we install an R package with the install.packages() function.

We only need to install a package once, but we need to load all packages we are using every time we open a new R session. Use the library() function to do so.

So, for example, type the following to load the tidyverse package

You should see messages like I did upon loading the tidyverse library. You should also see in the Packages tab, that you now have a check next to dplyr, forcats, ggplot2, purrr, readr tibble, and tidyr, as these are all loaded with tidyverse.

## 2.7 Preparing for success

Follow these Rules to help make this class and your life easier.

### Today!

1. Make a folder for this course and include a subfolder called data (as I said in the last chapter).

1. Open R right now and make a project called applied_biostats in the existing folder, applied_bioststats.

### Everyday for class homework etc!

1. Double click the applied_biostats.Rproj to open RStudio, rather than opening RStudio directly (or if you insist, open the project after you open RStudio).

2. Open a new script.

3. Write the date and what we are working on in a comment (that is, after a hash #)

4. Load all packages you will need (almost always tidyverse, sometimes more)

5. Before doing anything else, save the script in your applied_biostats folder with a nice name (e.g. class_02_intro_to_R.R).

#  Jane 21 2021
#  Good practces
library(tidyverse)

## 2.8 Observations and suggestions for learning R / computer stuff

Teaching this class for years, I’ve learned a few things about learning R that you should know.

### 2.8.1 Observations

• Some people pick R up fast, other slowly.
• The speed at which students get familiar with R is unrelated to intelligence.
• Everyone who keeps trying gets there eventually.
• Despair and feeling low/dumb are the things that get people jammed up.

### 2.8.2 Suggestions

• Don’t worry. Keep trying. But TAKE BREAKS.
• Step away from the computer as much as possible, code & make plans on scratch paper.
• Be patient & understanding with yourself and your friends.
• Be creative.
• When something works (or it doesn’t) take time to figure out how / why.
• Fight the urge to compare yourself (negatively or positively) to others.

Today at the RStudio conference, Hadley Whickham, conrasted the “automatic negative thoughts” we feel some time in coding to the “balanced alternative” that we want to get to.

## 2.9 RStudio primer

Be sure to complete this primer from RStudio. This will get you a solid foundation in R which we will build off in the coming weeks.

Figure 2.7: Primer on programming basics: Complete the RStudio programming basics tutorial from the RStudio website

## 2.10 Intro to R and RStudio: Quiz

Complete the quiz below, a nearly identical quiz will be on canvas.

### References

Ismay, Chester, and Albert Y Kim. 2019. Statistical Inference via Data Science: A ModernDive into r and the Tidyverse. CRC Press.


text:
# Classification of dimensions for the non-existence of exotic spheres

It turns out that the only dimensions $n$ for which a sphere $S^n$ admits a unique differentiable structure are exactly $n=1, 2, 3, 5, 6, 12, 56, 61$.

In all other dimensions, except $n=4$, we get the existence of exotic spheres.

What happens at dimension $4$ is still largely unknown and it goes by the name of smooth Poincare conjecture, the only open case of generalized Poincare conjecture.

format: plain


text:
# Suspended from suggesting edits

I suggested an edit to a question which was trivial in the small picture but was a grammatical punctuation mistake that I fixed. A few minutes later I find my edit rejected and a nearly identical edit made by a user with huge rep. Now I can't make any edit suggestions for 7 days for suggesting an edit that was clearly right (check this).

Could anyone help me regarding this? is there a fault of mine or am I overlooking a guideline?

• Which edit is this? Dec 9, 2021 at 23:09
• @bobble I just posted an answer with links. Turns out you and I were the rejecters (rejectors?) on all three edits. Dec 21, 2021 at 14:34

The edit that was rejected was replacing ,with ,  in something that's intended to be CSV, for consumption by computers rather than humans, where you shouldn't have spaces after the commas. I think it was correct for that edit to be rejected, and the similar edit that someone else made (removing spaces) was the right one.

What's stranger is that two other edit suggestions you'd made shortly before were rejected, for no reason I can fathom. (You suggested adding spoiler markup to two answers that didn't have it, and both suggestions were rejected.)

What got you (automatically) blocked from suggesting edits was that run of multiple rejected edits in rapid succession. Since they seem to me obviously benign, I have unblocked you.

Sorry, I only saw this meta post just now. As one of the people who voted to reject all three of your edits, I thought it's fair that I should post an answer here to explain my decisions:

1. This edit is misguided, and you're mistaken to say your edit was "clearly right" based on English punctuation rules which don't apply here as that's not a set of English sentences but a CSV list, in which (depending on the code used to interpret it) either spacing doesn't matter or there should be no spacing. It was pointed out to me after rejecting your edit that the list had an inconsistency, as one space was included in the original post, so I made a small edit to remove that one space (kind of the opposite of your attempted edit).

2. These two edits are more borderline. We do have a general practice of putting spoilertags in answers, and sometimes edits are made to add spoilertagging to older posts which didn't have it, but I don't feel that such edits are always necessary. Who's going to be "spoiled" by seeing an incorrect low-voted answer to a 5-year-old puzzle without needing an extra click to see it? It's one of those things where I think it's far too much effort (and too little gain) to bring all older posts into alignment with current practice on spoilertags.

I'm just one of two rejecters on each of those suggested edits, as edits can't be rejected singlehandedly except by mods and OPs. I didn't realise that you'd be edit-blocked as a consequence of those rejections - in fact, I didn't even realise that automatic edit blocks are possible!

By the way, you can see the reasons for rejection in the review item which still exists as a link, and you can see a list of all your own suggested edits from your profile (that's how I found the three items mentioned above to check and discuss them). Sometimes people don't bother writing a custom explanation for rejection ("The edit does not improve the quality of the post. Changes to the content are unnecessary or make the post more confusing." is just a boilerplate text), but for this one I did.

• I did see that, I know I should've thought about it a little, anyways I'm sorry for what happened back then , I didn't mean to blame any of you guys, y'all are awesome and do a great job as community mods, sorry if you felt anything like that though, I just wanted to know why it happened so that I dont repeat the same mistake again. Cause I didn't know in the first place that edit suspends do exist lol. Thanks for taking the time to write this though Thor, I appreciate it and I'll make sure I don't repeat it :) Dec 21, 2021 at 14:54


text:
+0

# Help me please i really need help

-2
149
2
+135

plz help me solve this problem Assuming that$$3u + 12v\neq0$$ , simplify $$\dfrac{12u^3 + 48u^2v}{3u+12v}$$ . Can you give me a step by step explanation

Jun 19, 2020

#1
+311
+1

Factor the top term and bottom to get:

$$\frac{12u^2(u+4v)}{3(u+4v)}$$

Now we can cancel out the term (u+4v) since the problem tells us that this doesn't equal 0 (division by 0 is undefined)

$$\frac{12u^2}{3}$$

Now simplify to get:

$$4u^2$$

Jun 19, 2020
#2
+135
-3

thank you so much!!!

Jun 19, 2020


text:
# Adjust Numbers in an expression by a set amount

• I am trying to adjust some subtitle files, so I have about 60 files that all need the same adjustments. The problem is that it’s not all the same numbers.
For example,

00:00:36.250 line:77%
00:00:36.250 line:84%
00:00:42.333 line:85%
00:00:47.458 line:84%

I need to move everything down by 5% so all the 84% should be 89%, all the 85% should be 90%, all the 77% should be 82%, etc. The 84, 85, 76, & 77 are common enough that I could do a general search for all of them, but every subtitle is just slightly off of where it should be. the ones that are a problem are the random ones at 13% or 24% or 35%. I saw another post that had a somewhat similar issue that was a bit different, so I figured I would see if someone knows something that’d help.

• @Leon-Bob-Noël

I don’t know exactly what you are going to do now.
Do you want to increase all percentages by 5 or not?
What if values are greater than or equal to 96%, do you want to set them to 100%? Or is there an upper limit?

• So I’m trying to increase the values by 5%. 100% is the upper limit, but 87% is the highest I’ve seen. The ones at the bottom 84, 85, with a couple at 86 & 87 I’m completely removing the line:84% value entirely because I want those to be at the bottom. So I’m not worried about it hitting the upper limit. Oh, yeah, so It does % by % down from the top, so when i say down that’s a higher number, sorry about that.
I want every “line:??%” value to increase by +5% of whatever is there. if there happens to be something that goes over 100% it will be ignored by VTT anyways. I’ve done for 1 folder doing a [Find In Files] starting at 99% & going down increasing everything by 5%, but it took a lot of time & I have to repeat the process for other shows when I find the appropriate % I need to shift. I figure there has to be a simpler way to do it.
Thanks for the help

• @Leon-Bob-Noël

I assume that this python script will do what you want to do

from Npp import editor

def increase(m):
current_value = int(m.group(0))
current_value = current_value+5 if current_value < 96 else 100
return  current_value

editor.rereplace('(?<=line:)\d+(?=%)', increase)

• def increase(m):
current_value = int(m.group(0))
current_value = current_value+5 if current_value < 96 else 100
return current_value

editor.rereplace(’(?<=line:)\d+(?=%)’, increase)

Awesome, it shifts the lines perfectly. But is there a way to make it work on more than 1 file at a time? I have folders of from 12 to 300 files that I need to do the same thing on. It’s a great tool to have on hand that I can adjust to whatever I need, but having to be doing it 60 times is still a problem. If it’s not possible it’s not possible, but I figured there has to be a way

• @Leon-Bob-Noël

One solution could be to use something like this

import os
from Npp import editor

def increase(m):
# As long as only one value in a line is changed
# one can set the default bookmark symbol to see where the changes took place

# start, end = m.span(0)
# start_line = editor.lineFromPosition(start)
# end_line = editor.lineFromPosition(end)
# for i in range(start_line, end_line+1):

current_value = int(m.group(0))
current_value = current_value+5 if current_value < 96 else 100
return  current_value

for currrent_directory, _, files in os.walk(r'PATH_WITHOUT_TRAILING_BAKSLASH'):
for _file in files:
if _file.endswith('.txt'):
editor.rereplace('(?<=line:)\d+(?=%)', increase)
# notepad.save() # automatically save changes
# notepad.close() # close active buffer

• It walks down from a given directory and loads the file with the txt extension and changes its contents if it matches something.

• @Ekopalypse Would this work if the extension is VTT? It’s set to open as a text document but I don’t think that counts

• Would this work if the extension is VTT?

Not as it is. But, really, is it that hard to see it?
I mean, the relevant line in the code reads almost like English:

if _file.endswith('.txt'):

Exercise left to the reader to figure out what to change it to. :-)

• @Alan-Kilborn oh yeah, cool. So do I not run this whithin Notepad ++ then?

• I’ve tried running it in Notepad ++ python scripts but no matter how I do it it does not work. With a file open in the directory it does nothing, with the directory open as workspace it does nothing, I didn’t try it with those setting with TXT files, assuming that changing it to “if _file.endswith(’.vtt’)::” didn’t work because Notepad++ wasn’t recognizing them because it doesn’t recognize the extension by default & doesn’t have the language in it’s database

• @Leon-Bob-Noël
It must run from within Npp but there is no need to load the file,
this is done by the script.
You just have to adjust the file ending and the root path.

os.walk(r'PATH_WITHOUT_TRAILING_BAKSLASH'):

example

os.walk(r'C:\Documents\whatever\directory\it\is'):

• @Ekopalypse Ah, thanks. Will is do recursive directories or just the root specified?

• @Leon-Bob-Noël - it walks the tree recursively.

• @Leon-Bob-Noël

You could just experiment with it to find out these answers, instead of asking and then waiting to have a response.

• @Alan-Kilborn if I was receiving answers while I was able to actually do it sure, but then if not I’d have to then ask if there was a way to do it. That seems much less efficient. I know when I’m helping someone I’d much rather have them ask questions right away. The longer they wait the less likely I’ll be looking at the forum to know they need a response. Maybe that’s just me, but having a question & waiting to ask it because it might not be necessary is just rude to the person giving help, while asking questions that are unnecessary right away is only really harmful to the ego of the asker, I’d rather look like I don’t know something I actually don’t know, than go to do something & have to come back & ask for more information because I was afraid of looking like an idiot, & thereby actually being an idiot


text:
# Why is the mapping class group of hyperbolic manifolds finite?

Hi! I'm trying to understand why a hyperbolic n-manifold has finite mapping class group if $n \geq 3$. In books I'm reading it's said it's a consequence of Mostow's rigidity theorem: "If M and N are complete hyperbolic manifolds with finite total volume, any isomorphism of fundamental groups is realized by a unique isometry."

A corollary of this is that: " If M is hyperbolic (complete, with finite total volume) and $n \geq 3$, then Out($\pi_{1}(M)$) is a finite group, isomorphic to the group of isometries of M ".

But how could this could solve my problem? I mean, I know there is Dehn-Nielsen Theorem which states that Out($\pi_{1}(M)$) is isomorphic to MCG(M), but I know this to be true only in dimension 2...what can I say in dimension (at least) 3? Thank you.

-
Hyperbolic manifolds have contractible universal covers (ie hyperbolic space), so they are $K(\pi,1)$'s. It is standard that there is a bijection between self-homotopy equivalences of $K(\pi,1)$'s and outer automorphisms of $\pi$. –  Andy Putman May 30 '11 at 15:09
I know there is Dehn-Nielsen Theorem which states that $Out(\pi_1(M))$ is isomorphic to $MCG(M)$, but I know this to be true only in dimension 2...what can I say in dimension (at least) 3?'' Taking away the hypothesis that $M$ is hyperbolic turns this into a much more interesting question (in my humble opinion). An attempt at rephrasing it is here: mathoverflow.net/questions/66484/… –  Dave Futer May 30 '11 at 19:31
@Lor: notice the difference between Agol's response and my own. Depending on how you define "mapping class group" the question you ask is quite different. My response was assuming "mapping class group" meant $\pi_0 HomotopyEquivalences(M)$. Ian's response is for $\pi_0 Homeo(M)$. I don't believe Ian's response applies to $\pi_0 Diff(M)$ provided the dimension of $M$ is large. –  Ryan Budney May 30 '11 at 19:36

In dimension three, this was proven by Gabai, Meyerhoff, and N. Thurston. This was proven orginally for Haken 3-manifolds by Hatcher. Gabai extended this to hyperbolic 3-manifolds satisfying a certain technical condition, which was then verified for all closed hyperbolic 3-manifolds in the above paper. Gabai extended this result to prove that $Diff(M) \simeq Isom(M)$.

The analogous result in higher dimensions was proved by Farrell and Jones (see Theorem 5, I think this is only for dimension $>5$, but this isn't explicitly stated). Proofs are given here. I don't think dimensions $4$ or $5$ have been worked out.

-
As Andy mentions, the isometry group $Isom(M)$ is isomorphic to $\pi_0 HomotopyEquiv(M)$ by Mostow rigidity. The isomorphism between $\pi_0 HomotopyEquiv(M)$ and $Out(\pi_1 M)$ is true for any $K(\pi,1)$-space, I believe this appears in Hatcher's Algebraic Topology book, but it's essentially the same as the argument you've seen for surfaces -- try comparing the two.


text:
# How to get secrets from the AWS Parameter Store into containers in ECS

on
Oct 22, 2019
in

On AWS we often use the AWS Parameter Store, to store secrets safely. But accessing the secrets from an application running in ECS, is rather intrusive. You have to call the AWS SSM API either in the application or in the entrypoint script of the container. In this blog we show you how a simple utility allows you to specify the references to the secrets as environment variables. It even allows you to specify sensible defaults.

## How does it work?

To use the utility, follow these two steps:

1. include the executable in your container and make it your Container entrypoint
2. Define environment variables with a URI using the ssm: protocol

### Include the executable

FROM docker.io/binxio/ssm-get-parameter:0.2.3 AS ssm

FROM alpine
COPY --from=ssm /ssm-get-parameter  /usr/local/bin
ENTRYPOINT [ "/usr/local/bin/entrypoint" ]

Make sure to move the old entrypoint to the CMD of the container.

### Define the environment variable

To retrieve the secrets into your container, define one or more environment variables with a URI using the ssm: protocol:

ENV PGPASSWORD=ssm:///postgres/root/password

If the parameters cannot be retrieved, the container will exit with an error. If you wish to continue, specify a default parameter:

ENV PGPASSWORD=ssm:///postgres/root/password?default=postgres

This will allow to run the container outside of AWS. You can also write the content of the secret
to a file by specifying the destination parameter.

ENV PRIVATE_KEY=ssm:///private-key?destination=/tmp/private-key

The value of the environment variable will be replaced with the name of the file, in this case /tmp/private-key.
If the parameter cannot be retrieved and the destination file already exists, the contents of that file will
be used as the default value.
Finally, if you need the secret in a string, you can use the template parameter:

ENV PGPASSFILE=ssm:///postgres/root/password?\
template=localhost:5432:kong:kong:{{.}}%0a&\
destination=\$HOME/.pgpass&\
default=postgres

## Conclusion

With the ssm-get-parameter utility you have an non-intrusive way of retrieving secrets from the parameter store and save them as environment variable values or in a file in your container. By using the default option, you can provide sensible defaults which allows you to run your container independent of AWS.
If you are looking for the same thing in Google Cloud Platform, read how to get secrets from the Google Secret Manager into your container.

Mark van Holsteijn is a senior software systems architect, and CTO of binx.io. He is passionate about removing waste in the software delivery process and keeping things clear and simple.


text:
baldymcgee6 Group Title Scientists discover a fossil that contains 74% as much radioactive carbon, 14C, as does a living mammal. Assuming the half-life of 14 C to be about 5730 years, write the ODE representing the decay of carbon in the specimen and estimate its age. one year ago one year ago

1. levinelevine Group Title

whats ODE

2. baldymcgee6 Group Title

ordinary differential equation

3. levinelevine Group Title

$\frac{ \delta fc }{ \delta t }=-\frac{ \ln(2) }{ half-life }fc$

4. levinelevine Group Title

where fc is the concentration of C14

5. baldymcgee6 Group Title

right, I know the formula for half-life but i don't know how to get the ODE

6. levinelevine Group Title

thats the ODE

7. levinelevine Group Title

you want the process to get there?

8. baldymcgee6 Group Title

9. levinelevine Group Title

Im too tired to explain how i got there, its a little bit complicated... srry mate

10. baldymcgee6 Group Title

Alright, thanks anyways.

11. levinelevine Group Title

but do u know how to solve that?


text:
# How to make the table of contents section title upper case without messing with the space between the chapter and section?

When I use this bellow to make the section text upper case:

\makeatletter
\renewcommand*{\l@section}[2]
{%
\l@chapapp{\uppercase{#1}}{#2}{\cftsectionname}
}
\makeatother

The spacing between my chapter and section is added to the same length as set by (TOC Spacing in Memoir):

\setlength{\cftbeforechapterskip}{12pt}

But if I remove these lines:

\makeatletter
\renewcommand*{\l@section}[2]
{%
\l@chapapp{\uppercase{#1}}{#2}{\cftsectionname}
}
\makeatother

The spacing between chapters and section is correct:

How to make the table of contents section title upper case without messing with the space between the chapter and section?

With this full code, you can reproduce the problem after building it two times:

\documentclass{abntex2}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

% TOC Spacing in Memoir
% https://tex.stackexchange.com/questions/60317/toc-spacing-in-memoir
\setlength{\cftbeforechapterskip}{12pt}

\makeatletter
\renewcommand*{\l@section}[2]
{%
\l@chapapp{\uppercase{#1}}{#2}{\cftsectionname}
}
\makeatother

\begin{document}

\begin{KeepFromToc}
\tableofcontents
\end{KeepFromToc}

\chapter*{Foreword}

\chapter*{Abstract}

\chapter{Chapter One}
\section{Section One One}
\subsection{Section One One}

\section{Section One Two}
\subsection{Section One Two}
\section{Section One Three}
\section{Section One Four}

\chapter{Chapter One}
\section{Section One One}

\section{Section One Two}
\section{Section One Three}
\section{Section One Four}

\end{document}

I managed to fix it using a general solution for the article class I find on How to make section name uppercase in ToC?:

\documentclass{memoir}
\usepackage{textcase}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\makeatletter
\let\oldcontentsline\contentsline
\def\contentsline#1#2{%
\expandafter\ifx\csname l@#1\endcsname\l@section
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{%
\oldcontentsline{#1}{\MakeTextUppercase{#2}}%
}{%
\oldcontentsline{#1}{#2}%
}%
}
\makeatother

\begin{document}

\begin{KeepFromToc}
\tableofcontents
\end{KeepFromToc}

\chapter*{Foreword}

\chapter*{Abstract}

\chapter{Chapter One}
\section{Section One One}
\subsection{Section One One}

\section{Section One Two}
\subsection{Section One Two}
\section{Section One Three}
\section{Section One Four}

\chapter{Chapter One}
\section{Section One One}

\section{Section One Two}
\section{Section One Three}
\section{Section One Four}

\end{document}

Also it was required to remove these statements from my file:

\renewcommand*{\l@chapter}[2]
{%
\l@chapapp{\uppercase{#1}}{#2}{\cftchaptername}
}

\renewcommand*{\l@section}[2]
{%
\l@chapapp{\ABNTEXsectionfont\uppercase{#1}}{#2}{\cftsectionname}
}

They were the cause of all my problems. I am not sure why they are scrolling everything, as causing the spacing between the section and chapter to be the same as the space between chapters.

This last should be due the fact that the command is redefining the \l@section with \l@chapapp, which is just like begging for trouble and weird behaviors.


text:
# Babymath: Story Problem Challenge III

<a href="http://www.flickr.com/photos/goetter/2352128932/"Photo by Raphael Goetter via Flickr

Alex and Leon enjoyed their baby sister, but they were amazed at how much work taking care of a baby could be. One particularly colicky night, everyone in the family took turns holding the baby, rocking the baby, patting her back, and walking her around before she finally succumbed to sleep.

Then Alex collapsed on the couch, and Leon sank into the recliner. They teased each other with these story problems.

# Graph-It Game

[Photo by Scott Schram via Flickr.]

For Leon’s Christmas gift, Alex made the Graph-It game. She wrapped a pad of graph paper and wrote up the instructions:

To play Graph-It, one person designs a picture made by connecting points on a coordinate graph. He reads the points to the other player, who tries to reproduce the picture.

# Renée’s Platonic Mobile

Alexandria Jones struggled to think of a Christmas gift that a one-month-old baby could enjoy, but finally she got an idea.

She cut empty cereal boxes to make regular polygons: 6 squares, 12 regular pentagons, and 32 equilateral triangles. Using small pieces of masking tape, she carefully formed the five Platonic solids. Then she mixed flour and water into a runny paste. She tore an old newspaper into small strips and soaked them in the paste. She covered each solid with a thin layer of paper.

# A Football Puzzle

[Photo by rdesai.]

The MIT Mathmen got the ball on their own 20-yard line for the last drive of the game. They were down by 2 points, so they needed at least a field goal to win the game.

If quarterback Zeno and his offense advanced the ball halfway to the opposing team’s end zone on each play…

# And the Baby Is . . .

[Photo by gabi menashe.] This story is continued from Alexandria Jones and the Eighty-Yard Drive

There was a time-out on the field, and the Jones family sat down for a brief rest. Sam asked, “How do babies decide when it’s time to be born?”

“Well, son, it has to do with numbers. You see,” Uncle Will explained, “the baby spends his first month thinking about the number one.”

“That’s not much to think about,” Sam said. “But I suppose he can’t handle much at that age.”

# Alexandria Jones and the Eighty-Yard Drive

[Photo by West Point Public Affairs.]

Alexandria Jones pulled the last sheet of chocolate chip cookies from the oven and inhaled deeply. Mmm! Perfect. And just in time — Mom was calling her to the car. She slid the cookies into a plastic bowl but left the lid off so the steam could escape. The Jones family was going to meet Uncle Will and Alex’s cousin Sam for a tail-gate picnic before the big football game.

# Alex Deals Out Equations

Image by incurable_hippie via Flickr

Looking around the room, Alex saw kids and parents moving from one table to another. Everyone seemed to be enjoying the Homeschool Math Carnival. She had six junior-high and high school students at her table, waiting while she shuffled her deck of cards.

“Okay,” she said. “These are Math Cards. I took out the face cards, so we just have numbers.”

# Cousin Sam’s 15 Challenge

Uncle Will drove in from the tree farm to drop off Alex’s cousin, Sam, so he could go to the Homeschool Math Carnival.

“Hey, Sam,” Alex said. “What’s in the sack?”

Sam smiled. “A secret puzzle.”

“Aw, c’mon,” Leon whined. “We’ll be busy with our own games at the carnival. Can’t you show us now?”

# Alexandria Jones and the Mathematical Carnival

Maria Jones hung up the phone and collapsed at the kitchen table. She buried her head in her hands and groaned. Alex looked up from her game of Solitaire.

“Let me guess,” she said. “Can’t-Say-No Syndrome, again?”

Mrs. Jones nodded. “This time I volunteered to plan an activity for next month’s homeschool group meeting.”

Leon wandered in and pulled an apple from the fruit bowl. “Ha!” he said. “She means she volunteered us to plan an activity, right?”

Mrs. Jones smiled. “That’s my motto: When in doubt, delegate!”

# Math History Tidbits: The Battling Bernoullis

July 27th is Alex’s birthday. She shares it with Johann Bernoulli, an irascible mathematician from the late 17th century. This coincidence intrigued her enough that she wrote a research paper on Johann and his mathematical brother, titled “Jeering Jacob and Jealous Johann.”

Of course, to make the alliteration work, she had to mispronounce Johann’s name — but she figured he kinda deserved that. Read the historical tidbits below to find out why one writer said the Bernoulli brothers were “the kind of people who give arrogance a bad name.”*

# Probability Issue: Hints and Answers

Remember the Math Adventurer’s Rule: Figure it out for yourself! Whenever I give a problem in an Alexandria Jones story, I will try to post the answer soon afterward. But don’t peek! If I tell you the answer, you miss out on the fun of solving the puzzle. So if you haven’t worked these problems yet, go back to the original posts. If you’re stuck, read the hints. Then go back and try again. Figure them out for yourself — and then check the answers just to prove that you got them right.

This post offers hints and answers to puzzles from these blog posts:

# Probability and Baby Blues

[Photo by audi_insperation.]

[In The Birthday Surprise, Alex discovered her family was expecting a new member...]

What will the baby look like, Alex wondered. “Dad, is there any way to tell whether the baby will have blue eyes like I do, or brown like the rest of the family?”

Dr. Jones shuffled the papers on his desk and found a blank page. “Over 100 years ago, the Austrian monk Gregor Mendel studied genetics, or how various traits are passed down from one generation to another.” He began to draw a diagram as he talked.

# Alexandria Jones and the Birthday Surprise

[Photo by D Sharon Pruitt.]

[July 27th is Alex’s birthday, which she shares with Johann Bernoulli, an irascible mathematician from the late 17th century.]

The guests had gone. Alex and her family sat around the table, sharing the last tidbits of birthday cake and ice cream. Alex smiled at her parents.

“Thanks, Mom and Dad,” she said. “It was a great party.”

Maria Jones, Alex’s mother, leaned back in her chair. “I do have one more surprise for you, Alex. But you will have to share this one with the whole family.”

Leon groaned. “I know what it is: Let’s all pitch in to clean up.”

“That wouldn’t be a surprise,” Alex said.

# Math History Tidbits: Agnesi, Euler, and China

I’ve fallen behind on my project of transcribing my Alexandria Jones stories. Finally, here are a few more tidbits from math history, along with links to relevant Internet sites and a few math puzzles for your students to try.

I hope you find them interesting.

Remember the Math Adventurer’s Rule: Figure it out for yourself! Whenever I give a problem in an Alexandria Jones story, I will try to post the answer soon afterward. But don’t peek! If I tell you the answer, you miss out on the fun of solving the puzzle. So if you haven’t worked these problems yet, go back to the original post. Figure them out for yourself — and then check the answers just to prove that you got them right.

Euclid’s Geometric Algebra

# Euclid’s Geometric Algebra

Picture from MacTutor Archives.

After the Pythagorean crisis with the square root of two, Greek mathematicians tried to avoid working with numbers. Instead, the Greeks used geometry to demonstrate mathematical concepts. A line can be drawn any length, so straight lines became a sort of non-algebraic variable.

You can see an example of this in The Pythagorean Proof, where Alexandria Jones represented the sides of her triangle by the letters a and b. These sides may be any length. The sizes of the squares will change with the triangle sides, but the relationship $a^2 + b^2 = c^2$ is always true for every right triangle.

# The Mosaic Tile Mystery

## Dear Alexandria Jones,

We continue to excavate the ancient building complex, which I believe may have been Pythagoras’s school. Yesterday, one of our digging crews uncovered a mosaic tile floor in the courtyard. The pattern of the tiles alternates between two square designs. (See enclosed sketches.)

During your family’s recent visit, you expressed an interest in the mathematical ideas of Pythagoras. Could you or your father offer us any insight into what these tile designs may represent?

I look forward to your response.

Sincerely,
Sofia Theano, Ph.D.
Crotone, Italy

# Alexandria’s Dog is Now a Teacher

Photo by alex-s.

A reader of Indian descent has been kind enough to write to me about a difference in our cultures. In the US, or at least in the parts with which I am familiar, it is common to name one’s pet after a famous person. In India, however, to name a dog after a human is a very deep insult.

I am sorry! It was not intended that way.

Therefore, I have re-named Alexandria Jones‘s dog after a Westerner. I would like to keep the tradition of naming the characters in my Alex stories after people in math history, so I am hoping this one will not offend anyone.

# Game: Avoid Three, or Tic-Tac-No!

Math concepts: slope, logical strategy
Number of players: 2 or more
Equipment: 4×4 or larger grid, pebbles or other tokens to mark squares

## Set Up

Alexandria Jones and her brother Leon played Avoid Three with pebbles on a grid scratched in the sand, but you can also use pencils or markers on graph paper. You need a rectangular playing area at least 4×4 squares large. The bigger your grid, the longer your game.

# Answers to Leon’s Figurate Number Puzzles

Remember the Math Adventurer’s Rule: Figure it out for yourself! Whenever I give a problem in an Alexandria Jones story, I will try to post the answer soon afterward. But don’t peek! If I tell you the answer, you miss out on the fun of solving the puzzle. So if you haven’t worked these problems yet, go back to the original post. Figure them out for yourself — and then check the answers just to prove that you got them right.

# Puzzle: Figuring Out Figurate Numbers

Photo by frumbert.

Alexandria Jones‘s parents decided that the family needed to relax after the excitement of tracking Simon Skulk, so they spent the next day at a beach on the Mediterranean coast. Leon collected pebbles and tried to build up figurate numbers — numbers that make a figure, or shape — the way Dr. Theano had shown them.

# The Puzzling Pythagorean Pebbles

Photo by meichimite.

Alexandria Jones and her family flew to Italy for spring break. Her father, the famous archaeologist, had to visit an excavation.

It was late when their plane landed in Crotone, a small coastal city near the instep of Italy’s boot. Dr. Jones had used the Internet to find a hotel that allowed pets, so Alex was able to snuggle down with her favorite pillow — her trusty dog, Ramus.

## The Original School of Mathematics

The next day, Dr. Jones introduced his family to Sonya Theano, a former student of his and the director of this dig. “Come, let me show you around,” Dr. Theano said. “We’ve uncovered several buildings of a small compound, set apart from the city of Crotona, as it was called then. From the pottery and trade goods, we estimate these buildings were in use around 550-500 BCE.”

# Answers to Alex’s and Leon’s Puzzles

Remember the Math Adventurer’s Rule: Figure it out for yourself! Whenever I give a problem in an Alexandria Jones story, I will try to post the answer soon afterward. But don’t peek! If I tell you the answer, you miss out on the fun of solving the puzzle. So if you haven’t worked these problems yet, go back to the original posts. Figure them out for yourself — and then check the answers just to prove that you got them right.

Leonhard’s block puzzles

Alex’s & Leon’s homeschool puzzle

# Alex’s & Leon’s Homeschool Puzzle

Photo by gotplaid?.

While checking out the book table after a homeschool group meeting, Maria Jones glanced up to see her children laughing with some kids she did not recognize. Driving home, she asked about the new family, but Alex and Leon had been too busy exchanging silly stories to even ask the strangers’ names.

“Well,” Leon said, “the boy told me he has twice as many sisters as brothers.”

No way!” said Alex. “The girl told me that she has the same number of brothers and sisters.”

How can that be?

# Leonhard’s Block Puzzles

Leonhard Jones is Alexandria Jones’s younger brother. He enjoys woodworking, and he cut a wooden cube into 8 smaller blocks to make himself a puzzle.

## Puzzle #1

Leon painted the 8 blocks with his two favorite colors: red and forest green. When he was finished, Leon could put the blocks together into a red cube, or he could switch them around to make a green cube.

How did Leon paint his blocks?

# Egyptian Fractions: The Answer Sheet

Remember the Math Adventurer’s Rule: Figure it out for yourself! Whenever I give a problem in an Alexandria Jones story, I will try to post the answer (relatively) soon afterward. But don’t peek! If I tell you the answer, you miss out on the fun of solving the puzzle. So if you haven’t worked these problems yet, go back to the original post. Figure them out for yourself — and then check the answers just to prove that you got them right.

## The Secret of Egyptian Fractions

Alex made a poster of Egyptian-style fractions, from 1/2 to 9/10. Many of the fractions were easy. She knew that…

$\frac{5}{10} = \frac{4}{8} = \frac{3}{6} = \frac{2}{4} = \frac{1}{2}$

Therefore, as soon as she figured out one fraction, she had the answer to all of its equivalents.

She had the most trouble with the 7ths and 9ths. She tried converting these to other fractions that were easier to work with. For example, 28 has more factors than 7, making 28ths easier to break up into other fractions with one in the numerator.

# The Secret of Egyptian Fractions

Photo from Library of Congress via pingnews.

Archaeology professor Dr. Fibonacci Jones came home from a long day of lecturing and office work. Stepping inside the front door, he held up a shiny silver disk.

“Ta-da!” he said.

“All right!” said his daughter Alexandria. “The photos are here.”

They had to chase Alex’s brother Leon off the computer so they could view the images on the CD, but that wasn’t hard. He wanted to see the artifacts, too. Alex recognized several of the items they had dug up from the Egyptian scribe’s burial plot: the wooden palette, some clay pots, and of course the embalmed body.

Then came several close-up pictures of writing on papyrus.

Remember the Math Adventurer’s Rule: Figure it out for yourself! Whenever I give a problem in an Alexandria Jones story, I will try to post the answer soon afterward. But don’t peek! If I tell you the answer, you miss out on the fun of solving the puzzle. So if you haven’t worked these problems yet, go back to the original post. Figure them out for yourself — and then check the answers just to prove that you got them right.

Alexandria Jones and the Christmas Present Quandary

Magic Square Puzzles

# Magic Square Puzzles

Alex handed her brother Leonhard a box wrapped in the rocket tessellation paper, with air holes carefully punched in two sides.

“Merry Christmas, Leon!” she said.

He ripped open the gift. Alex winced. Boys have no artistic appreciation, she thought.

“Oh, cool! Thanks,” Leon said.

“His name is Lo-shu,” said Alex. “But be careful. I used non-toxic tempera paint. The design will was off.”

Leon turned the turtle and studied the back of its shell. “Oh, that’s just like in the legend! I’ll copy it down before I let him near any water.”

• What do the shapes on Lo-shu’s back mean?
• Why are some dots white and some black?


text:
# New Features P3: Memory Management Scopes

Intro

It looks like the next build of 4coder (4.0.29) is going to be ready sometime in the next few weeks. The new build has been in development for a couple months and is loaded to the brim with new features that have all gone through interesting architectural and algorithmic design that I believe are worth sharing for several reasons. One it will prepare 4coder users who want to start writing customizations for how to think about the new features. Two it will help anyone who likes to think about the processes of architecture and algorithm design with some examples of my own process. Three it might expose me to some criticisms or suggestions that could help me improve the specifics of the new 4coder features before I put them into the wild.

Directory of all parts:
1. Memory Management Overview
2. Memory Management Variables and Objects
3. Memory Management Scopes
4. Custom UIs and Various Layers for Lister Wrappers
5. Custom Cursors, Markers, and Highlights, and the Render Caller

Scopes Basics

If you're not caught up with part 1 and part 2, go back and get caught up, because this part will make no sense without that context. Scopes are all about two things, managing lifetimes and keying values you want to store. Both of these terms deserves more elaboration. By "managing lifetimes" I mean a few things. There is the fact that the memory put on the scope is freed when the scope closes, thus preventing memory leaks, but there's a bit more to it too. Since scopes contain variables, we can close and reopen a scope to free it's contents and set all it's variables back to default. In other words managing lifetimes is about doing bulk actions that clear a state back to default.

By "keying values" I am talking about the method you use to store and retrieve a value. One big difference between an object and a variable in this system is that the two are keyed very differently. Variables are keyed by a scope and a compile time constant, while objects are keyed by runtime generated handles. These differences have all sorts of implications. If you have an function that does several variable operations inside a scope, that function only needs to be parameterized on the scope, whereas the same operation on several objects would have to be parameterized on each object handle. Of course we can construct all sorts of other scenarios where we would prefer not to have to have a scope and variable name and would rather just manipulate everything through a few runtime handles. The point of this is whenever we put something into a scope it's not just about tieing the lifetime of the allocation to the scope so that it will free at the appropriate time, but we're also setting ourselves up to be able to find that information when, and only when, we want to be able to get it back.

The core provides scopes tied to the lifetime of buffers, scopes tied to the lifetime of views.
 1 2 Managed_Scope buffer_get_managed_scope(Application_Links *app, Buffer_ID buffer_id); Managed_Scope view_get_managed_scope(Application_Links *app, View_ID view_id);

User Scopes

Tieing scopes to buffers and views does a lot of work, but once I started getting used to scopes I realized that module authors could have all sorts of reasons to create scopes themselves so that their own concepts with lifetimes could also have all the advantages of the scoping system. For instance suppose you build a little debugger integration into 4coder and you have a command that explicitly begins a debug sessions and another that explicitly ends the session. Those would be perfect times to start and end a managed scope, so that all the data you create and store along the way that is specifically relevant to the debugging session, but not relevant without it, can be on that scope. For this purpose I introduce a pair of calls for creating and destroying user managed scopes.

 1 2 Managed_Scope create_user_managed_scope(Application_Links *app); bool32 destroy_user_managed_scope(Application_Links *app, Managed_Scope scope);

Note that introducing this destroy call has the possibility to confuse users who think they can or should destroy scopes from the core like the view and buffer scopes. However I didn't want to introduce a different type for user scopes because, besides this one quirk, everything else a scope can do is universal between core scopes and user scopes: variable set, variable get, object allocate, and all of the scope operations to come in this post.

Bulk Clear - Heaps in Heaps

I've used the phrase "bulk" several times now, and this is the first part of the system that is algorithmically interesting. When I say bulk, I am not just saying that a whole bunch of individual frees are done automatically. That would be "bulk" in the sense that one call triggers a bunch of work for convenience, but I actually mean "bulk" in the sense that one call achieves a bunch of work by a more efficient method than you could achieve without going bulk. First, let's consider a scope as basically having two main allocation systems, the allocation for variable storage and the allocation for object storage. Variables are stored in a sparse lookup table that is allocated in a single contiguous block and can be freed in one operation no matter how many variables in the scope were actually modified from their default value.

Bulk freeing allocation for objects is the more interesting case. Recall that memory objects are allocated with a variable size and support a free operation:
 1 2 Managed_Object alloc_managed_memory_in_scope(Application_Links *app, Managed_Scope scope, int32_t item_size, int32_t count); bool32 managed_object_free(Application_Links *app, Managed_Object object);

In 4coder this is all based on a very simple heap style allocator, but the implementation type and optimization details are actually not important to the concept, an allocator that supports the following operations is all we need to alloc, free, and bulk free our objects:
 1 2 3 4 5 struct Allocator{ /*off topic*/ }; Allocator make_empty_allocator(); void allocator_extend_available_memory(Allocator *allocator, void *mem, int32_t size); void *alloc(Allocator *allocator, int32_t size); void free(Allocator *allocator, void *ptr);

The keys here are that we have an Allocator handle in each operation, so that we can build multiple allocators and easily parameterize allocations on the allocator, and that we can extend an allocator an arbitrary amount while knowning that it does not automatically extend itself. Then what we can do is have a source of memory at the top of the system which can be an Allocator or anything else, and then we can build a separate allocator for each scope. Whenever we allocate an object on the scope, we go through the allocator assigned to that scope, so all of the alocations belong to a set of larger contiguous ranges, and if we fail to get the memory we need we can go to the larger allocation system at the top of the system and get some more memory to extend the scope's allocator. Finally when the time comes to free all objects we can iterate each page that we got from the top and free it back to the top, we don't have to iterate all the little objects and free each one individually. If we do a good job of putting lots of objects on each page we have greatly reduced the amount of freeing work we have to do on a bulk free operation.

With this design I have found that it almost never takes more than two frees to the top to destroy any scope (often less than two because scopes don't allocate anything for variables or objects before they have to).

Bulk clears and resets are so useful that sometimes I think we will want to do them without destroying the scope, and sometimes we will want to do a bulk clear on a core scope that we can't destroy, and the API supports this:
 1 bool32 clear_managed_scope(Application_Links *app, Managed_Scope scope);

Scopes with Multiple Dependencies (Turning the wacky and wild dial to eleven)

It turns out that scopes as described so far, while they solve a lot of useful problems, also feel like they fall just short of fully solving the problem in a lot of cases. Let's look at the case of building the sticky jumps system in 4coder. Sticky jumps is the name for the system that powers jumping to error and jumping to items in a search list. They are "sticky" because once the jumps are parsed, the positions are marked with markers which will follow that text around as the buffer is edited. This means that jump lines and positions remain correct even as the text about the position change. We will look at how markers operate in more detail in part 5, but for now the important point is that markers are only relevant while the buffer they mark still exist and while the buffer that contains the jump lines still exists, because in 4coder the way you trigger a jump needs the jump buffer even after the markers for sticky jumps have been placed. So what do we do?

If we place the markers in the scope of the destination buffer, they will be freed automatically when that buffer is closed, but if the jump buffer is closed it has to manually free all the markers it created, and by the way jump buffers are closed and reopend all the time, for instance every time you rebuild the compilation buffer, which can have jumps, is closed and reopened. If we place the markers in the scope of the jump list buffer, we just flip the problem around without solving it, now the jump lists which are frequently closed get the bulk automatic free, but all other buffers in the entire system now have to take themselves out of all the lists out there whenever they close. We can't just leave markers in the scope of the jump list and hope the jump list gets closed and reopened soon, because as long as that info sits there, someone might try to jump to it even though the system should know that that's impossible now, it's not just a leak to leave something around it's a bug!

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // Bad scenario one: store markers in the scope of desitnation buffer BUFFER_CLOSE_HOOK(sticky_jump_cleanup_hook){ Jump_List *list = lookup_jump_list(buffer_id); if (list != 0){ for (int i = 0; i < list->count; i += 1){ managed_object_free(app, list->marker_handle[i]); } free_jump_list(list); } // By the way, when we close buffers that have // markers attached, do we just leave the stale // handle in the jump list, or... ??? } // Bad scenario two: store markers in the scope of the jump buffer BUFFER_CLOSE_HOOK(sticky_jump_cleanup_hook){ List_Of_Lists_That_Refer_To_A_Buffer *list_of_lists = lookup_list_of_lists(buffer_id); if (list_of_lists != 0){ for (int i = 0; i < list->count; i += 1){ Jump_List *list = lookup_jump_list(list_of_lists->lists[i].list_buffer_id); if (list != 0){ int index = list_of_lists->lists[i].my_sub_index; managed_object_free(app, list->marker_handle[index]); list->marker_handle[index] = 0; } } free_list_of_lists(list_of_lists); } }

I hope you can feel where this is going. We want a scope where we can place information and we want that scope to be dependent on two different buffers. When I started to feel this problem I decided to take some time to do some architectural investigation and figure out what it was I was really wanting. In this case all I knew about the API was I wanted a new way to get a Managed_Scope I couldn't confidently say more than that because I wasn't sure what was feasible, so I started thinking about the rest of the problem from the implementation end. Should I support some kind of "pairs of scopes" system? Or should I just go full arbitrary sets of dependencies? Should I create a user scope and set the dependency, or should the core own the scopes with multiple dependencies? I started by asking if the best case scenario was feasible: Arbitrary sets of dependencies, automatically managed by the core.

You might question whether "automatically managed by the core" is best case scenario, because it appears to remove some felxibility from the system. Maybe a user wants to create and close the scope manually and also set it to automatically close in other conditions! But I thought "core managed" was better because I wanted to rely on the scope's capacity for keying. For example, if I have a pair of buffers that I used to get a scope with multiple dependencies, and then I store a variable into that scope, I want it to be trivial to get that variable again the next time I happen to have the same pair of buffers. If I used user created scopes, then although the scope would have the right life time properties, the pair of buffers would not be a key that retrieves that scope, which is a feature I knew I would need.

CREDITS: Andrew Chronister, the Chronal Dragon, deseves the credit for coming up with the heart of this system. I had already conceived of the problem and endeavored to evaluate the best possible solution, and before I discussed it with Andrew, my best solution wasn't very good. He provided the key insight that I needed to support this feature. In the process we used to reach the solution we rephrased the problem into simpler components that capture the actual heart of the problem. In this case we have "objects" which are things like buffers and views, which we will name with capital letters A, B, C and "keys" where a key is a set of objects. All possible sets of objects are valid keys.

The connection back to scopes is that each possible key will have a scope associated with, and the objects are the things on which scopes are dependent. When you get the scope for a view or buffer, and when you create a user scope, you are getting a "basic scope" which is a scope associated to a "basic key" which is a key with one dependency.

Examples of basic keys:

1 = {A}
2 = {B}
3 = {C}
4 = {D}

A scope with multiple dependencies is a scope associated with a key with multiple elements. In other words keys like the following:

5 = {A, B}
6 = {A, C}
7 = {A, D}
8 = {A, B, C}

When we want a scope dependent on two different buffers we will get the scopes for each individual buffer, then pass the scopes into a call that builds the union of their keys and uses the new key to lookup and return the scope with multiple dependencies.

The tricky part of this is making sure we have enough information to do all the necessary cleanup work when we destroy an object. Obviously keys are constructed as a set of objects, so one option is that when we destroy object A, we iterate all keys and destroy any key that contains A, removing it from whatever accelerated lookup structures we use. But I didn't like this because I was expecting there to be a lot of keys. After all there is automatically one for each buffer and view, then for any union of basic keys that has been used at least once, those keys exist too. The key insight that I needed to put this whole thing together were following the steps for creating keys and destroying objects, described below in psuedo code:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 struct Key{ struct Object **objects; int object_count; }; struct Object{ // NOTICE: the object stores the list // of keys that currently contain it struct Key **keys; int key_count; int key_max; }; Object* create_object(){ return(AllocAndClearToZero(Object)) } Key* get_key(Object **objects, int object_count){ SortPointers(objects, object_count); object_count = RemoveNeighborDuplicates(objects, object_count); Key *key = LookupKeyInLookupStructures(key); if (key == 0){ key = AllocAndClearToZero(Key); key->objects = AllocArrayAndCopy(Object*, object_count, objects); key->object_count = object_count; // NOTICE: when we create a key we iterate the // member objects and insert ourself into the // object's key list for (int i = 0; i < object_count; i += 1){ StretchBufPush(objects[i]->keys, objects[i]->key_count, objects[i]->key_max, key); } InitObjectsAttachedToKey(key); InsertKeyIntoLookupStructures(key); } return(key); } void internal__destroy_key(Key *key, Object *cause_object){ for (int i = 0; i < key->object_count; i += 1){ // no point in doing anything to the cause object // it is about to free itself Object *object = key->objects[i]; if (cause_object == object) continue; // we remove key from this object // TODO: accelerate to avoid linear search? for (int j = 0; j < object->key_count; j += 1){ if (object->keys[j] == key){ object->key_count -= 1; Swap(Key*, object->keys[j], object->keys[object->key_count]); break; } } } CleanupAnythingAttachedToKey(key); RemoveKeyFromLookupStructures(key); Free(key->objects); Free(key); } void destroy_object(Object *object){ // NOTICE: we have the set of all keys that // contain object and we iterate it to destroy // all dependent keys for (int i = 0; i < object->key_count; i += 1){ internal__destroy_key(object->keys[i], object); } Free(object->keys); Free(object); }

The parts not in CamelCase constitute the heart of the system. We have objects that we create and destroy, and keys that we create under the hood whenever we first try to get them, and then are destroyed when any of their objects are destroyed. Creating a key puts it into all of the appropriate key lists for the appropriate objects. Destroying an object destroys all of it's keys, and destroying a key causes it to remove itself from all of it's objects. I usually don't like letting something get too complicated, and this definitely qualifies as complicated, but now we have the task of comparing it to the alternative.

The alternative is that everytime someone wants a scope with multiple dependencies they start going through the process of building lookup tables so that when an object gets destroyed they can find all of the data structures they need to cleanup. If you scroll back up to Bad scenario one you will see the comment:
 1 2 3 // By the way, when we close buffers that have // markers attached, do we just leave the stale // handle in the jump list, or... ???

And if you look at Bad scenario two you will see the List_Of_Lists_That_Refer_To_A_Buffer. I get the distinct impression from all of this that this pattern of self refential business, all this "keeping a list of places where there are pointers to me so I can remove them" stuff is just the general nature of this problem. Whether or not this is the simplest or best solution I don't know. What I do know for sure was that going case by case wasn't actually making it easier, the extra context of a specific case wasn't enough to simplify the problem. Maybe someday we'll find a simpler solution for this class of problem, but for now, I think we're all very likely to be rewriting the same pointer webs everywhere. I thought I might as well move all the pointer webing into the core, do it once, and get it right so that we never have to do it again for this class of problem.

All of that thinking and considering boils down into one little call:
 1 Managed_Scope get_managed_scope_with_multiple_dependencies(Application_Links *app, Managed_Scope *scopes, int32_t count);

This call really does a union operation on the scopes you pass in. If you pass the same scope twice, you'll get that scope back:

1 = {A}
1 union 1 = {A} union {A} = {A} = 1

If you pass a scope that was already the result of a union, it will be unioned again:

5 = {A B}
6 = {A C}
8 = {A B C}
5 union 6 = {A B} unkion {A C} = {A B C} = 8

Looking at the scopes in this way, it occurred to me that I was missing the scope for the empty set. Such a scope would represent a "global" scope. It has no member objects, so it requires no key to acquire it; when you're thinking about keying "requires no key to acquire" means global. This scope also had the unique property that nothing would ever be able to destroy it, since it is non-basic it has to be destroyed by destroying an object, but no object ever can destroy it. So, quite appropriately, the global scope is a scope that lasts forever (well until you close 4coder, as if that ever happens :D). You could acquire the global scope with get_managed_scope_with_multiple_dependencies by passing in no scopes, but go make life easier the API provides the call:
 1 Managed_Scope get_global_managed_scope(Application_Links *app);

This scope, being associated with the empty key, has the unique property that it has no effect when it's key is unioned to other keys:

0 = {}
4 = {D}
0 union 4 = {} union {D} = {D} = 4

This might seem confusing, but it is actually quite appropriate. The global scope always exists, so it should be meaningless to say that something depends on the lifetime of the global scope.

Finally, just as it is useful to do bulk clears of single scopes, it also strikes me as occasionally useful treat a basic scope as an identifier for the single object it contains, and clear all the scopes that depend on the same object as the basic scope.
 1 bool32 clear_managed_scope_and_all_dependent_scopes(Application_Links *app, Managed_Scope scope);

A Scope with Multiple Dependencies Example (Adjusting to the new whacky world we just created)

Okay that was a lot, let's see how this thing looks in action. Let's return our thoughts to the sticky jumps problem, and solve it with this new power. We can now put the markers into a scope that is dependent on both buffers. We still need a single list of all the object handles spread out across all those scopes, so that we can find what we're looking for from just the jump buffer. To this end we will create an array that stores information per-jump-line. The information will include the id of the destination buffer, a subindex that tells us that this is the Nth jump from this list that goes into this buffer, and the line number of the jump line in the jump buffer.

Triggering a jump looks something like this:
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 void jump_to_line_at_cursor_nearest(Application_Links *app){ View_Summary view = get_active_view(app, AccessAll); Managed_Scope jump_scope = buffer_get_managed_scope(app, view.buffer_id); Managed_Variable_ID jump_array_varid = managed_variable_create_or_get_id(app, "STICKY_JUMPS.jump_array", 0); uint64_t value = 0; if (!managed_variable_get(app, jump_scope, jump_array_varid, &value)){ return; } if (value == 0){ return; } Managed_Object jump_array = (Managed_Object)value; int count = managed_object_get_item_count(app, jump_array); Jump_Data *jumps = AllocArrayAndClearToZero(Jump_Data, count); managed_object_load_data(app, jump_array, 0, count, jumps); int best_index = find_best_jump(jumps, count, view.cursor.line); Jump jump = jumps[best_index]; Managed_Scope dest_scope = buffer_get_managed_scope(app, jump.dest_buffer_id); if (dest_scope == 0){ return; } Managed_Scope scope_array[2]; scope_array[0] = jump_scope; scope_array[1] = dest_scope; Managed_Scope marker_scope = get_managed_scope_with_multiple_dependencies(app, scope_array, 2); Managed_Variable_ID marker_array_varid = managed_variable_create_or_get_id(app, "STICKY_JUMPS.marker_array", 0); if (!managed_variable_get(app, marker_scope, marker_array_varid, &value)){ return; } if (value == 0){ return; } Managed_Object marker_array = (Managed_Object)value; Marker marker = {0}; if (!managed_object_load_data(app, marker_array, 0, 1, &marker)){ return; } DoJump(app, jump.destination_buffer_id, marker.pos); Free(jumps); }

If that looks like we've had to do more work here than we would have done without managed variables and objects and scopes everywhere, you're absolutely right. This code would be half as long if all the memory was allocated and managed directly by the custom side. However by doing the extra work to pass all memory management through this system, we are now completely free from having to write any freeing code for markers and lists, and while this is a lot of code, I find it much easier to get right than the "list of lists with pointers to me" type code.

We still leave stale handles behind, but now instead of those stale handles being pointers that could refer to memory that has been given a new purpose or taken out of the valid address space, now stale handles are gracefully handled by the API which checks and indicates that the handle has gone stale allowing us to prevent a crash and possibly even take appropriate actions in the absense of a viable jump destination.

Thanks for reading through on this whirlwind of a post! Next something much lighter: the entire UI system and series of layers of wrappers for listers, see you then!
Simon Anciaux,
Mr4thDimention
A scope with multiple dependcies is the scope...

should be "A scope with multiple dependencies is a scope..."
I'm sorry I'm only commenting on typos.


text:
# Bioimage Analysis Wiki

### Sidebar

EMBL BioImage Data Analysis

EuBIAS

NEUBIAS

Popularity Ranking

 The field for bioimage analyst expanding. British museum! https://t.co/KClNvxP948 About 2 days, 5 hours ago by: Kota Miura (@cmci_) RT @dgaboriau: Panel session: should I aim to become a bioimage analyst? With Robert Hasse @haesleinhuepf , Kota Miura @cmci_ and Arianne B… About 3 days, 19 hours ago by: Kota Miura (@cmci_) RT @martinjones78: Shoutout by @cmci_ for @clathrin's book https://t.co/x6d2OmfdxR as a great resource, here at #CBIAS2022 in the panel ses… About 3 days, 19 hours ago by: Kota Miura (@cmci_) RT @alex_paynedwyer: The one and only Kota Miura @cmci_ calling out all those dodgy contrast-mismatched figures #ethics in classic humorou… About 4 days, 3 hours ago by: Kota Miura (@cmci_) RT @RekadZeinab: Kicking the last session of #CBIAS2022 with the great master @cmci_ on the challenges of doing image analysis at the inter… About 4 days, 3 hours ago by: Kota Miura (@cmci_) RT @MaKaefer: Fear not: there is something that can be done! Abide by the guidelines or report everything that has been done - whether it i… About 4 days, 3 hours ago by: Kota Miura (@cmci_)
documents:100420frapinternal

# Lecture Notes: FRAP internal course

April 20, 2010 @EMBL
Kota Miura

will be also further added by Sebastian Huet and Christian Tischer

Google Chrome or Firefox (version > 3.6) is recommended for properly viewing math equations.

## Introduction

in vivo protein kinetics could be analyzed in two ways: measuring particular movement or averaged movement. By tracking labeled single protein molecules, we could estimate their diffusion and transport behavior. Such single molecule studies of membrane proteins, for example, enabled us to analyze how they are organized with their dynamics, such as boundary for movement constrained by membrane corrals. Motor protein moving along cytoskeletal tracks were analyzed in detail to know how they convert chemical energy into physical force. This was only possible by probing their singular movement and steps. While single particle tracking requires high-temporal and spatial resolution setup for analysis, analysis of averaged movement, measured by temporal changes in fluorescence intensity, could be achieved with larger spatial and temporal resolution (typically in micrometer scale).

Here, we focus on one of such averaged movement analysis technique: Fluorescence Recovery After Photobleaching (FRAP). We first start the explanation with a simpler case of monitoring averaged movement that does not need to bleach.

## Fluorescence intensity and Protein Dynamics

Measurement of VSV-G protein exit dynamics
First-order Chemical Reaction

Increase in intensity at observed area could be measured to know the net increase in the protein at that region. To characterize this dynamics, we can apply traditional biochemical kinetics. Example case: Kinetics of VSVG protein accumulation to ER exit site.

$${dI(t)\over dt}=k_{on}[VSVG_{free}]- k_{off}[VSVG_{ERES}]$$

Here,

• $k_{on}$ is the binding rate of VSVG protein to ER exit site
• $[VSVG_{free}]$ is the concentration of unbound VSVG protein
• $k_{off}$ is the dissociation rate of VSVG protein from ER exit site
• $[VSVG_{ERES}]$ is the density of VSVG protein bound to the ER exit site

During the initial phase of binding, when there is almost no VSVG protein bound to ER exit site, we can approximate the initial speed of the density increase at ERES site depends only on binding reaction: $k_{off}[VSVG_{ERES}]\simeq0$. \\Then

$${dI(t)\over{dt}}=k_{on}[VSVG_{free}]$$

Since there are enough free VSVG, we consider that $[VSVG_{free}]$ is constant, we are able to simply calculate the slope of initial increase of intensity, measure the free VSVG intensity and then calculate $k_{on}$.

For details, see Runz et al (2006).

## FRAP Simple Measures

Half-Max t and Mobile/Immobile fraction from FRAP curve

Unlike the example shown above, dynamics of protein are not observable to eyes (through microscope) in many cases. Even though proteins are exchanging in system, the flux of protein constituting the system is not evident if the in/out flux of protein is steady and constant (e.g. liver). In such cases, we need to some how experimentally treat the system. One way is FRAP.
In FRAP, we bleach some population of fluorescence-labeled protein and evaluate the mobility of the protein. Typically we use confocal microscopy and bleach fluorescence of small area of the system by short pulse of strong laser beam and measure following changes in the fluorescence intensity at that bleached spot over time. Detail on these measurement protocol has been presented in Stefan and Yury's talks (link?). Here, we focus on how to analyze the curve we obtained through such measurements.

From measured temporal changes in the intensity at the bleached Region of Interest (this curve indeed is the Fluorescence Recovery After Photobleaching, FRAP) we can measure two parameters which represents speed of recovery, and fraction of molecules that is moving around in the system.

• Half Max
• Mobile-Immobile fraction

Fitting the curve to exponential equation eases us to calculate these parameters. Half-Max value (time) is rather qualitative value, but is a simple and straightforward index for comparing different systems.

## FRAP Measurements based on Modelling

FRAP curve reflects the mobility of proteins. In dilute solution of with single protein solute, mobility of protein could probably be considered as pure-diffusion. But in many cases, this is does not hold. The mobility is often affected by the system.

• reaction with other proteins
• geometry of the system, that constrains the mobility
• active transport process

By modeling how the mobility is (generate some hypothesis how the protein mobility is affected in the system), we can set up equation/s to hypothesize what is the bases of FRAP curve. To test the hypothesis, we fit the experimental curves with theoretical curve. By evaluating the goodness of fit, we can discuss which models would be the most likely hypothesis. If the fit is good, then we could know the value of biochemical parameters which governs the recovery curve.

Currently we have more-or-less standardized protocol to analyze FRAP curves. Starting with simple model of diffusion, we test the fit of different curves and proceed to more complex models. See next section for the protocol.

### Choosing models based on trial fittings

Maybe Sebastian's flow chart here.

### Diffusion Recovery

Diffusion Recovery equation by Soumpasis, 1984

#### pure diffusion

Theoretical curve of the diffusion mediated fluorescence recovery was proposed by Soumpasis (1984) and has been widely used.
$$f(t)=e^{- \frac{\tau_D}{2t}}\left(I_{0}(\frac{\tau_D}{2t})+I_{1}(\frac{\tau_D}{2t})\right)$$ This theoretical equation assumes:

• 2D
• circular (cylindrical) bleaching

when above equation could be fitted nicely (evaluated by goodness of fit, such as Pearson's coefficient r or gamma-Q value), one could calculate diffusion coeffecient by using the obtained $\tau_D$ and radius of the circular ROI $w$.
$$D=\frac{w^{2}}{\tau_D}$$

For strip-ROI bleaching, empirical formula used by Ellenberg et al. (1997) could be used, and is also possible to use Gaussian curve fitting that Christian Tischer developed. For Christian's method, 100426FRAPgaussfit.

#### effective diffusion

(almost diffusion)

### Reaction Dominant Recovery

Protein cluster and fluorescence recovery
Modeling Reaction Dominant recovery

If molecule under study is binding/unbinding with other molecular species, FRAP curve is affected by these interactions. There are two cases on how these two events, diffusion and reaction, are combined in the curve. We could think of two cases.

1. Reaction-dominant recovery Cases when reaction binding rate (meaning “number of molecules that binds to the binding partner per second”) is much lower than the diffusion rate. In such cases, FRAP-bleached field will first become brighter due to diffusion, and then there will be a slower recovery of intensity due to none-bleached fluorescence exchange with the bleached fluorescence. In such cases, we could consider that the recovery curve is dominated by reaction since duration of diffusion-recovery phase is much shorter compared to reaction-recovery phase. In such case, these two phases are considered to be separable (call this reaction-dominant or diffusion uncoupled; this section). We even might not “see” the diffusion recovery phase, which requires high temporal resolution capturing.
2. Reaction-Diffusion Recovery Other cases would be when durations of diffusion-recovery phase and reaction-recovery phase are with comparable duration. Then recovery curve consists of a combination of fluorescence that came in with diffusion, and also by the binding of fluorescence molecule at the FRAP bleached field (“reaction-diffusion” or “diffusion-coupled” see the section below).

For a simple chemical reaction with singular type of interaction, we could again think of the reaction model that was already explained above, the first-order chemical reaction modeled as a compartment system (see figure right)
$$\frac {df(t)} {dt} = k_{on}[free] - k_{off}[bound]$$ where

• $k_{on}$ Binding constant
• $k_{off}$ Dissociation constant
• $[free]$ Density of free molecules
• $[bound]$ Density of bound-molecules

We solve the differential equation $$f(t)=A(1-e^{- \tau t})$$ where

• $\tau = k_{on} + k_{off}$
• $A = \frac {k_{on}}{k_{on} + k_{off}}$

#### Reaction Dominant Recovery with Immobile Binding Partner

Illustrated view of Fluorescence recovery at immobile binding partner
Modeling fluorescence recovery at immobile binding partner 01
Modeling fluorescence recovery at immobile binding partner 02

Next we modify above model to consider a situation a bit more frequently we see in cell biology. The protein we are analyzing is either freely diffusing in cytoplasm or bound to an immobile structure inside cell. We FRAP this structure, to know the kinetic constants of the protein interaction with the structure (e.g. microtubule binding protein, structure = microtubule) $$\frac {df(t)} {dt} = k_{on}[free][s] - k_{off}[bound]$$ where

• $k_{on}$ Binding constant
• $k_{off}$ Dissociation constant
• $[free]$ Density of free molecules
• $[s]$ Density of immobile binding partner
• $[bound]$ Density of bound-molecules

Since [s] is immobile and constant during experiment, we define $k*_{on}$ as $$k*_{on}=k_{on}[s]$$ in addition, density of free molecule in cytoplasm is almost constant so we assume $[free] = F$ and does not change. We then solve $$\frac {df(t)} {dt} = k*_{on}F - k_{off}[bound]$$ We get $$f(t)=1-Ce^{- \tau t}$$ where

• $\tau = k_{off}$

… note that the shape of recovery curve now only depends on $k_{off}$

### Diffusion and Reaction combined Recovery

Diffusion-Reaction Combined Model

$$\frac{\partial [free]}{\partial t} = D_{free} \nabla ^2[free]-k_{on}[free][s]+k_{off}[bound]$$ $$\frac{\partial [s]}{\partial t} = D_s \nabla ^2[s]-k_{on}[free][s]+k_{off}[bound]$$ $$\frac{\partial [bound]}{\partial t} = D_{bound} \nabla ^2[bound]+k_{on}[free][s]-k_{off}[bound]$$

Since

• [s] is constant and immobile
• $k*_{on} = k_{on}[s]$
• $\frac{\partial [s]}{\partial t}=0$
• bound molecules do not diffuse so $D_{bound}=0$

Then we solve only $$\frac{\partial [free]}{\partial t} = D_{free} \nabla ^2[free]-k*_{on}[free]+k_{off}[bound]$$ $$\frac{\partial [bound]}{\partial t} = k_{on}[free][s]-k_{off}[bound]$$

We could solve this either analytically (Sprague et al, 2004) or numerically (Beaudouin et al, 2006). In the latter paper, calculation involves spatial context (on-rate was spatially varied; see also “geometry” section below).

#### Sprague Method

Analytical solution was made in Laplace transformed equation. $$\overline{frap(p)} = \frac 1 p - \frac{F_{eq}}{p}\left(1-2K_1(qw)I_1(qw)\right)\times\left(1+\frac{k*_{on}}{p+k_{off}}\right)-\frac C {p+k_{off}}$$

### Diffusion and Transport combined Recovery

We did not talk about this issue in the course, but there is another factor that could interfere with recovery curve in vivo: active transport. There is some trial on including this factor by Hallen and Endow (2009).

### Diffusion and Reaction, along with Spatial Context, Geometry

Example case considering geometrical and structural parameters that are affecting the recovery, by Sbalzarini et al

Since molecular behavior inside cell is constrained largely by structure and geometry of intracellular architecture, FRAP measured at single point within a cell does not always represent the biochemical characteristic of that molecule. In fact, functionality of protein molecule is determined not only by switching on/off, but is also regulated by the position of that molecule within cell. This means that spatial context should be included when interpreting the FRAP measurement.

Physical parameters such as Diffusion coefficient measured by FRAP is affected largely by geometrical constraint. Even if the geometry is rather simple, there are many obstacles in intracellular space which will cause longer time for molecules to reach from one point to the other. In such cases (which probably is frequently the case), estimated diffusion coefficient would calculated to be smaller than that of the “true diffusion coefficient”. Presence of such obstacles should be somehow taken into account. For this reason, estimation of Diffusion coefficient could be more precise if one analyzes the structural geometry of where the molecule is constrained. Such protocol would be especially important if Diffusion and Reaction coupled recovery curve since wrong estimates on Diffusion coefficient would end up in wrong reaction parameters as well.

Joel Beaudouin who did PhD study in the Ellenberg lab in the EMBL actually encountered such question in his project on nuclear protein study and solved the problem by using initial image frames of the FRAP experiment and let the molecule to diffuse by simulation, then fit the simulation with the experimental FRAP image sequence. Diffusion-reaction model was used and simulation was done (see above) using ODE solver to scan through the parameter space. Excellent idea. For more details, see Beaudouin et al. (2006). We will later add some protocol to this lecture notes on how to fit FRAP image sequence data using ODE solver (with help of Sebastian Huet). Joel's method was actually made into application called “Tropical” by a team in University of Heidleberg, but it seems that there is no direct link for downloading.

Other papers we could refer to are Sbalzarini et. al. (2005, 2006). In these papers, authors did two things in parallel: 3D reconstruction of ER membrane structure and FRAP of certain molecule moving around along ER membrane. Using the 3D structure they reconstructed, geometrical constraint on protein diffusion could be determined and include this constraint on the estimation of Diffusion coefficient.

## Pitfalls in FRAP Analysis

Refer to Mueller et. al.(2008). In their paper, they pointed out

• Shape of the FRAP ROI largely affect estimated value of biochemical rate constants(diffusion is important)
• Problems of fitting double exponential curve
• Initial condition (laser intensity profile) is important
• “blinding” of photomultiplier after the FRAP bleaching

## List of Tools for FRAP Analysis

### Basic

• ImageJ Plugins: Two available ImageJ plugins for FRAP does intensity measurement and normalization. Fitting module is not implemented.
• There is a good step-by-step protocol for measurements and analysis using MBF ImageJ bundle. You need to download the bundle from the linked site, and also ask for some plugins directly by email.
• Import data output from Zeiss, Leica, Olympus measurements and do FRAP fitting.
• FRAP analyzer (University of Luxemburg)
• Similar to above, but stand alone and also incorporated diffusion-reaction model.
• Does measurement and fitting. Sprague et al. (2004) Reaction-Diffusion Full model is implemented.

### Analytical Approach

Sprague et. al. (explained above) is an example case of analytically solving the model for the fitting.

### ODE Simulation

Image based simulation with ODE solver

Tropical

• Numerical analysis based on ODE. Spatial context.

General Solvers

• Joel and Sebastian uses this software for fitting ODE.

### Particle Simulation

One of Particle Simulator, Smodldyn
Custom tool for Particle Simualation

Particle Simulation Packages

• Smoldyn
• GridCell
• MCell

Reviews, Protocols and textbooks

• McNally, J.G. (2008) Quantitative FRAP in analysis of molecular binding dynamics in vivo. Methods in Cell Biology 2008;85:329-51
• step-by-step protocol for analyzing FRAP. Flow chart for determining recovery model is useful.
• Sprague, B. L. and McNally, J. G.(2005). FRAP analysis of binding: proper and fitting. Trends Cell Biol 15, 84-91.
• Phair, R. D., Gorski, S. A. and Misteli, T. (2004). Measurement of dynamic protein binding to chromatin in vivo, using photobleaching microscopy. Methods Enzymol 375, 393-414.
• Already a bit of out-dated but “Double normalization” introduced in this protocol is widely used.
• Jacquez, J. A. (1972). Compartmental analysis in biology and medicine: Elsevier
• If you want to study basics about calculation of kinetics.

Research Papers