diff --git a/StudentData/PIXL_LIBS_Combined.Rds b/StudentData/PIXL_LIBS_Combined.Rds index c7bf055..88b47ca 100644 Binary files a/StudentData/PIXL_LIBS_Combined.Rds and b/StudentData/PIXL_LIBS_Combined.Rds differ diff --git a/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd b/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd index 7ac4ad6..d42d184 100644 --- a/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd +++ b/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd @@ -90,11 +90,8 @@ libs.df[,6:13] <- sapply(libs.df[,6:13],as.numeric) libs.df<-libs.df%>% filter(!(grepl("scct", target))) -#add a column to indicate the nearest pixl -libs.df<-cbind(nearestpixl=0,libs.df) - #make a dataframe of just the LIBS Lat/Long and target name and remove duplicates -libstargets.df<-libs.df[,c(1,3,4,5)] +libstargets.df<-cbind("nearestpixl"=0,libs.df[,1:4]) libstargets.df<-distinct(libstargets.df) ``` @@ -120,33 +117,24 @@ pixl.df<-pixl.df[c(2,4,6,8,10,12,14,16),] ### Combining datasets ```{r} -distance=100 -distCosine(pixl.df[1,c(1,2)],libstargets.df[1,c(2,3)], r=3393169) -for(i in 1:nrow(pixl.df)) { - libstargets.df<-libstargets.df%>%mutate(nearestpixl = ifelse(distHaversine(pixl.df[i,c(1,2)],c(lat,lon),r=3393169),pixl.df[i,5], nearestpixl)) - -} -``` - -```{r} +# Create a new dataframe with the LIBS metatdata as well as features corresponding to each PIXL Abrasion libstargets.df<-cbind(libstargets.df,"Distance"=0,"Bellegrade"=0,"Dourbes"=0,"Quartier"=0,"Alfalfa"=0,"ThorntonGap"=0,"BerryHollow"=0,"Novarupta"=0,"UganikIsland"=0) ``` ```{r} -#DistCosine(pixl.df[1,c(1,2)],libstargets.df[1,c(2,3)], r=3393169) - +#Calculate the distance between each LIBS target and each PIXL abrasion, then fill in the minimum distances for(i in 1:nrow(libstargets.df)) { - libstargets.df[i,c(6:13)]<-c(distHaversine(pixl.df[1,c(1,2)],libstargets.df[i,c(2,3)],r=3393169), - distHaversine(pixl.df[2,c(1,2)],libstargets.df[i,c(2,3)],r=3393169), - distHaversine(pixl.df[3,c(1,2)],libstargets.df[i,c(2,3)],r=3393169), - distHaversine(pixl.df[4,c(1,2)],libstargets.df[i,c(2,3)],r=3393169), - distHaversine(pixl.df[5,c(1,2)],libstargets.df[i,c(2,3)],r=3393169), - distHaversine(pixl.df[6,c(1,2)],libstargets.df[i,c(2,3)],r=3393169), - distHaversine(pixl.df[7,c(1,2)],libstargets.df[i,c(2,3)],r=3393169), - distHaversine(pixl.df[8,c(1,2)],libstargets.df[i,c(2,3)],r=3393169)) + libstargets.df[i,c(7:14)]<-c(distHaversine(pixl.df[1,c(1,2)],libstargets.df[i,c(3,4)],r=3393169), + distHaversine(pixl.df[2,c(1,2)],libstargets.df[i,c(3,4)],r=3393169), + distHaversine(pixl.df[3,c(1,2)],libstargets.df[i,c(3,4)],r=3393169), + distHaversine(pixl.df[4,c(1,2)],libstargets.df[i,c(3,4)],r=3393169), + distHaversine(pixl.df[5,c(1,2)],libstargets.df[i,c(3,4)],r=3393169), + distHaversine(pixl.df[6,c(1,2)],libstargets.df[i,c(3,4)],r=3393169), + distHaversine(pixl.df[7,c(1,2)],libstargets.df[i,c(3,4)],r=3393169), + distHaversine(pixl.df[8,c(1,2)],libstargets.df[i,c(3,4)],r=3393169)) - libstargets.df[i,1]<-which.min(libstargets.df[i,c(6:13)]) - libstargets.df[i,5]<-min(libstargets.df[i,c(6:13)]) + libstargets.df[i,1]<-which.min(libstargets.df[i,c(7:14)]) + libstargets.df[i,6]<-min(libstargets.df[i,c(7:14)]) } libstargets.df$nearestpixl<-as.factor(libstargets.df$nearestpixl) @@ -156,6 +144,7 @@ levels(libstargets.df$nearestpixl)<-(c("Bellegrade","Dourbes","Quartier","Alfalf ```{r} +#Create vectors of LIBS targets corresponding to each PIXL Abrasion Bellegrade<-libstargets.df[libstargets.df$nearestpixl=="Bellegrade",]$target Dourbes<-libstargets.df[libstargets.df$nearestpixl=="Dourbes",]$target Quartier<-libstargets.df[libstargets.df$nearestpixl=="Quartier",]$target @@ -166,26 +155,11 @@ Novarupta<-libstargets.df[libstargets.df$nearestpixl=="Novarupta",]$target UganikIsland<-libstargets.df[libstargets.df$nearestpixl=="UganikIsland",]$target ``` - -### Ternary Diagram ```{r} -meters=100 - -included.libs<-(libstargets.df%>% - filter(Distance% - filter(target %in% included.libs) - -libs.matrix <- libs.matrix[,c(5,7:14)] - -libs.tern <- as.data.frame(libs.matrix) %>% - mutate(x=(SiO2+Al2O3)/100,y=(FeOT+MgO)/100,z=(CaO+Na2O+K2O)/100) %>% - select(-c(SiO2,Al2O3,FeOT,MgO,CaO,Na2O,K2O,TiO2)) +#Add the nearest Abrasion to the LIBS data +libs.pixl.merged <- cbind("Abrasion"=0,libs.df) -libs.tern<-cbind("Abrasion"=0,libs.tern) - -libs.tern<-libs.tern%>% +libs.pixl.merged<-libs.pixl.merged%>% mutate(Abrasion = ifelse(target%in%Alfalfa,"Alfalfa", ifelse(target %in% Bellegrade, "Belegrade", ifelse(target %in% BerryHollow, "BerryHollow", @@ -193,55 +167,77 @@ libs.tern<-libs.tern%>% ifelse(target %in% Novarupta, "Novarupta", ifelse(target %in% Quartier, "Quartier", ifelse(target %in% ThorntonGap, "ThorntonGap", - ifelse(target %in% UganikIsland, "UganikIsland",Abrasion))))))))) + ifelse(target %in% UganikIsland, "Uganik Island",Abrasion))))))))) + +targetdistance<-libstargets.df[,2:6] +libs.pixl.merged<-merge(libs.pixl.merged,targetdistance,by=c("target","sol","lat","lon"),all.x=T) +``` + +```{r} +#Add back some pixl features +pix<-pixl.df[,c(1,2,4,5)] +libs.pixl <- merge(libs.pixl.merged, pix, by.x="Abrasion",by.y="abrasion",all.x=TRUE) + +#rename and reorder columns +libs.pixl<-cbind("LIBS.Target"=libs.pixl$target,libs.pixl[,4:5],"LIBS.Sol"=libs.pixl$sol,"LIBS.Point"=libs.pixl$point,"Distance"=libs.pixl$Distance,"PIXL.Abrasion"=libs.pixl$Abrasion,libs.pixl[,16:18],libs.pixl[,7:14]) +colnames(libs.pixl)<-c("LIBS.Target","LIBS.Lat","LIBS.Lon","LIBS.Sol","LIBS.Point", "Distance","PIXL.Abrasion","PIXL.Lat","PIXL.Lon","PIXL.Campaign","LIBS.SiO2","LIBS.TiO2","LIBS.Al2O3","LIBS.FeOT","LIBS.MgO","LIBS.CaO","LIBS.Na2O","LIBS.K2O") +``` -kabledf<-rbind("Distance (m)"=meters,"Targets"=length(included.libs),"Points"=nrow(libs.tern)) +```{r} +#setwd("~/DAR-Mars-F24/StudentData") +#saveRDS(libs.pixl,"PIXL_LIBS_Combined.Rds") +``` + +The libs.pixl dataframe is now saved to PIXL_LIBS_Combined.Rds, which can be found in the StudentData folder. + +### Ternary Diagram + +Example of creating a ternary plot filtering the combined LIBS and PIXL data +```{r} +libs.tern <- libs.pixl %>% + mutate(x=(LIBS.SiO2+LIBS.Al2O3)/100,y=(LIBS.FeOT+LIBS.MgO)/100,z=(LIBS.CaO+LIBS.Na2O+LIBS.K2O)/100) -kable(kabledf) +libs.tern<-libs.tern[,c(6,7,19:21)] ``` ```{r} +meters=7 + ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) + - geom_point(data=libs.tern,aes(color=Abrasion,alpha=0.5)) + + geom_point(data=subset(libs.tern,Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + theme_rgbw() + - labs(title=paste("Mars LIBS Data Within",distance,"meters of PIXL",sep=" "), + labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL",sep=" "), x="Si+Al", y="Fe+Mg", z="Ca+Na+K")+theme(legend.position="right") + guides(alpha="none") -``` - -### Line plot - -```{r} meters=100 -included.libs<-(libstargets.df%>% - filter(Distance% - filter(target %in% included.libs) +ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) + + geom_point(data=subset(libs.tern,Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + + theme_rgbw() + + labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL",sep=" "), + x="Si+Al", + y="Fe+Mg", + z="Ca+Na+K")+theme(legend.position="right") + + guides(alpha="none") +``` -libs.matrix <- libs.matrix[,c(5,7:14)] -libs.matrix<-libs.matrix[,c(1:2,4:9,3)] +### Line plot -libs.matrix<-cbind("Abrasion"=0,libs.matrix) +Example of how to add the pixl data as extra rows to the LIBS data, so that it can be graphed on the same plot -libs.matrix<-libs.matrix%>% - mutate(Abrasion = ifelse(target%in%Alfalfa,"Alfalfa", - ifelse(target %in% Bellegrade, "Belegrade", - ifelse(target %in% BerryHollow, "BerryHollow", - ifelse(target %in% Dourbes, "Dourbes", - ifelse(target %in% Novarupta, "Novarupta", - ifelse(target %in% Quartier, "Quartier", - ifelse(target %in% ThorntonGap, "ThorntonGap", - ifelse(target %in% UganikIsland, "UganikIsland",Abrasion))))))))) +```{r} +#remove certain features from the combined pixl libs dataset +libs.matrix <- libs.pixl[,c(7,1,11,13:18,12)] +#rename columns libs.matrix<-cbind(libsorpixl=1,libs.matrix) + +colnames(libs.matrix)<-c("libsorpixl","Abrasion","targets+names","SiO2","Al2O3","FeOT","MgO","CaO","Na2O","K2O","TiO2") ``` @@ -262,9 +258,7 @@ pixl.df<-cbind(libsorpixl=0,pixl.df) ``` ```{r} +#rename pixl columns and combine dataframes colnames(pixl.df)<-colnames(libs.matrix) pixllibs.df<-rbind(pixl.df,libs.matrix) ``` - - - diff --git a/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.Rmd b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.Rmd new file mode 100755 index 0000000..bb273e5 --- /dev/null +++ b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.Rmd @@ -0,0 +1,487 @@ +--- +title: "Data Analytics Research Individual Final Project Report" +author: "Margo VanEsselstyn" +date: "`r Sys.Date()`" +output: + html_document: + toc: yes + toc_depth: 3 + toc_float: yes + number_sections: no + theme: united + html_notebook: default + pdf_document: + toc: yes + toc_depth: '3' +--- +# DAR Project and Group Members + +* Project name: Mars +* Project team members: Charlotte Peterson, Doña Roberts, Xuanting Wang, David Walczyk, Charlotte Newman, Dante Mwatibo, Nicolas Morawski, CJ Marino, Aadi Lahiri, Ashton Compton + +# 0.0 Preliminaries. + +This report is generated from an R Markdown file that includes all the R code necessary to produce the results described and embedded in the report. Code blocks can be surpressed from output for readability using the command code `{R, echo=show}` in the code block header. If `show <- FALSE` the code block will be surpressed; if `show <- TRUE` then the code will be show. + +```{r} +# Set to TRUE to expand R code blocks; set to FALSE to collapse R code blocks +show <- TRUE +``` + +Executing this R notebook requires some subset of the following packages: + +* `ggplot2` +* `tidyverse` +* `ggtern` +* `knitr` +* `pheatmap` + +These will be installed and loaded as necessary (code suppressed). + + +```{r, include=FALSE} +# This code will install required packages if they are not already installed +# ALWAYS INSTALL YOUR PACKAGES LIKE THIS! +if (!require("ggplot2")) { + install.packages("ggplot2") + library(ggplot2) +} +if (!require("tidyverse")) { + install.packages("tidyverse") + library(tidyverse) +} +if (!require("ggtern")) { + install.packages("ggtern") + library(ggtern) +} +if(!require("knitr")) { + install.packages("knitr") + library(knitr) +} +if(!require("pheatmap")){ + install.packages("pheatmap") + library(pheatmap) +} +``` + +# 1.0 Project Introduction + +This project outlines my analysis of the Mars LIBS and PIXL data. It largely revolves around data processing and organization + +# 2.0 Organization of Report + +This report is organized as follows: + +* Section 3.0. Finding 1: Here we discuss the LIBS scct targets and the importance of differentiating them in future analysis + +* Section 4.0: Finding 2: Here we discuss the connection between the LIBS and PIXL data + +* Section 5.0 Overall conclusions and suggestions + +# 3.0 Finding 1: Understanding LIBS Targets + +I researched the meaning behind the LIBS target names, and categorized the LIBS data into a few major categories. I created a new Rds file that includes a column labeling each LIBS sample with its category. + +## 3.1 Data, Code, and Resources + +Here is a list data sets, codes, that are used in your work. Along with brief description and URL where they are located. + +1. supercam_libs_moc_loc.Rds is the Rds file containing the LIBS data [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds) + +2. libs_typed.Rds is the Rds file containing the LIBS data as well as a type column categorizing each sample [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/StudentData/libs_typed.Rds](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/StudentData/libs_typed.Rds) + +3. SupercamCalibrationTargets.pdf is a pdf containing information about the calibration targets used in the LIBS data. [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/SupercamCalibrationTargets.pdf](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/SupercamCalibrationTargets.pdf) + +4. v1_libs.Rds is the Rds file containing the LIBS data as well as my categorization that Doña put into a standardized format [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds) + + +I used the libs dataset with the standard deviation features, distances, and totals removed. I made sure that certain categories were numeric and added a new "type" column. + +Then, I added a description to each scct (calibration) target in the type column, which names the earth reference based on the pdf linked in this section. For example, the scct target containing "PMIFA0306" was typed "Olivine" + +I also labeled the targets with "aegis" in their names with AEGIS, these samples can be used the same as the other Mars LIBS samples, but it is noted that the measurement is taken using AEGIS, the rover's AI. So instead of the target being chosen intentionally by a scientist, it is chosen by the rover when it has extra resources to take a sample. + +From the analysts notebook, targets with "scam" in their names correspond to targets of other measurements, I went through the analysts notebook for these samples and added the other measurements that were taken at the same target into the type column. For example, the "villeplane_scam" target also had ZCam measurements taken at the same target, so I typed it "ZCAM-SCAM" + +I labeled two targets ("sei_________________" and "naakih______________"), with further descriptions because the analysts notebook had clear descriptions of what the target was intended to be sampling. + +All remaining samples are typed "other". + +```{r} +libs.df <- readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/Data/supercam_libs_moc_loc.Rds") + +#Drop the standard deviation features, the sum of the percentages, +#the distance, and the total frequencies +libs.df <- libs.df %>% + select(!(c(distance_mm,Tot.Em.,SiO2_stdev,TiO2_stdev,Al2O3_stdev,FeOT_stdev, + MgO_stdev,Na2O_stdev,CaO_stdev,K2O_stdev,Total))) + +# Convert the points to numeric +libs.df$point <- as.numeric(libs.df$point) +typedlibs<-cbind(libs.df[,1:4],"type"=0,libs.df[5:13]) +``` + +```{r} +targetlist<-c("tsrich0404","LCMB0006","LCA530106","PMIFS0505","TAPAG0206","PMIOR0507", + "PMIDN0302","PMIFA0306","PMIAN0106","PMIEN0602","TSERP0102","LBHVO20406", + "LJSC10304","LANKE0101","LSIDE0101","LJMN10106","NTE010301","NTE020106", + "NTE030106","NTE040106","NTE050301","SHERG02","TITANIUM","aegis", + "buzzard_rocks_scam","alfalfa_378_scam","chiniak_565_scam", + "garde_210_scam","guillaumes_168_scam","montpezat_350_scam","naltsos_scam", + "ouzel_falls_792_scam","pollock_knob_501_sca","rose_river_falls_sca", + "roubion_168_scam","villeplane_scam","atmo_mountain_637_sc", + "crosswind_lake_641_s") + +typelist<-c("BHVO-2 basalt and K sulfate mixture","Chert","Calcite","Ferrosilite", + "Fluoro-Chloro-Hydro Apatite","Orthoclase","Diopside","Olivine","Andesine", + "Enstatite","Serpentine/Talc","BHVO-2 standard basalt","Mars soil analog", + "Ankerite","Siderite","JMN-1 standard Mn nodule", + "Basalt dopped in minor elements - Cu, Zn", + "Basalt dopped in minor elements - Mn, Ba, Cr", + "Basalt dopped in minor elements - Zn", + "Basalt dopped in minor elements - Li, Sr", + "Basalt dopped in minor elements - Ni","Shergottite","Titanium","AEGIS", + "PIXL-SCAM","VISIR-Ramanx2-ZCAM-SCAM","AT-SCAM","AT-SCAM","PIXL-SCAM", + "PIXL-SCAM","PIXL-SCAM","AT-SCAM","ZCAM-SCAM","?-SCAM","ZCAM-PIXL-SCAM", + "ZCAM-SCAM","ZCAMMS-SCAM","ZCAM-SCAM") + +targettyped<-as.data.frame(cbind(targetlist,typelist),rownames=c(1)) + +for(i in 1:23){ + typedlibs<-typedlibs %>% + mutate(type = ifelse(grepl(targettyped[i,1],target,ignore.case=T), + targettyped[i,2], type)) +} + +for(i in 24:nrow(targettyped)){ + typedlibs<-typedlibs %>% + mutate(type= ifelse(grepl(targettyped[i,1], target,ignore.case=T) & type=="0", + targettyped[i,2],type)) +} + +typedlibs<-typedlibs %>% + mutate(type=ifelse(type=="0","other",type)) %>% + mutate(type= ifelse(target=="sei_________________", "other - fine soil",type)) %>% + mutate(type= ifelse(target=="naakih______________", "other - coarse soil",type)) + +kable(targettyped) +``` + +## 3.2 Contribution + +This section was sole work, except for Doña's standardization of my file into the v1_libs.Rds at the end. Later, in my ternary diagrams, I used the same seed and number of clusters as Aadi, so that my clustering would match his. + +## 3.3 Methods Description + +Now, we plot the average of each calibration/scct target, against the clustered mars LIBS data. The Mars data is separated from the reference data, we plot the reference data over the Mars data with labeled points corresponding to the table of reference types. + +```{r} +libs.matrix <- as.matrix(libs.df[,6:13]) + +libs.tern <- as.data.frame(libs.matrix) %>% + mutate(x=(SiO2+Al2O3)/100,y=(FeOT+MgO)/100,z=(CaO+Na2O+K2O)/100) %>% + select(-c(SiO2,Al2O3,FeOT,MgO,CaO,Na2O,K2O,TiO2)) + + +libs.tern<-cbind(libs.tern, "type"=typedlibs$type, "target"=typedlibs$target, + "shape"=typedlibs$type) + +libs.tern<-libs.tern %>% mutate(shape = ifelse(grepl("SCAM", type, ignore.case=T), + "other", shape)) %>% + mutate(shape = ifelse(grepl("other", type, ignore.case=T), + "other", shape)) %>% + mutate(shape = ifelse(grepl("scct", target, ignore.case=T), "scct", shape)) + +libs.tern$shape<-as.factor(libs.tern$shape) +``` + + +This is not specific analysis, moreso a recommendation that for future work, the scct values should be separated from the actual mars data. Previously, we had been analysing these targets as if they were mars data, when in fact they should be treated as reference or calibration data. + +When graphing the reference points on the ternary plot, ggrepel has a conflict with ggtern, so I had to manually add where the labels should go. If this issue with ggtern is fixed in the future, this can be simplified to use ggrepel for the labels. + +## 3.4 Result and Discussion + +```{r} +set.seed(1234) +km<-kmeans(libs.tern[,1:3],4) + +libs.tern<-as.data.frame(cbind(libs.tern,"cluster"=as.factor(km$cluster))) +``` + +```{r} +libs.tern.other<-libs.tern[libs.tern$shape=="other",] +libs.tern.scct<-libs.tern[libs.tern$shape=="scct",] + +#libs.scct.avg<-libs.tern.scct[, lapply(.SD, average), by= target] +libs.scct.avg<-aggregate(cbind(x,y,z) ~ type, data = libs.tern.scct, FUN = "mean") +libs.tern.other<-libs.tern.other[,c(1,2,3,7)] +libs.tern.other<-cbind(libs.tern.other,"type"=0) +libs.scct.avg<-cbind(libs.scct.avg[,2:4],"cluster"=libs.scct.avg$type,"type"=1) +libs.tern<-rbind(libs.scct.avg,libs.tern.other) +``` + +```{r} +libs.tern<-cbind(libs.tern,"num"=rownames(libs.tern),"legend"=0) +``` + +```{r} +libs.tern<-libs.tern %>% + mutate(legend=paste(num,cluster,sep=" ")) +``` + + +```{r} +libstern<-cbind(libs.tern,xend=0,yend=0,zend=0) +libstern<-libstern%>% + mutate(xend= ifelse(type=="1", x,xend)) %>% + mutate(yend= ifelse(type=="1", y,yend)) %>% + mutate(zend= ifelse(type=="1", z,zend)) +``` + +```{r} +for(i in c(1,10,11,13,17)){ + libstern[i,8:10]<-c(libstern[i,1]+0.06,libstern[i,2],libstern[i,3]-0.06) +} + +for(i in c(7)){ + libstern[i,8:10]<-c(libstern[i,1]+0.09,libstern[i,2],libstern[i,3]-0.09) +} + +for(i in c(15,20)){ + libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]+0.05,libstern[i,3]-0.05) +} + +for(i in c(3)){ + libstern[i,8:10]<-c(libstern[i,1]+0.02,libstern[i,2]+0.06,libstern[i,3]-0.08) +} + +for(i in c(14)){ + libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]-0.05,libstern[i,3]+0.05) +} + +for(i in c(4,16,19)){ + libstern[i,8:10]<-c(libstern[i,1]-0.08,libstern[i,2]+0.02,libstern[i,3]+0.06) +} + +for(i in c(2,9)){ + libstern[i,8:10]<-c(libstern[i,1]+0.03,libstern[i,2]-0.05,libstern[i,3]+0.03) +} + +for(i in c(6,8,12,18,22)){ + libstern[i,8:10]<-c(libstern[i,1]-0.06,libstern[i,2],libstern[i,3]+0.06) +} + +for(i in c(5)){ + libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]-0.09,libstern[i,3]+0.09) +} + +for(i in c(21)){ + libstern[i,8:10]<-c(libstern[i,1]-0.03,libstern[i,2]+0.07,libstern[i,3]-0.03) +} +``` + +```{r} +nv = -0.00 #Vertical Adjustment +pn = position_nudge_tern(y=nv,x=-nv,z=nv) + +ggtern(libstern, ggtern::aes(x=x,y=y,z=z)) + + geom_point(data=subset(libstern,type==0),aes(color=cluster),alpha=0.5) + + geom_point(data=subset(libstern,type==1),aes())+ + theme_rgbw() + + labs(title="Mars LIBS Data With Reference Samples Highlighted", + x="Si+Al", + y="Fe+Mg", + z="Ca+Na+K") + + theme(legend.position="bottom") + + geom_text(position=pn,data=subset(libstern,type==1), + aes(x=xend,y=yend,z=zend,label=num),check_overlap=T)+ + geom_segment(aes(x=x,xend = xend, y = y, yend=yend, z=z, zend=zend),size=0.3, + data = subset(libstern,type==1))+ + theme_nomask() +``` +This plot with the table of reference samples below allows us to examine our k-means clusters in the context of the earth reference samples. + +One of the primary results of looking at this graph is that many of the points that seemed to be outliers from the rest of the data are actually calibration targets. There are much fewer points in cluster 3, our smallest and most distinct cluster, when you consider that some of those original points are averaged into the reference points for calcite and Flouro-Chloro-Hydro Apatite. + +Also, it is interesting that much of cluster 2 has no earth references over it. This could indicate that samples like these are not common on earth, or it could indicate that the scientists deciding what earth references to include thought samples like those were unimportant. + +```{r} +kablelibstern<-cbind(point=libs.tern$num,"Description"=libs.tern$cluster) +kablelibstern<-kablelibstern[1:22,] + +kable(kablelibstern) +``` + +In the future, it would be helpful to be able to select only certain references, and to split these references into igneous and sedimentary categories so that when examining a specific igneous or sedimentary sample it is easy to see what references to compare it to. This is especially useful when examining these earth references in conjunction with the PIXL data, which can be plotted on a ternary plot as well. + +# 4.0 Finding 2: Matching LIBS and PIXL Data + +Matching the LIBS and PIXL data using their longitude and latitudes. + +## 4.1 Data, Code, and Resources + +Here is a list data sets, codes, that are used in your work. Along with brief description and URL where they are located. + +1. MatchingLIBSandPIXL.Rmd outlines a lot of the work behind matching the LIBS targets to PIXL samples. [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd) + +2. supercam_libs_moc_loc.Rds is the Rds file containing the LIBS data [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds) + +3. samples_pixl_wide.Rds is the Rds file containing all of the PIXL data [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/Data/samples_pixl_wide.Rds](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/Data/samples_pixl_wide.Rds) + +2. pixl_sol_coordinates.Rds contains the pixl data with the coordinates and sol metadata added from the analysts notebook [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/main/StudentData/pixl_sol_coordinates.Rds](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/main/StudentData/pixl_sol_coordinates.Rds). + +5. PIXL_LIBS_Combined.Rds is the final product of combining the LIBS and PIXL data created by Charlotte and I. [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentData/PIXL_LIBS_Combined.Rds](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentData/PIXL_LIBS_Combined.Rds) + +6. lahira-finalProjectF24.Rmd is the final notebook of Aadi Lahiri, which we get our earth scaling method from [https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/4d7fc8b60026364dbb4c571d7b3d6318a08f68bb/StudentNotebooks/Assignment08_FinalProjectNotebook/lahira-finalProjectF24.Rmd](https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/4d7fc8b60026364dbb4c571d7b3d6318a08f68bb/StudentNotebooks/Assignment08_FinalProjectNotebook/lahira-finalProjectF24.Rmd) + +## 4.2 Contribution + +I worked with Charlotte Peterson on this section, we matched the LIBS and PIXL data together. Then I graphed the ternary plot of the LIBS data colored by its closest PIXL sample. The earth scaling technique on my final heatmap was from Aadi Lahiri's notebook. + + +## 4.3 Methods Description + +First, columns with the PIXL coordinates and sol were added to the PIXL data. This information was found from the analyst's notebook. + +The final iteration of combined data is created in the MatchingLIBSandPIXL.Rmd file. The result of that file is the PIXL_LIBS_Combined.Rds, which contains every mars LIBS sample, so the scct/earth reference samples are removed. Each LIBS sample is listed with its closest PIXL sample, ignoring the atmospheric sample, and their distance in meters. + +The scct/earth reference samples were removed because their location has nothing to do with their data, the rover is taking a LIBS measurement of reference materials it carries with it. + +Even though some of the distances are farther than we would consider close or useful, ultimately, we chose not to remove any data points so that in the future people can make their own cutoff of what distance they consider to be significant or relevant. The recommendation we would make is to consider paired PIXL and LIBS samples that are within 7 meters of each other, as that is close to the range where the LIBS laser can reach. + +```{r} +pixllibs<-readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/StudentData/PIXL_LIBS_Combined.Rds") +``` + +```{r} +distancetable<-pixllibs[,c(1:4,6,7)] +distancetable<-distinct(distancetable) + +ggplot(data=distancetable, aes(x=Distance, group=PIXL.Abrasion, fill=PIXL.Abrasion)) + + ggtitle("Distances of LIBS Data to Nearest PIXL Abrasion")+ + geom_density(adjust=1.5, alpha=.4) +``` +Three of the PIXL Abrasions have a lot of points that are very close, but many others have data that is very spread. + +## 4.4 Result and Discussion + +Since the work of matching the LIBS and PIXL data has already been done, it is easy to import the combined RDS and convert that data into a dataframe to be used for a ternary diagram + +We can easily change what distance we would like to view + +```{r} +libs.tern <- as.data.frame(pixllibs) %>% + mutate(x=(LIBS.SiO2+LIBS.Al2O3)/100,y=(LIBS.FeOT+LIBS.MgO)/100,z=(LIBS.CaO+LIBS.Na2O+LIBS.K2O)/100) + +libs.tern<-libs.tern[,c(6,7,19,20,21)] +``` + + +```{r} +meters<- 100 + +ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) + + geom_point(data=subset(libs.tern, Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + + theme_rgbw() + + labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL Abrasion",sep=" "), + x="Si+Al", y="Fe+Mg",z="Ca+Na+K") + + theme(legend.position="right") + + guides(alpha="none",color=guide_legend(title="PIXL Abrasion")) + +meters<- 7 + +ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) + + geom_point(data=subset(libs.tern,Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + + theme_rgbw() + + labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL Abrasion",sep=" "), + x="Si+Al",y="Fe+Mg",z="Ca+Na+K") + + theme(legend.position="right") + + guides(alpha="none",color=guide_legend(title="PIXL Abrasion")) +``` + +We can see here that when interpreting the LIBS data within 7 meters of each PIXL abrasion, the data is not tightly clustered. For the most part, the data is just as spread as the entire data. + +```{r} +libs.heatmap<-pixllibs + +libs.heatmap<-libs.heatmap[libs.heatmap$Distance <= 7, ] + +libs.heatmap.mean<-aggregate(cbind(LIBS.SiO2,LIBS.TiO2,LIBS.Al2O3,LIBS.FeOT,LIBS.MgO,LIBS.CaO, + LIBS.Na2O,LIBS.K2O) ~ PIXL.Abrasion, data = libs.heatmap, FUN = "mean") +libs.heatmap.med<-aggregate(cbind(LIBS.SiO2,LIBS.TiO2,LIBS.Al2O3,LIBS.FeOT,LIBS.MgO, + LIBS.CaO,LIBS.Na2O,LIBS.K2O) ~ PIXL.Abrasion, data = libs.heatmap, FUN = "median") + +libs.heatmap.mean<-cbind(libs.heatmap.mean,"x"="mean") +libs.heatmap.mean$PIXL.Abrasion<-as.character(libs.heatmap.mean$PIXL.Abrasion) +libs.heatmap.mean<-libs.heatmap.mean %>% + mutate(x=paste(PIXL.Abrasion,x,sep=" ")) +rownames(libs.heatmap.mean)<-libs.heatmap.mean$x + +libs.heatmap.med<-cbind(libs.heatmap.med,"x"="median") +libs.heatmap.med$PIXL.Abrasion<-as.character(libs.heatmap.med$PIXL.Abrasion) +libs.heatmap.med<-libs.heatmap.med %>% + mutate(x=paste(PIXL.Abrasion,x,sep=" ")) + +rownames(libs.heatmap.med)<-libs.heatmap.med$x + +libs.heatmap<-rbind(libs.heatmap.mean,libs.heatmap.med) +libs.heatmap<-libs.heatmap[c(1,7,2,8,3,9,4,10,5,11,6,12),] + +pheatmap(libs.heatmap[,2:9],scale="column",cluster_rows=F,cluster_cols=F, + main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Column-Scaled") +pheatmap(libs.heatmap[,2:9],scale="none",cluster_rows=F,cluster_cols=F, + main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Unscaled") +``` +When looking at the heatmap, we can see more differences between the abrasions than are visible on the ternary plot. + +```{r} +libs_earth <- readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/Data/LIBS_training_set_quartiles.Rds") +earthheatmap <- libs.heatmap %>% select(c(LIBS.SiO2, LIBS.TiO2, LIBS.Al2O3, LIBS.FeOT, LIBS.MgO, + LIBS.CaO, LIBS.Na2O, LIBS.K2O,x)) %>% + rowwise() %>% mutate("Si"= (LIBS.SiO2-libs_earth[3,2])/(libs_earth[4,2] - libs_earth[2,2]), + "Ti"= (LIBS.TiO2-libs_earth[3,3])/(libs_earth[4,3] - libs_earth[2,3]), + "Al"= (LIBS.Al2O3-libs_earth[3,4])/(libs_earth[4,4] - libs_earth[2,4]), + "Fe"= (LIBS.FeOT-libs_earth[3,5])/(libs_earth[4,5] - libs_earth[2,5]), + "Mg"= (LIBS.MgO-libs_earth[3,6])/(libs_earth[4,6] - libs_earth[2,6]), + "Ca"= (LIBS.CaO-libs_earth[3,7])/(libs_earth[4,7] - libs_earth[2,7]), + "Na"= (LIBS.Na2O-libs_earth[3,8])/(libs_earth[4,8] - libs_earth[2,8]), + "K"= (LIBS.K2O-libs_earth[3,9])/(libs_earth[4,9] - libs_earth[2,9])) %>% + select(!c(LIBS.SiO2, LIBS.TiO2, LIBS.Al2O3, LIBS.FeOT, LIBS.MgO, LIBS.CaO, LIBS.Na2O, LIBS.K2O)) + +earthheatmap<-as.matrix(earthheatmap) +earthheatmap<-as.data.frame(earthheatmap) + +rownames(earthheatmap)<-earthheatmap$x + +#earthheatmap<-earthheatmap[,2:9] +earthheatmap[,2:9]<-sapply(earthheatmap[,2:9],as.numeric) + +pheatmap(earthheatmap[,2:9],scale="none",cluster_rows=F,cluster_cols=F, + main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Earth Scaled") +``` +Using Aadi's earth scaling technique, we can compare our two earlier heatmaps with an earth scaled heatmap. The main consistency between these heatmaps is high variation in the Mg or MgO columns. + +## 5.5 Conclusions, Limitations, and Future Work. + +More analysis of the LIBS data grouped by PIXL needs to be done. I think a Principle Component analysis could be interesting to help us see what factors break up the different groups. I also think a similarity analysis within the groups could be interesting. + +One potential issue with the combined LIBS and PIXL dataset, is that the LIBS data has some duplicate points with different latitude and longitudes. For example, the LIBS target "aegis_0907a_________" contains duplicate points with the same data with differing longitude and latitude values. This could indicate that there is more error than we think with the latitude and longitude of LIBS measurements. We are not 100% sure what the LIBS latitude and longitude is referring to (the laser or the rover), but this could indicate we understand it even less. This notebook runs on the assumption that the latitude and longitude refers to the location of the rover. + +# Bibliography +Provide a listing of references and other sources. + +* [Cousin21] Cousin, A., Sautter, V., Fabre, C., Dromart, G., Montagnac, G., Drouet, C., Meslin, P. Y., Gasnault, O., Beyssac, O., Bernard, S., Cloutis, E., Forni, O., Beck, P., Fouchet, T., Johnson, J. R., Lasue, J., Ollila, A. M., De Parseval, P., Gouy, S., & Caron, B. (2021). SuperCam calibration targets on board the perseverance rover: Fabrication and quantitative characterization. Spectrochimica Acta Part B: Atomic Spectroscopy, 106341. https://doi.org/10.1016/j.sab.2021.106341 + +* [Hamilton18] Hamilton NE, Ferry M (2018). “ggtern: Ternary Diagrams Using ggplot2.” _Journal of Statistical Software, Code Snippets_, *87*(3), + 1-17. doi:10.18637/jss.v087.c03 + +* [Hijmans24] Hijmans R (2024). _geosphere: Spherical Trigonometry_. R package version 1.5-20, + +```{r} +#citation("geosphere") +#citation("ggtern") +``` + + + diff --git a/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.html b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.html new file mode 100644 index 0000000..63a52a9 --- /dev/null +++ b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.html @@ -0,0 +1,2330 @@ + + + + + + + + + + + + + + + +Data Analytics Research Individual Final Project Report + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
+ +
+ + + + + + + +
+

DAR Project and Group Members

+
    +
  • Project name: Mars
  • +
  • Project team members: Charlotte Peterson, Doña Roberts, Xuanting +Wang, David Walczyk, Charlotte Newman, Dante Mwatibo, Nicolas Morawski, +CJ Marino, Aadi Lahiri, Ashton Compton
  • +
+
+
+

0.0 Preliminaries.

+

This report is generated from an R Markdown file that includes all +the R code necessary to produce the results described and embedded in +the report. Code blocks can be surpressed from output for readability +using the command code {R, echo=show} in the code block +header. If show <- FALSE the code block will be +surpressed; if show <- TRUE then the code will be +show.

+
# Set to TRUE to expand R code blocks; set to FALSE to collapse R code blocks 
+show <- TRUE
+

Executing this R notebook requires some subset of the following +packages:

+
    +
  • ggplot2
  • +
  • tidyverse
  • +
  • ggtern
  • +
  • knitr
  • +
  • pheatmap
  • +
+

These will be installed and loaded as necessary (code +suppressed).

+ +
+
+

1.0 Project Introduction

+

This project outlines my analysis of the Mars LIBS and PIXL data. It +largely revolves around data processing and organization

+
+
+

2.0 Organization of Report

+

This report is organized as follows:

+
    +
  • Section 3.0. Finding 1: Here we discuss the LIBS scct targets and +the importance of differentiating them in future analysis

  • +
  • Section 4.0: Finding 2: Here we discuss the connection between +the LIBS and PIXL data

  • +
  • Section 5.0 Overall conclusions and suggestions

  • +
+
+
+

3.0 Finding 1: Understanding LIBS Targets

+

I researched the meaning behind the LIBS target names, and +categorized the LIBS data into a few major categories. I created a new +Rds file that includes a column labeling each LIBS sample with its +category.

+
+

3.1 Data, Code, and Resources

+

Here is a list data sets, codes, that are used in your work. Along +with brief description and URL where they are located.

+
    +
  1. supercam_libs_moc_loc.Rds is the Rds file containing the LIBS +data https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds

  2. +
  3. libs_typed.Rds is the Rds file containing the LIBS data as well +as a type column categorizing each sample https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/StudentData/libs_typed.Rds

  4. +
  5. SupercamCalibrationTargets.pdf is a pdf containing information +about the calibration targets used in the LIBS data. https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/SupercamCalibrationTargets.pdf

  6. +
  7. v1_libs.Rds is the Rds file containing the LIBS data as well as +my categorization that Doña put into a standardized format https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds

  8. +
+

I used the libs dataset with the standard deviation features, +distances, and totals removed. I made sure that certain categories were +numeric and added a new “type” column.

+

Then, I added a description to each scct (calibration) target in the +type column, which names the earth reference based on the pdf linked in +this section. For example, the scct target containing “PMIFA0306” was +typed “Olivine”

+

I also labeled the targets with “aegis” in their names with AEGIS, +these samples can be used the same as the other Mars LIBS samples, but +it is noted that the measurement is taken using AEGIS, the rover’s AI. +So instead of the target being chosen intentionally by a scientist, it +is chosen by the rover when it has extra resources to take a sample.

+

From the analysts notebook, targets with “scam” in their names +correspond to targets of other measurements, I went through the analysts +notebook for these samples and added the other measurements that were +taken at the same target into the type column. For example, the +“villeplane_scam” target also had ZCam measurements taken at the same +target, so I typed it “ZCAM-SCAM”

+

I labeled two targets (“sei_________________” and +“naakih______________”), with further descriptions because the analysts +notebook had clear descriptions of what the target was intended to be +sampling.

+

All remaining samples are typed “other”.

+
libs.df <- readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/Data/supercam_libs_moc_loc.Rds")
+
+#Drop the standard deviation features, the sum of the percentages, 
+#the distance, and the total frequencies
+libs.df <- libs.df %>% 
+  select(!(c(distance_mm,Tot.Em.,SiO2_stdev,TiO2_stdev,Al2O3_stdev,FeOT_stdev,
+             MgO_stdev,Na2O_stdev,CaO_stdev,K2O_stdev,Total)))
+
+# Convert the points to numeric
+libs.df$point <- as.numeric(libs.df$point)
+typedlibs<-cbind(libs.df[,1:4],"type"=0,libs.df[5:13])
+
targetlist<-c("tsrich0404","LCMB0006","LCA530106","PMIFS0505","TAPAG0206","PMIOR0507",
+              "PMIDN0302","PMIFA0306","PMIAN0106","PMIEN0602","TSERP0102","LBHVO20406",
+              "LJSC10304","LANKE0101","LSIDE0101","LJMN10106","NTE010301","NTE020106",
+              "NTE030106","NTE040106","NTE050301","SHERG02","TITANIUM","aegis",
+              "buzzard_rocks_scam","alfalfa_378_scam","chiniak_565_scam",
+              "garde_210_scam","guillaumes_168_scam","montpezat_350_scam","naltsos_scam",
+              "ouzel_falls_792_scam","pollock_knob_501_sca","rose_river_falls_sca",
+              "roubion_168_scam","villeplane_scam","atmo_mountain_637_sc",
+              "crosswind_lake_641_s")
+
+typelist<-c("BHVO-2 basalt and K sulfate mixture","Chert","Calcite","Ferrosilite",
+            "Fluoro-Chloro-Hydro Apatite","Orthoclase","Diopside","Olivine","Andesine",
+            "Enstatite","Serpentine/Talc","BHVO-2 standard basalt","Mars soil analog",
+            "Ankerite","Siderite","JMN-1 standard Mn nodule",
+            "Basalt dopped in minor elements - Cu, Zn",
+            "Basalt dopped in minor elements - Mn, Ba, Cr",
+            "Basalt dopped in minor elements - Zn",
+            "Basalt dopped in minor elements - Li, Sr",
+            "Basalt dopped in minor elements - Ni","Shergottite","Titanium","AEGIS",
+            "PIXL-SCAM","VISIR-Ramanx2-ZCAM-SCAM","AT-SCAM","AT-SCAM","PIXL-SCAM",
+            "PIXL-SCAM","PIXL-SCAM","AT-SCAM","ZCAM-SCAM","?-SCAM","ZCAM-PIXL-SCAM",
+            "ZCAM-SCAM","ZCAMMS-SCAM","ZCAM-SCAM")
+
+targettyped<-as.data.frame(cbind(targetlist,typelist),rownames=c(1))
+
+for(i in 1:23){
+  typedlibs<-typedlibs %>%
+    mutate(type = ifelse(grepl(targettyped[i,1],target,ignore.case=T),
+                       targettyped[i,2], type))
+}
+
+for(i in 24:nrow(targettyped)){
+  typedlibs<-typedlibs %>%
+    mutate(type= ifelse(grepl(targettyped[i,1], target,ignore.case=T) & type=="0",
+                      targettyped[i,2],type))
+}
+
+typedlibs<-typedlibs %>%
+  mutate(type=ifelse(type=="0","other",type)) %>%
+  mutate(type= ifelse(target=="sei_________________", "other - fine soil",type)) %>%
+  mutate(type= ifelse(target=="naakih______________", "other - coarse soil",type))
+
+kable(targettyped)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
targetlisttypelist
tsrich0404BHVO-2 basalt and K sulfate mixture
LCMB0006Chert
LCA530106Calcite
PMIFS0505Ferrosilite
TAPAG0206Fluoro-Chloro-Hydro Apatite
PMIOR0507Orthoclase
PMIDN0302Diopside
PMIFA0306Olivine
PMIAN0106Andesine
PMIEN0602Enstatite
TSERP0102Serpentine/Talc
LBHVO20406BHVO-2 standard basalt
LJSC10304Mars soil analog
LANKE0101Ankerite
LSIDE0101Siderite
LJMN10106JMN-1 standard Mn nodule
NTE010301Basalt dopped in minor elements - Cu, Zn
NTE020106Basalt dopped in minor elements - Mn, Ba, Cr
NTE030106Basalt dopped in minor elements - Zn
NTE040106Basalt dopped in minor elements - Li, Sr
NTE050301Basalt dopped in minor elements - Ni
SHERG02Shergottite
TITANIUMTitanium
aegisAEGIS
buzzard_rocks_scamPIXL-SCAM
alfalfa_378_scamVISIR-Ramanx2-ZCAM-SCAM
chiniak_565_scamAT-SCAM
garde_210_scamAT-SCAM
guillaumes_168_scamPIXL-SCAM
montpezat_350_scamPIXL-SCAM
naltsos_scamPIXL-SCAM
ouzel_falls_792_scamAT-SCAM
pollock_knob_501_scaZCAM-SCAM
rose_river_falls_sca?-SCAM
roubion_168_scamZCAM-PIXL-SCAM
villeplane_scamZCAM-SCAM
atmo_mountain_637_scZCAMMS-SCAM
crosswind_lake_641_sZCAM-SCAM
+
+
+

3.2 Contribution

+

This section was sole work, except for Doña’s standardization of my +file into the v1_libs.Rds at the end. Later, in my ternary diagrams, I +used the same seed and number of clusters as Aadi, so that my clustering +would match his.

+
+
+

3.3 Methods Description

+

Now, we plot the average of each calibration/scct target, against the +clustered mars LIBS data. The Mars data is separated from the reference +data, we plot the reference data over the Mars data with labeled points +corresponding to the table of reference types.

+
libs.matrix <- as.matrix(libs.df[,6:13]) 
+
+libs.tern <- as.data.frame(libs.matrix) %>%
+  mutate(x=(SiO2+Al2O3)/100,y=(FeOT+MgO)/100,z=(CaO+Na2O+K2O)/100) %>%
+  select(-c(SiO2,Al2O3,FeOT,MgO,CaO,Na2O,K2O,TiO2))
+
+
+libs.tern<-cbind(libs.tern, "type"=typedlibs$type, "target"=typedlibs$target, 
+                 "shape"=typedlibs$type)
+
+libs.tern<-libs.tern %>% mutate(shape = ifelse(grepl("SCAM", type, ignore.case=T),
+                       "other", shape)) %>%
+  mutate(shape = ifelse(grepl("other", type, ignore.case=T),
+                       "other", shape)) %>%
+  mutate(shape = ifelse(grepl("scct", target, ignore.case=T), "scct", shape))
+
+libs.tern$shape<-as.factor(libs.tern$shape)
+

This is not specific analysis, moreso a recommendation that for +future work, the scct values should be separated from the actual mars +data. Previously, we had been analysing these targets as if they were +mars data, when in fact they should be treated as reference or +calibration data.

+

When graphing the reference points on the ternary plot, ggrepel has a +conflict with ggtern, so I had to manually add where the labels should +go. If this issue with ggtern is fixed in the future, this can be +simplified to use ggrepel for the labels.

+
+
+

3.4 Result and Discussion

+
set.seed(1234)
+km<-kmeans(libs.tern[,1:3],4)
+
+libs.tern<-as.data.frame(cbind(libs.tern,"cluster"=as.factor(km$cluster)))
+
libs.tern.other<-libs.tern[libs.tern$shape=="other",]
+libs.tern.scct<-libs.tern[libs.tern$shape=="scct",]
+
+#libs.scct.avg<-libs.tern.scct[, lapply(.SD, average), by= target]
+libs.scct.avg<-aggregate(cbind(x,y,z) ~ type, data = libs.tern.scct, FUN = "mean")
+libs.tern.other<-libs.tern.other[,c(1,2,3,7)]
+libs.tern.other<-cbind(libs.tern.other,"type"=0)
+libs.scct.avg<-cbind(libs.scct.avg[,2:4],"cluster"=libs.scct.avg$type,"type"=1)
+libs.tern<-rbind(libs.scct.avg,libs.tern.other)
+
libs.tern<-cbind(libs.tern,"num"=rownames(libs.tern),"legend"=0)
+
libs.tern<-libs.tern %>% 
+  mutate(legend=paste(num,cluster,sep="  "))
+
libstern<-cbind(libs.tern,xend=0,yend=0,zend=0)
+libstern<-libstern%>% 
+  mutate(xend= ifelse(type=="1", x,xend)) %>%
+  mutate(yend= ifelse(type=="1", y,yend)) %>%
+  mutate(zend= ifelse(type=="1", z,zend))
+
for(i in c(1,10,11,13,17)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.06,libstern[i,2],libstern[i,3]-0.06)
+}
+
+for(i in c(7)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.09,libstern[i,2],libstern[i,3]-0.09)
+}
+
+for(i in c(15,20)){
+  libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]+0.05,libstern[i,3]-0.05)
+}
+
+for(i in c(3)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.02,libstern[i,2]+0.06,libstern[i,3]-0.08)
+}
+
+for(i in c(14)){
+  libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]-0.05,libstern[i,3]+0.05)
+}
+
+for(i in c(4,16,19)){
+  libstern[i,8:10]<-c(libstern[i,1]-0.08,libstern[i,2]+0.02,libstern[i,3]+0.06)
+}
+
+for(i in c(2,9)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.03,libstern[i,2]-0.05,libstern[i,3]+0.03)
+}
+
+for(i in c(6,8,12,18,22)){
+  libstern[i,8:10]<-c(libstern[i,1]-0.06,libstern[i,2],libstern[i,3]+0.06)
+}
+
+for(i in c(5)){
+  libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]-0.09,libstern[i,3]+0.09)
+}
+
+for(i in c(21)){
+  libstern[i,8:10]<-c(libstern[i,1]-0.03,libstern[i,2]+0.07,libstern[i,3]-0.03)
+}
+
nv = -0.00  #Vertical Adjustment
+pn = position_nudge_tern(y=nv,x=-nv,z=nv)
+
+ggtern(libstern, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=subset(libstern,type==0),aes(color=cluster),alpha=0.5) + 
+  geom_point(data=subset(libstern,type==1),aes())+
+  theme_rgbw() + 
+  labs(title="Mars LIBS Data With Reference Samples Highlighted",
+       x="Si+Al",
+       y="Fe+Mg",
+       z="Ca+Na+K") + 
+  theme(legend.position="bottom") +
+  geom_text(position=pn,data=subset(libstern,type==1),
+            aes(x=xend,y=yend,z=zend,label=num),check_overlap=T)+
+  geom_segment(aes(x=x,xend = xend, y = y, yend=yend, z=z, zend=zend),size=0.3,
+               data = subset(libstern,type==1))+
+  theme_nomask()
+
## Warning in geom_text(position = pn, data = subset(libstern, type == 1), :
+## Ignoring unknown aesthetics: z
+
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
+## ℹ Please use `linewidth` instead.
+## This warning is displayed once every 8 hours.
+## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
+## generated.
+
## Warning in geom_segment(aes(x = x, xend = xend, y = y, yend = yend, z = z, :
+## Ignoring unknown aesthetics: z and zend
+
## Warning in acomp(data[, self$required_aes]): Negative values in composition are
+## used as detection limits
+

+This plot with the table of reference samples below allows us to examine +our k-means clusters in the context of the earth reference samples.

+

One of the primary results of looking at this graph is that many of +the points that seemed to be outliers from the rest of the data are +actually calibration targets. There are much fewer points in cluster 3, +our smallest and most distinct cluster, when you consider that some of +those original points are averaged into the reference points for calcite +and Flouro-Chloro-Hydro Apatite.

+

Also, it is interesting that much of cluster 2 has no earth +references over it. This could indicate that samples like these are not +common on earth, or it could indicate that the scientists deciding what +earth references to include thought samples like those were +unimportant.

+
kablelibstern<-cbind(point=libs.tern$num,"Description"=libs.tern$cluster)
+kablelibstern<-kablelibstern[1:22,]
+
+kable(kablelibstern)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
pointDescription
1Andesine
2Ankerite
3Basalt dopped in minor elements - Cu, Zn
4Basalt dopped in minor elements - Li, Sr
5Basalt dopped in minor elements - Mn, Ba, Cr
6Basalt dopped in minor elements - Ni
7Basalt dopped in minor elements - Zn
8BHVO-2 basalt and K sulfate mixture
9BHVO-2 standard basalt
10Calcite
11Chert
12Diopside
13Enstatite
14Ferrosilite
15Fluoro-Chloro-Hydro Apatite
16JMN-1 standard Mn nodule
17Mars soil analog
18Olivine
19Orthoclase
20Serpentine/Talc
21Shergottite
22Siderite
+

In the future, it would be helpful to be able to select only certain +references, and to split these references into igneous and sedimentary +categories so that when examining a specific igneous or sedimentary +sample it is easy to see what references to compare it to. This is +especially useful when examining these earth references in conjunction +with the PIXL data, which can be plotted on a ternary plot as well.

+
+
+
+

4.0 Finding 2: Matching LIBS and PIXL Data

+

Matching the LIBS and PIXL data using their longitude and +latitudes.

+
+

4.1 Data, Code, and Resources

+

Here is a list data sets, codes, that are used in your work. Along +with brief description and URL where they are located.

+
    +
  1. MatchingLIBSandPIXL.Rmd outlines a lot of the work behind +matching the LIBS targets to PIXL samples. https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd

  2. +
  3. supercam_libs_moc_loc.Rds is the Rds file containing the LIBS +data https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds

  4. +
  5. samples_pixl_wide.Rds is the Rds file containing all of the PIXL +data https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/Data/samples_pixl_wide.Rds

  6. +
  7. pixl_sol_coordinates.Rds contains the pixl data with the +coordinates and sol metadata added from the analysts notebook https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/main/StudentData/pixl_sol_coordinates.Rds.

  8. +
  9. PIXL_LIBS_Combined.Rds is the final product of combining the LIBS +and PIXL data created by Charlotte and I. https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentData/PIXL_LIBS_Combined.Rds

  10. +
  11. lahira-finalProjectF24.Rmd is the final notebook of Aadi Lahiri, +which we get our earth scaling method from https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/4d7fc8b60026364dbb4c571d7b3d6318a08f68bb/StudentNotebooks/Assignment08_FinalProjectNotebook/lahira-finalProjectF24.Rmd

  12. +
+
+
+

4.2 Contribution

+

I worked with Charlotte Peterson on this section, we matched the LIBS +and PIXL data together. Then I graphed the ternary plot of the LIBS data +colored by its closest PIXL sample. The earth scaling technique on my +final heatmap was from Aadi Lahiri’s notebook.

+
+
+

4.3 Methods Description

+

First, columns with the PIXL coordinates and sol were added to the +PIXL data. This information was found from the analyst’s notebook.

+

The final iteration of combined data is created in the +MatchingLIBSandPIXL.Rmd file. The result of that file is the +PIXL_LIBS_Combined.Rds, which contains every mars LIBS sample, so the +scct/earth reference samples are removed. Each LIBS sample is listed +with its closest PIXL sample, ignoring the atmospheric sample, and their +distance in meters.

+

The scct/earth reference samples were removed because their location +has nothing to do with their data, the rover is taking a LIBS +measurement of reference materials it carries with it.

+

Even though some of the distances are farther than we would consider +close or useful, ultimately, we chose not to remove any data points so +that in the future people can make their own cutoff of what distance +they consider to be significant or relevant. The recommendation we would +make is to consider paired PIXL and LIBS samples that are within 7 +meters of each other, as that is close to the range where the LIBS laser +can reach.

+
pixllibs<-readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/StudentData/PIXL_LIBS_Combined.Rds")
+
distancetable<-pixllibs[,c(1:4,6,7)]
+distancetable<-distinct(distancetable)
+
+ggplot(data=distancetable, aes(x=Distance, group=PIXL.Abrasion, fill=PIXL.Abrasion)) +
+  ggtitle("Distances of LIBS Data to Nearest PIXL Abrasion")+
+    geom_density(adjust=1.5, alpha=.4)
+

+Three of the PIXL Abrasions have a lot of points that are very close, +but many others have data that is very spread.

+
+
+

4.4 Result and Discussion

+

Since the work of matching the LIBS and PIXL data has already been +done, it is easy to import the combined RDS and convert that data into a +dataframe to be used for a ternary diagram

+

We can easily change what distance we would like to view

+
libs.tern <- as.data.frame(pixllibs) %>%
+  mutate(x=(LIBS.SiO2+LIBS.Al2O3)/100,y=(LIBS.FeOT+LIBS.MgO)/100,z=(LIBS.CaO+LIBS.Na2O+LIBS.K2O)/100)
+
+libs.tern<-libs.tern[,c(6,7,19,20,21)]
+
meters<- 100
+
+ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=subset(libs.tern, Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + 
+  theme_rgbw() + 
+  labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL Abrasion",sep=" "),
+       x="Si+Al", y="Fe+Mg",z="Ca+Na+K") +
+  theme(legend.position="right") + 
+  guides(alpha="none",color=guide_legend(title="PIXL Abrasion"))
+

+
meters<- 7
+
+ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=subset(libs.tern,Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + 
+  theme_rgbw() + 
+  labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL Abrasion",sep=" "),
+       x="Si+Al",y="Fe+Mg",z="Ca+Na+K") +
+  theme(legend.position="right") + 
+  guides(alpha="none",color=guide_legend(title="PIXL Abrasion"))
+

+

We can see here that when interpreting the LIBS data within 7 meters +of each PIXL abrasion, the data is not tightly clustered. For the most +part, the data is just as spread as the entire data.

+
libs.heatmap<-pixllibs
+
+libs.heatmap<-libs.heatmap[libs.heatmap$Distance <= 7, ]
+
+libs.heatmap.mean<-aggregate(cbind(LIBS.SiO2,LIBS.TiO2,LIBS.Al2O3,LIBS.FeOT,LIBS.MgO,LIBS.CaO,
+    LIBS.Na2O,LIBS.K2O) ~ PIXL.Abrasion, data = libs.heatmap, FUN = "mean")
+libs.heatmap.med<-aggregate(cbind(LIBS.SiO2,LIBS.TiO2,LIBS.Al2O3,LIBS.FeOT,LIBS.MgO,
+    LIBS.CaO,LIBS.Na2O,LIBS.K2O) ~ PIXL.Abrasion, data = libs.heatmap, FUN = "median")
+
+libs.heatmap.mean<-cbind(libs.heatmap.mean,"x"="mean")
+libs.heatmap.mean$PIXL.Abrasion<-as.character(libs.heatmap.mean$PIXL.Abrasion)
+libs.heatmap.mean<-libs.heatmap.mean %>%
+  mutate(x=paste(PIXL.Abrasion,x,sep=" "))
+rownames(libs.heatmap.mean)<-libs.heatmap.mean$x
+
+libs.heatmap.med<-cbind(libs.heatmap.med,"x"="median")
+libs.heatmap.med$PIXL.Abrasion<-as.character(libs.heatmap.med$PIXL.Abrasion)
+libs.heatmap.med<-libs.heatmap.med %>%
+  mutate(x=paste(PIXL.Abrasion,x,sep=" "))
+
+rownames(libs.heatmap.med)<-libs.heatmap.med$x
+
+libs.heatmap<-rbind(libs.heatmap.mean,libs.heatmap.med)
+libs.heatmap<-libs.heatmap[c(1,7,2,8,3,9,4,10,5,11,6,12),]
+
+pheatmap(libs.heatmap[,2:9],scale="column",cluster_rows=F,cluster_cols=F,
+    main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Column-Scaled")
+

+
pheatmap(libs.heatmap[,2:9],scale="none",cluster_rows=F,cluster_cols=F,
+    main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Unscaled")
+

+When looking at the heatmap, we can see more differences between the +abrasions than are visible on the ternary plot.

+
libs_earth <- readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/Data/LIBS_training_set_quartiles.Rds")
+earthheatmap <- libs.heatmap %>% select(c(LIBS.SiO2, LIBS.TiO2, LIBS.Al2O3, LIBS.FeOT, LIBS.MgO, 
+    LIBS.CaO, LIBS.Na2O, LIBS.K2O,x)) %>% 
+  rowwise() %>% mutate("Si"= (LIBS.SiO2-libs_earth[3,2])/(libs_earth[4,2] - libs_earth[2,2]), 
+                       "Ti"= (LIBS.TiO2-libs_earth[3,3])/(libs_earth[4,3] - libs_earth[2,3]),
+                       "Al"= (LIBS.Al2O3-libs_earth[3,4])/(libs_earth[4,4] - libs_earth[2,4]),
+                       "Fe"= (LIBS.FeOT-libs_earth[3,5])/(libs_earth[4,5] - libs_earth[2,5]),
+                       "Mg"= (LIBS.MgO-libs_earth[3,6])/(libs_earth[4,6] - libs_earth[2,6]),
+                       "Ca"= (LIBS.CaO-libs_earth[3,7])/(libs_earth[4,7] - libs_earth[2,7]),
+                       "Na"= (LIBS.Na2O-libs_earth[3,8])/(libs_earth[4,8] - libs_earth[2,8]),
+                       "K"= (LIBS.K2O-libs_earth[3,9])/(libs_earth[4,9] - libs_earth[2,9])) %>%
+  select(!c(LIBS.SiO2, LIBS.TiO2, LIBS.Al2O3, LIBS.FeOT, LIBS.MgO, LIBS.CaO, LIBS.Na2O, LIBS.K2O))
+
+earthheatmap<-as.matrix(earthheatmap)
+earthheatmap<-as.data.frame(earthheatmap)
+
+rownames(earthheatmap)<-earthheatmap$x
+
+#earthheatmap<-earthheatmap[,2:9]
+earthheatmap[,2:9]<-sapply(earthheatmap[,2:9],as.numeric)
+
+pheatmap(earthheatmap[,2:9],scale="none",cluster_rows=F,cluster_cols=F,
+    main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Earth Scaled")
+

+Using Aadi’s earth scaling technique, we can compare our two earlier +heatmaps with an earth scaled heatmap. The main consistency between +these heatmaps is high variation in the Mg or MgO columns.

+
+
+

5.5 Conclusions, Limitations, and Future Work.

+

More analysis of the LIBS data grouped by PIXL needs to be done. I +think a Principle Component analysis could be interesting to help us see +what factors break up the different groups. I also think a similarity +analysis within the groups could be interesting.

+

One potential issue with the combined LIBS and PIXL dataset, is that +the LIBS data has some duplicate points with different latitude and +longitudes. For example, the LIBS target “aegis_0907a_________” contains +duplicate points with the same data with differing longitude and +latitude values. This could indicate that there is more error than we +think with the latitude and longitude of LIBS measurements. We are not +100% sure what the LIBS latitude and longitude is referring to (the +laser or the rover), but this could indicate we understand it even less. +This notebook runs on the assumption that the latitude and longitude +refers to the location of the rover.

+
+
+
+

Bibliography

+

Provide a listing of references and other sources.

+
    +
  • [Cousin21] Cousin, A., Sautter, V., Fabre, C., Dromart, G., +Montagnac, G., Drouet, C., Meslin, P. Y., Gasnault, O., Beyssac, O., +Bernard, S., Cloutis, E., Forni, O., Beck, P., Fouchet, T., Johnson, J. +R., Lasue, J., Ollila, A. M., De Parseval, P., Gouy, S., & Caron, B. +(2021). SuperCam calibration targets on board the perseverance rover: +Fabrication and quantitative characterization. Spectrochimica Acta Part +B: Atomic Spectroscopy, 106341. https://doi.org/10.1016/j.sab.2021.106341

  • +
  • [Hamilton18] Hamilton NE, Ferry M (2018). “ggtern: Ternary +Diagrams Using ggplot2.” Journal of Statistical Software, Code +Snippets, 87(3), 1-17. doi:10.18637/jss.v087.c03 https://doi.org/10.18637/jss.v087.c03

  • +
  • [Hijmans24] Hijmans R (2024). geosphere: Spherical +Trigonometry. R package version 1.5-20, https://CRAN.R-project.org/package=geosphere

  • +
+
#citation("geosphere")
+#citation("ggtern")
+
+ + + +
+
+ +
+ + + + + + + + + + + + + + + + diff --git a/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.nb.html b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.nb.html new file mode 100644 index 0000000..a5f7e3d --- /dev/null +++ b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.nb.html @@ -0,0 +1,2609 @@ + + + + + + + + + + + + + + + +Data Analytics Research Individual Final Project Report + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+

DAR Project and Group Members

+
    +
  • Project name: Mars
  • +
  • Project team members: Charlotte Peterson, Doña Roberts, Xuanting +Wang, David Walczyk, Charlotte Newman, Dante Mwatibo, Nicolas Morawski, +CJ Marino, Aadi Lahiri, Ashton Compton
  • +
+
+
+

0.0 Preliminaries.

+

This report is generated from an R Markdown file that includes all +the R code necessary to produce the results described and embedded in +the report. Code blocks can be surpressed from output for readability +using the command code {R, echo=show} in the code block +header. If show <- FALSE the code block will be +surpressed; if show <- TRUE then the code will be +show.

+ + + +
# Set to TRUE to expand R code blocks; set to FALSE to collapse R code blocks 
+show <- TRUE
+ + + +

Executing this R notebook requires some subset of the following +packages:

+
    +
  • ggplot2
  • +
  • tidyverse
  • +
  • ggtern
  • +
  • knitr
  • +
  • pheatmap
  • +
+

These will be installed and loaded as necessary (code +suppressed).

+ + + +
+
+

1.0 Project Introduction

+

This project outlines my analysis of the Mars LIBS and PIXL data. It +largely revolves around data processing and organization

+
+
+

2.0 Organization of Report

+

This report is organized as follows:

+
    +
  • Section 3.0. Finding 1: Here we discuss the LIBS scct targets and +the importance of differentiating them in future analysis

  • +
  • Section 4.0: Finding 2: Here we discuss the connection between +the LIBS and PIXL data

  • +
  • Section 5.0 Overall conclusions and suggestions

  • +
+
+
+

3.0 Finding 1: Understanding LIBS Targets

+

I researched the meaning behind the LIBS target names, and +categorized the LIBS data into a few major categories. I created a new +Rds file that includes a column labeling each LIBS sample with its +category.

+
+

3.1 Data, Code, and Resources

+

Here is a list data sets, codes, that are used in your work. Along +with brief description and URL where they are located.

+
    +
  1. supercam_libs_moc_loc.Rds is the Rds file containing the LIBS +data https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds

  2. +
  3. libs_typed.Rds is the Rds file containing the LIBS data as well +as a type column categorizing each sample https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/StudentData/libs_typed.Rds

  4. +
  5. SupercamCalibrationTargets.pdf is a pdf containing information +about the calibration targets used in the LIBS data. https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentNotebooks/Assignment07_DraftFinalProjectNotebook/SupercamCalibrationTargets.pdf

  6. +
  7. v1_libs.Rds is the Rds file containing the LIBS data as well as +my categorization that Doña put into a standardized format https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds

  8. +
+

I used the libs dataset with the standard deviation features, +distances, and totals removed. I made sure that certain categories were +numeric and added a new “type” column.

+

Then, I added a description to each scct (calibration) target in the +type column, which names the earth reference based on the pdf linked in +this section. For example, the scct target containing “PMIFA0306” was +typed “Olivine”

+

I also labeled the targets with “aegis” in their names with AEGIS, +these samples can be used the same as the other Mars LIBS samples, but +it is noted that the measurement is taken using AEGIS, the rover’s AI. +So instead of the target being chosen intentionally by a scientist, it +is chosen by the rover when it has extra resources to take a sample.

+

From the analysts notebook, targets with “scam” in their names +correspond to targets of other measurements, I went through the analysts +notebook for these samples and added the other measurements that were +taken at the same target into the type column. For example, the +“villeplane_scam” target also had ZCam measurements taken at the same +target, so I typed it “ZCAM-SCAM”

+

I labeled two targets (“sei_________________” and +“naakih______________”), with further descriptions because the analysts +notebook had clear descriptions of what the target was intended to be +sampling.

+

All remaining samples are typed “other”.

+ + + +
libs.df <- readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/Data/supercam_libs_moc_loc.Rds")
+
+#Drop the standard deviation features, the sum of the percentages, 
+#the distance, and the total frequencies
+libs.df <- libs.df %>% 
+  select(!(c(distance_mm,Tot.Em.,SiO2_stdev,TiO2_stdev,Al2O3_stdev,FeOT_stdev,
+             MgO_stdev,Na2O_stdev,CaO_stdev,K2O_stdev,Total)))
+
+# Convert the points to numeric
+libs.df$point <- as.numeric(libs.df$point)
+typedlibs<-cbind(libs.df[,1:4],"type"=0,libs.df[5:13])
+ + + + + + +
targetlist<-c("tsrich0404","LCMB0006","LCA530106","PMIFS0505","TAPAG0206","PMIOR0507",
+              "PMIDN0302","PMIFA0306","PMIAN0106","PMIEN0602","TSERP0102","LBHVO20406",
+              "LJSC10304","LANKE0101","LSIDE0101","LJMN10106","NTE010301","NTE020106",
+              "NTE030106","NTE040106","NTE050301","SHERG02","TITANIUM","aegis",
+              "buzzard_rocks_scam","alfalfa_378_scam","chiniak_565_scam",
+              "garde_210_scam","guillaumes_168_scam","montpezat_350_scam","naltsos_scam",
+              "ouzel_falls_792_scam","pollock_knob_501_sca","rose_river_falls_sca",
+              "roubion_168_scam","villeplane_scam","atmo_mountain_637_sc",
+              "crosswind_lake_641_s")
+
+typelist<-c("BHVO-2 basalt and K sulfate mixture","Chert","Calcite","Ferrosilite",
+            "Fluoro-Chloro-Hydro Apatite","Orthoclase","Diopside","Olivine","Andesine",
+            "Enstatite","Serpentine/Talc","BHVO-2 standard basalt","Mars soil analog",
+            "Ankerite","Siderite","JMN-1 standard Mn nodule",
+            "Basalt dopped in minor elements - Cu, Zn",
+            "Basalt dopped in minor elements - Mn, Ba, Cr",
+            "Basalt dopped in minor elements - Zn",
+            "Basalt dopped in minor elements - Li, Sr",
+            "Basalt dopped in minor elements - Ni","Shergottite","Titanium","AEGIS",
+            "PIXL-SCAM","VISIR-Ramanx2-ZCAM-SCAM","AT-SCAM","AT-SCAM","PIXL-SCAM",
+            "PIXL-SCAM","PIXL-SCAM","AT-SCAM","ZCAM-SCAM","?-SCAM","ZCAM-PIXL-SCAM",
+            "ZCAM-SCAM","ZCAMMS-SCAM","ZCAM-SCAM")
+
+targettyped<-as.data.frame(cbind(targetlist,typelist),rownames=c(1))
+
+for(i in 1:23){
+  typedlibs<-typedlibs %>%
+    mutate(type = ifelse(grepl(targettyped[i,1],target,ignore.case=T),
+                       targettyped[i,2], type))
+}
+
+for(i in 24:nrow(targettyped)){
+  typedlibs<-typedlibs %>%
+    mutate(type= ifelse(grepl(targettyped[i,1], target,ignore.case=T) & type=="0",
+                      targettyped[i,2],type))
+}
+
+typedlibs<-typedlibs %>%
+  mutate(type=ifelse(type=="0","other",type)) %>%
+  mutate(type= ifelse(target=="sei_________________", "other - fine soil",type)) %>%
+  mutate(type= ifelse(target=="naakih______________", "other - coarse soil",type))
+
+kable(targettyped)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
targetlisttypelist
tsrich0404BHVO-2 basalt and K sulfate mixture
LCMB0006Chert
LCA530106Calcite
PMIFS0505Ferrosilite
TAPAG0206Fluoro-Chloro-Hydro Apatite
PMIOR0507Orthoclase
PMIDN0302Diopside
PMIFA0306Olivine
PMIAN0106Andesine
PMIEN0602Enstatite
TSERP0102Serpentine/Talc
LBHVO20406BHVO-2 standard basalt
LJSC10304Mars soil analog
LANKE0101Ankerite
LSIDE0101Siderite
LJMN10106JMN-1 standard Mn nodule
NTE010301Basalt dopped in minor elements - Cu, Zn
NTE020106Basalt dopped in minor elements - Mn, Ba, Cr
NTE030106Basalt dopped in minor elements - Zn
NTE040106Basalt dopped in minor elements - Li, Sr
NTE050301Basalt dopped in minor elements - Ni
SHERG02Shergottite
TITANIUMTitanium
aegisAEGIS
buzzard_rocks_scamPIXL-SCAM
alfalfa_378_scamVISIR-Ramanx2-ZCAM-SCAM
chiniak_565_scamAT-SCAM
garde_210_scamAT-SCAM
guillaumes_168_scamPIXL-SCAM
montpezat_350_scamPIXL-SCAM
naltsos_scamPIXL-SCAM
ouzel_falls_792_scamAT-SCAM
pollock_knob_501_scaZCAM-SCAM
rose_river_falls_sca?-SCAM
roubion_168_scamZCAM-PIXL-SCAM
villeplane_scamZCAM-SCAM
atmo_mountain_637_scZCAMMS-SCAM
crosswind_lake_641_sZCAM-SCAM
+ + + + + + +
+
+

3.2 Contribution

+

This section was sole work, except for Doña’s standardization of my +file into the v1_libs.Rds at the end. Later, in my ternary diagrams, I +used the same seed and number of clusters as Aadi, so that my clustering +would match his.

+
+
+

3.3 Methods Description

+

Now, we plot the average of each calibration/scct target, against the +clustered mars LIBS data. The Mars data is separated from the reference +data, we plot the reference data over the Mars data with labeled points +corresponding to the table of reference types.

+ + + +
libs.matrix <- as.matrix(libs.df[,6:13]) 
+
+libs.tern <- as.data.frame(libs.matrix) %>%
+  mutate(x=(SiO2+Al2O3)/100,y=(FeOT+MgO)/100,z=(CaO+Na2O+K2O)/100) %>%
+  select(-c(SiO2,Al2O3,FeOT,MgO,CaO,Na2O,K2O,TiO2))
+
+
+libs.tern<-cbind(libs.tern, "type"=typedlibs$type, "target"=typedlibs$target, 
+                 "shape"=typedlibs$type)
+
+libs.tern<-libs.tern %>% mutate(shape = ifelse(grepl("SCAM", type, ignore.case=T),
+                       "other", shape)) %>%
+  mutate(shape = ifelse(grepl("other", type, ignore.case=T),
+                       "other", shape)) %>%
+  mutate(shape = ifelse(grepl("scct", target, ignore.case=T), "scct", shape))
+
+libs.tern$shape<-as.factor(libs.tern$shape)
+ + + +

This is not specific analysis, moreso a recommendation that for +future work, the scct values should be separated from the actual mars +data. Previously, we had been analysing these targets as if they were +mars data, when in fact they should be treated as reference or +calibration data.

+

When graphing the reference points on the ternary plot, ggrepel has a +conflict with ggtern, so I had to manually add where the labels should +go. If this issue with ggtern is fixed in the future, this can be +simplified to use ggrepel for the labels.

+
+
+

3.4 Result and Discussion

+ + + +
set.seed(1234)
+km<-kmeans(libs.tern[,1:3],4)
+
+libs.tern<-as.data.frame(cbind(libs.tern,"cluster"=as.factor(km$cluster)))
+ + + + + + +
libs.tern.other<-libs.tern[libs.tern$shape=="other",]
+libs.tern.scct<-libs.tern[libs.tern$shape=="scct",]
+
+#libs.scct.avg<-libs.tern.scct[, lapply(.SD, average), by= target]
+libs.scct.avg<-aggregate(cbind(x,y,z) ~ type, data = libs.tern.scct, FUN = "mean")
+libs.tern.other<-libs.tern.other[,c(1,2,3,7)]
+libs.tern.other<-cbind(libs.tern.other,"type"=0)
+libs.scct.avg<-cbind(libs.scct.avg[,2:4],"cluster"=libs.scct.avg$type,"type"=1)
+libs.tern<-rbind(libs.scct.avg,libs.tern.other)
+ + + + + + +
libs.tern<-cbind(libs.tern,"num"=rownames(libs.tern),"legend"=0)
+ + + + + + +
libs.tern<-libs.tern %>% 
+  mutate(legend=paste(num,cluster,sep="  "))
+ + + + + + +
libstern<-cbind(libs.tern,xend=0,yend=0,zend=0)
+libstern<-libstern%>% 
+  mutate(xend= ifelse(type=="1", x,xend)) %>%
+  mutate(yend= ifelse(type=="1", y,yend)) %>%
+  mutate(zend= ifelse(type=="1", z,zend))
+ + + + + + +
for(i in c(1,10,11,13,17)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.06,libstern[i,2],libstern[i,3]-0.06)
+}
+
+for(i in c(7)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.09,libstern[i,2],libstern[i,3]-0.09)
+}
+
+for(i in c(15,20)){
+  libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]+0.05,libstern[i,3]-0.05)
+}
+
+for(i in c(3)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.02,libstern[i,2]+0.06,libstern[i,3]-0.08)
+}
+
+for(i in c(14)){
+  libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]-0.05,libstern[i,3]+0.05)
+}
+
+for(i in c(4,16,19)){
+  libstern[i,8:10]<-c(libstern[i,1]-0.08,libstern[i,2]+0.02,libstern[i,3]+0.06)
+}
+
+for(i in c(2,9)){
+  libstern[i,8:10]<-c(libstern[i,1]+0.03,libstern[i,2]-0.05,libstern[i,3]+0.03)
+}
+
+for(i in c(6,8,12,18,22)){
+  libstern[i,8:10]<-c(libstern[i,1]-0.06,libstern[i,2],libstern[i,3]+0.06)
+}
+
+for(i in c(5)){
+  libstern[i,8:10]<-c(libstern[i,1],libstern[i,2]-0.09,libstern[i,3]+0.09)
+}
+
+for(i in c(21)){
+  libstern[i,8:10]<-c(libstern[i,1]-0.03,libstern[i,2]+0.07,libstern[i,3]-0.03)
+}
+ + + + + + +
nv = -0.00  #Vertical Adjustment
+pn = position_nudge_tern(y=nv,x=-nv,z=nv)
+
+ggtern(libstern, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=subset(libstern,type==0),aes(color=cluster),alpha=0.5) + 
+  geom_point(data=subset(libstern,type==1),aes())+
+  theme_rgbw() + 
+  labs(title="Mars LIBS Data With Reference Samples Highlighted",
+       x="Si+Al",
+       y="Fe+Mg",
+       z="Ca+Na+K") + 
+  theme(legend.position="bottom") +
+  geom_text(position=pn,data=subset(libstern,type==1),
+            aes(x=xend,y=yend,z=zend,label=num),check_overlap=T)+
+  geom_segment(aes(x=x,xend = xend, y = y, yend=yend, z=z, zend=zend),size=0.3,
+               data = subset(libstern,type==1))+
+  theme_nomask()
+ + +
Warning in geom_text(position = pn, data = subset(libstern, type == 1),  :
+  Ignoring unknown aesthetics: z
+Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
+ℹ Please use `linewidth` instead.
+This warning is displayed once every 8 hours.
+Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
+Warning in geom_segment(aes(x = x, xend = xend, y = y, yend = yend, z = z,  :
+  Ignoring unknown aesthetics: z and zend
+Warning in acomp(data[, self$required_aes]) :
+  Negative values in composition are used as detection limits
+ + +

+ + + +

This plot with the table of reference samples below allows us to +examine our k-means clusters in the context of the earth reference +samples.

+

One of the primary results of looking at this graph is that many of +the points that seemed to be outliers from the rest of the data are +actually calibration targets. There are much fewer points in cluster 3, +our smallest and most distinct cluster, when you consider that some of +those original points are averaged into the reference points for calcite +and Flouro-Chloro-Hydro Apatite.

+

Also, it is interesting that much of cluster 2 has no earth +references over it. This could indicate that samples like these are not +common on earth, or it could indicate that the scientists deciding what +earth references to include thought samples like those were +unimportant.

+ + + +
kablelibstern<-cbind(point=libs.tern$num,"Description"=libs.tern$cluster)
+kablelibstern<-kablelibstern[1:22,]
+
+kable(kablelibstern)
+ + + +

In the future, it would be helpful to be able to select only certain +references, and to split these references into igneous and sedimentary +categories so that when examining a specific igneous or sedimentary +sample it is easy to see what references to compare it to. This is +especially useful when examining these earth references in conjunction +with the PIXL data, which can be plotted on a ternary plot as well.

+
+
+
+

4.0 Finding 2: Matching LIBS and PIXL Data

+

Matching the LIBS and PIXL data using their longitude and +latitudes.

+
+

4.1 Data, Code, and Resources

+

Here is a list data sets, codes, that are used in your work. Along +with brief description and URL where they are located.

+
    +
  1. MatchingLIBSandPIXL.Rmd outlines a lot of the work behind +matching the LIBS targets to PIXL samples. https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/StudentNotebooks/Assignment05/MatchingLIBSandPIXL.Rmd

  2. +
  3. supercam_libs_moc_loc.Rds is the Rds file containing the LIBS +data https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/2fbb9b7988d536656bb118a0d8e0b644392ca09a/Data/supercam_libs_moc_loc.Rds

  4. +
  5. samples_pixl_wide.Rds is the Rds file containing all of the PIXL +data https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/18a7440e2b4de50a2be8223adc9319f33f082f09/Data/samples_pixl_wide.Rds

  6. +
  7. pixl_sol_coordinates.Rds contains the pixl data with the +coordinates and sol metadata added from the analysts notebook https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/main/StudentData/pixl_sol_coordinates.Rds.

  8. +
  9. PIXL_LIBS_Combined.Rds is the final product of combining the LIBS +and PIXL data created by Charlotte and I. https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/e02a301198e2ec47e168448602eace6a6f7e3eaf/StudentData/PIXL_LIBS_Combined.Rds

  10. +
  11. lahira-finalProjectF24.Rmd is the final notebook of Aadi Lahiri, +which we get our earth scaling method from https://github.rpi.edu/DataINCITE/DAR-Mars-F24/blob/4d7fc8b60026364dbb4c571d7b3d6318a08f68bb/StudentNotebooks/Assignment08_FinalProjectNotebook/lahira-finalProjectF24.Rmd

  12. +
+
+
+

4.2 Contribution

+

I worked with Charlotte Peterson on this section, we matched the LIBS +and PIXL data together. Then I graphed the ternary plot of the LIBS data +colored by its closest PIXL sample. The earth scaling technique on my +final heatmap was from Aadi Lahiri’s notebook.

+
+
+

4.3 Methods Description

+

First, columns with the PIXL coordinates and sol were added to the +PIXL data. This information was found from the analyst’s notebook.

+

The final iteration of combined data is created in the +MatchingLIBSandPIXL.Rmd file. The result of that file is the +PIXL_LIBS_Combined.Rds, which contains every mars LIBS sample, so the +scct/earth reference samples are removed. Each LIBS sample is listed +with its closest PIXL sample, ignoring the atmospheric sample, and their +distance in meters.

+

The scct/earth reference samples were removed because their location +has nothing to do with their data, the rover is taking a LIBS +measurement of reference materials it carries with it.

+

Even though some of the distances are farther than we would consider +close or useful, ultimately, we chose not to remove any data points so +that in the future people can make their own cutoff of what distance +they consider to be significant or relevant. The recommendation we would +make is to consider paired PIXL and LIBS samples that are within 7 +meters of each other, as that is close to the range where the LIBS laser +can reach.

+ + + +
pixllibs<-readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/StudentData/PIXL_LIBS_Combined.Rds")
+ + + + + + +
distancetable<-pixllibs[,c(1:4,6,7)]
+distancetable<-distinct(distancetable)
+
+ggplot(data=distancetable, aes(x=Distance, group=PIXL.Abrasion, fill=PIXL.Abrasion)) +
+  ggtitle("Distances of LIBS Data to Nearest PIXL Abrasion")+
+    geom_density(adjust=1.5, alpha=.4)
+ + +

+ + + +

Three of the PIXL Abrasions have a lot of points that are very close, +but many others have data that is very spread.

+
+
+

4.4 Result and Discussion

+

Since the work of matching the LIBS and PIXL data has already been +done, it is easy to import the combined RDS and convert that data into a +dataframe to be used for a ternary diagram

+

We can easily change what distance we would like to view

+ + + +
libs.tern <- as.data.frame(pixllibs) %>%
+  mutate(x=(LIBS.SiO2+LIBS.Al2O3)/100,y=(LIBS.FeOT+LIBS.MgO)/100,z=(LIBS.CaO+LIBS.Na2O+LIBS.K2O)/100)
+
+libs.tern<-libs.tern[,c(6,7,19,20,21)]
+ + + + + + +
meters<- 100
+
+ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=subset(libs.tern, Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + 
+  theme_rgbw() + 
+  labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL Abrasion",sep=" "),
+       x="Si+Al", y="Fe+Mg",z="Ca+Na+K") +
+  theme(legend.position="right") + 
+  guides(alpha="none",color=guide_legend(title="PIXL Abrasion"))
+
+meters<- 7
+
+ggtern(libs.tern, ggtern::aes(x=x,y=y,z=z)) +
+  geom_point(data=subset(libs.tern,Distance<=meters),aes(color=PIXL.Abrasion,alpha=0.5)) + 
+  theme_rgbw() + 
+  labs(title=paste("Mars LIBS Data Within",meters,"meters of PIXL Abrasion",sep=" "),
+       x="Si+Al",y="Fe+Mg",z="Ca+Na+K") +
+  theme(legend.position="right") + 
+  guides(alpha="none",color=guide_legend(title="PIXL Abrasion"))
+ + + +

We can see here that when interpreting the LIBS data within 7 meters +of each PIXL abrasion, the data is not tightly clustered. For the most +part, the data is just as spread as the entire data.

+ + + +
libs.heatmap<-pixllibs
+
+libs.heatmap<-libs.heatmap[libs.heatmap$Distance <= 7, ]
+
+libs.heatmap.mean<-aggregate(cbind(LIBS.SiO2,LIBS.TiO2,LIBS.Al2O3,LIBS.FeOT,LIBS.MgO,LIBS.CaO,
+    LIBS.Na2O,LIBS.K2O) ~ PIXL.Abrasion, data = libs.heatmap, FUN = "mean")
+libs.heatmap.med<-aggregate(cbind(LIBS.SiO2,LIBS.TiO2,LIBS.Al2O3,LIBS.FeOT,LIBS.MgO,
+    LIBS.CaO,LIBS.Na2O,LIBS.K2O) ~ PIXL.Abrasion, data = libs.heatmap, FUN = "median")
+
+libs.heatmap.mean<-cbind(libs.heatmap.mean,"x"="mean")
+libs.heatmap.mean$PIXL.Abrasion<-as.character(libs.heatmap.mean$PIXL.Abrasion)
+libs.heatmap.mean<-libs.heatmap.mean %>%
+  mutate(x=paste(PIXL.Abrasion,x,sep=" "))
+rownames(libs.heatmap.mean)<-libs.heatmap.mean$x
+
+libs.heatmap.med<-cbind(libs.heatmap.med,"x"="median")
+libs.heatmap.med$PIXL.Abrasion<-as.character(libs.heatmap.med$PIXL.Abrasion)
+libs.heatmap.med<-libs.heatmap.med %>%
+  mutate(x=paste(PIXL.Abrasion,x,sep=" "))
+
+rownames(libs.heatmap.med)<-libs.heatmap.med$x
+
+libs.heatmap<-rbind(libs.heatmap.mean,libs.heatmap.med)
+libs.heatmap<-libs.heatmap[c(1,7,2,8,3,9,4,10,5,11,6,12),]
+
+pheatmap(libs.heatmap[,2:9],scale="column",cluster_rows=F,cluster_cols=F,
+    main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Column-Scaled")
+pheatmap(libs.heatmap[,2:9],scale="none",cluster_rows=F,cluster_cols=F,
+    main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Unscaled")
+ + + +

When looking at the heatmap, we can see more differences between the +abrasions than are visible on the ternary plot.

+ + + +
libs_earth <- readRDS("/academics/MATP-4910-F24/DAR-Mars-F24/Data/LIBS_training_set_quartiles.Rds")
+earthheatmap <- libs.heatmap %>% select(c(LIBS.SiO2, LIBS.TiO2, LIBS.Al2O3, LIBS.FeOT, LIBS.MgO, 
+    LIBS.CaO, LIBS.Na2O, LIBS.K2O,x)) %>% 
+  rowwise() %>% mutate("Si"= (LIBS.SiO2-libs_earth[3,2])/(libs_earth[4,2] - libs_earth[2,2]), 
+                       "Ti"= (LIBS.TiO2-libs_earth[3,3])/(libs_earth[4,3] - libs_earth[2,3]),
+                       "Al"= (LIBS.Al2O3-libs_earth[3,4])/(libs_earth[4,4] - libs_earth[2,4]),
+                       "Fe"= (LIBS.FeOT-libs_earth[3,5])/(libs_earth[4,5] - libs_earth[2,5]),
+                       "Mg"= (LIBS.MgO-libs_earth[3,6])/(libs_earth[4,6] - libs_earth[2,6]),
+                       "Ca"= (LIBS.CaO-libs_earth[3,7])/(libs_earth[4,7] - libs_earth[2,7]),
+                       "Na"= (LIBS.Na2O-libs_earth[3,8])/(libs_earth[4,8] - libs_earth[2,8]),
+                       "K"= (LIBS.K2O-libs_earth[3,9])/(libs_earth[4,9] - libs_earth[2,9])) %>%
+  select(!c(LIBS.SiO2, LIBS.TiO2, LIBS.Al2O3, LIBS.FeOT, LIBS.MgO, LIBS.CaO, LIBS.Na2O, LIBS.K2O))
+
+earthheatmap<-as.matrix(earthheatmap)
+earthheatmap<-as.data.frame(earthheatmap)
+
+rownames(earthheatmap)<-earthheatmap$x
+
+#earthheatmap<-earthheatmap[,2:9]
+earthheatmap[,2:9]<-sapply(earthheatmap[,2:9],as.numeric)
+
+pheatmap(earthheatmap[,2:9],scale="none",cluster_rows=F,cluster_cols=F,
+    main="Means and Medians of LIBS data within 7m of PIXL Abrasion, \n Earth Scaled")
+ + + +

Using Aadi’s earth scaling technique, we can compare our two earlier +heatmaps with an earth scaled heatmap. The main consistency between +these heatmaps is high variation in the Mg or MgO columns.

+
+
+

5.5 Conclusions, Limitations, and Future Work.

+

More analysis of the LIBS data grouped by PIXL needs to be done. I +think a Principle Component analysis could be interesting to help us see +what factors break up the different groups. I also think a similarity +analysis within the groups could be interesting.

+

One potential issue with the combined LIBS and PIXL dataset, is that +the LIBS data has some duplicate points with different latitude and +longitudes. For example, the LIBS target “aegis_0907a_________” contains +duplicate points with the same data with differing longitude and +latitude values. This could indicate that there is more error than we +think with the latitude and longitude of LIBS measurements. We are not +100% sure what the LIBS latitude and longitude is referring to (the +laser or the rover), but this could indicate we understand it even less. +This notebook runs on the assumption that the latitude and longitude +refers to the location of the rover.

+
+
+
+

Bibliography

+

Provide a listing of references and other sources.

+
    +
  • [Cousin21] Cousin, A., Sautter, V., Fabre, C., Dromart, G., +Montagnac, G., Drouet, C., Meslin, P. Y., Gasnault, O., Beyssac, O., +Bernard, S., Cloutis, E., Forni, O., Beck, P., Fouchet, T., Johnson, J. +R., Lasue, J., Ollila, A. M., De Parseval, P., Gouy, S., & Caron, B. +(2021). SuperCam calibration targets on board the perseverance rover: +Fabrication and quantitative characterization. Spectrochimica Acta Part +B: Atomic Spectroscopy, 106341. https://doi.org/10.1016/j.sab.2021.106341

  • +
  • [Hamilton18] Hamilton NE, Ferry M (2018). “ggtern: Ternary +Diagrams Using ggplot2.” Journal of Statistical Software, Code +Snippets, 87(3), 1-17. doi:10.18637/jss.v087.c03 https://doi.org/10.18637/jss.v087.c03

  • +
  • [Hijmans24] Hijmans R (2024). geosphere: Spherical +Trigonometry. R package version 1.5-20, https://CRAN.R-project.org/package=geosphere

  • +
+ + + +
#citation("geosphere")
+#citation("ggtern")
+ + + + +
+ +
LS0tCnRpdGxlOiAiRGF0YSBBbmFseXRpY3MgUmVzZWFyY2ggSW5kaXZpZHVhbCBGaW5hbCBQcm9qZWN0IFJlcG9ydCIKYXV0aG9yOiAiTWFyZ28gVmFuRXNzZWxzdHluIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRoZW1lOiB1bml0ZWQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzMnCi0tLQojIERBUiBQcm9qZWN0IGFuZCBHcm91cCBNZW1iZXJzCgoqIFByb2plY3QgbmFtZTogTWFycwoqIFByb2plY3QgdGVhbSBtZW1iZXJzOiBDaGFybG90dGUgUGV0ZXJzb24sIERvw7FhIFJvYmVydHMsIFh1YW50aW5nIFdhbmcsIERhdmlkIFdhbGN6eWssIENoYXJsb3R0ZSBOZXdtYW4sIERhbnRlIE13YXRpYm8sIE5pY29sYXMgTW9yYXdza2ksIENKIE1hcmlubywgQWFkaSBMYWhpcmksIEFzaHRvbiBDb21wdG9uCgojIDAuMCBQcmVsaW1pbmFyaWVzLgoKVGhpcyByZXBvcnQgaXMgZ2VuZXJhdGVkIGZyb20gYW4gUiBNYXJrZG93biBmaWxlIHRoYXQgaW5jbHVkZXMgYWxsIHRoZSBSIGNvZGUgbmVjZXNzYXJ5IHRvIHByb2R1Y2UgdGhlIHJlc3VsdHMgZGVzY3JpYmVkIGFuZCBlbWJlZGRlZCBpbiB0aGUgcmVwb3J0LiAgQ29kZSBibG9ja3MgY2FuIGJlIHN1cnByZXNzZWQgZnJvbSBvdXRwdXQgZm9yIHJlYWRhYmlsaXR5IHVzaW5nIHRoZSBjb21tYW5kIGNvZGUgYHtSLCAgZWNobz1zaG93fWAgaW4gdGhlIGNvZGUgYmxvY2sgaGVhZGVyLiBJZiBgc2hvdyA8LSBGQUxTRWAgdGhlIGNvZGUgYmxvY2sgd2lsbCBiZSBzdXJwcmVzc2VkOyBpZiBgc2hvdyA8LSBUUlVFYCB0aGVuIHRoZSBjb2RlIHdpbGwgYmUgc2hvdy4gCgpgYGB7cn0KIyBTZXQgdG8gVFJVRSB0byBleHBhbmQgUiBjb2RlIGJsb2Nrczsgc2V0IHRvIEZBTFNFIHRvIGNvbGxhcHNlIFIgY29kZSBibG9ja3MgCnNob3cgPC0gVFJVRQpgYGAKCkV4ZWN1dGluZyB0aGlzIFIgbm90ZWJvb2sgcmVxdWlyZXMgc29tZSBzdWJzZXQgb2YgdGhlIGZvbGxvd2luZyBwYWNrYWdlczoKCiogYGdncGxvdDJgCiogYHRpZHl2ZXJzZWAKKiBgZ2d0ZXJuYAoqIGBrbml0cmAKKiBgcGhlYXRtYXBgCgpUaGVzZSB3aWxsIGJlIGluc3RhbGxlZCBhbmQgbG9hZGVkIGFzIG5lY2Vzc2FyeSAoY29kZSBzdXBwcmVzc2VkKS4gCgo8IS0tIFRoZSBgaW5jbHVkZT1GQUxTRWAgb3B0aW9uIHByZXZlbnRzIHlvdXIgY29kZSBmcm9tIGJlaW5nIHNob3duIGF0IGFsbCAtLT4KYGBge3IsIGluY2x1ZGU9RkFMU0V9CiMgVGhpcyBjb2RlIHdpbGwgaW5zdGFsbCByZXF1aXJlZCBwYWNrYWdlcyBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBpbnN0YWxsZWQKIyBBTFdBWVMgSU5TVEFMTCBZT1VSIFBBQ0tBR0VTIExJS0UgVEhJUyEKaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsKICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCiAgIGxpYnJhcnkoZ2dwbG90MikKfQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7CiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpCiAgIGxpYnJhcnkodGlkeXZlcnNlKQp9CmlmICghcmVxdWlyZSgiZ2d0ZXJuIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Rlcm4iKQogIGxpYnJhcnkoZ2d0ZXJuKQp9CmlmKCFyZXF1aXJlKCJrbml0ciIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQogIGxpYnJhcnkoa25pdHIpCn0KaWYoIXJlcXVpcmUoInBoZWF0bWFwIikpewogIGluc3RhbGwucGFja2FnZXMoInBoZWF0bWFwIikKICBsaWJyYXJ5KHBoZWF0bWFwKQp9CmBgYAoKIyAxLjAgUHJvamVjdCBJbnRyb2R1Y3Rpb24KClRoaXMgcHJvamVjdCBvdXRsaW5lcyBteSBhbmFseXNpcyBvZiB0aGUgTWFycyBMSUJTIGFuZCBQSVhMIGRhdGEuIEl0IGxhcmdlbHkgcmV2b2x2ZXMgYXJvdW5kIGRhdGEgcHJvY2Vzc2luZyBhbmQgb3JnYW5pemF0aW9uCgojIDIuMCBPcmdhbml6YXRpb24gb2YgUmVwb3J0CgpUaGlzIHJlcG9ydCBpcyBvcmdhbml6ZWQgYXMgZm9sbG93czogCgoqIFNlY3Rpb24gMy4wLiAgRmluZGluZyAxOiBIZXJlIHdlIGRpc2N1c3MgdGhlIExJQlMgc2NjdCB0YXJnZXRzIGFuZCB0aGUgaW1wb3J0YW5jZSBvZiBkaWZmZXJlbnRpYXRpbmcgdGhlbSBpbiBmdXR1cmUgYW5hbHlzaXMgCgoqIFNlY3Rpb24gNC4wOiBGaW5kaW5nIDI6IEhlcmUgd2UgZGlzY3VzcyB0aGUgY29ubmVjdGlvbiBiZXR3ZWVuIHRoZSBMSUJTIGFuZCBQSVhMIGRhdGEKCiogU2VjdGlvbiA1LjAgT3ZlcmFsbCBjb25jbHVzaW9ucyBhbmQgc3VnZ2VzdGlvbnMgCgojIDMuMCBGaW5kaW5nIDE6IFVuZGVyc3RhbmRpbmcgTElCUyBUYXJnZXRzCgpJIHJlc2VhcmNoZWQgdGhlIG1lYW5pbmcgYmVoaW5kIHRoZSBMSUJTIHRhcmdldCBuYW1lcywgYW5kIGNhdGVnb3JpemVkIHRoZSBMSUJTIGRhdGEgaW50byBhIGZldyBtYWpvciBjYXRlZ29yaWVzLiBJIGNyZWF0ZWQgYSBuZXcgUmRzIGZpbGUgdGhhdCBpbmNsdWRlcyBhIGNvbHVtbiBsYWJlbGluZyBlYWNoIExJQlMgc2FtcGxlIHdpdGggaXRzIGNhdGVnb3J5LiAKCiMjIDMuMSBEYXRhLCBDb2RlLCBhbmQgUmVzb3VyY2VzCgpIZXJlIGlzIGEgbGlzdCAgZGF0YSBzZXRzLCBjb2RlcywgIHRoYXQgYXJlIHVzZWQgaW4geW91ciB3b3JrLiBBbG9uZyB3aXRoIGJyaWVmIGRlc2NyaXB0aW9uIGFuZCBVUkwgd2hlcmUgdGhleSBhcmUgbG9jYXRlZC4KCjEuIHN1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMgaXMgdGhlIFJkcyBmaWxlIGNvbnRhaW5pbmcgdGhlIExJQlMgZGF0YSBbaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iLzJmYmI5Yjc5ODhkNTM2NjU2YmIxMThhMGQ4ZTBiNjQ0MzkyY2EwOWEvRGF0YS9zdXBlcmNhbV9saWJzX21vY19sb2MuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMpCgoyLiBsaWJzX3R5cGVkLlJkcyBpcyB0aGUgUmRzIGZpbGUgY29udGFpbmluZyB0aGUgTElCUyBkYXRhIGFzIHdlbGwgYXMgYSB0eXBlIGNvbHVtbiBjYXRlZ29yaXppbmcgZWFjaCBzYW1wbGUgW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi8yZmJiOWI3OTg4ZDUzNjY1NmJiMTE4YTBkOGUwYjY0NDM5MmNhMDlhL1N0dWRlbnREYXRhL2xpYnNfdHlwZWQuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9TdHVkZW50RGF0YS9saWJzX3R5cGVkLlJkcykKCjMuIFN1cGVyY2FtQ2FsaWJyYXRpb25UYXJnZXRzLnBkZiBpcyBhIHBkZiBjb250YWluaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjYWxpYnJhdGlvbiB0YXJnZXRzIHVzZWQgaW4gdGhlIExJQlMgZGF0YS4gW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi9lMDJhMzAxMTk4ZTJlYzQ3ZTE2ODQ0ODYwMmVhY2U2YTZmN2UzZWFmL1N0dWRlbnROb3RlYm9va3MvQXNzaWdubWVudDA3X0RyYWZ0RmluYWxQcm9qZWN0Tm90ZWJvb2svU3VwZXJjYW1DYWxpYnJhdGlvblRhcmdldHMucGRmXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvZTAyYTMwMTE5OGUyZWM0N2UxNjg0NDg2MDJlYWNlNmE2ZjdlM2VhZi9TdHVkZW50Tm90ZWJvb2tzL0Fzc2lnbm1lbnQwN19EcmFmdEZpbmFsUHJvamVjdE5vdGVib29rL1N1cGVyY2FtQ2FsaWJyYXRpb25UYXJnZXRzLnBkZikKCjQuIHYxX2xpYnMuUmRzIGlzIHRoZSBSZHMgZmlsZSBjb250YWluaW5nIHRoZSBMSUJTIGRhdGEgYXMgd2VsbCBhcyBteSBjYXRlZ29yaXphdGlvbiB0aGF0IERvw7FhIHB1dCBpbnRvIGEgc3RhbmRhcmRpemVkIGZvcm1hdCBbaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iLzJmYmI5Yjc5ODhkNTM2NjU2YmIxMThhMGQ4ZTBiNjQ0MzkyY2EwOWEvRGF0YS9zdXBlcmNhbV9saWJzX21vY19sb2MuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMpCgoKSSB1c2VkIHRoZSBsaWJzIGRhdGFzZXQgd2l0aCB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIGZlYXR1cmVzLCBkaXN0YW5jZXMsIGFuZCB0b3RhbHMgcmVtb3ZlZC4gSSBtYWRlIHN1cmUgdGhhdCBjZXJ0YWluIGNhdGVnb3JpZXMgd2VyZSBudW1lcmljIGFuZCBhZGRlZCBhIG5ldyAidHlwZSIgY29sdW1uLgoKVGhlbiwgSSBhZGRlZCBhIGRlc2NyaXB0aW9uIHRvIGVhY2ggc2NjdCAoY2FsaWJyYXRpb24pIHRhcmdldCBpbiB0aGUgdHlwZSBjb2x1bW4sIHdoaWNoIG5hbWVzIHRoZSBlYXJ0aCByZWZlcmVuY2UgYmFzZWQgb24gdGhlIHBkZiBsaW5rZWQgaW4gdGhpcyBzZWN0aW9uLiBGb3IgZXhhbXBsZSwgdGhlIHNjY3QgdGFyZ2V0IGNvbnRhaW5pbmcgIlBNSUZBMDMwNiIgd2FzIHR5cGVkICJPbGl2aW5lIgoKSSBhbHNvIGxhYmVsZWQgdGhlIHRhcmdldHMgd2l0aCAiYWVnaXMiIGluIHRoZWlyIG5hbWVzIHdpdGggQUVHSVMsIHRoZXNlIHNhbXBsZXMgY2FuIGJlIHVzZWQgdGhlIHNhbWUgYXMgdGhlIG90aGVyIE1hcnMgTElCUyBzYW1wbGVzLCBidXQgaXQgaXMgbm90ZWQgdGhhdCB0aGUgbWVhc3VyZW1lbnQgaXMgdGFrZW4gdXNpbmcgQUVHSVMsIHRoZSByb3ZlcidzIEFJLiBTbyBpbnN0ZWFkIG9mIHRoZSB0YXJnZXQgYmVpbmcgY2hvc2VuIGludGVudGlvbmFsbHkgYnkgYSBzY2llbnRpc3QsIGl0IGlzIGNob3NlbiBieSB0aGUgcm92ZXIgd2hlbiBpdCBoYXMgZXh0cmEgcmVzb3VyY2VzIHRvIHRha2UgYSBzYW1wbGUuCgpGcm9tIHRoZSBhbmFseXN0cyBub3RlYm9vaywgdGFyZ2V0cyB3aXRoICJzY2FtIiBpbiB0aGVpciBuYW1lcyBjb3JyZXNwb25kIHRvIHRhcmdldHMgb2Ygb3RoZXIgbWVhc3VyZW1lbnRzLCBJIHdlbnQgdGhyb3VnaCB0aGUgYW5hbHlzdHMgbm90ZWJvb2sgZm9yIHRoZXNlIHNhbXBsZXMgYW5kIGFkZGVkIHRoZSBvdGhlciBtZWFzdXJlbWVudHMgdGhhdCB3ZXJlIHRha2VuIGF0IHRoZSBzYW1lIHRhcmdldCBpbnRvIHRoZSB0eXBlIGNvbHVtbi4gRm9yIGV4YW1wbGUsIHRoZSAidmlsbGVwbGFuZV9zY2FtIiB0YXJnZXQgYWxzbyBoYWQgWkNhbSBtZWFzdXJlbWVudHMgdGFrZW4gYXQgdGhlIHNhbWUgdGFyZ2V0LCBzbyBJIHR5cGVkIGl0ICJaQ0FNLVNDQU0iCgpJIGxhYmVsZWQgdHdvIHRhcmdldHMgKCJzZWlfX19fX19fX19fX19fX19fXyIgYW5kICJuYWFraWhfX19fX19fX19fX19fXyIpLCAgd2l0aCBmdXJ0aGVyIGRlc2NyaXB0aW9ucyBiZWNhdXNlIHRoZSBhbmFseXN0cyBub3RlYm9vayBoYWQgY2xlYXIgZGVzY3JpcHRpb25zIG9mIHdoYXQgdGhlIHRhcmdldCB3YXMgaW50ZW5kZWQgdG8gYmUgc2FtcGxpbmcuIAoKQWxsIHJlbWFpbmluZyBzYW1wbGVzIGFyZSB0eXBlZCAib3RoZXIiLgoKYGBge3J9CmxpYnMuZGYgPC0gcmVhZFJEUygiL2FjYWRlbWljcy9NQVRQLTQ5MTAtRjI0L0RBUi1NYXJzLUYyNC9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHMiKQoKI0Ryb3AgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBmZWF0dXJlcywgdGhlIHN1bSBvZiB0aGUgcGVyY2VudGFnZXMsIAojdGhlIGRpc3RhbmNlLCBhbmQgdGhlIHRvdGFsIGZyZXF1ZW5jaWVzCmxpYnMuZGYgPC0gbGlicy5kZiAlPiUgCiAgc2VsZWN0KCEoYyhkaXN0YW5jZV9tbSxUb3QuRW0uLFNpTzJfc3RkZXYsVGlPMl9zdGRldixBbDJPM19zdGRldixGZU9UX3N0ZGV2LAogICAgICAgICAgICAgTWdPX3N0ZGV2LE5hMk9fc3RkZXYsQ2FPX3N0ZGV2LEsyT19zdGRldixUb3RhbCkpKQoKIyBDb252ZXJ0IHRoZSBwb2ludHMgdG8gbnVtZXJpYwpsaWJzLmRmJHBvaW50IDwtIGFzLm51bWVyaWMobGlicy5kZiRwb2ludCkKdHlwZWRsaWJzPC1jYmluZChsaWJzLmRmWywxOjRdLCJ0eXBlIj0wLGxpYnMuZGZbNToxM10pCmBgYAoKYGBge3J9CnRhcmdldGxpc3Q8LWMoInRzcmljaDA0MDQiLCJMQ01CMDAwNiIsIkxDQTUzMDEwNiIsIlBNSUZTMDUwNSIsIlRBUEFHMDIwNiIsIlBNSU9SMDUwNyIsCiAgICAgICAgICAgICAgIlBNSUROMDMwMiIsIlBNSUZBMDMwNiIsIlBNSUFOMDEwNiIsIlBNSUVOMDYwMiIsIlRTRVJQMDEwMiIsIkxCSFZPMjA0MDYiLAogICAgICAgICAgICAgICJMSlNDMTAzMDQiLCJMQU5LRTAxMDEiLCJMU0lERTAxMDEiLCJMSk1OMTAxMDYiLCJOVEUwMTAzMDEiLCJOVEUwMjAxMDYiLAogICAgICAgICAgICAgICJOVEUwMzAxMDYiLCJOVEUwNDAxMDYiLCJOVEUwNTAzMDEiLCJTSEVSRzAyIiwiVElUQU5JVU0iLCJhZWdpcyIsCiAgICAgICAgICAgICAgImJ1enphcmRfcm9ja3Nfc2NhbSIsImFsZmFsZmFfMzc4X3NjYW0iLCJjaGluaWFrXzU2NV9zY2FtIiwKICAgICAgICAgICAgICAiZ2FyZGVfMjEwX3NjYW0iLCJndWlsbGF1bWVzXzE2OF9zY2FtIiwibW9udHBlemF0XzM1MF9zY2FtIiwibmFsdHNvc19zY2FtIiwKICAgICAgICAgICAgICAib3V6ZWxfZmFsbHNfNzkyX3NjYW0iLCJwb2xsb2NrX2tub2JfNTAxX3NjYSIsInJvc2Vfcml2ZXJfZmFsbHNfc2NhIiwKICAgICAgICAgICAgICAicm91Ymlvbl8xNjhfc2NhbSIsInZpbGxlcGxhbmVfc2NhbSIsImF0bW9fbW91bnRhaW5fNjM3X3NjIiwKICAgICAgICAgICAgICAiY3Jvc3N3aW5kX2xha2VfNjQxX3MiKQoKdHlwZWxpc3Q8LWMoIkJIVk8tMiBiYXNhbHQgYW5kIEsgc3VsZmF0ZSBtaXh0dXJlIiwiQ2hlcnQiLCJDYWxjaXRlIiwiRmVycm9zaWxpdGUiLAogICAgICAgICAgICAiRmx1b3JvLUNobG9yby1IeWRybyBBcGF0aXRlIiwiT3J0aG9jbGFzZSIsIkRpb3BzaWRlIiwiT2xpdmluZSIsIkFuZGVzaW5lIiwKICAgICAgICAgICAgIkVuc3RhdGl0ZSIsIlNlcnBlbnRpbmUvVGFsYyIsIkJIVk8tMiBzdGFuZGFyZCBiYXNhbHQiLCJNYXJzIHNvaWwgYW5hbG9nIiwKICAgICAgICAgICAgIkFua2VyaXRlIiwiU2lkZXJpdGUiLCJKTU4tMSBzdGFuZGFyZCBNbiBub2R1bGUiLAogICAgICAgICAgICAiQmFzYWx0IGRvcHBlZCBpbiBtaW5vciBlbGVtZW50cyAtIEN1LCBabiIsCiAgICAgICAgICAgICJCYXNhbHQgZG9wcGVkIGluIG1pbm9yIGVsZW1lbnRzIC0gTW4sIEJhLCBDciIsCiAgICAgICAgICAgICJCYXNhbHQgZG9wcGVkIGluIG1pbm9yIGVsZW1lbnRzIC0gWm4iLAogICAgICAgICAgICAiQmFzYWx0IGRvcHBlZCBpbiBtaW5vciBlbGVtZW50cyAtIExpLCBTciIsCiAgICAgICAgICAgICJCYXNhbHQgZG9wcGVkIGluIG1pbm9yIGVsZW1lbnRzIC0gTmkiLCJTaGVyZ290dGl0ZSIsIlRpdGFuaXVtIiwiQUVHSVMiLAogICAgICAgICAgICAiUElYTC1TQ0FNIiwiVklTSVItUmFtYW54Mi1aQ0FNLVNDQU0iLCJBVC1TQ0FNIiwiQVQtU0NBTSIsIlBJWEwtU0NBTSIsCiAgICAgICAgICAgICJQSVhMLVNDQU0iLCJQSVhMLVNDQU0iLCJBVC1TQ0FNIiwiWkNBTS1TQ0FNIiwiPy1TQ0FNIiwiWkNBTS1QSVhMLVNDQU0iLAogICAgICAgICAgICAiWkNBTS1TQ0FNIiwiWkNBTU1TLVNDQU0iLCJaQ0FNLVNDQU0iKQoKdGFyZ2V0dHlwZWQ8LWFzLmRhdGEuZnJhbWUoY2JpbmQodGFyZ2V0bGlzdCx0eXBlbGlzdCkscm93bmFtZXM9YygxKSkKCmZvcihpIGluIDE6MjMpewogIHR5cGVkbGliczwtdHlwZWRsaWJzICU+JQogICAgbXV0YXRlKHR5cGUgPSBpZmVsc2UoZ3JlcGwodGFyZ2V0dHlwZWRbaSwxXSx0YXJnZXQsaWdub3JlLmNhc2U9VCksCiAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0dHlwZWRbaSwyXSwgdHlwZSkpCn0KCmZvcihpIGluIDI0Om5yb3codGFyZ2V0dHlwZWQpKXsKICB0eXBlZGxpYnM8LXR5cGVkbGlicyAlPiUKICAgIG11dGF0ZSh0eXBlPSBpZmVsc2UoZ3JlcGwodGFyZ2V0dHlwZWRbaSwxXSwgdGFyZ2V0LGlnbm9yZS5jYXNlPVQpICYgdHlwZT09IjAiLAogICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0dHlwZWRbaSwyXSx0eXBlKSkKfQoKdHlwZWRsaWJzPC10eXBlZGxpYnMgJT4lCiAgbXV0YXRlKHR5cGU9aWZlbHNlKHR5cGU9PSIwIiwib3RoZXIiLHR5cGUpKSAlPiUKICBtdXRhdGUodHlwZT0gaWZlbHNlKHRhcmdldD09InNlaV9fX19fX19fX19fX19fX19fIiwgIm90aGVyIC0gZmluZSBzb2lsIix0eXBlKSkgJT4lCiAgbXV0YXRlKHR5cGU9IGlmZWxzZSh0YXJnZXQ9PSJuYWFraWhfX19fX19fX19fX19fXyIsICJvdGhlciAtIGNvYXJzZSBzb2lsIix0eXBlKSkKCmthYmxlKHRhcmdldHR5cGVkKQpgYGAKCiMjIDMuMiBDb250cmlidXRpb24KClRoaXMgc2VjdGlvbiB3YXMgc29sZSB3b3JrLCBleGNlcHQgZm9yIERvw7FhJ3Mgc3RhbmRhcmRpemF0aW9uIG9mIG15IGZpbGUgaW50byB0aGUgdjFfbGlicy5SZHMgYXQgdGhlIGVuZC4gTGF0ZXIsIGluIG15IHRlcm5hcnkgZGlhZ3JhbXMsIEkgdXNlZCB0aGUgc2FtZSBzZWVkIGFuZCBudW1iZXIgb2YgY2x1c3RlcnMgYXMgQWFkaSwgc28gdGhhdCBteSBjbHVzdGVyaW5nIHdvdWxkIG1hdGNoIGhpcy4gCgojIyAzLjMgTWV0aG9kcyBEZXNjcmlwdGlvbiAKCk5vdywgd2UgcGxvdCB0aGUgYXZlcmFnZSBvZiBlYWNoIGNhbGlicmF0aW9uL3NjY3QgdGFyZ2V0LCBhZ2FpbnN0IHRoZSBjbHVzdGVyZWQgbWFycyBMSUJTIGRhdGEuIFRoZSBNYXJzIGRhdGEgaXMgc2VwYXJhdGVkIGZyb20gdGhlIHJlZmVyZW5jZSBkYXRhLCB3ZSBwbG90IHRoZSByZWZlcmVuY2UgZGF0YSBvdmVyIHRoZSBNYXJzIGRhdGEgd2l0aCBsYWJlbGVkIHBvaW50cyBjb3JyZXNwb25kaW5nIHRvIHRoZSB0YWJsZSBvZiByZWZlcmVuY2UgdHlwZXMuIAoKYGBge3J9CmxpYnMubWF0cml4IDwtIGFzLm1hdHJpeChsaWJzLmRmWyw2OjEzXSkgCgpsaWJzLnRlcm4gPC0gYXMuZGF0YS5mcmFtZShsaWJzLm1hdHJpeCkgJT4lCiAgbXV0YXRlKHg9KFNpTzIrQWwyTzMpLzEwMCx5PShGZU9UK01nTykvMTAwLHo9KENhTytOYTJPK0syTykvMTAwKSAlPiUKICBzZWxlY3QoLWMoU2lPMixBbDJPMyxGZU9ULE1nTyxDYU8sTmEyTyxLMk8sVGlPMikpCgoKbGlicy50ZXJuPC1jYmluZChsaWJzLnRlcm4sICJ0eXBlIj10eXBlZGxpYnMkdHlwZSwgInRhcmdldCI9dHlwZWRsaWJzJHRhcmdldCwgCiAgICAgICAgICAgICAgICAgInNoYXBlIj10eXBlZGxpYnMkdHlwZSkKCmxpYnMudGVybjwtbGlicy50ZXJuICU+JSBtdXRhdGUoc2hhcGUgPSBpZmVsc2UoZ3JlcGwoIlNDQU0iLCB0eXBlLCBpZ25vcmUuY2FzZT1UKSwKICAgICAgICAgICAgICAgICAgICAgICAib3RoZXIiLCBzaGFwZSkpICU+JQogIG11dGF0ZShzaGFwZSA9IGlmZWxzZShncmVwbCgib3RoZXIiLCB0eXBlLCBpZ25vcmUuY2FzZT1UKSwKICAgICAgICAgICAgICAgICAgICAgICAib3RoZXIiLCBzaGFwZSkpICU+JQogIG11dGF0ZShzaGFwZSA9IGlmZWxzZShncmVwbCgic2NjdCIsIHRhcmdldCwgaWdub3JlLmNhc2U9VCksICJzY2N0Iiwgc2hhcGUpKQoKbGlicy50ZXJuJHNoYXBlPC1hcy5mYWN0b3IobGlicy50ZXJuJHNoYXBlKQpgYGAKCgpUaGlzIGlzIG5vdCBzcGVjaWZpYyBhbmFseXNpcywgbW9yZXNvIGEgcmVjb21tZW5kYXRpb24gdGhhdCBmb3IgZnV0dXJlIHdvcmssIHRoZSBzY2N0IHZhbHVlcyBzaG91bGQgYmUgc2VwYXJhdGVkIGZyb20gdGhlIGFjdHVhbCBtYXJzIGRhdGEuIFByZXZpb3VzbHksIHdlIGhhZCBiZWVuIGFuYWx5c2luZyB0aGVzZSB0YXJnZXRzIGFzIGlmIHRoZXkgd2VyZSBtYXJzIGRhdGEsIHdoZW4gaW4gZmFjdCB0aGV5IHNob3VsZCBiZSB0cmVhdGVkIGFzIHJlZmVyZW5jZSBvciBjYWxpYnJhdGlvbiBkYXRhLiAKCldoZW4gZ3JhcGhpbmcgdGhlIHJlZmVyZW5jZSBwb2ludHMgb24gdGhlIHRlcm5hcnkgcGxvdCwgZ2dyZXBlbCBoYXMgYSBjb25mbGljdCB3aXRoIGdndGVybiwgc28gSSBoYWQgdG8gbWFudWFsbHkgYWRkIHdoZXJlIHRoZSBsYWJlbHMgc2hvdWxkIGdvLiBJZiB0aGlzIGlzc3VlIHdpdGggZ2d0ZXJuIGlzIGZpeGVkIGluIHRoZSBmdXR1cmUsIHRoaXMgY2FuIGJlIHNpbXBsaWZpZWQgdG8gdXNlIGdncmVwZWwgZm9yIHRoZSBsYWJlbHMuIAoKIyMgMy40IFJlc3VsdCBhbmQgRGlzY3Vzc2lvbiAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQprbTwta21lYW5zKGxpYnMudGVyblssMTozXSw0KQoKbGlicy50ZXJuPC1hcy5kYXRhLmZyYW1lKGNiaW5kKGxpYnMudGVybiwiY2x1c3RlciI9YXMuZmFjdG9yKGttJGNsdXN0ZXIpKSkKYGBgCgpgYGB7cn0KbGlicy50ZXJuLm90aGVyPC1saWJzLnRlcm5bbGlicy50ZXJuJHNoYXBlPT0ib3RoZXIiLF0KbGlicy50ZXJuLnNjY3Q8LWxpYnMudGVybltsaWJzLnRlcm4kc2hhcGU9PSJzY2N0IixdCgojbGlicy5zY2N0LmF2ZzwtbGlicy50ZXJuLnNjY3RbLCBsYXBwbHkoLlNELCBhdmVyYWdlKSwgYnk9IHRhcmdldF0KbGlicy5zY2N0LmF2ZzwtYWdncmVnYXRlKGNiaW5kKHgseSx6KSB+IHR5cGUsIGRhdGEgPSBsaWJzLnRlcm4uc2NjdCwgRlVOID0gIm1lYW4iKQpsaWJzLnRlcm4ub3RoZXI8LWxpYnMudGVybi5vdGhlclssYygxLDIsMyw3KV0KbGlicy50ZXJuLm90aGVyPC1jYmluZChsaWJzLnRlcm4ub3RoZXIsInR5cGUiPTApCmxpYnMuc2NjdC5hdmc8LWNiaW5kKGxpYnMuc2NjdC5hdmdbLDI6NF0sImNsdXN0ZXIiPWxpYnMuc2NjdC5hdmckdHlwZSwidHlwZSI9MSkKbGlicy50ZXJuPC1yYmluZChsaWJzLnNjY3QuYXZnLGxpYnMudGVybi5vdGhlcikKYGBgCgpgYGB7cn0KbGlicy50ZXJuPC1jYmluZChsaWJzLnRlcm4sIm51bSI9cm93bmFtZXMobGlicy50ZXJuKSwibGVnZW5kIj0wKQpgYGAKCmBgYHtyfQpsaWJzLnRlcm48LWxpYnMudGVybiAlPiUgCiAgbXV0YXRlKGxlZ2VuZD1wYXN0ZShudW0sY2x1c3RlcixzZXA9IiAgIikpCmBgYAoKCmBgYHtyfQpsaWJzdGVybjwtY2JpbmQobGlicy50ZXJuLHhlbmQ9MCx5ZW5kPTAsemVuZD0wKQpsaWJzdGVybjwtbGlic3Rlcm4lPiUgCiAgbXV0YXRlKHhlbmQ9IGlmZWxzZSh0eXBlPT0iMSIsIHgseGVuZCkpICU+JQogIG11dGF0ZSh5ZW5kPSBpZmVsc2UodHlwZT09IjEiLCB5LHllbmQpKSAlPiUKICBtdXRhdGUoemVuZD0gaWZlbHNlKHR5cGU9PSIxIiwgeix6ZW5kKSkKYGBgCgpgYGB7cn0KZm9yKGkgaW4gYygxLDEwLDExLDEzLDE3KSl7CiAgbGlic3Rlcm5baSw4OjEwXTwtYyhsaWJzdGVybltpLDFdKzAuMDYsbGlic3Rlcm5baSwyXSxsaWJzdGVybltpLDNdLTAuMDYpCn0KCmZvcihpIGluIGMoNykpewogIGxpYnN0ZXJuW2ksODoxMF08LWMobGlic3Rlcm5baSwxXSswLjA5LGxpYnN0ZXJuW2ksMl0sbGlic3Rlcm5baSwzXS0wLjA5KQp9Cgpmb3IoaSBpbiBjKDE1LDIwKSl7CiAgbGlic3Rlcm5baSw4OjEwXTwtYyhsaWJzdGVybltpLDFdLGxpYnN0ZXJuW2ksMl0rMC4wNSxsaWJzdGVybltpLDNdLTAuMDUpCn0KCmZvcihpIGluIGMoMykpewogIGxpYnN0ZXJuW2ksODoxMF08LWMobGlic3Rlcm5baSwxXSswLjAyLGxpYnN0ZXJuW2ksMl0rMC4wNixsaWJzdGVybltpLDNdLTAuMDgpCn0KCmZvcihpIGluIGMoMTQpKXsKICBsaWJzdGVybltpLDg6MTBdPC1jKGxpYnN0ZXJuW2ksMV0sbGlic3Rlcm5baSwyXS0wLjA1LGxpYnN0ZXJuW2ksM10rMC4wNSkKfQoKZm9yKGkgaW4gYyg0LDE2LDE5KSl7CiAgbGlic3Rlcm5baSw4OjEwXTwtYyhsaWJzdGVybltpLDFdLTAuMDgsbGlic3Rlcm5baSwyXSswLjAyLGxpYnN0ZXJuW2ksM10rMC4wNikKfQoKZm9yKGkgaW4gYygyLDkpKXsKICBsaWJzdGVybltpLDg6MTBdPC1jKGxpYnN0ZXJuW2ksMV0rMC4wMyxsaWJzdGVybltpLDJdLTAuMDUsbGlic3Rlcm5baSwzXSswLjAzKQp9Cgpmb3IoaSBpbiBjKDYsOCwxMiwxOCwyMikpewogIGxpYnN0ZXJuW2ksODoxMF08LWMobGlic3Rlcm5baSwxXS0wLjA2LGxpYnN0ZXJuW2ksMl0sbGlic3Rlcm5baSwzXSswLjA2KQp9Cgpmb3IoaSBpbiBjKDUpKXsKICBsaWJzdGVybltpLDg6MTBdPC1jKGxpYnN0ZXJuW2ksMV0sbGlic3Rlcm5baSwyXS0wLjA5LGxpYnN0ZXJuW2ksM10rMC4wOSkKfQoKZm9yKGkgaW4gYygyMSkpewogIGxpYnN0ZXJuW2ksODoxMF08LWMobGlic3Rlcm5baSwxXS0wLjAzLGxpYnN0ZXJuW2ksMl0rMC4wNyxsaWJzdGVybltpLDNdLTAuMDMpCn0KYGBgCgpgYGB7cn0KbnYgPSAtMC4wMCAgI1ZlcnRpY2FsIEFkanVzdG1lbnQKcG4gPSBwb3NpdGlvbl9udWRnZV90ZXJuKHk9bnYseD0tbnYsej1udikKCmdndGVybihsaWJzdGVybiwgZ2d0ZXJuOjphZXMoeD14LHk9eSx6PXopKSArCiAgZ2VvbV9wb2ludChkYXRhPXN1YnNldChsaWJzdGVybix0eXBlPT0wKSxhZXMoY29sb3I9Y2x1c3RlciksYWxwaGE9MC41KSArIAogIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQobGlic3Rlcm4sdHlwZT09MSksYWVzKCkpKwogIHRoZW1lX3JnYncoKSArIAogIGxhYnModGl0bGU9Ik1hcnMgTElCUyBEYXRhIFdpdGggUmVmZXJlbmNlIFNhbXBsZXMgSGlnaGxpZ2h0ZWQiLAogICAgICAgeD0iU2krQWwiLAogICAgICAgeT0iRmUrTWciLAogICAgICAgej0iQ2ErTmErSyIpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArCiAgZ2VvbV90ZXh0KHBvc2l0aW9uPXBuLGRhdGE9c3Vic2V0KGxpYnN0ZXJuLHR5cGU9PTEpLAogICAgICAgICAgICBhZXMoeD14ZW5kLHk9eWVuZCx6PXplbmQsbGFiZWw9bnVtKSxjaGVja19vdmVybGFwPVQpKwogIGdlb21fc2VnbWVudChhZXMoeD14LHhlbmQgPSB4ZW5kLCB5ID0geSwgeWVuZD15ZW5kLCB6PXosIHplbmQ9emVuZCksc2l6ZT0wLjMsCiAgICAgICAgICAgICAgIGRhdGEgPSBzdWJzZXQobGlic3Rlcm4sdHlwZT09MSkpKwogIHRoZW1lX25vbWFzaygpCmBgYApUaGlzIHBsb3Qgd2l0aCB0aGUgdGFibGUgb2YgcmVmZXJlbmNlIHNhbXBsZXMgYmVsb3cgYWxsb3dzIHVzIHRvIGV4YW1pbmUgb3VyIGstbWVhbnMgY2x1c3RlcnMgaW4gdGhlIGNvbnRleHQgb2YgdGhlIGVhcnRoIHJlZmVyZW5jZSBzYW1wbGVzLiAKCk9uZSBvZiB0aGUgcHJpbWFyeSByZXN1bHRzIG9mIGxvb2tpbmcgYXQgdGhpcyBncmFwaCBpcyB0aGF0IG1hbnkgb2YgdGhlIHBvaW50cyB0aGF0IHNlZW1lZCB0byBiZSBvdXRsaWVycyBmcm9tIHRoZSByZXN0IG9mIHRoZSBkYXRhIGFyZSBhY3R1YWxseSBjYWxpYnJhdGlvbiB0YXJnZXRzLiBUaGVyZSBhcmUgbXVjaCBmZXdlciBwb2ludHMgaW4gY2x1c3RlciAzLCBvdXIgc21hbGxlc3QgYW5kIG1vc3QgZGlzdGluY3QgY2x1c3Rlciwgd2hlbiB5b3UgY29uc2lkZXIgdGhhdCBzb21lIG9mIHRob3NlIG9yaWdpbmFsIHBvaW50cyBhcmUgYXZlcmFnZWQgaW50byB0aGUgcmVmZXJlbmNlIHBvaW50cyBmb3IgY2FsY2l0ZSBhbmQgRmxvdXJvLUNobG9yby1IeWRybyBBcGF0aXRlLgoKQWxzbywgaXQgaXMgaW50ZXJlc3RpbmcgdGhhdCBtdWNoIG9mIGNsdXN0ZXIgMiBoYXMgbm8gZWFydGggcmVmZXJlbmNlcyBvdmVyIGl0LiBUaGlzIGNvdWxkIGluZGljYXRlIHRoYXQgc2FtcGxlcyBsaWtlIHRoZXNlIGFyZSBub3QgY29tbW9uIG9uIGVhcnRoLCBvciBpdCBjb3VsZCBpbmRpY2F0ZSB0aGF0IHRoZSBzY2llbnRpc3RzIGRlY2lkaW5nIHdoYXQgZWFydGggcmVmZXJlbmNlcyB0byBpbmNsdWRlIHRob3VnaHQgc2FtcGxlcyBsaWtlIHRob3NlIHdlcmUgdW5pbXBvcnRhbnQuIAoKYGBge3J9CmthYmxlbGlic3Rlcm48LWNiaW5kKHBvaW50PWxpYnMudGVybiRudW0sIkRlc2NyaXB0aW9uIj1saWJzLnRlcm4kY2x1c3RlcikKa2FibGVsaWJzdGVybjwta2FibGVsaWJzdGVyblsxOjIyLF0KCmthYmxlKGthYmxlbGlic3Rlcm4pCmBgYAoKSW4gdGhlIGZ1dHVyZSwgaXQgd291bGQgYmUgaGVscGZ1bCB0byBiZSBhYmxlIHRvIHNlbGVjdCBvbmx5IGNlcnRhaW4gcmVmZXJlbmNlcywgYW5kIHRvIHNwbGl0IHRoZXNlIHJlZmVyZW5jZXMgaW50byBpZ25lb3VzIGFuZCBzZWRpbWVudGFyeSBjYXRlZ29yaWVzIHNvIHRoYXQgd2hlbiBleGFtaW5pbmcgYSBzcGVjaWZpYyBpZ25lb3VzIG9yIHNlZGltZW50YXJ5IHNhbXBsZSBpdCBpcyBlYXN5IHRvIHNlZSB3aGF0IHJlZmVyZW5jZXMgdG8gY29tcGFyZSBpdCB0by4gVGhpcyBpcyBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGV4YW1pbmluZyB0aGVzZSBlYXJ0aCByZWZlcmVuY2VzIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIFBJWEwgZGF0YSwgd2hpY2ggY2FuIGJlIHBsb3R0ZWQgb24gYSB0ZXJuYXJ5IHBsb3QgYXMgd2VsbC4KCiMgNC4wIEZpbmRpbmcgMjogTWF0Y2hpbmcgTElCUyBhbmQgUElYTCBEYXRhCgpNYXRjaGluZyB0aGUgTElCUyBhbmQgUElYTCBkYXRhIHVzaW5nIHRoZWlyIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGVzLiAKCiMjIDQuMSBEYXRhLCBDb2RlLCBhbmQgUmVzb3VyY2VzCgpIZXJlIGlzIGEgbGlzdCAgZGF0YSBzZXRzLCBjb2RlcywgIHRoYXQgYXJlIHVzZWQgaW4geW91ciB3b3JrLiBBbG9uZyB3aXRoIGJyaWVmIGRlc2NyaXB0aW9uIGFuZCBVUkwgd2hlcmUgdGhleSBhcmUgbG9jYXRlZC4KCjEuIE1hdGNoaW5nTElCU2FuZFBJWEwuUm1kIG91dGxpbmVzIGEgbG90IG9mIHRoZSB3b3JrIGJlaGluZCBtYXRjaGluZyB0aGUgTElCUyB0YXJnZXRzIHRvIFBJWEwgc2FtcGxlcy4gIFtodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMThhNzQ0MGUyYjRkZTUwYTJiZTgyMjNhZGM5MzE5ZjMzZjA4MmYwOS9TdHVkZW50Tm90ZWJvb2tzL0Fzc2lnbm1lbnQwNS9NYXRjaGluZ0xJQlNhbmRQSVhMLlJtZF0oaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iLzE4YTc0NDBlMmI0ZGU1MGEyYmU4MjIzYWRjOTMxOWYzM2YwODJmMDkvU3R1ZGVudE5vdGVib29rcy9Bc3NpZ25tZW50MDUvTWF0Y2hpbmdMSUJTYW5kUElYTC5SbWQpCgoyLiAgc3VwZXJjYW1fbGlic19tb2NfbG9jLlJkcyBpcyB0aGUgUmRzIGZpbGUgY29udGFpbmluZyB0aGUgTElCUyBkYXRhIFtodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMmZiYjliNzk4OGQ1MzY2NTZiYjExOGEwZDhlMGI2NDQzOTJjYTA5YS9EYXRhL3N1cGVyY2FtX2xpYnNfbW9jX2xvYy5SZHNdKGh0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi8yZmJiOWI3OTg4ZDUzNjY1NmJiMTE4YTBkOGUwYjY0NDM5MmNhMDlhL0RhdGEvc3VwZXJjYW1fbGlic19tb2NfbG9jLlJkcykKCjMuIHNhbXBsZXNfcGl4bF93aWRlLlJkcyAgaXMgdGhlIFJkcyBmaWxlIGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBQSVhMIGRhdGEgW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi8xOGE3NDQwZTJiNGRlNTBhMmJlODIyM2FkYzkzMTlmMzNmMDgyZjA5L0RhdGEvc2FtcGxlc19waXhsX3dpZGUuUmRzXShodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvMThhNzQ0MGUyYjRkZTUwYTJiZTgyMjNhZGM5MzE5ZjMzZjA4MmYwOS9EYXRhL3NhbXBsZXNfcGl4bF93aWRlLlJkcykKCjIuIHBpeGxfc29sX2Nvb3JkaW5hdGVzLlJkcyBjb250YWlucyB0aGUgcGl4bCBkYXRhIHdpdGggdGhlIGNvb3JkaW5hdGVzIGFuZCBzb2wgbWV0YWRhdGEgYWRkZWQgZnJvbSB0aGUgYW5hbHlzdHMgbm90ZWJvb2sgW2h0dHBzOi8vZ2l0aHViLnJwaS5lZHUvRGF0YUlOQ0lURS9EQVItTWFycy1GMjQvYmxvYi9tYWluL1N0dWRlbnREYXRhL3BpeGxfc29sX2Nvb3JkaW5hdGVzLlJkc10oaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iL21haW4vU3R1ZGVudERhdGEvcGl4bF9zb2xfY29vcmRpbmF0ZXMuUmRzKS4gCgo1LiBQSVhMX0xJQlNfQ29tYmluZWQuUmRzIGlzIHRoZSBmaW5hbCBwcm9kdWN0IG9mIGNvbWJpbmluZyB0aGUgTElCUyBhbmQgUElYTCBkYXRhIGNyZWF0ZWQgYnkgQ2hhcmxvdHRlIGFuZCBJLiBbaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iL2UwMmEzMDExOThlMmVjNDdlMTY4NDQ4NjAyZWFjZTZhNmY3ZTNlYWYvU3R1ZGVudERhdGEvUElYTF9MSUJTX0NvbWJpbmVkLlJkc10oaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iL2UwMmEzMDExOThlMmVjNDdlMTY4NDQ4NjAyZWFjZTZhNmY3ZTNlYWYvU3R1ZGVudERhdGEvUElYTF9MSUJTX0NvbWJpbmVkLlJkcykKCjYuIGxhaGlyYS1maW5hbFByb2plY3RGMjQuUm1kIGlzIHRoZSBmaW5hbCBub3RlYm9vayBvZiBBYWRpIExhaGlyaSwgd2hpY2ggd2UgZ2V0IG91ciBlYXJ0aCBzY2FsaW5nIG1ldGhvZCBmcm9tIFtodHRwczovL2dpdGh1Yi5ycGkuZWR1L0RhdGFJTkNJVEUvREFSLU1hcnMtRjI0L2Jsb2IvNGQ3ZmM4YjYwMDI2MzY0ZGJiNGM1NzFkN2IzZDYzMThhMDhmNjhiYi9TdHVkZW50Tm90ZWJvb2tzL0Fzc2lnbm1lbnQwOF9GaW5hbFByb2plY3ROb3RlYm9vay9sYWhpcmEtZmluYWxQcm9qZWN0RjI0LlJtZF0oaHR0cHM6Ly9naXRodWIucnBpLmVkdS9EYXRhSU5DSVRFL0RBUi1NYXJzLUYyNC9ibG9iLzRkN2ZjOGI2MDAyNjM2NGRiYjRjNTcxZDdiM2Q2MzE4YTA4ZjY4YmIvU3R1ZGVudE5vdGVib29rcy9Bc3NpZ25tZW50MDhfRmluYWxQcm9qZWN0Tm90ZWJvb2svbGFoaXJhLWZpbmFsUHJvamVjdEYyNC5SbWQpCgojIyA0LjIgQ29udHJpYnV0aW9uCgpJIHdvcmtlZCB3aXRoIENoYXJsb3R0ZSBQZXRlcnNvbiBvbiB0aGlzIHNlY3Rpb24sIHdlIG1hdGNoZWQgdGhlIExJQlMgYW5kIFBJWEwgZGF0YSB0b2dldGhlci4gVGhlbiBJIGdyYXBoZWQgdGhlIHRlcm5hcnkgcGxvdCBvZiB0aGUgTElCUyBkYXRhIGNvbG9yZWQgYnkgaXRzIGNsb3Nlc3QgUElYTCBzYW1wbGUuIFRoZSBlYXJ0aCBzY2FsaW5nIHRlY2huaXF1ZSBvbiBteSBmaW5hbCBoZWF0bWFwIHdhcyBmcm9tIEFhZGkgTGFoaXJpJ3Mgbm90ZWJvb2suIAoKCiMjIDQuMyBNZXRob2RzIERlc2NyaXB0aW9uIAoKRmlyc3QsIGNvbHVtbnMgd2l0aCB0aGUgUElYTCBjb29yZGluYXRlcyBhbmQgc29sIHdlcmUgYWRkZWQgdG8gdGhlIFBJWEwgZGF0YS4gVGhpcyBpbmZvcm1hdGlvbiB3YXMgZm91bmQgZnJvbSB0aGUgYW5hbHlzdCdzIG5vdGVib29rLiAKClRoZSBmaW5hbCBpdGVyYXRpb24gb2YgY29tYmluZWQgZGF0YSBpcyBjcmVhdGVkIGluIHRoZSBNYXRjaGluZ0xJQlNhbmRQSVhMLlJtZCBmaWxlLiBUaGUgcmVzdWx0IG9mIHRoYXQgZmlsZSBpcyB0aGUgUElYTF9MSUJTX0NvbWJpbmVkLlJkcywgd2hpY2ggY29udGFpbnMgZXZlcnkgbWFycyBMSUJTIHNhbXBsZSwgc28gdGhlIHNjY3QvZWFydGggcmVmZXJlbmNlIHNhbXBsZXMgYXJlIHJlbW92ZWQuIEVhY2ggTElCUyBzYW1wbGUgaXMgbGlzdGVkIHdpdGggaXRzIGNsb3Nlc3QgUElYTCBzYW1wbGUsIGlnbm9yaW5nIHRoZSBhdG1vc3BoZXJpYyBzYW1wbGUsIGFuZCB0aGVpciBkaXN0YW5jZSBpbiBtZXRlcnMuIAoKVGhlIHNjY3QvZWFydGggcmVmZXJlbmNlIHNhbXBsZXMgd2VyZSByZW1vdmVkIGJlY2F1c2UgdGhlaXIgbG9jYXRpb24gaGFzIG5vdGhpbmcgdG8gZG8gd2l0aCB0aGVpciBkYXRhLCB0aGUgcm92ZXIgaXMgdGFraW5nIGEgTElCUyBtZWFzdXJlbWVudCBvZiByZWZlcmVuY2UgbWF0ZXJpYWxzIGl0IGNhcnJpZXMgd2l0aCBpdC4gCgpFdmVuIHRob3VnaCBzb21lIG9mIHRoZSBkaXN0YW5jZXMgYXJlIGZhcnRoZXIgdGhhbiB3ZSB3b3VsZCBjb25zaWRlciBjbG9zZSBvciB1c2VmdWwsIHVsdGltYXRlbHksIHdlIGNob3NlIG5vdCB0byByZW1vdmUgYW55IGRhdGEgcG9pbnRzIHNvIHRoYXQgaW4gdGhlIGZ1dHVyZSBwZW9wbGUgY2FuIG1ha2UgdGhlaXIgb3duIGN1dG9mZiBvZiB3aGF0IGRpc3RhbmNlIHRoZXkgY29uc2lkZXIgdG8gYmUgc2lnbmlmaWNhbnQgb3IgcmVsZXZhbnQuIFRoZSByZWNvbW1lbmRhdGlvbiB3ZSB3b3VsZCBtYWtlIGlzIHRvIGNvbnNpZGVyIHBhaXJlZCBQSVhMIGFuZCBMSUJTIHNhbXBsZXMgdGhhdCBhcmUgd2l0aGluIDcgbWV0ZXJzIG9mIGVhY2ggb3RoZXIsIGFzIHRoYXQgaXMgY2xvc2UgdG8gdGhlIHJhbmdlIHdoZXJlIHRoZSBMSUJTIGxhc2VyIGNhbiByZWFjaC4gCgpgYGB7cn0KcGl4bGxpYnM8LXJlYWRSRFMoIi9hY2FkZW1pY3MvTUFUUC00OTEwLUYyNC9EQVItTWFycy1GMjQvU3R1ZGVudERhdGEvUElYTF9MSUJTX0NvbWJpbmVkLlJkcyIpCmBgYAoKYGBge3J9CmRpc3RhbmNldGFibGU8LXBpeGxsaWJzWyxjKDE6NCw2LDcpXQpkaXN0YW5jZXRhYmxlPC1kaXN0aW5jdChkaXN0YW5jZXRhYmxlKQoKZ2dwbG90KGRhdGE9ZGlzdGFuY2V0YWJsZSwgYWVzKHg9RGlzdGFuY2UsIGdyb3VwPVBJWEwuQWJyYXNpb24sIGZpbGw9UElYTC5BYnJhc2lvbikpICsKICBnZ3RpdGxlKCJEaXN0YW5jZXMgb2YgTElCUyBEYXRhIHRvIE5lYXJlc3QgUElYTCBBYnJhc2lvbiIpKwogICAgZ2VvbV9kZW5zaXR5KGFkanVzdD0xLjUsIGFscGhhPS40KQpgYGAKVGhyZWUgb2YgdGhlIFBJWEwgQWJyYXNpb25zIGhhdmUgYSBsb3Qgb2YgcG9pbnRzIHRoYXQgYXJlIHZlcnkgY2xvc2UsIGJ1dCBtYW55IG90aGVycyBoYXZlIGRhdGEgdGhhdCBpcyB2ZXJ5IHNwcmVhZC4gCgojIyA0LjQgUmVzdWx0IGFuZCBEaXNjdXNzaW9uIAoKU2luY2UgdGhlIHdvcmsgb2YgbWF0Y2hpbmcgdGhlIExJQlMgYW5kIFBJWEwgZGF0YSBoYXMgYWxyZWFkeSBiZWVuIGRvbmUsIGl0IGlzIGVhc3kgdG8gaW1wb3J0IHRoZSBjb21iaW5lZCBSRFMgYW5kIGNvbnZlcnQgdGhhdCBkYXRhIGludG8gYSBkYXRhZnJhbWUgdG8gYmUgdXNlZCBmb3IgYSB0ZXJuYXJ5IGRpYWdyYW0KCldlIGNhbiBlYXNpbHkgY2hhbmdlIHdoYXQgZGlzdGFuY2Ugd2Ugd291bGQgbGlrZSB0byB2aWV3CgpgYGB7cn0KbGlicy50ZXJuIDwtIGFzLmRhdGEuZnJhbWUocGl4bGxpYnMpICU+JQogIG11dGF0ZSh4PShMSUJTLlNpTzIrTElCUy5BbDJPMykvMTAwLHk9KExJQlMuRmVPVCtMSUJTLk1nTykvMTAwLHo9KExJQlMuQ2FPK0xJQlMuTmEyTytMSUJTLksyTykvMTAwKQoKbGlicy50ZXJuPC1saWJzLnRlcm5bLGMoNiw3LDE5LDIwLDIxKV0KYGBgCgoKYGBge3J9Cm1ldGVyczwtIDEwMAoKZ2d0ZXJuKGxpYnMudGVybiwgZ2d0ZXJuOjphZXMoeD14LHk9eSx6PXopKSArCiAgZ2VvbV9wb2ludChkYXRhPXN1YnNldChsaWJzLnRlcm4sIERpc3RhbmNlPD1tZXRlcnMpLGFlcyhjb2xvcj1QSVhMLkFicmFzaW9uLGFscGhhPTAuNSkpICsgCiAgdGhlbWVfcmdidygpICsgCiAgbGFicyh0aXRsZT1wYXN0ZSgiTWFycyBMSUJTIERhdGEgV2l0aGluIixtZXRlcnMsIm1ldGVycyBvZiBQSVhMIEFicmFzaW9uIixzZXA9IiAiKSwKICAgICAgIHg9IlNpK0FsIiwgeT0iRmUrTWciLHo9IkNhK05hK0siKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJyaWdodCIpICsgCiAgZ3VpZGVzKGFscGhhPSJub25lIixjb2xvcj1ndWlkZV9sZWdlbmQodGl0bGU9IlBJWEwgQWJyYXNpb24iKSkKCm1ldGVyczwtIDcKCmdndGVybihsaWJzLnRlcm4sIGdndGVybjo6YWVzKHg9eCx5PXksej16KSkgKwogIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQobGlicy50ZXJuLERpc3RhbmNlPD1tZXRlcnMpLGFlcyhjb2xvcj1QSVhMLkFicmFzaW9uLGFscGhhPTAuNSkpICsgCiAgdGhlbWVfcmdidygpICsgCiAgbGFicyh0aXRsZT1wYXN0ZSgiTWFycyBMSUJTIERhdGEgV2l0aGluIixtZXRlcnMsIm1ldGVycyBvZiBQSVhMIEFicmFzaW9uIixzZXA9IiAiKSwKICAgICAgIHg9IlNpK0FsIix5PSJGZStNZyIsej0iQ2ErTmErSyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InJpZ2h0IikgKyAKICBndWlkZXMoYWxwaGE9Im5vbmUiLGNvbG9yPWd1aWRlX2xlZ2VuZCh0aXRsZT0iUElYTCBBYnJhc2lvbiIpKQpgYGAKCldlIGNhbiBzZWUgaGVyZSB0aGF0IHdoZW4gaW50ZXJwcmV0aW5nIHRoZSBMSUJTIGRhdGEgd2l0aGluIDcgbWV0ZXJzIG9mIGVhY2ggUElYTCBhYnJhc2lvbiwgdGhlIGRhdGEgaXMgbm90IHRpZ2h0bHkgY2x1c3RlcmVkLiBGb3IgdGhlIG1vc3QgcGFydCwgdGhlIGRhdGEgaXMganVzdCBhcyBzcHJlYWQgYXMgdGhlIGVudGlyZSBkYXRhLiAKCmBgYHtyfQpsaWJzLmhlYXRtYXA8LXBpeGxsaWJzCgpsaWJzLmhlYXRtYXA8LWxpYnMuaGVhdG1hcFtsaWJzLmhlYXRtYXAkRGlzdGFuY2UgPD0gNywgXQoKbGlicy5oZWF0bWFwLm1lYW48LWFnZ3JlZ2F0ZShjYmluZChMSUJTLlNpTzIsTElCUy5UaU8yLExJQlMuQWwyTzMsTElCUy5GZU9ULExJQlMuTWdPLExJQlMuQ2FPLAogICAgTElCUy5OYTJPLExJQlMuSzJPKSB+IFBJWEwuQWJyYXNpb24sIGRhdGEgPSBsaWJzLmhlYXRtYXAsIEZVTiA9ICJtZWFuIikKbGlicy5oZWF0bWFwLm1lZDwtYWdncmVnYXRlKGNiaW5kKExJQlMuU2lPMixMSUJTLlRpTzIsTElCUy5BbDJPMyxMSUJTLkZlT1QsTElCUy5NZ08sCiAgICBMSUJTLkNhTyxMSUJTLk5hMk8sTElCUy5LMk8pIH4gUElYTC5BYnJhc2lvbiwgZGF0YSA9IGxpYnMuaGVhdG1hcCwgRlVOID0gIm1lZGlhbiIpCgpsaWJzLmhlYXRtYXAubWVhbjwtY2JpbmQobGlicy5oZWF0bWFwLm1lYW4sIngiPSJtZWFuIikKbGlicy5oZWF0bWFwLm1lYW4kUElYTC5BYnJhc2lvbjwtYXMuY2hhcmFjdGVyKGxpYnMuaGVhdG1hcC5tZWFuJFBJWEwuQWJyYXNpb24pCmxpYnMuaGVhdG1hcC5tZWFuPC1saWJzLmhlYXRtYXAubWVhbiAlPiUKICBtdXRhdGUoeD1wYXN0ZShQSVhMLkFicmFzaW9uLHgsc2VwPSIgIikpCnJvd25hbWVzKGxpYnMuaGVhdG1hcC5tZWFuKTwtbGlicy5oZWF0bWFwLm1lYW4keAoKbGlicy5oZWF0bWFwLm1lZDwtY2JpbmQobGlicy5oZWF0bWFwLm1lZCwieCI9Im1lZGlhbiIpCmxpYnMuaGVhdG1hcC5tZWQkUElYTC5BYnJhc2lvbjwtYXMuY2hhcmFjdGVyKGxpYnMuaGVhdG1hcC5tZWQkUElYTC5BYnJhc2lvbikKbGlicy5oZWF0bWFwLm1lZDwtbGlicy5oZWF0bWFwLm1lZCAlPiUKICBtdXRhdGUoeD1wYXN0ZShQSVhMLkFicmFzaW9uLHgsc2VwPSIgIikpCgpyb3duYW1lcyhsaWJzLmhlYXRtYXAubWVkKTwtbGlicy5oZWF0bWFwLm1lZCR4CgpsaWJzLmhlYXRtYXA8LXJiaW5kKGxpYnMuaGVhdG1hcC5tZWFuLGxpYnMuaGVhdG1hcC5tZWQpCmxpYnMuaGVhdG1hcDwtbGlicy5oZWF0bWFwW2MoMSw3LDIsOCwzLDksNCwxMCw1LDExLDYsMTIpLF0KCnBoZWF0bWFwKGxpYnMuaGVhdG1hcFssMjo5XSxzY2FsZT0iY29sdW1uIixjbHVzdGVyX3Jvd3M9RixjbHVzdGVyX2NvbHM9RiwKICAgIG1haW49Ik1lYW5zIGFuZCBNZWRpYW5zIG9mIExJQlMgZGF0YSB3aXRoaW4gN20gb2YgUElYTCBBYnJhc2lvbiwgXG4gQ29sdW1uLVNjYWxlZCIpCnBoZWF0bWFwKGxpYnMuaGVhdG1hcFssMjo5XSxzY2FsZT0ibm9uZSIsY2x1c3Rlcl9yb3dzPUYsY2x1c3Rlcl9jb2xzPUYsCiAgICBtYWluPSJNZWFucyBhbmQgTWVkaWFucyBvZiBMSUJTIGRhdGEgd2l0aGluIDdtIG9mIFBJWEwgQWJyYXNpb24sIFxuIFVuc2NhbGVkIikKYGBgCldoZW4gbG9va2luZyBhdCB0aGUgaGVhdG1hcCwgd2UgY2FuIHNlZSBtb3JlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIGFicmFzaW9ucyB0aGFuIGFyZSB2aXNpYmxlIG9uIHRoZSB0ZXJuYXJ5IHBsb3QuIAoKYGBge3J9CmxpYnNfZWFydGggPC0gcmVhZFJEUygiL2FjYWRlbWljcy9NQVRQLTQ5MTAtRjI0L0RBUi1NYXJzLUYyNC9EYXRhL0xJQlNfdHJhaW5pbmdfc2V0X3F1YXJ0aWxlcy5SZHMiKQplYXJ0aGhlYXRtYXAgPC0gbGlicy5oZWF0bWFwICU+JSBzZWxlY3QoYyhMSUJTLlNpTzIsIExJQlMuVGlPMiwgTElCUy5BbDJPMywgTElCUy5GZU9ULCBMSUJTLk1nTywgCiAgICBMSUJTLkNhTywgTElCUy5OYTJPLCBMSUJTLksyTyx4KSkgJT4lIAogIHJvd3dpc2UoKSAlPiUgbXV0YXRlKCJTaSI9IChMSUJTLlNpTzItbGlic19lYXJ0aFszLDJdKS8obGlic19lYXJ0aFs0LDJdIC0gbGlic19lYXJ0aFsyLDJdKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIlRpIj0gKExJQlMuVGlPMi1saWJzX2VhcnRoWzMsM10pLyhsaWJzX2VhcnRoWzQsM10gLSBsaWJzX2VhcnRoWzIsM10pLAogICAgICAgICAgICAgICAgICAgICAgICJBbCI9IChMSUJTLkFsMk8zLWxpYnNfZWFydGhbMyw0XSkvKGxpYnNfZWFydGhbNCw0XSAtIGxpYnNfZWFydGhbMiw0XSksCiAgICAgICAgICAgICAgICAgICAgICAgIkZlIj0gKExJQlMuRmVPVC1saWJzX2VhcnRoWzMsNV0pLyhsaWJzX2VhcnRoWzQsNV0gLSBsaWJzX2VhcnRoWzIsNV0pLAogICAgICAgICAgICAgICAgICAgICAgICJNZyI9IChMSUJTLk1nTy1saWJzX2VhcnRoWzMsNl0pLyhsaWJzX2VhcnRoWzQsNl0gLSBsaWJzX2VhcnRoWzIsNl0pLAogICAgICAgICAgICAgICAgICAgICAgICJDYSI9IChMSUJTLkNhTy1saWJzX2VhcnRoWzMsN10pLyhsaWJzX2VhcnRoWzQsN10gLSBsaWJzX2VhcnRoWzIsN10pLAogICAgICAgICAgICAgICAgICAgICAgICJOYSI9IChMSUJTLk5hMk8tbGlic19lYXJ0aFszLDhdKS8obGlic19lYXJ0aFs0LDhdIC0gbGlic19lYXJ0aFsyLDhdKSwKICAgICAgICAgICAgICAgICAgICAgICAiSyI9IChMSUJTLksyTy1saWJzX2VhcnRoWzMsOV0pLyhsaWJzX2VhcnRoWzQsOV0gLSBsaWJzX2VhcnRoWzIsOV0pKSAlPiUKICBzZWxlY3QoIWMoTElCUy5TaU8yLCBMSUJTLlRpTzIsIExJQlMuQWwyTzMsIExJQlMuRmVPVCwgTElCUy5NZ08sIExJQlMuQ2FPLCBMSUJTLk5hMk8sIExJQlMuSzJPKSkKCmVhcnRoaGVhdG1hcDwtYXMubWF0cml4KGVhcnRoaGVhdG1hcCkKZWFydGhoZWF0bWFwPC1hcy5kYXRhLmZyYW1lKGVhcnRoaGVhdG1hcCkKCnJvd25hbWVzKGVhcnRoaGVhdG1hcCk8LWVhcnRoaGVhdG1hcCR4CgojZWFydGhoZWF0bWFwPC1lYXJ0aGhlYXRtYXBbLDI6OV0KZWFydGhoZWF0bWFwWywyOjldPC1zYXBwbHkoZWFydGhoZWF0bWFwWywyOjldLGFzLm51bWVyaWMpCgpwaGVhdG1hcChlYXJ0aGhlYXRtYXBbLDI6OV0sc2NhbGU9Im5vbmUiLGNsdXN0ZXJfcm93cz1GLGNsdXN0ZXJfY29scz1GLAogICAgbWFpbj0iTWVhbnMgYW5kIE1lZGlhbnMgb2YgTElCUyBkYXRhIHdpdGhpbiA3bSBvZiBQSVhMIEFicmFzaW9uLCBcbiBFYXJ0aCBTY2FsZWQiKQpgYGAKVXNpbmcgQWFkaSdzIGVhcnRoIHNjYWxpbmcgdGVjaG5pcXVlLCB3ZSBjYW4gY29tcGFyZSBvdXIgdHdvIGVhcmxpZXIgaGVhdG1hcHMgd2l0aCBhbiBlYXJ0aCBzY2FsZWQgaGVhdG1hcC4gVGhlIG1haW4gY29uc2lzdGVuY3kgYmV0d2VlbiB0aGVzZSBoZWF0bWFwcyBpcyBoaWdoIHZhcmlhdGlvbiBpbiB0aGUgTWcgb3IgTWdPIGNvbHVtbnMuCgojIyA1LjUgQ29uY2x1c2lvbnMsIExpbWl0YXRpb25zLCAgYW5kIEZ1dHVyZSBXb3JrLgoKTW9yZSBhbmFseXNpcyBvZiB0aGUgTElCUyBkYXRhIGdyb3VwZWQgYnkgUElYTCBuZWVkcyB0byBiZSBkb25lLiBJIHRoaW5rIGEgUHJpbmNpcGxlIENvbXBvbmVudCBhbmFseXNpcyBjb3VsZCBiZSBpbnRlcmVzdGluZyB0byBoZWxwIHVzIHNlZSB3aGF0IGZhY3RvcnMgYnJlYWsgdXAgdGhlIGRpZmZlcmVudCBncm91cHMuIEkgYWxzbyB0aGluayBhIHNpbWlsYXJpdHkgYW5hbHlzaXMgd2l0aGluIHRoZSBncm91cHMgY291bGQgYmUgaW50ZXJlc3RpbmcuIAoKT25lIHBvdGVudGlhbCBpc3N1ZSB3aXRoIHRoZSBjb21iaW5lZCBMSUJTIGFuZCBQSVhMIGRhdGFzZXQsIGlzIHRoYXQgdGhlIExJQlMgZGF0YSBoYXMgc29tZSBkdXBsaWNhdGUgcG9pbnRzIHdpdGggZGlmZmVyZW50IGxhdGl0dWRlIGFuZCBsb25naXR1ZGVzLiBGb3IgZXhhbXBsZSwgdGhlIExJQlMgdGFyZ2V0ICJhZWdpc18wOTA3YV9fX19fX19fXyIgY29udGFpbnMgZHVwbGljYXRlIHBvaW50cyB3aXRoIHRoZSBzYW1lIGRhdGEgd2l0aCBkaWZmZXJpbmcgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSB2YWx1ZXMuIFRoaXMgY291bGQgaW5kaWNhdGUgdGhhdCB0aGVyZSBpcyBtb3JlIGVycm9yIHRoYW4gd2UgdGhpbmsgd2l0aCB0aGUgbGF0aXR1ZGUgYW5kIGxvbmdpdHVkZSBvZiBMSUJTIG1lYXN1cmVtZW50cy4gV2UgYXJlIG5vdCAxMDAlIHN1cmUgd2hhdCB0aGUgTElCUyBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlIGlzIHJlZmVycmluZyB0byAodGhlIGxhc2VyIG9yIHRoZSByb3ZlciksIGJ1dCB0aGlzIGNvdWxkIGluZGljYXRlIHdlIHVuZGVyc3RhbmQgaXQgZXZlbiBsZXNzLiBUaGlzIG5vdGVib29rIHJ1bnMgb24gdGhlIGFzc3VtcHRpb24gdGhhdCB0aGUgbGF0aXR1ZGUgYW5kIGxvbmdpdHVkZSByZWZlcnMgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSByb3Zlci4gCgojIEJpYmxpb2dyYXBoeQpQcm92aWRlIGEgbGlzdGluZyBvZiByZWZlcmVuY2VzIGFuZCBvdGhlciBzb3VyY2VzLgoKKiBbQ291c2luMjFdIENvdXNpbiwgQS4sIFNhdXR0ZXIsIFYuLCBGYWJyZSwgQy4sIERyb21hcnQsIEcuLCBNb250YWduYWMsIEcuLCBEcm91ZXQsIEMuLCBNZXNsaW4sIFAuIFkuLCBHYXNuYXVsdCwgTy4sIEJleXNzYWMsIE8uLCBCZXJuYXJkLCBTLiwgQ2xvdXRpcywgRS4sIEZvcm5pLCBPLiwgQmVjaywgUC4sIEZvdWNoZXQsIFQuLCBKb2huc29uLCBKLiBSLiwgTGFzdWUsIEouLCBPbGxpbGEsIEEuIE0uLCBEZSBQYXJzZXZhbCwgUC4sIEdvdXksIFMuLCAmIENhcm9uLCBCLiAoMjAyMSkuIFN1cGVyQ2FtIGNhbGlicmF0aW9uIHRhcmdldHMgb24gYm9hcmQgdGhlIHBlcnNldmVyYW5jZSByb3ZlcjogRmFicmljYXRpb24gYW5kIHF1YW50aXRhdGl2ZSBjaGFyYWN0ZXJpemF0aW9uLiBTcGVjdHJvY2hpbWljYSBBY3RhIFBhcnQgQjogQXRvbWljIFNwZWN0cm9zY29weSwgMTA2MzQxLiBodHRwczovL2RvaS5vcmcvMTAuMTAxNi9qLnNhYi4yMDIxLjEwNjM0MQoKKiBbSGFtaWx0b24xOF0gSGFtaWx0b24gTkUsIEZlcnJ5IE0gKDIwMTgpLiDigJxnZ3Rlcm46IFRlcm5hcnkgRGlhZ3JhbXMgVXNpbmcgZ2dwbG90Mi7igJ0gX0pvdXJuYWwgb2YgU3RhdGlzdGljYWwgU29mdHdhcmUsIENvZGUgU25pcHBldHNfLCAqODcqKDMpLAogIDEtMTcuIGRvaToxMC4xODYzNy9qc3MudjA4Ny5jMDMgPGh0dHBzOi8vZG9pLm9yZy8xMC4xODYzNy9qc3MudjA4Ny5jMDM+CiAgCiogW0hpam1hbnMyNF0gSGlqbWFucyBSICgyMDI0KS4gX2dlb3NwaGVyZTogU3BoZXJpY2FsIFRyaWdvbm9tZXRyeV8uIFIgcGFja2FnZSB2ZXJzaW9uIDEuNS0yMCwgPGh0dHBzOi8vQ1JBTi5SLXByb2plY3Qub3JnL3BhY2thZ2U9Z2Vvc3BoZXJlPgoKYGBge3J9CiNjaXRhdGlvbigiZ2Vvc3BoZXJlIikKI2NpdGF0aW9uKCJnZ3Rlcm4iKQpgYGAKCgoK
+ + + +
+ + + + + + + + + + + + + + + + diff --git a/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.pdf b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.pdf new file mode 100644 index 0000000..e6d7af4 Binary files /dev/null and b/StudentNotebooks/Assignment08_FinalProjectNotebook/vanesm_finalProjectdF24.pdf differ