GABA Measurement Degraded by Head Movement

 
Nuclear Magnetic Resonance Spectroscopy Measurement of Gamma-Amino-Butyric Acid Is Degraded by Head Movement

Motivation

Nuclear Magnetic Resonance Spectroscopy (NMRS) is an important tool for measuring neurochemical levels in human subjects in clinical research. However, its measurement is heavily impacted by subject’s head movement. Here, we want to explore how specifically head movement can impact NMRS measurements.

A brief introduction to data analyzed

Movement data

The size of the raw data is 2.6GB. The head movement data is acquired by video recording of visual markers (Figure A) affixed onto the head of human subjects, with video sampling at 5 Hz (example image shown in Figure B). The position of the markers are extracted by image processing protocol written in MATLAB (https://github.com/sapphire008/MATLAB/tree/master/image_reg3), using techniques including template matching (Modified Hausdorff Displacement) and kmeans clustering. Displacement and Speed (Figure D, showing both vertical and horizontal movements) are obtained from the relative position and the first derivative of position of the centroid of the square images, respectively. This time series is then low-pass filtered with a Butterworth filter at 0.25 hZ cutoff. In the following analyses, however, Displacement and Speed refers to a feature engineered parameter, which is the Euclidean Displacement of the two dimensions over each time point and then taken the root-mean-square of the time series to obtain a single number.

Neurochemical measurements

This is a set of target parameters, including various NMRS measurement of neurochemicals in the brain. The size of the raw data is 10GB.

library(ggplot2)
library(bbmle)
library(plyr)

# Loading existing data
load("D:/Edward/Documents/Assignments/Imaging Research Center/GABA Movement Second Submission/Analysis/data/data_results_11202014.RData")

Building a maximum likelihood model for each neurochemical signals against movement parameters

Qeustion: Do the Displacement and/or speed of head movement negatively impact neurochemical signal measurement?

# Use maximum likelihood to do simple linear regression
# Custom fitting function
LL <- function(params){
  beta = matrix(NA, nrow = length(params) - 2, ncol = 1)
  beta[,1] = params[1:(length(params)-2)]
  mu       = params[[length(params)-1]]
  sigma    = params[[length(params)]]
  minusll  = -sum(suppressWarnings(dnorm(Y - X %*% beta, 0, sigma, log=T))) # Minus of log likelihood
  return(minusll)
}
residuals.mle<- function(params) return(Y -X %*%as.matrix(params[1:(length(params)-2)]))
predict.mle <- function(params) return(X %*%as.matrix(params[1:(length(params)-2)]))
# GABA: against both Displacement and speed of movement
X <- model.matrix(lm(GABA.Cr ~ D + S, data = data.clean.GABA.DS))
Y <- data.clean.GABA.DS$GABA.Cr
parnames(LL) <- c('Intercept', 'D', 'S', 'mu', 'sigma')
mle.GABA.DS <- mle2(LL, start = c(Intercept = 0.1, D = 0.2, S = 0.1, mu = 0, sigma = 1),
     vecpar = TRUE, parnames = c('Intercept', 'D', 'S', 'mu', 'sigma'))
summary(mle.GABA.DS)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, D = 0.2, S = 0.1,
    mu = 0, sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "D", "S", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.6877e-01  6.6436e-03 25.4031 < 2.2e-16 ***
D         -9.5368e-03  4.7700e-03 -1.9993  0.045574 *
S         -1.8287e-01  6.1756e-02 -2.9612  0.003064 **
mu         0.0000e+00  3.0317e-15  0.0000  1.000000
sigma      1.1007e-02  1.4784e-03  7.4454 9.667e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -173.2451 
# GABA: against Displacement of movement only
X <- model.matrix(lm(GABA.Cr ~ D, data = data.clean.GABA.D))
Y <- data.clean.GABA.D$GABA.Cr
parnames(LL) <- c('Intercept', 'D', 'mu', 'sigma')
mle.GABA.D <- mle2(LL, start = c(Intercept = 0.1, D = 0.2, mu = 0, sigma = 1),
                   vecpar = TRUE, parnames=c('Intercept', 'D', 'mu', 'sigma'))
summary(mle.GABA.D)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, D = 0.2, mu = 0,
    sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "D", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.5577e-01  5.5588e-03 28.0222 < 2.2e-16 ***
D         -1.0391e-02  5.1171e-03 -2.0305    0.0423 *
mu         0.0000e+00  9.6376e-16  0.0000    1.0000
sigma      1.2387e-02  1.6345e-03  7.5788 3.487e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -172.5711 
# GABA: against speed of movement only
X <- model.matrix(lm(GABA.Cr ~ S, data = data.clean.GABA.S))
Y <- data.clean.GABA.S$GABA.Cr
parnames(LL) <- c('Intercept', 'S', 'mu', 'sigma')
mle.GABA.S <- mle2(LL, start = c(Intercept = 0.1, S = 0.2, mu = 0, sigma = 1),
                   vecpar = TRUE, parnames=c('Intercept', 'S', 'mu', 'sigma'))
summary(mle.GABA.S)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, S = 0.2, mu = 0,
    sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "S", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.6043e-01  5.1357e-03 31.2385 < 2.2e-16 ***
S         -1.8650e-01  6.0571e-02 -3.0791  0.002076 **
mu         0.0000e+00  2.8010e-14  0.0000  1.000000
sigma      1.1508e-02  1.5228e-03  7.5576 4.105e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -176.9467 
# NAA
X <- model.matrix(lm(NAA.Cr ~ D + S, data = data.clean.NAA.DS))
Y <- data.clean.NAA.DS$NAA.Cr
parnames(LL) <- c('Intercept', 'D', 'S', 'mu', 'sigma')
mle.NAA.DS <- mle2(LL, start = c( Intercept = 0.1, D = 0.2, S = 0.1,  mu = 0, sigma = 1),
                   vecpar = TRUE, parnames=c('Intercept', 'D', 'S', 'mu', 'sigma'))
summary(mle.NAA.DS)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, D = 0.2, S = 0.1,
    mu = 0, sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "D", "S", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value   Pr(z)
Intercept  1.8018e+00  5.9850e-02 30.1058 < 2e-16 ***
D         -5.0059e-02  4.2585e-02 -1.1755  0.2398
S          5.9440e-03  5.7699e-01  0.0103  0.9918
mu         0.0000e+00  1.3518e-11  0.0000  1.0000
sigma      9.8290e-02  1.3136e-02  7.4824 7.3e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -50.45492 
X <- model.matrix(lm(NAA.Cr ~ D, data = data.clean.NAA.D))
Y <- data.clean.NAA.D$NAA.Cr
parnames(LL) <- c('Intercept', 'D', 'mu', 'sigma')
mle.NAA.D <- mle2(LL, start = c(Intercept = 0.1, D = 0.2, mu = 0, sigma = 1),
                   vecpar = TRUE, parnames=c('Intercept', 'D', 'mu', 'sigma'))
summary(mle.NAA.D)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, D = 0.2, mu = 0,
    sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "D", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.7875e+00  4.5878e-02 38.9626 < 2.2e-16 ***
D         -2.8772e-02  4.2114e-02 -0.6832    0.4945
mu         0.0000e+00  6.1171e-14  0.0000    1.0000
sigma      1.0190e-01  1.3382e-02  7.6149 2.639e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -50.16316 
X <- model.matrix(lm(NAA.Cr ~ S, data = data.clean.NAA.S))
Y <- data.clean.NAA.S$NAA.Cr
parnames(LL) <- c('Intercept', 'S', 'mu', 'sigma')
mle.NAA.S <- mle2(LL, start = c(Intercept = 0.1, S = 0.2, mu = 0, sigma = 1),
                  vecpar = TRUE, parnames=c('Intercept', 'S', 'mu', 'sigma'))
summary(mle.NAA.S)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, S = 0.2, mu = 0,
    sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "S", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.7679e+00  4.5673e-02 38.7084 < 2.2e-16 ***
S         -1.2854e-01  5.4529e-01 -0.2357    0.8136
mu         0.0000e+00  7.7801e-13  0.0000    1.0000
sigma      9.9816e-02  1.3108e-02  7.6151 2.636e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -51.36223 
# Glx
X <- model.matrix(lm(Glx.Cr ~ D + S, data = data.clean.Glx.DS))
Y <- data.clean.Glx.DS$Glx.Cr
parnames(LL) <- c('Intercept', 'D', 'S', 'mu', 'sigma')
mle.Glx.DS <- mle2(LL, start = c( Intercept = 0.1, D = 0.2, S = 0.1,  mu = 0, sigma = 1),
                   vecpar = TRUE, parnames=c('Intercept', 'D', 'S', 'mu', 'sigma'))
summary(mle.Glx.DS)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, D = 0.2, S = 0.1,
    mu = 0, sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "D", "S", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.3020e-01  7.3627e-03 17.6838 < 2.2e-16 ***
D         -4.0622e-03  5.2388e-03 -0.7754    0.4381
S          3.6026e-02  7.0981e-02  0.5075    0.6118
mu         0.0000e+00  1.1135e-13  0.0000    1.0000
sigma      1.2092e-02  1.6256e-03  7.4382 1.021e-13 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -168.0179 
X <- model.matrix(lm(Glx.Cr ~ D, data = data.clean.Glx.D))
Y <- data.clean.Glx.D$Glx.Cr
parnames(LL) <- c('Intercept', 'D', 'mu', 'sigma')
mle.Glx.D <- mle2(LL, start = c(Intercept = 0.1, D = 0.2, mu = 0, sigma = 1),
                  vecpar = TRUE, parnames=c('Intercept', 'D', 'mu', 'sigma'))
summary(mle.Glx.D)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, D = 0.2, mu = 0,
    sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "D", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.3287e-01  5.5395e-03 23.9864 < 2.2e-16 ***
D         -4.2456e-03  5.0850e-03 -0.8349    0.4038
mu         0.0000e+00  2.6552e-16  0.0000    1.0000
sigma      1.2304e-02  1.6204e-03  7.5930 3.127e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -172.8912 
X <- model.matrix(lm(Glx.Cr ~ S, data = data.clean.Glx.S))
Y <- data.clean.Glx.S$Glx.Cr
parnames(LL) <- c('Intercept', 'S', 'mu', 'sigma')
mle.Glx.S <- mle2(LL, start = c(Intercept = 0.1, S = 0.2, mu = 0, sigma = 1),
                  vecpar = TRUE, parnames=c('Intercept', 'S', 'mu', 'sigma'))
summary(mle.Glx.S)
Maximum likelihood estimation

Call:
mle2(minuslogl = LL, start = c(Intercept = 0.1, S = 0.2, mu = 0,
    sigma = 1), vecpar = TRUE, parnames = c("Intercept",
    "S", "mu", "sigma"))

Coefficients:
             Estimate  Std. Error z value     Pr(z)
Intercept  1.3132e-01  6.4165e-03 20.4657 < 2.2e-16 ***
S         -4.7113e-02  7.6607e-02 -0.6150    0.5386
mu         0.0000e+00  1.0891e-14  0.0000    1.0000
sigma      1.4023e-02  1.8475e-03  7.5902 3.195e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

-2 log L: -165.3215 

Conclusion: GABA seems to be very sensitive to movement, whereas the other two more abundant chemical does not seem to be affected.

Plot measurements of neurochemical signals in primary visual cortex against movement parameter and fit a line

# GABA
lm.GABA.D <- lm(GABA.Cr ~ D, data.clean.GABA.D)
lm.GABA.D$coefficients <- coef(mle.GABA.D)[1:2]
names(lm.GABA.D$coefficients) <- c("(Intercept)","D")
grid <- with(data.clean.GABA.D, expand.grid(D = seq(min(D), max(D), length=20)))
grid$GABA.Cr <- stats::predict(lm.GABA.D, newdata=grid)
err <- stats::predict(lm.GABA.D, newdata=grid, se = TRUE)
grid$ucl <- err$fit + 1.96 * err$se.fit
grid$lcl <- err$fit - 1.96 * err$se.fit
p = ggplot(data.clean.GABA.D, aes(x=D, y=GABA.Cr)) +
  geom_point(shape=1,size=6) + #geom_smooth(method=lm)+
  geom_smooth(aes(ymin = lcl, ymax = ucl), data = grid, stat="identity")+
  xlab(expression("RMS of Displacement " * Delta ~ " (mm)"))+
  ylab("V1 GABA/Cr")
# L = paste("R^2 ~ \"=\" ~", round(summary(lm(GABA.Cr ~ D, data.clean.GABA.D))$adj.r.squared,digits=4))
L = paste("-2 ~ logL ~ \"=\" ~", round(as.numeric(logLik(mle.GABA.D))*-2,digits=2))
p + geom_text(aes(x=1.5,y = 0.17, label = L),size=6,parse=T)+
  theme(axis.text.x = element_text(size=18),axis.title.x = element_text(size=20),
        axis.text.y = element_text(size=18),axis.title.y = element_text(size=20))

lm.GABA.S <- lm(GABA.Cr ~ S, data.clean.GABA.S)
lm.GABA.S$coefficients <- coef(mle.GABA.S)[1:2]
names(lm.GABA.S$coefficients) <- c("(Intercept)","S")
grid <- with(data.clean.GABA.S, expand.grid(S = seq(min(S), max(S), length=20)))
grid$GABA.Cr <- stats::predict(lm.GABA.S, newdata=grid)
err <- stats::predict(lm.GABA.S, newdata=grid, se = TRUE)
grid$ucl <- err$fit + 1.96 * err$se.fit
grid$lcl <- err$fit - 1.96 * err$se.fit
p = ggplot(data.clean.GABA.S, aes(x=S, y=GABA.Cr)) +
  geom_point(shape=1,size=6) +#geom_smooth(method=lm)+
  geom_smooth(aes(ymin = lcl, ymax = ucl), data = grid, stat="identity")+
  xlab(expression("RMS of Speed " * Sigma ~ " (mm/s)"))+
  ylab("V1 GABA/Cr")
L = paste("-2 ~ logL ~ \"=\" ~", round(as.numeric(logLik(mle.GABA.S))*-2,digits=2))
p + geom_text(aes(x=0.14,y = 0.17, label = L),size=6,parse=T)+
  theme(axis.text.x = element_text(size=18),axis.title.x = element_text(size=20),
        axis.text.y = element_text(size=18),axis.title.y = element_text(size=20))

# NAA
lm.NAA.D <- lm(NAA.Cr ~ D, data.clean.NAA.D)
lm.NAA.D$coefficients <- coef(mle.NAA.D)[1:2]
names(lm.NAA.D$coefficients) <- c("(Intercept)","D")
grid <- with(data.clean.NAA.D, expand.grid(D = seq(min(D), max(D), length=20)))
grid$NAA.Cr <- stats::predict(lm.NAA.D, newdata=grid)
err <- stats::predict(lm.NAA.D, newdata=grid, se = TRUE)
grid$ucl <- err$fit + 1.96 * err$se.fit
grid$lcl <- err$fit - 1.96 * err$se.fit
p = ggplot(data.clean.NAA.D, aes(x=D, y=NAA.Cr)) +
  geom_point(shape=1,size=6) + #geom_smooth(method=lm)+
  geom_smooth(aes(ymin = lcl, ymax = ucl), data = grid, stat="identity")+
  xlab(expression("RMS of Displacement " * Delta ~ " (mm)"))+
  ylab("V1 NAA/Cr")
# L = paste("R^2 ~ \"=\" ~", round(summary(lm(NAA.Cr ~ D, data.clean.NAA.D))$adj.r.squared,digits=4))
L = paste("-2 ~ logL ~ \"=\" ~", round(as.numeric(logLik(mle.NAA.D))*-2,digits=2))
p + geom_text(aes(x=1.5,y = 2.0, label = L),size=6,parse=T)+
  theme(axis.text.x = element_text(size=18),axis.title.x = element_text(size=20),
        axis.text.y = element_text(size=18),axis.title.y = element_text(size=20))

lm.NAA.S <- lm(NAA.Cr ~ S, data.clean.NAA.S)
lm.NAA.S$coefficients <- coef(mle.NAA.S)[1:2]
names(lm.NAA.S$coefficients) <- c("(Intercept)","S")
grid <- with(data.clean.NAA.S, expand.grid(S = seq(min(S), max(S), length=20)))
grid$NAA.Cr <- stats::predict(lm.NAA.S, newdata=grid)
err <- stats::predict(lm.NAA.S, newdata=grid, se = TRUE)
grid$ucl <- err$fit + 1.96 * err$se.fit
grid$lcl <- err$fit - 1.96 * err$se.fit
p = ggplot(data.clean.NAA.S, aes(x=S, y=NAA.Cr)) +
  geom_point(shape=1,size=6) +#geom_smooth(method=lm)+
  geom_smooth(aes(ymin = lcl, ymax = ucl), data = grid, stat="identity")+
  xlab(expression("RMS of Speed " * Sigma ~ " (mm/s)"))+
  ylab("V1 NAA/Cr")
L = paste("-2 ~ logL ~ \"=\" ~", round(as.numeric(logLik(mle.NAA.S))*-2,digits=2))
p + geom_text(aes(x=0.13,y = 2.0, label = L),size=6,parse=T)+
  theme(axis.text.x = element_text(size=18),axis.title.x = element_text(size=20),
        axis.text.y = element_text(size=18),axis.title.y = element_text(size=20))

# Glx
lm.Glx.D <- lm(Glx.Cr ~ D, data.clean.Glx.D)
lm.Glx.D$coefficients <- coef(mle.Glx.D)[1:2]
names(lm.Glx.D$coefficients) <- c("(Intercept)","D")
grid <- with(data.clean.Glx.D, expand.grid(D = seq(min(D), max(D), length=20)))
grid$Glx.Cr <- stats::predict(lm.Glx.D, newdata=grid)
err <- stats::predict(lm.Glx.D, newdata=grid, se = TRUE)
grid$ucl <- err$fit + 1.96 * err$se.fit
grid$lcl <- err$fit - 1.96 * err$se.fit
p = ggplot(data.clean.Glx.D, aes(x=D, y=Glx.Cr)) +
  geom_point(shape=1,size=6) + #geom_smooth(method=lm)+
  geom_smooth(aes(ymin = lcl, ymax = ucl), data = grid, stat="identity")+
  xlab(expression("RMS of Displacement " * Delta ~ " (mm)"))+
  ylab("V1 Glx/Cr")
# L = paste("R^2 ~ \"=\" ~", round(summary(lm(Glx.Cr ~ D, data.clean.Glx.D))$adj.r.squared,digits=4))
L = paste("-2 ~ logL ~ \"=\" ~", round(as.numeric(logLik(mle.Glx.D))*-2,digits=2))
p + geom_text(aes(x=1.5,y = 0.16, label = L),size=6,parse=T)+
  theme(axis.text.x = element_text(size=18),axis.title.x = element_text(size=20),
        axis.text.y = element_text(size=18),axis.title.y = element_text(size=20))

lm.Glx.S <- lm(Glx.Cr ~ S, data.clean.Glx.S)
lm.Glx.S$coefficients <- coef(mle.Glx.S)[1:2]
names(lm.Glx.S$coefficients) <- c("(Intercept)","S")
grid <- with(data.clean.Glx.S, expand.grid(S = seq(min(S), max(S), length=20)))
grid$Glx.Cr <- stats::predict(lm.Glx.S, newdata=grid)
err <- stats::predict(lm.Glx.S, newdata=grid, se = TRUE)
grid$ucl <- err$fit + 1.96 * err$se.fit
grid$lcl <- err$fit - 1.96 * err$se.fit
p = ggplot(data.clean.Glx.S, aes(x=S, y=Glx.Cr)) +
  geom_point(shape=1,size=6) +#geom_smooth(method=lm)+
  geom_smooth(aes(ymin = lcl, ymax = ucl), data = grid, stat="identity")+
  xlab(expression("RMS of Speed " * Sigma ~ " (mm/s)"))+
  ylab("V1 Glx/Cr")
L = paste("-2 ~ logL ~ \"=\" ~", round(as.numeric(logLik(mle.Glx.S))*-2,digits=2))
p + geom_text(aes(x=0.13,y = 0.16, label = L),size=6,parse=T)+
  theme(axis.text.x = element_text(size=18),axis.title.x = element_text(size=20),
        axis.text.y = element_text(size=18),axis.title.y = element_text(size=20))

Is it true that the longer the subject stay in the scanner, the worse the signal?

library(nlme)
load("D:/Edward/Documents/Assignments/Imaging Research Center/GABA Movement Fourth Submission/analysis/data/data_results_10302016.RData")
lme.GABA.Cr = lme(GABA.Cr ~ Region.Run.Order, data=data.homogeneous, random=~1|Subject)
summary(lme.GABA.Cr)
Linear mixed-effects model fit by REML
 Data: data.homogeneous 

Random effects:
 Formula: ~1 | Subject
        (Intercept)    Residual
StdDev: 0.009674584 0.005029841

Fixed effects: GABA.Cr ~ Region.Run.Order 
 Correlation:
                  (Intr) R.R.O2
Region.Run.Order2 -0.326
Region.Run.Order3 -0.326  0.500

Standardized Within-Group Residuals:
       Min         Q1        Med         Q3        Max
-1.6856021 -0.7082410  0.1739974  0.5781646  1.6793817

Number of Observations: 45
Number of Groups: 15 
lme.Glx.Cr = lme(Glx.Cr ~ Region.Run.Order, data=data.homogeneous, random=~1|Subject)
summary(lme.Glx.Cr)
Linear mixed-effects model fit by REML
 Data: data.homogeneous 

Random effects:
 Formula: ~1 | Subject
        (Intercept)    Residual
StdDev: 0.006411252 0.006937828

Fixed effects: Glx.Cr ~ Region.Run.Order 
 Correlation:
                  (Intr) R.R.O2
Region.Run.Order2 -0.519
Region.Run.Order3 -0.519  0.500

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max
-1.80202593 -0.43097103  0.04998176  0.60270971  2.22699679

Number of Observations: 45
Number of Groups: 15 
lme.NAA.Cr = lme(NAA.Cr ~ Region.Run.Order, data=data.homogeneous, random=~1|Subject)
summary(lme.NAA.Cr)
Linear mixed-effects model fit by REML
 Data: data.homogeneous 

Random effects:
 Formula: ~1 | Subject
        (Intercept)   Residual
StdDev:   0.1156031 0.02517245

Fixed effects: NAA.Cr ~ Region.Run.Order 
 Correlation:
                  (Intr) R.R.O2
Region.Run.Order2 -0.15
Region.Run.Order3 -0.15   0.50

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max
-1.73280721 -0.45729043  0.08660261  0.59497552  1.88347078

Number of Observations: 45
Number of Groups: 15 

Conclusion: Yes. The longer the subjected stayed in the scanner (i.e. the longer time it takes to complete the measurement), the worse the GABA and Glx signal, but not NAA signal.

LS0tDQp0aXRsZTogIk51Y2xlYXIgTWFnbmV0aWMgUmVzb25hbmNlIFNwZWN0cm9zY29weSBNZWFzdXJlbWVudCBvZiBHYW1tYS1BbWluby1CdXR5cmljIEFjaWQgSXMgRGVncmFkZWQgYnkgSGVhZCBNb3ZlbWVudCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQojIyBNb3RpdmF0aW9uDQpOdWNsZWFyIE1hZ25ldGljIFJlc29uYW5jZSBTcGVjdHJvc2NvcHkgKE5NUlMpIGlzIGFuIGltcG9ydGFudCB0b29sIGZvciBtZWFzdXJpbmcgbmV1cm9jaGVtaWNhbCBsZXZlbHMgaW4gaHVtYW4gc3ViamVjdHMgaW4gY2xpbmljYWwgcmVzZWFyY2guIEhvd2V2ZXIsIGl0cyBtZWFzdXJlbWVudCBpcyBoZWF2aWx5IGltcGFjdGVkIGJ5IHN1YmplY3QncyBoZWFkIG1vdmVtZW50LiBIZXJlLCB3ZSB3YW50IHRvIGV4cGxvcmUgaG93IHNwZWNpZmljYWxseSBoZWFkIG1vdmVtZW50IGNhbiBpbXBhY3QgTk1SUyBtZWFzdXJlbWVudHMuDQoNCg0KIyMgQSBicmllZiBpbnRyb2R1Y3Rpb24gdG8gZGF0YSBhbmFseXplZA0KDQojIyMgTW92ZW1lbnQgZGF0YQ0KVGhlIHNpemUgb2YgdGhlIHJhdyBkYXRhIGlzIDIuNkdCLiBUaGUgaGVhZCBtb3ZlbWVudCBkYXRhIGlzIGFjcXVpcmVkIGJ5IHZpZGVvIHJlY29yZGluZyBvZiB2aXN1YWwgbWFya2VycyAoRmlndXJlIEEpIGFmZml4ZWQgb250byB0aGUgaGVhZCBvZiBodW1hbiBzdWJqZWN0cywgd2l0aCB2aWRlbyBzYW1wbGluZyBhdCA1IEh6IChleGFtcGxlIGltYWdlIHNob3duIGluIEZpZ3VyZSBCKS4gVGhlIHBvc2l0aW9uIG9mIHRoZSBtYXJrZXJzIGFyZSBleHRyYWN0ZWQgYnkgaW1hZ2UgcHJvY2Vzc2luZyBwcm90b2NvbCB3cml0dGVuIGluIE1BVExBQiAoaHR0cHM6Ly9naXRodWIuY29tL3NhcHBoaXJlMDA4L01BVExBQi90cmVlL21hc3Rlci9pbWFnZV9yZWczKSwgdXNpbmcgdGVjaG5pcXVlcyBpbmNsdWRpbmcgdGVtcGxhdGUgbWF0Y2hpbmcgKE1vZGlmaWVkIEhhdXNkb3JmZiBEaXNwbGFjZW1lbnQpIGFuZCBrbWVhbnMgY2x1c3RlcmluZy4gRGlzcGxhY2VtZW50IGFuZCBTcGVlZCAoRmlndXJlIEQsIHNob3dpbmcgYm90aCB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBtb3ZlbWVudHMpIGFyZSBvYnRhaW5lZCBmcm9tIHRoZSByZWxhdGl2ZSBwb3NpdGlvbiBhbmQgdGhlIGZpcnN0IGRlcml2YXRpdmUgb2YgcG9zaXRpb24gb2YgdGhlIGNlbnRyb2lkIG9mIHRoZSBzcXVhcmUgaW1hZ2VzLCByZXNwZWN0aXZlbHkuIFRoaXMgdGltZSBzZXJpZXMgaXMgdGhlbiBsb3ctcGFzcyBmaWx0ZXJlZCB3aXRoIGEgQnV0dGVyd29ydGggZmlsdGVyIGF0IDAuMjUgaFogY3V0b2ZmLiBJbiB0aGUgZm9sbG93aW5nIGFuYWx5c2VzLCBob3dldmVyLCBEaXNwbGFjZW1lbnQgYW5kIFNwZWVkIHJlZmVycyB0byBhIGZlYXR1cmUgZW5naW5lZXJlZCBwYXJhbWV0ZXIsIHdoaWNoIGlzIHRoZSBFdWNsaWRlYW4gRGlzcGxhY2VtZW50IG9mIHRoZSB0d28gZGltZW5zaW9ucyBvdmVyIGVhY2ggdGltZSBwb2ludCBhbmQgdGhlbiB0YWtlbiB0aGUgcm9vdC1tZWFuLXNxdWFyZSBvZiB0aGUgdGltZSBzZXJpZXMgdG8gb2J0YWluIGEgc2luZ2xlIG51bWJlci4NCiFbXShEOi9FZHdhcmQvRG9jdW1lbnRzL0Fzc2lnbm1lbnRzL0ltYWdpbmcgUmVzZWFyY2ggQ2VudGVyL0dBQkEgTW92ZW1lbnQgRmlmdGggU3VibWlzc2lvbi9maWd1cmVzL01ldGhvZC1icmllZi5QTkcpDQoNCiMjIyBOZXVyb2NoZW1pY2FsIG1lYXN1cmVtZW50cw0KVGhpcyBpcyBhIHNldCBvZiB0YXJnZXQgcGFyYW1ldGVycywgaW5jbHVkaW5nIHZhcmlvdXMgTk1SUyBtZWFzdXJlbWVudCBvZiBuZXVyb2NoZW1pY2FscyBpbiB0aGUgYnJhaW4uIFRoZSBzaXplIG9mIHRoZSByYXcgZGF0YSBpcyAxMEdCLg0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShiYm1sZSkNCmxpYnJhcnkocGx5cikNCg0KIyBMb2FkaW5nIGV4aXN0aW5nIGRhdGENCmxvYWQoIkQ6L0Vkd2FyZC9Eb2N1bWVudHMvQXNzaWdubWVudHMvSW1hZ2luZyBSZXNlYXJjaCBDZW50ZXIvR0FCQSBNb3ZlbWVudCBTZWNvbmQgU3VibWlzc2lvbi9BbmFseXNpcy9kYXRhL2RhdGFfcmVzdWx0c18xMTIwMjAxNC5SRGF0YSIpDQpgYGANCg0KDQojIyBCdWlsZGluZyBhIG1heGltdW0gbGlrZWxpaG9vZCBtb2RlbCBmb3IgZWFjaCBuZXVyb2NoZW1pY2FsIHNpZ25hbHMgYWdhaW5zdCBtb3ZlbWVudCBwYXJhbWV0ZXJzDQpRZXVzdGlvbjogRG8gdGhlIERpc3BsYWNlbWVudCBhbmQvb3Igc3BlZWQgb2YgaGVhZCBtb3ZlbWVudCBuZWdhdGl2ZWx5IGltcGFjdCBuZXVyb2NoZW1pY2FsIHNpZ25hbCBtZWFzdXJlbWVudD8NCg0KYGBge3J9DQojIFVzZSBtYXhpbXVtIGxpa2VsaWhvb2QgdG8gZG8gc2ltcGxlIGxpbmVhciByZWdyZXNzaW9uDQojIEN1c3RvbSBmaXR0aW5nIGZ1bmN0aW9uDQpMTCA8LSBmdW5jdGlvbihwYXJhbXMpew0KICBiZXRhID0gbWF0cml4KE5BLCBucm93ID0gbGVuZ3RoKHBhcmFtcykgLSAyLCBuY29sID0gMSkNCiAgYmV0YVssMV0gPSBwYXJhbXNbMToobGVuZ3RoKHBhcmFtcyktMildDQogIG11ICAgICAgID0gcGFyYW1zW1tsZW5ndGgocGFyYW1zKS0xXV0NCiAgc2lnbWEgICAgPSBwYXJhbXNbW2xlbmd0aChwYXJhbXMpXV0NCiAgbWludXNsbCAgPSAtc3VtKHN1cHByZXNzV2FybmluZ3MoZG5vcm0oWSAtIFggJSolIGJldGEsIDAsIHNpZ21hLCBsb2c9VCkpKSAjIE1pbnVzIG9mIGxvZyBsaWtlbGlob29kDQogIHJldHVybihtaW51c2xsKQ0KfQ0KDQpyZXNpZHVhbHMubWxlPC0gZnVuY3Rpb24ocGFyYW1zKSByZXR1cm4oWSAtWCAlKiVhcy5tYXRyaXgocGFyYW1zWzE6KGxlbmd0aChwYXJhbXMpLTIpXSkpDQpwcmVkaWN0Lm1sZSA8LSBmdW5jdGlvbihwYXJhbXMpIHJldHVybihYICUqJWFzLm1hdHJpeChwYXJhbXNbMToobGVuZ3RoKHBhcmFtcyktMildKSkNCmBgYA0KDQoNCmBgYHtyfQ0KIyBHQUJBOiBhZ2FpbnN0IGJvdGggRGlzcGxhY2VtZW50IGFuZCBzcGVlZCBvZiBtb3ZlbWVudA0KWCA8LSBtb2RlbC5tYXRyaXgobG0oR0FCQS5DciB+IEQgKyBTLCBkYXRhID0gZGF0YS5jbGVhbi5HQUJBLkRTKSkNClkgPC0gZGF0YS5jbGVhbi5HQUJBLkRTJEdBQkEuQ3INCnBhcm5hbWVzKExMKSA8LSBjKCdJbnRlcmNlcHQnLCAnRCcsICdTJywgJ211JywgJ3NpZ21hJykNCm1sZS5HQUJBLkRTIDwtIG1sZTIoTEwsIHN0YXJ0ID0gYyhJbnRlcmNlcHQgPSAwLjEsIEQgPSAwLjIsIFMgPSAwLjEsIG11ID0gMCwgc2lnbWEgPSAxKSwgDQogICAgIHZlY3BhciA9IFRSVUUsIHBhcm5hbWVzID0gYygnSW50ZXJjZXB0JywgJ0QnLCAnUycsICdtdScsICdzaWdtYScpKQ0Kc3VtbWFyeShtbGUuR0FCQS5EUykNCmBgYA0KDQpgYGB7cn0NCiMgR0FCQTogYWdhaW5zdCBEaXNwbGFjZW1lbnQgb2YgbW92ZW1lbnQgb25seQ0KWCA8LSBtb2RlbC5tYXRyaXgobG0oR0FCQS5DciB+IEQsIGRhdGEgPSBkYXRhLmNsZWFuLkdBQkEuRCkpDQpZIDwtIGRhdGEuY2xlYW4uR0FCQS5EJEdBQkEuQ3INCnBhcm5hbWVzKExMKSA8LSBjKCdJbnRlcmNlcHQnLCAnRCcsICdtdScsICdzaWdtYScpDQptbGUuR0FCQS5EIDwtIG1sZTIoTEwsIHN0YXJ0ID0gYyhJbnRlcmNlcHQgPSAwLjEsIEQgPSAwLjIsIG11ID0gMCwgc2lnbWEgPSAxKSwNCiAgICAgICAgICAgICAgICAgICB2ZWNwYXIgPSBUUlVFLCBwYXJuYW1lcz1jKCdJbnRlcmNlcHQnLCAnRCcsICdtdScsICdzaWdtYScpKQ0Kc3VtbWFyeShtbGUuR0FCQS5EKQ0KYGBgDQoNCmBgYHtyfQ0KIyBHQUJBOiBhZ2FpbnN0IHNwZWVkIG9mIG1vdmVtZW50IG9ubHkNClggPC0gbW9kZWwubWF0cml4KGxtKEdBQkEuQ3IgfiBTLCBkYXRhID0gZGF0YS5jbGVhbi5HQUJBLlMpKQ0KWSA8LSBkYXRhLmNsZWFuLkdBQkEuUyRHQUJBLkNyDQpwYXJuYW1lcyhMTCkgPC0gYygnSW50ZXJjZXB0JywgJ1MnLCAnbXUnLCAnc2lnbWEnKQ0KbWxlLkdBQkEuUyA8LSBtbGUyKExMLCBzdGFydCA9IGMoSW50ZXJjZXB0ID0gMC4xLCBTID0gMC4yLCBtdSA9IDAsIHNpZ21hID0gMSksDQogICAgICAgICAgICAgICAgICAgdmVjcGFyID0gVFJVRSwgcGFybmFtZXM9YygnSW50ZXJjZXB0JywgJ1MnLCAnbXUnLCAnc2lnbWEnKSkNCnN1bW1hcnkobWxlLkdBQkEuUykNCmBgYA0KDQpgYGB7cn0NCiMgTkFBDQpYIDwtIG1vZGVsLm1hdHJpeChsbShOQUEuQ3IgfiBEICsgUywgZGF0YSA9IGRhdGEuY2xlYW4uTkFBLkRTKSkNClkgPC0gZGF0YS5jbGVhbi5OQUEuRFMkTkFBLkNyDQpwYXJuYW1lcyhMTCkgPC0gYygnSW50ZXJjZXB0JywgJ0QnLCAnUycsICdtdScsICdzaWdtYScpDQptbGUuTkFBLkRTIDwtIG1sZTIoTEwsIHN0YXJ0ID0gYyggSW50ZXJjZXB0ID0gMC4xLCBEID0gMC4yLCBTID0gMC4xLCAgbXUgPSAwLCBzaWdtYSA9IDEpLA0KICAgICAgICAgICAgICAgICAgIHZlY3BhciA9IFRSVUUsIHBhcm5hbWVzPWMoJ0ludGVyY2VwdCcsICdEJywgJ1MnLCAnbXUnLCAnc2lnbWEnKSkNCnN1bW1hcnkobWxlLk5BQS5EUykNCmBgYA0KDQoNCmBgYHtyfQ0KWCA8LSBtb2RlbC5tYXRyaXgobG0oTkFBLkNyIH4gRCwgZGF0YSA9IGRhdGEuY2xlYW4uTkFBLkQpKQ0KWSA8LSBkYXRhLmNsZWFuLk5BQS5EJE5BQS5Dcg0KcGFybmFtZXMoTEwpIDwtIGMoJ0ludGVyY2VwdCcsICdEJywgJ211JywgJ3NpZ21hJykNCm1sZS5OQUEuRCA8LSBtbGUyKExMLCBzdGFydCA9IGMoSW50ZXJjZXB0ID0gMC4xLCBEID0gMC4yLCBtdSA9IDAsIHNpZ21hID0gMSksDQogICAgICAgICAgICAgICAgICAgdmVjcGFyID0gVFJVRSwgcGFybmFtZXM9YygnSW50ZXJjZXB0JywgJ0QnLCAnbXUnLCAnc2lnbWEnKSkNCnN1bW1hcnkobWxlLk5BQS5EKQ0KYGBgDQoNCmBgYHtyfQ0KWCA8LSBtb2RlbC5tYXRyaXgobG0oTkFBLkNyIH4gUywgZGF0YSA9IGRhdGEuY2xlYW4uTkFBLlMpKQ0KWSA8LSBkYXRhLmNsZWFuLk5BQS5TJE5BQS5Dcg0KcGFybmFtZXMoTEwpIDwtIGMoJ0ludGVyY2VwdCcsICdTJywgJ211JywgJ3NpZ21hJykNCm1sZS5OQUEuUyA8LSBtbGUyKExMLCBzdGFydCA9IGMoSW50ZXJjZXB0ID0gMC4xLCBTID0gMC4yLCBtdSA9IDAsIHNpZ21hID0gMSksDQogICAgICAgICAgICAgICAgICB2ZWNwYXIgPSBUUlVFLCBwYXJuYW1lcz1jKCdJbnRlcmNlcHQnLCAnUycsICdtdScsICdzaWdtYScpKQ0Kc3VtbWFyeShtbGUuTkFBLlMpDQoNCmBgYA0KDQpgYGB7cn0NCiMgR2x4DQpYIDwtIG1vZGVsLm1hdHJpeChsbShHbHguQ3IgfiBEICsgUywgZGF0YSA9IGRhdGEuY2xlYW4uR2x4LkRTKSkNClkgPC0gZGF0YS5jbGVhbi5HbHguRFMkR2x4LkNyDQpwYXJuYW1lcyhMTCkgPC0gYygnSW50ZXJjZXB0JywgJ0QnLCAnUycsICdtdScsICdzaWdtYScpDQptbGUuR2x4LkRTIDwtIG1sZTIoTEwsIHN0YXJ0ID0gYyggSW50ZXJjZXB0ID0gMC4xLCBEID0gMC4yLCBTID0gMC4xLCAgbXUgPSAwLCBzaWdtYSA9IDEpLA0KICAgICAgICAgICAgICAgICAgIHZlY3BhciA9IFRSVUUsIHBhcm5hbWVzPWMoJ0ludGVyY2VwdCcsICdEJywgJ1MnLCAnbXUnLCAnc2lnbWEnKSkNCnN1bW1hcnkobWxlLkdseC5EUykNCmBgYA0KDQoNCmBgYHtyfQ0KWCA8LSBtb2RlbC5tYXRyaXgobG0oR2x4LkNyIH4gRCwgZGF0YSA9IGRhdGEuY2xlYW4uR2x4LkQpKQ0KWSA8LSBkYXRhLmNsZWFuLkdseC5EJEdseC5Dcg0KcGFybmFtZXMoTEwpIDwtIGMoJ0ludGVyY2VwdCcsICdEJywgJ211JywgJ3NpZ21hJykNCm1sZS5HbHguRCA8LSBtbGUyKExMLCBzdGFydCA9IGMoSW50ZXJjZXB0ID0gMC4xLCBEID0gMC4yLCBtdSA9IDAsIHNpZ21hID0gMSksDQogICAgICAgICAgICAgICAgICB2ZWNwYXIgPSBUUlVFLCBwYXJuYW1lcz1jKCdJbnRlcmNlcHQnLCAnRCcsICdtdScsICdzaWdtYScpKQ0Kc3VtbWFyeShtbGUuR2x4LkQpDQpgYGANCg0KDQpgYGB7cn0NClggPC0gbW9kZWwubWF0cml4KGxtKEdseC5DciB+IFMsIGRhdGEgPSBkYXRhLmNsZWFuLkdseC5TKSkNClkgPC0gZGF0YS5jbGVhbi5HbHguUyRHbHguQ3INCnBhcm5hbWVzKExMKSA8LSBjKCdJbnRlcmNlcHQnLCAnUycsICdtdScsICdzaWdtYScpDQptbGUuR2x4LlMgPC0gbWxlMihMTCwgc3RhcnQgPSBjKEludGVyY2VwdCA9IDAuMSwgUyA9IDAuMiwgbXUgPSAwLCBzaWdtYSA9IDEpLA0KICAgICAgICAgICAgICAgICAgdmVjcGFyID0gVFJVRSwgcGFybmFtZXM9YygnSW50ZXJjZXB0JywgJ1MnLCAnbXUnLCAnc2lnbWEnKSkNCnN1bW1hcnkobWxlLkdseC5TKQ0KYGBgDQoNCioqQ29uY2x1c2lvbjogR0FCQSBzZWVtcyB0byBiZSB2ZXJ5IHNlbnNpdGl2ZSB0byBtb3ZlbWVudCwgd2hlcmVhcyB0aGUgb3RoZXIgdHdvIG1vcmUgYWJ1bmRhbnQgY2hlbWljYWwgZG9lcyBub3Qgc2VlbSB0byBiZSBhZmZlY3RlZC4qKg0KDQojIyBQbG90IG1lYXN1cmVtZW50cyBvZiBuZXVyb2NoZW1pY2FsIHNpZ25hbHMgaW4gcHJpbWFyeSB2aXN1YWwgY29ydGV4IGFnYWluc3QgbW92ZW1lbnQgcGFyYW1ldGVyIGFuZCBmaXQgYSBsaW5lIA0KYGBge3J9DQojIEdBQkENCmxtLkdBQkEuRCA8LSBsbShHQUJBLkNyIH4gRCwgZGF0YS5jbGVhbi5HQUJBLkQpDQpsbS5HQUJBLkQkY29lZmZpY2llbnRzIDwtIGNvZWYobWxlLkdBQkEuRClbMToyXQ0KbmFtZXMobG0uR0FCQS5EJGNvZWZmaWNpZW50cykgPC0gYygiKEludGVyY2VwdCkiLCJEIikNCmdyaWQgPC0gd2l0aChkYXRhLmNsZWFuLkdBQkEuRCwgZXhwYW5kLmdyaWQoRCA9IHNlcShtaW4oRCksIG1heChEKSwgbGVuZ3RoPTIwKSkpDQpncmlkJEdBQkEuQ3IgPC0gc3RhdHM6OnByZWRpY3QobG0uR0FCQS5ELCBuZXdkYXRhPWdyaWQpDQplcnIgPC0gc3RhdHM6OnByZWRpY3QobG0uR0FCQS5ELCBuZXdkYXRhPWdyaWQsIHNlID0gVFJVRSkNCmdyaWQkdWNsIDwtIGVyciRmaXQgKyAxLjk2ICogZXJyJHNlLmZpdA0KZ3JpZCRsY2wgPC0gZXJyJGZpdCAtIDEuOTYgKiBlcnIkc2UuZml0DQpwID0gZ2dwbG90KGRhdGEuY2xlYW4uR0FCQS5ELCBhZXMoeD1ELCB5PUdBQkEuQ3IpKSArDQogIGdlb21fcG9pbnQoc2hhcGU9MSxzaXplPTYpICsgI2dlb21fc21vb3RoKG1ldGhvZD1sbSkrDQogIGdlb21fc21vb3RoKGFlcyh5bWluID0gbGNsLCB5bWF4ID0gdWNsKSwgZGF0YSA9IGdyaWQsIHN0YXQ9ImlkZW50aXR5IikrDQogIHhsYWIoZXhwcmVzc2lvbigiUk1TIG9mIERpc3BsYWNlbWVudCAiICogRGVsdGEgfiAiIChtbSkiKSkrDQogIHlsYWIoIlYxIEdBQkEvQ3IiKQ0KIyBMID0gcGFzdGUoIlJeMiB+IFwiPVwiIH4iLCByb3VuZChzdW1tYXJ5KGxtKEdBQkEuQ3IgfiBELCBkYXRhLmNsZWFuLkdBQkEuRCkpJGFkai5yLnNxdWFyZWQsZGlnaXRzPTQpKQ0KTCA9IHBhc3RlKCItMiB+IGxvZ0wgfiBcIj1cIiB+Iiwgcm91bmQoYXMubnVtZXJpYyhsb2dMaWsobWxlLkdBQkEuRCkpKi0yLGRpZ2l0cz0yKSkNCnAgKyBnZW9tX3RleHQoYWVzKHg9MS41LHkgPSAwLjE3LCBsYWJlbCA9IEwpLHNpemU9NixwYXJzZT1UKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemU9MjApLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpDQpgYGANCg0KYGBge3J9DQpsbS5HQUJBLlMgPC0gbG0oR0FCQS5DciB+IFMsIGRhdGEuY2xlYW4uR0FCQS5TKQ0KbG0uR0FCQS5TJGNvZWZmaWNpZW50cyA8LSBjb2VmKG1sZS5HQUJBLlMpWzE6Ml0NCm5hbWVzKGxtLkdBQkEuUyRjb2VmZmljaWVudHMpIDwtIGMoIihJbnRlcmNlcHQpIiwiUyIpDQpncmlkIDwtIHdpdGgoZGF0YS5jbGVhbi5HQUJBLlMsIGV4cGFuZC5ncmlkKFMgPSBzZXEobWluKFMpLCBtYXgoUyksIGxlbmd0aD0yMCkpKQ0KZ3JpZCRHQUJBLkNyIDwtIHN0YXRzOjpwcmVkaWN0KGxtLkdBQkEuUywgbmV3ZGF0YT1ncmlkKQ0KZXJyIDwtIHN0YXRzOjpwcmVkaWN0KGxtLkdBQkEuUywgbmV3ZGF0YT1ncmlkLCBzZSA9IFRSVUUpDQpncmlkJHVjbCA8LSBlcnIkZml0ICsgMS45NiAqIGVyciRzZS5maXQNCmdyaWQkbGNsIDwtIGVyciRmaXQgLSAxLjk2ICogZXJyJHNlLmZpdA0KcCA9IGdncGxvdChkYXRhLmNsZWFuLkdBQkEuUywgYWVzKHg9UywgeT1HQUJBLkNyKSkgKw0KICBnZW9tX3BvaW50KHNoYXBlPTEsc2l6ZT02KSArI2dlb21fc21vb3RoKG1ldGhvZD1sbSkrDQogIGdlb21fc21vb3RoKGFlcyh5bWluID0gbGNsLCB5bWF4ID0gdWNsKSwgZGF0YSA9IGdyaWQsIHN0YXQ9ImlkZW50aXR5IikrDQogIHhsYWIoZXhwcmVzc2lvbigiUk1TIG9mIFNwZWVkICIgKiBTaWdtYSB+ICIgKG1tL3MpIikpKw0KICB5bGFiKCJWMSBHQUJBL0NyIikNCkwgPSBwYXN0ZSgiLTIgfiBsb2dMIH4gXCI9XCIgfiIsIHJvdW5kKGFzLm51bWVyaWMobG9nTGlrKG1sZS5HQUJBLlMpKSotMixkaWdpdHM9MikpDQpwICsgZ2VvbV90ZXh0KGFlcyh4PTAuMTQseSA9IDAuMTcsIGxhYmVsID0gTCksc2l6ZT02LHBhcnNlPVQpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkNCmBgYA0KDQpgYGB7cn0NCiMgTkFBDQpsbS5OQUEuRCA8LSBsbShOQUEuQ3IgfiBELCBkYXRhLmNsZWFuLk5BQS5EKQ0KbG0uTkFBLkQkY29lZmZpY2llbnRzIDwtIGNvZWYobWxlLk5BQS5EKVsxOjJdDQpuYW1lcyhsbS5OQUEuRCRjb2VmZmljaWVudHMpIDwtIGMoIihJbnRlcmNlcHQpIiwiRCIpDQpncmlkIDwtIHdpdGgoZGF0YS5jbGVhbi5OQUEuRCwgZXhwYW5kLmdyaWQoRCA9IHNlcShtaW4oRCksIG1heChEKSwgbGVuZ3RoPTIwKSkpDQpncmlkJE5BQS5DciA8LSBzdGF0czo6cHJlZGljdChsbS5OQUEuRCwgbmV3ZGF0YT1ncmlkKQ0KZXJyIDwtIHN0YXRzOjpwcmVkaWN0KGxtLk5BQS5ELCBuZXdkYXRhPWdyaWQsIHNlID0gVFJVRSkNCmdyaWQkdWNsIDwtIGVyciRmaXQgKyAxLjk2ICogZXJyJHNlLmZpdA0KZ3JpZCRsY2wgPC0gZXJyJGZpdCAtIDEuOTYgKiBlcnIkc2UuZml0DQpwID0gZ2dwbG90KGRhdGEuY2xlYW4uTkFBLkQsIGFlcyh4PUQsIHk9TkFBLkNyKSkgKw0KICBnZW9tX3BvaW50KHNoYXBlPTEsc2l6ZT02KSArICNnZW9tX3Ntb290aChtZXRob2Q9bG0pKw0KICBnZW9tX3Ntb290aChhZXMoeW1pbiA9IGxjbCwgeW1heCA9IHVjbCksIGRhdGEgPSBncmlkLCBzdGF0PSJpZGVudGl0eSIpKw0KICB4bGFiKGV4cHJlc3Npb24oIlJNUyBvZiBEaXNwbGFjZW1lbnQgIiAqIERlbHRhIH4gIiAobW0pIikpKw0KICB5bGFiKCJWMSBOQUEvQ3IiKQ0KIyBMID0gcGFzdGUoIlJeMiB+IFwiPVwiIH4iLCByb3VuZChzdW1tYXJ5KGxtKE5BQS5DciB+IEQsIGRhdGEuY2xlYW4uTkFBLkQpKSRhZGouci5zcXVhcmVkLGRpZ2l0cz00KSkNCkwgPSBwYXN0ZSgiLTIgfiBsb2dMIH4gXCI9XCIgfiIsIHJvdW5kKGFzLm51bWVyaWMobG9nTGlrKG1sZS5OQUEuRCkpKi0yLGRpZ2l0cz0yKSkNCnAgKyBnZW9tX3RleHQoYWVzKHg9MS41LHkgPSAyLjAsIGxhYmVsID0gTCksc2l6ZT02LHBhcnNlPVQpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkNCmBgYA0KDQpgYGB7cn0NCmxtLk5BQS5TIDwtIGxtKE5BQS5DciB+IFMsIGRhdGEuY2xlYW4uTkFBLlMpDQpsbS5OQUEuUyRjb2VmZmljaWVudHMgPC0gY29lZihtbGUuTkFBLlMpWzE6Ml0NCm5hbWVzKGxtLk5BQS5TJGNvZWZmaWNpZW50cykgPC0gYygiKEludGVyY2VwdCkiLCJTIikNCmdyaWQgPC0gd2l0aChkYXRhLmNsZWFuLk5BQS5TLCBleHBhbmQuZ3JpZChTID0gc2VxKG1pbihTKSwgbWF4KFMpLCBsZW5ndGg9MjApKSkNCmdyaWQkTkFBLkNyIDwtIHN0YXRzOjpwcmVkaWN0KGxtLk5BQS5TLCBuZXdkYXRhPWdyaWQpDQplcnIgPC0gc3RhdHM6OnByZWRpY3QobG0uTkFBLlMsIG5ld2RhdGE9Z3JpZCwgc2UgPSBUUlVFKQ0KZ3JpZCR1Y2wgPC0gZXJyJGZpdCArIDEuOTYgKiBlcnIkc2UuZml0DQpncmlkJGxjbCA8LSBlcnIkZml0IC0gMS45NiAqIGVyciRzZS5maXQNCnAgPSBnZ3Bsb3QoZGF0YS5jbGVhbi5OQUEuUywgYWVzKHg9UywgeT1OQUEuQ3IpKSArDQogIGdlb21fcG9pbnQoc2hhcGU9MSxzaXplPTYpICsjZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHltaW4gPSBsY2wsIHltYXggPSB1Y2wpLCBkYXRhID0gZ3JpZCwgc3RhdD0iaWRlbnRpdHkiKSsNCiAgeGxhYihleHByZXNzaW9uKCJSTVMgb2YgU3BlZWQgIiAqIFNpZ21hIH4gIiAobW0vcykiKSkrDQogIHlsYWIoIlYxIE5BQS9DciIpDQpMID0gcGFzdGUoIi0yIH4gbG9nTCB+IFwiPVwiIH4iLCByb3VuZChhcy5udW1lcmljKGxvZ0xpayhtbGUuTkFBLlMpKSotMixkaWdpdHM9MikpDQpwICsgZ2VvbV90ZXh0KGFlcyh4PTAuMTMseSA9IDIuMCwgbGFiZWwgPSBMKSxzaXplPTYscGFyc2U9VCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MjApKQ0KYGBgDQoNCmBgYHtyfQ0KIyBHbHgNCmxtLkdseC5EIDwtIGxtKEdseC5DciB+IEQsIGRhdGEuY2xlYW4uR2x4LkQpDQpsbS5HbHguRCRjb2VmZmljaWVudHMgPC0gY29lZihtbGUuR2x4LkQpWzE6Ml0NCm5hbWVzKGxtLkdseC5EJGNvZWZmaWNpZW50cykgPC0gYygiKEludGVyY2VwdCkiLCJEIikNCmdyaWQgPC0gd2l0aChkYXRhLmNsZWFuLkdseC5ELCBleHBhbmQuZ3JpZChEID0gc2VxKG1pbihEKSwgbWF4KEQpLCBsZW5ndGg9MjApKSkNCmdyaWQkR2x4LkNyIDwtIHN0YXRzOjpwcmVkaWN0KGxtLkdseC5ELCBuZXdkYXRhPWdyaWQpDQplcnIgPC0gc3RhdHM6OnByZWRpY3QobG0uR2x4LkQsIG5ld2RhdGE9Z3JpZCwgc2UgPSBUUlVFKQ0KZ3JpZCR1Y2wgPC0gZXJyJGZpdCArIDEuOTYgKiBlcnIkc2UuZml0DQpncmlkJGxjbCA8LSBlcnIkZml0IC0gMS45NiAqIGVyciRzZS5maXQNCnAgPSBnZ3Bsb3QoZGF0YS5jbGVhbi5HbHguRCwgYWVzKHg9RCwgeT1HbHguQ3IpKSArDQogIGdlb21fcG9pbnQoc2hhcGU9MSxzaXplPTYpICsgI2dlb21fc21vb3RoKG1ldGhvZD1sbSkrDQogIGdlb21fc21vb3RoKGFlcyh5bWluID0gbGNsLCB5bWF4ID0gdWNsKSwgZGF0YSA9IGdyaWQsIHN0YXQ9ImlkZW50aXR5IikrDQogIHhsYWIoZXhwcmVzc2lvbigiUk1TIG9mIERpc3BsYWNlbWVudCAiICogRGVsdGEgfiAiIChtbSkiKSkrDQogIHlsYWIoIlYxIEdseC9DciIpDQojIEwgPSBwYXN0ZSgiUl4yIH4gXCI9XCIgfiIsIHJvdW5kKHN1bW1hcnkobG0oR2x4LkNyIH4gRCwgZGF0YS5jbGVhbi5HbHguRCkpJGFkai5yLnNxdWFyZWQsZGlnaXRzPTQpKQ0KTCA9IHBhc3RlKCItMiB+IGxvZ0wgfiBcIj1cIiB+Iiwgcm91bmQoYXMubnVtZXJpYyhsb2dMaWsobWxlLkdseC5EKSkqLTIsZGlnaXRzPTIpKQ0KcCArIGdlb21fdGV4dChhZXMoeD0xLjUseSA9IDAuMTYsIGxhYmVsID0gTCksc2l6ZT02LHBhcnNlPVQpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkNCmBgYA0KDQpgYGB7cn0NCmxtLkdseC5TIDwtIGxtKEdseC5DciB+IFMsIGRhdGEuY2xlYW4uR2x4LlMpDQpsbS5HbHguUyRjb2VmZmljaWVudHMgPC0gY29lZihtbGUuR2x4LlMpWzE6Ml0NCm5hbWVzKGxtLkdseC5TJGNvZWZmaWNpZW50cykgPC0gYygiKEludGVyY2VwdCkiLCJTIikNCmdyaWQgPC0gd2l0aChkYXRhLmNsZWFuLkdseC5TLCBleHBhbmQuZ3JpZChTID0gc2VxKG1pbihTKSwgbWF4KFMpLCBsZW5ndGg9MjApKSkNCmdyaWQkR2x4LkNyIDwtIHN0YXRzOjpwcmVkaWN0KGxtLkdseC5TLCBuZXdkYXRhPWdyaWQpDQplcnIgPC0gc3RhdHM6OnByZWRpY3QobG0uR2x4LlMsIG5ld2RhdGE9Z3JpZCwgc2UgPSBUUlVFKQ0KZ3JpZCR1Y2wgPC0gZXJyJGZpdCArIDEuOTYgKiBlcnIkc2UuZml0DQpncmlkJGxjbCA8LSBlcnIkZml0IC0gMS45NiAqIGVyciRzZS5maXQNCnAgPSBnZ3Bsb3QoZGF0YS5jbGVhbi5HbHguUywgYWVzKHg9UywgeT1HbHguQ3IpKSArDQogIGdlb21fcG9pbnQoc2hhcGU9MSxzaXplPTYpICsjZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHltaW4gPSBsY2wsIHltYXggPSB1Y2wpLCBkYXRhID0gZ3JpZCwgc3RhdD0iaWRlbnRpdHkiKSsNCiAgeGxhYihleHByZXNzaW9uKCJSTVMgb2YgU3BlZWQgIiAqIFNpZ21hIH4gIiAobW0vcykiKSkrDQogIHlsYWIoIlYxIEdseC9DciIpDQpMID0gcGFzdGUoIi0yIH4gbG9nTCB+IFwiPVwiIH4iLCByb3VuZChhcy5udW1lcmljKGxvZ0xpayhtbGUuR2x4LlMpKSotMixkaWdpdHM9MikpDQpwICsgZ2VvbV90ZXh0KGFlcyh4PTAuMTMseSA9IDAuMTYsIGxhYmVsID0gTCksc2l6ZT02LHBhcnNlPVQpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkNCg0KYGBgDQoNCiMjIElzIGl0IHRydWUgdGhhdCB0aGUgbG9uZ2VyIHRoZSBzdWJqZWN0IHN0YXkgaW4gdGhlIHNjYW5uZXIsIHRoZSB3b3JzZSB0aGUgc2lnbmFsPw0KYGBge3J9DQpsaWJyYXJ5KG5sbWUpDQpsb2FkKCJEOi9FZHdhcmQvRG9jdW1lbnRzL0Fzc2lnbm1lbnRzL0ltYWdpbmcgUmVzZWFyY2ggQ2VudGVyL0dBQkEgTW92ZW1lbnQgRm91cnRoIFN1Ym1pc3Npb24vYW5hbHlzaXMvZGF0YS9kYXRhX3Jlc3VsdHNfMTAzMDIwMTYuUkRhdGEiKQ0KYGBgDQoNCg0KYGBge3J9DQpsbWUuR0FCQS5DciA9IGxtZShHQUJBLkNyIH4gUmVnaW9uLlJ1bi5PcmRlciwgZGF0YT1kYXRhLmhvbW9nZW5lb3VzLCByYW5kb209fjF8U3ViamVjdCkNCnN1bW1hcnkobG1lLkdBQkEuQ3IpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbG1lLkdseC5DciA9IGxtZShHbHguQ3IgfiBSZWdpb24uUnVuLk9yZGVyLCBkYXRhPWRhdGEuaG9tb2dlbmVvdXMsIHJhbmRvbT1+MXxTdWJqZWN0KQ0Kc3VtbWFyeShsbWUuR2x4LkNyKQ0KYGBgDQoNCg0KYGBge3J9DQpsbWUuTkFBLkNyID0gbG1lKE5BQS5DciB+IFJlZ2lvbi5SdW4uT3JkZXIsIGRhdGE9ZGF0YS5ob21vZ2VuZW91cywgcmFuZG9tPX4xfFN1YmplY3QpDQpzdW1tYXJ5KGxtZS5OQUEuQ3IpDQpgYGANCg0KDQoqKkNvbmNsdXNpb246IFllcy4gVGhlIGxvbmdlciB0aGUgc3ViamVjdGVkIHN0YXllZCBpbiB0aGUgc2Nhbm5lciAoaS5lLiB0aGUgbG9uZ2VyIHRpbWUgaXQgdGFrZXMgdG8gY29tcGxldGUgdGhlIG1lYXN1cmVtZW50KSwgdGhlIHdvcnNlIHRoZSBHQUJBIGFuZCBHbHggc2lnbmFsLCBidXQgbm90IE5BQSBzaWduYWwuKioNCg0KDQoNCg0KDQoNCg==